程序員生存定律--成長路上常見的坑

1.“博”與“專”上的迷失

 

假設說一個人的學習已經聚焦,並且學習的內容和自己實際參與的項目也相吻合,那麼是不是就沒有問題了?很不幸,答案仍然是否定的,在任何一個子領域裏,仍然需要進一步去考慮“博”與“專”的均衡。

 

對於軟件開發而言,設計是再常見不過,再簡單不過的一個詞了。可如果把視角拔高一點就會發現,單以設計而論仍然是一個不可窮盡的領域,我們可以快速掃描一下和設計相關的部分概念:

 

(1)面向對象分析與設計

(2) 結構化分析與設計

(3) 模型驅動開發

(4) 契約式編程

(5) 面向方面的開發

(6)基於組件的開發

(7)元編程

 

有些時候方法論也會和設計牽扯到一起:

(1)測試驅動開發

(2)敏捷軟件開發

 

如果感覺這個還不夠多,那可以去Wiki上查編程的範式(paradigms)這個條目,那裏列了47種範式,每個都和設計多少有點關係。

 

上述這些還只是說了設計,如果橫向展開,那麼在特定領域中必然還會牽涉到框架的選用、輔助工具的使用等等。這也就意味着,從博的角度來看,即使是在設計這樣一個看似狹小的領域中仍然是沒邊界的。

 

與此同時,把一個API研究的再透,也是低值人羣,因爲這種深入理解和單純會用某個API相比,從創造價值的角度看,差別不大。

 

這也就意味着對於大多數軟件開發人員而言,要去尋找廣博與精專間的均衡點:既不能閉上眼睛,也不能就用顯微鏡來看世界。而這一均衡點的價值則可用反木桶原理來說明:木桶原理說的是桶裏的水是由最短的一塊板決定的,但考量人的價值時卻是適用於反木桶原理,即人的價值往往由最長的一塊板決定。

 

考慮博和專的問題不能離開產品開發進行考慮,前面曾經提到過,產品開發往往和公司的現金流綁定的更緊,能爲現金流貢獻力量的技術纔是有價值的技術。而產品開發本身事實上對博和專的程度提出了最基本的要求,這種要求往往具有迭代的特質。爲了形象的說明這一點,這裏舉一個通用的例子來進行一點說明:

 

在第一次跌代裏,往往需要達到兩個最基本的目標。第一個目標是可以爲產品貢獻自己力量,但代碼質量普通。這個目標如果達不到,一個人會失去自己的存在價值。

 

這時候最少需要了解某種語言(比如:C++)、某個平臺(比如:Windows)、某個IDE(比如:VisualStudio)和某些業務相關的知識(比如:打印體系)。這個範圍可以儘可能圈的小點,但用到的則要學透。比如:不管接觸到那個框架,都要去了解它的內存機制、線程機制、異常處理組件構建和國際化處理這些全局性的機制,而不能只是瞭解某個接口怎麼用。

 

這並非是很高的要求,沒有這些就變成了“靠運氣編程”,寫完程序後還要祈禱他能跑起來。瞭解這些之後就可以負擔起部分開發工作,否則的話只能做旁觀者,沒法參與到實際工作中來。

 

第二個目標是把事情做好,並能負擔些層次更高的工作。這時候要比較深入的瞭解面向對象、結構化方法、設計模式、理解設計原則,並能把它們用好。至少要能判定,這個程序寫的好,那個程序寫的不好,同時面對需求能把工作進行下去。

 

前兩個目標是基礎,一般來講學校中基礎打的越好,這個階段越短。達成這兩個基本目標之後就可以結合情境來做進一步的選擇,可以認爲這是博與專選擇上的第二次迭代。當然這時候也要謹記不要和實踐分開。

 

完成上述兩個層次後,可以有兩個方向可供選擇:

(1)可以進一步考慮專的問題,比如在特定領域裏把知識深化下去。做驅動就要理解操作系統的核心機制,做打印的就要了解頁面描述語言等,但這個時候要適當警惕邊際效應。

 

邊際效應是說,你讓一畝地從畝產500斤增加到1000斤可能只需要投入100塊;讓畝產從1000增加到1500可能就需要200塊;讓畝產從1500增加到2000則需要400塊了。

 

