品質與實用的辯證#

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 嚴格度」與「迭代速度」間的平衡
  • 投資於好的軟體抽象:解一次困難問題、放大整個團隊的生產力。但別過早地把不確定的事抽象起來
  • 以自動化測試擴展品質:先寫能省最多時間的測試
  • 管理技術債:別盲目還債,專注在利息最高的部分