时间在说话

时长凑不出来——阅读统计的跨端合并难题

手机 10 小时、电脑 5 小时,合计的 15 谁来算?时长是计数器语义不是寄存器语义:按设备拆表、上报全量快照、合并取 max 换幂等。而 v1.0.3 顺手把服务端合计写回本机计数器的一行 if,让时长每同步一轮就膨胀一倍。

老刘 老刘 发布于 2026-10-26

从"后写覆盖"到三层裁决——两台设备同时改了进度,听谁的

LWW 在阅读场景的两个误判:回看也是新写入、离线设备永远翻身。v1.0.5 把"读到哪"拆成水位/位置/时间三层,信任分级:前进无条件、小幅回退看时间、大幅回退要显式跳转。

老刘 老刘 发布于 2026-10-26

差之毫厘谬以千里——进度锚点为什么用绝对下标

章内偏移是相对解析结果的坐标,解析器一进化就错位。同步协议的权威位置改为全书绝对字符下标——BookKey 一致时逐字符精确,且与章节切分、排版彻底解耦。

老刘 老刘 发布于 2026-10-25

只算一次——身份计算的成本预算

BookKey 在导入时对落盘文件算一次,之后打开书、同步、翻页全部读缓存。性能不靠算得快,靠少算——以及身份稳定优先于内容新鲜的取舍。

老刘 老刘 发布于 2026-10-23

一个换行符——CRLF 跨块血案与修复

两个字节被缓冲区边界劈开,42 MB 的小说在两台设备上领了不同的身份证。复盘 v1.0.2 那次修复:跨块挂起的 NewlineNormalizer、精确构造的边界测试,以及老数据为何救不回来。

老刘 老刘 发布于 2026-10-22

不用抽样——指纹为什么必须算全量

不用抽样——指纹为什么必须算全量 旦阅诞生记 · 第 7 篇。上一篇结尾说 BookKey 一辈子只算一次,这一篇先回答一个更早的问题:既然要"算得快",为什么不干脆只算一小段?——这是 BookKey 设计评审时讨论最久的一页,也是被否决得最干脆的一页。它值得单独一篇,因为记录"为什么不做"比记录

老刘 老刘 发布于 2026-10-21

接缝——块边界上的六个陷阱

接缝——块边界上的六个陷阱 旦阅诞生记 · 第 6 篇。上一篇讲了流式 BookKey 怎么把 100MB 的指纹算进 424 毫秒,途中带过了三个跨块陷阱。这一篇把"块边界"当成一类 bug 的母题,把散落在三端代码里的六个接缝一次讲透——它们症状各异,病根是同一个。 一、只要按块读,就有接缝 O

老刘 老刘 发布于 2026-10-18

100MB 的指纹——从 60 秒到 424 毫秒

100MB 的指纹——从 60 秒到 424 毫秒 旦阅诞生记 · 第 5 篇。上一篇说到 BookKey 的归一化口径:去 BOM、行尾统一、首尾裁剪。口径定了,新问题立刻浮出水面——这个指纹怎么算得动。本文所有代码取自 eggBookServer-wb / eggBookWin-wb / egg

老刘 老刘 发布于 2026-10-17

同一本书,两台设备认不出彼此——BookKey 与归一化

同一本书,两台设备认不出彼此——BookKey 与归一化 旦阅诞生记 · 第 04 篇(第二辑 · 认出同一本书) 从这一篇开始进入系列的核心:BookKey。它是旦阅整个同步体系的根——三端靠它认出"我们说的是同一本书"。这一篇讲它最基础的一层:怎么给一本内容相同、字节不同的 txt,算出同一个身

老刘 老刘 发布于 2026-10-16

技术选型的取舍——三端技术栈为什么这样选

技术选型的取舍——三端技术栈为什么这样选 旦阅诞生记 · 第 03 篇 上一篇把旦阅的整体架构摊开讲了一遍:三端一套算法,靠一份跨端契约(BookKey + 进度参数)把手机、电脑、服务端绑成一个整体。这一篇往回退一步,讲讲这三端的技术栈是怎么选出来的——以及每一个"选了它"的背后,都对应着一个"放

老刘 老刘 发布于 2026-10-15