🎯 什麼情境該想到我
當你正想寫一段「很聰明但很難懂」的程式,或方案越滾越複雜時。
⚙️ 怎麼用
先讓它對,再讓它清楚,再讓它快——而且只在必要時才追求快。
- 預設選最簡單、最清楚的寫法;清楚勝過聰明。
- 不要過早最佳化:先量測,確定瓶頸再優化,且只優化熱點。
- 記住:除錯比寫程式更難——寫到極限聰明,就沒餘力除錯它。
- 通用與自動化優先:能少寫特例、能自動化就別手動。
★ 「清楚勝過聰明」的具體對照
// 聰明:一行,用了位元技巧
func isPow2(n int) bool { return n > 0 && n&(n-1) == 0 }
// 如果團隊裡多數人看不懂 n&(n-1),至少要有名字和一行 why 註解
// isPow2 回報 n 是否為 2 的冪次。n&(n-1) 會清掉最低位的 1,
// 2 的冪次只有一個 1,清完必為 0。這個例子說明「簡單清楚」不是禁止技巧,而是:技巧必須被命名並解釋,讓讀者不必重新發明它。真正要避免的是無名的聰明——在業務程式碼中間突然出現一段需要五分鐘才能看懂的運算式。
★ 「先對,再清楚,再快」的實際流程
| 階段 | 做什麼 | 完成標準 |
|---|---|---|
| 1. 對 | 最直接的寫法,先有測試 | 測試通過 |
| 2. 清楚 | 命名、拆函式、刪多餘的東西 | 同事不需要你解說就能讀懂 |
| 3. 量 | 在真實規模的輸入上量:Go 用 go test -bench + pprof;線上用 profile | 知道時間花在哪裡 |
| 4. 快(只改熱點) | 只改 profile 裡排前幾名的函式 | 量到的數字真的變好,且還看得懂 |
第 3 步不能跳:直覺猜的瓶頸大多是錯的。Go 內建的工具讓這一步幾乎零成本——go test -bench=. -cpuprofile=cpu.out 然後 go tool pprof -top cpu.out。
★ Go 語言本身就是這條原則的產物
Go 刻意拿掉很多「聰明」的語法(沒有三元運算子、沒有運算子多載、泛型晚了十幾年才加且刻意受限),代價是有時要多寫幾行,換到的是任何人寫的 Go 讀起來都差不多。在 Go 裡追求「最短的寫法」通常是逆著語言設計走。
★ 「除錯比寫程式難」的推論
這句話的完整推論(Kernighan 的說法)是:如果你寫程式時已經用上了你全部的聰明才智,那你就沒有足夠的聰明去除錯它。實務意義:
- 寫程式時保留腦力餘裕,給半年後凌晨三點被叫起來的自己。
- 程式碼被讀的次數遠多於被寫的次數,最佳化的對象應該是讀者。
🧪 我實際套用的紀錄
- 2026-07-14:(待填)
⚠️ 注意
-
「簡單」指認知簡單,不是偷懶少做該做的驗證。
-
簡單 ≠ 容易:「簡單」是指概念少、交纏少;「容易」是指對我來說熟悉、上手快。引入一個大家都熟悉的大型框架可能很「容易」,但一點也不「簡單」——它帶進了你看不見的大量交纏。
-
簡單的方案常常比較難想出來:第一個想到的往往是複雜的版本;多花時間在設計上,才能把它削到簡單。
🔗 相關工具
- 工具-管理複雜度 —— 上位準則,簡單清楚是它最直接的操作化版本
- 工具-介面設計原則 —— 落到 API 這一層:露出什麼、藏什麼決定了使用者眼中的簡單程度
- 工具-Go可讀性五原則 —— Go 風格指南的具體排序:清楚 > 簡潔 > 簡單 > 可維護 > 一致,以及「最少機制」的升級階梯