运维123 - 应用软件
type: channel
link: https://www.sddts.cn/index.php/category/%E5%BA%94%E7%94%A8%E8%BD%AF%E4%BB%B6/
items: 从零重建VisiCalc电子表格软件
items: 生活在平面国的程序员
items: 足够详细的规范就是代码
items: rathole 入门指南
items: 每一层审查让你慢 10 倍
items: Folio-OCR 三栏文档 OCR 工作台
items: Meta 重启 jemalloc 开发承诺投资基础设施
items: The Linux Programming Interface 作为大学课程教材
items: Emacs 与 Vim 在 AI 时代的未来
items: NVMe 驱动自动加载配置指南

从零重建VisiCalc电子表格软件
type: item
date: 2026-03-21T01:27:12+00:00
description: 从零重建 VisiCalc 电子表格软件一、概述1. 项目背景A. VisiCalc 的历史意义VisiCalc 是世界上第一款电子表格软件，由 Dan Bricklin 和 Bob Frankston 于 1979 年创造。这款软件仅用数千行 6502 汇编代码编写，却能在 16KB 内存的机器上运行。它成为 Apple II 的杀手级应用，销量超过 100 万份，将早期的个人电脑转变为真正的商业工具。B. 电子表格的设计理念电子表格被誉为史上最佳用户体验设计之一。它具有极简的学习曲线，允许用户快速操作数据、描述逻辑、可视化结果，甚至可以用它创作艺术和运行 GameBoy 模拟器。C. 本文目标从零开始构建一个最小化的 VisiCalc 克隆版本，探索电子表格的核心设计原理。最终实现将包含完整的数据模型、公式求值器和简单的终端用户界面。2. 核心问题如何用最少的代码实现一个功能完整的电子表格系统，需要解决以下问题：如何表示和存储单元格数据如何解析和计算数学公式如何处理单元格间的依赖关系如何构建高效的用户界面二、系统设计1. 核心概念电子表格系统由以下几个基本概念组成：单元格（Cell）：表格的基本单位，可存储值、公式或标签网格（Grid）：单元格的二维集合公式（Formula）：引用其他单元格的数学表达式响应式计算：当单元格值变化时自动重新计算相关公式2. 数据模型设计A. 单元格结构每个单元格可以处于四种状态之一：空、数值、标签或公式。#define MAXIN 128 // 单元格输入最大长度 enum { EMPTY, NUM, LABEL, FORMULA }; // 单元格类型 struct cell { int type; // 单元格类型 float val; // 数值 char text[MAXIN]; // 原始用户输入 };B. 网格结构Excel 有 1,048,576 行和 16,384 列的限制，原始 VisiCalc 有 256 行和 64 列。我们的迷你版本可以使用更小的尺寸：#define NCOL 26 // 最大列数 (A..Z) #define NROW 50 // 最大行数 struct grid { struct cell cells[NCOL][NROW]; };3. 系统架构graph TB subgraph 用户界面 UI[TUI 界面] Input[输入处理] end subgraph 核心引擎 Grid[网格数据] Parser[公式解析器] Recalc[重新计算] end subgraph 数据模型 Cell[单元格] Formula[公式] end UI --> Input Input --> Grid Grid --> Parser Parser --> Recalc Recalc --> Grid Grid --> Cell Cell --> Formula三、公式求值器1. 解析器设计使用递归下降解析器（Recursive Descent Parser）来计算公式。解析器需要能够：识别数字和单元格引用处理运算符优先级支持函数调用访问网格中的单元格值A. 解析器结构struct parser { const char* s; // 公式字符串 int pos; // 当前位置 struct grid* g; // 网格引用 };2. 语法解析层次公式解析遵循经典的运算符优先级规则：表达式（Expression）：由加法和减法连接的项项（Term）：由乘法和除法连接的因子因子（Factor）：数字、单元格引用、函数调用或括号表达式graph TD A[表达式 Expression] --> B[项 Term] B --> C[因子 Factor] C --> D[数字 Number] C --> E[单元格引用 CellRef] C --> F[函数调用 Function] C --> G[括号表达式 ParenExpr] B -->|+/-| B A -->|*//| A3. 解析实现A. 因子解析因子是最基本的语法单位，可以是：带符号的一元运算函数调用（以 @ 开头）括号表达式数字字面量单元格引用float primary(struct parser* p) { skipws(p); if (!*p->p) return NAN; // 处理一元加号 if (*p->p == '+') p->p++; // 处理一元减号 if (*p->p == '-') { p->p++; return -primary(p); } // 函数调用 if (*p->p == '@') { p->p++; return func(p); } // 括号表达式 if (*p->…