一個典型的例子是對C++的學習,C++是公認的複雜,如果想做C++的律師,那麼估計搞個10年可能夠資格了,但問題是把時間都投在這個上,投入產出比可能不好。而停在那裏合適則是個尺度問題,大致來講是可以靠時間彌補的細節問題,並不適合專到最底層。比如對於100萬行的程序,預先花時間去了解每一處細節,就有點過了。

 

(2)可以把博再推進一步,比如:熟悉專門領域的專業知識、熟悉多種既存框架的特性、熟悉提高用戶體驗的關鍵點。熟悉多種既存框架的特性的具體含義是:

 

設計某一種解決方案時,首先要考慮的就是是自己開發還是使用現有的模塊。一旦決定使用現有的模塊(包,框架等),那就要進一步考慮究竟用那個。

 

做這類工作時,如果沒有一定廣博的知識,做選擇的時候就會特別的艱難。

 

假使說現在公司內部要導入一套項目管理系統,那麼做決定的負責人必須至少考慮所有下面這些事情:

(1)自己從頭造,還是用現成的做二次開發?

(2)用現成的,是用開源產品,微軟的還是其他公司的?

(3)用微軟的話,是用MSProject還是基於SharePoint,還是混合?考慮License費用的話真的划算麼?

(4)用開源產品,有這麼多選項究竟導入那一個?

(5)如果自己從頭造,那麼是基於微軟的技術,還是基於LAMP這樣的技術?

(6)使用什麼框架?

(7)如果要做,用什麼語言?

 

一個人很難精通上面所有的領域,但當做選擇時,完全沒有概念也是災難性的。

 

此外,考慮博與專平衡點時似乎有一種特例,鑽研特定算法的人,從一開始就只往專的方向發展,並不會考慮其他。比如:鑽研TTS的人,可能幾十年如一日只要專注於TTS就完了。

 

至於具體選擇那個方向,則要根據自身情形來定。總的原則是要以當下工作爲根基,以實用爲目的甄選各種知識,並追求平衡點。

 

大致上講,期望做技術專家的更適合前一個方向,而期望做技術管理的則更適合後一類方向。

 

學習軟件工程的時機與必要性

 

簡單來講越是沒實踐經驗的人越不適合學習軟件工程,越需要規劃整體把握全局的時候越需要學習軟件工程。

 

軟件工程中覆蓋的元素非常繁雜,可以有管理、流程、開發模型、估算、分析設計方法等。這無疑會把知識面擴展的很寬,一旦沒有根底,就很容易變成紙上談兵,誇誇其談。

 

在衆多軟件相關的知識中,軟件工程絕對是很特別的一個。很多人很鄙視軟件工程,說:我一看到軟件工程的書就直接略過;與之相對應,很多人很推崇軟件工程,會花很大的心思去研究敏捷、CMMI等。

 

剛入職場的程序員大致上是討厭軟件工程的,因爲這東西離自己的實踐有點遠,並且主要是添加束縛。但既然更加複雜紛繁的歷史都可以總結出規律,忽視軟件開發的內在規律無疑的對有志於成爲管理者的人是不利的。

 

真要學習軟件工程,不太適合從抽象層次很高的教科書開始,而適合從《代碼大全》這樣與實際關聯比較緊密的書籍開始。

 

在國內軟件工程的落地似乎始終困難,軟件工程相關名詞始終在不停的變換(ISO,CMMI,敏捷等),但實際能落地起作用的卻不多,這最終導致了一種弔詭的局面:剛對一個絕望,就開始對新的一個報以希望,並在這兩個簡單的步驟上做無限循環。這種狀況也許有其更深層次的原因,比如生存壓力過於強大導致工程力量的長遠價值被漠視,進而使方法論並不爲解決現實問題而存在,而是爲了證書而存在。很難據此就說軟件工程毫無價值。

 

2.錯過人生中的好時機

 

沒畢業的程序員或者剛畢業的程序員往往感覺空餘時間比較充沛,還很苦惱不知道如何打發時間,但實際上一個人一生中可以用於充電的時間遠比想的少。一旦錯過時機,往往悔之莫及。

 

對於大多數人而言,人生就像個模板,小處還有偏差,大處卻基本相同。

 

20~30歲這個階段可以講是黃金時期,這個階段裏,家庭負擔較小,可以自由支配的時間較多。當然撞到了很特別的、需要瘋狂加班的公司只能另算。

 

