不只是敲鍵盤:Coding Interview 請別忘記「溝通」

by 好豪

在軟體工程或資料科學的求職過程,大家幾乎都免不了要面對寫程式的技術面試(Coding Interview)或者白板題。技術面試當然是在檢驗程式能力,但絕對不是一直低頭敲鍵盤、寫出符合要求程式碼,就能獲得滿分,「溝通」也是技術面試裡非常重要的檢驗項目。

在這則筆記裡,我將從自己找資料科學工作的面試經驗出發,介紹為什麼 Coding 面試需要溝通、並分享技術面試不得不注意的三項溝通要點,我也引用高手的模擬面試影片作為範例,幫助讀者學會如何在實戰中展現溝通技能。

本文提及的技巧只要是面對面的技術面試都適用,不論你寫 Python、SQL、或者 R,都值得把這些技巧學起來。

釐清資料的溝通

動手寫 Code 前,沒有先釐清資料,在面試中絕對是扣分

做資料處理或抽取的時候,程式碼內其實都包含了對資料的理解,然而在面試過程,我們到手的都是全新的資料、不可能馬上通盤理解。要是沒有花點力氣理解新資料的特徵就直接寫程式,那就像無頭蒼蠅一樣迷失方向,程式碼就算語法正確、也只會讓面試官覺得你沒想好就動手、不夠專業。

關鍵提問:「我是否可以假設…」

面試過程該如何理解新資料呢?就是提問!你可以直接開口與面試官討論你擔心可能會出現的資料問題,即使面試官沒有直接回答,你也必須說出你對資料的假設、來釐清你接下來為什麼這樣寫程式碼。

在筆者的經驗裡,對資料的提問通常包括以下幾種面向:

  • 對於商業目標的定義
  • 期望結果的形式
  • 資料缺失、或者雜訊
  • 資料表之間的 JOIN 方式(Primary Key & Foreign Key)
  • 極端情況

在以下的 SQL 模擬面試影片中,Andrew 對這幾個面向都各自有提出問題或假設,我們就以此為範例:

首先,在影片的 3:13,Andrew 被要求處理「員工」與「專案」兩份資料表,計算完成至少 10 個專案的員工中,薪資最低的幾個人是誰。對此,他直接提出他對資料的假設:

  • 所有員工都包含在資料表內(資料無缺失)
  • 資料表內不會包含尚未開始或無意義的專案紀錄(資料無雜訊)
  • 用 ID 欄位來 JOIN 兩份資料表(確認 Primary Key & Foreign Key)

接著,在影片的 5:34,Andrew 也跟面試官確認了期望結果的形式:只需要員工的 ID。所有資料表有那麼多欄位,最後對解決問題有幫助的可能只有特定幾個,因此我們需要注意最終輸出結果只包含重點欄位即可。

在影片的 7:19,Andrew 問面試官「完成專案」的定義是什麼,這是同時是在釐清解決問題的目標以及資料特性。也是 Andrew 主動提問之後,面試官才提出「完成專案」如何用起訖時間來定義。

在影片的 9:59,遇上延伸問題,要計算「未完成專案」的員工的薪水,Andrew 利用他面試過程目前為止對資料的理解提出多種極端情況(Corner Case)來討論定義「未完成專案」會有的問題,例如:不能單用 完成時間 = NULL 來定義未完成,因為可能出現「完成時間在未來」的資料!

值得一提的是,上述 Andrew 提出釐清問題的提問與假設,不一定全部都要在寫 Code 之前一次提出來,有些資料問題,可能是動筆寫程式寫到一半、或者是寫完才想到,這時遇到問題再提出討論,也依然是有做好溝通、不會扣分。只需要記得:如果寫程式前,沒有任何一句對釐清資料的假設或提問,那肯定是個警訊!


筆者在某次 SQL 面試遇到的問題是:找出全班考試總得分第一名的同學。當時經驗不足,只確認了幾個資料缺失的可能問題,就直接動筆寫程式了。在我自信地寫完 SQL 程式碼、沾沾自喜之際,面試官眉頭一皺問我:「如果有多個同學考試總得分並列第一名,你的程式只會找出第一名,對嗎?」。

聽到這個問題,我就知道自己犯了大忌了,在開始寫程式之前,我對解題目標與極端情況欠缺考慮、更沒有提出討論。發生「分數並列第一」的情況是再合理不過,我卻沒有注意到這項可能,在面試官眼裡,我就成了粗枝大葉、沒有縝密思考就行動的人。


Pseudo Code 的溝通

釐清資料問題後,還有一個步驟可以提升我們溝通程式碼的效率:Pseudo Code

寫 Pseudo Code 不使用特定程式語法,而是用口語的方式寫出程式運作的邏輯。換言之,寫 Pseudo Code 的時候,我們不用因為程式語言的特性步步為營,只需要寫清楚程式的每一步驟要做什麼、專注在 問題拆解 即可。

以下的影片是由 Kaggle 的資料科學家示範 R 語言的面試:

影片中,Rachael 被賦予的任務是寫出可以計算出欄位內離群值的函式,她寫出的 Pseudo Code 步驟如下:

  1. 函式輸入的參數是一個欄位(Column)
  2. 算出不屬於離群值的最大與最小值
  3. 查看欄位內,有哪幾列資料超出最大與最小值的範圍
  4. 用布林陣列表示第 3 步驟的資料點篩選,並且回傳