生活在平面国的程序员
type: item
date: 2026-03-20T06:39:28+00:00
description: 生活在平面国的程序员一、概述1. 文章简介A. 标题The programmers who live in Flatland（生活在平面国的程序员）B. 发布时间2025 年 11 月 24 日C. 来源Red Planet Labs 博客D. 作者Nathan Marz（Clojure 专家、Rama 框架创始人）2. 核心隐喻文章借用 Edwin Abbott 的经典小说《Flatland：A Romance of Many Dimensions》中的概念：二维世界的居民无法理解第三维度的存在。作者将此隐喻延伸到编程领域——许多程序员受限于自己的"维度"，无法理解更强大的编程抽象。3. 文章主旨大多数程序员生活在"编程平面国"中，他们无法理解 Lisp/Clojure 宏（macros）所代表的更高维度的编程能力。这并非因为宏没有价值，而是因为他们缺乏理解这种抽象所需的"表征机制"。二、背景故事：Paul Graham 与 Lisp1. Beating the Averages2001 年，Paul Graham 发表著名文章《Beating the Averages》，核心论点包括：A. Lisp 的根本优势Lisp 比其他语言本质上更强大宏（macros）是 Lisp 的核心区分能力Viaweb 使用 Lisp 构建了竞争对手无法实现的功能B. 作者的亲身体验Nathan Marz 受这篇文章影响，过去 15 年一直将 Clojure 作为主要编程语言。他证实 Paul Graham 关于宏的描述"绝对正确"。2. 现实困境A. 采用率极低Lisp/Clojure 全球使用比例极小（Stack Overflow 调查显示约 2.6%）与其巨大的优势不成正比B. 常见误解"生态系统"障碍：对 Common Lisp 有效，但 Clojure 可与 Java 生态系统互操作"括号很怪"的直观反应括号的感知成本从未与 Clojure 的巨大收益进行权衡C. Blub ParadoxPaul Graham 提出的"Blub 悖论"试图解释这种脱节，本文从另一个角度补充这个解释。三、编程的维度1. 两类抽象A. 自动化抽象大多数程序员使用的抽象属于此类：将一组操作打包在一个名称后面函数是经典例子：接受输入，产生输出只需要了解函数的规格和性能特征B. 维度扩展抽象罕见的抽象类型：扩展编程本身的代数改变基本概念和概念间关系的种类创造新的"维度"2. Lisp/Clojure 宏的维度之力A. 语言的自我组合源于语言的统一性，使语言能够自我组合：编译时逻辑可以像运行时一样执行使用相同的函数和技术语法树可以被操纵和转换B. 语义控制实现对代码语义本身的控制：宏不仅仅是语法糖它们改变了代码的结构和含义可以创造全新的控制结构C. 编译时的轻松操纵effortless compile-time manipulation 是一个新的编程维度：编译时代码生成变得简单元编程成为一等公民运行时和编译时的界限变得模糊3. Flatland 隐喻graph LR subgraph Flatland["2D 平面国"] F1[三角形] F2[正方形] F3[圆形] end subgraph Spaceland["3D 空间国"] S[球体] end S -.-> F1 S -.-> F2 S -.-> F3在 Flatland 中，正方形无法理解第三维度，因为他只能以 2D 思考。同样，你无法理解新的编程维度，因为你不知道如何在该维度中思考。你没有"表征机制"来理解新维度提供的东西。2D 程序员可能会得出 3D 概念客观上错误的结论——这不是因为他们理解了它，而是因为他们试图将其扁平化到自己的坐标系中。四、学习新维度1. 说服的局限性你不能用 3D 论据说服 2D 的人。这就像在 Flatland 中，球体无法让正方形理解"上"和"下"的含义。2. 隐喻的断裂点然而，这正是隐喻失效的地方：你的大脑永远无法理解 4D 空间但你的大脑可以适应新的编程维度3. Lisp 学习曲线采用 Lisp/Clojure 的人通常描述相似的经历：graph LR A[不适感] --> B[一系列清晰时刻] B --> C[无法回头的顿悟] C --> D[新维度的思维方式]A. 第一阶段：不适感语法看起来"奇怪"编程范式不同需要改变思维习惯B. 第二阶段：清晰时刻逐渐理解宏的威力开始看到代码抽象的新可能性意识到之前方法的局限性C. 第三阶段：无法回头新维度的思维成为自然回到旧语言感觉受限理解了什么是真正的编程抽象4. 突破认知偏见需要的只是：好奇心理解最好的编程思想有时无法立即被欣赏识别自己的认知偏见认识到这种偏见足以打破它，这是作为程序员成长的最好方式之一。五、社区讨论与…

