天天看點

程式員生存定律--程式設計的起點與可能的失足

程式員生存定律這系列的目錄在這裡:程式員生存定律--目錄

喜歡從頭瞄的,可以移步。

-------------------------------------------------------------------------------

從大環境來看,想不寫程式直接去做管理工作是很難的。大多時候都要在開發上做出一定成績,接下來才有選擇技術還是管理的機會。是以即使是希望選擇管理方向,技術上的基本功還是需要的。是以下面這節的内容和選擇做管理方向還是技術方向關聯不大,隻要是想做程式員,大緻上都有必要一讀。

從那裡開始程式設計生涯

大學裡經常會開設軟體工程專業,在這門課程裡面大多時候會講解需求工程、開發模型、設計方法、項目管理等。但很多同學會感覺這課程讓人摸不着頭腦,認真學也學不到什麼。從這種普遍現象可以發掘出一些本質問題。

這裡的本質問題是指軟體開發是實踐性非常強的科目,是以不适合先從概念開始。這不意味着軟體工程、設計思想不重要,而隻是說不适合從純粹的概念開始學習程式設計。 

在軟體這個行業裡,很多比較資深的人員對如何學習程式設計是有統一認識的:學一點,實踐一點,再學一點,再實踐一點。但困難的是每個人對每次疊代的“一點”究竟是多少認知不同,對“一點”是什麼的定義也是不同。

我個人的觀點是以3000代碼行為界算第一個一點,也就是說一個人學會某個語言後小練習不算,先完成一個3000代碼行左右的,沒有UI的獨立程式。為解釋什麼叫獨立的程式,舉一個具體的例子。

在《靈活軟體開發:原則、模式和實踐》一書中有一個薪水支付的例子程式,正好是這個規模,很适合幫助達成這一目的。這個程式的基本規格說明是:

(下文引自《靈活軟體開發:原則,模式與實踐》)

  • 有些雇員是鐘點工。會按照他們雇員記錄中每小時報酬字段的值對他們進行支付。他們每天會送出工作時間卡,其中記錄了日期及工作小時數。如果他們每天工作超過8小時,那麼超過的部分會按照正常報酬的1.5.倍進行支付。每周五對他們進行支付。
  • 有些雇員完全以月薪進行支付。每個月的最後一個工作日對他們進行支付。在他們的雇員記錄中有一個月薪字段。
  • 同時對于一些帶薪(Salaried)雇員,會根據銷售情況,支付給他們一定數量的酬金。他們會送出銷售憑條其中記錄了銷售的日期和數量。在他們的雇員記錄中有一個酬金字段。每隔一周的周五對他們進行支付。
  • 雇員可以選擇支付方式。可以選擇把支付支票郵寄到他們指定的郵政位址;也可以把支票儲存在出納人員那裡随時支取;或者要求将薪水直接存入他們指定的銀行賬戶。
  • 一些雇員會加入協會。在他們的雇員記錄中有一個每周應付款項字段。這些應付款必須要從他們的薪水中扣除。協會有時也會針對單個協會成員征收服務費用。協會每周會送出這些服務費用。服務費用必須要從相應雇員的下個月的薪水總額中扣除。
  • 薪水支付程式每個工作日運作一次,并在當天為相應的雇員進行支付。系統會被告知雇員的支付日期。這樣它會計算從雇員上次支付日期到規定的本次支付日期間應付的數額。

在學完程式設計語言、面向對象、UML之後可以先參照這份規格說明,什麼例子程式都不看,自己完整的做一份實作,實作中要包含UML圖和代碼,接下來可以去把Robert C.Martin的例子程式下載下傳回來,同自己的實作在設計上和實作細節上做詳細的比較,找出那點自己好,那點Robert C.Martin的好。這樣對程式設計語言、對面向對象、對設計原則就可以有比較踏實的一些了解。此外,這個程式的一個額外的好處是它可以完全獨立于平台,隻依賴于語言和标準庫即可。 

假設說一個新手已經熟練掌握了一門語言,那麼完成上述的任務估計需要2~4人周,當然有經驗的人1個人周左右已經足夠了。

