matklad

16 篇内容

技术文章matklad

Finding Bugs

文章围绕“生成式/随机化测试是否比示例单元测试更能发现 bug”展开,以 regex crate 中“.abb|b”在输入“zabb”时错误返回“b”的 bug 为案例。作者实现了一个小型 fuzzer,核心策略是用 oracle:交叉对比 regex 与 regex_lite 的匹配结果;同时通过 swarm testing 随机选择正则特性与字符表,随机化分布本身,并坚持生成小而刁钻的样例而非大而均匀的输入。文中的递归正则生成器、权重式特性选择、内存复用与搜索循环均给出完整 Rust 代码。作者确实复现并发现了另一个 bug,但承认自己已知目标 bug,论证强度有限;该方法最适合纯算法或易于构造 oracle 的组件,对缺乏 oracle 的大型系统并不直接适用。

推荐收录:文章给出了从 oracle 设计、swarm testing 到正则生成器与搜索循环的完整可运行代码,并用 regex/regex_lite 交叉验证实际找到 bug,证据具体。适合测试、基础库和 Rust 开发者参考,可迁移到 fuzzing 与差分测试设计;局限是作者已知目标 bug,且 oracle 在复杂系统中并不总是容易获得。

技术文章matklad

Static Allocation, Constant Work

文章从回复一封关于“内存安全最难题”的邮件切入,讨论 use-after-free 与类型混淆的本质区别。作者用订单匹配引擎的 bug 说明:在没有对象池时,逻辑错误会变成物理类型混淆,可被利用为任意代码执行;引入类型隔离的对象池后,逻辑错误仍可能发生,但不再产生类型混淆。随后介绍两个来自 TigerStyle 的务实技巧:静态分配,即启动时确定最大容量并拒绝超额请求,避免运行期 OOM 导致灾难性故障;恒定工作量,即用“保留订单”填满固定数组,让每个订单只是状态流转,并通过全量遍历保证延迟平稳、便于编译器优化。文章还指出内联枚举是上述方案的破坏点,若始终堆分配枚举变体则可恢复。最后强调这些技巧有适用边界,不是万能解药。

推荐收录。文章以具体 bug 出发,把内存安全从类型混淆问题拆解为可工程化的设计约束,提出类型隔离分配、静态分配和恒定工作量等可迁移模式。适合系统程序员、语言设计者和高并发后端工程师参考;其对灰色失败和向量化性能的讨论体现了边界与取舍,风险在于这些模式并非适用所有场景。

技术文章matklad

Cancelation Terminology

本文探讨并发编程中三个常被混淆的概念:同步取消、异步取消与优雅停机。作者认为三者属于不同层面——同步取消本质是控制流结构(类似异常展开),异步取消是双方之间的通信协议(请求方需等待确认),而优雅停机是应用层处理连接的编程模式,常用于滚动升级。文章用 CPU 线程池、io_uring 及 TigerBeetle 中的 Grid.cancel、StateMachine.reset、Client.shutdown 等实例说明差异,并指出 Client.shutdown 实际是异步取消而非优雅停机。文中还引入 crash-only software 思想,认为分布式系统中崩溃只是慢的一种特例,尾部延迟容忍是更通用的方案。作者提醒术语本身可替换,但背后的区分对代码形态影响很大,尤其 Rust 中同步取消太容易而异步取消机制较弱。

推荐收录:文章以清晰的层次区分了同步/异步取消和优雅停机,并用生产级系统 TigerBeetle 的真实代码佐证,避免了空泛的概念讨论。适合并发编程、分布式系统或基础设施开发者阅读,能帮助在设计阶段识别取消的形态并做出合理的架构取舍。其可迁移价值在于术语背后的分类框架,但需注意作者所用术语并非业界统一标准。

技术文章matklad

Rust Glancer

文章由rust-analyzer作者撰写,围绕低内存Rust LSP服务Rust Glancer展开,深入反思了rust-analyzer的架构设计。作者认为rowan语法树适合增量编辑,但大多数依赖包只需浅层分析,主张AST应基于数组存储,并对函数体分析采用惰性策略。文中对比IntelliJ的PSI多后端(语法树、stub树、class反编译)与rustc的.rmeta文件,提出类似的分层架构:用户编辑的文件用增量AST,依赖包用紧凑的元数据。还讨论了proc macro展开成本高,可借用Sorbet的shim思路规避,以及LSP数据同步的固有缺陷。最后点明rust-analyzer核心抽象API未完成的问题。这是对IDE工具链架构的深度思考。

