วิศวกรรมซอฟต์แวร์

ถาม - ตอบสำหรับมืออาชีพนักวิชาการและนักเรียนที่ทำงานในวงจรการพัฒนาระบบ

6
ใน TDD ฉันต้องเขียน Test ก่อนหรือ Interface ก่อน?
ฉันกำลังเรียนรู้ TDD โดยใช้ c # เท่าที่ฉันรู้ว่าการทดสอบควรผลักดันการพัฒนานั่นคือการเขียนการทดสอบที่ล้มเหลวครั้งแรกหลังจากที่เขียนรหัสขั้นต่ำที่เปลือยเปล่าเพื่อผ่านการทดสอบแล้วทำการทดสอบใหม่ แต่มันก็ยังกล่าวว่า " โปรแกรมเพื่อการเชื่อมต่อที่ไม่ได้ดำเนินการ " เพื่อเขียนอินเตอร์เฟซแรก นี่คือสิ่งที่ความสับสนของฉันเริ่มต้นขึ้นถ้าฉันกำลังเขียนส่วนต่อประสานกันก่อนสิ่งนั้นจะเป็นการละเมิดสองสิ่ง รหัสที่ถูกเขียนขึ้นสำหรับอินเตอร์เฟซจะไม่ได้แรงหนุนจากการทดสอบ มันไม่ได้เป็นขั้นต่ำเปล่าแน่นอนฉันสามารถเขียนด้วยชั้นเรียนที่เรียบง่าย ฉันควรเริ่มด้วยการเขียนการทดสอบสำหรับอินเทอร์เฟซด้วยหรือไม่ ฉันจะทำการทดสอบโดยไม่ใช้อะไร หากคำถามนี้ฟังดูน่าเสียใจสำหรับเรื่องนั้น แต่ฉันสับสนอย่างที่สุด อาจเป็นเพราะฉันกำลังทำสิ่งต่าง ๆ อย่างแท้จริงเช่นกัน
23 c#  unit-testing  tdd 

4
เหตุใดภาษาการเขียนโปรแกรมแบบไดนามิกที่ใช้เป็ดจำนวนมากจึงใช้วิธีการแบบคลาสแทน OOP ต้นแบบ
เนื่องจากภาษาการเขียนโปรแกรมแบบไดนามิกค่อนข้างมากมีคุณสมบัติในการพิมพ์เป็ดและพวกเขายังสามารถเปิดและแก้ไขวิธีการเรียนหรืออินสแตนซ์ได้ตลอดเวลา (เช่นRubyและPython ) ดังนั้น ... คำถามที่ 1) ความต้องการห้องเรียนในภาษาแบบไดนามิกคืออะไร ทำไมภาษาจึงออกแบบวิธีการใช้คลาสเป็น“ เทมเพลต” บางชนิดแทนที่จะเป็นแบบต้นแบบและใช้แค่วัตถุ? จาวาสคริปต์ยังเป็นรุ่นต้นแบบ แต่CoffeeScript (เวอร์ชันปรับปรุงของจาวาสคริปต์) จะเลือกวิธีที่อิงกับคลาส และมันก็เหมือนกันสำหรับLua (รุ่นต้นแบบ) และMoonScript (ตามคลาส) นอกจากนี้ยังมีคลาสใน ES 6 ดังนั้น ... คำถามที่ 2) มีการแนะนำหรือไม่ว่าถ้าคุณพยายามปรับปรุงภาษาที่ใช้ต้นแบบเป็นต้นคุณควรเปลี่ยนเป็นแบบเรียนหรือไม่ ถ้าไม่ทำไมมันถูกออกแบบมาอย่างนั้น?

2
คลาสการทดสอบหน่วยที่มีฟังก์ชันการทำงานออนไลน์
เมื่อหน่วยทดสอบฟังก์ชั่นของคลาสที่มีฟังก์ชั่นส่วนตัวที่ต้องการฟังก์ชั่นออนไลน์ เราจะทดสอบมันได้ยังไง? ตัวอย่างเช่น: public class Foo { public int methodA() { int val = goOnlineToGetVal(); return val; } private int goOnlineToGetVal() { CloudService c = new CloudService(); int oval = c.getValueFromService(); return oval; } } ถ้าฉันจะทดสอบฟังก์ชั่น: 'methodA ()' มันจะพยายามใช้ 'goOnlineToGetVal ()' ซึ่งจะลองใช้งานออนไลน์อย่างไรก็ตามหากการทดสอบนี้เสร็จสิ้นโดยไม่มีการใช้งาน ฉันจะได้รับความคุ้มครองระดับ 100% โดยไม่ต้องออนไลน์ได้อย่างไร

