1. Palmerston 勳爵的名言#
英國首相 Lord Palmerston 曾經談到 Schleswig-Holstein 問題時說:「只有三個人真正理解這個問題——已故的 Prince Consort、一位已經發瘋的德國教授,還有我自己——而我已經忘了。」
Joel 借用這個典故來說明一個類似的現象:程式設計中有些概念是真的很難,不是因為教學方法不好,也不是因為學生不夠聰明,而是因為問題本身就是複雜的。
這篇文章的核心訊息並非「放棄學習困難的東西」,而是「承認有些東西確實困難」——這是一種誠實,也是邁向真正理解的第一步。
2. 程式設計中「真正困難」的概念#
Joel 列舉了一些在電腦科學教育中讓大量學生跌倒的概念。這些不是因為教材寫得差,而是因為它們需要一種特殊的抽象思維能力:
2.1 指標(Pointers)#
指標是 C/C++ 程式設計的核心概念,也是最常讓學生絆倒的地方:
- 你需要同時思考「一個東西」和「指向那個東西的地址」——兩個層次的間接引用
- 指標的指標(
**p)更是讓人腦袋打結 - 動態記憶體配置中的指標操作,需要在腦中維護一個記憶體布局的心智模型
- 一旦搞錯,產生的 bug(dangling pointer、memory leak、buffer overflow)極難追蹤
2.2 遞迴(Recursion)#
遞迴要求你接受一種看似矛盾的邏輯——「用自己來定義自己」:
- 理解遞迴需要能在腦中展開多層呼叫堆疊
- 要同時思考 base case 和 recursive case
- 更進階的遞迴(如樹的遍歷、動態規劃的遞迴解法)需要更深的抽象能力
2.3 其他公認困難的概念#
- 併發與多執行緒(Concurrency):Race condition、deadlock、memory visibility——這些問題不是直覺能解決的
- 函數式程式設計(Functional Programming):高階函數、閉包(Closure)、Monad——需要跳脫命令式思維
- 型別系統(Type Systems):泛型(Generics)、協變與逆變(Covariance / Contravariance)、型別推斷——每一個都是一場心智體操
3. 接受複雜性,而非逃避#
Joel 的核心主張是:面對程式設計中真正困難的問題,正確的態度是接受並擁抱這種複雜性,而非尋求過度簡化的解決方案。
3.1 過度簡化的危害#
當我們試圖把真正複雜的概念簡化到「人人都能懂」時,往往會:
- 遺漏關鍵的細節與邊界條件
- 建立一種虛假的理解感——學生以為自己懂了,但遇到實際問題時完全束手無策
- 培養出只能處理「教科書範例」但無法應對「現實世界問題」的工程師
3.2 Fred Brooks 的「本質複雜度」#
Joel 的觀點與 Fred Brooks 在《No Silver Bullet》中的概念呼應。Brooks 區分了兩種複雜度:
- 偶然複雜度(Accidental Complexity):由工具、語言、框架的不完善所造成,可以透過更好的工具消除
- 本質複雜度(Essential Complexity):問題本身固有的複雜性,無論用什麼工具都無法消除
指標、遞迴、併發等概念之所以難,不是因為 C 的語法設計不好,而是因為底層的問題本身就是複雜的。換一種語言或框架,也許可以隱藏一部分複雜性(例如用 Garbage Collection 代替手動記憶體管理),但核心的概念性困難依然存在。
沒有 silver bullet 可以消除本質複雜度。試圖用「更簡單的工具」來迴避這些概念的人,最終會在遇到真正困難的問題時付出代價。
4. 對教育與職業發展的啟示#
4.1 教育應該誠實面對難度#
- 不要因為怕嚇跑學生就假裝一切都很簡單
- 明確告訴學生:「這個概念很難,大多數人第一次不會完全理解,需要反覆練習」
- 提供足夠的練習機會和漸進式的學習路徑
4.2 開發者應該主動挑戰自己#
- 不要只停留在舒適區——如果你從來不碰指標、從來不寫併發程式、從來不深入型別系統,你的成長會有上限
- 理解困難概念的過程本身就是一種訓練——它鍛鍊的是你的抽象思維能力,這種能力可以遷移到其他領域
4.3 區分「我不需要用」和「我不需要懂」#
- 你可能在日常工作中不需要直接操作指標,但理解指標能讓你更好地理解記憶體模型、效能特性、甚至高階語言的行為
- 你可能不寫函數式程式碼,但理解函數式的概念能讓你寫出更好的命令式程式碼
如何攻克困難的程式設計概念
Joel 雖然沒有提供具體的學習方法,但從文章精神可以推導出以下策略:
- 多角度學習:同一個概念,用不同的教材、不同的程式語言去接觸。每次都會理解得更深一點
- 動手實作:光看書不夠,必須親手寫程式碼。遞迴只有在你自己寫過並 debug 過之後才會真正「點開」
- 接受不適感:學習困難概念時的困惑是正常的。不要因為困惑就放棄或跳過——那種「快要懂了但還差一點」的感覺,往往意味著你正處於突破的邊緣
- 給自己時間:有些概念需要「沈澱」。今天不懂的東西,過一週再看可能就豁然開朗了
如果你發現某個程式設計概念很難理解,不要急著怪自己或怪教材。先問問:「這個東西是不是本來就很難?」如果答案是肯定的,那你需要的不是一個更好的解釋,而是更多的時間和練習。