ในบทความที่แล้ว เราคุยกันในเรื่อง Soft skill ของผู้สมัครด้วย Behavioral Interview

บทความนี้จะพูดถึงรูปแบบในการวัด Technical Skill กันบ้าง โดยผมจะยกตัวอย่างวิธีการวัด Technical Skill ต่างๆที่ผมเคยเจอมา ซึ่งแต่ละแบบก็จะมีข้อดีข้อเสียแตกต่างกัน

Photo by Helloquence on Unsplash

Coding Interview - Algorithm & Data structure Focus

ไม่มีใครอยากจ้างโปรแกรมเมอร์ที่เขียนโค้ดไม่ได้ใช่ไหมครับ? ดังนั้น Coding Interview จึงเป็นอะไรที่ขาดไม่ได้ในการสัมภาษณ์โปรแกรมเมอร์

วิธีการวัดแบบนี้ เราจะถามโจทย์สมมติกับผู้สมัคร แล้วให้ผู้สมัครออกแบบอัลกอริทึมกับโครงสร้างข้อมูลเอง แล้วทำการโค้ด ทดสอบ และวิเคราะห์

จงเขียนโปรแกรมตัดคำ โดยกำหนดให้ Input เป็น String ที่ไม่มีช่องว่าง เช่น “applepie” และคำที่อยู่ในพจนานุกรม จงเขียนโปรแกรมในการตัดคำออกโดยให้รีเทิร์นค่าออกมาเป็น Array ของคำที่ถูกตัดเสร็จแล้ว

Input: String “applepie”, Dictionary [“apple”, “fruit”, “orange”, “pie”]
Output: [“apple”, “pie”]

เฉลย

สิ่งหลักที่เราต้องการวัด คือ

  1. ผู้สมัครสามารถหาวิธีการแก้ปัญหาที่มีประสิทธิภาพได้หรือไม่ (โจทย์นี้ถ้าใช้ Dynamic Programming จะเป็น Polynomial แต่ถ้า Brute Force จะเป็น Exponential)
  2. ผู้สมัครสามารถเปลี่ยนวิธีการแก้ปัญหาให้เป็นโค้ดได้รึเปล่า

ลักษณะเด่นของวิธีการนี้คือผู้สมัครสามารถแก้ปัญหาด้วยภาษาอะไรก็ได้ และไม่ต้องใช้ความรู้อะไรมากกว่าที่เคยเรียนในวิชา Data Structure กับ Algorithm ซึ่งถือว่าโปรแกรมเมอร์ทุกคนควรจะมีความเข้าใจในสองเรื่องนี้เป็นอย่างดี

การสัมภาษณ์สไตล์นี้จึงเป็นวิธีที่บริษัทไอทีใหญ่ๆอย่าง Google เลือกใช้ เพราะ

  1. ทดสอบได้ว่าผู้สมัครเขียนโค้ดได้จริงๆ
  2. เช็คความรู้ 2 ด้านที่สำคัญมากๆในการเขียนโปรแกรมให้มีประสิทธิภาพ เพื่อรองรับผู้ใช้งานหลักล้านหรือพันล้าน
  3. ใช้มาตรฐานเดียวทั้งบริษัทในการรับ Engineer จึงสามารถเอาคนจากทีมไหนมาสัมภาษณ์ก็ได้ (ex. สามารถเอาคนเขียน C ฮาร์ดคอร์ มาสัมภาษณ์คนเขียน JavaScript ใน Front-end ได้)

เนื่องจากบริษัทเหล่านี้มีขนาดใหญ่พอ สามารถให้เวลาพนักงานเรียนรู้ระบบหรือภาษาใหม่ๆ บริษัทจึงเน้นการสัมภาษณ์ที่ความรู้พื้นฐาน มากกว่าความรู้ด้านเทคโนโลยี ที่เปลี่ยนไวกว่ามาก

Coding Interview - Practical Implementation

