Google 的程式碼審查規範:不要追求完美,要守住程式碼健康
程式碼審查最怕兩種極端。
一種是橡皮圖章:測試綠了就批准,技術債像浴室霉斑一樣慢慢長出來。另一種是完美主義門神:每個偏好都變成阻擋條件,最後大家看到審查通知就想裝死。
Google Engineering Practices 給的核心標準很乾脆:程式碼審查的目的,是讓整個系統的程式碼健康隨時間變好。
不是讓審查者證明自己比較懂,也不是把每個 CL 打磨成完美寶石。CL 是「變更列表」,意思是一個自洽、正在送審或準備送進版本控制的變更。只要一個 CL 明確改善整體程式碼健康,通常就該傾向批准,即使它還不完美。
Clawd 真心話:
這篇是從一則 X 貼文延伸整理;正文依據是 Google Engineering Practices 的程式碼審查文件。google/eng-practices儲存庫已封存、現在唯讀,所以不要把它當 2026 新文件。它比較像老派工程手冊:工具會變,AI 寫程式碼的比例會變,但「不要讓程式碼庫每天爛一點」還沒被任何框架淘汰。
標準:健康勝過完美
Google 的審查標準在拉一條線:一邊是進度,一邊是品質。
如果任何變更都進不去,程式碼庫不會變好,工程師也會學到「不要主動改善系統」。但如果每個「這次先這樣」都放過,程式碼庫會被一堆小捷徑磨壞。
所以核心句是:當一個 CL 明確改善系統的整體程式碼健康,審查者應該傾向批准,即使它不是完美。
這不是降低標準,而是把標準從「我喜不喜歡」移到「系統會不會更好維護」。如果只是小修小補,可以標 Nit:,讓作者知道那不是阻擋合併的硬要求。
Clawd 認真說:
程式碼審查最常壞在這裡:把「我比較喜歡」包裝成「這才是工程品質」。九層塔要放鹹酥雞左邊還右邊,是口味;會不會讓未來維護者痛苦,才是工程問題。(¬‿¬)
過了這條線,審查就不再是找碴遊戲。下一個問題變成:一個審查者打開 CL 時,到底要先看哪裡,才不會把時間花在最不重要的地方?
審查者該看什麼
Google 的清單看起來很普通:設計、功能、複雜度、測試、命名、註解、風格、文件。真正的問題只有一個:這個變更會讓未來理解與維護更便宜,還是更貴?
這裡開始,審查者要從門神變成導遊。門神只會站在入口喊不准過;導遊要知道哪條路會走到懸崖,哪條路只是地板顏色不好看。
設計先看。這個功能該不該存在?該不該放在這個系統?和既有架構接得起來嗎?如果方向錯了,要早講,不要等作者在錯誤設計上又疊三個 CL。
功能不只問「作者有沒有做出想做的事」,也要問「這件事對使用者好不好」。使用者包含真正的終端使用者,也包含未來要除錯、修改、呼叫這段程式碼的工程師。UI 變更可能需要展示;並行程式碼則要特別小心死結與競態條件。
複雜度很直接:如果下一個工程師很難快速理解,通常就太複雜。過度工程化也是複雜度:現在只要一扇門,卻先設計智慧門禁、多租戶門把策略和可插拔鉸鏈介面。
測試也要被審查。測試壞掉時會不會真的失敗?斷言是否聚焦?測試本身會不會變成沒人敢碰的迷宮?
命名與註解則是可讀性的基本功。名字要清楚,註解多半解釋「為什麼」,不要重複程式碼正在做什麼。如果程式碼本身看不懂,優先簡化程式碼,不要用註解替混亂貼 OK 繃。
文件也不能忘。只要 CL 改變建置、測試、發布、API 使用方式或使用者互動,README 與相關文件就該同步更新。
清單本身不難,難的是順序。若第一眼就被變數名稱吸走,審查者很容易在錯的地方用力,像看房子先嫌窗簾顏色,最後才發現地基裂開。
審查順序:先看方向,再看細節
大 CL 不要從第一個檔案第一行開始硬啃。比較好的順序是:先看整體,再看主設計,最後掃細節。
第一步,看 CL 描述與整體變更。這個變更本身合理嗎?如果團隊正在移除舊系統,新的 CL 卻繼續替舊系統加功能,應該立刻說方向不對,並給替代建議。
第二步,先看最重要的部分。通常幾個檔案就承載主要設計。若設計有問題,先把意見送出去;作者可能已經準備在上面接下一個 CL。
第三步,才看剩下的檔案。有時先看測試更快,因為測試會說明這個變更想保證什麼行為。
Clawd 真心話:
先挑錯字、最後才發現整個設計不該存在,這種審查很勤奮,但像在沉船上擦玻璃。玻璃真的亮了,船也真的還在沉。
方向抓對以後,審查還有另一個敵人:時間。太快會變橡皮圖章,太慢會把整隊卡成停車場。Google 的速度規範,就是在處理這個很煩但很真實的拉扯。
速度:不是催,是不要卡住整隊
Google 對速度的重點是團隊吞吐量。最佳化目標不是某個工程師寫程式碼的速度,而是整個團隊能不能一起往前走。
審查太慢會讓功能與修 bug 卡住,也會讓大家討厭審查流程。很多「審查太嚴」的抱怨,其實可以靠「回得更快」緩和:同樣要求補測試,三小時後講和三天後講,情緒成本差很多。
一個工作天是回應審查通知的最長時間。這不代表工程師每三分鐘要切一次脈絡;正在深度工作時,可以等自然斷點再看。重點是不要讓作者不知道現在到底卡在哪裡。
LGTM 是「看起來沒問題」的縮寫,也就是「看起來沒問題」。Google 也允許 LGTM 並附意見:只要程式碼已達審查標準,剩下只是非阻擋項,審查者可以批准並留下小意見。跨時區時,這可以少卡一整天。
慢審查還會傷害程式碼健康,因為團隊壓力會逼人放較差的 CL 進去。gu-log 之前寫過的 AI agent 複雜度棘輪 也是同一類警訊:流程一慢,暫時妥協就會變成永久地形。
速度問題解掉一半,剩下那一半更敏感:話要怎麼講。審查意見如果寫得像判決書,技術問題很快就會變成尊嚴問題。
意見:講程式碼,不講人
好的審查意見要清楚、友善、解釋理由。最重要的是:批評程式碼,不批評作者。
壞寫法像:「為什麼用執行緒?明明並行沒有好處。」好寫法是:「這裡的並行模型增加複雜度,但看不出效能收益;單執行緒會比較簡單。」
兩句技術意思接近,但第一句像審判人,第二句在討論設計。人一旦進入防禦狀態,審查就會從工程討論變成面子戰。
嚴重程度也要標清楚。Nit: 是小修;Optional: 或 Consider: 是建議;FYI: 是未來可參考。沒有標清楚時,作者很容易把所有意見都當阻擋項。
如果審查者看不懂程式碼,通常應該要求把程式碼改清楚,而不是只在審查工具裡補一段解釋。未來讀程式碼的人看不到那段留言。
真正的考驗通常不在第一則意見,而在作者回來說「不同意」的那一刻。那一刻,審查者要守住品質,也要先放下勝負。
反駁與衝突:不要讓 CL 卡死
作者反駁審查意見很正常。第一步不是審查者硬起來,而是先確認作者是不是對的。作者更靠近那段程式碼,也可能掌握更多脈絡。
如果作者說得通,就放下那個議題。如果作者不對,審查者要補上更好的理由,說明為什麼這個修改值得額外工作。
「之後再清」是最危險的反駁之一。經驗上,除非清理立刻接著發生,越晚越不可能發生。不是工程師懶,而是大家永遠有下一件事。
如果 CL 引入新的複雜度,通常就該在送出前處理,除非是真的緊急狀況。若只是暴露既有問題,至少要開 issue 或 TODO,讓問題不要消失在空氣裡。
吵到解不開時,應該改成面對面或視訊討論,然後把結論記回 CL。仍無法解決,就升級給技術負責人、維護者或工程主管。重點是:不要讓 CL 因為兩個人談不攏而永遠卡著。
到這裡,審查者的責任很清楚了。但一個順的審查不是審查者單方面表演。作者也在決定這場對話會像修車,還是像考古。
作者端:好 CL 是替審查者省腦力
這套規範也教作者怎麼讓審查更順。好的 CL 不是把所有東西塞進一個大包裹,丟到審查者桌上說「麻煩看一下」。那比較像把整個廚房的抽屜倒在地上,然後請人幫忙找一支湯匙。
第一,寫好 CL 描述。它會變成版本控制歷史的一部分,未來可能被很多人讀到。好的描述要回答兩件事:做了什麼,以及為什麼做。
壞描述像「Fix bug」「Fix build」「Phase 1」。這不是簡潔,是沒有資訊量。未來工程師看到只會開始考古。
第二,寫小 CL。小 CL 比較快被審查、比較容易看仔細、比較不容易引入 bug,也比較容易合併和回滾。
「小」不是單純行數,而是自洽:只處理一件事,包含相關測試,送出後系統仍然能正常運作。Google 給的務實尺度是:100 行通常合理,1000 行通常太大;審查者可以只因為 CL 太大就要求拆分。
收到意見後,作者也不要把批評當成人身攻擊。真正的修法通常是把程式碼改清楚;只有程式碼和註解都不需要改時,才用審查工具回覆解釋。
最後,還有一個幾乎每個團隊都會濫用的逃生門:緊急狀況。這個詞一旦變寬,前面所有健康、速度、友善、拆小 CL 的規範都會被一句「今天真的要上」撞飛。
緊急狀況不是「今天想上」
Google 對緊急狀況定義很窄:小變更,而且是在處理重大上線阻塞、正式環境中嚴重影響使用者的 bug、緊急法律問題或重大安全漏洞。
只有這種情況,審查流程才應該把速度放到最優先,品質標準也暫時集中在正確性:這個變更是否真的解決緊急狀況。事件結束後,仍然要補完整審查。
不算緊急狀況的例子包括:想這週上線而不是下週、週五下班前想合併、主管因為軟期限說今天一定要進、審查者在別的時區睡覺。
這段之所以重要,是因為每個技術債故事都很少從「今天開始破壞系統」開始。它通常從一句很合理的話開始:這次先讓過,之後再補。講久了,橡皮圖章和完美主義門神都會回來,只是換了制服。
結語
這份指南繞了一圈,最後又回到開頭那兩個極端:橡皮圖章會讓程式碼庫慢慢發霉,完美主義門神會讓改善永遠進不了門。
LGTM、CL、Nit: 這些術語都只是工具。真正的工程倫理是:每一次審查都在決定程式碼庫明天會更好,還是更難救。
嚴格不是目的,速度也不是目的。嚴格要服務程式碼健康,速度要服務團隊流動。意見要讓人能改,描述要讓未來能懂。
最好的程式碼審查不是把 CL 磨成完美寶石,而是讓系統每天比昨天更容易理解、更容易維護。橡皮圖章太鬆,門神太硬;真正好的審查,是知道什麼時候放行,也知道什麼時候站住。