怎樣纔算是編程高手?

【文章來源微信公衆號:每天學編程】

程序員生存定律這系列的目錄在這裏:程序員生存定律–目錄

喜歡從頭瞄的,可以移步。

一旦度過了初始階段,做過了前面說的那些事情,那麼一個人算是基本入行了,接下來的目標就非常簡單,要在選定方向上成爲高手。高手意味着專業,而在分工無限細化的年代裏,專業則是生存、發展好最爲重要的一個前提。

1 高手的定義和養成關鍵

我估計如果問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板,而是自己一年多的辛苦投入。這種情況下強調學的知識將來有用是沒有太大意義的,因爲還有兩刀在等着:如果你三年都不做這個,你今天學到的知識可能會被更迭掉了,同時由於你年紀增長了,可能也不太適合與大批新介入這個行業的人員進行競爭。

這類事情使軟件行業中的成爲高手這事變得複雜了。

爲了在成爲高手這條路上走的順暢,事實上有三個關鍵點:一是要有一張全局性的地圖,以便選好方向;二是要知道都有那些坑,好繞開它,免得掉進去。三是要有足夠的熱情和動力,能堅持走下去。下面將分別從這三個方面來說明成爲高手途徑和方法,而這種途徑和方法會因爲具體目標不同而有所微調。

2 全局性的地圖

清代著名學者曾對知識地圖的必要性做過非常精確的表述:

凡讀書最切要者,目錄之學也。目錄明,方可讀書,不明,終是亂讀。

—王鳴盛,《十七史商榷》

目錄即是地圖。

對於軟件開發的知識,我更願意使用下面的的“地圖”,這不一定是最合理的,但確實對歸納各種軟件開發知識有所幫助。

  • 通用的領域知識
  1. 編程語言(C/C++,Java,C#,Python,Perl,PHP等)
  2. 框架和類庫(Struts,Spring,OSGi的某個具體實現,MFC,Boost等)
  3. 平臺(Windows API,POSIX,.Net Framework※1,Java API,C/C++ Runtime Library等)。恰如Jeffry Richter所說,大多時候可以從內存機制、線程機制、錯誤處理、異常處理、組件構建、組件組合等方面來進一步考察一個平臺。
  4. 計算機體系結構(CPU指令,虛擬存儲等)
  5. 數據庫
  6. 實用技巧(調試方法,代碼生成器等 )
  7. … …

※1 有的時候子類別間的界限並不是很容易界定,其中一個主要原因就是存在着像.Net Framework這樣涵蓋了過多內容的概念。

  • 概念和邏輯創建和優化
  1. 面向對象分析和設計/結構化分析和設計
  2. 設計模式
  3. 重構
  4. 契約式編程
  5. UML ※2
  6. … … ※2 從形式上來看UML更近似於一種編程語言,但從其目的上來看也許歸在這裏是更合適的一種選擇。
  • 專業領域知識
  1. 圖形圖像算法
  2. 網絡協議
  3. 人工智能
  4. 數值/非數值類算法
  5. 財務知識
  6. 負載均衡
  7. … …

關於軟件的間接知識:

  • 需求開發和描述

  • 估算

  1. 估算法。比如,COCOMO, FP等。
  2. 估算術。比如,使用計數等原始辦法。
  • 軟件工程和方法論
  1. 輕量型方法論。比如敏捷。
  2. 大方法論。比如CMMI
  3. 綜合分析。比如,《人月神話》,《人件》所做的工作。

隨着待解決問題越來越複雜,通用的領域知識中,幾種技術往往會組成一種技術Stack,他們更需要被看做一組必須一起掌握的知識,比如:LAMP(Linux+Apache+MySQL+Python)。

當然上面羅列的遠不是全部,這種羅列更多的是展示一種分類的方法。通過對這種分類方法的補充和完善,大多可接觸到知識都可以被歸入特定的類別,比如說:WinRT可以看做一種新的平臺,HTML5則可以看做是一種語言等。

每個人可以根據自己的情形,參照上面的分類建立屬於自己的地圖,有點問題沒關係,有就比沒有要好很多。接下來依據這樣的地圖就可以選一條自己的線路,持續累積,尋求實踐機會,最終就很可能會成爲真正的高手。

而關於增值所需的動力,所要避開的陷阱,將下面陸續提到。

增值、讀書與大局觀

單純從達成某一目的而言,讀書往往非是絕對必要條件。

秦始皇把書一把火燒了,劉邦項羽一樣造反並取得勝利。但讀書無疑的可以加速一個人增值的過程,記不得是誰說過:實踐無疑是人類最好的老師,但只靠實踐來認知世界無疑也是愚蠢的。這是非常精闢的。除此之外,要想培養大局觀,那就非讀書不可。

每個人的親身經歷,在大的時空背景中往往只是一個簡單的截面,這一截面中絕不會包含可以歸納出所有真理的事實,因此只依賴於自身的實踐也就必然限定了一個人的視野。 這一點隨着一個人的責任範圍變大往往會體現爲一種制約和限制。所以培根講:有實際經驗的人雖能夠處理個別性的事務,但若要綜觀整體,運籌全局,卻唯有學識方能辦到。

即使從實踐來看也是如此,要想培養出一種大局觀,那就非讀書不可。而大局觀往往是成爲將帥之才的必要條件。

具體到軟件而言,有一本很有名的書對培養技術的大局觀有幫助:《代碼大全》。至於專業性較強的書,反倒是可以根據自己的情景比較容易的選擇,這裏就不提了。

基於上面這樣的一張地圖,我們就可以具體的去考慮幾條進階路徑。

路徑一:由程序員而架構師

架構師是一個很火的職位名字,但你很難給它下精確的定義。

下面所陳述的一切是我個人的理解和體會,我無法保證它和其他人的解釋完全吻合。因爲架構師,乃至架構設計實在是一種非常模糊的概念,如果你用心去找,可以找到各種定義(甚至IEEE和SEI的定義也不一致),這就導致你只能參照別人,相信自己。

本質來講架構設計也是設計,所以凡是做設計的都可以稱自己爲架構師。

當一個系統的規模變大的時候,設計上的決策就具有了特別的價值,並且也越來越需要專門的人來做,架構設計也就越來越像是一種特別的設計。比如說:考慮架構設計的時候,可能需要考慮選用什麼樣的數據庫)、選用那個開源框架、選用什麼樣的硬件平臺,這些東西在小規模程序中往往是居於次要地位的。

