踩下刹车时,中间隔着一台电脑

原标题When You Hit the Brakes, a Computer Is in the Way

Bjarne Stroustrup 谈 C++ 为何仍然站在踏板与刹车片之间,以及为什么要多付代价的抽象不该进入这门语言。

BSBjarne Stroustrup嘉宾
频道
Lex Fridman Podcast
发布
2019年11月7日
视频
1:47:13
阅读
24 分钟
原文
英语
在 YouTube 打开
往下滚动阅读时,视频会缩到右下角继续播放。字幕跟随阅读语言。
阅读语言共 2 种语言可读
由 AI 从英语原文翻译。打开“对照原文”可以逐段核对。
摘要

30 秒看懂

2019 年与 Lex Fridman 的一次对话中,C++ 的创造者 Bjarne Stroustrup 把四十年的设计选择追溯到几条约束:性能、可靠性,以及在电话交换机里运行十年后依然能工作的代码。他主张,安全是整个系统的属性;零开销原则不只是一句口号,它还是筛选特性的过滤器;用于预筛选的机器学习准确率已经足够,却不足以用在那些绝不能请睡着的司机出手相助的机器上。

  1. 1Simula 给他上的一课是:模块化可以做得很漂亮,这样程序的问题就只与规模同步增长,不会随着规模的平方一起膨胀。
  2. 2缓存一旦用坏,性能会暴跌到原来的百分之一,而且这笔账不因语言而异。
  3. 3在他看来,现代 C++ 编译成汇编的样子颇为难看:原本那些类 C 的部分,落到机器码上后体积膨胀,面目全非。
  4. 4直接把想法表达出来,程序往往反而更快;机器因此更少,可能出故障的硬件也更少。
  5. 5只剩一种实现时,它的主人会慢慢僵化:没人竞争,也没人逼着他创新,阻碍改变反而对他最有利。
  6. 6在他看来,要是一个 AI 只给睡着的司机三秒钟去接管,那就是架构选错了;他宁愿在反应堆和汽车里,都不指望人来兜底。
全文

按章节阅读完整文稿

01

踩下刹车踏板时,踏板和刹车片之间没有机械连接

Stroustrup 提醒听众,踩下汽车刹车踏板时,踏板并不与任何机械装置直接相连。中间有一台电脑,而且这台电脑必须靠得住。这类机器上的大量代码,都是用他于 1979 年开始开发的语言写成的。C++ 仍然支撑着 YouTube 的关键后端部分,谷歌、Facebook、亚马逊、Twitter、微软的大多数应用、大多数数据库系统,以及真正在世界上运动的那些物理系统,比如汽车、机器人和火箭,也都离不开它。

Lex Fridman 本人写过数十万行 C++ 代码,2019 年他把 Stroustrup 请到了《Artificial Intelligence Podcast》。这场对话并不纠缠于语法,更像是 Stroustrup 在讲述四十年来的各种取舍:什么必须快,什么必须可靠,以及他宁可根本不放进语言里的东西是什么。

Stroustrup 记得自己写的第一个程序,是大学二年级的作业。他要计算一个椭圆的形状,把周长上的点连起来,然后在纸上打印出星形图案。他是在大学二年级才开始学编程的。他最钟情的第一门语言是 Algol 60。Fortran 没能让他着迷,Pascal 也没有。“它总是处处碍事。”

02

Pascal 的类型系统碍事,Simula 更严格的类型系统却帮了忙

汇编语言更有意思。之后他认真投入了一段时间的 BCPL,那是他第一份真正有报酬的工作,还负担了他的硕士学业。然后他发现了 Simula,它是 Algol 60 的扩展,主要为仿真而设计。在此过程中,它的设计者发明了面向对象编程、继承和运行时多态。Simula 让他明白,程序的问题可以随着规模增长,而不是随着规模的平方增长。“你其实可以把它模块化得很好。这让我大吃一惊。”

第二个意外和类型有关。Pascal 的类型系统总是妨碍他,而 Simula 的类型系统比 Pascal 更严格,却反而帮了他的忙。这个教训后来变成了他设计 C++ 时的一条信念:要组织代码,你需要强大的类型系统,而且它必须可扩展、足够灵活。以他的记忆,Pascal 大致就是 Niklaus Wirth 在当时的需求下能定义出的最简单的语言。它带着一种颇有道德说教味道的口吻:如果你能用 Pascal 表达,那就是好的;如果不能,那就是不好的。

