如何管理飛揚(yáng)跋扈的技術(shù)人員

2014/04/02 10:55      韓偉

 

在互聯(lián)網(wǎng)項(xiàng)目當(dāng)中,相信每一個(gè)項(xiàng)目經(jīng)理或者制作人,最頭疼的就是技術(shù)部的管理。因?yàn)榧夹g(shù)工作看起來是那么的棘手,一般人難以理解,而且技術(shù)人員大多數(shù)都似乎情商不高。管理人員既不能輕易了解技術(shù)工作的內(nèi)涵,技術(shù)人員也覺得很難和管理人員溝通。特別是技術(shù)工作,難以在不同人之間交接,很多技術(shù)人員都聲稱無法繼續(xù)別人做過的項(xiàng)目。這讓管理者覺得技術(shù)人員特別喜歡耍大牌,而且他們要偷懶也非常容易。但正如軍事中的定理,對付坦克最好的武器就是坦克,對付航母最好的武器也是航母,這條理論是通用的。要管理好技術(shù)人員,就一定要懂技術(shù)。這是任何一種其他號稱完美的管理方法都無法替代的。

開發(fā)是一切——何時(shí)寫文檔

對于技術(shù)管理來說,很多公司會(huì)非常注重文檔。雖然開發(fā)的結(jié)果是代碼,但對于管理來說,代碼往往難以閱讀,也很少有人擅長接手別人的系統(tǒng)。為了讓代碼不至于被丟棄,公司管理人員就祭起文檔這個(gè)法寶。我認(rèn)為文檔是很重要的,但也發(fā)現(xiàn)這些文檔中很典型地存在幾個(gè)問題:文檔和代碼不同步;文檔的可讀性差,需要的文檔沒寫,不需要的文檔寫了一大堆;文檔和代碼脫節(jié),文檔很多,開發(fā)出來的成果很少。

我們應(yīng)該何時(shí)寫什么文檔,這是需要有嚴(yán)格定義,并且有檢查過程的,而不是任由大家自然發(fā)展就可以完善的。代碼的編寫需要按不同類型,定義好在各個(gè)階段中所需要完成的部分。

設(shè)計(jì)類文檔—— 這類文檔往往在項(xiàng)目、模塊啟動(dòng)的時(shí)候,大家都會(huì)想到要去寫,作為討論和最后決議的成果,顯然是很自然的。然而在項(xiàng)目進(jìn)入開發(fā)之后,碰到實(shí)際問題時(shí),往往就不能完全按照設(shè)計(jì)的初衷去做了,所以通常設(shè)計(jì)文檔就在這個(gè)時(shí)候和代碼脫離了聯(lián)系。但有一點(diǎn)是絕對可以做的,就是在重構(gòu)的時(shí)候,按照現(xiàn)有狀況,重新增加重構(gòu)前的系統(tǒng)狀況說明,然后再添加上重構(gòu)后的設(shè)計(jì)。這樣就把重構(gòu)的設(shè)計(jì)和文檔的更新結(jié)合到一起了。

API(應(yīng)用編程接口)文檔——現(xiàn)代軟件都希望能提高重用的程度,因此很多程序員都會(huì)自己構(gòu)造自己的業(yè)務(wù)API,以便在之后的開發(fā)中使用。而這種業(yè)務(wù)API,也是很多分工合作的基礎(chǔ)。這種代碼的說明,會(huì)直接影響日常的開發(fā),因此非常有必要保證和代碼的高度一致性。

使用文檔—— 一般來說,一個(gè)軟件的使用文檔必須包含以下幾個(gè):《產(chǎn)品版本說明》、《產(chǎn)品安裝和部署文檔》、《產(chǎn)品使用教程以及例程》、《產(chǎn)品FAQ文檔》。這里面的《產(chǎn)品版本說明》應(yīng)該在每次發(fā)版的時(shí)候,作為發(fā)布流程的一個(gè)固有環(huán)節(jié)來設(shè)計(jì)?!懂a(chǎn)品使用教程以及例程》是我認(rèn)為所有文檔中,最值得花大力氣去寫好的?!懂a(chǎn)品安裝和部署文檔》內(nèi)容越少越好,應(yīng)該讓安裝部署盡量智能化、自動(dòng)化。

