ชุมชนโปรแกรมเมอร์กำลังพูดถึงกรณีศึกษาที่น่าสนใจที่เผยให้เห็นข้อจำกัดพื้นฐานของระเบียบวิธีการพัฒนาแบบเข้มงวด เรื่องราวนี้มีศูนย์กลางอยู่ที่แนวทางที่แตกต่างกันสองแบบในการสร้างตัวแก้ปัญหา Sudoku ซึ่งเน้นย้ำว่าทำไมเทคนิคการเขียนโปรแกรมแบบเดียวจึงไม่สามารถแก้ปัญหาทั้งหมดได้
เรื่องเล่าของตัวแก้ปัญหา Sudoku สองแบบ
Ron Jeffries ผู้สนับสนุน Test-Driven Development (TDD) อย่างเด่นชัด ได้พยายามสร้างตัวแก้ปัญหา Sudoku โดยใช้ระเบียบวิธีที่เขาชื่นชอบ แม้จะมีบล็อกโพสต์หลายเรื่องและความพยายามอย่างกว้างขวางเป็นเวลา 20 ปี แนวทางของเขาก็ยังดิ้นรนที่จะสร้างโซลูชันที่สวยงาม ในขณะเดียวกัน Peter Norvig หัวหน้าฝ่ายวิจัยของ Google และผู้เชี่ยวชาญด้าน AI ได้แก้ปัญหาเดียวกันด้วยโค้ดที่สะอาดและเป็นระบบประมาณ 20 บรรทัด
ความแตกต่างนั้นชัดเจนมาก Jeffries เข้าหาปัญหาแบบค่อยเป็นค่อยไป เขียนเทสต์ก่อนแล้วสร้างฟังก์ชันการทำงานทีละชิ้น อย่างไรก็ตาม วิธีการนี้นำเขาไปสู่เส้นทางที่ซับซ้อนโดยไม่มีความเข้าใจที่ชัดเจนเกี่ยวกับโครงสร้างของปัญหาพื้นฐาน ในทางกลับกัน Norvig วิเคราะห์ปัญหาระดับสูงก่อน ระบุว่าเป็นปัญหา constraint satisfaction problem และใช้เครื่องมืออัลกอริทึมที่เหมาะสม
Constraint Satisfaction Problem (CSP): ปัญหาทางคณิตศาสตร์ที่คุณต้องหาค่าสำหรับตัวแปรที่ตอบสนองกฎหรือข้อจำกัดบางอย่าง
การเปรียบเทียบแนวทางการเขียนโปรแกรม:
- Ron Jeffries (TDD): โพสต์บล็อกหลายโพสต์ การทำซ้ำมากกว่า 20 ปี แนวทางแบบเพิ่มทีละน้อยที่ซับซ้อน ดิ้นรนเพื่อเข้าถึงโซลูชันที่สง่างาม
- Peter Norvig (ความรู้เฉพาะด้าน): โค้ดประมาณ 20 บรรทัด การวิเคราะห์อย่างเป็นระบบ แนวทางการแก้ปัญหาด้วยข้อจำกัด โซลูชันที่สะอาดและมีประสิทธิภาพ
ปัญหาพื้นฐานของแนวทางเป็นระบบ
การอภิปรายของชุมชนเผยให้เห็นปัญหาเชิงปรัชญาที่ลึกซึ้งกว่า นักพัฒนาหลายคนเคยพบเจอสถานการณ์ที่คล้ายกันที่การยึดติดกับระเบียบวิธีอย่างเข้มงวดกลับขัดขวางการแก้ปัญหามากกว่าช่วยเหลือ ปัญหาไม่ได้อยู่ที่ TDD แย่โดยธรรมชาติ แต่อยู่ที่การนำไปใช้กับปัญหาที่ความรู้ด้านอัลกอริทึมการค้นหามีความสำคัญมากกว่าระเบียบวิธีการทดสอบ
หากคุณไม่รู้วิธีเข้าหาปัญหา คุณจะไม่ได้รับโซลูชัน
ข้อมูลเชิงลึกนี้สัมผัสกับความจริงพื้นฐานในการเขียนโปรแกรม: ระเบียบวิธีเป็นเครื่องมือ ไม่ใช่โซลูชันวิเศษ พวกมันทำงานได้ดีที่สุดเมื่อคุณเข้าใจโดเมนของปัญหาแล้วและสามารถใช้เทคนิคที่เหมาะสม เมื่อ Jeffries ดิ้นรนกับ Sudoku ไม่ใช่เพราะ TDD ล้มเหลวในฐานะแนวคิด แต่เพราะเขาขาดความรู้เฉพาะเกี่ยวกับอัลกอริทึมการค้นหาและ constraint satisfaction ที่ปัญหาต้องการ
ความเป็นไปไม่ได้ของการแก้ปัญหาแบบสากล
การอภิปรายเชื่อมโยงตัวอย่างปฏิบัติจริงนี้กับแนวคิดเชิงทฤษฎีที่ลึกซึ้งกว่าจากวิทยาการคอมพิวเตอร์ Entscheidungsproblem หรือปัญหาการตัดสินใจ ได้พิสูจน์ทางคณิตศาสตร์ว่าไม่มีอัลกอริทึมสากลสำหรับการกำหนดว่าข้อความใดๆ ที่กำหนดให้สามารถพิสูจน์ได้จากชุดกฎหรือไม่ สิ่งนี้มีผลกระทบอย่างลึกซึ้งต่อระเบียบวิธีการเขียนโปรแกรม
หากเราไม่สามารถกำหนดได้ว่าโปรแกรมแก้งานเฉพาะในทุกกรณีหรือไม่ เราก็ไม่สามารถสร้างวิธีการสากลสำหรับการเขียนโปรแกรมที่แก้งานใดๆ ที่กำหนดให้ได้แน่นอน นี่หมายความว่าความฝันของระเบียบวิธีการพัฒนาแบบเดียวเหมาะกับทุกสถานการณ์นั้นเป็นไปไม่ได้ทางคณิตศาสตร์
Entscheidungsproblem: ปัญหาที่มีชื่อเสียงในตรรกศาสตร์คณิตศาสตร์ที่ถามว่ามีอัลกอริทึมที่สามารถกำหนดได้หรือไม่ว่าข้อความทางคณิตศาสตร์ใดๆ สามารถพิสูจน์ได้
แนวคิดทางเทคนิคหลัก:
- ปัญหาการหาคำตอบที่ต้องเป็นไปตามข้อจำกัด (CSP): กรอบการทำงานทางคณิตศาสตร์สำหรับปัญหาที่มีตัวแปรซึ่งต้องเป็นไปตามกฎเกณฑ์เฉพาะเจาะจง
- Entscheidungsproblem: การพิสูจน์ทางทฤษฎีที่แสดงให้เห็นว่าไม่มีอัลกอริทึมสากลที่สามารถกำหนดความสามารถในการพิสูจน์ทางคณิตศาสตร์ได้
- การพัฒนาโดยใช้การทดสอบเป็นหลัก (TDD): วิธีการที่เขียนการทดสอบก่อนการเขียนโค้ดสำหรับการใช้งานจริง
สิ่งที่ใช้ได้จริงในทางปฏิบัติ
แทนที่จะพึ่งพาระเบียบวิธีเดียว โปรแกรมเมอร์ที่ประสบความสำเร็จจะสร้างชุดเครื่องมือที่หลากหลาย พวกเขาเรียนรู้แนวทางที่แตกต่างกันสำหรับปัญหาประเภทต่างๆ และพัฒนาสัญชาตญาณเกี่ยวกับเวลาที่จะใช้เครื่องมือแต่ละอย่าง สำหรับปัญหาอัลกอริทึมเช่น Sudoku การเข้าใจเทคนิคการค้นหาและ constraint satisfaction เป็นสิ่งสำคัญ สำหรับแอปพลิเคชันธุรกิจ TDD อาจมีค่ามากกว่าเพราะความต้องการมักไม่ชัดเจนและเปลี่ยนแปลงบ่อย
ชุมชนได้ระบุแนวทางปฏิบัติหลายอย่างที่มีแนวโน้มจะใช้ได้ผลในโดเมนปัญหาต่างๆ: ใช้เวลากับนักพัฒนาที่มีประสบการณ์ คิดอย่างเป็นวิทยาศาสตร์โดยการตั้งสมมติฐานและทดสอบ ถอยหลังเพื่อได้มุมมองใหม่ และเขียนโค้ดจำนวนมากเพื่อสร้างการรู้จำรูปแบบเมื่อเวลาผ่านไป
เครื่องมือแก้ปัญหาที่ชุมชนแนะนำ:
- ใช้เวลากับผู้ปฏิบัติงานที่มีประสบการณ์
- ประยุกต์ใช้การคิดเชิงวิทยาศาสตร์ (สมมติฐาน → ทดสอบ → ปรับปรุง)
- ถอยออกมาเพื่อมองมุมมองใหม่
- เขียนโค้ดเพื่อสร้างการรู้จำรูปแบบ
- พูดคุยแลกเปลี่ยนความคิดกับผู้อื่น
- ใช้เครื่องมือที่เหมาะสม เช่น LLMs เมื่อมีประโยชน์
ภาพใหญ่
กรณีศึกษานี้เป็นการเตือนใจว่าการเขียนโปรแกรมยังคงเป็นศิลปะมากเท่ากับวิทยาศาสตร์ แม้ว่าเราจะมีเครื่องมือและระเบียบวิธีที่ทรงพลัง แต่พวกมันต้องการการตัดสินใจของมนุษย์เพื่อใช้อย่างมีประสิทธิภาพ นักพัฒนาที่ประสบความสำเร็จมากที่สุดไม่ใช่คนที่ปฏิบัติตามกระบวนการที่เข้มงวด แต่เป็นคนที่เข้าใจว่าเมื่อไหร่และอย่างไรจึงจะใช้แนวทางที่แตกต่างกัน
เรื่อง Sudoku ในที่สุดแสดงให้เห็นว่าความเชี่ยวชาญมาจากการสร้างชุดเครื่องมือเทคนิคที่หลากหลายและพัฒนาปัญญาในการรู้ว่าเครื่องมือใดเหมาะกับสถานการณ์ไหน ไม่มีระเบียบวิธีใดๆ ไม่ว่าจะมีเจตนาดีเพียงใด ที่สามารถแทนที่ความเข้าใจอย่างลึกซึ้งของโดเมนปัญหาและความยืดหยุ่นในการปรับแนวทางเมื่อจำเป็น
อ้างอิง: Reflections on Sudoku, Or the Impossibility of Systematizing Thought