海交通大學電腦學士,企業管理碩士。現任職於英特爾中國軟體實驗室,從事嵌入式Linux相關的開發工作。PMT Community發起人之一,PMT是一個由軟體行業專業人士自發組成的非營利性團體,致力於軟體技術和管理的研究與實踐。
寫下這段流水帳似的周末加班經曆,並不是因為無聊。只是老婆要我交待,一個“臭”(這個字眼只有很少機會享用)做軟體的,老是這麼晚回來,究竟在外面做些什麼。如果哪天你也被要求寫這樣的材料,你可以參考;除了這個作用以外,或許,不同的人會從中看到不同的東西吧。
(此處刪除了向老婆表忠心的500字)
背景:
我們的軟體產品需要在A、B、C三種硬體平台(理論上對我們的軟體影響是不大的)上工作,早些時候已經成功在A上工作了,但在B、C上還有些問題,加班的那天是一個deadline,需要保證在B、C上也能夠工作。這個產品由X、Y、Z三個部分組成,分別由三個team負責,基本的關係是:X和使用者打交道,X調用Y,Y是資料進資料出,Y調用Z,Z和硬體打交道。
其中,X和Y都是新寫的程式,而且早些時候,在X上發現了較多BUG,Y基本上沒發現問題。Z的代碼在以前的產品中就有,相對已經比較穩定。由於項目的時間壓力,這三個部分沒有時間做分別的測試,只是程式員簡單測一下自己的代碼後,就要整合和測試了(這就是我的具體工作)。除了三個team的leader留下外,X的程式員都留下了;Y的leader檢查了team members的工作後,認為沒什麼問題就放他們回家了;Z的leader最“無辜”,目送所有手下下班後,自己不得不留下。
都是指標惹的禍:
一開始要加班是因為X的工作還沒有完成,於是大家就一邊等,一邊“催”(X的leader聲稱要到12點才能完成,真是烏鴉嘴),一邊各忙各的(我在上網看新聞)。事實上,X到7點多就完成了,但一測試發現有明顯的記憶體訪問問題。於是X就調試,由於X在記憶體訪問問題上已經“臭名昭著”了,所以大家(至少我)相信是以前類似的問題,或者是以前的修改沒有徹底。
但很快,X發現問題是:Y傳了一個null 指標給X;很快,Y也證實了X的說法。大家責問 Y,為什麼程式員自己測試時沒有發現?其實很簡單,程式員的單元測試程式會檢查是否是null 指標,如果空就列印空行。於是,X和Y開始“踢球”,互相要對方加上null 指標的錯誤處理代碼;但踢了一會後,新的疑問出現了,Y照理不應該出現null 指標,所以要麼Y的代碼有問題,要麼Y要證明自己沒錯。
找一個BUG好難:
於是Y的leader也加入了調試隊伍,因為Y的代碼都有詳細的Log,所以很快就定位到了他的一個team member的代碼裡。不幸的是,Y learder的開發機器在關鍵時刻down掉了。好在我們初步實施了軟體組態管理,Y leader很快在別人的機器上重新搭建好了調試環境。
Y 作了些修改(事實上,他改的這些代碼都是無關緊要的),經我測試後,發現還是不行。以我的職業感覺,我覺得X也有問題(後來知道是歪打正著)。但X寧可上 sina看“北京某景區有人裸泳”也不肯檢查一下自己的代碼。Y經過艱苦的調試(其實絕大部分時間我想是在理解這些不屬於他的代碼),發現是因為某個資料沒有取得而導致了null 指標的出現,但照理,Z應該總是把這項資料傳送給Y的。但Y對Z的“指控”很快被證明是無效的,因為Z leader向大家“展示”了她從硬體取得的資料是好好的。
於是,Z leader繼續吃餅乾;Y leader繼續調試;X一干人等繼續“研究”我國風景區的管理問題。而我也終於無聊到了極點,開始“友情贊助”,檢查Y的問題代碼。代碼很少注釋,寫得也很隨意,甚至縮排的格式都顯林亂;但好在代碼不長,邏輯也不複雜。我重點檢查了記憶體的操作,但沒有發現問題。
正在我納悶同樣一段代碼,為什麼其他資料都可以取得,偏偏這項資料取不到的時候,傳來了Y learder的叫聲。雖然聽起來很像絕望後的慘叫,但我敢肯定,這的確是找到真正問題後的歡呼(和慘叫相似也是情理之中,畢竟都是在身心及其疲憊後發出的)。果然,他發現了:這項取不到的資料的名稱寫錯了,應該是Status,但寫成了State。(Y向Z要資料時,要傳給Z一個資料的名稱,然後Z就從硬體取得,並返回給Y。這些資料的名稱是Z定義的)那麼,怎麼會發生這種低級錯誤的呢?原來,出錯的代碼Y的那個程式員從另外一處Copy來的,其他資料項目的名稱都是相同的,偏偏這項資料的名稱不同。
有多少Code可以重來:
Y leader忙著改C檔案和H檔案,因為這個資料項目的名稱出現在多處,所以Y leader改得很仔細,也很辛苦;我想他心裡一定在臭罵他的這個team member,為什麼不定義一個常量或者宏。在Y leader改代碼的時候,我也在想,這簡直就像Z在故意製造陷阱:這兩組資料這麼類似,而且其他資料項目的名稱都相同,為什麼偏偏這項資料,一個叫 State,另一個叫Status,真是有空,真TMD。
Y leader終於確認改正了所有該改的State。但用他的team member的單元測試程式一測發現還是有老問題。你可以想象到我們當時的感覺,就像吃了一噸廣告上那個很誇張的“涼”得透頂的潤喉糖。
但是! Y leader大叫:單元測試程式裡的State也要改成Status。在無數雙眼睛的注視下,Y leader顫抖著replace all,save,F5。終於,當大家看到電腦上的一串字元後,每個人都舒心的笑了。(當然,如果沒有剛才的虛驚一場,可能不是每個人都在快工作到午夜的時候還能笑得動的)。我想,此時此刻,此情此景,在Y leader的眼裡,一定滾動著些東西,除了眼屎。
現在,又輪到我上場了。Build時發現X的代碼中也需要把一些State改成Status。(如果當初他們也檢查一下就好了)。X的程式員也沒有定義常量或者宏的習慣,所以我Build了多次,他們才把所有要改的State改掉。
一個QA的精彩:
後來發生的事可以用一個“峰迴路轉”來形容,在無數雙眼睛的注視下(我的手沒有顫抖,因為人已經麻木了,或者說一切都習慣了),我啟動了我們的軟體,串連到B平台上,檢查所有的資料,全部OK;串連到C平台上,檢查所有的資料,全部OK。搞定了!
“回家,回家,回家的感覺是多麼多麼……”,我想,當時,也許每個人的心裡都在回蕩著王傑的這首老歌(如果知道這首歌的話),包括陪我們加班到深夜的可憐的老闆。
當其他人已打算轉身時,我的思想在激勵的鬥爭著。看著同事們的臉,包括老闆滄桑的臉和幾張幼稚卻不顯年輕的程式員的臉,想著家裡一天沒能見到老爸的孩子,我想回家,但是,我是QA。我默默的連上了A平台,然後發現什麼資料都沒有。(如果把這個情境定格或者淡出,我怎麼想都覺得象好萊塢預示續集的結尾)。
當我喊住大家時,我不知道該如何描述自己的感受。
無聲,無聲,又見無聲!突然,老闆告訴大家:今天的deadline搞定B和C平台就可以了,A平台下個禮拜再說。管他是真是假,老闆發話就可以了,還不開溜。3分鐘後(其中半分鐘是給CVS打上Tag),我坐上了回家的Taxi。
淩晨一點的上海還是霓虹閃爍,好美。
後記:
本文純屬虛構,如有雷同,實屬巧合。
(事實上,本文99.99%是真實的,除了一些藝術加工,如果算得上“藝術”的話。我只是不想我的可愛的可敬的同事們發現我在背後罵他們烏鴉嘴和TMD)