注:本文轉載自《程式設計師》
文/方坤 作者結合切身經歷,展示了他之前所在團隊軟體專案延期的種種原因,而其中印象最深刻的是各種人事紛擾乃至於勾心鬥角。
六年前,畢業未久的我在一家外企工作,我所在團隊開發的軟體專案在交付到整合測試組時因種種原因延期一週。這本身根本不是什麼大事情,但其間各種人事紛擾乃至於勾心鬥角卻著實令我印象深刻。
公司
我的老東家是一家大型跨國電信裝置開發商,曾具有輝煌的歷史。我還記得在公司110週歲的生日慶典上,一位高管致辭說:“110年,這不是奇蹟,是成績”,令人不勝欷歔。遺憾的是,公司在.com泡沫中遭遇重創,一蹶不振。時任CEO為求擺脫困境,打起了人力成本的主意。當時,公司在美國僱用一名工程師的綜合人力成本接近中國的2.5倍【注:工資只是其中一小部分】。至於法國,成本比美國還要略高一些,而且不要忘了,人家可是35小時工作周。大家都是聰明人,很快就看到端詳:公司正在法國裁員,將專案轉移到中國。
令人尷尬的是,我所在的中國團隊恰好就在與法國團隊合作。這一專案最早完全在法國,此後幾年時間,中國團隊大規模擴張人手(我就是這樣進來的),將專案模組逐一從法國團隊手中接過來。剛開始,法國工程師將原先的模組移交中國之後,便轉而從事其他專案或職位,談不上什麼個人損失,雙方共事可謂融洽。後來可就不是這麼回事了。有一次,兩位中國工程師去巴黎接手一個專案,一位法國工程師負責培訓,為時2~3個月。在這位法國老師兢兢業業的幫助下,兩位中國工程師成功掌握整個模組,按期於聖誕節前夕歸國。告別巴黎時,沒有一個法國同事去跟他們寒暄話別—那位法國老師被裁掉了,他的最後一個工作日恰好就在兩位中國工程師離開的同一天,法國同事都去送他了。
到發生本文將要詳述的交付延期之時,所有模組的開發工作都已從法國團隊移交到中國團隊,而整合測試雖然仍由法國團隊負責,但從法國到中國的移交也已開始。不妨猜猜看,法國整合測試團隊的工程師們此刻在想些什麼。
團隊
我很幸運,畢業後初入職場就遇到一位好經理H,坦率地說,她也是我到目前為止跟隨過的幾位經理中最好的一位。中國很多女經理都有一個共同的特點:沒有私心。她們對於自己的晉升、提薪並無多大熱情,更願意把心思、時間和精力花在輔導和培養自己的團隊上面。
H因分娩而“暫時”離開我們團隊。經過短暫的過渡,接任我們經理的是T,一位新近招聘的職業經理人。他的風格與H大為不同。僅舉一例說明。當年向H請一天年假,她總是微笑著說:“沒問題。不影響工作吧?”T則會端起架子:“不影響工作吧?沒問題。”語序上的變化,加上語氣的差別,雖然只是細微末節,卻反映了態度的不同、對員工是否尊重。除此之外,更嚴重的是工作態度問題。現在我們知道,T在北京待了不到一年時間,買下兩套房、一輛車,還辦妥了到加拿大的移民和那邊的工作—而在當時,我們這些員工僅僅只是知道,我們的經理不太在辦公室出現。
在團隊內部,我所在的FM小組與另一個CM小組工作是緊密銜接的。但在CM小組的核心員工之間卻存有罅隙:小組長B與技術骨幹S矛盾日增。怎麼說呢,這兩位都是很好的同事,然而好人之間也會彼此鄙視的:S認為B不懂技術,瞎指揮;B認為S目空一切,難以共事。缺少一位好領導來調和,好員工也不能組成一個好團隊。
流程
我們開發的是一個龐大的電信軟體專案—3G接入網網管系統,採用的開發流程仍然是傳統的瀑布式。簡單來說,依時間順序,一個軟體工程師(首先是各小組的小組長)需要依次參與以下幾個階段。需求階段:跟蹤和審閱由系統架構師撰寫的需求文件,必要時要求澄清,然後預估工作量,經理據此調整人員安排。
- 設計階段:分析需求文件,完成模組設計,據此撰寫高層設計文件和底層設計文件,前者以定義模組介面為主,後者則涉及更多細節。
- 編碼階段:根據兩份設計文件完成實際編碼工作。
- 單元測試階段:是的,你沒有看錯。根據本部門正式的、成文的流程,單元測試階段在編碼階段之後安排時間進行。在實踐中倒是沒有這麼僵化,大家儘可以測試先行,只要時間大致齊即可。
- 各開發團隊在完成各自負責的一或多個模組的單元測試之後,將程式碼提交到統一的程式碼庫,打上標籤,然後將這些標籤連同其他注意事項寫成文件儲存到指定目錄。其後,就是整合測試階段了—整合測試團隊收集所有團隊的所有標籤,從程式碼庫提出相應的程式碼進行編譯,編譯成功後即按照事先準備的測試用例進行測試,給開發團隊提Bug。
我參與了前面幾個版本3.X、4.0的開發,僅從技術角度而言,瀑布式開發流程工作得尚稱流暢。但工程師是要領工資的,軟體寫出來是要賣錢的,一套經典的瀑布式流程走下來往往耗時幾個月甚至年餘,等到軟體產品正式釋出,使用者需求已然發生變化,這怎麼趕得上趟呢。公司不是沒有意識到這一問題,但捨不得做傷筋動骨的鉅變,只願意在現有流程上做一些微調,效果甚微。
有一個例子很能說明問題。當時,中國的銷售部門向總部反映,我們在中國市場遭遇到本土廠商的強力阻擊,要想爭奪中國市場,就必須在定製化方面下更大工夫。在大中華區乃至總部高層的大力支援下,我們部門成立了一個“快速特性”開發小組,專門根據中國客戶的需求為我們的產品新增相應的特性。有一個快速特性是這樣的:本來,我們的網管系統會在電腦螢幕上顯示一臺虛擬的機器,如果某個部件壞了,代表該部件的綠燈就會變成紅燈並開始閃爍,提醒操作員注意。中國客戶看過演示後說不錯,但光紅燈閃爍還不夠,還應該放點兒警報聲出來,不然操作員離開座位了怎麼辦。我們的銷售一口答應下來。猜猜這個特性我們做了多久才交付給客戶?三個月!這就是瀑布式流程下的“快速特性”!(當然,中國的銷售部門和開發部門分別向國外的上司彙報,由老外負責協調中國的事情,這也是造成拖延的一個同等重要的原因。)
這樣拖拖沓沓做出來的產品,其銷路如何不問可知。公司應對的辦法,就是一方面推新版本、新特性來吸引客戶,另一方面強調開發速度的重要。很顯然,這兩者之間存在矛盾:新特性越多,開發時間就越長,客戶不會買賬;可是如果新特性太少,跟上一版本差異不大,客戶同樣不會買賬。
版本
有一天,經理通知大家:我們們要開始做新版本4.1了。其後,像往常一樣,我們就陸續接到一批批需求文件,開始預估工作量。然而這一次,事情一開始就有些不同:這些需求文件寫得異常混亂,常常不知所云。我們如何能夠根據一份看不懂的需求文件來預估工作量呢?我們隨後聯絡法國的系統架構師(他們處境安全,跟我們合作融洽)要求澄清,他們也很不好意思,有時還確實能夠做出澄清,但大多數時候要麼含含糊糊地來一句“我們也在研究”,要麼說“根據我的經驗,這條需求應該與你們模組關係不大”云云。大家就這麼半猜半蒙,在磕磕絆絆中前行,心中滿是不詳的預感。
4. 1版本很倉促地做出來了。又有一天,經理通知大家:4.1版本過於保守,連公司自己都覺得銷路不會好,決定立刻開始4.2版本計劃。於是一切都重新來過,而這一次,情況更糟:大多數需求文件都是匆匆寫就,語焉不詳。一些需求文件只有一個標題,正文人家根本就沒來得及寫,而經理就要求我們根據這樣的需求文件來預估工作量。如果你認為這樣很誇張的話,那我只能批評你想象力有限—個別文件只有一個編號,收納到某一領域的寫作計劃之中,連標題都沒有,而我們仍然要據此預估工作量!就這樣,日復一日,我上報一些連我自己也不相信的數字給經理,而他則努力裝出相信的樣子。
軟體工程應該怎樣做?我本來以為CMM、TL 9000等是王道,經歷這一風波我才深切地體會到,再好的流程與制度也經不住扯淡啊。人和最重要。
4. 2版本更倉促地做出來了。又又有一天,經理通知大家:4.2版本過於激進,工期又短,從設計到實現毛病多多,公司也不看好,決定立刻開始5.0版本計劃。這一次倒是沒有太荒唐的事情發生。5.0版本實際上沒有什麼全新的特性,而是將4.1、4.2這兩個版本的特性做一折中,從這個意義上講,叫它4.1.5版本更合適,當然這個話不能對客戶說。就這樣,幾個月以來第一次,大家終於能夠做點兒靠譜的事情。然後,出事了。
風起
第一波的事故,我是直接責任人之一:因為我的失誤,我負責的FM模組沒有通過編譯。
我還記得前幾個版本交付時和H一起工作的情景。她會敦促我們儘量提前完成開發和測試工作,提交程式碼,打上標籤,撰寫交付文件。她會親自檢查我們的交付文件,連一個細節也不放過。比如有一次,她就發現我無意中開啟了Microsoft Word的中文自動糾錯功能,把“…”(在版本配置中具有特殊含義)自動替換成了半個中文省略號“…”,讓我臉上無光。大大小小的問題被她連續抓住幾次之後,我開始小心謹慎,此後幾個版本都順利過關。印象最深的還是編譯時的一次次待命。由於時差的關係,法國同事依據標籤提出程式碼開始編譯的時間是在北京的晚上,每一次,H都會帶領我們幾個少數技術骨幹在辦公室待到夜裡,直到我們團隊負責的所有模組都成功編譯之後才離開。這可真是一件苦差事,而且在我當時看來毫無必要—我們的模組從來都是一次編譯成功,錯誤(如果有的話)從來都屬於其他團隊。有一次,法國同事連續犯錯,導致編譯遲遲不能開始。當時我還保留著自校園帶出來的早睡的習慣,時間一長,上下眼皮開始打架。H就跑到我的座位,談人生,談理想,談八卦,反正就是不讓我睡著。一直堅持到凌晨兩點,編譯開始之後照例一次成功,H才領著飢腸轆轆的我們離開辦公室,請我們到樓下的小店吃宵夜。喝著溫暖的豆漿,我在心中嘀咕:“真是事兒媽啊。”
這一次,“事兒媽”不在了,新任經理給予我們“完全的信任”,從頭至尾都放開手—這同一件事情我們都連續做了好幾遍了,還能出什麼錯呢?
還真就出事了。前幾次,我們至少能夠提前一週左右的時間完成全部工作,這搶下的一週時間足夠我們反覆測試、排查問題,併為應對突發事件留下時間—儘管突發事件從未發生。而這一次,大家經過連續幾次折騰之後疲憊不堪,工作效率低下,更何況這次的工期本來就偏緊,還被前面幾個環節擠佔不少。我們FM小組勉強提前幾天完成工作,CM小組卻陷入苦戰,加班加點,緊趕慢趕才在最後一天完成。FM模組依賴於CM模組,這樣一來,我們也受到連累,不得不換上CM小組最新的標籤,重新測試FM模組、打標籤、修改交付文件。等到我餓著肚子敲完最後一個字元,又仔仔細細檢查了幾遍,已是週五晚上7~8點鐘的光景。我長吁一口氣,站起身來,搖搖晃晃地離開了辦公室。
等到我週一早晨回到辦公室,這才發現自己犯下低階錯誤:我忘記將修改後的交付文件儲存在指定目錄了!這樣一來,法國同事據以編譯的乃是先前儲存的老版本的交付文件,FM模組編譯失敗!我趕緊寄出道歉信,連同最新的交付文件。然而,晚上的編譯仍然沒有成功。根據法國同事提供的編譯錯誤日誌,我很快就發現問題:FM模組與其他依賴模組之間使用了不一致的標籤。說起來還是怪我們兩邊當時掉以輕心,只是口頭約定了一下,也不知怎麼就聽岔了,關鍵時刻害人。又是一番折騰,FM模組在第三次編譯中順利通過,我心中一塊石頭才算是落了地。
亂戰
我這邊沒事了,CM小組卻開始焦頭爛額。
CM模組幾次編譯均告失敗,而法國同事提供的編譯錯誤日誌亂七八糟,毫無幫助。原來,我們專案當時尚未採用分散式編譯技術,為了縮短編譯時間(僅僅某一個子模組單機重新編譯就需要18小時),法國的整合測試團隊自行編寫了一個指令碼,開啟幾路程式並行編譯各個子目錄。這個指令碼寫得過於簡單,幾路程式的輸出資訊全都雜七雜八攪到了一塊兒,以至於CM小組研究了幾天,連到底哪個子目錄編譯不過都沒鬧明白!
CM小組嘗試向風雨飄搖中的法國整合測試團隊請求幫助:“你們能否用單路程式編譯CM模組的各個子目錄,將錯誤資訊提供給我們?”
法國人回答:“請中國團隊儘快修復編譯,你們堵住了整個專案!”
CM小組解釋說:“我們正在努力,你們能不能幫忙……”
法國人回答:“請中國團隊儘快修復編譯,你們堵住了整個專案!”
CM小組再次嘗試:“這一錯誤本地不能復現,而編譯日誌……”
法國人回答,並且抄送各路神仙:“請中國團隊儘快修復編譯,你們堵住了整個專案!”
外事不靖,內部也不安寧:CM小組的小組長B和技術骨幹S此刻正在鬥氣!從一開始,B就將編譯錯誤的排查工作分配給自己和另一位同事,沒有邀請S介入,而S也不主動過問。沒想到這麼一個乍看上去再簡單不過的錯誤一拖就是好幾天,這樣一來,雙方陷入僵局。站在B的角度,如果連個編譯問題自己都解決不了,還得請S來當救兵,這不是坐實了自己不懂技術的指控嗎,這張臉以後還怎麼擱?再說S一直面無表情地坐在自己的電腦前做自己那一攤事情,一句問話沒有,這不擺明了是要袖手旁觀嗎?而S也有自己的苦衷:自己要是一開始就主動介入倒也罷了,如果拖到現在才出手,那怎麼解釋自己前幾天不聞不問的態度?就算自己辯解說確實沒有端架子、看領導笑話的意思,完完全全是在服從領導安排,也得有人信啊!雙方有一點想法倒是共同的:這個編譯錯誤趕緊消失了吧……
既然CM小組遲遲不能修復編譯,順理成章地,專案經理(一個不偏不倚的法籍華人)開始找他們的上級,也就是我們共同的經理T。然而—她找不到T!事情就是這麼湊巧,雖然T平時就神龍見首不見尾,可像這次這樣整個禮拜辦公室都不怎麼見人影、寫信也不太回的情況還真不多。連續幾天,專案經理從法國給T的座機打電話,按說這是法國的休息時間,中國的上班時間,可是法國那邊有人打,中國這邊沒人接。電話留言、電子郵件都不好使。專案經理急了,電子郵件寫得越來越不客氣,每封信的結尾都是同一句話—“T在哪裡!”……
事情終於驚動了上面,領匯出來問話了:“發生了什麼事?為什麼會耽誤到現在?”法國團隊再次暗示中國團隊無能,中國團隊則強調本地無法復現,必須法國團隊配合,專案經理在居中調解的同時狠狠地告了T一狀……領導不愧是領導,跳過T的事情不提,和藹可親地建議法國團隊考慮中國團隊的合理要求……事情終於走上正軌。法國團隊終於按照CM小組的建議嘗試單路編譯;與此同時,B主動去徵求S的意見,問他是否願意參與排查,而S也立刻答應下來;T又神祕地出現在辦公室裡,如果這有關係的話……經過整整一週的紛擾,週五,編譯終於成功。
那麼,這一編譯錯誤到底是如何產生的呢?說起來,這居然還與前述混亂的版本計劃有關。在4.0版本中,出於相容舊有裝置的需要,CM模組中有些檔案按照foo_V4.h的格式命名,後來升級到4.1、4.2版本後檔案內容相應修改,檔名保持不變。可是5.0版本實際上是4.1、4.2版本的綜合,CM小組被迫把4.1、4.2這兩個版本的foo_V4.h檔案都引入5.0版本,檔名分別命名為foo_V41.h和foo_V42.h以示區別。換言之,檔名變長了一個字元,而這就導致法國整合測試團隊的編譯指令碼中的命令列超過了最大長度的限制……
尾聲
軟體工程應該怎樣做?我本來以為CMM、TL 9000等是王道,經歷這一風波我才深切地體會到,再好的流程與制度也經不住扯淡啊。人和最重要。
無論版本號如何,我們的產品終究還是銷路不暢。新任CEO上臺後,大刀闊斧厲行改革,將整條產品線出售。畢竟,對於IT業來說,創新才是利潤之源,單純的削減成本沒有出路。基於這一認識,我轉投網際網路公司,從此踏上新的征程……
作者方坤,Google中國資深軟體工程師,清華大學電子工程系碩士。曾先後在創業公司與大型外企任職,2006年加入Google中國,先後從事過基礎架構、產品搜尋、音樂等專案的研發和運營維護。