假設說一個人已經掌握了一門或幾門編程語言、面向對象、設計模式、能夠很熟練的寫出質量較高的代碼,接下來他想成爲架構師,這個時候他需要做什麼?

我個人認爲,這時候這個人首先要有一個“專業”。這個專業可以是“金融”,“財務”,“電商”,“管理”等等。這是一種屬於某一專業的領域知識,而不是編程技術。如果把需求和最終的代碼,看成描述同一事物的一體兩面,那麼設計始終是要架起這兩者間的橋樑。而架橋的時候,怎麼可能只知道一端而不知道另一端。

接下來是深化設計所需要的各種通用領域知識(UML、面向對象、性能確保等)。這時和一般所說的設計的一個關鍵區別是,那就是架構設計要分心思去考慮那些東西用別人的就好了,而那些東西要自己開發。而一般所說的設計技術中,比較側重自己應該怎麼幹(面向對象、測試驅動等)。爲達成這一目的,就需要對現有技術的優劣有相對比較清晰的認識,比如要能分清楚那些是成熟穩定的技術,那些是處在實驗階段的技術

最後一點要說的是,做架構設計已經相對於在做技術管理工作,至少要適當涉獵估算並能做出合適的任務分解,這樣一旦日程緊張,則可以通過增加人手等手段來在質量、成本和進度之間進行均衡。

由於知識面已經擴的比較大,架構師在具體某個專業領域上的深度可能會有所欠缺,比如:在做一款電子消費產品時用到了TTS,但架構師不一定能很好的瞭解TTS的算法—這是CodeGuru的領域。

架構師所需要達成的最終目標可以形象的描述爲:產品經理考慮用戶和市場建立了一個模型,那麼架構師要能把這東西映射到技術的世界裏來。如果是在互聯網行業,那麼在你的主導設計下要可以做出高併發的網站。換到其他行業也與此類似,從產品的的角度往回看,架構師要能解決和技術相關的所有問題,主導完成商業上有價值的產品或項目的開發工作。實現手段上倒並無限制,可以是購買,可以是組織人員進行開發,只要能平衡短期和長期利益,解決特定的問題即可。

路徑二:由程序員而CodeGuru

與架構師相對應,在某些智力密集型的程序中,也需要技能高超的程序員,這種程序員往往被稱爲Guru。

這條路線裏,程序員並不把自己擅長的領域擴的太寬,但在指定領域上會挖掘的很深。驅動、字庫、圖形庫、算法庫、OCR等都偏向於這一領域。

假如說,一個程序員在掌握基本語言之後,想往這個方向發展,那麼需要的技能和架構師差別很大。比如:一個人如果想往驅動方向發展,那麼就需要了解CPU的基本結構、內核調試方式、操作系統中與相應驅動所對應的機制、硬件側的規格、通訊協議等。

這時候很可能由於程序規模並不十分龐大,面向對象、設計模式這類東西沒有太大發揮空間,而是需要處理的是大量或麻煩或艱深的細節。

路徑三:由程序員而純管理

純管理工作和技術管理工作可以用是否接觸乃至編寫代碼來區分。純管理工作往往需要把精力放在預算編制、人員職業路徑、考評、度量、流程改善這些工作上。一定程度上講,這等價於和編程工作說拜拜,當然前提是你得有編程經驗,有一些通用領域知識和概念創建乃至邏輯優化的知識,否則的話和程序員沒法溝通,進而給工作造成障礙。

從需要讀的書來看,這時候可能要看過PMBOK,《項目管理修煉之道》,《管理的實踐》,《基業長青》等等。

