## 耐用的数据库:超越简单的预写式日志 预写式日志 (WAL) 是数据库持久性的基础——在将更改应用于内存*之前*将其记录到磁盘,从而能够在崩溃后恢复。然而,仅仅写入数据是不够的;磁盘容易发生静默故障。 本文详细介绍了五层防御数据丢失的措施。首先,**校验和**检测由硬件错误引起的静默数据损坏。其次,**双 WAL 文件**(写入两个磁盘)可防止潜在扇区错误——写入看似成功但实际上未存储。第三,**`O_DIRECT + O_DSYNC`** 绕过内核可能易失的页面缓存,确保数据立即写入磁盘。第四,**链接 I/O 排序**(使用如 Linux 的 `io_uring` 之类的工具)保证写入操作按正确的顺序完成。最后,**fsync 后验证读取**在写入*之后*确认数据完整性。 这些层解决了常见的问题:数据滞留在 RAM 中、静默损坏和写入顺序颠倒。忽视这些问题可能导致数据丢失,正如现实世界中未检测到的潜在扇区错误或内核崩溃擦除缓存数据所证明的那样。 构建一个健壮的 WAL 并非简单的代码问题;而是对数据完整性的承诺,以及承认硬件*会*发生故障。正确实现的 WAL 即使在面对逆境时也能兑现持久性的承诺。
## 社交网络早期萌芽:Last.fm & Audioscrobbler (2002)
在Web 2.0 广泛应用之前,英国的两项独立学生项目——Last.fm 和 Audioscrobbler——率先使用**协同过滤**为在线音乐发现开创了社交功能。 受亚马逊“购买此商品的顾客也购买了…”推荐的启发,两者都旨在根据用户的收听习惯和相似用户的偏好来推荐音乐。
Last.fm 由 Ravensbourne College 的学生开发,通过基于集体用户数据的“音乐地图”可视化音乐连接。与此同时,南安普顿大学的 Richard Jones 创建了 Audioscrobbler,并创造了“scrobbling”(记录收听数据)一词。
这两个项目试图超越传统的“广播”电台,让用户通过他人发现音乐—— 类似于与朋友分享唱片的体验。 虽然最初受到音乐许可的限制(仅提供 30 秒的样本),但 Last.fm 最终获得了许可并发展成为在线广播服务。 值得注意的是,这两个项目的创始人最终合并了,Audioscrobbler 被整合到 Last.fm 中,这表明他们对更具社交性和个性化的音乐体验有着共同的愿景。 这些早期努力预示了社交网络的未来以及集体用户数据的力量。
## 揭穿对症结疗法
认为阅读障碍是视觉问题,源于字母倒置,这一想法催生了一个市场,各种产品承诺轻松解决问题——从特殊眼镜和彩色滤镜到独特设计的字体。这种观念源于1927年的早期观察,但目前的研究表明,阅读障碍本质上是一种*语言基础*的学习差异,影响的是音素与字母的关系,而非视力。
尽管声称可以提高阅读速度和准确性,但研究一致表明,“阅读障碍字体”如OpenDyslexic和Dyslexie的表现并不比标准字体(如Arial或Times New Roman)更好——有时甚至*更差*。这些字体甚至可能产生虚假希望,并在未能实现承诺结果时让学生感到沮丧。
专家强调,易读的字体(Arial、Verdana)和适当的字号对*所有*读者都有益。有效的阅读障碍支持需要基于证据、系统的教学,侧重于语音学和音素意识,以及有声读物和辅助技术等辅助措施。最终,解决阅读障碍需要有针对性的语言支持,而不是视觉“疗法”。
## 大胆行动的有限机会
本文认为,个人一生中只有有限的几次能够发起有影响力的事业——“射门机会”,此时风险、精力、资本和信念都对齐,带来不对称的回报。人生的大部分时间都花在*准备*这些机会上,而不是不断尝试。
作者确定了六个关键时刻:**18岁(天真信念)**,由无知和精力驱动;**23岁(直面现实)**,结合早期经验和新兴洞察;**28岁(高效行动)**,利用能力和人脉;**36岁(横向跳跃)**,将领域专业知识应用于被低估的问题;**42岁(资本化执行)**,利用资源进行有目的、基于假设的冒险;以及**51岁(持久创造)**,专注于长期韧性和影响力。
每个阶段都需要不同的方法。年轻的创业者依靠速度和信念,而后期的创业者则优先考虑经验、资本和经过计算的执行。常见的错误是误判自己当前的优势,或在准备充分之前就进行冒险。
核心观点:认识到这些有限的机会窗口,理解你在每个阶段的优势,并专注于建立必要的资源,以便在机会出现时抓住它——而不是追逐持续的、分散的风险。
## 完美的木器涂饰探索
为手工雕刻的木勺和杯子寻找一种食品安全、耐用且易于应用的涂饰是一项挑战。理想的涂饰需要快速固化、无溶剂、疏水且外观吸引人——这很难实现。
纯桐油固化后天然且食品安全,但干燥需要数周时间,并留下哑光效果。聚合桐油干燥更快,但很难找到,并且通常需要溶剂。亚麻籽油会变黄且味道难闻,而其他干燥油稀有且昂贵。像Osmo这样的商业硬蜡油固化迅速,但含有大量的溶剂,存在健康问题。双组分硬蜡油提供了一种解决方案,但难以混合和应用。
最终,作者尝试将桐油与蜡和树脂混合。最初使用巴西棕榈蜡的尝试是脆性的。添加蜂蜡和羊毛脂改善了稠度,但缺乏耐用性。最有希望的配方结合了桐油、巴西棕榈蜡、蜂蜡、羊毛脂、达玛树脂、椰子油以及少量金属干燥剂(锰、锆和钙),以加快固化并增强光泽。这种混合物在保护、美观和安全性之间取得了平衡,目前用于他们在线商店出售的商品。进一步的实验仍在继续,旨在实现光泽和易用性的完美平衡。
## PostgreSQL 维护:不仅仅是运行 VACUUM
许多开发者认为定期运行 `VACUUM` 操作可以保持 PostgreSQL 数据库的健康,通过清理死元组和回收空间来实现。然而,`VACUUM` 并不能完全解决 *索引膨胀* 问题。虽然它可以移除索引中的死条目,但它不会重构 B 树本身——这与它压缩表数据(“堆”)的方式不同。
索引对于快速查询至关重要,它们维护着排序顺序。删除操作会留下空隙,`VACUUM` 无法合并这些空隙,导致索引比必要的尺寸大得多,从而降低性能,因为查询计划器会错误地计算成本。
像 `pg_statindex` 这样的监控工具以及比较预期索引大小与实际索引大小的查询可以揭示膨胀情况。超过 2.0 的“膨胀比”值得关注。解决方案包括 `REINDEX CONCURRENTLY`(在线重建索引)和 `pg_squeeze`(一种更全面、低影响的重建工具,适用于表和索引)。应避免使用 `VACUUM FULL`,因为它会获取排他锁。
最终,`VACUUM` 至关重要,但理解它在索引方面的局限性是主动数据库维护的关键。不要仅仅依赖 `VACUUM`——积极监控并解决出现的索引膨胀问题。
## ZX Spectrum BASIC 效率:行号与程序结构
本文探讨了 ZX Spectrum BASIC 解释器的设计如何影响程序效率,重点关注行号和程序结构。与现代语言不同,ZX BASIC 依赖于对行号的顺序搜索,这使得行顺序对速度至关重要。
解释器不使用行地址的索引表,导致线性搜索(O(n)复杂度)用于 `GOTO`、`GOSUB`、`NEXT` 和函数调用 (`FN`) 的目标。每次跳转的执行时间会因目标行之前每行代码而增加 71 微秒。
关键优化包括:将经常调用的例程、循环和函数放置在程序的开头附近;使用长行来最小化搜索距离;以及删除不必要的行(如 `REM` 语句和末尾的 `DATA`)。ZX-Basicus 工具,如 `--profile`(用于识别热点)和 `--move`(用于重新排列代码),可以辅助此过程。
避免参数化跳转(例如 `GOTO 2*n+100`),以提高可维护性,并考虑展开短循环。解释器还在行内搜索 `NEXT` 和 `RETURN` 等语句,因此将这些语句放在行首可以提高性能。最终,理解这些限制能够让程序员编写更快、更高效的 ZX Spectrum BASIC 代码。