了解什么是軟件架構(gòu)

了解軟件架構(gòu)的范疇,才能有針對性地去把握軟件開發(fā)中的風(fēng)險(xiǎn),從而管理好軟件開發(fā)的過程。簡單來說,軟件架構(gòu)就是應(yīng)對需求所產(chǎn)生的“一系列決定”。軟件會(huì)根據(jù)這些決定來開發(fā)。根據(jù)軟件需要應(yīng)對的需求,軟件架構(gòu)一般包含以下幾個(gè)部分。

邏輯架構(gòu) 主要是為了明確“功能性需求”而做的設(shè)計(jì),針對需求以及需求變化作為架構(gòu)目標(biāo)所做出的關(guān)于代碼之間的劃分、耦合、關(guān)聯(lián)的決定。采用合理的邏輯架構(gòu),將會(huì)大大降低需求變更對開發(fā)的延遲作用。邏輯架構(gòu)最直接指導(dǎo)代碼中互相耦合的情況,仔細(xì)設(shè)計(jì)好耦合的規(guī)則,會(huì)讓后續(xù)開發(fā)事半功倍。

運(yùn)行時(shí)架構(gòu) 運(yùn)行時(shí)架構(gòu)是為了滿足運(yùn)行期的質(zhì)量需求,所做出的關(guān)于對象行文、進(jìn)程結(jié)構(gòu)、通信協(xié)議、數(shù)據(jù)結(jié)構(gòu)等方面的決定。運(yùn)行架構(gòu)一旦確定,等于大部分的“實(shí)現(xiàn)”代碼都確定了,設(shè)計(jì)有足夠擴(kuò)展性和可用性的運(yùn)行架構(gòu),可以為后續(xù)工作節(jié)省時(shí)間,也降低了系統(tǒng)在運(yùn)行期對開發(fā)工作的干擾。

開發(fā)架構(gòu) 為了滿足開發(fā)時(shí)的需求所做的決定,主要是軟件根據(jù)分工開發(fā)、測試驗(yàn)證流程等需求劃分的軟件層次和區(qū)域以及各種接口設(shè)計(jì),也包含使用的軟件包、組件庫、開發(fā)工具,以及編譯構(gòu)建的方法。一個(gè)好的開發(fā)架構(gòu),可以讓溝通成本降低,開發(fā)速度提高。

部署架構(gòu) 現(xiàn)代軟件系統(tǒng),基本上都包括了客戶端和服務(wù)端程序,如何快速、高效、穩(wěn)定地部署和發(fā)布這些程序,如網(wǎng)絡(luò)機(jī)房的分布、服務(wù)器硬件的搭配、監(jiān)控和維護(hù)工具軟件的安裝、開發(fā)測試網(wǎng)絡(luò)和運(yùn)營網(wǎng)絡(luò)的設(shè)置??梢垣@得安全性的配置,良好的部署能力,能推動(dòng)軟件進(jìn)行更頻繁、更全面的測試,從而提高軟件質(zhì)量和開發(fā)效率。

數(shù)據(jù)架構(gòu) 數(shù)據(jù)是軟件項(xiàng)目的核心財(cái)富,關(guān)于數(shù)據(jù)的結(jié)構(gòu),數(shù)據(jù)的存放、備份、傳輸會(huì)直接影響到運(yùn)行性能、業(yè)務(wù)功能、部署、安全等需求。在面向?qū)ο蟮拈_發(fā)模式下,數(shù)據(jù)到對象的ORM架構(gòu)也是很重要的設(shè)計(jì)。一個(gè)完整的數(shù)據(jù)架構(gòu)包括了數(shù)據(jù)流圖、數(shù)據(jù)字典、ORM結(jié)構(gòu)(如果需要的話)、數(shù)據(jù)索引和備份機(jī)制等幾個(gè)方面。

何時(shí)以及如何評審

