顶级的程序员是怎么样的?

贝尔实验室中的顶级程序员

计算机先驱布莱恩·W. 克尼汉(Brian,W.,Kernighan)

Brian,W.,Kernighan

我出生于多伦多,曾就读于多伦多大学,专业是工程物理(后来改名为工程科学),这是为那些自己也不知道想学什么的人准备的“大杂烩”专业。我毕业于1964年,那时电子计算正处于早期阶段:我大三时才第一次见到计算机。整个学校只有一台IBM 7094大型计算机,算是当时最高端的设备。它拥有32K(32 768)个36位字长的磁芯存储器(如今我们会说是128 KB),还有大机械硬盘形态的次级存储。当时它价值足足300万美元,安放在空调机房中,由专业操作员照料,普通人(尤其是学生)不允许靠近。

所以,尽管我努力学习Fortran语言,但身为本科生,也只能浅尝辄止。对于那些曾经挣扎着写出自己第一段程序的人,我感同身受。我精读了丹尼尔·麦克拉肯(Daniel McCracken)的Fortran II大作[2],学会了各种编程规则,但还是不懂怎样写出第一段程序。动手能力跟不上理论知识,这该是很多人都会遇到的障碍吧。

在大学生活第一年结束前的那个夏天,我在多伦多帝国石油(Imperial Oil)公司找到一份工作,加入为精炼厂开发优化软件的小组。新泽西标准石油(Standard Oil of New Jersey)公司是帝国石油公司的股东,标准石油于1972年更名为埃克森(Exxon)。

回想起来,我在实习时的表现远低于平均水平。我花了整个夏天的时间编写一套体量庞大的COBOL程序,用来分析精炼数据。我不记得其具体功能,但它肯定没能正常工作。我其实并不清楚如何编程。COBOL缺乏对良好程序组织方式的支持,结构化编程也还未被发明出来。我的代码充斥着没完没了的IF语句,在我想到要做什么事时,将执行流程分支到另外某处。

我还尝试让Fortran程序在帝国石油的IBM 7010上运行,因为相对于COBOL而言,我对Fortran懂得多一点儿,而且Fortran大概更适合用来做数据分析。在与JCL(IBM的作业控制语言)搏斗了几周之后,我才发现7010上根本没有Fortran编译器。JCL错误信息如此晦涩难懂,以至于以前根本没人搞清楚过这个问题。

度过略有挫败感的暑假之后,我回到学校继续完成学业。我对编程的兴趣依然强烈。学校没正式开设计算机科学课程,但我高年级时的论文都与人工智能有关。人工智能在当时是热门主题。定理证明器、下国际象棋和跳棋的程序、自然语言的机器翻译似乎触手可及,看似只需要一点点程序设计就可以实现。

1964年毕业后,我不知何去何从,所以就像很多其他学生一样,打算直接读研究生。我申请了十来所美国大学(那时加拿大人不怎么申请美国学校),并有幸被其中几所录取,其中就有麻省理工学院和普林斯顿大学。普林斯顿大学说,完成博士学业通常需要3年时间,麻省理工学院说大概需要7年;普林斯顿大学提供全额奖学金,麻省理工学院说我得每周做30小时的研究助理工作——结论显而易见。而且,我的好友,高我一届的多伦多校友阿尔·阿霍,已就读于普林斯顿大学,于是我就去了普林斯顿大学。事实证明,这是一个超级幸运的选择。

1966年,好运再度降临。因为普林斯顿大学研究生李·瓦里安(Lee Varian)上一年在麻省理工学院干得不错,所以我得到了暑期去麻省理工学院实习的机会。我在那儿使用兼容分时系统(Compatible Time-Sharing System,CTSS)和密歇根算法译码器(Michigan Algorithm Decoder,MAD,ALGOL 58语言的分支)编写程序,为一种叫作Multics的新操作系统打造工具。我在麻省理工学院名义上的老板是费尔南多·科巴托(Fernando Corbató)教授,人人都叫他“科尔比(Corby)”。他创建了CTSS,负责Multics,是一位了不起的绅士。1990年,科尔比因其为分时系统做的基础工作获得图灵奖。他于2019年去世,享年93岁。

除了带领团队设计、实现CTSS和Multics,科尔比还是输入密码访问计算机的发明人。批量计算很少用到这种方式,但运行共享文件系统的分时计算机的确需要某种安全机制来保护私有文件。

