經(jīng)過兩周的連續(xù)加班jdwp終于快告一段落了,如果不出什么問題的話馬上就會進(jìn)入FRT了。我
們從今年過完年就基本上在搞這個東西,期間問題無數(shù),可以作為一個典型的失敗案例,貌
似自我進(jìn)來之后參與的所有項目都沒有一帆風(fēng)順的,就拿這個最典型的開刀,以醒后世。
先介紹一下我們這個項目:是將open source的一個實(shí)現(xiàn)拿到自己的產(chǎn)品當(dāng)中(當(dāng)然license
上是沒問題的)。主要的工作是移植+少量的升級,原來的實(shí)現(xiàn)只支持主流的Intel平臺,我
們要將這個東西移植到12個平臺,而且我們已經(jīng)有了一套port層的API,也就是說我們只需要
將所有涉及到和平臺相關(guān)的代碼全部替換成port層中對應(yīng)的API。原來的實(shí)現(xiàn)層次上也很清
晰,大部分都是相同的代碼,少數(shù)不同的地方也都放在了不同的文件。看起來是個非常簡單
的項目,那么我們就來看看這樣一個簡單的項目是如何失敗。
一共4個人投入這個項目,計劃兩個人做升級,兩個人做移植,我被分去做移植。
問題一
四個人都是做java的,只有一個在項目中使用C/C++,其他人都只停留在學(xué)校作業(yè)的水平
如果從上面的需求看,這樣的狀況完全是可以接受的。只要理解了框架,在合適的位置加點(diǎn)
代碼就可以了,已有的代碼也是個很好的參照;移植基本就是個體力活,仔細(xì)不出錯就沒問
題了。事實(shí)證明,對于不熟悉的語言,解決問題的效率明顯下降,很多我們折騰了幾天了的
問題,有經(jīng)驗(yàn)的人可能一分鐘就能搞定。不過項目組里在實(shí)在是沒有其他人了,這個風(fēng)險應(yīng)
該是已經(jīng)計算在內(nèi)了。但是許多小問題堆積起來有可能就是致命的,這只能算是其中的一個
了。
問題二
沒有及時的與其他模塊集成
我們這個號稱敏捷的team在這一點(diǎn)上連敏捷最基本的盡早集成,持續(xù)集成都沒有做到,汗顏
啊。我們只是在自己的小作坊里拼命的搞呀搞,最后發(fā)現(xiàn)我們的東西拿給integration team
根本就沒法build,然后花了大量的時間來解決在各個平臺上的build問題。這時問題一就凸
顯出來了,面對不熟悉的語言,不熟悉的工具,完全陌生的平臺,寫腳本去build一個復(fù)雜
的工程(原來用的都是已有的東西)。由于build的問題遲遲沒能解決,導(dǎo)致后面測試和我
們fix bug的時間非常有限。
問題三
不求甚解
就我來說,我做完移植后都不知道整個模塊的運(yùn)行機(jī)制,工作原理,只是一個API翻譯的碼
工。其他人也都差不多,對整體的構(gòu)架和大致的流程都不是很清楚。不過我們這群人還是很
強(qiáng)的,都是fix bug的高手,每天維護(hù)這大量完全不熟悉的代碼,即使不懂,不太懂照樣游
刃有余。這里的問題是我們沒有責(zé)任感,為移植而移植,為升級而升級,完全不去試圖理解
自己所在做的事情,殊不知,這些拿進(jìn)產(chǎn)品的代碼最終還是要我們自己來維護(hù)的啊。這種情
況一直到項目的最后期才有所好轉(zhuǎn),修了那么多bug,再不熟都說不過去了。但這種從局部
一點(diǎn)點(diǎn)的理解不僅效率低下,而且始終對代碼沒有充分的自信。即使現(xiàn)在我們也不敢對已有
的代碼做大的改動,因?yàn)槲覀兺耆恢涝谶@里的修改是否會影響的其他部分。
我覺得在項目剛開始應(yīng)該首先學(xué)習(xí)已有的代碼,順便溫習(xí)C/C++的知識,對項目整體的了解
是必要的,也是最基本的。
問題四
對風(fēng)險估計不足
細(xì)心的讀者可能已經(jīng)發(fā)現(xiàn)了,我們前面項目的概述中有兩個重要的風(fēng)險沒有考慮到:已有代
碼中的bug和我們依賴的port API的bug,我們都假設(shè)它們是不存在的!!就是這兩個東西讓
我們陷入了泥沼無法自拔。客觀的說從open source拿的代碼質(zhì)量還是非常高的,而且有一
個完整的測試框架和大量的自動化測試用例,但要作為產(chǎn)品,顯然還需要錘煉。port API的
問題相對少一些,但很難發(fā)現(xiàn),而且一旦出問題修正的周期非常長,無疑對我們的進(jìn)度會有
很大的影響。
剛過了TCK我們說,TCK都過了,應(yīng)該沒啥問題了,可是SVT報過來一堆bug,我們恍然,SVT比
TCK牛多了,真是什么bt的測試都有。等SVT都過了,突然冒出個RAD,一下就是十幾個bug,
還發(fā)現(xiàn)一個spec沒實(shí)現(xiàn),一問結(jié)果人家是人肉測試 -_-!!
做最好的希望,做最壞的打算任何時候都是適用的
問題五
兵力分散
上一條對這個有直接的影響,也跟我們team人太少有關(guān)。項目中的4個人只有一個人是絕大
部分時間在這上面,其他人是需要了再過來,搞著jdwp還要搞其他的東西,嚴(yán)重分散了精力。
期間由于沒趕上SR2,中間有一段相對空閑的時間,大部分人都被抽取干其他的任務(wù),默認(rèn)
是不會再有什么問題了。。。這實(shí)際上是我們team一直存在的問題,一人多職,每個人都沒
法專注在一件事上,造成每件事都效率不高。
問題六
反饋遲緩
敏捷啊,又犯了敏捷的大忌。從項目開始的頭幾個月我們沒有試圖去獲得或者爭取任何反
饋,直到測試組參與進(jìn)來。即使我們能夠獲得完整的SVT測試用例我們也沒有嘗試主動去獲取
反饋(跑SVT測試),我們始終都是被動的。我們雖然沒辦法讓客戶嘗試還沒正式發(fā)布的版
本,但至少我們自己可以,在team內(nèi)部使用還是沒什么問題的。jdwp大家平時調(diào)程序都會用
到,如果我們自己使用的話,很多顯而易見的bug就不會到最后才被發(fā)現(xiàn)。雖然作為SDK本事
不穩(wěn)定會影響大家開發(fā)的效率,但能及時發(fā)現(xiàn)問題,將其扼殺在搖籃中,我認(rèn)為還是非常值
得的。
問題七
基礎(chǔ)設(shè)施(Infrastructure)不健全
我們的code repository還是不能不說的。為什么會變成這樣我也不太清楚,總之它現(xiàn)在的情
況是這樣的:我們有自己的code repository A,每次做integration build,我們會把當(dāng)前
最新的代碼發(fā)布到另一個repository B,這個B不僅包括了我們jdwp的代碼,還有其他我們放
進(jìn)產(chǎn)品的代碼,integration build會從這里拿代碼去build。注意這里的發(fā)布其實(shí)就是復(fù)制
A里的文件到B并且修改所有文件頭的日期信息,這個動作是由腳本完成的,commit的注釋就
是load module balabala之類沒啥意義的東西,如果用svn diff看某個版本的修改,你會看
到所有的文件都被修改了,絕大部分僅僅是文件頭被改了。看官可能要罵了,不就是個用來
做integration build的臨時庫嘛,講這么多干嘛,其實(shí)我們的項目只能在這個臨時庫
build,因?yàn)樾薷倪^的腳本都在這里。各位現(xiàn)在能理解我們的痛苦了嗎?我們必須在B上開
發(fā),而B除了做更新外沒有任何用處,如果要查看歷史,請去A,要提交修改,對不起請去A,
我在B上開發(fā)竟然要去A上提交!!!就這樣來回的折騰啊,我們的時間就這樣消耗啊。。。
這樣看來整個項目真是一團(tuán)糟,但我們竟然真的把它放進(jìn)SR3了,當(dāng)然還會有
SR4,5,6,7。。。為了不讓慘劇繼續(xù)上演還有很多需要做:
1. 修改 repository A 上的build腳本,以后直接在A上工作
2. clean 測試用例,補(bǔ)充測試用例,這是保證質(zhì)量的第一關(guān)。
3. 組織一次組內(nèi)sharing,share項目的整體構(gòu)架,運(yùn)行機(jī)制,常見工具的使用,常用的解
決問題的方式,將其記錄在wiki上。
4. 號召大家在日常工作中使用自己開發(fā)的工具,小白鼠從自己做起。