การเขียนโปรแกรม มีปัญหายากที่สุดอยู่จริงๆแค่สองอย่าง
เป็น Quote ที่แพร่หลายกันมาก เห็นบางคนสงสัยว่ามันหมายความว่าอย่างไร ก็เลยลองพยายามอธิบายดู อันนี้เขียนจากประสบการณ์และความเข้าใจส่วนตัว ถ้ามีความเห็นยังไงก็เชิญตรง comment ได้ครับ
ก่อนอื่น ขอสำแดงวิชาร้อยกรองอันมีเท่าหางอึ่ง ถอดความเป็นกลอนไทย
“เขียนโปรแกรม ปัญหายาก มีสองอย่าง
อยู่ตามทาง ให้ประสบ พบสงสัย
แรกเหมือนง่าย พอซับซ้อน เริ่มบรรลัย
ยิ่งพบไป ก็ว่ายิ่ง ยากจริงเออ
หนึ่งคือ การตั้งชื่อ ให้ทุกอย่าง
มองพลางพลาง นี่โคตรง่าย ยากไงเหรอ
ลองตั้งชื่อ ของร้อยอย่าง ดูสิเธอ
ตั้งจนเบลอ เหนื่อยชิบหาย ตายพอดี
เพราะว่าตั้ง แล้วนั้น ต้องห้ามซ้ำ
ความหมายย้ำ ต้องสื่อไว้ ในชื่อนี้
ถ้าชื่อยาว ก็คงไม่ ค่อยเข้าที
สั้นไปนี่ คนก็อ่าน ไม่เข้าใจ
อย่างที่สอง cache invalidation
บางอย่างนั้น ต้องคิดนาน ช้าไม่ไหว
จึงใช้ cache คอมคิดแล้ว จำลงไป
ถามย้ำไซร้ จะได้ตอบ ได้ทันที
แล้วทีนี้ จะจำไป ถึงเมื่อไหร่
ถ้าตอบไป ข้อมูลเปลี่ยน ก็ผิดซี่
แต่ถ้าเช็ค ข้อมูลใหม่ ทุกทุกที
ทำแบบนี้ มันก็เหมือน ไม่ได้จำ
อย่างที่สาม off by one มันส์ที่สุด
ใช่ยากสุด แต่ชอบหลุด แถมไม่ขำ
ควรทำสอง รอบที่สาม กลับเผลอทำ
debug ช้ำ กว่าจะเจอ เบลอทุกที”
— @kristw
กลอนข้างบนได้รับแรงบันดาลใจจากคำคมคลาสสิคสองอันนี้
There are only two hard things in Computer Science: cache invalidation and naming things.
— Phil Karlton
There is also a variation on this that says:
There are two hard things in computer science: cache invalidation, naming things, and off-by-one errors.
ปัญหาสองสามอันนี้จริงๆอาจจะไม่ใช่ปัญหาที่ยากซับซ้อนที่สุด ถ้าพูดกันจริงๆ มีปัญหาทางทฤษฎีอีกเยอะที่นักวิจัยทำงานกันหัวแตกเพื่อพยายามแก้ แต่ที่ชอบเอาปัญหาสองสามอันนี้มาแหย่กันเล่นว่ายากที่สุดก็เพราะว่ามันเป็นปัญหาทางปฏิบัติเมื่อทำงานจริงๆที่โปรแกรมเมอร์ส่วนใหญ่จะต้องเคยเจอและปวดหัวกับมันมาไม่น้อย สองอย่างแรกไม่มีคำตอบตายตัวว่าควรแก้อย่างไร ต้องปรับและพิจารณาให้เหมาะสมตามสถานการณ์
การตั้งชื่อ (ไม่ว่าจะเป็นตัวแปร, function, หรือชื่อ file, folder) อาจจะมี naming guideline หรือ convention เมื่อเริ่มต้น project แต่เมื่อ project โตถึงจุดหนึ่งมันมักจะมีสิ่งที่ guideline ไม่ได้คำนึงถึงในตอนแรก แล้วก็ต้องปรับกันใหม่ หรือถ้าไม่ปรับ ก็จะเริ่มเละ
Cache invalidation ก็ยากเพราะ ถ้าเลือก cache อะไรซักอย่างก็ต้องคิดด้วยว่าจะคำนวณผลใหม่เมื่อไหร่ ถ้าใจกล้าๆตั้งไปเลยว่า cache อยู่ได้ 1 ชม.ก็มีความเสี่ยงว่าถ้าข้อมูลเปลี่ยนไป คนที่เข้ามาใน 1 ชม.นั้นก็จะเห็นผลผิดๆ หรือถ้าจะต้องเช็คว่าข้อมูลเปลี่ยนไปมั้ยก่อนจะใช้ cache จะเช็คเร็วๆยังไงให้ไม่เสียเวลาเท่ากับคำนวณใหม่ แล้วการเช็คเร็วๆนี้จะ cache ผลของมันไว้ด้วยมั้ย อาจจะให้ผลการเช็คอยู่ได้สัก 10 นาที เผื่อคนเข้าซ้ำๆจะได้เช็คแค่ทุกๆ 10 นาที แต่ถ้า cache ก็จะเจอปัญหาเดิมอีกรอบ
ส่วน off-by-one error นี่ก็ถามจริงๆว่าใครไม่เคยผิดบ้าง วน loop แล้วทำเกิน/ขาดไป 1 รอบ ไอ้ bug ประเภทนี้มักจะหาตัวยากเพราะมันไม่ค่อย error ไม่แสดงตัวตนที่แท้จริง อาจจะไปผิดตรงผลลัพธ์ ต้องให้เราเล่นไล่จับว่ามันบวกลบคูณหารผิดตรงไหน สุดท้ายแก้แค่บรรทัดเดียวหรือบางทีแค่ตัวอักษรเดียว