相信大部分公司都有評審這個(gè)環(huán)節(jié),評審可以包括方案評審、代碼評審、項(xiàng)目專項(xiàng)議題的評審,比如對存留Bug的處理評審等。而這些評審,常常會(huì)變成一個(gè)挑毛病的會(huì)議。要解決評審給產(chǎn)品帶來的負(fù)面影響,同時(shí)發(fā)揮這個(gè)活動(dòng)的優(yōu)點(diǎn),我們需要關(guān)注以下幾個(gè)方面。

評審由誰發(fā)起 相對比較好的是,由負(fù)責(zé)此項(xiàng)目的“領(lǐng)導(dǎo)”來召集人員評審,并且一定要有負(fù)責(zé)開發(fā)的人員參加評審。參與評審的受邀請人員可能會(huì)與方案提交者就一些問題有分歧,但提交者有最終決定權(quán)。要把權(quán)力給有能力承擔(dān)它的人。這樣做可以讓“防止風(fēng)險(xiǎn)”的一部分人和“注重效率”的開發(fā)人員形成平等的意見交換。

什么時(shí)候做評審 應(yīng)該在每個(gè)迭代、每個(gè)較大的版本開工前,或者僅僅是某個(gè)認(rèn)為比較重要的決定做出前,都來一次簡短的評審。如果開始時(shí)只是做一個(gè)DEMO,那么需要評審的東西也比較少,而隨著不斷的開發(fā),評審也能遍歷所有的開發(fā)。

做評審的方法 真正對項(xiàng)目有幫助的,是了解項(xiàng)目的需求,分析面臨的難點(diǎn),思考方案為何這樣做,提出自己的解決方案,給項(xiàng)目開發(fā)者以建議和啟發(fā)。多說“我建議這樣解決這個(gè)問題”,而不要僅僅去說“這樣做可能有問題,應(yīng)該添補(bǔ)這樣的功能”。以建設(shè)性的心態(tài)和思路去做評審,而不是以找問題的思路去做,這就是兩種做法的最大區(qū)別。

分層開發(fā),盡快運(yùn)行

為了降低軟件耦合給開發(fā)帶來的負(fù)面影響,正確的做法是要高度重視軟件開發(fā)方法,從代碼風(fēng)格、軟件架構(gòu)、設(shè)計(jì)模式、開發(fā)模式方面來提高水平。其中一個(gè)最簡單有效的做法,就是分層。在經(jīng)典的架構(gòu)模式中,分層模式幾乎是所有模式的基本模式:把代碼按照你所需的范圍劃分層次,然后規(guī)定層次之間的耦合接口,層次之間只可單向依賴,而且盡量減少跨層耦合。劃分層次的范圍,由你的開發(fā)團(tuán)隊(duì)水平和項(xiàng)目的復(fù)雜程度決定。

非功能需求決定成敗

世界上類似的項(xiàng)目非常多,但成功的占少數(shù),失敗的占多數(shù),這種現(xiàn)象的背后有一個(gè)重要的原因,就是非功能需求。非功能需求具體包括:軟件開發(fā)效率的相關(guān)需求,比如代碼結(jié)構(gòu)、代碼風(fēng)格、內(nèi)容開發(fā)工具、自動(dòng)構(gòu)建部署工具;軟件的質(zhì)量穩(wěn)定性的需求,如測試方面的需求,產(chǎn)品結(jié)構(gòu)對于缺陷的防范,代碼質(zhì)量;軟件的運(yùn)行承載力需求,包括可用性、容災(zāi)性、可維護(hù)性、承載力、運(yùn)行性能和成本需求;軟件的信息搜集方面的需求,如故障上報(bào)、數(shù)據(jù)統(tǒng)計(jì)和挖掘。

如何才能做好這些非功能需求呢?

首先是在項(xiàng)目成本規(guī)劃時(shí),分配足夠多的資源,比如人力和時(shí)間,去做好這個(gè)事情;其次是要盡量合理地規(guī)劃和設(shè)計(jì)這些非功能需求,既不能貪多求全,也不能無所作為。

 

追求代碼質(zhì)量

