Agili 的 Hacker Podcast 2026-08-09

Agili 的 Hacker Podcast 2026-08-09

NaN分钟 ·
播放数7
·
评论数0

Agili 的 Hacker Podcast 今日速览

把手机变成个人云服务器、用 8086 汇编重建四十年前的图形桌面、用数学技巧让寻路算法快上十倍。今天的文章里有动手派把抽屉里的闲置手机跑成数据中心,有复古派在淘汰硬件上做操作系统考古,也有算法派在旧数学里挖出新加速。

Shopify 把 Redis 换成 MySQL 做库存预留,反而更稳了

库存预留的老问题

下单时“到底有没有货”是个看似简单实则棘手的问题。Shopify 原来的系统把预留存在 Redis,库存账本在 MySQL,两个系统没办法同时更新。支付成功后的扣库存和清理 Redis 这两步如果顺序不对,就会出现超卖(商品卖了但账本没扣)或欠卖(库存已扣但还被标记为预留)。Redis 本身也缺少多地点库存感知,团队还要多维护一个集群。

一行一件的妙招

新方案把思路倒过来:不再用“一行一个商品、一列库存数量”的模型,而是“一个可售单元一行”。10 个库存就是 10 行,预留 3 个就锁定并转移 3 行。整个过程在同一个 MySQL 数据库里完成,预留和扣账共享 ACID 保证,不再需要协调两个系统。

为了不让表太大,每个“商品 × 地点”组合只维护上限 1,000 行的可用行池。预留从池里消耗行,补充进程在后台回填。1,000 这个数字是根据闪购期间的预留速率估算的,既要接住突发流量,又要保持表紧凑。

锁才是真正的瓶颈

几个技术细节直接影响性能。第一个原型用自增主键,每次预留产生两行锁。改用复合主键后一行一个锁。空表上跑 SELECT … FOR UPDATE SKIP LOCKED 出现间隙锁挡住了补充进程,把事务隔离级别从 REPEATABLE READ 换成 READ COMMITTED 后解决。结账路径上其他代码持有连接时间过长,把连接池推到崩溃边缘——预留本身并不慢。

Hacker News 上有读者担心 1,000 行池会在高峰时不够用,还有人讨论“为什么不在加购物车时扣库存”,回答是购物车放弃率太高,提前锁定会让库存大量闲置。也有评论认为 Redis 的问题不在性能,而在两个系统之间的数据一致性。

A* 寻路变快的数学技巧:先算好几个地标

启发函数可以不瞎猜

A* 寻路算法的效率大半靠启发函数——它告诉算法“往哪边走离目标近”。普通的距离启发不知道墙在哪,常把人往错误方向推。Red Blob Games 的文章介绍了一种叫差分启发的方法:先选几个地标,用 Dijkstra 算法算出所有点到每个地标的最短距离,存进二维数组。之后每次寻路时,用三角不等式推导出一个比普通距离好得多的下界。

从几万降到几千

方法的核心很简单:如果起点是 B,目标是 X,地标是 L,那么 B 到 X 的真正距离一定大于等于 |B 到 L 的距离减去 X 到 L 的距离|。这个下界知道墙的位置,因为它基于真实路径算出来的。单个地标只对部分路径有效,所以要用多个地标,取所有下界的最大值。文章演示中,迷宫地图的探索点数从 92054 降到 12585,只用 4 个地标。

地标放哪是个好问题

地标如果放在路径“之后”才有效。可以用算法自动找:随机生成大量路径,统计哪些位置能覆盖尽可能多的路径。实验里地标通常落在地图外缘,第二个远离第一个,第三个远离前两个,逐个评估新增收益。地标放得不好效果有限,但不会比普通 A* 更差。

我让手机变成了服务器,跑着我的个人应用

从刷机失败到妥协

作者把个人服务放 VPS 上跑 Chrome 太吃力,贵的又觉得不值。抽屉里那台 CMF Phone 1 有 8 核、8GB 内存、128GB 闪存,还有自带电池备份,比 VPS 划算。第一次尝试刷 postmarketOS(面向手机的 Linux 发行版),结果 Wi-Fi、蓝牙全是坏的,手机险些变砖。教训是 Android 已经为所有硬件写好了驱动,丢掉它去追求传统 Linux 是错误取舍。

架构:Termux + chroot + Tailscale

最后方案保留 Android,用 Termux(Android 上的终端环境)做宿主。起一堆服务:OpenSSH、runit 进程监督、Caddy 反向代理、Cloudflared 隧道。Tailscale 给手机一个稳定私有地址。省电机制对服务器不友好,写了一套配置关闭深度休眠、防止 Wi-Fi 挂起。跑 Linux 应用先试了 proot(用户态根文件系统模拟),普通 Web 服务没问题,但 Chrome 负载受不了翻译层。给手机 root 后用真正 chroot 挂载 Debian 文件系统,速度提升明显。