足够详细的规范就是代码
type: item
date: 2026-03-19T09:10:38+00:00
description: 足够详细的规范就是代码一、新闻概述1. 标题足够详细的规范就是代码2. 发布时间2026 年 3 月 17 日3. 来源Haskell for all 技术博客二、核心内容1. 事件摘要A. 主要内容本文作者以批判的视角分析了"从规范文档生成代码"（agentic coding）的理念，认为这种做法本质上是在重蹈历史覆辙——试图用自然语言替代精确的代码表达。B. 核心亮点指出 agentic coding 宣传的两个常见误解以 OpenAI 的 Symphony 项目为案例，剖析其"规范文档"的本质引用 Dijkstra 的理论，说明精确描述必然演变为代码通过实际测试证明，即使非常详细的规范也无法可靠生成工作代码2. 关键信息A. 涉及项目OpenAI Symphony：一个声称从规范文档生成的 agent 编排器B. 核心论点当规范文档足够精确到能可靠生成实现时，它必然扭曲成代码或类似代码的形式规范文档从来不是省时工具，如果追求交付速度，直接写代码更有效C. 技术术语Agentic coding：基于 AI agent 的代码生成Specification：规范文档Narrow interfaces：狭义接口（即代码）3. 背景介绍A. 相关上下文近年来，业界兴起"从自然语言规范生成代码"的理念，宣传工程师可以转变为编写规范的"管理者"，而由 AI agent 完成编码工作。B. 作者立场作者对此持反对意见，认为这是对软件工程本质的误解。三、详细报道1. 主要内容A. 两个常见误解误解 1：规范文档比对应代码更简单Agentic coding 推广者常将此理念卖给相信者，让他们幻想工程师变成管理者，只需编写规范文档后交给 agent 团队执行。这只有在规范工作比实际编码更便宜时才成立。误解 2：规范工作必须比编码工作更深思熟虑推广者用此观点说服怀疑者，声称通过规范文档过滤工作能提高质量并促进更好的工程实践。B. Symphony 案例分析OpenAI 的 Symphony 项目被宣传为从规范文档生成项目的范例。其所谓的"规范文档"（SPEC.md）实际上更像 Markdown 形式的伪代码，而非传统意义上的规范。文档包含：数据库 schema 的散文描述：列出字段名、类型、约束代码的散文描述：如并发控制、重试逻辑专门为模型代码生成添加的"速查表"部分完整的算法代码块示例：服务启动算法function start_service(): configure_logging() start_observability_outputs() start_workflow_watch(on_change=reload_and_reapply_workflow) state = { poll_interval_ms: get_config_poll_interval_ms(), max_concurrent_agents: get_config_max_concurrent_agents(), running: {}, claimed: set(), retry_attempts: {}, completed: set(), codex_totals: {input_tokens: 0, output_tokens: 0, total_tokens: 0, seconds_running: 0}, codex_rate_limits: null } ...C. Dijkstra 理论支持Edsger W. Dijkstra 在 EWD667 文章中解释了为何精确描述必然演变为代码：数学史表明，希腊数学停留在口头和图形阶段，穆斯林代数在符号化尝试后因回归修辞风格而消亡，现代文明世界只有在西欧摆脱中世纪经院主义后才能兴起。软件工程同理，试图用自然语言追求精确性是徒劳的。2. 技术细节A. 规范与代码的关系graph LR A[自然语言想法] --> B{足够精确?} B -->|否| C[模糊规范] B -->|是| D[结构化形式] D --> E[伪代码] D --> F[形式化规范] E --> G[实际代码] F --> G C --> H[生成失败/不完整]B. 实际测试结果作者尝试使用 Claude Code 按照 Symphony 规范生成 Haskell 实现，结果：存在多个 bug，需要多次提示修复即使"成功"运行，codex agent 也只是静默旋转，无法处理 Linear 工单结果存储在 Gabriella439/symphony-haskell 仓库C. 其他规范示例YAML 规范极其详细、广泛使用、包含一致性测试套件，但大多数 YAML 实现仍不完全符合规范。这印证了精确规范不等于可靠实现。3. 数据与事实A. 规…

rathole 入门指南
type: item
date: 2026-03-19T05:50:52+00:00
description: rathole 入门指南一、概述1. 简介A. 是什么rathole 是一个用 Rust 编写的轻量级、高性能反向代理工具，用于 NAT 穿透。它可以将位于 NAT 后面的设备上的服务暴露到互联网上。与 frp 和 ngrok 类似，rathole 通过一台具有公网 IP 的服务器来中转流量，使内网服务可被外网访问。B. 为什么学解决家庭服务器或 NAS 无法直接访问的问题相比 frp 具有更高的性能和更低的资源占用用 Rust 编写，二进制文件可小至 500KiB，适合嵌入式设备C. 学完能做什么在公网服务器上部署 rathole 服务端在内网设备上配置客户端，将本地服务暴露到公网配置加密传输，保护数据安全热重载配置，无需重启服务二、环境准备1. 系统要求服务器：具有公网 IP 的 Linux 服务器客户端：位于 NAT 后面的设备（家用电脑、NAS 等）操作系统：Linux、macOS、Windows、支持 Docker 的平台2. 安装步骤从官方发布页面下载预编译二进制文件：Linux:wget https://github.com/rathole-org/rathole/releases/download/v0.5.0/rathole-x86_64-unknown-linux-musl.tar.gz tar -xzf rathole-x86_64-unknown-linux-musl.tar.gzDocker:docker pull rapiz1/rathole从源码编译：git clone https://github.com/rathole-org/rathole.git cd rathole cargo build --release3. 验证安装./rathole --version三、核心概念1. 基本术语服务端（Server）：运行在具有公网 IP 的服务器上，监听来自客户端的连接和来自外网的访问请求客户端（Client）：运行在 NAT 后面的设备上，主动连接服务端并注册需要转发的服务Token：服务端和客户端之间用于身份验证的密钥服务（Service）：需要转发的具体应用，如 SSH、Web 服务器等2. 工作原理graph LR A[外网用户] -->|访问公网端口| B[服务端] B <-->|加密通道| C[客户端] C -->|转发请求| D[本地服务]rathole 的工作流程如下：客户端主动连接服务端，并使用 Token 进行身份验证服务端记录客户端注册的服务映射关系外网用户访问服务端的公网端口服务端通过加密通道将流量转发给客户端客户端将流量转发到本地服务四、快速上手1. 基本示例：暴露 NAS 的 SSH 服务场景你有一台位于家庭网络的 NAS，希望从互联网上通过 SSH 访问它。服务端配置创建 server.toml 文件：[server] bind_addr = "0.0.0.0:2333" [server.services.my_nas_ssh] token = "use_a_secret_that_only_you_know" bind_addr = "0.0.0.0:5202"启动服务端：./rathole --server server.toml客户端配置创建 client.toml 文件：[client] remote_addr = "myserver.com:2333" [client.services.my_nas_ssh] token = "use_a_secret_that_only_you_know" local_addr = "127.0.0.1:22"启动客户端：./rathole --client client.toml验证连接ssh -p 5202 myserver.com2. 多服务配置可以在一个配置文件中定义多个服务：客户端配置：[client] remote_addr = "myserver.com:2333" [client.services.ssh] token = "ssh_token" local_addr = "127.0.0.1:22" [client.services.web] token = "web_token" local_addr = "127.0.0.1:8080" [client.services.minecraft] token = "mc_token" local_addr = "127.0.0.1:25565" type = "tcp"服务端配置：[server] bind_addr = "0.0.0.0:2333" [server.services.ssh] token = "ssh_token" bind_addr …

