我们毕生的使命,就是要造就另一个人-《程序开发心理学》读后感

  PS:大师的书永远那么富有哲理,能够从一个方面影响到你对整个人生的看法和态度,也能非常有效并且从根本上改变你自己。而我,除了持续下去,不断加强,还有什么好说的呢?
  
  序言
    读者的责任是根据自己的经历和需要,对每个观点进行判断。而不是把书中的所言所想奉若神明。书只是供给思考的食物,而不是个人思考的替代品。
    
    老师、朋友和学生——每个人都兼具这三种身份,我也希望每个人都能这样看待我,把我作为他们的良师益友兼学生。
  
  
  第1篇 作为人类行为的程序开发
  
  第1章 阅读程序
    没有人会真的相信管理员能够阅读程序。他们为什么要这么做呢?要知道,即使是写程序的程序员,也从来不读程序。这样的言论只是想吸引那些希望摆脱受制于程序员的处境的管理人员为此花钱。
    程序开发是一种写作形式,与其他写作形式一样。要学习写作,一种方式就是动手去写,但是与所有其他写作形式一样,为了学习写作还需要进行阅读。
    我们首先需要一种阅读程序的方法,与小说不同,阅读程序的最好方法并不总是从头读到尾。一个程序最好的部分是不确定的,实际上,我们可以用程序的所有初始片段构成一个概念上的框架,并以此为基础进行阅读。(也就是说,在阅读每段代码的过程中,我们经常问自己这样一个问题:“这段代码在这里有什么作用?”)
  
    计算机的局限性
    将代码分段的一个原因是,在解决问题时,现实中运行程序的计算机,总是会在某些方面比理想的计算机有所局限。
    计算机在计算时使用的并不是实数,而是有理数的一个有限子集。然而,程序员却很容易忘记这是硬件的局限,而把这当作无法改变的事实。
    从程序员的角度看,我们发现有很多程序开发工作,都是致力于克服那些我们可能遇到的硬件配置的不尽完美之处。
  
    语言的局限性
    程序开发语言更接近于程序开发中人所发挥的基础作用,因为没有人再用机器语言进行程序设计。
    从机器语言发展到高级语言的一个后果就是,用户不再能够利用硬件的某些功能。为了克服语言的局限性,代码和数据都必须改动。
    有理由认为,未来的语言将会让我们察觉到现在使用的语言的那些还未发现的限制。(这是一个心理学问题)
  
    程序员的局限性
    究竟有多少代码是由于程序员没有完全掌握他的计算机、他的语言、或他自己而写下的?这是一个与心理学更直接相关的问题。
    当然,除了没有掌握语言的全部用法之外,程序员还可能有其他的一些局限性——比如我们所说的“词汇局限”。例如,程序员也许不知道某些算法,或者不能同时兼顾一个问题的多个方面,从而不能避免某些重复性的工作。而这些问题都是属于程序开发心理学的范畴。
  
    历史
    我们常常发现程序中的内容可以用上述的某一种局限性来解释,但是它们之所以出现,实际上是由于程序的开发历史造成的。
  
    规范
    世界上所有代码中,只有很少一部分与我们试图解决的问题有关。从整体上考虑,这一看法与实际情况非常符合——虽然在几乎所有程序中,总是会有一些代码真正去实现程序预订的功能。然而,即使我们能够成功地将这些程序的核心代码剥离出来,我们也不应该错误地认为,可以将这些核心代码作为规范,而让某些系统应付其他的局限。在所知不多的情况下,很难确定程序员的意图;如果在制定规范时,对计算机能做什么不甚了解,那么根据此规范开发出高效的代码也是很困难的。即使抛开这些显而易见的困难,在大多数情况下我们也会面对这样一个事实:我们常常只有在很快地动手编程以后,才能弄明白自己到底想做什么。
    规范会与程序和程序员一起发展。编写程序是一个学习的过程——不论对程序员,还是对委托开发程序的人。而且,这种学习是在特定的计算机型号、特定的程序设计语言、特定的程序员或开发团队、特定的工作环境,以及特定的历史事件等背景下展开的,这些北京不仅决定了代码的形式,而且决定了代码的功能。
    从某种意义上讲,我们研究人们编写程序的过程,最重要的原因并不是为了提高程序的效率、使程序更加紧凑、更加便宜或更易于理解。相反,这些研究最重要的收获是有望从程序中得到我们想要的东西——而不是那些我们可以设法通过摸索式的、笨拙的方式得到的东西。
  
    小结
    程序的开发方式受许多因素的影响。然而由于我们通常只是从外部考察代码,而不是阅读代码本身,所以总是无法意识到这些因素的多样性。如果我们真的阅读了代码,就会发现其中有些是由于计算机的局限性编写的,有些是由于语言的局限性编写的,还有些是由于程序员的局限性、历史的偶然性或规范等原因而编写的——不论是重要代码还是非重要代码。但是不管是由于什么原因使得一段特定的代码进入到最终产品中,这个原因都有其心理学的一面——这使得我们相信,将程序开发作为一种人的行为来研究,会使我们得到丰硕的、甚至出人意料的结果。 
  
    评注
    在软件维护期间被阅读得最多的代码,通常并非是最好的代码。也许正因为如此,这些代码才需要维护。如果阅读程序的人不知道什么代码好、什么样的不好。那么阅读代码就不会有什么帮助。。
    开发人员为什么那么不愿意让别人来审查他的工作,或者通过审查别人的工作来提高自己的技能呢?令人奇怪的是,出色的程序员善于通过演练和审查过程来发现有价值的东西,而那些自以为聪明的人不这样做。所以,毫不意外, 出色的程序员越来越出色,差劲的却越来越差。 
  
  第2章 优秀程序的要素
    程序开发不只是一种人类的行为,它还是一种复杂的人类的行为。无法以绝对的标准来衡量程序的好坏。
    因此,我们不是单纯地就程序本身进行比较,而是把它们放在开发它们的背景(整体背景)下进行比较。如果坦诚地看待这一背景,那么我们就不会试图找出最好的程序,也很少会去找好的程序,而总是会去寻找那个满足特定需求的程序。
  
    技术规范
    在程序面对的所有要求中,最基本也是最重要的一个就是要求它必须正确。也就是说,对于任何可能的输入,它都应该给出正确的输出。
    如果程序不能用,那么衡量它的效率、适应性或开发版本就毫无意义。不管怎样,我们必须现实一些,承认我们也许从未开发过任何完美的程序。所有真正大型和重要的程序,都“至少有一个错误”。因此,程序满足的技术规范(“能用”)的程度不尽相同,评估程序时,必须考虑到其不完美的方面。
  
    进度计划
    即使不考虑技术要求的问题,效率问题仍然不是最重要的。在程序开发过程中,符合开发的进度计划是一个不断出现的问题,延迟交付的程序常常会失去价值。至少,我们必须权衡一下,用更长时间开发出更有效率的程序所带来的好处,是否能够弥补推迟交付程序所带来的损失。
    困扰人们的并不是预先估计的平均开发时间,而是实际开发时间的巨大波动。大多数人宁愿每天早晨都花10分钟等公交车,也不愿意在其中4天等待1分钟,而另外一天等待26分钟。尽管后一种方案平均时间只有6分钟,但是这不能弥补由于某次无法预测的长时间等待所造成的混乱。
    如果程序开发中也存在这样的现象,那么在对某种程序开发实践的效果进行研究时,就应该衡量其对于开发时间波动性的影响——而不是像现在的大多数研究那样,只考虑平均时间。
  
    适应性
    我们不能避开运行效率和适应性这两个因素哪个相对更重要这一问题,事实将会证明,先解决程序适应性的问题将会更有利。
    适应性不是没有代价的。一个系统对某个特定环境适应得越好,对新环境的适应性就越差。
  
    效率
    衡量程序真正效率的任务,并不像看起来那样简单。
    进行效率正在成为计算中不甚清晰的问题。无论通过什么标准衡量,测试效率标准的不平衡都是存在的,而且会越来越严重。因此以后我们将听到关于效率的言论会越来越少,而关于有效性的言论会越来越多。
  
    小结
    回答什么样的程序才是好程序这一问题并不容易,而且这甚至都不是一个正确的问题。每个程序都必须基于其自己的优点和相对于它所处的环境来考虑。一些要考虑的重要因素包括:
    1)程序是否满足技术要求?或者说,它在多大程度上满足技术要求?
    2)程序是否按计划完成?通过一些特定的方法,我们预期的完成时间,会有多大偏差?
    3)在条件出现变化时,是否能对程序进行修改?修改的成本会有多大?
    4)程序的效率如何?这里效率是指什么?我们是否为了获得某一方的高效,而使得另一面出现低效?
    今后,我们都应该避免使用“优秀程序”或“优秀程序员”这样的概念,不能把它们当作已得到广泛认同、可以得到广泛认同或应该得到广泛认同的概念而加以使用。
  
    评注
    判断代码最重要的因素就是经济因素,如果写程序的目的就是为了赚钱,那么其变现程序赚钱最多的人,当然就是最好的程序员——他最善于理解用户的需求。
    质量,就是对某个(某些)人的价值。
    计算机运行时间和人工时间之间的权衡已经改变了。而效率在某些(但不是全部)工作中仍然很重要。
    似乎人类行为存在着前后一致性,,而人类在技术方面却不是这样。
  
  第3章 研究程序开发的方法
    人类的知识必然是不完整的。我们无法预先确定哪些是我们能够掌握的,哪些是本质上不可知的。但是有一点可以确定:如果我们不尝试去查明事情的真相,那么我们将永远不可能成功。
  
    自省
    自省是研究人类行为最基础的基石。我们对自己思维状态的了解,要远远超过对与之相伴的大脑情况的了解。
    我们每天都会出错,如果我们只是抱怨它,而不进行自省,我们只会继续出错,直到最后成为错误的奴隶。
    我们虽然应该从自省开始,但是我们不能只满足于自省,否则我们就是在从事魔法或者宗教行动,而不是现实的生活。
    仅仅根据一两个自省的例子,我们很难证明定律的存在。为了证明一条定律,我们必须研究其原理,以便对其适用范围做一界定,这是因为所有的定律都会受到这种限制,实际上,这些了解限制比了解定律本身更为重要,而且如果只有通过调查研究大量的案例,才能够明确这些限制。
    因此,如果不进行自省,调查研究就不会有任何成果,而如果不进行调查研究,自省在应用中的价值也很难令人信服。
  
    观察
    自省之后的下一步,就是观察人们到底在做什么,而不是他们认为自己在做什么。
    观察时需要注意的问题:
    1)观察可以告诉我们人们在做什么,而不一定能告诉我们他们能做什么。
    2)决定我们观察到的是什么。(在将一种环境下观察结论带到另一种环境时,我们必须非常谨慎,因为各个环境之间总会有这样那样的差异)
    3)观察者对被观察对象的干扰(测不准原理,也叫霍索恩效应)
  
    实验
    为了减少观察产生的大量数据所造成的成本,一种方法就是设计一些实验。通过使用这些实验,我们可以从较少的数据中获得与我们感兴趣的行为相关的更多信息。
    实验所具有的危险:
    1)可能实验本身设计得过于细致,以至于漏掉了我们最感兴趣的数据。(实验的特殊条件也许对被观察对象的行为有太多的限制,以至于我们再也无法观察到在正常情况下所观察到的现象)
    2)实验本身需要大量的研究费用,因此在选择被观察对象的时候,往往会无意间引用一些限制。把这些限制带入到调查研究中,混淆两种的区别,并把它们当作“科学的证据”(实际上,这样的应用结果是非常有限的)
    3)程序开发和很多行为实际上是社会群体行为,而不是个人行为。人们大部分的时间是在与他人协作,而不是独自工作。所以研究对象的挑选实际上是破坏了原有的群体团队行为。这样得到的实验结果是有很大问题的,甚至是无效的
    由于忽视社会的影响,也使得所有个体性的研究受到质疑,因为这些研究都强行将个体从平常的工作环境中脱离出来。
  
    心理学测量标准
    毫无疑问,在所有科学家中,心理学家是最爱管闲事的。然而,在所有的科学之中,心理学可能测量的事物似乎是最多的——多得让任何理性的人无法理解。
    当我们研究人类行为时,我们不能享受如物理学家简化模型的好处。我们并不是用“可以测量什么”来定义这门学科,而是用“我们想知道什么”——也就是人类行为——来定义。
    所以,我们就必须在许许多多可以测量的标准中探索,以期通过其中的一个或几个标准来使我们得到一些启发,再将这些启发带回到我们最初的问题。在这个探索的过程中,任何蛛丝马迹都不能放过,任何建议都不能因为看起来似乎荒谬而被摒弃。在进行人类行为的研究中,我们要怀有谦卑之心。
    严肃的工作者不能提前排除任何因素,因为那样做可能会使结果出现偏差。
  
    利用行为科学的数据
    不要沉迷于那些过于具体的理论,因为我们最终会发现这些理论所基于的前提条件,不满足你当前的情况。
    所谓信仰,就是相信那些毫无根据的事物;所谓神话,就是将其他人当作神来信仰。
  
    小结
    在准备程序开发心理学方面的研究时,我们应该特别地注意避免落入常见的陷阱。其中主要的问题包括:
    1)未证明其有效性,就贸然进行自省
    2)在过于狭窄的基础上进行观察
    3)观察了错误的指标,或未能观察正确的指标
    4)干扰了被观察对象
    5)生成数据过多,但有效信息却不足
    6)对实验的限制太多
    7)只选择实习生充当被观察对象
    8)没有研究群体效应和群体行为
    9)只测量易于测量的指标
    10)使用未经验证的精度
    11)将其他领域的研究成果,应用于并不适合的环境
    对于任何新兴的领域来说,最大的错误也许是过于谨慎。虽然我们会尽力保证观察的正确性,但是即使实验中出现错误,也总比完全不做试验要好得多。
  
    评注
    最优秀的程序员,往往也是最善于自省的。如果他们做错了什么,他们会对造成这个错误的思维过程(或物理过程)进行检讨;然后,他们会采取行动来改变这一过程。这也叫作根源分析(root-cause analysis)方法。
    关于人类行为的实验成本很高,而且难度极大。大部分的实验都是在大学的环境中进行的,虽然这些实验很吸引人,但是它们对实际的程序开发实践的影响却非常缓慢和微小。即使这些工作非常重要,并且应该得到承认,但研究人员还是需要将其成果转换为可以传达的信息片段。
    个体之间的差异性,仍然是项目可预测性的天敌。
  
  
  
  第2篇 作为社会行为的程序开发
  
  第4章 程序开发组
    正式与非正式的组织机构
    人与人之间的交流绝不是很狭窄,很直截了当的,也很少像组织结构图中显示的方向进行。人们曾经犯下许多严重的错误,就是因为他们认为只有正式的结构,才是组织机构中唯一的结构。
    非正式组织机构与正式组织机构的相符程度,取决于项目的组织化程度。但是非正式的组织机构是任何时候都会慢慢形成的,也不会和正式组织机构完全一样。
    非正式的机制在任何情况下都是存在的,如果没有搞懂他们就做出改变,将十分危险,要避免扰乱那些本来运行良好的,并且很难用相似成本替代的系统(非组织结构)。
  
    物理环境和社会组织
    物理环境会影响我们工作的质量和数量。遵循如何将工作人员的工作场所安排在一起的设计准则,可以带来巨大好处。
  
    错误和自我主义
    对于常见的个体特征,有一种方法是从3个方面来衡量:
    1)依从的:喜欢与人合作并对人有所帮助
    2)进取的:希望获得金钱和荣誉
    3)离群的:只有独自待着才能保持创造力
    每个人都是这3种态度的综合体,只不过大多数人都偏向其中的一个性格特征
  
    物极必反,过于离群的程序员会遇到两大困难:
    1)人们并不阅读程序,因此对程序员的赞美并不能导致对他们所编写程序的仿效,而只会导致他们养成怪癖的编程风格
    2)计算机做出的程序员的程序是无可辩驳的,程序员不能像艺术家那样不理会那些令人不快的批评意见
  
    如果我们只是按照自己的意愿来行事,那么我们将会忽略我们的最明显的错误——这些错误其他人一眼就能看出来。
  
    无私的程序开发
    解决自我主义的办法并不是采取直接手段——因为那样只能导致对抗,而对抗正是我们力图消除的。相反,为了解决自我主义的问题,必须重构社会环境,然后通过这种方式,重新建立这一环境中程序员们的价值体系。
    克服自我主义并不是空想,实际上经过培训,一般的人也可以接受自身人性的特点——即他们不能像机器那样工作——重视这种特点,并与他人合作,以便这种特点保持在控制范围之内,以确保程序开发的成功。
    始终注意使程序保持清晰和易于理解,以便有人会阅读它。
  
    创建和维持程序开发环境
    维持这样的环境要比建立这样的环境要简单很多,因为要建立这样的环境,需要克服社会结构的“锁定”和"凝固"现象。如果某种局势下所建立的环境,有利于这种局势的保持,就会发生凝固现象。
  
    小结
    程序员工作的环境是多样而复杂的,充满了人与人之间的复杂交互,各种变数,以及易于使人误解的表象。为了了解这种环境,必须首先理解正式与非正式组织结构的区别,以及造成这种环境的许多因素,如周围的物理环境、个人的自我主义等。在一个正在运转的程序开发工厂中,这种环境的丰富性使它具有一种自我保持的特性,可以抵抗来自外界的强加的影响——尤其是那些在不理解正式与非正式结构之间区别的情况下,就强行执行的命令。在任何社会层面上,都存在这种自我保持现象,从本质上讲,不能简单地说这是好的还是坏的,它只是程序开发过程中的一个客观事实而已。
  
    评注
    主管们面对关于他们具体工作的信息已经够多了,但是坦率地讲,对于其工作而言,主管们仍然缺乏培训,或者是自我培训。
    如果你不希望别人检查你的代码的理由不是基于逻辑,那么你永远不会信服逻辑的观点而改变你的生活方式。
  
    也许主管们其实知道开放的程序开发团队的好处,但是出于对个人职位的考虑,他们总是采取相反的做法。对主管们的考评,现在仍然是主要通过最终成果的质量来决定。在这样的压力下,主管们会使用任何心口不一的沟通技巧,来哄骗他们的下属,以期在短期内达到效果。有些下属看明白了这一点,于是仿效着对他们的下属采取同样的手段,直到他们也成为这样的主管。这种主管不相信构建团队会有什么用,开发不出高质量的成果,却会让更多的下属成为和他一样被误导的主管。
  
  
  第5章 程序开发团队
    团队的组建
    程序开发团队应针对无法由一个人完成的工作需求来组建。这种需求不仅仅与待完成工作的技术要求相关,而且还与可以参与这项工作的人的能力以及完成工作分配的时间相关。为使工作切实可行,团队成员的能力和要求完成的时间——都有其最低要求。
    成员能力与开发进度之间存在互补关系,而开发进度与工作结构之间也存在重要关系。
    我们必须要在团队中补充额外的成员以防止可能出现的意外问题。
    在程序开发的过程中,一个团队成员的地位,通常在很大程度上取决于其他成员对他的能力的了解程度。
  
    设立和接受目标
    如果某个成员由于分配给他的任务而感到自卑,那么压抑这种感觉会令人吃惊地损害团队的工作。采用无私程序开发可以缓解这种情绪,因为每个人都感觉系统的大部分工作中自己都有份。然而,如果团队的工作开展太快,而对项目结构和工作分配方面的共识尚未达成,那么问题迟早会以某种方式出现。
    如果一名与多名成员的目标与团队的目标不一致,那么就会影响团队的整体表现。这种影响不仅来自与该成员自己的工作,而且还来自集体内部的其他成员绩效的下降,因为他们总是会意识到团队内的分歧,或者某个成员的冷漠态度。
    由于成员意见不统一而造成的代价,要过很久才能体现出来;但是一旦这个时间来临,就会付出这个代价,付出这个巨大的代价。
    为了对团队目标达成真正的一致,最好的办法就是让团队自己来设定目标,这样有2个好处:
    1)团队成员参与目标的设定,可以确保目标能被他们充分理解
    2)可以堂团队的每个成员对团队目标进行公开承诺,而这种公开承诺——可能是由于认知失调的原因——以证明有助于提高目标的接受程度
    如果程序开发团队不是要开发一个特定的系统,而是要为其他开发组提供某种服务或支持,那么目标不明确就会造成更严重的问题。
    当目标不一致的矛盾暴露出来以后,特别是双方都以自己的方式投入了相当多的精力——必然会导致严重的冲突。同时,如果不同成员对团队目标的理解不一致,而且各种相互矛盾的想法很难区分开来,那么消除这种分歧常常会非常紧迫。如果团队成员之间持续出现这种争论,那么这个信号可以确定,团队中存在更深层次的矛盾——也许是为了争夺领导权——所以因为不能因为这些争论很琐碎,就对他们置之不理。
  
    团队领导及其领导地位
    对于希特勒,应该说人们对他只是“盲从”而不是“领导”,因为是有这样一种类型的领导,只不过是许多人根深蒂固的个人崇拜而已。而一般情况下我们都不需要这样的领导,而这也是常常让人无法忍受的。
    影响团队成员满意度的4个因素:
    1)物质奖励和机会
    2)工作本身的挑战性和趣味性
    3)所属的更大组织中的整体条件,如员工福利、工作环境、该团队在同类团队中的地位等
    4)主管和领导的能力(这个其实是最普遍的问题)
  
    领导地位:影响他人的能力
  
    在一个民主的团队中,领导地位(或影响力)并不仅限于个人,而是会随着需要符合某个成员的能力或想法,从团队中当前的成员传递给那位成员。民众团队正常运行的重要条件,并不在于每个成员都有同等的领导地位,而在于领导地位的确定基于的是团队的内部的真实生活,而不是基于外部施加的影响。一个民主的团队,总是能极好地适应环境的变迁,所以在面对难以预料的困难时,能够成为一个可信赖的开发团队。
    在现实中,民主化团队团队的存在有以下3个困难:
    1)团队中也许不存在这样的人选
    2)个性因素也许会妨碍对当前最佳人选的选举
    3)从外部指定的领导来到团队中,总是会使团队偏离民主的方向
    指定的领导是团队和外部力量之间的信息载体,而外部力量总是希望影响团队所追求的目标
  
    团队领导必须知道:
    1)主管们,无论怎么强调承诺,真正想要的是结果
    2)如果整个团队都追求他们参与设定的目标,那么取得结果将容易得多
  
    关于领导力的一个悖论:只有准备好辞职的领导,才能获得真正成功的机会。
  
    危机中的团队
    团队工作可分为两类:为了完成团队目标而做的工作(面向任务),和为了团队在面对危机时维持有效地运转而做的工作(面向维持)
    民主地组织起来的团队在外人看来也许显得非常冷漠和不友好,而独裁式团队的成员对新加入的人极为热情和友好。而当有团队成员离开时,民主性团队受到的影响要比独裁式团队小得多。
    在为团队挑选程序员时,我们应该尽量选择那些可以很好地适应这种自我调节式结构的人,而这种结构既不会太自主,也不会太被动。在培训程序员时,我们应该尽量教会他们如何听从有才能的领导的指挥,教会他们在自己是团队中最有资格的候选人时,如何抓住机会,承担领导责任。在团队的生命周期内,如果我们是局外人,就应该尽量不要干涉这些民主的过程。虽然从表面上看,这些过程会对团队及其成员造成一定损伤;但从长远来看,这将使得团队以最有效的方式运转。
  
    小结
    在许多程序开发环境中,最基本的工作单位是团队,而不是个人。影响团队生命周期和效率的因素包括:
    1)个体长处和短处之间的差异
    2)设定目标的方式
    3)待开发程序的结构
    4)外界强加给团队的领导组织结构
    5)某几个成员的性别,以及其他成员对这种性别的态度
    6)团队与其所处环境的其余部分之间的沟通联系
    7)团队领导在技术上的才能或不足之处
  
    短期群体的行为既会受到团队成员的过去经验的影响,也会受到他们对未来一起工作的预期影响
  
    评注
    在任何情况下,程序开发团队的规模和组成都符合这样的基本规则——即为了以最少的成本开发出最好的程序,对于你能找到的最好的程序员,给予他们足够的时间,这样你需要的程序员人数也将最少。同时还需要注意一下3点:
    1)所谓最少的人数,绝不是指一名程序员
    2)“足够的时间”必须包括组建团队的时间。因此,如果选择一个有历史记录的现有团队,常常会带来很多好处
    3)在有真正关键的问题需要解决之前,就让团队先开始工作,这样常常会给你带来更多的好处
  
    防止危机的发生要比处理危机容易得多
  
  
  第6章 程序开发项目
    在改变中保持稳定
    大型组织一个最大的特点就是:它们经过很长时间仍然能够存活下来,而这段时间比任何一个成员呆在其中的时间都要长得多。任何人无论多么强大,也不能代表这个组织。
    在成员离开后团队仍继续存在,这是团队的一个最大的长处。团队的这种能力来自于成员间的交流,正是这种交流,使得在原来的成员离开时,团队的目标和成就得以传达给新来的成员并得以保留下来。
    但是,很多人尤其是主观认为项目的结构更像是一栋房子——拿走任何一根房梁,整个结构就会坍塌。他们对项目中的人(特别是所谓的“关键”人物)的态度,反映了他们这种静态的观点,这种观点常常会带来灾难性的后果。
    很多员工在被加薪以后会选择辞职,从心理学上他们这样做有2种理由:
    1)他们认为他们需要承担额外的责任
    2)他们认为上级想通过钱去替代他们真正想要的东西
  
    随着项目的进行,人们会由于不断成长而逐渐不满于其所承担的有限责任,或者——让我们实话实说 ——会由于认为工作难度低于他们的能力而感到厌倦。不是所有程序员都愿意接受更具挑战性的工作——有些人会因为压力增长太快而选择离开——但是,对于大多数程序员来说,如果不能在工作中运用自己逐渐积累的知识,他们很快就会心生不满。因此,为了使项目在很长的一段时间内保持稳定,项目主管必须让项目具有某种“程序员处理工厂”的作用——一端不停地补充新手实习生,而另一端则源源不断地培养出经验丰富地领导者,在这两段中间的人则随着流动的防线不断提高职位。
    同时,如果主管希望项目能够稳定地运行,就必须遵循这样一条格言:如果有哪位程序员是不可或缺的,那还是让他尽快走人的好。
  
    衡量绩效
    绩效的衡量在大型项目中会非常的困难,这种困难部分来源于需要考察的方面太多,以至于任何个人都无法对所有方面做出评判。由于项目进度是一个主观判断的问题,所以即使不考虑其他因素,对于一个特定程序达到的进度也会有不同的看法。如果只是比较并结合不同人对不同程序的看法,以形成对项目进度的某种概念。在这种汇总的过程中,存在大量可能造成心理伤害的地方。
    当团队组织复杂以后,会对项目失去控制:有些事情不可能是他们伪称的那样的,人们却愿意相信他们;另一方面,每一次向上提交项目进度报告,审阅人都会对报告进行一些平均化处理,他们处理的时间最长,但与此同时他们对项目的贡献却是最小的。导致最终底层报告和最上层完成的最终报告之间,并没有什么关系。实际上,底层报告也只是对进度的预测而已,所以在层层向上提交的过程中,对报告作任何修改都没有意义。
    如果输入的是垃圾信息,那么输出的也必然是垃圾信息。
    如果要使学习速度达到最快,学习者就必须得到关于他做得好坏程度的反馈。但是这里我们容易忽略一点,如果人们感觉到他们的绩效正在接受别人的评价,同时又没有足够的信息来判断自己做得有多好,那么他们就会尝试做出改变以试探这个评价体系。
  
    主管必须要学会的,应该是促使人们修正自己的工作方式或者提高工作效率,而不是促使他们隐瞒自己的工作。因此,主管们应该重视那些对工作进展提交了准确报告的人,否则,这种机构中的报告系统会随着时间的推移而变得越来越没有意义。
    其他人做出的判断,很容易会影响到我们对一些问题的具体看法,而随着做出判断的难度加大,这种影响的效果也会变得更加明显。
  
    项目结构
    如果程序开发项目想要战胜那些进度评估的过程中固有的心理陷阱,那么将工作的开展与进行评估相互隔开非常重要。而以层次结构组织起来的机构来说,最严重的缺陷也许就在于无法实现这种隔离。因为对工作开展施加控制的方向,与提交进度报告的方向相反。这样的系统往往会导致交流的机制在性能上逐渐退化。
    如果项目的管理层能够把对项目的运作,当时是为了使项目得以完成的组织形式、而不是为了其个人野心而去攀登的金字塔,那么上面的问题的大部分都可以得到解决。
  
    大型项目中共同的社会问题
    项目领导与底层程序员的距离太远,是大型项目中出现许多社会性问题的根源。
  
    小结
    人们在试图应付那些他们并不理解的问题,以及那些他们还不知道自己不理解的问题——这本身就是管理上的失败。
  
    评注
    一个人若能被金钱束缚住,那么他也会被更多的金钱所解放。
    团队合作,是项目成功的核心因素。
    项目中产生的大部分社会性问题都来源于缺乏自尊(尤其是对象征地位的需求而争夺),解决办法是建立一种能够激发而不是毁灭自尊的环境。
  
  
  
  第3篇 作为个人行为的程序开发
  
  第7章 程序开发任务的差异
    专业的与业余的程序开发
    专业与业余的最大的区别,就在于他们所编写的程序的最终用户。业余程序员编写的程序,其唯一的用户几乎总是他们自己,而专业程序员所编写的程序将会被其他人所使用。
    由于业余程序员就是自己程序的用户,所以他们可以自由选择,是在程序开发前进行构思还是在之后进行思考。而专业程序员需要面对这个残酷的世界——特别是自己的程序受到批评的时候,所以专业程序员需要考虑非常多的事情,而这些是不得不面对的。
    事实是:专业与业余之间用眼都存在一条无法逾越的鸿沟,业余者缺乏对专业领域复杂性的理解。
    面对问题,业余程序员学到的只是他的问题的经验;他所进行的任何程序开发方面的学习,对他而言即使不是为了装装样子,也是一庄令他们苦恼的麻烦事。相反,专业程序员则是在学习他的专业——程序开发——而通过编程所解决的问题,不过是在他们提高水平的过程中迈出的一小步而已。与此同时相关的一个结论就是,专业程序员绝不会像业余程序员那样,很认真地对待某个具体的问题。他以前遇到的错误,将来还会遇到很多。
  
    程序员想要做什么
    因为彼此不能认识到对方的复杂性,所以专业程序员与业余程序员之间有一种不对称的关系。
    程序与任何其他的人造物一样,在设计时设计者的脑海都有一个确定的生命期以及应用范围。
    每个程序都有一种适当的细致和复杂级别,这取决于它的具体用途。从某种意义上讲,如果付出的努力超出这种级别,要比低于这种级别更不专业。当然了,通常的情况是,程序员之所以不能根据手边待解决的问题来调整自己的行为,是因为他们根本不知道待解决的问题是什么。同样客观事件会由于项目目标的不同而对项目产生不同的影响。
    在对目标进行沟通时,存在着某种文献:目标居然可以改变人们的估计!
  
    程序开发工作的阶段
    对于专业程序员来说,要把技术规范转变成可交付使用的程序,这个过程需要各种不同的工作,而这些工作要求有各种类型的人才来完成。(系统设计工作要求一种纵观全局的能力,而调试阶段的工作则要求必须能够清晰地看到所有的细节;编码的工作往往需要将冗余的代码减少到最少,而文档化的工作则可能需要把简单的句子扩充为一段话)
    如果我们要确保在需要的时候总能找到合适的人选,我们就必须将程序员要做的工作进行合理、细致的分类,而不是笼统地称之为“程序开发”。
    一支团队所完成的工作,要远比其中任何一名成员更为出色——如果他们对自己的才能和缺点有自知之明的话。
  
    小结
    程序开发并不是一个始终如一的过程,专业程序员需要的工具与业余程序员并不相同,程序开发工作可以被划分为若干个阶段,而这种划分并不是非常清晰绝对的。而程序员们的工作就是对不同阶段做不同的事。
    我们只有更加关注细节,而不是像通常那样泛泛地讨论,才能够得出普遍有效的结论。也许我们会发现,“怎样才能成为优秀的程序员”本质上与“怎样才能培养出深厚的友谊”很像——它们都是人与人之间相互承认与鼓励的问题。
  
    评注
    无(现在已经对以前的专业与业余之间的问题达成了共识)
  
  
  第8章 个性因素
    从某种意义上讲,“个性”这个概念包括所有我们可以从人们身上发现的个体性差异。智力和教育性水平会影响到人的个性。它是一个人所有性格特点的综合——也就是对一个人的概括,从这个意义上讲,一个人的个性就是区别于他人的特点。
  
    炸弹狂人
    对于那些无所不知但是固执己见的“炸弹狂人”,与那些知之甚少毫无经验的人相比虽然个性相差很大,但是实际上造成的对程序项目的破坏的结果是一致的,某些角度来说甚至更糟。
  
    个性的改变
    关于个性与程序开发如果相互影响的研究中,可以将个性如下定义:
    所谓个性,就是一个人的所有特征的唯一性集合,这个集合决定了此人如何适应不断变化的环境,同时他的适应方式也会反过来改变这个集合。
    一个人的个性并不是固定不变的。不过,在个性中确定有些品质是经久不变的,所以尽管有时从表面看起来个性似乎有所变化,但是除非有特殊的原因,否则个性就不会改变。而实现确定个性变化的原因要比时候确定困难的多。即使是相同的个性改变,也可能是原子多种不同的原因——身体的、精神的,甚至完全来自外部。
    即使有些问题的根源不能这样容易地消除,做一些调整至少也能使问题得到缓解。而如果没有找出问题的真正根源,那么久无法采取有效的行动来对个性问题进行纠正或自我调整。我们如果只是根据一个人外在的表现来对他做出心理方面的判断,那么我们将永远不会成功。但是,如果我们把这些外在表现当作线索,并在采取行动之前继续深入了解情况——而这些情况只能从当事人那里得知——那么他最终采取的措施就非常有可能获得成功。
  
    个性中始终如一的部分
    既然个性“会在适应环境的过程中发生变化”,那么我们就可以将个性上的变化,用作一个人所处环境发生变化的信号。但是个性上的变化——虽然它们也许代表着极为严重的情况——并非如此频繁。长期来看,我们应该更加关注的是程序员个性中始终如一的、影响着他的工作的那些部分。
  
    关键的个性特征
    对于程序开发来说个性因素比治理因素更重要。
    一般来说,专业的程序要需要有以下特征:
    1)耐力:在高压力的环境中坚持一个多星期的能力
    2)灵活:由于技术的飞速发展,如果一个人多少有些不能适应快速的变化,那么他也不能胜任专业程序员的工作(干了大半天的劳动结果成为了垃圾而变得无法接受,情绪失控)
    3)整洁:尽量把自己手头的资料规整好
    4)谦虚:不懂得谦虚的人主动会有一个希腊戏剧式的命运:成功导致过分自信(骄傲自大),进而又导致因闭目塞听而自我毁灭
    5)批判:为了完成任务,有时候就必须绕过困难、跳过困难或者战胜困难,否则将完不成任何工作
    6)幽默:不能让计算机把自己变成了傻瓜
  
    个性测试
    从某种意义上讲,个性测试其实就是一种智力测试——一场与测试方法的设计者进行的智力竞赛。所以如果不在测试里作弊(尤其是面试),那这样的“智力”的确不适合做程序员工作...
  
    小结
    由于程序开发任务所固有的复杂性,所以程序员的个性——他的性情和身份——对其成功的影响之大,远远超过人们通常的估计。然而,个性测试并未成功地用于挑选出将来会成为优秀程序员的程序员。其失败的原因,一部分可以归结为测试本身的局限性,另一部分可以归结为我们对程序开发过程本身的理解不足,还有一部分可以归结为,我们对某种个性因素在程序开发过程的哪个部分中会起到什么作用这一问题的知识还很不够。
    不过,还是有证据显示,关键的个性因素可以被分离出来,并且与特定的程序开发任务联系在一起——至少从某些个性因素会使程序员不能很好地完成任务这个意义上讲是这样的。因此,无论是心理学研究者、程序开发主管还是程序员本人,只要对个性问题有所重视,就能从本质上有助于程序员工作绩效的提高。
  
    评注
    MBTI和Satir关于应对态度的理论,让我的关于人类行为领域的思考、培训以及咨询等多经历了一次革命。
  
  
  第9章 治理、或问题解决能力
    我们可以做一个合理的估计:程序员的平均智商甚至比大学研究生还要高,而且基本上程序员越成功,其平均智商也会越高。正因为如此,如果我们从治理水平对程序开发工作的影响(不论是什么样的影响)这一角度来考察程序开发,那么肯定会对其得到更好的理解。
  
    心理定势
    心理定势的两种影响:
    1)被观察对象会把不是单词的字符串当成单词,这是因为当他在很多单词中看到这个字符串时,他有一种把这个字符串堪称是单词的倾向
    2)如果被观察对象事先被告知列表中的单词都是与“兽类或鸟类”相关的,那么他就很可能会把“dack”看成“duck”。反之,如果他事先被告之这些单词是与“交通工具”有关的,那么他往往会把“dack”看成“dock”
    与心理定势概念相对的是距离,比如“daxk”就不会被误认为是“duck”,而“gucr”与“daxk”相比更加不会看成“daxk”,虽然二者都只与“duck”只相差2个字母。
    
    助记符号尤其容易引起程序阅读者的麻痹。助记符号之所以会使我们产生误会,有以下几个原因:
    1)它们容易让程序看起来是“合理的”,因为它们满足了我们通常都会有的,倾向于将无意义的东西看成有意义的心理定势。
    2)它们利用了我们倾向于相信名字,而不是名字所代表的含义这种定势。(符号“FIVE“代表的可能不是5而是4...)
    3)它们倾向于给出一些并不是最优“距离”的符号式样。(LEAD可以表示领先,也可以表示铅,如果在同一个程序里面代表不同的意思很容易混乱)
    4)由于我们的缩写有一定的规律,结果使得最佳距离被进一步缩小了,这可能也会造成歧义。(PEND可以表示一个处于挂起状态的记录,也可能是“P单元的末尾”的缩写)
  
    在程序中添加注释的目的,是为了让读者能够正确地理解相应的指令或者语句。如果注释所说明的代码本身有错误,那么由于注释所引起的心理定势,只能使得代码中的错误更难被发现。心理定势虽然有助于理解正确的代码,但是如果你正在调试程序,那么它就会把这项本来就十分棘手的工作搞得更加让人头疼。
  
    问题求解的一些维度
    心理定势会对那些我们肯定称之为问题求解的行为产生影响。在考虑问题求解这一问题之前,应该先考虑问题回避的问题。
    从理论上来看,那些使自己陷入问题的程序员,不管他们最终是否能够解决这个问题,都不如那些能够完全回避这个问题的程序员聪明。然而,理论上关于智力的思想,很少能够与我们对实际情况的理解相一致。所以从这一点上说,回避问题的行为虽然是最明智的行为,但是如果只是为了引起其缺乏训练的主管的注意,这种行为却又不是那么明智。
    一个问题之所以会很难,最常见的一个原因是我们忽视了某个因素。一旦我们自己发现或者是被告诉说这个因素很重要,再去找解决办法就会变得非常容易。如果我们向别人提出了一个问题,我们通常都会同时提供给他关于这个因素的提示,这样对于他来说,这个问题就已经解决了90%。于是,他会想不通为什么我们会觉得这个问题如此困难,而我们也很快会开始对自己感到诧异。
  
    在动手解决问题之前,不要先听任何的解释。这是因为,这些解释会很容易将倾听者引入到同样一条做出错误假设的老路上去,正式这些错误的假设组织了解释者自己找到那个错误。于是有人就感觉,问题求解的第一条法则就是:“千万不要做出任何假设”。但是这是完全错误的。如果我们希望在问题求解时获得成功,我们就必须进行一些假设。如果我们每次遇到的问题真的都是全新的问题,那么我们在问题求解方面的表现就不可能得到提高。因此,明智的做法并不是要抛弃所有的假设,而是应该根据具体的需求,能够充分灵活地利用各种假设。也就是说,为了明智地解决问题,我们不是要拥有什么万能的可以适用于所有问题的解决模式,而是拥有许多的解题模式,同时不会对其中任何一种模式有所偏爱,并愿意在需要时放弃它,转而采用另一种模式。
  
    智力最多只是一个统计上的概念。我们并不能根据其在某个特定问题上的表现,来断定一个人的智力水平,因为还有许多非智力的因素可以得出“正确的”解答,同时也有许多智力因素可能会得出“错误的”解答。
  
    程序开发的智力因素
    适应能力是所有类型的智力行为都必须的。
    在很大程度上,每一种问题求解技术都是因不同问题而异的,这只是因为某些人能够比别人更好地做某些事情。任何人只要足够聪明,都会在寻找解决问题的方法时,充分运用其最擅长的方面,同时回避自己最不擅长的方面。
    不同的工作环境,会偏好不同形式的智力行为;类似地,不同的程序开发阶段,也会给不同的程序员提供展露其才华的机会。当然,一个程序员不论是缺乏创造力还是缺乏选择能力,在设计程序时都将会遇到困难。
  
    智力测验
    智力测验只能衡量应对测验的能力。而程序开发并不是竞赛,它是一种多样化的行为,任何之给出一种能够评分的测验都无法充分地衡量所需要的智力。
    另一方面,他们只强调短期的——而不是长期的——记忆。它们也只能这样,因为要受到很多来自管理上的约束。在一项智商测验中,会要求接受测验的人记住一些毫无意义的单词,或者任意的序列。但是在“真实的生活”中,只有选择性的记忆——即忘记不重要的信息,同时长时间记住重要信息的能力——才有用。但是校园环境中却不是看重这种能力,于是我们的智商测验与在校的成绩之间的关系越来越密切——但是却离我们真正关心的东西越来越远。
  
    程序员的智力测验
    确实,程序员的智力分数与某些形式的培训之间有一定的相关性。(如IBM的PAT测试)但是这样的相关性实在很可怜,一项测试被长期使用而不做实质的改进,那么只会变成一个硬性考试(多考几次就肯定能过),这对于我们对程序员的挑选并没有什么用处。
    最直接的办法就是最好的办法,让他坐下来,写上一小段程序,或者阅读并说明一套技术规范,然后简要地讲一下实现的方法,这些方法都很好。但是,往往是我们看不懂程序(自然也看不懂他写的如何),或者招人实在是太难了...
  
    小结
    与智力因素相比,个性、工作习惯和培训等方面的因素更为重要。这些因素与智力因素不同,它们都可以通过培训等方面的因素更为重要,这些因素与智力因素不同,它们都可以通过后天经验的积累而改变,所以挑选程序员的问题就转化成为培养程序员的问题。也就是说,优秀的程序员是培养出来的,而不是天生的;所以,我们应该把注意力放到培养或者培训的过程上来。
  
    评注
    问题求解模式是因人而异的。因此,如果强行让一位程序员以另一个人的模式来思考问题,就会降低他解决问题的能力。所以,最大的挑战并不在于创造性的思维,而是在创造性的沟通:以一种别人(他们都有独特的思考方式)能够理解的方式来表达自己的思想。
  
  
  第10章 积极性、培训与经验
    人们在完成给定任务时的表现,既取决于任务本身,也取决于人们对任务的理解程度。虽然人的个性可以改变,智力也可以有所提高,但是工作表现的实质性提高主要还是来自于培训和经验积累。
    心理学本身并不是一门严密的科学,以后也不会成为严密的科学。
  
    积极性
    即使是最粗略地考察一下人类的行为,也会让我们承认,人类并不是其所处环境的一种被动的牺牲品。相反,我们都很容易得出这样的结论:人类似乎可以自己决定要对哪些刺激做出反应,要忽略哪些刺激,哪些信息需要学习,哪些信息又是可以忽视的。这些观察构成了一种观点的基础,这种观点认为人们存在某种内在的“导向驱动力”或者“内在的活力源泉”。这种内在的导向里,正是我们大多数人所说的“积极性”。
    关于积极性,有一点最广为人知:如果增加“驱动力”,将首先会使工作绩效得以提高,但是一旦超过一定的极限,继续增加“驱动力”智慧另工作绩效很快将为零。
    人们口头上声称的正在或者将要做的事情,与他们实际的所作所为之间,没有任何必然的联系。
    只要允许程序员以自己的方式进行工作,那么程序开发这项工作本身就是对他们最大的激励。
  
    培训、课程学习与教育
    在教育发展的过程中,人们总是将“参加课程学习”与“接受教育”相互混淆,还常把“接受教育”与“参加培训”相互混淆。实际上它们之间关系不大甚至毫无关系。如果前期没有接受特定的培训,后面的教育就无法进行。
  
    学习的阻力
    只有当存在阻碍学习的负面因素时,学习才会失败。
    只要让我们自己决定学习的方向,我们总是可以学到大量的东西——虽然这些东西不一定是我们应该学的。
    作为一名真正的专业人员,一个真正有实力的人,承认自己的不足并不会给自己带来任何损失。
    在最初学习的时候,如果独自一个人进行,那么学习的效果将会最好——因为这时任何错误都不会被人知道。
  
    如何学习程序开发
    如果一名程序员想提高自己,那么他就不能只依赖于正式的培训,也不能指望主管能够仁慈地根据需要把他送去进修。同样地,他也不能依靠纯粹的“经验”,因为经验不一定能教给他任何东西。如果一名程序员想把经验利用起来,那么他就必须学会如何去学习。
    掌握学习之道的第一步,就是要了解自己拥有什么,缺少什么——也就是要有“自知之明”。
    找到适合自己的学习方式:听力(讲座、听课);视觉(读书、看图表);实践(解决问题);交流(谈论讨论)
    关于什么才是学习的最佳环境的争论,也许永远没有尽头,因为本质上他们所争论的问题根本就没有答案,学习本身就是一个主动探索的过程。
    管理人员往往要求尽快“完成”任务的压力。但是如果一名程序员想学到东西,那么他就必须顶住这种压力。
    正规的教育只知道一味地向程序与啊反复灌输知识,结果却是让他们对自己所学的工具感到厌烦。而真实情况是,因为我们使用的工具,才能够教会我们如何去成为一名出色的劳动者。
  
    小结
    为了培养程序员的工作绩效,我们可以从两个主要方面着手,培养他对工作的渴望,并使他掌握完成工作所必需的知识。而我们真正的老师,正是计算机本身——永远是那么默默无闻,永远是那么耐心,也永远是那些有学习能力的程序员的老师。我们应该为我们的学校制定一个目标,就是让学生们自己去学习。
  
    评注
    INTJ类型的人,更愿意去剥去事物外在的神秘外衣,以展现其中本质性的,优美的核心。
  
  
  第4篇 程序开发工具
  
  第11章 程序开发任务的差异
    程序开发语言与自然语言
    如果说有哪个领域,其中的每个人都是专家的话,这个领域就是语言
    程序开发语言的想法实际上是与程序开发这一想法本身一同出现的
    程序语言还达不到自然语言的几个方面:
    1)听说信道(我说你听)
    2)迅速消失
    3)广播发送和定向接收
    4)可互换性
  
    程序开发语言缺乏口语形式的一个后果,就是会使语言的发展变得缓慢,而在自然语言中,口语往往是新的语言形式的重要源泉。另一个后果是,如果没有黑板或者纸笔,那么我们讨论程序开发语言时就会很困难。因此,每个程序开发办公室都应该配备黑板、粉笔和许多黑板擦。
  
    自然语言的6种功能:表达情绪、命令、陈述、元语言、诗歌、以及交际。尽管我们在程序开发语言中,也能找出所有这些功能,但其相对重要性和使用频率则非常不同于自然语言。如果哪位程序员不是时而把自己的程序当作是艺术品来看待,那么他就不是一个真正的程序员。
  
    程序开发语言的设计
    一般而言,我们往往是终于克服了心理障碍,并学会了一门新语言之后,才发现以前使用的语言是多么差劲。也就是说,我们的标准是不断变化的——在程序开发语言的设计中必须充分考虑到这一事实。不过由于机器本身的严密性,以及由此带来的程序开发语言的严密性,以减少他所想要的和实际情况之间的差距。只能忍气吞声、学会在现有的条件下生存。
    因为机器是僵化刻板的,所以使用机器的人如果想要成功,就必须变得更灵活一些。在为了适应某种程序开发语言而调整自己的过程中,我们很容易会因为自己付出得太多了,而变得非常依赖这种语言。大多数人宁愿承受当前的痛苦(无论多大),也不愿意放弃一个熟悉的伴侣,而去尝试未知的新事物。让他放弃一门语言,就好象告诉他肯定会有痛苦却不一定有快乐来补偿一样。
    为了理解程序开发语言,除了阅读程序之外,我们还需要做更多的事——我们必须观察程序开发的过程。而且我们必须使用许多资源和设备,才能得到比直觉稍微好一些的结果。之所以要这么复杂,其中一个原因就是:程序员自己也很少清楚他在组什么以及为什么这么做——在研究人类的任何行为时,这都是一个普遍存在的问题。
  
    从某种程度上说,我们之所以很难把程序开发效率低下,归咎于程序员或者程序开发语言中的任何一方,其愿意就在于如果我们拥有理想的程序员。程序开发语言就是多余的了。
  
    小结
    在“程序开发语言”中使用“语言”这个词,从许多方面妨碍了人机交互的发展。将其称为语言,并不能使它成为真正的语言,反而可能会导致错误的类比,从而导致研究的努力方向。为了在程序开发语言方面取得进展,我们就必须首先放弃企图用“真正”的语言来编写程序的信念,因为程序开发语言你永远不可能和人类的自然语言一样。我们可以要求程序开发语言更“自然”一些,但绝不是要它们跟英语或建造通天塔时使用的其他某种语言完全相同,而是说表达的方式和表达者的思想要协调一致。但最终,为了更好的“匹配”,也许用户将不得不受些委屈——或许最终我们不得不改变自己的想法,以便适应我们的计算机。为什么不呢?人类的每个发明创造不都改变了人类自身吗?
  
    评注
    程序开发语言正在向“可视”的方向发展——这会使盲程序员的生活变得更加复杂。虽然细节变了,但是原则并没有变:一个人喜欢的语言,也许另一个人却非常讨厌。
    虽然科技进步了,但有些东西却完全没有改变。虽然白板取代了黑板,但它们的基本功能是一样的(而且擦除的速度仍然不够快)
  
  
  第12章 程序开发语言设计的一些原则
    一致性
    记住一组数据的难度,与这组数据的“信息容量”有关,然而,“信息容量”是很难测量的,因为它不仅仅取决于这组数据所包含的信息,而且还取决于这组数据之外的一些信息——就是记忆者大脑中存在的那些信息。
    大体上说来,程序开发语言设计中的一致性原则可以这样表述:不管在哪里,同一件事情应该以同一种方式完成
    如果一种语言在某种程度上与这个表述有出入,那么它就违反了一致性原则,因此将会更难以学习,更难以保证在使用时不犯错误,并且更难以用来创造“新”技术。另一方面,一致性也表现在同一个语法结构在不同的上下文应该有着相同的意思。
    使用不一致的语言的程序员会容易变得灰心丧气,不愿意尝试新事物(就像经常被禁止做这做那的孩子一样)。语法上的不一致,必定会打击程序员进行语义探索的积极性,因为它会让程序员不清楚自己有多大驾驭语言的能力,这样他会困惑,而程序员本来不应该对他们的程序开发语言感到困惑。
    从调试的观点来看,少量的不一致性要比大量的不一致性更糟糕,因为大部分地方的一致性会使我们麻痹大意。
  
    简洁性
    人类的头脑在能力方面存在一些固有的局限,虽然每个人的局限各有不同,而且对于不同的问题局限也会不一样,但是对于同一个人来说,一个较短的程序总是要比更长的程序更容易理解(即使是增加不会执行的注释,也会增加阅读程序的困难)。
    然而,程序的简洁性并不只是通过统计程序使用了多少个字符来衡量的,而是通过当事人“组块”的能力来决定的,或者通过数据的结构化来达到简洁(压缩、序列化、提供默认值、消除无用冗余等)
  
    局部性与线性
    设计良好的程序开发语言,也可以像良好的记忆力一样帮助程序员——让相关的信息触手可得。在这里我们使用人类记忆能力中的两种:联觉能力(synesthetic,对应于局部性)与顺序能力(sequential,对应于线性)
    程序开发语言中的那些可能会导致非局部性的功能,通常并不是由于语言设计得不好才出现的;否则,这些功能早就被取消了(或者废弃),没有人会觉得惋惜。辖区内广泛程序开发语言提供的很多功能都是为了提高局部性而存在的。
    实验表明,严格按照线性顺序编排的一系列判断,要比有分支或者循环的序列更容易处理。
  
    传统与创新
    为了使程序开发语言实现轻松的表达方式,同时使错误减到最少,一种最重要的方法就是使其变得“自然”。
    如果我们刚开始使用一种语言,我们不能注意到一致性,而只能注意到语言中那些似乎与我们预先对“正确”的感觉不符的地方,这样的感觉来源主要有以下2种:
    1)自然语言(如英语、法语、中文,特别是不同的语系)
    2)程序开发语言(ASM、C++、Ruby等区别很大不同类型的语言)
    请记住,虽然很多语言是有相似性的,但是如果只是因为相似性而学习这些语言,那么我们必须要为这种快速学习付出代价。这是因为没有哪两种程序开发语言是完全一样的——否则它们就是同一种语言,如果两种语言的差别很细微,那么就会出现“抑制”的心理现象(倒摄或者前摄)。
    最常用的提高语言的适应性的方法就是有所创新,但是创新要时刻注意:程序开发并非只是一个人与一台计算机之间的交流。采用自适应性过大的话可能我们的程序对别人来说,就像是精神分裂症患者的自言自语一样难以理解。
  
    专用的、多用的以及玩具式语言
    如果我们要为某个特定的应用领域设计一种专门的语言,那么只要对语言涉及的范围加以限制,就可以立即得到心理上的回报。然而,有时这些限制只是通过限定语言的功能来实现的,同时假定这个领域的问题绝对不会超出某个范围。这意味着语言原来所提供的许多功能都可以被完全去除——但这同时也意味着,该语言将无法模拟某些特定的问题。
    程序开发语言的确会反过来影响人们的思考过程,这样产生的一个后果就是:人们会尝试去解决问题,将受到他掌握哪种程序开发语言以及掌握到何种程度的限制。因此,会出现一种对专用程序开发语言以及自己目前知识水平自我满足倾向。专用语言会以这种方式限制人们的思维从这个意义上讲,对于那些可能需要解决更大型问题的使用者来说,专用语言是有害处的。
    这个矛盾看起来似乎无法解决——一种程序开发语言在它专门设计的用途方面做得越好,它对其使用者思想的束缚也就越大,特别是他们以后需要解决新问题时,这种限制就会暴露出来。
    我们在计算机专业人员的小圈子之外,还承担着更多的社会责任,因为还有很多人不知道怎么保护自己,不知道怎么解决自己的问题(请不要去忽悠他们,因为最终伤害的是你自己)。还是让我们在一个合理的行为准则能够应用到其设计与测试的环境中来开发程序吧,让我们不仅成为专业的程序员,而且成为专业的程序语言设计者。
  
    小结
    程序开发并不是数学的一个分支,它是一种独特的交流形式,人类在这个过程中扮演了一个积极的角色,而计算机则常常扮演消极的角色。也许我们再程序开发语言上遇到的种种问题,正是来源于这种交流的单向性。只有在这些理论家们意识到程序开发“语言”中“相互交流”的一面,他们才会不得不承认,他们需要学习的,并不是符号操作,而应该是人的行为。
  
    批注
    每位程序员都是一位元语言专家
  
  
  第13章 其他程序开发工具
    程序测试工具
    如果只是从测试的角度来看,程序开发的工作应该可以是卓有成效的——要知道,程序开发中唯一的实质问题,只是让程序正确地运行,并且能证明这一点。
    程序开发的特点就是这样,错误的“大小”和它造成的问题并没有直接的关系。因此对于程序测试,很难简单地提出什么目标,更别说做到“消除所有错误”——这是一项不可能完成的任务。
    在我们的社会中,人们自然会相信:事物会按照他们希望的样子存在,所以一种程序测试工具必须尽力向我们展示事物的本来面目(当然,我们能够想到,在所有的代码段都至少执行了一次之前,我们所使用的测试工具会不断地烦扰我们)。而由于人们你对自己的代码都倾向于持乐观的态度,所以也许只有遵循“摧毁信心”的原则,才能设计出好的测试工具——当然,这种信心在必要时应该能够恢复。
    在进行给定次数的测试之后,我们对程序会更有信心。因此,最好的测试工具,必须同时建立在程序开发语言和程序结构的高度一致性上。也就是说,局部性和紧凑性的缺乏会使程序难以测试。
    事先为测试用例所做的工作绝不会是徒劳无功的——除非我们沉迷于此前所取得的“卓越”成绩,而产生了省略后续测试工作的想法。
    如果程序员无法找到错误,那么往往是因为他找的地方不对。最重要的测试工具的目标是要让程序员不再陷在同一个地方。
  
    操作系统
    不管计算机制造者们怎么想,有关性能评估的信息都是任何操作系统任务的重要部分:
    1)有关性能的统计数字经常能为寻找程序错误提供独立的线索
    2)如果程序员打算学习如何编写高性能程序,那么他们也会直接需要这种有关性能的信息
    3)有关程序在计算机系统上的运行统计数字,反馈给计算中心和操作系统的设计者,他们可以以此对程序使用者提供帮助,以及提高设计更好的操作系统
  
    无论实际的环境是好是坏,程序员最终都会以对自己最有利的方式去适应它。所以通过设立优先级等制度,最初每个人似乎都会以为自己的任务应该是这些规则之外的一个特例;但是,如果大家都遵守这些规则,就能使实际的效果大幅度提升,那么人们希望尽快提交各自任务的本能想法就会开始改变。对自己的工作把握也会越来越精确,而那些曾被当作“至关重要”而受到激烈辩护的特殊位置,现在也似乎消失了。
    然而,如果要建立一套合理的规定和限制,操作系统必须具有足够的灵活性,以接受和实行这些规定和限制。为了确保系统的使用是高效和有效的,最好的方式就是让那些高效且有效的方式变得非常易于使用。通过这种方式,程序员们的工作将变得更轻松,从而引导他们掌握更好地使用计算机的方式。
  
    分时与批处理
    即使是考虑最周全的研究者,偶尔也会在解释他的研究成果时犯错误。
    我们也许并不能像自己希望的那样,分离出一些“纯粹”的因素,因为我们的系统本身就具有系统的复杂性。
    也许这些研究所得到的核心结果,就是不存在任何真实的情况,可以证明其中一种模式整体而言比另一种模式更有优势。而所有的研究都无一例外的表明,在性能上个体差异的影响要远远大于计算机系统差异的影响。要想在提高人绩效用方面取得重大突破,其关键似乎就在于研究个体差异的本质与结构,以及人类解决问题的方式。无论一个机构的目标是为了更有效地传授计算机科学,还是为了低成本地开发计算机程序,掌握了人类在人机交互的过程中解决问题方面的基本知识,都是有效地实现系统以及机构目标的必由之路。
  
    文档
    文档是程序开发过程中的蓖麻油——主管们很喜欢它,但是程序员们很讨厌它(以至于程序员们像小孩子喝蓖麻油一样,找出许多怠工的方式,使自己写出的文档毫无用处)!
    只有编写良好的文档,才能体现出文档的价值。如果写出的文档很糟糕,那么还不如根本没有文档的好。
    为了得到高质量的文档,唯一的希望就是让程序员相信写文档对他们有好处。如果写文档的工作对程序员没有任何价值,那么他们只会尽可能避免去做这样的工作;但是如果写文档的工作能够展现出良好的效果,那么就不会有什么因素能够妨碍程序员写出质量合适(不能对文档期望过高,根本原因在于我们每个人都有差异,有不同的层次需求)的文档。
    文档的深度以及自我描述的结构是最基本的需求。
  
    高质量的文档当然很好,但是如果需要为此花钱,情况就不一样了。
    我们不是要让计算机来解决调试以及文档化的问题,而是希望计算机能够帮助人们利用自己所拥有的强大的心理资源,来克服他们那些巨大的心理弱点。
  
    从程序开发本身作为一种人类行为出现开始,我们已经在程序开发方面经历了一个怪圈。那些对程序开发一知半解的管理人员,认为任何人都能编写程序;而努力使人们承认自己是专业的程序员们,直到现在才开始得偿所愿。并不是任何人——无论他有什么样的背景,或受过什么样的训练——都能够做好程序开发这项工作。
  
    小结
    系统是复杂的。这种复杂性意味着一方面实验结果有着双倍的重要性,但另一方面为了获得和解释实验结果,也会遇到双倍的困难。要点并不是这些问题中哪个会被“解决”——复杂性就此而言实在是太大了,而是在于哪些问题值得我们去解决?不管怎样,我们看重的不是得到了多少解决办法,而是在尝试得到这些解决办法的过程中获取的经验。
  
    批注
    完全利己的程序开发方式和专业测试人员的社会地位等问题如今仍然存在。显然,通过完善测试工具并不能解决这些问题,真正的解决之道应该从提高管理水平入手,
    无论怎样,在为软件开发人员提供完全集成的开发/测试/维护环境方面,我们仍然有很长的路要走。程序开发的历史就一直见证着这种由重要向非重要转变的过程。
    在基础性工作的定义不断改变的过程中,今天的大多数程序员都会感到不快。
  
  
  第5篇 结语
  
  
  第14章 结语
    在自己的生活中随身携带一台装备精良的机器,可以用来对行为进行观察分析。我们应该研究我们自己的中央处理器(而不是过分关注于计算机)。如果要使我们自己的计算机更加高效,我们就要更细致的观察我们自己以及我们周围的事物。
    如果某件事情根本不值得去做,那么无论做的多么出色都肯定是没有意义的。
    千万不要成为出卖自己的人(雇主们总是可以找到为了追求快乐或利益,甘于出卖自己的劳力与脑力的追随者)
    努力让自己的心灵纯洁,这样才能得到更多的帮助。也许个人的努力对最终结果都不会有什么影响,但是我们决不能放弃尝试,因为如果放弃,其结果必然是回到专制。

    我们毕生的使命,就是要造就另一个人。


转自:http://book.douban.com/review/4968947/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值