运维与安全

整个主机由 Ansible 管理,版本、服务定义、密钥、健康检查都在一个私有仓库里。发布按校验和固定,通过原子符号链接切换,回滚就是改回旧版本再应用。密钥不留手机,Ansible Vault 加密值存在基础设施仓库,保险库密码由 1Password SSH agent 远程签署。对外流量走 Cloudflare Tunnel,没有入站路由器规则,手机换网络隧道自动重连。

社区争论集中在电池安全和标题语序。有人担心锂聚合物电池 24/7 插电会鼓包,作者把充电限制在 80%。标题“My server is a phone now”引起语言学讨论,有评论比喻“就像说我的水现在是冰,大家会以为水结冰,而不是冰化成水”。

四十年后,有人在 IBM XT 上重建了 1984 年的 Mac 桌面

8086 汇编写的图形操作系统

os8088 是给 Intel 8086/8088 处理器设计的图形操作系统,从软盘引导启动,不依赖 DOS。桌面模仿 1984 年 Macintosh System 1:重叠窗口、下拉菜单、串口鼠标、可加载程序。甚至还加了当年 Mac 没有的抢占式多任务——定时器以 18.2Hz 触发,保存当前任务寄存器、切换栈指针,全程约三十条指令。1987 年的 MultiFinder 才给 Mac 带来合作式多任务。

如何在 256KB 内存里画窗口

系统用真实模式 NASM 汇编写成,内核 78,950 字节,核心代码加缓冲区必须装进 64KB 段。256KB 内存就能跑,没有后备缓冲,直接画屏幕——256KB 机器的后备缓冲会吃掉一半内存。窗口拖拽用一像素 XOR 轮廓的橡皮筋方式,松手才重绘,4.77MHz 下全窗重绘根本不现实,和当年 Mac 做法一样。扫雷程序只有 1,510 字节,同屏可开多个实例。磁盘镜像已写到真实软盘,在 1981 年 IBM 5150 上成功启动,和模拟器速度一致。

历史与争议

1985 年 Digital Research 的 GEM 1.0 是 PC 上的 Mac 风格桌面,Apple 起诉后移除了重叠窗口。os8088 四十年后在同一类机器上把想法重建出来。项目代码主要由 Claude 生成,作者称“手提示的”,这一度引起争议。有评论质疑 AI 生成的项目算不上成就,也有人反驳说这不是念一句咒语,大量迭代和调试仍要人做,“以前没人做过的事,现在存在了”。

把图片藏进 QR 码:抖动是怎么做到的

QR 码的两种区域

QR 码由功能图案和数据模块组成。功能图案帮扫描器定位,必须保持清晰;数据模块在定位完成后才被读取,可以动。做法是把每个数据模块缩到三乘三网格的中心一格,其余空间放图片。图片以黑白位图显示,QR 码仍然可扫。单纯压成黑白会丢掉中间调,需要抖动。

两次误差扩散

用 Floyd-Steinberg 误差扩散从左上到右下逐像素处理:每个像素被阈值化成黑或白后,把亮度误差分给周围未处理的像素。这里做了两次扩散:第一次处理数据模块,像素颜色已被 QR 码决定,不能改,设为正确颜色后把误差扩散到周围八格,图片看起来干净很多。第二次处理普通像素。生成器还支持旋转码、尝试不同编码,以及允许改变少数高误差模块。

社区提醒这是美观和可扫性的权衡。大屏幕上可能没问题,纸质传单或弯折场景就需要更多冗余。有人把这种现象比作汽车安全配置:原本用于应对缺损的纠错余量,被品牌 Logo 逐渐吃掉。还有人遇到支付二维码扫不出来,只能手动输入下方文字。

“难度曲线”该换成“难度锯”——一位《Lemmings》开发者的反思

曲线不是斜坡

游戏开发中常说的“难度曲线”被多数人默认成持续上升的斜坡。Dave Strachan 曾是《Lemmings》开发团队成员,他提出游戏的目标不是让玩家越玩越难,而是让玩家感受到自己变强。把新机制分组,每个机制单独走一条“学会—熟练—变着花样用”的小曲线。

怎么教玩家蹬墙跳

具体关卡设计给了一个模板:先在安全区用唯一出口逼玩家学会操作;再进入主体,与该机制和旧机制混用,加入敌人或追击压力;最后在收尾处加带变式的挑战和用该技巧换取收集品的隐藏路线。教学阶段要排除干扰,用粒子特效、脚印、金币等视觉提示引导。

动态难度的正反两面

