Margaret Hamilton:报警声中,软件没有退场

本节阅读量:
Margaret Hamilton 站在 Apollo 飞行软件源代码清单旁。

Margaret Hamilton 站在 Apollo 飞行软件源代码清单旁。 图片:Wikimedia Commons

1969 年 7 月 20 日,Apollo 11 的登月舱 Eagle 正在靠近月面。

这本该是人类航天史上最紧张、也最精密的一段下降过程。燃料有限,时间有限,宇航员的注意力也有限。就在这时,计算机报警了。

1202

很快,又一次 1202

几分钟后,另一个报警号出现:

1201

登月舱里的 Neil Armstrong 和 Buzz Aldrin 等待地面判断。地面上的工程师也必须立刻回答一个问题:继续,还是中止?

最后指令传来:继续。

Eagle 没有因为报警而放弃任务。计算机并不是“没事”,它确实过载了;但它能重启,恢复关键任务,不再继续那些错误调度的次要工作,把导航、制导和显示留在前台。几分钟后,Eagle 落在月面;几个小时后,Armstrong 走下舷梯,人类第一次踏上月球。

这就是 Margaret Hamilton 这篇文章最应该从这里开始的原因:她的传奇不在“写了很多代码”,而在关键时刻,软件没有退场。


软件第一次如此醒目地站到台前

今天我们已经习惯了软件支配世界:手机、飞机、汽车、交易系统、医疗设备,背后都是程序。但在 Apollo 的年代,软件还没有今天这种地位。

那时很多人更容易相信硬件。火箭、雷达、仪表、导航设备,看得见、摸得着,也更像传统工程。软件则显得轻飘飘:一些指令,一些纸带,一些清单,一些会被改来改去的逻辑。

Hamilton 面对的正是这种时代缝隙。Apollo 需要软件,但软件必须证明自己配得上“工程”这个词。

她后来常被那张照片代表:一个年轻女性站在一摞几乎和她一样高的代码清单旁边。那张照片有一种奇妙的冲击力。它让人意识到,所谓“软件”,并不是屏幕上几行轻飘飘的字符,而是一座由判断、测试、异常处理和责任堆起来的山。


她不是一开始就在月球项目里

Hamilton 本科在 Earlham College 学数学,毕业后做过教师。后来她来到 MIT,先参与气象相关的软件项目,又为 SAGE 防空系统写过程序。

这些经历很关键。气象和防空系统都不是“算错了明天再改”的玩具项目。它们让程序员很早就面对真实世界:输入会混乱,设备会限制你,时间会逼你,错误会造成后果。

等她进入 Apollo 项目时,她带进去的不是“我会写代码”这么简单的能力,而是一种更严肃的直觉:

程序要假设世界会出错。

人会误操作,硬件会给出意外状态,任务会被打断,资源会被耗尽。真正可靠的软件,不是正常路径写得漂亮,而是异常到来时仍然知道自己该保护什么。


那个被小孩触发的问题

据 WIRED 对 Hamilton 的采访叙述,她有时会带女儿 Lauren 去 MIT 实验室。一次,Lauren 在 Apollo 模拟器的 DSKY 键盘上玩,误触发了飞行中不该进入的 P01 预发射程序,结果把模拟器弄崩了。

很多人可能会把这当成一次普通事故:小孩乱按,模拟器崩了,重启就好。

Hamilton 看到的却是另一个问题:如果真正的宇航员也误操作呢?

她想加代码防止这种情况,但当时有人认为宇航员训练充分,不会犯这种错。最后,她至少把警告写进了文档。

后来 Apollo 8 飞行中,Jim Lovell 真的意外进入了 P01。导航数据被清掉,MIT 团队不得不紧急想办法恢复。

这个故事不只是一个“她预判对了”的桥段。它真正说明的是:优秀的软件工程师会认真对待那些看起来“不该发生”的事情。

初学编程时,我们常常只关心主线能不能跑通。输入正确、步骤正确、环境正确,程序就输出正确结果。但真实系统从来不会这么乖。真实系统里,用户会点错,文件会损坏,内存会不足,网络会断,并发会乱序。

Hamilton 的不同之处在于,她很早就把这些“不该发生”当成设计的一部分。


Apollo 11 的报警为什么没有毁掉任务

Apollo 11 登月时出现的 12011202 报警,本质上和计算机负载有关。当时会合雷达相关的任务被反复调度,占用了本不该占用的计算资源。

关键点在于:系统没有平均对待所有任务。

它知道哪些事情更重要。它会重启并恢复关键任务,让导航、制导、发动机控制和显示继续运行。报警不是崩溃宣言,而是系统告诉人类:我超载了,但我正在保住最重要的事。

这背后不是某一个灵光一闪的技巧,而是一整套工程思想:

  1. 任务要有优先级。
  2. 失败要被检测出来。
  3. 恢复路径要提前设计。
  4. 正常路径和异常路径都必须被认真对待。

这就是 Hamilton 的贡献为什么重要。她不是只写了“能跑”的代码,而是参与建立了一套让软件在高风险任务中可被信任的纪律。


她改变了“软件工程”的分量

Hamilton 后来长期推动“software engineering”这个说法。今天我们听到“软件工程”已经没什么感觉,但在当时,这个词有一种争取地位的意味。

工程意味着什么?

不是随手写脚本,不是靠运气上线,也不是出了问题再补洞。工程意味着你要面对约束、风险、验证、边界和责任。

Apollo 让很多人看见了这一点:软件不是硬件旁边的小配角。它可能在最紧张的一刻决定任务能不能继续。

这也是为什么她的故事适合放在 C++ 学习网站里。C++ 给程序员很高的控制权,也把很多责任交给程序员。你可以管理资源,也可能泄漏资源;你可以写出高性能系统,也可能制造悬空指针、数据竞争和越界访问。

控制权越大,越需要工程纪律。


学 C++ 可以偷学什么

从 Hamilton 身上,C++ 学习者最该偷学的不是某个语法技巧,而是这几个问题:

  1. 如果这里失败了,程序会怎样?
  2. 如果用户误操作,系统会留下什么状态?
  3. 如果资源不足,最重要的任务是什么?
  4. 如果异常路径发生,我有没有真的测试过?
  5. 代码有没有把责任交给类型和对象,而不是交给人的记忆?

这会直接影响你写 C++ 的方式。

你会更愿意初始化每一个对象。你会更愿意用 RAII 管理资源,而不是把 openclosenewdelete 散落在各处。你会更认真地处理错误返回值和异常。你会知道并发代码里“看起来没事”不等于真的没事。


最后记住这个画面

一边是登月舱下降时刺耳的报警,一边是地面团队快速判断后的那句继续。

那一刻,软件没有成为任务的负担。软件帮助人类在混乱里保住了最重要的东西。

Margaret Hamilton 的传奇就在这里:她让程序不只是“能跑”,而是在真正紧张、真正危险、真正混乱的时候,仍然知道自己该守住什么。


延伸资料

  1. NASA:Margaret Hamilton Apollo software
  2. Apollo 软件故事,Wired
  3. Margaret Hamilton 传记,Britannica
  4. NASA Apollo 11 Mission Overview
  5. NASA Apollo 11 Lunar Surface Journal:1201/1202 报警
  6. 图片来源:Wikimedia Commons