相比之下,Simula 让你自己搭建类型系统,而不必把自己塞进 Wirth 的那个世界里。你真正构建的,是一组类型以及类型之间的关系,用来描述某个应用,这接近于最初的领域特定语言(DSL)的理念。凡是用 class 这个词来表示类型的语言,直接或间接都是 Simula 的后代。它的设计者是数学家。他们思考的单位是元素的集合与类,而非类型,所以他们把类型称为 class。

03

消防车左转,正是继承存在的理由

人们常常只学会类层次结构和虚函数,却忽略了 Stroustrup 认为更根本的东西:你是想用自己的类型来写程序,并受制于自己的硬件和环境约束。当类型彼此相关、而你又不希望它们各自独立时,类层次结构才有意义。经典的例子是一组车辆。如果是自行车,就写自行车左转的代码;如果是汽车,就写汽车左转的方式;如果是消防车,就写消防车左转的方式。最后你就得到一堆巨大的 case 语句和层层嵌套的 if。

有了继承,你只需要告诉基类,也就是“车辆”,让它按自己的方式左转。每一种具体类型都已经知道怎么做。这并不是教科书里的卡通例子。他说,1960 年代,有人就用它来仿真和优化某个地方的急救服务。你需要继承和运行时多态,是因为你想以一种可控的方式处理一组车辆,而且每次出现一种新车辆时,你都不必重写调度代码。

Fridman 把 Lisp 列为自己最喜欢的语言之一。Stroustrup 很坦率:Lisp 很重要,也很有意思,很多人用它写代码,但等到要上线的时候,又会用 C 或 C++ 重写。他的世界受制于性能、可靠性、可部署性和硬件成本。他不喜欢太过动态的东西。一段代码,既完美又灵活,小到能跑在普通电脑上,还能放进波哥大的一台电话交换机里,这种可能性有多大?如果那台交换机在周日深夜出了故障,而你发现自己正在调试器里摸索,那么现场站着一个程序员的概率为零。

04

专业人士应该掌握五门语言,第二门最重要

Stroustrup 说过,一个专业程序员至少应该掌握五种语言。他自己估计,他大约掌握过二十五种。在他做 C++ 的那个年代,语言规模较小,学一门语言不必先吞下整套编程环境。重要的不是某个具体数字。只会说一种语言的人,就像只生活过一种文化的人,很可能会觉得自己的生活方式是唯一的。第二种语言是最能改变你思维方式的那一种。过了这一关,凑齐五种语言也就不算太远了。

被问到到底该掌握什么,他给的是一类类的知识,而不是一份固定清单。即使在今天,C++ 的优化器会替你生成机器码,懂机器码依然是好事。他认为,如果不了解机器码和机器架构,他就无法欣赏那些优化器。实际的理由很残酷:一旦搞乱了缓存,性能就会差上一百倍。如果你在乎速度,或者在乎你要部署的那台计算机有多大,就无法忽视这一点,而这种代价并不属于哪一门语言。

如今,靠下沉到底层来换取性能已经不再有效。真正有效的,是把想法表达得足够清晰,让你自己能想明白,也让优化器能看懂你想干什么。他现在最喜欢的优化手段,是把那些耍聪明的部分统统扔掉,看看程序是否仍然跑得很快。有时候,它反而跑得更快。所以他需要像 C++ 这样的抽象机制,来写紧凑、高性能的代码。再加上一门函数式语言,比如 Haskell 或 ML,他并不在乎具体是哪一门,用它来获得严格的类型和清晰的数学表达;还需要一门能快速搞出东西的语言,比如 JavaScript、Python 或 Ruby。

05

类 C 的代码编译之后,变得更丑、也更大

他提到 Jason Turner 在 CppCon 上的主题演讲。Turner 决定在摩托罗拉 6800 上编写 Pong 游戏。他认为,这台机器看起来仍然像一块微控制器:硬件专用,内存很小,速度相对较慢。Turner 现场从相当直白的底层代码开始,借助 C++11 提高抽象层次,并看着 Compiler Explorer 把它翻译成汇编。即使你读不懂汇编,也能看出效果:源代码变得更干净,更容易维护。它越来越短,而且还在继续变短。