8
ฟังก์ชั่นรับประกันว่าจะไม่ส่งคืนค่าเดิมสองครั้ง [ปิด]
ปิด คำถามนี้จะต้องมีมากขึ้นมุ่งเน้น ไม่ยอมรับคำตอบในขณะนี้ ต้องการปรับปรุงคำถามนี้หรือไม่ อัปเดตคำถามเพื่อให้มุ่งเน้นที่ปัญหาเดียวโดยแก้ไขโพสต์นี้ ปิดให้บริการใน5 ปีที่ผ่านมา นี่เป็นคำถามที่ฉันถูกถามในการสัมภาษณ์งานและฉันไม่สามารถหาคำตอบที่พวกเขากำลังมองหาดังนั้นฉันหวังว่าบางคนที่นี่อาจมีความคิดบางอย่าง เป้าหมายคือการเขียนฟังก์ชั่นที่รับประกันว่าจะไม่ส่งคืนค่าเดิมสองครั้ง สมมติว่าฟังก์ชั่นนี้จะสามารถเข้าถึงได้โดยหลายเครื่องพร้อมกัน ความคิดของฉันคือการกำหนดรหัสเฉพาะให้แต่ละเครื่องแล้วส่งค่านั้นไปยังฟังก์ชันตัวสร้างค่าที่ไม่ซ้ำกัน: var i = 0; function uniq(process_id, machine_id) { return (i += 1).toString() + machine_id + "-" + process_id; } สิ่งนี้จะหลีกเลี่ยงการตกออกมาจากสภาพการแข่งขันเนื่องจากแม้ว่ากระบวนการสองกระบวนการขึ้นไปอ่านค่าเดียวกัน แต่ค่าiส่งคืนแต่ละครั้งจะถูกติดแท็กการรวมกันที่ไม่ซ้ำกันของ id กระบวนการและรหัสเครื่อง อย่างไรก็ตามผู้สัมภาษณ์ของฉันไม่ชอบคำตอบนี้เพราะการนำเครื่องอื่นมาใช้ออนไลน์เกี่ยวข้องกับการกำหนดรหัส ใครจะคิดวิธีอื่นในการแก้ปัญหานี้ที่ไม่เกี่ยวข้องกับการกำหนดค่าเครื่องแต่ละเครื่องให้มีรหัสเฉพาะหรือไม่? ฉันต้องการคำตอบในกรณีที่คำถามนี้เกิดขึ้นอีกครั้ง ขอบคุณ

6
มัลติเธรด: ฉันทำผิดหรือเปล่า?
ฉันกำลังทำงานกับแอพพลิเคชั่นที่เล่นดนตรี ในระหว่างการเล่นบ่อยครั้งสิ่งต่าง ๆ ต้องเกิดขึ้นในเธรดแยกต่างหากเนื่องจากพวกเขาต้องเกิดขึ้นพร้อมกัน ตัวอย่างเช่นบันทึกของคอร์ดจำเป็นต้องได้ยินร่วมกันดังนั้นแต่ละคนจึงได้รับมอบหมายให้เล่นเธรดของตัวเอง (แก้ไขเพื่อชี้แจง: การโทรnote.play()ค้างเธรดจนกว่าโน้ตจะเล่นเสร็จและนี่คือเหตุผลที่ฉันต้องการสาม แยกเธรดเพื่อให้สามารถได้ยินโน้ตสามโน้ตพร้อมกัน) พฤติกรรมแบบนี้จะสร้างเธรดจำนวนมากในระหว่างการเล่นเพลง ตัวอย่างเช่นลองฟังเพลงที่มีท่วงทำนองสั้น ๆ และเพลงประกอบสั้น ๆ ท่วงทำนองทั้งหมดสามารถเล่นได้ในเธรดเดียว แต่ความก้าวหน้าต้องใช้สามเธรดเพื่อเล่นเนื่องจากแต่ละคอร์ดมีสามโน้ต ดังนั้นโค้ดหลอกสำหรับการเล่นโปรเกรสซีจึงเป็นดังนี้: void playProgression(Progression prog){ for(Chord chord : prog) for(Note note : chord) runOnNewThread( func(){ note.play(); } ); } ดังนั้นสมมติว่าความก้าวหน้ามี 4 คอร์ดและเราเล่นสองครั้งกว่าที่เราเปิด3 notes * 4 chords * 2 times= 24 เธรด และนี่เป็นเพียงการเล่นครั้งเดียว จริงๆแล้วมันใช้งานได้ดีในทางปฏิบัติ ฉันไม่เห็นความล่าช้าแฝงที่เห็นได้ชัดหรือข้อบกพร่องที่เกิดจากสิ่งนี้ แต่ฉันต้องการถามว่านี่เป็นการฝึกที่ถูกต้องหรือไม่หรือว่าฉันกำลังทำอะไรผิดปกติ มีเหตุผลหรือไม่ที่จะสร้างเธรดจำนวนมากในแต่ละครั้งที่ผู้ใช้กดปุ่ม? …

