程序員不得不讀的書前二就是
《程序員修煉之道》和《代碼大全》
大學時曾讀過《程序員修煉之道》,最近換工作轉正答辯前要求重新讀此書
以下是精華提煉,和個人總結
(一)注重實效的哲學
對於我們的缺點—還有我們的無知和我們的錯誤—我們必須誠實
正確認識已經發生的錯誤,對自己的職業生涯負責。對於已經發生的錯誤,重要的是如何處理來挽回局面,這樣也可以贏得別人的幫助
正確認識已經發生的錯誤,對自己的職業生涯負責。對於已經發生的錯誤,重要的是如何處理來挽回局面,這樣也可以贏得別人的幫助
這點在接手項目的時候最爲明顯。往往好的項目讓人不忍心去破壞其中完美的邏輯和美好的語言。一旦自己開始利用混亂的邏輯和糟糕的代碼,往後的編碼質量往往直線下滑。
做變化的催化劑;記住大圖景
拖延,規範,要時刻提醒。設計出合理的東西,然後拿出他,這就是石頭。
使質量成爲需求問題
質量一般都是隱含的需求。但也不要過分追求質量而停止腳步。停滯的結果往往就是自己都失去耐心。
定期爲你的知識資產投資
你說什麼和你怎麼說同樣重要
多問,多說。態度很重要。
(二)注重實效的途徑
DRY—Don’t Repeat Yourself 不要重複你自己;讓複用變得容易
代碼的重複,往往是由於經受不住誘惑而直接拷貝。抽取是一個好辦法,抽取與重構應該自主的進行。結合上一章, 想清楚哪些以後可以重複使用,或者在工作完成之後對代碼進行重構抽取出可以重複利用的部分。當然,這些都需要一定的功力。做好設計。
開發者的重複往往是由於相互之間缺乏溝通,但目前來看貌似在項目管理軟件下,這種情況發生的比較少,往往在共同修改某些小功能上容易發生。
消除無關事物之間的影響
其實主要說的就是減少模塊之間的耦合性。包括在設計的時候,選擇技術的時候。目前各種框架的使用很好的減少了前臺與後端之間的耦合性,但在工作中仍舊會發現某些代碼之間嵌套的很死,耦合性很差。注意保持解耦,減少全局變量,並寫好相關文檔。
另外在做習題的時候發現面向對象由於多態,繼承等不同於面向過程語言的一些特性,似乎更容易發生耦合現象。這個tip還需要在以後工作中持續思考。
不存在最終決策
這個tip是個啓發。沒有最終決策不等同於可以隨意改變最初的需求文檔。需求一旦定死即可不更改,但實現的方式可以是多種多樣,在實現過程中尋求最優,或者最便利(有時往往不是最優)的解決方案,應該在項目開發生命週期中持續進行。這應該就是同事說的“工作方法”。當然其中也應該包括程序員的自尊心,即便是做統計數據用in也不要圖方便用union all(笑)。
用光彈找到目標
這裏說說的應該是前期的一些實驗代碼,實驗後有可能廢棄,也可能融合在項目中保存生命力。一些小的實驗代碼往往可以尋求問題的解決之道,這裏不要怕浪費時間,但相反也不要進入拿起來就做的狀態,防止陷入做了那麼多才發現自己做錯了的狀態。
爲了學習而製作原型
這裏並沒有什麼體會。不知道在原有項目基礎上進行重新架構的項目算不算。記下來以後再看。
靠近問題領域編程
估算,以避免發生意外
這裏給出一種估算的簡單方式。建模,分割作爲組件,給各個參數指定值,計算,驗證。我認爲這裏是提出了一種估算項目進度的訓練方式。
在被要求進行估算時說什麼:我等會兒回答你
(三)基本工具
選擇領域內的某一個ide,學會所有功能和快捷鍵,熟練掌握,並樂於潮語IDE所世家的各種限制
用純文本保存知識
任何語言都可以操作純文本,
使用純文本(可以是.md) 可以在任何平臺上展示
利用shell 的力量
熟練掌握各平臺終端命令,熟練掌握git命令
命令行往往比gui強大,雖然平時可以使用gui,但是gui不可能給出所有使用場景,所以建議必須精通命令
用好一種編譯器
vs code 與idea
注意
- 可拓展性
- 可配置性
- 可編程 可運行
統一IDEA與格式化規則
進步遠非由變化組成,而是取決於好記性,不能記住過去的人,被判重複過去
記住合理使用UNDO 和 TODO
總是使用源碼控制
一次項目開發最好一次提交記錄(rebase)這樣以後排查錯誤,以及查看開發書會比較簡潔
要修正問題而不是發出指責
bug是誰的不是最重要的,最重要的是爲什麼會出現,察覺潛在隱患時爲什麼沒有重視,
不要恐慌
-
恐慌會讓你找不到bug原因(實戰有遇到)
-
解決bug的第一要素:復現bug。越容易復現的bug,越好修復
-
詳細陳述涉及bug的相關邏輯,或許原因就在你的話裏
不要假定,要證明
學會一種文本操縱語言
編寫能編寫代碼的代碼生成器
用來解決固定且簡單重複的場景
- 動態sql查詢器?
(四)注重實效的偏執
你不可能寫出完美的軟件
沒有人能寫出完美的軟件
通過合約進行設計
DBC 按合約設計
死程序不會說謊
如果有一個常見錯誤,意味着可能有很多錯誤。
如果它不可能發生,用斷言確保它不會發生
如果它不可能發生,用斷言確保它不會發生
將異常用於異常問題
要有始有終
使用資源時用完就要換,有一個有始有終的過程
(五)彎曲或折斷
保持靈活的一種辦法是儘可能保持代碼精簡
使模塊之間的耦合減少至最低
函數的得墨忒法則
- 每個單元對於其他的單元只能擁有有限的知識:只是與當前單元緊密聯繫的單元;
- 每個單元只能和它的朋友交談:不能和陌生單元交談;
- 只和自己直接的朋友交談。
要配置不要集成
儘可能保證程序可配置,即使開發時沒有配置需求,也需要可配置需求,可以使用程序開頭變量配置,其次可以使用運營平臺配置。
將抽象放進代碼裏,細節放在元數據裏
元數據是關於數據的數據,元數據是任何對應用進行描述的數據—應用該怎樣運行、它應該使用什麼資源
(Put Abstractions in Code, Details in Metadata) 爲一般情況編程,將細節放在被編譯的代碼庫之外。
分層思想,分層設計
分析工作流,以改善併發性:
(Analyze Workflow to Improve Concurrency) 利用你的用戶的工作流中的併發性。
用服務進行設計:
(Design Using Services) 根據服務——獨立的、在良好定義、一致的接口之後的併發對象——進行設計。
總是爲併發進行設計:
(Always Design for Concurrency) 容許併發,你將會設計出更整潔、具有更少假定的接口。
視圖與模型分離:
(Separate Views form Models) 要根據模型和視圖設計你的應用,從而以低廉的代碼獲取靈活性。
用黑板協調工作流:
(Use Blackboards to Coordinate Workflow) 用黑板協調完成不同的事實和因素,同時又使各參與方保持獨立和隔離。
(六)當你編碼時
不要靠巧合編程:
(Don’t Program by Coincidence) 只依靠可靠的事物。注意偶發的複雜性,不要把幸運的巧合與有目的的計劃混爲一談。
估計你的算法的階:
(Estimate the Order of Your Algorithms) 在你編寫代碼之前,先大致估算事情需要多長時間
測試你的估計:
(Test your Estimates) 對算法的數學分析並不會告訴你每一件事情。在你的代碼的目標環境中測定他的速度。
早重構,常重構:
(Refactor Early, Refactor Often) 就和你會在花園裏除草、並重新佈置一樣,在需要時對代碼進行重寫、重做和重新架構。要剷除問題的根源。
爲測試而設計:
(Design to Test) 在你還沒有編寫代碼時就還是思考測試問題。
測試你的軟件,否則你的用戶就得測試:
(Test Your Software, or Your Users Will) 無情地測試。不要讓你的用戶爲你查找bug。
不要使用你不理解的嚮導代碼:
(Don’t Use Wizard Code You Don’t Understand) 嚮導代碼可以生成大量代碼。在你把它們合併進你的項目之前,確保你理解全部這些代碼。
(七)在項目開始之前
不要蒐集需求——挖掘它們:
(Don’t Gather Requirements – Dig for Them) 需求很少存在於表面上。它們深深地埋藏在層層假定、誤解和政治手段下面。
與用戶一同工作,像用戶一樣思考:
(Work with a User to Think Like a User) 要了解系統實際上將如何被使用,這是最好的方法。
抽象比細節活得更長久:
(Abstractions Live Longer than Details) “投資”於抽象,而不是現實。抽象能在來自不同的現實和新技術的變化的“攻擊”之下存活下去。
使用項目詞彙表:
(Use a Project Glossary) 創建並維護項目中使用的專用術語和詞彙的單一信息源。
不要在盒子外面思考——要找到盒子:
(Don’t Think Outside the Box – Find the Box) 在遇到不可能解決的問題時,要確定真正的約束。問問你自己:“它必須以這種方式完成嗎?它真的必須完成嗎?”
等你準備好在開始:
(Start When You’re Ready) 你的一生都在積累經驗。不要忽視反覆出現的疑慮。
對有些事情“做”勝於“描述”:
(Some Things are Better Done than Described) 不要掉進規範的旋渦——在某個時刻,你需要開始編碼。
不要做形式方法的奴隸:
(Don’t Be a Slave to Formal Methods) 如果你沒有把某項技術放進你的開發實踐和能力的語境中,不要盲目地採用它。
昂貴的工具不一定能製作出更好的設計:
(Costly Tools Don’t produce Better Designs) 小心供應商的炒作,行業教條、以及價格標籤的誘惑。要根據工具的價值判斷它們。
(八)注重實效的項目
圍繞功能組織團隊:
(Organize Teams Around Functionality) 不要把設計師與編碼員分開,也不要把測試員與數據建模員分開。按照你構建代碼的方式構建團隊。
個人總結
不要按照單純的前端後端,測試UI進行團隊劃分,而是按照項目和產品線進行劃分
不要使用手工流程:
(Don’t Use Manual Procedures) Shell腳本或批文件會一次次地以同一順序執行同樣的指令。
個人總結
儘量藉助工具去完成流程,輔助開發工具總是需要以銷量爲第一要義
早測試,常測試,自動測試
(Test Early. Test Often. Test Automatically) 與呆在書架上的測試計劃相比,每次構建時運行的測試要有效的多。
個人總結
個人開發中,整合單個功能測試+模塊測試+集成測試,一切以運行起來的程序測試爲準
要通過全部測試,編碼纔算完成:
(Coding didn’t Done Until All the Tests Run) 就是這樣。
個人總結
只有預期開發的要求全部測試通過,整個編碼過程纔算完成
通過“蓄意破壞”測試你的測試:
(Use Saboteurs to Test Your Testing) 在單獨的軟件副本上故意引用bug,以檢驗測試能夠抓住它們。
測試狀態覆蓋,而不是代碼覆蓋:
(Test State Coverage, Not Code Coverage) 確定並測試重要的程序狀態。只是測試代碼行是不夠的。
一個bug只抓一次:
(Find Bugs Once) 一旦測試員找到一個bug,這應該是測試員最後一次找到它。此後自動測試應該對應其進行檢查。
英語就是一種編程語言:
(English is Just a Programming Language) 像你編寫代碼一樣編寫文檔:遵守DIY原則、使用原數據、MVC、自動生成,等等。
把文檔建在裏面,不要拴在外面:
(Build Documentation In, Don’t Bolt It On) 與代碼分離的文檔不太可能被修整和更新。
溫和地超出用戶的期望:
(Gently Exceed Your Users’ Expectations) 要理解你的用戶的期望,然後給他們的東西要多那麼一點。
在你的作品上簽名:
(Sign Your Work) 過去時代的手工藝人爲能在他們的作品上簽名而自豪。一夜應該如此。