这是「进击的Coder」的第 177 篇热点新闻
作者:OneFlow社区
来源:OneFlow
“
阅读本文大概需要 17 分钟。
”根据计算机领域的摩尔定律,如果在 18 个月内都还没有发布产品,几乎意味着项目要流产了。Windows NT 操作系统的最初计划也是 18 个月,但现在,他们已经整整研发三年了。
好在,这个大制作已经进入测试和 Bug 修复阶段,只差临门一脚。还有不到两个月,他们将最终交付这个计算机系统领域具有划时代意义的操作系统内核。“记住这美好的旧日时光吧”,大卫·卡特勒(David Cutler)希望工程师们再鼓一把劲。
如果这是美好时光,Windows NT 的缔造者们会觉得有点不幸。
经历一次次延期发布,所有人身心俱疲,单调和乏味充斥着日常工作,而卡特勒这个暴躁工头还在催赶工期,如果有工程师在家扎小人诅咒卡特勒,也不会让人感到意外。毕竟,在这个 1993 年的 6 月,为了解压和泄愤,他们就随手完成了一次集体性反动恶作剧。
一天,办公室上方掉下了一条百叶窗的绳子,落在了走廊上形成了一个圆环。不久这个环出现了一些硬币,随后又有人放入了一支玫瑰花,一些赌博用的筹码,奇怪的是,没有人清理掉这些东西。
很快,圆环里多了一个装糖果的盒子,还加入了一张卡特勒的滑稽大头照。两根蜡烛也随后出现在圆环外面,尽管没有点燃,但气氛似乎恰到好处,给卡特勒照片营造了一种诡异的肃穆感。
没错,那是献给卡特勒的祭坛。根据《观止:微软创建 NT 和未来的夺命狂奔》一书的描述,这些东西好几周都没有人移动,直到一天,卡特勒停下来问身边的同事那些鬼东西像什么,知道真相的他愤怒地走开了,也许是假装愤怒。
大多数工程师跟着他过着一维的生活,工作就是他们的全部。对下属,他更多展现的是粗鲁、严厉、蛮横、好斗、无情的暴君形象,甚至在招聘女秘书时会问怎么看 F 打头的那个词。然而,很少有人会质疑他对待工作的态度,专注、严谨、激情十足、不拘一格,具有天生领导力,而且有女性工程师看出他有时暴怒的背后只是虚张声势。
这些混杂的印象让很多人对他产生了一种微妙的情感,怨恨中带有丝丝仰慕,用当代比较时髦的词来形容,有些人说不准就会讨伐这个中年男是在“PUA”了。
有些牛人就是这样,厉害到能让别人忍受他身上的种种缺陷,更不用说卡特勒这种被誉为 engineer's engineer(“公鸡中的战斗鸡”)式的人物。
戈登·贝尔和比尔·盖茨是他职业生涯中最重要的两个伯乐。大学毕业后的卡特勒先在杜邦公司自学编程,而后入职 DEC,1970 年代后期在时任 DEC 副总裁的贝尔支持下,开创性地开发了 VMS 操作系统,贝尔称他是世界上最好的操作系统编写者。
1988 年,在盖茨的招募下,他来到微软,历时 5 年花费 1.5 亿美元,领导 200 多位工程师开发出有 430 万行代码的 Windows NT。其技术革命性严重冲击了 Novell 的 Netware 和 UNIX 操作系统的地位,为微软带来不可估量的商业价值,影响着超过 20 亿人的计算体验。也因此,他成为迄今为止唯一一位享有微软 Senior Technical Fellow 头衔的工程师,待遇比肩集团 VP。微软前 CEO 鲍尔默更是直言,没有他,就没有今天的微软。
不过,相比对这个世界产生的影响,他在外界的知名度却不如同级别的 Linus Torvalds,Jeff Dean 那样响亮。但他对此毫不在意,只专注于高质量地完成工作,奉行行胜于言。他会强势向你展示一种让可能性变成现实的决心:我就是喜欢做这件事,我就要做成这件事。
Windows NT 就是卡特勒决心要实现的那件事。
1
“双非”工程师的逆袭
不同于大多数有着显赫经历的牛人,卡特勒既非计算机科班出身,也非名校毕业生。在奥利韦特学院(Olivet College)上大学时,他拿的是数学学士,对电脑一窍不通,毕业也并不想从事编程这种“似乎非常缺乏创造力且枯燥的工作”。
后来,他进入杜邦公司从事材料测试,但工作任务无可避免地需要编程来建模,卡特勒只好去 IBM 开办的学校去学习编程,并将他写的代码运行在 DEC 的小型机上,假以时日,竟然不小心成了 DEC 计算机专家。
这段经历让他在 1971 年顺利进入 DEC 公司编写软件。在那里,他为 DEC 的 PDP-11 计算机构建实时操作系统 RSX-11M 时发挥了关键作用,通过结合总体概念和设计原则,利用汇编语言在非常有限的内存空间内实现了多项系统功能,比如树型文件系统、交换应用程序、实时调度和一整套开发工具等。过硬的技术和积极工作赢得了赞誉,尽管他的暴脾气没给任何人留下好印象。
还好有贵人识才。有 DEC 技术灵魂之称的贝尔发现卡特勒是个一流工程师,还让他主导为新的产品线 Vax 编写 VMS 操作系统,这个系统需要满足向后兼容已有应用,同时要能在不同配置的 Vax 计算机上运行。巨大压力之下,他花两年时间完成了这一任务,35 岁的卡特勒一战成名。
(左为戈登·贝尔,右为大卫·卡特勒)
当打之年的卡特勒有着远大抱负。但 DEC 日益增长的官僚气息让他无法忍受,并威胁要离开公司,贝尔挽留了他。1985 年,DEC 给他约 200 人的软硬件工程师来设计一个全新的计算机系列 Prism,其操作系统叫 Mica。
起初,这个团队几乎像一个独立的公司那样运作。可好景不长,期间贝尔离开后没人罩着,DEC 其他部门对卡特勒团队的业务下手了。
1988 年 6 月,DEC 总部告诉他项目完全取消。心灰意冷的卡特勒准备离开。几年过后,当一个类 Mica 的操作系统问世之际,DEC管 理层会为当初放掉这员猛将而付出“代价”。
彼时,计算机产业正处在激情澎湃的技术革新期,新的软硬件创业公司层出不穷,如 OneFlow 此前写过的思维机器和 Multiflow 公司。
正如日中天的却是微软,DOS 系统的成功让盖茨迈向美国首富,但他却嗅到了面临的危机。微软的现金牛 DOS 可能面临潜在威胁:一是 RISC 芯片的出现可能取代英特尔芯片,DOS 却与英特尔的芯片高度绑定;二是许多公司开始销售装有 UNIX 的电脑。要应对这一难题,他想要微软开发一个可移植的操作系统运行在任一 RISC 芯片上,成为个人计算的通行标准,这个新系统叫Windows New Technology,也就是 Windows NT。
卡特勒要离开 DEC 的消息传到了盖茨那里,相约见面后,这个看起来很自负的工程师从上到下喷了一顿微软的产品,但后者认定,他将是领导新操作系统团队的最佳领导人选。大把股票、自主选择研发团队和开发新操作系统的机会,以及盖茨表现出的诚恳态度最终将卡特勒这个狂人收入麾下,入职后还顺便招募了不少他在 DEC 时的死忠。
2
踌躇满志却状况百出
初来乍到,卡特勒团队与“微软人”一度互相看不上,他把团队搞成了前 DEC 工程师的小圈子。
为了让新人融入微软体系,盖茨将足智多谋的骨干工程师 Steve Wood 派到了这个团队。Wood 曾接手被微软最大的客户 IBM 大力支持的 OS/2 系统,这是个 16 位操作系统,只能在英特尔硬件上运行且不可移植。他对卡特勒没有盲目崇拜,但发现与其他团队成员倒是“臭味相投”。
经过几个月的持续招募,在 1989 年 4 月,一个较为完整的 NT 团队就绪,带着失意、愤懑的复仇情绪,卡特勒准备大干一场。
NT 操作系统的目标既具挑战性又雄心勃勃:
可移植且可用于多个目标(MIPS、Alpha、PowerPc、x64)
可以在多个操作系统(POSIX (UNIX)、OS/2 和 Windows 32)上运行
安全性和 C2 认证(受信任的计算机认证)
在具有多个处理器的系统上运行,并且能同时运行多个程序,这在当时 PC 市场上独有
高可靠性的要求使得卡特勒将 NT 分成了两个部分:一个是内核,不与程序发生关联,不会被它运行失败时所影响,另一个是操作系统的图形化部分。这个模式的最大问题是会牺牲系统运行的效率。盖茨也表达了质疑,但卡特勒坚称,他们会以高超的编程技巧弥补性能不足。
根据日程表,他们打算在 1990 年 7 月写完NT的所有代码,并在 1991 年 3 月 30 日交出最终版本。很快,那些预料之中和始料未及的挑战会让他一次次食言。
首先是技术上的难题。一方面,支持和测试 NT 系统的机器还没制造出来,在英特尔的 i860 芯片上运行 NT 的代码,效果太差,而切换到卡特勒看好的 MIPS 芯片要走很多回头路,后来他们切换到英特尔的 386 系列芯片,但还是必须忍受硬件的毛病。另一方面,缺乏编程工具拖慢了系统研发的进展,打造工具也分散了团队的部分力量。
其次是团队磨合不畅。卡特勒只想专注小团队去开发 NT 内核,不想负责管理与之相关的图形、网络、测试小组。他们各自工作风格不一,卡特勒甚至把测试小组当做累赘,他从不依靠测试小组,认为测试工程师只会让程序看起来更糟糕。这种偏见源自他的个人编程风格,在写代码前,他会先在头脑里形成代码图,然后高精确度地写下极少有 Bug 的代码,每一行代码都有注释。
同时,他还要很不情愿地根据项目经理带来的客户意见来修改代码和功能。
1990 年春天,图形可视化部分也遭遇严重困境,尤其采用 C++ 语言使得程序容量超过计算机内存,而 MIPS 芯片的发布也延迟了,盖茨还把 NT 向 386 芯片移植的工作视为项目最高优先级,但是没有完成。
更糟糕的是,不少人怀疑模型 NT 的客户-服务模型会降低运行应用的性能,包括盖茨也因为害怕牺牲太多速度,始终没有认可这种模型。但卡特勒依然坚信他们会解决这个问题,在系统的可靠性和速度之间做出选择时,他最不能容忍的是不稳定。
至此,要在 7 月写完所有代码的计划不可能实现。卡特勒讨厌不能如期兑现承诺,种种问题让他很崩溃,但现在没法撂挑子了,除了测试部门,网络、图形、兼容性等团队都交由其管理。他第一次感觉到,自己的事业与 NT 的命运已经联系在一起。
3
截止日期节节败退
1990 年 6 月,Windows 3.0 的发布让整个软件行业大变样。他们开始思考如何将 NT 运行到 Windows 上。但最大的矛盾在于,OS/2 和 Windows 控制系统 PC 的方法互不兼容,这让客户和工程师都变得难以适从。对微软来说,他们不可能主要去支持 OS/2,但也不想与最大客户 IBM 产生决裂。
盖茨给 IBM 灌了两斤迷魂汤。他让后者相信,NT 分别支持 Windows 和 DOS 系统将带来诸多好处,尽管这与他建立统一软件标准的说法有矛盾。背地里,微软只让来自以色列的一小队人马去设计 NT 的 OS/2 变种,而卡特勒团队却向 Windows 发展成计算机标准这一真正的目标前进。
对卡特勒个人来说,此举不仅让他摆脱了 IBM,也将实现替代 UNIX 的期望。他早前就以蔑视 UNIX 而闻名,认为这是一帮博士设计出来的垃圾。那时的 UNIX 缺乏对系统资源配额的支持(例如,任何进程都可能通过分配过多内存或 fork() 循环导致系统崩溃),还缺乏 VMS 风格的进程权限、微内核架构,以及缺乏对多个子系统的支持。
半年后,IBM 才发现到被微软摆了一道,还是后者主动披露的。1991 年 1 月,在微软举办的应用软件开发者大会上,IBM 工程师幻想着微软NT团队会介绍支持 OS/2 的内容,但直到演讲快结束都有提到。IBM 工程师当场质疑,NT 工程师挑明要放弃支持 OS/2,这导致 IBM 解除了与微软的合作关系。
随后新的研发进度表出炉,卡特勒承诺会在 1991 年 10 月 31 日,在万圣节前 NT 代码将会完成。而测试和修 Bug 的工作则会推迟到 1992 年的第二季度,这也是把 NT 交付给客户的时间。
NT 逐渐成型,卡特勒希望团队都能尝试使用 NT 系统,这样就可以检查 NT 各个部分存在的缺陷和瑕疵,并对某些类型的程序缺陷进行改进。他们将转换到 NT 系统的计算机上分为三个阶段:纯内核 NT、图形以及网络阶段。
真正评判代码优劣的方法就是运行代码。随着更多工程师使用 NT,他们发现,要在 NT 上完成一件工作非常困难,不得不花费数小时甚至数天时间进行修复 Bug,大大影响了项目的进度。直到 1991 年 5 月底,没有 Windows 图形的 NT 版本运行得很快,可依然是个很差的替代品。
1991 年 8 月,他们需要在三个月内基本完成 NT 的程序以赶上截止日期,但现实是,NT 的代码最多只能完成 80%。这时 NT 团队要考虑的是系统的安全性问题,主要是防止信息篡改。他们大大低估了这个工作的难度。再一次,卡特勒放弃了在 10 月完成 NT 的计划,那时即使是最好的版本都有很多缺陷,而且性能上也有局限,尽管此前的测试表明 Windows 应用在 NT 上运行只比在 DOS 上慢比较小的百分点。
他给的最新截止日期是 1992 年 4 月。没有人比他更想看到 NT 早日发布。
除了统一 NT 的两个版本进展缓慢,让他更头疼的是不断新增的新功能,比如容错性,直到 1991 年圣诞节前夕都没有完成,文件系统也迟迟没有定型。甚至到 1991 年底,测试都没有开始。兼容 DOS 和 Windows 应用的进展也落后了。而图形小组由于使用 C++ 而不是更容易的 C 语言降低了效率。
也不全是要延期的坏消息。卡特勒用强硬手段帮助团队度过了难关,使得 NT 的 MIPS- 英特尔版本在圣诞节前发布。在开发早期阶段,NT 就达到了一个在其他系统上很难达到的水平,在他眼里这是一个重大成就。
项目进度安排很严谨,但研发过程中的项目工作量依然充满未知。1992 年 2 月,这是研发 NT 的第三年了,卡特勒的计划一次次被 NT 的复杂性作弄。
节节败退的日程表让他很不安。卡特勒一直认为,操作系统的开发最好是尽早发布第一个版本,更多功能将来可以再添加,但 Windows NT 开发到现在已不只是按照他的个人想法可转移。
这次,他把公开测试版推迟到了 7 月 1 日。
焦头烂额之际,卡特勒得到了一个意外喜讯。他的老东家 DEC 同意成为购买 NT 的第一个计算机制造商。在他看来,被 DEC 取消的 Mica 项目和 NT 大体是等价的,实际上,NT 的许多元素都有他在 DEC 做系统时的技术映射,比如内存管理、进程和调度与 VMS 非常相似,而 DEC 现在却花大价钱买下原本可以免费拥有的东西,这让他体会到一丝复仇打脸的快感。
4
混乱终将变得有序
随后卡特勒要求团队快马加鞭,让工程师注意细节,为了激励他们的斗志,有时还亲自上阵负责写模块。
终于,1992 年 6 月 29 日,他们发布了一个 WindowsNT Beta 版本,主要改善了系统的质量和可靠性。接下来,他们需要花几个月时间完成未完的功能、修复 Bug、提高性能并尽可能减小 NT,最终版本将在年底发布。
太大、太慢是一直困扰他们的关键问题。有人调侃,NT 是一头吃内存的飞猪,在性能方面是一只蜗牛,这两个指标离盖茨在三年前设定的目标还很远。
卡特勒承认 NT 太慢,但现在差不多达到他的期望了,因为对性能的改进没有止境。软件历史充分证明,从 IBM 的 360 到不同风格的 UNIX,再到微软的 Windows,几乎所有划时代的系统都是在不成熟的状态就发布出来,然后逐步演进并赢得更广泛的认可。
内存方面,盖茨的公开目标是将 NT 的最低内存要求设定为 8MB,但现在至少需要 16MB 才能满足典型用户的应用需求,而当时大多数个人电脑装备的是 4MB 内存,而增加内存容量的话要花更多成本。
至此,盖茨只能放弃了在 8MB 内存的 PC 运行 NT 的打算,但在性能的问题上他不会让步,当时操作系统业务大约占微软所有销售额的一半,如果这一点不能满足客户的要求,它们就可能转向 IBM 的 OS/2。
一次次的延期发布挫伤了团队的士气。但催促连续不断,而且没有明确的结束期限。当大多数人认为这个操作系统快结束了,其实还有几个月的乏味测试,以及尚未完成的功能和性能改进等着他们。每天大约有 2000 个 Bug 需要解决,卡特勒关注 Bug 数量,就像关注着战场上的伤亡数字。
他制定的残酷进度让很多人难以忍受,尤其最后的死亡行军期间,很多团队成员挣扎在工作和个人生活这条线上,让他们跟情人、朋友、孩子的关系变得很紧张。卡特勒二次婚姻破灭,基本没有家庭生活上的牵绊,也一直待在战壕里。NT 团队此刻的拼劲后来也激励了一位来自遥远东方的深度学习框架创业者,在《观止》的第 187 页空白处,他写下了一段批注,“看看创造奇迹的人”。
距离创造奇迹还有一步之遥,只是卡特勒再没敢承诺系统发布的准确时间。为了提升团队士气,他在全员邮件中重复着他的口号,“记住这美好的旧日时光”。
1993 年 6 月 21 日,NT 的发布终于进入倒计时,为了庆祝项目即将生产,工程师们为他献上一个祭坛。一个月后的 7 月 26 日,Windows NT 终于发到工厂生产了。
独自坐在办公室的卡特勒难掩激动心情,他发布了一封全员邮件,开头写着:NT 发布了,再说一遍,NT 发布了——一连摁了 5 个感叹号。
5
那美好的旧日时光
卡特勒似乎是那个注定为 Windows NT 而生的人,它的成功占据天时地利人和。
微软迫切需要一个可移植的操作系统来帮助其赢得未来,它拥有打造这个系统所具备的足够资金和人才资源,但只差卡特勒这样的技术领导者,同样不容忽视的是,盖茨和鲍尔默给了他本人最大程度的信任和支持,在微软王国里封给了卡特勒一片拥有高度决策权的自由领地。
远大目标的呼召和自由的管理空间对卡特勒推进 NT 至关重要。在这里他完全施展了他独特的领导和技术才能。NT 团队没有固定的汇报层级,他本人拒绝过度管理,讨厌复杂的规章制度,尽可能不插手下属的工作,相信最突出的才干会在人数较少的小团队中显现。他在分配工作时留有一定灵活性,喜欢让每个人扮演不同角色,可以主动解决没有明确职责归属的事,而不是画地为牢。
卡特勒像是同时兼电影导演、演员和场务于一身,他证明自己可以把混乱的系统变得有序,不管它有多么难控制。
作为导演,他依赖于召集到的所有人的才能,同时将自己的思想和偏好施加到下属身上。如果在方向问题出现各种创意和分歧,最后由他拍板如何去做。他的挑战在于如何让这些有才华的人遵循同一份进度安排,服从同一份通知。同时,作为演员和场务,他又能时刻亲自上阵,为系统的每一条程序把脉,值得一提的是,NT 的 177 个 .c 文件出自卡特勒,比 NT 首席架构师 Mark Lucovsky 还要多一倍。在长期无序的技术架构和组织结构演变中,他是运筹帷幄的那个人。
可以想象,在研发 Windows NT 的 5 年里,如果不是由卡特勒这样执着、强悍的猛人把持,要带领 250 名精英工程师在心力交瘁的上千个日夜里不断推进绝非易事,换个人领导 NT 团队可能会是另一番光景。
当然,NT 的成功离不开每一位工程师付出的艰苦努力。而该项目后来的巨大成功也证明,他们的付出是值得的。一直到 2001 年 Windows XP 发布,NT 已成为所有 Windows 产品的内核系统,包括 2021 年最新发布的 Windows 11,而它却是一个 30 年前设计的系统,老年的卡特勒会自豪地告诉你,那全部都基于 NT。
这离不开 NT 内核的技术创新。从NT发布的第一天起,其诸多特性从根本上保证很多方面优于 UNIX,以及后来的 Linux:
日志文件系统 NTFS,具有抗崩溃能力和性能。Linux 在 NT 发布 6 年后开始才具备类似的日志功能集
含有第三代扩展文件系统 ext3。
服务。在 UNIX 里,“守护进程(daemons)”是常规进程。要启动一个守护进程,你必须知道它的位置、语法和依赖关系。而 NT 允许用户集中管理服务进程并自动管理它们的依赖项。GNOME 和 KDE 在 2000 年有了类似 NT 的服务概念,几年后被 DBus 标准化。MacOS 和 SystemD 则分别于 2005、2011 年才有。
注册表,用于存储和检索应用程序配置数据的统一模型。UNIX 在 /etc 中有任意格式的文本文件,但在实践中效果不佳,导致产生版本控制/隔离问题。
线程和进程有很大区别。UNIX 将进程作为执行和地址空间的单位,它的一些实现支持线程(或 LWP,轻量级进程),但在 POSIX 线程出现前,它们的创建成本更高且非标准。
NT 的模块化设备驱动架构允许在系统初始化后加载设备驱动,而当时的 UNIX 通常将驱动编译到内核中。NT 还支持 PnP 和“设备树(device trees)”,所以可以正确计算驱动初始化的依赖项。2003 年,Linux 才具备“统一设备模型”能力。
一个 O(1) 调度程序。直到 2003 年 Linux 才具备。
NT的内核是“可抢占的”,有更好的系统响应能力和并行处理性能。在 OS X Leopard 前,OS X 的抢占性(粗粒度锁定)非常有限。Linux 在 2011 年才摆脱了粗加锁方式。
1996 年,卡特勒停止管理整个 NT 项目,但继续领导内核开发直到 2006 年。自 2000 年以来,他参与开发了每一个 Windows 版本的核心技术,包括第一个完整 32 位的 Windows 版本,同时对 AMD64 平台的 Windows XP、Server 2003 系统做出重要贡献。后来随着计算机行业从服务器转向云服务,他在 2008 年担任微软 Azure 云计算平台的主要开发者。2012 年,他参与开发了 Xbox 主机操作系统部分。
在几十年职业生涯中,他在架构设计、编码、注释等方面表现出的严谨风范,深刻影响了微软技术团队的工程文化,这也是他影响工程师的永久性遗产。
如今,这位出生于 1942 年,现已是 79 岁的高龄工程师依然还会去办公室写代码。他喜欢完成自己的代码,然后看着它正常工作。休息间隙,这个倔老头儿或许还会忆起开发NT的那美好的旧日时光。
题图源自微软官网、维基百科
参考资料
1.《观止:微软创建NT和未来的夺命狂奔》,G. Pascal Zachary著,张银奎等译
2.https://news.microsoft.com/features/the-engineers-engineer-computer-industry-luminaries-salute-dave-cutlers-five-decade-long-quest-for-quality/
3.https://retrocomputing.stackexchange.com/questions/14150/how-4.should-we-interpret-dave-cutlers-criticism-of-unix/14151
5.https://en.wikipedia.org/wiki/Dave_Cutler
6.https://en.wikipedia.org/wiki/Windows_NT
7.https://www.tech-insider.org/windows/research/1993/0526.html
End
「进击的Coder」专属学习群已正式成立,搜索「CQCcqc4」添加崔庆才的个人微信或者扫描下方二维码拉您入群交流学习。
看完记得关注@进击的Coder
及时收看更多好文
↓↓↓
崔庆才的「进击的Coder」知识星球已正式成立,感兴趣的可以查看《我创办了一个知识星球》了解更多内容,欢迎您的加入:
好文和朋友一起看~