1966年夏天我在麻省理工学院时,系统自动为我生成了两个可拼读的短密码,我至今仍然想得起来。使用两个密码确有必要。夏日的某天,有人搞混了存储密码的文件和保存当日欢迎登录消息的文件。密码都是明文存储的,结果一登录系统就会看到所有人的密码。

我的办公室属于约瑟夫·魏岑鲍姆(Joseph Weizenbaum)教授,那个暑假他不在学校,记得办公室里也没有其他人。早在1966年,魏岑鲍姆就发表了对Eliza的描述。Eliza是模拟与罗杰斯学派心理学家对话的程序[3],也是使用自然语言与计算机互动的早期尝试之一。它令人惊奇地有效,起码在我第一次看到时特别有效。我也乐意带领访客去看它。如今有许多模拟Eliza的网页程序,虽然这些程序很快就会“原形毕露”,但和它们聊几分钟还是很有意思的。

1967年夏天,终极好运从天而降:墨里山的贝尔实验室计算科学研究中心让我去实习,老板是道格·麦基尔罗伊(图1-4)。道格建议我研究内存分配评估问题,这也是他长期关注的方向。遵循最佳实习传统,我最终做出了与老板要求风马牛不相及的东西。我写了一套函数库,以方便在Fortran程序中做列表处理。整个夏天我都在墨里山的大型计算机GE 635上编写严密的汇编语言。GE 635实际上是重整过后更有条理的IBM 7094,同时也是Multics专用机GE 645的简化版。那差不多是我最后一次写汇编语言。尽管我所做的事从根上就走错了方向,但代码写得十分过瘾,让我与编程结下了不解之缘。

道格•麦基尔罗伊,约1981年

迪克•汉明

迪克•汉明,约1975年,穿着他招牌式的格子正装(维基百科)

1968年,他得到通知说自己获得了当年的图灵奖,这个奖现在被看作计算机科学领域的诺贝尔奖。我目睹了他的自嘲式反应:诺贝尔奖当时奖金价值10万美元,而图灵奖奖金价值2 000美元,他说自己得了2%个诺贝尔奖。这是第三届图灵奖,第一、二届分别颁给了艾伦·佩里斯(Alan Perlis)和莫里斯·威尔克斯(Maurice Wilkes),他们两位也是计算领域的先锋人物。迪克因其在数值方法、自动编码系统、错误侦测及错误纠正方面所做的工作而获奖。

迪克是促使我开始写书的人。写书是一件好事。他对大多数程序员评价甚低,因为他感觉他们没有得到像样的培训。至今他的话仍在我耳边萦绕:

“我们给他们一本词典和一套语法规则,说:‘孩子,你已经是伟大的程序员了。’”

他认为,应该像教写作一样教编程。好代码应该与坏代码风格迥异,应该教会程序员如何写出漂亮的、风格优雅的代码。

对于怎样才能做到这一点,我和他有分歧。但我听取他的意见,于1974年写了我的第一本书《编程格调》(The Elements of Programming Style),合著者是当时坐在我隔壁办公室的P. J.“比尔”·普劳格(P. J. “Bill” Plauger)。我们仿效威廉·斯特伦克(William Strunk)和E. B.怀特(E.B.White)的《风格的要素》(The Elements of Style),展示写得差的代码片段,然后阐述如何对其进行改进。

迪克于1976年从贝尔实验室退休,去了加利福尼亚州蒙特雷的美国海军研究生院(Naval Postgraduate School in Monterey,California)任教,直至1998年初逝世,享年82岁。据说,他有一门课被学生称为“汉明论汉明”(Hamming on Hamming),正与本节内容相呼应。

迪克无时无刻不在深思自己在做什么,为什么要这么做。他常说“算以获识,非算以得数”[6],他甚至有一条(用中文)写着这句话的领带。他很早就认为,电子计算将在贝尔实验室的工作中占到一半比例。同事们都不这么认为,但很快他的预测就成真了。他常说,周五下午宜哲思,所以他每逢这个时间就安坐思考,但也随时欢迎我这样的访客。

退休后的几年,迪克总结了关于职业生涯成功之道的建议,开设讲座,题为“You and Your Research”(你和你的研究)。你可以在网上找到相关内容。最早一次讲座于1986年3月在Bellcore(即贝尔通信研究院[7])举办,肯·汤普森开车载我一起去听。

