第 8 / 11 部 待錄

當您寫程式時上-直覺與刻意

《The Pragmatic Programmer 務實的程式設計師》Podcast 準備稿:當您寫程式時(上)直覺與刻意

書名: 務實的程式設計師 The Pragmatic Programmer(Your Journey to Mastery, 20th Anniversary Edition) 作者: David Thomas & Andrew Hunt 系列: 啃一本大書(恩普拉氏) 公開標題建議: 啃一本大書|The Pragmatic Programmer.聆聽蜥蜴腦、別靠巧合寫程式、及早重構 (8/11) 涵蓋範圍: 第7章 當您寫程式時(上)Topic 37-40:聆聽您的蜥蜴腦、靠巧合寫程式、演算法速度、重構

背景速覽

第七章是全書最厚的一章,所以拆成上下兩集。開場作者就推翻一個傳統觀念:一旦專案進入「編碼階段」,工作就大多是機械性的——把設計翻譯成語句。作者認為這種態度正是軟體專案失敗的最大原因。編碼不是打字,每分鐘都有需要判斷的決策。這一集(上半)談「坐在鍵盤前最內在的功夫」:傾聽你的直覺、別讓程式靠運氣跑起來、用 Big-O 務實估算演算法、把重構當成每天的除草而非偶爾的大翻修。下半集(EP9)再談測試、安全與命名。

一句話重點

編碼是一連串需要判斷力的決策,不是機械翻譯——務實程式設計師會聆聽自己卡住時的不安(那是經驗在用沒有語言的方式說話)、拒絕靠巧合寫出「我不知道為什麼能跑」的程式、用 Big-O 務實(而非過早)地估算演算法、並把重構當成每天的小步除草,趁問題還小時就處理。

值得討論的重點

1. 聆聽你的蜥蜴腦:直覺是沒有語言的經驗

Tip 61「Listen to Your Inner Lizard」。本能是對模式的反應,儲存在非意識大腦裡——你的「蜥蜴腦」不斷累積隱性知識(哪些有效、哪類錯誤的可能原因)。它的共同特徵是沒有語言:本能讓你「感覺」而非「思考」,被觸發時你不會看到燈泡,而是感到緊張、不安、覺得「這工作量怎麼這麼大」。書講兩個典型情境:對空白頁的恐懼(新專案/新模組那個閃爍的游標——背後是蜥蜴腦在暗示某種懷疑,或單純怕犯錯、冒名頂替症候群)與跟自己搏鬥(編碼感覺像在泥巴裡爬坡時,別硬撐,那是 code 在告訴你「這比它該有的更難」——可能結構有問題、或你在解錯的問題)。怎麼跟蜥蜴對話?三招:先停下來(離開鍵盤、散步、睡一覺,讓想法自行滲透)、外化問題(畫圖、向同事或橡皮鴨解釋)、用原型突破僵局(貼張「我在做原型」的便利貼,提醒自己這是要丟的,幫大腦卸下壓力)。

2. 靠巧合寫程式:別當踩過地雷還繼續走的士兵

Tip 62「Don’t Program by Coincidence」。開場隱喻:黑白戰爭片裡的士兵用刺刀戳地、沒爆炸就前進,最後被炸碎——他的初探沒發現地雷只是運氣,卻得出了錯誤結論。我們每天也在地雷區工作。靠巧合寫程式的故事主角 Fred:加一段 code、好像能跑,再加一段、好像能跑,幾週後突然壞了卻修不好——因為他從頭就不知道它為什麼能跑。書拆解幾種陷阱:實作的意外(依賴了未記錄的行為、邊界條件、錯誤的呼叫順序——「它現在能用了,別動好了」)、差不多正確不等於正確(那個著名的災難:硬體單元時區衝突導致結果總是差一,開發者養成到處 +1/-1 的習慣,最後整個 codebase 充斥不正確的 +1/-1,專案報廢)、幻想的模式(人天生在巧合裡看到因果,每千次請求一次的錯誤可能是競態、可能是 bug、也可能只是巧合——不要假設,要證明)、上下文的意外(貨物崇拜 code:從網路抄第一個答案,你確定上下文一樣嗎?)。解方是刻意編程:永遠清楚你在做什麼、能向初級工程師解釋、不在黑暗中編碼、只依賴可靠的東西、記錄並測試你的假設(用合約 + 斷言,呼應 EP5)。

3. 演算法速度:用 Big-O 務實估算,但別過早最佳化

Tip 63「Estimate the Order of Your Algorithms」、Tip 64「Test Your Estimates」。這是務實程式設計師幾乎每天用的估算:演算法消耗的時間/記憶體。你知道 1,000 筆跑得順,但 1,000,000 筆呢?Big-O 是近似的上界——它不給你實際數字,只告訴你「輸入變大時成本怎麼長」(O(n^2) 代表輸入翻倍、時間約變四倍)。用常識就能估很多:簡單迴圈 O(n)、巢狀迴圈 O(n^2)、二分搜尋 O(log n)、排序 O(n log n)。但兩個務實的煞車很關鍵:最快不一定最好(小資料集上插入排序可能跟 Quicksort 一樣快、還更好寫好除錯;也要注意演算法的設置成本,小輸入時設置可能主宰執行時間)、以及那句不朽的警告——警惕過早最佳化(premature optimization),先用 profiler 確認某段真的是瓶頸,再投入時間去改它。

4. 重構:軟體是園藝不是建築,每天除草

