2. 專案計劃
在一個產品發布並使用之後,其中肯定有許多地方不如意和值得改進的地方。客戶在使用的過程中會發現一些問題,提出更高的需求,市場也在發生變化,我們的競爭者也在發展,新的技術不斷地產生,這些因素推動著我們的產品不斷地向前發展,使它的版本不停地往上增長。這些發展的需求不是一下子提出來的,在客戶使用的過程中發現某些不如意不方便的地方,他們會向我們的技術支援人員提意見,而技術支援人員會把這些需求以BUG的形式存入BUG資料庫中,其層級一般定義為下一個版本的Feature。有些上一個版本未解決的BUG也可能需要在本版本中來解決。因此當我們來開發下一個版本時,其許多特性已經存在於BUG資料庫中了。當然新版本的特性不是只從BUG中獲得,管理層可能從市場的角度來提出新的特性以求領先競爭者,開發人員本身也可提出某些要求來納入新版本開發的計劃中,如要求對某部分代碼進行重構以使其結構更清晰更容易維護,執行效率更高。
每個人把同自己相關的功能模組收集起來,同時預估時間,其中主要包括寫文檔的時間、開發時間和單元測試的時間,一般要求精確到工作日。這些資訊發送給組長,組長再把本小組人員的任務和預估時間發送給管理層,由管理層對此任務及進度進行評估審核,管理層會根據產品發布時間及客戶需求、市場因素等方面作出選擇,可能某些功能由於時間緊急會被延遲到下一個版本中去。若預估出來的時間同預計的產品發布時間有較大衝突,而且此功能是本版本中必須得做的,則開發小組會被要求重新預估時間,加快開發速度來達到這個要求。
雖然這個開發進度時間是一個大概的估計時間,但我們要儘力按照這個開發進度來執行。每個星期五下午我們有一個Status Meeting(一般那時工作效率較低,適合開會),在此會議上我們會根據這個進度來review我們的工作,每個人手上的工作是否按照這個進度在走,是否有人延後了,是否block住別人的工作了。在此會議上每個人都要報告自己的進度,同時還要報告上個星期做了什麼,正在做什麼,以及下個星期打算做什麼。通過這個會議,會讓你覺得有人在監督你,無形之中迫使你不斷地督促自己不要使任務延後,如果有延後的跡象也會儘早發現而趕上。若某些經過努力不能趕上,那也沒有辦法,只能修改原先的進度表,因為那是我們的估計與現實發生了偏差,我們必須使我們的進度表符合實際情況,這可以避免許多項目發生最後的20%的工作量會佔據80%甚至一直拖後的情況。修改進度表的情況我們曾經發生過,有一次在按照原先的進度執行到將要完成的狀態時突然接到通知由於市場及客戶的原因要求加入另一項重大的功能,這個功能對我們程式的結構有非常大的影響,因此我們就要重新制定一個進度來滿足需求。在這種情況下,產品原先的開發進度被打亂,發布時間也因此延遲。當然這種情況應當儘力避免,尤其在項目後期產生新的需求,若不得已也應重新規划進度,而不是仍舊依照原先的進度去執行,因為老的進度已不能反映現實的情況。
3. 開發文檔
在項目進度安排中我們已經把寫文檔的時間也規划進去了,這裡雖然是寫文檔,其實是設計程式,整理一下思路與架構,磨刀不誤砍柴工,這樣在實際寫代碼時會流暢很多,節省時間,因此可以說真正有思想性的東西都在寫文檔這段時間內完成了。當然我們這裡的文檔格式不象ISO那樣規定了條條框框,我們的文檔格式相對自由,基本上能隨意發揮,但對於幾個主要點一般來說是需要說明的。要求寫的文檔能讓他人比較容易地看明白,能把問題講清楚,能反映你的設計思想。文檔的數量也不多,開發文檔有兩類,一類是function Spec,另一類是Design Document。
function Spec中需要寫明的是本模組完成的任務,解決什麼問題,有什麼作用,為什麼要這些功能,此外我們還會添加進適用範圍,有什麼不足,注意點是什麼,還有哪些地方在以後可以進行改進。在這個function Spec中不涉及到任何非常詳細的演算法。此文檔不光給開發人員看,還讓QA及其他成員以及後來的新人能根據此文檔來瞭解此模組的大致功能,同時也會給文檔編寫者看,他們會根據這些function Spec整理出一份使用者手冊,告訴使用者此版本中新增了哪些功能,各功能模組有什麼作用,如何使用等資訊。因此在我們的開發過程中function Spec是很重要的文檔,此文檔完成後會抽出一段時間同相關人員及QA一起review這個文檔,讓QA瞭解設計者的意圖,同時熟悉新的功能模組,為接下來的測試作準備。如果其中有誤解或不明之處,大家會提出來探討並由開發人員修正。
Design Document中主要描述實現此模組所涉及到的主要演算法、資料結構、類的階層及調用關係。這個文檔的閱讀者主要是開發人員,包括任何想瞭解詳細實現代碼的人,協助人們理解代碼。在某些功能模組比較簡單的程式中,此文檔所描述的資訊會比較少。此文檔不象function Spec要在開始寫代碼前就編寫完成,它可以隨著代碼編寫的進行而增加,但基本上遵循文檔先行原則,也就是要增加新的代碼或修改代碼前若有涉及到文檔部分的應先修改文檔,然後再修改代碼。
4. 編寫代碼
由於我們用JAVA語言進行開發,因此我們藉助了Jbuilder IDE工具。關於代碼風格,我們基本上套用Jbuilder中自動的代碼格式編排,但其中需要改變的是縮排是4個字元,類與類之間間隔2行,方法與方法之間間隔2行,import類時用完整的類名。寫代碼時要對類及函數提供詳細的注釋及說明,基本做到看它們的說明就能知道這個類或函數的功能以及主要演算法的實現原理。在開發過程中對主要的模組要編寫UnitTest,同時要UnitTest先行,也就是遵循XP規則中的測試驅動原則,當所有的單元測試代碼通過時,此功能也就基本上完成了。
5. 代碼管理
我們採用VSS+SourceOffsite進資料列版本設定,其中存放了此產品的所有原始碼、庫檔案、文檔及release時的安裝程式,各個部分存放在不同的目錄中。每天早上要求開發人員從VSS中get latest version的原始碼,然後進行編譯並開始一天的工作。在下班之前理論上要求員工check in所有當天修改的代碼,在check in之前要保證編譯是能通過的。若有誰check in的代碼導致daily build失敗則會被要求某些懲罰措施或警告,象微軟公司要負責照看當日的每日構建。有時我們編寫的代碼涉及到多個檔案,而且此改動是比較複雜需要花費多天的工作量,如果現在check in進去可能會導致BVT(Build Verify Test)測試通不過,因為有些代碼沒有完全完成,而之前的代碼能使BVT測試通過,而且這些代碼基本上不會涉及到他人,在這種情況下可以不check in進去,直到全部程式碼完成能提交BVT測試時再一起check in進去。
每天我們都會做daily build,一般是在淩晨4點進行,那時有個程式會自動從VSS中拉下最新的代碼並進行編譯。因為我們同美國進行同步開發,因此如果想要把修改的代碼進入到這個build中去那就需要在淩晨4點之前把相應的代碼check in進去。若有人check in進去的代碼導致編譯通不過則會在本步驟中被發現。當編譯完成之後自動產生安裝包,測試部門將會對這些代碼進行BVT測試,同時對VSS中開發庫打上label,如果發現了什麼BUG就能根據這個label知道是哪個時候開始出現這個BUG的。BVT是指Build Verify Test,是對組件中準系統的測試。這個測試每天都會進行,看新加入的代碼或修改是否會影響系統的準系統,便於及早發現錯誤。
6. 測試
在開發人員完成了function Spec後,測試部門開始了測試規劃,確定需要測試哪些方面,如何測試及進度安排。測試人員需要寫許多測試代碼,有些測試代碼需要整合進BVT測試,有些可能需要進行單獨的測試,目的都是為了使產品符合要求,使開發人員容易找出問題所在並改正。產品功能是否符合了要求,是否能被發布是由測試人員決定的,因此測試人員也比較辛苦,責任重大。通過了每天的BVT測試,還有一些效能測試、相容性測試、災難測試等需要在產品發布前進行。在完成這些測試之後由測試人員決定本產品是否能release出去了,如果沒有什麼問題則會給某些關係較好的使用者進行β測試,之後再最終release出去。
7. BUG管理
由於我們每天進行著測試,因此經常有BUG被測試部門發現,一旦發現了新的BUG,就會被添加進BUG Tracking System中。目前較流行的BUG Tracking System有TestTrack、ClearQuest、Bugzilla等。BUG tracking system是開發人員和QA之間的紐帶,開發人員和QA通過BUG tracking system聯絡著。每個BUG有其類型和層級,預定的類型有Crash-Data Loss, Crash-No Data Loss, Incorrect functionality, Cosmetic, Feature request等, 層級有P1、P2一直到P6,它們分別代表了重要性及緊急程度,P1的BUG需要很快fix,P5之前的BUG在本版本release之前必須fix掉,若真的不能或不重要則由QA確定並降低優先順序進入到下一個版本中去fix。QA發現一個BUG後在BUG Track中增加一個BUG,同時填入相關資訊並assign給相應的開發人員,開發人員收到BUG分析並fix後assign給QA去verify,其中要填上分析的結果以及如何解決的詳細說明。若QA對此BUG verify通過則close BUG,否則verify failed並重新assign給開發人員並等待其fix。每星期在Status Meeting上會進行BUG狀況報告,主要由QA組長報告BUG的狀況,主要是新增BUG數,fix掉多少,還有多少處於open狀態,有多少處於等待verify的狀態,據此可以瞭解開發及測試情況。有時在Status Meeting上我們也會進行BUG Review,BUG Review有時是單獨一個小組內進行,其主要作用是重新明確每個人頭上的BUG以及瞭解每個BUG的狀況,如開發人員對此BUG將作何處理等,以此來瞭解開發中是否有碰到比較棘手的問題,增加了產品發布風險。在QA增加BUG和開發人員fix BUG的遊戲中,BUG的數量曲線圖會象股市曲線一樣上下波動,但總體趨勢一般是前期BUG放量攀升,後期震蕩下挫,若到了後期新open的BUG數量一直上升則說明風險在增大,有可能無法控制,也就是說fix了一個BUG導致了多個新的BUG產生。在量化開發進度中也可以用代碼數量的曲線圖來粗略的呈現。在有大量新功能增加時可能代碼量的增加會較快,當在fix bug階段,代碼的修改較多,因此代碼數量的增幅會降低,依據代碼量可以看出開發的狀況處於何種階段。
需要指出的是我們對BUG的定義比較廣泛,一些新功能也可以作為BUG被提出,只不過這些BUG層級比較低,讓它們進入到下一個版本中去實現。因此BUG的建立者也可以是技術支援人員、市場人員甚至開發人員本身。關於開發人員本身,因為他可能會找出一些BUG,有些是其他開發人員的,有些可能是此開發人員本身的,把這個BUG添加進BUG庫中可以協助開發人員在以後產生新問題時或類似的BUG時有一個借鑒和思路,但此BUG的verify必須要讓測試本模組的測試人員來verify。
8. Code Freeze
當P5之前的BUG都被修複了,這時離產品發布日期也就不遠了,一般是2個星期後就能release產品,這時要對VSS中的代碼進行freeze,以保證程式碼程式庫的穩定性。Code freeze階段一般會把各開發人員的check in和check out的許可權關閉,若在這時仍有BUG報告上來並經討論確定是重大的且必須在本版本中fix的,則需要經管理層同意並特殊地授予許可權,在修改完成後修改者要把修改了哪些檔案,影響了哪些文檔等資訊上報給各部門如QA、build人員、文檔編寫者等。在code freeze階段,測試部門在緊張地進行著各種測試,得出各種資料,並決定本版本是否可以release了。
9. Tech Talk
電腦知識更新速度非常快,經常有一些新的術語、新的名詞、新的思想、新的技術所產生,如過離開此行業幾個月後重新回來就會對這些新的事物不解,而我們平時為了自己的項目埋頭苦幹可能忘了周圍的世界發生了什麼。Tech Talk就提供了一個讓我們瞭解新知識和最新發展趨勢的機會,讓大家把知識共用,共同提高。Tech Talk一般會在項目不是太忙碌的時候進行,主持人會提前一個星期指定某個人去準備一下Tech Talk,一般此人可能對某方面比較感興趣,然後他會花一些時間去瞭解這方面的情況,寫成一個文檔如PowerPoint並上傳到區域網路內,同時通知大家可以先去瀏覽。Tech Talk的內容非常廣泛,不一定同我們的項目緊密相關,任何新的思想、新的知識(當然一般是限在電腦領域內)都可作為Tech Talk的內容,而在主講人講完之後還有一段時間被大家提問,共同對這個話題進行討論,答疑解惑。當然Tech Talk也可同我們的項目相關,如研究一下競爭者的產品技術,本公司產品的架構等。研究本公司的產品架構可以使大家對本公司的產品有一個全域的概念,從整體上來看自己的產品,順便整理一下產品的架構使之更加清晰有條理。平時大家都只注重於自己負責的其中的一小塊,在Tech Talk中可以跳出自己的小框框來瞭解全域,同時這也是新員工瞭解公司核心技術整體架構的好機會。每個模組的負責人需要闡述此模組的方方面面,讓大家來瞭解並回答問題。
10. Code Review
當進行工作移交時我們會進行Code Review,在碰到棘手的BUG時也會進行Code Review,Code Review是大家瞭解其詳細實現的一個好機會。在Code Review之後會對此代碼產生親切感而不是陌生懼怕感,相信很多人在讀他人代碼時會有非常痛苦的經曆,Code Review是減少此痛苦感的好藥方。在進行Code Review前,主講人會提前發出一個通知告訴相關人員要review哪些代碼,這樣參與者可以抽出時間提前瞭解相關代碼,對不懂的地方做個筆記以便在Code Review進行中提出疑問。在我們碰到比較棘手的BUG沒有什麼思路或大惑不解時,這時找幾個相關人員或對此代碼也熟悉的人進行一次Code Review,這時形式比較隨意,大家可以臨時提出問題,讓主講人解答,在這個過程中可能聽的人並不會非常快地瞭解其中的詳細過程,但是講的人在這個過程中重新理了一下思路,對所寫的代碼被迫重新審視了一遍,在其中可能就會發現出解決問題的辦法。在Code Review時有時代碼非常多,但可以一個功能模組一個功能模組地從總體到局部,由淺入深層層遞進的方式進行。一次Code Review的時間不要太長,但可以分多次進行。Code Review中大家會提出問題和建議,集思廣益,多個人共同出主意,有些可能一個人沒有想到的問題會被大家發現,互相學習,共同進步。
11. 溝通與交流
大部分員工的大部分時間是在公司裡度過的,因此公司的生活成了大家主要組成部分。員工之間關係的融洽,交流的暢通顯得非常重要,同時大家也不想自己的生活這樣枯燥乏味,一直同機器打交道。溝通無處不在,交流隨時發生,有許多關係是在工作之外建立起來的。軟體公司內是很容易產生各種矛盾的,因為這是由你的工作性質所決定的,比如QA或使用者會對你的實現不滿意,提出各種要求時,我相信你有時會有所抱怨的,無形之中就產生了對立,發展到後來會有抵觸心理。我相信大部分人都會有此感受,這不是你的錯,這主要是由我們的工作性質決定的。如果你的工作是把財富帶給對方,則對方會非常歡迎你的到來,把你奉為財神爺來對待,同你的關係會非常融洽友好。因此我們需要在工作之外來消除這種對立矛盾的關係,建立一種融洽的工作氛圍。我們在平時吃飯的時候飯桌上大家互相聊天溝通。我們建立了happy郵件清單,其中會發一些幽默笑話之類的郵件,給我們緊張的工作增加點輕鬆的氛圍。在下班後大家可以組織一下活動,增加了公司的凝聚力。一個產品發布後組織一下旅遊,讓繃緊的神經鬆弛一下,更好地迎接下一個挑戰。
12. 後記
不同公司有不同的做法,我只是把我認為比較好的流程與管理方式呈現出來,讓大家有個借鑒,當然它也不是十全十美的,也不是放之四海而皆準的,如果你覺得某些地方對你有所協助或值得推廣,這是本文最想達到的效果。非常感謝I公司給了我這麼美好的經曆,也非常感謝I公司的同事們曾給我的巨大協助,在此衷心地祝福I公司越來越壯大,逐步走向成功!也衷心地祝福我的同事們幸福快樂!