《人月神話》讀書筆記

人月神話讀書筆記

焦油坑

為什么兩個人的創(chuàng)業(yè)團隊可以超越大公司9倍以上的效率開發(fā)任何程序。而大公司的產(chǎn)業(yè)化團隊效率只有1000代碼行/年

程序員,就像詩人一樣,幾乎僅僅工作在單純的思考中。程序員憑空運用自己的想象,來建造自己的“城堡”。很少有這樣的介質(zhì)——創(chuàng)造的方式如此靈活,如此得益于精煉和重建,如此得容易實現(xiàn)概念上的設(shè)想。

評論:這個觀點與《黑客與畫家》中的觀點不謀而合,后者把程序員的工作看成和畫家、作家一樣的類似。但是也正因為程序員所做的工作是純粹的智力創(chuàng)造,不斷的推到重來就成為常態(tài)。概念設(shè)計上的不完善,使得軟件架構(gòu)變得越來越龐大、復(fù)雜并且難以為繼,成為一個焦油坑,越是掙扎,越是深陷其中。

人月神話

Brooks法則:

“向進度落后的項目中增加人手,只會使進度更加落后?!?/p>

“Adding mapower to a late software project makes it later.”

評論:注明的Brooks法則,人月神話一文的核心觀點。用人月這一觀念來衡量項目進度帶有欺騙性。因為他使得項目看上去好像人力和時間是可交換的。如果時間不夠,那么增加人手就可以加快進度。但是這個衡量方式忽略了新增加人手的培訓(xùn)時間、隊員之間的溝通時間等等因素,結(jié)果就是,盲目的增加人手只會導(dǎo)致項目落后。所以問題是,如何使得項目進度不落后;要想使得項目進度不落后,就要制定出合理的項目進度。所以,問題是,如何制定出合理的項目進度。

對于軟件任務(wù)的進度安排,以下是我使用了很多年的經(jīng)驗法則:

1/3 計劃

1/6 編碼

1/4 構(gòu)建測試和早期系統(tǒng)測試

1/4 系統(tǒng)測試,所有的構(gòu)建已完成

評論:充足的測試時間,只占1/6的編碼時間??上Ш芏鄷r候我們常常以為編碼時間就是全部的時間了,難怪會進度落后。

外科手術(shù)隊伍

最好的和最差的表現(xiàn)在生產(chǎn)率上平均為10:1,在運行速度和空間上具有5:1的驚人差異!簡言之,$20,000/年的程序員的生產(chǎn)率可能是¥10,000/年程序員的10倍。

得出的結(jié)論很簡單:如果一個200 人的項目中,有25 個最能干和最有開發(fā)經(jīng)驗的項目經(jīng)理,那么開除剩下的175 名程序員,讓項目經(jīng)理來編程開發(fā)。

評論:所以說有經(jīng)驗的程序員才是最廉價的勞動力啊

Harlan Mills 的提議提供了一個嶄新的、創(chuàng)造性的解決方案2,3。Mills 建議大型項目的每一個部分由一個團隊解決,但是該隊伍以類似外科手術(shù)的方式組建,而并非一擁而上。

也就是說,同每個成員截取問題某個部分的做法相反,由一個人來進行問題的分解,其他人給予他所需要的支持,以提高效率和生產(chǎn)力。

評論:有時候民主和平等也許并非是最好的選擇:因為首先在人在智力上、能力上就并不平等。外科手術(shù)式的團隊其實是延續(xù)了早期英雄式的編程風(fēng)格:主要的程序員決定了項目的大部分內(nèi)容,而其他人則成為他的副手,幫助他完成各項細節(jié)性的工作。

貴族專制、民主政治和系統(tǒng)設(shè)計

現(xiàn)在讓我們來處理具有濃厚感情色彩的問題——貴族統(tǒng)治和民主政治。結(jié)構(gòu)師難道不是新貴?他們一些智力精英,專門來告訴可憐的實現(xiàn)人員如何工作?是否所有的創(chuàng)造性活動被那些精英單獨占有,實現(xiàn)人員僅僅是機器中的齒輪?難道不能遵循民主的理論,從所有的員工中搜集好的創(chuàng)意,以得到更好的產(chǎn)品,而不是將技術(shù)說明工作僅限定于少數(shù)人?