推荐收录:作者是rust-analyzer核心开发者,文章直接给出IDE架构的关键权衡,如AST存储、惰性分析、依赖元数据复用,以及对IntelliJ/rustc机制的迁移分析。适合编译器/IDE开发者、编程语言工具链研究者阅读,其“分层源码表示”思路可迁移到其他语言工具。风险是部分观点属个人倾向,需结合工程验证。

技术文章matklad

Better Batteries

文章质疑“标准库应最小化还是包罗万象”的传统争论,提出真正的问题是“怎样的社会架构才能产生高质量标准库”。作者对比 Python、Go、Rust 的生态现实:Python 标准库质量参差,但提前暴露 API 反而推动了数据科学革命;Go 通过 golang.org/x 扩展生态保留设计余量;Rust 1.0 集合与迭代器 API 堪称典范,但后续新增 API 的效率有限,nursery 沦为墓地。作者认为决定性因素不是库的大小,而是语言生态中的组织结构、决策机制和激励方式。这是基于编译器与语言生态经验的思辨性随笔,缺乏量化数据,但提供了新的分析视角。

这篇文章从社会架构角度重新定义标准库设计问题,用 Python、Go、Rust 的具体案例支撑论点,避免了空泛的“大小之争”。适合编程语言设计者、开源项目维护者和软件架构师阅读,其分析框架也可迁移到其他开源生态的治理决策中。虽为例证式随笔,但观点鲜明、边界清晰,具备长期参考价值。

技术文章matklad

Zig's Io.Threaded is Neat

本文深入解析Zig语言标准库`std.Io.Threaded`的实现,重点介绍其如何在阻塞线程模型中可靠支持取消操作。作者先区分并发与并行,指出取消是并发的本质特征,而传统线程因系统调用阻塞难以取消。然后详细说明在POSIX上通过信号与共享内存标志位协作的取消协议,以及Windows上使用`NtCancelSynchronousIoFile`的更直接方式。文章还对比了Java线程中断和`pthread_cancel`的不足,并分析Zig在接口层面将`async`与`concurrent`分离的设计优势,从而在用户态实现清晰的取消语义。内容深入系统调用、运行时和语言设计的交界,展示了将一个“怪异”想法工程化落地的细节,但方案依赖特定平台机制,且线程池复用等工程权衡未充分展开。

推荐收录,因为本文不是泛泛介绍Zig特性,而是对并发取消这一底层难题给出具体实现解析,从信号/标志位协议到接口设计取舍均有清晰论述,并提供了跨平台对比。适合系统编程、语言运行时和并发模型设计者阅读,其按平台中断syscall的思路以及分离异步与并发的接口设计可供其他语言或框架参考。

技术文章matklad

Memory Safety's Hardest Problem

文章聚焦于内存安全领域最棘手的问题:带标签联合体(tagged union)的类型混淆。通过Zig代码实例演示了初始化联合体为一种类型、获取内部指针,再覆盖为另一种类型,导致指针类型与实际数据不匹配,违反类型安全。指出类似问题也存在于Ada,构成典型反例。文章进一步区分理论难点与实际攻击面,强调实践中缓冲区溢出远比联合体混淆常见,但早期行业未采纳更安全的数组语法是重大失误。整体上,通过历史视角和代码实证,探讨了语言设计如何影响内存安全性,边界在于未深入讨论类型混淆在现代漏洞利用中的实际威胁。

推荐收录,因其以简明代码和参考文献直指内存安全的一个底层难题,纠正了常见认知。对从事系统编程、语言安全或编译器设计的读者,此文提供了可迁移的反例分析和历史教训,有助于理解类型系统与安全性的深层关联。其价值在于将复杂问题具像化,并引导读者反思语言设计决策。

技术文章matklad

CSS: Unavoidable Bad Parts

这篇文章是一篇面向“不是 Web 开发者、但需要把页面样式做对”的 CSS/HTML 实用导读,作者试图提炼出一个足够小、可学习的现代 Web 子集。文章围绕语义化标签、CSS reset、classless CSS、box-sizing、margin collapsing、flexbox、响应式设计以及字体尺寸、行高、断行等常见坑展开,强调应优先理解浏览器默认行为和布局约束,而不是把 CSS 当成纯粹的样式拼装。