每一层审查让你慢 10 倍
type: item
date: 2026-03-17T11:29:21+00:00
description: 每一层审查让你慢 10 倍一、新闻概述1. 标题每一层审查让你慢 10 倍2. 发布时间2026 年 3 月 16 日3. 来源apenwarr.ca（Avery Pennarun 的个人博客）二、核心内容1. 事件摘要A. 主要内容Tailscale CEO Avery Pennarun 发表观点文章，指出软件开发中每一层审查都会让流程变慢 10 倍。文章分析了为什么 AI 代码生成无法解决这一瓶颈，并提出了通过减少审查层级和建立信任文化来提高开发效率的方案。B. 核心亮点每一层审查会让流程慢 10 倍（按实际时间计算，而非工作量）AI 的加速作用被后续审查等待时间抵消传统 QA（质量保证）模式反而会降低质量通过模块化和小组信任文化替代多层级审查2. 关键信息A. 版本号/发布内容这是一篇博客观点文章，非产品发布B. 重要数据简单 Bug 修复：30 分钟同事代码审查：300 分钟（5 小时）设计文档批准：50 小时（约 1 周）跨团队协调：500 小时（12 周，一个季度）高管决策：10 个季度（约 2.5 年）C. 涉及产品/技术软件开发流程、代码审查、质量保证、AI 编码助手、模块化架构3. 背景介绍A. 前置版本/历史作者 Avery Pennarun 之前有多篇关于系统设计的文章，本文是其系统设计系列的延续，特别关注 LLM（大型语言模型）时代的软件工程问题。B. 相关上下文随着 Claude Code 等 AI 编码工具的兴起，软件开发速度大幅提升，但传统的审查流程成为新的瓶颈。三、详细报道1. 主要内容A. 审查层级的速度衰减规律作者提出一个经验法则：每一层审查会让流程变慢 10 倍。这里的变慢指的是实际时间，而非工作量。大部分额外时间都花在等待上。具体示例：graph LR A[简单 Bug 修复 30 分钟] --> B[同事代码审查 300 分钟] B --> C[设计文档批准 3000 分钟] C --> D[跨团队协调 30000 分钟] D --> E[高管决策 75000 分钟]B. AI 无法解决等待延迟问题AI 编码工具可以将编码时间从 30 分钟缩短到 3 分钟，但：如果开发者用节省的时间自己审查 AI 生成的代码，仍然是循环等待如果直接提交未验证代码，审查者仍需 5 小时，且会因阅读低质量代码而不满如果用于大型项目，代码太长无法一次审查，需要拆分为多个小块，每个都有 5 小时审查周期C. QA（质量保证）的悖论作者引用 W. E. Deming 的质量管理哲学，指出传统 QA 模式的问题：在工厂环境中，如果每一轮 QA 能捕获 90% 的缺陷，理论上两轮就能减少 100 倍缺陷。但现实中的问题：第一道 QA 知道有第二道 QA，会降低工作标准第二道 QA 不愿过于严格，因为这会影响同事的评价生产人员知道有 QA 检查，会降低生产时的质量控制这种"多层检查"模式实际上激励了质量控制的外部化，而非内部化。D. 日本汽车制造业的启示著名的丰田生产系统完全取消了专门的 QA 阶段，而是给每个工人一个"停止生产线"按钮。当发现缺陷时，任何人都可以停止生产线进行修复。美国汽车制造商试图复制这一系统，安装了同样的按钮，但没有人敢使用，因为害怕被解雇。关键差异在于信任：员工信任上级真心希望了解每个缺陷管理层信任员工会主动发现问题执行层信任系统确实有效E. 代码审查的真正使命代码审查者的工作不是审查代码，而是弄清楚如何让这一类评论在未来不再出现。等到审查发现错误时，错误已经发生了。审查只是症状，而非根本原因。F. 模块化和小组协作的解决方案作者提出的解决方案：组件应该由能全权负责的小团队构建小团队可以建立对质量的共识和信任通过清晰定义的接口，组件可以可靠地交付给其他团队可以让多个小组竞争构建同一组件，通过进化选择质量利用 AI 快速尝试不同的模块边界代码现在很便宜，但好的想法仍然稀缺。AI 编码使我们能比以往更快地实验新想法。2. 技术细节A. AI 开发者的堕落循环作者描述了 AI 辅助开发中常见的恶性循环：graph TD A[1. 原型快速完成] --> B[2. 发现 Bug 让 AI 修复] B --> C[3. 每次修复引入新 Bug] C --> D[4. 用 AI 代理审查代码] D --> E[5. 人工在代理间传递数据] E --> F[6. 需要代理框架] F --> G[7. 让 AI 编写代理框架] G --> A许多开发者陷入这个循环，不断让 AI 生成更复杂的代理框架，而实际代码质量没有提升。B. 单体和微服务的平衡微服务之前名声不好，因为它们"太微"。在原始术语中，一个"微"服务正好适合"两个披萨团队"独立构建和运维。有了 AI，可能只需要一个披萨和一些 token。有趣的是…