Stroustrup 说,他在合理的时间内,根本写不出比编译器从相当漂亮的现代 C++ 生成的代码更好的汇编。他更进一步:那种看起来像 C 的代码,一旦变成机器码,会明显变得更丑、更大。这次演示把抽象从审美问题拉回到了工程问题。只有优化器真正能看见的抽象,才配有一席之地。

他对工具的用途十分谨慎。做出一个工具时,你并不知道它会怎样被使用;你只能尽量防止人们割伤自己的手指,但其实并没有真正的控制力。他为 C++ 的某些用法感到自豪,但也希望有些用法别再出现。比特币挖矿是他最喜欢举的例子:它耗费的能量和整个瑞士差不多,而且大多服务于犯罪活动。浏览器里的 JavaScript,尽管十分粗陋,却让很多“更讲究原则”的设计没能落地的事情得以实现,因为非专业的程序员看不懂那些设计。“咱们别这么狭隘了。”

06

安全(safety)、性能和安全防护(security)都是整个系统的属性

照他的讲法,C++ 是为那些想把硬件用到极致、并想通过抽象来驾驭这份复杂性的人而存在的。可靠性不是什么次要的任务。他希望电话能打通,声音也保持完整。银行不能崩溃,因为出问题的可能是你的账户。游戏崩了,也不会死人。他在意的,是性能作为可靠性的支撑:如果你把所有时间都花在解释一次简单的函数调用上,就没有时间去做那些让通话声音听起来正确的信号处理;否则你就需要十倍的计算机,而那样的话,谁也负担不起这部电话。

现代汽车里本来就有数百万行代码,驾驶辅助和自动驾驶还会再加上更多。Fridman 接触过一些监管人员,他们对可能做出致命决定的软件极度紧张。Stroustrup 的第一步,是拒绝一个常见的陷阱。和性能与安全防护一样,安全(safety)同样是系统层面的属性。人们常常只看系统的某一部分,就说那一部分是安全的。如果你真想要可靠性、性能或安全性,就必须看整个系统。把某个局部做到完美,甚至未必是通往最高可靠性的最佳路径。

有人指出,C++ 不是类型安全的,你是可以把它搞坏的。他的回答很直接:任何跑在电脑上的东西,他都能搞坏。如果他想闯进你的机器,大概也不会去攻你的类型系统,他会试试 SQL 注入。只要环节中有人,要证明某个安全水平很快就毫无希望。于是他把话题拉回到一件你能取得进展的事情上:让 C++ 程序少崩溃,主要靠的是简化。

07

丑代码比美代码更容易辨认

第一步不是测试框架,也不是对所有东西做运行时检查,尽管这些之后也会用上。第一步是减少代码,让代码本身更不容易出错。如果你思考问题的方式没有体现在代码里,那就有一块缺失的部分只存在于你的脑子里。读者能看到程序做了什么,却看不到你是怎么想的,除非你把想法直接表达出来。一旦做到这一点,代码就更容易维护、更容易调试、更容易修改,也更容易测试。“瞧,它竟然跑得更快了。”你也就可以用更少的计算机,这意味着更少可能出故障的硬件。他引用爱因斯坦的说法:尽可能简单,但不能更简单。

Fridman 问了一个显而易见的问题:如果有人把福特 F-150 的代码交给你,你能不能看出它是不是一团糟?Stroustrup 说,有经验的开发者能嗅出来,他们会寻找那些与别处的 bug 相关的“坏套路”。他一直在尝试写下好代码是什么样子,目前的版本就是 C++ 核心准则(C++ Core Guidelines)。这类规则本身并不能造就好程序员,但能限制损失,减少出错的机会。你可以把雕塑的每一条规则都凿进大理石里,也成不了米开朗基罗。一个好程序,就像一件严肃的艺术品,需要灵感的火花,而这东西没法靠规定来管。你能做的,只是逼近那份手艺。

丑陋比美更容易辨认,因为美有时来自某种创新和不寻常之处,你得动脑子才能欣赏它。烂代码有许多共同点。静态和动态检查工具能抓住大量最常见的错误。他特别喜欢静态分析,因为它检查的不只是语言规则,还有用法。你把代码表示成一种结构,让程序可以遍历它,并找出对与错的地方。资源泄漏是他最喜欢的例子。在 C 语言层面,一个 malloc 必须有一个与之配对的 free。在同一个函数里,这往往很容易做到。可一旦指针逃出了函数,问题几乎就无解了。