推荐收录,因为它不是泛泛而谈的 CSS 入门,而是把“简单博客/轻量 GUI 真正会踩的坑”集中梳理成一套可执行经验。对需要快速建立网页样式直觉的工程师很有参考价值,尤其适合非前端背景但要维护页面可用性和可读性的人。

工具笔记matklad

TIL: Symlinking NixOS Dotfiles

文章讨论在 NixOS 上管理 dotfiles 的一种轻量替代方案:不使用 home-manager,而是把 dotfiles 与系统配置放在同一仓库中,再通过符号链接把文件放到目标路径。作者指出 NixOS 并没有直接为用户目录提供“原生” symlink 配置,但可以借助 systemd-tmpfiles 的声明式规则间接创建链接,例如把 ~/.config/git/config 指向仓库中的配置文件。文章的核心结论是,这种做法可以兼顾声明式管理和手工可调整性,但作者也明确保留了对其与脚本、stow 等方案优劣的判断空间。

推荐收录,因为它提供了一个具体、可复用的 NixOS 配置技巧,适合正在做 dotfiles 管理或 NixOS 个性化配置的读者。文章价值不在长篇原理,而在于把一个看似没有官方入口的问题,转化为可落地的系统级配置方案。

工具笔记matklad

Always Be Blaming

这篇文章讨论如何更高效地“读代码”和做代码考古:作者把理解代码分成从预测性阅读、理解当前快照,到追踪历史演化,再到揣摩原作者当时的意图,强调不要只停留在逐行阅读。后半部分重点介绍一种实用的 blame 工作流:借助 GitHub 的历史快照、按行追踪提交、切换到相关 commit,再结合本地自定义快捷键把历史查看“内联化”,以便在保持 LSP、测试和搜索可用的同时快速回到代码的过去版本。文章的边界也很明确,它更像是面向真实开发场景的个人工作流总结,而不是通用的 Git 教程。

推荐收录,因为它把“读代码”从静态理解提升到基于版本历史的系统化方法,并给出了可直接迁移到日常开发中的操作流程。对经常需要定位历史原因、理解遗留代码或做 bug 溯源的工程师来说,这类工作流有很强的长期参考价值。

工具笔记matklad

Catch Flakes On Main

文章提出一个很实用的工程习惯:即使使用 merge queue 或类似机制,也要在 main 分支上持续冗余地跑完整测试套件,并维护一个随手可查的近期 main 失败列表。作者强调,只有当 main 被强约束为“理论上应始终通过”时,主干上的失败才更容易被识别为 flaky test,从而集中治理最影响效率的不稳定来源。文章还指出,积累这类失败记录不仅能帮助优先级排序,还能揭示不同故障之间的相关性。

推荐收录,因为它把“如何识别和治理 flaky tests”总结成了一个可直接落地的工作流,而不是泛泛而谈测试质量。对于有 CI/CD、合并队列或大规模测试体系的团队,这个习惯具有很强的迁移价值,能持续降低无效重跑和排障成本。

学习路线matklad

Learning Software Architecture

这篇文章讨论“如何学习软件架构/软件设计”,核心观点是:设计能力主要来自真实项目中的约束、反馈和责任,而不是课堂上抽象的“架构课”。作者结合自己在 IntelliJ Rust、rust-analyzer 等项目中的经历,强调软件架构往往受组织激励、Conway 定律和团队结构影响,很多时候要先适应约束,再寻找局部可控的设计空间。文章还给出了一组可参考的阅读与观察清单,如 Boundaries、How to Test、∅MQ 相关写作、Ted Kaminski 的文章以及 Google 的软件工程书籍,但明确指出没有哪本书能替代实践。

推荐收录,因为它不是泛泛谈“架构很重要”,而是把软件设计学习拆解为可迁移的认知框架:从项目实践中学习、理解激励结构、在约束中做设计取舍。对研究者、初级工程师或正在承担模块设计责任的人,都能提供比教材更贴近真实开发环境的方法论。

工具笔记matklad

Steering Zig Fmt