評論:為了實現(xiàn)概念完整性,在軟件體系結(jié)構(gòu)設(shè)計的時候必須實行貴族專制,讓少數(shù)的架構(gòu)師來決定整體的架構(gòu),普通程序員毫無發(fā)言權(quán)。但是Brooks為了安慰那些可憐的普通程序員,就告訴他們:其實實現(xiàn)細節(jié)也是需要一樣的創(chuàng)造性、同樣的新思路和卓越的才華。但是誰都知道,如果能夠成為貴族,為何要在制造工藝上費勁心思呢?

畫蛇添足

第二個系統(tǒng)是設(shè)計師們所設(shè)計的最危險的系統(tǒng)。而當(dāng)他著手第三個或第四個系統(tǒng)時,先前的經(jīng)驗會相互驗證,得到此類系統(tǒng)通用特性的判斷,而且系統(tǒng)之間的差異會幫助他識別出經(jīng)驗中不夠通用的部分。

一種普遍傾向是過分地設(shè)計第二個系統(tǒng),向系統(tǒng)添加很多修飾功能和想法,它們曾在第一個系統(tǒng)中被小心謹慎地推遲了。

評論:這個標(biāo)題起得讓人摸不清頭腦,其實值得是第二系統(tǒng)效應(yīng)(second-system effect)。認識到第二個系統(tǒng)存在的風(fēng)險,可以讓架構(gòu)師保持警惕,少犯錯誤。

為什么巴比倫塔會失?。?/h2>
  1. 清晰的目標(biāo)?是的,盡管幼稚得近乎不可能。而且,項目早在遇到這個基本的限制之前,就已經(jīng)失敗了。
  1. 人力?非常充足。
  1. 材料?在美索不達米亞有著豐富的泥土和柏油瀝青。
  1. 足夠的時間?沒有任何時間限制的跡象。
  1. 足夠的技術(shù)?是的,金字塔、錐形的結(jié)構(gòu)本身就是穩(wěn)定的,可以很好分散壓力負載。對磚石建筑技術(shù),人們有過深刻的研究。同樣,項目遠在達到技術(shù)限制之間,就已經(jīng)失敗了。

那么,既然他們具備了所有的這些條件,為什么項目還會失敗呢?他們還缺乏些什么?兩個方面——交流,以及交流的結(jié)果——組織。他們無法相互交談,從而無法合作。當(dāng)合作無法進行時,工作陷入了停頓。通過史書的字里行間,我們推測交流的缺乏導(dǎo)致了爭辯、沮喪和群體猜忌。很快,部落開始分裂——大家選擇了孤立,而不是互相爭吵。

胸有成竹

本章只解決一個問題:一個程序員的生產(chǎn)效率究竟有多高?

對規(guī)模平均為3200指令的程序...大約單個的程序員所需要的編碼和調(diào)試時間為178個小時,由此可以外推得到每年35800語句的生產(chǎn)率。而規(guī)模只有一半的程序花費時間大約僅為前者的四分之一,相應(yīng)推斷出的生產(chǎn)率幾乎是每年80,000代碼行1。計劃、編制文檔、測試、系統(tǒng)集成和培訓(xùn)的時間必須被考慮在內(nèi)。因此,上述小型項目數(shù)據(jù)的外推是沒有意義的。就好像把100碼短跑記錄外推,得出人類可以在3分鐘之內(nèi)跑完1英里的結(jié)論一樣。

工作量和代碼行數(shù)不是線性關(guān)系,而是指數(shù)型關(guān)系:

工作量 = (常數(shù))×(指令的數(shù)量)^1.5

Aron的數(shù)據(jù):

很少的交互 10,000指令每人年

少量的交互 5,000

較多的交互 1,500

Harr的數(shù)據(jù)

OS/360的數(shù)據(jù)

600-800(經(jīng)過調(diào)試的指令)/人年

Corbato的數(shù)據(jù)

平均生產(chǎn)率是1200行經(jīng)過調(diào)試的PL/I語句/人年
Corbato的數(shù)據(jù)是行為單位,每行語句對應(yīng)3-5個指令。

