工程哲學:Linus Torvalds,消失的特例

重點摘要
- 好品味,就是讓特例消失的那一刻。 重塑資料結構——用指向指標的指標取代單純的指標——那個處理邊界情況的
if,就再也無處容身。 - 「把程式碼拿給我看」是一種認識論,而非口號。 設計只是假設;唯有能跑的程式碼,才能了結爭論。
- git 讓「分散式」成為其資料結構的必然結果。 以內容定址的物件意味著每一個儲存庫地位平等,於是「唯一正本」這種需要捍衛的東西,從一開始就不存在。
- 規模化的信任必須有結構,而非靠假設。 Torvalds 解決了兩次——以維護者樹來釐清「誰」該負責,以防竄改的歷史來記錄「發生了什麼」。
核心原則
「我希望你明白,有時候你可以用不同的角度看待一個問題,重寫它,讓特例消失、化為常態,這就是好程式碼。」——Linus Torvalds,TED,20161
當時 Torvalds 站在 TED 的舞台上,並排舉著兩段 C 函式。兩段都是要從單向鏈結串列中刪除一個節點。第一段用一個 prev 指標走訪串列,先判斷待刪除的節點是不是串列的頭,然後分岔:頭是特例,其餘一律走通用情況。十行程式碼,一個 if。第二段用指向指標的指標走訪串列——**indirect——於是串列的頭根本不再是一個特殊位置。它只不過是這個指向指標的指標恰好指到的第一個東西罷了。四行程式碼,沒有 if。1
行數較少從來就不是重點。第一個版本裡的條件判斷之所以存在,只因為程式設計師把串列的頭模型化成與串列其餘部分不同的東西。換一個更好的資料結構——用指向指標的指標取代單純的指標——這個差異便煙消雲散。那個邊界情況從來不是問題本身固有的;它只是問題被表述方式所留下的人為產物。Torvalds 所謂的品味,正是這一步;這也是同一份信念,讓品味成為一套技術系統,而非審美偏好:那個優雅的版本之所以勝出,不是因為它比較好看,而是因為它更正確——能出錯的地方更少了。
那股直覺——消除特例,讓邊界情況無處藏身——貫穿了 Torvalds 所打造的一切。它也解釋了為什麼他另一句名言,讀起來不像宣言,反倒像一道指令:「空談廉價。把程式碼拿給我看。」2

在上方試試看:先刪一個中間節點,再分別在兩種模式下刪除頭節點。在「顯而易見的方式」中,頭節點會觸發 if (!prev) 分支;在「好品味」中,頭節點只是另一個連結,同一行程式碼就把它處理掉了。
背景脈絡
Linus Benedict Torvalds 於 1969 年出生在芬蘭赫爾辛基,生於一個說瑞典語的家庭。在赫爾辛基大學就讀資訊科學時,他使用 Minix——一個小型的類 Unix 作業系統,由荷蘭教授 Andrew Tanenbaum 撰寫作為教學工具。Minix 富有教育意義,卻刻意有所侷限——Tanenbaum 讓它保持簡單,好讓學生能讀完整套程式碼。Torvalds 想要的,比他被允許擁有的更多。
1991 年 8 月 25 日,他在 comp.os.minix 這個 Usenet 新聞群組發文:「我正在做一個(免費的)作業系統(只是個興趣,不會像 gnu 那樣龐大而專業)給 386(486)AT 相容機。」3 那句括號裡的保留語,是軟體史上被引用最多的一次誤判。