Folio-OCR 三栏文档 OCR 工作台
type: item
date: 2026-03-16T22:01:43+00:00
description: Folio-OCR 三栏文档 OCR 工作台一、概述1. 简介A. 是什么Folio-OCR 是一款基于 GLM-OCR 和 Ollama 的三栏文档 OCR 工作台，专为书籍和文档的日常批量识别设计。它提供了一个现代化的 Web 界面，支持图片和 PDF 文件的批量光学字符识别，并具备智能版面分析、实时编辑和多种格式导出功能。B. 为什么学解决文档数字化过程中的人工识别效率问题利用本地化 OCR 方案保护数据隐私学习 FastAPI 前后端分离架构和版面分析技术了解如何将大型语言模型集成到实际应用中C. 学完能做什么搭建本地化的 OCR 识别服务批量处理 PDF 和图片文档使用版面分析技术提高识别准确率将识别结果导出为 Markdown、TXT 或 Word 文档2. 前置知识A. 必备技能基础的 Linux 命令行操作了解 Docker 基础概念B. 推荐知识Python 基础编程知识Web 开发基础概念OCR 和版面分析基础二、环境准备1. 系统要求操作系统：Linux、macOS、Windows 10/11Docker：20.10+（推荐使用 Docker 部署）Python：3.10+（本地部署）Ollama：已安装（本地部署）硬件：建议 8GB+ 内存，有 NVIDIA 显卡可获得更好性能2. 安装步骤Docker 部署（推荐）# 1. 克隆项目 git clone https://github.com/vorojar/Folio-OCR.git cd Folio-OCR # 2. 启动服务 docker compose up -d # 3. 下载 OCR 模型（约 2GB，只需执行一次） docker compose exec ollama ollama pull glm-ocr本地部署# 安装依赖 pip install -r requirements.txt # 拉取模型 ollama pull glm-ocr # 启动服务 python server.py # Windows 一键启动 start.bat3. 验证安装打开浏览器访问 http://localhost:3000，若能看到界面则表示安装成功。# 检查 Ollama 状态 curl http://localhost:11434/api/tags # 检查服务状态 curl http://localhost:3000/api/status三、核心概念1. 基本术语GLM-OCR：智谱 AI 开发的 OCR 模型，用于图像文字识别Ollama：本地化大模型运行平台，提供 GLM-OCR 的推理服务FastAPI：Python Web 框架，用于构建后端 APIPP-DocLayoutV3：PaddlePaddle 的文档版面分析模型SQLite：轻量级数据库，用于持久化存储文档和 OCR 结果版面分析：自动检测文档中的标题、正文、表格、图片等区域2. 工作原理graph LR User[用户] --> FE[前端界面] FE --> API[FastAPI 后端] API --> DB[(SQLite 数据库)] API --> Layout[版面分析模型] API --> Ollama[Ollama OCR 服务] Layout --> API Ollama --> API API --> FE API --> Storage[文件存储]系统采用三层架构设计：前端层：提供三栏式用户界面，负责文件上传、结果显示和用户交互后端层：FastAPI 提供 RESTful API，处理版面分析、OCR 调用和数据持久化服务层：Ollama 提供 OCR 推理服务，PP-DocLayoutV3 提供版面分析能力四、快速上手1. 基本使用流程graph TD A[启动服务] --> B[上传文档] B --> C[自动拆页处理] C --> D[版面分析] D --> E[OCR 识别] E --> F[编辑校对] F --> G[导出文档]2. 上传文档支持以下文件格式：图片：PNG、JPG、GIF、BMP文档：PDF支持多文件混合上传，系统会自动将所有文件合并为一个文档，并按页码顺序排列。3. OCR 识别系统提供两种 OCR 模式：单页识别：对选中的页面进行 OCR批量识别：点击 OCR All Pages 一键处理全部页面识别过程中会显示实时进度条和 ETA 时间估算，用户可以随时点击 Stop 按钮中断处理。4. 编辑与导出识别结果支持：Edit 模式：纯文本编辑，便于手动修正Preview 模式：实时渲染 HTML 表格和 Markdown 格式段落重排：自动合并因换行断开的段落导出格式：Markdown（.md）纯文本（.txt）Word 文档（.…

