1. 程式人生 > >我的Lean & Agile(精簡和敏捷)經歷(這才是最佳實踐)

我的Lean & Agile(精簡和敏捷)經歷(這才是最佳實踐)

我說的精簡和敏捷並不是說我的減肥或瘦身的經歷。精簡和敏捷就是製造業裡的敏捷管理和精簡庫存的意思。精簡和敏捷管理在90年代初才被引入軟體製造業,現在國內知道最多的是Martin Fowler,或是IBM用的那一套,還有最近微軟也開始推崇精簡和敏捷管理,併為此設計了一些軟體。我所經歷的精簡和敏捷管理和這些都沒有聯絡,話收回來,我的經歷和微軟有一點點關係,和Martin Fowler也有點關係。下面就是我的故事。

200511月份左右,我還是微軟一個普通的合同工,當時我和Volt Computer Services的合同差不多過期了,我剛剛把我的夫人接到美國,不找份正式工作心裡不踏實。我一開始先嚐試著在微軟找份工作,我去了一個

MS Office測試組的面試,結果面試發現這個組使用手動測試居多,自動化測試很少。我的能力和方向和他們相差還很大,自然沒有通過。我當時所在的小組又沒有任何全職機會,所以我就開始尋找雷德蒙地區(華盛頓州的微軟的老窩)其他機會。有一天我收到了一封來自Peter Stroeve的信,可能是我在HotJob上張貼的Resume引來的注意。我和他來回了幾封電子信,我最後決定去這個名叫Net Objectives 的公司進行一個面試。當時我們就聊了聊天,我和Peter見了面,他是個很沉默的人,和他一起的還有David Moynohiem(不知道有沒拼錯),後來還來了一位Kevin Yu(廣東人)。我和他們海吹山侃地聊了
25分鐘,然後又做了些他們出的題目。他們對我非常滿意,就派我到MSN旗下一個搞上網安全軟體的小組面試。我輕鬆搞定了這個簡單面試。

隨後我開始了我事業生命中最光彩,最難忘的經歷。當時David告訴我說,這是一個微軟MSN的外包專案,我們準備用了Lean & Agile的管理模式來進行這個專案的設計和製作。我不知道這個Lean & Agile究竟是什麼,我當時心想不管怎麼樣,先當優秀的士兵,在連長安排下衝鋒陷陣,做好本職工作,發揮110%的自我能力,肯定沒有問題。我打心裡就不相信所謂的Lean & Agile能夠做好一個軟體。當時我看到的微軟在Vista上的人員互動,我對軟體設計管理丟失了信心,我只知道自己能力不錯,能處理任何問題,當時的信念是“一夫當關,萬夫莫開”。我對自己的能力的信任是沒有任何疑問的。

第一個星期整個小組在招人,和我同時選上的還有一名叫Nadim Rubeiz的黎巴嫩人,Kevin是專案負責人。後來我們又招了一個叫Brian Young的測試員。他是個硬體驅動高手,對視窗核心和驅動設計瞭如指掌,是個不折不扣的高手。我們又招了一個叫Said Fathababel的埃及人,此人對視窗內部的構造十分了解,也是高手。BrianSaid都有一定的問題,我後面再慢慢敘述。這第一週我們先是選定辦公地點,是公司中一個稍大的會議廳,Kevin定購了一張很大的會議桌,我們四人團團圍著桌子坐,當時我覺得這樣辦公好寒慘。幾分鐘後才知道這才是Lean & Agile的最佳工作方式。我們隨後安裝了新買的Dell電腦,開始將所有的任務寫在紙上,貼在窗上。我們的開發就此開始。