2
รูปแบบการออกแบบสำหรับการตรวจสอบข้อมูล
รูปแบบการออกแบบที่ดีที่สุดสำหรับปัญหานี้คืออะไร: ฉันมีวัตถุ A. วัตถุ A สามารถลงทะเบียนหรือลบออกจากฐานข้อมูลขึ้นอยู่กับคำขอของผู้ใช้ การตรวจสอบข้อมูลจะดำเนินการก่อนการลงทะเบียนหรือการลบวัตถุ มีชุดของกฎที่จะตรวจสอบก่อนที่จะสามารถลงทะเบียนวัตถุและชุดของกฎอื่นสำหรับการลบ กฎเหล่านี้บางข้อถือเป็นเรื่องปกติสำหรับการดำเนินการทั้งสองอย่าง จนถึงตอนนี้ฉันคิดว่ารูปแบบการออกแบบห่วงโซ่ความรับผิดชอบเหมาะสมที่สุด แต่ฉันมีปัญหาในการใช้งาน

7
เป็นการสุ่มเปลี่ยนรหัสที่อนุญาตให้ใช้ในการต่อสู้
พื้นหลัง ทีมของฉันใช้การต่อสู้ ฉันยังไม่ได้มอบหมายงาน ไม่มีงานที่รอดำเนินการใน Backlog วันนี้เป็นวันแรงงานสำหรับลูกค้าของฉัน ไม่มีสิ่งต่าง ๆ ที่ต้องทำในวันนี้ฉันต้องการเริ่มการรีแฟคเตอร์รหัสบางอย่างที่ฉันเห็นในโปรเจคที่ฉันกำลังทำงานอยู่ ตกลงในการต่อสู้ถ้าฉันเริ่มการสุ่มรหัสใหม่ที่ฉันมีและไม่ได้เขียนที่รบกวนฉันอยู่ตลอดเวลา แต่ไม่มีเวลาวันอื่น ๆ ที่จะแก้ไขได้เนื่องจากการมอบหมายวันอื่น ๆ ? แล้ววันอื่น ๆ ที่ฉันมีเวลาว่างระหว่างการวิ่ง ฉันทำได้จริงและเชื่อในการฟื้นฟูอย่างต่อเนื่อง ฉันมักจะทำกับชิ้นส่วนของรหัสที่ฉันทำงานเมื่อกำหนดเรื่อง แต่สิ่งที่เกี่ยวกับรหัสอื่น ๆ ที่ฉันเห็นว่าไม่เกี่ยวข้องกับสิ่งที่ฉันกำลังทำงานอยู่ในขณะนั้น?

