Agili 的 Hacker Podcast

Agili 的 Hacker Podcast 2025-12-14


Listen Later

欢迎收听 Agili 的 Hacker Podcast,今天我们的话题横跨古今,从北美大陆消失的猫科动物之谜,到在 Mac 上运行的万亿参数 AI 模型;我们既深入探讨 Win32 底层编程和编译器工程的实践智慧,也反思 AI 自动化带来的深刻反讽与软件供应链安全的严峻挑战。

为 Win32 回调函数注入“闭包”

在 Win32 API 编程中,如何为像 WNDPROC 这样的回调函数传递上下文数据,一直是个棘手的问题。Chris Wellons 在他的文章《Closures as Win32 window procedures》中,展示了一种巧妙而硬核的解决方案:通过即时编译(JIT)生成汇编跳板(trampoline),为这些固定签名的回调函数“添加”一个自定义的上下文参数,在 C 语言层面实现了类似“闭包”的功能。

文章要点精炼说明

文章首先回顾了处理 Win32 窗口过程上下文的两种常见方法:

  1. 全局变量:简单粗暴,但会导致代码难以维护和扩展。
  2. GWLP_USERDATA:Win32 提供的标准机制,通过 SetWindowLongPtr 绑定一个指针到窗口。但此方法设置繁琐,且每次使用都需调用 API 检索。
  3. 作者提出的创新方案是通过一个 JIT 编译的跳板函数,为 WNDPROC 引入一个“第五个参数”——上下文指针。其核心实现细节包括:

    • 跳板的运作方式:在 x64 架构下,跳板是一段动态生成的汇编代码。它接收 Win32 传递的四个寄存器参数,然后手动调整栈帧,在调用我们真正的处理函数 Wndproc5 之前,将自定义的上下文指针作为第五个参数压入栈中。
    • 可执行内存分配:作者利用 GNU 汇编器和链接器,在可执行文件内部定义了一个可写可执行的特殊段 .exebuf,这简化了 JIT 代码对主程序函数和数据的引用。
    • make_wndproc 函数:该函数负责接收自定义函数指针和上下文指针,动态生成并填充跳板的汇编代码,最终返回一个符合 WNDPROC 签名的函数指针。
    • 适用性:该技术不仅适用于 WNDPROC,也能解决其他 Win32 API 回调函数缺乏上下文指针的问题。
    • 评论区观点分析:实用性、历史回顾与替代方案

      社区围绕此方法的实用性、历史背景、潜在问题及替代方案展开了多角度探讨:

      • 实用性与“炫技”的争论:一些人认为,相比 GWLP_USERDATA,这种方法过于复杂,更像一种“派对把戏”。但也有人指出,在处理 WM_GETMINMAXINFO 等 GWLP_USERDATA 尚未设置的边缘情况时,跳板方法能“天然”地解决问题。
      • 历史回顾与 Win32 设计哲学:讨论追溯到 Win16 时代的 MakeProcInstance 机制,以及早期 ATL/WTL 库中类似的技术。有人推测,WNDPROC 缺少上下文指针的设计是为了保证控件类的可重用性。
      • 替代方案与改进:有开发者分享了使用 cbWndExtra 分配额外窗口数据、结合 GWLP_USERDATA 与 GWLP_WNDPROC 实现 Rust 闭包,或利用线程局部存储(thread local)等多种替代和变通策略。
      • 技术细节的探讨:讨论还涉及 CPU 缓存与安全(如是否需要 FlushInstructionCache())以及 C++ Lambdas 的适用性问题。最终结论是,带捕获的 C++ lambda 无法直接转换为裸函数指针,这恰恰凸显了文章所解决的核心痛点:如何将一个有状态的函数适配到不接受上下文的 C API 中。
      • 打造护眼工作站:将电子墨水平板用作 Linux 显示器

        长时间盯屏导致的眼部疲劳是许多开发者的痛。Alireza Alavi 分享了他利用 Onyx BOOX Air 2 这款 Android 电子墨水(E-Ink)平板,作为 Linux 系统辅助显示器的成功经验,旨在打造一个更护眼的阅读和轻度编辑环境。

        在排除了导致延迟过大、显示不清的 Deskreen 方案后,作者最终选择了 VNC 方案。他使用 TigerVNC 作为 Linux 端的服务器,AVNC 作为 Android 端的客户端。成功的关键在于,运行 x0vncserver 时,通过 geometry 参数将分辨率与 E-Ink 平板精确匹配,并调整主显示器分辨率以消除边框,从而实现最佳显示效果。

        作者强调,此方案并非旨在替代主显示器,而是作为补充,非常适合大量阅读和简单文本写作。虽然刷新率仍是瓶颈,但它在阅读时能极大减轻眼部负担。此外,通过 VNC,平板还能作为输入设备,方便在办公室移动办公。

        社区观点与实践分享
        • 痛点共鸣与健康价值:许多用户表示有类似需求,认为为了健康,牺牲一些刷新率是值得的。有人甚至将 E-Ink 的低刷新率视为一种优势,因为它能阻止分心的行为,让用户更专注于文字。
        • 商业产品 vs DIY 方案:社区提到了 Dasung、Boox Mira Pro 等专业 E-Ink 显示器,价格昂贵但体验更佳,甚至可以进行一些低帧率游戏。然而,商业产品也存在驱动闭源、Linux 兼容性差等问题,凸显了 DIY 方案的灵活性。
        • 技术局限与挑战:延迟和刷新率是 E-Ink 最大的瓶颈,即使是简单的命令行操作,输入延迟也可能过高,被一些人称为“人体工程学的噩梦”。
        • 未来展望:社区对 E-Ink 的未来充满期待,渴望出现带 E-Ink 屏幕的 Linux 笔记本,甚至为 Framework 笔记本开发 E-Ink 模块。Modos Paper Monitor 等众筹项目也备受关注。
        • 安全与隐私考量:有用户提醒,部分品牌的 E-Ink 设备可能存在数据安全隐患,建议在处理敏感信息时,通过私人网络连接 VNC 以增加安全性。
        • 代码的“诗与远方”:重温 J 语言的早期实现

          一篇来自 Roger K.W. Hui 的老文章《J 语言的实现 (1992)》引发了社区对数组语言的再次热议。J 语言作为 APL 的一个方言,以其极度简洁的 ASCII 语法和强大的数组处理能力著称。这篇文章深入探讨了 J 语言在 1990 年代初的 C 语言底层实现,包括句子解析、词法构成、内存管理以及核心的动词、副词等概念。

          社区洞察与多角度探讨
          • 数组语言的魅力与高效:许多开发者对数组语言赞不绝口,认为它们提供了高效且富有表现力的编程体验。代码的“压缩性”让人感到清爽,处理数据如同“揉面团”般自如,尤其在算法挑战中表现出色。
          • 陡峭的学习曲线与可读性:与赞美声相伴的是对其高学习门槛和可读性的抱怨。J 语言独特的隐式语法和动词链被认为难以记忆和掌握,导致代码风格如同“噩梦”,缺乏现代语言的“可读性”。
          • “思维工具”的辩论:APL/J 社区常提的“思维工具”概念引发了讨论。有观点认为,所有编程语言都是思维工具,而 J 语言尤其擅长改变人们处理批量数组数据的思维方式,鼓励用户从更高维度思考问题。
          • 特定应用场景与类比:社区普遍认为数组语言并非通用解决方案,但在特定领域(如矩阵运算)表现卓越。有人将其与正则表达式类比:都是在特定领域内极其强大的工具,并建议主流语言可以考虑嵌入一个数组语言解析器,用于处理局部的小型矩阵操作。
          • 持续发展与开源:尽管文档古老,但 J 语言本身仍在持续发展。社区分享了其在 GitHub 上的开源代码库,证明了它至今仍是一个活跃的开发项目。
          • 欧洲健康数据风波:一桩引人担忧的跨国收购案

            一篇来自 "Follow the Money" 的报道揭露,负责处理欧洲多国政府、医院等机构敏感数据的安全公司 Zivver,已被美国公司 Kiteworks 收购。这引发了对欧洲数百万公民健康数据隐私和安全的广泛担忧。

            报道指出,令人不安的是,收购方 Kiteworks 的首席执行官及多位高管,均有以色列国防军精英网络情报部队(如“8200部队”)的背景。尽管 Zivver 声称其服务对文件进行了加密,但调查显示该公司实际上有能力读取这些文件的内容。这意味着,欧洲公民的高度敏感个人数据,现在不仅受到美国法律(如 CLOUD Act)的管辖,还由一家与外国情报机构有密切联系的公司负责监督。网络安全专家认为,这笔交易本应被阻止或进行更严格的评估,担心数据可能被用于不可预见的用途。

            Hacker News 社区对此事的讨论异常激烈。许多评论者强调,欧洲人对数据隐私极为重视,这不仅源于 GDPR 的规定,也出于对个人信息被滥用、敲诈或泄露的普遍担忧。对 Kiteworks 公司背景的质疑声不绝于耳,一些人担忧该公司可能是情报机构的前沿阵线。

            然而,也有观点试图进行更中立的分析,认为前密码学家利用专业知识创办网络安全公司是合乎逻辑的,不应直接推断出恶意。另一些人则指出,任何将文件上传到第三方平台的服务,都存在服务提供商访问数据的固有风险。这次收购事件凸显了在全球化背景下,国家数据主权、个人隐私权与国际商业交易之间复杂且敏感的平衡。

            “猫科动物空白期”:北美大陆一段被遗忘的演化史

            古生物学中有一个引人入胜的谜题——“猫科动物空白期”(Cat Gap),它描述了大约 2500 万到 1850 万年前,北美洲化石记录中猫科或类猫物种化石异常稀少的时期。

            文章要点精炼

            这个“空白期”持续了约 650 万年。在此之前,北美大陆生活着外观似猫的“裂齿猫”(Nimravids),但它们并非现代猫科的直系祖先。裂齿猫灭绝后,直到真正的猫科动物——拟虎(Pseudaelurus)——从亚洲迁徙而来,才填补了这一生态空白。关于造成空白期的原因,假说众多:

            1. 极度食肉倾向:裂齿猫过度特化的食肉习性使其对环境变化极其脆弱。
            2. 气候与栖息地变化:全球变冷导致森林被稀树草原取代,使依赖森林的类猫捕食者失去生态位。
            3. 大规模火山活动:超级火山爆发可能引发“火山冬天”,导致全球降温和大规模灭绝。
            4. 晚新生代冰河时代:持续的全球变冷使得北美更适合犬形亚目物种生存。
            5. 社区观点总结与分析

              Hacker News 社区的讨论充满了科技爱好者的独特视角和幽默感:

              • 猫科动物的智能与未来遐想:许多评论以幽默的方式推测,猫科动物可能是超级智能物种,它们发明了人类来服务自己,然后“功成身退”。这种思路延伸到科幻场景,设想未来即使人类灭绝,AI 和机器人也会继续服务猫咪。
              • 猫的驯化与社会性:讨论延伸到猫的驯化史,以及它们在特定条件下(如流浪猫群)表现出的群居行为,这可能与“幼态持续”现象有关。
              • “空白期”的科学严谨性:有评论质疑“空白期”是否只是化石记录中的“采样偏差”,因为捕食者的骨骼化石本就稀少。但也有人反驳,空白期前后物种的演化不连续性证明了其真实存在。
              • 幽默与梗文化:“我们必须弥合猫科动物空白期!”——模仿肯尼迪总统的著名演讲,充满了网络迷因色彩,为这个科学话题增添了趣味。
              • mathlib4:用代码构建可验证的数学宇宙

                mathlib4 是一个为 Lean 4 定理证明器打造的、由社区维护的庞大数学库。它旨在将从代数到拓扑学等众多数学理论形式化,并提供机器可验证的证明,是数学与计算机科学交叉领域备受关注的项目。

                mathlib4 不仅是一个数学公式的集合,更是一个包含编程基础设施、数学概念定义以及辅助证明策略的综合性工具。该项目由一个活跃的社区共同维护,拥有完善的文档体系和交流社区,为用户和贡献者提供了丰富的学习资源,并提供了从 Lean 3 迁移到 Lean 4 的详细指南。

                社区洞察:学习定理证明器的职业前景

                社区最关心的问题之一是:学习 Lean 或类似的定理证明器能带来哪些职业机会?

                • 工业界应用广泛:评论指出,定理证明技术已在工业界得到显著应用。例如,亚马逊、微软、ARM 和苹果等公司已将其用于核心系统验证、密码学算法安全、硬件芯片设计等领域,以确保系统的绝对正确性。新兴的区块链公司也利用它来验证智能合约的安全性。
                • 学术与研究机会:另一方面,Lean 的社区也提供了大量学术职位信息,表明在大学和研究机构中,仍有大量与 Lean 相关的研究和教学岗位。
                • 独特的竞争优势:综合来看,形式化验证和定理证明器技术正从纯学术领域扩展到对安全性、可靠性要求极高的工业应用中。掌握 Lean 等技能的开发者,将在高可信系统、安全关键软件和硬件、以及复杂算法验证等领域拥有独特的竞争优势。
                • 万亿参数模型本地化:Kimi K2 在 Mac Studio 上的运行实践

                  一则“Kimi K2 1T 模型在两台配备 512GB M3 Ultra 的 Mac 上运行”的消息,展示了在高端消费级硬件上运行万亿参数模型的可能性,引爆了社区对模型特性、本地部署价值以及未来发展方向的深入思考。

                  Kimi K2 的独特魅力

                  许多用户对 Kimi K2 模型赞不绝口,认为它有别于市面上常见的、倾向于“讨好”用户的模型:

                  • 独树一帜的风格:Kimi K2 的写作风格“非常独特”,它不像其他模型那样一味奉承,而是“毫不犹豫地指出现实”,甚至“直言不讳地指出你的错误或废话”,使其成为优秀的编辑工具。
                  • 高情商和精准:Kimi K2 对“情商”有很好的理解,能精准解读信息中的信号和意图。EQ-bench 情感智能基准测试也显示其名列前茅。
                  • 卓越的逻辑推理:Kimi K2 在一些特定基准测试中(如“时钟测试”)表现出色,暗示其在逻辑和空间推理方面可能拥有不同寻常的能力。
                  • 本地运行的价值与成本之辩

                    社区还围绕在本地运行大型 LLM 的成本、可行性以及与云端服务的对比进行了深入探讨:

                    • 高昂的硬件成本:运行 Kimi K2 1T 所需的双 M3 Ultra 配置总价高达 19000 美元,引发了关于投资回报的讨论。
                    • 本地运行的价值
                      • 隐私与安全:对于处理敏感信息的用户,本地运行是首选,避免了数据外泄的风险。
                      • 自主性与控制权:拥有本地解决方案意味着不受云服务商未来商业策略变化的影响。
                      • 低延迟与定制化:本地部署能提供更稳定、更灵活的响应和实验空间。
                      • 云端服务的优势
                        • 成本效益:对于非全天候使用场景,云端服务的按需付费模式更具经济吸引力。
                        • 便捷性:云端服务省去了硬件采购、维护和部署的复杂性。
                        • 总的来说,Kimi K2 以其独特的风格找到了市场定位,而其在 M3 Ultra 上的运行,则点燃了社区关于本地 LLM 部署的大讨论。这不仅仅是性能与成本的权衡,更关乎用户对数据控制、自主性以及未来 AI 发展方向的深层思考。

                          Trigger.dev 供应链攻击复盘:从 Shai-Hulud 事件中汲取教训

                          Trigger.dev 发布了一篇详细的事件复盘报告,讲述了其开发机器如何被 Shai-Hulud 恶意软件攻陷,并导致 GitHub 组织访问权限被盗的全过程。这起事件是 Shai-Hulud 2.0 在 JavaScript 生态系统中迅速蔓延的一部分。

                          事件复盘:攻击、响应与教训
                          • 攻击起源:恶意软件通过 pnpm install 进程中的 preinstall 脚本启动,利用 TruffleHog 工具扫描并窃取了开发者机器上的 GitHub token、AWS 凭证等敏感信息。
                          • 攻击行为:攻击者在获取凭证后,进行了长达 17 小时的侦察,大规模克隆了 Trigger.dev 的 669 个代码仓库,随后进行了短暂但破坏性极强的操作,如 force-push 和关闭 PR,提交信息伪装成“Linus Torvalds”。
                          • 检测与响应:团队在 Slack 频道收到大量异常通知后迅速响应,在 4 分钟内移除了被入侵账户,成功阻止了攻击的进一步扩大。
                          • 应对措施:团队采取了多项强化安全措施,包括全局禁用 npm 脚本、升级 pnpm 并启用安全功能、将 npm 发布流程转向 OIDC(开放身份连接),以及对所有代码仓库启用分支保护。
                          • 人文关怀:文章特别强调了不应归咎于受害工程师,因为根本问题在于生态系统允许软件包在安装时静默运行任意代码。
                          • 社区观点:责任、防御与反思
                            • “npm install 并非疏忽”的争论:社区对此展开激烈讨论。多数人认同文章观点,认为这是包管理器生态系统的根本性安全缺陷,应从系统层面解决。但也有人认为,在多次发生类似事件后,开发者若仍不采取更严格的措施,就是一种疏忽。
                            • 凭证管理与防范措施:社区强烈推荐使用硬件安全模块(如 YubiKey)、TPM、或密码管理器(如 1Password)来保护 SSH 密钥和敏感凭证,并尽可能使用短生命周期的临时凭证(如通过 OIDC 获取)。
                            • GitHub 组织安全:大家一致认同分支保护(Branch Protection)的重要性,它可以有效防止未经审查的 force-push,是组织安全的基本防线。
                            • 对攻击者行为的困惑:许多人对攻击者在窃取数据后为何采取高调的破坏性行动感到不解,猜测其目的可能是为了混淆视听或进行挑衅。
                            • 透明度的重要性:社区高度赞扬 Trigger.dev 的透明复盘,认为这对整个行业提升安全意识至关重要。
                            • 编译器工程实践:教科书之外的智慧

                              Sean Silva 的系列博客开篇文章《编译器工程实践——第一部分:什么是编译器?》,旨在分享那些经验丰富的编译器开发者心照不宣、却鲜少系统性记录的实践智慧。文章超越了教科书的定义,从工程实践角度深入探讨了编译器的核心挑战。

                              核心要点解析
                              1. 编译器的本质与可调试性:从工程角度看,编译器只是一个读写文件的程序。如果设计得当,它非常容易在隔离环境中调试,因为其大部分 bug 都是可重现的,无需面对操作系统或网络中的复杂异步问题。
                              2. 可靠性的极致要求:编译器对可靠性的要求极高。“误编译”(Miscompile)——即编译器生成的代码未能忠实再现源程序行为——的后果极其严重。因此,编译器开发的大部分工作都围绕着如何在产生错误输出前阻止编译器运行
                              3. 中间表示(IR)的复杂性:编译器的核心复杂性在于其中间表示(IR)数据结构。IR 是软件工程中最复杂的数据结构之一,体现在其复杂的节点模式(Schema)和节点间的交互上。开发者必须精确区分不同抽象级别的 IR,以避免不当的优化导致错误。
                              4. 编译器也是软件:尽管有其特殊性,编译器仍需遵循优秀的软件工程原则,如 API 设计、测试和复用性。
                              5. 社区观点与实践分享
                                • 理论与实践的距离:有资深开发者分享了早期编译器优化因超越基准测试预期而被误解为“作弊”的案例,生动说明了实践与理论的差距。许多人认同“理解编译器的唯一方法是自己写一个”。
                                • IR 的双面性:有评论认为,IR 恰恰是通过将大问题分解为小转换,从而让编译器变得“可管理”,而非“困难”。但同时,IR 的转换也给错误信息的报告带来了挑战,因为难以将底层错误精确定位回原始源代码。
                                • 误编译的细节:社区对文章中关于“整数溢出误编译”的例子进行了技术性探讨,展现了开发者对细节的严谨追求。
                                • 编译器与其他软件工程领域的比较:讨论延伸到编译器与并发垃圾收集器等其他复杂领域的比较,凸显了不同领域复杂性的差异和主观性。总体共识是,编译器工程的挑战在于如何让众多优化安全、可预测且可调试地协同工作。
                                • AI 与自动化的反讽:当智能系统遇上人类专家

                                  一篇引人深思的文章《AI 与自动化中的反讽——第二部分》,借鉴了 1983 年工业自动化的经典论文《自动化的反讽》,探讨了人工智能在“白领”工作自动化中带来的深刻挑战和意想不到的后果。

                                  文章指出,尽管现代 AI 自动化与当年的工业自动化情境不同,但其引出的问题却惊人地相似:

                                  • “最糟糕的用户界面”问题:AI 代理通常以冗长而自信的语气提供行动计划,人类操作员被期望在 AI 罕见犯错时进行干预。然而,这种交互方式极易导致“监控疲劳”,使微小但关键的错误被忽略。
                                  • “培训悖论”:随着 AI 接管日常工作,人类的专业技能会迅速退化。然而,当 AI 遇到无法预见的复杂问题时,仍需人类专家介入。最大的反讽在于,自动化程度越高的系统,对人类操作员的培训投入反而需要越大,因为他们需要为那些极其罕见的异常情况做好准备。
                                  • “领导力困境”:监督 AI 代理不仅仅是被动监控,更需要主动“引导”它们,这本质上是一种领导角色。然而,许多领域专家并不具备这种领导力,也未接受过相应培训,导致在与 AI 协作时感到不适。
                                  • 社区洞察与延伸思考
                                    • 技能退化与专业知识丧失:社区普遍担忧 AI 会导致技能衰退,就像计算器导致心算能力下降一样。但也有人指出,与计算器等确定性系统不同,LLM 本质上是非确定性的,其输出即使看似正确也可能含有潜在问题,这使得人类持续的验证和监督变得更加必要和复杂。
                                    • “最糟糕的用户界面”的共鸣:许多人分享了自动化导致“静默失败”的经历。一个自动化的报告可能错误了几个月都未被发现,因为自动化降低了人们检查和验证的本能。
                                    • 航空业的启示:社区将 AI 自动化的挑战与航空业的经验进行比较。为了确保安全,飞行员即使在高度自动化的环境下,也需要进行大量的真实场景训练以保持手动操作技能。这与软件行业追求“快速迭代”的文化形成鲜明对比,后者往往忽视了对长期风险和人员培训的投入。
                                    • 更广泛的文化影响:有评论者担忧 AI 生成内容正在“污染公共领域”,特别是在艺术和写作等创意领域,可能导致社会失去其“创造性图书馆”,使未来的模型内容与现实脱节。
                                    • 相关链接:

                                      • Closures as Win32 Window Procedures
                                      • Using e-ink tablet as monitor for Linux
                                      • An Implementation of J (1992)
                                      • Europeans' health data sold to US firm run by ex-Israeli spies
                                      • Cat Gap
                                      • Lean theorem prover mathlib
                                      • Kimi K2 1T model runs on 2 512GB M3 Ultras
                                      • Shai-Hulud compromised a dev machine and raided GitHub org access: a post-mortem
                                      • Compiler Engineering in Practice
                                      • AI and the ironies of automation – Part 2
                                      ...more
                                      View all episodesView all episodes
                                      Download on the App Store

                                      Agili 的 Hacker PodcastBy Agili 的 Hacker Podcast