Rob Pike的“抱怨”與Go的“解藥”:直面軟件膨脹的四大根源
今年年初,Go語言之父、UTF-8編碼的發(fā)明者Rob Pike的一篇題為"On Bloat"(關(guān)于膨脹)的演講幻燈片(在2024年下旬做的)在技術(shù)圈,尤其是在Hacker News(以下簡稱HN)上,引發(fā)了相當(dāng)熱烈的討論。Pike作為業(yè)界泰斗,其對當(dāng)前軟件開發(fā)中普遍存在的“膨脹”現(xiàn)象的犀利批評,以及對依賴管理、軟件分層等問題的深刻擔(dān)憂,無疑戳中了許多開發(fā)者的痛點。

HN上的討論更是五花八門,開發(fā)者們紛紛從自身經(jīng)歷出發(fā),探討“膨脹”的定義、成因和后果。有人認(rèn)為膨脹是“層層疊加的間接性”導(dǎo)致簡單修改寸步難行;有人認(rèn)為是“不必要的功能堆砌”;還有人歸咎于“失控的依賴樹”和“缺乏紀(jì)律的開發(fā)文化”。
那么,Rob Pike究竟在“抱怨”什么?他指出的軟件膨脹根源有哪些?而作為我們Gopher,Go語言的設(shè)計哲學(xué)和工具鏈,能否為我們從純技術(shù)層面提供對抗膨脹的“解藥”呢?今天,我們就結(jié)合Pike的演講精髓和HN的熱議,深入聊聊軟件膨脹的四大根源,并從Go的視角嘗試尋找一下應(yīng)對之道。
“膨脹”的真相:遠(yuǎn)不止代碼大小和運行速度
在深入探討根源之前,我們需要認(rèn)識到,“膨脹”并不止是字面意義上我們理解的最終編譯產(chǎn)物的大小或者應(yīng)用的運行速度慢,Pike的觀點和HN討論中的“軟件膨脹”體現(xiàn)在多個維度:
- 復(fù)雜性失控: 過度的抽象層次、復(fù)雜的依賴關(guān)系、難以理解的代碼路徑,使得維護和迭代變得異常困難。
- 維護成本劇增: 添加新功能的長期維護成本(包括理解、測試、修復(fù)Bug、處理兼容性)遠(yuǎn)超初次實現(xiàn)的成本,但往往被低估。
- 不可預(yù)測性與脆弱性: 龐大且快速變化的依賴樹使得我們幾乎無法完全理解和掌控軟件的實際構(gòu)成和行為,任何更新都可能引入未知風(fēng)險。
下面我們具體看看Pike指出的“膨脹”幾個核心根源:
根源一:特性 (Features) —— “有用”不等于“值得”
圖片
Pike 指出,我們不斷地為產(chǎn)品添加特性,以使其“更好”。但所有特性都會增加復(fù)雜性和成本,而維護成本是最大的那部分,遠(yuǎn)超初次實現(xiàn)。他警示我們要注意“有用謬論” —— 并非所有“有用”的功能都值得我們付出長期的維護代價。
HN討論也印證了這一點:功能冗余、為了匹配競品或滿足某個高層“拍腦袋”的想法而添加功能、甚至開發(fā)者為了個人晉升而開發(fā)復(fù)雜功能的現(xiàn)象屢見不鮮。
技術(shù)層面:Go的“解藥”在哪?
- 簡潔哲學(xué): Go從設(shè)計之初就強調(diào)“少即是多”,鼓勵用簡單的原語組合解決問題,天然地抵制不必要的復(fù)雜性。
- 強大的標(biāo)準(zhǔn)庫: Go 提供了功能豐富且高質(zhì)量的標(biāo)準(zhǔn)庫,覆蓋了網(wǎng)絡(luò)、并發(fā)、加解密、I/O 等眾多領(lǐng)域,減少了對外部特性庫的依賴。很多時候,“自己動手,豐衣足食”(使用標(biāo)準(zhǔn)庫)比引入一個龐大的外部框架更符合Go的風(fēng)格。
- 關(guān)注工程效率: Go的設(shè)計目標(biāo)之一是提高軟件開發(fā)(尤其是大型項目)的工程效率和可維護性,這促使Go社區(qū)更關(guān)注代碼的清晰度和長期成本。
注:技術(shù)層面包括語言、工具以及設(shè)計思路和方法。
根源二:分層 (Layering) —— 在錯誤的層級“打補丁”
圖片
Pike 認(rèn)為,現(xiàn)代軟件層層疊加(硬件 -> 內(nèi)核 -> 運行時 -> 框架 -> 應(yīng)用代碼),當(dāng)出現(xiàn)問題時,我們太容易在更高的層級通過包裝(wrap)來“修復(fù)”問題,而不是深入底層真正解決它。這導(dǎo)致了層層疊疊的“創(chuàng)可貼”,增加了復(fù)雜性和維護難度。他列舉了ChromeOS文件App的例子,并強調(diào)要在正確的層級實現(xiàn)功能和修復(fù)。
在HN的討論中,有開發(fā)者描述的修改按鈕顏色需要穿透17個文件和多個抽象層的例子,正是這種“錯誤分層”或“過度抽象”的生動體現(xiàn)。
技術(shù)層面:Go的“解藥”在哪?
- 小接口哲學(xué): Go 鼓勵定義小而專注的接口,這使得組件之間的依賴更清晰、更松耦合。當(dāng)問題出現(xiàn)時,更容易定位到具體的接口實現(xiàn)層去修復(fù),而不是在外部層層包裝。
- 組合優(yōu)于繼承: Go 通過組合(struct embedding)而非繼承來實現(xiàn)代碼復(fù)用,避免了深度繼承帶來的復(fù)雜性和脆弱性,使得在“正確層級”修改代碼更易操作。
- 顯式錯誤處理: if err != nil 的模式強制開發(fā)者在調(diào)用點處理錯誤,使得問題更難被“隱藏”到上層去統(tǒng)一“包裝”處理,鼓勵在錯誤發(fā)生的源頭附近解決或添加上下文。
根源三:依賴 (Dependencies) —— 看不見的“冰山”
圖片
這是Pike演講中著墨最多、也最為憂慮的一點。他用數(shù)據(jù)(NPM 包平均依賴 115 個其他包,每天 1/4 的依賴解析發(fā)生變化)和實例(Kubernetes 的復(fù)雜依賴圖)強調(diào):
- 現(xiàn)代軟件依賴數(shù)量驚人且變化極快。
- 我們幾乎不可能完全理解自己項目的所有直接和間接依賴。
- 依賴中隱藏著巨大的維護成本、Bug 和安全風(fēng)險。
- 簡單的 npm update 或 audit 無法解決根本問題。
他強烈建議要理解依賴的成本,嚴(yán)格、定期地審視依賴樹,并推薦了 deps.dev 這樣的工具。
HN 社區(qū)對此深有同感,紛紛吐槽“為了一個函數(shù)引入整個庫”、“脆弱的傳遞性依賴”、“供應(yīng)鏈安全”等問題,并呼喚更好的依賴分析工具。
技術(shù)層面:Go的“解藥”在哪?
- Go Modules: 相比 NPM 等包管理器,Go Modules 提供了相對更好的依賴管理機制,包括語義化版本控制、go.sum 校驗和、最小版本選擇 (MVS) 等,提高了依賴的可預(yù)測性和安全性,但也要注意Go module并非完美。
- 強大的標(biāo)準(zhǔn)庫: 這是 Go 對抗依賴泛濫的最有力武器。很多功能可以直接使用標(biāo)準(zhǔn)庫,避免引入外部依賴。
- 社區(qū)文化: Go 社區(qū)相對而言更推崇穩(wěn)定性和較少的依賴。引入一個大型框架或過多的外部庫在 Go 社區(qū)通常需要更充分的理由。
- 工具支持: Go 提供了 go mod graph, go mod why 等命令,可以幫助開發(fā)者理解依賴關(guān)系。結(jié)合 deps.dev,可以在一定程度上實踐 Pike 的建議。
根源四:開源模式 (Open Source Development) —— “大門敞開” vs “嚴(yán)格把關(guān)”
圖片
Pike 對比了兩種開源開發(fā)模式:
- “真正的開源方式” (The true open source way): 接受一切貢獻(xiàn) (Accept everything that comes)。他認(rèn)為這是膨脹和 Bug 的巨大來源。
- 更好的方式: 設(shè)立嚴(yán)格的代碼質(zhì)量、標(biāo)準(zhǔn)、評審、測試、貢獻(xiàn)者審查等“門檻”,對允許合入的內(nèi)容有標(biāo)準(zhǔn)。這種方式維護成本低得多。
他暗示 Go 項目本身更傾向于后者,強調(diào)“先做好再提交”(make it good before checking it in)。可能很多Gopher也感受到了這一點,Go項目本身對代碼質(zhì)量的review非常嚴(yán)格,這一定程度上也“延緩”了一些新特性進入Go的時間點。
HN 的討論中也涉及了類似 "Bazaar vs Cathedral" 的模式對比,但觀點更加復(fù)雜,認(rèn)為現(xiàn)實中的項目往往處于兩者之間的某個位置,并且“完全不接受外部貢獻(xiàn)”也并非良策。
技術(shù)層面:Go的“解藥”在哪?
- Go 自身的開發(fā)模式: Go 語言本身(由 Google 主導(dǎo))的開發(fā)流程相對嚴(yán)謹(jǐn),對代碼質(zhì)量和向后兼容性有較高要求,可以看作是“嚴(yán)格把關(guān)”模式的體現(xiàn)。
- 標(biāo)準(zhǔn)庫的設(shè)計: Go 標(biāo)準(zhǔn)庫的設(shè)計精良、接口穩(wěn)定,為開發(fā)者提供了一個高質(zhì)量的基礎(chǔ)平臺,減少了對外部“隨意貢獻(xiàn)”的依賴。
- 社區(qū)項目實踐: 觀察 Go 社區(qū)一些知名的開源項目,其貢獻(xiàn)流程和代碼標(biāo)準(zhǔn)通常也比較嚴(yán)格。
反思與現(xiàn)實:Go 也非萬能,“警惕與紀(jì)律”仍是關(guān)鍵
雖然 Go 的設(shè)計哲學(xué)和工具鏈在對抗軟件膨脹方面提供了許多“天然優(yōu)勢”和“解藥”,但我們必須清醒地認(rèn)識到,Go 語言本身并不能完全免疫膨脹。
正如 Pike 在其“建議”(Advice) 中反復(fù)強調(diào)的,以及 HN 討論中部分開發(fā)者指出的,最終軟件的質(zhì)量很大程度上取決于**開發(fā)者和團隊的“警惕與紀(jì)律” (vigilance and discipline)**:
- 我們是否真正理解并避免了增加不相稱成本的特性?
- 我們是否努力在正確的層級解決問題?
- 我們是否審慎地評估和管理了每一個依賴?
- 我們是否堅持了高標(biāo)準(zhǔn)的開發(fā)和評審流程?
如果缺乏這些,即使使用 Go,項目同樣可能變得臃腫、復(fù)雜和難以維護。同時,HN 討論也提醒我們,軟件膨脹背后還有更深層次的組織、文化和經(jīng)濟因素,這些往往超出了單純的技術(shù)和開發(fā)者紀(jì)律所能解決的范疇。
小結(jié):擁抱 Go 的簡潔,但需務(wù)實前行
Rob Pike 的“抱怨”為我們敲響了警鐘,Hacker News 的熱議則展現(xiàn)了軟件膨脹問題的復(fù)雜性和普遍性。它確實是我們在工程實踐中需要持續(xù)對抗的“熵增”現(xiàn)象。
Go 語言以其簡潔、顯式、組合的設(shè)計哲學(xué),以及強大的標(biāo)準(zhǔn)庫和相對穩(wěn)健的依賴管理,在技術(shù)層面上,為我們提供了對抗膨脹的有力武器。理解并擁抱這些 Go 的“基因”,無疑能在一定程度上幫助我們構(gòu)建更健康、更可持續(xù)的軟件系統(tǒng)。
當(dāng)然,Pike 的觀點也并非金科玉律。有批評者指出,他的視角可能帶有一定的“NIH(非我發(fā)明)傾向”,并且存在兩個關(guān)鍵的“盲點”:
- 忽視了“不使用依賴”同樣是巨大的技術(shù)債。 每一行自寫的代碼都需要永遠(yuǎn)維護。
- 現(xiàn)實中的選擇往往不是“使用依賴 vs 自己實現(xiàn)”,而是“使用依賴 vs 根本不做這個功能”。 面對復(fù)雜的合規(guī)要求(如 ADA、GDPR)、第三方集成或 FIPS 認(rèn)證等,從零開始構(gòu)建的成本(可能需要數(shù)百人年)往往讓“自己實現(xiàn)”變得不切實際。為了讓產(chǎn)品能夠及時上線并滿足用戶(哪怕是 Pike 本人可能也在使用的“緩慢”網(wǎng)站)的需求,引入依賴和一定的“膨脹”有時是必要且務(wù)實的選擇。
注:“NIH(非我發(fā)明)傾向”是一種心理現(xiàn)象,指的是人們對他人提出的想法或創(chuàng)新持有偏見,通常因為這些想法不是自己發(fā)明的。這種傾向使得人們傾向于低估或拒絕其他人的創(chuàng)意,盡管這些創(chuàng)意可能是有價值的。
這種批評也提醒了我們,雖然 Pike 對簡潔和紀(jì)律的呼吁值得我們高度重視,但在真實的商業(yè)環(huán)境和復(fù)雜的工程約束下,我們必須做出務(wù)實的權(quán)衡。純粹的技術(shù)理想有時需要向現(xiàn)實妥協(xié)。
最終,我們每一位 Gopher 都需要在理解 Go 簡潔之道的同時,保持批判性思維和務(wù)實態(tài)度。 在日常的每一個決策中,審慎地權(quán)衡簡單與復(fù)雜、理想與現(xiàn)實、引入依賴與自主掌控,才能在這場與“膨脹”的持久戰(zhàn)中,找到最適合我們項目和團隊的平衡點,交付真正有價值且可持續(xù)的軟件。
你如何看待 Rob Pike 對軟件膨脹的觀點?你認(rèn)為他的批評切中要害,還是忽視了現(xiàn)實的復(fù)雜性?歡迎在評論區(qū)分享你的思考與實踐!
參考資料
[1] Rob Pike - On Bloat: https://docs.google.com/presentation/d/e/2PACX-1vSmIbSwh1_DXKEMU5YKgYpt5_b4yfOfpfEOKS5_cvtLdiHsX6zt-gNeisamRuCtDtCb2SbTafTI8V47/pub?slide=id.p
[2] HN:On Bloat: https://news.ycombinator.com/item?id=43045713
[3] Pike is wrong on bloat: https://blog.habets.se/2025/02/Pike-is-wrong-on-bloat.html
[4] On Bloat: https://commandcenter.blogspot.com/2025/02/on-bloat-these-are-slides-from-talk-i.html





















