码路指南
此文章所在專題列表如下:
碼路指南:緣起
?專治各種迷茫
我們這一代的父輩,大部分都不是程序員,沒有從事編程的經驗。以我自己來說,我是2000年初中二年級才接觸的電腦,而那時候也正是個人電腦開始普及的時候,所以我是隨著PC和互聯網蓬勃發展而涌起的編程者大浪中的一員。由于可鑒的前車并不多,這朵大浪會如何走向,又會有多少人拍死在沙灘上,后繼的浪潮我們又該如何正確看待,這些問題其實我們都是要想清楚的。畢竟我們最起碼要生活,那么職業發展問題是個大問題。
我相信很多程序員都會有各種各樣的迷茫,比如:
- 我該如何入門?
- 我該如何提高自己的編程水平?
- 我的編程水平遇到瓶頸了,如何突破?
- 為什么我努力看書學習,還是感覺沒多大提升?
- 我覺得我現在是專家,啥都做得出了!但其實你還是個編程新手
- 我在公司里無晉升/加薪希望,該怎么辦?
- 我都過30歲了,還在編程一線加班,怎么辦?
- 等等……
這些問題我們都需要弄明白。如何自己想不明白,就需要外人點播一下。
我一直關注博客園的“理想流”(http://www.cnblogs.com/daoshi/),很欣賞他獨到的思考,最近看到他出的書,還有寫的“程序員生存定律(http://www.cnblogs.com/daoshi/p/3776814.html)”一系列文章,私以為對指導我們程序員的職業生涯有不錯的幫助,于是拜讀并加以排版整理,后續會再加入自己的一些看法,記錄在“碼路指南”這個專題里。希望更多人看到,也希望幫助更多人解決迷茫。
碼路指南:怎樣才算是編程高手?
高手的定義
一旦度過了初始階段,做過了前面說的那些事情,那么一個人算是基本入行了,接下來的目標就非常簡單,要在選定方向上成為高手。高手意味著專業,而在分工無限細化的年代里,專業則是生存、發展好最為重要的一個前提。
高手的定義和養成關鍵
我估計如果問100個人“什么樣的程序員是高手?”,那答案會有100多個。因為同一個人還可能給高手下不同的定義。
在這里我們認為,在特定領域里能搞定大部分人搞不定事情的就是高手。從這樣一個定義出發,我們會發現在技術人員和銷售人員眼里,高手的內涵是有很大差異的。
純技術人員更多的關注性能能不能提到極致,并發能不能處理的很好,內存溢出Bug能不能很快搞定,類庫的機理熟悉不熟悉等等。而在銷售人員的眼里,則在技術外還多看了些東西,比如業務流程熟不熟悉、使用性好不好、能否迅速對應變化、能否在限定工期和預算下搞定任務等。
考慮到職場和產品銷售有著非常緊密的關系,我們這里使用后一個視角,而非是單純的技術視角。
有幾類本質上很不同的人都會被視為高手,比如說:
- 能寫出很牛的病毒的。這個不舉例子,但當年讀過CIH的代碼,我是被其精巧給震住了。此外也許搞加密解密的也應該放在這個類別里。
- 能把一堆3D圖形放到64K的。以前專門有個比賽是干這個的,64K大小的EXE能給你放10幾分鐘很酷的3D動畫,第一次見絕對會很震驚。
- 能迅速調試出問題所在的。內存泄露、多線程同步這類問題往往讓人糾纏很久也搞不定,但就是有人能很快的解決這類問題。
- 能僅靠幾個人就架起高并發網站的。新興Web2.0網站如:Flickr,甚至還可以包括Google,在初期往往是幾個人搞起來的,這些人名聲不顯,但絕對是高手。
- 能主導開發出很牛的產品的。這個上可以想想Unix和Linux的作者等。
- 能主持大規模軟件設計的。這個往往更有商業價值,我們常說的Martin?Fowler應該可以算在這個類別。
- 能把一種語言研究的特別牛的。想想各個編程語言的創建者,想想C++的大牛們。當然創建某一門語言的也可以歸到這個類別里。
- 能開辟自己方法論的。比如搞CMMI的Watts?S.?Humphrey。
- 能寫出很牛的書的。比如:Windows平臺下寫了Windows核心編程的Jeffry?Richard。
- 能寫出很牛的算法的。比如:Donald?Knuth。
- ……
這個表應該還可以加長很多,單以大家認可這個角度來看確實高手可以從各個方面冒出來。?
不管在那一方面,要想成為上面所描述的高手總是需要學習、思考、實踐這些環節,這沒什么可說的。但和軟件相關的知識其實多如牛毛,完全不像小說里武功秘籍那么稀缺,幾乎可以講滿地都是。這就使選擇和集中成為難題。
軟件的三個基本特征(技術更迭快、低介入門檻、多內部分野)就像鍘刀一樣,一旦選擇出錯,就會把個人的努力切的粉碎,一點價值也留不下來。而與此相對的,則是人的黃金學習時間其實并不多 —— 不過是畢業后的10年左右的時間。
曾經有人希望自己能夠從事嵌入式軟件的開發,因此給自己買了ARM板,自己在家里花了很多時間來學習并實踐相關知識,最終卻因為其他的原因進入了一家做網絡的公司。這個人等價于被軟件的內部分野較多,而彼此間技能流動性較差這樣的一個特質斬了一刀,被斬掉的倒不是ARM板,而是自己一年多的辛苦投入。這種情況下強調學的知識將來有用是沒有太大意義的,因為還有兩刀在等著:如果你三年都不做這個,你今天學到的知識可能會被更迭掉了,同時由于你年紀增長了,可能也不太適合與大批新介入這個行業的人員進行競爭。?
這類事情使軟件行業中的成為高手這事變得復雜了。
為了在成為高手這條路上走的順暢,事實上有三個關鍵點:一是要有一張全局性的地圖,以便選好方向;二是要知道都有那些坑,好繞開它,免得掉進去。三是要有足夠的熱情和動力,能堅持走下去。下面將分別從這三個方面來說明成為高手途徑和方法,而這種途徑和方法會因為具體目標不同而有所微調。
碼路指南:程序員的幾個職場發展方向
職場該如何走?
清代著名學者曾對知識地圖的必要性做過非常精確的表述:
凡讀書最切要者,目錄之學也。目錄明,方可讀書,不明,終是亂讀。
—— 王鳴盛,《十七史商榷》
目錄即是地圖。
對于軟件開發的知識,我更愿意使用下面的的“地圖”,這不一定是最合理的,但確實對歸納各種軟件開發知識有所幫助。
1. 通用的領域知識
※1?有的時候子類別間的界限并不是很容易界定,其中一個主要原因就是存在著像.Net?Framework這樣涵蓋了過多內容的概念。
2. 概念和邏輯創建和優化
※2 ?從形式上來看UML更近似于一種編程語言,但從其目的上來看也許歸在這里是更合適的一種選擇。
3. 專業領域知識
4. 關于軟件的間接知識:
- 需求開發和描述
- 估算
- 估算法。比如,COCOMO,?FP等。
- 估算術。比如,使用計數等原始辦法。
- 軟件工程和方法論
- 輕量型方法論。比如敏捷。
- 大方法論。比如CMMI
- 綜合分析。比如,《人月神話》,《人件》所做的工作。?
隨著待解決問題越來越復雜,通用的領域知識中,幾種技術往往會組成一種技術Stack,他們更需要被看做一組必須一起掌握的知識,比如:LAMP(Linux+Apache+MySQL+Python/PHP)。
當然上面羅列的遠不是全部,這種羅列更多的是展示一種分類的方法。通過對這種分類方法的補充和完善,大多可接觸到知識都可以被歸入特定的類別,比如說:WinRT可以看做一種新的平臺,HTML5則可以看做是一種語言等。
每個人可以根據自己的情形,參照上面的分類建立屬于自己的地圖,有點問題沒關系,有就比沒有要好很多。接下來依據這樣的地圖就可以選一條自己的線路,持續累積,尋求實踐機會,最終就很可能會成為真正的高手。
而關于增值所需的動力,所要避開的陷阱,將下面陸續提到。
增值、讀書與大局觀
單純從達成某一目的而言,讀書往往非是絕對必要條件。
秦始皇把書一把火燒了,劉邦項羽一樣造反并取得勝利。但讀書無疑的可以加速一個人增值的過程,記不得是誰說過:實踐無疑是人類最好的老師,但只靠實踐來認知世界無疑也是愚蠢的。這是非常精辟的。除此之外,要想培養大局觀,那就非讀書不可。
每個人的親身經歷,在大的時空背景中往往只是一個簡單的截面,這一截面中絕不會包含可以歸納出所有真理的事實,因此只依賴于自身的實踐也就必然限定了一個人的視野。 這一點隨著一個人的責任范圍變大往往會體現為一種制約和限制。所以培根講:有實際經驗的人雖能夠處理個別性的事務,但若要綜觀整體,運籌全局,卻唯有學識方能辦到。?
即使從實踐來看也是如此,要想培養出一種大局觀,那就非讀書不可。而大局觀往往是成為將帥之才的必要條件。
具體到軟件而言,有一本很有名的書對培養技術的大局觀有幫助:《代碼大全》。至于專業性較強的書,反倒是可以根據自己的情景比較容易的選擇,這里就不提了。
基于上面這樣的一張地圖,我們就可以具體的去考慮幾條進階路徑。
路徑一:由程序員而架構師
架構師是一個很火的職位名字,但你很難給它下精確的定義。
下面所陳述的一切是我個人的理解和體會,我無法保證它和其他人的解釋完全吻合。因為架構師,乃至架構設計實在是一種非常模糊的概念,如果你用心去找,可以找到各種定義(甚至IEEE和SEI的定義也不一致),這就導致你只能參照別人,相信自己。
本質來講架構設計也是設計,所以凡是做設計的都可以稱自己為架構師。
當一個系統的規模變大的時候,設計上的決策就具有了特別的價值,并且也越來越需要專門的人來做,架構設計也就越來越像是一種特別的設計。比如說:考慮架構設計的時候,可能需要考慮選用什么樣的數據庫、選用那個開源框架、選用什么樣的硬件平臺,這些東西在小規模程序中往往是居于次要地位的。
假設說一個人已經掌握了一門或幾門編程語言、面向對象、設計模式、能夠很熟練的寫出質量較高的代碼,接下來他想成為架構師,這個時候他需要做什么?
我個人認為,這時候這個人首先要有一個“專業”。這個專業可以是“金融”,“財務”,“電商”,“管理”等等。這是一種屬于某一專業的領域知識,而不是編程技術。如果把需求和最終的代碼,看成描述同一事物的一體兩面,那么設計始終是要架起這兩者間的橋梁。而架橋的時候,怎么可能只知道一端而不知道另一端。
接下來是深化設計所需要的各種通用領域知識(UML、面向對象、性能確保等)。這時和一般所說的設計的一個關鍵區別是,那就是架構設計要分心思去考慮那些東西用別人的就好了,而那些東西要自己開發。而一般所說的設計技術中,比較側重自己應該怎么干(面向對象、測試驅動等)。為達成這一目的,就需要對現有技術的優劣有相對比較清晰的認識,比如要能分清楚那些是成熟穩定的技術,那些是處在實驗階段的技術。Pinterest網站就曾經進行過下列這樣的架構改進,在這樣的改進過程中,不知道各種技術的優劣是代價很大的:
Pinterest 早期階段:
- Rackspace
- 1?small?web?engine
- 1?small?MySQL?DB
2011/1:
- Amazon EC2 + S3 + CloudFront
- 1 NGinX, 4 Web Engines (for redundancy, not really for load)
- 1 MySQL DB + 1 Read Slave (in case master goes down)
- 1 Task Queue + 2 Task Processors
- 1 MongoDB (for counters)
- 2 Engineers
2011/9:
- Amazon EC2 + S3 + CloudFront
- 2NGinX, 16 Web Engines + 2 API Engines
- 5 Functionally sharded MySQL DB + 9 read slaves
- 4 Cassandra Nodes
- 15 Membase Nodes (3 separate clusters)
- 8 Memcache Nodes
- 10 Redis Nodes
- 3 Task Routers + 4 Task Processors
- 4 Elastic Search Nodes
- 3 Mongo Clusters
- 3 Engineers
2012/1:
- Amazon EC2 + S3 + Akamai, ELB
- 90 Web Engines + 50 API Engines
- 66 MySQL DBs (m1.xlarge) + 1 slave each
- 59 Redis Instances
- 51 Memcache Instances
- 1 Redis Task Manager + 25 Task Processors
- Sharded Solr
- 6 Engineers
2012/10:
- Amazon EC2 + S3 + Edge Cast,Akamai, Level 3
- 180 Web Engines + 240 API Engines
- 88 MySQL DBs (cc2.8xlarge) + 1 slave each
- 110 Redis Instances
- 200 Memcache Instances
- 4 Redis Task Manager + 80 Task Processors
- Sharded Solr
- 40 Engineers (and growing)
摘自:http://highscalability.com/blog/2013/4/15/scaling-pinterest-from-0-to-10s-of-billions-of-page-views-a.html
這個過程比較真實,大家可以參照著想想如果自己來主導,那還欠缺什么。
最后一點要說的是,做架構設計已經相對于在做技術管理工作,至少要適當涉獵估算并能做出合適的任務分解,這樣一旦日程緊張,則可以通過增加人手等手段來在質量、成本和進度之間進行均衡。
由于知識面已經擴的比較大,架構師在具體某個專業領域上的深度可能會有所欠缺,比如:在做一款電子消費產品時用到了TTS,但架構師不一定能很好的了解TTS的算法---這是CodeGuru的領域。
架構師所需要達成的最終目標可以形象的描述為:產品經理考慮用戶和市場建立了一個模型,那么架構師要能把這東西映射到技術的世界里來。如果是在互聯網行業,那么在你的主導設計下要可以做出高并發的網站。換到其他行業也與此類似,從產品的的角度往回看,架構師要能解決和技術相關的所有問題,主導完成商業上有價值的產品或項目的開發工作。實現手段上倒并無限制,可以是購買,可以是組織人員進行開發,只要能平衡短期和長期利益,解決特定的問題即可。
路徑二:由程序員而CodeGuru
與架構師相對應,在某些智力密集型的程序中,也需要技能高超的程序員,這種程序員往往被稱為Guru。
這條路線里,程序員并不把自己擅長的領域擴的太寬,但在指定領域上會挖掘的很深。驅動、字庫、圖形庫、算法庫、OCR等都偏向于這一領域。
假如說,一個程序員在掌握基本語言之后,想往這個方向發展,那么需要的技能和架構師差別很大。比如:一個人如果想往驅動方向發展,那么就需要了解CPU的基本結構、內核調試方式、操作系統中與相應驅動所對應的機制、硬件側的規格、通訊協議等。
這時候很可能由于程序規模并不十分龐大,面向對象、設計模式這類東西沒有太大發揮空間,而是需要處理的是大量或麻煩或艱深的細節。
2013年1月,ITeye發布了一條信息說:Intel面向學生免費提供?C++?開發工具,并簡單的介紹了一下是那些工具免費向學生提供:
- Intel?C++編譯器(高度優化的編譯器)?
- Intel數學核心函數庫(高性能數學庫)?
- Intel線程構建模塊(C++任務模型、最流行的C++并行方法)?
- ?Intel集成性能基元(多媒體基元庫)?
看到這張列表,我們可以思考下要開發這類工具需要什么樣的程序員。上面這些工具的開發都屬于高難度的工作,和開發大規模的MIS系統完全不同,如果不是某方面的專家,基本不太可能負擔起相應的責任。而這類領域則正是Guru的天下。
路徑三:由程序員而純管理
純管理工作和技術管理工作可以用是否接觸乃至編寫代碼來區分。純管理工作往往需要把精力放在預算編制、人員職業路徑、考評、度量、流程改善這些工作上。一定程度上講,這等價于和編程工作說拜拜,當然前提是你得有編程經驗,有一些通用領域知識和概念創建乃至邏輯優化的知識,否則的話和程序員沒法溝通,進而給工作造成障礙。
從需要讀的書來看,這時候可能要看過PMBOK,《項目管理修煉之道》,《管理的實踐》,《基業長青》等等。
但如果一個人認為想做管理要從PMP開始,那大概是還沒太明白管理這項工作的本質。管理本身是一種借勢,雖然有技術性的一面,比如要理解掙值曲線這類,但這方面知識其實并沒有想的那么復雜 —— 至少沒有C++11復雜,只要有時間正常智商的人都可以在不太長的時間內掌握。所以如果你想做管理,并使用了和學習C++語言一樣的方法,那基本上是偏離了方向。
拋開機緣這類東西不論,做好管理工作有兩點很關鍵:
- 一是要把技術工作做的相對比較好。這好像有點學而優則仕的意味,但大多時候人們更愿意相信“將軍起于行伍,宰相拔于州郡”,而不愿意相信單只會耍嘴皮子的人。過度務實的人容易迷失于道路,過度務虛的人則容易飄的太高而喪失根基。管理者正應該身處在這兩者之間的一個平衡點。
- 二是要能夠借勢。要情商比較好,能把很多人組織在一起。這個時候要知道那些東西需要規則化,那些東西需要靈活把握。過度偏向規則是教條,過度偏向靈活則是人治,平衡點始終要根據具體人員的狀況,工作特質這些不可改變的事情來把握。這有點微妙。但即使程序員這個群體相對簡單,但并不能推翻先人后事這類規則。這不知道是不是東方特色,當你想做管理并想推進事情的時候,終究要理清人際上的關系,否則就和可能會欲速則不達。這點會在后面進一步展開來談。
下面我們來看一個具體點的例子,這個例子出自郭致星老師的博客,是一個學員的真實疑問(文字上有修飾),X入職后的現狀如下:
開發部現在26個人。基本組織架構是由開發組、需求組、測試組、運維部四個部門組成。需求組的人收集需求,再通過系統指派給開發組,進行開發。開發組的文檔嚴重缺乏。
現在公司內有技術總監和開發部經理的崗位。眼下全公司就X一個項目經理,目前是跟著開發部經理,在熟悉一個核心系統,由于沒有任何文檔的遺留,所以現在是相當于一個開發人員在開發一些實際的功能,一邊開發一邊熟悉現有系統。
現在X并沒有項目的實際權力,而且整個項目組也只有開發部經理,加上2個開發,再加上1個測試和X共5個人。其中X和其中一個開發都是新來的。
與此同時,業務部門在搞一些流程,但還沒做完,沒有在開發部進行實施。工作氣氛比較沉悶。技術總監和開發部經理,都是技術型的人,比較偏向技術,平時工作也多偏向于具體執行。
在使用一個Redmine系統進行項目管理和BUG跟蹤。
這里的系統大部分都類似于產品線制,屬于需要長期開發維護的,需求源源不斷的來,相應人員也就需要不停的做,沒有版本制度,也沒有計劃和規劃。
系統現在主要的問題是性能問題。?
問題就是在這樣的一種環境下,X應該如何開始自己的管理工作?
這類問題通常并沒有唯一答案,但確實有些通行的手段可供參考,最終做不做的好和個人能力乃至環境關聯很緊:
在不同類型的公司里,對應手段上會有不同。比如在規范性比較強的大公司,第4,5兩步的權重就會比較低。在上述這樣的場景下,PMP這類書籍中所提到的種種技術手段誠然是必要的,但和人打交道的部分(老板、直屬上司、下屬)往往會對最終的結果產生更大的影響,這是管理工作與純粹技術工作不同的地方。
碼路指南:為何你成不了編程高手?
成長路上常見的坑
前面講到了程序員成為高手需要有一張地圖,借助這樣一張地圖,程序員可以嘗試成為架構師、Guru或者純管理者。但這條路總是不會那么順暢。
升級練功流的網游中總會給修仙的主人公設置下幾大關卡,比如:金丹難成、元神難成、成了元神后還有天人五衰等等。沒有這些關口,情節很難推動,所以仙俠類的網游幾乎無一例外依賴于這類設定。這一傳統甚至可以追溯到《西游記》和《封神演義》。
拿這個來對照程序員的增值道路,就會猛地發現,升級練功流也不完全是扯淡。不管走那條道路,程序員的修煉路上同樣的也有三災九難,要想成就高手,還是得一個個跨過去才行。如果一個程序員達到一定高度后再回頭觀望,那就會發現自己的同學、曾經的同事總是會因為這樣那樣的原因倒下去。這并不是一個簡單的天道酬勤就可以敷衍的行當,下面就讓我們來具體看看,究竟增值過程中可能遇到那些陷阱,掉到坑里又需要付出多大代價才爬的出來。?
學習失去焦點
軟件行業里有幾個經典的題目,每過一段時間就會被翻出來PK一下,比如關于編程語言優劣的比較等。其中一個經典題目是軟件和數學的關系。
從結果來看,一派人認為數學是軟件的基礎,而另一派人認為數學和軟件沒什么太大關系,除非是在某幾個特定領域里。如果你用心觀察過這事情,你就會發現這事情特別有意思。
比如說:2011年,CSDN轉了一篇,叫:“數學是成就卓越開發人員的必備技能”的文章,在文末作者說:
那么,數學對所有事都有利么?這事情很難說,我對我現在的處境十分滿意,或許你也如此,但這都和潛能有關系。如果你是協作世界的一名開發人員,你真的不需要數學。如果你樂于你的整個職業生涯是這樣的:在工作時間中做企業CRUD應用,或在閑暇時間滑翔跳傘或極限水上滑板(或其他各種時髦的極客運動),也分配較多時間在Spring、Hibernate、Visual Studio或其它東西上。那些特殊的職位并沒有真正限制你的潛力,你能變得極具價值,甚至可深入追求。但是如果你想為多樣化的職業生涯而奮斗,想要有能力嘗試幾乎所有涉及代碼的事,從信息檢索到Linux內核。
總之,如果你想成為一個開發人員、程序員和計算機科學家的完美組合,你必須確保你的數學技能達到標準。長話短說,如果你在數學方面有一定天賦,那在軟件開發領域中所有的大門都是向你敞開的,如果沒有,那你就安安心心地做CRUD型工作吧!
總的來看,這個作者認為數學很關鍵,得學。
而在2012年CSDN又轉了篇文章,叫:編程需要知道多少數學知識?在文章里作者說:
數學和編程有一種容易讓人誤解的聯系。許多人認為在開始學習編程之前必須對數學很在行或者數學分數很高。但一個人為了編程的話,需要學習多少數學呢?
實際上不需要很多。這篇文章中我會深入探討編程中所需要的數學知識。你可能已經都知道了。
對于基本的編程,你需要知道下面的:
- 加減乘除 —— 實際上,電腦會幫你作加減乘除運算。你僅需要知道什么時候運用它們。
- 模運算 —— 模運算是用來計算余數,它的符號通常用%百分號來表示。所以23除以7等于3,余數是2。23?mod?7?=?2。
- 判斷是奇數還是偶數的模運算 —— 如果你想知道一個數是奇數還是偶數,用它mod?2來作模運算。如果結果是0,它就是偶數。如果結果是1,就是奇數。23?mod?2等于1,所以23是奇數,24?mod?2等于0,24是偶數。
- 對一個數作百分數運算,就是用這個數來乘以一個百分數。譬如你要得到279的54%,就是用0.54*279。這就意味著為什么1.0等于100%,0.0等于0%。
- 知道負數是什么。負數乘以負數等于正數。負數乘以正數等于負數。就這么簡單。
- 知道迪卡爾坐標系統。在編程中,(0,0)代表屏幕左上角,Y坐標的正軸往下。
- 知道勾股定律,因為它是用來計算笛卡爾坐標中兩點之間的距離的。勾股定律a^2+^2=c^2。(x1,y1)和(x2,y2)兩點之間的距離等于((x1–x2)^2+(y1–y2)^2)。
- 知道十進制、二進制、十六進制。十進制就是我們通常用的十個數:0-9。通常認為這個十進制系統是人類發明的,因為我們有十個手指。
總的來看,這個作者認為數學不太關鍵,大多時候可以不學。
你如果持續關注這事兒,各種極端對立的觀點絕對會吵爆你的頭。但這事情其實不可能有結論,因為被對立起來的兩極都是太大的概念。
比如說:如果把軟件開發縮減為應用軟件的開發,那爭議性就會降低很多。
這里的關鍵問題是,假如一個人的目標是應用軟件開發,卻花了10年來學習數學,接下來在實際應用程序開發過程中,每天面對的是UI布局、IDE使用、圈復雜度控制、面向對象使用、設計模式的使用和類庫的使用這類問題,那么這個人就會發現數學其實沒啥用,他等價于因為失去焦點而失去了10年。
這里想表明的是,一旦誤讀了知識與目的間的因果關系,那么學習就會失去焦點,進而造成負效應,畢竟相對于人的可承受負荷而言,這個世界上的知識不是太少,而是太多。
一般的認識是只要學習就必然有所得,所以對人生的影響一定的是正面的。但實際上這個想法是偏頗的,尤其是在軟件行業里。
在軟件行業中,這種風險之所以異常突出,就在于前面提到過的軟件的兩個特質:更迭速度快和子領域眾多。這兩個因素導致軟件相關的知識是爆炸性增長。
而避免“失去焦點”這一陷阱的第一關鍵則是分類:對軟件開發進行分類,對軟件所關聯的知識也進行分類,形成自己的大局觀和整體視圖。
前文曾經提過集中對知識進行分類,對軟件進行分類的方法,這里再補充一個對繞過這一陷阱有幫助的分類方法,它來自《軟件成本估算:COCOMOII模型方法》這本書。
書里面把軟件分成了下面幾個類別:
| 終端用戶編程(一般的應用程序) | ||
| 應用程序生成器(開發工具等) | 應用組裝 | 系統集成 |
| 基礎結構(OS,DB等) | ||
在進行分類的同時,書里還給出了一組數據,即95%的人從事的是終端用戶編程。
這個分類的意義在于,通過它我們可以認識到每一類別背后隱含的知識需求其實不一樣,程序員則要根據自己的目的設定焦點。再來看一個具體的例子:
算法領域中,最經典的書籍恐怕是Donald?Knuth的《計算機程序設計藝術》。對此書的評價已經不止是高那么簡單了,如:
這部多卷專著是公認的對經典計算機科學最權威的描述。幾十年來,無論是學生、研究人員還是編程從業人員,本套書的前三卷都是他們學習編程理論、進行編程實踐的寶貴資源。?
這是一套集所有基礎算法之大成的經典之作,當今軟件開發人員所掌握的絕大多數計算機程序設計的知識都來源于此。?
—— Byte
那么是不是每個人都應該把這書讀一讀?這書的前三卷大致有2000頁,上班的人都讀通估計要1~2年這個樣子。
至少在我來看,答案是否定的。具體情況要看你做的是那類軟件,你人生的下一步在那里而定。
假設說一個人做的是終端用戶編程(比如:財務類軟件),并且目標也是在這個方向上繼續深造,那么你讀這書其實是在浪費時間。
這是因為在終端用戶編程上,自己去寫算法的機會非常的少,甚至可能沒有。反倒是業務領域知識(會計知識)、OO、設計模式、甚至于估算這些知識都比研究算法更有價值。?既然如此,那么從務實的觀點上看,為什么去學習不能在可見范圍內創生價值的東西,而不是去學習立刻可以變現的東西。走極端的人會找出需要寫算法的例子來反駁上述立論,但點不足以表征面,即使偶爾需要自己了解下算法,真就值得花那么多時間去學習么,為什么不盡可能借鑒現成的。
而在基礎結構性的軟件開發中,情形就不同,這時算法無疑是非常核心的東西。所以Google這類公司的面試中往往非常強調算法。
這里最關鍵的就是聚焦,聚焦的根本則是要在限定時間范圍內創生價值。
從方法上講,聚焦就是找到一個適合自己大小的區域,然后做深。才華橫溢的不論,一般來講,橫向穿越和縱向穿越都不太行,除非已經基本窮盡當前的領域。縱向穿越是指從底層穿到上層(想想開發網絡協議的和用網絡協議的),橫向穿越則指橫跨太多的領域(想想從內核驅動跨越到信息管理軟件)。
其實如果一個人真的擁有無限的時間資源,那么什么時間點學習什么就變得不太關鍵。但這是不可能的,同時一個人的學習時間遠不像想的那么充沛。這點會在后面探討。?
在清楚自己的目標后,再配合前面提到的知識分類地圖,那么避開這一陷阱的幾率就大了很多。
學習與實踐相分離
喜歡看網文的很少有人會不知道起點,不過估計很少有人注意過起點給小說分類的標簽。在網文小說里有很多個流派,其中一個叫做“扮豬吃虎”。這個流派的基本特征是很厲害的一個人要假裝很菜,最后在關鍵時刻力挽狂瀾。這個流派十分有人氣,大概僅次于“升級練功”,而遠高于“重生”、“轉世”這類的流派。
網文是絕對的市場導向,所以這個現象可以從側面說明很多人喜歡“扮豬吃虎”或者說潛意識里有著“扮豬吃虎”的情節。“扮豬吃虎”這事兒小說里看著很爽,但挪到現實里來很容易讓人掉到學習陷阱里。更可怕的是,現實里有這種心思的人其實也還很多。
有時候會看到這樣一種現象:很多人自學的東西和工作中用的東西完全沒關系。比如:一邊用著C#做Web開發,一邊自己學習著C/C++做嵌入式。
這事并不一定不對,只能說非常危險,很可能會導致那樣都沒有高度。我們得承認當人生被錯位的時候,往往只能這樣來改變命運,這是沒辦法,也是正確的。但首先要認識到這樣做是相當低效的,低效到一定程度后對的事情也并不一定有結果。
CSDN曾經做過一份薪酬統計(http://www.programmer.com.cn/5877/),這里面有三個與上述身在曹營心在漢現象有關聯的結論:
- 一是73%的程序員對自己的薪資并不滿意。
- 二是各個主流開發語言上的差異并沒有想的那么大。雖然C#開發者中月收入小于5000元的比例最高,但5000~10000這個群體在主流開發語言上相差并不大。
- 三是平均來看,收入增長和工作年限正相關。當然認為到那個歲數工資自然就高了是很危險的。
對薪資不滿意應該是程序員希望跨界的一個原動力,但收入和年限正相關,與語言非正相關卻說明單純從功利角度看跨界并不明智。因為假設一個人Java語言用過三年,C#用過三年,總的來看收入水平更可能處在三年的水平上,而不是六年的水平上。
軟件是一種固化的思維,這就軟件開發更多是一種實踐而非是一種理論。軟件開發內的很多領域,總體上看體現的是復雜而不是艱難,不論是前端開發還是驅動開發。
講到到這里就有必要簡單區分一下“復雜”和“艱難”。考試出題可以有兩種方法:一是每道題都不是很難,但題量很大;一是題量很少,但每道很難。從結果來看,兩類考試方法下,得高分都并不容易,但其難度的來源卻并不相同,前者更多的體現為復雜,而后者卻體現為艱難。
在軟件行業里,除了一些專門的領域,比如圖像算法等,軟件開發則更類似于前者,所以經過培訓后大部分人都可以做軟件開發,進入門檻并不高。
解決艱難問題時,天分很重要;解決復雜問題時,練習很重要。所以軟件開發的學習過程中,實踐很重要,純理論知識的權重較低,當然基本的算法復雜度還是要明白的。
這也就意味著脫離項目實踐的學習投入產出比往往會差。比如說:編程中常見的多線程問題。如果單純從學習的角度看,創建線程本身并不復雜,掌握各種線程同步方法(事件、信號燈、互斥量等)也并不復雜。寫簡單例子的時候,也很少會出錯。但一旦落到具體的場景下,雖然多線程的本質沒變,但沒經驗的人幾乎一定會在涉及多線程的代碼上導致一會兒出,一會兒不出的問題。
再比如說:你可能看了很多設計的書,但從來沒有從頭到尾寫過什么程序,總是在既有代碼上修修改改,或者只是完成幾千行代碼的小工具,那么你的設計知識是很難融匯貫通的,也還是無法很好的承擔大系統的設計工作。
這點上有一個旁證,根據統計最多的Bug是由新手導致的。這從側面說明,能做和能做好之間的鴻溝需要大量的實踐來填平的。
在這樣一種前提下,期望先選個工作,再自己學習,努力轉行這樣的想法是損失很大的。單純從增值效能上看,解決這點很簡單,除非必須放棄當前的工作領域,否則要以當前參加的項目為根基展開學習,這樣才能比較好的調和學習和實踐。
而除非一個工作領域過于偏狹,大多時候在編程語言(C#→C/C++)、不同領域間(圖形處理→地理信息系統等)穿越損失可能更大。
至于如何在“博”與“專”間平衡,如何選中更適合自己的工作領域,將在后續章節里陸續談到。
碼路指南:在博與專之間取得平衡 平衡最合適
?“博”與“專”上的迷失
假設說一個人的學習已經聚焦,并且學習的內容和自己實際參與的項目也相吻合,那么是不是就沒有問題了?很不幸,答案仍然是否定的,在任何一個子領域里,仍然需要進一步去考慮“博”與“專”的均衡。
對于軟件開發而言,設計是再常見不過,再簡單不過的一個詞了。可如果把視角拔高一點就會發現,單以設計而論仍然是一個不可窮盡的領域,我們可以快速掃描一下和設計相關的部分概念:
- 面向對象分析與設計
- 結構化分析與設計
- 模型驅動開發
- 契約式編程
- 面向方面的開發
- 基于組件的開發
- 元編程
有些時候方法論也會和設計牽扯到一起:
- 測試驅動開發
- 敏捷軟件開發
如果感覺這個還不夠多,那可以去Wiki上查編程的范式(paradigms)這個條目,那里列了47種范式,每個都和設計多少有點關系。
上述這些還只是說了設計,如果橫向展開,那么在特定領域中必然還會牽涉到框架的選用、輔助工具的使用等等。這也就意味著,從博的角度來看,即使是在設計這樣一個看似狹小的領域中仍然是沒邊界的。
與此同時,把一個API研究的再透,也是低值人群,因為這種深入理解和單純會用某個API相比,從創造價值的角度看,差別不大。
這也就意味著對于大多數軟件開發人員而言,要去尋找廣博與精專間的均衡點:既不能閉上眼睛,也不能就用顯微鏡來看世界。而這一均衡點的價值則可用反木桶原理來說明:木桶原理說的是桶里的水是由最短的一塊板決定的,但考量人的價值時卻是適用于反木桶原理,即人的價值往往由最長的一塊板決定。
考慮博和專的問題不能離開產品開發進行考慮,前面曾經提到過,產品開發往往和公司的現金流綁定的更緊,能為現金流貢獻力量的技術才是有價值的技術。而產品開發本身事實上對博和專的程度提出了最基本的要求,這種要求往往具有迭代的特質。為了形象的說明這一點,這里舉一個通用的例子來進行一點說明:
在第一次跌代里,往往需要達到兩個最基本的目標。第一個目標是可以為產品貢獻自己力量,但代碼質量普通。這個目標如果達不到,一個人會失去自己的存在價值。
這時候最少需要了解某種語言(比如:C++)、某個平臺(比如:Windows)、某個IDE(比如:Visual?Studio)和某些業務相關的知識(比如:打印體系)。這個范圍可以盡可能圈的小點,但用到的則要學透。比如:不管接觸到那個框架,都要去了解它的內存機制、線程機制、異常處理組件構建和國際化處理這些全局性的機制,而不能只是了解某個接口怎么用。
這并非是很高的要求,沒有這些就變成了“靠運氣編程”,寫完程序后還要祈禱他能跑起來。了解這些之后就可以負擔起部分開發工作,否則的話只能做旁觀者,沒法參與到實際工作中來。
第二個目標是把事情做好,并能負擔些層次更高的工作。這時候要比較深入的了解面向對象、結構化方法、設計模式、理解設計原則,并能把它們用好。至少要能判定,這個程序寫的好,那個程序寫的不好,同時面對需求能把工作進行下去。
前兩個目標是基礎,一般來講學校中基礎打的越好,這個階段越短。達成這兩個基本目標之后就可以結合情境來做進一步的選擇,可以認為這是博與專選擇上的第二次迭代。當然這時候也要謹記不要和實踐分開。
完成上述兩個層次后,可以有兩個方向可供選擇。
1. 可以進一步考慮專的問題,比如在特定領域里把知識深化下去。做驅動就要理解操作系統的核心機制,做打印的就要了解頁面描述語言等,但這個時候要適當警惕邊際效應。
邊際效應是說,你讓一畝地從畝產500斤增加到1000斤可能只需要投入100塊;讓畝產從1000增加到1500可能就需要200塊;讓畝產從1500增加到2000則需要400塊了。
一個典型的例子是對C++的學習,C++是公認的復雜,如果想做C++的律師,那么估計搞個10年可能夠資格了,但問題是把時間都投在這個上,投入產出比可能不好。而停在那里合適則是個尺度問題,大致來講是可以靠時間彌補的細節問題,并不適合專到最底層。比如對于100萬行的程序,預先花時間去了解每一處細節,就有點過了。
2. 可以把博再推進一步,比如:熟悉專門領域的專業知識、熟悉多種既存框架的特性、熟悉提高用戶體驗的關鍵點。熟悉多種既存框架的特性的具體含義是:
設計某一種解決方案時,首先要考慮的就是是自己開發還是使用現有的模塊。一旦決定使用現有的模塊(包,框架等),那就要進一步考慮究竟用那個。
做這類工作時,如果沒有一定廣博的知識,做選擇的時候就會特別的艱難。
假使說現在公司內部要導入一套項目管理系統,那么做決定的負責人必須至少考慮所有下面這些事情:
- 自己從頭造,還是用現成的做二次開發?
- 用現成的,是用開源產品,微軟的還是其他公司的?
- 用微軟的話,是用MS?Project還是基于SharePoint,還是混合?考慮License費用的話真的劃算么?
- 用開源產品,有這么多選項究竟導入那一個?
- 如果自己從頭造,那么是基于微軟的技術,還是基于LAMP這樣的技術?
- 使用什么框架?
- 如果要做,用什么語言?
一個人很難精通上面所有的領域,但當做選擇時,完全沒有概念也是災難性的。
此外,考慮博與專平衡點時似乎有一種特例,鉆研特定算法的人,從一開始就只往專的方向發展,并不會考慮其他。比如:鉆研TTS的人,可能幾十年如一日只要專注于TTS就完了。
至于具體選擇那個方向,則要根據自身情形來定。總的原則是要以當下工作為根基,以實用為目的甄選各種知識,并追求平衡點。
大致上講,期望做技術專家的更適合前一個方向,而期望做技術管理的則更適合后一類方向。
學習軟件工程的時機與必要性
簡單來講越是沒實踐經驗的人越不適合學習軟件工程,越需要規劃整體把握全局的時候越需要學習軟件工程。
軟件工程中覆蓋的元素非常繁雜,可以有管理、流程、開發模型、估算、分析設計方法等。這無疑會把知識面擴展的很寬,一旦沒有根底,就很容易變成紙上談兵,夸夸其談。
在眾多軟件相關的知識中,軟件工程絕對是很特別的一個。很多人很鄙視軟件工程,說:我一看到軟件工程的書就直接略過;與之相對應,很多人很推崇軟件工程,會花很大的心思去研究敏捷、CMMI等。
剛入職場的程序員大致上是討厭軟件工程的,因為這東西離自己的實踐有點遠,并且主要是添加束縛。但既然更加復雜紛繁的歷史都可以總結出規律,忽視軟件開發的內在規律無疑的對有志于成為管理者的人是不利的。
真要學習軟件工程,不太適合從抽象層次很高的教科書開始,而適合從《代碼大全》這樣與實際關聯比較緊密的書籍開始。
在國內軟件工程的落地似乎始終困難,軟件工程相關名詞始終在不停的變換(ISO,CMMI,敏捷等),但實際能落地起作用的卻不多,這最終導致了一種吊詭的局面:剛對一個絕望,就開始對新的一個報以希望,并在這兩個簡單的步驟上做無限循環。這種狀況也許有其更深層次的原因,比如生存壓力過于強大導致工程力量的長遠價值被漠視,進而使方法論并不為解決現實問題而存在,而是為了證書而存在。很難據此就說軟件工程毫無價值。
碼路指南:別錯過人生中學習的黃金時期
保持知識更新
錯過人生中的好時機
沒畢業的程序員或者剛畢業的程序員往往感覺空余時間比較充沛,還很苦惱不知道如何打發時間,但實際上一個人一生中可以用于充電的時間遠比想的少。一旦錯過時機,往往悔之莫及。
對于大多數人而言,人生就像個模板,小處還有偏差,大處卻基本相同。
- 20~30歲這個階段可以講是黃金時期,這個階段里,家庭負擔較小,可以自由支配的時間較多。當然撞到了很特別的、需要瘋狂加班的公司只能另算。
- 30歲之后因為娃娃出生等,家庭上的時間開銷增加,個人可支配時間變少。其中很大一部分人還有很大可能會面對電視劇里常說的婆媳矛盾,讓你每天心緒不寧。
- 40歲之后,家庭瑣事會進一步增加,典型的上有老下有小。實在運氣不好的自己也會生點病---頸椎病、腰間盤突出、胃病大概可以入選程序員的三大職業病。
- 50歲之后,時間上會再次解脫,但可惜的是自己也老了,時機不在。
如果把人生按照年齡畫一條拋物線的話,40歲左右一個人可以達到的人生的頂點,未來再突破的幾率則變小。從歷史人物來看,大器晚成的不是沒有,但真的很少。
用心觀察就會發現,招聘啟示里經常會注明年齡要在35周歲以下或者40周歲以下,除非是招聘高層。這反過來意味著如果沒有到高層,人生會在40之前定型,之后有下滑危險(如遭遇不景氣、公司倒閉等)。對程序員而言,這種風險尤其的大,因為很可能你辛苦掌握的知識體系被更迭掉了。
學習本身無疑的是需要順應這種自然規律的。
很多人很大的一個錯誤在于,在黃金時期,沒做什么積累,就顧得享受生活了,而一旦意識到積累的必要性時,卻又受困于諸多瑣事而欲振乏力,最終人生高度有限,并迅速走低。這就是現代程序員版的“少壯不努力,老大徒傷悲”。
基本上講,35歲以前要把需要花大量時間,比較硬的技能,學習曲線陡的技能掌握,具備工作所需要的所有主要技能,而35歲之后則主要關注知識的更新和某些軟技能。
學習時添水戰術效率真的很差,每次點一根火柴燒水,一億年水也燒不開一壺。同時,比較硬的技能(比如:Donald?Knuth的《計算機程序設計藝術》)往往是需要大塊時間投入的,但年紀越大時間越呈現為碎片化,越難搞定硬的知識 —— 先天就容易造就添水戰術。比較軟的技能,則可以用碎片時間來學習,比如:提高PPT的制作水平,提高表達能力。
如果能夠安排好自己的時間和軟硬知識的關系,那么就可以在特定基礎上做積累,小步前進,使自己的價值越來越高。從這個角度看,年輕絕對是一種債務,大多數人必須在他沒完全結束前,還掉所欠的東西。
那么具體來講那些東西是比較硬的,要在35歲前搞定呢?這因目標而異,但下面這些項目應該具有非常高的通用性:
- 精通一門最常用的語言
- 了解一個最常用平臺的基本機制,比如:內存管理、線程機制等
- UML圖和面向對象分析設計方法
- 設計原則,如:職責單一等
- 設計模式
- 《代碼大全》里講的一切
- 精讀一個知名的,但有點規模的程序。這點上要感謝開源項目給我們提供了這么多優秀程序。但要謹防好高騖遠,動輒挑戰Linux內核,精讀是關鍵。
- 累積一定的代碼量,比如:獨立的完整做過一個數萬代碼行的東西。這里的關鍵是完全自己打造,一定不要拷貝粘貼。
- 掌握基本算法和數據結構(可以不自己寫,但至少要知道其復雜度和區別)
- 養成一種清晰的編碼風格
- 有自己的專業(金融、高并發網站,圖像處理,TTS等)
學習英語的時機和必要性
總的來看,程序員學習英語是一項投資回報率相對比較好的投入。從目標上來看,程序員未必一定要口語流利,但最低要達到閱讀英文資料沒有障礙的程度。這里面有一個微妙的事情,一旦英語閱讀問題較大,查找問題會習慣用百度,這天然會限制一個人的視野。不是說百度自身有多不好,而是說英語的世界里有著更多更精彩的內容。
不管喜歡不喜歡,我們必須承認一種現實,在IT的世界里英語是一種世界語,一方面是由于美國公司的強大,一方面則是由于開源選擇了英語。這最終導致IT世界里的新動向、解決問題的小技巧、網站的架構等等都要到英語的世界里去找。在StackOverlow很容易找到各種小問題的答案,在Quora則很容易找到各種網站的架構。
從學習時機來看,這件事情特別應該在大學里面搞定,如果不行至少也要在畢業1~2年內達到閱讀無障礙的程度,當然希望加入外企還需要額外的付出。從學習方法來看,學習外語真沒什么特別的竅門,堅持并投入時間即可。
停止知識更新
對程序員的增值而言,人生里最大的陷阱也許是為安全的假象所欺騙而徹底的放松自己。這種狀況在生存環境比較惡劣的情形下不太會發生,但在壟斷企業或某一領域中絕對領先的企業里則容易滋生。發現自己是否停止知識更新了并不困難,比如:一年一本書沒看,一年一點新知識沒接觸,一年中工作負荷基本不滿等都可以成為一種信號。
這真的是溫水煮青蛙,一旦到了三十幾歲,并在這種環境中呆習慣了,那么再想跳出來,基本沒可能。唯一能做的事情是,祈禱公司不要掛掉,公司也不要來場運動,進行人員的大換血。孔夫子說:日當三省吾身,這是很有必要的,至于認識危險后能否做點什么,那就是事在人為了。
1. 技術人員的知識更新
接觸一個新的崗位后,大致要經歷一個學習并逐漸勝任的過程,這個時間段里大多數人的學習熱情是很高的。一旦基本勝任之后,事情就有了變化。
很大一部分人可能會感覺,反正工作也就用到這么些知識,學習其他的也用不上,因此開始把自己封閉起來,不太看書,不太看技術新聞。
這其實很危險,因為這種做法等于把自己綁死在當前這份工作上。而任何一個產品都有自己的生命周期,一旦一個產品的生命周期結束時,碰巧其所用的技術也已經過時,那么當事人就會很尷尬。因為產品可以結束,生活卻還得繼續。
這里面一個非常經典的例子是MFC。微軟的這款產品的歷史非常悠久,從1992年發布到2012年幾近存在了20年時間。隨著90后程序員的逐漸出現,馬上這款技術就要變得比程序員的年紀還要大了。
即使到今天,很多桌面應用仍然是基于MFC開發的,這可以通過查看程序包的dll依賴來很容易的進行驗證。MFC是一個很大的池子,有深度、有歷史。想把MFC的類繼承關系、消息機制、框架結構、RTTI、序列化都搞清楚還是要很花一點時間的。
現在我們假設一款龐大的企業應用是基于MFC開發的,一個程序員也通過幾年的努力了解了MFC,了解了應用本身,并可以負擔起Bug修正,新功能追加等任務了。
接下來這個程序員似乎沒什么好學的了。因為MFC的更新幾乎已經停滯,因此對MFC的學習幾乎不需要花太多的時間了。現有代碼也理清楚了,也不需要再花很多時間學習了。現有程序也比較好的滿足了企業的需求,推倒重來的可能性幾乎沒有。
那這個時候這個程序員不需要學習了么?答案一定是否定的。這里面蘊藏著一個天大的矛盾。
從企業的角度看,一定是需要一個團隊來維持這個程序的開發的。但從個人的角度看,如果把所有的青春都耗費在老技術上,那么一旦老技術退出歷史舞臺,個人該何去何從?
還是上面的例子,假設說一個人持續投入在這類開發上,當他45歲的時候,當前產品生命周期結束,世界變的只有移動開發和云端開發,那么只擅長MFC的他該何去何從?
如果真的如此,這個人就被逼到了死角里,人生很可能產生巨大滑落。所以一定不能認為所學足夠而停止技能的更新與學習。
從具體應對措施來看,一是要參照知識的地圖,橫向擴展知識的廣度,比如不只要盯著代碼,也要了解業務;不只關注開發也關注一點估算;二是提升可流動性比較好的東西的掌握程度,比如:面向對象分析與設計,這樣跨越到其他技術時就能夠比較平緩的進行過渡。三是要爭取輪換崗位,爭取多種實踐機會。
2. 管理者的知識更新
到現在為止大部分人認同,管理者是需要懂技術的。從邏輯上看“懂”基本上是不瞎指揮的前提,所以這可以稱為中國版的“現場主義”,估計爭議不大。
那關鍵問題就是究竟要“懂”到什么程度?
如果說兩個人,一個選擇了管理方向,一個選了技術方向。接下來要求管理方向上的人技術水平要和技術方向的一樣,那么除非這個人特別天才,否則不太可能。正像前面所說,這是由于這兩個方向的“Key”不同所造成的。
如果把目標設定為確保最終產品的成功,同時假設管理者有更高的決策權,那么管理者必須在下面這些方面有技術感覺。
從做產品來看,要想成功,有兩個關鍵維度需要同時進行把握,一是產品的概念完整性的把握;一是用合適的手段去實現這個產品。
前一個話題很老,《人月神話》就有提及,但實踐中卻總是被人忘記。好的產品必須貫徹某一種統一意志,iPhone、微信又重新驗證了這一個老的原則。?機械拼湊的產品雖然融合了很多人的想法,但往往是平庸的,并且在項目執行過程中,往往是出錯的根源。很像是雖然有法律,但每個人有自己的理解,各行其是這樣一個狀態。這種概念完整性是管理者第一個需要有所把握的事情,其次就是解決如何去構建產品這個問題。為達成這一目標在下面這幾個方面上,管理者要有自己的理解,至少要有自己的原則:
下面簡單列舉幾個比較關鍵的考量,這和前面論及的如何往博的方向發展有點重疊:
- 使用現有產品還是自己開發
- 比如:那些模塊適合自己搞定而那些購入就可以了。購入的時候要遵循怎么樣的標準去選擇。
- 使用那種平臺技術
- 比如:是使用微軟的技術,還是開源的技術。
- 現行架構是否可以達成產品目標
- 比如:在硬件加軟件可以同時支撐的并發數目。
- 代碼可維護性如何約束
- 這要求必須熟練掌握一些原則性的東西,比如:什么信息隱藏、正交分解、抽象是否充分等。以及一些無歧義指標,比如:圈復雜度,單元測試的收益平衡。
- 那些環節必須固化為流程,那些一定要團隊自由決定
- 比如文檔化要到什么程度才合適,不同階段間什么是必須的輸入輸出。
- ?...?...
假設說有人不這么認為,而是在做了管理后,表現出足夠的惰性,不再持續更新自己的知識體系了,那么會發生什么事情?
這時候會很可能會管理倒置。即管理者是名義上的上級,但基本失去對現場的把握,所有的決策完全依賴于下屬。得力下屬不在,各種決定就只能靠瞎蒙,最終變成只會溝通的管理者---即使被食人族吃了也不會有人注意到,因為存在價值已經被無限稀釋,變成了一個象征性的符號。也可能會和下屬爆發激烈沖突。因為這類管理者沒有自己的立場,上面有任務只能下壓。結果同實際情況偏離萬里,不具有可實現性,這類管理者無法對自己的上司陳述,也就只能向下轉移壓力。
不管是那種,一旦到這種地步,其實是趨于失敗,只能祈禱食人族不要來。
為什么中層管理者也要堅持知識更新?
在IT行業流傳著一個很有名的關于食人族的笑話,這個笑話說的是:
兩個食人族的人應聘進了某家大公司,公司人事主管知道這兩個這伙每天都要吃人,于是警告他們:“如果你們膽敢在公司吃一個人,你們就會立即被炒掉!”兩個食人族唯唯喏喏地答應,表示絕不會在公司吃人。兩個月過去了,公司平安無事。
突然有一天,公司發現負責打掃公司衛生的清潔工不見了。于是人事主管非常氣憤,找來兩個食人族怒斥,并當場炒掉了他們。出了公司大門,一個食人族馬上對另一個抱怨起來:“我一直警告你不要吃有在做事的人,你就是不聽!我們兩個月來每天吃一個經理,沒人發現。你看現在吃了清潔工,他們馬上就發現了!你真是個豬!”
這個笑話嘲諷的是某些大公司大企業病發作,人浮于事。大企業病的成因很難一下子說的清楚,但結果卻比較明顯,一定會導致較多人成為中層管理者。如果說成功的企業天然有感染大企業病的趨勢,那無疑的中層管理者也天然有著膨脹趨勢。從個人角度看,成為被食人魔吃掉也沒有人在意的經歷并非是什么好事,因為這意味著存在價值減弱,也不需要什么知識更新。一旦面臨裁員這類事情,這個人很可能已經失去了面對殘酷競爭的能力。
碼路指南:物質驅動與興趣驅動
編程驅動力是什么?
在國內普遍有一個很特別的現象:高中像打了雞血一樣使勁學習的人,到了大學往往會放松下來,跑去享受生活了,大學里打游戲、打牌、臨考沖刺的大有人在。
這倒也在情理之中,高中不學真考不上大學,考不上大學真就完蛋了;大學不學,只要能畢業,大致還能找到工作。但人生是場長跑,稍一停頓,后面的人就嗖嗖的竄到你前面了,雖然你不一定能看得到到底是誰。這很像龜兔賽跑,但為了避免不成為那只兔子,單靠口號層次的主觀意愿是不行的。
停下來的人其實很多,有的人停在了大學里,有的人停在了小有成績之后,而為了持續前行而成為高手,那首先要給自己找個動力源,而要想找到動力源,那么首先要拷問自己的內心,知道自己為什么上山學藝,為什么要成為高手。
純物質上的驅動力
如果回看歷史就會發現歷史記下名字的人(孔子、商鞅、漢武帝、李白、王安石等等),往往具有一個共通的特征:他們具有澎湃的生命力,絕對不是每天混混日子的人,雖然生命力的表現往往不同。
這似乎和好人壞人,理想高尚與否無關,必須的只是這個人要有所執著,并持續的運用你的腦力、體力去做某件事情。而一個人要想有所執著,那就必須有一種持續存在的驅動力。
在這個時代里,對于大多數人而言第一驅動力無疑是物質及金錢,但這似乎只可以做起點而不能做終點。這就和梁山好漢一樣,最開始沒準只是為了大碗喝酒,大塊吃肉,可聚了義之后,則要考慮替天行道,除暴安良這類比較高端一點的事情了。
組織行為學中的研究佐證了這一結論,美國人的研究顯示,當年薪超過40000美元后,薪資將不再是工作滿意度的核心支撐因素。在中國估計相差不大,20萬以上年薪的人,往往需要尋找其他的驅動力。否則這個時候程序員會處在一種瓶頸狀態:基本物質需求得到滿足(比如:住房、汽車等),但更高一層的物質需求又很不現實(比如:別墅、游泳池等)。
這個時候單純的物質支撐會讓生命力變的萎靡,人也就會變得無可無不可,工作中即不會很高興,也不會很不高興,每天也只是例行公事。接下來人生就會開始下滑,倒霉的話還會失業。等到困境真的來了,再想振作,卻沒那份兒心力了。
在2012年11月,新聞報導百度總裁李彥宏在公司內呼喚狼性,排斥小資。具體來講,呼喚的是敏銳的嗅覺、不屈不撓奮不顧身的進攻精神,群體奮斗,排斥的是信奉工作只是人生的一部分,不思進取,追求個人生活的舒適的態度。這事情的是非很復雜,這里略過不提,反倒是百度這一行動本身說明公司里確實容易存在一種生命力萎靡的狀態,這點甚至讓CEO忍無可忍。
興趣的力量
如果說純物質上的驅動有一定局限性,那么興趣又如何?
當問及一個人為什么從事軟件開發時,很多人會回答是:興趣。但人們這么表達的時候可能并沒有意識到常說的這種興趣是一個不怎么靠得住的驅動力。這種興趣往往是一種一時的好奇心,而不是與自己性格特質相契合,可以用來給生命解悶的那種興趣。
總的來看,興趣可以分為兩個層次:一個是淺層次的。比如看到一個游戲比較酷可能想玩玩,看別人寫博客,自己也寫幾篇;另一種則是深層次的。比如:愛因斯坦你不讓他思考,他可能感覺活著就沒什么意思了。
找到后一種興趣的人是幸運的,但大多數人并沒有這么幸運,所以一般所說的興趣都是前一種,尤其是即將畢業和剛畢業不久的人。
真正做軟件產品的時候,牽涉的往往是大量比較繁瑣的細節,大多時候臟活、累活、苦活遠比看上去風光的活,有趣的活多。具體一點講就是,可能需要面對比較垃圾的既存代碼,可能要面對不怎么負責的同事,無理的需求變更,十分緊張的日程等。除非你做的是很高端的研究。
這些東西本身并非是很有趣的,它們很快會讓初始時的一點夾雜著好奇心的,淺層次的興趣消耗殆盡。最初印象和實際的偏差很可能是造成某些程序員提前退場的一個主要原因。
這種原生態的興趣消失后,又沒有其他支撐點的話,人就越來越會像機器人,并可能會厭惡自己的生活。因為每天大部分時間都花在工作上,而工作本身又是如此的無聊。所以故事到興趣這里并沒有結束,還需要繼續找尋驅動力。
當然很可能以興趣為出發點而找尋其他,最終反倒又回到起點,這是人生常態,倒不值得驚訝。
興趣、體力與智力
人和人之間的體力往往相差不大,但智力的差異卻往往不可以道里計。所以一個經驗豐富的老農半天種一畝地,一個不太熟練的忙和一天大致也可以搞定一畝地。
純體力上不太拉得開人的差距。而智力則不一樣,人的智力容易有數量級上的差異。前蘇聯著名物理學家、諾貝爾獲得者朗道將世界上的物理學家從一級到五級分為5個層次,每個層次的貢獻差一個數量級。朗道認為自己是2.5級,獲得諾貝爾獎后,才把自己生為1.5級。就不用再考慮5級的物理學家和普通人的差異了。
我個人感覺,越是靠近體力一端的工作越不可能興趣驅動,而越靠近智力一端的工作越可能是純興趣驅動。恰如我很難相信干重體力活的人是因為興趣一樣,我也很難相信愛因斯坦不去做以色列總統而選擇繼續研究物理不是因為興趣。
程序員的工作在這兩個極端間,所占跨度較大,但產品開發也許是中間偏左,完全的興趣驅動估計很難。即使是興趣驅動,也不是我喜歡游泳,我喜歡吃小籠包這個層面的興趣。
物質驅動和興趣驅動,看起來貌似都不是特別靠譜,那么什么驅動力才能使人生永動呢?
碼路指南:保持內心的青春與理想
理想驅動編程
如果說物質和單純的興趣不足以成為一種長久的驅動力,那么無疑的我們需要繼續去尋找一種可以使人生永動的勢能。
很多一部分程序員其實是認識到了技術更迭這樣的特征時刻在掏空自己立足的根基的,但很多的人在這種時候并不是采取積極的態度去面對,而是會試圖欺騙自己,給自己一種安全的假象。比如可能會告訴自己,反正公司短時間沒問題,把手里的事做好就行了。讓自己那么辛苦干什么?這在某些有點年紀生活相對安穩的程序員身上比較常見,這很可怕,有時候會把自己逼到死角里。擺脫這種狀況當然需要一定的危機意識,但更關鍵的是要找到一種使人生永動的勢能。
據說美軍的麥克阿瑟將軍非常喜歡一篇名為《青春》的散文,在占領日本期間日本人在美軍總部發現了這篇散文,于是這篇文章很快變得很流行,在商界大佬(如松下幸之助等)間流傳甚廣。那《青春》這篇散文說的究竟是什么呢?我們來一起看一下:
青春不是年華,而是心境;青春不是桃面、丹唇、柔膝,而是深沉的意志,恢宏的想象,炙熱的戀情;青春是生命的深泉在涌流。?
青春氣貫長虹,勇銳蓋過怯弱,進取壓倒茍安。如此銳氣,二十后生而有之,六旬男子則更多見。年歲有加,并非垂老,理想丟棄,方墮暮年。?
歲月悠悠,衰微只及肌膚;熱忱拋卻,頹廢必致靈魂。憂煩,惶恐,喪失自信,定使心靈扭曲,意氣如灰。?
無論年屆花甲,擬或二八芳齡,心中皆有生命之歡樂,奇跡之誘惑,孩童般天真久盛不衰。人人心中皆有一臺天線,只要你從天上人間接受美好、希望、歡樂、勇氣和力量的信號,你就青春永駐,風華常存。?
一旦天線下降,銳氣便被冰雪覆蓋,玩世不恭、自暴自棄油然而生,即使年方二十,實已垂垂老矣;然則只要樹起天線,捕捉樂觀信號,你就有望在八十高齡告別塵寰時仍覺年輕。?
—— 塞繆爾-厄爾曼德
文字非常優美,但意思并不深奧。青春是一種進取的精神,是一種遠離頹廢追逐理想的狀態。我個人非常認同這種觀點。
人的思維和欲望具有無邊界特質,只要在未來和現在之間制造一種差距,那么就會產生無盡的勢能,人也就會不斷的前行。而制造這種差距的最佳素材往往只能是理想。
大多數人可能誤解了理想和道德間的關系,但實際上理想并非是一個高尚的詞匯,與善惡無關,更與宏大與渺小無關。
魯智深說:平生不修善果,專愛殺人放火,這也可以是種理想,只要你可以承受它所帶來的負能量并不感到痛苦。物質需要、成就需要、權利需要、歸屬需要這些動機理論中經常提到的東西,乃至前文提到的興趣都可以成為理想的素材。所以反過來講,理想是什么似乎并不關鍵,關鍵是要有,并且你真的可以很狂熱的投入去做,這就可以產生一定的勢能。
對與天生對代碼狂熱的程序員而言,這并不是什么問題;但對大多數人這種理想往往并不在程序之內,而在程序之外。這時候很可能需要疊加幾類東西才能給自己蓄積足夠的勢能:物質的需求、成就的渴望、不安全感的驅離、技術上的追求等都是不錯的素材。
當然這是個人的私有領域,最終只能由個人做出選擇。?
這里最后想說的是有理想、有斗志不一定會成功,但無理想、無斗志幾乎一定會鑄就平庸和失敗,因為細致想來世界本身歸根到底是理想主義者的。
這可以通過一個簡單的邏輯游戲來做點證明:
意識決定行動:個人意志決定個人行止,組織意志決定組織行為 → 理想主義者個人意志更為鮮明,自我意識強烈,而無理想的個人意志薄弱,愿意隨波逐流 → 意識強者上位 → 處于組織核心地位的是理想主義者?→ 無理想的人不論在個人層面還是組織層面都淪為追隨者?→?從資源掌控的角度看理想主義者掌控世界。
對這事而言,理論其實不關鍵,選擇與堅持非常關鍵,但還是把它們放在這里,供大家參考。
動機理論與人生勢能
如果把我們前面提到的“勢能”做細致分解,那么你可以得到各種各樣的動機理論。動機理論卻真的可以解釋現代人種種行為,因此在這里對其做一點介紹。
1.?馬斯洛的需求層次理論?
動機理論里最有名的可能是馬斯洛的需求層次理論,即:
- 生理需要:包括覓食,飲水,棲身,性和其它身體需要。
- 安全需要:保護自己免受生理和情緒傷害的需要。
- 社會需要:愛、歸屬、接納和友誼。
- 尊重的需要:自尊、自主和成就感;地位、認可和關注等。
- 自我實現的需要。
2.?ERG理論:
- 存在需要(Existence):與馬斯洛的生理、安全需要相似。
- 關系需要(Relatedness):與馬斯洛的社會及地位需要相似。
- 成長需要(Growth):與馬斯洛的自尊及自我實現需要相似。
3.?X理論和Y理論:
X理論持下面四種假設:
- 員工生來不喜歡工作,只要有可能,他們就逃避工作。
- 由于員工不喜歡工作,因此必須采取強制和控制措施,或采用懲罰威脅他們從而實現目標。
- 只要有可能,員工就會逃避承擔責任,并尋求正式的指令。
- 大多數員工把安全感視為高于其他所有工作相關因素,并且沒有雄心壯志。
與之相反,Y理論持四種積極的人性假設:
- 員工視工作如同休息、娛樂那樣自然。
- 如果員工承諾完成某個目標,他會進行自我引導和自我控制。
- 通常人們都能學會承擔責任,甚至會主動尋求責任。
- 人們普遍具有做出創造決策的能力,并不僅僅是管理者才具備這種能力。
如果把X理論和Y理論對應到IT行業,那么提倡人件和敏捷的基本是基于Y理論,而提倡CMMI和大棒加胡蘿卜的基本是基于X理論。
4. 雙因素理論(two-factor?theory)
也被稱為激勵-保健理論(motivation-hygiene?theory)。這個理論認為激勵和讓人不煩(保健)是兩碼事情。滿意與不滿意不是對立的兩極,滿意對立的是沒有滿意,而不滿意對立的則是沒有不滿意。簡單來講管理質量、薪金水平、公司政策、工作環境這些被認為是保健因素,他們不產生滿意,只產生不滿意或沒有不滿意兩種狀態。要想激勵員工必須在晉升、個體成長上有所作為。
5. 麥克萊蘭的需要理論
這個理論把人的內在需要歸為三類:成就需要、權利需要和歸屬需要。成就需要是一種追求卓越、獲取成功的需要。權利需要則是一種控制他人行為的需要。歸屬需要則是建立良好人際關系的需要。
6. 認知評價理論
這個理論比較神奇。他認為工作本身的樂趣是已經是一種內在的獎勵,而外部獎勵反倒會降低動機的水平。這聽著比較抽象,但意思是如果總是用獎金配合績效考核來激勵員工,那么個人由于興趣而從事某項工作的動力就會降低。這很難理解,但確實也有證據來支持這個理論。
7. 目標設置理論
由于很多公司會做目標管理,所以很多程序員對這一理論反倒不陌生。這一理論大意是說:明確而具體的目標有助于提高個人效能,目標的挑戰性、針對目標的反饋都在此基礎上進一步提高目標的效果。
8. 自我效能理論
這個理論走到極端就是常說的“人有多大膽,地有多大產”。大意是說一個人對自己有能力完成某項任務的信念越強,那效能越高。或者簡單說就是自信很重要,而促成自信的方式可以是:過去的成功經驗、從榜樣吸取力量、受到言語激勵等。
9. 公平理論
公平理論是說一個人總是會拿自己的產出收入比和另一個人比較,如果比率相似,那么人們會認為環境是公平的。
這落到個人頭上,就是我們要重視這種差異么?都是同樣的學校、同樣的智商、同樣的家庭背景,如果一個人收入等比你多很多,你在意么?
10. 期望理論
這種理論把人的動機分解成幾個部分:一是如果我努力了,那么這種努力能否在績效評估中表現出來?二是如果我獲得了良好的績效評估,那么能否得到獎勵?三是即使我被獎勵了,這東西是不是我想要的。
這些動機理論從公司的角度看是激勵員工的方法,從自己的角度看則是努力前行的動力。我還是上面的觀點,這些理論知道就可,但如果無法找到對自己內心進行觸動的點,理論在這里并沒有很大的價值。如果想進一步了解,則需要閱讀組織行為學相關的書籍了。上面的內容則主要參照了人民大學出版的《組織行為學》一書。
最后想說的是單純從境界上來說似乎有一種精神遠遠超出動機理論所能涵蓋的范圍,這種澎湃的生命力和永不屈服的精神,雖然年代久遠,乃至失去傳承,但這種精神卻正是上古華夏民族所身體力行的精神。
何新先生為自己國學經典系列寫了一個總序,對此進行了很好的描述,他說:
華夏民族的先史中有一個神話時代。這個時代實際就是華夏民族肇始和文明濫觴的英雄時代。
女媧是敢于蹈火補天的英雄。伏羲、神農、黃帝、炎帝、蚩尤、大禹,或創世紀,或創文明,或拓大荒,或開民智,或奮身為天下法。
鯀與大禹父死子繼,以身濟世,拯黎民于水火;蚩尤共工九死不悔,雖失敗而壯志不屈,天地為之崩陷。
夸父逐日,體現了對神靈的藐視。而精衛填海,則表現了對宿命的不馴。
由此觀之,中華民族的神話先古時代,實在是一個群星燦爛的時代,慷慨悲壯的時代,奮進剛毅的時代;是獻身者的時代,殉道者的時代,創造英雄和產生英雄的時代。
傳說中華民族是龍和鳳的傳人,而龍鳳精神,我以為就是健與美的精神。?
我個人總是感覺很難用動機理論去解釋這種宏大且壯闊的精神。?
小結
IT這個行業確實是年輕人更容易出頭的行業,如果不信,去看看騰訊和銀行高層的年齡吧。一個企業興起的時候往往會帶著一批人走上成長的快車道。在這類企業里沒有太多的歷史包袱所以占據高位的往往是些年輕人,這和有個幾十年歷史的行業非常不同。
而為了達成這一目的,程序員首先必須有效的持續增值并成為某一方的高手(架構師、Guru或者優秀的管理者)。單純從技能上講,你一定不能和金字塔最底層的百萬大軍競爭,想象一下一個剛學會某門語言的人和一個每天思考虛擬機原理與設計、設計跨平臺系統的人有多大的差距。而從公司的角度看,高手則意味著可以為公司在現在或將來創生較大價值。
想成為高手就需要選定一個大致的方向,持續深化,并避開學習路上的諸多陷阱,如:失去焦點、分離學習與實踐、過散而不專等等。
總結
- 上一篇: jmeter基础之MD5加密
- 下一篇: python输出斐波那契数列_pytho