今年年初,Linux 内核的代码行数突破了 4000 万行。而作为这个庞大项目的掌舵者,Linus Torvalds 对外宣称自己“已经不再是程序员”、“不再编程”了,那么,他在整个项目中到底负责什么?又是如何把控、维护这个项目的?他会用 AI 来做内核工作吗?
近日,Linus Torvalds 出席了 Linux 基金会在日本举办的开源峰会,与 Verizon 开源项目办公室负责人 Dirk Hohndel 展开了第 29 次对谈(https://www.youtube.com/watch?v=yEzdHYjY_RU)。其二人聊到了 Linux 内核维护的高密度节奏、合并窗口期的挑战,以及 AI 在代码中可能扮演的角色。
Linus 表示,在 Linux 内核的世界里,没有捷径可走,他们每 9 周发布一个版本,一个合并窗口期里,自己通常要处理大约 12,000 次提交,算上合并后的提交大约在 11,000 到 13,000 次之间。其中,他会花两周时间用来合并代码,接下来的七周则用于查找并修复 bug。
值得关注的是,Linux 内核维护中有条铁律:no regressions——不允许功能倒退、不允许引入回退性问题,也不能破坏向后兼容性。
Linus 称,真正让自己完全不能接受的行为是,是有人不愿意承认是自己引入了 bug。
至于 AI,Linus 也直言自己的态度:“我其实很讨厌‘AI’这个词,不是因为讨厌技术本身,而是因为它被炒得太厉害,好像现在所有事情都非 AI 不可。”
他指出,「AI 和当年编译器的出现,本质上是一样的。别觉得 AI 会突然彻底改变编程,这件事我们早就经历过了——几十年前写编译器的那些人已经完成过一次革命。」
以下是这场对话的完整内容:
最新的 Linux 版本还是一如既往的“枯燥”
Dirk Hohndel:早上好,我是 Dirk Hohndel,在 Verizon 负责开源业务,Verizon 是美国最大的移动运营商。
Linus Torvalds:我是 Linus Torvalds。我们已经这样对谈过很多次了。我不喜欢做演讲,也不做 Keynote。对我来说,更愿意和 Dirk 进行这种对我来说“毫无准备”的问答环节,而且我们已经这样聊了很多年了。
Dirk Hohndel:没错,这是我们的第 29 次对谈。那,Linus,你的职业版图是不是又扩展了?听说你现在成了 YouTube 明星了?
Linus Torvalds:不不不。我确实在几周前录了一个 YouTube 视频,大概是上周发布的。但说实话,这也确实是我在 Linux 事业中乐在其中的一点——我可以去做一些平时通常不会做的奇怪事情。我拍了这个 YouTube 视频,我觉得对我来说这已经足够了。
Dirk Hohndel:总之,看到你在一种完全不同的对话场景中出现真的很有趣。但现在我们还是回到我们更常规的交流方式上。Linux Kernel 6.18 上周发布了,你能给我们介绍一些亮点吗?有什么值得关注的内容?
Linus Torvalds:对我来说,亮点就是它“一如既往,还是老样子”。
我喜欢“枯燥”、平淡无奇。当你开发的内核被所有人依赖时——无论是手机还是超级计算机——你真的不希望有太多的意外和刺激。
我已经做了 35 年了,我觉得核心词应该是“稳步推进”。我们最近做了相当多的清理工作。当然,其中很大一部分依然是对新硬件的支持,这是不断更迭的部分。内核的工作大约有一半实际上就是硬件驱动程序。
Dirk Hohndel:我觉得关于 6.18 很重要的一点是,它是下一个 LTS(长期支持)版本。它做了大量的清理、许多细小的改进,而不是巨大的、颠覆性的生态系统变动,这也是项目目标的一部分。这是设计的有意为之,还是仅仅是巧合?
Linus Torvalds:这是设计使然,虽然这种“设计”也是多年来逐渐演变而成的。我相信 Greg(Greg Kroah-Hartman)现在就在观众席的某个地方,他负责维护长期支持版本,并接手特定版本,进行多年的维护,这样无论是大公司、小公司还是个人,都能有一个可以长期依赖的标准版本。
Dirk Hohndel:Linux 过去通常不会预先宣布哪个版本将是下一个 LTS 版本,但这在几年前改变了,现在一般是每年的最后一个版本。
Linus Torvalds:我不认为这是官方提前公布的事情,但大家大概能猜到会发生什么。我们有计划,但它也是灵活的。
Dirk Hohndel:过去我们不预先宣布的原因是为了避免那种“为了赶上版本而匆忙合入代码”的情况吗?
Linus Torvalds:我们曾经遇到过这样的问题:当人们知道某个版本将成为下一个 LTS 时,就会拼命想把功能塞进去。这会导致问题,因为原本应该是最稳定的内核,有时反而因为人们急于合入新代码而变得不稳定。
但我觉得大家现在已经非常习惯我们的工作方式了。即便你知道预期是什么,那种“冲刺感”也没那么强了,因为大家已经见证这种机制运行了这么久。他们知道如果错过了一个 LTS 版本,下一个总会到来。而且大多数依赖 LTS 的公司也知道,一年的时间其实很短。
9 周一个发布周期,大约会收到 12,000 次提交
Dirk Hohndel:就像你说的,这个流程已经持续了很久,大约 20 年了。现在你正处于下一个内核的合并窗口期,大约完成了三分之二。我今天真的很想聊聊这个:请带我们了解一下这个过程,对你来说,“合并窗口期”意味着什么?
Linus Torvalds:合并窗口期间是我非常忙碌的一段时期。我会接收维护者们认为已经为下一个内核准备就绪的所有新代码,并没有一个硬性的“功能规则”来规定下一个内核必须包含什么。它本质上是关于“这些代码现在准备好了”,所以当合并窗口开启时,我们就可以进行整合。
事实证明,这对我这个维护者以及开发者来说,压力都小得多。因为没有一个绝对的截止日期说“你的代码必须在某月某日准备好”。它更像是“代码什么时候准备好了,它就会被合并”。既然我们大约每两个月(确切地说是 9 周)发布一个版本,如果有人错过了一个版本,他也知道再过 9 周下一个发布周期就会开始。这真的减轻了开发过程中的很多压力。
不过,对我个人而言,那两周确实很忙。我需要合并所有新代码。如果其中一周正好赶上出差,而且明天还要参加内核维护者峰会,这意味着上周我在赶飞机前尝试完成所有工作,压力确实比平时大一点。
Dirk Hohndel:但你刚才略过了我真正想了解的部分。那你具体是做什么的?
Linus Torvalds:我现在已经不写代码了,如果你是想问这个的话。实际上,我做的事情是:把别人开发的、由别人维护的代码整理起来,然后当这些子维护者觉得某个代码模块准备好了,就会发给我一个 pull request。我来合并它。
一个合并窗口,我通常会收到大约 12,000 次提交。如果算上合并后的提交,大约在 11,000 到 13,000 次之间。它们是通过几百个 pull request 发给我的。所以在第一个星期,我几乎一直在合并代码,这不只是朝九晚五,是从早到晚,整整一周都在做。第二周我会放慢节奏,处理一些滞后的提交,有些是因为我需要仔细检查,有些只是提交晚了。总之,两周时间处理所有新功能,然后我就停止接收新功能。
在之后的 7 周时间里,我们会尝试找出所有的 Bug,尝试修复所有的 Bug,并让内核处于尽可能好的状态。我们做这个流程已经很久了,也越来越熟练。在那个阶段,我会发布每周的候选版本(Release Candidates),直到发布最终版本。对于 LTS 版本和所有版本,之后都会有一段时间的稳定维护期。
“在合并窗口的前一天收到 PR,会惹毛我,却也总有人想试试”
Dirk Hohndel:我觉得很有意思的是,要让你真正讲你在做的有趣的事情,可不容易。因为凡是合并过不同 pull request 的人都知道,这从来不是“点一下就好了”。你要在两周内合并 12,000 个提交、几百个 pull request,不可避免会遇到冲突和各种挑战。
Linus Torvalds:我合并这么多次了,现在几乎可以闭着眼睛合并了。很多人应该也都了解,当两个人修改了同一片代码区域,出现冲突时会发生什么。
我几乎每天都在处理这种情况,对这种合并已经很熟练了,以至于我让子维护者不要帮我提前合并。即便他们比我更了解自己的模块,我合并的经验也比绝大多数人都丰富,所以我更喜欢自己来合并。原因有两点:
- 一是我能清楚知道哪些地方发生过冲突,这对我很重要,我想知道不同团队在同一区域的交互情况;
- 二是如果冲突比较复杂,我有时会让子维护者先在测试目录里做预合并,然后我再比对我的结果。这样我有时候会发现自己合并的问题,但更常见的是发现他们的预合并有问题。
所以这就是我做的事情。我很久没真正写代码了,我会给别人发代码片段说“嘿,可以这样改”。但我真正做的,是保持对整个项目的高层次理解,合并不同团队的代码,知道大局发生了什么,也能判断什么时候两组代码冲突。
你想想,Linux 内核里面有 4000 万行代码和文档、几百个维护者、每次发布都有几千个开发者参与,每九周一次,这就足够我跟进了。我不会纠结小细节,那交给我信任的开发者和子维护者去做。我关注的是维护、流程,确保发布计划合理、内核运作正常。这就是我的工作。
Dirk Hohndel:这很有趣,因为我接下来的问题正是:你多久会看一次这些代码,即进行代码审查?多久会遇到合并冲突,然后说“嗯,这里不对”?
Linus Torvalds:当冲突发生时,我不仅想知道冲突本身,还要理解代码,这样我才能确保冲突修复是正确的。
现在我看得最多的就是冲突代码。有时候我看完代码就会说:“哦,这里写错了。”这种情况几乎每个合并窗口都会发生。就几天前,我合并一个提交时出现冲突,我看了冲突的代码,发现问题出在有人提交的代码上有明显错误,然后我就从 tree 上撤回那段代码,并要求发送代码的人给出解释。
所以这就是我现在仍然涉及的编程部分——我会看代码、会修改代码,但我是以维护者的身份,而不是开发者身份去做。
Dirk Hohndel:我想在场有不少人都做过 Git 合并。哪怕只是偶尔做一次,但想到要在两周内处理几百个 merge,都会觉得压力很大。那在你做了这么多年、流程也这么成熟、大家也都很有经验的情况下,有没有什么“雷点”?哪些事情最容易把你惹毛?
Linus Torvalds:有那么几个。一个是时间点。我偶尔会收到别人在星期六发来的拉取请求,也就是我正准备结束合并窗口的前一天。我心里就会想:“不是说好代码应该在合并窗口前就准备好的吗?现在我正准备收尾、让节奏慢下来、准备第一个 RC,你却在这时候发过来。”有时候我会直接说:“不行,等下一个版本吧,再等九周。因为你太晚了,你本该更清楚。”其实大家都知道这个道理,但有时候还是会有人这样试一试。我觉得大概就是这么回事。
另外一件让我比较恼火的事是——我不只是合并代码,我每天都会运行自己的内核。我不会每合并一次就重启,但我会在自己所有机器上用最新的内核。也就是说,每一个版本我都会自己用一遍,而几乎每次发布我都会发现 bug。这本不该发生。
我做的事情并不奇怪,我的机器也很普通。如果我都能遇到 bug,那说明有人在提交前根本没有好好测试。如果问题严重到我是第一个发现的人,我确实会有点不爽,有时也会给维护者发邮件,直接说:“你这次没把工作做好。”
Dirk Hohndel:语气会很客气吗?
Linus Torvalds:不一定。我通常还是尽量保持礼貌的,但有些人我已经合作了几十年,当我觉得他们明明应该更清楚的时候,语气确实会变得有点冲。
真正让我完全不能接受的,是有人不愿意承认自己引入了 bug。出 bug 本身没问题,这是不可避免的。我们并不完美,再小心也会犯错,这很正常,我不会为这个生气。但当别人指出 bug 时,你应该站出来说:“抱歉,那是我的错,我会修复它。”
可有时候我收到的回应是:“我修了另一个 bug。”这就不行了。这不是“前进一步、后退两步”的问题。你不能拿“我修了一个 bug,但又引入了另一个”当借口。这只会让系统变得不可信。
说实话,我宁愿有一个大家都知道、可以绕开的老 bug,也不愿意 bug 到处跑、让人完全没法应对。所以内核里一直有一个非常严格的原则:不允许产生回归(no regressions)。这并不意味着回归不会发生,而是说一旦发生,我们就要认真对待,而不是说一句“是回归,不过……”就算了。
所以确实有几件事特别容易触发我的情绪。我也一直在努力让自己更克制一点,让自己变得有礼貌。如果我曾经伤到过在座某些人的感情,我在这里道歉。我也会有压力,大家都会有。归根结底,我们都是人,犯错是难免的,而我们建立这些流程,就是为了尽量把错误的影响降到最低。
“我很讨厌‘AI’一词,但我非常相信 AI 作为工具的价值”
Dirk Hohndel:你刚才也提到,你做这件事做了这么久,已经非常熟练了。但我在想:有没有什么工具能让这件事更轻松?毕竟现在是 AI 的时代,大家都在谈 AI……
Linus Torvalds:好一个转折(笑)。
Dirk Hohndel:我觉得这并不突兀。其实正好呼应了你刚才讲的那些内容:代码合并、冲突处理、bug 处理。有没有可能,用一些工具,甚至是 LLM 这样的现代 AI 系统,来减轻你的工作负担?
Linus Torvalds:当然可以。我们本来就是一个高度依赖工具的开发环境,用来检查代码的工具非常多。明天我们要参加年度维护者峰会,其中一个重要话题就是:在使用 AI 工具这件事上,我们该如何扩展现有工具链和相关规则。
我其实很讨厌“AI”这个词,不是因为我讨厌 AI 技术本身,而是因为它被炒得太厉害了,好像现在所有事情都非 AI 不可。但话说回来,我非常相信 AI 作为工具的价值。我们已经有一些项目在用 AI 做代码审查。
就我个人来说,因为我是维护者,代码审查对我非常重要,所以我对“用 AI 写代码”反而没那么感兴趣。很多人一谈编程就想到用 AI 写代码,但在我看来,这远没有“用 AI 来帮助维护代码”有意思。这是完全不同的方向,而且我们已经有好几个相关项目在推进了。
我不确定哪些已经公开讨论过,其中不少是在公司内部,把 AI 作为现有工具链之上的一层,用来检查补丁、避免发布有问题的代码。理想情况下,它们甚至能在代码到我这里之前就把问题拦下来,那我的工作流也会轻松很多。
这件事其实已经讨论了很久,现在我也开始看到一些 AI 代码审查的实际案例,其中有些非常有前景。所以我对这件事很有信心,希望明年它能成为我们工作流程中一个相当重要的组成部分。
Dirk Hohndel:出于保密原因我就不点名了,不过现在确实有一个工具正在开发中。你最近刚好用分析了一个有 Bug 的改动。那个 AI 工具在识别和解释问题方面表现得非常出色。
Linus Torvalds:对,那次其实不是我亲自用的,而是在某家公司内部完成的,我只是看到了最终结果。当时我就想:“对,这个工具我想要。”那确实是个很好的例子,而且事情就发生在这一次合并窗口里——我对那个改动本身就有意见,而那个 AI 工具不仅找出了我提出的那些问题,还额外发现了一些。
这一直是个非常好的信号:当一个工具连专家没注意到的东西都能发现,那就说明它真的有价值。所以这一点毫无疑问——炒作确实很多,甚至有点过头,但技术本身也确实很有意思。
当然,现在所有 AI 公司基本都在用 Linux,Linux 也是大多数 AI 工作负载的基础。但反过来,用 AI 来帮助 Linux 内核开发,这件事我们其实还做得不多,不过这一点肯定会到来。
AI 如同当年的编译器,别觉得 AI 会突然彻底改变编程
Dirk Hohndel:我很喜欢你刚才说的一个观点:真正的突破点在“审查”和“解释”上。不过我注意到,每次合并窗口回顾时,贡献者数量和新贡献者数量都非常高。我在想,LLM 这种 AI 工具,能在多大程度上帮助新人入门?
毕竟内核有 4000 万行代码,流程复杂、工具繁多,想真正开始参与内核开发之前,要学的东西实在太多了。那在流程的另一端、也就是最开始的阶段,你觉得这些工具能不能降低门槛,让更多人更容易参与进来?
Linus Torvalds::我觉得是可以的。不过先说一句,内核里已经有很多开发者了,而且说实话,内核并不一定是你入门编程的最佳起点。内核是个很特殊的领域。
当然,我也认为内核是编程世界里最有意思的地方之一,所以我很推荐大家去了解、去尝试。但如果你刚开始学编程,也许可以先从规模更小、复杂度没那么高的项目入手。
总体来说,我把 AI 看作是任何人都可以使用的工具。它确实新鲜、也很有吸引力,但同时它又并不陌生。它和当年编译器的出现,本质上是一样的。你得意识到,我刚入行的时候,编译器其实很糟糕,而今天编译器能做的事情简直像魔法。
现在的编译器,让程序员不用了解那么多底层细节就能完成工作,这本身就是一次巨大的飞跃。有人总爱说 AI 能带来“10 倍效率提升”,但编译器带来的是上千倍的提升。所以 AI 并没有那么“特别”。别觉得 AI 会突然彻底改变编程,这件事我们早就经历过了——几十年前写编译器的那些人已经完成过一次革命。
如果 AI 在此基础上再带来 10 倍、甚至 100 倍的提升,那当然很好,它会让我们能做出更多、更好、更有意思的项目。但归根结底,它依然只是个工具。这就是我的看法。当然,如果 10 年后机器人统治世界、把我们都干掉了,那我就承认我说错了。
Dirk Hohndel:AI 工具和编译器之间的区别是:AI 工具在犯错时要有礼貌得多。当它弄错时,例如 Claude 会说:“哦,是的,你说的对,我弄错了,很抱歉”。从来没有编译器对我这么说过。
Linus Torvalds:我听说有人专门用内核相关的数据训练了一个 AI,不只是代码,还包括内核邮件列表的内容。结果他们后来发现,得教这个 AI 少说脏话,因为它学到的表达方式并不总是那么有礼貌。这听起来也许只是个玩笑。
但我真正喜欢 AI 的地方在于,你不需要向它解释所有底层细节。相比之下,当你试图向编译器说明你的意图时,往往必须在非常底层的层面把事情说清楚,这个过程既繁琐又费力。
AI 的优势在于,它提供了一个额外的抽象层。你可以用更高层次的语言去表达你的想法,而不只是告诉系统每一步该怎么做。这一点让人类完成事情变得更容易,也更高效。所以我对 AI 抱有很大的期待。
Linux 铁律:拒绝出现回归
Dirk Hohndel:我这里还有 12 个关于 AI 方面的问题,但为了能“活着”离开这间屋子,我还是换个话题吧。你刚才提到了,我们有这样一条规则:在内核中,不允许回归(no regressions),也不能破坏向后兼容性。有意思的是,真正能长期坚持这项原则的项目并不多。在来这里的路上我们还聊到,Python 3.14 的一次更新,导致你正在使用的一个业余项目工具失效了。那么,为什么做到“不破坏现有功能”这么难?
Linus Torvalds:从技术角度看,这件事确实很难。并不是所有的内核开发者都喜欢我这条“不许产生回归”的规则,要长期坚持这一规则确实很辛苦。
问题在于,所谓的“回归”,往往不是马上就能发现的。比如某个行为在两年前改变了,但当时大家都在运行旧的 LTS 内核,并没有察觉异常。等到两年后,他们升级到新内核,才发现某个细节和以前不一样了,而这个差异恰好破坏了他们的特定应用。
更麻烦的是,两年的时间已经过去,其他应用程序可能已经开始依赖这种“新的行为”。这时我们就会陷入一个非常棘手的局面:如果去修复当初的回归,就会影响那些已经适配了新行为的程序,等于制造新的回归。所以这件事远没有听起来那么简单。
嘴上说一句「不许产生回归」很容易,真正坚持下去却极其困难。
为了守住这个原则,我们不得不做出一些非常极端的选择。比如,在内核中,对不同的程序表现出不同的行为——因为我们很清楚,某些程序期待的是旧的行为,而另一些程序已经建立在新的行为之上。站在软件工程师的角度,你其实并不想这样做,这种方案本身是“丑陋”的。
还有一个现实问题是,很多人,尤其是在开源社区里,之所以投入时间做这些事情,本身就是因为热爱编程。而对开发者来说,“有趣”的事情,往往是做一些和过去不一样的、带有创新性的改动:你引入了新的行为,从旧的模型中学到了很多,也可能觉得旧的设计本身就是错的,于是想把它修掉。这种冲动完全可以理解。
但如果你开发的是一个被他人依赖的库,或者是一个被库依赖、进而被无数人依赖的内核,你就不只是在修复你自己的 Bug,你是在破坏所有依赖你项目的程序。
开发者或许会很容易说一句:“我已经把问题修好了,你去重新编译你的应用吧。”但现实是,很多应用依赖的,可能是一个 30 年前写成、如今早已无人维护的库。当底层基础设施悄然改变了行为,修复这类问题往往几乎不可能。
来源:https://www.youtube.com/watch?v=yEzdHYjY_RU
想了解更多行业资讯
扫码关注👇

了解更多考试相关
扫码添加上智启元官方客服微信👇

17认证网








