mockgle - mock's love story

Story of a man who falls in love with Google. Sorry, people of the World, but this is in Thai.

Friday, February 03, 2006

[4] Long distance - ทางไกล

เสียงโทรศัพท์ของผมดังขึ้นอีกครั้งเมื่อตอนบ่ายๆ ของวันที่ 8 ม.ค. 06 เป็นโทรศัพท์ทางไกลจากเมาเท่นวิว แคลิฟอร์เนีย ใช่แล้ว เขาคือคุณอาร์ทูโร่ที่ผมเฝ้าคอย

คุณอาร์ทูโร่แนะนำตัวว่าเขาเป็นหัวหน้าทีมเอ็นจิเนียร์ฝ่าย Billing & Payment System เรียกได้ว่าเป็นฝ่ายหารายได้มาเลี้ยงบริษัทนั่นเอง สตางค์ทุกดอลล่าร์ทุกเซนต์ที่ Google ได้รับจากค่าโฆษณา [https://www.google.com/adsense/], ค่าขายวิดิโอใน video store [http://video.google.com/], หรือค่าสมาชิก Google Earth Plus/Pro [http://earth.google.com/] นั้นล้วนต้องผ่านระบบที่ทีมของคุณอาร์ทูโร่สร้างขึ้นมา

ว้าว! คิดแล้วคงเป็นทีมที่รวยไม่น้อยเลย

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

แน่นอนผมเลือกโปรเจกล่าสุดที่กำลังทำอยู่ในปัจจุบัน

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

ผมขอไม่กล่าวถึงโปรเจกของผมในที่นี้ (เพราะมันยังไม่เสร็จ) แต่สิ่งที่ผมตอบไปนั้น ผมพยายามอธิบายให้เขาฟังว่าผมได้รับแรงบันดาลใจมาจาก gmail ของ Google นั่นเอง ดูคุณอาร์ทูโร่จะชอบใจเมื่อผมบอกเขาว่าผมใช้ gmail มาราวปีครึ่งแล้ว ผมฟอร์เวอร์ดอีเมลล์ทุกฉบับของผมจากแอดเดรสอื่นเข้า gmail เพราะสามารถจัดการง่าย ค้นหาง่าย และมีพื้นที่มหาศาล ใช้ทั้งชาติก็ไม่หมด (เพราะมันเพิ่มขึ้นเรื่อยๆ -- ถ้ายังไม่พออีกก็ขอ account ใหม่ ฮ่าๆๆๆ)

สิ่งหนึ่งใน gmail ที่น่าสนใจก็คือเมื่อเราเปิดดูอีเมลล์ที่มีข้อความที่คล้ายๆ กับที่อยู่ (เช่น มีบ้านเลขที่ มีชื่อถนน ชื่อเมือง รหัสไปรษณีย์) จะมีคำแนะนำโผล่ขึ้นมาบนแถบทางขวาทันทีว่า "ดูแผนที่" หรือเมื่อเราสั่งซื้อของออนไลน์ (เช่นจาก amazon.com) แล้วทางร้านส่งอีเมลล์มาบอก UPS tracking number (รหัสพัสดุ) กับเรา ทางแถบด้านขวาจะขึ้นข้อความว่า "ติดตามพัสดุนี้"

และนั่นก็คือจุดเด่น (feature) หนึ่งใน gmail ที่ผมใช้เป็นแรงบันดาลใจในโปรเจกของผม

คุณอาร์ทูโร่ดูจะชอบใจมาก (ใครๆ [ที่รักบริษัท] ก็คงชอบทั้งนั้นเมื่อเราบอกว่าผลิตภัณฑ์จากบริษัทของเขาเป็นแรงบันดาลใจให้กับเรา) แต่เขาไม่ตกหลุม ปล่อยให้ผมเลีย ...เอ๊ย.. ประจบ ..เอ๊ย.. กล่าวชื่นชม Google อยู่อย่างนี้ตลอด 45 นาทีหรอกครับ ไม่นานนักเขาก็เปลี่ยนเรื่องคุย

หลังจากโม้เรื่องโปรเจกตัวเองมานาน ผมเริ่มคอแห้ง ผมหยิบน้ำเย็นเจี๊ยบที่เตรียมไว้ขึ้นดื่มหนึ่งอึก

โดยไม่รีรอ เขาถามคำถามผมแบบตรงไปตรงมา ... แบบที่ทำให้ผมตั้งตัวแทบไม่ติด และแบบที่ทำให้ผมแทบสำลักน้ำอึกนั้น

"ตลอดชีวิตการเขียนโปรแกรมของคุณ มีบั๊กตัวใดที่น่าสนใจมากที่สุด?"

คำถามนี้หินมาก หินกว่าคำถามใดๆ ที่เคยเจอมาทั้งหมด และเป็นคำถามเดียวที่ผมไม่คาดคิดว่าจะพบเจอ

ผมทำเสียงแบบมั่นใจ แบบไม่ตกใจ (แต่ไม่ทราบว่าทำได้ดีแค่ไหนเหมือนกัน) แล้วตอบไปว่า "ผมเชื่อว่าในชีวิตของโปรแกรมเมอร์นั่นย่อมเคยเขียนบั๊กมานับไม่ถ้วน แต่ละตัวก็มีระดับความน่ารำคาญ/น่าตื่นเต้น/น่าสนใจแตกต่างกันไป ผมเองก็เช่นกัน จำนวนบั๊กที่มากมายเหล่านั้นทำให้เป็นการยากที่จะ 'เลือก' ตัวใดตัวหนึ่งออกมาได้ในระยะเวลาอันสั้น เพื่อความยุติธรรมต่อบั๊กทุกๆ ตัว ผมขอเวลาตัดสินใจสักครึ่งนาทีได้ไหมครับ?"

สิ่งที่ผมพูดไปนั้นก็เพียงเพื่อให้มีคำตอบแก้เก้อไปเฉพาะหน้าเสียก่อน ระหว่างที่พูดอยู่นั้นเราก็สามารถใช้สมองอีกส่วนหนึ่งในการคิดค้นหาคำตอบที่แท้จริงได้ เทคนิคการพูดเช่นนี้ภาษาไทยอาจเรียกว่าการ "เตะถ่วง" ภาษาอังกฤษอาจเรียกว่า ... เอ่อ ... bullsh**

เวลาผ่านไปสักพักผมก็ได้คำตอบว่า "ผมคิดว่า 'ความผิดพลาด' ที่น่าสนใจที่สุดที่เคยพบเจอในการเขียนโปรแกรม โดยเฉพาะในโปรเจกที่ผมกล่าวถึงนั้นก็คือความผิดพลาดด้านโครงสร้างและการออกแบบ (design problem) เช่นเมื่อเราเขียนโมดูลหนึ่งไปแล้ว เขียนไปแทบเป็นแทบตาย ทดสอบแล้วถูกต้องทุกอย่าง โมดูลใช้ได้ดีเยี่ยม แต่พอจะเอาไปใช้จริงในโปรแกรมแม่กลับพบว่ารูปแบบการสนทนากับโมดูล (interface) ไม่เป็นไปในแบบที่โปรแกรมแม่ต้องการ ทำให้ต้องเลือกระหว่าง i) แก้ interface และอาจต้องเขียนโมดูลใหม่ หรือ ii) หาทางแก้ไขเฉพาะหน้าในโปรแกรมแม่ (workaround, hacking) ซึ่งเป็นกระบวนการที่เจ็บปวดมาก"

คุณอาร์ทูโร่บอกว่า "คำตอบคุณเยี่ยมมาก ผมเห็นด้วยกับคุณ ผมก็ประสบปัญหาเช่นนั้นบ่อยๆ เหมือนกัน ... แต่...เอ่อ.."

"แต่ในทางเทคนิคมันไม่จัดเป็น 'บั๊ก' ใช่ไหมครับ?" ผมพูดอย่างรู้ทัน .. รู้ทันว่าผมตอบไม่ตรงคำถาม!

"ครับผม" คุณอาร์ทูโร่ตอบ "ผมอยากได้คำตอบที่เป็นบั๊กทางเทคนิค ทางด้านการเขียนโปรแกรม ทางด้าน code ซะมากกว่า คุณพอจะให้ตัวอย่างได้ไหมครับ?"

ผมคิดหนัก และขอเวลาคิดอีก 2 นาที (คราวนี้ขอกันตรงๆ .. ไม่มีการบูลชิ*)

นี่คือสิ่งที่แล่นในความคิดผม "เวรกรรม บ้าเอ๊ย ถามมาได้ อุตส่าห์ตอบเลี่ยงแล้วเชียว โอย คิดไม่ออก คิดไม่ออก เอาอะไรดี? เอ้า ใจเย็นๆ ค่อยๆ คิด คิดดูซิเราเคยเขียน bug อะไรมาบ้าง? .. โอ้โห ร้อยล้านอย่าง เอ้า! ค่อยๆ พิจารณาทีละอย่าง มีอะไรบ้างล่ะ? .....hmmmm.... hmmm....hmm..... [ผ่านไปแล้ว 1 นาที] เฮ้ย! คิดไม่ออกซักอย่าง ทำไมสมองมันปิด มันมึนตึ้บอย่างนี้? เฮ่ออ แย่ละเว้ย แย่ละเว้ย ... ต้องตอบอะไรไปสักอย่างซะแล้ว เวลาจะหมดแล้ว ทำไงดี? ทำไง? ว๊าาาก จ๊ากกกกกกก"

ผมตอบกลับไป "segmentation fault" -- หวังว่าเขาจะเข้าใจว่านั่นคือคำตอบ ไม่ใช่ว่าเป็น error message ที่สมองของผมพิมพ์เข้าไปใส่ stderr หลังจากที่ต้อง dump core เพราะคิดหาคำตอบจน stack corrupted

[ผู้ที่ไม่เข้าใจย่อหน้าที่แล้ว: โปรดดีใจ...คุณปกติแล้ว]

แน่นอนครับ คำตอบเพียงแค่นั้นยังต้องการคำอธิบาย ผมก็จำไม่ค่อยได้แล้วเหมือนกันว่าวันนั้นผมอธิบายไปว่าอย่างไรบ้าง แต่บางประเด็นที่ผมยกขึ้นมาสนับสนุนความน่าสนใจของ segฯ fault ก็อย่างเช่น...
  1. segฯ fault เป็นสิ่งที่พบได้บ่อยที่สุดในการโปรแกรมใน C
  2. segฯ fault เป็นสิ่งที่ยังคงพบได้ แม้จะทดสอบโปรแกรมหลายครั้งแล้วก็ตาม
  3. หลายครั้ง segฯ fault นั้นยากที่จะ reproduce
  4. ไม่ใช่เรื่องง่ายที่จะหาว่าส่วนใดเป็นต้นเหตุของ segฯ fault เพราะแม้จะทราบว่าบรรทัดสุดท้ายก่อน segฯ fault คือบรรทัดไหน แต่ก็ไม่ได้หมายความว่าบรรทัดนั้นเป็น "ผู้ผิด" เสมอไป (แท้จริงแล้วกลับตรงกันข้าม -- บรรทัดนั้นมักไม่ใช่ผู้ผิด)
  5. การหา "ผู้ผิด" ในกรณี segฯ fault นั้นหมายถึงการไล่หาจุดที่อาจเป็นจุดเกิดเหตุทั้งหมดก่อนจะถึงบรรทัดที่ segฯ fault แต่ละจุดนั้นต้องใช้เหตุผลในการอธิบายให้แน่ใจว่าส่วนนี้ถูกต้องหรือไม่ (เช่น pointer นี้เป็น NULL ได้หรือไม่? ได้จัดสรรเมมโมรี่ไว้เพียงพอหรือเปล่า? เหลือที่ให้ null character หลังจบ string หรือยัง? ฯลฯ)
  6. จากประสบการณ์ในการติวเตอร์ เป็นการยากที่จะอธิบายให้โปรแกรมเมอร์มือใหม่เข้าใจ(และเชื่อ)ได้ว่า บรรทัดที่เกิด segฯ fault มักจะไม่ใช่บรรทัดที่ผิดพลาดเสมอไป ผมเคยเกือบต้องทะเลาะกับนักเรียนที่ผมติวมาแล้ว -- เพียงเพราะผมบอกว่า "การที่มันพังตรงนี้ไม่ได้หมายความว่ามันผิดตรงนี้ มันอาจเป็นกรรมเก่า" เขาหาว่าผมเชื่อในไสยศาสตร์

ผมไม่ทราบว่าคุณอาร์ทูโร่คิดกับคำตอบ (ที่สร้างขึ้นแบบ on-the-fly) ของผมอย่างไร -- ผมยังตื่นเต้นจนไม่ทันได้สังเกต แต่เขาบอกว่านั่นเป็นคำตอบที่ดี (แน่นอน เขาต้องพูดเช่นนั้นตามมารยาท) และชวนผมคุยเรื่องที่เป็น technical มากขึ้น

เขาอยากเห็นผมเขียนโปรแกรม ... ผมถามว่าจะเห็นได้อย่างไร เราคุยโทรศัพท์กันอยู่ เขาบอกว่าให้ผมเขียนในกระดาษก็ได้ เขียนเสร็จแล้วค่อยอ่านให้เขาฟัง

เขาบอกว่ามีโจทย์ที่น่าสนใจมาให้ข้อหนึ่ง ไม่ยาก -- เพียงแค่อาจต้องการสมาธิและความสามารถในการแปลงจากไอเดียให้เป็น code

ผมตื่นเต้นยิ่งนักว่าโจทย์นั้นจะเป็นอะไร?

คุณอาร์ทูโร่พูดว่า "สมมติว่ามี array A และ array B ทั้งคู่บรรจุตัวเลขอยู่คนละ n ตัว เรียงแล้วจากน้อยไปหามาก ผมต้องการสร้าง array C ขนาด 2n ที่บรรจุตัวเลขจาก A และ B เรียงตามลำดับจากน้อยไปหามาก ช่วยเขียนฟังก์ชันที่ทำอย่างนั้นให้หน่อย ภาษาอะไรก็ได้"

"นี่ก็คือฟังก์ชั่น merge ใน merge sort นี่ครับ? เป็นอัลกอริธึมมาตรฐาน" ผมเอ่ยถาม .. เพื่อให้แน่ใจว่าเขาต้องการให้ผมเขียนสิ่งนี้จริงๆ

"ใช่ครับ เขียนให้ผมดูหน่อย คุณไปเขียนในกระดาษสัก 5 นาทีก่อนก็ได้" คุณอาร์ทูโร่ตอบ

อ้าว .. ผมบอกไปแล้วนะว่าผมรู้จักสิ่งที่เขาจะให้ผมเขียนแล้ว และ เหอะๆๆๆ วะฮ่าๆๆๆ ถ้าท่านผู้อ่านไม่ได้อ่านข้ามบทคงจะทราบว่าในบทที่แล้วผมเพิ่งจะเขียน merge sort ไปหมาดๆ!! อยากจะบอกว่าไม่เพียงแต่ไอเดียที่ผมยังจำได้ แต่ code ดังกล่าวยังคงตราตรึงอยู่ในสมอง

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

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

คุณอาร์ทูโร่ถามกลับมาคำเดียว "คุณเคยทำแล้วเหรอครับ?"

ผมตอบในใจ: "ป้าดโธ่! เคยทำไม่รู้กี่สิบครั้งแล้ว บอกแล้วไงนี่มันอัลกอฯ มาตรฐาน"

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

คุณอาร์ทูโร่ถามต่อไป "เอาหละครับ ดีมาก ผมเชื่อว่าสิ่งที่คุณบอกมามันคือ code แล้ว และผมเชื่อว่ามันถูกต้องครับ คราวนี้คุณช่วยอธิบาย running time ของ code คุณด้วย"

"O(n) ครับ" ผมตอบ และแน่นอน อัลกอริธึมมาตรฐานย่อมมีคำอธิบายมาตรฐาน ผมอธิบายไปว่าทำไมมันถึงเป็น O(n) อย่างที่โฆษณา

คุณอาร์ทูโร่ถามต่อว่า "คราวนี้ถ้าหาก A มีตัวเลขสักล้านตัว แต่ B มีตัวเลขแค่ไม่กี่สิบตัว คุณจะมีวิธีทำให้มันเร็วขึ้นได้ไหม?"

ผมตอบว่า "อย่างไรเสียมันไม่มีทางดีกว่า O(n) ครับ ยังไงคุณก็ต้องคัดลอกข้อมูลทุกตัวไปไว้ในที่ใหม่ ยกเว้นแต่ว่าคุณจะใช้ linked list แทน array"

คุณอาร์ทูโร่ตอบว่า "ใช่เลย! เราต้องใช้ linked list เอาหละ สมมติว่าทั้ง A และ B เป็น linked list คุณจะแก้ปัญหานี้อย่างไร? ... สมมติว่าเราอนุญาตให้คุณแก้ไขลิสต์ A และ B ได้ จะเก็บคำตอบไว้ใน A หรือ B ก็ได้"

ผมขอเวลาคิดสักพัก เอ.. มันจะเร็วไปกว่า O(n) ได้อย่างไร? ถ้าหากเอาของใน B ไปค่อยๆ ใส่ไว้ใน A ทีละตัว มันก็จะเป็น O(size A * size B) มิแย่กว่าเดิมหรือ? ... อ้อ ไม่ใช่ซะทีเดียว เพราะจำนวนการเขียนข้อมูลนั้นเท่ากับขนาดของ B (ซึ่งเล็กกว่า A มาก) และจำนวนการอ่าน/เปรียบเทียบข้อมูล (ซึ่งเร็วกว่าการเขียนมาก) นั้นในกรณีที่แย่ที่สุดจริงๆ ก็จะราวๆ ขนาด A คูณ ขนาด B ดังนั้นนี่อาจเป็นคำตอบที่ดีก็ได้

ผมอธิบายหลักการดังกล่าวให้คุณอาร์ทูโร่ฟัง เขาเชื่อและเข้าใจในวิธีการ ลำดับต่อไปคือเขาถามว่า "ถ้างั้นคุณใส่ข้อมูลของ B เข้าไปใน A ตามลำดับได้อย่างไรครับ? ช่วยเขียน code ให้หน่อย"

นี่เป็นอีกหนึ่งฟังก์ชั่นมาตรฐานที่เรียนแล้วเมื่อปี 1 (ไม่ว่าในคลาส 15-111 ซึ่งเป็นจาวา หรือ 15-113 ซึ่งเป็นซี) มีนามว่า "insert_in_order()"

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

คราวนี้ผมเลือกที่จะเขียนด้วยจาวา และมันก็ผ่านไปได้ด้วยดี (แม้จะไม่แคล่วคล่องว่องไวจนน่าสงสัยเท่า merge sort) ในใจผมคิดว่าทำไมผมจึงโชคดีอย่างนี้ เจอแต่โจทย์ที่เคยทำแล้ว (ยกเว้นแต่เรื่อง segฯ fault นั่น)

ผมคาดว่าคุณอาร์ทูโร่คงจะชอบ Java คำถามต่อมานั้นเขาถามผมว่า "คุณถนัด Java ใช่ไหมครับ? ผมขอถามคำถามเกี่ยวกับ OOP ใน Java ซะหน่อย"

และนี่คือคำถาม: "abstract class ต่างกับ interface อย่างไร?"

นี่ก็เป็นคำถามมาตรฐานอีกคำถามหนึ่ง ผมตอบกลับไปตามที่ผมทราบ ความจริงแล้วคำถามนี้เคยมีคนถามอยู่บ่อยๆ จึงไม่ใช่เรื่องยากที่จะอธิบาย (แต่ก็ขอไม่อธิบายในที่นี้เนื่องจากที่นี่ไม่ใช่ java tutorial)

ดูท่าทางคุณอาร์ทูโร่จะพึงพอใจกับคำอธิบาย กระนั้นก็ยังไม่วายถามอีกว่า "เมื่อไหร่จะเลือกใช้ abstract class เมื่อไหร่จะเลือกใช้ interface ล่ะครับ?"

ผมตอบไปว่า "คำถามนี้ในแง่หนึ่งเป็นคำถามเชิงปรัชญา ซึ่งยากที่จะตอบได้สมบูรณ์ แต่หากมองในแง่ของการนำมาใช้งานแล้วละก็ ผมมักจะเลือกใช้ interface ทุกครั้งที่เป็นไปได้เพราะแต่ละคลาสสามารถ implement ได้หลายๆ interface พร้อมๆ กัน ในขณะที่สามารถ extend (เป็น subclass ของ) abstract class ได้เพียงคลาสเดียว แต่ abstract class ก็มีความสามารถที่ interface ไม่มี นั่นคือเราสามารถ implement บาง method ที่ทุก subclass ต้องใช้ร่วมกันได้ทันที" [ฟังแล้วงงไหม? -- ผมก็งง]

คุณอาร์ทูโร่เป็นคนต้องการเห็นอะไรชัดเจน เป็นรูปธรรม จึงเอ่ยว่า "อธิบายได้ดีครับ คราวนี้ช่วยยกตัวอย่างกรณีที่ชัดๆ สักกรณีหนึ่งที่คุณจะเลือกใช้ abstract class แทนที่จะใช้ interface"

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

ผมขอเวลาคิด 1 นาทีเช่นเคย

แล้วผมก็ได้ตัวอย่างนี้มา "สมมติว่ามีสัตว์เลี้ยงอยู่สองชนิดคือหมาและแมว สมมติว่าหมาและแมวเดินท่าเดียวกันแต่ร้องเสียงไม่เหมือนกัน ผมสามารถสร้าง abstract class ชื่อ สัตว์เลี้ยง ขึ้นมาแล้วประกาศ method ร้อง() เป็น abstract เอาไว้ ในขณะที่ผมสามารถ implement method เดิน() ไปได้เลย จากนั้นผมก็สร้างคลาส หมา ให้ extends สัตว์เลี้ยง แล้วเขียน method ร้อง() ว่า {ออกเสียง("โฮ่งๆ");} ส่วนแมวนั้นก็ extends สัตว์เลี้ยงเช่นกันแต่มี method ร้อง() เป็น {ออกเสียง("เมี้ยวๆ");} ในกรณีนี้ผมเขียน method ร้อง() สองครั้ง แต่เีขียน เดิน() แค่ครั้งเดียว"

หมดเวลาพอดี คุณอาร์ทูโร่ก็บอกว่าหมดคำถามพอดี "คุณมีคำถามอะไรหรือเปล่า?" เขาถามทิ้งท้าย

ผมตอบ "ไม่มีครับ แค่จะบอกว่าผมไปดูเว็บไซต์คุณแล้วเห็นว่าคุณชอบปีนเขา ผมว่าน่าสนุกมากเลย รูปภาพในเว็บคุณก็สวยงามดี วันหลังผมจะไปลองปีนบ้าง นี่ผมก็เพิ่งกลับมาจาก Yosemite ไปดูความสวยงาม แต่ไม่ได้ปีนเขา -- ไม่รู้วิธีครับ วันหลังถ้าผมโชคดีได้ทำงานกับคุณคงจะต้องให้คุณช่วยชี้แนะ"

คุณอาร์ทูโร่ท่าทางดีใจเล็กน้อยที่ทราบว่าเราเตรียมตัวค้นประวัติเขามาอย่างดี เขาบอกว่า "นั่นคือสิ่งที่ผมทำแล้วสนุก .. เอ่อ ผมหมายความว่า ผมทำงานใน Google ก็สนุก แต่ตอนวันหยุดผมก็ไปหาความสนุกอีกแบบด้วยการปีนเขา ชีวิตผมมีแต่ความสนุก ชีวิตชาว Google ทุกคนก็คงจะเป็นอย่างนั้นเหมือนกัน :)"

"ผมเชื่อเช่นนั้นครับ นั่นคือเหตุผลที่ผมอยากทำงานที่ Google ผมเชื่อว่าการเขียนโปรแกรมนั้นสนุก ยิ่งถ้าเป็นการเขียนให้ Google แล้วละก็ [...บทประจบมาตรฐาน...ความยาว 1 นาทีครึ่ง...]" ผมตอบ

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

ผมเข้าใจว่าขั้นตอนต่อไปคงเป็น "ขอเชิญคุณบินมาสัมภาษณ์รอบต่อไปที่ Mountain View" หรือไม่ก็ "ขอบคุณที่สนใจใน Google แต่เราตัดสินใจรับคนอื่นไปแล้ว โปรดสมัครใหม่ในปีหน้า" ผมหวังว่าจะเป็นแบบแรก

ใจหนึ่งผมนึกอยากจะถามคุณอาร์ทูโร่ไปตรงๆ ว่า "แล้วการสัมภาษณ์ในวันนี้นับว่าผ่านไปด้วยดีหรือเปล่า?" ... แต่ไม่เอาดีกว่า ของบางอย่างเก็บไว้เป็น mystery สักเล็กน้อยก็ดูตื่นเต้นดี

ผมขอบคุณคุณอาร์ทูโร่ อำลา และวางหูโทรศัพท์ ความหวังผมยังเต็มเปี่ยม แต่ก็ยังไม่ทราบว่ามันจะเป็นอย่างไรต่อไป ถ้าอยากทราบต้องติดตามอ่านบทถัดไป

5 Comments:

  • At 5:01 PM, Anonymous Anonymous said…

    ohhh my gosh. So technical. I kinda skipped a lot of stuffs.... hoho anyhow... congratulations!!!

     
  • At 12:20 AM, Blogger keaw said…

    ผมตอบว่า "อย่างไรเสียมันไม่มีทางดีกว่า O(n) ครับ ยังไงคุณก็ต้องคัดลอกข้อมูลทุกตัวไปไว้ในที่ใหม่ ยกเว้นแต่ว่าคุณจะใช้ linked list แทน array"

    ไม่แย๊บไปอีกหน่อยล่ะว่า ถ้าใช้ data structure ที่ advance กว่า linked list ก็อาจจะลดลงได้เยอะกว่า O(n)

     
  • At 3:53 AM, Blogger mock said…

    น้องวาว: ขอบคุณครับ :)

    พี่แก้ว: 555, good advice ครับพี่ ... แต่ตอนนั้นผมนึกไม่ออก กลัวเค้าให้อธิบายด้วยว่าต้องทำอย่างไร (จริงๆ ตอนนั้นนึกอะไรหลายอย่างไม่ออก)

     
  • At 1:06 AM, Blogger n* said…

    อืมมมม มานั่งแก้ข้องมูลทางด้าน technical แบบพี่แก้งได้แน่ๆ... เพราะงั้น.. ขอบอกแค่ว่า "mistery" สะกดผิดละกัน... :P :P :P

    but anyway, i think you did pretty well in the interview!! เก่งนิ... เอาเหอะ อย่างน้อยๆก็รู้ๆกันว่า... even if you got drunk before the interview, you'd have nailed at least one question. ;)

    มาเขียนต่อไวๆละกัน

     
  • At 1:37 AM, Blogger mock said…

    ตายหละวา เขียนผิดมาตั้งนาน ขอบคุณมากครับหน่อย แก้แล้วจ้า

    and, well, i drank, but i wasn't drunk krab :D

     

Post a Comment

<< Home