Meta 重启 jemalloc 开发承诺投资基础设施
type: item
date: 2026-03-16T21:48:41+00:00
description: Meta 重启 jemalloc 开发承诺投资基础设施一、新闻概述1. 标题Investing in Infrastructure: Meta's Renewed Commitment to jemalloc2. 发布时间2026 年 3 月 2 日3. 来源Engineering at Meta二、核心内容1. 事件摘要A. 主要内容Meta 宣布重新聚焦 jemalloc，这是一款高性能内存分配器。Meta 将致力于减少维护需求、现代化代码库，同时继续演进分配器以适应最新的硬件和工作负载。B. 核心亮点原始 jemalloc 开源仓库已解档Meta 继续担任项目维护者承诺与开源社区共同开发规划四大重点改进方向2. 关键信息A. 涉及产品/技术jemalloc（Jason Evans malloc）、内存分配器B. 重要数据预计阅读时间：3 分钟作者：Wenlei He, Paul Saab, Stan AngelovC. 发布背景jemalloc 长期以来一直是 Meta 软件栈中高度杠杆化的组件，与 Linux 内核和编译器一起为 Meta 提供可靠和高性能的基础设施。3. 背景介绍A. 技术定位构建软件系统就像建造摩天大楼：人们看到的产品是顶部，但防止其倒塌的是埋在泥土中的基础和隐藏的脚手架。jemalloc 正是这样的一种基础组件。B. 历史演进jemalloc 随着底层硬件和上层软件的变化不断适应，为 Meta 带来了长期收益。三、详细报道1. 主要内容A. 倾听与反思近年来， jemalloc 的开发逐渐偏离了长期指导其发展的核心工程原则。虽然某些决策带来了短期收益，但产生的技术债务最终拖慢了进度。B. 社区合作Meta 认真听取了社区的反馈。本着合作精神，团队深入反思了作为维护者的角色及其对 jemalloc 长期健康的影响。Meta 已与多位社区成员会面，包括项目创始人 Jason Evans，分享了反思内容以及如何改变方法。C. 改变开始团队已开始努力消除技术债务，并为 jemalloc 重建长期路线图。2. 技术细节A. jemalloc 在 Meta 的地位graph TB subgraph Meta 软件栈 A[jemalloc] B[Linux 内核] C[编译器] end A -->|内存分配| D[上层应用] B -->|系统调用| D C -->|代码生成| D A -.持续适应.-> E[硬件变化] A -.持续适应.-> F[软件变化] subgraph 长期收益 G[可靠性] H[高性能] end A --> G A --> HB. 工程原则在实用与原则性工程实践的谱系中， jemalloc 这样的基础软件组件需要最高的严谨性。虽然 jemalloc 提供的高杠杆作用可能带来短期收益的诱惑，但组织需要强大的自律来抵制这种诱惑并坚持核心工程原则。3. 新章节规划Meta 为 jemalloc 制定了四个重点改进领域：A. 技术债务减少专注于清理技术债务、重构和增强 jemalloc，确保其对所有用户保持高效、可靠和易用。B. 大页分配器继续改进 jemalloc 的大页分配器（HPA），以更好地利用透明大页（THP），提高 CPU 效率。C. 内存效率计划改进打包、缓存和清除机制，以优化内存效率。D. AArch64 优化确保 jemalloc 在 AArch64（ARM64）平台上具有良好的开箱即用性能。四、影响分析1. 行业影响A. 技术趋势Meta 作为技术巨头重新重视基础设施组件，表明基础软件的重要性正在被重新认识。B. 开源社区jemalloc 仓库解档并恢复活跃开发，对依赖该项目的广大开源社区是重大利好。2. 用户影响A. 现有用户更稳定的内存分配器更好的性能优化更容易的维护体验B. 潜在用户AArch64 平台用户将获得更好的原生性能对大页支持有需求的用户将受益3. 技术趋势A. 基础设施投资大型科技公司越来越重视基础软件组件的长期健康，而非短期功能迭代。B. 社区协作Meta 强调与开源社区共同开发，体现了开放协作的趋势。五、各方反应1. 官方回应Meta 表示信任是通过行动赢得的，希望通过时间证明其对 jemalloc 的重新承诺。2. 社区合作Meta 邀请社区加入这个新章节，分享反馈并帮助塑造 jemalloc 的未来。团队期待与社区合作推动 jemalloc 向前发展。3. 关键人物Jason Evans：jemalloc 项目创始人，已参与 Meta 的反思和规划讨论Wenlei He、Paul Saab、Stan Angelov：本文作者六、相关链接1. 官方公告Engineering at Meta 原文2. 技术文档jemalloc 官方仓库3. 相关资源J…