第一個星期的工作基本上是投石問路,我們大概知道我們的使用者期待的是什麼,我們大體把前三個星期該做的事列舉下來了,第一週過後,我們和客戶見面進行了45分鐘的會談,首先Kevin介紹了Lean& Agile的管理原理,我們外包人員是一輛汽車,我們的客戶是駕駛員,客戶的意願加上我們的做事程式,將完成客戶所期待的價值。隨後我們把該做的事和客戶進行溝通,選出了兩週左右該做的事。這些都叫“故事”(Stories),最準確的名稱應該是“任務”。我們把故事的重要性進行分類;最重要最急迫的被劃分並放入“Front Burner”;不急不緩的“故事”被放入“Back Burner”;最不急的“故事”被放進“Cold Frig”。所有最重要的“故事”必須在第一個開發週期(兩週)內完成。這並不是硬性指標,因為完不成的任務往往是重要“故事”中最不重要的任務。這些完不成的任務和“Back Burner”中的任務重新被衡量,最重要的這些未完成的“故事”被選擇到“Front Burner”中,作為下一週期中該進行的任務。就這樣周而復始地,所有的任務要麼在最後基本完成,要麼時間全部用完但是一部分任務根本沒有完成,而這些“故事”正是客戶不需要的。這就是Lean & Agile

我們開完會,回到公司開始開工。我們先總結了一天的工作,這是一個15分鐘的短會,叫“Scrum”。每個人必須站立著,向工程負責人彙報昨天作的事,這是每個開發人員每天做的一件事。然後在每個週期開始,我們要進行設計會議,我們把故事細化,然後把所有的故事列在白板上,大家每人選擇一個自己有興趣的“故事”去做,做完驗收後,再選擇一個新的“故事”去做。我們第一個開發週期的進度完成地非常順利,我們設計了一個簡單的使用者介面,然後是一個簡單的中介軟體,最後是一個後臺資料儲存件。設計的時候我們遵循了“測試為先,開發隨後”(Test Driven Development)的設計準則,利用CxxText作為我們的單元測試框架,事實上我們好多測試都是用CxxUnit來完成的,我們除了硬體,作業系統,和Visual Studio .Net 2005外所有的資源都是自己搞出來的,微軟貢獻的,或是開源資源。我們五個人組成的開發團隊最大的價值是我們過硬的技術能力,這些基本上就能在外包行業賺取利潤。當然,這並不代表我們的團隊沒有任何問題。下面我就要談談我們所面對的問題。

從第二週開始,我們的進度就開始影響。首先是Brian在第一個開發週期時沒有完成他所要完成的測試任務。事實他在整個開發過程中沒有做什麼事,他有一個不滿週歲的小孩,每天不到10301100我們不一定能見到他走進辦公室。下午早在330,就見他準備回家接孩子。好在他的合約籤的是合同制,否則這樣每天五小時的工作算成八小時的工作,我們的公司不是被他騙去不少錢。隨即出現的問題是,Lean & Agile要求組配對設計,兩人一起解決一個設計問題,這需要兩人相互給對方提意見,然後相互吸取對方的意見,這種做法就是強迫設計小組中的任意兩人進行取長補短。既然這是一種硬性規定,我們就必須虛心相互溝通。Brian並不是這樣的人,他的智商可能有156,所以他認為所有的人都比他愚蠢。我根本和他合不來,我的意見他根本聽不進去。一個簡單的測試程式我們爭吵了三四小時,我覺得這個程式五十行碼就能寫完,他偏偏要用各種鑽進牛角尖的方法進行設計,我的簡單設計他聽不進去,我也無法說服他採納我的意見,然後我只好和他擡槓。這種情況本身就是與Lean & Agile背道而馳的。面對這樣的問題我毫無辦法。等到我們的程式突破三百行程式碼時,我們才設計了整個程式的一半。我實在無法控制這樣的局面,在他離開後就只好向Kevin坦白我實在無法和他溝通。SaidBrian幾天前出現過同樣的問題,他們甚至為雙方的專業背景而產生爭執。事情是這樣,Said背僱傭後,Brian問他是否是搞驅動背景的。當時Brian的態度很不好,給Said的感覺是Brian 藐視了他對小組能做出的貢獻。當時大家的心態都很不好,我們三人(我,BrianSaid)都在微軟工作過,我們剛剛被Layoff,大家都希望自己在這個新公司裡的位置穩一點。Brian大概是害怕Said作為一個懂視窗結構的老手來奪取他在公司裡的位置,而Said則覺得自己好不容易在丟了工作後找到這麼一個來之不易的機會又受到一個年輕Punk的排擠。Said氣忿之下兩人就爭吵起來,後來我們只好開會互相諒解。後來Nadim花費了一個上午才說服Brian嘗試簡單的設計思路。後面我們發現Brian和整個小組的配合並不很好,所以我們後面的做法是,儘可能少給他事情做,將他變成一個可以隨便取代的成員。因為他擁有更好的測試手段,和硬體測試技術,有利用價值,所以我們一直容忍他的不作為到專案結束,最後我們也發現他的存在確實在關鍵是可能幫上忙,正應驗了古時候“雞鳴狗盜”故事中的寓意。