运行一个静态分析器,你会发现一些泄漏,也会发现不少分析无法做到完整的地方,原因可能是运行时的依赖关系,分析器本身的能力所限,或者干脆是时间不够。把分析器和一套用法规则结合起来,你就能看出规则为何被违反,从而避开那些根本无解的情况。你并不想解决全部问题。分析器发挥得最好时,是一种教学工具:它会指导你以后怎样写代码。他宁愿在程序运行之前就找出错误。程序一旦跑起来,出了故障就意味着你需要错误处理程序,而错误处理代码是最难写的一类,因为你通常并不清楚究竟出了什么问题。不知道问题是什么,又该怎样恢复?

08

如果有了抽象,它就不该多花任何代价

Fridman 说,高层抽象与效率之间存在张力。Stroustrup 同意,但又把这个说法倒过来:往往是最好的抽象,带来最好的效率。抽象是他提升性能的主要工具。他还想对这一点正式澄清:人们总是引用他的话说 C++ 是一门面向对象语言。他说自己从来没这么说过。他说的是,C++ 支持面向对象编程以及其他技术。大多数复杂而有意思的问题,最好的解决方案都需要面向对象、数据抽象、函数式风格,以及普通的类 C 代码中的思想。

你不能只是一个个地往里加功能。如果把看起来漂亮的东西,或者用户要的东西,逐一加进去,你得到的就不会是一个连贯的整体。你需要一些准则,决定什么可以进来,什么必须留在外面,以及一项功能在进入之前必须做怎样的修改。这些规则大多不是语言技术层面的。“不要破坏静态类型系统”之所以存在,是因为他希望程序能在合理数量的硬件上可靠运行。其中一条规则就是零开销原则:如果你有一个抽象,那么它相比于在更低层次上写出等价的代码,不应该带来任何额外开销。

用矩阵抽象写出的矩阵乘法,应该做到:即使退回到数组和指针,也不会变快。有人写出过这样的乘法,而且生成的代码比 Fortran 还快,因为正确的抽象让编译器能够消除临时对象,并做循环融合,这些事情在底层语言里手工做起来非常痛苦。讲座演示过这一点之后,常见的问题是:如果我把你的 C++ 改写成 C,它会快多少?答案是慢得多。他第一次看到这种效果,是在 1980 年代,和 Doug McIlroy 一起。只有当你下到汇编层面,去处理编译器并不了解的那一部分机器时,才有可能打败这种抽象。

09

之所以有四个前端,是因为他讨厌单一生态

他说,零开销的魔法并不存在于某一个地方。你需要编程技巧、语言特性和实现技术三者结合。Brian Kernighan 指出,C++ 能够成功,原因之一是 Stroustrup 在早期编译器上下的功夫;他不仅设计了这门语言,还用它写了不少代码。没有哪个人能掌握 C++ 所用到的每个领域所需要的全部技能。光是并发编程,就需要并发算法、无锁代码的细节、编译器技术,还要有图形或网页服务器这样的具体应用领域。这些东西装不进一个脑袋里,两三个人合起来才撑得住。

为什么会有这么多实现?没人决定过要有很多。他设计 C++ 时,世界上并不是只有运行 Linux 的 x86 机器。IBM、Sun、摩托罗拉,各家公司都有自己的编译结构。他写的是前端,假设如果这门语言成功,别人会去写编译器;而他希望利用那里已经存在的后端基础设施。他的用户当时在用二十五种不同的链接器。他本可以自己写一个链接器,但他不可能写出二十五个,还同时继续推进这门语言。如今至少有四个前端:Clang、GCC、微软的编译器,以及 EDG;EDG 为相当大比例的独立机构和嵌入式行业提供支持。后端则多到数不过来,因为嵌入式架构差异太大,单一实现根本不可能成为选项。

