程序員生存定律--成長路上常見的坑
1.“博”與“專”上的迷失
假設(shè)說一個人的學(xué)習已經(jīng)聚焦,并且學(xué)習的內(nèi)容和自己實際參與的項目也相吻合,那么是不是就沒有問題了?很不幸,答案仍然是否定的,在任何一個子領(lǐng)域里,仍然需要進一步去考慮“博”與“專”的均衡。
對于軟件開發(fā)而言,設(shè)計是再常見不過,再簡單不過的一個詞了。可如果把視角拔高一點就會發(fā)現(xiàn),單以設(shè)計而論仍然是一個不可窮盡的領(lǐng)域,我們可以快速掃描一下和設(shè)計相關(guān)的部分概念:
(1)面向?qū)ο蠓治雠c設(shè)計
(2) 結(jié)構(gòu)化分析與設(shè)計
(3) 模型驅(qū)動開發(fā)
(4) 契約式編程
(5) 面向方面的開發(fā)
(6)基于組件的開發(fā)
(7)元編程
有些時候方法論也會和設(shè)計牽扯到一起:
(1)測試驅(qū)動開發(fā)
(2)敏捷軟件開發(fā)
如果感覺這個還不夠多,那可以去Wiki上查編程的范式(paradigms)這個條目,那里列了47種范式,每個都和設(shè)計多少有點關(guān)系。
上述這些還只是說了設(shè)計,如果橫向展開,那么在特定領(lǐng)域中必然還會牽涉到框架的選用、輔助工具的使用等等。這也就意味著,從博的角度來看,即使是在設(shè)計這樣一個看似狹小的領(lǐng)域中仍然是沒邊界的。
與此同時,把一個API研究的再透,也是低值人群,因為這種深入理解和單純會用某個API相比,從創(chuàng)造價值的角度看,差別不大。
這也就意味著對于大多數(shù)軟件開發(fā)人員而言,要去尋找廣博與精專間的均衡點:既不能閉上眼睛,也不能就用顯微鏡來看世界。而這一均衡點的價值則可用反木桶原理來說明:木桶原理說的是桶里的水是由最短的一塊板決定的,但考量人的價值時卻是適用于反木桶原理,即人的價值往往由最長的一塊板決定。
考慮博和專的問題不能離開產(chǎn)品開發(fā)進行考慮,前面曾經(jīng)提到過,產(chǎn)品開發(fā)往往和公司的現(xiàn)金流綁定的更緊,能為現(xiàn)金流貢獻力量的技術(shù)才是有價值的技術(shù)。而產(chǎn)品開發(fā)本身事實上對博和專的程度提出了最基本的要求,這種要求往往具有迭代的特質(zhì)。為了形象的說明這一點,這里舉一個通用的例子來進行一點說明:
在第一次跌代里,往往需要達到兩個最基本的目標。第一個目標是可以為產(chǎn)品貢獻自己力量,但代碼質(zhì)量普通。這個目標如果達不到,一個人會失去自己的存在價值。
這時候最少需要了解某種語言(比如:C++)、某個平臺(比如:Windows)、某個IDE(比如:VisualStudio)和某些業(yè)務(wù)相關(guān)的知識(比如:打印體系)。這個范圍可以盡可能圈的小點,但用到的則要學(xué)透。比如:不管接觸到那個框架,都要去了解它的內(nèi)存機制、線程機制、異常處理組件構(gòu)建和國際化處理這些全局性的機制,而不能只是了解某個接口怎么用。
這并非是很高的要求,沒有這些就變成了“靠運氣編程”,寫完程序后還要祈禱他能跑起來。了解這些之后就可以負擔起部分開發(fā)工作,否則的話只能做旁觀者,沒法參與到實際工作中來。
第二個目標是把事情做好,并能負擔些層次更高的工作。這時候要比較深入的了解面向?qū)ο蟆⒔Y(jié)構(gòu)化方法、設(shè)計模式、理解設(shè)計原則,并能把它們用好。至少要能判定,這個程序?qū)懙暮茫莻€程序?qū)懙牟缓茫瑫r面對需求能把工作進行下去。
前兩個目標是基礎(chǔ),一般來講學(xué)校中基礎(chǔ)打的越好,這個階段越短。達成這兩個基本目標之后就可以結(jié)合情境來做進一步的選擇,可以認為這是博與專選擇上的第二次迭代。當然這時候也要謹記不要和實踐分開。
完成上述兩個層次后,可以有兩個方向可供選擇:
(1)可以進一步考慮專的問題,比如在特定領(lǐng)域里把知識深化下去。做驅(qū)動就要理解操作系統(tǒng)的核心機制,做打印的就要了解頁面描述語言等,但這個時候要適當警惕邊際效應(yīng)。
邊際效應(yīng)是說,你讓一畝地從畝產(chǎn)500斤增加到1000斤可能只需要投入100塊;讓畝產(chǎn)從1000增加到1500可能就需要200塊;讓畝產(chǎn)從1500增加到2000則需要400塊了。
一個典型的例子是對C++的學(xué)習,C++是公認的復(fù)雜,如果想做C++的律師,那么估計搞個10年可能夠資格了,但問題是把時間都投在這個上,投入產(chǎn)出比可能不好。而停在那里合適則是個尺度問題,大致來講是可以靠時間彌補的細節(jié)問題,并不適合專到最底層。比如對于100萬行的程序,預(yù)先花時間去了解每一處細節(jié),就有點過了。
(2)可以把博再推進一步,比如:熟悉專門領(lǐng)域的專業(yè)知識、熟悉多種既存框架的特性、熟悉提高用戶體驗的關(guān)鍵點。熟悉多種既存框架的特性的具體含義是:
設(shè)計某一種解決方案時,首先要考慮的就是是自己開發(fā)還是使用現(xiàn)有的模塊。一旦決定使用現(xiàn)有的模塊(包,框架等),那就要進一步考慮究竟用那個。
做這類工作時,如果沒有一定廣博的知識,做選擇的時候就會特別的艱難。
假使說現(xiàn)在公司內(nèi)部要導(dǎo)入一套項目管理系統(tǒng),那么做決定的負責人必須至少考慮所有下面這些事情:
(1)自己從頭造,還是用現(xiàn)成的做二次開發(fā)?
(2)用現(xiàn)成的,是用開源產(chǎn)品,微軟的還是其他公司的?
(3)用微軟的話,是用MSProject還是基于SharePoint,還是混合?考慮License費用的話真的劃算么?
(4)用開源產(chǎn)品,有這么多選項究竟導(dǎo)入那一個?
(5)如果自己從頭造,那么是基于微軟的技術(shù),還是基于LAMP這樣的技術(shù)?
(6)使用什么框架?
(7)如果要做,用什么語言?
一個人很難精通上面所有的領(lǐng)域,但當做選擇時,完全沒有概念也是災(zāi)難性的。
此外,考慮博與專平衡點時似乎有一種特例,鉆研特定算法的人,從一開始就只往專的方向發(fā)展,并不會考慮其他。比如:鉆研TTS的人,可能幾十年如一日只要專注于TTS就完了。
至于具體選擇那個方向,則要根據(jù)自身情形來定。總的原則是要以當下工作為根基,以實用為目的甄選各種知識,并追求平衡點。
大致上講,期望做技術(shù)專家的更適合前一個方向,而期望做技術(shù)管理的則更適合后一類方向。
學(xué)習軟件工程的時機與必要性
簡單來講越是沒實踐經(jīng)驗的人越不適合學(xué)習軟件工程,越需要規(guī)劃整體把握全局的時候越需要學(xué)習軟件工程。
軟件工程中覆蓋的元素非常繁雜,可以有管理、流程、開發(fā)模型、估算、分析設(shè)計方法等。這無疑會把知識面擴展的很寬,一旦沒有根底,就很容易變成紙上談兵,夸夸其談。
在眾多軟件相關(guān)的知識中,軟件工程絕對是很特別的一個。很多人很鄙視軟件工程,說:我一看到軟件工程的書就直接略過;與之相對應(yīng),很多人很推崇軟件工程,會花很大的心思去研究敏捷、CMMI等。
剛?cè)肼殘龅某绦騿T大致上是討厭軟件工程的,因為這東西離自己的實踐有點遠,并且主要是添加束縛。但既然更加復(fù)雜紛繁的歷史都可以總結(jié)出規(guī)律,忽視軟件開發(fā)的內(nèi)在規(guī)律無疑的對有志于成為管理者的人是不利的。
真要學(xué)習軟件工程,不太適合從抽象層次很高的教科書開始,而適合從《代碼大全》這樣與實際關(guān)聯(lián)比較緊密的書籍開始。
在國內(nèi)軟件工程的落地似乎始終困難,軟件工程相關(guān)名詞始終在不停的變換(ISO,CMMI,敏捷等),但實際能落地起作用的卻不多,這最終導(dǎo)致了一種吊詭的局面:剛對一個絕望,就開始對新的一個報以希望,并在這兩個簡單的步驟上做無限循環(huán)。這種狀況也許有其更深層次的原因,比如生存壓力過于強大導(dǎo)致工程力量的長遠價值被漠視,進而使方法論并不為解決現(xiàn)實問題而存在,而是為了證書而存在。很難據(jù)此就說軟件工程毫無價值。
2.錯過人生中的好時機
沒畢業(yè)的程序員或者剛畢業(yè)的程序員往往感覺空余時間比較充沛,還很苦惱不知道如何打發(fā)時間,但實際上一個人一生中可以用于充電的時間遠比想的少。一旦錯過時機,往往悔之莫及。
對于大多數(shù)人而言,人生就像個模板,小處還有偏差,大處卻基本相同。
20~30歲這個階段可以講是黃金時期,這個階段里,家庭負擔較小,可以自由支配的時間較多。當然撞到了很特別的、需要瘋狂加班的公司只能另算。
30歲之后因為娃娃出生等,家庭上的時間開銷增加,個人可支配時間變少。其中很大一部分人還有很大可能會面對電視劇里常說的婆媳矛盾,讓你每天心緒不寧。
40歲之后,家庭瑣事會進一步增加,典型的上有老下有小。實在運氣不好的自己也會生點病---頸椎病、腰間盤突出、胃病大概可以入選程序員的三大職業(yè)病。
50歲之后,時間上會再次解脫,但可惜的是自己也老了,時機不在。
如果把人生按照年齡畫一條拋物線的話,40歲左右一個人可以達到的人生的頂點,未來再突破的幾率則變小。從歷史人物來看,大器晚成的不是沒有,但真的很少。
用心觀察就會發(fā)現(xiàn),招聘啟示里經(jīng)常會注明年齡要在35周歲以下或者40周歲以下,除非是招聘高層。這反過來意味著如果沒有到高層,人生會在40之前定型,之后有下滑危險(如遭遇不景氣、公司倒閉等)。對程序員而言,這種風險尤其的大,因為很可能你辛苦掌握的知識體系被更迭掉了。
學(xué)習本身無疑的是需要順應(yīng)這種自然規(guī)律的。
很多人很大的一個錯誤在于,在黃金時期,沒做什么積累,就顧得享受生活了,而一旦意識到積累的必要性時,卻又受困于諸多瑣事而欲振乏力,最終人生高度有限,并迅速走低。這就是現(xiàn)代程序員版的“少壯不努力,老大徒傷悲”。
基本上講,35歲以前要把需要花大量時間,比較硬的技能,學(xué)習曲線陡的技能掌握,具備工作所需要的所有主要技能,而35歲之后則主要關(guān)注知識的更新和某些軟技能。
學(xué)習時添水戰(zhàn)術(shù)效率真的很差,每次點一根火柴燒水,一億年水也燒不開一壺。同時,比較硬的技能(比如:DonaldKnuth的《計算機程序設(shè)計藝術(shù)》)往往是需要大塊時間投入的,但年紀越大時間越呈現(xiàn)為碎片化,越難搞定硬的知識---先天就容易造就添水戰(zhàn)術(shù)。比較軟的技能,則可以用碎片時間來學(xué)習,比如:提高PPT的制作水平,提高表達能力。
如果能夠安排好自己的時間和軟硬知識的關(guān)系,那么就可以在特定基礎(chǔ)上做積累,小步前進,使自己的價值越來越高。從這個角度看,年輕絕對是一種債務(wù),大多數(shù)人必須在他沒完全結(jié)束前,還掉所欠的東西。
那么具體來講那些東西是比較硬的,要在35歲前搞定呢?這因目標而異,但下面這些項目應(yīng)該具有非常高的通用性:
(1)精通一門最常用的語言
(2) 了解一個最常用平臺的基本機制,比如:內(nèi)存管理、線程機制等
(3)UML圖和面向?qū)ο蠓治鲈O(shè)計方法
(4) 設(shè)計原則,如:職責單一等
(5) 設(shè)計模式
(6)《代碼大全》里講的一切
(7)精讀一個知名的,但有點規(guī)模的程序。這點上要感謝開源項目給我們提供了這么多優(yōu)秀程序。但要謹防好高騖遠,動輒挑戰(zhàn)Linux內(nèi)核,精讀是關(guān)鍵。
(8) 累積一定的代碼量,比如:獨立的完整做過一個數(shù)萬代碼行的東西。這里的關(guān)鍵是完全自己打造,一定不要拷貝粘貼。
(9) 掌握基本算法和數(shù)據(jù)結(jié)構(gòu)(可以不自己寫,但至少要知道其復(fù)雜度和區(qū)別)
(10) 養(yǎng)成一種清晰的編碼風格
(11) 有自己的專業(yè)(金融、高并發(fā)網(wǎng)站,圖像處理,TTS等)
學(xué)習英語的時機和必要性
總的來看,程序員學(xué)習英語是一項投資回報率相對比較好的投入。從目標上來看,程序員未必一定要口語流利,但最低要達到閱讀英文資料沒有障礙的程度。這里面有一個微妙的事情,一旦英語閱讀問題較大,查找問題會習慣用百度,這天然會限制一個人的視野。不是說百度自身有多不好,而是說英語的世界里有著更多更精彩的內(nèi)容。不管喜歡不喜歡,我們必須承認一種現(xiàn)實,在IT的世界里英語是一種世界語,一方面是由于美國公司的強大,一方面則是由于開源選擇了英語。這最終導(dǎo)致IT世界里的新動向、解決問題的小技巧、網(wǎng)站的架構(gòu)等等都要到英語的世界里去找。在StackOverlow很容易找到各種小問題的答案,在Quora則很容易找到各種網(wǎng)站的架構(gòu)。
從學(xué)習時機來看,這件事情特別應(yīng)該在大學(xué)里面搞定,如果不行至少也要在畢業(yè)1~2年內(nèi)達到閱讀無障礙的程度,當然希望加入外企還需要額外的付出。從學(xué)習方法來看,學(xué)習外語真沒什么特別的竅門,堅持并投入時間即可。
3.停止知識更新
對程序員的增值而言,人生里最大的陷阱也許是為安全的假象所欺騙而徹底的放松自己。這種狀況在生存環(huán)境比較惡劣的情形下不太會發(fā)生,但在壟斷企業(yè)或某一領(lǐng)域中絕對領(lǐng)先的企業(yè)里則容易滋生。發(fā)現(xiàn)自己是否停止知識更新了并不困難,比如:一年一本書沒看,一年一點新知識沒接觸,一年中工作負荷基本不滿等都可以成為一種信號。
這真的是溫水煮青蛙,一旦到了三十幾歲,并在這種環(huán)境中呆習慣了,那么再想跳出來,基本沒可能。唯一能做的事情是,祈禱公司不要掛掉,公司也不要來場運動,進行人員的大換血。孔夫子說:日當三省吾身,這是很有必要的,至于認識危險后能否做點什么,那就是事在人為了。
(1)技術(shù)人員的知識更新
接觸一個新的崗位后,大致要經(jīng)歷一個學(xué)習并逐漸勝任的過程,這個時間段里大多數(shù)人的學(xué)習熱情是很高的。一旦基本勝任之后,事情就有了變化。
很大一部分人可能會感覺,反正工作也就用到這么些知識,學(xué)習其他的也用不上,因此開始把自己封閉起來,不太看書,不太看技術(shù)新聞。
這其實很危險,因為這種做法等于把自己綁死在當前這份工作上。而任何一個產(chǎn)品都有自己的生命周期,一旦一個產(chǎn)品的生命周期結(jié)束時,碰巧其所用的技術(shù)也已經(jīng)過時,那么當事人就會很尷尬。因為產(chǎn)品可以結(jié)束,生活卻還得繼續(xù)。
這里面一個非常經(jīng)典的例子是MFC。微軟的這款產(chǎn)品的歷史非常悠久,從1992年發(fā)布到2012年幾近存在了20年時間。隨著90后程序員的逐漸出現(xiàn),馬上這款技術(shù)就要變得比程序員的年紀還要大了。
即使到今天,很多桌面應(yīng)用仍然是基于MFC開發(fā)的,這可以通過查看程序包的dll依賴來很容易的進行驗證。MFC是一個很大的池子,有深度、有歷史。想把MFC的類繼承關(guān)系、消息機制、框架結(jié)構(gòu)、RTTI、序列化都搞清楚還是要很花一點時間的。
現(xiàn)在我們假設(shè)一款龐大的企業(yè)應(yīng)用是基于MFC開發(fā)的,一個程序員也通過幾年的努力了解了MFC,了解了應(yīng)用本身,并可以負擔起B(yǎng)ug修正,新功能追加等任務(wù)了。
接下來這個程序員似乎沒什么好學(xué)的了。因為MFC的更新幾乎已經(jīng)停滯,因此對MFC的學(xué)習幾乎不需要花太多的時間了。現(xiàn)有代碼也理清楚了,也不需要再花很多時間學(xué)習了。現(xiàn)有程序也比較好的滿足了企業(yè)的需求,推倒重來的可能性幾乎沒有。
那這個時候這個程序員不需要學(xué)習了么?答案一定是否定的。
這里面蘊藏著一個天大的矛盾。
從企業(yè)的角度看,一定是需要一個團隊來維持這個程序的開發(fā)的。但從個人的角度看,如果把所有的青春都耗費在老技術(shù)上,那么一旦老技術(shù)退出歷史舞臺,個人該何去何從?
還是上面的例子,假設(shè)說一個人持續(xù)投入在這類開發(fā)上,當他45歲的時候,當前產(chǎn)品生命周期結(jié)束,世界變的只有移動開發(fā)和云端開發(fā),那么只擅長MFC的他該何去何從?
如果真的如此,這個人就被逼到了死角里,人生很可能產(chǎn)生巨大滑落。所以一定不能認為所學(xué)足夠而停止技能的更新與學(xué)習。
從具體應(yīng)對措施來看,一是要參照知識的地圖,橫向擴展知識的廣度,比如不只要盯著代碼,也要了解業(yè)務(wù);不只關(guān)注開發(fā)也關(guān)注一點估算;二是提升可流動性比較好的東西的掌握程度,比如:面向?qū)ο蠓治雠c設(shè)計,這樣跨越到其他技術(shù)時就能夠比較平緩的進行過渡。三是要爭取輪換崗位,爭取多種實踐機會。
(2)管理者的知識更新
到現(xiàn)在為止大部分人認同,管理者是需要懂技術(shù)的。從邏輯上看“懂”基本上是不瞎指揮的前提,所以這可以稱為中國版的“現(xiàn)場主義”,估計爭議不大。
那關(guān)鍵問題就是究竟要“懂”到什么程度?
如果說兩個人,一個選擇了管理方向,一個選了技術(shù)方向。接下來要求管理方向上的人技術(shù)水平要和技術(shù)方向的一樣,那么除非這個人特別天才,否則不太可能。正像前面所說,這是由于這兩個方向的“Key”不同所造成的。
如果把目標設(shè)定為確保最終產(chǎn)品的成功,同時假設(shè)管理者有更高的決策權(quán),那么管理者必須在下面這些方面有技術(shù)感覺。
從做產(chǎn)品來看,要想成功,有兩個關(guān)鍵維度需要同時進行把握,一是產(chǎn)品的概念完整性的把握;一是用合適的手段去實現(xiàn)這個產(chǎn)品。
前一個話題很老,《人月神話》就有提及,但實踐中卻總是被人忘記。好的產(chǎn)品必須貫徹某一種統(tǒng)一意志,iPhone、微信又重新驗證了這一個老的原則。機械拼湊的產(chǎn)品雖然融合了很多人的想法,但往往是平庸的,并且在項目執(zhí)行過程中,往往是出錯的根源。很像是雖然有法律,但每個人有自己的理解,各行其是這樣一個狀態(tài)。這種概念完整性是管理者第一個需要有所把握的事情,其次就是解決如何去構(gòu)建產(chǎn)品這個問題。為達成這一目標在下面這幾個方面上,管理者要有自己的理解,至少要有自己的原則:
下面簡單列舉幾個比較關(guān)鍵的考量,這和前面論及的如何往博的方向發(fā)展有點重疊:
(1)使用現(xiàn)有產(chǎn)品還是自己開發(fā)
比如:那些模塊適合自己搞定而那些購入就可以了。購入的時候要遵循怎么樣的標準去選擇。
(2)使用那種平臺技術(shù)
比如:是使用微軟的技術(shù),還是開源的技術(shù)。
(3)現(xiàn)行架構(gòu)是否可以達成產(chǎn)品目標
比如:在硬件加軟件可以同時支撐的并發(fā)數(shù)目。
(4)代碼可維護性如何約束
這要求必須熟練掌握一些原則性的東西,比如:什么信息隱藏、正交分解、抽象是否充分等。以及一些無歧義指標,比如:圈復(fù)雜度,單元測試的收益平衡。
(5)那些環(huán)節(jié)必須固化為流程,那些一定要團隊自由決定
比如文檔化要到什么程度才合適,不同階段間什么是必須的輸入輸出。
......
假設(shè)說有人不這么認為,而是在做了管理后,表現(xiàn)出足夠的惰性,不再持續(xù)更新自己的知識體系了,那么會發(fā)生什么事情?
這時候會很可能會管理倒置。即管理者是名義上的上級,但基本失去對現(xiàn)場的把握,所有的決策完全依賴于下屬。得力下屬不在,各種決定就只能靠瞎蒙,最終變成只會溝通的管理者---即使被食人族吃了也不會有人注意到,因為存在價值已經(jīng)被無限稀釋,變成了一個象征性的符號。也可能會和下屬爆發(fā)激烈沖突。因為這類管理者沒有自己的立場,上面有任務(wù)只能下壓。結(jié)果同實際情況偏離萬里,不具有可實現(xiàn)性,這類管理者無法對自己的上司陳述,也就只能向下轉(zhuǎn)移壓力。
不管是那種,一旦到這種地步,其實是趨于失敗,只能祈禱食人族不要來。
為什么中層管理者也要堅持知識更新?
在IT行業(yè)流傳著一個很有名的關(guān)于食人族的笑話,這個笑話說的是:
兩個食人族的人應(yīng)聘進了某家大公司,公司人事主管知道這兩個這伙每天都要吃人,于是警告他們:“如果你們膽敢在公司吃一個人,你們就會立即被炒掉!”兩個食人族唯唯喏喏地答應(yīng),表示絕不會在公司吃人。兩個月過去了,公司平安無事。
突然有一天,公司發(fā)現(xiàn)負責打掃公司衛(wèi)生的清潔工不見了。于是人事主管非常氣憤,找來兩個食人族怒斥,并當場炒掉了他們。出了公司大門,一個食人族馬上對另一個抱怨起來:“我一直警告你不要吃有在做事的人,你就是不聽!我們兩個月來每天吃一個經(jīng)理,沒人發(fā)現(xiàn)。你看現(xiàn)在吃了清潔工,他們馬上就發(fā)現(xiàn)了!你真是個豬!”
這個笑話嘲諷的是某些大公司大企業(yè)病發(fā)作,人浮于事。大企業(yè)病的成因很難一下子說的清楚,但結(jié)果卻比較明顯,一定會導(dǎo)致較多人成為中層管理者。如果說成功的企業(yè)天然有感染大企業(yè)病的趨勢,那無疑的中層管理者也天然有著膨脹趨勢。從個人角度看,成為被食人魔吃掉也沒有人在意的經(jīng)歷并非是什么好事,因為這意味著存在價值減弱,也不需要什么知識更新。一旦面臨裁員這類事情,這個人很可能已經(jīng)失去了面對殘酷競爭的能力。
本文鏈接:http://www.cocoachina.com/gamedev/misc/2014/0811/9354.html