《人月神话(The Mythical Man-Month)》看清问题的本质:如果我们想解决问题,就必须试图先去理解它...
第一章 焦油坑(The Tar Pit)
史前史中,沒有比巨獸在焦油坑中垂死掙扎的場面更令人震撼的了。上帝見證著恐龍、猛犸象、劍齒虎在焦油中掙扎。它們掙扎得越是猛烈,焦油糾纏得越緊,沒有任何猛獸足夠強壯或具有足夠的技巧,能夠掙脫束縛,它們最后都沉到了坑底。
No scene from prehistory is quite so vivid as that of the mortal struggles of great beasts in the tar pits. In the mind's eye one sees dinosaurs, mammoths, and sabertoothed tigers struggling against the grip of the tar. The fiercer (猛烈)the struggle, the more entangling the tar, and no beast is so strong or so skillful but that he ultimately sinks.
過去幾十年的大型系統開發就猶如這樣一個焦油坑,很多大型和強壯的動物在其中劇烈地掙扎。他們中大多數開發出了可運行的系統——不過,其中只有非常少數的項目滿足了目標、時間進度和預算的要求。各種團隊,大型的和小型的,龐雜的和精干的(wiry),一個接一個淹沒在了焦油坑中。表面上看起來好像沒有任何一個單獨的問題會導致困難,每個都能被解決,但是當它們相互糾纏和累積在一起的時候,團隊的行動就會變得越來越慢。對問題的麻煩程度,每個人似乎都會感到驚訝,并且很難看清問題的本質。不過,如果我們想解決問題,就必須試圖先去理解它。
Large-system programming has over the past decade been such a tar pit, and many great and powerful beasts have thrashed (掙扎)violently in it. Most have emerged with running systems—few have met goals, schedules, and budgets. Large and small, massive or wiry, team after team has become entangled in the tar. No one thing seems to cause the difficulty—any particular paw can be pulled away. But the accumulation of simultaneous and interacting factors brings slower and slower motion. Everyone seems to have been surprised by the stickiness of the problem, and it is hard to discern the nature of it. But we must try to understand it if we are to solve it.
因此,首先讓我們來認識一下軟件開發這個職業,以及充滿在這個職業中的樂趣和苦惱吧。
Therefore let us begin by identifying the craft of system programming and the joys and woes inherent in it.
編程系統產品的演進(The Programming Systems Product)
程序(Program)。它本身是完整的,可以由作者在所開發的系統平臺上運行。
水平邊界以下,程序變成編程產品(Programming Product),測試、修復和擴展的程序。它可以運行在多種操作系統平臺上,供多套數據使用。要成為通用的編程產品,程序必須按照普遍認可的風格來編寫,特別是輸入的范圍和形式必須擴展,以適用于所有可以合理使用的基本算法。接著,對程序進行徹底測試,確保它的穩定性和可靠性,使其值得信賴。這就意味著必須準備、運行和記錄詳盡的測試用例庫,用來檢查輸入的邊界和范圍。此外,要將程序提升為程序產品,還需要有完備的文檔,每個人都可以加以使用、修復和擴展。經驗數據表明,相同功能的編程產品的成本,至少是已經過測試的程序的三倍。
回到圖中,垂直邊界的右邊,程序變成編程系統(Programming System)中的一個構件單元。它是在功能上能相互協作的程序集合,具有規范的格式,可以進行交互,并可以用來組裝和搭建整個系統。要成為系統構件,程序必須按照一定的要求編制,使輸入和輸出在語法和語義上與精確定義的接口一致。同時程序還要符合預先定義的資源限制——內存空間、輸入輸出設備、計算機時間。最后,程序必須同其它系統構件單元一道,以任何能想象到的組合進行測試。由于測試用例會隨著組合不斷增加,所以測試的范圍非常廣。因為一些意想不到的交互會產生許多不易察覺的 bug,測試工作將會非常耗時,因此相同功能的編程系統構件的成本至少是獨立程序的三倍。如果系統有大量的組成單元,成本還會更高。
圖 1.1 的右下部分代表編程系統產品(Programming Systems Product)。情況不同的是,它的成本高達九倍。然而,只有它才是真正有用的產品,是大多數系統開發的目標。
編程的樂趣(The Joys of the Craft)
編程為什么有趣?作為回報,它的從業者(practitioner)期望得到什么樣的快樂?
Why is programming fun? What delights may its practitioner expect as his reward?
首先是一種創建事物的純粹快樂。如同小孩在玩泥巴時感到愉快一樣,成年人喜歡創建事物,特別是自己進行設計。我想這種快樂是上帝創造世界的折射,一種呈現在每片獨特、嶄新的樹葉和雪花上的喜悅 。
First is the sheer joy of making things. As the child delights in his mud pie, so the adult enjoys building things, especially things of his own design. I think this delight must be an image of God's delight in making things, a delight shown in the distinctness and newness of each leaf and each snowflake.
其次,快樂來自于開發對其他人有用的東西。內心深處,我們期望其他人使用我們的勞動成果,并能對他們有所幫助。從這個方面,這同小孩用粘土為“爸爸辦公室”捏制鉛筆盒沒有本質的區別。
Second is the pleasure of making things that are useful to other people. Deep within, we want others to use our work and to find it helpful. In this respect the programming system is not essentially different from the child's first clay pencil holder "for Daddy's office."
第三是整個過程體現出魔術般的力量——將相互嚙合的零部件組裝在一起,看到它們精妙地運行,得到預先所希望的結果。比起彈珠游戲或點唱機所具有的迷人魅力,程序化的計算機毫不遜色。
Third is the fascination of fashioning complex puzzle-like objects of interlocking moving parts and watching them work in subtle cycles, playing out the consequences of principles built in from the beginning. The programmed computer has all the fascination of the pinball machine or the jukebox mechanism, carried to the ultimate.
第四是學習的樂趣,來自于這項工作的非重復特性。人們所面臨的問題,在某個或其它方面總有些不同。因而解決問題的人可以從中學習新的事物:有時是實踐上的,有時是理論上的,或者兼而有之。
Fourth is the joy of always learning, which springs from the nonrepeating nature of the task. In one way or another the problem is ever new, and its solver learns something: sometimes practical, sometimes theoretical, and sometimes both.
最后,樂趣還來自于工作在如此易于駕馭的介質(tractable medium)上。程序員,就像詩人一樣,幾乎僅僅工作在單純的思考中。程序員憑空地運用自己的想象,來建造自己的“城堡”(castle)。很少有這樣的介質——創造的方式如此得靈活,如此得易于精煉和重建,如此得容易實現概念上的設想。(不過我們將會看到,容易駕馭的特性也有它自己的問題。)
Finally, there is the delight of working in such a tractable medium. The programmer, like the poet, works only slightly removed from pure thought-stuff. He builds his castles in the air, from air, creating by exertion of the imagination. Few media of creation are so flexible, so easy to polish and rework, so readily capable of realizing grand conceptual structures. (As we shall see later, this very tractability has its own problems.)
然而程序畢竟同詩歌不同,它是實實在在的東西;可以移動和運行,能獨立產生可見的輸出;能打印結果,繪制圖形,發出聲音,移動支架。神話和傳說中的魔術在我們的時代已變成了現實。在鍵盤上鍵入正確的咒語,屏幕會活動、變幻,顯示出前所未有的或是已經存在的事物。
Yet the program construct, unlike the poet's words, is real in the sense that it moves and works, producing visible outputs separate from the construct itself. It prints results, draws pictures, produces sounds, moves arms. The magic of myth and legend has come true in our time. One types the correct incantation on a keyboard, and a display screen comes to life, showing things that never were nor could be.
編程非常有趣,在于它不僅滿足了我們內心深處進行創造的渴望,而且還愉悅了每個人內在的情感。
Programming then is fun because it gratifies creative longings built deep within us and delights sensibilities we have in common with all men.
職業的苦惱(The Woes of the Craft)
然而這個過程并不全都是喜悅。我們只有事先了解一些編程固有的煩惱,這樣,當它們真的出現時,才能更加坦然地面對。
Not all is delight, however, and knowing the inherent woes makes it easier to bear them when they appear.
首先,必須追求完美。因為計算機也是以這樣的方式來變戲法:如果咒語中的一個字符、一個停頓,沒有與正確的形式一致,魔術就不會出現。(現實中,很少的人類活動要求完美,所以人類對它本來就不習慣。)實際上,我認為學習編程的最困難部分,是將做事的方式往追求完美的方向調整。
First, one must perform perfectly. The computer resembles the magic of legend in this respect, too. If one character, one pause, of the incantation is not strictly in proper form, the magic doesn't work. Human beings are not accustomed to being perfect, and few areas of human activity demand it. Adjusting to the requirement for perfection is, I think, the most difficult part of learning to program.
其次,是由他人來設定目標,供給資源,提供信息。編程人員很少能控制工作環境和工作目標。用管理的術語來說,個人的權威和他所承擔的責任是不相配的。不過,似乎在所有的領域中,對要完成的工作,很少能提供與責任相一致的正式權威。而現實情況中,實際(相對于正式)的權威來自于每次任務的完成。
Next, other people set one's objectives, provide one's resources, and furnish one's information. One rarely controls the circumstances of his work, or even its goal. In management terms, one's authority is not sufficient for his responsibility. It seems that in all fields, however, the jobs where things get done never have formal authority commensurate with responsibility. In practice, actual (as opposed to formal) authority is acquired from the very momentum of accomplishment.
對于系統編程人員而言,對其他人的依賴是一件非常痛苦的事情。他依靠其他人的程序,而往往這些程序設計得并不合理,實現拙劣,發布不完整(沒有源代碼或測試用例),或者文檔記錄得很糟。所以,系統編程人員不得不花費時間去研究和修改,而它們在理想情況下本應該是可靠完整的。
The dependence upon others has a particular case that is especially painful for the system programmer. He depends upon other people's programs. These are often maldesigned, poorly implemented, incompletely delivered (no source code or test cases), and poorly documented. So he must spend hours studying and fixing things that in an ideal world would be complete, available, and usable.
下一個煩惱——概念性設計是有趣的,但尋找瑣碎的 bug 卻只是一項重復性的活動。伴隨著創造性活動的,往往是枯燥沉悶的時間和艱苦的勞動。程序編制工作也不例外。
另外,人們發現調試和查錯往往是線性收斂的,或者更糟糕的是,具有二次方的復雜度。結果,測試一拖再拖,尋找最后一個錯誤比第一個錯誤將花費更多的時間。
The next woe is that designing grand concepts is fun; finding nitty little bugs is just work. With any creative activity come dreary hours of tedious, painstaking labor, and programming is no exception.
Next, one finds that debugging has a linear convergence, or worse, where one somehow expects a quadratic sort of approach to the end. So testing drags on and on, the last difficult bugs taking more time to find than the first.
最后一個苦惱,有時也是一種無奈——當投入了大量辛苦的勞動,產品在即將完成或者終于完成的時候,卻已顯得陳舊過時。可能是同事和競爭對手已在追逐新的、更好的構思;也許替代方案不僅僅是在構思,而且已經在安排了。
現實情況比上面所說的通常要好一些。當產品開發完成時,更優秀的新產品通常還不能投入使用,而僅僅是為大家談論而已。另外,它同樣需要數月的開發時間。事實上,只有實際需要時,才會用到最新的設想,因為所實現的系統已經能滿足要求,體現了回報。
The last woe, and sometimes the last straw, is that the product over which one has labored so long appears to be obsolete upon (or before) completion. Already colleagues and competitors are in hot pursuit of new and better ideas. Already the displacement of one's thought-child is not only conceived, but scheduled.
This always seems worse than it really is. The new and better product is generally not available when one completes his own; it is only talked about. It, too, will require months of development. The real tiger is never a match for the paper one, unless actual use is wanted. Then the virtues of reality have a satisfaction all their own.
誠然,產品開發所基于的技術在不斷地進步。一旦設計被凍結,在概念上就已經開始陳舊了。不過,實際產品需要一步一步按階段實現。實現落后與否的判斷應根據其它已有的系統,而不是未實現的概念。因此,我們所面臨的挑戰和任務是在現有的時間和有效的資源范圍內,尋找解決實際問題的切實可行方案。
Of course the technological base on which one builds is always advancing. As soon as one freezes a design, it becomes obsolete in terms of its concepts. But implementation of real products demands phasing and quantizing. The obsolescence of an implementation must be measured against other existing implementations, not against unrealized concepts. The challenge and the mission are to find real solutions to real problems on actual schedules with available resources.
這,就是編程。一個許多人痛苦掙扎的焦油坑以及一種樂趣和苦惱共存的創造性活動。對于許多人而言,其中的樂趣遠大于苦惱。而本書的剩余部分將試圖搭建一些橋梁,為通過這樣的焦油坑提供一些指導。
This then is programming, both a tar pit in which many efforts have floundered and a creative activity with joys and woes all its own. For many, the joys far outweigh the woes, and for them the remainder of this book will attempt to lay some boardwalks across the tar.
總結
以上是生活随笔為你收集整理的《人月神话(The Mythical Man-Month)》看清问题的本质:如果我们想解决问题,就必须试图先去理解它...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 组合博弈游戏
- 下一篇: 搜狗收录方法之搜狗推送接口实现