LLM 将从根本上改变软件工程
(从这里X 发布
你听说过 ChatGPT4、Bing、GPT3 这样的大型语言模型吗?我相信你一定听说过。
我经常听到关于这些技术的炒作,其中一个观点是这些技术对某些人有害$reason
(“它们是随机鹦鹉”、“它们胡说八道”、“它们不能推理”、“它们编造事实”、“它们可能会取代初级开发人员,但不会取代高级开发人员”),虽然从技术上来说这是正确的,但却忽略了一个更重要的点:如果你从事软件编写行业,这些东西是有用的。
事实上,它们运行得如此出色,以至于我认为我们即将见证软件构建方式的根本性变革。这将对几乎所有领域产生巨大影响。讽刺的是,编程可能是最容易被这些技术取代的工作之一。本文主要针对我的读者群中的程序员:我们正处于一个关键时刻,程序员需要以自己的方式理解和运用这些技术,以免被资本主义取代。
我曾写过我如何坚信法学硕士(LLM)将为务实型程序员带来范式转变,并开始更详细地阐述我使用这些模型及其相关应用的目的。我也写过我对于这项技术的初步道德立场,本文将不再赘述。1
我认为我们正处于软件开发方式一场巨大变革的起点。我们还不知道如何使用这些工具:我们刚刚发现了外星拖拉机技术。许多批评家试图把它当成一把普通的园艺耙子来使用,因为它犁过他们的花坛就对它不屑一顾。
我希望分享一些我通过法学硕士(LLM)学习编程后获得的感悟。我发现,无论是软件、写作还是音乐,培养一种实践、一种方法论和工作流程都是智力工作的关键。由于编程与高效的团队合作紧密相连(尤其是在我们这个资本主义社会的背景下),这种实践必须共享。编程的意义在于协调个人的工作以创造共同的成果,而成功取决于我们协调得如何。
我认为,拥有法学硕士学位的编程将彻底改变软件架构、系统架构、编程实践、沟通模式和组织结构。这是一个激动人心的时代,因为我们有能力塑造未来的编程。
我的背景是系统编程
我首先认为自己是一名程序员。我从五岁起就梦想着按下按钮让机器做事,而我的自闭症兴趣之一也一直与计算机有关。甚至我的音乐、绘画和写作都与这些神奇的机器密不可分。我已经写了数百万行代码,几乎每天都会提交一些代码。总而言之,我对那些有用的东西有着浓厚的兴趣,而且我已经尝试了很多很多东西。我非常在意编程,如果法学硕士学位没用的话,我就不会每天都用它们了。3
自从 Copilot 处于测试阶段以来,我就一直在大量使用它进行编程。从它公开发布后的一周起,我就一直在用 ChatGPT 解决我能想到的每一个实际问题。我主要编写“无聊的 胶水代码”,并且是在我所谓的“系统编程”中,也就是构建系统(操作系统、嵌入式系统、分布式系统、物流、供应链)的过程中编写的。另一个定义可能是“用各种复杂的方式编写 memcpy” 。4
辅助我神奇的自动完成功能
我喜欢“质朴”的编程语言:我最喜欢的是PHP、Javascript、Java、Go(以及 Common Lisp 5 ,原因超出了本文的讨论范围)。对我来说,“质朴”意味着你所看到的就是作者的意图,无需过多的润色:能够清晰地表达其语境的语言。它就像你祖父建造的餐桌,由你母亲升级,现在你继承了它:它有点笨重,油漆也开始剥落,但它已经完美地工作了近一个世纪。Copilot 在这些语言上做得非常出色。它应该使用的模式通常非常“扁平”,并且经常出现在它周围的代码中。符号的含义不受隐藏特性、抽象或模块系统的影响。这并不是说语言的“复杂性”或抽象级别导致了结果较差,而是因为从训练语料库中推断代码完成的样子更加困难。
这就是让 Copilot 能够出色地完成工作的原因(虽然我在 2022 年夏天尝试将它用于 Haskell 和 Rust,但自那以后我就没再尝试过。从那时起,Copilot 取得了一些令人瞩目的进步,所以我在这里的看法可能已经完全过时了。我已经习惯了 Copilot 在写下前几个字后就能不可思议地推断出我想要做什么。事实上,我已经注意到在编程过程中我的肌肉记忆是如何变化的。如果我的网络断了,而我——上帝保佑!——必须自己输入代码,我就必须进行一次心理转换。一开始,我会写 3 个字,并期望写出 10 行代码。我花了几秒钟才意识到我的神奇朋友副驾驶弗兰克已经失踪了。
随机鹦鹉,有效代码?
大型语言模型常见的一个诟病是它们经常输出错误代码。这倒是真的(ChatGPT4 的门槛明显提高了,但让它输出错误代码也并不难)!然而,我认为就此打住是不够仔细的。快速编写、易于纠正的错误代码,不过是好代码的另一种说法罢了。
我的编程工作很大一部分是用长篇大论的方式写一些琐碎的想法。我会先从“我需要把这些数据从这里复制到这里”(所以我称之为“memcpy 编程”)开始,然后依次用 HTTP 调用、Promise、SQS 事件、批处理作业等形式逐一阐述。只需写上注释,call the HTTP api /api/products and send the result to our SNS topic /products
Copilot 就能基本完成所有工作。
因为我不是火箭科学家,所以方法将会是这样的(用伪 Javascript):
http.GET("/api/products").
then((products) => if (validateProducts(products)) {
this.sns.enqueue()
} else {
fail("invalid products")
})
如果您在撰写上述评论后自动完成 copilot,则很可能会出现:
http.GET("/api/products").
then((products) => if (validator.checkProducts(products)) {
const sns = new SNS(this.topic)
sns.enqueue(products)
} else {
throw Exception("invalid products")
})
我认为纠结于它到底用了validateProducts
没用,并没有validator.checkProducts
抓住重点。它真正的好处是,我通常只需要10分钟就能完成原本需要2小时才能完成的事情。
我认为这个事实的意义远不止“好吧,现在我们刚刚取代了代码猴子”。我认为,能够以这样的速度编写繁琐的代码会关闭如此多的反馈回路,从而产生改变我们构建软件方式的突发效应。
题外话#1:帮助 Copilot 输出有效代码
尽管 Copilot 非常渴望发现你的代码库,但它需要了解你喜欢的风格。它需要了解你已拥有哪些 API 和辅助方法,以及需要导入哪些包。
如果你想用 Tab 键补全 90% 左右的代码,解决方案是什么?访问几个你想让 Copilot “学习” 的文件,或者写一个它应该生成的示例。如果你想让 Copilot 熟练使用一个不太常用的库,只需浏览它的源代码,访问几个示例,然后返回去疯狂地用 Tab 键补全,最终生成一个可以运行的应用程序。
同样的技术也适用于 ChatGPT。你想让 ChatGPT 输出一个不错的结果吗?只需预先复制粘贴大量示例代码即可。复制粘贴你的类定义、类定义的注释、一些 DDL 语句、一些示例 CSV 代码。经常粘贴,每次代码出现问题时都粘贴。取出代码,修改后再粘贴回来。粘贴文档页面。粘贴整个 StackOverflow 帖子。粘贴粘贴,这里需要的是上下文。
方法论转变#1:编写文档
这是我们遇到的第一个方法论上的变化。除了为人类编写 API 文档之外,我们还需要编写代码(以及工具!),使 API 能够被 LLM 发现和“理解”。在大多数情况下,两者相辅相成。编写清晰简洁的注释可以让 LLM 了解它在训练集上看到的上下文,从而帮助它推断出正确的答案。清晰简洁的 API,加上有意义的名称,使我们能够有效地(标记越少越好)向工具传达我们的意图。
我认为我们将开始看到一些实践,将文档既易于人类阅读,又易于“机器解析”(简短、简洁,并包含一些具体任务的示例)。我们将不再使用诸如 UML、ODL、SOAP、Swagger、JSON Schema 之类的形式化语言,而是回归到简洁、实用的 README 文件,它只提供简短的概述和一些使用示例。这样做并非因为简单就更好(我们一直在重复造轮子是有原因的)。这样做之所以有效,是因为 README 文件能够很好地表达我们的“人类”意图,而源代码则以极其细致的方式体现了我们希望系统执行的操作,而 LLM 可以将两者结合起来,生成更“正式”的代码供机器解释,或者生成更简练的文本供人类解释。
我认为我们没有意识到与人类沟通的最有效方式现在也是与机器沟通的有效方式。
这当然是双向的。大型语言模型在将糟糕的评论转化为文笔流畅、表达清晰的段落方面非常有效。它们可以在我说“请”的时间内生成 5 个有趣的示例。它们可以在几秒钟内重构现有文档以匹配更新后的 API(这很麻烦,因为目前需要在 ChatGPT 之间复制粘贴)。Copilot Labs 正在试验“画笔”,但由于我使用的是 Intellij 而不是 Copilot,所以我很少使用它们。
他们可以用相同的方式更新代码以匹配文档的变更,或者根据简洁、编写良好的文档生成有效的代码。你甚至可以在终端中 curl 几个端点,将所有内容直接粘贴到 ChatGPT 中,无需任何编辑。然后,你可以让它创建一个包含模拟、单元测试、示例和文档的 API 库。这通常会输出比我写得更好的结果。
我再也不用手动编写任何数据处理/API 封装/结果验证的代码了。最近我不得不用 Google Tag Manager 构建一个服务器到服务器的集成。我直接把网页复制粘贴到一个简单的三行提示符中,现在只需一个简单的shell 命令就可以生成 PHP 类、TypeScript 接口、事件日志解析器和 SQL 序列化。
既然精心编写的文档既基础又几乎免费,我们该怎么做呢?我们应该成为作家吗?还是成为编辑?
我个人认为是的。没有理由不写出优秀的文档(或者用 Tab 键补全来写),文档风格和文档质量将变得像我们在花括号前加多少空格一样可自动化和可 lint,代码注释也永远不会过时(为什么你的 IDE 不会标记与代码行为不匹配的文档呢?)。6
如果我们成为编辑,这是否意味着,现在学习成为一名程序员,从一开始就意味着学习阅读、批评和修改代码?这些技能,是自专业软件工程爆发以来,我们在过去三四十年里痛苦地付诸实践的,而且通常只属于“高级”阶层,初级程序员则忙于敲打编译器之类的。但现在,成为一名初级程序员实际上意味着成为一名批判性阅读者。代码审查就是新的编程方式 。7
方法论转变#2:白板和橡皮鸭练习
攻读法学硕士学位可以让你明白,软件架构的核心在于模式匹配,而这些模式其实相当简单。但问题在于,ChatGPT 这类软件默认就像一个“设计面试扯淡机”。它会自信满满地使用各种巧妙的词汇,在白板上画出各种图表,却完全无法提出真正有价值的观点。如果你问 ChatGPT 如何设计某个应用程序,得到的答案会是一堆雷同的、裹着特氟龙外衣、却又与现实格格不入的陈词滥调(ChatGPT4 在这方面已经把门槛设得更高了……)。
说出正确的事情很容易,查找有效的事件驱动架构也很容易,但要弄清楚究竟需要做什么、哪些容易、哪些困难、哪些有效以及哪些在实际场景中会失败,却要困难得多。但是,使用上面展示的技术,一旦你开始询问 ChatGPT 如何构建一个具体的应用程序,例如勾勒出潜在的 API、充实基础架构、决定使用哪些协议,你通常会得到很多看起来合理、具体的代码。
我发现生成“合理”的代码本身就很有用。我不需要相信代码的正确性——整体结构和氛围让我了解这个东西将如何运作,哪里有问题,哪里巧妙。它拥有大量高质量的代码,可以依赖它们找到有趣的模式和命名恰当的类;当我想到什么的时候,我可以引导它。我基本上拥有一只非常“智能”的橡皮鸭。8使用 ChatGPT 进行头脑风暴的感觉就像和同事坐在白板前,只是想象一些东西,只不过你最终通常会得到相当接近工作的代码。虽然我从未与真人和 ChatGPT 进行过“三方”白板/橡皮鸭会议,但我认为这将成为一些人的常规做法。
方法论转变#3:构建更多原型
ChatGPT 非常适合生成各种大小的原型。向它询问一个主题,它不仅会回答,而且通常还会用你选择的语言提供一个完全可运行的示例。它可能会执行,也可能不会,但那都是一堆我不需要输入的无聊废话。一旦法学硕士写出一个玩具示例,我就可以把这个简单的例子改造成更多的东西:
- 完整的命令行应用程序
- 单元测试套件
- 模糊测试工具
- 文档的一个例子。
- 压力测试工具
- 一个简单的 Web UI(“为发布到 /api/product 的字段编写 HTML,并将生成的 JSON 显示为表格。然后,编写 CSS 使其像 geocities 页面一样设置样式。”就是这样做的……)
- 用于 CICD 的 Docker 容器
- ...
法学硕士将勘探成本降低至几乎为零。
我最近想写一个 OBS 插件,如果我在 1 分钟内没有关闭一个模式,录制就会停止。我之前从未写过 OBS 代码,但花了三个小时,我做到了以下几点:
- 构建一个看起来很有前途的 Python 脚本
- 与 OBS 斗争,直到我意识到尝试让 arm64 python 工作太令人沮丧了(损失了 1 小时......)
- 用 LUA 重写脚本并使其运行
- 我意识到我以为的那个奇怪的幻觉实际上是在 LUA 中实现类似模态函数的最佳方法。我觉得它很烂。
- 编写一个 Go CLI 应用程序来控制通过 websocket 进行的录制。
- 用 Go 编写一个跨平台的 UI,向我展示模式和各种其他按钮来控制录制
我尝试了两次死路一条(说实话,这并非法学硕士的错),最终开发出了一个健壮的可运行工具,我会继续扩展它。我讨厌编写 UI,讨厌与我不了解的晦涩 API 作斗争。我以前只在遇到麻烦到无法忍受的时候才会编写工具。我有一个正在努力戒掉的坏习惯:把开发个人工具当成是为大规模生产环境设计的(也就是说:做了三天“专业”的软件工程之后,我就精疲力竭,最终把工具扔进了沟里,虽然充满希望,但最终还是没能完成。)
对于专业编程来说,这意味着你现在可以写代码,写很多代码,写出海量的代码,然后直接扔掉。没有人会责怪你和 ChatGPT 聊了会儿,会生成 5000 行代码,然后就关掉标签页。但事实是,你写了 5000 行代码,然后觉得它们不值得。你上次这样做是什么时候?
如果现在的标准做法是,先对手头的问题进行简洁、文笔流畅的描述(参见上一节),然后要求法学硕士(LLM)提供一份 Go 语言的微服务架构草图、一份 Rust 语言的同步多线程草图、一份 Deno 版本的 TypeScript 代码,甚至可能是一份 Lambda 表达式,会怎么样?如果让它为 AWS、Azure 和 GCP 生成 Terraform,会怎么样?如果现在架构提案至少尝试 A、B、C、D 才能最终确定一个方案,而不是和同事无休止地争论 A 还是 B,才能进入审核阶段,会怎么样?我们都知道人人都有偏见。我们都持有强烈的意见,而这些意见只有 n 为 1 的证据才能支持。当我看到真实的代码草图时,我通常会更有信心。
我们过去常常嘲笑“以嘴巴的速度编写代码”,但现在这已成为现实。
方法论转变#4:构建更多工具
这让我想到了下一个我认为会非常有益的做法。我们都知道工具很重要,创建有效的工具很有挑战性,而且管理层并不关心或理解工具的必要性。法学硕士 (LLM) 让我们能够以所谓的“口语速度”构建工具。我知道我现在可以花 30 到 45 分钟与 ChatGPT 交谈,就能开发出一个相当不错的工具。以前,这可能需要我编程 4 到 5 个小时,这意味着我必须把它分成 2-3 个工作日(考虑到会议、代码审查、午休和其他干扰)。这通常意味着这个工具无法开发出来。
以下是我在过去 3 个月内构建的工具列表:
- sqleton - 以命令行应用程序形式运行 SQL 查询的工具
- escuse-me - 与 elasticsearch 相同
- geppetto - 与 GPT API 相同
- biberon - 与 bibtex 相同(非常简陋,它完成了一项工作)
- majuscule - 一个 Twitter 标签分割原型,但带有动态 HTML 调试 UI
- 当我离开电脑时停止 OBS 录制的脚本
- 许多工作实用工具:
- 将任意文档转换为代码(参见上面的 Google Tag Manager 示例)。
- 解析和分析搜索日志。
- 用于所述搜索日志的 SQL 构建器。
- 功能齐全的 GTM 服务器端实现。
- 用于管理横幅及其资产的工具。
- 一个通过 OCR 运行发票的应用程序,使用 GPT 进行清理,在 ElasticSearch 中搜索 SKU,并呈现与我们的库存相匹配的清理发票
- 我必须进行的每一个数据湖调试的报告生成器
- Google Tag Manager JSON 导出的文档生成器
现在我每天可以构建 2 个高质量工具来解决我想要解决的每一个问题,我无法表达编程的感觉有多么根本不同。
附言#2:基本面可能同样重要
我认为,抽象的学习主要源于观察和实践足够多的具体用例,最终形成了更高级的结构。抽象是一把双刃剑,不合适的抽象会导致持续的摩擦。虽然法学硕士(LLM)允许我们在“模糊抽象”层面上工作(这种抽象尚未准备好被形式化,但它正在形成和塑造用于描述问题的词汇),并快速探索具体的实现,但“掌控”法学硕士(LLM)的最佳方式是对问题有扎实的理解。
我在学习对话式法学硕士(LLM)的过程中遇到的一个非常现实的缺点是,你会忍不住不断地聊天和钻研一个问题,希望模型最终能“搞定”。当你对试图解决的问题没有充分理解时,这种情况会更加严重。你的注意力会从富有成效的对话转移到被幻觉所困扰,最终徒劳无功。在这种情况下,我发现自己会彻底断网。相反,我会坚持阅读线下文档和书籍,直到我更好地理解自己正在处理的问题。
掌握了“真”的知识后,向法学硕士提出正确的问题,会让整个过程更加高效。任何嘲笑“提示工程”是一门荒谬学科的人,都是在编写有效的提示方面投入了足够的时间。
题外话#3:避免无效的聊天
我希望未来的对话代理能够及时发现这些无效循环的发生。目前,ChatGPT 仍在继续发挥作用,但我预计它会在某个时候停止,并指出合适的教程和资源。另一个选择是询问更多细节。ChatGPT4 似乎取得了令人印象深刻的进展(我只认真使用了两天,所以无法给出确切的评价)。这个领域教会我的一件事是,不要对下一代模型的能力妄下结论。它可能存在与当前模型相同的根本问题,但它可能会变得“足够好”,以至于无论出于何种目的,这都无关紧要。
方法论转变 #5:持续代码审查
我认为工具的一个主要重点将是“持续代码审查”。模型可以观察你构建软件的过程,推断你的意图和思维结构,并针对你的方法提供反馈。它可以标记拼写错误、安全错误以及 API 的非惯用用法。ChatGPT4 能够纠正我的代码,并自行将问题有效地分解成接口和函数,这让我印象深刻。事实上,我认为,从小处来说,ChatGPT4 的编程能力比我强得多。它掌握了更多的惯用语,不会忘记安全问题,而且能够以令牌采样的速度生成单元测试。
那些认为这些模型会导致充斥着安全漏洞的 StackOverflow 底层代码泛滥的人,忽略了这些模型在自身功能上改进的速度有多快。我认为这是因为人们很容易忘记现在网上能找到多少优秀的代码。优秀的代码必然会在其训练语料库中得到更广泛的传播,而这些语料库也肯定会受到严格的审查和调整。从软件架构“修辞”角度来看,从 ChatGPT3.5 到 ChatGPT4 的飞跃就充分证明了这一点。
我使用一系列提示,要求模型针对安全问题、我遗漏的边缘情况以及文档不清晰的问题提供反馈。目前,我必须手动将这些信息复制粘贴到 chatgpt 中,提供缺失的上下文,并完善其答案。但这其实是一个工程问题。模型本身已经做得非常出色。这比我职业生涯中收到的大多数代码审查都要好得多,而且是即时的,并提供了重现问题的示例和修复建议。
现在,编写复杂的、模糊的 Linter 来检查特定领域和代码库的模式基本上变得更容易了,因为这些提示由一些(信息丰富的)人类语言提示组成。指示 LLM Linter “检查单例是否仅在处理客户数据时使用” 可能比在 editorconfig 中正确配置花括号行为更快。它不会捕获所有用例,但捕获的内容足够多,值得一试。
方法论转变#6:使用法学硕士的认知影响
这或许是最微妙的转变,但我相信这也是法学硕士给我带来的最深刻的变化。在专注于把“繁琐的事情”做好(使用正确的 API、检查正确的错误、正确调用 API X、为 Y 实现单元测试和模拟、为 Z 编写 API 包装器)一整天后,我的大脑会完全沉迷其中,被那些为了不犯错而必须的琐碎细节和高强度工作所占据。我会花一晚上的时间打游戏或看 Netflix 来恢复体力。
自从广泛使用 Copilot 和 ChatGPT 以来,这种认知疲惫几乎消失了。下午 6 点,我感觉自己花了一整天与好友聊天,但已经合并了 5 个 PR,编写了单元测试,改进了两个工具,并且代码已经发布。
这让我的开源项目取得了显著进展。我知道晚饭前能完成一件重要的事,晚饭后或许还能完成一两件。以前我会在周六花三个小时尝试运行 AWS Lambda,心里琢磨着“我周六到底为什么要这样过”,但现在我会很开心地解决一两张工单,然后把剩下的时间花在陪伴家人和做家务上。
进行更多“高层次”思考
我坚信让事情静下来,并进行“淋浴思考驱动”的软件工程。我相信有必要深入思考某件事,尝试构建一些原型,然后让它沉淀下来。真正的灵感(以及解决问题)往往发生在散步时,大脑充分休息时,运动后,或者沐浴后。以前,我每天或许能从这种“空闲”时间中抽出 30 分钟到 1 小时,但现在我可以把过去需要 4 小时才能完成的繁琐工作压缩到 1 到 2 小时(我这里只是平均时间,但编写像 API 包装器这样的程序现在只需 10 分钟而不是 2 天),而现在我每天有 3 到 4 小时的“空闲”思考时间。
这意味着我可以思考哪些需要做,哪些不需要做。这意味着我可以花一些时间尝试其他方法(构建更多原型,如上所述)。我可以花更多时间与利益相关者沟通,明确我们的需求。我可以思考团队本身需要哪些工具。我可以编写教学材料。我可以把报告写得漂亮些。这些事情以前并非无法做到,只是现在成本已经变得如此低廉,没有理由不去做。
结论
我希望更多资深开发人员能够花时间以开放的心态,认真评估这些技术,而不是下意识地做出防御性反应。这些技术令人担忧,因为它们明确表明,程序员将成为第一批被机器取代的群体。
以上列出的所有“改进”都将被我们行业的现有结构所利用(从某种程度上来说,企业已经是人工智能了),从而榨取更加令人窒息的生产力,造福于极少数人。我们现在有机会认真思考如何应对这些新兴力量。除了撰写我认为有价值的工程洞见之外,我还在努力思考自己想要走的方向:将这些技术从硅谷公司的护城河中解放出来;在企业赶上之前利用这些“改进的”生产力来探索组织方式;利用法学硕士(LLM)来构建更好的开源项目;利用这些技术为人们而非企业构建工具。
-
此外,虽然我可能会不经意地将LLM拟人化,但我这样做的方式就像我说的“编译器思考”一样。在我看来,LLM是相对简单的代码片段,用大量数据训练而成,而ChatGPT并不比
/bin/ls
我的S3生产日志存储桶更鲜活、更具有推理能力或更具感觉能力。它不知道,它不记得,它没有意图,它与世界没有任何互动。我希望我们讨论LLM的本质:基于给定上下文预测下一个token的语言概率模型,这些token是在经过精确训练之后基于给定上下文进行的。这种表述竟然催生了ChatGPT这样的项目,这让我大吃一惊,但我对讨论这些无可辩驳的猜测不感兴趣。我只想写代码,伙计…… ↩ -
编程与软件工程之间存在着一个我从未完全理解的界限。软件工程当然是关于构建优秀的软件,而编程,嗯,也同样是关于构建优秀的软件。当我绘制图表时,我在编程。当我撰写文档时,我在编程。当我在白板前与同事交流时,我们也在编程。当我阅读和编写大量软件时,我实际上也在进行大量的软件工程,因为我希望我的软件今天、明天、十年后都能正常工作(这意味着测量、测试、基准测试、突破、压力测试和文档记录)。我希望即使在 30 个人在截止日期的压力下工作时,它也能正常工作(这意味着设计、重构、测试、构建开发工作流程、撰写文档、沟通、理解团队结构和业务目标以及遗留问题和个人认知风格)。我称之为编程,因为我们实际上能够达成一致的唯一切实成果就是最终的成果(源代码和文档)。我喜欢研究和阅读遗留代码库,你可以在源代码本身中读到大多数“更抽象”的东西(简单来说:团队功能失调、目标不一致、沟通不足;难点在于:良好的入职培训、个人贡献者成长、良好的业务协同)。这就是为什么我经常提到编程。你可以把各种概念说得天花乱坠,但真正重要的是最终写出的代码。对我来说,好的代码等同于好的工程(好的代码可以是:解决业务问题的代码,通常没有代码才是最好的代码;优雅的代码(有些程序员喜欢做优雅的东西,大多数人喜欢使用优雅的东西);有趣的代码;等等……) 。↩
-
如果这听起来像是在吹牛,那么去年我发现自己患有自闭症后学到的一件事就是不要太在意别人的印象。我觉得自己是个很糟糕、很粗心的程序员;我喜欢分享我所知道的一切:我希望每个人都能像我一样,在使用电脑时感受到我的热爱。我很失望自己永远无法成为万事通,因为外面有太多很酷的东西了。我会把精通留给那些拥有更专注好奇心的人 。↩
-
这似乎又是一个含义丰富的术语,人们对此的定义争论不休。我将嵌入式、部分 Web、分布式、操作系统和部分数据库开发归入系统编程的范畴。这似乎是一个非常宽泛的范畴,但从编程的角度来看,我认为它包括队列、资源所有权、资源初始化和拆卸、并发、锁定的编程;协议、数据序列化、存储、带宽、吞吐量、延迟的编程;状态机、协程、调度程序、线程、驱动程序和 API 的编程。当我们从编程角度(我们编写的代码)定义“系统编程”时,我们会发现许多相似之处,这些相似之处是“生成性的”,即它们通过使用代码来产生洞察力和想法。这与将“系统编程”定义为操作系统编程形成对比。这阻碍了洞察力。它导致一代又一代的 Web 开发人员每次想要管理精简的资源而不是使用资源池时,都要重新发明轮子。它导致一代又一代的嵌入式开发人员拒绝更好的工具以及有效的测试和部署实践。它导致了设计糟糕的嵌入式 UI、缓慢的 Web 应用程序、令人不快的并发抽象以及认为一切都是整数的操作系统的出现 。↩
-
你可能想知道为什么我把 Common Lisp 和 PHP 归为一类。Common Lisp 语言的特别之处在于,它允许你随时随地以任何方式构建自己的语言。你可以交互式地对其进行优化。如果你的目标是编写结构清晰、上下文明确的代码,那么 Common Lisp 是一个绝佳的工具。你无需将你的沟通强行塞进一个现成的僵化框架中,而是可以构建一个适合你沟通的结构。正如我们将看到的,这正是法学硕士 (LLM) 能够出色完成工作的原因。另外,看看 Common Lisp 规范,告诉我它不是……笨重且表面粗糙 。↩
-
浏览geppetto 的仓库后,你可能会发现……不写文档也很容易。它肯定不是完全免费的。另一个原因是我暂时还不想让人们使用这个工具。我已经在glazed 的文档上投入了更多精力,包括受Mathematica优秀文档 的启发,构建了一个完整的帮助系统。↩
-
我认为那些担心初级程序员被淘汰的人,更应该担心的是初级程序员取代资深程序员。人们很容易相信,随着年龄的增长,你的思维会越来越年轻。然而,在 Discord 上和充满激情的 15 岁孩子混在一起,我很快发现自己变得多么僵化。我可能认为,我对前端框架和基于组件的 CSS 的优雅理解,我精心设计的 git 工作流程和可观察性实践,就是技艺的体现。与此同时,孩子们认为,当他们合并当天的第 30 个拉取请求时,我也可以编写 COBOL 语言。这将使他们能够完全自动化地进行持续集成和持续交付 (CICD),从而部署新创建的工件。在 Tiktok 上分享的每个随机存储库都会在几天内获得 300(3000?30000?)颗星。1998 年,我编写开源代码可能意味着合并一个补丁,因为我认识 IRC 上某个关心的人,而今天,这意味着快速成长,并迅速成为一名敏捷技术主管 。↩
-
作为一个需要滔滔不绝地跟别人唠叨才能理清思路的人,这简直是魔法。缺点是,这个工具的“个性”会随着时间推移而改变。它会抓住新奇的概念,并大量删减或淡化那些比较武断的陈述,这通常是为了应对那些提示性的攻击,以及为了减少幻觉和其他副作用。这和你在头脑风暴时想要的效果完全相反,在头脑风暴中,那些天马行空的想法才能激发快乐。为了解决这个问题,我经常会提示最糟糕的模型,然后把他们的胡言乱语粘贴到更合理的模型上,以此来扰乱整个过程 。↩