在此之後,可以精讀一個上點規模的(1~5萬行最佳)獨立性比較強的應用程式,由于已經上了規模,做到完全的與平台相隔離就有點難了,沒法提供統一的例子作參考。但選擇标準主要有兩個,一個是盡可能和自己未來期望的方向相吻合,一個是盡可能比較獨立和經典。獨立的目的是友善調試,經典的目的是確定代碼品質。比如:如果是Windows本地應用就可以考慮Notepad++類的開源應用,Web應用就可以考慮WordPress等。這個時間點上需要避免好高骛遠,Linux核心與Chrome當然很好,但它們并不适合初學者的。 

在精讀過程中可能需要幾類書籍:一是平台架構相關的(線程機制等),一類是模式相關的,一類是工具型的書(如何調試)。這個時候是要耐下心來讀幾本比較經典的書的。 

精讀之後,就要再找到一個項目來實踐。這裡的關鍵是真的項目,至少要有真的使用者,并且使用者數目越多越好。最好是能夠向知名開源項目送出代碼。 

各種基礎知識中比較例外的是計算機體系結構、資料結構和算法這類理論性比較強的東西,這種學習曲線比較陡的東西需要結合大學的課程把它學會,接下來再在實踐中逐漸應用,而不能一邊做事一邊學習。原因是學習曲線越陡的東西越需要大塊時間,畢業之後再學效率會差。 

總的來看,上述幾個步驟,應該在大學畢業後2~3年内完成,最好在大學裡完成,這樣可能會有點優勢。這些完成之後,打基礎階段可以算是基本結束。

打牢根基 VS 速成道路

有很多不同的方法可以學會程式設計,比如說:一個人既可以先打牢基礎,接下來再逐漸學會如何進行各種開發工作;也可以不管三七二十一,先借助各種IDE把程式做出來再說。上一節主要介紹的是先打根基的方法,而不是速成的方法。 

相對于打根基的方法,後一種學習方法更容易在短時間内看到效果,是以很多人都是這麼入的行,比如:先從IDE開始,接下來再從表面往本質去學,逐漸去了解控件拖放背後所隐含的東西。這不能說完全不好,但我認為這是一種失足,幾乎一定會催生程式員隻能吃青春飯的結果。 

在剛開始程式設計的時候,如果形成對IDE的過度依賴,那就會導緻根基淺薄,能做的事很可能被限制在某個有限的範圍内。當下的大多IDE功能已經非常強勁,這對提高産品的生産率無疑是非常有必要的,但在學習階段,則要盡可能避免過度依賴于IDE,避免用各種控件來快速完成任務。 

比如說:微軟在Visual Studio 2012裡面内置了一種名為LightSwitch的技術,基于這項技術,一個人可以在基本不編碼的情況下,完成資訊系統的開發,并支援相對比較豐富的功能(增删改查,搜尋,排序等)。無疑的基于這樣的工具做開發速度會快上很多,但在學習階段過度使用這類工具,卻會毀了一個人的根基。 

想象一下,在使用LightSwitch的過程中一個人會學到什麼?他所能學到的主要是這種工具的使用方法,既不會學到SQL語句,也不會學到資料庫表格的設計方法,也不會學到ASP.net的基本架構(雖然ASP.net已經封裝了非常多的東西)。這樣一來,這個人雖然能夠快速的完成某個工作,但卻給自己埋下了很深的隐患---他很容易的被束縛于某個工具,并且無法應對新領域。 

善用IDE內建好的功能進行快速開發不是學習階段應該做的事情,學習階段最根本的目的是打基礎,把一門語言學精,把一種設計思想學精,把一種算法學精等等,這種基礎可能不直接表現為生産力,即使把算法學精了,可能還是無法立刻寫出來比較炫的程式,但這有助于面對不停變化的世界,這與單純的達成某個目的,完成某個程式不同。這可以類比為打地基與蓋樓,地基部分顯然不能單獨進行銷售,也不能住人,但沒有地基也就沒有其上幾十層可以高價售出的住宅,樓越高,地基也就越深。當然,隻蓋地基或者讓五層樓和五十層樓使用一樣的地基也沒必要,這不用多說。 