The Linux Programming Interface 作为大学课程教材
type: item
date: 2026-03-16T21:38:57+00:00
description: The Linux Programming Interface 作为大学课程教材一、概述1. 书籍简介A. 书籍信息The Linux Programming Interface（简称 TLPI）是由 Michael Kerrisk 编写的 Linux/UNIX 系统编程权威指南。这本书深入介绍了 Linux 系统编程的各个方面，包括文件 I/O、进程管理、线程、网络编程等核心技术。B. 目标读者虽然作者在编写本书时并未专门针对大学市场，但如今已有许多大学教师将 TLPI 用作 Linux 或 UNIX 系统编程课程的必读教材或推荐读物。C. 教学价值TLPI 内容全面、讲解深入，适合作为大学计算机相关课程的系统编程教材，帮助学生掌握 Linux 系统级编程的核心知识和实践技能。2. 使用现状A. 大学应用多所高校已将 TLPI 纳入课程体系，用作系统编程、操作系统原理等相关课程的教材。B. 课程级别主要用于高年级本科生（大三、大四）或研究生课程。二、作者反馈征集1. 反馈目的作者 Michael Kerrisk 希望了解更多关于 TLPI 在大学课程中使用情况的细节，以便在未来版本的书籍改进中更好地满足大学教学需求。2. 征集对象正在使用或计划使用 TLPI 作为课程教材的大学教师。3. 调查问题A. 基本信息您所在的机构名称和网站地址是什么？您能否提供或指向使用 TLPI 的课程大纲？该课程属于哪个年级？（如大三、大四等）课程有多少学生？B. 使用情况TLPI 是作为必读教材，还是推荐读物？C. 改进建议在您看来，如何改进 TLPI 以更好地作为大学课程教材使用？作者欢迎详细建议，内容越多越好！三、使用建议1. 适用课程类型A. 系统编程课程涵盖 Linux 系统调用、库函数、进程管理等核心内容。B. 操作系统课程实践性强的操作系统原理课程配套教材。C. 高级编程课程需要深入理解系统级编程概念的高级编程课程。2. 教学优势A. 内容全面覆盖 Linux 系统编程的各个方面，从基础到高级。B. 实践导向包含大量代码示例和练习，便于实践教学。C. 权威性强作者 Michael Kerrisk 是 Linux man-pages 项目的维护者，内容具有高度权威性。四、联系方式如果正在使用 TLPI 作为大学课程教材，欢迎发送邮件联系作者，分享您的使用经验和改进建议。参考资料The Linux Programming Interface as a university course textThe Linux Programming Interface - Official Site

Emacs 与 Vim 在 AI 时代的未来
type: item
date: 2026-03-16T03:06:05+00:00
description: Emacs 与 Vim 在 AI 时代的未来一、新闻概述1. 标题Emacs and Vim in the Age of AI（Emacs 与 Vim 在 AI 时代）2. 发布时间2026 年 3 月 9 日3. 来源(think) 个人博客二、核心内容1. 事件摘要A. 主要内容文章作者 Bozhidar Batsov 作为拥有 20 年以上 Emacs 使用经验的核心贡献者，深入分析了在 AI 工具快速发展的背景下，Emacs 和 Vim 这两款传统编辑器面临的挑战与机遇。B. 核心亮点VS Code 和专用 AI 编辑器（Cursor、Windsurf 等）正在形成强大的吸引引力AI 改变了编程的核心技能：从编辑速度转向意图表达和代码审查AI 可能降低 Emacs Lisp 和 VimScript 的学习门槛终端原生 AI 工具与 Emacs/Vim 的工作流天然契合2. 关键信息A. 作者背景Emacs 狂热使用者超过 20 年维护了多个热门 Emacs 包，包括 copilot.el近期重新学习 Vim 和 NeovimB. 涉及技术Emacs、Vim、NeovimClaude Code、Copilot、Cursor、Windsurf 等 AI 工具gptel、ellama、aider.el、avante.nvim 等集成插件C. 文章定位这是一篇技术观点文章，而非纯粹的新闻报道，基于作者多年开源社区经验对未来趋势的思考。3. 背景介绍A. 前置背景VS Code 已经在编辑器市场占据绝对主导地位，并且正在获得所有主要 AI 工具的一流集成支持。微软有充分的资源和动力让 VS Code 成为 AI 辅助开发的最佳宿主。B. 相关上下文编程领域正在经历根本性转变，AI 越来越多地承担代码生成工作，人类的角色从编写代码转向审查、引导和精炼代码。三、详细报道1. 风险分析A. IDE 的引力井VS Code 的市场份额已经远超其他编辑器，正在获得 Copilot、Codex、Claude、Gemini 等 AI 工具的深度集成。Cursor、Windsurf 等专用 AI 编辑器也吸引了大量投资和人才。这些工具围绕 AI 工作流构建完整的体验，提供集成的上下文管理、内联差异、多文件编辑和代理循环。每个转向这些工具的开发者都是一个不再学习 Emacs 或 Vim 快捷键、不再编写 Elisp、不再为生态系统做出贡献的人。这种引力井效应是真实的。B. "强力工具"的必要性存疑Emacs 和 Vim 一直以来的卖点在于让用户更快地编写和编辑代码。快捷键、宏、可扩展性——所有这些都在于让人类更高效地完成编码的机械动作。但如果 AI 正在编写你的大部分代码，机械编辑速度还重要吗？当你正在审查和引导 AI 生成的差异而不是逐个字符地输入代码时，瓶颈从"我能编辑多快"转移到"我能多清楚地表达意图并评估输出"。这是一种完全不同的技能，而且不清楚 Emacs 或 Vim 在这方面有内在优势。学习曲线的论证也变得更难成立。当使用 Cursor 的初级开发者可以在一个下午搭建整个应用程序时，要求某人花费六个月学习 Emacs 以获得 10 倍速度是一个艰难的推销。C. 企业支持的不对称VS Code 有微软。Cursor 有风险投资。Emacs 有一小群志愿者和自由软件基金会。Vim 有 Bram 和现在的维护者社区。Neovim 有一个小型但专注的核心团队。这种情况一直存在，但 AI 放大了差距。构建深度 AI 集成需要跟上快速发展的 API、模型和范式。资金充足的团队可以专门投入工程师全职从事这项工作。志愿者驱动的项目以人们业余时间和热情的节奏前进。D. 末日场景让我们走向极端：如果我们熟悉的编程在下一个十年内完全自动化会怎样？如果 AI 代理可以接收规范并生成工作、经过测试、已部署的软件而无需人工干预，我们就根本不需要编码编辑器了。没有 Emacs，没有 Vim，没有 VS Code，没有 Cursor。整个类别变得无关紧要。作者认为这在短期内不太可能，但值得承认这是一种可能性。AI 能力的轨迹甚至让乐观主义者感到惊讶。2. 机遇分析A. AI 使配置和扩展变得微不足道几乎没有人谈论这一点：Emacs 和 Vim 一直受困于其扩展语言的晦涩。Emacs Lisp 是大多数程序员从未见过的 20 世纪 80 年代的 Lisp 方言。VimScript 就是 VimScript。即使是 Neovim 专门采用因为它更易接近的 Lua，也足够小众以至于大多数开发者没有写过一行。这几十年来一直是两个生态系统的最大瓶颈。不是编辑器本身——它们极其强大——而是自定义它们需要学习一种不熟悉的语言，而且大多数人从未超越从博客文章和 README 文件复…