但如果一個人認爲想做管理要從PMP開始,那大概是還沒太明白管理這項工作的本質。管理本身是一種借勢,雖然有技術性的一面,比如要理解掙值曲線這類,但這方面知識其實並沒有想的那麼複雜—至少沒有C++11複雜,只要有時間正常智商的人都可以在不太長的時間內掌握。所以如果你想做管理,並使用了和學習C++語言一樣的方法,那基本上是偏離了方向。

拋開機緣這類東西不論,做好管理工作有兩點很關鍵:

一是要把技術工作做的相對比較好。這好像有點學而優則仕的意味,但大多時候人們更願意相信“將軍起於行伍,宰相拔於州郡”,而不願意相信單隻會耍嘴皮子的人。過度務實的人容易迷失於道路,過度務虛的人則容易飄的太高而喪失根基。管理者正應該身處在這兩者之間的一個平衡點。

二是要能夠借勢。要情商比較好,能把很多人組織在一起。這個時候要知道那些東西需要規則化,那些東西需要靈活把握。過度偏向規則是教條,過度偏向靈活則是人治,平衡點始終要根據具體人員的狀況,工作特質這些不可改變的事情來把握。這有點微妙。但即使程序員這個羣體相對簡單,但並不能推翻先人後事這類規則。這不知道是不是東方特色,當你想做管理並想推進事情的時候,終究要理清人際上的關係,否則就和可能會欲速則不達。這點會在第五章進一步展開來談。

下面我們來看一個具體點的例子,這個例子出自郭致星老師的博客,是一個學員的真實疑問(文字上有修飾),X入職後的現狀如下:

開發部現在26個人。基本組織架構是由開發組、需求組、測試組、運維部四個部門組成。需求組的人收集需求,再通過系統指派給開發組,進行開發。開發組的文檔嚴重缺乏。

現在公司內有技術總監和開發部經理的崗位。眼下全公司就X一個項目經理,目前是跟着開發部經理,在熟悉一個核心繫統,由於沒有任何文檔的遺留,所以現在是相當於一個開發人員在開發一些實際的功能,一邊開發一邊熟悉現有系統。

現在X並沒有項目的實際權力,而且整個項目組也只有開發部經理,加上2個開發,再加上1個測試和X共5個人。其中X和其中一個開發都是新來的。

與此同時,業務部門在搞一些流程,但還沒做完,沒有在開發部進行實施。工作氣氛比較沉悶。技術總監和開發部經理,都是技術型的人,比較偏向技術,平時工作也多偏向於具體執行。

在使用一個Redmine系統進行項目管理和BUG跟蹤。

這裏的系統大部分都類似於產品線制,屬於需要長期開發維護的,需求源源不斷的來,相應人員也就需要不停的做,沒有版本制度,也沒有計劃和規劃。

系統現在主要的問題是性能問題。

問題就是在這樣的一種環境下,X應該如何開始自己的管理工作?

這類問題通常並沒有唯一答案,但確實有些通行的手段可供參考,最終做不做的好和個人能力乃至環境關聯很緊:

1.瞭解現有系統的狀況,包括規格、代碼規模、代碼質量、代碼內部結構、工作流程、問題所在等。比如說:很可能這類系統缺乏一種整體設計,是靠單純的增加代碼的量堆積出來的,代碼冗餘非常厲害,數據庫的表也創建的比較隨意。

2.瞭解人員。包括人員的能力水平、工作意願狀況、性格。

3.瞭解公司。尤其是公司的運作風格,有的公司偏人治有的公司偏於規則。短期對這類現行秩序要考慮如何順應,而不是如何改變。

4.對當前系統的狀況和人的狀況有所把握後,要對願景進行描畫,比如在功能上做那些改善,對速度做如何改善,目標的高低要適度,要能獲得上司和下屬的支持。這時候還要能平衡短期和長期目標,既不能長時間投入沒有產出,也不能有產出但進步不可見。在這一步驟裏最典型的忌諱是急功近利的做超出自己影響力範圍的事情。比如:目標與現有人員的能力完全不匹配或者完全不顧及對銷售可能產生的影響而單純的做系統的優化。最理想的情形是,連續達成幾個目標,提升自己的影響力。

5.搞清楚團隊成員和公司的的基本訴求,在取得成績的同時儘可能雙贏的擴大自己的影響力,目標是確保團隊的執行力。

6.逐步導入基本流程,使項目上軌道。但流程不能成爲成績的藉口。

7.接下來進一步的規劃願景,看能否取得更大的成績,比如:挑戰是否能做出真正有特色比較優異的產品。

在不同類型的公司裏,對應手段上會有不同。比如在規範性比較強的大公司,第4,5兩步的權重就會比較低。在上述這樣的場景下,PMP這類書籍中所提到的種種技術手段誠然是必要的,但和人打交道的部分(老闆、直屬上司、下屬)往往會對最終的結果產生更大的影響,這是管理工作與純粹技術工作不同的地方。

從事全棧6年,專門建立的學習Q-q-u-n ⑦⑧④-⑦⑧③-零①② 分享學習方法和需要注意的小細節,互相交流學習,不停更新最新的教程和學習技巧(從零基礎開始到WEB前端項目實戰教程,學習工具,全棧開發學習路線以及規劃)點:學習前端,我們是認真的

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