Kaggle 的資料科學家示範面試中的 Pseudo Code 寫法(Source: Kaggle Youtube

在此,Rachael 甚至還沒寫程式,光是用註解 Pseudo Code、加上口述表達的方式,就已經向面試官展現出「她很懂!」:

  • 她具有足夠的統計學知識來解決問題、知道怎麼計算離群值
  • 她懂得拆解問題,變成可以用程式來解決多個步驟
  • 她有釐清函式(或者說 API)的需求,訂定出恰當的輸入與輸出

使用 Pseudo Code 可以讓面試官更容易跟上你的邏輯思維。如果沒有寫 Pseudo Code,最糟糕的情況是,程式碼自顧自地寫得又臭又長,面試官又失去耐心看你的程式碼,那整場面試等於是零分!相反地,先寫好 Pseudo Code,面試官就會知道我們已經理解問題點、並懂得如何解決,即使之後寫出來的程式語法不是 100% 正確,只要 Pseudo Code 能反映你的邏輯正確、還是能獲得大部分的分數。

更重要的是,Pseudo Code 不只是寫給面試官看的、它對我們面試者而言也是 寫程式的骨架,到了真的動筆寫程式的階段,程式碼就只是 Pseudo Code 的換句話說而已,有 Pseudo Code 會讓我們寫程式的過程更輕鬆、不會迷失方向。


筆者好豪在某次 SQL 面試的倒數 3 分鐘,面試官突然拋出一個比較困難的 SQL 加分題,問我要不要試試。我當時心想 3 分鐘內,大概不能把 SQL 語法寫到完美,索性決定放棄程式語法,直接用口頭討論 SQL 解題。我先釐清資料問題,再口述我的 SQL Pseudo Code 包含哪些步驟,所有溝通過程,在我與面試官交流的白板上,我只寫下幾個超簡單的關鍵字,像是:

  • CROSS JOIN table1 & table2
  • WHERE user_id 相同 以及 DATE_DIFF(table1, table2) = 1

就這樣,在沒有真的寫出程式碼的情況下,我也成功解出這個加分題、通過這場面試。從這場超短時間限制的難關中,我深刻地學到:

表達正確的解題邏輯,比程式碼本身還重要!


呈現結果的溝通

就算你已經辛辛苦苦地把程式碼寫完了,面試也還沒有結束!在實戰場景,寫完程式後,還有許多工作要完成,而在面試中,你也需要展現出自己知道寫完程式之後該做什麼、以及如何溝通自己的成果。因此,技術面試不是寫完程式就算了,你需要主動把握機會、呈現與說明你的結果。

在以下這部影片中,Zhia 摘要了幾種能夠展示「好隊友」素質的溝通要點:

對於溝通能力,面試官評估的是:「你會是個好隊友嗎?」

首先,即使你卡關、想不出程式怎麼寫,你也要即時提出、並且講清楚自己哪裡解不開。你能想像,你的同事遇到困難只悶不吭聲、隔了兩週的會議中你才發現他停滯的進度拖慢了整個專案嗎?如果是個好的隊友,應該要考慮整個團隊的效率,遇到困難能夠在適當的時機對同事尋求支援,而不是閉門造車浪費時間、甚至拖延扯後腿。

在技術面試中,當下寫不出程式免不了被扣分,但是我們還是可以適時向面試官說明自己已經完成多少、而未解的難題有哪些,這麼做除了不浪費彼此的時間,也爭取一絲補救機會、讓面試官從其他方面繼續測試你的能力,例如:修改題目定義,看看你能不能寫出較簡單的版本。

此外,即使在完整寫出程式後,你也需要主動提出你寫的程式有哪些優劣勢、還可以怎麼改進,證明自己有分析程式的能力。Zhia 在影片中提及的分析方法包括:

  • 用 Unit Test 說明程式可行性,以及因為面試時間太短沒有解完的是哪些 Edge Cases
  • 說明此程式碼所做的權衡(Trade-off):空間 v.s. 時間、可讀性 v.s. 效能、等等
  • 提出 Coding Style 改進方向,例如哪裡值得 重構(Refactor)

筆者的某次 Python 演算法程式面試,在時間到以前,寫了一個空間複雜度O(N) 的演算法,我在時間只剩一分鐘的時候才發現可以進一步最佳化成 O(1)、但是時間已經來不及修改了。我當時主動用口頭討論的方式,和面試官分享我的改進計畫,面試官聽完後,決定多給我兩分鐘修改程式碼,也因為爭取到時間,最後成功改成 O(1),達到最佳效能、通過面試。


結語

在技術面試的不同階段,本文介紹了三項值得注意的溝通要點:

  • 開始寫程式前,需要釐清問題
  • 寫程式時,善用 Pseudo Code 呈現思考流程
  • 寫完程式後,分析現有結果、並說明改進計畫

不管是面試還是實戰工作,寫程式都不是「寫完、交件」這麼簡單的單向溝通,本文介紹這些溝通要點的核心目標,都是為了主動爭取與面試官的雙向交流、證明自己是善於合作的人。試想:如果自己是面試官,應該都會想找好溝通的人來當自己的新同事吧!

希望讀過這篇筆記之後,讀者除了瘋狂鑽研 LeetCode 以外,也能夠練習一下溝通技巧,我相信必能幫助讀者更順利通過技術面試。筆者好豪在 另一篇文章 也筆記了我在 Udemy 課程學到的 Coding Interview 解題原則,推薦讀者延續這篇學到的溝通技巧、繼續提升技術面試能力。


如果這則筆記有幫助到你,歡迎追蹤 好豪的粉絲專頁,我會持續分享資料科學以及 Python 相關文章;也可以點選下方按鈕,分享知識給你的朋友!

推薦閱讀