3 คะแนน โดย GN⁺ 2024-04-22 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • ผลลัพธ์ที่เห็นเป็นโค้ดไม่ใช่งานทั้งหมดของวัน แต่ใกล้เคียงกับ ผลลัพธ์ล้วน ๆ ที่เหลืออยู่หลังจากอ่าน ค้นคว้า ดีบัก ตรวจสอบ และตัดสินใจ
  • จากคำถามอย่างไม่เป็นทางการที่ถามโปรแกรมเมอร์มาหลายปี คำตอบที่พบบ่อยที่สุดสำหรับการพิมพ์การเปลี่ยนแปลงที่ใช้เวลา 6 ชั่วโมงกลับเข้าไปใหม่โดยดูจาก diff เพียงอย่างเดียวคือ ประมาณ 30 นาที
  • สัดส่วนนี้ไม่ได้มาจากงานวิจัยทางวิทยาศาสตร์ แต่ตั้งอยู่บนแบบสอบถามและการสังเกต diff ถึงอย่างนั้นก็เป็นเกณฑ์เชิงปฏิบัติในการมองว่าการเขียนโปรแกรมคือ 1/12 เป็นการลงมือทำ และ 11/12 เป็นการคิด
  • การพัฒนาซอฟต์แวร์ใกล้เคียงกับ งานออกแบบ มากกว่าการผลิตแบบโรงงาน และหลังจากมีการออกแบบครั้งแรกแล้ว เครื่องจักรจะทำการคัดลอกด้วยต้นทุนส่วนเพิ่มที่แทบเป็นศูนย์
  • หากการจัดการและกระบวนการถูกปรับให้เหมาะกับการเพิ่มเวลาพิมพ์ ก็จะให้ผลผิดทิศทาง สิ่งที่สำคัญกว่าคือ สภาพแวดล้อมและวิธีทำงานร่วมกัน ที่ยกระดับคุณภาพของการคิด

เวลาที่ใช้ในการพิมพ์งาน 6 ชั่วโมงกลับเข้าไปใหม่

  • สมมติว่าในวันที่ดีที่แทบไม่มีประชุมและสิ่งรบกวน โปรแกรมเมอร์ได้ทำ งานเขียนโปรแกรมอย่างจริงจัง 6 ชั่วโมง
  • ก่อนเลิกงานได้พิมพ์ diff ออกมา แต่ในช่วงกลางคืนระบบควบคุมเวอร์ชันเสียหายและถูกกู้คืนจากแบ็กอัปของวันก่อน ทำให้งานทั้งวันหายไป
  • แก่นของคำถามคือ เมื่อโปรแกรมเมอร์ได้รับ diff แล้ว จะใช้เวลานานเท่าไรในการพิมพ์งาน 6 ชั่วโมงนั้นกลับเข้าไปใน codebase อีกครั้ง
  • ตลอดหลายปี ได้ถามคำถามนี้กับโปรแกรมเมอร์ในงานประชุม ลูกค้า เพื่อนร่วมงาน และโปรแกรมเมอร์ที่เพิ่งพบกันครั้งแรก คำตอบที่พบบ่อยที่สุดคือ ประมาณ 30 นาที
  • ใน 6 ชั่วโมงมีช่วง 30 นาทีอยู่ 12 ครั้ง ดังนั้นการสังเกตนี้จึงนำไปสู่ถ้อยคำว่าการเขียนโปรแกรมคือ 1/12 เป็นการลงมือทำ และ 11/12 เป็นการคิด

ลักษณะและข้อจำกัดของสัดส่วนนี้

  • ตัวเลขนี้ไม่ได้มาจากงานวิจัยทางวิทยาศาสตร์ที่เข้มงวด และไม่ใช่การสำรวจอย่างเป็นทางการที่มีบันทึกอย่างดี
  • เป้าหมายไม่ใช่การค้นหากฎเชิงสถิติหรือคณิตศาสตร์ของกิจกรรมการเขียนโปรแกรม แต่คือการหา คำตอบที่สมเหตุสมผล ต่อคำถามที่สมเหตุสมผล
  • ไม่มีบริษัทใดต้องการลบงานทั้งวันจริง ๆ เพื่อพิสูจน์หรือโต้แย้งการทดลองนี้ ดังนั้นหลักฐานจึงยังอยู่ในระดับการประมาณและการสังเกต diff รายวัน
  • จากการดู changelog และ diff จำนวนมาก พบว่าในวันที่ดี ปริมาณการเปลี่ยนแปลงล้วน ๆ โดยทั่วไปดูเหมือนจะอยู่ที่ราว 30 นาที ± 10 นาที

การพิมพ์ไม่ใช่คอขวด

  • คำกล่าวว่า “การพิมพ์ไม่ใช่คอขวด” ถูกพูดซ้ำมานานแล้วทั้งบนสติกเกอร์และโซเชียลมีเดีย
  • สำหรับโปรแกรมเมอร์บางคน การพิมพ์เองอาจเป็นคอขวดได้ แต่หัวใจของการผลิตโค้ดอย่างรวดเร็วมักไม่ใช่แค่ความเร็วในการพิมพ์หรือความชำนาญในการใช้เครื่องมือ
  • ในบทความยาวบน Quora เรื่อง “How do programmers code so quickly?” ผู้ตอบคนหนึ่งกล่าวถึง muscle memory, ความชำนาญในการใช้เครื่องมือ, ความสามารถในการดีบัก, ความสามารถในการพิมพ์ และความสามารถในการค้นหาข้อมูล
  • อย่างไรก็ตาม ในการผลิตโค้ดอย่างรวดเร็ว การพิมพ์และเครื่องมือเป็นเพียงตัวช่วย มากกว่า และเวลาที่ใช้ตัดสินใจว่าควรทำอะไรมีสัดส่วนมากกว่า