那具體來講,那些東西可以被認為是程式設計的根基,需要在學習階段紮實的掌握?下面将通過推薦幾本書(或者說幾類書)來描述一個共通于所有程式員的最小集合。 

  • 計算機體系結構

這一類别下最具代表性的書籍是《深入了解計算機系統》,作者是Randal E.Bryant和David O’Hallaron。讀這本書的目的是了解計算機到底是怎麼個東西,軟體到底運作在什麼樣的基礎之上。

  • 算法和資料結構

這一類别下最具代表性的書籍是《算法導論》,作者是Thomas H.Cormen,Charles E.Leiserson,Ronald L.Rivest,Clifford Stein。讀這本書的目的是了解軟體到底可以用什麼樣的手段幹些什麼事情。軟體是一種工具,可以幫助解決人類面臨的許多問題,而主要手段則隻有兩種,一種是這本書裡所介紹的算法和資料結構;另一種則是下一類别中所涉及到的分析和設計方法。它們像小刀子一樣,可以把各種領域中的各種問題進行分割,并映射到程式的世界裡來。 

  • 設計原則和模式

這一類别中比較有代表性的書籍是《靈活軟體開發:原則、模式與實踐》,作者是Robert C.Martin。讀這本書的目的是了解資料結構和算法之外另一種對現實問題進行抽象的方法如面向對象以及進行這種抽象時所要遵守的原則。

這類書籍經典的還有很多比如:GoF的《設計模式》,而之是以選擇上述這本是因為這本書裡提供一些比較完整的例子,更适合初學者一些。

  • 軟體工程

這一類别中最具代表性的書籍是《代碼大全》,作者是Steve McConnell。讀這本書的目的是建立對軟體開發的全局視圖。知道一個軟體從無到有所要經曆的一系列過程。

軟工的書還有很多,比如很有名的《人月神話》,但《人月神話》類書其實對很多人是不适合的,對初學者就更不适合。

上面四本書是一個最小集合,針對不同場景需要進行不同的增加,比如可能需要進一步了解某種架構的機制,那就需要讀《XX技術内幕》這類書。但即使是讀這幾本書也不适合隻讀書而不動手,最好是穿插在上一節中提到的實踐中來讀,否則的話對後兩本的了解會有所欠缺。

如果想走厚積薄發這條路的上面幾本書是一定要預先讀通的。閱讀過程中,如果發現有些細節問題徹底無法了解,那就要在實踐過程中進一步琢磨,找到自己的答案。讀這類書時,有一件事情一定要有心理準備:雖然這些書讀通并不容易,很花時間,但想讀了這些書後立刻寫出來一個能賣點錢的工具是不太可能的,這真和大樓的地基一樣,沒什麼立竿見影的效果。如果想盡快達成後者這樣的目的,那很可能就要走速成的道路,去讀些介紹IDE怎麼用,某個架構怎麼用的書,比如:《C#進階程式設計》這類。

為避免誤解,有一點需要額外進行一點說明。前面強調的避免過度IDE依賴主要是指不要用封裝良好的子產品來取代對基礎知識的學習,不是說不需要建立自己的工具箱。查找工具、調試工具(程序線程檢視等)、二進制資料檢視工具、正規表達式工具、持續內建工具、文檔生成工具(JavaDoc)、正規表達式工具等對一個程式員的生産力是非常有幫助的,應該在學習過程中逐個掌握。軟體開發工作發展到現在,任何一個類别下面都有相當多的比較成熟好用工具了,關鍵是標明一個把它用熟。

------------------------------------------------------------------------------

關于我自己的各種資訊,在左邊欄可找到,想了解下寫這書的人是不是騙子和大忽悠的可以瞄。

最後希望感興趣的支援V衆投,感覺上這應該是國内最靠譜的生活購物等的問答社群了吧,都是朋友給朋友做的答案,同時實行一人一号,一人一票制度,想找什麼答案關注公衆号:vzhongtou(左側有二維碼)就行了。

繼續閱讀