品質與實用的辯證#
Facebook 前工程總監 Bobby Johnson: 「『對錯』不是一個準確或有用的世界觀。我更喜歡用『行得通 vs. 行不通(Works vs. Doesn’t Work)』來思考——這讓決策更清晰、也更有效。」
Google 對程式碼品質有極高要求:
- 各語言官方 Style Guide 規範到變數命名、空白
- 每次 Commit 都需要至少一名工程師 Review
- 工程師需通過該語言的 Readability Review,才能獨立 approve 程式碼
這支撐了 Google 在全球 60 多國、4.5 萬名員工下仍能高效運作。然而,這套規範在小型公司或新創就是過度投資——快速實驗的程式碼會被嚴格規範拖慢,部分工程師甚至為此跳槽到能快速迭代的公司。
Facebook 早期工程師 Evan Priestley 的辯證:
- 必須快才能做出好軟體:因為現實會變,你需要快速應變
- 必須好才能跑得快:糟糕的軟體最終會反過來拖慢你
找到適合你和團隊的「實用平衡」,本身就是高槓桿活動。
建立可持續的 Code Review 機制#
2008 年針對 12,500 個專案、650 家公司的研究:經過設計與程式碼審查的流程,平均能移除 85% 的殘留錯誤。
Code Review 的五大效益#
| 效益維度 | 核心功能 | 對團隊的長遠影響 |
|---|---|---|
| 品質門神 | 提早抓 Bug 與設計缺陷 | 降低生產環境的修復成本 |
| 行為約束 | 提升 Code 責任感 | 避免「反正別人收拾」的 Quick-and-dirty |
| 技術傳承 | 良好程式碼的範本 | 新人有可模仿的標竿 |
| 知識共享 | 至少還有第二個人懂 | Bus Factor > 1 |
| 長期敏捷 | 易讀易改的程式碼 | 維持團隊長期開發速度 |
Code Review 不是 0 或 1,而是一個光譜#
Dropbox 前四年沒有正式的 Code Review,但仍累積數千萬使用者後才導入; Instagram 早期用「並肩看螢幕」做 over-the-shoulder Review; Square 與 Twitter 常以 Pair Programming 取代 Review。
作者親身採用過的不同等級:
- Ooyala 起步:先在 Email 上 Review,先做核心模組,且常在 Commit 後事後 Review
- Quora:只 Review Business Logic(Model/Controller),View 程式碼略過;對新人與基礎設施內部變更則更嚴格
工具進步也大幅降低 Review 成本:GitHub / Phabricator 提供 inline 留言、Git Hook 自動通知、Linter 自動掃描風格——把工程師時間留給「真正重要的回饋」。
用抽象(Abstraction)管理複雜度#
作者在 MIT 為自己的論文寫一個 4 機分散式資料庫花了數週、數千行程式碼。 在 Google 用 MapReduce 寫一個 billions 級網頁的單詞統計,只花 30 分鐘、20 行程式碼。
Google 的 MapReduce 推出後四年內,內部已寫出超過 10,000 個應用——這就是好的抽象帶來的乘數效應。
好的抽象提升生產力的三種方式#
- 將複雜問題簡化為基本元素:MapReduce 把可靠性、容錯性等隱藏,使用者只需思考 Map 與 Reduce 兩個概念
- 降低未來維護成本:複雜 plumbing code 只需寫一次,後人不必重寫、維護
- DRY 原則的最大化:難解問題解一次,每次重複使用都在攤提成本
Google、Facebook 等公司都重度投資抽象:MapReduce、Protocol Buffers、Sawzall、BigTable、Thrift、Hive、Tao……動輒把開發時間從數週縮短到數小時。
但抽象也有反例#
Asana 早期花了近一整年開發 Web 框架 Luna,甚至自己造了 Lunascript 語言。 兩年後仍無法公開展示產品,最終放棄並回到 JavaScript。
過早或過度地建立抽象,會犧牲產品交付的時機。
好抽象的特質#
Joshua Bloch 在「How to Design a Good API」演講中歸納:
- 易於學習(Easy to learn)
- 無文件也能用(Easy to use even without documentation)
- 難以誤用(Hard to misuse)
- 功能足夠強大(Sufficiently powerful)
- 易於擴展(Easy to extend)
- 適合對象(Appropriate to the audience)
Clojure 作者 Rich Hickey 在「Simple Made Easy」中補充:好的抽象不糾纏多個概念——每個元件只做一件事、處理一個角色。
自動化測試#
隨著功能增加,錯誤率(Error Rate)會跟著飆升。 自動化測試(Automated Testing) 能平滑掉這些尖峰,並降低整體錯誤率。

Figure 8.1: Error rates over time, with and without automated testing.
為什麼測試是高槓桿活動#
- 減少手動重複工作:跑一次 vs. 跑無數次的成本差距
- 大膽重構的勇氣:作者大規模重構數千行程式碼時最感謝測試
- 快速定位責任人:沒測試保護,問題往往被歸咎於擁有者,而非「真兇」(Dropbox Alex Allain 即經歷過資料層改動意外打壞商務客戶流程,多隊抓兇的事故)
- 執行版的文件:測試本身就是「這段程式碼設計來處理什麼 case」的最佳記錄
但不必盲目追求 100% 覆蓋率。在有限時間下:
- 小單元測試:好寫、回報率高,數量累積後信心十足
- 整合測試:難寫、難維護,但精選幾個就極具槓桿
從第一個有用的測試開始#
Zynga 的 Cityville 早期沒有測試文化,工程師每天要產出三批新內容根本沒時間寫測試。 但某天有人寫了一個簡單測試:檢查每個建築 config 引用的圖檔是否真的存在於 codebase。 此測試立刻避免了過去常見的合併刪除錯誤,省下的時間極為可觀。 團隊問:「既然能檢查圖檔,為什麼不檢查 config 其他欄位?」——測試文化由此滾起來。
接手沒有測試的舊系統時,不要一次補完。 從 最有價值(Most Valuable) 的測試開始:能省最多時間的,就是高槓桿。
償還技術債(Technical Debt)#
Wiki 發明人 Ward Cunningham 1992 年提出技術債的概念: 「Shipping first time code is like going into debt. **少量債務能加快開發,前提是能即時還款;**真正的危險是不還——你花在『將就用』的程式碼上的每分鐘,都是這筆債的利息。」
技術債並非全來自草率#
很多時候我們在尚未完全理解問題時就動工,初版設計必然不夠優雅——這也是一種債。
別盲目還債——按槓桿決定優先順序#
並不是所有的債都值得還。資源放在還債上,就會排擠新建設。
Effective 工程師專注在最高槓桿的債:「高流量區域」 × 「修復成本低」 的程式碼。 這類改進能帶來最高效益。
各家公司的還債節奏#
- Asana:每季最後一週做 Polish and Grease Week
- Quora:每場一週 Hackathon 後配一天清理日
- Google:定期辦 Fixit Day(Docs、Customer Happiness、Internationalization 等主題)
- LinkedIn:上市後暫停兩個月新功能,修復過長的部署流程,再以更快速度恢復開發
重點摘要(Key Takeaways)#
- 建立 Code Review 文化:找到「Review 嚴格度」與「迭代速度」間的平衡
- 投資於好的軟體抽象:解一次困難問題、放大整個團隊的生產力。但別過早地把不確定的事抽象起來
- 以自動化測試擴展品質:先寫能省最多時間的測試
- 管理技術債:別盲目還債,專注在利息最高的部分