《程序員修煉之道》---- 修的是什麼

學習最好的方式,是有個好師傅。他根據你的不一樣階段,教導你不一樣的技能,按部就班;師傅不單教你練功,還會教你作人,使你內修於心,外化於形。教你的一些道理,你可能當時不太懂,但等你苦練多日,歷經曲折,終有一日茅塞頓開,再去學藝作事,事半功倍,大有精進; 有一個位好導師天然是得之我幸的事情,但實際工做中很可貴,也許有前輩們偶爾的點撥,有朋友的激勵,但最平實可靠的方法仍是來自於閱讀java

本書原名 "The Pragmatic Programmer",也就是「注重實效的程序員」。本書涵蓋了程序員成長過程當中和軟件開發過程當中須要注意的地方。兩位做者除了是程序員,Andy Hunt仍是一位木匠和音樂家,而Dave Thomas 則喜歡駕駛單引擎飛機。就兩位做者而言,編程和木匠活和音樂創造,或是駕駛飛機同樣,既須要稟賦,更須要堅持不懈的學習和訓練,也正如書中所說。編程是一種技藝,一種須要用心學習的技藝。----- 這本書將助你成爲更好的程序員。git

面對這份職業,你應如何開始?程序員

和程序員讀的絕大多數應用書籍不一樣的是,開篇給你講的就是態度。對待錯誤、不整潔的代碼、團隊協做以及學習。算法

"個人源碼讓貓給吃了。"數據庫

1.咱們爲咱們的能力自豪,但對於咱們的缺點---還有咱們的無知和咱們的錯誤---咱們必須誠實。

誰都會犯錯,最好方式是認可本身的錯誤,並給出可行的彌補方案。而不是找荒唐的藉口。編程

2.不要留着「破窗戶」(低劣的設計、錯誤決策、或上糟糕的代碼)不修。發現一個修一個。

而面對不整潔的代碼,就猶如破窗戶同樣。應該發現一個就修一個。這和咱們第一期讀的《代碼整潔之道》殊途同歸,壞代碼會污染環境,最後會壞掉整個項目。保持整潔的習慣,發現髒代碼就要及時糾正。架構

文中說了一個石頭湯的故事,幾個士兵用一鍋石頭,招呼村民各自出料,結果燉出了一鍋香噴噴的菜。而映射到生活中,大部分的項目都要經歷從0到1的過程,作好它就須要各方出力。雖然每一個人都會保衛本身的資源,但人們發現,參與正在發生的成功更容易,讓他們瞥見將來,你就能讓他們彙集在你周圍。讓我想起一句話:「若是你想造一艘船,不要鼓勵人們去伐木、去分配工做、去發號施令。你應該作的是,教會人們去渴望大海的寬廣無邊和高深莫測。——聖-埃克蘇佩裏」併發

 人們須要的是引導,而不是約束。而面對學習,面對日益變遷的技術呢?知識管理就如金融投資mvc

3.知識上的投資總能獲得最好的回報。你的知識和經驗是你最最重要的職業財富。遺憾的是,他們是有「時效的資產」隨着新技術、語言及環境的出現,你的知識會變的過期。

咱們喜歡把程序員所知道的關於計算機技術和他們所工做的應用領域的所有事實、以及他們的全部經驗視爲他們的知識資產。管理知識資產和管理金融資產很是類似:  編輯器

 1)嚴肅的投資者按期投資----做爲習慣。

     --按期爲你的知識資產投資。

 2)多元化是長期成功的關鍵

      --掌握的技術越多,越能進行調整。

 3)聰明的投資者在保守的資產和高風險、高回報的投資之間平衡他們的資產。

      -- 把全部金錢買入可能忽然崩盤的高風險股票不是一個好主意,也不要把全部的技術雞蛋放在一個籃子裏。

 4)投資者設法低買高賣,以得到最大回報。

     -- java剛出現時學習它可能有風險,但對於已經步入改領域頂尖者,已經取得了很是大的回報。

 5)應週期性的從新評估和平衡資產。

    -- 重溫學過的東西。

 做者給出三點建議:

  •  每一年至少學習一種新語言
  •  每季度閱讀一本技術書籍
  •  也要閱讀非技術書籍

有哪些能夠實踐?

思想上有了必定的認識,接下來怎麼作呢?