4
การสื่อสารที่เข้ารหัสด้วย XOR ง่าย ๆ นี้ปลอดภัยหรือไม่?
สมมติว่า Alice และ Peter มีหน่วยความจำแฟลช USB 4GB พวกเขาพบและบันทึกไฟล์ทั้งสองไฟล์สองไฟล์ชื่อว่าalice_to_peter.key(2GB) และpeter_to_alice.key(2GB) ซึ่งมีบิตที่สร้างแบบสุ่ม พวกเขาไม่เคยพบกันอีก แต่สื่อสารด้วยระบบอิเล็กทรอนิกส์ อลิซยังคงรักษาตัวแปรที่เรียกว่าalice_pointerและปีเตอร์รักษาตัวแปรที่เรียกว่าpeter_pointerซึ่งทั้งสองจะถูกตั้งค่าเริ่มต้นเป็นศูนย์ เมื่ออลิซต้องการส่งข้อความถึงปีเตอร์เธอก็ทำ (อยู่ที่nข้อความที่ nthth): encrypted_message_to_peter[n] = message_to_peter[n] XOR alice_to_peter.key[alice_pointer + n] encrypted_payload_to_peter = alice_pointer + encrypted_message_to_peter alice_pointer += length(encrypted_message_to_peter) (และเพื่อความปลอดภัยสูงสุดสามารถลบส่วนที่ใช้แล้วของคีย์ได้) ปีเตอร์ได้รับencrypted_payload_to_peterอ่านที่alice_pointerเก็บไว้ที่จุดเริ่มต้นของข้อความและทำ: message_to_peter[n] = encrypted_message_to_peter[n] XOR alice_to_peter.key[alice_pointer + n] และเพื่อความปลอดภัยสูงสุดหลังจากอ่านข้อความจะลบส่วนที่ใช้ไปของคีย์ด้วย - แก้ไข: อันที่จริงขั้นตอนนี้ด้วยอัลกอริทึมแบบง่าย ๆ (ไม่มีการตรวจสอบความสมบูรณ์และการรับรองความถูกต้อง) ช่วยลดความปลอดภัยให้ดูที่Paŭlo Ebermann โพสต์ด้านล่าง เมื่อปีเตอร์ต้องการที่จะส่งข้อความไปยังอลิซที่พวกเขาทำกลับครั้งนี้ด้วยและpeter_to_alice.keypeter_pointer …

4
ตัวเลือกการพึ่งพาเป็น npm?
ฉันมีคำถามที่คล้ายกันนี้แต่ไม่เหมือนกัน ฉันต้องการให้ผู้ใช้แอปของฉันติดตั้งด้วยการอ้างอิงอะไรก็ตามที่จำเป็นสำหรับวิธีที่เขาต้องการใช้ ตัวอย่างเช่นหากพวกเขาต้องการคงอยู่กับ MongoDB จะมีการติดตั้งเฉพาะไลบรารีที่เกี่ยวกับ Mongo เท่านั้น แต่หากพวกเขาต้องการที่จะคงอยู่กับ Redis จะมีการติดตั้งเฉพาะไลบรารีที่เกี่ยวข้องกับ Redis เท่านั้น ฉันไม่ต้องการให้พวกเขาดาวน์โหลดและติดตั้งห้องสมุดที่พวกเขาจะไม่ใช้ ฉันรู้ว่าฉันสามารถทำได้เพื่อจุดประสงค์ในการพัฒนาdevDependenciesแต่สิ่งนี้ยิ่งไปกว่านั้น ดังที่คำตอบในคำถามข้างต้นกล่าวว่านี่เกี่ยวข้องกับโปรไฟล์setuptools extras_requireของPython และ Clojure leiningenมากขึ้น มีอะไรแบบนั้นในเวลา 23.00 น. ฉันรู้สึกว่าdevDependenciesควรเป็นdevโปรไฟล์ของวิธีที่หลากหลายในการระบุการพึ่งพา

4
Data Oriented Design - ทำไม่ได้กับสมาชิกมากกว่า 1-2 โครงสร้าง?
ตัวอย่างปกติของ Data Oriented Design ที่มีโครงสร้าง Ball: struct Ball { float Radius; float XYZ[3]; }; แล้วพวกเขาก็สร้างอัลกอริทึมที่วนซ้ำstd::vector<Ball>เวกเตอร์ จากนั้นพวกเขาก็ให้สิ่งเดียวกัน แต่นำไปใช้ใน Data Oriented Design: struct Balls { std::vector<float> Radiuses; std::vector<XYZ[3]> XYZs; }; ซึ่งเป็นสิ่งที่ดีและทั้งหมดถ้าคุณจะทำซ้ำรัศมีทั้งหมดก่อนอื่นจากนั้นทุกตำแหน่งและอื่น ๆ อย่างไรก็ตามคุณจะย้ายลูกบอลในเวกเตอร์ได้อย่างไร ในรุ่นเดิมหากคุณมีstd::vector<Ball> BallsAllคุณก็สามารถย้ายใดๆBallsAll[x]BallsAll[y] อย่างไรก็ตามในการทำเช่นนั้นสำหรับ Data Oriented เวอร์ชั่นคุณต้องทำสิ่งเดียวกันสำหรับทุก ๆ คุณสมบัติ (2 ครั้งในกรณีของ Ball - radius and position) แต่มันจะแย่ลงถ้าคุณมีคุณสมบัติมากขึ้น คุณจะต้องเก็บดัชนีสำหรับ "ลูกบอล" แต่ละลูกและเมื่อคุณพยายามที่จะย้ายไปรอบ …