肯·汤普森

肯的太太休了3周假,就有了Unix

贝尔实验室退出Multics项目后,项目组成员得找其他事来做。肯·汤普森(图2-2)还是想做操作系统,但实验室管理层被Multics伤透了心,不肯给操作系统项目买硬件。肯和其他人只能纸上谈兵,设计操作系统的各种组件,无法开展具体的实现工作。

肯·汤普森,约1981年

恰在此时,肯找到一台没怎么用过的DEC PDP-7计算机。这种计算机的主要功能是做电路设计的输入设备。

PDP-7于1964年推出,但计算机领域演进太快,到了1969年,它已经过时。这台机器本身不算很强大,只有8K(8192)个18位字长的内存(16 KB),但其图形显示非常漂亮,所以肯就为它写了个太空旅行游戏。在这个游戏里,玩家可以漫游太阳系、探访各个行星。这个游戏有点让人上瘾,我玩了好几个小时。

PDP-7还有一个好玩的外设——磁盘驱动器高耸,直直架着一块磁盘。据传,万一盘片飞出来,站在它前面的人就有可能遇险。磁盘运转速度远高于计算机读写速度。为了解决这个古怪的问题,肯写了个磁盘调度算法来提升磁盘的总吞吐量。这个算法在任意磁盘上都可用,但主要是为PDP-7的这块磁盘设计的。

如何测试这个算法呢?这需要往磁盘上装载数据,肯认为他需要一个批量写数据的程序。

“在某一时刻,我发现离实现一个操作系统仅有3周之遥了。”他需要写三个程序,每周写一个:用来创建代码的编辑器;将代码转换为PDP-7能运行的机器语言的汇编器;再加上“内核的外层——操作系统齐活了”。

正在那时,肯的太太休了3周假,带着一岁大的儿子去加利福尼亚探望公婆,这样肯就有了3周不受打扰的工作时间。正如他在2019年一次采访中所说,“一周,一周,再一周,我们就有了Unix。”无论以何种方式来度量,这都体现了真正的软件生产力。

肯和我都从贝尔实验室退休几年之后,我问他3周内写出Unix是否属实。下面是他回复邮件的原文,谈到的情况和最近那次采访完全一致。

1969年年中至年末,有明确Unix特征的系统就已在运行,可以说那就是Unix诞生的时间了。

日期:2003年1月9日,星期四,13:51:56-0800
Unix是用来测试吞吐量之类的文件系统实现。实现出来之后,我发现很难用数据给它加上负载。我可以在循环中调用读/写操作,但做不了更复杂的事。这就是邦妮(Bonnie)去圣迭戈(San Diego)探望我父母时,我面临的状况。
我认为它已经很接近分时系统了,只是还缺少执行调用(exec call)、shell、编辑器和汇编器。(没有编译器)执行调用手到擒来。其他三个每周做一个——加起来正好是邦妮在那边待的时间。
计算机内存有8k×18位。4k做内核,4k供用户程序换入换出。

肯于1966年加入贝尔实验室,开始做Multics研发工作,后来又写了Unix。这些事前面已谈过,此处不赘述。

肯对游戏的兴趣由来已久。他从小就热爱国际象棋。他不愿输棋,但又会替输了的对手惋惜,所以最终只能做个看客。1971年,他为PDP-11写了一个国际象棋程序。这路子似乎行得通,于是他着手制作用于加速运算(如算出从指定点开始的合规走法)的特殊用途硬件。这些工作累积成了Belle项目(图2-3)。Belle是肯与乔·康登(Joe Condon)从1976年至1980年开发的国际象棋计算机。

肯·汤普森与乔·康登(计算机历史博物馆供图)

Belle(图2-4)赛绩骄人。在与人类棋手的常规比赛中,斩获2200等级分,成为第一台荣升国际象棋大师的计算机。它还获得了1980年世界计算机国际象棋大赛(World Computer Chess)冠军。在被史密森学会(Smithsonian Institution)收藏之前,它还得过好几次ACM计算机国际象棋锦标赛冠军。

图2-4 Belle国际象棋计算机(计算机历史博物馆供图)