“根据玩家表现动态调整难度”引发最激烈讨论。有开发者直言“永远别这么做”,觉得玩家会把系统看穿。支持者搬出《求生之路》的导演系统:根据队伍状态随机生成尸潮和补给品,很多人根本没察觉。《上古卷轴 4》式的等级缩放则是反面教材——路边强盗穿神装,练级像在受罚。好的动态难度要么完全透明(如《异星工厂》污染值越高虫族越多),要么只是避免玩家陷入死局。

用 AI 克隆开源应用还骗记者,道歉被说“像狗吃了作业”

事件经过

开发者 Terry Godier 发布名为 Dark Hours 的天文工具,高度相似另一位开发者的开源应用 DarkHours.app。对方向他在 Bluesky 指出后,他承诺改名、写博客介绍原项目。一个多小时后承认用 Claude 生成的应用与原项目几乎一模一样,连原开发者后来修过的一个 bug 都复现了。更严重的是,他此前一款占星应用被 App Store 拒绝后,把内容换成克隆的天文应用,还联系了 Daring Fireball 的 John Gruber 写了篇批评苹果审核的文章。Gruber 事后发现自己被误导,发布了写作 24 年来的第一篇撤回声明。

“Claude 干的”不成立

Hacker News 普遍不接受这篇道歉。“Claude 干的”被比作政治人物说“狗吃了我的作业”。多位开发者指出,Claude 不会在未被明确指示的情况下复刻另一个项目的名称、功能和特定 bug。一条评论强调:“只要你用 AI 生成内容并发布,你就要对发布的每个字负责。”全文没有向 Gruber 道歉,而被误导最深的正是 Gruber。

Word 1.1a 被移植成原生 64 位应用,源码不是开源

移植思路

一位开发者把微软 Word for Windows 1.1a(代号 Opus)移植成了原生 Windows x64 应用,没有用模拟器,也不是用现代编辑器重新实现。16 位 x86 汇编入口点翻译成定宽 C/C++,分段和双重间接内存句柄映射到 x64 安全的原生运行时,Win16 行为适配到现代 Win32 API。CMake 构建,测试套件覆盖运行时、数据结构、命令表和自动化 UI 工作流。

社区提到源码来自 Computer History Museum,是“源码可用”而非开源,许可对研究用途够用。有人看到截图后调侃 Word 1.0 时代就有 3D GUI 元素,当时跑得动它的电脑想必很厉害。移植过程是否用了 Claude Opus 也成了个小议论点。

每阶都有魔法六边形?数学家用 AI 发现并证明了新结论

为什么 n=3 是唯一的

魔法六边形要求格子沿三个方向的每条直线总和相同。正规魔法六边形把数字 1 到 3n²−3n+1 全部用上,非平凡的只有 n=3 这一个,因为所有数字的总和必须能被 2n−1 整除,而 n>3 时通不过。但放宽条件——数字仍然连续,只是不必从 1 开始——立刻打开新世界。

反演对称和势场

作者加了反演对称条件:数字取自对称区间 −K…K,中心放 0,旋转 180 度后相对的格子互为相反数,约束少一大半。还用“势场”表示六边形,把局部环组合成基,让直线总和自动为零,搜索空间大幅缩小。GPT-5.6 Sol 顺着思路把问题跟 Heffter 数组联系起来,写出自定义模拟退火求解器,很快得到 n 直到 21 的所有反演零和魔法六边形。

从求解到证明

模型随后给出确定性构造方案,覆盖所有 n>114。结合暴力搜索的 n≤21 的解,所有 n>3 的阶都被覆盖。证明尚未在 Lean 中形式化,也没有独立验证。作者反思 AI 承担了大部分创造性工作,自己更像乘客,但也注意到模型容易“隧道视野”,方向对时高效,方向错时需要人来提醒。

一个赌局赌一个 URL 能活 11 年,后来它真活下来了

2011 年的赌注

Long Bets 上曾有一个赌约:2011 年 Jeremy Keith 认为链接失效是 web 的熵,11 年对大多数资源已太长。Matt Haughey 认为有技术基础的人完全能维持稳定 URL,他的网站当时已运行 13 年。赌约规定 2022 年 2 月 22 日打开 longbets.org/601 必须返回包含原预测文字的 HTML。结果页面还在,HTML 里也保留着那段话。保守派输了。

保持 URL 存活没那么难,也没那么简单

讨论中有人说保持 URL 不难:写测试、把静态内容转成 HTML 就行。但也有人指出多数 URL 不是被误删的——公司破产、老板要删旧东西、域名过期,都不是技术问题。有人注意到赌约条款的漏洞:“http://”前缀最可能出问题,现在都在往 HTTPS 迁移;JavaScript 单页应用返回的初始 HTML 往往只有一个空壳,真正内容要靠脚本渲染,curl 能不能抓到也成了实际问题。


相关链接: