《人月神话》(The Mythical Man-Month)看清问题的本质:如果我们想解决问题,就必须试图先去理解它...

news2024/12/23 13:34:42

2200fb39d598fae4896f725927230385.png

第一章 焦油坑(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 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 Programming Systems Product)

9a55807f2cd17976b455443b1b972047.png

程序(Program)。它本身是完整的,可以由作者在所开发的系统平台上运行。

eadb674e472ecf170face3f84ebb5209.png

水平边界以下,程序变成编程产品(Programming Product),测试、修复和扩展的程序。它可以运行在多种操作系统平台上,供多套数据使用。要成为通用的编程产品,程序必须按照普遍认可的风格来编写,特别是输入的范围和形式必须扩展,以适用于所有可以合理使用的基本算法。接着,对程序进行彻底测试,确保它的稳定性和可靠性,使其值得信赖。这就意味着必须准备、运行和记录详尽的测试用例库,用来检查输入的边界和范围。此外,要将程序提升为程序产品,还需要有完备的文档,每个人都可以加以使用、修复和扩展。经验数据表明,相同功能的编程产品的成本,至少是已经过测试的程序的三倍。

回到图中,垂直边界的右边,程序变成编程系统(Programming System)中的一个构件单元。它是在功能上能相互协作的程序集合,具有规范的格式,可以进行交互,并可以用来组装和搭建整个系统。要成为系统构件,程序必须按照一定的要求编制,使输入和输出在语法和语义上与精确定义的接口一致。同时程序还要符合预先定义的资源限制——内存空间、输入输出设备、计算机时间。最后,程序必须同其它系统构件单元一道,以任何能想象到的组合进行测试。由于测试用例会随着组合不断增加,所以测试的范围非常广。因为一些意想不到的交互会产生许多不易察觉的 bug,测试工作将会非常耗时,因此相同功能的编程系统构件的成本至少是独立程序的三倍。如果系统有大量的组成单元,成本还会更高。

图 1.1 的右下部分代表编程系统产品(Programming Systems Product)。情况不同的是,它的成本高达九倍。然而,只有它才是真正有用的产品,是大多数系统开发的目标。

0646ade45017282996cb2b0764958771.png


【更多阅读】

  • 【架构师必知必会系列】系统架构设计需要知道的5大精要(5 System Design fundamentals)

  • 《人月神话》8 胸有成竹(Chaptor 8.Calling the Shot -The Mythical Man-Month)

  • 《人月神话》7(The Mythical Man-Month)为什么巴比伦塔会失败?

  • 《人月神话》(The Mythical Man-Month)6贯彻执行(Passing the Word)

  • 《人月神话》(The Mythical Man-Month)5画蛇添足(The Second-System Effect)

  • 《人月神话》(The Mythical Man-Month)4概念一致性:专制、民主和系统设计(System Design)

  • 《人月神话》(The Mythical Man-Month)3 外科手术队伍(The Surgical Team)

  • 《人月神话》(The Mythical Man-Month)2人和月可以互换吗?人月神话存在吗?

  • 在平时的工作中如何体现你的技术深度?

  • Redis 作者 Antirez 讲如何实现分布式锁?Redis 实现分布式锁天然的缺陷分析&Redis分布式锁的正确使用姿势!

  • 程序员职业生涯系列:关于技术能力的思考与总结

  • 十年技术进阶路:让我明白了三件要事。关于如何做好技术 Team Leader?如何提升管理业务技术水平?(10000字长文)

  • 当你工作几年就会明白,以下几个任何一个都可以超过90%程序员

  • 编程语言:类型系统的本质

  • 软件架构设计的核心:抽象与模型、“战略编程”

  • 【图文详解】深入理解 Hbase 架构  Deep Into HBase Architecture

  • HBase 架构详解及读写流程原理剖析

  • HDFS 底层交互原理,看这篇就够了!

  • MySQL 体系架构简介

  • 一文看懂MySQL的异步复制、全同步复制与半同步复制

  • 【史上最全】MySQL各种锁详解:一文搞懂MySQL的各种锁

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/74246.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux简化版线程池

