4 บั๊กใน Java ที่ซ่อนตัวอยู่หลังการเคาะเว้นวรรคผิดพลาด
มาดู 4 ข้อผิดพลาดในภาษา Java ที่คอมไพเลอร์มองไม่เห็นแต่ตบตาโปรแกรมเมอร์ได้ง่ายๆ พร้อมวิธีแก้ปัญหาด้วยระบบจัดรูปแบบอัตโนมัติ

ภาพประกอบจากคลังภาพสต็อก ไม่ใช่ภาพจากเหตุการณ์จริง
- คอมไพเลอร์ Java ไม่สนใจช่องว่างและการจัดหน้าโค้ด ทำให้อ่านความตั้งใจของมนุษย์คลาดเคลื่อน
- บั๊กปัญหาส่วนใหญ่เกิดจากวงเล็บปีกกาที่วางผิดตำแหน่งหรือการละเลยเครื่องหมายวงเล็บ
- เคสตัวอย่างในประวัติศาสตร์เคยทำให้เกิดช่องโหว่ความปลอดภัยระดับ CVE-2014-1266 มาแล้ว
- การใช้ระบบ format on save และบังคับกฎใน CI ช่วยตัดปัญหาโค้ดเยื้องผิดเพี้ยนได้เด็ดขาด
ในโลกของการพัฒนาซอฟต์แวร์ คอมไพเลอร์อย่าง javac ไม่เคยใส่ใจว่าหน้าตาโค้ดของคุณจะจัดเรียงสวยงามแค่ไหน เนื่องจากช่องว่าง (Whitespace) ไม่มีน้ำหนักความหมายใดๆ ในข้อกำหนดภาษา Java ตัวคอมไพเลอร์จึงอ่านไฟล์ของคุณเป็นกระแสโทเค็นและข้ามทุกเคาะเว้นวรรคที่คุณพิมพ์ไปทั้งหมด ซึ่งไม่มีปัญหากับเครื่องจักร แต่มันกลายเป็นหายนะสำหรับมนุษย์ เพราะการเยื้องหน้าโค้ด (Indentation) คือภาษาที่ใช้สื่อสารระหว่างมนุษย์ด้วยกัน เมื่อเลย์เอาต์ของโค้ดบอกอย่างหนึ่งแต่วงเล็บปีกกาทำงานอีกอย่างหนึ่ง ผู้อ่านมักจะเชื่อเลย์เอาต์ตามสายตา และสุดท้ายบั๊กตัวนั้นก็หลุดรอดไปสู่ระบบจริงในที่สุด
นี่คือ 4 รูปแบบข้อผิดพลาดที่ผู้เขียนเคยเผลอส่งโค้ด หลุดผ่านการรีวิว หรือเกือบพลาดไป โดยทุกโค้ดสนิปเป็ตสามารถคอมไพล์ผ่านได้ปกติ แต่มีการเยื้องบรรทัดที่จงใจหลอกตาเรา
- กับดักลูป for และ while เช่น บรรทัด for (Item item : items); ที่ใส่เครื่องหมาย semicolon ปิดท้ายทันที ทำให้ลูปทำงานวนรอบจนจบโดยไม่ทำอะไรเลย ส่วนบรรทัดถัดไปที่เยื้องหน้าไว้จะถูกรันแค่ครั้งเดียวนอกลูป
- ปัญหาคำสั่งเงื่อนไข if ซ้อน if เมื่อเขียนโค้ดลักษณะ if (customer.isVip()) if (order.isGiftWrapped()) includeGiftCard(order); else chargeUpgradeFee(order); ตามหลักของ Java แล้วคำสั่ง else จะถูกผูกติดกับคำสั่ง if ที่อยู่ใกล้ที่สุดเสมอ ส่งผลให้ลูกค้าทั่วไปไม่ได้ถูกคิดค่าธรรมเนียมอัปเกรด แต่กลับกลายเป็นลูกค้า VIP ที่ไม่มีห่อของขวัญต่างหากที่ต้องเสียเงินส่วนนี้
- ปัญหาหลังจากกระบวนการ refactor เมื่อมีคนลบโค้ดออกหนึ่งบรรทัด ทำให้วงเล็บปีกกาปิดขยับขึ้นสูงไปหนึ่งแถวโดยไม่มีการจัดรูปแบบโค้ดใหม่
- รูปแบบที่มีบรรพบุรุษโด่งดังอย่าง CVE-2014-1266 หรือบั๊ก goto fail ของ Apple ในภาษา C ซึ่งมีโค้ดซ้ำกันภายใต้เงื่อนไขที่ไม่มีวงเล็บปีกกา จนทำให้การตรวจสอบใบรับรอง SSL บน iOS ถูกข้ามไปนานกว่าหนึ่งปี

ภาพประกอบจากคลังภาพสต็อก ไม่ใช่ภาพจากเหตุการณ์จริง
การที่โค้ดสามารถคอมไพล์ผ่านได้แม้ว่าการเยื้องบรรทัดจะผิดเพี้ยน สะท้อนให้เห็นข้อจำกัดสำคัญของ static analysis เครื่องมืออัตโนมัติส่วนใหญ่จะตรวจจับรูปแบบความผิดพลาดเหล่านี้ได้ก็ต่อเมื่อมีนักพัฒนาสั่งรันมันจริงๆ เท่านั้น การพึ่งพาสายตามนุษย์ในช่วงเดดไลน์ที่กระชั้นชิดมักทำให้ความสามารถในการตรวจสอบลดลงอย่างมาก ทางออกที่ยั่งยืนจึงไม่ใช่การพยายามอ่านโค้ดให้ละเอียดขึ้น แต่เป็นการโอนสิทธิ์การจัดการเลย์เอาต์ให้เครื่องจักรทำแทนทั้งหมดเพื่อป้องกันปัญหานี้ตั้งแต่ต้นทาง
แนวทางการแก้ไขปัญหาความผิดเพี้ยนของการจัดหน้าโค้ดได้อย่างเด็ดขาด มีขั้นตอนสำคัญที่สามารถนำไปปรับใช้ได้ทันที:
- เปิดใช้งานฟังก์ชัน Format on save ใน IDE เช่น IntelliJ save actions หรือฟีเจอร์จัดรูปแบบอัตโนมัติใน VS Code เพื่อรักษาโครงสร้างโค้ดให้อยู่ในรูปแบบมาตรฐานตลอดเวลา
- บังคับใช้เครื่องมือตรวจสอบในกระบวนการ CI เช่น Spotless, Checkstyle หรือ fmt-maven-plugin เพื่อสั่งหยุดการ Build ทันทีหากโค้ดไม่ตรงตามรูปแบบ
- ใช้เครื่องมือออนไลน์อย่าง JavaFmt สำหรับตรวจทานสนิปเป็ตด่วนในเบราว์เซอร์โดยที่โค้ดไม่หลุดออกจากแท็บ
ที่มา: Dev.to
พบข้อมูลผิดพลาดในบทความนี้? แจ้งปัญหาบทความนี้
ความคิดเห็น
แสดงความคิดเห็น