ความแตกต่างระหว่างโรงงานซอฟต์แวร์กับงานออกแบบ

  • ในการผลิตสินค้าทางกายภาพ งานส่วนใหญ่ที่มองเห็นได้คือการเคลื่อนไหว การรีด ปั๊ม กด มิลลิ่ง จัดวาง และประกอบเหล็กดูเหมือนเป็นตัวงาน
  • โรงงานสมัยใหม่ทำการเคลื่อนไหวที่แม่นยำบนพื้นฐานของแบบจำลองเชิงนามธรรมหรือข้อมูล เช่นเดียวกับเครื่อง CNC และมนุษย์ทำหน้าที่จัดการเครื่องจักรแทนการลงมือทำด้วยมือโดยตรง
  • ในฝั่งซอฟต์แวร์ โรงงานนั้นสร้างเสร็จแล้ว ผู้ใช้กดปุ่ม “copy” หรือ “download” เพื่อรับ bit-perfect copy ได้
  • เมื่อมีแบบจำลองแรกอยู่แล้ว ต้นทุนส่วนเพิ่มของการคัดลอกครั้งต่อ ๆ ไปแทบเป็นศูนย์ และซอฟต์แวร์คือ สินค้าทางปัญญา
  • Uncle Bob Martin กล่าวมาตลอดว่าการพัฒนาซอฟต์แวร์ไม่ใช่งานผลิต แต่เป็นงานออกแบบ และหลังจากมีการออกแบบครั้งแรกแล้ว เครื่องจักรจะทำการคัดลอกด้วยต้นทุนที่แทบเป็นศูนย์
  • โปรแกรมเมอร์, เทสเตอร์, PO, Scrum Master และผู้จัดการซอฟต์แวร์ ออกแบบ แบบจำลองข้อมูล ที่เป็นฐานให้สำเนาซึ่งลูกค้าและชุมชนจะใช้งาน

งานทางปัญญาสังเกตได้ยาก

  • วิธีคิดแบบยุคอุตสาหกรรมพยายามมองการพัฒนาซอฟต์แวร์เหมือนโรงงาน และนักพัฒนาถูกกดดันให้ทำให้มันดูเหมือนแรงงานทางกายภาพ แม้ว่าจะเป็นผลเสียต่อกระบวนการจริงก็ตาม
  • กิจกรรมทางปัญญาสังเกตและวัดได้ยาก และไอเดียที่เสร็จแล้ว 80% ไม่มีรูปทรงทางกายภาพ
  • อาจมีการทดลอง, โค้ด proof-of-concept หรือบันทึก แต่สิ่งเหล่านี้ไม่สามารถแสดง เปอร์เซ็นต์ความสำเร็จ ได้แม่นยำเหมือนงานทางกายภาพ
  • เก้าอี้ที่กำลังผลิตอยู่เมื่อถึงจุด 50% จะดูเหมือนเสร็จแล้วประมาณ 50% และเมื่อเสร็จสมบูรณ์ก็จะดูเหมือนสินค้าสำเร็จรูป
  • การออกแบบเก้าอี้อาจยังไม่ปรากฏบนกระดาษจนกว่าจะคืบหน้าเกิน 70% และก่อนการออกแบบจะเสร็จ ก็ยากที่จะรู้ได้จริง ๆ ว่ามันเสร็จแล้ว 70% หรือไม่

เหตุผลที่การเปลี่ยนแปลง 30 นาทีหมายถึงงาน 6 ชั่วโมง

  • 30 นาทีคือเวลาที่ใช้สร้าง ผลลัพธ์ล้วน ๆ ของโค้ดที่เขียน ลบ แก้ไข และสร้างใหม่มาตลอดวัน ไม่ใช่ความพยายามทั้งหมดที่ลงไป
  • โปรแกรมเมอร์ประเมินและตั้งสมมติฐานอยู่ตลอดขณะเขียนโค้ด เพื่อหลีกเลี่ยงข้อบกพร่องและช่องโหว่ด้านความปลอดภัย
  • ข้อความของโค้ดบอกเพียงว่าโปรแกรมควรทำอะไรเมื่อรัน แต่โดยทั่วไปไม่ได้เหลือร่องรอยว่าเหตุใดจึงเลือกวิธีนั้น จะกระทบส่วนอื่นของระบบอย่างไร หรือเคยใส่ข้อผิดพลาดใดลงไปแล้วลบออก
  • งานจริงส่วนใหญ่ไม่ได้อยู่ที่การเปลี่ยนแปลงเอง แต่อยู่ที่ การตัดสินใจว่าจะเปลี่ยนอย่างไร และเพราะต้องเข้าใจโค้ดเดิม โค้ดที่รกหรือซอร์สที่ไม่เผยให้เห็นดีไซน์จึงใช้เวลามากขึ้น
  • ผลงานของโปรแกรมเมอร์ถูกผสานเข้ากับ codebase ที่ใช้ร่วมกัน จึงมีบริบททางสังคม และงานที่ช่วยให้โปรแกรมเมอร์คนอื่น เทสเตอร์ และฝ่ายปฏิบัติการเข้าใจงาน ก็สร้างต้นทุนและประโยชน์ที่ไม่ปรากฏในโค้ด

จำนวนบรรทัดโค้ดไม่ใช่มาตรวัดความคืบหน้า

  • งานทางปัญญา 6 ชั่วโมงอาจผ่านการอ่าน ค้นคว้า ตัดสินใจ ยืนยัน ตรวจสอบ และรีวิว แล้วกลายเป็นการเปลี่ยนแปลงล้วน ๆ ใน codebase ที่ใช้เวลา 30 นาที
  • นี่ไม่ได้หมายถึงจำนวนบรรทัดโค้ดที่เพิ่มขึ้น และมีกรณีที่แม้จะแก้บั๊กและเพิ่มฟีเจอร์แล้ว จำนวนบรรทัดโค้ดปลายสัปดาห์กลับน้อยกว่าต้นสัปดาห์
  • เคยเกิดปัญหาเมื่อทีมบันทึก จำนวนบรรทัดโค้ดติดลบ ติดต่อกันหลายสัปดาห์ โดยไม่รู้ว่าผู้บริหารระดับสูงของทีมกำลังรายงาน SLOC ราวกับเป็นตัวชี้วัดความคืบหน้า
  • สิ่งที่โปรแกรมเมอร์ทำจริง ๆ ใกล้เคียงกับการอ่าน เรียนรู้ ทำความเข้าใจ คาดเดา ค้นคว้า ดีบัก ทดสอบ คอมไพล์ รัน ตั้งสมมติฐาน และหักล้างสมมติฐาน
  • งานจำนวนมากท้ายที่สุดยังคงเป็น การคิดและการตัดสินใจ