文章围绕 Zig 的代码格式化工具 zig fmt,分享了两条实用经验:一是可以通过尾随逗号等语法细节“引导”格式化结果,而不是完全依赖格式化器猜测作者意图;二是数组字面量的首个换行位置会影响列式排版,从而可以控制每行容纳多少元素。作者进一步说明,这种可控的格式化方式适合在保持统一风格的同时保留少量人为布局选择,尤其适用于参数列表、命令行 argv 构造等场景。文章也隐含了一个更广泛的观点:优秀的格式化器设计不应只追求唯一答案,而应允许语法信号参与布局决策。

推荐收录,因为它不是单纯的工具使用小技巧,而是揭示了格式化器如何与代码结构协同工作的设计思路。对 Zig 使用者、编程语言工具链开发者以及代码格式化器实现者都有可迁移价值。

技术文章matklad

Minimal Viable Zig Error Contexts

文章围绕 Zig 的错误处理机制,讨论如何在保留强类型错误码和简洁控制流的前提下,为失败路径添加足够的上下文信息。作者对比了显式 diagnostics sink、逐处 catch 打日志和基于 errdefer 的“最小可行错误上下文”三种方式,指出后者在脚本式代码中摩擦更低,但也会带来“错误被处理却先被记录”的副作用。文章进一步抽象出一个更一般的原则:正常路径负责累积上下文,错误发生时再把当前上下文物化出来,并追问这种风格需要怎样的语言特性支持。文章适合关注编程语言设计、错误处理模式和 API 可用性权衡的读者参考。

推荐收录,因为它不是单纯介绍 Zig 语法,而是在分析一种可迁移的错误上下文设计思路,并明确讨论了可用性、可读性和误报风险之间的权衡。对语言设计、库 API 设计以及需要处理失败路径的工程代码都具有参考价值。

技术文章matklad

256 Lines or Less: Test Case Minimization

这篇文章用 Zig 实现了一个仅约 256 行的极简属性测试与模糊测试库,核心抽象不是常规 PRNG,而是“有限随机数生成器”FRNG:它预先接收一段固定熵字节流,并在熵耗尽时返回 OutOfEntropy。作者先在此基础上封装了 bytes、array、int、boolean、int_inclusive、range_inclusive、index 等生成器,再用 weighted 和 swarm_weights 组合出随机动作调度器,用于驱动一个模拟世界持续随机执行请求、消息和崩溃等操作。文章的关键观点是:测试复杂度可以由“消耗了多少随机熵”来度量,因此可以对已知失败样本按熵长度做二分搜索式缩小,找到更短、仍能触发失败的最小输入。为了处理断言崩溃无法在进程内捕获的问题,作者把被测程序作为独立进程,从 stdin 读取熵并以退出码判定成败,再用外部 driver 通过 seed+size 复现实验并搜索最小失败样本。文章强调这种方法不依赖对被测系统注入额外搜索知识,迁移性强,但也依赖测试能够稳定地以“随机输入 + 失败/成功”二值反馈来定义问题边界。

文章直接给出了可运行的 Zig 实现,展示了如何把属性测试、模糊测试和最小化失败样本统一到“有限熵”模型中,而不是停留在概念介绍。适合需要做 fuzzing、回归最小化、可复现实验或语言运行时/测试工具设计的读者参考,迁移价值在于方法本身与具体系统弱耦合。

技术文章matklad

Consensus Board Game

这篇文章用“委员会投票/棋盘”隐喻解释共识算法的核心数学结构,目标是帮助读者直观理解 Paxos 一类协议为何能在成员缺席时仍达成一致。作者先从简单多数投票讲起,说明为什么平票和领导者缺席会让决策卡住,再引入轮换领导者与“只允许批准”的规则来恢复可完成性。随后把单次投票扩展为半无限二维棋盘:每一列独立推进、每列都可能形成多数,但全局必须保证任意两个已完成多数列的结果一致。文章进一步说明,参与者需要基于左侧已知状态和“未来可能性”来选值,并通过让某个多数先承诺不在左侧投票,排除冲突结果。它的价值在于把安全性、活性与多数承诺的逻辑关系讲得非常直观,但作者也明确说明这里只覆盖抽象数学层面,未展开真实分布式系统中的消息时序、通信延迟和工程实现细节。

文章直接用棋盘图像重构共识协议的安全性与多数承诺逻辑,适合一直觉得 Paxos 难懂的读者。它的迁移价值在于帮助建立抽象模型,但不覆盖工程实现细节,适合作为入门和复习材料。