上述所有數(shù)據(jù)的結(jié)論:

  1. 對于常用編程語句而言,生產(chǎn)率似乎是固定的。這個固定的生產(chǎn)率包括了編程中需要注釋,并可能存在錯誤的情況。
  2. 生產(chǎn)率隨著系統(tǒng)復(fù)雜性或者難度增加而降低。
  3. 使用適當(dāng)?shù)母呒壵Z言,編程的生產(chǎn)率可以提高5倍。

未雨綢繆

因此,管理上的問題不再是“是否構(gòu)建一個試驗性的系統(tǒng),然后拋棄它?”你必須這樣做?,F(xiàn)在的問題是“是否預(yù)先計劃拋棄原型的開發(fā),或者是否將該原型發(fā)布給用戶?”從這個角度看待問題,答案更加清晰。將原型發(fā)布給用戶,可以獲得時間,但是它的代價高昂——對于用戶,使用極度痛苦;對于重新開發(fā)的人員,分散了精力;對于產(chǎn)品,影響了聲譽,即使最好的再設(shè)計也難以挽回名聲。

因此,為舍棄而計劃,無論如何,你一定要這樣做。

雖然Brooks在50年前就已經(jīng)提出構(gòu)建可拋棄原型的必要性,并且在各類開發(fā)模型中也都強調(diào)原型的必要性,但是到今天,可拋棄原型仍然沒有被大部分實踐所接受?;蛟S,知道該做什么,和實際去做之間,永遠存在一個鴻溝。另一種可能性是,可拋棄原型雖然很好,但是顯然沒有達到“必須”的程度。它帶來的好處不足以彌補其代價,是今天大部分實踐中并未采用的原因。

系統(tǒng)軟件開發(fā)是減少混亂度(減少熵)的過程,所以它本身是處于亞穩(wěn)態(tài)的。軟件維護是提高混亂度(增加熵)的過程,即使是最熟練的軟件維護工作,也只是放緩了系統(tǒng)退化到非穩(wěn)態(tài)的進程。

系統(tǒng)開發(fā)的熵論,非常的形象有趣。為變更而計劃組織架構(gòu),其實只是一句讓你認識到軟件開發(fā)過程中“唯一不變的是變化”這一條真理。然而這也是一條悖論,如果只有變化的話,那么計劃就沒有意義了。關(guān)鍵在于我們需要計劃出不變的部分,為變化留出空間。

禍起蕭墻

項目是怎樣延遲了整整一年的時間?…一次一天。

但是一天一天的進度落后是難以識別、不容易防范和難以彌補的。昨天,某個關(guān)鍵人員生病了,無法召開某個會議。今天,由于雷擊打壞了公司的供電變壓器,所有機器無法啟動。明天,因為工廠磁盤供貨延遲了一周,磁盤例程的測試無法進行。下雪、應(yīng)急任務(wù)、私人問題、同顧客的緊急會議、管理人員檢查——這個列表可以不斷地延長。每件事都只會將某項活動延遲半天或者一天,但是整個進度開始落后了,盡管每次只有一點點。

對于這種逐漸延遲的進度,Brooks提議簡歷項目里程碑,并且持續(xù)的修訂項目計劃,這樣無論最后的情況變得多么糟糕,它都不會有太大的變化。里程碑是指百分之百的事件,必須有明顯的邊界和沒有歧義。這樣就很好有人可以在里程碑進展上弄虛作假。

另外一面

需要文檔的必要性不言而喻,問題在于什么樣的文檔才是好的文檔。
本文中給出了以下文檔必要內(nèi)容的參考:

  1. 目的。主要的功能是什么?開發(fā)程序的原因是什么?
  2. 環(huán)境。程序運行在什么樣的機器、硬件配置和操作系統(tǒng)上?
  3. 范圍。輸入的有效范圍是什么?允許顯示的合法范圍是什么?
  4. 實現(xiàn)功能和使用的算法。精確地闡述它做了什么。
  5. 輸入-輸出格式。必須是確切和完整的。
  6. 操作指令。包括控制臺及輸出內(nèi)容中正常和異常結(jié)束的行為。
  7. 選項。用戶的功能選項有哪些?如何在選項之間進行挑選?
  8. 運行時間。在指定的配置下,解決特定規(guī)模問題所需要的時間?
  9. 精度和校驗。期望結(jié)果的精確程度?如何進行精度的檢測?

