C.4 架構演進與技術債案例#
軟體的壽命經常比我們想像的長,也因此「如何在舊系統上持續演進」比「從零開始寫新系統」更困難。本節四個案例分兩組:兩個反面——Netscape 的「從頭重寫」災難、Y2K 的技術債總清算;兩個正面——Git 因痛點而誕生、Netflix 用混沌工程重塑架構。它們共同回答第 4 章與第 12 章的難題:在不斷變動的基礎上,如何安全地演進?
案例一:Netscape 重寫——軟體工程史上最貴的一課#
背景:1990 年代,Netscape Navigator 市占率一度超過 80%。1998 年,面對微軟 IE 的步步進逼,高層決定一個大動作:把 Navigator 4.0 的程式碼全部廢棄,從零重寫成 6.0。
災難結果:重寫工程比預期複雜數倍,耗時兩年多。這段期間舊產品無法更新修 bug,市場被 IE 蠶食。新版上市時市占率已潰敗,公司最後被 AOL 收購。知名工程師 Joel Spolsky 後來撰文指出,這是「軟體公司最容易犯的單一最大錯誤」。
技術真相:舊程式碼裡每一個醜陋的 workaround、每一處混亂的邊界,背後都代表過去某個工程師被真實問題打敗後留下的血淚經驗。丟掉舊碼,等於把好不容易累積的「踩坑知識」一起丟掉。
啟示(連結本書):與其「重寫」不如「重構」(Refactoring,見 4.2 節)。重構是一小步一小步地、在測試網保護下改進,風險可控;重寫則是把整個團隊押上高空走鋼索而不帶安全網。對 AI 時代的啟示更直接:AI 產出的「全新替代品」往往因為不認識既有系統的歷史包袱而看起來「很乾淨」,但乾淨不等於正確——看到 AI 建議「重寫這整段程式碼」時,要像看到 Netscape 決策一樣警惕(見 4.4 節)。
案例二:Y2K 千禧蟲——技術債的全球總清算#
背景:1960-1980 年代記憶體極貴,軟體工程師普遍用 2 位數字存年份(1985 存成 85)。當西元 2000 年到來,系統會把 00 讀成 1900,導致銀行利息錯算、電力排程崩潰、基礎設施失序。這是全球最大規模的一次技術債到期。
結果:各國啟用海量人力清查修正 COBOL 等舊程式,全球估計耗費 3,000 億至 6,000 億美元才勉強跨越千禧年。
啟示(連結本書):任何為了當下效率而妥協的資料設計,都會在未來以更高的代價回報(見 6.1 節、12.1 節)。「看起來省了一點空間、快了一點」的短期取捨,正是 1.2 節所說「附屬性困難」被低估的例子。資料模型(3.3 節)、時間處理(4.1 節)這類「一旦定型就很難改」的決策,值得在第一時間付出多一點成本——因為「將來」永遠比想像中快。
案例三:Git 的誕生——從痛點長出的工具革命#
背景:Linux 核心是全球最大的開源專案,2005 年前賴以協作的版本工具 BitKeeper 突被撤銷免費授權。Linus Torvalds 沒有等待商業替代品,而是閉關數週,以「極度分散、極致效能、高併發分支」為目標親手寫出 Git。
啟示:Git 不只是一個檔案工具,它改變了軟體工程的協作上限——今天 GitHub、CI/CD、Code Review 全部建立在 Git 之上(見附錄 A)。它同時示範了正面模式:當既有工具成為瓶頸時,頂尖工程師會重新定義工具的「規格」,而不只是忍受(見 2.6 節 Spec-Driven、12.3 節工具選型)。
具體技術上,Git 之所以能支撐全球數百萬開發者平行協作,正因為它取捨正確:
- 內容位址化:以內容雜湊(SHA-1)定址,天生偵測竄改與重複
- 分散式:每人持有一份完整歷史,不依賴中央伺服器(附錄 A.1)
- 分支即資料夾:建立分支成本極低,鼓勵大量平行嘗試(呼應 A.3 分支策略)
案例四:Netflix 混沌工程——為失敗而設計#
背景:2008 年 Netflix 仍是單體架構。當年 8 月資料中心一場嚴重災難讓串流與 DVD 服務停擺三天,促使 Netflix 徹底轉向微服務 + 雲端原生架構。
技術真相:轉型之際,Netflix 發明 Chaos Monkey——一個會在生產環境隨機殺伺服器、斷網路的自動化程式,強迫工程師把系統設計成「任何單點陣亡都不影響服務」。這套原則後來演變成「混沌工程(Chaos Engineering)」,與「Design for Failure」哲學一起開源,奠定現代雲端原生與 DevOps 的基礎(見 6.1、6.4 節)。
啟示(連結本書):單體架構初期開發快,但擴展性與抗災能力差(見 1.1 節附屬性困難)。而「為失敗而設計」的反直覺之處在於:要用「主動製造失敗」的方式來練兵(見 6.4 節「AI 驅動自癒」、9.3 節驗證機制)。對 AI 系統同樣成立——一個 Harness 若從不故意出錯、從不測試自己的降級路徑,一旦真出錯時將毫無準備。
想一想#
- 如果你的團隊想用 AI 大規模改寫一份十年前的 legacy 程式碼,Netscape 與 Y2K 的案例給你哪些「停下來想一下」的理由?
- Git 的「分支即資料夾」讓試錯成本極低。想想看:如何把這種「低成本試錯」的精神帶進你自己的實驗與 AI 協作流程?
- Chaos Monkey 是「故意弄壞系統來測試」。若要為一個 AI Agent 系統設計「Chaos」測試,你會故意弄壞系統的哪些部分?(提示:回顧 9.2 約束與 9.4 糾正)
本章小結#
架構演進的兩個反面案例告訴我們「重寫與技術債有多危險」,兩個正面案例則告訴我們「在正確的底層設計上,成本與風險可以被工具與原則大幅降低」。共通的核心是:演進是常態,原地踏步才危險——但演進的方式必須是漸進重構、明確契約、並主動為失敗做準備(見 4.2、12 章)。