他恰好也不喜欢单一生态(monoculture)。它们很危险,因为拥有者可以故步自封。没有竞争,也没有创新的动力,却有很大的动力去给变化设置障碍,因为他们已经拥有一个舒适的世界。GCC 曾经很出色,后来有些停滞;Clang 出现之后,GCC 现在好多了。微软也好了很多。少数几个前端,会给标准符合性、性能、错误信息和编译速度带来压力。被问到他个人最喜欢的特性时,他并没有去挑某个新东西。他说的是构造函数和析构函数。构造函数为使用对象建立环境,析构函数则在最后把残局收拾干净。这正是 C++ 不必依赖垃圾回收,同时能提供可预测性能的原因。

这个想法更广为人知的名字是 RAII,即资源获取即初始化。这恰好证明他不该去做广告。“我得到了最好的点子,然后把它叫作资源获取即初始化。”构造函数和析构函数,是在 1979 年开工后的第二周,加入当时称为“带类的 C”的语言里的。一旦你控制了对象的“生”与“死”,你就必须控制复制,因为复制也是创建对象的一种方式。然后你还得能够移动对象,于是就有了移动操作。这一整套操作,决定了一个 C++ 类型是否被允许存在。Fridman 把话题引向哲学:创建一个实例、释放它的资源,就像生与死定义了一生。Stroustrup 顺着这个方向又走了一步。哲学很重要。没有它,你就做不好语言设计,因为你所决定的,正是人们能够表达什么,以及如何表达。

10

概念(concepts)花了三十年才成形,因为灵活性和速度都不能打折

模板是 C++ 实现泛型编程的方式。编译器看到模板和实参后,把它们组合起来,生成的代码就像你亲手为那个具体类型写了一个 vector 一样,额外开销最小。有了多个参数,它能把编译器通常不会一次看到的信息组合在一起,有时甚至比那些精巧的手写代码跑得还快。代价在于调试。经过优化的 C++ 一直都很难看:早在 1983 年的 Cfront 就已经有了前端和后端优化,而它输出的 C 代码是给机器看的,不是给人看的。模板让情况更糟,因为优化器会把程序不同部分的信息拽到一起。实际做法往往是:先关掉优化器调试第一层,再把它重新打开。

1987 年前后,设计模板时,他希望有三个特性。第一是极端的灵活性:它必须能表达他想象不到的东西,因为他吃过那种只允许你做设计者认为好的事情的语言的苦头。第二是它必须跑得和手写代码一样快,甚至更快:比如 vector<char> 要和一个不带参数化的手写 vector 一样快。第三是他希望能表达模板对实参施加的约束,就像函数原型描述接口那样。当时他和其他人都不知道如何同时做到这三点。对 C++ 而言,前两点必须有,否则它就不是 C++。第三点困扰了他二十年左右。他曾是把函数参数的类型检查引入 C 语言的人,所以他很清楚一个好的接口有多珍贵。

2003 年前后,他和 Gabriel Dos Reis 开始分析这个问题;印第安纳大学的一个小组也启动了一个项目。他们原以为两三年就能搞定,那样的话,C++11 就能变成 C++06 或 C++07 的标准版本了。问题在于,核心思想太传统了:它们和 C++ 契合得不好,对隐式转换处理得很弱,对混合类型的算术运算也很弱。很多思想来自函数式编程社区,那个社区处理多类型的方式和 C++ 不一样,表达能力的限制也更多,而且没有 C++ 那样近乎苛刻的性能要求。它们编译得不够快,用起来太难,而且除非有超出当时最先进水平的优化器,否则运行也不够快。直到现在,情况依然如此。

最终落地的版本,是编译期谓词。你可以问一个类型:你是一个序列吗?你有 begin 和 end 吗?你是随机访问序列吗?你支持下标运算吗?你的元素类型支持小于比较吗?现在模板可以说“我接受可排序的东西”,这一点有明确的定义,不必再说“我接受任何类型的参数”。“concept”这个词来自 Alex Stepanov,他是 C++ 意义上泛型编程的开创者:一个领域的基本概念,理应就叫概念。到 2019 年,这套设计(与 Dos Reis、Andrew Sutton 以及 Stroustrup 一起完成)已经在 GCC 和 Clang 中提供了多年,正在进入微软的编译器,并且成为 C++20 的一部分,包括标准库在内。

11

标准化像民主,只是得按三年一次的周期交付

