ชีวิตนี้แอบรู้สึกโชคดีที่เลือกทำงานด้านโปรแกรมมิ่งตั้งแต่เด็กจนโต ไม่ใช่เพราะเรื่องเงินหรือความต้องการของตลาดอะไรเลย แต่เป็นเพราะว่า
"เราสามารถใช้เทคนิคที่ใช้ในการเขียนโปรแกรมมาประยุกต์ใช้ในชีวิตประจำวันได้เยอะเลย"
เรียกว่ามีประโยชน์กับการใช้ชีวิตมากเลยหละ
อาจจะงงสงสัยว่าอย่างไร สำหรับหลาย ๆ คนที่ไม่เคยแตะงานโปรแกรมมิ่งอาจจะคิดว่างานด้านนี้เป็นการสร้างอะไรขึ้นมา ก็จริงอยู่กึ่งหนึ่งเพราะปลายทางเป็นอย่างนั้น แต่ที่สำคัญจริง ๆ คือระหว่างทางต่างหาก การจะเขียนโปรแกรมจนสำเร็จออกมาได้ต้องใช้ศาสตร์หลายด้านประกอบกันมาก และส่วนตัวแล้วศาสตร์ที่คิดว่าเป็นพื้นฐานที่สุดและสำคัญสุดของงานด้านนี้เลยคือ
"การแก้ปัญหา"
เพราะงานเขียนโปรแกรมมักจะเป็นงานที่สลับซับซ้อน Requirement ที่ฟังดูเหมือนง่าย แต่เอาเข้าจริงตอนลงมือเขียนโปรแกรมก็จะมีเรื่องราวมาเกี่ยวข้องเยอะแยะมากมาย บางเรื่องก็อาจรู้อยู่แล้ว บางเรื่องก็เป็นเรื่องใหม่ รวมแล้ววุ่นวายไปหมด คราวนี้โจทย์ที่แท้จริงคือ "จะแก้ปัญหาเหล่านั้นแล้วทำออกมาเป็นงานเชิงโปรแกรมมิ่งได้อย่างไร"
ถ้าแก้ได้ก็จะเขียนโปรแกรมออกมาได้อย่างสมบูรณ์แบบ ยิ่งใครแก้ปัญหาเก่งก็จะยิ่งเขียนโปรแกรมออกมาได้ประสิทธิภาพสูงขึ้นเท่านั้น ทั้งเขียนออกมาเร็วและทำงานได้เร็ว
นี่ทำให้คนที่ทำงานด้านโปรแกรมมิ่งมาเลยมักจะมีความคิดและลอจิคในการแก้ปัญหาติดตัวมาด้วยเสมอ
และนี่แหละคือสิ่งที่เราคิดว่ามันมีประโยชน์มาก เพราะเอาจริง ๆ ถามว่าชีวิตมนุษย์แต่ละวันมันคืออะไร ? มันคือการแก้ปัญหาล้วน ๆ เลยนะ ไม่ว่าจะเป็นปัญหาทางการงานหรือชีวิต ทุกวินาทีมักจะมีความท้าทายมาเสิร์ฟให้เราแก้ปัญหาอยู่เรื่อยไป ใครแก้ปัญหาได้เร็วก็จะได้เปรียบคนอื่นเค้าเสมอ
เทคนิคการแก้ปัญหาเชิงโปรแกรมมิ่งที่มีสอนกันก็มีอยู่หลายตัว ทุกอย่างก็เหมาะกับบริบทที่ต่างกันออกไป แต่สำหรับเราแล้วจะมีอยู่ตัวนึงที่พิเศษหน่อยคือใช้ได้กับทุกบริบทเลย และเราจัดให้เป็นพื้นฐานความคิดของการแก้ปัญหาใด ๆ ในโลกเลย ไม่ได้จำกัดแค่ปัญหาทางคอมพิวเตอร์ด้วยนะ ปัญหาอะไรก็ได้เลย เทคนิคนี้มีชื่อว่า "Divide and Conquer" หรือ "แบ่งแยกและเอาชนะ" ครับ
ซึ่งเราเกลียดชื่อภาษาไทยมาก ดังนั้นบล็อกนี้เราจะเขียนชื่อเป็นภาษาอังกฤษหมดนะ เอาหละ ไปดูกันว่ามันคืออะไรและเจ๋งยังไง
อะไรคือ Divide and Conquer ?
ความจริงมันเป็นเทคนิคที่ไม่มีอะไรลึกลับซับซ้อนเลย ค่อนข้างตรงไปตรงมามาก นิยามแบบบ้าน ๆ คือ
Divide and Conquer คือการแบ่งปัญหาที่มีออกเป็นปัญหาเล็ก ๆ หลาย ๆ ข้อ ซึ่งมักจะแก้ได้ง่ายกว่า ถ้าปัญหาที่ย่อยออกมายังใหญ่ไปอีก ก็ย่อยมันลงไปอีกจนถึงจุดที่ย่อยไม่ได้แล้ว เมื่อแก้ปัญหาเล็ก ๆ นั้นได้หมด ปัญหาใหญ่ก็จะถูกแก้ไขไปได้ด้วย
เพราะในชีวิตจริง ปัญหาที่ถูกส่งมาให้เราแก้มันไม่เคยถูกแบ่งเป็นข้อย่อย ๆ ให้เราแก้ง่าย ๆ หรอก มันจะมาเป็นปัญหาใหญ่ ๆ ที่มีความซับซ้อนสูง และไม่ว่าปัญหาจะโหดร้ายแค่ไหน หน้าที่ของเราในภาพใหญ่ก็คือ "ต้องแก้มันให้ได้"
และหากปัญหามันใหญ่และมีสิ่งเกี่ยวพันกันเยอะ หากลุยแก้ไปเลยโดยไม่คิดไม่วางแผน บอกเลยว่าไม่มีทางแก้ปัญหาได้สำเร็จหรอก และวิธีที่ดีที่สุดในการจัดการกับปัญหาซับซ้อน ๆ แบบนี้คือ "ย่อยมันออกมาเป็นปัญหาง่าย ๆ เล็ก ๆ ก่อนสิ !"
ธรรมชาติของปัญหาคือ ยิ่งปัญหาเล็กก็ยิ่งแก้ง่าย ดังนั้นยิ่งเรามีความสามารถในการย่อยปัญหาได้มากเท่าไหร่ ก็จะทำให้เราสามารถแก้ปัญหาที่ซับซ้อนได้มากขึ้นเท่านั้น หน่ึงใน Quote ที่ทำให้เรารัก Divide and Conquer มาก ๆ มาจากสุดยอดศาสตราจารย์ที่เราเคารพมาก ๆ อย่าง ศ.ดร.ประภาส แห่งภาควิศวกรรมศาสตร์คอมพิวเตอร์จุฬาลงกรณ์มหาวิทยาลัย เคยสอนไว้ว่า
"ปัญหาใหญ่ ๆ จริง ๆ แล้วอาจจะไม่ได้ใหญ่อย่างที่เห็นก็ได้ ปัญหาที่ดูแก้ยาก ๆ จริง ๆ ถ้าค่อย ๆ แบ่งมันเป็นปัญหาเล็ก ๆ แล้วแต่ละอันอาจจะแก้ง่าย ๆ ก็ได้ แล้วก็ไล่แก้ทีละอันไปสิ"
- ศ.ดร.ประภาส จงสถิตย์วัฒนา
ตอนที่เรียนก็ยังไม่เข้าใจมากเพราะขาดประสบการณ์ แต่พอผ่านชีวิต Software Engineer มาสิบกว่าปีก็ทำให้เข้าใจตรงนี้อย่างถ่องแท้ละ คือตอนแรกใช้กับงานโปรแกรมมิ่งแต่ไป ๆ มา ๆ ก็ใช้มันกับทุกอย่างในชีวิตจริง ๆ ละ ซึ่งส่งผลดีมาก
ก็ตามนั้น จริง ๆ มันก็แค่เทคนิคการย่อยปัญหาให้เล็กจะได้แก้ไขได้ง่าย ๆ มาดูตัวอย่างกัน
ตัวอย่าง D&C กับข้าวผัดกระเพราไก่ไข่ดาว
ถึงเราจะรู้จัก Divide and Conquer จากการเขียนโปรแกรม แต่ตอนนี้เราบอกได้เลยว่าเราใช้กับทุกเรื่องจริง ๆ และเพื่อไม่ให้บล็อกมัน Geek เกินไป เลยขอยกตัวอย่างการนำ D&C มาใช้ในภาษามนุษย์ละกันนะ โดยขอยกเรื่องของ "การทำข้าวผัดกระเพราไก่ไข่ดาว"
ปัญหาก็ง่าย ๆ
"ทำไมทำข้าวผัดกระเพราไก่ไข่ดาวให้อร่อยเหมือนร้านข้างบ้านไม่ได้"
คือมันฟังดูเป็นปัญหาที่ง่ายมากเลยนะ แต่จริง ๆ มันไม่ได้ง่ายป่ะ การจะทำข้าวผัดกระเพรามันมีขั้นตอนเยอะมาก การพยายามแก้ไขปัญหาใหญ่แบบนี้โดยไม่ยอมย่อยปัญหาออกมาก่อนนี่ไม่มีทางจะทำให้ข้าวผัดกระเพราอร่อยได้เลย หรือกว่าจะทำได้นี่อาจจะต้องใช้เวลาเป็นปี ๆ
เอาใหม่ ไหนลองย่อยปัญหาดูว่ามีปัญหาอะไรบ้างที่เราต้องแก้
1) กระทะร้อนรึเปล่า ?
2) น้ำมันใส่เยอะไปรึเปล่า ?
3) ไฟแรงไปรึเปล่า ?
4) ใบกระเพราเน่ารึเปล่า ?
5) ใส่ซีอิ้วขาวมากไปรึเปล่า ?
6) ไก่สดรึเปล่า ?
7) ข้าวเละไปรึเปล่า ?
8) ใส่เครื่องปรุงผิดรึเปล่า ?
9) ใส่เครื่องปรุงไม่ถูกลำดับรึเปล่า ?
10) ไข่ดาวสุกไปรึเปล่า ?
11) ฯลฯ
คราวนี้ถ้าค่อย ๆ มาดูทีละข้อแล้วไล่เช็คก็จะทำให้เราแก้ไขปัญหาได้ภายในเวลาวันเดียวและได้ข้าวผัดกระเพราไก่ไข่ดาวที่อร่อยมาอย่างเร็วไว ในขณะที่ถ้ายังมัวงมว่าทำไมไม่อร่อยว้าแล้วก็มั่วไปเรื่อย ๆ เพราะไม่ยอมย่อยปัญหาก่อน อันนี้คงไม่ได้กินในเดือนนี้แน่นอน
สำหรับบางปัญหาที่สามารถย่อยลงไปได้อีก เช่น น้ำมันต้องใส่มากน้อยแค่ไหน เราก็สามารถสร้างเป็นปัญหาใหญ่อันใหม่ได้เช่นกันว่า "เราจะหาปริมาณน้ำมันที่พอดีให้เร็วที่สุดได้ยังไง" แล้วก็ย่อยมันออกมา สุดท้ายก็จะได้คำตอบของปัญหาใหญ่เองครับ
ตัวอย่าง D&C กับการอัปไฟล์ขึ้น Dropbox
ลองกับปัญหาที่เนิร์ดขึ้นมาหน่อย ... "ทำไมอัปไฟล์ขึ้น Dropbox ไม่ได้ว้า"
ปัญหาคลาสสิคที่สุดท้ายมักจะต้องรบกวน IT Support ให้มาช่วยดูให้ แต่จริง ๆ ถ้าเราสามารถย่อยเองได้ว่าปัญหาเกิดจากอะไรบ้างก็อาจจะแก้ไขเองได้เลย แถมเก่งขึ้นด้วย ไหนดูสิมีปัญหาอะไรบ้าง
1) คอมพ์ต่อเนตรึยัง ?
2) เนตที่ใช้บล็อค Dropbox รึเปล่า ?
3) Dropbox ล่มรึเปล่า ?
4) Dropbox พื้นที่เต็มรึเปล่า ?
ก็ไล่เช็คทีละปัญหาสิ สุดท้ายก็จะรู้แล้วว่าเกิดอะไรขึ้นแล้วก็แก้ไขได้
ก็จะเห็นว่าถ้าเราย่อยปัญหาเป็น ทุกปัญหาในโลกจะง่ายลงอย่างทันตา หลาย ๆ ปัญหาที่เราคิดว่าไม่มีทางแก้ได้แน่ ๆ ก็อาจจะกลายเป็นปัญหาจิ๊บ ๆ ไปในทันที
"ขอแค่ย่อยปัญหาเป็น"
การใช้ Divide and Conquer ในการสงคราม
Divide and Conquer ไม่ได้ใช้แค่ในงานโปรแกรมมิ่ง แต่จริง ๆ ถูกใช้ในทุกอย่างเลย การสงครามก็ไม่เว้น
ในอดีตตอนอาณาจักรโรมันเข้าตีและยึดครองอังกฤษ แผนการรบที่โรมันใช้ก็คือ Divide and Conquer นี่แหละ เพียงแต่ศัพท์ทางการที่ใช้จะใช้อีกคำนึงคือ "Divide and Rule"
แนวคิดก็คือ ในการสงครามนั้นมีกองทหารอยู่หลายส่วน ถ้าเข้าตีแค่กลุ่มเดียวก็อาจจะโดนกองอื่นมาตีตลบหลังจนทำให้พ่ายแพ้ได้ ดังนั้นโรมันจึงเลือก
"แบ่งกองทหารออกมาเป็นหลาย ๆ กองแล้วเข้าตีแยกกันจนได้ชัยชนะในที่สุด"
ซึ่งตรงนี้เป็นความหมายที่ตรงกับคำว่า Divide and Conquer สุด ๆ "แบ่งแยกและเอาชนะไง" ถ้าเอาชนะทุกปัญหา(ทุกกองทัพ)ได้ ชัยชนะทั้งหมดก็จะเป็นของเรา
ลองฝึกฝนดูนะ
จะเห็นว่า Key Takeaway ของเรื่องนี้คือ
"ยิ่งย่อยปัญหาเก่ง ก็จะยิ่งแก้ปัญหาเก่ง"
ความได้เปรียบจะเกิดกับคนที่มีสามารถในการมองปัญหาและย่อยมันออกมาให้เป็นปัญหาง่าย ๆ เล็ก ๆ ได้ และนั่นต้องใช้ "ประสบการณ์" พอสมควร
สิ่งที่อยากให้ลองคือ อยากให้ลองฝึกฝนย่อยปัญหาดู ซึ่งทำได้ไม่ยากเพราะชีวิตทุกวันเราจะมีปัญหาให้ต้องแก้ไขอยู่แล้ว ลองลิสต์เลยว่าปัญหานั้น ๆ ประกอบด้วยปัญหาย่อยอะไรบ้าง แล้วก็ลองพยายามแก้ไขด้วยวิธี Divide and Conquer ดู
ฝึกฝนซ้ำไปซ้ำมาเรื่อย ๆ แล้วพอถึงจุดนึง ไม่ว่ามีปัญหาอะไรเข้ามา คุณก็จะมองมันเป็นปัญหาเล็ก ๆ ได้ในทันที
ลองดูนะ เราว่ามันมีประโยชน์ต่อชีวิตมากกกก =)
เป็นบล็อกชิว ๆ สำหรับวันพักผ่อน ไว้มาต่อซีรีส์หนีมาอยู่เมกาต่อบล็อกถัดไปน้าาาา แว้บบบ