代碼質(zhì)量不高帶來的危害包括人員流動(dòng)后沒法接手、Bug頻繁出現(xiàn)、效率問題難以定位、開發(fā)速度慢等。

什么樣的代碼才叫高質(zhì)量的代碼?代碼質(zhì)量存在一個(gè)唯一標(biāo)準(zhǔn),就是可閱讀性??勺x性好的代碼,結(jié)構(gòu)通常更簡單清晰,Bug也少;更多人愿意去閱讀的代碼,也會(huì)有更多的機(jī)會(huì)去改正Bug以及其他的缺陷。可讀性好,也意味著你能更簡單地去找到改進(jìn)性能的方法,減少修改代碼帶來的風(fēng)險(xiǎn)。

提高代碼質(zhì)量的手段,最簡單的兩條,一是執(zhí)行代碼規(guī)范,二是進(jìn)行代碼評審。除了規(guī)范制定和評審?fù)?,組織學(xué)習(xí)代碼質(zhì)量的知識,提倡并獎(jiǎng)勵(lì)高質(zhì)量代碼的人員,也是提高代碼質(zhì)量的有效手段。

搭好測試這個(gè)安全網(wǎng)

單元測試是最原始的工程概念之一。單元測試對于互聯(lián)網(wǎng)應(yīng)用來說,一般會(huì)有一個(gè)困難,就是需要大量的“腳手架”,比如為了測試數(shù)據(jù)庫操作,必須要有一段代碼 “重置”數(shù)據(jù)庫的狀態(tài);為了測試網(wǎng)絡(luò)打包解包,則需要用一個(gè)程序向某個(gè)網(wǎng)絡(luò)端口發(fā)數(shù)據(jù)。而準(zhǔn)備這些測試工具代碼的時(shí)間往往會(huì)比較長,需要有足夠的耐心去做,但一旦做好了,往往能讓開發(fā)風(fēng)險(xiǎn)大大降低。

對于單元測試,我認(rèn)為最少應(yīng)該覆蓋所有正確的路徑,以及重點(diǎn)防御的錯(cuò)誤路徑。覆蓋了這些重點(diǎn)關(guān)注的地方之后,放手重構(gòu)代碼就很方便了。

單元測試應(yīng)該是屬于代碼的一部分,和源代碼一起存放。自動(dòng)構(gòu)建時(shí)也應(yīng)該進(jìn)行檢查輸出結(jié)果。提交代碼時(shí)都會(huì)自動(dòng)運(yùn)行單元測試,當(dāng)“版本樹”需要合并“分支” 時(shí),單元測試尤為重要,而最重要的是在分支上建立的單元測試。這些測試會(huì)大大加強(qiáng)系統(tǒng)的穩(wěn)定性,因?yàn)闄z驗(yàn)了“合并”功能產(chǎn)生的代碼—這些代碼是最容易出錯(cuò)的。

自己掌控開發(fā)方向

開發(fā)工作往往被需求變化“牽著鼻子走”,需求往往會(huì)有很多來源:產(chǎn)品策劃的想法、老板的意見、用戶的反饋、數(shù)據(jù)統(tǒng)計(jì)的結(jié)論等。提出的各種需求,往往會(huì)對開發(fā)團(tuán)隊(duì)造成很大壓力。這些問題都需要我們對需求做出有效的管理。然而我們應(yīng)該如何去搜集、記錄、過濾、實(shí)現(xiàn)這些需求呢?

我們需要很好地搜集記錄需求。有的團(tuán)隊(duì)會(huì)設(shè)立兩面故事墻,任何方面的需求,都可以減縮成一個(gè)故事,寫到一張便簽紙上,貼到故事墻上,專人處理,而不會(huì)石沉大海。

有的公司會(huì)試圖把這個(gè)事情用電子化流程來做,但電子化流程有個(gè)顯著的缺點(diǎn),就是為了更多地自動(dòng)化處理,會(huì)加入大量的字段,對于故事這種還未謹(jǐn)慎定義過的東西,要認(rèn)真填寫太多的資料,無疑會(huì)給使用者造成額外的負(fù)擔(dān)。

告別救火隊(duì)員