丹尼斯·里奇曾经为国际计算机象棋联盟(International Computer Chess Association)写过一篇短文,介绍肯·汤普森对计算机游戏的贡献[5]。文章写道,肯对游戏的广泛兴趣,远远不止国际象棋。文章还写了1978年12月5日Belle在ACM计算机国际象棋锦标赛上击败Blitz 6.5的过程。文中引用计算机围棋先锋蒙蒂·纽伯恩(Monty Newborn)及国际大师戴维·利维(David Levy)的评论:

1.e4 e5 2. Nf3 Nc6 3. Nc3 Nf6 4. Bb5 Nd4 5. Bc4 Bc5 6. Nxe5 Qe7
7.Bxf7+ Kf8 8. Ng6+ hxg6 9. Bc4 Nxe4 10. O-O Rxh2!! 11. Kxh2 {加速损失} Qh4+ 12. Kg1 Ng3 13. Qh5 {无效拖延} gxh5 14. fxg3+ Nf3# {防住将军,双将且将死,难得一见。“截至目前,计算机程序下出的最妙招数……计算机国际象棋见证了新时代的开始。”}

国际象棋有赢、输或和3种终局。“50步规则”规定,如果在50步棋以内,没有吃子,或者兵没有移动过,则棋手可以提出和局。这条规则能防止玩家在无法赢棋时干耗时间。

肯决定研究50步是否是合适的数字。他使用Belle和一些复杂的数据库组织方式来评估所有4子或5子和局,发现如果采用最佳下法,其中部分棋局可以分出胜负。此时,肯在国际象棋圈已颇有名气,时不时有特级大师来实验室与Belle对弈,尤其是下残棋。我曾经只是因为周末刚好在实验室,就见到了世界冠军阿纳托利·卡尔波夫(Anatoly Karpov)和维希·阿南德(Vishy Anand)。

肯热爱飞行,常常自己或搭载乘客从莫里斯敦机场起飞,在新泽西上空巡航。在他的影响下,1127中心的其他成员也喜欢上了飞行。高峰时期,“1127空军”拥有六七名私人飞行员。他们常常飞去看秋叶,或者到有意思的地方吃午饭。道格·麦基尔罗伊回忆说:

“除了去新英格兰看秋叶,‘1127空军’还去阿迪朗达克山观赏过月食。感谢肯驾驶飞机,罗布·派克提供望远镜。还有一次飞行是去观测水星凌日。Unix组员为天文研究所做的贡献从乔·奥桑纳写的azel[6]开始,这个程序用来控制‘电星一号’(Telstar)的地面站,追踪人造卫星位置。然后是鲍勃 · 莫里斯写的sky程序,还有肯写的天体事件预测器、李·麦克马洪(Lee McMahon)用我的map程序画了星图,最后是罗布写的scat天体目录程序。”

1992年12月,肯和弗雷德·格兰普(Fred Grampp)到莫斯科驾驶一架米格29战机,比他们平时开的赛斯纳飞机更上一层级。图2-5和图2-6展示了肯起飞前和落地滑行的情形。

肯·汤普森准备起飞(cat-v供图)

肯·汤普森降落滑行(cat-v供图)

肯和我都于2000年年末从贝尔实验室退休。我去了普林斯顿大学,他加入贝尔实验室同事创办的恩智斐(Entrisphere)公司。2006年,他加入谷歌公司,和罗布·派克及罗伯特·格里塞默(Robert Griesemer)一起发明了Go语言。我听说他离开Entrisphere公司加入谷歌公司,去信询问详情。他回邮件说:

日期:2006年11月1日,星期三,16:08:31 -0800
主题:回复:旧时来声
是真的。我没有改变谷歌员工年龄中位数太多,但我想确实拉高了年龄平均线。

丹尼斯·里奇

丹尼斯(图3-13)生于1941年9月。他的父亲阿利斯泰尔·里奇(Alistair Ritchie)在默里山的贝尔实验室工作多年。丹尼斯在哈佛大学完成了物理学的本科学业和应用数学的研究生学业。他博士论文[4](1968年)的主题是函数的亚递归层次结构,这是专家才能应对的题目,远远超出我的能力范围。图3-14展示的是丹尼斯博士论文中的一页,取自一份模糊的复本。在谈及职业道路时,丹尼斯说:

丹尼斯·里奇,约1981年 (杰勒德·霍尔兹曼供图)

摘自丹尼斯·里奇的博士论文书影(计算机历史博物馆供图)

“本科经历告诉我,我不够聪明,成不了物理学家,那时我也认识到计算机有多厉害。研究生经历令我确信,我不够聪明,成不了算法理论专家。我也认识到,自己更喜欢过程式语言而不是函数式语言。”

