從許多方面看,程序員之間的差異都非常大,只有很了解程序設計的人才能完全理解這一點。大多數公司的高層管理者對所有的程序員一視同仁,這是一個可怕的錯誤。微軟公司的Bill Gates和Adobe Systems公司的John Warnock都沒有犯這樣的錯誤,因為他們倆本質上也都是程序員。
這種差異為什么很重要?也許不應該很重要,但事實上,這種差異真的很重要。歷經多年的程序員管理工作之后,我們仍然驚嘆于程序員之間的巨大差異,需要有區別地進行問題處理和激勵。對我們而言,有一點是毫無疑問的:要想成功地管好程序員,首先必須真正地了解每個程序員。
有一點值得重視:我們發現一般情況下,程序員的年齡、性別、種族或文化不會造成太大的差異。根據我們對數以百計的程序員招聘與管理的經驗,程序員之間的差異主要來自個人內在因素,而不是外在屬性。當然,后天的訓練和經歷肯定是有影響的,但個人的天賦和與生俱來的特點才是真正的區別所在。
理解程序員的方法有很多種,我們從以下幾個不同的角度來考慮:
程序設計工種;
程序員的類型;
領域知識;
程序員的工作要求與能力;
工作地點與關系;
代系特點;
個人特點。
1.程序設計工種
了解程序員的第一種方法是分析他們的程序設計工作可以歸為哪些類型。程序設計工作通常有下面4種類型:
客戶端程序員;
服務器程序員;
數據庫程序員;
Web開發人員及其他腳本編寫者。
當然,可能有許多特殊的程序設計工作難以確切地歸結為上述某種類型。但總的來說,這4種類型已經覆蓋了世界上的絕大多數程序員,其中每一種程序員擅長的問題解決方法、使用的工具以及側重的產品方向都各不相同。一些極有天分的程序員能夠勝任所有工作,但大多數程序員認為自己雖然能完成所有的程序設計任務,但其實只能把其中一種做好。
一般情況下,我們建議為不同類型的工作任務安排不同的程序員,不要指望哪個程序員能同時兼任多種類型的工作,否則你很可能會為這個決策感到后悔。因此,在雇用程序員或者為項目安排人手之前,首先必須明確自己需要什么類型的程序員。
1.1 客戶端程序員
把所有曾經從事過程序設計工作的程序員都統計在內,大部分程序員都屬于客戶端程序員。這里術語客戶端(client)指的是程序所在的位置,通常是終端用戶的計算機上。個人電腦的出現催生了無數的“客戶端程序”——文字處理軟件、電子表格、工作效率程序、游戲以及眾多的實用工具(包括微軟的Word與Excel、Brøderbund的Myst游戲以及Lemke的GraphicConverter工具等)。而在個人電腦出現之前,程序員所編寫的大多數程序都在中央系統中運行。程序的開發者負責把“客戶端結果”傳輸到非智能終端或者智能終端,或者通過打印出的報告提交“客戶端結果”。這些程序開發者也是客戶端程序員。
隨著低成本微處理器的普及,客戶端程序員逐漸把業務拓展到嵌入式應用領域,所開發和交付的應用可以在游戲控制臺、手機、iPad以及其他的消費電子設備和終端用戶設備上運行。
為什么把這些程序員都歸類為客戶端程序員呢?因為他們在工作時幾乎可以完全控制自己的資源。客戶端程序員的任務范圍通常是有限的,所需要交付的產品也是明確的。因此,客戶端程序員/團隊的職責很明晰,除了服務器端傳來的數據外也幾乎不依賴其他東西。
1.2 服務器程序員
你可以通過學習Java視頻來成為一名服務器端程序員這里術語服務器(server)不僅指出了程序所處的位置,還表明了編寫程序的目的通常是向遠程客戶端傳輸信息和數據。服務器程序所在的機器通常離終端用戶都很遠,而且大多數這樣的程序必須能夠同時處理來自多個客戶端的多種行為,這就使得服務器程序通常比客戶端程序員開發的程序更復雜一些。在編寫和部署服務器程序時,通常還要求在增加新機器與資源時能不用改變程序的基本結構,這又進一步增加了開發服務器程序的復雜度。
隨著互聯網的出現,術語客戶/服務器(client/server)就成了Web瀏覽器與(“在網上某個地方的”)Web服務器之間交互方式的代名詞。基于客戶端的Web瀏覽器很復雜,但實踐證明,創建能夠使數以百計或數以千計的終端用戶同時訪問同一臺Web服務器的服務器程序,確實是一項更為復雜的工作。構建這樣的系統通常離不開在各個服務器系統與程序之間進行接口轉發、數據傳輸及同步的工作。這類工作是典型的服務器程序員需要完成的任務。
1.3 數據庫程序員
數據庫程序員與客戶端程序員或服務器程序員不同,他們使用完全不同的程序設計語言和工具,編寫的程序給出的結果也截然不同。數據庫程序員通常是對終端用戶或應用程序所使用或產生的數據進行組織、存儲和提取工作。
這些年來,不同數據庫系統之間的差別逐年減少,數據庫程序員在一個數據庫系統中積累的“基本”技術技巧也更容易遷移到別的數據庫系統了。盡管像Hadoop這樣用于訪問TB級數據的“大數據”系統已經涌現出來,但較常用的數據系統仍然是關系數據庫,包括Oracle、Microsoft SQL Server、IBM DB2、MySQL、Postgres和Berkeley DB。這些系統中的多數關鍵概念是相同的,它們都使用SQL語句(以及等價的API)來訪問數據。因此,有人可能會認為,其中某個系統的大牛很可能也是另一個系統的大牛。但根據我們的觀察,除非是很基本的數據庫操作,否則在特定數據庫系統上的實戰經驗仍然是必需的。
數據庫程序員就像是汽車修理工。你可能會隨便找一個汽車修理工幫你換輪胎或者雨刮器;但是對于保時捷汽車上的重要問題,你一定不會讓一個完全不了解保時捷的修理工來做。數據庫程序員也是如此:我們可能會隨便找一個數據庫程序員撰寫報告來訪問Oracle數據庫中的數據;但需要在數據庫系統(如Oracle、SQL Server)上進行重要的開發時,一定不會考慮實戰經驗不足的程序員。
1.4 Web開發人員及其他腳本編寫者
許多Web開發人員使用的開發工具完全不同于其他程序員,在大多數開發工作中,其他類型的程序員通常使用C、C++、C#、Java、Ruby等核心程序設計語言,Web開發人員通常使用格式化標記語言(如HTML、XML、CSS、ASP/JSP)和腳本工具(如Perl、PHP、JavaScript)。Web開發人員的工作有時可以歸納為“剪切、粘貼和修改”(復制一些現成的代碼,進行適當的修改以完成不同的任務)。他們也會使用更高層次的工具(如Flash、Dreamweaver或Cold Fusion)來簡化腳本編寫和部署過程。這就意味著只從事Web開發的程序員雖能夠從正規的計算機科學訓練中受益,但又不像其他程序員那么依賴正規的計算機科學訓練。
另一方面,更多的處理工作逐漸從服務器移至瀏覽器,通過JavaScript和基于AJAX的框構來完成,這一變化也對Web開發產生了深遠影響。瀏覽器兼容性問題是Web開發人員長期面臨的棘手問題。在客戶端引入更多的邏輯會加劇這些問題,要求Web開發人員引入更多的傳統程序設計原理,所引發的需求,要求Web程序員像客戶端程序員一樣技術高超。Web開發人員越來越需要學習客戶端程序設計及其所面臨的問題了。
前面描述的4種程序員類型是一般性的情況,一些技術高深的程序員實際上可以勝任所有這4種工作。但是,大多數程序員都只專精于其中一個領域,只有在編寫“適合自己”類型的代碼時才能獲得較大的產出。讓程序員加入風格不合的項目往往只會引發災難。程序員也許能夠勝任其他類型的工作,但大多數程序員對此沒什么興趣。而如果程序員對自己所從事的工作沒有興趣,那就遲早要出問題了。
2 程序員的類型
為了選擇合適的職員,我們還需要理解另一種看待程序員的方法。在上一節討論的幾種類型中,我們側重考慮了程序員所從事的工作的類型(即客戶端、服務器、數據庫、Web)。實際上,從技術知識、實踐經驗和程序員的專長角度去考慮也是很重要的,按這樣的思路可以把程序員分類為:
系統工程師/架構師;
系統程序員;
應用程序員;
非真正意義上的程序員。
2.1 系統工程師/架構師
在所有開發類職員中,系統工程師/架構師是更有技術和經驗的。要想理解所有相關的系統組件(操作系統、通信系統、數據庫、在線/離線訪問、安全性、硬件等)之間的復雜關系,需要對所有這些技術和系統都有豐富的專業知識和經驗。通常,在一個規模合理的團隊中,只會有一兩個“真正的”系統工程師/架構師。杰出的系統工程師/架構師可以使團隊中的其他人表現得更好。他們的系統工作起來會更可靠,通常看起來也更簡潔。
Gracenote就是由一個技術和經驗都很豐富的系統工程師/架構師創立的,純粹由他完成的設計和實現創造出了一種令人難以置信的可靠、可擴展而且靈活的服務。Google公司的聯合創始人Larry Page和Sergey Brin也是類似的系統工程師/ 架構師,他們在設計和實現上培育的優雅風格幫助Google公司在技術和商業領域都取得了成功。
2.2 系統程序員
大多數系統工程師/架構師都是從系統程序員做起的。系統程序員理解系統中所有組件的工作原理,包括客戶端和/或服務器端的操作系統和通信系統。Alan Kay在他的博士論文中引用了Bob Barton對其他程序員如何看待系統程序員的總結:
系統程序員相當于民間宗教中的大祭司。
——Bob Barton
系統程序員負責編寫與硬件交互的設備驅動程序,創建能夠為設備驅動程序和應用程序執行提供運行時環境的操作系統,為其他程序員創建編譯器和調試工具,通常還會為其他程序員提供工具和服務用于交付程序。
在過去,對社交能力正常的人來說,被稱為系統程序員幾乎可以說是一種侮辱。我們認識許多系統程序員,他們的著裝和舉止如今已成為代表性的極客造型并流行開來。每當我們想起自己認識的那許多系統程序員,就會想到“我當極客的時候,極客還不受歡迎”這句話(順便提一下,我們兩位也曾經是系統程序員)。
2.3 應用程序員
在專業程序員、學生以及自稱為程序員的業余愛好者中,絕大部分都屬于應用程序員。應用程序員開發的程序或其結果通常給終端用戶直接使用。應用程序員開發的程序包括文字處理軟件、電子表格、日歷、Web瀏覽器、iTunes與Windows Media Player之類的媒體播放器、游戲等。應用程序也可以由數據庫程序員開發,以便對數據庫中取出或存入的數據執行特定的操作。數據庫應用程序包括財務軟件、機票預訂系統以及Oracle Financials之類的數據挖掘工具等。
一些應用程序員能夠跳出代碼本身的束縛,與應用程序的用戶產生同感,真正從用戶的角度看問題,從而很好地把握各種可視化、交互式的設計之間的細微差別。這樣的應用程序員很適合從事用戶界面(UI)的開發。如果讓這樣一位有天分的應用程序員與一名UI設計師(通常不僅有圖形設計背景,而且對人性甚至認知心理學都有所研究)合作,將產生一加一遠大于二的效果。
有一些項目(如MacOS的桌面UI——Mac Finder)側重于UI,要求整個團隊都由這種有天分的應用程序員組成。因此,Ron在蘋果公司領導Mac Finder團隊時,在尋找和面試候選人的過程中,特別看重程序設計技巧和用戶視角。他認為:“只懂得程序設計技巧的程序員在那個團隊中是無法取得成功的。”
2.4 非真正意義上的程序員
開發團隊中有一些被稱為“程序員”的技術人員其實并不是真正意義上的程序員。他們當中有些人使用圖形用戶接口(GUI)指定程序邏輯或商業邏輯,然后生成用戶可訪問的應用程序;有些人則通過創建腳本或修改配置文件來定制顯示的內容。這些“程序員”與真正的程序員之間的主要差別在于:他們使用現成的工具或應用程序,而不是自己直接寫代碼。
這類“程序員”有其重要性和價值,但他們的技術深度通常不能與我們所討論的其他類型的程序員相提并論。隨著程序設計工具的出現和日益強大,像這樣的程序員正變得越來越多,但在本書中我們不會直接討論他們。
我們所介紹的許多程序設計技術也適用于這種另類的“程序員”。但根據我們的經驗,他們中的多數人僅滿足于把自己的工作做好,而不像“真正的”程序員那樣渴求學習、動力十足。
3 領域知識
程序員在組織所處領域或行業的背景與知識也各不相同。
我們發現職位的分類、描述和需求中對經驗的要求是隨著經濟狀況而變化的。經濟狀況較好時,組織需要具有寬廣領域知識的技術人員和技術經理,希望他們能貢獻出創造性的思維、集體的智慧以及在其他領域已經得到運用的實踐。例如,Ron受雇從產品領域進入金融服務IT行業時,他的團隊已經有了豐富的交互計算經驗(Mac操作系統)和娛樂產品(游戲與多媒體工具)。Web在1996年屬于新生事物,Schwab需要一個外部技術大神來領導其團隊為投資者構建具有高度交互性的Web工具。
而當經濟狀況不好時,組織則會控制規模、縮減開支,只在核心領域功能方面進行快速、有限的發展。企業在這一時期只能夠招聘很少數的新雇員,為了降低風險,它們傾向于招聘在特定領域具有多年知識背景的專業人士。
不管經濟狀況如何,每個團隊都可以由具有程序設計天賦、領域知識、分析能力以及技術交流能力的人員混合構成。其中領域知識在雇用程序員團隊時是一個重要的考量因素。
4 程序員的工作要求與能力
要想成功地招聘和管理程序員,首先要認識到每個程序員都有其自身的能力。就像雪花一樣,任何兩個程序員都不會是完全一樣的。我們常常會說,程序員之間寫代碼的能力可能相差一個數量級。這種差異是怎么出現的呢?教育、經驗、天賦以及直覺,還有其他無形的因素,都有可能導致這樣的差異。
多數程序員不需要借助顯式的排名或者頭銜,從直覺上就能理解同行之間的差異。但是如果能把程序員的類型與等級正式記錄下來,并簡要描述每種類型與等級的職位要求與能力,那么管理工作將會輕松很多,項目經理將更容易找到各種任務和項目的較好人選,高級管理層也將能對組織及其構成有更深刻的認識。