เขียนให้น้อยลงอาจเป็นการพัฒนาได้เร็วขึ้น

  • หนึ่งในคำตอบบน Quora กล่าวว่า สิ่งที่เห็นคือการที่นิ้วเคลื่อนไหวบนคีย์บอร์ด แต่เวลาที่ใช้คุยกับผู้ใช้ ถกปัญหากับเพื่อนร่วมงาน ค้นคว้า และคิดนั้นมองไม่เห็น
  • ผู้ตอบอีกคนกล่าวว่า การช่วยลูกค้าตัดความคิดที่ไม่จำเป็นซึ่งพวกเขาเรียกว่า “requirements” หรือ “must have” ออกไป คือสิ่งที่เร่งการส่งมอบโซลูชันได้มากที่สุด
  • ผู้ตอบอีกคนกล่าวว่านักพัฒนาที่ยอดเยี่ยมทำงาน มากกว่า 90% ก่อนแตะคีย์บอร์ด ด้วยการทำความเข้าใจ requirements และคิดแนวทางแก้ปัญหาที่เหมาะสม
  • “รู้ว่าจะไม่เขียนอะไร”, “ทำน้อยลง”, “ทำงานเป็นขั้นที่เล็กลง”, “เข้าใจก่อนว่าควรทำอะไรก่อน” เป็นคำตอบที่ปรากฏซ้ำ ๆ
  • คนที่พิมพ์มากขึ้นหรือ copy & paste มากขึ้น อาจมีการคิดและความเข้าใจไม่เพียงพอ และผลคืออาจเพิ่มข้อผิดพลาด รวมถึงเพิ่มภาระให้โปรแกรมเมอร์คนอื่นในการทำความเข้าใจและแก้ไข

กระบวนการควรถูกออกแบบมาเพื่อการคิด

  • หากการเขียนโปรแกรมมี 1/12 เป็นการลงมือทำ และ 11/12 เป็นการคิด ก็ไม่ควรกดดันให้ผู้คนพิมพ์ตลอด 11/12 ของเวลา
  • สิ่งที่จำเป็นคือ วัตถุดิบ สภาพแวดล้อม และกระบวนการ ที่ยกระดับคุณภาพของการคิด
  • หากทำตรงกันข้าม ก็จะเป็นการปรับระบบให้เหมาะกับผลลัพธ์ที่ผิด
  • ผลิตภาพอาจสูงขึ้นเมื่อสร้างระบบอย่างตั้งใจเพื่อให้ผู้คนคิดร่วมกันเกี่ยวกับซอฟต์แวร์และตัดสินใจได้ง่ายขึ้น
  • ควรทดลองการเรียนรู้ระหว่างทำงาน และคิดหาวิธีสร้างระบบที่ทำให้การคิดเหมาะสมที่สุด

