1、掌握讀程式碼的方法和技巧
不管最終想成為什麼,剛入行之後,一定離不開的是讀程式碼和寫程式碼。這裡將介紹一些讀程式碼的方法和技巧。
讀程式碼這事,先要分是精讀還是泛讀。從學習的目的來看,一定要精讀一定量的經典程式碼。而精讀是指每行都讀懂,不看程式碼腦子裡就能勾畫出程式的基本結構。要想判斷是不是精讀了有個很形象的判斷方法:精讀程式碼時會滿腦子都是程式碼,放不下,甚至睡覺前腦子裡也是程式碼。達到這個程度就是精讀了,否則應該就還不是。精讀程式碼要控制規模(初始階段一萬行以下即可)並用心,不太需要什麼特別的方法。這節裡主要關注的是如何泛讀較大規模程式碼,不是精讀。現存的很多系統往往很大,幾十萬行的可能也只算普通。這時候一旦加入了這樣一個專案,應該如何去讀程式碼?讀規模較大的程式前,先得把規格說明書大致弄清楚,而不能上來就讀。比如:對於應用程式,要先大致整清楚它的使用方法、使用場景;對於庫則要弄清楚它對外介面的定義。如果其中有涉及到某些專門的領域知識,比如:流程、財會等,那也最好預先有些認識。這類東西徹底的從程式碼裡反推回來是不太可能的。如果弄不清這類東西,很多時候對讀程式是個很大的障礙。你不知道程式碼做的是什麼,卻去讀對應的程式,那就只能看到呼叫來呼叫去,最終會雲裡霧裡。
接下來從大往小,從面到點來看,一旦開始接觸程式碼,那要先弄清楚程式碼的基本靜態結構。如:包構成、類構成等。這裡幾乎一定會涉及一個層次問題。一下子把層次探的太深,就容易盯在細節上出不來。把層次拔得太高,又容易流於表面。從數目上看,一個層次最好不要超過10個關鍵概念,超過了真記不住。在靜態結構這步,要弄清楚每個部分的核心職責,可以是很簡單的概括,最好能記住。接下來選擇出最常用的典型場景,然後在典型場景下考察上面的靜態結構是如何發揮作用的。典型場景下用到的介面往往就是關鍵的介面,要弄清楚他們的定義和作用。也要整清楚典型場景下資料流的變遷。通過這兩個步驟等價於腦子裡可以生成一份比較高層次的靜態和動態結構圖,很像UML裡的Sequence圖和類圖。牽涉到資料庫的時候,一般需要對相應的資料規格有所瞭解。
接下來要關注程序、執行緒的結構。比如:都是什麼時候開始、什麼時候結束的,在上述典型場景下都負責幹什麼。
上述四步(規格、靜態結構、典型場景、程序執行緒)完成後,對程式的第一次泛讀完成。檢驗是否達成目標的方法可以很簡單,如果真的基本讀懂了,這時應該能夠單靠紙筆描述出程式典型場景的Sequence圖。
做第一次泛讀的時候,要抑制自己的求知慾,因為總是很想在偵錯程式裡通過call stack把一個功能的實現細節整清楚。至少在第一個次泛讀裡,可以先不要這樣。
第一次泛讀後,就要進入深掘的過程,一般來講需要針對自己會負責的部分進行深入挖掘。這部分功能往往會隱藏在某個介面之下。
這時候一般來講可以把功能型的模組優先順序降低,比如:XML解析的模組等。其他部分可以認為是需要把之前所說的四個步驟再重複一下。但這時候要關注細節和呼叫堆疊了。
不管是在那個讀程式碼的層次,有兩個基本技巧總是需要的,一個是要掌握具體程式裡內嵌的Log機制,要能看Log,必要時可能還得加Log;一個是基本除錯方法。同時一個合適的程式碼閱讀工具會對提升程式碼閱讀速度有所幫助,比如:一款名叫SourceInsight的小工具中可以把視窗分拆為幾個部分,點選任何方法的時候,這個方法的實現以及CallsGraph都可以被自動展開,這樣的小功能無疑的對閱讀程式碼是有幫助的。
2、從哪門程式語言開始學習好些?
學習程式設計至少要掌握一門程式語言,但從那門程式語言開始是一個極其容易引起爭議的問題。為使結論經得起推敲,這裡需要做一點系統的分析。
純從未來應用的角度看,結果是不確定的,在學習的時候,其實沒人能夠知道未來會主要使用那門語言。因為最終工作中使用那門程式語言往往取決於一些很偶然的因素,比如現有產品的開發語言,待解決問題的領域等。比如說如果命運安排你去做和Hadoop相關的工作,那很可能會用到Java,如果安排你去做驅動開發,那就很可能會用到C/C++。
如果上述這點成立,並且被預設為前提,那麼在學習階段應該學什麼就可以有個相對確定的答案:學習階段學習語言的目的是為了掌握程式設計的基礎概念並能更快速的學好另一門語言。顯然這仍然是打基礎的範疇。
從這個角度看,只有一門語言是必須學的,那就是C。因為不瞭解這門語言會造成一定視野上的限制,使基礎薄弱,比如不掌握C語言的人,很可能無法瞭解《深入理解計算機系統》這樣的書,進一步也就不理解什麼是指標,什麼Stack,什麼是StackOverflow,什麼是寫超界,做效能優化的時候可能也就想不到一些系統級的手段。Joel在《軟體隨想錄》裡專門有一章叫“學校只教Java的危險性”,其中所表達的觀點與這裡的觀點類似。
作為結果,儘管很可能在工作中用不上C語言,在學習的時候還是要把它掌握,除非在最初階段就已經下定決心只把技術當做敲門磚,而不想走的更遠。要不然根基就過於薄弱了。
至於其他一些比較主流的語言比如C++,Java,C#等可以完全按照興趣來進行選擇,唯一關鍵的是不管選擇那個都要累積一定程式碼量並把它學透。這樣依此擴充套件到將來要用的程式語言,學習曲線往往就會很平,大致2~3周就可以用新的語言做一些基本的開發工作。
選擇程式語言的另一種思路是從指令碼語言入手,比如PHP,Python,Javascript等。這就和趙匡胤當年要下決策是先搞定弱的南唐還是先搞定強的遼國一樣,是個兩難的話題。從入手容易,培養興趣的角度看,顯然指令碼更好些,並且指令碼語言也是網際網路的顯學,未來用到的機會很高;但如果想多積累,厚積薄發那麼就還是從C入手會好些。我個人的建議是如果在大學裡那就先難後易好些,因為人生裡不總是有這麼大塊的時間;但如果是後想轉入這個行業,那就直接找指令碼開始吧。
3、小結
寫程式、讀程式、學好學習曲線陡的知識、避免IDE依賴這些事情的根本目的都是為了打好基礎。這個環節裡最忌諱的是急功近利,比如:學習一堆IDE的操作方法、每個程式語言都掌握一點。很多人可能誤以為這對找工作有幫助,所以把但凡接觸過的技術都列到簡歷裡是很常見的做法。但其實這個認識是不對的,但凡有點規模的公司招聘畢業生或者剛畢業不久的開發人員的時候都更看重他的基礎和發展潛力。而基礎和潛力這兩樣東西很難精確度量,但並不難判斷,通過簡單的面試既可以判斷出來。只關注當下這個人能幹什麼的公司很可能是看不到明天的公司。DevStore 全球首家開發者服務商店 傾情奉獻。
原作者: 理想流的部落格