Tip 65「Refactor Early, Refactor Often」。最該打破的迷思是「軟體像建築施工」——其實軟體更像園藝:有機的、會長雜草、需要修剪、不斷監控健康狀態並調整。引 Martin Fowler 對重構的定義:「一種有紀律的技術,在不改變外部行為的前提下,重組現有 code 的內部結構。」兩個關鍵:它是有紀律的(不是隨意亂改)、不改外部行為(不是加功能的時候)。重構不該是一次性大翻修,而是日常活動——低風險的小步,像除草耙地,不是把整座花園翻掉。觸發時機:發現重複(違反 DRY)、非正交設計、過時的知識(需求漂移、理解加深)、實際使用顯示某功能比預想重要、效能、測試剛通過(潛入整理一下剛寫的東西的好時機)。對抗「沒時間重構」的藉口,作者給了犀利的醫學比喻:把要重構的 code 想成腫瘤——趁小切除,或等它長大擴散到切除更貴更危險、甚至失去整個病人。Fowler 的三條操作建議:別同時重構和加功能、開始前先有好測試(頻繁跑)、採取短小刻意的步驟(每步後測試)。

注意事項

⚠️ 「聆聽蜥蜴腦」別講成「跟著感覺走、憑直覺亂寫」。作者的意思恰好相反——直覺是訊號,不是答案:當你感到不安,那是提醒你「停下來分析」,把無語言的感覺「結晶」成具體可處理的問題。直覺負責喊「這裡怪怪的」,理性負責查清楚為什麼。

⚠️ Big-O 那節別讓聽眾走向另一個極端——「為了 O 漂亮而過度設計」。作者明確警告過早最佳化,並強調「最快不一定最好」。Big-O 是用來在「資料量真的會大」時做出有根據的選擇,不是拿來炫技或在小資料集上自找麻煩。

專家補充

💡 「聆聽蜥蜴腦」其實是 Daniel Kahneman《Thinking, Fast and Slow》系統一(快、直覺)/系統二(慢、理性)的工程版。資深工程師的「code smell 雷達」正是系統一——多年經驗壓縮成的快速模式辨識。本書的高明在於:它不叫你只信直覺,而是教你用直覺當「該啟動系統二」的觸發器。專家的價值,一半在於知道「什麼時候該停下來認真想」。

💡 「過早最佳化是萬惡之源(premature optimization is the root of all evil)」這句常被歸給 Donald Knuth(原話更完整:「我們應該忘記小效率,約 97% 的時間;過早最佳化是萬惡之源」)。本書把它收進來,與「先 profile 再優化」一起,構成務實的效能觀——這條與《Clean Code》、《A Philosophy of Software Design》完全一致:可讀性優先,效能等量測證明有瓶頸再說。

💡 「軟體是園藝不是建築」是本書貢獻給軟體思想史的重要隱喻之一。建築隱喻(藍圖、地基、施工)暗示「一次規劃好就定型」,誤導了整個瀑布式年代;園藝隱喻(有機、修剪、持續照料)才符合軟體會持續演化的本質。這條與第一章「軟體的熵/腐敗」(EP1)首尾呼應——熵講「不照料會腐敗」,重構講「怎麼持續照料」。

討論問題

🎙️ 開場鉤子:「你有沒有過這種經驗——一段 code 你不知道為什麼能跑,但它就是跑起來了,於是你不敢碰它?那不是程式在幫你,那是你踩過了一顆沒爆的地雷。這集講的是怎麼從『碰運氣』變成『刻意』。」

🎙️ 自問自答:「卡住的時候,該硬撐還是該停?」——本書的答案是停。當編碼感覺像在泥巴裡爬坡,那不是你不夠努力,是你的 code 在用沒有語言的方式告訴你『這比它該有的更難』——可能結構錯了、可能你在解錯的問題。停下來、外化它、做個原型,往往比硬幹快得多。

🎙️ 帶走的一題:「挑一段你『不太敢動』的 code——逼自己向一個想像中的初級工程師完整解釋它每一行為什麼這樣寫。如果你解釋不出來,你剛找到一段靠巧合活著的程式碼。」

更大範圍關聯

  • 與三經典:重構直接引用 Martin Fowler《Refactoring》的定義與操作步驟——本書給「為什麼/何時」,Fowler 給「怎麼做」的完整目錄,兩本是天作之合。「刻意編程」與《Clean Code》「程式碼要能表達意圖」同源。
  • 認知科學背景:聆聽蜥蜴腦接 Kahneman 的雙系統理論、Gary Klein 的「直覺即專業判斷」研究、以及《The Gift of Fear》(書中引言出處)。
  • 效能觀:Big-O + 過早最佳化接 Knuth、《Programming Pearls》(Bentley);「先量測再優化」是與《A Philosophy of Software Design》一致的工程共識。
  • 首尾呼應:重構回扣第一章「軟體的熵/破窗」(EP1)與第二章「可逆性/設計可替換的 code」(EP2/EP5)——熵是病,重構是日常的免疫系統。

錄製建議

  • 建議時長:約 24-26 分鐘。配比:聆聽蜥蜴腦約 7 分(空白頁恐懼、跟自己搏鬥很有共鳴)、靠巧合寫程式約 8 分(士兵/Fred/差一災難都是好故事,主菜)、演算法速度約 4 分(Big-O + 過早最佳化兩個煞車)、重構約 6 分(園藝隱喻、腫瘤比喻是亮點)。
  • 討論策略:用「從碰運氣到刻意」這條主線——蜥蜴腦是『傾聽訊號』,靠巧合是『別假裝懂』,重構是『持續照料』,三者都在反對「機械式打字」這個迷思。把 Kahneman 雙系統、Knuth 過早最佳化、園藝隱喻這幾條思想史引線放進去,增加縱深。
  • 結尾預告 EP9「當您寫程式時(下)」——同一章的後半,談測試的真正意義(不是找 bug)、安全的基本原則、以及命名這門揭示意圖的功夫。