在第二個開發週期的前期,Nadim重新設計了後臺資料儲存系統。然後我們重複了幾次有關UNICODEANSI的爭執。Nadim希望使用ANSI編碼作為後臺資料儲存系統檔案的編碼,這樣檔案的大小比較小。我覺得視窗都是用UNICODE編碼,如果使用ANSI,我們要用一堆的轉換函式,這是非常繁瑣的操作。具體的原因我也不記得了,我們改了兩次,最終將設計定為用UNICODE編碼作為後臺資料儲存系統檔案的編碼。我也在設計中犯過錯誤,我和Said花費了三小時設計了使用者介面和中介軟體銜接。Nadim來了以後稽核了我們的工作,結果推翻了我的設計,我們花了一小時半,將所有的設計重新搞了一遍。我當時非常惱火,但是仔細看了看他的設計思路,他的思路更好,完全分開了中介軟體和使用者介面。這時我才意識到這樣成對進行設計的好處就是取長補短,這種好處是有條件的,兩人都必須是水平相等的;兩人都必須是有一定深度的開發能力;兩人都必須尊重對方,並能接受成對設計這種思想。

在第二個開發週期中,最大的一次問題是第二個星期的星期五。我們把所有的設計原始碼上交後準備回家,結果單元測試輸出了六十多個錯誤。結果我們仔細察了一下,有人沒有完全做好自己的單元測試,就隨隨便便提交了自己的程式碼。這個人是Said。既然出了問題,那我只好留下來陪他把問題解決。那天是2005聖誕前夕,Brian已經早退;Kevin好像有事所以也先走了;Nadim腿有上傷,比Kevin還早就走了。既然是程式出錯,我又是QA,所以我就和Kevin說我可以留下幫一下Said。我們花了兩小時,沒有任何進展,又是聖誕,所以我們就回家了。事實上這個問題解決方法不難,我們使用了Win32 API的使用者許可權函式,結果效果很不理想。後來我在一本叫“Write Secure Code”(我們第一個設計也是從這本書裡抄出來的)找到一段用ATL設計的程式碼,我在家裡試了下,效果不錯,就推薦給了Said。後來Said又和Nadim 成對進行了設計,最終在第三個星期一完成了修改。這裡學到的教訓是,加班是麼沒有用的。一週的工作已經讓人十分疲倦,將員工的休息時間轉換成更多的工作時間完完全全是錯誤做法。疲倦的員工心裡只有一件事,休息,放鬆,不想工作。強迫員工加班或是員工自願加班的行為只能損傷員工的健康,同時很少的進展能在這樣的狀態下完成,最後公司還要為這樣次等的工作付出加班費,這就是一種浪費。

