截取至:https://im1.book.com.tw/image/getImage?i=https://www.books.com.tw/img/001/085/63/0010856354.jpg&v=5e9ecb36k&w=348&h=348

簡介:本書以1999年《The Pragmatic Programmer》初版修訂而成,添加了新的專題如敏捷開發、DevOps、容器和微服務等,書中以實用的方法論為特點,主張專注於解決問題,提倡自我學習和不斷改進,並提供了許多實用的技巧和工具幫助讀者在工作中更有效地編寫程式碼及團隊協作,以面對複雜的軟體開發挑戰。

心得:這是本關於做(doing)的書,書中提及作為一個務實的程式設計師,早期採用/快速適應、好奇、批判性思考、現實主義、萬事通為共通點,並時常思考自己在做什麼,對每一次下的決策進行批判性評估。作為剛入門軟體開發一年多工作經驗的小白,書中的觀念及建議使我重新檢視這一年來撰寫的程式碼及合作的專案是否有達到業界的標準,並反思在溝通合作上及開發上有無可以精進的方面,尤其是在緊迫的時間壓力下如何不斷地測試及優化軟體並順暢的和客戶、同事、PM及主管溝通,期許自己成為問題解決者而不僅是軟體開發人員。

ChatGPT心得:《The Pragmatic Programmer》是一本經典的程式設計指南,由Andy Hunt和Dave Thomas所著,至今已經推出20週年紀念版。本書精選了40篇經典文章,涵蓋了程式設計、軟體工程、專案管理等議題。作者以實用主義的觀點,給予讀者實用的建議和技巧,幫助他們成為出色的軟體工程師。其中,本書最著名的觀點是「精益軟體開發」,即在不斷地測試、優化、改進的過程中,不斷提高軟體的品質。作者提醒我們,在快速變化的軟體產業中,唯有不斷學習和改進,才能保持競爭力。此外,本書還教導我們如何寫出高品質的軟體程式,並且如何在團隊合作中取得成功。作者建議我們應該建立良好的程式碼標準、制定合理的專案計劃、建立高效的溝通渠道,以及懂得如何與客戶建立良好的關係。總的來說,《The Pragmatic Programmer》是一本值得擁有的軟體工程指南。無論是初學者還是資深工程師,都能從本書中獲益良多。