沒有銀彈——軟件工程中的根本和次要問題

沒有任何技術(shù)或管理上的進展,能夠獨立地許諾十年內(nèi)使生產(chǎn)率、可靠性或簡潔性獲得數(shù)量級上的進步。

There is no single development, in either technology or management technique, which by itself promises even one order-of-magnitude improvement within a decade in productivity, in reliability, in simplicity.

軟件工程領(lǐng)域最著名的論斷。

所有軟件活動包括根本任務(wù)——打造由抽象軟件實體構(gòu)成的復(fù)雜概念結(jié)構(gòu),次要任務(wù)——使用編程語言表達這些抽象實體,在空間和時間限制內(nèi)將它們映射成機器語言。

軟件工程領(lǐng)域的根本難題在于復(fù)雜度,一致性,可變性和不可見性。值得注意的是,文章末尾提出了一些可能的銀彈,比如面向?qū)ο缶幊?,只能解決軟件工程中的非本質(zhì)困難,而對于軟件工程根本的問題于事無補。就是說,我們某種程度上能夠解決使用編程語言表達抽象的實體,或者將其變得結(jié)構(gòu)化,構(gòu)建起完整的概念結(jié)構(gòu),但是仍然沒有解決軟件工程的根本難題——復(fù)雜度、一致性、可變性和不可見性。

因此,現(xiàn)在的技術(shù)中最有希望的,并且解決了軟件的根本而非次要問題的技術(shù),是開發(fā)作為迭代需求過程的一部分——快速原型化系統(tǒng)的方法和工具。

快速原型之所以可以解決根本問題,是因為快速原型有助于澄清軟件工程的概念結(jié)構(gòu),從而降低了后期變更的幅度?;诳焖僭瓦M行增量開發(fā),目前已經(jīng)成為實際開發(fā)的標(biāo)準(zhǔn)流程。

再論《沒有銀彈》

Brooks在這篇文章里面再次討論了很多潛在的銀彈。因為自從《沒有銀彈》發(fā)表以后,遭到了大量的誤解、批評和質(zhì)疑,Brooks專門寫了這篇文章來繼續(xù)解釋他的觀點和回應(yīng)批評。

首先一個可能的銀彈是Harel提出的一種叫做Vanilla的框架,有助于程序的概念設(shè)計和圖形化呈現(xiàn),看上去確實直面軟件工程開發(fā)的根本困難:復(fù)雜性和不可見性。Brooks甚至也贊同如果Vanilla框架得到發(fā)展應(yīng)用,也許就是銀彈。但是今天看來,20年過去了似乎Vanilla已經(jīng)遭人遺忘。顯然它并非軟件開發(fā)的銀彈。

另一個可能的銀彈是定制軟件包的開發(fā)?;旧辖裉斓拈_源社區(qū)已經(jīng)這樣做了。大量的公共庫被開發(fā)出來,確實提高了通用需求的開發(fā)效率。Brooks也承認,他低估了軟件包客戶化的程度和重要性。

面向?qū)ο缶幊?,被稱為“銅制子彈”。但是面向?qū)ο蠹夹g(shù)“不會加快首次或第二次的開發(fā),產(chǎn)品族中第五個項目的開發(fā)才會異乎尋常的迅速”。不過經(jīng)過20年再來看,面向?qū)ο箅m然發(fā)展緩慢,但是的確已經(jīng)統(tǒng)治了軟件開發(fā)行業(yè),稱得上一顆“銅制子彈”。

軟件重用,也是一個可能的解決方案。

大多數(shù)有豐富經(jīng)驗的程序員擁有自己的私人開發(fā)庫,可以使他們使用大約30%的重用代碼來開發(fā)軟件。公司級別的重用能提供70%的重用代碼量,它需要特殊的開發(fā)庫和管理支持。公司級別的重用代碼也意味著需要對項目中的變更進行統(tǒng)計和度量,從而提高重用的可信程度。

但是重用面臨一個問題,就是重用所帶來的好處,必須大于其代價,才得以實施。比如一個數(shù)學(xué)庫函數(shù),如果不重用,那么程序員自己需要學(xué)習(xí)大量的相關(guān)知識才能寫得出來。而對于項目中的某個功能,與其花費很多功夫?qū)ふ抑赜玫哪K,可能程序員直接重新實現(xiàn)一次是更快捷的做法。