這個興趣,以任何部署指標來衡量,都成了地球上執行最廣泛的核心——它驅動了大多數的網頁伺服器、每一支 Android 手機,以及雲端與超級運算基礎設施中壓倒性的占比。
它的架構從一開始就充滿爭議。1992 年初,Tanenbaum 開了一個標題為「LINUX is obsolete」的討論串,主張單體核心是「倒退回 1970 年代的一大步」,而微核心——也就是把作業系統拆解成彼此隔離、以訊息傳遞溝通的各項服務——才是未來。4 Torvalds 承認,從「理論與美學」的角度看,微核心確實更優越,接著他依然繼續打造那個單體核心,因為它能運作、它快,而且它出貨了。這場辯論後來被銘記為一種性情的奠基文獻:理論,終究敗給了一個跑得起來的系統。
主要作品
Linux 核心(1991 年起):一個能規模化的單體
Linux 是一個單體核心:排程器、記憶體管理員、檔案系統與裝置驅動程式,全都在單一的特權位址空間中執行。Tanenbaum 的批評在理論上並沒有錯——單體核心中一個驅動程式的錯誤,可能拖垮整個系統,而微核心能將其隔離。Torvalds 的回應是經驗性的。單體更快、更容易撰寫,而且能由數千名貢獻者修改,而不必要求每個人先學會一套訊息傳遞協定。那個在學術辯論中落敗的架構,卻贏得了部署戰爭,因為它降低了貢獻的成本。
今日的核心是有史以來最龐大的協作工程產物之一——數千萬行程式碼,每個版本有數千名貢獻者。這份規模沒有任何一部分是事先設計出來的。它是一個合併的修補程式接著一個,逐漸累積而成,而這套開發模式,同樣是 Torvalds 不得不發明出來的。
維護者模型:把信任化為一棵樹
Torvalds 並不會閱讀進入 Linux 的大多數程式碼。他做不到——那個量遠遠超出任何一個人的能力。取而代之的,是核心由一套信任的層級體系所治理。子系統的維護者掌管自己的領域。他們審查修補程式,把它們併入自己的樹中,再向上把拉取請求送給副手,最終送到 Torvalds 手上,由他合併那些他信任的樹。他是位於根部的仁慈獨裁者,但他真正的工作是策劃「他信任誰」,而非稽核他們產出的每一行程式碼。
維護者樹是一種社會架構,它正面迎擊每一條現代軟體供應鏈都會遇到的同一個問題:你無法親自驗證每一件事,因此信任必須有結構,而非靠假設。這正是為什麼儲存庫不該為自己的可信度投票,也是為什麼開放原始碼不是一道安全邊界——唯有當有人為「看」這件事負責時,那一雙雙眼睛才真正有用。郵件論壇,連同它出了名直率的審查,正是讓這棵信任樹清晰可讀的機制:決策與其理由都是公開的、被歸檔的、可追溯歸屬的。
git(2005 年):把分散式信任化為一種資料結構

