中國IT行業的「好工程師」應該是什麼樣的?有哪些客觀標準可供自我評估?


國外的技術問答社區StackOverflow,有個帖子討論得很火,說的正是「How does a
programmer employ deliberate practice? (程序員如何應用"刻意練習")」。

程序員進行「刻意練習」,最早是在《Software Craftmanship(軟體工藝)》一書中正式提到,新出的《程序員應該知道的97件事》也有一小節提及。但最系統、詳盡討論的是《Apprenticeship
Patterns: Guidance for the Aspiring Software Craftsman(軟體開發者路線圖:從學徒到高手)》,可以稱得上是程序員「刻意練習」的一本行動教科書。

程序員進行」刻意練習「,與其他領域相比有一個天然優勢,就是可以充分利用網路和開源。除了《軟體開發者路線圖:從學徒到高手》提到的方法,
Hacker News技術社區的討論還建議了一些網路資源,如Coding Dojo(編程擂台)、Code Kata(精心設計的21個編程練習),Ruby社區的Ruby Quiz郵件列表等。

優秀的開源代碼也是很好的學習對象。StackOverflow問答社區建議,可以借鑒富蘭克林學習寫作的方法,分析一段優秀的開源代碼,梳理邏輯、做好筆記,然後嘗試自己重新實現,再與源代碼進行比對。這個過程可以循環遞進地進行。


最近我們出版的這本書構建之法——現代軟體工程得到諸多好評,比如:

蔣濤CSDN(Sina Visitor System)
驚艷,打開@@程序員鄒欣 《構建之法——現代軟體工程》,就停不下來,把軟體開發方法講得清晰有趣實用,程序員應該人手一冊,通讀完畢思維水平立馬從業餘升級到專業! 一定要請@程序員鄒欣 給我們@黑馬程序員訓練營 同學們講課,每個黑馬程序員都應該讀完這本書,先來200本

請看:《構建之法》試讀

書中第三章的主題是「軟體工程師的成長」 ,作者鄒欣老師結合中國軟體行業的特點,歸納出在中國IT行業「好工程師」的要素,並做成一個自我評價清單:現代軟體工程 課件 軟體工程師能力自我評價表

現代軟體工程 課件 軟體工程師能力自我評價表(37條)

1.保持高標準,不要受制於破窗理論(broken windows theory)。

[i]

當你看到不靠譜的設計、糟糕的代碼、過時的文檔和測試用例的時候,不要想「既然別人的代碼已經這樣了,我的代碼也可以隨便一點啦。」

2. 主動解決問題。當看到不靠譜的設計,糟糕的代碼的時候,不要想「可能別人會來管這個事情」 ,或者「我下個月發一個郵件讓大家討論一下」。要主動地把問題給解決了。

[ii]

3. 經常給自己充電,身體訓練是運動員生活的一部分,學習是軟體工程師職業的伴侶。每半年就要了解和學習一些新的相關技術。通過定期分享(面對面的分享,寫技術博客等)來確保自己真正掌握了新技術。