關於程式設計的兩三句話…

  1. 程序員的責任不僅僅是寫出可以工作的代碼,更重要的是要寫出易於維護、易於理解、易於擴展的代碼。
  2. 過早地優化是萬惡之源。在你知道哪些部分是瓶頸之前,不要嘗試進行優化。
  3. 用“刻意練習”來提高自己的技能。學習新技能的過程中,不斷重覆練習和實踐,直到變得自然而然。
  4. 不要依賴於工具來解決問題。工具只是輔助手段,你需要理解底層原理和概念,才能真正掌握技能。
  5. 保持簡單,避免過度設計。最好的設計是能夠應對需求變化的設計。
  6. 要做好錯誤處理,不要忽略錯誤。一個好的程序應該能夠正確地處理各種異常情況,並提供友好的錯誤提示。
  7. 與團隊成員保持溝通和合作,分享知識和經驗。每個人都有自己的專長和弱點,通過合作,可以取長補短,共同進步。
  8. 要保持開放的心態,接受批評和反饋,並從中吸取教訓。學習是一個不斷叠代的過程,你需要不斷反思和改進自己的做法。
  9. 編寫文檔是一項必要的工作,不要將其視為額外負擔。好的文檔可以提高代碼的可讀性和可維護性,降低溝通成本。
  10. 不要害怕失敗,不要放棄嘗試。只有通過不斷嘗試和學習,才能不斷提升自己的能力和水平。
  11. 定期投資知識資產,其建議獲取方式:每年至少學一門新語言、每個月讀一本技術書、閱讀非技術類書籍、上課、參與本地使用者群組或會議、體驗不同的環境、了解目前技術發展。
  12. 不要放任『破窗』(糟糕的設計/程式碼/決策)壞在那裡不修。
  13. 啟動疲勞(start-up fatigue):確切知道需要做什麼及如何去做,但是請求處理事情時,人們傾向成立委員會並保護自己的資源。
  14. 溝通的意義就是得到回應。
  15. ETC原則:更容易改變-單一責任原則、低耦合和內聚性。
  16. DRY原則-不要重複:在一個系統中,每一條知識都必須有一個單一的、明確的、權威的表達。
  17. DRY(知識和意圖上的重複)的辨識方法:當修改一處程式碼時,是否同時需要修改其他多個地方?分別修改程式碼、文件、資料庫模式和結構?
  18. 當被問到評估時,請說:我稍後會告訴您;花時間檢查要求、分析風險、設計實作整合與驗證。
  19. 計畫評核術:每個任務都有一個樂觀的、一個最有可能的和一個悲觀的評估。
  20. 除錯策略:複製錯誤、二元切分(divide and conquer)、log和trace、黃色小鴨、排除法。
  21. 正交性:其中一個的變化不影響其他任何一個,則兩個或多個事物是正交的,資料庫程式碼與使用者介面是正交的。
  22. 合約式設計:前置條件、後置條件、類別不變量。
  23. 使用assertion避免不可能發生的事、由取得資源的人負責釋放資源。
  24. 撰寫保持正交性的程式碼:去耦合、避免全域資料、避免相似的功能。
  25. 原型生成的程式碼是用完即丟的,而曳光彈程式碼簡單但完整,也是最終系統的一部分。
  26. 不要採取太大的任務:任何需要『算命』的任務,只為看見的未來進行設計。
  27. 直接命令,不要詢問:不應該根據物件內部狀態做出決策,然後才更新該物件,這樣破壞封裝的好處,改以下
    public void applyDiscount(customer, orderId, discount){
    totals=customer.orders.find(orderId).getTotals();
    totals.grandTotal = totals.grandTotal - discount;
    totals.discount = discount;
    }

    成為以下程式碼
    public void applyDiscount(customer, orderId, discount){
    customer.findOrder(orderId).applyDiscount(discount);
    }

    或是
    public void applyDiscount(customer, orderId){
    customer.applyDiscountToOrder(orderId);
    }
  28. 盡量不要串連呼叫方法:存取某個東西時,盡量不要使用超過一個「.」。
  29. 避免全域資料:全域資料就像為每個方法都加一個額外的參數,真要使用時,確保用API包起來。
  30. 撰寫“事件”類型的應用程式:有限狀態機、觀察者模式、發布/訂閱、回應式程式設計和串流
  31. finite state machine: 狀態機為處理事件的規範,對於每個狀態,我們列出該狀態有意義的事件並重新定義系統的目前狀態當事件發生時。
    state = transitions[state][msg.msg_type] || :error or state, action = transitions[state][ch] || transitions[state][:default]
  32. observer pattern: 事件源頭為可觀察物和一堆客戶端,觀察者對感興趣的事件向可觀察物註冊,通常將要呼叫的函式參照傳遞給可觀察物,以callback通知應用程式某些互動已發生。問題為耦合及『同步』產生的效能瓶頸。
  33. publish/subscribe: 這兩種角色透過通道(channel:抽象化來減少耦合)連接,而通道是在獨立的程式碼中實作的,將觀察者模式泛型化並解決耦合及效能問題,無法用來建立回應組合事件系統。
  34. reactive programming: 依靠串流(stream:非同步)組裝事件,可觀察物的填充動作具有平行執行的能力。
  35. 所有的程式都做著轉換資料的工作,將輸入轉換為輸出:不在轉換之間傳遞原始值,將他們封裝在一個資料結構或類型中,該結構告訴我們其內容值是否有效。
  36. 不要使用繼承:繼承就是一種耦合,使用介面和協定/委派/混合和特性來共享型態資訊、加入功能或共用方法。
  37. interface/protocol:表達多型關係且不耦合。
  38. delegation:包含服務,代價是需要寫更多的程式碼。
  39. mixin/trait/categorie/protocol extensions:合併現有及新內容,共享功能可使功能加到類別中。
  40. 將設定當成一種服務:將資訊包裝在一個API後面而非一般檔案或資料庫。
  41. 活動圖(activity diagram):分析工作流程以提升並行。
  42. 不要共用狀態:semaphore/mutex和互斥來控制資源的存取,參與者模型可達成不共用狀態的並行工作,因為參與者是根據收到的訊息各自解決問題。
  43. 如何重構:不要同時重構和添加新功能、良好的測試、簡短而慎重的步驟。
  44. 測試的目的不是為了要找出bug,以測試驅動程式碼撰寫(TDD)、回饋及第一個使用者,其好處體現在思考及撰寫時,而非執行:提供設計、api及耦合性的回饋(考慮測試邊界條件)。
  45. 用點到點而非自上而下或自下而上建構程式碼。
  46. 以屬性(合約和不變數)為基礎測試。
  47. 安全基本原則:最小化攻擊表面積(輸入取得資料或呼叫服務執行的所有存取點的加總)、最小權限原則、安全預設值、對敏感性資料加密、維護安全更新。
  48. 所謂的達到完美,並不是指再也無法加入任何東西,而是無法拿走任何東西。
  49. 需求是從回饋的循環中了解的,而政策是描述性資料,將整個專案的一切活動視為需求搜集活動。
  50. 需求文件不是給客戶看的而是為了計畫。
  51. agile是您做事的方式:個體間互動比流程及工具重要、能正常工作的軟體勝過複雜完整的文件、客戶協作勝過合約談判、回應變化而不是遵循計畫。
  52. 工具:版本控制(驅動建構和發布流程)、回歸測試(好專案的測試程式碼可能比產出的多:單元、整合、效能測試)、完全自動化。

上述喜愛的段落及句子皆節錄自:

書名:The Pragmatic Programmer 20週年紀念版
作者:David Thomas, Andrew Hunt
出版:碁峰