NVMe 驱动自动加载配置指南
type: item
date: 2026-03-15T18:04:30+00:00
description: NVMe 驱动自动加载配置指南一、概述1. 简介A. 是什么NVMe（Non-Volatile Memory Express）是一种专为闪存存储设计的通信协议和驱动接口。Linux 内核 6.12.63 已内置完整的 NVMe 驱动模块，但默认情况下未配置为启动时自动加载。B. 为什么需要配置虽然现代 Linux 系统支持 udev 按需自动加载模块，但显式配置自动加载有以下优势：确保 NVMe 设备驱动在设备插入前已就绪，避免竞态条件系统启动时提前加载驱动，减少设备识别延迟明确的配置便于系统维护和故障排查C. 配置后效果系统启动时自动加载 nvme 及其依赖模块插入 NVMe 设备后系统可立即识别可通过 lsmod、lsblk 等命令快速验证模块状态2. 前置知识A. 必备技能基本 Linux 命令行操作了解 systemd 管理机制B. 推荐知识了解 Linux 内核模块管理熟悉 systemd 配置目录结构二、系统环境1. 系统要求Linux 内核版本：6.12.63+（已内置 NVMe 驱动）systemd 管理的系统（大多数现代 Linux 发行版）root 权限或 sudo 访问权限2. 模块依赖关系graph TD A[nvme] -->|依赖| B[nvme_core] B -->|依赖| C[nvme_auth] D[modules-load配置] -->|加载| A三、配置原理1. systemd modules-load 机制systemd-modules-load.service 是 systemd 提供的一个服务，负责在系统启动早期阶段自动加载内核模块。该服务会读取 /etc/modules-load.d/ 目录下的配置文件，并将列出的模块传递给 modprobe 命令进行加载。2. 配置目录结构graph LR A[/etc/modules-load.d] -->|优先级高| B[nvme.conf] C[/usr/lib/modules-load.d] -->|优先级低| D[系统默认配置] E[systemd-modules-load.service] -->|读取| A E -->|读取| C三、配置原理1. systemd modules-load 机制systemd-modules-load.service 是 systemd 提供的一个服务，负责在系统启动早期阶段自动加载内核模块。该服务会读取 /etc/modules-load.d/ 目录下的配置文件，并将列出的模块传递给 modprobe 命令进行加载。2. 配置目录结构/etc/modules-load.d/ 目录中的配置文件优先级高于 /usr/lib/modules-load.d/，系统会自动合并两个目录中的配置，冲突时以 /etc/ 目录为准。四、配置步骤1. 创建模块自动加载配置文件创建 /etc/modules-load.d/nvme.conf 文件，添加 nvme 模块：sudo tee /etc/modules-load.d/nvme.conf > /dev/null << 'EOF' # NVMe 驱动模块自动加载配置 # 添加 nvme 模块以确保 NVMe 设备驱动在启动时加载 # nvme 模块会自动加载依赖的 nvme-core 模块 nvme EOF2. 配置文件说明配置文件内容简洁，仅包含模块名称 nvme。模块加载时会自动处理依赖关系：模块名大小说明nvme约 57KBNVMe 主驱动模块nvme_core约 225KBNVMe 核心功能模块（自动加载）nvme_auth约 24KBNVMe 认证模块（自动加载）3. 可选扩展配置如需支持 NVMe over TCP 或 RDMA 传输，可在配置文件中添加额外模块：# 编辑配置文件添加 sudo nano /etc/modules-load.d/nvme.conf # 添加以下模块（按需选择） nvme-tcp # NVMe over TCP 传输 nvme-rdma # NVMe over RDMA 传输 nvme-fabrics # Fabric 传输核心模块五、验证配置1. 验证配置文件使用 systemd-analyze 命令验证配置是否正确：systemd-analyze cat-config modules-load.d/nvme.conf预期输出显示配置文件路径和内容。2. 重载 systemd 配置sudo systemctl daemon-reload3. 检查服务状态sudo systemctl status systemd-modules-load.service --no-pager服务状态应显示为 active（exited），…