แม้การสัมภาษณ์ข้างต้นจะดูเหมาะสมมาก แต่ในความเป็นจริงแล้ว การสัมภาษณ์ที่เน้น Algorithm & Data structure นั้นมีช่องโหว่อยู่ 2 อย่าง

  1. ไม่แฟร์กับผู้สมัครบางกลุ่ม เช่น ผู้สมัครที่ไม่ได้ผ่านการเรียน Computer Science มา (เช่น โปรแกรมเมอร์ที่ฝึกและเรียนรู้ด้วยตัวเอง) หรือผู้สมัครที่จบมานานแล้ว และไม่ได้ใช้ Algorithm หรือ Data Structure ที่ซับซ้อนไปกว่า Array
  2. ถามในสิ่งที่ไม่ได้ใช้งานจริง เช่น บางปัญหาสามารถแก้ได้อย่างรวดเร็วและสวยงามกว่าด้วย Recursive แต่ในทางปฏิบัติจริง น้อยครั้งมากที่เราเขียน Recursive ใน Production โค้ด เพราะจะโดน Stack Overflow เอาง่ายๆ หรือ Data Structure อย่าง Tree หรือ Tries ที่ใช้จริงค่อนข้างน้อย แต่ถูกถามกันบ่อยมากในการสัมภาษณ์ข้างต้น

เรื่องแฟร์ไม่แฟร์นี่ก็แล้วแต่คนจะคิดนะครับ แล้วในโลกแห่งความเป็นจริง มันไม่มีทางที่จะแฟร์ไปหมดทุกอย่างอยู่แล้ว

แต่เรื่องการถามในสิ่งที่ไม่ได้ใช้งานจริง อันนี้มีผลกระทบต่อการคัดเลือกมาก ดังนั้น บางบริษัท จึงเลือกที่จะสัมภาษณ์ด้วยคำถามที่ใกล้เคียงกับเนื้องานจริงมากกว่า ตัวอย่างเช่น

จงเขียนโปรแกรมที่ใช้ดึงข้อมูลจาก Backend ที่เป็น REST API แสดงผลในรูปแบบของตารางด้วย React รวมทั้งจัดการกรณีที่ Backend ไม่สามารถส่งค่าคืนมาได้

คำถามนี้มีการกำหนดเทคโนโลยีชัดเจน เพื่อเป็นการทดสอบว่าผู้สมัครชำนาญในการใช้ Library สำคัญๆมากแค่ไหน

วิธีการวัดแบบนี้แม้จะเจาะจงกว่า แต่ก็จะมีข้อเสียตรงที่ผู้สัมภาษณ์ต้องเชี่ยวชาญในเทคโนโลยีที่ถาม และผู้สมัครก็ต้องเข้าใจเทคโนโลยีนั้นๆดีพอด้วย

แต่หากความชำนาญนี้ไม่ตรงกันล่ะ? ตัวอย่างเช่น เราอยากได้คนที่เก่ง Django + React แต่ผู้สมัครมีประสบการณ์เป็น Django + VueJS มา แล้วคนในทีมก็ไม่มีใครเคยใช้ VueJS ลึกๆมาก่อน

อย่างนี้แปลว่าเราไม่ควรจะให้ผู้สมัครผ่านตั้งแต่รอบคัดใบสมัครเลยรึเปล่า?

หรือ เราควรจะมองว่า แม้ผู้สมัครจะไม่รู้จัก React แต่ความรู้จากการใช้ VueJS ก็สามารถทำให้เรียนรู้ได้อย่างรวดเร็ว

Real Coding on Small Feature

การสัมภาษณ์แนวนี้เหมาะกับบริษัทที่มีขนาดเล็ก เพราะได้ข้อมูลที่ใกล้เคียงกับเวลาผู้สมัครเขียนโค้ดจริงๆมากที่สุด

โดยเราใช้โจทย์คล้ายกับวิธีที่แล้ว เพียงแต่มีโปรแกรมเมอร์อีกคนมานั่งข้างกัน แล้วนั่งแก้ปัญหาไปด้วยกัน

วิธีนี้ตั้งอยู่บนแนวคิดที่ว่า การนั่งเขียนโค้ดด้วยกัน เป็นวิธีที่ดีที่สุดในการวัดความสามารถของโปรแกรมเมอร์