30歲之後因爲娃娃出生等,家庭上的時間開銷增加,個人可支配時間變少。其中很大一部分人還有很大可能會面對電視劇裏常說的婆媳矛盾,讓你每天心緒不寧。

 

40歲之後,家庭瑣事會進一步增加,典型的上有老下有小。實在運氣不好的自己也會生點病---頸椎病、腰間盤突出、胃病大概可以入選程序員的三大職業病。

 

50歲之後,時間上會再次解脫,但可惜的是自己也老了,時機不在。

 

如果把人生按照年齡畫一條拋物線的話,40歲左右一個人可以達到的人生的頂點,未來再突破的機率則變小。從歷史人物來看,大器晚成的不是沒有,但真的很少。

 

用心觀察就會發現,招聘啓示裏經常會註明年齡要在35週歲以下或者40週歲以下,除非是招聘高層。這反過來意味着如果沒有到高層,人生會在40之前定型,之後有下滑危險(如遭遇不景氣、公司倒閉等)。對程序員而言,這種風險尤其的大,因爲很可能你辛苦掌握的知識體系被更迭掉了。

 

學習本身無疑的是需要順應這種自然規律的。

 

很多人很大的一個錯誤在於,在黃金時期,沒做什麼積累,就顧得享受生活了,而一旦意識到積累的必要性時,卻又受困於諸多瑣事而欲振乏力,最終人生高度有限,並迅速走低。這就是現代程序員版的“少壯不努力,老大徒傷悲”。

 

基本上講,35歲以前要把需要花大量時間,比較硬的技能,學習曲線陡的技能掌握,具備工作所需要的所有主要技能,而35歲之後則主要關注知識的更新和某些軟技能。

 

學習時添水戰術效率真的很差,每次點一根火柴燒水,一億年水也燒不開一壺。同時,比較硬的技能(比如:DonaldKnuth的《計算機程序設計藝術》)往往是需要大塊時間投入的,但年紀越大時間越呈現爲碎片化,越難搞定硬的知識---先天就容易造就添水戰術。比較軟的技能,則可以用碎片時間來學習,比如:提高PPT的製作水平,提高表達能力。

 

如果能夠安排好自己的時間和軟硬知識的關係,那麼就可以在特定基礎上做積累,小步前進,使自己的價值越來越高。從這個角度看,年輕絕對是一種債務,大多數人必須在他沒完全結束前,還掉所欠的東西。

 

那麼具體來講那些東西是比較硬的,要在35歲前搞定呢?這因目標而異,但下面這些項目應該具有非常高的通用性:

(1)精通一門最常用的語言

(2) 瞭解一個最常用平臺的基本機制,比如:內存管理、線程機制等

(3)UML圖和麪向對象分析設計方法

(4) 設計原則,如:職責單一等

(5) 設計模式

(6)《代碼大全》裏講的一切

(7)精讀一個知名的,但有點規模的程序。這點上要感謝開源項目給我們提供了這麼多優秀程序。但要謹防好高騖遠,動輒挑戰Linux內核,精讀是關鍵。

(8) 累積一定的代碼量,比如:獨立的完整做過一個數萬代碼行的東西。這裏的關鍵是完全自己打造,一定不要拷貝粘貼。

(9) 掌握基本算法和數據結構(可以不自己寫,但至少要知道其複雜度和區別)

(10) 養成一種清晰的編碼風格

(11) 有自己的專業(金融、高併發網站,圖像處理,TTS等)

 

學習英語的時機和必要性

總的來看,程序員學習英語是一項投資回報率相對比較好的投入。從目標上來看,程序員未必一定要口語流利,但最低要達到閱讀英文資料沒有障礙的程度。這裏面有一個微妙的事情,一旦英語閱讀問題較大,查找問題會習慣用百度,這天然會限制一個人的視野。不是說百度自身有多不好,而是說英語的世界裏有着更多更精彩的內容。不管喜歡不喜歡,我們必須承認一種現實,在IT的世界裏英語是一種世界語,一方面是由於美國公司的強大,一方面則是由於開源選擇了英語。這最終導致IT世界裏的新動向、解決問題的小技巧、網站的架構等等都要到英語的世界裏去找。在StackOverlow很容易找到各種小問題的答案,在Quora則很容易找到各種網站的架構。

 