在產(chǎn)品進(jìn)入運(yùn)營期間,最牛的程序員似乎總是在充當(dāng)救火員,各種各樣的突發(fā)事件、棘手問題中,我們的“高手”往往疲于奔命,永遠(yuǎn)都在做一些補(bǔ)救的措施。有經(jīng)驗(yàn)的人員一直沒空做開發(fā),因此大量的代碼由那些水平較差的人來完成,反過來埋下了更多的問題。然而,如果不是忙著亡羊補(bǔ)牢,我們的資深程序員就可以把更多的精力放在開發(fā)上,這些有經(jīng)驗(yàn)的程序員所生產(chǎn)的代碼,又會(huì)進(jìn)一步降低出故障的概率,這才是走向良性循環(huán)的方法。

為了減少運(yùn)營期間的壓力,在系統(tǒng)設(shè)計(jì)時(shí),就要特別注意關(guān)于可維護(hù)性的非功能需求。運(yùn)營事故當(dāng)中,因?yàn)椴渴疱e(cuò)誤所導(dǎo)致的占很大一部分,因此降低部署錯(cuò)誤需要做到:全代碼包發(fā)布,每個(gè)發(fā)布版本要包含所有的可執(zhí)行文件;所有的服務(wù)器上部署的配置文件和數(shù)據(jù)文件都必須做到完全一致,降低更新文件的復(fù)雜度。本機(jī)IP地址應(yīng)該用代碼從網(wǎng)卡上直接讀取,但應(yīng)該提供可以配置的選擇,預(yù)備多個(gè)IP的服務(wù)器使用;只使用命令行方式來啟動(dòng)不同功能,如選擇配置文件路徑、輸入不同功能進(jìn)程或服務(wù)器的配置;程序支持關(guān)閉、重載配置這兩個(gè)信號。在處理這兩個(gè)信號時(shí),都不應(yīng)該讓使用者感覺突然“掉線”;開發(fā)用于安全關(guān)閉程序、重載配置的腳本或功能;開發(fā)用戶自動(dòng)重啟所部署進(jìn)程的腳本,以及配置開機(jī)自動(dòng)啟動(dòng)所部署的進(jìn)程;每個(gè)進(jìn)程都不應(yīng)該強(qiáng)行鎖定某資源,必須要能做到一份安裝復(fù)制多進(jìn)程并行運(yùn)行等。

每天發(fā)版

如果你想知道項(xiàng)目每一天的開發(fā)進(jìn)度,你就必須要做到每天發(fā)版,測試每天的工作進(jìn)度,如果要順利地每天發(fā)版,就必須建立一個(gè)持續(xù)集成的系統(tǒng)。一般來說持續(xù)集成系統(tǒng)會(huì)有以下的先后步驟:單元測試—自動(dòng)構(gòu)建—自動(dòng)部署—集成測試—自動(dòng)發(fā)布。

單元測試關(guān)鍵是要能堅(jiān)持覆蓋所有新加入的代碼;自動(dòng)構(gòu)建是由構(gòu)建腳本、構(gòu)建服務(wù)器、持續(xù)集成系統(tǒng)幾部分組成。

對于美術(shù)、產(chǎn)品或者別的非技術(shù)人員,添加的數(shù)據(jù)往往也需要有自動(dòng)部署的工具,而且因?yàn)橥ǔK麄儺a(chǎn)生的文件比較大,每次的全體打包然后覆蓋,可能會(huì)非常沒效率。雖然事情要做得完美不是很容易,但絕對是物有所值。

版本列車

我們時(shí)常只是對技術(shù)工作有版本管理的過程,而對于其他環(huán)節(jié),常常停留在最原始的狀態(tài)。我們需要在整個(gè)項(xiàng)目開發(fā)的每個(gè)環(huán)節(jié),都進(jìn)行合理的項(xiàng)目管理。在多個(gè)項(xiàng)目的經(jīng)驗(yàn)積累之后,提出了全過程的項(xiàng)目管理的概念:版本列車。

