為什麼要先談複雜度?#
複雜度(complexity)是精實組織與個人最大的敵人。本書其餘章節都在處理「如何攻擊複雜度」,但首先你必須認得它在哪裡、長什麼樣子。
本書的複雜度定義:「由多個部分組成、難以分析、理解或解釋的整體。」這個定義刻意寬鬆,因為複雜度幾乎無所不在——股市、社交網路、政治、十萬行的 Windows 原始碼,都是複雜度的舞台。
對程式設計師而言,複雜度特別容易在以下幾個面向襲來:
- 程式專案的生命週期(Project Life Cycle)
- 軟體與演算法理論
- 學習新事物的過程
- 業務流程
- 社交網路
- 日常生活
新手第一個敵人:選擇癱瘓#
「我該怎麼開始?」是初學者最常問的問題,背後就是被以下複雜度淹沒:
- 該選哪個程式語言?
- 該投入哪個開源專案?
- scikit-learn、NumPy、TensorFlow 該用哪個?
- 該押注 Alexa app、手機 app、瀏覽器 web app,還是 VR?
- 編輯器要 PyCharm、IDLE,還是 Atom?
解法:以專案為中心的學習#
不要先讀書,挑一個簡單的實際專案,用你現有的能力硬著頭皮做完。每完成一個專案,自然會逐步學到:
- 如何選編輯器
- 如何安裝語言環境
- 如何讀取檔案輸入
- 如何把資料存進變數
- 如何把輸入轉換成想要的輸出
作者舉的例子:一位學生想做投資組合回測 dashboard,過程中接觸 Python Dash、學了必要的 HTML/CSS,一年內不僅產品上線、還加入 Dash 開發團隊並寫了書。做中學,比讀完所有書再開始有效得多。
專案生命週期中的複雜度#
依照 IEEE 軟體工程標準,一個專案會經歷六個階段(敏捷開發只是把這些階段反覆跑得更快):

Figure 1-1: 軟體開發生命週期(SDLC)的六個階段。
- Planning(規劃):決定要做哪些功能。需考量成本、風險、價值、行銷、可維護性、合規 ⋯⋯ 這是最該套用 80/20 思維的階段。
- Defining(定義):把規劃轉成正式需求規格。「知識的詛咒(curse of knowledge)」會讓你高估別人能聽懂多少。
- Designing(設計):規劃架構、模組與介面。設計者必須深諳各工具優缺點,例如:方便的函式庫往往執行慢;自製函式庫雖難但更快。
- Building(建造):寫程式。即使前期準備充分,仍會出現外部 bug、效能問題、資料汙染、人為錯誤——一個拼字錯誤就可能毀掉整個產品。
- Testing(測試):許多人主張測試驅動開發(test-driven development, TDD),先寫測試再實作。
- Deployment(部署):發佈、行銷、修 bug、跨平台支援、長期維護。
測試的範例#
書中以一個計算 RGB 平均值的函式示範:
def average_rgb(pixels):
r = [x[0] for x in pixels]
g = [x[1] for x in pixels]
b = [x[2] for x in pixels]
n = len(r)
return (sum(r)/n, sum(g)/n, sum(b)/n)看似簡單,但實務上要問:
- pixel tuple 只有兩個元素怎麼辦?
- 出現非整數型別怎麼辦?
- 浮點誤差會不會影響結果?
單元測試(unit test)就是在不同輸入下檢查每個函式的正確性。然而即使單元測試全過,整體互動測試與真實環境(例如自駕車跑數萬英里)還可能暴露新問題。複雜度在每一層都會反撲。
軟體與演算法理論的複雜度#
演算法複雜度(Algorithmic Complexity)#
研究演算法在不同輸入規模下的資源消耗。同一個排序問題:
- Bubble sort:複雜度最差,資料量一大時執行時間爆炸。
- Quicksort、Timsort:漸進複雜度相同,但 Timsort 常數較小,因此 Python 內建
sorted()用 Timsort。

Figure 1-2: 兩種排序演算法的複雜度差異示意圖。

Figure 1-3: Bubble sort、Quicksort、Timsort 三者執行時間比較。

Figure 1-4: 拉近觀察 Quicksort 與 Timsort——後者隨資料量增長仍維持較佳效能。
演算法研究是人類最有價值的智慧資產之一——「我們站在巨人肩膀上(we stand on the shoulders of giants)」,用更少的資源解決同樣的問題。
圈複雜度(Cyclomatic Complexity)#
由 Thomas McCabe 於 1976 年提出,計算程式中線性獨立路徑的數量。每多一個 if,圈複雜度加一。
- 它是「認知複雜度(cognitive complexity)」的良好替代指標——也就是程式有多難理解。
- 但圈複雜度忽略了多層巢狀迴圈帶來的負擔,因此後來有 NPath complexity 等改良指標。

Figure 1-5: 兩段 Python 程式的圈複雜度對比。
學習中的複雜度:知識圖譜#
事實之間並非彼此獨立。Google 在 2012 年推出的**知識圖譜(Knowledge Graph)**就是把事實串成關聯網絡:
- 圖靈(Alan Turing)→ 出生年 1912
- 圖靈 → 博士指導教授 → 邱奇(Alonzo Church)
- 邱奇 → 研究領域 → 電腦科學
可以推論出「圖靈博士指導教授的研究領域是什麼?」這類問題的答案。

Figure 1-6: 知識圖譜的節點與關係表示方式。
任何專業領域都只是這個巨大圖譜的一小塊。你想做交易機器人嗎?需要會 Python、NumPy、scikit-learn、ccxt、TensorFlow、Flask、機器學習、API、分散式系統、資料庫、交易策略、市場理論 ⋯⋯。
學得越多,越覺得自己不夠。 結果還沒開始就放棄。對抗這種焦慮的解方就是專注、簡化、降階、減法、極簡主義(minimalism)。
流程的複雜度#
流程的複雜度由動作數量、參與者、分支數決定。Uber 之前,從 A 到 B 要查電話、比費率、準備不同付款方式;Uber 把這些整合成一個 app,把流程徹底簡化。

Figure 1-7: 兩種流程對比——一人開發 vs. 團隊開發。
公司一複雜,創新就推不動,資源會在冗餘步驟中浪費。管理者常以「再加一個流程」應對問題,反而陷入惡性循環。極簡主義是正解:你不太可能把流程簡化過頭。
日常生活:千刀萬剮#
電腦科學家 Cal Newport 在《Deep Work》中指出:
- 對深度思考的需求增加(程式、研究、醫學、寫作)
- 但用於深度思考的時間因通訊與娛樂裝置普及而萎縮
即時滿足 vs. 延後滿足#
- 深度工作帶來延後滿足(delayed gratification)——花幾週寫的程式終於跑起來。
- 但人腦渴望即時滿足:滑訊息、看 Netflix、隨意閒聊。
- 結果:你的專注力死於千刀萬剮(death by a thousand cuts)。
對症下藥的不是「自制力管理」,而是從根源動刀:
- 直接刪除社群 app,而不是試圖控制使用時間
- 減少同時進行的專案數,而不是工作更久
- 深耕一個程式語言,而不是在多個語言間切換
結論#
複雜度傷害生產力,會吞噬你最珍貴的資源——時間。人生終點時,你不會用「回了多少封 email、玩了幾小時電玩」來衡量人生意義。
學會駕馭複雜度、保持簡潔,就是建立競爭優勢的方式。下一章將進入第一個強力工具:80/20 原則——專注於關鍵少數,忽略瑣碎多數。