ซึ่งผมเห็นด้วยกับแนวคิดนี้มาก ผมเคยโดนสัมภาษณ์ด้วยวิธีครั้งนึง นอกจากเค้าจะวัดผมแล้ว ผมยังรู้ถึงสกิลของคนสัมภาษณ์ด้วย

ข้อดีคือ เราจะได้ข้อมูลทางปฏิบัติชัดเจนมาก เราจะเห็นว่าผู้สมัครมีวิธีการแก้ปัญหาอย่างไร คิดก่อนโค้ด วางเทสต์เคสก่อนโค้ดหรือไม่ มีการออกแบบก่อนเขียนรึเปล่า หรือเวลาเจอบั้กแล้วดีบั้กยังไง เวลาใช้ StackOverflow นี่อ่านก่อนก็อบมารึเปล่า?

ในบางครั้ง เราอาจได้ข้อมูลของ Soft Skill เพิ่มด้วย

ข้อเสียคือ การมีคนอีกคนที่ไม่รู้จักมานั่งข้างๆ ถามนู่นถามนี่ขณะที่กำลังนั่งโค้ดอยู่ อาจจะน่ารำคาญมากสำหรับผู้สมัคร และทำให้ไม่สามารถเขียนได้ดีแบบปกติ โดยเฉพาะอย่างยิ่งถ้าผู้สมัครไม่ได้ทำ Pair Programming เป็นประจำ

อีกข้อเสียหนึ่งก็คือเรื่องของเวลา การสัมภาษณ์ประเภทนี้มักจะใช้เวลานาน และอาจต้องมีการเซ็ตอัพ Tool ที่ผู้สมัครคุ้นเคยก่อนเริ่มโค้ดด้วย

อย่างไรก็ตาม ในบริษัทขนาดเล็ก การจ้างคนผิดมีผลกระทบต่อบริษัทมาก (เช่น ทั้งบริษัทมีโปรแกรมเมอร์แค่ 5 คน ถ้าคนหนึ่งทำงานแย่ จะส่งผลกระทบต่อ 20% ของทั้งหมด เทียบกับบริษัทที่มีโปรแกรมเมอร์ 100 คน) การใช้วิธีสัมภาษณ์นี้ในตอนท้ายๆของขั้นตอนการสมัคร จะช่วยลดความเสี่ยงในการจ้างคนผิดได้มาก

System Design Interview

ในสามวิธีข้างต้น เราเน้นทดสอบความสามารถในการเขียนโค้ด แต่อีกทักษะที่สำคัญมากในโปรแกรมเมอร์ที่มีประสบการณ์เกิน 3-5 ปี คือการออกแบบระบบ (System Design)

การสัมภาษณ์แบบนี้จะให้ทดลองออกแบบระบบสมมติ โดยให้คำถามที่กว้างมาก เช่น

“จงออกแบบระบบย่อ URL เช่น ย่อ http://www.notaboutcode.com/very-long-post-name ให้เป็น http://shorturl.com/abcde"

เนื่องด้วยคำถามกว้างมาก วิธีการวัดแบบนี้สามารถเจาะลึกไปยังส่วนต่างๆได้ เช่น

  • เก็บ Requirement เพิ่มเติมเป็นรึเปล่า เช่น ผู้สมัครที่ดี ควรจะถามคำถามเพิ่มเติมว่า
    1. ต้องการเก็บ URL นานแค่ไหน
    2. หากปริมาณ url ที่ในระบบเกิน 26^5 แล้วควรจะขยาย URL ต่อหรือไม่
    3. อัตราการ Read/Write ข้อมูลเป็นอย่างไร
    4. ฯลฯ
  • สามารถมองภาพรวม แล้วออกแบบ High-Level Component หลักๆของระบบได้รึเปล่า
  • รู้จักเลือกใช้ Load balancer, Reverse Proxy, Web Server, Cache layer, SQL/NoSQL Database ให้เหมาะสมกับสถานการณ์และ Requirement
  • สามารถออกแบบระบบที่ Scale ตามปริมาณการใช้งาน และจำนวนข้อมูลที่เก็บในระบบ
    1. จะจัดการกับ Concurrent Write Access เยอะๆอย่างไร
    2. ถ้าจำเป็นต้องออกแบบ Distributed System สามารถเลือก Trade-off ของ Consistency แบบต่างๆได้หรือไม่
  • ฯลฯ