4. DRY (Don"t Repeat Yourself)——別重複。在一個系統中,每一個知識點都應該有一個無異議的、正規的表現形式。

5. 消除不相關模塊之間的影響,在設計模塊的時候,要讓它們目標明確並單一,能獨立存在,沒有不明確的外部依賴。

6. 通過快速原型來學習,快速原型的目的是學習,它的價值不在於代碼,而在於你通過快速原型學到了什麼。

7. 設計要接近問題領域,在設計的時候,要接近你目標用戶的語言和環境。

8. 估計任務所花費的時間,避免意外。在開始工作的時候,要做出時間和潛在影響的估計,並通告相關人士,避免最後關頭意外發生。

9. 圖形界面的工具有它的長處,但是不要忘了命令行工具也可以發揮很高的效率,特別是可以用腳本構建各種組合命令的時候。

10. 有很多代碼編輯器,請把其中一個用得非常熟練。讓編輯器可以實現自己的定製,可以用腳本驅動,用起來得心應手。

11. 理解常用的設計模式,並知道擇機而用。設計模式不錯,更重要的是知道它的目的是什麼,什麼時候用,什麼時候不用。

12. 代碼版本管理工具是你代碼的保障,重要的代碼一定要有代碼版本管理。

13. 在debug的時候,不要驚慌,想想導致問題的原因可能在哪裡。一步一步地找到原因。要在實踐中運用工具,善於分析日誌(log),從中找到bug。同時,在自己的代碼裡面加 log.

14. 重要的介面要用形式化的「合同」來規定。用文檔和斷言、自動化測試等工具來保證代碼的確按照合同來做事,不多也不少。使用斷言 (assertion) 或者其他技術來驗證代碼中的假設,你認為不可能發生的事情在現實世界中往往會發生。

15. 只在異常的情況下才使用異常 (Exception), 不加判斷地過多使用異常,會降低代碼的效率和可維護性。記住不要用異常來傳遞正常的信息。

16. 善始善終。如果某個函數申請了空間或其他資源,這個函數負責釋放這些資源。

17. 當你的軟體有多種技術結合在一起的時候,要採用松耦合的配置模式,而不是要把所有代碼都集成到一起。

18. 把常用模塊的功能打造成獨立的服務,通過良好的界面 (API) 來調用不同的服務。

19. 在設計中考慮對並行的支持,這樣你的API 設計會比較容易擴展。

20. 在設計中把展現模塊 (View) 和實體模塊 (Model) 分開,這樣你的設計會更有靈活性。

21. 重視演算法的效率,在開始寫之前就要估計好演算法的效率是哪一個數量級上的(big-O)。

22. 在實際的運行場景中測試你的演算法,不要停留在數學分析層面。有時候一個小小的實際因素 (是否支持大小寫敏感的排序,數據是否支持多語言)會導致演算法效率的巨大變化。

23. 經常重構代碼,同時注意要解決問題的根源。

24. 在開始設計的時候就要考慮如何測試 ,如果代碼出了問題,有log 來輔助debug 么? 儘早測試,經常測試,爭取實現自動化測試,爭取每一個構建的版本都能有某些自動測試。

25. 代碼生成工具可以生成一堆一堆的代碼,在正式使用它們之前,要確保你能理解它們,並且必要的時候能debug 這些代碼。

26. 和一個實際的用戶一起使用軟體,獲得第一手反饋

27. 在自動測試的時候,要有意引地入bug,來保證自動測試的確能捕獲這些錯誤。

28. 如果測試沒有做完,那麼開發也沒有做完。

29. 適當地追求代碼覆蓋率:每一行的代碼都覆蓋了,但是程序未必正確。要確保程序覆蓋了不同的程序狀態和各種組合條件。

30. 如果團隊成員碰到了一個有普遍意義的bug, 應該建立一個測試用例抓住以後將會出現的類似的bug。

31. 測試:多走一步,多考慮一層。如果程序運行了一星期不退出,如果用戶的屏幕解析度再提高一個檔次,這個程序會出什麼可能的錯誤?

32. (帶領團隊)了解用戶的期望值,稍稍超出用戶的期望值,讓用戶有驚喜。

33. (帶領團隊) 不要停留在被動地收集需求,要挖掘需求。真正的需求可能被過時的假設、對用戶的誤解或其他因素所遮擋。

34. (帶領團隊)把所有的術語和項目相關的名詞、縮寫等都放在一個地方

35. (帶領團隊)不要依賴於某個人的手動操作,而是要把這些操作都做成有相關許可權的人士都能運行的腳本。這樣就不會出現因為某人休假而項目被卡住的情況。

36. (帶領團隊)要讓重用變得更容易。一個軟體團隊要創造一種環境,讓軟體的重用變得更容易。

37. (帶領團隊)在每一次迭代之後,都要總結經驗,讓下一次迭代的日程安排更可靠。

[i] 參見:Broken windows theory

[ii] Jim Barksdale 是Netscape 公司的CEO, 他提出了Snake Rule,見到問題,就要解決問題,但是也不要沉溺於無法挽回的事情中。參見:MenkBlog 以及 Jim Barksdale Said It


=====繼續劇透=====

1 《構建之法》試讀:目錄
2 《構建之法》試讀:推薦序(北航李未院士推薦)
3 《構建之法》試讀:前言

每次用到歐洲公司開發的控制軟體,我一直在思考的是,他們到底用什麼開發模式來開發如此穩定可靠好用的軟體?國內很多很有名的自動化企業,生產的PLC或者機器人控制器的底層軟體其實都是購買歐洲公司產品,而歐洲一家很小的公司,也能推出一個功能完整的機器人控制器產品,說明我們自動化軟體的構建能力和歐洲同行比還很弱。可以想像,一個具備良好機電背景和軟體構建能力的畢業生,將有無比廣闊的舞台。」——摘自構建之法,超越軟體 (評論: 構建之法)

 「程序員,就像詩人一樣,幾乎僅僅工作在單純的思考中。他們運用自己的想像,來建造自己的「城堡」,《人月神話》里的這句話勾勒出軟體開發的畫面,想像的畫面總是太美,但實際中的場景卻沒有想像的那麼美。軟體開發中的各種問題讓軟體工程師打造的城堡總是或多或少的出現問題,如何去改善開發過程來減少這些問題已經成為學術界和工業界共同追求的目標。多年來,鄒欣老師一直將企業的最佳實踐和大學的實際教學結合起來,並結合軟體工程當前的最新研究進展,寫出了這本《構建之法》,使得原本枯燥的軟體工程問題躍然紙上,也使得原本有些草莽的開發路數變得高大上。就這本書來看,不管是兩人合作、還是團隊流程,不管是MSF,還是敏捷流程,不管是軟體測試,還是需求工程,每章的寫法都駕輕就熟,舉重若輕,能把一個個鮮活的例子(或故事)與軟體工程的相關問題恰到好處的結合起來,然後再根據相關的理論進行分析,使得文章深入淺出,讀起來沁人心脾。像團隊和流程、敏捷流程、需求分析、設計與實現這些章節我是看了又看,作者從常見場景入手、到最佳實踐,然後結合相關理論進行分析。最後兩章,作者再次用其熟悉的手法,闡釋了創新及軟體工程領域的職業道德問題,引起很多的共鳴。易經有云:「形而上者謂之道、形而下者謂之器」,這本書給我最大的感受是從「形上形下」寫得「道器兼修」。 ——摘自形上形下,道器兼修 (評論: 構建之法)


說下個人的理解,可能片面了,僅供參考交流:

什麼是一個優秀的軟體工程師?
1、能搞清楚目的和需求。需求包括:老闆的需求,自己的需求,客戶的需求。
2、能用比較好的方式滿足需求。好的方式包括:可靠性,可維護性,可擴展性,可伸縮性,可讀性等軟體工程中定義的關於軟體特質的要求。

哪些特質有助於幫助一個人成為優秀的軟體工程師?
1、責任心。做一個負責的東西包括對現在和未來的負責的coder。
2、自省能力。能在盒子內部看問題,能跳出盒子看問題。
3、數理邏輯紮實。軟體從最初的過程+數據,到面相對象,面相組件等思路方法都有很強的數理邏輯和認識邏輯,基本功需要紮實。這也是為什麼培訓班出來的很難成為一個優秀的大師;
4、不斷學習。不學習就意味著落後,保持不斷學習的心態才能一步步邁向優秀。

這樣的人有哪些?

  • Kent Beck
  • Grady Booch
  • Fred Brooks
  • Barry Boehm
  • Peter Chen
  • Ward Cunningham
  • Ole-Johan Dahl
  • Tom DeMarco
  • Martin Fowler
  • C. A. R. Hoare
  • Watts Humphrey
  • Michael A. Jackson
  • Ivar Jacobson
  • James Martin
  • Bertrand Meyer
  • David Parnas
  • Winston W. Royce
  • James Rumbaugh
  • Niklaus Wirth
  • Edward Yourdon
  • Victor Basili
  • James_Gosling

參考1:互聯網英雄們:http://www.zhihu.com/question/20219892
參考2:wiki上的軟體領域大師:http://en.wikipedia.org/wiki/Martin_Fowler 等等各個計算機領域的牛人們。


這個問題問的是「軟體工程師」而不是「程序員」,我假設問的人和回答者均了解「工程師」和「程序員」之間的區別,儘管上面一些答案明顯指向的是「優秀的程序員」。我認為三種特質的顯著與否決定工程師的優秀程度:

  1. 好奇:充滿對軟體工程的激情會導致一種好奇心,這種好奇心驅使一個人去了解全景,掌握思考問題的卓越方法論,知其所以然,不限於表象的掌握,追求更深層次的完整理解,並好奇於新技術和技術創新的方法,持續採用更精湛的方式思考和解決問題,好奇是根本源泉。
  2. 質疑:不完全相信權威,對專業存在自己的看法是很重要的,其中包括了一種專業觀點,一名優秀的工程師應該對所在專業有自己的觀點,才會形成自己的方法論,自己的設計模式和實現的把握。如果工程師能夠產生自己的方法論和觀點,並統一地以此思考問題,必然產生對很多權威的質疑,質疑導致了論證和對自身觀點及方法論的持久矯正。
  3. 精明:很多文章說優秀的工程師都很懶,因為懶才字字璣珠,我認為那是外行的說法,成為優秀工程師的道路是靠努力作為基本基礎的,勤勞和天賦是權重相當的兩個因素,但缺一不可。優秀的工程師不是「懶」,而是精明,程序的極簡實現、直接命中主題的設計都來自於「事事精明」的習慣,而且融會貫通才能不拘一格,產生漂亮的設計和實現,不相信「勤能補拙」,但堅信「事事精明」應該是個工程師的基本心態,優秀的工程師明白自己的優勢在於融會貫通的精明思考,而非蠻力導致的碼農苦力。

我不是技術背景,從旁觀者的角度說說。

1. 基本功紮實,精通一種語言,其它的幾天就能手到擒來。
2. 懂演算法,一樣的問題實現出來速度能差到一至幾個數量級。
3. 有同情心,知道讀代碼是很痛苦的一件事,所以寫的很容易讀懂。
4. 溝通能力,可以和產品,設計,上下級做有效溝通。


簡單說,八個字: 概念清晰,直指本質


概念清晰,意思是對接觸到的東西,都要有打破砂鍋問到底的好習慣。而且不僅要問,還要去理解、進而舉一反三。

如果有人連一樣東西究竟是什麼都弄不清楚,還指望能正確理解它?

有了概念清晰這個基礎,下一個要追求的就是「直指本質」(很顯然,如果概念都不清晰,還指望看到本質?)

直指本質,意思就是要能最簡潔但又最準確的,概括多個概念之間的關係。

寫程序,本質上就是在用程序維護或模擬概念之間的關係;甚至程序語言本身,就包含了很多基本概念(如順序、分支、循環);而這些基本概念內部或者之間,又有複雜的聯繫。

任何理解錯誤,最終都會體現為bug。而且是不提高自己就無從發現的「高難度」bug(很顯然,對不同人,高難度的定義也不同)。


概念越清晰,基礎抽象就越不容易出現偏差;本質抓的越准,代碼出現邏輯錯誤的機會就越少——這自然而然就導向了KISS(Keep IT Simply Stupid )。

當然,概念清晰、直指本質的人,知識面不一定就很寬、很深;在他們知識面拓寬、鑽深之前,是不能稱為優秀軟體工程師的;但一個概念不清晰的人,絕對不會是一個很好的工程師——任何行業都是如此。


個人認為,注重基礎。

藉此在新技術新概念層出不窮的今天能夠區分糟粕和精華,經典和曇花。


其實吧,我覺得吧,如果是要成為優秀程序員,那就多讀源代碼,搞定這件事就成就一半了;如果是優秀工程師呢,那就多多與人合作,小夥伴們的力量是強大的;如果要不限於「優秀」,而是試圖了類拔萃呢,就多點勤奮;如果要成為受人敬重的大師呢,那就得知道「能力越大,責任越大」,是責任而不是工作成就了那些大師。


1. 看經典的技術書籍(技術、設計模式、底層原理、演算法),不要拋棄數學
2. 多實踐,應用到工作的項目中
3. 具備技術分享的能力(當你能夠將一樣東西清晰分享給很多人的時候,說明真的對這個東西有深刻的理解)
4. 要有技術追求,不斷優化,降低機器成本,提升服務效率


介於急躁、懶惰和傲慢之間。
介於實用主義和完美主義之間。

懂經濟。


好奇心


優秀。
當然,等於沒說。可是其他答案中的那些,大多是碼農的自我YY:自己有什麼特點,就沾沾自喜的拿出來宣揚炫耀一下了。活該一輩子做碼農。


基礎。知其然,知其所以然


優秀評估的指標有很多,個人拙見:
1、良好的積極溝通。問題不可能自動消失,不要被動等待;
2、學習。學習技術,包括不喜歡的,比你聰明的人天天都在努力,你真的沒有理由不學習;
3、需求分析能力。包含溝通能力,換位思考,需要主動培養;
4、解決問題能力。系統突然出現問題時,有一套解決思路;
5、工作效率和規劃。工作遵循流程,提升效率積極完成,得到認可的速度會加快,這條適應任何崗位;
附:碼農與菜農對比
菜農瓜農:耕地鬆土、播種、除草、除蟲、施肥、成長收穫,很辛苦的,但賣了好價錢
碼農:規劃、開發、除蟲(bug)、溝通、學習,成長收穫,也很辛苦的,但得到了認可
說自己是碼農的也很了不起


既然是最重要,我覺得是:始終保持謙虛


是否願意自己動手重建整個世界


曾經有個段子是這樣的..... 作為一名真正的程序員可以把手放在自己的胸口上,對著自己的內心說我是真心的喜愛編程.


為什麼要成為軟體工程師?


優秀軟體工程師?
別特么搞笑了,碼農就是碼農,真以為自己寫兩行代碼就變成工程師了?

理想是豐滿的,現實是骨幹的。等你成為合伙人之前,就永遠是個碼農的命,還優秀工程師,呵呵,除了好聽能騙騙外行騙騙妹子以外,還能做什麼?

就一句話:拿人錢財,替人消災。你品質再好,態度在好,語言掌握的再好,bug修得再好,有什麼用?老闆不在乎。老闆只在乎一個,你能,還是不能,解決問題。他不會在乎你用的是什麼手段解決的問題,他只在乎結果。

你也只需要在乎結果。然後等你有資格在乎是不是一個好程序員,好工程師的時候,你已經不需要考慮自己是不是這樣一個人了。


如果只是想成為一個優秀的程序員那我認為正確的學習方法+毅力或許就可以達到。
但事實並非如此,往往你工作所針對的行業和公司是否重視技術以及自我遭遇決定了你對現實的屈服程度和職業方向的改變。
在國內大多數程序員從事著重複的體力勞動,而參與創造性或者原創性項目的比例並不高,而且在針對性比較薄弱的中小項目中技術扮演的角色並非會得到足夠的重視和應有的待遇,他們只是在不停的複製粘貼著最基礎的代碼。而能讓他們欣喜的也只是最終產品能否發揮應有的價值。

隨著年齡增長、生活壓力增大以及職業發展過程和天賦等問題,潛移默化的決定著你能否成為一名優秀的軟體工程師。而你當初的喜歡也會伴隨著現實慢慢冷淡甚至夭折。

當你,不能成為「大牛」並且為了生存、喜歡還依然堅持著編程。那麼,我認為應該從編程以為獲得更多,拓寬自己的思路,至少做一個能用有限技術去合理解決現有需求以及學會把複雜問題簡單化的碼農!


推薦閱讀:

開發一個網站需要什麼會哪些技術?
軟體版本號命名的依據有哪些?
大型公司開發軟體的流程是怎樣的?
3 年開發經驗進得了 BAT 公司么?
程序員如何快速上手一個自己不太熟悉的新項目?有什麼技巧?

TAG:互聯網 | 程序員 | 軟體開發 | iOS開發 | Android開發 | 軟體工程師 |