重用是一件說起來容易,做起來難的事情。它同時需要良好的設(shè)計和文檔。即使我們看到了并不十分常見的優(yōu)秀設(shè)計,但如果沒有好的文檔,我們也不會看到能重用的構(gòu)件。

“不管怎樣,重用的模塊一般是一些通用功能?!?/p>

軟件重用的另一個問題是學(xué)習(xí)的成本。越復(fù)雜的功能,學(xué)習(xí)成本越高。高級語言比機器語言功能強大,但是也更加復(fù)雜。而重用一個模塊,則需要學(xué)習(xí)相應(yīng)該模塊的成本。這種成本今天已經(jīng)在各類專門開發(fā)職業(yè)中體現(xiàn)出來,如后臺程序員,Web前段或者手機客戶端,不同類別的程序員差別就在于其對某一重用模塊的專門知識的掌握。

20年后的人月神話

今天,我比以往更加確信。概念完整性是產(chǎn)品質(zhì)量的核心。擁有一位結(jié)構(gòu)式是邁向概念完整性的最重要一步。這個原理不僅限于軟件系統(tǒng),它適用于所有的復(fù)雜事物。

如果要我用一個詞語來概括人月神話,我想我會說“溝通代價”;如果可以有兩個詞,那就加上“概念完整性”。

20年后的人月神話有些結(jié)論得到驗證,有些情況已經(jīng)變化,下面是這些情況的簡單概括:

  • 第二系統(tǒng)定律得到驗證:開發(fā)第二個系統(tǒng)總是因為盲目的功能導(dǎo)致易用性、甚至是可用性的災(zāi)難。
  • 圖形界面的成功
  • 瀑布模型被證明是錯的了,因為沒有構(gòu)建舍棄原型。事實上增量開發(fā)與快速迭代才是理想的開發(fā)方式。
  • 增量開發(fā)和快速原型,漸進地精華,讓軟件像生物進化那樣逐漸演化成更為復(fù)雜的結(jié)構(gòu),演化出更多的功能。
  • 信息隱藏:Parnas是正確的,我是錯誤的。20年前關(guān)于信息隱藏的兩大觀念,其一是Brooks主張的,所有的程序員應(yīng)該了解所有的材料。而Parnas則認為代碼模塊應(yīng)該采用定義良好的接口來封裝,這些模塊內(nèi)部結(jié)構(gòu)應(yīng)該是程序員的私有財產(chǎn)。Brooks承認,Parnas所主張的方案確實更符合實際。
  • 對人月神話實際研究發(fā)現(xiàn),向進度落后的項目中添加人手會增加項目的成本,但是不一定會使項目更加落后。如果在項目早期添加額外的人比在后期添加額外的人更安全些。
  • 人就是一切。這一點可以從《人件:高生產(chǎn)率的項目和團隊》可以見出。
  • 放棄權(quán)利的力量——公司通過將權(quán)利下放到具體的團隊,事實上使得組織機構(gòu)變得更加“融洽和繁榮”。
  • 最令人驚訝的新事物——數(shù)百萬的計算機
  • 使用塑料包裝的成品軟件包作為構(gòu)建:成熟的模塊和對象組合提升了軟件復(fù)用的層次。

軟件工程的未來

軟件工程的焦油坑在將來很長一段時間內(nèi)會繼續(xù)地使人們舉步維艱,無法自拔。軟件系統(tǒng)可能是人類創(chuàng)造中最錯綜復(fù)雜的事物,只能期待人們在力所能及的或者剛剛超越力所能及的范圍內(nèi)進行探索和嘗試。這個復(fù)雜的行業(yè)需要:進行持續(xù)的發(fā)展;學(xué)習(xí)使用更大的要素來開發(fā);新工具的最佳使用;經(jīng)論證的管理方法的最佳應(yīng)用;良好判斷的自由發(fā)揮;以及能夠使我們認識到自己不足和容易犯錯的——上帝所賜予的謙卑。

參考

《人月神話》FREDERICK P. BROOKS, JR.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容