จะเห็นว่าการสัมภาษณ์ด้วยวิธีนี้สามารถเช็คได้ครอบจักรวาลมาก และไม่มีคำตอบที่ถูกตายตัว จึงต้องอาศัยผู้สัมภาษณ์ที่มีประสบการสูง และถามคำถามเจาะลึกที่เหมาะสมกับตำแหน่งที่ต้องการรับสมัครว่าต้องการความสามารถด้านไหนบ้าง

บางบริษัทอาจจะแคร์ในเรื่องของการเก็บ Requirement เพราะในตำแหน่งนี้ต้องคุยกับ User ค่อนข้างเยอะ บางบริษัทอาจจะแคร์เรื่องของ Scalability เพราะปริมาณผู้ใช้งานเยอะมาก อันนี้ก็ต้องมีการวางเกณฑ์ให้ดีตั้งแต่แรก ว่าต้องการเช็คอะไรบ้าง

Straight Questions

แทนที่จะเสียเวลาอ้อมค้อมไปเช็คนู่นเช็คนี้ เราสามารถถามตรงๆเลย ว่าผู้สมัครมีความรู้ที่จำเป็นต้องใช้ในงานมากแค่ไหน ตัวอย่างเช่น

ถ้าอยากรู้ว่าผู้สมัครเข้าใจ OOP ดีแค่ไหน อาจถามว่า

Inheritance กับ Composition ต่างกันอย่างไร แล้วยกตัวอย่างโปรแกรมที่เคยเขียนที่เคยใช้หนึ่งในสองวิธีนี้มา ทำไมถึงเลือกวิธีนี้?

หรืออาจจะวัดความรู้ด้านเน็ตเวิร์คพื้นฐานตรงๆ

Network มีทั้งหมดกี่ Layer จำ Layer ไหนได้บ้าง ทำไมถึงต้องมีการแบ่ง Layer แบบนี้ ปกติ Internet อยู่ที่ Layer ไหน?
UDP กับ TCP ต่างกันยังไง กรณีไหนที่ควรจะใช้อะไรบ้าง?

หรือเช็คว่าผู้สมัครเข้าใจการทำ ทำงานของเว็บมากแค่ไหน

เวลาเราเข้าเว็บ เกิดอะไรขึ้นบ้างหลังจากกด Enter ใน Address bar
ในขั้นตอนเหล่านี้ มีการทำ Caching ที่ระดับไหนบ้าง ในกรณีไหนที่เราควรจะทำ Caching ในระดับนั้น

สำหรับคนที่เขียน Java ก็ถามกันโต้งๆเลย

JVM มี Memory Leak ได้ไหม เพราะอะไร ถ้าได้ ให้ยกตัวอย่างด้วยว่า Leak ได้ในกรณีไหน และป้องกันได้อย่างไร
เคยใช้ Generic ไหม? ถ้าเคย ใช้ในกรณีไหน เพราะอะไรถึงใช้?

หรืออยากจะดูว่ามีประสบการณ์ด้าน Operation มากแค่ไหน

สมมติว่าระบบมีปัญหา ส่งค่า Internal Error 500 กลับมาตลอด เราจะทำยังไง?
หากระบบมี Latency สูงขึ้นกว่าเดิมเท่าตัว อาจจะเกิดจากสาเหตุอะไรได้บ้าง?

ช่องโหว่ของวิธีนี้คือ บางครั้ง คำถามของเรา อาจจะไปชนในเรื่องที่ผู้สมัครไม่รู้พอดี แม้ว่าผู้สมัครจะมีความรู้ในด้านอื่นที่ชดเชยกันได้ (อย่างผมเอง ก็จำ 7 Network Layers ได้ไม่ครบเหมือนกัน)

ดังนั้น หากจะถามคำถามประเภทนี้ ต้องเตรียมคำถามไว้เยอะๆหน่อยเพื่อให้กว้างและครอบคลุมพอให้เห็นภาพรวม ว่าผู้สมัครมีความรู้กว้างแค่ไหน และลึกแค่ไหนในแต่ละหัวข้อ

