作为一本与计算机有关的图书,在1971年初次出版之后,能够经过45年仍然保持活力,不能不说它是一本神奇的书。“本书开创了一个新的领域,即将程序开发作为一种人类行为来看待,而不仅仅是与硬件、软件相关。” 45年来,虽然计算机软硬件技术在飞速地更新换代,但人类作为程序开发的主体,人类的心理状态和行为模式与45年前并没有太大的不同。因此本书作者温伯格先生45年前的诸多真知灼见如今依然适用。又由于20年前出版银年纪念版的时候,作者没有直接修改原书,而是在保持原貌的基础上增加评注,让我们可以更真切地看到在开始的25年间,软硬件技术进步和管理知识积累给程序开发的各方面带来的或多或少的影响。
我猜有两类人大概会喜欢这本书:第一类是有一些开发经历,喜欢观察、思考并愿意尝试改善开发过程的程序员;第二类是程序员出身转而从事开发管理工作,同样喜欢观察、思考并愿意不断尝试对开发过程做出改善的技术主管。此外,我非常希望其他管理层的主管们也能来读一读这本书,对软件开发的过程及组织能够有更多的了解,不过书里吐槽管理层的地方有点儿多,只怕他们就算勉强来读了也不见得喜欢。
另外在序言中,温伯格先生提醒读者:
读者的责任是要根据自己的经验与需求,对书中的所有观点进行权衡取舍。... ... 我不希望读者在阅读过程中贸然接受某种观点,因为这种读书的态度正是我们应该努力戒除的。本书中提供的素材只是读者在自己思想形成的过程中需要消化、吸收的食物,而不应该是个人思想的简单替代品。
这个要求其实适用于读任何书。
本书从 1、作为人类行为的程序开发;2、作为社会行为的程序开发;3、作为个人行为的程序开发;4、程序开发工具 四个方面进行了阐述。
第一篇 作为人类行为的程序开发
本篇前两章阅读程序和优秀程序的要素尝试将程序开发看成一项以人为主体的行为加以研究,并论述了进行这种研究的可行性和必要性,第三章如何研究程序设计则从人类行为学和心理学研究方法的角度进一步讨论了对程序开发进行研究的可行性。
(作为一名程序员,阅读本书的乐趣与收获更多来自温伯格先生随意挥洒的各种经验之谈。每章结尾的小结、思考题和本章评注,也是值得多花费些时间和精力的部分。)
第一章 阅读程序
程序被编写成什么样子,取决于众多的因素。有的是由于计算机的局限,有的是由于程序语言的局限,有的是由于程序员的局限,有的是因为历史的偶然,而有的则可能是因为规范。
思考题:
请主管回答
1.如果你是一线主管,你是否有能力阅读你手下的程序员所编写的程序?或者,就阅读程序的能力而言,你是否与“老一辈”的计算机和语言一同落伍了?如果你有这个能力,你真的会去阅读程序吗?如果此前你不阅读程序,为什么现在不尝试一下,看看会发现什么?
2.如果你是高层主管,你手下的一线主管们是否有能力阅读他们手下的程序员所编写的程序?你能肯定吗?向程序员了解一下,然后重新回答这个问题。然后查明一线主管是否真的阅读程序,即使他们有这个能力。我们的调查显示,由于各种原因,九成的一线主管不阅读程序。你是否认为,如果不经常阅读程序员的程序,一线主管能知道程序员的能力如何,工作是否出色吗?
请程序员回答
1.你上次阅读别人的代码是在什么时候?为什么经过了这么长的时间?最近一次有人阅读你的程序并且与你讨论,是在什么时候?这个人是你的主管吗?
2.到程序库或者向你的好友借一份程序。试着分析并找出其中各段代码存在的原因,看看是否属于本文中介绍的某种情况。通过这个练习,你有什么收获?
3.找出你至少一个月之前亲自编写的一个程序,参照第2题的方式进行分析。从这个练习中,你又有什么收获?
除了回答问题,我们还能从思考题中看到什么呢?哪些作者提出的问题经过这四十多年已经被很好的解决了?哪些问题目前仍然继续存在呢?哪些问题在良好管理的团队里已经不再是问题,而在管理不善的团队中仍然存在呢?
本章评注:
在软件维护的过程中被阅读得最多的代码,往往并非是最好的代码。也许正因为如此,这部分代码才最需要维护。对于根本区分不出代码优劣的那些用户来说,阅读程序的确不会有什么帮助。25年来,这些问题始终没有改变。
但是,开发人员把他们的工作提交给别人审阅,或者希望通过审阅他人的工作来提高水平时,为什么会如此之难呢?令人奇怪的是,高明的程序员善于通过排演和审查过程来发现有价值的东西,而那些自以为是的人却不是这样。正因为如此,和司空见惯的情况一样,高手越来越出色,差劲的越差。
45年之后,情况依旧。
第二章 优秀程序的要素
那些叫嚣着要追求效率的管理者,正是那些在得知修改代码的沉重代价后,为此而伤透脑筋的人。相反,那些过于强调程序的通用性和易于修改性的主管们,在发现自己的程序运行起来又慢又费空间时,往往又会变得怨天尤人。对于这些问题,我们必须保持一种成熟的心态——要知道,无论是心理学还是魔法,都无法帮助我们同时实现这两个相互矛盾的目标。通常我们必须在二者之间做取舍。
在温伯格先生写作本书的45年前,效率主要指程序在计算机中的运行效率,在硬件性能已经翻天覆地的今天,把“效率”这个词理解为软件的开发效率,这段话同样成立。
作为一个好程序,必须具备哪些要素呢?我们必须考察到不同程序各自的优点,同时还要兼顾其所在的环境。其中一些重要的因素有:
1.该程序是否符合功能要求?或置更确切地说,它在多大程度上满足功能要求?
2.该程序的开发是否按照计划完成?根据一些特定的方法,我们能够预测出的项目计划可能的偏差幅度会有多大?
3.当条件改变时,该程序是否可能修改?修改的成本有多大?
4.程序的效率如何?这里的效率是指什么?为了补偿某一个方面的低效率,我们是否会牺牲另一方面的高效率?
思考题:
请主管回答:
1.你根据什么标准来确定应该奖励哪个程序员?在你的标准中,是否存在互相矛盾的现象(比如,强调程序的效率,同时又要求程序具有通用性)?你会很明确地告诉程序员,自己希望在他们的程序中找到什么吗?或者说,你是否只是告诉他们,你希望程序很快、很小、整洁、易于修改、错误很少,并且能在一周内完成?
3.在你的公司中,制定开发进度表的重要程度如何?你是否认为“失之毫厘、谬以千里”?或者你是否认为,在奖励程序员时应该更加看重稳定性,而不是偶然的一次歪打正着?即使一个计划不可靠,只要它是完成进度的唯一希望(尽管可能根本无法完成该程序),程序员还是会采用它——你知道这是为什么吗?
请程序员回答
1,在开始进行某个项目时,你的脑子里是否已经有了一些明确的准则?在确立这些准则时,你根据的是不是自己对于重要性的认识?或者,是依照上级主管的看法?在项目的进行过程中,这些准则有无更改?或者,你是否有某种办法,来确保其不被动摇?
2.在编写程序时,你曾经有多少次想到过它在未来可能被别人修改?反过来,在修改别人的程序时,你又曾经咒骂过几回?
3.你是否曾经因为追求"性能"而延误了工作进度?反过来,是否曾经因为要在规定时间完成,而没有做到尽善尽美?
第三章 如何研究程序设计
最优秀的程序员同时也是那些最善于自省的。如果他们发现做错了什么,他们会对导致这个结果的思维过程(或物理过程)进行检讨,然后,他们会采取一些相应的措施,对这个过程进行调整。这种被称为“根源分析”的方法,正是人们希望从我这里获得的,同时也是我希望让更多企业掌握的——然而不幸的是,这种方法还没有得到很多人的青睐。更多的人仍然喜欢使用“过失追究分析”的方法,这种方法的效果恰恰相反,它会诱导人们把引发问题的根源隐藏起来。
管理心理学中的一条基本原则:关注下属工作的主管,将会取得更好的成绩。
许多主管都希望他们手下的程序员像一个个代码模块似的工作,那些曾经做过程序员的主管们更是如此。这些主管认为,每个部下犹如一个小黑盒,只要输入要求,工作结果就会源源不断地输出;根本无需任何观察,更不用说相互之间的交流沟通了。很多负责软件开发的主管,就是不愿意与下属并肩工作——这里最主要的原因就是,他们从未接受过任何有关的培训,以至于他们根本不了解具体工作应该如何着手。
第二篇 作为社会行为的程序开发
本篇主要从社会行为角度对程序开发进行研究,温伯格先生把程序员集体分成三种类型:程序开发组、程序开发团队和程序开发项目,并用三章的篇幅来依次讨论。
我理解,这里的程序开发组指的是一种自发形成的带有互助性质的最小型的松散组织,它有可能跟正式的组织结构重合(最理想状态,可以极大提高整个组织的开发效率和产品质量),但更多情况下会是一种非正式的结构。小组成员有可能是同事或者前同事、也可能是技术讨论组中正在进行类似的开发工作的网友,而后一种情况也有可能通过换工作转变成前一种情况。成员们乐于把工作和学习中碰到的问题拿出来互相讨论,互相帮助查找问题,取长补短,相互学习,共同进步。技术主管应该致力于把自己领导的团队变成一个这样的开发组。
程序开发团队则是一个正式的组织结构,程序员们被组织到一起来完成一项必须多人协作才能完成的任务。
程序开发项目是进一步扩大的组织,它由多个团队组成,一起完成一项复杂的、可分割的大型项目。随着组织的扩大,程序开发项目主管会遇到更多的组织管理问题,甚至一些社会性问题。
第四章 程序开发组
为提高开发的效率与质量,程序员需要避免唯我独尊式的心理,克服认知失调。温伯格先生提出了“无私式程序开发”。
冯·诺伊曼很早就意识到,他在检查自己工作方面,确实能力不够,他也许是能够认识到这一点的第一位程序员。那些与他相识的人们回忆说,冯·诺伊曼总是跟别人讲自己是多么蹩脚的程序员,并且不厌其烦地请别人阅读他的程序,期望发现其中的错误与纰漏之处。然而在今天人们的心目中,冯·诺伊曼一定是位无与伦比的计算天才——他浑身上下每个毛孔都应该是完美无缺的。当然,冯·诺伊曼的天才丝毫不容怀疑。然而他对自己作为一个人所具有的缺陷非常清楚,他的这种自知之明,也使他远远超过当今的一般程序员。
关于团队集体在软件开发过程中的价值,还有个别人仍然没有认识到。或者也许他们确实认识到了,但是受制于其对个人职位的患得患失,他们的做法总是南辕北辙。现在对软件开发主管们的考评,很大程度上仍然是根据其已有的成果多少,而不是看其是否有能力建立能够创造出更多成果的团队,或是看他们的成果质量。在这样的压力下,主管们就会极尽其能事,编造种种相互矛盾的甜言蜜语去哄骗其属下,以期得到更多成果——当然,这些成果大多是短期的。他们的一些下属也可能领悟出这个游戏的原理,于是也会效仿这种伎俩,去欺骗他们的下属······,这样一直下去,直到他们也成为这样的主管。这种主管根本不屑于去建立团队,也开发不出什么高质量的成果,而只会再带出更多像他一样的下属——有朝一日这些人又将成为下一代被这样误导的主管。
第五章 程序开发团队
无论具体情况如何,程序开发团队的规模和组成似乎都符合这样一条基本的规律——如果希望通过最小的代价获得最佳的开发效果,你必须找到尽可能出色的程序员,并且给他们以尽可能长的时间,这样你需要的程序员数量也将最少。反之,如果你希望工作能尽可能快地完成,或者雇用尽量少的经验丰富的程序员,那么开发成本与不确定性都会随之增加。
在程序开发的过程中,开发团队中各成员的地位,通常在很大程度上取决于其他人对其个人能力的了解程度。如果程序能够(在团队中自由)流通,供程序员们相互评判、指正,那么“精英们”就能够更快地脱颖而出。
为了实现在集体目标上真正的意见一致,最好的办法莫过于让开发组自己来确定其目标。首先,在目标制定时广泛参与,可以确保目标能够被大家充分理解。另外,这个过程使集体中的每个成员可以有机会对共同的目标做出公开的承诺,而——也许是因为认知失调的作用——这种公开的承诺已被证明可以提高目标的可接受性。这种参与和其他因素不相干,但是参与本身却似乎是一项重要的因素,它能够决定各个成员是否真的接受了开发团队的任务目标,并提高开发效率。
而最大的危险则来自于主管,由于他们都是经过程序开发中的层层选拔才得以出头的,所以这些人总是希望在手下成员看到问题之前,就已经把每一个细枝末节都详细地定义好了。再没有其他做法能够更挫伤成员的积极性了,它只能使成员觉得自己不过是“编码器”而已。
就社会科学家对“领导能力”一词的使用而言,其含义应该是“对他人的影响能力”。程序员一般会更加注重创造性的工作及专业能力,在他们所从事的工作范围内,他们会对些被自己认定为很出色的人更加器重。这样,与那些世界级的口若悬河的推销商们相比,作为一名语调温和的程序开发奇才,将可以更加轻松地对程序员们进行领导(或影响)。当一名根本没有编过程序的领导者被指定负责某个开发团队时,除非该领导者明确地或者含蓄地承认自己在技术问题上的能力欠缺,否则注定会有麻烦发生。即便是那些曾经当过程序员的人,只要他后来有相当长的时间脱离了这个行当,如果他依然企图去与团队中的其他成员在程序开发才能方面一比高低,那么情况简直就糟糕透顶了。对于那些公开承认自己在程序开发方面经验欠缺的人,他的团队成员还有可能会尊重他,但是如果有人企图掩盖自己在这些方面的无知,那么等到他迟早露馅的时候,就会招致程序员们的无情嘲弄。
目光短浅、难以依赖的团队领导者可能会认为博得管理层欢心的最好方法,就是无论他们要求什么都满口答应。但是最后,管理层需要的不只是诺言,而更重要的是恪守诺言,只有在团队的领导者有能力使整个团队都接受这个诺言,并且以此作为集体的目标,诺言才有可能兑现。
团队的领导者需要学习的东西包括:
1、无论主管们怎样地强调诺言,他们真正关心的只是结果。
2、如果希望得到的结果与在整个团队的参与下所确定的工作目标一致,那么这一目标就会非常容易地实现。
领导能力方面的一个悖论非常简单:只有随时准备下台的领导者,才有可能获得成功。
将影响到一个团队的生命期及其绩效的因素包括:
1.各成员的特长与不足。
2.目标设定的方式。
3.待开发的程序的结构。
4.由外界强加的领导管理结构。
5.某些成员的性别,以及其他成员对待这种性别的态度。
6.团队与其周围环境中其他部分之间的沟通联系。
7.团队领导人在技术方面的能力与欠缺。
第六章 程序开发项目
如果项目主管希望稳定地推进自己的项目,他就必须严格遵守这样一条简单的格言:
如果某个程序员是不可或缺的,那么还是越快请他走人越好。
关于绩效评价,温伯格先生举了一个逐层汇报系统的例子。
有一个众所周知的心理学原理:如果要使学习的速度最快,必须向主体及时地反馈其表现之好或之坏到了什么地步。但是也许不为人所知的一点是如果人们感到他们的绩效正在受人考评,同时又不能充分了解别人到底如何评价自己的工作,那么他们就会通过不断变化的方法来试探这个评价系统。在像这样的报告系统之中,如果在提供了输人数据之后,处于底层的人们没法获得相应的评价反馈,那么他们就会随心所欲地改变自己输人的数据,然后观察可能产生的不同效果——以期得到一些反馈,哪怕评价的结果很不理想。
第三篇 作为个人行为的程序开发
在探讨了程序开发中人类作为主体的共性问题之后,本篇开始讨论具体程序员的个体偏差。我感觉这部分没有前面两篇精彩,尤其是与性格理论相关部分,温伯格先生在评注中也表示,如果要在25年后重写这本书的话,这一部分将是改动最多的。
在谈到业余程序员与专业程序员时,温伯格先生说:
如果希望确定一名程序员的工作是否出色,我们就必须看看,他是不是按照恰当的级别来处理这个问题。有些人可以凭借其才气与个性,成为一名出色的业余程序员,但是从专业程序员的标准来看,这种才气与个性往往正是极不合适的。重要的是根据手头待解决的问题来调整自己工作方式的能力,而一旦缺乏这种能力,任何人都绝对不适合做一名专业程序员。
程序员工作绩效的差异,在很大程度上取决于其对完成任务目标的不同理解。
除了智力以外,程序开发的成功(或者失败)还取决于其他的很多因素。我确实曾经发现,有些人貌似驽钝,却可以写出高质量的、很有用的代码;而另外一些人虽然看起来更显聪颖,却从没写出过任何有用的代码。简而言之,今天的我依然坚持自己经过了25年时间考验的立场:“·····较之智力因素,人格因素、工作习惯及培训等方面的因素要与此更为相关。这些因素与智力因素不同,它们都可以通过后天经验发生改变。因此,选拔程序员的问题就转化成为培养程序员的问题。"
我所谓的“培养程序员”,并不是强行要求他们按照某种“最佳”模式进行思考。我在自己的博士学位论文中曾清楚地指出问题求解的模式是因人而异的。所以,如果有什么力量强制某个程序员按照另一个人的模式进行思考,那么就必将削弱该程序员解决问题的能力。因此,最大的挑战并不在于创造性思维本身,而是创造性的交流,用可以为(各有其独特思维方式的)其他人所接受的方式重新表述我们自己的思想。
对照自己前些日子的工作,创造性交流是我目前十分欠缺的。
主管们所犯的一个错误就是,他们总是假设工作绩效差的原因是由于缺乏积极性。于是,他们会企图借助一点“外部驱动力”来弥补“内在驱动力”的不足。而在这种时候,其实程序员所承担的外部压力往往已经够大了,而并非不够。
关于积极性,最广为人知、也最广为人接受的一项研究成果就是:如果适当地增加“驱动力”,那么在开始阶段确实可以提高工作绩效;但是一旦超过一定的极限之后,继续增加这种“驱动力”只会很快地令工作绩效降为0。在复杂的任务中,更容易看到这种工作绩效急速下降的现象,这正是它对程序开发如此重要的原因所在。比方说,过于努力地去查找错误,与根本不去查找同样坏,至还要更坏。实际上,往往要等到程序员已经决定放弃从而不再承受压力之后,许多程序错误才能被排除掉。给程序员施加高压,以期他们能够很快地排除某个程序错误,这种做法已经被证明是最差的策略——尽管截至目前,这仍然是最常采用的策略。
为了激励程序员,就可以授予他们金钱之处的奖赏——比如说,对他的工作质量给予更多地关心,或者让他负责一点规划工作。需要提醒你的是:这并不只是要为公司节省经费,而是为了更有效地激励他们。
也许正是由于管理人员反复不断地催促尽快“完成”任务,所以经常出现的情况就是:一旦程序被认为是“可以工作的”,程序员马上就宣告其大功告成——其实这往往是一种误解。但是作为程序员,只要希望学习,那么你就必须一边顶住来自管理层的压力,一边花时间对自己的成功进行总结。而对于管理人员来说,一个好的做法就是:每当程序员宣称自己的项目已经“大功告成”时,给他一天的时间放松一下——这并不是一种奖赏,而是为了让程序员加深对该项目的理解。
第四篇 程序开发工具
本篇中温伯格先生花了很多篇幅讨论语言问题。我对此不感兴趣,因此略过。
第五篇结语
结语的最后一段我很喜欢,摘录于此:
我们正站在一个新时代的边缘,正是由于蕴藏于计算机之中、迟早要发生的革命,这个时代才有可能到来。站在这个边缘,我们有两个可以选择的力向——迈人自由的黄金时代,抑或是倒退回专制的黑暗年代——无论你如何选择,这个世界中任何已知的事物都将被人类征服。也许任何个人的努力对最终的结果都不会有什么影响,但是我们绝对不应该放弃尝试,因为否则其后果必然是回到专制。这本书就是我反抗专制、反抗人奴役人、反抗被自己的无知所奴役的一次努力。但愿专制的力量不会利用这本书,但是毫无疑问,专制的力量确实会借鉴这本书。既然在这方面的希望破灭了,那么我只能希冀,处于杠杆另一端的正义力量能够从本书中获得更大的帮助。