2
เว็บไซต์ที่ใช้งานภายใน: มีกรณีที่น่าสนใจสำหรับ SQLite หรือไม่?
เฟรมเวิร์กเว็บจำนวนมากเช่นFlaskหรือDjangoใช้SQLiteเป็นฐานข้อมูลเริ่มต้น SQLiteนั้นน่าสนใจเพราะมันรวมอยู่ในไพ ธ อนและค่าใช้จ่ายในการจัดการค่อนข้างต่ำ อย่างไรก็ตามไซต์การผลิตสาธารณะที่มีปริมาณการใช้งานสูงส่วนใหญ่ใช้ฐานข้อมูลที่หนักกว่า: mySQL, Oracle หรือ postgresql คำถาม : สมมติ: ปริมาณการใช้ของไซต์อยู่ในระดับปานกลางและการเข้าถึงแบบอ่าน / เขียนในฐานข้อมูลจะเกิดขึ้นพร้อมกัน เราจะใช้SQLAlchemyกับล็อคการเขียน SQLite (แม้ว่าความคิดเห็นนี้ทำให้ฉันกังวลเล็กน้อย) ฐานข้อมูลอาจมีบันทึก 60,000 รายการ โครงสร้างข้อมูลไม่ต้องการคุณสมบัติขั้นสูงที่พบในฐานข้อมูลที่หนักกว่า มีกรณีที่น่าสนใจต่อการเกิดพร้อมกันของSQLiteสำหรับเว็บไซต์ที่ทำหน้าที่เป็นเครื่องมือภายในองค์กรที่มีปริมาณการใช้งานปานกลางหรือไม่? ถ้าเป็นเช่นนั้นเงื่อนไขใดที่ทำให้SQLiteมีปัญหาการทำงานพร้อมกัน? ฉันกำลังมองหาสาเหตุที่เฉพาะเจาะจงที่เป็นที่รู้จักแทนการกลัวนิ้วชี้โดยทั่วไป / ไม่พร้อมเพรียง

