<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>拾光集</title>
    <link>https://blog.hoofungson.cn</link>
    <description>一个安静的地方，存放关于技术、阅读与生活的长思考。</description>
    <language>zh-CN</language>
    <lastBuildDate>Thu, 13 Aug 2026 16:00:00 GMT</lastBuildDate>
    <atom:link href="https://blog.hoofungson.cn/feed.xml" rel="self" type="application/rss+xml"/>
    <item>
      <title>重新开始写博客</title>
      <link>https://blog.hoofungson.cn/#/post/restart-blog</link>
      <guid isPermaLink="false">https://blog.hoofungson.cn/post/restart-blog</guid>
      <pubDate>Thu, 13 Aug 2026 16:00:00 GMT</pubDate>
      <description>停更三年之后，我删掉了原来的博客，从零写了这个静态站点。这篇说说为什么。</description>
      <category>随笔</category>
      <category>写作</category>
      <content:encoded><![CDATA[<p>上一个博客停在 2023 年春天，最后一篇的标题是《下周继续更新》。三年过去，那篇「下周」始终没有到来。</p>
<p>删掉它的时候我没有太多犹豫。真正让我决定重写的，不是内容不够多，而是<strong>写的过程太累</strong>——每次想记点什么，先要打开编辑器、等依赖装完、处理插件冲突，等这一切结束，想说的话已经凉了。</p>
<h2 id="h-三个具体的理由">三个具体的理由<a class="heading-anchor" href="#h-三个具体的理由" data-anchor="h-三个具体的理由" aria-label="本节链接">#</a></h2>
<p>一是我发现自己<strong>只在写下来的时候才真正想清楚</strong>。读过的书、写过的代码、下过的棋，如果没有落成文字，过两个月就只剩一个模糊的印象：「好像读过」。</p>
<p>二是对「输出」这件事的重新理解。以前我以为写博客是为了被人看到，所以总在纠结选题够不够硬、观点够不够新。现在觉得，它更像是一个<strong>公开的笔记本</strong>：有人看很好，没人看也不亏。</p>
<p>三是技术上的洁癖。我想要一个十年后还能正常打开的站点：</p>
<ul><li><p>没有构建工具链，<code>index.html</code> 用浏览器直接打开就能看</p></li><li><p>没有 CDN 依赖，断网也能读</p></li><li><p>文章是纯文本的 Markdown，即使这个站点全丢了，文件还在</p></li></ul>
<blockquote><p>关于最后一点，我几乎是被迫学会的：2019 年用某个 CMS 写的四十多篇东西，因为数据库导出格式没人维护，现在全部躺在硬盘里打不开。</p></blockquote>
<h2 id="h-这个站点的实现">这个站点的实现<a class="heading-anchor" href="#h-这个站点的实现" data-anchor="h-这个站点的实现" aria-label="本节链接">#</a></h2>
<p>整个站点只有四类文件：</p>
<div class="table-scroll"><table><thead><tr><th>文件</th><th>作用</th></tr></thead><tbody><tr><td><code>content/posts/*.md</code></td><td>文章正文，唯一的内容源头</td></tr><tr><td><code>assets/js/markdown.js</code></td><td>自己写的 Markdown 渲染器</td></tr><tr><td><code>assets/js/app.js</code></td><td>路由、检索、主题与目录</td></tr><tr><td><code>index.html</code> + <code>style.css</code></td><td>外壳与样式</td></tr></tbody></table></div>
<p>构建脚本只用 Node 内置模块，做三件事：读取 Markdown 与 front matter、生成 <code>posts.generated.js</code>、顺带产出 <code>feed.xml</code> 与 <code>sitemap.xml</code>。</p>
<div class="code-block" data-lang="bash"><div class="code-block__head"><span class="code-block__lang">bash</span><button class="code-block__copy" type="button" data-copy>复制</button></div><pre><code>npm run build     # 生成数据与 RSS
npm run serve     # 本地预览 http://localhost:4173</code></pre></div>
<h2 id="h-接下来">接下来<a class="heading-anchor" href="#h-接下来" data-anchor="h-接下来" aria-label="本节链接">#</a></h2>
<p>我不打算给自己定更新频率——定过的计划，大多死在了计划本身。只留一个最低要求：<strong>每月至少写一篇</strong>，写不动长文就写短的。</p>
<p>如果非要说有什么目标，大概是这句：</p>
<blockquote><p>写得慢一点，但每篇都值得三个月后的自己再读一遍。</p></blockquote>]]></content:encoded>
    </item>
    <item>
      <title>围棋的「线」与坐标：一份读谱笔记</title>
      <link>https://blog.hoofungson.cn/#/post/go-coordinates</link>
      <guid isPermaLink="false">https://blog.hoofungson.cn/post/go-coordinates</guid>
      <pubDate>Sat, 01 Aug 2026 16:00:00 GMT</pubDate>
      <description>古人记谱用的是「平上去入」四隅加顺逆数数的办法。弄清这套坐标，读宋明棋谱才不至于迷路。</description>
      <category>围棋</category>
      <category>文献学</category>
      <category>笔记</category>
      <content:encoded><![CDATA[<p>刚开始读古代棋谱的时候，我被「六·三」「三·六」这类记法卡了很久。后来才明白，它不是我们熟悉的直角坐标，而是一套<strong>先定隅、再顺逆数数</strong>的定位系统。</p>
<h2 id="h-四隅与四声">四隅与四声<a class="heading-anchor" href="#h-四隅与四声" data-anchor="h-四隅与四声" aria-label="本节链接">#</a></h2>
<p>棋盘四角各有一个名字，对应四个声调：</p>
<ul><li><p><strong>平</strong> —— 左手方向（棋盘以左手为尊）</p></li><li><p><strong>上</strong>、<strong>去</strong>、<strong>入</strong> —— 依序轮转</p></li></ul>
<p>每个角管辖 90 路，四角合计 360 路，再加上棋心一路「太极」，正好 361。宋代《忘忧清乐集》里写得很清楚：</p>
<p><figure><img src="content/images/go-four-corners.svg" alt="围棋四隅与四声示意图" loading="lazy" decoding="async"><figcaption>四隅分属四声；四四位的对角势子以实心与空心棋子表示（示意图）</figcaption></figure></p>
<blockquote><p>夫棋盘有三百六十一路，以分平上去入四字，各管一角，计九十路……若言「六·三」，先顺数六而后逆数三；或言「三·六」，先顺数三而后逆数六是也。</p></blockquote>
<p>也就是说，<strong>数字的先后顺序是有意义的</strong>——它决定了你沿哪条边走。</p>
<h2 id="h-顺数与逆数">顺数与逆数<a class="heading-anchor" href="#h-顺数与逆数" data-anchor="h-顺数与逆数" aria-label="本节链接">#</a></h2>
<p>把这一点翻译成今天的语言，大约是：</p>
<ol><li><p>先确定这个点属于哪个角（平 / 上 / 去 / 入）；</p></li><li><p>从角上的「一一」出发，沿一条边<strong>顺数</strong>到第一个数字；</p></li><li><p>再沿另一条边<strong>逆数</strong>到第二个数字。</p></li></ol>
<p>清代的《弈理指归》把这件事编成了口诀，方便记：</p>
<blockquote><p>局分四隅，谱寓四声。落子数数，先纵后横。</p></blockquote>
<h2 id="h-线其实是圈">「线」其实是圈<a class="heading-anchor" href="#h-线其实是圈" data-anchor="h-线其实是圈" aria-label="本节链接">#</a></h2>
<p>这是另一个容易误解的地方。我们平常说「第三线」，听起来像是一条直线，但古人说的「第\*线」是一个<strong>方形圈</strong>。</p>
<p>从四隅的「一一」互相连起来，得到「第一线」；四隅的「二二」互相连起来，得到「第二线」——以此类推，共九条线。所以「一一」的两边都在第一线上，「三三」的两边都在第三线上。</p>
<div class="table-scroll"><table><thead><tr><th>称谓</th><th>构成方式</th><th>常见叫法</th></tr></thead><tbody><tr><td>第一线</td><td>四隅「一一」互连</td><td>死亡线</td></tr><tr><td>第三线</td><td>四隅「三三」互连</td><td>实利线</td></tr><tr><td>第四线</td><td>四隅「四四」互连</td><td>势力线</td></tr></tbody></table></div>
<div class="callout"><span class="callout__label">笔记</span><p>坐标本身不是下棋必需的东西，它只是学习与复盘的工具。真正对局时，棋手看到的是形状，不是数字。</p></div>
<h2 id="h-势子为什么要摆在对角">势子为什么要摆在对角<a class="heading-anchor" href="#h-势子为什么要摆在对角" data-anchor="h-势子为什么要摆在对角" aria-label="本节链接">#</a></h2>
<p>传统开局前，要在四隅的「四四」位对角各摆两黑两白，称为<strong>势子</strong>（也叫座子）。《棋经十三篇》说：</p>
<blockquote><p>权舆者，弈棋布置，务守纲格。先于四隅分定势子。</p></blockquote>
<p>对角而非同边的摆法，让开局天然带着均衡与张力。这一点和现代围棋取消座子、追求自由布局的方向，恰好是两种不同的审美。</p>
<h2 id="h-一点提醒">一点提醒<a class="heading-anchor" href="#h-一点提醒" data-anchor="h-一点提醒" aria-label="本节链接">#</a></h2>
<p>需要说明的是，十九路棋盘并非自古如此。考古发现的棋盘里，还有十七路、十五路等形制；棋子也有双面凸、单面凸、双面平（表面带文字或花纹）的区别。本文的讨论，只以流传千年的十九路形制为基准。</p>
<p>读谱这件事，术语弄清之后，剩下的就是耐心了。</p>]]></content:encoded>
    </item>
    <item>
      <title>从范数到距离：为什么「近」需要被定义</title>
      <link>https://blog.hoofungson.cn/#/post/norm-and-distance</link>
      <guid isPermaLink="false">https://blog.hoofungson.cn/post/norm-and-distance</guid>
      <pubDate>Mon, 20 Jul 2026 16:00:00 GMT</pubDate>
      <description>我们天天说两个向量「很像」，但「像」是一个需要被人为选择的东西。范数就是那个选择。</description>
      <category>数学</category>
      <category>机器学习</category>
      <category>笔记</category>
      <content:encoded><![CDATA[<p>「这两个向量很接近」——这句话在直觉上毫无歧义，落到代码里却处处是坑。因为<strong>距离不是天生的，是被定义出来的</strong>。</p>
<h2 id="h-范数给向量量个长度">范数：给向量量个长度<a class="heading-anchor" href="#h-范数给向量量个长度" data-anchor="h-范数给向量量个长度" aria-label="本节链接">#</a></h2>
<p>一个范数 <span class="math">\|\cdot\|</span> 要满足三条性质：非负性、齐次性、三角不等式。翻译成人话：</p>
<ul><li><p>长度不能是负的，只有零向量长度为 0；</p></li><li><p>把向量拉长 $k$ 倍，长度也正好是 $k$ 倍；</p></li><li><p>走三角形两边不会比走第三边更近。</p></li></ul>
<p>最常见的三个：</p>
<div class="table-scroll"><table><thead><tr><th>名称</th><th>定义</th><th>几何形状</th><th>典型用途</th></tr></thead><tbody><tr><td>L1</td><td><span class="math">\sum \lvert x_i \rvert</span></td><td>菱形</td><td>稀疏解、特征选择</td></tr><tr><td>L2</td><td><span class="math">\sqrt{\sum x_i^2}</span></td><td>圆形</td><td>欧氏距离、正则化</td></tr><tr><td>L∞</td><td><span class="math">\max \lvert x_i \rvert</span></td><td>正方形</td><td>最坏情况上界</td></tr></tbody></table></div>
<p>那个「几何形状」看起来很抽象，其实是理解它们差异的钥匙：<strong>单位球的形状，决定了大梯度方向偏向哪里</strong>。</p>
<h2 id="h-为什么-l1-会产生稀疏解">为什么 L1 会产生稀疏解<a class="heading-anchor" href="#h-为什么-l1-会产生稀疏解" data-anchor="h-为什么-l1-会产生稀疏解" aria-label="本节链接">#</a></h2>
<p>一句话版本：L1 的单位球在坐标轴上有<strong>尖角</strong>，而损失函数的等高线通常是光滑的椭圆。两者相切时，切点大概率落在尖角上——而尖角就在坐标轴上，那里意味着「某些分量为零」。</p>
<div class="math-block">\min_w \|y - Xw\|_2^2 + \lambda \|w\|_1</div>
<p>反观 L2，单位球是圆的，没有尖角，切点落在哪儿都正常，于是权重只会被压小、不会归零。</p>
<div class="callout"><span class="callout__label">提示</span><p>如果你只是想防止过拟合，用 L2；如果你想要一个能解释「哪些特征重要」的稀疏模型，用 L1。两者都要，就是 Elastic Net。</p></div>
<h2 id="h-从范数到距离">从范数到距离<a class="heading-anchor" href="#h-从范数到距离" data-anchor="h-从范数到距离" aria-label="本节链接">#</a></h2>
<p>有了范数，距离只是把差向量塞进去：</p>
<div class="math-block">d(x, y) = \|x - y\|</div>
<p>但注意：<strong>距离函数不一定要来自范数</strong>。只要满足非负、对称、三角不等式，任何函数都能当距离用。这带来了很多有意思的选择：</p>
<ul><li><p>余弦距离 <span class="math">1 - \frac{x \cdot y}{\|x\|\|y\|}</span>：只关心方向，不关心长度，适合文本向量</p></li><li><p>编辑距离：两次字符串变换的最少操作数</p></li><li><p>Jaccard 距离：集合的交并比，适合标签与推荐</p></li></ul>
<h2 id="h-一段容易踩坑的代码">一段容易踩坑的代码<a class="heading-anchor" href="#h-一段容易踩坑的代码" data-anchor="h-一段容易踩坑的代码" aria-label="本节链接">#</a></h2>
<p>下面的写法看起来很自然，但在高维下会失效：</p>
<div class="code-block" data-lang="python"><div class="code-block__head"><span class="code-block__lang">python</span><button class="code-block__copy" type="button" data-copy>复制</button></div><pre><code>import numpy as np

def euclidean(a, b):
    return np.sqrt(np.sum((a - b) ** 2))

# 高维下所有点对的 L2 距离会趋同，
# 「最近邻」逐渐失去区分度 —— 这就是维度灾难的一种表现。
x = np.random.rand(1000, 5000)
d = np.linalg.norm(x[:, None, :] - x[None, :, :], axis=-1)
print(d.std() / d.mean())   # 数值越小，说明区分度越差</code></pre></div>
<p>所以做向量检索时，通常不是「选个距离然后开算」，而是：</p>
<ul class="contains-task-list"><li class="task-item"><label class="task-list-item"><input type="checkbox" disabled checked><span>先看数据的尺度，做标准化</span></label></li><li class="task-item"><label class="task-list-item"><input type="checkbox" disabled checked><span>判断该关心方向还是绝对位置</span></label></li><li class="task-item"><label class="task-list-item"><input type="checkbox" disabled><span>盲目套用欧氏距离</span></label></li><li class="task-item"><label class="task-list-item"><input type="checkbox" disabled><span>忘了高维下距离会失效</span></label></li></ul>
<h2 id="h-一点体会">一点体会<a class="heading-anchor" href="#h-一点体会" data-anchor="h-一点体会" aria-label="本节链接">#</a></h2>
<p>范数这个概念，我在课本上见过很多次，真正弄懂却是在写检索功能的时候：<strong>当「相似」要被写进代码，你必须先回答「相似是什么意思」</strong>。数学只是把这个回答变得更精确，它并不能替你回答。</p>]]></content:encoded>
    </item>
    <item>
      <title>用三百行写一个 Markdown 渲染器</title>
      <link>https://blog.hoofungson.cn/#/post/markdown-renderer</link>
      <guid isPermaLink="false">https://blog.hoofungson.cn/post/markdown-renderer</guid>
      <pubDate>Sat, 04 Jul 2026 16:00:00 GMT</pubDate>
      <description>为了让博客完全不依赖 CDN，我手写了一个 Markdown 解析器。记录几个真正费劲的细节。</description>
      <category>前端</category>
      <category>JavaScript</category>
      <category>造轮子</category>
      <content:encoded><![CDATA[<p>这个博客的一个硬性要求是：<strong>断网也能正常显示</strong>。这意味着不能从 CDN 引 <code>marked</code> 或 <code>markdown-it</code>，只能自己写。</p>
<p>结论先行：块级解析比行内解析难，行内解析比想象中危险。</p>
<h2 id="h-架构两遍扫描">架构：两遍扫描<a class="heading-anchor" href="#h-架构两遍扫描" data-anchor="h-架构两遍扫描" aria-label="本节链接">#</a></h2>
<p>解析器分成两层，互不干扰：</p>
<ol><li><p><strong>块级解析</strong>：按行扫描，识别标题、列表、代码块、引用、表格、段落；</p></li><li><p><strong>行内解析</strong>：对段落与标题的文本内容，处理粗体、链接、行内代码等。</p></li></ol>
<div class="code-block" data-lang="javascript"><div class="code-block__head"><span class="code-block__lang">javascript</span><button class="code-block__copy" type="button" data-copy>复制</button></div><pre><code>function render(src) {
  var lines = src.replace(/\r\n?/g, '\n').split('\n');
  var html = renderBlocks(lines);       // 块级
  return { html: html, toc: toc };      // 顺便收集目录
}</code></pre></div>
<p>块级函数返回 <code>{ html, next }</code>——<code>next</code> 是下一个待处理行号。这个约定让「消费掉若干行」的块（代码块、列表、表格）能干净地交还控制权。</p>
<h2 id="h-坑一列表的续行与嵌套">坑一：列表的续行与嵌套<a class="heading-anchor" href="#h-坑一列表的续行与嵌套" data-anchor="h-坑一列表的续行与嵌套" aria-label="本节链接">#</a></h2>
<p>这是最麻烦的部分。列表项可能跨多行：</p>
<div class="code-block" data-lang="markdown"><div class="code-block__head"><span class="code-block__lang">markdown</span><button class="code-block__copy" type="button" data-copy>复制</button></div><pre><code>- 第一行
  缩进两格的续行
  - 嵌套的子项</code></pre></div>
<p>我的策略是<strong>先切成项、再递归</strong>：</p>
<ol><li><p>找出这个列表的基础缩进量 <code>baseIndent</code>；</p></li><li><p>缩进等于 <code>baseIndent</code> 的行，开启新项；</p></li><li><p>缩进更深的行，剥离缩进后并入当前项；</p></li><li><p>对每一项的内容数组，再次调用 <code>renderBlocks</code>——嵌套就自然发生了。</p></li></ol>
<div class="code-block" data-lang="javascript"><div class="code-block__head"><span class="code-block__lang">javascript</span><button class="code-block__copy" type="button" data-copy>复制</button></div><pre><code>var m = line.match(/^(\s*)([-*+]|\d{1,9}[.)])\s+(.*)$/);
if (m &amp;&amp; m[1].length &gt;= baseIndent &amp;&amp; m[1].length &lt;= baseIndent + 3) {
  items.push([m[3]]);          // 新列表项
}</code></pre></div>
<h2 id="h-坑二先转义再解析">坑二：先转义，再解析<a class="heading-anchor" href="#h-坑二先转义再解析" data-anchor="h-坑二先转义再解析" aria-label="本节链接">#</a></h2>
<p>如果不转义就解析，用户写一句 <code>&lt;img src=x onerror=alert(1)&gt;</code> 就直接注入了。我的做法是<strong>先转义再匹配</strong>：</p>
<div class="code-block" data-lang="javascript"><div class="code-block__head"><span class="code-block__lang">javascript</span><button class="code-block__copy" type="button" data-copy>复制</button></div><pre><code>var text = escapeHtml(raw);   // &amp; &lt; &gt; 先变实体
text = text.replace(/\*\*(?=\S)([\s\S]*?\S)\*\*/g, '&lt;strong&gt;$1&lt;/strong&gt;');</code></pre></div>
<p>但这里有个细节：<strong>引号不能一起转义</strong>，否则链接的标题语法 <code>[文字](url "标题")</code> 里的引号会变成 <code>&amp;quot;</code>，正则再也匹配不上。所以属性值单独用 <code>escapeAttr</code> 处理。</p>
<p>另外，<code>javascript:</code> 这类协议不会包含 <code>&amp;&lt;&gt;</code>，所以必须显式拦截：</p>
<div class="code-block" data-lang="javascript"><div class="code-block__head"><span class="code-block__lang">javascript</span><button class="code-block__copy" type="button" data-copy>复制</button></div><pre><code>function safeUrl(url) {
  if (/^\s*(javascript|vbscript|data)\s*:/i.test(url)) return '#';
  return url;
}</code></pre></div>
<h2 id="h-坑三行内代码要最先处理">坑三：行内代码要最先处理<a class="heading-anchor" href="#h-坑三行内代码要最先处理" data-anchor="h-坑三行内代码要最先处理" aria-label="本节链接">#</a></h2>
<p>行内代码里的内容不应该被二次解析。比如 <code>`**不要加粗**`</code> 必须原样输出。解决办法是用「占位符暂存」：</p>
<div class="code-block" data-lang="javascript"><div class="code-block__head"><span class="code-block__lang">javascript</span><button class="code-block__copy" type="button" data-copy>复制</button></div><pre><code>function stash(html) {
  store.push(html);
  return '\u0000' + (store.length - 1) + '\u0000';   // 用 NUL 字符占位
}</code></pre></div>
<p><code>\u0000</code> 在正常文本里几乎不可能出现，所以不会被后续规则误伤；等所有行内规则跑完，再把占位符还原成真正的 HTML。</p>
<h2 id="h-坑四兼容性">坑四：兼容性<a class="heading-anchor" href="#h-坑四兼容性" data-anchor="h-坑四兼容性" aria-label="本节链接">#</a></h2>
<p>写的时候顺手用了一个后行断言：</p>
<div class="code-block" data-lang="javascript"><div class="code-block__head"><span class="code-block__lang">javascript</span><button class="code-block__copy" type="button" data-copy>复制</button></div><pre><code>// 危险：旧版 Safari 会在「解析阶段」直接抛 SyntaxError，整个 JS 文件都不执行
code.replace(/(?&lt;=\S) $/g, '');</code></pre></div>
<p>这类问题不会给出友好的运行时报错，而是<strong>整个脚本静默失效、页面白屏</strong>。改成普通写法就好：</p>
<div class="code-block" data-lang="javascript"><div class="code-block__head"><span class="code-block__lang">javascript</span><button class="code-block__copy" type="button" data-copy>复制</button></div><pre><code>code.replace(/^ +| +$/g, '');</code></pre></div>
<div class="callout"><span class="callout__label">注意</span><p>正则字面量的语法错误是解析期错误，<code>try/catch</code> 拦不住，出错位置之前的所有代码也都不会执行。写兼容性要求高的代码时，避免使用较新的正则特性。</p></div>
<h2 id="h-成果">成果<a class="heading-anchor" href="#h-成果" data-anchor="h-成果" aria-label="本节链接">#</a></h2>
<p>最终支持的范围：</p>
<div class="table-scroll"><table><thead><tr><th>语法</th><th>状态</th></tr></thead><tbody><tr><td>标题 / 段落 / 引用</td><td>✅</td></tr><tr><td>有序、无序、任务列表（可嵌套）</td><td>✅</td></tr><tr><td>表格（含对齐）</td><td>✅</td></tr><tr><td>行内代码 / 围栏代码块</td><td>✅</td></tr><tr><td>粗体、斜体、删除线、高亮</td><td>✅</td></tr><tr><td>裸链接自动识别</td><td>✅</td></tr><tr><td>内嵌原始 HTML</td><td>❌ 有意不支持</td></tr><tr><td>数学公式（<span class="math">...</span> / $<span class="math">...</span>$）</td><td>✅ 轻量排版，不引入 KaTeX</td></tr></tbody></table></div>
<p>不支持的项是有意为之：<strong>功能范围越小，行为越可预测</strong>。对一个博客来说，这比支持所有冷门语法重要得多。</p>]]></content:encoded>
    </item>
    <item>
      <title>慢读：把一本书读三遍的方法</title>
      <link>https://blog.hoofungson.cn/#/post/slow-reading</link>
      <guid isPermaLink="false">https://blog.hoofungson.cn/post/slow-reading</guid>
      <pubDate>Wed, 17 Jun 2026 16:00:00 GMT</pubDate>
      <description>读得快不等于读得多。三遍读法看起来很笨，但它是我唯一坚持下来的读书方法。</description>
      <category>阅读</category>
      <category>方法</category>
      <category>随笔</category>
      <content:encoded><![CDATA[<p>我曾经是个「读书数量」爱好者。一年五十本的目标完成过两次，代价是现在让我说出那两年读过的任何一本书的核心观点，我大概只能想起三本。</p>
<p>问题不在于读得快，而在于<strong>读的时候没有停下来</strong>。</p>
<h2 id="h-三遍读法">三遍读法<a class="heading-anchor" href="#h-三遍读法" data-anchor="h-三遍读法" aria-label="本节链接">#</a></h2>
<p>现在我读一本非虚构的书，会分三遍：</p>
<h3 id="h-第一遍当小说读">第一遍：当小说读<a class="heading-anchor" href="#h-第一遍当小说读" data-anchor="h-第一遍当小说读" aria-label="本节链接">#</a></h3>
<p>不划重点，不做笔记，不求甚解。遇到看不懂的地方直接跳过，目标是<strong>知道这本书在讲什么、作者想说服我什么</strong>。</p>
<p>这一遍通常能在一两个晚上完成。它的作用不是记住，而是建立一个「地图」——后面再碰到细节时，知道该把它挂在哪儿。</p>
<h3 id="h-第二遍当工具书读">第二遍：当工具书读<a class="heading-anchor" href="#h-第二遍当工具书读" data-anchor="h-第二遍当工具书读" aria-label="本节链接">#</a></h3>
<p>隔几天再回来。这一遍只读目录和标题，挑出<strong>真正与我的问题相关的两三章</strong>精读，其余略过。</p>
<p>配合的动作是：</p>
<ul class="contains-task-list"><li class="task-item"><label class="task-list-item"><input type="checkbox" disabled checked><span>每读完一节，用一句话在空白处写下这节在说什么</span></label></li><li class="task-item"><label class="task-list-item"><input type="checkbox" disabled checked><span>遇到反直觉的论断，标记出来并写下「为什么我不同意」</span></label></li><li class="task-item"><label class="task-list-item"><input type="checkbox" disabled><span>抄写金句（这件事几乎没有用）</span></label></li></ul>
<div class="callout"><span class="callout__label">提示</span><p>「用自己的话复述一遍」是最有效的检验。如果一句话憋不出来，说明这一节其实没读懂。</p></div>
<h3 id="h-第三遍当材料读">第三遍：当材料读<a class="heading-anchor" href="#h-第三遍当材料读" data-anchor="h-第三遍当材料读" aria-label="本节链接">#</a></h3>
<p>这一遍只在需要输出的时候做——写文章、做分享、解决具体问题时，回到书里找那几段，把它变成自己的素材。</p>
<h2 id="h-为什么第三遍最重要">为什么第三遍最重要<a class="heading-anchor" href="#h-为什么第三遍最重要" data-anchor="h-为什么第三遍最重要" aria-label="本节链接">#</a></h2>
<p>因为<strong>输入的价值只有在被调用时才兑现</strong>。</p>
<p>前两遍建立的是「我知道这本书里有这个东西」的索引；第三遍才是真正的取用。很多人读了很多书却写不出东西，原因往往不是读得不够，而是从来没有走到第三遍。</p>
<div class="table-scroll"><table><thead><tr><th>遍数</th><th>目标</th><th>时长</th><th>产出</th></tr></thead><tbody><tr><td>第一遍</td><td>建立地图</td><td>1–2 晚</td><td>无</td></tr><tr><td>第二遍</td><td>理解论证</td><td>1 周内</td><td>页边批注</td></tr><tr><td>第三遍</td><td>变成素材</td><td>用到时</td><td>文章、笔记、方案</td></tr></tbody></table></div>
<h2 id="h-一个反面清单">一个反面清单<a class="heading-anchor" href="#h-一个反面清单" data-anchor="h-一个反面清单" aria-label="本节链接">#</a></h2>
<p>下面这些事，我做过并且确认没用：</p>
<ol><li><p><strong>抄金句</strong>——抄的时候很爽，抄完永远不会再看；</p></li><li><p><strong>追求读完</strong>——读到 60% 发现没用还硬读完，是最贵的一种节俭；</p></li><li><p><strong>同时开五本</strong>——同时开五本的结果通常是一本也没读完；</p></li><li><p><strong>把划线当理解</strong>——划线只说明「这句话写得好看」，不说明「我懂了」。</p></li></ol>
<h2 id="h-一点退让">一点退让<a class="heading-anchor" href="#h-一点退让" data-anchor="h-一点退让" aria-label="本节链接">#</a></h2>
<p>这套方法不适合小说。小说就该一口气读完，被打断的阅读体验会毁掉整本书。所以我的实际做法是：</p>
<ul><li><p>非虚构 → 三遍读法</p></li><li><p>小说 → 一遍读完，中间不插别的书</p></li></ul>
<p>读得慢下来之后，年阅读量掉到了十几本。但这两年我写出来的东西，比之前五年加起来还多。</p>
<p>这笔账，我觉得划算。</p>]]></content:encoded>
    </item>
  </channel>
</rss>