Experience-based Style

วิธีนี้จะให้ผู้สมัครเล่าถึงโปรเจ็คที่เคยทำ แล้วผู้สัมภาษณ์จะถามเจาะลงไปในแต่ละด้านเพื่อเช็คดูว่าผู้สมัครมีความรู้ในด้านนั้นๆมากแค่ไหน

เช่น ผู้สมัครอาจเล่าว่าเคยทำ Web Application ด้วย React กับ Spring เพื่อใช้ในการจองที่พักกับโรงแรม

เราสามารถถามเจาะต่อได้ว่า

  1. มีการทำ CI/CD ไหม? ทำด้วย Tool อะไร เซ็ตอัพแบบไหน ทำไมถึงเลือกออกแบบ Pipeline แบบนี้?
  2. มีการเขียน Test ในระดับไหนบ้าง ถ้าเป็น Unit test จะจัดการกับเทสต์ที่โครงสร้างเหมือนกัน แต่ Input/Output ต่างกันอย่างไร ถ้าเป็น Selenium Test มีการ Abstract ตัว Page Object ออกจากกันหรือเปล่า?
  3. ออกแบบ State ใน Application ยังไง แยก Component ออกเป็นกี่ระดับ มีแบบไหนบ้าง สามารถเอา Component ไป Reuse ได้อย่างไร
  4. จะดึงข้อมูลที่พักที่ว่างจากโรงแรมยังไง? ถ้าหาก API ของโรงแรมไม่เสถียร มีการ Down บ่อย ออกแบบระบบอย่างไรเพื่อไม่ให้ระบบเราได้ผลกระทบ
  5. ฯลฯ

ข้อดีคือเราได้ข้อมูลที่มาจากงานที่ทำจริงๆ แต่ข้อเสียคือ ผู้สมัครจะต้องเข้าใจในเทคโนโลยีที่ใช้ลึกพอที่จะถามคำถามและวัดผลได้ ซึ่งในความเป็นจริง โอกาสที่ทั้งผู้สมัครและผู้สัมภาษณ์จะใช้ Stack ตรงกันนั้นยากมาก

วิธีนี้คล้ายกับ System Design Interview ตรงที่สามารถถามได้กว้างมาก ดังนั้น การกำหนดเกณฑ์การวัดและคำถามไว้ล่วงหน้าจึงสำคัญมาก

สรุป

บทความนี้เล่าถึงรูปแบบการวัด Technical Skill ของผู้สมัครด้วยวิธีแบบต่างๆ พร้อมยกตัวอย่างคำถาม ให้เห็นภาพว่าจะสามารถนำไปปฏิบัติจริงได้อย่างไร

วิธีการวัดแต่ละแบบมีจุดเด่นและจุดด้อยต่างกัน ไม่มีวิธีไหนดีที่สุด การเลือกวิธีที่เหมาะสมขึ้นอยู่กับ

  1. ประสบการณ์และความถนัดของผู้สัมภาษณ์ และผู้สมัคร
  2. เวลาที่มีให้ใช้ในการสัมภาษณ์
  3. เรามีข้อมูลของผู้สมัครมากแค่ไหน (เช่น ถ้าผู้สมัครมี Github Account ที่มีโค้ดให้ดูอยู่แล้ว เราอาจจะไม่จำเป็นต้องเช็คส่วน Coding ละเอียดมาก)
  4. จำนวนผู้สัมภาษณ์ (ถ้ามีผู้สัมภาษณ์หลายคน เราอาจใช้วิธีที่ละเอียดน้อยหน่อย แต่ใช้เวลาสั้น และใช้ข้อมูลที่ได้จากผู้สัมภาษณ์หลายคนมาชดเชยในส่วนนี้)

ทั้งนี้ทั้งนั้น การสัมภาษณ์งานจะต้องมีเกณฑ์การวัดที่ตกลงร่วมกันทั้งทีม (ดังที่ อธิบายไว้ในบทความนี้ ) มิเช่นนั้นแล้ว ต่อให้เลือกวิธีที่ดีแค่ไหน เราก็ไม่สามารถวัดผลได้อย่างชัดเจนครับ