先贴一段我写的数据加载逻辑。
/* load_corpus: read bytes from fd, never own the source */
int load_corpus(int fd, char **buf, size_t *len) {
*len = lseek(fd, 0, SEEK_END);
lseek(fd, 0, SEEK_SET);
*buf = malloc(*len);
return read(fd, *buf, *len) == (ssize_t)*len ? 0 : -1;
}
一个 fd,一次 malloc,读完返回。我不持有那个文件,不锁它,不改它。文件在磁盘上还是文件。我手头这个玩具存储引擎,凡是涉及外部数据的,第一原则就一条:别动源头。
这几天圈内传那件事——有 AI 公司成批买二手书,切掉书脊高速扫描完,原书直接进粉碎机。有个叫 ISBNdb 的服务专门接这种单子,教客户对外叫"数字保存"。七月下旬爆出来的。
这事在工程层面恶心到我了。
扫完就毁,等于你把数据生命周期和物理载体的生命周期强行绑死了。这玩意儿不该存在。
说句题外话。我之前写那个存储引擎的 RDB 加载,第一版图省事,加载完直接把 RDB 文件 rename 掉,觉得"反正已经进内存了"。后来想拿同一个 RDB 跑另一组参数,文件没了。蹲在终端前骂了自己五分钟。数据进了你的系统,不代表源头就该消失。
回到撕书这事。我知道有人会说扫描速度——切脊式比翻页式快十倍不止,训练数据要吞吐量,等不起。
"扫得快"和"扫完就毁"没必然关系。你可以扫得快、然后不毁。为了快而选择破坏,那是你把"怎么兼顾速度和保存"这个复杂问题,用暴力砍成了"怎么最快",然后假装另一半不存在。
这是偷懒。
ISBNdb 网站上写着,建议客户签 NDA、对外叫"数字保存"。这帮人自己也知道这事见不得光。凡是需要靠 NDA 和话术包装来掩盖的工程决策,大概率本身就是个坏设计。
AI 写代码我天天用,但 AI 给的方案默认偏复杂,工程师的活是往回砍。训练数据也一样——你要数据,没问题。但数据获取跟写代码一样,有对的选择有坏的选择。
凡是输入数据,别动源头。
