Code Review 關卡:在別人的程式碼裡找 bug

· 9 分鐘閱讀

程式碼能編譯。如果有測試,測試也通過。而在這段程式碼裡,埋著兩三個深淺不一的問題——你挖得多深,就是這一關的分數。

為什麼公司要考這一關

讀程式碼占了這份工作的大部分。一項針對 78 名職業開發者的實地研究(Xia 等,ICSE 2018)量到,他們大約 58% 的工作時間花在理解既有程式上,而不是寫新的程式碼。空白的編輯器永遠考不出這一點,這一關可以直接考。

它也很省事:二十分鐘、一段準備好的程式碼,面試官就能知道你會不會注意到競爭條件、能不能把真正的問題和風格偏好分開,以及你怎麼提出批評——這點很重要,因為下個月你就要 Review 同事的程式碼了。

照這個順序看

  • 先看正確性。它對所有輸入都做到它宣稱的事嗎,而不只是對範例?off-by-one、空集合、null、零這種邊界。
  • 再看失敗路徑。相依服務掛掉時會怎樣——網路逾時、檔案不存在、解析失敗。被吞掉的例外和空的 catch 區塊就住在這裡,而且是很常被埋的一種。
  • 接著是並行與資源。先檢查再動作(check-then-act)的模式、共享的可變狀態、打開了卻在錯誤路徑上沒釋放的連線。一個跳過 close 的提早 return 是經典,正因為它看起來人畜無害。
  • 然後是效能,但只看要緊的地方。迴圈裡的查詢是真的發現;五個元素的字串串接稍微沒效率,是雜訊。
  • 風格放最後,而且要短。命名和格式值一句話,不值五句。一開口就講這些,等於告訴面試官你沒找到真正的問題。

陷阱:停在第一個 bug

面試官通常會埋好幾個深淺不同的問題。上面的位置會有一個很明顯的——少了一個 null 檢查,十秒就看得到——它存在的意義,是看你找到之後會做什麼。

宣布完就停下來的人,回答的是另一個問題。把它記下來、繼續往下讀的人,會在四十行之後找到那個資源洩漏,而整個關卡就是圍繞它設計的。

把淺的那個快速講掉,然後繼續:「第四行少了 null 檢查,很好改。我先往下看完,再提修改建議。」

怎麼講,同樣會被打分數

這一關同時也在考你怎麼給回饋,因為這段程式碼出自一位假想的同事,而面試官正在想像你對著一個真人講這些話。

兩個習慣聽起來很好。區分嚴重程度——明講哪些發現會擋住合併、哪些只是偏好,因為把所有事都當成一樣緊急的 Reviewer,合作起來非常累。以及描述故障,而不是描述作者:「兩個請求同時進來時,這裡會回傳過期資料」,而不是「這裡寫錯了」。

Google 公開的工程實踐指南把這兩個習慣寫成了規則:只評論程式碼、絕不評論開發者,說明理由,並用 Nit:、Optional:、FYI: 這類前綴標出次要意見,讓作者分得清哪些一定要改、哪些只是建議。

如果你比較想問作者一句,而不是直接斷言有 bug,就直接講出來:「我會先問這個方法有沒有被同時呼叫——如果有,這個計數器就不安全。」真正的 Review 意見就長這樣。

最常被埋的幾個 bug

沒有人公布面試程式碼片段的統計,但下面這些正是 Google 公開的 Review 指南要求檢查的問題類型,包括可能造成死結或競爭條件的並行程式碼。

  • 被吞掉的錯誤。catch 裡什麼都不記錄就繼續,於是故障在下游變得隱形,而不是在源頭大聲報出來。
  • 洩漏的資源。上面打開、下面關閉,中間一個提早 return 直接跳過了關閉。
  • 先檢查再動作的競爭條件。讀一個值、依此判斷、再寫回去——單執行緒沒問題,兩個呼叫者同時進來的瞬間就錯了。
  • 可變的預設值或共用的快取鍵。本來每次呼叫應該獨立的狀態卻跨呼叫保留下來,產生的 bug 只在有負載時才會出現。

如果這段程式碼其實沒問題

偶爾那段程式碼基本上是對的,而這一關考的是你會不會為了顯得仔細而捏造問題。捏造,就是失敗。

正確的回答是講出你檢查了什麼、結果是乾淨的,然後講出你在核准之前還想知道什麼:「在我看得到的這些情況下,邏輯是成立的。我想知道上游呼叫失敗時它會怎麼表現,另外我會補一個空輸入的測試——但這裡沒有需要我擋下來的東西。」

這個回答展示的是一套 Review 流程。三個捏造出來的小毛病,展示的是相反的東西。

Copilot 在哪裡幫得上忙

Interview Copilot 即時跟著這一關,對方一講完問題,就把結構放到你的螢幕上:這道題真正在問什麼、哪個限制條件才要緊、哪個取捨值得講出來。不是一份照念的講稿,而是你用自己的話開口時可以扶著的架子。

資料來源

註:Google 的面試建議頁面寫明,面試期間不允許使用 Google 搜尋和 AI 工具。其他公司各有規定——在真正的面試中使用任何助手之前,先確認對方的規則。

FAQ

Code Review 面試是什麼?

面試官給你一段埋了問題的程式碼,問你會改什麼。它考的是你能不能讀懂陌生的程式碼、分得清什麼重要,以及能不能給出同事真的能照著改的回饋。

Review 程式碼時應該先看什麼?

先看正確性,再看失敗路徑、並行與資源,然後才是效能,風格放最後而且只值一句話。一開口就講命名和格式,等於告訴面試官你沒找到真正的問題。

找到一個 bug 之後就可以停了嗎?

不行。面試官通常埋了好幾個深淺不同的問題,上面那個明顯的就是用來看你找到之後會做什麼。快速講掉它,然後繼續往下讀。

如果程式碼其實沒問題怎麼辦?

不要捏造。講出你檢查了哪些方面、結果是乾淨的,再講出你在核准前還想知道什麼——這展示的是一套 Review 流程,而捏造三個小毛病展示的是相反的東西。

應用程式在這裡怎麼幫忙

相關文章