版本列車的含義是按照項(xiàng)目的工作流程,為每個(gè)有產(chǎn)出的環(huán)節(jié)都定義一個(gè)版本“車廂”,然后按照工作流程的先后依賴順序,形成一個(gè)完整的“版本列車”。第一個(gè)工作環(huán)節(jié)負(fù)責(zé)版本號,然后在這個(gè)版本號之下填充版本內(nèi)容。當(dāng)工作完成,此版本的工作內(nèi)容則帶著版本號進(jìn)入下一個(gè)“車廂”,依此類推。

這樣做的好處是,每個(gè)環(huán)節(jié)的每份產(chǎn)出都可以明確地知道其進(jìn)度位置,安排在什么時(shí)候做。對于需要提前準(zhǔn)備市場推廣或者別的工作部門,有一個(gè)非常明確的長期計(jì)劃。對于進(jìn)度管理來說,各個(gè)部門也能知道整個(gè)項(xiàng)目的當(dāng)前狀態(tài)。

論功行賞(績效評估)

不管是對被評的人,還是對評價(jià)別人的來說,績效評估都非常難做。因?yàn)楹芏喙ぷ鞑⒎悄芎軠?zhǔn)確地列舉出一二三來,工作任務(wù)也可能有大量臨時(shí)變更。太過主觀會(huì)讓人覺得草率;非要去依據(jù)可量化的數(shù)據(jù),又過于死板和片面。但沒有一個(gè)公司敢不做考核,所以說績效評估是“明知山有虎,偏向虎山行”。

績效考核應(yīng)該重點(diǎn)關(guān)注的是做了什么事,而不是做得怎么樣。這個(gè)讓很多按“結(jié)果”管理的老板很不接受??冃Э己藨?yīng)該是推動(dòng)別人去做某件事的工具。對于已經(jīng)明確的方法或者子目標(biāo),通過這種細(xì)化的方式去指導(dǎo)下屬工作。因?yàn)槭切枰潞笏阗~的,而且是量化的,所以下屬會(huì)對這個(gè)事情很認(rèn)真,同時(shí)那些不好量化的事情,管理者也很難執(zhí)行績效考核。所以“去做某些事”,是績效考核最好的目標(biāo)。

通過考核結(jié)果提供正式的工作方法意見??冃Э己吮旧碛袀€(gè)反饋的過程,這個(gè)反饋的過程應(yīng)該提供給下屬針對每個(gè)具體事情的建議。這種具體地,單獨(dú)地,一對一地指導(dǎo),會(huì)提高團(tuán)隊(duì)的穩(wěn)定性,而且也讓團(tuán)隊(duì)成員獲得“受關(guān)注”的感覺,這種感覺是形成高效團(tuán)隊(duì)的重要工具。

考核不能代替目標(biāo),不能阻礙目標(biāo),而應(yīng)該是一個(gè)溝通工具。目標(biāo)達(dá)成情況是考核的客觀指標(biāo),但不應(yīng)該作為主要績效考核指標(biāo)。最簡單的績效考核指標(biāo)就是收入或者利潤率。但這種簡單指標(biāo)除了在動(dòng)機(jī)上提高下屬的工作熱情外,并沒有從方法和經(jīng)驗(yàn)上幫助團(tuán)隊(duì)成員。有效的考核應(yīng)該是引導(dǎo)下屬按照更有經(jīng)驗(yàn)的方法去實(shí)現(xiàn)目標(biāo)。

本文節(jié)選自《世界500強(qiáng)互聯(lián)網(wǎng)產(chǎn)品經(jīng)理管理筆記》一書,刊登時(shí)內(nèi)容有修改。作者先后就職于多家互聯(lián)網(wǎng)公司,經(jīng)歷橫跨技術(shù)開發(fā)、產(chǎn)品設(shè)計(jì)、團(tuán)隊(duì)管理。通過梳理十年多從業(yè)經(jīng)歷,將大型團(tuán)隊(duì)管理和產(chǎn)品開發(fā)領(lǐng)域?qū)嵺`經(jīng)驗(yàn)與讀者分享。電子工業(yè)出版社授權(quán)刊發(fā)。

相關(guān)閱讀