梦断代码读书笔记1
第0章 软件时间
作者迷恋于一个开放代码并可以由游戏玩家更改程序的一个游戏,并为在它的基础上创新和增添一些功能而乐此不疲。
0代表程序员的思维方式,因为计算机从0开始计数。
"Hello World " 程序能够唤醒每个程序员心中乐观的一面。既然能叫它说话,就能让它做任何事!
计算机器协会(The Association for Computing Machinery ), 维护了一张网页,上面列出将近两百种编程语言版本的"Hello World" 程序。简直就是程序代码的罗塞塔石碑。
网页地址:http://www2.latech.edu/~acm/HelloWorld.html
为什么就是不能像造桥那样造软件?
人类文明运行于软件之上。软件创建艺术却隐于暗处,即便对于专家们也是如此。互联网时间带来了快速发展的技术产生、公司创立、创造财富等也同时带来了程序的缺陷问题。而对软件开发者来说,则过的是时快时慢:如果灵感到了,一切顺利,则全然忘记时间,全心投入高速的开发之中。反之遇到瓶颈,则举步维艰的软件时间。软件不能像建造桥梁那样一劳永逸可以造福上百年。反而漏洞百出,麻烦不断,错误不停。带来无穷尽的改进和苦恼。
在现代软件研究领域多有建树的专家弗里德里克·布鲁克斯(Frederick Brooks) 在1987 年写了一篇题为( 没有银弹(No Silver Bullet )〉的著名论文。布鲁克斯在论文中称,无论编写计算机程序是如何地令我们倍感挫败,也永远无法找到一种魔法般的突破-我们只能期待渐次前行。1/4个世纪过去了,银弹仍然没有发现。
第1章 死定了
一个错误就可能让一个项目“死定了”。往往带来不可知因素的时间陷阱。
记录于Bugzilla 中的第44 个缺陷,最初于2003 年1 月19 日登记,描述信息是“ 当修改窗体大小时出现闪烁”。。安德森认为这是个小问题,不过还是应该查实和修正。可直到将近六个月之后的今天,他仍然没能修正。问题不在自己和同事编写的代码上,出错的根源在于一个称作wxWidgets 的软件里面,Chandler 小组采用该软件作为项目的构造块。安德森要么等着wxWidgets的开发者修正代码,要么就得绕过问题所在。
软件项目难以按进度安排实现,这种情况极为常见。在软件开发的世界里,进度延误普遍到人们特意生造出—个委婉词来描述它:slippage(失速)。
软件时间自我扭曲再头尾相接,如同莫比乌斯环。一般令人费解。进度忽而突飞猛进,忽而不知何故驻足道中。在你以为大功即将告成之时,却又山穷水尽, 花上整半年时间,一无所得。
IBM System/360 主机操作系统是当时规模最大的软件项目。那台巨大而昂贵的大型计算机,本应是后来二十年中生意场上的中流砾柱,但它的孕育和诞生却饱受延误和成本超支之苦。正如布鲁克斯所言,它变成了一个“沥青坑”, 一个能粘住大企业的陷阱,哪怕对于IBM这样“孔武有力”的公司也不例外。
布鲁克斯法则:
向已延误的项目中补充人力,只会使其继续延误。
布鲁克斯写道,软件开发者通常都是乐天派,他们认定每个缺陷都可以被迅速修正,且修正旧缺陷必能减少新缺陷的数量。
布鲁克斯发现,在实际开发中,编码只占软件项目开发时间的1/6, 有一半时间用于测试和修正缺陷。但只有少数项目经理会真正按照这种思路来安排开发人员的工作时间。
所谓“人月", 是一种科学管理概念,它假定生产力可被拆分为不连续、无差异、可替换的单元。
布鲁克斯观察到,“只有在任务能分派给许多互相之间无须沟通的工作者时,人和月才是可互换品。
“对于软件而言,项目各有差异、工具不断升级,每当团队中加入一个新组员,老组员就得放下手边的工作,帮助新组员进入角色,每位组员都要等待重新分派任务,好让新组员有事可做。在你意识到这一切之前,已经远远落后于进度了。也就是说,每次重新安排进度计划,都导致雇用更多人力,于是又不得不重新安排进度。
制作软件的大量工作受困于“序列约束",它限制了任务分解的程度:完成某项任务是处理其他任务的先决条件,这与人力投入多少无关。
布鲁克斯法则暗示最理想的开发组规模是一个人——无须停下工作与同事沟通的单个开发者。
一切均顺序进行,确保项目维持布鲁克斯所谓“概念上完整”的状态· 项目中所有环节目标一致,且按计划完美结合。
但是对于庞大且涉及面极广的一个程序来说几乎不可能。从理论上团队开发就是不得不被认可的,何况实践上它几乎必不可少。
开放源代码软件开发(open source software development),它能彻底改变软件开发的具体过程——将其从少数隐士手里拿出来,散播到广大人群中。在它之前,软件开发都采用大教堂模式。即“最重要的软件……需要像建教堂一般,由独立的巫师或一队相互隔离的魔法师精心打造,在面世之前绝不发布beta 版本。”
开发源码开发方式(又叫开源集市)在一方面,低成本、广泛地接入像互联网那样的网络, 让开发者之间能建立迅速、可信的沟通渠道,存储可被开放访问的共享知识和代码池;另一方面,围绕一种领导方式——如托瓦茨那样的方式——形成合作团队的良好风气,欢迎新人进入、鼓励成员做出贡献,同时尽可能增加合格成员。
开源运动的新集市模式在很多方面改变了计算世界,但说到能比大教堂模式更快地让新产品面世,却并无显著建树。
"愉悦是金,“艾瑞克· 瑞蒙德写道。“开源的成功告诉我们,对于创造性工作,玩耍是最经济有效的模式。”
第2章 Agenda之魂
Chandler 项目并没有真的“正在“改变世界(至少尚未开始)。但Chandler 项目正是为改变世界之梦所驱动。
卡普尔自己以及他的莲花公司还有更多开发者对项目的执着与对灾难的坚持。正是某种意义上的开发者的精神。
卡普尔(Mitchell Kapor)在接受戴维·甘斯的采访时说过的一段话:
“在变成数字资本家之前,我曾教人超觉静坐。,还在一家社区医院的精神科做过心理咨询师,这些经历对我影响极深。我拥有心理咨询的硕士学位。所以,我另有志趣。我只是误入计算机领域,无意成为比尔·盖茨——只有比尔·盖茨才能做比尔·盖茨。我向来不求做大公司、赚大钱。我只是办了家叫做莲花的小公司, 做了个几百万人争相购买的软件产品,结果这家小公司陡然暴长,员工数千,每年收入数亿美元。很不爽。至少对我个人来说,很不爽。所以我离开了。在某一天,我离开了。”
莲花公司有个叫做Agenda 的项目,为了解决卡普尔的小纸片问题而设立。即采用计算机人工智能来管理记录信息的小纸片——名片、随手贴、笔记页等。莲花公司于1988 年发布了Agenda 软件。
Agenda的“自动分派”特性一一在意义模糊的短语里面,如“ 下周五与约翰共进午餐"'找出“下周五”这个曰子——如同魔法一般,没有其他软件能与之媲美。它还引入了一种管理数据的新手段——介于传统计算机数据库的严格结构和字处理软件的自由格式之间。
Agenda的创建者们认定这样一些超乎常规的原则:
用户不用关心软件的存储结构,只管输入数据就好,用户应该能够容易地扩展和修改数据结构、添加新分类, 且不会导致数据丢失,用户应该能够用自己创建的新方式查看数据——也可以在自己创建的视图中操作和修改数据。
在当时,程序或网站总是要你按它设定的方式而不是你自己的方式填空——社会保险号码里面不得包括连字符!信用卡号中不得包括空格!——而Agenda 早有独门秘技让用户随意输入。
卡普尔离开莲花公司后,投身于开创开放网络的工作。但他放不下Agenda。他珍视的并非Agenda 的“特性列表”——软件的种种特殊功能一一而是动态适应性的程序精髓,即“先扔进去,延后处理”。于是,Chandler项目诞生了。
关于Chandler,米奇.卡普尔只知道三个要素:它应当开源,它应当挠到Exchange 的痒处,它应当承继Agenda 之精髓。
鼠标之父道格拉斯·恩格巴特( Douglas Engelhart ) 的"OnLine System (在线系统, NLS)" 就是—种PIM(personal information manager) 。NLS 的目标是让用户能够“保存并研究想法,使之相互关联,并能交叉引用”。
现在的计算机用户大概会把这叫做outliner (大纲工具)——以可折叠和展开的节点对信息行进行层级结构化组织的程序。但NLS 可以在网络上共享,而不仅限于单机使用。
在1962 年关于增进人类智慧研究计划的论文中,恩格巴特阐述了程序员最有可能成为初期目标用户的原因。“成果也可用千智慧增进研究项目自身,改进研究和开发智慧增进系统编程活动的效能。设计、实现和修改程序的能力,在衡量研究进展时颇为重要。”
若NLS 能帮助程序员更好地编程,则程序员就能更快地改进NLS。这就出现了正向循环。这就是“提靴带(bootstrapping)" 。
在恩格巴特看来,提靴带(bootstrapping)的意思是“让改进的过程得到改进”。提靴带(bootstrapping)并不改进过程——如让人更快地解决问题。它改进的是改进过程的速率一一如怎样才能快速教会他人更快地解决问题。
初次启动计算机时,内存是空的。这就造成了鸡与蛋的悖论:计算机硬件需要操作系统软件来装载程序——包括操作系统本身。计算机系统发明者们通过一个叫做"bootstrap loader (靴带装载者,引导程序)”的小程序让机器具备刚好足够把大操作系统装入内存的能力,开始正常运行。
米奇· 卡普尔总把恩格巴特作为自己的灵感之源,而Agenda 在某种意义上则是NLS的传承者。
之后,本章介绍了很多个失败的项目,这些项目失败的原因都是因为项目需求不断地变化。用一句话来概括就是:标靶移来移去。目的忽上忽下。计划不切实际。期限一拖再拖。预算膨胀超支。绝望已极。混乱不堪。
第3章 原型与Python
卡普尔的团队开始问自己一个看似简单的问题:我们如何组织信息?如何对这种信息组织法建模——需要怎样的数据结构才能让计算机也能回答这个问题?
软件没有磁芯。它就像洋葱般层层叠叠,每一层都辛辛苦苦地建立于前一层基础之上。程序员把这种结构叫做“抽象层叠",每当新添一层时,就要把一些复杂而特殊的东西转换为简单而通用的东西。
在抽象层叠的最底端, 正好在核心内存之上的部分就是汇编语言。
语言的选择可能都是一个项目在前期选择时必须要经历的痛苦抉择。文中谈到了汇编、Fortran、C、Perl,谈到了编译型语言和解释型语言,最后项目用Python语言来实现。
Python 是一种“解释型语言(interpreted language)" 。“编译型语言(compiled language)" 通过编译器先将程序员的源代码翻译为机器可读的二进制代码后再运行,而解释型语言则是在运行时做类似的工作——解释器逐行翻译源代码,再喂给处理器运行。解释型语言效率较差,因为你要同时运行自己的程序和解释器。但这也使得解释型语言较为敏捷。
Python是解释型语言,但是简单易懂的语言,很明显在修改错误和拓展程序上事半功倍。这恰恰说明了,解释型语言这种往往被忽略的“脚本语言”是至关重要的。
很多语言都用括号或其他符号来划分代码块,而Python 却只简单地用缩进表示。它的另一个优点是变量类型设定宽松。
Python 的信条,范·罗萨姆说,是TOOWTDI: There’s only way to do it. (仅此一途。)
Python和Java语言一样提供了“垃圾回收(garbage collection)"机制。
当程序不再需要先前申请的内存空间, Python 就会负责清理。
面向对象技术不是围绕一系列命令行来组织程序,而是基于一些叫做对象的代码片段来组织程序。当接收到其他对象的呼叫时,对象就会做出操作。对象之间通过严格定义的输入输出彼此相关。软件对象通过互相之间发“消息(message)" 来触发”事件(event)",达到交互的目的。共享特性对象可以组建为“类(class)", 还可以从“父类(parent)" 继承特性。
语义网时基于一种名为RDF(Resource Description Framework , 资源描述框架)的技术。RDF 以“ 三元组(triples)" ——包括三个部分的语句——存储所有信息,描述事物之间的关系。
电梯游说:就是当你有幸在电梯间遇到某位权钱人士时,能脱口而出,在短时间内说服他。