作者 | Peter Wayner 策划 | 万佳 为什么几十年前,NASA 可以开发出软件而成功登上月球,而现在的程序员却不能开发出一款有效的投票 App。
先说一件事:
最近,美国ai荷华州召开民主党总统候选人初选大会。以前,选举都是使用纸质投票的方式进行,这次要使用一款名为“IowaReporterApp”的电子计票应用程序。与纸质投票的人工计票方式不同,这款 App 最初有望投票 2 小时后快速公布投票结果。然而,让人大跌眼镜的是,这款 App 在使用时发生故障,导致大规模混乱,一直到第二天还未能公布结果。
最后,人们将数据导出,重新进行纸质计票审核。目前,该 App 的整个后端已经关闭,无法通过它或公司服务器访问任何信息。(更多信息,参见 InfoQ 报道《花 40 多万开发的 App 扰乱了一场大选,几乎毁了一家公司》)
https://www.infoq.cn/article/AyrPxtjpAkTCNm9jNF5z
InfoWorld 的编辑 Peter Wayner 撰文写道,对程序员而言,ai荷华州召开民主党总统候选人初选大会计票软件的失败是一个残酷提醒,告诉他们事情会变得有多糟糕。
简单的投票计数并不像有些事情那么复杂,比如制造一辆自动驾驶汽车、训练人工智能推荐电影,甚至安全更新银行数据库,但是程序员们没有成功。有一条带有恶意的推文写道,“很难相信,我们把人类送上了月球。”
https://twitter.com/DamonLinker/status/1224823407457554434
问题在于将这件事与登月相比是不公平的。
尽管引导阿波罗着陆器登上月球似乎比制表统计几千张选票要更困难,但是,所有与现代选票统计相关的额外工作让它变得更复杂。
有些部分变得更容易。新兴的“无服务器”让我们只需编写最基本的逻辑就行,但我们还未做到这一点。
当然,编写函数更简单,而其余时间我们都在处理配置选项。
我们花数小时编写几百行 YAML 代码,详细说明一个又一个的决策,但由于某些原因,这并不被认为是“编码”。
不管是不是编码,所有这些想法都有一定的道理。不是程序员就不会理解这一点。这里有一些可以解释的因素,而不是当作借口的理由。
当今,开发软件是非常困难和复杂的。
1 以前的代码更简单
想了解 NASA 的工作是怎么做的,最好的方法是阅读一些代码,这些代码被保存在 GitHub 存储库中。
https://github.com/chrislgarry/Apollo-11
随机选择一个文件,例如 GROUND_TRACKING_DETERMINATION_PROGRAM.agc,该文件有 204 行,其中超过 85 行是注释。与现代语言不同,每一行只包含一个操作,而现代语言可以将几十个具有多个选项的操作打包到一行中。
https://github.com/chrislgarry/Apollo-11/blob/master/Comanche055/GROUND_TRACKING_DETERMINATION_PROGRAM.agc
当你浏览这些文件时,明显感觉到它很简单。尽管代码在打印出来并放入活页夹时看起来令人印象深刻,但它只有几百个文件,大多数都很小,而且有非常详细的注释。
要知道,他们必须如此,阿波罗制导计算机只有 36K 的 ROM 来存放编译好的版本。
https://en.wikipedia.org/wiki/Apollo_Guidance_Computer
这意味着程序员可以很容易地忽略一些特性请求,只专注于最重要的步骤。
对大多数现代程序员来说,代码本身看起来难以理解,因为现在很少有开发人员学习阅读汇编语言或机器码。而学习编写的人就更少了。
虽然它看起来很神秘,但语义要简单得多。毕竟,机器只有一些寄存器、少量 RAM 和几个用于分支的 IF-THEN 选项。
将这些规则与现代程序员处理 closures 或 recursive object data 等抽象时必须掌握的规则进行下比较。Java 团队现在正推出第 14 版,一路走来,每个新版本都提供了新机制。
即使是旨在简化编程的思想,比如 JavaScript 中的回调函数,也需要相当的抽象思维。
https://www.infoworld.com/article/3322904/asynchronous-javascript-callbacks-and-promises-explained.html
一旦你弄明白汇编程序的神秘指令名,它实际上就比较容易编写了。
2 那时的安全更简单
对于发射,NASA 的安全措施很严格,但程序员们不必为连到互联网的机器编写代码而操心。
阿波罗制导计算机只与休斯敦通信,而且频率很低。而现在,每一部智能手机都在后台不断地与数十个可能背地里存在恶意的网站和服务进行交互。
这让如今的代码发布成为一个安全噩梦。
为保证一切安全,部署一个基本的容器需要处理一个特殊的文件,其中包含所有的密码和“secrets”。
Android 和 iOS 应用程序开发人员必须管理多个密钥来为他们的应用程序签名,然后才能上传至应用商店。如果这些 secrets 中的任何一个泄露出去,那任何一个连到互联网的人都有可能强行进入并按自己的方式使用它。
现代的互联网显然更复杂,里面有很多“坏人”,而垃圾邮件发送者、劫持者和网络钓鱼分子还算“好的”。
3 那时功能是重点
当时,还没有设计委员会考虑按钮是否应该移动一两个像素。
没有启动画面、没有移动图标、没有背景阴影,也没有数百万种字体。直到 1961 年,IBM 才推出可更改的字体 Selectric。
https://www.ibm.com/ibm/history/ibm100/us/en/icons/selectric/
虽然现代程序员能利用优秀的标准,如 HTML、CSS 和 SVG,以及不计其数的库,如 React 或 Vue,但同样的程序员也必须遵循这些标准。
只要这些小真空管还在发光,宇航员们就很高兴。
4 那时的移动部件更少
机械工程师往往会计算移动部件的数量,并将其作为衡量复杂性的指标。
月球着陆器的导航计算机有一项非常重要的工作,就是跟踪位置,仅此而已。
智能手机在同一时间做了无数事情,其中很多都被不加思考、漠不关心的大众认为是理所当然的,但是,如果应用程序在几毫秒内没有响应,他们就会卸载它。
所有这些都增加了复杂性。自动化构建代码、定义良好的 API 和无穷无尽的库意味着程序员可以让持续集成 pipeline 中的“精灵”来做大部分工作,但复杂性仍然存在。
一个仅打印“Hello World”的 Go 应用程序使用 1.7 版本编译只有 1.6MB,而 Go 社区对这个消息感到很兴奋,因为它之前有 2.3MB。
https://blog.golang.org/go1.7-binary-size
5 那时可免于和律师打交道
根据我的计算,在亚马逊云服务上租用一台机器的基本服务条款有 2.2 万字。为使用网站租用机器,还有一个完全不同的服务条款。
https://aws.amazon.com/service-terms/
https://aws.amazon.com/terms/
然后,每个单独的产品通常都有自己的 TOS,比如 Activate。它们加起来比月球着陆器电脑 ROM 里 36000 个指令字还要长得多。
https://aws.amazon.com/activate/terms/
阿波罗程序员不知道电影《外星人》会有这样的广告语:“在太空中,没有人能听到你的尖叫”,但他们理解这个想法,也知道这意味着趁人之危的律师听不到你的声音。
相关阅读:
https://www.infoworld.com/article/3519612/5-reasons-we-dont-write-code-like-we-used-to.html