目录 一,线程池设计 二,线程池应用场景 三,线程池准备 1,包装一个锁 2,一个任务类 三,线程池 1,成员介绍 2,设计单例模式 3,创建线程池 4,线程池执…

【吴恩达机器学习笔记】十六、应用实例:图片文字识别

✍个人博客:https://blog.csdn.net/Newin2020?spm1011.2415.3001.5343 📣专栏定位:为学习吴恩达机器学习视频的同学提供的随堂笔记。 📚专栏简介:在这个专栏,我将整理吴恩达机器学习视频的所有内容的笔记&…

【Linux】Zabbix5.0平台的搭建

文章目录项目背景视频展演一、Linux基础配置1、查看当前系统版本2、修改主机名3、修改 IP 地址4、配置防火墙5、关闭 SELINUX6、修改系统时间及时区7、配置 YUM 库方式 1方式 2二、安装apache1、安装 apache2、启动 apache 服务3、设置 httpd 服务开机启动4、查看服务状态5、防…

深度学习——制作自己的VOC图像分割数据集

1、数据集介绍 COCO数据集有80个类别,VOC数据集有20个类别。当这些数据集类别中没有自己需要的时候,就需要自己动手做自己的数据集了。 我自己在做数据集的时候主要使用到了labelme和labelImg两个工具。labelme主要是制作语义分割数据集(ImageSets,JPEGImages,SegmentationC…

kubernetes 1.18 部署 ingress-nginx

文章目录kubernetes 1.18 部署 ingress-nginx1. 下载 yaml 文件2. 安装 ingress-nginx3. 检查安装情况4. 测试验证4.1 查看ingress规则4.2 访问测试5. 其他内容kubernetes 1.18 部署 ingress-nginx 1. 下载 yaml 文件 在 GitHub 下载完成之后可以直接使用,不需要修…

[基因遗传算法]进阶之三:sko.GA的实践TSP

参考资料:《VRP问题分类》 相关文章: 《[基因遗传算法]原理思想和python代码的结合理解之(一) :单变量》 《[基因遗传算法]进阶之二:最优规划问题–多种编码方式多变量》 文章目录一. GA的用法1.1 help(sko.GA)1.2 目标函数的书写A. 单变量的书写B. 多变量的书写C. 变量的范围…

mysql中的B+树、索引跳跃扫描

普通索引 B树的叶子节点上记录的是聚簇索引(主键索引)的值。 联合索引 叶子节点中记录的是name,age两个字段以及主键id的值。 MySQL一定是遵循最左前缀匹配的,这句话在mysql8以前是正确的,没有任何毛病。但是在M…

(文章复现)7.计及电转气协同的含碳捕集与垃圾焚烧虚拟电厂优化调度(MATLAB程序)

联系方式:2645521500 复现文章: 计及电转气协同的含碳捕集与垃圾焚烧虚拟电厂优化调度——孙惠娟(电网技术—2020) 摘要: 为了促进多能源互补及能源低碳化,本文提出了计及电转气协同的含碳捕集与垃圾焚…

有手就会做,保姆级Jmeter分布式压测操作流程(图文并茂)

分布式压测原理 分布式压测操作 保证本机和执行机的JDK和Jmeter版本一致 配置Jmeter环境变量 配置Jmeter配置文件 上传每个执行机服务jmeter chmod -R 755 apache-jmeter-5.1.1/ 执行机配置写自己的ip 控制机配置所有执行机ip,把server.rmi.ssl.disable改成true 将本机也作…

Java-1208

JVM与Java体系结构 JVM整体结构(上图主要针对hotspot虚拟机) 类加载器: 将字节码文件加载进去,并不一定是java字节码文件,很多语言都会编译成字节码文件使用JVM 运行时数据区: 方法区和堆:使用了…

毕业设计 STM32单片机智能WiFi天气助手 - 物联网 单片机

文章目录0 前言1 设计内容2 软件设计3 关键代码4 最后0 前言 🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不…

Go设计与实现--数组与切片

数组 初始化 Go语言数组的初始化是在编译期就已经执行好了。这个是初始化的代码&#xff1a; // NewArray returns a new fixed-length array Type. func NewArray(elem *Type, bound int64) *Type {if bound < 0 {base.Fatalf("NewArray: invalid bound %v", …

Security实现前后端分离

Security实现前后端分离 说明 ​ 上一篇和上上一篇我大致介绍了一下security基础使用和oauth2的一些流程&#xff0c;这里在深入了解一些相关的配置项。 ​ 首先我们在梳理一下相关概念&#xff0c;首先基本的security是负责用户认证这这一环节&#xff0c;总而言之就是用户…

PCB入门学习—原理图的绘制1(MCU部分)

目录 2.1 STM32F103VET6 MCU核心电路的绘制 学习目录 2.1 STM32F103VET6 MCU核心电路的绘制 总结&#xff1a;放置元件&#xff0c;连线&#xff0c;放置网络标号&#xff0c;更新序号。 主控放上去之后原理图图纸不太够&#xff1a;双击右边边缘&#xff0c;默认图纸大小是…

【Java小案例】从简到精完美判断年份是闰/平年和该年二月份有几天

目录前言问题描述思路分析解决方案方案一方案二方案三方案四结语前言 1、平年指阳历没有闰日或农历没有闰月的年份&#xff0c;闰年是公历中的名词&#xff0c;是为了弥补因人为历法规定造成的年度天数与地球实际公转周期的时间差而设立的&#xff0c;补上时间差的年份为闰年&a…

QA | SWCF2022 笔记:GNSS模拟赋能汽车HIL测试

2022年度SWCF卫星通信与仿真测试研讨会正在进行中&#xff0c;精彩演讲&#xff1a;GNSS模拟赋能汽车HIL测试&#xff0c;感谢大家的观看与支持&#xff01;收到一些粉丝的技术问题&#xff0c;我们汇总了热点问题并请讲师详细解答&#xff0c;在此整理分享给大家&#xff01; …

高通平台开发系列讲解(UART篇)高速串口代码流程

文章目录 一、初始化1.1、Registration with the SPS driver1.2、UART port registration二、Port open三、Port close沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇章主要介绍高通平台高速串口代码流程。 一、初始化 初始化流程: msm_serial_hs_init() ->

数据传送指令MOV、XCHG

学习过程中要重点掌握对标志寄存器的影响 数据传送类指令&#xff08;不影响标志位&#xff09; 一&#xff1a;MOV指令 先要知道图片中这几个英文表示什么 立即数&#xff08;immediaate operand&#xff09; 寄存器&#xff08;register&#xff09; 内存&#xff08;…

WEB前端大作业HTML静态网页设计旅游景点区主题——三亚旅游网页设计

家乡旅游景点网页作业制作 网页代码运用了DIV盒子的使用方法&#xff0c;如盒子的嵌套、浮动、margin、border、background等属性的使用&#xff0c;外部大盒子设定居中&#xff0c;内部左中右布局&#xff0c;下方横向浮动排列&#xff0c;大学学习的前端知识点和布局方式都有…

基于Java+Swing实现超级玛丽游戏

基于JavaSwing实现超级玛丽游戏一、系统介绍二、功能展示三、其他系统一、系统介绍 超级玛丽小游戏的JAVA程序&#xff0c;进入游戏后首先按空格键开始&#xff0c;利用方向键来控制的马里奥的移动&#xff0c;同时检测马里奥与场景中的障碍物和敌人的碰撞&#xff0c;并判断马…