4
มันแย่แค่ไหนที่เรียก println () บ่อยครั้งกว่าการต่อสตริงเข้าด้วยกันและเรียกมันครั้งเดียว?
คำถามนี้ถูกโยกย้ายจาก Code Exchange Stack Stack เพราะสามารถตอบได้ใน Software Engineering Stack Exchange อพยพ 5 ปีที่ผ่านมา ฉันรู้ว่าผลลัพธ์ไปยังคอนโซลเป็นการดำเนินการที่มีราคาแพง ในความสนใจของการอ่านรหัสบางครั้งมันก็ดีที่จะเรียกฟังก์ชั่นเพื่อส่งออกข้อความสองครั้งแทนที่จะมีสตริงข้อความยาวเป็นอาร์กิวเมนต์ ตัวอย่างเช่นมีประสิทธิภาพน้อยกว่าที่จะมี System.out.println("Good morning."); System.out.println("Please enter your name"); เมื่อเทียบกับ System.out.println("Good morning.\nPlease enter your name"); ในตัวอย่างความแตกต่างเป็นเพียงการโทรหนึ่งครั้งprintln()แต่จะเกิดอะไรขึ้นถ้ามีมากกว่านั้น ในหมายเหตุที่เกี่ยวข้องคำแถลงเกี่ยวกับการพิมพ์ข้อความอาจดูแปลกในขณะที่ดูซอร์สโค้ดหากข้อความที่จะพิมพ์ยาว ถ้าตัวอักษรไม่สามารถทำให้สั้นลงได้สิ่งที่สามารถทำได้? ควรเป็นกรณีที่มีการprintln()โทรหลายสายหรือไม่? มีคนเคยบอกฉันว่าบรรทัดของรหัสไม่ควรเกิน 80 อักขระ (IIRC) ดังนั้นคุณจะทำอย่างไร System.out.println("Good morning everyone. I am here today to present you with a very, …
23 java  c++  performance  c  io 

6
ออกแบบสำหรับการซิงค์ข้อมูลใน Android
ฉันเห็นการปรับใช้สองแบบสำหรับการซิงค์ข้อมูลระหว่างเซิร์ฟเวอร์และไคลเอนต์ในแอปส่วนใหญ่ สิ่งนี้ถือว่าไม่มีการตั้งค่า GCM: - เรียกใช้บริการเจตนาเป็นระยะ ๆ ซึ่งจะดาวน์โหลดข้อมูลจากเครือข่ายและจัดเก็บในฐานข้อมูล การนำ Sync Adapter มาใช้ซึ่งทำงานเป็นระยะ คุณแนะนำให้ใช้ข้อใดข้างต้นในแอพของคุณและเพราะเหตุใด

4
Odata ต้องการอะไรเมื่อฉันมี JSON
ฉันกำลังพยายามที่จะเข้าใจจุดของ Odata และเมื่อมันจะทำให้รู้สึก ตอนนี้ฉันทำงานอย่างไรฉันใช้ตัวควบคุม ASP.NET และ MVC / WebApi เพื่อทำให้เป็นอันดับ / ดีซีเรียลไลซ์ออบเจ็กต์ลงใน JSON และให้จาวาสคริปต์ทำอะไรบางอย่างกับมัน จากสิ่งที่ฉันสามารถบอกได้ว่าประโยชน์ของ OData นั้นสามารถสืบค้นได้โดยตรงจาก URL ... แต่เนื่องจากฉันเขียนรหัสลูกค้าและเซิร์ฟเวอร์ไม่จำเป็นต้องทำเช่นนั้น ใครบ้างที่เคยแยกผลลัพธ์ของแบบสอบถาม ODaya ใน javascript? บางที OData เป็นอีกเรื่องเกี่ยวกับการให้จุดสิ้นสุดทั่วไปสำหรับไคลเอนต์ทั้งหมดเพื่อรับข้อมูลรายละเอียดจากแบบสอบถามที่ JSON ไม่ได้ให้ ดังนั้นถ้าฉันเป็นผู้ให้บริการข้อมูลฉันคิดว่าเป็นสิ่งที่ Odata ใช้เพื่ออะไร ช่วยฉันเข้าใจวัตถุประสงค์และการใช้ REST / JSON / ODATA
23 javascript  rest  json 

4
ต้องการตัวอย่างมากกว่าเอกสาร มันเป็นปัญหาพฤติกรรมหรือไม่?
เมื่อใดก็ตามที่ฉันเจอAPIใหม่หรือภาษาการเขียนโปรแกรมหรือแม้แต่หน้าลินุกซ์อย่างง่ายฉันมักจะหลีกเลี่ยงพวกเขา (นับตั้งแต่ที่ฉันจำได้) และมักจะพึ่งพาตัวอย่างเพื่อทำความเข้าใจแนวคิดใหม่ ๆ โดยไม่รู้ตัวฉันจะหลีกเลี่ยงเอกสาร / API ทุกครั้งที่มันไม่ตรงไปตรงมาหรือเป็นความลับหรือน่าเบื่อเพียงธรรมดา เป็นเวลาหลายปีแล้วที่ฉันเริ่มเขียนโปรแกรมและตอนนี้ฉันรู้สึกว่าฉันต้องแก้ไขวิธีการของฉันเมื่อฉันรู้ว่าฉันสร้างความเสียหายมากขึ้นโดยการละเว้นจากการอ่านเอกสารที่เป็นความลับ / ยากเนื่องจากยังดีกว่าตัวอย่างเป็นทางการ เอกสารมีความครอบคลุมมากกว่าตัวอย่างจากที่นั่น แม้หลังจากตระหนักว่าตัวอย่างควรได้รับการปฏิบัติเหมือนเป็นค่า "เพิ่ม" แทนที่จะเป็นแหล่ง "หลัก" สำหรับการเรียนรู้ ฉันจะทำลายนิสัยที่ไม่ดีนี้ในฐานะโปรแกรมเมอร์หรือฉันคิดมากได้อย่างไร

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.