Brian比起來,和Said的合作還算正常。和他的互動我發現他對單元測試並不感冒,他寫的很多的單元測試都是部分的整合測試(Partial Integration Test)。Said是個C程式設計師,所以很多他寫的程式碼都要看兩遍才能知道他在做什麼,但是,這些程式碼效率確實很好。可是有時我們發現什麼錯誤,都要花不少時間來查詢問題在什麼地方。在這個專案之前,我用Visual StudioDebugger用得很少,這次我可是實實在在地學瞭如何使用這個工具。Said最厲害的地方,可能我現在還沒有學會這個,就是如何在程式碼裡挖蟲。我們在第二個週期裡設計了一個壓力測試程式,當時Kevin叫我們設計這麼一個程式,我就花了半小時用C#寫了這麼一個程式。我們運行了一下發現微軟給我們的TDI驅動裡有嚴重的記憶體洩漏。我找了幾小時找不出問題,Kevin 就叫我把這個問題轉讓給SaidSaid在兩小時內就發現了幾個檔案柄沒有關閉的問題。後面兩個設計週期中,他不斷地在微軟給我們的程式碼中發現這樣的問題。我從他那裡學到了不少查詢蟲子的方法,特別是使用像Sysinternal的一些第三方的工具來監測記憶體洩漏。當然我也學了一些C程式設計有關的技巧。但是和他合作,速度是一個很大問題,有些問題只要45 秒鐘可以解決的,但是他要看4分鐘才能想到這個45秒鐘的問題,這樣反而減慢了整個開發的速度,這樣的開發反而有個好處,因為他在思考的時候方方面面都考慮到了,所以速度和周全相互抵消,最後的設計效果有時反而很好。有時這樣的過多思考反而效果不好。我記得在最後一個開發週期中,我們有個改進要做,假設兩個使用者一個改變了程式設定,然後快速轉變使用者,換到另一個使用者,這時Systray中的ICON也要同時改變。我和Said嘗試了一個非常複雜的設計,當然我的技術沒有那麼厲害,所以Said提供了這個方案,在使用者一那裡改變設定,然後使用者一更新Systray中的ICON。接著,程式在使用者一的桌面上向用戶二所在的桌面的同一程式送一個資訊,讓這個程式更新Systray中的ICON。然後我們一起編寫了這個設計。當然這麼一個想當然的方法沒有成功。我回頭一想,每個使用者在快速變換(Fast User Switch)時,程式能夠檢測使用者快速變換,所以在第二個使用者桌面轉成螢幕上的桌面時,只要重新將程式設定更新一下,第二個使用者的Systray中的ICON就更新了。這個第二種方案几十行程式碼就解決了,一點都不麻煩。我們犯的錯誤就是想過頭了,真正的Lean & Agile 就是要從最簡單的解決方法想起。

我和Nadim的合作產生的毛病最少,我和他的合作一般是早上我大約在9點多進公司,第一件事我先是做些有關一天要做的任務的調查,然後等所有的人進了公司後我才和他或Said進行成對設計。這樣的效率也非常高,我早上查詢的資訊一般在90分鐘到內變成可用的程式碼。我和Nadim合作設計了好幾個使用者介面有關的部分,他是一個很優秀的設計者,我的技術和他比起來就要差一些。所以我完全可以承認我的技術功底不是很優秀,後來微軟沒有招我做正式員工也是能理解的,我畢竟不是異常優秀的程式設計人。但是如果微軟招我做了正式員工,那麼我就不可能有機會和這些微軟以外的高手合作,不可能有機會在實踐中體驗Lean & Agile這麼先進的軟體工程管理理論,更無法想象一個工程小組能如此高效,如此精簡敏捷地進行客戶能夠滿意的開發。Nadim讓我佩服的是他的理解能力,我記得那一段時間中最丟人的經歷是花了一天時間沒搞出如何用WiX技術進行安裝包的製作。Nadim的耐心讓他在一天中搞出一個很漂亮的安裝包,對這個壯舉我是十分佩服的。我還記得我們兩人搞了一下午的單元測試來摸索微軟給我們的一個特殊字串處理類,叫MSN::CString,這個庫是專門用來處理URL字串的。當時我們的配合非常好,我和他輪流想出測試這個庫裡的函式的測試單元用來試探這個庫的使用方法,以此,我們在毫無文件解說的情況下摸索出了這個庫的使用方法。當時MSN的開發人員問我們說,沒有文件你們怎麼知道如何使用這個庫的?我們的部門經理很自豪地回答說全靠遵循我們開發管理系統中的一套制度摸索出來的。我和他還一起解決過一個有關CListViewMFC)處理大量物件(List View Item)速度太慢的問題。當時CListView自己的加入物件並顯示的速度在處理10000個物件時要花幾秒鐘,我們用Google查找了90分鐘,找到了一套自己載入這些物件加入 ListView的辦法把整個速度加快到處理100000個物件只需兩秒。一下把效率提高過來。這個改進當時又一次讓MSN對我們感到非常滿意,加上後來我們在他們的程式碼中找到許多檔案柄沒有關閉的問題之後,我們的高效和專業敬業完完全全取得了他們的信任。我覺得Nadim最讓我值得尊敬的素質是他的領導能力。Kevin是個非常優秀的領導,Nadim則是Kevin不在時的替補領導。因為他的技術基礎過硬,和許多的開發經驗,所以贏得我們所有人的尊重,我們會尊重他的意見,我們在他的帶領下進行開發。沒有他在後面用技術做領導,這個專案完成後的質量不一定是那麼好。我同時感覺他在整個過程中對Lean & Agile的領悟非常深,他和我一樣喜歡這套做事方式。