1 ความคิดเห็น

 
GN⁺ 2024-04-22
ความคิดเห็นบน Hacker News
  • ประโยคในบทความที่ว่า “นักพัฒนาที่เก่งจริง ๆ จะทำงานเสร็จไปแล้วมากกว่า 90% ก่อนจะแตะแป้นพิมพ์” บางครั้งก็ถูก แต่ผมคิดว่ามันมองข้ามข้อเท็จจริงที่ว่าคนเราไม่สามารถเก็บข้อจำกัดและแนวคิดจำนวนมากไว้ในหัวพร้อมกันได้
    ขอบเขตที่เราจะคิดล้วน ๆ ได้โดยไม่เขียนอะไรเลยนั้นจำกัดมาก ดังนั้นถ้ามีแนวทางที่เป็นไปได้ผุดขึ้นมาแม้เพียงอย่างเดียว ผมก็มักจะจับแป้นพิมพ์แทบจะทันที ก่อนจะขัดเกลาให้เป็นแบบออกแบบที่ระบุรายละเอียดครบถ้วน
    เมื่อได้ลองเขียนโค้ดจริงและทดสอบหลาย ๆ แนวทาง บ่อยครั้งที่วิธีแก้ที่ตอนแรกคิดว่าดีที่สุดกลับแย่กว่าวิธีที่เคยดูมีความหวังน้อยกว่ามาก และไม่มีอะไรเปิดเผยปัญหาได้ดีเท่ากับ โค้ดที่เป็นรูปธรรมและรันได้
    ท้ายที่สุดแล้ว การเขียนโค้ดคือกระบวนการทำให้ไอเดียกลายเป็นโค้ดเพื่อพิสูจน์ตรวจสอบ และควรมองว่าการเขียนโค้ดก็เป็นส่วนหนึ่งของกระบวนการคิด เช่นเดียวกับมุมมองการทำ prototype ที่ว่า ให้ทิ้งรอบแรกไป

    • ตอนอ่านประโยคนั้นก็คิดเหมือนกัน และเดาว่าเขาอาจนึกถึงกรณีอย่าง Linus Torvalds
      แบบตำนานที่ว่าเขาคิดเรื่อง Git อยู่ราวหนึ่งเดือน แล้วทำเสร็จใน 6 วันและพักในวันที่ 7 แต่สำหรับคนทั่วไป โดยเฉพาะผม มันใกล้เคียงกับการโต้ตอบไปมามากกว่า คือคิดว่าจะเขียนอะไร เขียน ทดสอบ คิดใหม่ แล้วแก้บางส่วน
      สุดท้าย กระบวนการไปให้ถึงเวอร์ชันสุดท้ายที่ทำงานได้ก็ใกล้เคียงกับ ศิลปะ อยู่ระดับหนึ่ง
    • โดยปกติผมจะ ทำซ้ำเป็นรอบ ๆ
      หลังจากจับไอเดียคร่าว ๆ ได้แล้ว ผมจะเริ่มเขียนโค้ดจากส่วนที่ “เหนียว” ซึ่งดูมีโอกาสเกิดปัญหามากที่สุดก่อน
      เราคาดการณ์ปัญหาทั้งหมดล่วงหน้าไม่ได้ จึงต้องไปชนของจริง และวิธีนี้มักทำให้ต้องทิ้งงานไปจำนวนมาก
      ผมแทบไม่เขียนเอกสารจนกว่าจะมั่นใจว่ากำลังไปถูกทาง[0] เพราะแบบนั้นช่วยลดสภาวะที่ผมเรียกว่า Concrete Galoshes[1] ได้
      [0] https://littlegreenviper.com/miscellany/evolutionary-design-...
      [1] https://littlegreenviper.com/miscellany/concrete-galoshes/
    • หากจะออกแบบแอปพลิเคชันทั้งระบบในหัว คุณต้องคุ้นเคยอย่างมากกับ กับดักของแพลตฟอร์มและเทคโนโลยี ที่ใช้
      วิธีเดียวที่จะเรียนรู้สิ่งนั้นได้คือการเขียนโค้ดจริงจำนวนมากและการเรียนรู้อย่างกระตือรือร้น และยังหมายถึงการใช้ tech stack เดิมซ้ำ ๆ ต่อไปด้วย
      ผมชอบแนวทางที่อยู่กับ stack เดิมเพื่อโฟกัสที่ตัวปัญหาเอง แต่ “นักพัฒนาที่ยอดเยี่ยม” ในความหมายนี้มีความเป็นไปได้สูงว่าจะค่อนข้าง มิติเดียว ในแง่การเลือกเครื่องมือ
    • เริ่มจากคิดในระดับมหภาคก่อน แล้วจัดระเบียบความเชื่อมโยงและโครงสร้างด้วย mind map และ diagram
      ยิ่งอายุมากขึ้นก็ยิ่งเห็นชัดว่า สถาปัตยกรรม สำคัญกว่าการตัดสินใจระดับจุลภาคมาก
      เรื่องระดับจุลภาคยัง optimize ได้ แต่การตัดสินใจระดับมหภาคมักจะถาวร
    • ผมคิดมาตลอดว่านี่คือเหตุผลที่ใช้ TDD
      บ่อยครั้งผมออกแบบโค้ดภายใน test และปล่อยให้มันนำการ implement ไปในระดับหนึ่ง
      หลังจากนึกภาพผลลัพธ์สุดท้ายในหัวแล้ว ก็เขียน test ในรูปแบบที่คิดว่าเป็น API ที่ดีสำหรับระบบ แล้วเริ่มจากตรงนั้น
      ผลก็คือโค้ดจะ test ได้โดยพื้นฐาน และเมื่อวน Red → Green → Refactor หลาย ๆ รอบ ก็จะไปถึงสภาพที่น่าพอใจ
      อยากรู้ว่าคนอื่น ๆ ก็ทำงานแบบนี้ไหม
  • ผมชอบคำอธิบายในหนังสือ “The Secret Life of Programs” ของ Jonathan E. Steinhart ที่สุด
    ใจความคือการเขียนโปรแกรมคอมพิวเตอร์มีสองขั้นตอน: 1. เข้าใจจักรวาล 2. อธิบายให้เด็กสามขวบฟัง
    หมายความว่าเราเขียนโปรแกรมให้ทำสิ่งที่เราเองไม่เข้าใจไม่ได้ ถ้าไม่รู้กฎการสะกดคำก็สร้างตัวตรวจการสะกดไม่ได้ และถ้าไม่รู้ฟิสิกส์ก็ยากที่จะสร้างเกมแอ็กชันวิดีโอที่ดี
    หากอยากเป็นโปรแกรมเมอร์ที่ดี ควรเรียนรู้เรื่องอื่น ๆ ให้มากที่สุดเท่าที่ทำได้ เพราะทางแก้ของปัญหามักมาจากที่ที่คาดไม่ถึง ดังนั้นไม่ควรมองข้ามเพียงเพราะตอนนี้ดูไม่เกี่ยวข้อง
    ขั้นตอนที่สองคือการอธิบายสิ่งที่คุณรู้ให้เครื่องจักรที่มองโลกอย่างเข้มงวดมากเหมือนเด็กสามขวบฟัง
    ถ้าถามเด็กว่า “รองเท้าอยู่ไหน?” เด็กอาจตอบว่า “ตรงนั้น” ซึ่งก็ตอบคำถามแล้ว แต่จริง ๆ แล้วไม่ได้อนุมานเจตนาว่าคุณอยากให้ใส่รองเท้าแล้วออกไปข้างนอก
    เด็ก ๆ เติบโตขึ้นและเรียนรู้ความยืดหยุ่นกับความสามารถในการอนุมาน แต่คอมพิวเตอร์นั้นเหมือน Peter Pan ที่ไม่มีวันโต

    • อยากรู้ว่ามีหนังสือแนวคล้าย ๆ กันแนะนำอีกไหม
    • การเขียนโปรแกรมส่วนใหญ่คือการคิดก็จริง แต่การคิดมีได้หลายแบบ
      วิธีคิดที่เหมาะสมแตกต่างกันไปตามคนและปัญหา และถ้าเรียนรู้วิธีคิดและเขียนโปรแกรมหลาย ๆ แบบ เราก็จะมีเครื่องมือให้เลือกมากขึ้น
      เพราะฉะนั้นผมจึงไม่ชอบข้ออ้างที่ว่าการเขียนโปรแกรมต้องเกิดขึ้นด้วยวิธีที่ถูกต้องเพียงวิธีเดียว
      คำพูดที่ว่า “คุณไม่สามารถเขียนโปรแกรมในสิ่งที่คุณไม่เข้าใจได้” ก็ไม่จริงเช่นกัน เพราะเรามักใช้ซอฟต์แวร์เพื่อทำความเข้าใจว่าสิ่งหนึ่งทำงานจริงอย่างไร
      การจำลองฟิสิกส์ก็มักไม่ได้มีเป้าหมายเป็นความเที่ยงตรงสมบูรณ์ต่อความเป็นจริง แต่เป็นการสำรวจเพื่อหาสมดุลระหว่าง ประสบการณ์ผู้ใช้และความยาก ของเกม
      การเขียนโปรแกรมสามารถเป็นเครื่องมือทางปัญญาเชิงสำรวจได้ และไม่ได้หมายความว่าความคิดส่วนใหญ่ต้องมาก่อนเสมอ
      ผมชอบ generalist และคนที่เรียนรู้ด้วยตัวเอง แต่สิ่งเหล่านี้ไม่ใช่ขั้นแรกที่จำเป็นสำหรับการเป็นโปรแกรมเมอร์ที่ดี
      เด็ก ๆ ไม่ได้มี “โลกทัศน์ที่เข้มงวด” เท่าไรนัก แต่เพียงอนุมานนัยทางสังคมไม่ได้เสมอไป และคอมพิวเตอร์ก็สามารถถูกโปรแกรมให้ดึงข้อสรุปเชิงตรรกะจากข้อเท็จจริงที่รู้ได้
      ผมเคยอธิบายบางอย่างให้เด็กหลายวัยฟัง รวมถึงเด็กสามขวบด้วย แต่ประสบการณ์นั้นไม่เหมือนการเขียนโปรแกรมคอมพิวเตอร์เลย
  • ผมค่อนข้างมั่นใจว่าตัวเลขนี้แทบจะถูกต้อง แต่จนถึงตอนนี้ยังไม่มีบริษัทไหนยอมลบงานทั้งวันทิ้งเพื่อพิสูจน์หรือหักล้างการทดลองนี้
    สมัยก่อนตอนที่ผมยังอดทนกว่านี้มาก เคยมีหัวหน้าที่ทุกคืนจะตรวจการเปลี่ยนแปลงโค้ดทั้งหมด แล้วลบสิ่งที่ไม่ชอบทิ้ง
    หัวหน้าคนนั้นเชื่อว่า version control ซับซ้อนเกินไป จึงพยายามทำให้การรีโมตเข้า network drive ที่บ้านของเขาเป็นมาตรฐานของบริษัท
    ดังนั้นบางครั้งพอมาทำงานวันถัดไป งานของเมื่อวานก็ถูกลบไปแล้ว และสุดท้ายก่อนจะแอบติดตั้ง SVN ผมก็เก่งมากในการสร้างงานของวันก่อนหน้าขึ้นมาใหม่
    แม้รวมการทดสอบ edge case แล้ว ก็แทบไม่มีงานไหนที่ใช้เวลาเกินหนึ่งชั่วโมง

    • ตัวอย่างมีน้อย แต่ในงาน embedded สองที่แรกของผม ทั้ง 2 ใน 2 ที่ใช้ network share กับการ copy/paste เพื่อทำ version control โค้ด
      งานแรกทำให้เกิดแผลใจบางอย่าง พองานที่สองผมเลยถามทันทีว่ามี Git repository ไหม หัวหน้าก็ตอบว่าเขาคิดว่า Git คือสิ่งเดียวกับ Github และไม่อยากเปิดเผยโค้ดต่อสาธารณะ
      ต่อมาบริษัทใหญ่กว่าเข้าซื้อกิจการ ทำให้ได้สิทธิ์เข้าถึง intranet และในนั้นผมพบ instance ของ GitLab จึงเอาโค้ดที่ส่วนใหญ่ทำคนเดียวไปทำ version control และทำเอกสารไว้ที่นั่น แถมยังติดตั้ง GitLab Runner ด้วย
      ผมทำเอกสารวิธีรันโค้ดไว้เป็นขั้นตอนด้วย พอตอนถูกเลิกจ้าง เขาบอกให้ส่งมอบโค้ด ผมก็แสดงให้ดูทั้งหมดและบอกวิธีทำซ้ำ หัวหน้าค่อนข้างประทับใจและขอบคุณ
      การที่ผมยืนกรานทำในแบบที่คิดว่าถูกต้องในที่ทำงานห่วย ๆ อาจทิ้งผลกระทบดี ๆ ไว้บ้างก็ได้
      ก่อนจะเจอ GitLab นั้น ผมสร้าง raw Git repository ไว้บน network share แล้ว push ไปที่นั่น
    • ไม่มีทางรู้ได้เลยว่าเขาเป็นหัวหน้าที่แย่ หรือเป็น ปรมาจารย์เซน กันแน่
    • ปัญหาที่ใหญ่กว่าคือ ผู้จัดการเข้ามาแทรกแซงโค้ด
      ต่อให้เจตนาดี แต่เมื่อผู้จัดการเข้ามายุ่งกับโค้ดหรือรีวิว แทบทุกครั้งจะเป็นผลขาดทุนสุทธิต่อทีม
    • ใครที่เคยใช้ผลิตภัณฑ์ Microsoft Office อย่างจริงจังในยุค 2000 และ 2010 จะรู้ว่านี่เป็นเรื่องจริง หรือไม่ก็จะกดบันทึกโดยอัตโนมัติทุก ๆ 5–10 นาที
    • สงสัยว่างานที่ทำใหม่รอบที่สองนั้นออกมาดีกว่าหรือแย่กว่ากัน
  • เป็นบทความที่เหมาะจะส่งให้คนที่ไม่ใช่โปรแกรมเมอร์
    เช่นเดียวกับที่โปรแกรมเมอร์ต้องมีความรู้โดเมน คนที่ต้องการได้อะไรบางอย่างจากโปรแกรมเมอร์ก็ควรเข้าใจการเขียนโปรแกรมอยู่บ้าง
    แม้จะเป็น diff เล็กมาก ก็อาจใช้เวลาหลายชั่วโมงเพราะการ debug การออกแบบ และการเรียนรู้
    มันง่ายที่จะไม่รู้สึกประทับใจเมื่อดูแค่ปริมาณผลลัพธ์ แต่การมีคนอธิบายให้ฟังกับการเอาหัวโขกกำแพงเองหลายชั่วโมงเพื่อค้นให้เจอนั้นต่างกันโดยสิ้นเชิง

    • ชิ้นโค้ดที่เล็กที่สุดที่ผมส่งมอบมักเป็นสิ่งที่ใช้เวลานานที่สุด สร้างผลกระทบมากที่สุด และพอเข้าใจแล้วก็ให้ความพอใจมากที่สุด
      ประมาณว่าต้องใช้เวลาหลายวันเพื่อหา commit บรรทัดเดียวที่ ปรับปรุงประสิทธิภาพได้ 100 เท่า ขณะเดียวกันในประชุม sync ก็ต้องอธิบายว่าทำไม ticket ถึงไม่ขยับ
  • ดังนั้น ความรู้โดเมน คือหัวใจสำคัญ
    ผมทำงานในสายการเงิน นั่งอยู่ที่ trading desk ดูตลาดหลายแห่ง และเขียนโค้ดที่ทำกลยุทธ์ต่าง ๆ
    ถ้าไม่รู้ว่าธุรกิจควรทำอะไร ก็คิดไม่ได้ว่าคอมพิวเตอร์ควรทำอะไร
    จากมุมมองนี้ การฝึก coder ให้เหมือนนักแปลก็อาจสมเหตุสมผล
    เพื่อนนักแปลของผมรู้ไวยากรณ์และสำนวนของหลายภาษาเป็นอย่างดี และเรียนภาษาใหม่เหมือนที่เราเรียนภาษาโปรแกรมมิ่งใหม่ ๆ แต่เขาก็ใช้เวลามากพอสมควรเรียนรู้เกี่ยวกับอุตสาหกรรมยา และตอนนี้แปลเอกสารทางการแพทย์
    ทนายความและนักบัญชีก็เป็นอาชีพที่มีกำแพงด้านภาษาเช่นกัน
    เมื่อเป็นผู้เชี่ยวชาญ เราจะเรียนภาษาของกฎหมาย บัญชี และซอฟต์แวร์ แต่ผู้เชี่ยวชาญที่ดีจะตอบด้วย ภาษาธุรกิจ ไม่ใช่ภาษาผู้เชี่ยวชาญ
    ทนายที่ยังไม่ดีนักจะบอกผลลัพธ์ที่เป็นไปได้ทั้งหมดด้วยศัพท์กฎหมายแล้วปล่อยให้ตัดสินใจเอง แต่ทนายที่ดีจะบอกว่า แม้จะมีความเป็นไปได้ยิบย่อยมากมาย แต่ในทางปฏิบัติลูกค้าที่อยู่ในตำแหน่งเดียวกันล้วนทำ X เพราะเป้าหมายทางธุรกิจนี้
    ในงาน trading แรกของผม มี trader คนหนึ่งสร้างโมดูล Excel VBA เพื่อรันขั้นตอนกวาดดูหุ้นและหาสิ่งที่จะเทรด
    มีเพียงไฟล์ที่บันทึกไว้บนดิสก์ ไม่มี version control และคนที่เพิ่งเข้ามาใหม่ภายในไม่กี่สัปดาห์ก็เผลอบันทึกทับโดยลบโมดูล VBA ทั้งหมดนั้นทิ้ง ไม่มี backup และ IT ก็ช่วยอะไรไม่ได้
    trader คนนั้นหน้าแดงก่ำ ก่อนจะสงบลง ยอมรับความจริงว่าที่จริงควรมี backup อยู่แล้ว และก็ไม่รู้ไปทำอะไรด้วย VBA อยู่ จากนั้นก็นั่งพิมพ์ทั้งหมดขึ้นมาใหม่ ราวกับหน้าจอ terminal ยุค 80 ที่ตัวอักษรค่อย ๆ ปรากฏทีละตัว

    • การพัฒนาในโดเมนที่รู้ดีแล้วกับโดเมนใหม่มีความแตกต่างกันมาก
      หลักคิดของผมคือ หากจะสร้างทางออกที่ดี ต้องมี ประสบการณ์ ในโดเมนนั้นก่อน
      ตอนนี้ผมใช้เวลาส่วนใหญ่เพื่อเก็บประสบการณ์ในโดเมนใหม่ และนั่งข้างผู้เชี่ยวชาญโดเมนเพื่อสะสมความรู้ที่จำเป็นให้เร็วขึ้น
    • จากประสบการณ์ของผมในฐานะ software engineer และ CPA บริษัทต่าง ๆ โดยทั่วไปไม่ได้ใส่ใจ ความรู้โดเมน แบบนั้นมากนัก
      พวกเขาชอบ software engineer ที่ทำซอฟต์แวร์เกี่ยวกับบัญชีมา 15 ปีมากกว่าคนที่มีพื้นหลังแบบผม แล้วเลือกให้คนนั้นคุยกับนักบัญชี 30 นาที
    • การเขียนโปรแกรมเป็นสาขาที่กว้างเกินไป จึงยากมากที่จะสรุปแบบเหมารวมให้ใช้ได้กับทั้งหมด
      เรามักเห็นข้อกำหนดซ้ำ ๆ ว่าการเขียนโปรแกรมต้องทำงานแบบใดแบบหนึ่งเสมอ แต่ประเภทงานในแต่ละสาขาย่อยต่างกันมาก
      ผมคิดว่าดีกว่าที่จะเข้าใจ กระเป๋าเครื่องมือ ที่มีหลายแนวทางและหลาย methodology รวมถึงสถานการณ์ที่แต่ละอย่างเหมาะสม แทนที่จะพยายามเรียนหรือสอน methodology เดียวที่สมบูรณ์แบบและใช้ได้กับทุกสาขา
    • จริง แต่บริษัททุกแห่งในประเทศของเรามี ข้อกำหนดห้ามทำงานกับคู่แข่ง ดังนั้นต่อให้เรียนรู้ความรู้โดเมนแล้ว หากนายจ้างปัจจุบันเลิกจ้าง ก็ไม่สามารถนำไปใช้ต่อในงานถัดไปได้
      จึงทำให้ต้องข้ามไปมาระหว่างอุตสาหกรรมและมุ่งเน้นทักษะโปรแกรมมิ่งทั่วไปที่ถ่ายโอนไปใช้ที่อื่นได้
  • ในช่วงต้นของหนังสือ PPP ของ Bjarne[0] ก็มีแนวคิดคล้ายกัน
    ใจความคือ “แม้แต่โปรแกรมเมอร์ที่เก่งที่สุด โดยเฉพาะโปรแกรมเมอร์ที่เก่งที่สุด ใช้เวลาส่วนใหญ่ไปกับการทำความเข้าใจปัญหา ไม่ใช่การเขียนโค้ด การทำความเข้าใจปัญหามักต้องใช้เวลาอย่างจริงจังและต้องใช้ความพยายามทางปัญญาไม่น้อย นั่นแหละคือความท้าทายทางปัญญาที่โปรแกรมเมอร์จำนวนมากหมายถึงเมื่อบอกว่าการเขียนโปรแกรมนั้นน่าสนใจ”
    ผมก็ซื้อฉบับใหม่[1] ที่เพิ่งขึ้นหน้าแรก[2] เมื่อไม่นานนี้ด้วย
    [0]: https://www.stroustrup.com/PPP2e_Ch01.pdf
    [1]: https://www.stroustrup.com/programming.html
    [2]: https://news.ycombinator.com/item?id=40086779

    • โดยรวมก็ถูก แต่ปัญหาใหญ่ที่สุดคือรู้สึกว่าเราใช้เวลาไปกับการถกเถียงเรื่องเดิมซ้ำแล้วซ้ำเล่า
      อย่างจะใช้ฐานข้อมูลอะไร ภาษาไหนดีที่สุด จะยอมให้มี null ในโค้ดและฐานข้อมูลไหม รูปแบบ API รูปแบบ log อะไรทำนองนี้
      มันไม่ได้ชวนสนใจเป็นพิเศษ และบางครั้งก็จำเป็นต้องทบทวนใหม่ แต่การเสียเวลาแบบนี้ที่เจอในสามบริษัทล่าสุด ส่วนใหญ่รู้สึกเหมือนเป็นปัญหาที่ควรถูกแก้ไปแล้ว
      จริง ๆ ถ้าบริษัทมีแนวคิดที่หนักแน่น ต่อให้ชวนสงสัยอยู่บ้าง ก็อาจทำงานได้มีประสิทธิภาพกว่ามาก
      ถ้าถูกกำหนดตายตัวว่าใช้ Perl, MongoDB, CGI ผมคิดว่าแม้จะมีสแต็กแบบนั้น ก็อาจทำงานได้มีประสิทธิภาพกว่าช่วงหลัง ๆ เสียอีก
    • ส่วนที่ยากที่สุดคือการคิดให้ออกว่า อะไรที่ไม่ควรเขียนโค้ด ไม่ว่าจะเป็นช่วงออกแบบก่อนลงมือเขียน หรือหลังจากได้เรียนรู้จาก prototype หรือ iteration ก่อนหน้า
    • *Bjarne
  • “การเขียนโปรแกรมส่วนใหญ่คือการคิด” เป็นหนึ่งในประโยคที่เราบอกตัวเองเหมือนเป็นสัจธรรมลึกซึ้ง แต่ในฐานะข้อสังเกตแล้วไม่ค่อยก่อให้เกิดผลนัก
    การที่การเขียนโปรแกรมคือการคิดนั้น ก็มีความหมายเหมือนกับที่งานความรู้ทุกอย่างคือการคิดนั่นแหละ
    งานออกแบบก็ส่วนใหญ่คือการคิด งานบัญชีก็ส่วนใหญ่คือการคิด และงานบริหารก็โดยมากคือการคิด
    ความแตกต่างที่มีความหมายไม่ใช่ตัวการคิดเอง แต่คือ คิดเกี่ยวกับอะไร
    ผู้จัดการต้องดีบักปัญหาของคน จึงต้องใช้เวลากับคนมาก ๆ นั่นก็คือการประชุม
    นักพัฒนาต้องดีบักปัญหาของคอมพิวเตอร์ จึงต้องใช้เวลากับคอมพิวเตอร์มาก ๆ
    ตรงนี้มีแรงตึงที่ชัดเจน และสุดโต่งด้านไหนก็ใช้ไม่ได้ จึงต้องหาสมดุลเพื่อรบกวนงานของกันและกันให้น้อยลง

    • บทความนี้ไม่ได้เขียนมาเพื่อโปรแกรมเมอร์ แต่เขียนเพื่อ คนที่ไม่ใช่โปรแกรมเมอร์ อย่างผู้จัดการที่คิดว่าการเขียนโปรแกรมส่วนใหญ่คือการพิมพ์ และอธิบายว่าเกิดอะไรขึ้นตอนที่เราไม่ได้พิมพ์
    • อาจารย์สมัยปริญญาเอกของผมเคยพูดไม่หยุดว่า ถ้าทำงานโดยไม่จำ shortcut กับ macro จะเสียเวลาในแต่ละวันไปมากแค่ไหนกับการยกมือออกจากคีย์บอร์ด แต่นี่เป็นข้อสังเกตที่มีประโยชน์กว่านั้นมาก
    • ความแตกต่างสำคัญอย่างหนึ่งในการเขียนโปรแกรมคือ บ่อยครั้งการทำสิ่งเดิมด้วย โค้ดที่น้อยกว่า นั้นดีกว่า
      ไม่ได้หมายถึงโค้ดแบบ code golf ที่อ่านยาก แต่หมายถึงแง่ที่ว่าทุกสิ่งที่เราผลิตออกมาต้องถูกดูแลรักษาต่อ
      ซึ่งต่างจากนักเขียนนิยายที่อาจไม่ได้สนใจการบำรุงรักษามากนัก และสนใจอารมณ์ที่ข้อความสร้างขึ้นมากกว่าอย่างชัดเจน
  • การปรับให้ดีที่สุดสำหรับคำถาม “จะสร้างระบบที่ทำให้การคิดถูกปรับให้เหมาะสมผ่านการทดลองเรียนรู้ระหว่างทำงานได้อย่างไร?” คือ ลดการรบกวน
    งานวิจัยชี้ว่าการรบกวนส่งผลทำลายล้างต่อการเขียนโปรแกรม
    หลังถูกขัดจังหวะต้องใช้เวลา 10–15 นาทีจึงจะกลับมาทำงานต่อได้ โปรแกรมเมอร์มีแนวโน้มว่าจะได้ช่วงเวลา 2 ชั่วโมงที่ไม่ถูกรบกวนเพียงช่วงเดียวต่อวัน และช่วงที่กำลังแก้ไข ค้นหา หรือทำความเข้าใจ เป็นจังหวะที่แย่ที่สุดในการรบกวน
    ผมสงสัยว่ามีวิธีติดตามและแสดงการรบกวนเหล่านี้ไหม
    [0] http://blog.ninlabs.com/2013/01/programmer-interrupted/

    • ถ้าบอกผู้จัดการว่าเอาการประชุม 1 ชั่วโมงมาแบ่งเป็นช่วงละ 10 นาที กระจายตลอด 6 ชั่วโมง คุณจะได้เห็นสีหน้าประหลาดใจจริง ๆ
      แต่กลับมีการคาดหวังให้นักพัฒนาทำงานเขียนโค้ดที่ต้องใช้เวลาหลายชั่วโมงให้เสร็จ ท่ามกลางการประชุมไม่รู้จบ ping สั้น ๆ ใน Slack/Zoom และการ sync ต่าง ๆ
      บางครั้งตอนที่ต้องทำงานจากบ้านในวันหยุดสุดสัปดาห์ ผมเห็นว่างานช่วงสุดสัปดาห์ที่ไม่มีการรบกวนมีคุณภาพดีกว่าวันธรรมดาที่วุ่นวายมาก
    • เพราะงั้น 80% จึงทำงานตอนกลางคืน
      มันไม่ได้เหมาะกับทุกคนและไม่ได้เหมาะกับทุกกรณี ส่วนอีก 20% คือการประสานงานกับคนที่ทำงานตอนกลางวัน แต่ productivity ที่ได้จาก ช่วงเวลาปลอดการรบกวน ดี ๆ ต่อเนื่องหลายชั่วโมงนั้นเทียบกันไม่ได้
      ขอย้ำว่าไม่ใช่วิธีที่เหมาะกับทุกคน และอาจไม่เหมาะกับคนส่วนใหญ่ด้วย
    • เพราะความต้องการใช้เวลาสูงและการรบกวน ทำให้ตอนทำงานจากที่บ้านผม productive กว่าประมาณหลายเท่าระดับเลขหลักเดียว
      ที่บ้านไม่มีใครมาขัดจังหวะผม และถึงมีสิ่งรบกวนเข้ามา ผมก็เลือกเองได้ว่าจะตอบสนองเมื่อไหร่
      โดยเฉพาะเมื่อกำลังจัดการปัญหายาก ๆ ถ้าถูกขัดทุก 10–20 นาที ก็เลิกทำไปเลยดีกว่า ไม่อย่างนั้นมีโอกาสสูงที่จะสร้างโค้ดเละ ๆ ที่ภายหลังทำให้ปวดหัว
    • ผมเคยนำโปรเจกต์พัฒนาเครื่องมือในบริษัทใหญ่เพื่อติดตามว่าผู้คนใช้เวลาอย่างไร
      เราออกแบบให้เคารพความเป็นส่วนตัว โดยบันทึกว่ามีการใช้เว็บเบราว์เซอร์ แต่ไม่บันทึก URL เฉพาะว่าเป็นอินทราเน็ตในบริษัทหรือ fb.com
      บางครั้งมี popup ให้ผู้ใช้ประเมิน productivity ของตัวเองและทิ้งคอมเมนต์แบบข้อความอิสระ และไม่ผูกกับ user ID เพื่อไม่ให้ผู้คนโกหกให้ตัวเองดูเหนือมนุษย์
      เราสร้าง frontend บน Windows และ backend ด้วย Scala แล้วแจกให้กลุ่มอาสาสมัครที่รวมทั้งนักพัฒนา ทนายความ และเจ้าหน้าที่การเงิน แต่หลังจากวิเคราะห์ข้อมูลชุดแรก พอเริ่มน่าสนใจก็หมดเวลาและงบประมาณ จึงไม่ได้ตีพิมพ์เป็นบทความวิจัย
      เราดูเครื่องมือที่มีอยู่แล้วอย่าง Rescue Time( https://www.rescuetime.com/
      ) ด้วย แต่ตัดสินว่าไม่อาจยอมรับการเก็บข้อมูล productivity ภายในไว้บน cloud ภายนอกได้
  • การเขียนโปรแกรมที่ดีบางครั้งส่วนใหญ่คือการคิด แต่คำกล่าวที่ว่า “ไม่มีแผนใดอยู่รอดได้หลังปะทะศัตรูครั้งแรก” นั้นถูกต้อง
    การเขียนโปรแกรมเชิงปฏิบัติคือการผสมผสานอย่างรอบคอบระหว่างการวางแผนกับการลองเอาโค้ดขึ้นใน IDE และจุดสมดุลนั้นควรเปลี่ยนไปตาม use case

    • การเขียนโปรแกรมไม่ใช่แค่การคิด แต่ส่วนใหญ่คือ การลาดตระเวน
      ถ้าคุณไม่เขียนโค้ดเลยเป็นเวลาหลายวัน แปลว่าคุณรู้พื้นผิวของปัญหาอย่างครบถ้วนแล้ว หรือไม่ก็แค่กำลังเดาอยู่
      ถ้าเป็นอย่างหลัง ก็ไม่ได้มีอะไรให้คิดมากนัก
    • การรันครั้งแรกใน IDE คล้ายกับการเคลียร์ด่านเกมครั้งแรก
      ครั้งที่สองจะเร็วขึ้น
      ผมเห็นด้วยว่าสามารถขยายความหมายของการคิดให้เป็น “การคิดที่มีเครื่องมือช่วย” ได้
  • เป็นการกล่าวย้ำแนวคิด Programming as Theory Building ของ Peter Naur และมีบทบาทสำคัญต่อการที่ผมเข้าใจแก่นแท้ของการเขียนโปรแกรม
    การเขียนโปรแกรมไม่ใช่งานที่สร้างตัวโปรแกรมขึ้นมาเอง แต่เป็นงานในการก่อรูปความเข้าใจเชิงลึกบางอย่างเกี่ยวกับสิ่งต่าง ๆ ในโลก และโค้ดที่ได้ออกมาในท้ายที่สุดก็เป็นเพียงการแสดงออกอย่างเรียบง่ายของทฤษฎีที่ตนเองสร้างขึ้นเท่านั้น