大约在 1980 年代初,有一个 IBM 的人和一个 HP 的人走进他的办公室,说他们想把 C++ 标准化。他说,这东西还没做完,也还没准备好。对方说,他并没有明白这件事的关键。他们的机构依赖 C++,却不能依赖一个属于另一家公司、还可能是竞争对手的东西。他们可以信任他,可他万一被公交车撞了呢。他们准备按照正式的规则来做标准化,而他非常想参与其中,因为否则他们就会自己动手,而他们也知道他能做得更好。经过一番软硬兼施,第一次会议于 1989 年底召开:约二十五人参会,这在那类会议中大概是个纪录,会上讲的都是 ANSI 的规则。

这个过程是开放的。你要交一笔费用,最初约 1000 美元,到 2019 年约 180 美元,然后就可以进入会议室旁听。他们一年开三次会,每次一周,进行技术讨论并投票。每个机构只有一票,所以 IBM 不能带十个人进来就主导局面。他认为,大多数人都会同意,这比他一个人拍板,或者由 AT&T 这样的单一机构决定,要好得多。标准化并不让人愉快,甚至有点吓人。它就像民主。丘吉尔的那句名言在这里同样适用:民主是最糟糕的制度,只是比其他所有已经试过的制度都好一点。

第一次技术会议在 1990 年召开;他们在 1998 年投票通过了第一版标准,用了八年,而不是 ISO 传统上的十年,而且所有国家都投了赞成票。他们原以为下一版只需要六年,因为现在已经很熟练了。结果用了十三年。这是“第二系统效应”:他们知道该怎么做了,于是野心就更大了。而且在漫长的周期里,就在要发布之前,总会有人冒出一个非加不可的好主意。这一点他们在 STL 上成功做到了,他认为 STL 救了 C++。后来的尝试没那么戏剧化,耗时也更长。C++11 之后,他们决定更频繁地发布。如果周期是十年,拖延一下你就会发现已经过去了十一年;如果周期是三年,错过一次,功能也只会在三四年内重新回来。C++14 和 C++17 都按时发布,他有信心 C++20 也能如期完成。

可预测性对实现者很重要,因为他们有一个目标,并且能够达到它。C++11 之后,大多数编译器花了两年才足够好。到 C++14 时,它们已经好得多。到 C++17,几乎所有人都按时交付了。对于 C++20,大多数实现在 2019 年之前就已经在交付了。从最高层看,这门语言是为那些想把硬件用到极致、并通过抽象来驾驭复杂性的人准备的:底层是面向机器、类 C 的一层,而类则是用户定义的类型,应该能像内置类型那样使用——比如一个不会溢出的整数,用在真实的船用柴油机燃油喷射系统里;或者一个矩阵;或者游戏里的一个地精(gnome)。相关类型用继承来表达,另一种相似性则用模板来表达,比如适用于任何类型的 vector。

12

原则可以共享,权衡却不能

Fridman 问,语言设计有没有可能有朝一日建立在一套统一的原则之上,就像物理学追求统一理论那样。Stroustrup 把时间尺度摆了出来。现代物理学从伽利略算起,已有约七百年。现代计算机的历史从 1949 年前后算起,只有七十年,相差约十倍。而且物理学家不必像语言设计者那样为用户操心,因为编程是由人来完成的。这个领域还不成熟。在哲学层面,你仍然可以在一些原则上达成一致:不要泄漏资源;不要在运行时处理你根本不需要处理的错误;不要破坏你选定的类型系统。类型系统可以各不相同,但一旦选定了,就不要破坏它。

他曾和 Common Lisp 的设计者坐在一起,谈论语言和特性。起初他们几乎什么都不认同,他甚至拿括号开了个玩笑。后来,某个地方突然对上了。他描述了一个问题,以及他解决这个问题所依据的原则;而对方面对的是另一个问题,却用的是同一类原则。他们一起逐段过了 C++ 和 Common Lisp 的大量内容,发现底下有相似的推理。约束条件和预设用户都很不一样。原则可以共享,但权衡取舍不能共享。他已经在现实中看到了趋同:C++ 很早就采用的 RAII,几十年后在带垃圾回收的语言里以“资源释放”模式的形式出现了,因为这些语言想尽量不把一切都交给垃圾回收。他还指出,Rust 采用了 RAII,而且有人半开玩笑地指责他,说他在别人发现它之前二十年就已经“借用”了它。