1.DRY(don't repeat yourself)原則:系統中的每一項知識都必須具備單1、無歧義、權威的表示。

避免重複的主要緣由是要減小維護的成本。文中的重複不只只代碼上的重複,還包括多餘的註釋、多餘的設計(屬性);鼓勵多閱讀別人的源碼與文檔,無論是正式的仍是非正式的,去學習,一樣也不要由於別人閱讀你的代碼而苦惱。

2.若是組件是相互隔離的,改變其中之一而沒必要擔憂其他的組件。編寫正交的系統能夠提升生產率和下降風險。

正交性在計算機中表示某種不相依賴性和解耦性。若是一個事物發生變化而不影響其餘事物,那麼這些事物就是正交的。正交的系統更容易測試,能促進複用;正交性的另外一個有趣的變體就是面向方面編程,也就是你們熟悉的(Aspect-Origin Programming)AOP;在項目團隊中,若是團隊的組織有許多重疊,每一次改動都會須要整個團隊開一次會,他們中的全部人都會受影響。這也是一個正交問題。

3.原型設計的目的就是回答一系列問題,與投入的使用的產品相比,它們的開發要便宜的多,快捷的多。原型製做是一種學習經驗。其價值不在於產生的代碼,而在於所學到的經驗教訓。

好比汽車製造商也許會製造一個粘土模型用於測試空氣風洞實驗,作一個輕木模型測試工藝。原型和曳光彈的區別是,原型代碼在使用完能夠丟掉。

4.太簡單的語言也許容易解析,但卻可能晦澀難懂,因此建議先就採用更復雜、可讀性更好的語言。最初的努力將在下降支持與維護費用方面獲得許多倍的回報。

越底層的語言效率越高,但也是越不容易理解。不光性能,時間是一個昂貴的成本。

工欲善其事必先利其器

1.工具放大你的才幹。你的工具越好,你掌握的越熟練,你的生產力越高。

比起了解多種開發工具(編輯器),你應該有一種很熟悉的,快捷鍵,命令行,會使用第三方插件等等。

2.工具是手的延伸,建議最好精通一種編輯器,好的編輯器應該是可配置、可擴展、可編程、自動縮進、類IDE

你可能想起那宇宙第一IDE,讓你麒麟臂隱隱發做。

3.若是你使用GUI完成全部的任務,你就會錯過你環境的某些能力。GUI的好處是所見即所得,缺點就是所見即所有所得。

不要太依賴於界面操做,記住一些經常使用的命令,很是有助於提升效率。

4.源碼控制的諸多好處之一,它是一個巨大的撤銷鍵。好的源碼控制系統能夠跟蹤變更,誰改動了這行代碼?版本之間的區別?哪一個文件改動的最頻繁。還能管理開發樹種的分支,好比有穩定版本,新功能版本,預發佈版本。

編碼不僅是一我的事情,也不僅是當下的事情,熟用一種源碼管理技術(git/svn)來記錄你的代碼。

5.要修正問題,而不是發出指責;要找到問題的根源,而不是問題的特定表現

咱們都曾會遇到相似這樣的對話:A:「xx出問題了」,B:"我電腦上沒問題啊"... ,bug是你的過錯仍是別人的過錯,並非真的頗有關係。它仍然是你的問題。調試的時候可能遇到抵賴、推諉、撇腳的藉口、甚至是無動於衷,這就回到了第一章第一節的態度問題,要接受事實:調試就是要解決問題。調試須要思考的問題

  • 正在報告的問題是底層bug的直接結果,仍是隻是症狀?
  • bug的位置在哪?是你代碼的問題,仍是調用的組件有問題。
  • 你如何向同事詳細解釋這個問題?
  • 若是可疑代碼經過了單元測試,測試是否足夠完整?
  • 形成bug的這個條件是否還存在系統的其餘地方?
6.編寫能編寫代碼的代碼

木匠面臨重複製造同樣東西的任務時,他們會取巧,製做夾具或模板,這樣就能夠反複製做某樣工件。夾具帶走了複雜性,下降了出錯的機會,從而讓工匠更自由的專一質量問題。一樣,合適的是你可使用代碼生成器增長你的威力。

更上一層樓

1.與計算機系統打交道很困難,與人打交道更困難,咱們花費在弄清楚人們的交往問題上的時間更長;確保雙方坦率的最佳方案就是合約。合約規定了你的權利和責任,也規定對方的權利和責任。此外還有關任何一方沒有遵照合約的後果的約定。

按合約設計,用文檔記載程序的聲明,並進行校驗軟件中的每個函數或方法都會作某件事情,開始和結束都須要知足必定的條件,繼承和多態是面嚮對象語言的基石,是合約能夠真正閃耀的領域

2.有許多時候,讓程序崩潰是你的最佳選擇,而不是繞過繼續執行、甚至把壞數據寫入到某個重要的數據庫。

死程序不說謊。JAVA或者C#的異常若是沒有捕捉,就會滲透到程序頂部,直到程序終止並顯示堆棧信息。死程序帶來的危害要比帶有疾患的程序小得多。

3.異常不多應該做爲程序的正常流程的一部分使用;異常應該保留給意外事件。

例如,若是你用代碼試圖讀取一個文件,而文件不存在,應該引起異常嗎? 這要看實際狀況,若是文件應該在那裏(重要配置文件),那麼異常就應該發生--某件意外之事發生了。另外一方面若是你不清楚文件是否存在,那麼你找不到這個文件就不算異常狀況,返回錯誤提示就是合適的。

4.只要在編程,咱們都要管理資源:內存、事務、線程、文件、定時器--全部數量有限的事物。許多開發者對資源的分配和解除沒有一個計劃。

寫代碼要善始善終:好比文件的讀取,每一次的打開都有對應的關閉。對於一次不止須要一個資源的程序,要有與資源分配次序相反的次序解除資源分配;不一樣的地方引用同一組資源時要按照一樣的順序(好比A申請了resource1,正申請resource2,而B申請了resource2,正申請resource1,那麼這兩個進程會永遠的等下去);在異常處理中,確保程序退出前要釋放資源。JAVA或者C#中的finally塊使得咱們在異常發生時總能作一些處理;另外對資源的使用狀況進行檢查也是個好注意。

5.建立靈活代碼的一個關鍵概念是數據模型(model)與該模型的視圖(view即表現)的分離。

有許多沒必要要依賴關係的系統很是難維護(並且很是昂貴),每每高度不穩定。要使模塊直接的耦合減至最少。但解耦也是有代價的,在實踐中有時候須要編寫大量包裝方法,只是把請求轉發給被委託者,這些方法會帶來運行時代價。因此也會有折中,經過反其道而行之,使模塊緊耦合來換取性能的改進。因此不要爲了解耦而解耦,要平衡。

6.大多數人的思考方式都是線性的,先作A再作B,這樣就帶來了時間上的耦合,咱們須要考慮併發,並解除任什麼時候間上或次序上的依賴,這樣就能得到靈活性。

在設計時就考慮了併發,能夠更容易的知足可伸縮性或性能需求。

7.元數據是關於數據的數據。是任何對應用進行描述的數據

Asp.net mvc中的模型元數據(modelmetadata)就是一個很好的例子.元數據是用於作高度可配置的系統,諸如算法、數據庫產品、中間件技術和用戶界面風格等做爲配置選項,而不是經過集成或工程實現。

當你編碼時...

工做若是隻是機械的把設計轉換成可執行語句,這種態度是許多程序醜陋、低效、結構糟糕、不可維護和徹底錯誤的最大的一個緣由。

1.學會估算本身算法的時間,並找到合適的算法。好比集合很小時,直接的插入排序的性能將和快速排序同樣好,而你編碼和調試時間將更少。

根據算法的複雜度能夠估算開銷的時間。好比一些常見算法,簡單循環:極可能就是O(n) 時間隨着n線性增長;嵌套循環:若是在循環中嵌套了另外的循環,算法的複雜度就是O(m*n),也就是O(n^2);二分法:你的算法在每次循環的時候把事物一分爲二,那麼複雜度就是對數型O(log(n));分而治之:劃分輸入,並獨立的在兩個部分上進行處理,而後把結果組合起來的算法極可能是O(nln(n));組合:只要算法考慮到事物的排列,其運行時間可能失去控制。若是涉及到階乘,5!=120。

2.重寫、重作和從新架構代碼合起來,稱爲重構。

出現下面的特徵,你就應該考慮重構代碼:

  • 重複,你發現違反了DRY原則
  • 非正交的設計(一個模塊改動會影響另外的模塊)。
  • 過期的知識,事情變了,需求轉移了,你對問題的理解加深了。代碼須要跟上這些變化。
  • 性能。爲改善性能,你必須把功能從系統的一個區域移到另外一個區域。
3.測試你的軟件,不然你的用戶就得測試。測試是技術,但更是文化。無論用什麼語言,儘可能讓這樣的文化滲入到項目中。

編寫易於測試的代碼,並不要依賴於測試人員來測試。代碼交出去或提交以前要確保它是ok的。

談談項目和需求

你是否有過你的項目註定要失敗的感受,也許你如今能夠建議結束它,而且爲出資人省下一些錢。

1.挖掘需求的時候,要找出用戶爲什麼作特定事的緣由、而不僅是他們目前作這件事的方式。你的開發必須解決他們的商業問題,而不僅是知足他們陳述的需求。
2.成爲產品的用戶。與用戶同樣工做,同樣思考。

咱們很容易被吸進「只是再增長一個特性」的巨大漩渦,每每需求方變了又變。但咱們工做的最終目的是把事情作成,而不僅是把代碼敲完。要理解需求,理解用戶,纔會作出好的產品。

3.不要在盒子外面思考,而是要找到盒子。

有時候項目設計沒有頭緒,或者是發覺代碼難以編寫,或者問題看起來沒法解決。而這裏的‘盒子’指的是各類約束和條件的邊界,而解開謎題的關鍵就在於肯定加給你的各類約束,而且肯定你擁有的自由度,這樣你纔會在其中找到解決方案。

4.不要作形式方法的奴隸。

咱們喜歡有些技術和方法,但咱們相信,盲目地採用任何技術,而不把它放進你的開發實踐和能力環境中,這樣的處理方法確定會讓你失望。

記住,注重實效

1.質量是一個團隊問題,最勤勉的開發者若是派到不在意質量的團隊裏,他也很難保持修正瑣碎問題的熱情。團隊做爲一個總體,不該該容忍破窗戶(小小的,無人修正的不完美),必須爲產品的質量負責。

產品的質量就是團隊的招牌。

2.人工流程不能保證一致性,也沒法保證可重複性。

推進團隊內部的自動化,好比項目編譯是一件應該可靠、可重複地進行的瑣碎工做,.net下可使用ccnet。寫程序的不要讓程序所累。善用工具或者本身開發工具,採用自動化方案。

3.尋找bug就像是結網捕魚,咱們用纖細的小網(單元測試)捕捉小魚,用粗大的網(集成測試)捕捉吃人的鯊魚。有時候魚會設法逃跑,因此爲了抓住項目池塘裏遊動的,愈來愈狡猾的魚,要補上任何發現的漏洞

這個比喻好。測試分爲三個方面,測試什麼、怎樣測試以及什麼時候測試。

4.設法將文檔製做成在線發佈的形式,這樣讓讀者能夠了解到哪些內容是最新的、哪些是更改過的。

相似於javaDoc和DOC++這樣的工具,能夠根據源碼生成API級別的文檔。文檔和代碼是同一底層模型的不一樣視圖,不要讓文檔變成二等公民。.net中能夠用sandcastle根據xml註釋生成文檔,也能夠打形成在線的方式。文檔作好了,是一個前人栽樹後人乘涼的舉措。

5.項目的成功是由它在多大的程度上知足了用戶的指望來衡量的。用戶一開始就會帶着對他們所需東西的想象來到你面前,那可能不完整、不一致或者是在技術上不可能作到。但就像過聖誕節的小孩同樣,他們投入了一些感情,你不能簡單的忽視它。

後面的章節儼然已經上升到項目經理的視角,雖然只是做爲團隊中的一員,擁有這些意識才是好的團隊意識,而不是簡單我很好說話就表明別人能和我合做愉快。

6.鼓勵在本身的做品上簽名,「這是我編寫的,我對本身的工做負責。」

我爲本身帶鹽!亮出你的代碼。

小結:篇幅可能有些長,但若是細看下來會有不少感同身受,也有不少金玉良言。全書的內容基本上涵蓋軟件開發的各個方面,讓一個程序員對這個軟件開發有一個全面的視角,對代碼的要求,對質量的要求,對需求的理解,以及團隊協做的效率都有啓發。因此不難理解,爲何不少公司推薦這本書爲入職前必讀了。若是你沒有好師傅,不妨讀讀這本書。

書山有路第十一期

相關文章
相關標籤/搜索