從學習時機來看,這件事情特別應該在大學裏面搞定,如果不行至少也要在畢業1~2年內達到閱讀無障礙的程度,當然希望加入外企還需要額外的付出。從學習方法來看,學習外語真沒什麼特別的竅門,堅持並投入時間即可。

 

3.停止知識更新

 

對程序員的增值而言,人生裏最大的陷阱也許是爲安全的假象所欺騙而徹底的放鬆自己。這種狀況在生存環境比較惡劣的情形下不太會發生,但在壟斷企業或某一領域中絕對領先的企業裏則容易滋生。發現自己是否停止知識更新了並不困難,比如:一年一本書沒看,一年一點新知識沒接觸,一年中工作負荷基本不滿等都可以成爲一種信號。

 

這真的是溫水煮青蛙,一旦到了三十幾歲,並在這種環境中呆習慣了,那麼再想跳出來,基本沒可能。唯一能做的事情是,祈禱公司不要掛掉,公司也不要來場運動,進行人員的大換血。孔夫子說:日當三省吾身,這是很有必要的,至於認識危險後能否做點什麼,那就是事在人爲了。

 

(1)技術人員的知識更新

接觸一個新的崗位後,大致要經歷一個學習並逐漸勝任的過程,這個時間段裏大多數人的學習熱情是很高的。一旦基本勝任之後,事情就有了變化。

 

很大一部分人可能會感覺,反正工作也就用到這麼些知識,學習其他的也用不上,因此開始把自己封閉起來,不太看書,不太看技術新聞。

 

這其實很危險,因爲這種做法等於把自己綁死在當前這份工作上。而任何一個產品都有自己的生命週期,一旦一個產品的生命週期結束時,碰巧其所用的技術也已經過時,那麼當事人就會很尷尬。因爲產品可以結束,生活卻還得繼續。

 

這裏面一個非常經典的例子是MFC。微軟的這款產品的歷史非常悠久,從1992年發佈到2012年幾近存在了20年時間。隨着90後程序員的逐漸出現,馬上這款技術就要變得比程序員的年紀還要大了。

 

即使到今天,很多桌面應用仍然是基於MFC開發的,這可以通過查看程序包的dll依賴來很容易的進行驗證。MFC是一個很大的池子,有深度、有歷史。想把MFC的類繼承關係、消息機制、框架結構、RTTI、序列化都搞清楚還是要很花一點時間的。

 

現在我們假設一款龐大的企業應用是基於MFC開發的,一個程序員也通過幾年的努力瞭解了MFC,瞭解了應用本身,並可以負擔起Bug修正,新功能追加等任務了。

 

接下來這個程序員似乎沒什麼好學的了。因爲MFC的更新幾乎已經停滯,因此對MFC的學習幾乎不需要花太多的時間了。現有代碼也理清楚了,也不需要再花很多時間學習了。現有程序也比較好的滿足了企業的需求,推倒重來的可能性幾乎沒有。

 

那這個時候這個程序員不需要學習了麼?答案一定是否定的。

 

這裏面蘊藏着一個天大的矛盾。

 

從企業的角度看,一定是需要一個團隊來維持這個程序的開發的。但從個人的角度看,如果把所有的青春都耗費在老技術上,那麼一旦老技術退出歷史舞臺,個人該何去何從?

 

還是上面的例子,假設說一個人持續投入在這類開發上,當他45歲的時候,當前產品生命週期結束,世界變的只有移動開發和雲端開發,那麼只擅長MFC的他該何去何從?

 

如果真的如此,這個人就被逼到了死角里,人生很可能產生巨大滑落。所以一定不能認爲所學足夠而停止技能的更新與學習。

 

從具體應對措施來看,一是要參照知識的地圖,橫向擴展知識的廣度,比如不只要盯着代碼,也要了解業務;不只關注開發也關注一點估算;二是提升可流動性比較好的東西的掌握程度,比如:面向對象分析與設計,這樣跨越到其他技術時就能夠比較平緩的進行過渡。三是要爭取輪換崗位,爭取多種實踐機會。

 

(2)管理者的知識更新

 

到現在爲止大部分人認同,管理者是需要懂技術的。從邏輯上看“懂”基本上是不瞎指揮的前提,所以這可以稱爲中國版的“現場主義”,估計爭議不大。

 

那關鍵問題就是究竟要“懂”到什麼程度?

 