就像C++的创造者本贾尼·斯特劳斯特鲁普曾说过的那样,“如果丹尼斯决定把那10年的时间花在研究深奥的数学上,Unix就会‘胎死腹中’。”

丹尼斯在贝尔实验室度过了几个夏天,并于1967年正式入职,成为计算科学研究中心技术团队的一员。在最初的几年里,他一直参与研发Multics。如前所述,Multics被证明野心过甚,而且大家越来越明白,目标无法实现。贝尔实验室于1969年退出Multics研发计划,肯、丹尼斯和其他同事拥有了设计创新操作系统的经验和对高级语言实现的品位,并得到机会,向着更合适的目标重新启程。其结果就是Unix操作系统和C语言。

C语言的起源可以追溯到20世纪70年代初。它基于丹尼斯为Multics实现高级语言的经验而创造,但由于当时大多数计算机能力有限,根本没有足够的内存或处理能力来支持复杂语言的复杂编译器,所以C语言的规格大大缩小了。这种被迫最小化符合肯和丹尼斯对简单性和统一性的偏好。对于真实的计算机硬件来说,C语言也很适合,将其翻译为高效运行的好代码的方法显而易见。

有了C语言,就有可能使用高级语言编写整个操作系统。到了1973年,Unix已经从原来的汇编语言改为C语言编写,系统的维护和修改变得更加容易。将操作系统从最初的PDP-11计算机移植到其他不同架构的计算机,这是C语言带来的另一个巨大进步。由于大部分系统代码都用C语言编写,所以移植系统所需工作并不比移植C语言编译器多多少。

丹尼斯是超一流的技术作家,文风清雅,用词灵巧,字里行间闪烁着干练的智慧,准确地反映了他的个性。我和他合著了《C程序设计语言》(The C Programming Language),该书于1978年出版,1988年出第2版,此后被翻译成20多种语言。丹尼斯原著的C语言参考手册是1988年首次推出的ANSI/ISO(美国国家标准学会American National Standards Institute/国际标准化组织International Organization for Standardization)的C标准的基础,也是该标准的主要构成部分。毋庸置疑,C语言和Unix的部分成功可以归功于丹尼斯的写作。

因他和肯·汤普森一起为C语言和Unix所做的工作,丹尼斯获得了许多荣誉和奖项,包括ACM图灵奖(1983年)、美国国家技术奖章(National Medal of Technology)(1999年)、日本信息通信奖(Japan Prize for Information and Communications[5])(2011年)并入选美国国家发明家名人堂(National Inventors Hall of Fame)(2019年追授)。

在很多年里,丹尼斯成功逃脱承担管理职责的重任,但最终还是屈服,担任软件系统部门主管,负责组建Plan 9操作系统团队。2007年,丹尼斯卸任,正式退休,但几乎每天都会来贝尔实验室,直到2011年10月去世。

想了解更多贝尔室验室的顶级程序员读一读《UNIX传奇:历史与回忆》

1. 计算机先驱布莱恩·W. 克尼汉,继《C程序设计语言》后的全新力作!

2. 跨越50年历史河流,带你走进贝尔实验室,亲历IT发展史实。

(1)以肯·汤普森、丹尼斯·里奇、道格·麦基尔罗伊等传奇人物小传,串联成20世纪一系列重要发明的起源/发展线路图。

(2)以Unix的诞生与迭代、优秀而开明的管理体制、有远见的持续投资等精彩故事,揭示出贝尔实验室如何孕育出科技创新的真相。

(3)以Unix诞生见证者回忆往事的轻松口吻和不为人知的有趣图片,述说Unix的“设计哲学”如何被计算机世界有效利用且延续至今。

本书不但书写Unix的历史,而且记录作者的回忆,一探Unix的起源,试图解释什么是Unix,Unix是如何产生的,以及Unix为何如此重要。除此之外,本书以轻松的口吻讲述了一群在贝尔实验室工作的发明天才的有趣往事,本书中每一个故事都是鲜为人知却又值得传播的宝贵资源。

本书适合对计算机或相关历史感兴趣的人阅读。读者不需要有太多的专业技术背景,就可以欣赏Unix背后的思想,了解它的重要性。

猜你喜欢

转载自blog.csdn.net/epubit17/article/details/120033113