最後說說Kevin。他是一個很優秀的領導,沒有他對Lean & Agile管理的深刻認識,我們肯定不可能在兩個半月內將這專案完成,但是他要是沒有我們這些人,也不可能把這個專案完成。他是一個非常勤奮的人,他的主要職責不是和我們一樣開發,他的職責是和使用者溝通,他把使用者所希望得到的最後期望轉化成一個個細節的“故事”然後吩咐給我們設計。我們把他作為我們的客戶,我們做完了一個區域性設計先讓他看,他認為滿意,我們就知道客戶對這樣的設計一定也會滿意。他要是不滿意,馬上會告訴我們應該達到什麼樣的效果。客戶要達到的效果,他能仔細地分析細化,然後和使用者溝通哪些是重要的,哪些是不重要的,排序以後,我們再簡單討論如何分配這些“故事”給每個人做。他耐心地和Brian還有Said解釋Lean & Agile的理念。特別是BrianBrian的貢獻最少,但是他還是耐心地和Brian一起成對進行設計。後面我實在沒有興趣和Brian成對進行測試,因為Brian每次碰到機會就反對我的意見,每次他自己出現問題就是花費數小時自己去閱讀,試圖理解這個問題的方方面面,完全不顧整個開發進度,完全不顧其他人是否有這方面的專長能否幫他把眼下工程搞完。Kevin不懂C++,只懂C#,可他還是堅持和Brian成對程式設計。他不是想學技術,他是儘自己最大努力監督BrianBrian 自己該做的任務做完。可以看出Said是沒有時間Brian糾纏,Nadim似乎也沒有興趣和Brian糾纏,我就完全承認,我是沒有好脾氣和Brian扯皮。但是作為一個設計組的領袖,Kevin不得不做壞人,用威信逼迫Brian做到他想要的結果,當然這樣最終還是逼著Brian做完了該做的事。而且在同時,我們在沒有Brian搗亂的狀態下做完了我們該做的事。Kevin的表現100%完美地展示了Lean & Agile的管理和開發過程,他是個非常優秀的Scrum Master。由他的帶領下,我們做正事的,遵守了所有Lean & Agile要求,他靈活地運用了Lean & Agile的管理模式,而不是死板地遵照書本上寫的教條,所以我們在最短時間內做了三倍同樣時間能做的事。我們每個人都接觸了一些我們平時沒有搞過的事,我搞了不少Build有關的工作。就是微軟內部用來建造的系統,就是Win DDK加上Platform SDK。我花了60%的時間在開發上,但也有40%的時間搞我該搞的QA工作。總得來說我在這個專案了做了異常多的工作,這是我覺得我應該在這麼短時間內做完這麼多的工作量。Nadim完成的工作量比我多,他也和我一樣穿梭在各種各樣的任務中。SaidBrian各自也最大化地盡了他們的努力。Brian在最後一個週期,特別是臨近交貨的一天中花了9小時測試了整個使用者介面的功能,查找出不少值得改進的地方,我這時才發現他並沒有我想象地那麼沒用。Said就不用說了,他在關鍵的時刻就能為我和Nadim提供一些非常有價值的反饋。Said的程式碼修改實在讓人敬佩,他寫的東西就是很靈巧(這個詞大概我五年沒用了)。Kevin在排程員工讓每個人在必要時發揮自己的能力做得實在讓我佩服,這也說明他運用Lean & Agile十分嫻熟。當然和他合作,我也有感到不耐煩的時候,我向他解釋一些比較技術的問題,我要解釋三遍才能解釋清楚。他經常在我正做得興起的時候把我打斷,然後進行15分鐘的Scrum會議,這時我在一開始就會覺得有點煩躁。同樣的問題,有時他會在我做事的時候把我打斷,叫我更新用來記錄工程進度的Wiki主頁。但是這些小小的愉快根本算不上什麼。在這樣的設計組裡工作,合作的愉快遠遠大過一些小小的不舒服。