如果說兩個人,一個選擇了管理方向,一個選了技術方向。接下來要求管理方向上的人技術水平要和技術方向的一樣,那麼除非這個人特別天才,否則不太可能。正像前面所說,這是由於這兩個方向的“Key”不同所造成的。

 

如果把目標設定爲確保最終產品的成功,同時假設管理者有更高的決策權,那麼管理者必須在下面這些方面有技術感覺。

 

從做產品來看,要想成功,有兩個關鍵維度需要同時進行把握,一是產品的概念完整性的把握;一是用合適的手段去實現這個產品。

 

前一個話題很老,《人月神話》就有提及,但實踐中卻總是被人忘記。好的產品必須貫徹某一種統一意志,iPhone、微信又重新驗證了這一個老的原則。機械拼湊的產品雖然融合了很多人的想法,但往往是平庸的,並且在項目執行過程中,往往是出錯的根源。很像是雖然有法律,但每個人有自己的理解,各行其是這樣一個狀態。這種概念完整性是管理者第一個需要有所把握的事情,其次就是解決如何去構建產品這個問題。爲達成這一目標在下面這幾個方面上,管理者要有自己的理解,至少要有自己的原則:

 

下面簡單列舉幾個比較關鍵的考量,這和前面論及的如何往博的方向發展有點重疊:

(1)使用現有產品還是自己開發

比如:那些模塊適合自己搞定而那些購入就可以了。購入的時候要遵循怎麼樣的標準去選擇。

 

(2)使用那種平臺技術

比如:是使用微軟的技術,還是開源的技術。

 

(3)現行架構是否可以達成產品目標

比如:在硬件加軟件可以同時支撐的併發數目。

 

(4)代碼可維護性如何約束

這要求必須熟練掌握一些原則性的東西,比如:什麼信息隱藏、正交分解、抽象是否充分等。以及一些無歧義指標,比如:圈複雜度,單元測試的收益平衡。

 

(5)那些環節必須固化爲流程,那些一定要團隊自由決定

比如文檔化要到什麼程度才合適,不同階段間什麼是必須的輸入輸出。

 

......

 

假設說有人不這麼認爲,而是在做了管理後,表現出足夠的惰性,不再持續更新自己的知識體系了,那麼會發生什麼事情?

 

這時候會很可能會管理倒置。即管理者是名義上的上級,但基本失去對現場的把握,所有的決策完全依賴於下屬。得力下屬不在,各種決定就只能靠瞎蒙,最終變成只會溝通的管理者---即使被食人族吃了也不會有人注意到,因爲存在價值已經被無限稀釋,變成了一個象徵性的符號。也可能會和下屬爆發激烈衝突。因爲這類管理者沒有自己的立場,上面有任務只能下壓。結果同實際情況偏離萬里,不具有可實現性,這類管理者無法對自己的上司陳述,也就只能向下轉移壓力。

 

不管是那種,一旦到這種地步,其實是趨於失敗,只能祈禱食人族不要來。

 

爲什麼中層管理者也要堅持知識更新?

在IT行業流傳着一個很有名的關於食人族的笑話,這個笑話說的是:

 

兩個食人族的人應聘進了某家大公司,公司人事主管知道這兩個這夥每天都要吃人,於是警告他們:“如果你們膽敢在公司吃一個人,你們就會立即被炒掉!”兩個食人族唯唯喏喏地答應,表示絕不會在公司吃人。兩個月過去了,公司平安無事。

 

突然有一天,公司發現負責打掃公司衛生的清潔工不見了。於是人事主管非常氣憤,找來兩個食人族怒斥,並當場炒掉了他們。出了公司大門,一個食人族馬上對另一個抱怨起來:“我一直警告你不要吃有在做事的人,你就是不聽!我們兩個月來每天吃一個經理,沒人發現。你看現在吃了清潔工,他們馬上就發現了!你真是個豬!”

 

這個笑話嘲諷的是某些大公司大企業病發作,人浮於事。大企業病的成因很難一下子說的清楚,但結果卻比較明顯,一定會導致較多人成爲中層管理者。如果說成功的企業天然有感染大企業病的趨勢,那無疑的中層管理者也天然有着膨脹趨勢。從個人角度看,成爲被食人魔吃掉也沒有人在意的經歷並非是什麼好事,因爲這意味着存在價值減弱,也不需要什麼知識更新。一旦面臨裁員這類事情,這個人很可能已經失去了面對殘酷競爭的能力。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章