趁着這幾天無事,好好總結一下從事軟件開發以來的一些想法,這篇blog嘗試從我自身的一些經從來談談程序員應該具有哪些素質。若有不足之處,還請不吝賜教!java
下面,我將列出並展開全部我認爲程序員必須具有的素質。c++
你也許是像我同樣的自學者,沒有數電/模電,編譯原理,操做系統原理,網絡與數據庫等方面的知識,可是對於這些你應該嘗試去了解、理解。當初跨專業考研之時學習的操做系統/網絡/數據結構/數據庫的知識於我如今的工做仍然有益,我有遇到過一些能力很強的人,他們作解決方案很強,可是debug能力說實話不大匹配其水平,緣由就在於其不瞭解不少底層的原理。程序員
對於C/C++程序員而言,其底層是操做系統和編譯器,因此須要瞭解操做系統原理,彙編,編譯原理等。web
對於java/c#程序員而言,其底層是虛擬機和框架,也應該去嘗試瞭解虛擬機的構成,GC原理等。算法
我在網上遇到不少c/c++,java/c#程序員,不少時候都發現前者更喜歡追根溯底,後者更在意如何使用框架,沒法評判那種態度更好,可是瞭解得更深刻很顯然是有好處的。數據庫
推薦閱讀《大話數據結構》,《算法導論》。編程
算法與數據結構怎麼強調都不爲過,雖然大部分程序員在工做中並不必定會用到不少高級算法,也並不會去參加ACM,可是理解經常使用算法應該是一種基本素質。c#
應該掌握的經常使用的數據結構:數組,單鏈表,棧,隊列,二叉樹。數組
應該掌握的經常使用的算法:順序查找,二分查找;冒泡排序,選擇排序,插入排序;深度優先算法,廣度優先算法。網絡
進階數據結構:雙鏈表,循環鏈表,雙端隊列,哈希表,跳錶,大根/小根堆,哈夫曼樹,排序二叉樹,平衡二叉樹,紅黑樹,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中積累而來的,多作總結。
推薦閱讀《軟件調試》、《格蠹彙編:軟件調試案例集錦》。
沒有不出現任何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的傳說已經漸隱漸逝了。
團隊協做包括溝通能力,接口協商,版本控制工具的使用等方面。容易出現的是相互推諉責任,對別人的請求不耐煩等,這於團隊協做毫無益處。
高效的團隊協做應該是模塊間接口穩定,基礎類庫一致,框架代碼共享,版本更新信息及時,溝通反應快速有效。