日度歸檔:2017年10月22日

人月神話

抽空把《人月神話》複習了一遍,回顧自己近期的工作,想對書中的一些觀點談談自己的感受。

  1. 編程行業「滿足我們內心深處的創造渴望和愉悅所有人的共有情感」,其提供了五種樂趣

    • 創建事物的快樂;
    • 開發對其他人有用的東西的樂趣;
    • 將可以活動、相互嚙合的零部件組裝成類似迷宮的東西,這個過程所體現出令人神魂顛倒的魅力;
    • 面對不重複的任務,不斷學習的樂趣
    • 工作在如此易於駕馭的介質上的樂趣——純粹的思維活動——其存在、移動和運轉方式完全不同於實際物體

    最近公司接了一個活,目標是把一個windows上的軟件產品做成跨平台的,也就是windows和mac。僱主那邊寫了一個類似於WPF的框架,目前需要我們把原來用MFC寫的界面換成用他們的框架寫成的界面。寫了2天之後我發現這個工作大部分是體力活。首先你需要把原來的界面用他們的框架畫好,就跟寫WPF界面差不多。然後把原來界面中的邏輯重新實現一下。因為沒有文檔,全靠參照前期領導寫的代碼和問同事,所以寫得比較累。繼續寫了幾天以後,感覺這個東西沒有給我帶來任何成就感。我覺得我成了流水線上的工人,原來編程帶給我樂趣都不存在了,有的只是重複和被push的壓力。原來覺得編程是一種腦力勞動,現在發現在你掌握了一定的技術基礎之後,有些事情就變成了體力勞動。對於這種工作,我的態度是按時上班,按時下班,不付出額外的勞動。因為我覺得這個工作不值得我付出哪怕多一點的精力。它對程序員而言是一種痛苦。加班加點地做這種痛苦的事只會使自己逐漸喪失對編程的樂趣。所以我一直在自學一些覺得有意思的東西,始終讓自己保持對編程的新鮮感。我知道我還要寫幾十年的程序,保持興趣才能讓我不斷進步。

  2. 所有的編程人員都是樂觀主義者,「一切都將動作良好」。
    這個是我感受最深的一點。從我非常有限的編程實踐中,我發現從project manager到一線程序員,普遍都對進度做了過於樂觀的估計。書中提到了幾個點說明為什麼進度常常不是按照我們估計得那樣進行。

    • 由於編程人員通過純粹的思維活動來開發,我們期待在實現過程中不會碰到困難。但是我們的構思本身是有缺陷的,因此總會有bug.
    • 圍繞着成本核算的估計技術,混淆了工作量和項目進度。人月是危險和帶有欺騙性的神話,因為它暗示人員數量和時間是可以相互替換的。
    • 在若干人員中分解任務會引發額外的溝通工作量——培訓和相互溝通。

    做樂觀的進度估計很多時候來自於客戶或者僱主的壓力。項目經理會受到來自於客戶的壓力,一線開發者又會受到同事和項目經理的壓力。然而實際完成的時間並不會由於估計的時間少就會早完成。從實際來看,我完成的時間一般都是領導估計時間的3倍左右。我覺得我領導估計時間更多地考慮了代碼變動所花的時間,而忽視了其它活動所花的時間。因此實際完成時間和預估時間相差比較大。

  3. 目標上(和開發策略上)的一些正常變化無可避免,事先為它們做準備總比假設它們不會出現好的多。
    程序員都希望需求是一成不變的,可是實際項目的需求往往一變再變。來公司3個月的時候,領導給了我一個小需求。要求在原來的界面上加幾個控件,本來位置和個數寫死就行了,後來變成了控件類型和數量都可以動態變化,控件位置也要動態改變。我原來實現的時候,只用了一層抽象去實現,這樣實現起來可以滿足需求,但可能很難應對變化。領導建議我把控件分組,增加一層抽象。後來僱主又要求控件布局也要動態變化,我才想到領導的先見之明。提前想想可能出現的需求變化,在前期適當增加一些抽象,往往可以更容易應對以後的需求變化。當然這個其實要求你對業務比較熟悉,能夠對可能的需求變化做一些預測。後來我想寫出好的軟件除了需要精通各種技術之外,還需要熟悉業務,不熟悉業務很難做出有價值的決策。

  4. 缺陷修復總會以20%~50%的幾率引入新的bug.
    在不斷的改bug過程中,我越來越覺得這是真理。因為改bug需要你先理解原有的邏輯,對於老項目而言,特別是沒有文檔的老項目,理解它一個模塊的各個邏輯是比較費力的。有時候你覺得你理解了它原有的邏輯,但你可能忽略了其中一個case,於是你的這次改動就引入了新的bug. 很多時候也是由於面前工期的壓力,你沒有時間完全理解原有的邏輯,只想快點解決這個比較嚴重的bug。這些都是導致新bug的原因。

  5. 即使是完全開發給自己使用的程序,描述性文字也是必須的,因為它們會被用戶——作者遺忘
    這條說的是文檔的重要性。就我現在做的項目而言,是美國的外包項目。美國那邊很重視文檔,一開始就把詳細的需求說明書(或者叫規格說明書)寫好,並在以後根據情況隨時更新。這樣開發做起來就完全清楚要做什麼功能,把功能具體做成什麼樣。原來待過一個月的A公司,經常是領導口頭交待任務,具體做成什麼樣領導自己也不清楚,靠自己去問其他人,沒有任何規範。我很難想像它這個項目能維護下去。現在做的這個項目已經有20多年的歷史了,仍然能夠維護下去,我覺得文檔是很重要的一點。有什麼問題,先看看原來的文檔是怎麼定義功能的,這樣很多東西都有據可查。另外一點,代碼中的注釋也是極重要的,特別是針對特定case所寫的代碼,一定要寫上注釋,否則後面維護的人可能就倒霉了。在這一點上,我覺得我的領導給我做了很好的示範。通過他的code review,我逐漸明白了何時注釋以及怎樣寫好的注釋。

  6. 在未來的十年內,無論是在技術還是管理方法上,都看不出有任何突破性的進步,能夠保證在十年內大幅度地提高軟件的生產率、可靠性和簡潔性。
    這是Brooks博士最重要的論點。他認為軟件開發中最主要的困難是規格說明、設計和測試這些概念上的結構,而不是對概念進行表達和對實現逼真程度進行驗證。軟件開發中有一些無法避免的內在特性:複雜度、一致性、可變性和不可見性。正是這些內在特性導致了軟件開發的生產率不會得到大幅度的提高。在他論文發表後的幾十年時間裏,軟件開發領域出現了很多新的語言、工具、程序庫,但這些只解決了軟件開發中的一部分次要困難。
    不過,Brooks博士也提出了一些解決主要困難的方法。其中一個是需求精鍊和快速原型。需求精鍊是說,必須與客戶進行深入的溝通,明確化客戶需求中模糊的部分。但即使這樣客戶還是會有很多地方無法精確表達自己的需求,而改變傳統的軟件開發流程可能對解決這個問題有很大幫助,即快速原型。首先系統應該能夠運行,即使未完成任何有用功能,只能正確調用一系列偽子系統。接着,系統一點一點被充實,子系統被輪流開發,或者在更低的層次調用程序、模塊、子系統的佔位符。這種方法要求自上而下的設計,因為它本身是一種自上而下增長的軟件。
    讀完這個論點,我還是有點雲里霧裡的。可能是經驗太少,做的只是一小塊,所以感觸也不多。

最後,想用書中的一段評論來結尾,送給國內的開發者:
現實世界中的管理就是在更大程度上以人員的生命為代價,讓他們更努力、更長時間的工作。經理們總是不停地吹噓他們的人員的加班時數和能從這些人身上榨取更多時間的小把戲。這種情況下,開發產品的質量一定會下降,甚至慘不忍睹,因為開發人員唯一能控制的是質量,當他們不得不犧牲質量,痛苦地面對自己的工作,踐踏工作的樂趣時,可以想像項目成本會大大增加,並且項目的發佈往往伴隨着一大批程序員的倒下。Read the rest