最後總結一下我對這個工程的感想。這個工程是我覺得自己所參加過最好的一個專案。我們100% 地執行了Lean & Agile工程管理模式,我們在規定的時間內為客戶完成了客戶所期待的產品。我們沒有完成所有客戶所希望的產品功能,我們完成了所有客戶認為最重要的產品功能,客戶對我們的評價是“You guys are the superstars!”但是等我們做完後,他們沒有其他專案給我們做,允許為我們在其他專案的投標中為我們提供好的評價。我們交出工程後,15天內,客戶從來沒有和我們聯絡讓我們進行維護,說明我們的工程質量完全合格。我們在整個專案中,除了最後一個開發週期,基本上都沒有加班過。最後一個開發週期中,我們七天不停地工作,我那一段時間加班賺了不少錢,但是馬上又病了一段時間。說說我對這套工程管理模式感到不滿意的地方,就像我說的,任何工程管理模式都有一些不足的地方。首先是大家工作的時間表,除我以外,大家都在早上10點半甚至是11點才到辦公地點,然後自願做到晚上89點才回家,我挺不喜歡這種工作方式。我在這個工程過程中發現,能夠保證工程順利進行的主要還是人的因素,一個開發組要有能夠接受這樣的開發風格的人相互協作,心無二念,能夠服從領導的指揮。一個開發組必須擁有一個很有能力的Scrum Master,必須能夠準確地和客戶溝通產品的功能,能夠記錄客戶提出的每一個要求,再和開發組進行溝通,Scrum Master還要有很好的管理能力。每個組員的能力也是一個很重要的因素,沒有能力強,能夠合作的組員,一個工程也很難繼續。在這個工程開發中,一個技術能力很強但是合作能力很差的人,給整個小組的貢獻其實很少,為了保持進度,我們其他組員都要承擔這個人的任務,這樣讓我們所有人都覺得累。其他問題還包括,我們並沒有完全遵守Lean & Agile的規則,我們對設計的細化做得不夠,我們的單元測試,整合測試做得也不夠,最後我們交給客戶的產品我是滿意的,我覺得它可以被設計得更好,可惜我們沒有更多的時間來完善。我對這個工程的最後結果是很滿意的,我的經歷告訴我,這樣的工程管理是非常有效的,前提是,這麼一個開發小組需要的高效,技術好,能合作,能把事情做完的人,需要一個能力高超的管理人員,需要所有的人員都能按照Lean & Agile的規則做事。一個開發小組缺少這些因素中任意一個,開發就不一定能成功。