多年來,核心的開發都使用 BitKeeper,一套專有的分散式版本控制系統,其開發商授予專案免費使用權。2005 年,這項安排在一場授權爭議中破局,Torvalds 突然失去了一個能應付核心工作流程的工具。5 於是他寫了一個。git 的第一個提交在 2005 年 4 月 7 日;大約十天之內,它就能自我託管,並開始管理核心了。6
讓 git 成為與鏈結串列範例同一原則之展現的,正是它核心的資料結構。git 並不儲存差異再去重建狀態。每一個檔案的每一個版本、每一棵目錄樹、每一個提交,都以其自身內容的 SHA-1 雜湊值來命名,儲存為一個物件——一個以內容定址的儲存庫。Torvalds 明確指出,雜湊「從來都不是為了安全。而是為了找出損壞。」6 身分就是內容:兩個位元組相同的檔案會自動成為同一個物件,而單單翻轉一個位元,就會產生一個不同的名稱,從而可被偵測。也因為「每一個儲存庫都相同且平等」,所以不存在一個具特權的中央伺服器——「唯一正本」這個特例消失了,正如「串列的頭」那個特例消失的方式一樣。6 分散式不是後來才栓到 git 上的功能;它是選對資料結構的必然結果。
最後這項特性——一條以內容定址、可防竄改的提交鏈——正是為什麼這張提交圖能承載超越程式碼的意義,也是為什麼我認為會話就是提交訊息:歷史本身就是那件作品,而不是它的副產物。
方法
Torvalds 的方法,是一種由證據來執行的務實主義。「空談廉價。把程式碼拿給我看」是他在核心郵件論壇上,對某個描述自己修補程式會做什麼的人,所給出的字面回覆。2 設計是假設;修補程式才是實驗。在程式碼存在並能執行之前,爭論都還沒了結。
在這之下,是他對「工程判斷究竟存在於何處」最精確的一句陳述:「差勁的程式設計師擔心程式碼。優秀的程式設計師擔心資料結構及其彼此的關係。」7 鏈結串列的範例,就是這句話的具體化身。如果資料結構對了,操作它的程式碼就會很短、分支很少,因為那個結構已經把複雜性吸收掉了。如果資料結構錯了,你就得永遠在特例上付出代價——付在那些只為了替糟糕模型遮羞而存在的 if 敘述上。擔心程式碼,是在治標。擔心資料結構,才是治本。
治理的方法,與技術的方法相互呼應。仁慈獨裁者與副手的模型存在,與其說是為了集中自我意志,不如說是為了讓合併決策對單一品味負責,同時把審查的勞動分散給最貼近每個子系統的人。而他在程式碼審查中的直率——依他本人後來的承認,有時確實越界成了不必要的嚴苛——源自同一個根源:程式碼是依其是否正確來評判,而非依誰寫的、或它代表了多少心力。即便表達方式並不對事不對人,那個標準本身始終對事不對人。
影響鏈
是誰形塑了他
Andrew Tanenbaum 與 Minix。 Minix 是 Torvalds 學習所用的作業系統,也是他試圖超越的對象。Tanenbaum 給了他一個可讀的類 Unix 系統去鑽研,並且透過「LINUX is obsolete」那場辯論,給了他一個夠鋒利的對照,清楚地映照出 Torvalds 究竟看重什麼:一個能出貨的系統,勝過一個令人滿意的架構。(奠基性影響)4
Unix 與 GNU 工具。 Linux 在設計血統上是一種 Unix——行程、檔案、管線,以及「一切皆檔案」的抽象。而它之所以能派上用場,只因為 GNU 專案的編譯器、shell 與各項工具早已存在,可以在它之上執行;Torvalds 在核心還做不了多少事之前,就移植了 bash 與 gcc。3 他打造了那唯一缺失的一塊——核心——然後讓既有的那些零件去完成其餘的事。需要什麼就打造什麼;能用的就拿來重複利用。(直接影響)
是他形塑了誰
整個開放原始碼世界。 Linux 證明了一個全球分散、由志願者與企業混合組成的群體,能在最大的規模上,在工程上勝過專有團隊,而維護者模型也成了大型開放專案如何運作的範本。
在它之後的每一套分散式版本控制系統。 git 不只是勝出——它成了底層基礎。GitHub、GitLab,以及現代的拉取請求工作流程,全都建立在 Torvalds 在那十天裡所選擇的「內容定址、分散式」模型之上。那個資料結構,活得比催生它的那場緊急事件更久。
貫穿的主線
John Carmack 與 Torvalds,從相反的專長出發,卻抵達了同一個地方。Carmack 把一個問題壓榨到演算法與硬體嚴絲合縫、毫無浪費為止;Torvalds 則重塑一個問題,直到資料結構讓特例憑空消失。兩人都把效能與優雅視為同一個性質的兩面,也都拒絕讓理論凌駕於一個確實跑得起來的東西之上。在這整個系列中,好品味從來都不指裝飾;它指的是一種你能感受到的正確性。(系列之橋)
我從中學到什麼
鏈結串列的教訓,是我最常拿來用的那一個。當程式碼長出一個 if 來處理「第一個」或「空的情況」或「管理員使用者」時,那個分支通常是一句自白:資料模型有點不對。修正之道,鮮少是一個更好的 if。而是一個更好的表述,在那之後,那個分支不再需要了,因為它原本所防範的那個情況,已經再也不可能發生。那是可能成本最低的防禦:一個不可能存在的邊界情況,根本不需要任何程式碼去處理它。
第二個教訓,是關於規模化的信任,也是在我如今所建構的世界裡最要緊的那一個——代理系統,在其中你所協調的工作,並非由你逐行寫成。Torvalds 解決了同一個問題兩次:在社會層面,用一棵維護者樹來建構「誰」該負責;在技術層面,用 git 以內容定址的歷史,讓「發生了什麼」可防竄改。你無法讀完一個代理產出的一切,正如 Torvalds 無法讀完每一個核心修補程式。所以你做他所做的事——讓信任有結構,讓歷史可驗證——這也正是為什麼我把品味當作基礎設施,把供應鏈當作攻擊面。那份從興趣造就一個核心的紀律,與那份讓程式庫加速而非衰敗的紀律,是同一份紀律:把結構弄對,特例就不再繁衍。
常見問題
Linus Torvalds 對程式碼中「好品味」的定義是什麼?
在他 2016 年的 TED 訪談中,Torvalds 用兩種從鏈結串列刪除節點的實作來定義好品味。他稱之為缺乏品味的版本,用了一個 if 敘述把刪除串列的頭當作特例處理;他稱之為好程式碼的版本,則用了指向指標的指標,讓頭根本不再是一個特例。他的總結是:「有時候你可以用不同的角度看待一個問題,重寫它,讓特例消失、化為常態,這就是好程式碼。」1
Linus Torvalds 創造了什麼?
Torvalds 創造了 Linux 核心,他在 1991 年 8 月 25 日於 comp.os.minix 新聞群組首次宣告它,如今它是全世界部署最廣泛的作業系統核心。2005 年,在 Linux 專案失去專有工具 BitKeeper 的使用權之後,他還創造了 git,這套分散式版本控制系統。他至今仍是 Linux 核心的首席維護者。35
Linus Torvalds 為什麼打造 git,又花了多久?
Linux 專案一直使用 BitKeeper——一套專有的分散式版本控制系統,直到 2005 年一場授權爭議終結了專案的免費使用權。Torvalds 寫了 git 來取代它,第一個提交在 2005 年 4 月 7 日,而這個工具在大約十天內就開始管理核心——不過他指出,在那之前他已花了數個月思考整套設計。56
「空談廉價。把程式碼拿給我看。」是什麼意思?
Torvalds 在 2000 年 8 月 25 日把這句話發到 Linux 核心郵件論壇,作為對一場「某段程式碼會做什麼」之討論的直接回覆。2 它捕捉了他的務實主義:對一種做法的描述,只不過是一個假設,而在能執行、能測試的可運作程式碼出現之前,爭論都還沒了結。(註:相關的「只要有夠多的眼睛,所有臭蟲都無所遁形」是 Eric Raymond 所表述的Linus 定律,並非出自 Torvalds 本人之口。8)
資料來源
-
Linus Torvalds, “The mind behind Linux,” TED interview with Chris Anderson, 2016 (good-taste / linked-list segment, approx. 14:10). Because the TED transcript renders client-side, the quote and the pointer-to-a-pointer technique are corroborated in full by the annotated source walkthrough at mkirchner/linked-list-good-taste, which reproduces the talk’s exact wording and timestamp. ↩↩↩
-
Linus Torvalds, “Talk is cheap. Show me the code,” message to the Linux Kernel Mailing List, 25 August 2000. The line is catalogued with that exact date and source at Wikiquote: Linus Torvalds and archived in the LKML thread at lkml.org/lkml/2000/8/25/132. ↩↩↩
-
Linus Torvalds, “What would you like to see most in minix?” comp.os.minix Usenet newsgroup, 25 August 1991. The “just a hobby, won’t be big and professional like gnu” announcement. Context: Tom’s Hardware, “Linux is 34 years old today.” ↩↩↩
-
“Tanenbaum-Torvalds debate,” Wikipedia. The “LINUX is obsolete” thread, 1992; “giant step back into the 1970s”; microkernel vs. monolithic kernel; Torvalds’ “theoretical and aesthetical” concession. ↩↩
-
“A Git Origin Story,” Linux Journal. The BitKeeper licensing collapse of 2005 and git’s creation; first commit 7 April 2005. ↩↩↩
-
“Git turns 20: A Q&A with Linus Torvalds,” The GitHub Blog, 2025. “Every repository is the same and equal”; “SHA-1 hashes were never about the security. It was about finding corruption”; the ~10-day timeline. ↩↩↩↩
-
Linus Torvalds, “Bad programmers worry about the code. Good programmers worry about data structures and their relationships,” Linux Kernel Mailing List, 27 June 2006. ↩
-
Eric S. Raymond, “The Cathedral and the Bazaar,” 1997. Raymond coined and named “Linus’s Law” – “given enough eyeballs, all bugs are shallow” – as his own formulation, crediting Torvalds for the underlying development model rather than the wording. ↩