趁着這幾天無事,好好總結一下從事軟體開發以來的一些想法,這篇blog嘗試從我自身的一些經曆來談談程式員應該具備哪些素質。如有不足之處,還請不吝賜教!
下面,我将列出并展開所有我認為程式員必須具備的素質。
基礎知識
你也許是像我一樣的自學者,沒有數電/模電,編譯原理,作業系統原理,網絡與資料庫等方面的知識,但是對于這些你應該嘗試去了解、了解。當初跨專業考研之時學習的作業系統/網絡/資料結構/資料庫的知識于我現在的工作仍然有益,我有遇到過一些能力很強的人,他們做解決方案很強,但是debug能力說實話不大比對其水準,原因就在于其不了解很多底層的原理。
對于C/C++程式員而言,其底層是作業系統和編譯器,是以需要了解作業系統原理,彙編,編譯原理等。
對于java/c#程式員而言,其底層是虛拟機和架構,也應該去嘗試了解虛拟機的構成,GC原理等。
我在網上遇到很多c/c++,java/c#程式員,很多時候都發現前者更喜歡追根溯底,後者更在乎如何使用架構,無法評判那種态度更好,但是了解得更深入很顯然是有好處的。
算法與資料結構
推薦閱讀《大話資料結構》,《算法導論》。
算法與資料結構怎麼強調都不為過,雖然大部分程式員在工作中并不一定會用到很多進階算法,也并不會去參加ACM,但是了解常用算法應該是一種基本素質。
應該掌握的常用的資料結構:數組,單連結清單,棧,隊列,二叉樹。
應該掌握的常用的算法:順序查找,二分查找;冒泡排序,選擇排序,插入排序;深度優先算法,廣度優先算法。
進階資料結構:雙連結清單,循環連結清單,雙端隊列,哈希表,跳表,大根/小根堆,哈夫曼樹,排序二叉樹,平衡二叉樹,紅黑樹,B樹/B+樹,圖,etc。
進階算法:二叉排序樹查找;快速排序,希爾排序,堆排序,歸并排序,桶排序,基數排序;KMP字元串比對算法 ,etc。
自學能力
自學能力對于程式員來說非常重要,因為IT這行更新的太快了,幾年不學習很容易就會被時代抛棄,國内塵嚣其上的“30歲轉行論”有這方面的原因。我不是科班畢業的,大學學的是水利,和程式員什麼關系都沒有,一直以來都是自學,我将結合我的經曆談談自學。
首先需要學習的是程式設計語言。我接觸的第一門語言是Visual Basic,大部分理工科應該都有這樣的一門程式設計課,或是vb,或是c,也有的是c++。這種課程對于大部分不感興趣的人來說都是一種折磨,不過我對這種計算機按照我的意圖來執行非常感興趣,是以這樣的課程很對我的口味。在課餘,我會去圖書館借一些vb的書來看看,偶爾也會跟着書上的代碼對照着敲代碼。後來覺得vb功能有限,且無法了解vb之下的秘密,是以轉而自學java,這次是在網上找的馬士兵老師的java視訊教程,跟着學習了一段時間。因為我的筆記本性能不夠,臃腫的JVM運作的非常慢,轉而學習C++。現在我在學C++11。
其次要學的是架構,庫,API等,這時候你可以嘗試做一些有意思的程式出來,通過這些學習基本上可以勝任某些方面的工作。
再次要學的是某個具體的方向,比如web,圖形,圖像,搜尋引擎,機器學習等等專業領域,這些知識的學習應該是在日常工作中不斷積累的。
這段時間的自學告訴我,凡事隻要去努力去學習,都會有成果,所有看起來高大上的東西了解之後會發現就那麼回事。此外,比較廣泛的閱讀了許多書籍,對我現在的工作仍然有利,許多事情是你首先得了解你才會去應用,很多好東西在書上在網上,你知道了才會在某個未來的時刻用上,如果你不知道那你隻能錯失良方許久。
學習是持久的,在實際應用中仍然會碰到你不熟悉的特性,會碰到坑,這時候你需要的是資訊搜集與篩選的能力!
資訊搜集與篩選
在實際程式設計中,肯定會碰到各種各樣的問題,有些是常見的問題,有些是莫名其妙的問題。
我的建議是首先嘗試自己解決,次之看官方文檔和讨論區是否有解釋,然後再去搜尋引擎/stackoverflow查找有沒有相似問題的解決方案,最後再去社群(CSDN/cnblogs/oschina/stackoverflow等)提問。
強烈建議分享自己的解決方案和思考!
作為一個網際網路/開源受益者,分享應該是一種基本美德,特别鄙視釋出問題自己找到解決方案之後就結貼走人的程式員。
分享自己的解決方案與思考不僅僅是讓像你一樣的疑惑者受益,同時還是教學相長的一個過程,自己也會從中獲益。
如何分享自己的思考,這時候你需要的是總結的能力!
總結能力
總結使人進步 ! 在網上看到一個段子,分享一下:
-“你有幾年的工作經驗,怎麼寫的代碼這麼差勁?”
-“5年工作經驗”
-“呵呵,是1年經驗當5年用了吧。”
決定我們是1年經驗當5年用還是真有5年經驗,最重要的就是記得總結自己碰到的問題,自己的想法,前輩的教導!
需求分析與文檔編寫
一個項目的流程大緻為:需求分析 –> 估計進度 –> 設計架構 –> 編碼實作 –> Debug –> 測試 –> Release 。其中coding,debug,test可能會反複疊代。
可以看出需求分析是決定項目的第一個關鍵部分,有些公司是由專門人員進行需求分析,但是作為程式員,應該要了解需求,确認需求。
文檔包括很多方面,需求文檔、設計文檔、測試文檔、使用文檔、注釋等,貫穿軟體開發的所有流程。良好的文檔不僅僅是對項目的負責,同時也會有利于項目的維護。
在項目注釋中,強烈建議添加:TODO , FIXME , HACK , XXX 等标簽以幫助實作邏輯。
架構能力
推薦《架構之美》
在我剛入職的時候,每當接到一個任務時,我都迫不及待的去在IDE中敲代碼,這種渴望很強烈,很有成就感。但是一個前輩告訴我,你首先應該做的是架構設計,充分考慮所有可能的情況并記錄下來之後再去coding,我記下來了但是在沒有教訓之前仍然沒有很強烈的體悟,後來我便後悔了。在某個項目中,我很快的寫出了原型,然後洋洋得意地在這個原型上像打更新檔一樣擴充各種功能,最後在新加的某個功能上栽了跟頭,這個功能完全沒辦法湊進去 。是以,作為程式員,我們需要拟制住自己的編碼沖動以及修改代碼的沖動,先架構設計,然後再編碼。
架構期應該給各個子產品/類之間涉及一套相對合理穩定的接口,實作是易變的,接口不應該頻繁變化。
我認為開發任何一個子產品,首先要做的是了解需求,然後做架構設計,再然後布置基礎設施(包括log,複用的宏,工具代碼等),接着進行編碼實作。
代碼編寫
推薦閱讀《編寫可讀代碼的藝術》、《代碼整潔之道》。
這個不用多說,沒有代碼就沒有軟體。想追求卓越,應該讓我們的代碼更優美,性能更好。
代碼編寫功底包括變量命名,函數拆分與提取,面向對象的特性應用,跨平台意識,多線程的同步,等。
這種能力是在日常coding中積累而來的,多做總結。
Debug能力
推薦閱讀《軟體調試》、《格蠹彙編:軟體調試案例集錦》。
沒有不出現任何bug的一次性成型的代碼,debug是經常會出現的場景。
debug應該盡量的少,同架構設計一樣,碰到問題應該首先看代碼,能直接找出來問題最好。如果看不出來,就需要專業的debug能力了。
bug的場景包括:邏輯錯誤,程式crash,記憶體洩露。
bug的範圍包括:單子產品,多子產品;單線程,多線程;單程序,多程序;單機,聯機。
bug的頻率包括:100%出現,容易出現,很難出現。
可見debug的範圍之廣,bug總是如影随形。
很多時候我會抱怨,oh,見鬼了,這太莫名其妙了,在我機器上都不會出現,等等。我現在明白拿到回報的bug我該怎麼做了:首先閉嘴,然後重制問題,接着縮小問題範圍,最後借助調試器或者log找出問題原因。
代碼閱讀能力
說實話這一段我寫的很傷感,因為要寫“read the fucking source code”實在是太fucking了。
對于接手一個遺留項目,你需要的不僅僅是勇氣,還有耐心。對于一個拿到的項目,首先要做的應該是先跑起來,作為使用者去使用,了解它的功能;接着閱讀設計文檔,了解設計意圖;再然後如果有版本控制曆史的話,可以嘗試從早期版本進行代碼閱讀;再然後是從main函數起大緻走一下流程,了解關鍵route;再然後是對感興趣部分進行單步深入;最後是通讀代碼,可以先将功能性代碼比如log,hashtable等标記為已讀,從頭檔案看代碼間的聯系,弄懂各個類/函數的職責。
說實話,對于具有一定強迫症的同學來說,閱讀其他人寫的代碼應該是挺痛苦的,這時候有時間的話不妨對這些代碼按你的标準進行重構。
重構能力
推薦閱讀《重構,改善既有的代碼設計》。
不管是重構别人寫的代碼,還是重構自己寫的代碼,好像都不是什麼令人愉快的體驗。重構,不僅可以使得架構更加合理,而且使得程式更加健壯。
重構,按我的了解分為兩種。
一種是自頂向底的重構,這需要對項目具有徹底的了解,才能高屋建瓴的對子產品/接口/類/函數進行重新劃分,再将以前的代碼邏輯填充到新的架構下。
另一種是自底向頂的重構,這種方式是對某些代碼進行優化重構,并且保證不影響實作,在重構部分區域之後調整局部結構,最後達到整體重構。
工具的選擇與積累
作為程式員,都應該有一套自己使用的得心應手的工具,這樣會事半功倍。
這些工具包括:IDE,編輯器,輔助debug的工具,檢測系統/程式狀态的工具,版本控制工具,檔案比較工具,性能分析工具,make/cmake等等。
團隊協作
現代軟體工程單打獨鬥基本上不大現實了,像傳說中的彙編寫wps的求伯君大牛那樣獨自搞wps的傳說已經漸隐漸逝了。
團隊協作包括溝通能力,接口協商,版本控制工具的使用等方面。容易出現的是互相推诿責任,對别人的請求不耐煩等,這于團隊協作毫無益處。
高效的團隊協作應該是子產品間接口穩定,基礎類庫一緻,架構代碼共享,版本更新資訊及時,溝通反應快速有效。
如果你喜歡這篇文章,歡迎推薦!
開放,共享,網際網路的未來 !
技術改變世界,我是程式員,我喂自己袋鹽 !