Fridman 认为,机器学习是构建另一种东西的方式:接受输入,产出输出,模糊而有噪声,很像人。Stroustrup 没有绕弯子:那是另一个世界,而在他的领域里,他不喜欢模糊。人们常说,希望每个人都能编程。他并不希望每个人都来编写他的飞机控制程序或汽车控制系统。他希望这些事情由经过专门教育和训练的工程师来做。C++ 是一把锋利、有效的工具,服务于追求精确的专业人士。你不会让不懂数学的人负责计算。靠手指数数,是送不到月球上去的。Fridman 提到了 99.8% 的准确率。而 Stroustrup 见过的更像是 84%,再投入大量心血,才能提升到 92.5%。这足以用来在人工查看之前做预筛选,但对于攸关生命的场合,它还远远不够。

最让他害怕的设计,是这样一种:神经网络遇到太复杂的情况,就向人类求助,而那个人正在看书,或者在睡觉,只有三十秒或三秒钟,要弄清楚 AI 处理不了的是什么,并做出正确的决定。机器与人之间的交接成本,很难估算。把问题说清楚,不等于宣布它无解。他的偏好很简单:干脆不要依赖人。在驾驶核反应堆或自动驾驶汽车时,更好的做法是设计那些永远不需要向人求助的系统。他补充说,这些软件的底层仍然是 C++,所以他会留意这个领域的动向,尽管他永远不会成为这个领域的专家。今天没有哪个大型系统是用单一语言写成的,这背后有充分的理由。

同频道的其他文章

3:36:56EN → 简体中文
Lex Fridman· 2026年9月16日播客精神病学至今没有属于自己的青霉素主持 Lex Fridman历史学家 Andrew Scull 与 Lex Fridman 谈到,这门学科对症状有所缓解,但没有哪一种重大精神疾病真正被根治;过度自信的时候,代价要由病人来扛。Mental HealthPublic HealthNeuroscience
5:15:51EN → 简体中文
Lex Fridman· 2026年8月26日播客 · 2 人对谈DHH 没有亲手写一行 Omarchy Quattro 的代码嘉宾 DHH · 主持 Lex Fridman与莱克斯·弗里德曼一次充满怀疑的对话过去十三个月后,Rails 的创造者讲述了 Opus 4.5、一群编码智能体(Agent)和一个一分钟的 Linux 安装器,如何结束了他一凿一凿手写 Ruby 的时代。编程智能体Vibe Coding智能体工程+3
3:12:58EN → 简体中文
Lex Fridman· 2026年8月12日播客 · 2 人对谈一个冷水澡,二十位冠军:Khabib Nurmagomedov 是如何炼成的嘉宾 Khabib Nurmagomedov · 主持 Lex Fridman在马哈奇卡拉的一间学校体育馆里,七十个人共用一个淋浴间,而且只有冷水。Martial ArtsCombat SportsCoaching+3
3:46:18EN → 简体中文
Lex Fridman· 2026年7月28日播客 · 2 人对谈抽掉奴隶制,就没有美国内战嘉宾 Gary Gallagher · 主持 Lex Fridman1860 年,美国奴隶主名下的奴隶价值,超过了全美所有铁路和工厂的总和。Political PhilosophyLeadershipHistory
3:51:47EN → 简体中文
Lex Fridman· 2026年6月30日播客 · 2 人对谈46% 的皇帝被暴力推翻,帝国照样延续下来嘉宾 Anthony Kaldellis · 主持 Lex Fridman历史学家 Anthony Kaldellis 与 Lex Fridman 一起走过 2200 年的罗马史,并主张我们所说的拜占庭,其实就是罗马本身。Political PhilosophyGeopoliticsLeadership
2:53:42EN → 简体中文
Lex Fridman· 2026年5月29日播客 · 2 人对谈月亮一直在下落,却总也落不到地球上嘉宾 Biggest Mysteries in Physics · 主持 Lex Fridman费米实验室(Fermilab)物理学家 Don Lincoln 在与 Lex Fridman 的对谈中说,物理学的历史就是一部统一的历史;反物质(antimatter)、暗能量(dark energy)和万物理论(theory of everything)依然远在我们能做的实验之外。Quantum MechanicsScience CommunicationPhilosophy of Science