<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Aronnax&apos;s Blog</title><description>Software Engineering &amp; AI | Learning | ACG Aesthetics</description><link>https://aronnax.site/</link><item><title>Linux 元年来了吗</title><link>https://aronnax.site/blog/linux-desktop-year/</link><guid isPermaLink="true">https://aronnax.site/blog/linux-desktop-year/</guid><description>DHH 说 2026 年是 Linux 元年。从商业预装、发行版碎片化到 Proton、Agent 与 Omarchy，聊聊桌面 Linux 差在哪一步，以及元年到底是意愿的事还是门槛的事。</description><pubDate>Sat, 29 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;何同学说，2019 年是 5G 元年；推特博主们说，2025 年是 LLM 元年乃至 AI 元年；DHH 说，2026 年是 Linux 元年。&lt;/p&gt;
&lt;p&gt;第一个论断是错的，那是何同学元年；第二个论断或许有些道理；但是现在没有人确定第三个是不是对的，因为 2026 年还是现在进行时。&lt;/p&gt;
&lt;p&gt;作为一个某种意义上的技术爱好者，我还没有参与过庞大的项目，没有开源过里程碑式的作品，最近「民办 XXX」的概念很火，我想我们正是技术达人和普通用户之间的那一层，也就是「民办程序员」，这一层属性或许能让我有足够的底气说我比 DHH 这样的大佬或者啥都不懂的小白更有底气谈这个问题。以下请听我的分析。&lt;/p&gt;
&lt;h2&gt;Linux 为什么迟迟不普及&lt;/h2&gt;
&lt;p&gt;首先请允许我纠正一个概念，我们的标题，实则应该是「Linux 桌面元年来了吗」，也就是 Linux 是否正积极的运行在大家的个人 PC 上；而 Linux 操作系统本身，早在很久以前就已经广泛普及了，上到如今需求正旺的数据中心、训练中心的服务器，下到大家手里拿着的 Android 手机，又或者是乘坐地铁时看到的电子告示板，都是运行在 Linux 上的，如果说「广义 Linux」的话，他的市场份额大概是百分百的全球第一。&lt;/p&gt;
&lt;p&gt;而今天我们讨论的问题是，Linux 桌面发行版为什么迟迟不进入大家的个人电脑。&lt;/p&gt;
&lt;h3&gt;商业环境&lt;/h3&gt;
&lt;p&gt;我想第一点在于商业环境，截至现在，还没多少厂商愿意预装 Linux 系统直接销售，从硅谷到中国乡镇，大家在数码商店买到的笔记本电脑或整机有不低于 90% 的几率是 Windows 系统或者 macOS 系统。剩下的特例包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;华为，不过他们预装的是鸿蒙系统，我们暂且相信鸿蒙是一个自研系统&lt;/li&gt;
&lt;li&gt;在官网直接购买时，确实可以看到预装 Linux 的机型，不过各家装的不是同一个：Dell 的 XPS Developer Edition 是 Ubuntu，HP 的 Dev One 是 Pop!_OS，Framework 则在 2026 年 8 月开始给 Laptop 12 的预装机提供 Fedora KDE，理由是这个型号有八成用户本来就在跑 Linux&lt;/li&gt;
&lt;li&gt;中国的政府机构、国有企业采购的电脑可能搭载的是统信系统，也算一种 Linux 发行版&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;或许有人说 DIY 玩家不就可以自由选择了吗？首先，我们必须承认 DIY 玩家的份额比想象中少得多；再次，对于这些「玩家」来说，或许没有什么理由去装一个跑游戏还有兼容性问题的系统；最后，在庞大的中国市场，盗版 Windows 是一股不容小觑的力量，装一个盗版 Windows 比装一个 Linux 发行版还要容易很多。&lt;/p&gt;
&lt;p&gt;综上所述，即使有一些特例，我们仍然可以认为现在一个人无论通过何种方式买一台电脑，极大概率买到的不是一台 Linux 电脑。而对于绝大部分用户来说，直接结果就是，没有理由去换掉一个厂商已经装好的系统。对于不熟悉电脑操作的用户，去动手换一个自己不熟悉的系统完全没有必要，哪怕是从 Windows 10 升级到 Windows 11 这么一个「一键式」的体验，都需要犹豫很久，不必多想我们身边会有一些老人怀念 Windows 10、Windows 7 乃至 Windows XP，更何况一个需要手动分区，进 BIOS，涉及到终端操作的系统呢？&lt;/p&gt;
&lt;p&gt;此时又有人问，为什么这些厂商不去主动贩卖搭载 Linux 系统的电脑呢？&lt;/p&gt;
&lt;p&gt;Linux 作为一个自由软件，背后没有一个像微软那样有动力掏钱补贴 OEM 的商业主体，所以电脑是否预装 Linux 发行版，基本是厂商单方面决定的。微软为了维持 Windows 的市场份额，会和厂商有 OEM 协议与生态补贴，厂商没有理由去不选择微软。其次，一个很现实的理由是厂商不敢去为用户预装一个没有 Microsoft Office 兼容的系统，哪怕是 2026 年，Office 依然是大多数人使用电脑的主要用途。&lt;/p&gt;
&lt;p&gt;除去微软，其实 Adobe 系列软件也是如此，大量使用 Photoshop、PR 的视觉创意用户是不敢去贸然使用 Linux 的。&lt;/p&gt;
&lt;h3&gt;内部矛盾&lt;/h3&gt;
&lt;p&gt;除去商业问题，Linux 的内部矛盾是一个更加令人头疼的问题。别说小白用户不会选，现在所谓的「技术大佬」们，也都还在为选择哪个 Distro 而发愁。&lt;/p&gt;
&lt;p&gt;这是 GNU/Linux 作为自由软件（开源软件）的必然后果，开源为大家提供了可能性，同时无法抑制多样性。在这里，这幅经典的图片不得不再次摆出来：&lt;/p&gt;
&lt;figure&gt;
	&lt;div
		style=&quot;max-height: 70vh; overflow-y: auto; border: 1px solid rgba(128,128,128,0.3); border-radius: 6px;&quot;
	&gt;
		&lt;a
			href=&quot;/blog-images/linux-desktop-year/linux-distribution-timeline.svg&quot;
			target=&quot;_blank&quot;
			rel=&quot;noopener&quot;
		&gt;
			&lt;img
				src=&quot;/blog-images/linux-desktop-year/linux-distribution-timeline.svg&quot;
				alt=&quot;Linux 发行版时间线&quot;
				style=&quot;width: 100%; display: block;&quot;
			/&gt;
		&lt;/a&gt;
	&lt;/div&gt;
	&lt;figcaption&gt;Linux 发行版时间线（框内可滚动，点击看完整大图）&lt;/figcaption&gt;
&lt;/figure&gt;&lt;p&gt;如你所见，当你真正尝试迈出一步去选择一个发行版，第一关是「选择困难症」。&lt;/p&gt;
&lt;p&gt;大家有着不同的包管理器、桌面环境、显示协议、开发理念，开发者自己玩的很尽兴，但是代价是用户没那么多时间去沉下心来研究上面这幅图，还在没有外人干扰的情况下做出选择。一个只用 Office 的人，会愿意去花上一个上午的时间，听听 GNOME 和 KDE 谁才是老大吗。&lt;/p&gt;
&lt;p&gt;这些巨大分歧也造成了软件厂商们无法积极的去适配 Linux，进一步恶化了 Linux 的非编程领域软件生态。以我自己为例，我最心爱的桌面远程软件网易 UU 远程至今没有 Linux 版，原因很简单，想要给 Linux 适配一个远程软件，网易的开发人员们必须做好兼容 X11 和 Wayland，兼容各类显卡驱动，兼容各类窗口管理器，作为一个大众软件，还必须同时提供 deb、rpm、AppImage 乃至 AUR 包。对于软件开发者来看，优化 Linux 体验是一个高投入、低回报的过程。这和为什么 iPhone 用户能买到各种各样的手机壳，而安卓用户却不行是一个道理——做 iPhone 手机壳每年只需要开三到四个磨具，而安卓厂商每年有五花八门的中杯大杯超大杯，单一机型销量还不如 iPhone 零头。&lt;/p&gt;
&lt;h3&gt;其他原因&lt;/h3&gt;
&lt;p&gt;Linux 不入流，也有其他原因，比如硬件适配性，大众购买笔记本电脑这一品类时，OEM 厂商预装的 Windows 都是为单一机型特定优化好的，比如以我的 Asus 电脑为例，触控板上的 DialPad，在我离开 Windows 后再也没有见他亮起来过。&lt;/p&gt;
&lt;p&gt;更著名的例子则是 Nvidia 显卡驱动，相信对于对 Linux 感兴趣的读者对这幅图不陌生。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/blogimages/linux-desktop-year/nvidia-linus.jpeg&quot; alt=&quot;Linus 对 Nvidia 比中指&quot;&gt;&lt;/p&gt;
&lt;p&gt;这里不得不说提一嘴，Linux 内核安装驱动的体验实则是比 Windows 要好得多的，装好 Linux 后大多数硬件是可以直接用的，如果你重装过微软官网下载的纯净 Windows 镜像，想必还记得网卡驱动都还得自己装的窘态。奈何 OEM 镜像已经把这一步提前做了。&lt;/p&gt;
&lt;p&gt;此外还有用户的个人心理因素，工作场所对于电脑系统的指定，以及特定软件的需求等等，要说为什么 Linux 不流行，我们还能写 3000 字。&lt;/p&gt;
&lt;h2&gt;为什么 Linux 元年要来了？&lt;/h2&gt;
&lt;p&gt;开头说的 DHH 说「Linux 元年要来了」，实际上是他在给自己的新发行版 &lt;strong&gt;Omarchy&lt;/strong&gt; 打广告，不过这句话或许真的在成真。&lt;/p&gt;
&lt;h3&gt;Linux 游戏体验正大幅提升&lt;/h3&gt;
&lt;p&gt;虽然我目前的重度游戏场景依然驻扎在 Windows 一侧，但不得不承认，如今在 Linux 上打游戏，比在 Mac 上靠谱得多。作为一个对硬核大作需求不高的人，我起码能打包票：《雀魂麻将》和《小丑牌》在 Omarchy 上跑得丝般顺滑，毫无兼容性问题。而这一切的最大功臣，就是大家都喜爱的 Steam 及其背后的硬件野心 Steam Deck——更准确地说，是其核心的 Proton 转译层。&lt;/p&gt;
&lt;p&gt;无论你是常看 LTT 还是国内数码 UP 主的硬核科普，大概都对 Proton 的大名有所耳闻。简单概括，Proton 绝非那种吃硬件资源的「虚拟机」，而是一个高效的「转译层」（本质上是 Wine 的进化版）。它负责将 Windows 的 DirectX 图形指令实时翻译成 Linux 支持的 Vulkan 指令。得益于 V 社财大气粗还有心积极拥抱开源社区，Proton 的转译效率达到了前所未有的高度。在不少评测中，甚至出现了性能倒挂的现象，在 Linux 下用 Proton 转译跑 3A 游戏的帧数，居然反超了 Windows 原生平台。原因很简单——「轻量的 Linux + Proton 转译损耗」的整体负担，有时真就小于「繁重的 Windows 后台服务 + 游戏本体」。&lt;/p&gt;
&lt;p&gt;除去带有内核级反作弊系统的多人游戏目前仍是一道难关，Proton 的生态已经随着 SteamOS 的普及而高度成熟。更关键的是，因为 V 社自己要拿它来卖掌机，这套机制做到了真正的「开箱即用」。直接点击运行游戏即可，彻底终结了过去 Linux 玩家为了打个游戏还要开终端、改配置文件的痛苦折磨。&lt;/p&gt;
&lt;p&gt;在我看来，很多技术达人虽然动手能力极强，却迟迟不愿彻底将主战机切换到 Linux，根本原因就在于「极客」与「玩家」这两个身份有着极高的重叠度。如今，随着 Linux 游戏体验这块最大短板被大幅补齐，我相信，它所能撬动并吸引来的新 Linux 桌面玩家，绝对会远超所有人的预期。&lt;/p&gt;
&lt;h3&gt;Windows 正失去公信力&lt;/h3&gt;
&lt;p&gt;是的，Linux 的市场份额有可能好转，离不开微软的自己作死。不必过度思考，我就可以快速列下好几个微软的罪证：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;哪怕在中国市场高度不可用，还是强推 Copilot&lt;/li&gt;
&lt;li&gt;哪怕是没有 AI 的时候，也强推 Office 365 和 OneDrive&lt;/li&gt;
&lt;li&gt;系统极度臃肿，开机空载占用一堆无用进程，被迫兼容一堆历史工具，「设置」「控制面板」至今仍然并存&lt;/li&gt;
&lt;li&gt;隔三岔五更新&lt;/li&gt;
&lt;li&gt;软件生态已经不适合最新的 Agent 发展，满地的 dll 文件远不如 Unix 的「一切皆文件」哲学&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在海外，LTT 发「There&amp;#39;s NO Excuse Not To Try Linux!」或许不算什么，但是当 PewDiePie 也开始发「I installed Linux (so should you)」时，我认为这确实意味着一个节点到来了。&lt;/p&gt;
&lt;h3&gt;Linux 是 Agent 的天然领地&lt;/h3&gt;
&lt;p&gt;诸位可能知道无论是当时的 OpenClaw 还是现在的 Codex，都是 Mac First，很多人争先恐后的去购买 Mac mini，也有观点认为 Mac First 是因为 OpenAI 内部都在用 mac，这诚然是一个角度，但是我认为与其说是 Mac First，不如说是 Unix-like First。&lt;/p&gt;
&lt;p&gt;首先需要简单介绍一下 Linux、macOS 和 Unix 的关系。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-mermaid&quot;&gt;graph TD
    UNIX[早期 UNIX &amp;lt;br/&amp;gt; 贝尔实验室] --&amp;gt; BSD[BSD 分支]
    UNIX --&amp;gt; MINIX[MINIX]
    BSD --&amp;gt; Mach[Mach 内核]
    Mach --&amp;gt; NeXT[NeXTSTEP]
    BSD --&amp;gt; NeXT
    NeXT --&amp;gt; macOS[macOS]
    MINIX -.-&amp;gt;|仅为启发&amp;lt;br/&amp;gt;非代码派生| Linux[Linux 内核]
    Linux --&amp;gt; Distros[各大 Linux 发行版]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;简单来说，macOS 和 Linux 都和 Unix 本身有着千丝万缕的关系，macOS 目前仍然是正版授权，后者则是以相同的系统哲学铸成的。Linus 当年是在 MINIX 上写的 Linux，文件系统布局也照抄过，但内核是从零写的，没有继承 MINIX 的代码，这也正是后来那场 Tanenbaum-Torvalds 论战的由来。要说这份哲学是什么——「一切皆文件」（Everything is a file）以及极简、透明的命令行哲学。&lt;/p&gt;
&lt;p&gt;对于目前的 AI Agent 来说，它们的核心是处理与生成文本的大语言模型。Agent 想要接管系统并自动执行任务，最自然的方式就是通过 CLI 输入指令，并直接读取纯文本的配置文件或日志反馈。在 Linux 体系中，无论是修改网络代理、部署 Docker 容器还是配置环境变量，系统状态几乎全以纯文本形式暴露；而在 Windows 环境下，错综复杂的图形设置界面、深不可测的注册表（Registry），以及重度依赖 GUI 操作的软件生态，对基于文本流的 AI 来说完全是难以解析的黑盒。&lt;/p&gt;
&lt;p&gt;更进一步看，在终端 Shell 的选择上，Linux/macOS 标配的 Bash/Zsh 相比 Windows 的 PowerShell 具有极其明显的优势：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;纯文本流 vs 对象管道&lt;/strong&gt;：PowerShell 的核心是 .NET 对象管道（Object Pipeline），这种设计在 C# 生态和 Windows 运维里固然强大，但也带来了沉重的运行时开销与复杂的类型推导。相比之下，Bash 和 Zsh 坚守了 Unix 经典的纯文本流（&lt;code&gt;stdin&lt;/code&gt;/&lt;code&gt;stdout&lt;/code&gt;）。对大模型而言，文本就是它最天然的介质，处理 Bash 的文本输出远比解析 PowerShell 那一层层包装的 .NET 对象结构要直接且高效得多。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Token 效率&lt;/strong&gt;：互联网上数十年的 CI/CD 自动化脚本、Docker 镜像构建文件以及开源项目文档，绝大多数都是基于 POSIX 标准编写的。AI Agent 执行一行简单的 &lt;code&gt;grep&lt;/code&gt;、&lt;code&gt;awk&lt;/code&gt; 或 &lt;code&gt;sed&lt;/code&gt;，不仅语义紧凑，而且在 LLM 的训练数据中拥有极高且稳定的提示词映射率。反观 PowerShell 那一套动辄十几个字符的 Verb-Noun 命名规范（如 &lt;code&gt;Get-ChildItem&lt;/code&gt;）以及独特的参数转义逻辑，不仅白白消耗更多的 Token，还无形中增加了大模型推导生成时的歧义与幻觉几率。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;当未来的软件开发与系统自动化越来越依赖大模型时，天生对脚本、纯文本和自动化极度友好的 Unix-like 系统，在整体的适配度上，我认为是远超过 Windows 阵营的。&lt;/p&gt;
&lt;p&gt;有人可能会反驳 Codex 等客户端都是先有 macOS，再有 Windows，最后才有 Linux，我觉得这和前面的内容并不冲突。前面讲的是 Agent 操作一个系统的情况下，Unix-like 有巨大优势；而在 GUI harness 这个背景下，是人如何与 Agent 交互的问题。Codex Desktop 迟迟不上 Linux，并不是 Codex 内置的 Agent 无法适配 Linux——相反，在 Claude Code、Codex CLI、Hermes 等工具的发布框架下，一般都是 Bash First，pwsh 才是二等公民——Codex Desktop 上 Linux 晚，是落入了上述的 Linux 下面向用户的软件兼容困难的问题，Computer Use 等功能才是延迟发布的关键。&lt;/p&gt;
&lt;p&gt;说起 Computer Use，Linux 不得不再赢一遍，这个功能在 Linux 下有很大可能是不怎么被需要的，因为能用修改配置文件解决的事情，为什么要模拟人类操作电脑呢？&lt;/p&gt;
&lt;h3&gt;Omarchy 与独裁系统&lt;/h3&gt;
&lt;p&gt;回到开头的故事。DHH 发布了 Omarchy，反响很大，他自己甚至说这可能带来 The year of Linux。&lt;/p&gt;
&lt;p&gt;先说 Omarchy 是什么。按官方介绍，它是一款基于 Arch、平铺窗口管理器 Hyprland 和桌面构建工具包 Quickshell 的 omakase（主厨精选）发行版，从 Neovim 到 Chromium、从 Obsidian 到 LibreOffice 全部预装，开箱即用。DHH 强调这不是预装软件的大杂烩，而是「我平时会用到的一切」；同时他也提醒你，要欣赏这种重度 TUI、主题精致、平铺窗口的美感，「需要一个适应的过程」。&lt;/p&gt;
&lt;p&gt;两个关键词：&lt;strong&gt;主厨精选&lt;/strong&gt;、&lt;strong&gt;适应过程&lt;/strong&gt;。问题最后都落在第二个上。&lt;/p&gt;
&lt;p&gt;我想给「主厨精选」换一个更中性、甚至略带贬义的说法：&lt;strong&gt;独裁系统&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;这个词脱胎于 BDFL（Benevolent Dictator For Life，终身仁慈独裁者）——项目创始人在社区出现争议时握有最终决定权。我把它挪到操作系统上：所谓独裁系统，就是发行者已经替你做完了几乎所有决定，哪怕你一行配置都没写，它依然以发行者本人的习惯高效运转。你不必选，甚至不能选。&lt;/p&gt;
&lt;p&gt;不过这里要先做个区分。独裁有硬有软。macOS 是硬独裁：苹果替你规定了快捷键、动画曲线、设计语言乃至窗口逻辑，而且你&lt;strong&gt;换不掉&lt;/strong&gt;——你没办法把 WindowServer 拆下来装一个平铺窗口管理器。Omarchy 是软独裁：底下毕竟还是 Arch，你想换 KDE、想扔掉 Hyprland，没人拦得住你，&lt;code&gt;pacman&lt;/code&gt; 一句话的事。它的强制力来自默认值本身的完成度：好到你不想动它。&lt;/p&gt;
&lt;p&gt;也正因为如此，说 Omarchy 是「第一个有主见的发行版」并不成立。elementary OS 有近乎洁癖的人机界面规范，Pop!_OS、Zorin 各有各的执念，ChromeOS 更极端，平铺这条线上也早有 Regolith 和 Garuda。Omarchy 真正特别的地方不在于「有主见」，而在于&lt;strong&gt;它是一个人的 dotfiles 直接当产品发行&lt;/strong&gt;。Ubuntu 和 Fedora 的取舍是委员会的产物，是为了适合所有人而不断妥协的结果，代价就是用户装完系统之后，依然要面对扩展插件、桌面美化和环境配置的泥潭。而 Arch + Hyprland + Neovim + 一整套调好的 config，其中任何一项自己来配都要搭进去大半天写配置文件外加长期微调，DHH 直接把他自己在用的那套甩给你。这里面一点妥协都没有，全是一个人的审美偏执和生产力哲学。&lt;/p&gt;
&lt;p&gt;对 Linux 桌面来说，有人这么干是好事。开源的多样性给了它生命力，也带来了没完没了的选择困难：桌面环境选 GNOME 还是 KDE？显示协议用 Wayland 还是 X11？包管理器用 apt、pacman 还是 Flatpak？每一个环节都有几十种组合，消耗掉的是普通用户的耐心，劝退的是想做适配的厂商。社区里人人都在造轮子、发新的发行版，却很少有人敢站出来端出一套完成度足够高的默认体验，然后告诉用户：别选了，听我的，这套就是最帅、最高效的。macOS 能在开发者和创作者群体里建立起极其稳固的口碑，靠的正是这种绝对的独裁：用户让渡一部分自定义的自由，换来统一性、像样的默认美学，以及真的开箱即用。&lt;/p&gt;
&lt;p&gt;所以问题不在于要不要独裁，而在于 Omarchy 的独裁是替谁做的。&lt;/p&gt;
&lt;p&gt;「适应过程」就是 DHH 不打自招的地方。他浪漫地把它称作一场超出舒适区的冒险，但现实是绝大多数人把电脑当生产力工具，没人想在工具上冒险。而 Omarchy 要求的适应，就是最劝退的那几种。&lt;/p&gt;
&lt;p&gt;平铺窗口与全键盘操控，对极客是双手不离键盘的效率，对习惯拖拽窗口、点「最大化/最小化」的人来说，只意味着背一堆 Super/Alt 组合键，以及随之而来的挫败感。TUI 与终端依赖，即使到了 2026 年，让一个只想写写文档、看看视频的用户打开终端去改纯文本配置文件，依然是一道跨不过去的沟。而所谓主厨精选，如果真要走向大众，主菜应当是直觉的、图形化的、零学习成本的；Omarchy 的主菜却是重度命令行与平铺窗口——相当于主厨端上来一盘需要熟记复杂吃法规矩的高级刺身，然后对客人说：吃不惯是因为你还没适应。&lt;/p&gt;
&lt;p&gt;Omarchy 的尴尬就在这里：&lt;strong&gt;它解决的，恰恰是最不需要被解决的那群人的碎片化困境。&lt;/strong&gt; 能欣赏它的人，本来就有能力也有耐心自己配出一套 Hyprland；而真正需要一位仁慈独裁者替他做决定的人，第一天就会被 Super+Enter 劝退。&lt;/p&gt;
&lt;p&gt;Omarchy 的叙事底色是「开发者逃离 macOS」，目标受众从第一天起就写在脸上。不过 DHH 的野心不止于此。2026 年 8 月，他成立了 Omacom 基金会，拿到 800 万美元认捐，出资人里坐着 Michael Dell、Patrick Collison、Jack Dorsey 和 Jason Fried；第一笔钱给了 Hyprland 的作者 vaxry，三年独家赞助，让他全职做下去。Dell 官方博客同期发了《Year of the Linux Laptop: Omarchy on XPS》，联合 Intel 给 2026 款 XPS 做了 Day One 支持。他是认真要去撬那几亿台桌面的。&lt;/p&gt;
&lt;p&gt;可钱和大佬解决不了主菜的问题。Dell 做的是让你装完能用；替你装好这一步，它没做——ISO 还是得你自己下，启动盘还是得你自己做。800 万美元也许能让 Omarchy 支持更多机型、被更多人听说，可它端出来的仍然是 Hyprland 和 Neovim。Omarchy 或许会成为几十万程序员和 Linux 极客梦寐以求的年度新欢，却绝不可能是撬动 Windows/macOS 用户的那一下。The year of Linux 这个口号，错的不是野心，是菜单。&lt;/p&gt;
&lt;p&gt;Linux 桌面真正需要的独裁，不是教用户怎么用 Neovim 和 Hyprland 的独裁，而是让用户可以彻底不碰 Terminal 的独裁，是安装包能双击打开的独裁，是有一个全局统一应用商店的独裁。&lt;/p&gt;
&lt;p&gt;讽刺的是，今天离这个目标最近的既不是 Ubuntu，也不是 DHH，而是来自中国的政企定制 Linux。统信 UOS、麒麟这一类系统从来没打算做极客的玩具，它们要交付的是能让一间办公室里几百个只会用 Windows 的人第二天就上手的东西：安装包双击运行、统一的应用商店、图形化的一切、几乎不需要终端。这些在极客眼里毫无技术含量甚至有点土的取舍，正好就是大众化需要的全部条件。它们不是想通了什么，只是被需求逼到了正确的位置上。&lt;/p&gt;
&lt;h2&gt;所以，桌面元年来了吗&lt;/h2&gt;
&lt;p&gt;不是 2026 年，Omarchy 也没有做到它承诺的那件事。&lt;/p&gt;
&lt;p&gt;这篇文章的前后两半其实在回答两个不同的问题。后半篇那三股力量涨的是意愿：Proton 让游戏不再是借口，微软自己把用户往门外推，Agent 让 Unix-like 从个人偏好变成了结构优势。想换的人确实比几年前多得多。前半篇列的那些障碍涨的是门槛，而它们一条都没被解决——电脑买来还是 Windows，只用 Office 的人还是打不开 Office，Photoshop 依然没有，显卡驱动依然会让人回论坛发帖，我的 DialPad 依然不亮。&lt;/p&gt;
&lt;p&gt;元年是门槛的事，不是意愿的事。想装的人再多，卡在第一步的人一样多。&lt;/p&gt;
&lt;p&gt;Omarchy 的尴尬也在这里。它把「装完以后」做到了几乎最好，却对「装之前」和「装不下去的人」束手无策。800 万美元能让它支持更多机型，不能让它变成一个双击就打得开的东西。&lt;/p&gt;
&lt;p&gt;门槛什么时候降，我给不出年份，但给得出条件：电脑买来就是 Linux，安装包双击能开，一个应用商店装完所有东西，Office 和 Adobe 要么进来、要么被彻底替代。这几件事没有一件需要新技术，需要的是有人愿意去干这些不好玩的活。统信和麒麟已经在干了，只不过他们的甲方是一间办公室。&lt;/p&gt;
&lt;p&gt;但我判断这一天不远。Linux 桌面这几年确实在往好的方向走，前面那三股力量是真的在把人往这边推，而人一多，总会有人去接那些不好玩的活。&lt;/p&gt;
&lt;p&gt;至于验收标准，我只有一条：我敢给一个只用 Office 的长辈装一台 Linux，装完不用留下我的电话。&lt;/p&gt;
&lt;p&gt;现在还不敢。但比以前敢一点了。&lt;/p&gt;
</content:encoded></item><item><title>Does the Three-Episode Rule Really Work?</title><link>https://aronnax.site/blog/three-episode-rule/</link><guid isPermaLink="true">https://aronnax.site/blog/three-episode-rule/</guid><description>An anime folk heuristic, formalised as a multi-armed bandit problem and tested on 4,153 real shows. Bilingual — use the language toggle in the navigation bar.</description><pubDate>Sat, 22 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;div data-lang=&quot;en&quot;&gt;&lt;h2&gt;1. The heuristic&lt;/h2&gt;
&lt;p&gt;Japanese anime is released in seasons. Every three months, thirty to fifty new series begin airing at once, most of them running twelve weekly episodes. A viewer picking up several at the same time has to decide, early and repeatedly, which ones to abandon.&lt;/p&gt;
&lt;p&gt;The community&amp;#39;s answer is a rule that nobody wrote down and almost everybody follows: &lt;strong&gt;watch the first three episodes, then decide whether to keep going or drop the show.&lt;/strong&gt; The usual justification is that a series often withholds its real premise until the second or third episode, so a single episode is not enough evidence.&lt;/p&gt;
&lt;p&gt;Three is a suspiciously round number for a decision problem, and the rule has a precise structure: a fixed exploration budget per arm, followed by an irrevocable commitment. That is the shape of an Explore-Then-Commit policy. So the number is testable, and this post tests it on real rating data.&lt;/p&gt;
&lt;h2&gt;2. Formalisation&lt;/h2&gt;
&lt;p&gt;For one broadcast season, let the arms be the $K$ series airing concurrently. Pulling arm $i$ means watching one episode of series $i$; the reward is the viewer&amp;#39;s satisfaction with that episode, a value in ${1,\dots,10}$. Write $\mu_i$ for the true mean quality of series $i$ and $E = 12$ for its episode count.&lt;/p&gt;
&lt;p&gt;Under this map the folk rule has the shape of Explore-Then-Commit with $m = 3$: sample every arm $m$ times, then commit to the surviving set for the remaining $E - m$ episodes. The question is whether $m^* = 3$.&lt;/p&gt;
&lt;p&gt;Two things are worth separating before going further, because the rest of this post moves between them. &lt;em&gt;ETC&lt;/em&gt; describes an &lt;strong&gt;allocation&lt;/strong&gt; — uniform exploration followed by an irrevocable decision. It says nothing about what the decision is for. The folk rule borrows that allocation but serves a different &lt;strong&gt;objective&lt;/strong&gt; from the one ETC is usually analysed against, and §4 makes that objective precise. Under the threshold objective the same uniform-then-commit allocation is what the pure-exploration literature calls &lt;em&gt;uniform allocation&lt;/em&gt;; the ETC name is recovered in §6, once a shared budget turns the problem back into cumulative-regret minimisation.&lt;/p&gt;
&lt;h2&gt;3. Data&lt;/h2&gt;
&lt;p&gt;All rewards come from &lt;a href=&quot;https://bangumi.tv&quot;&gt;bangumi.tv&lt;/a&gt;, the largest Chinese-language anime database, via &lt;em&gt;bangumi/Archive&lt;/em&gt; [1] — the site&amp;#39;s own periodic data export, published weekly through GitHub Releases specifically so that projects like this one do not have to scrape. Nothing here was crawled; the snapshot used throughout is the dump of 2026-08-18.&lt;/p&gt;
&lt;p&gt;The export ships one JSON-lines file per entity type. Only &lt;code&gt;subject.jsonlines&lt;/code&gt; is needed here, filtered to &lt;code&gt;type = 2&lt;/code&gt; (anime) and &lt;code&gt;platform = TV&lt;/code&gt;. Each record carries the fields an experiment needs to be reproducible — &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;date&lt;/code&gt;, &lt;code&gt;platform&lt;/code&gt;, &lt;code&gt;eps&lt;/code&gt;, &lt;code&gt;tags&lt;/code&gt;, &lt;code&gt;score&lt;/code&gt;, &lt;code&gt;rank&lt;/code&gt; — and, critically, &lt;code&gt;score_details&lt;/code&gt;: the &lt;strong&gt;complete one-to-ten rating histogram&lt;/strong&gt;, not merely an average.&lt;/p&gt;
&lt;p&gt;That last field is what makes the study possible without modelling assumptions. Rewards are drawn from the empirical distribution of real votes, so nothing about the arms has to be assumed — not Bernoulli, not Gaussian, not bounded-subgaussian. The per-arm mean and standard deviation used below are simply the moments of that histogram,&lt;/p&gt;
&lt;p&gt;$$
\mu_i=\frac{1}{N_i}\sum_{v=1}^{10} v,n_{i,v},\qquad \sigma_i^2=\frac{1}{N_i}\sum_{v=1}^{10}(v-\mu_i)^2 n_{i,v},
$$&lt;/p&gt;
&lt;p&gt;with $n_{i,v}$ the number of votes of value $v$ and $N_i=\sum_v n_{i,v}$. Series with fewer than 100 votes are excluded; each season is restricted to its ten most-voted titles, which is roughly the number a single viewer would actually consider.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/blogimages/three-episode-rule/P2a-real-dist-en.png&quot; alt=&quot;Empirical rating histogram of one series&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fig. 1.&lt;/strong&gt; The reward distribution of a single arm, taken directly from the published vote histogram. The mass is concentrated and left-skewed, and nothing about its shape was chosen.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/blogimages/three-episode-rule/P2b-bernoulli-en.png&quot; alt=&quot;A Bernoulli arm with the same mean&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fig. 2.&lt;/strong&gt; The textbook substitute: a Bernoulli arm with the same mean. It matches $\mu_i$ by construction and misrepresents everything else, including the variance that determines how many episodes a decision needs.&lt;/p&gt;
&lt;h2&gt;4. The objective is a threshold test, not best-arm identification&lt;/h2&gt;
&lt;p&gt;Classical MAB asks for $\arg\max_i \mu_i$. That is not what a viewer wants. The question is not which of a season&amp;#39;s shows is best, but whether each show, taken on its own, is &lt;strong&gt;good enough&lt;/strong&gt;. The model therefore fixes a personal bar $\theta$ — say $\theta = 7$ out of 10 — and evaluates every arm against $\theta$ rather than against the other arms.&lt;/p&gt;
&lt;p&gt;This is a change of objective, not of algorithm: the allocation is still uniform-then-commit, but what it is trying to get right is a per-arm classification rather than a maximisation. The setting is close to the &lt;strong&gt;Thresholding Bandit Problem&lt;/strong&gt; (TBP) of Locatelli &lt;em&gt;et al.&lt;/em&gt; [2], a fixed-budget pure-exploration problem in which the learner must return the set of arms whose means lie above a known threshold $\tau$, up to a precision $\varepsilon$. Their difficulty measure is&lt;/p&gt;
&lt;p&gt;$$
\Delta_i := |\mu_i - \tau| + \varepsilon, \qquad H := \sum_{i=1}^{K}\Delta_i^{-2},
$$&lt;/p&gt;
&lt;p&gt;and their algorithm, APT (Anytime Parameter-free Thresholding), attains a matching upper and lower bound on the &lt;strong&gt;probability of misclassification&lt;/strong&gt; — a 0–1 criterion over the returned set. The uniform-sampling baseline it is measured against is called Uniform Allocation (UA), which is precisely the allocation the folk rule performs.&lt;/p&gt;
&lt;p&gt;Two things separate the present setting from theirs.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Mistakes are not equally expensive.&lt;/strong&gt; APT is judged on whether the returned set is right at all, so every misclassification counts the same. Here the cost of a mistake scales with the gap: keeping a show far below the bar wastes more time than keeping one that barely misses it. The objective is therefore a weighted loss rather than an error probability.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The two error directions are asymmetric.&lt;/strong&gt; Watching additional episodes of a show &lt;em&gt;above&lt;/em&gt; the bar costs nothing — exploration and exploitation coincide on good arms. The only losses are (a) time spent on a show below the bar, and (b) the forfeited enjoyment of a good show dropped too early. There is no symmetric &amp;quot;regret of over-exploration&amp;quot; on the good side at all.&lt;/p&gt;
&lt;p&gt;Making this precise: after $m$ episodes the sample mean of arm $i$ has standard error $s_i = \sigma_i/\sqrt{m}$, and by the CLT the probability of each misclassification is a normal tail. Writing $d_i = \mu_i - \theta$, the expected season loss is&lt;/p&gt;
&lt;p&gt;$$
L(m)=\underbrace{\sum_{i:,d_i&amp;lt;0}(-d_i)\Big[,m+(E-m),\Phi!\big(d_i/s_i\big)\Big]}&lt;em&gt;{\text{time wasted on shows below the bar}};+;\underbrace{\sum_{i:,d_i&amp;gt;0}d_i,(E-m),\Phi!\big(-d_i/s_i\big)}&lt;/em&gt;{\text{enjoyment lost by dropping good shows}}
$$&lt;/p&gt;
&lt;p&gt;where $\Phi(d_i/s_i) = \Pr[\bar X_i \ge \theta]$ is the chance a below-bar show still looks acceptable after $m$ episodes, and $\Phi(-d_i/s_i)$ is the chance an above-bar show still looks unacceptable. The first term grows in $m$ (screening is itself expensive); the second falls in $m$ (more evidence, fewer good shows discarded). The optimum is&lt;/p&gt;
&lt;p&gt;$$
m^* = \arg\min_{1\le m\le E} L(m).
$$&lt;/p&gt;
&lt;p&gt;Note that $m$ is a single number shared by the whole season, not chosen per show. That constraint is not an approximation for tractability — it is what the folk rule actually is.&lt;/p&gt;
&lt;h2&gt;5. What the optimum turns out to be&lt;/h2&gt;
&lt;p&gt;For Spring 2025 at $\theta = 7$, the two terms cross and the total is minimised at $m^* = 2$.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/blogimages/three-episode-rule/P1a-loss-curves-en.png&quot; alt=&quot;Two loss terms and their sum against m&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fig. 3.&lt;/strong&gt; The two terms of $L(m)$ pull in opposite directions. Time wasted on shows below the bar rises with $m$; enjoyment lost to premature drops falls with it. The total has an interior minimum, here at $m^* = 2$, one episode earlier than the folk rule.&lt;/p&gt;
&lt;p&gt;Run over the fourteen most recent seasons, $m^*$ always lands between 1 and 3, and where it lands is determined by the bar. At a demanding bar the optimum moves earlier: the gaps $\Delta_i$ are larger for most arms, each episode is more informative, and less screening is needed. At a relaxed bar of $\theta = 6.5$ the optimum is &lt;strong&gt;exactly three&lt;/strong&gt;, in six of the fourteen seasons.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/blogimages/three-episode-rule/P1b-optimal-m-en.png&quot; alt=&quot;Distribution of optimal m over fourteen seasons at three bars&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fig. 4.&lt;/strong&gt; $m^*$ computed independently for each of the last fourteen seasons, at three values of the bar. The optimum never leaves ${1,2,3}$, and the bar alone decides where inside that range it falls.&lt;/p&gt;
&lt;p&gt;So the folk number is not arbitrary. It is the correct answer for a viewer who is easy to please, and it sits at the boundary of the optimal range for everyone else. What the community got wrong is not the number but its universality: three is a solution to one instance of the problem, presented as a solution to all of them.&lt;/p&gt;
&lt;h2&gt;6. Reintroducing the shared budget&lt;/h2&gt;
&lt;p&gt;The model so far has a structural gap. Each show is screened independently, its losses summed; nothing forces the arms to compete. Real viewing is not like that. Ten interesting shows at twelve episodes each is 120 episodes, roughly forty-eight hours in a three-month window, and few people have forty-eight hours to spend this way.&lt;/p&gt;
&lt;p&gt;Imposing a shared budget $B \ll KE$ restores the classical bandit: the arms now compete for a scarce resource, exploration genuinely trades off against exploitation, and the folk rule becomes one policy among several that can be compared on regret against the best-arm benchmark. This is also where the ETC label becomes exact rather than merely descriptive — the objective is now cumulative regret, which is what ETC is normally analysed against, so putting it beside UCB1 and Thompson Sampling is a fair comparison rather than an analogy. Crucially, &lt;strong&gt;the screening is paid for out of $B$&lt;/strong&gt; — running the folk rule with $m = 3$ over ten shows consumes 30 episodes before any exploitation begins.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Budget&lt;/th&gt;
&lt;th&gt;Thompson Sampling&lt;/th&gt;
&lt;th&gt;Folk rule ($m=3$)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;$B = 40$ (tight)&lt;/td&gt;
&lt;td&gt;16.1&lt;/td&gt;
&lt;td&gt;24.6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$B = 80$ (loose)&lt;/td&gt;
&lt;td&gt;13.5&lt;/td&gt;
&lt;td&gt;17.1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/blogimages/three-episode-rule/P3-budget-B40-en.png&quot; alt=&quot;Regret by policy at a budget of 40 episodes&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fig. 5.&lt;/strong&gt; Tight budget, $B = 40$. Screening ten shows for three episodes each consumes 30 of the 40 available, leaving almost nothing for exploitation, and the adaptive policies separate clearly.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/blogimages/three-episode-rule/P3-budget-B80-en.png&quot; alt=&quot;Regret by policy at a budget of 80 episodes&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fig. 6.&lt;/strong&gt; Loose budget, $B = 80$. The same fixed screening cost is now a quarter of the budget rather than three quarters, and the gap narrows sharply.&lt;/p&gt;
&lt;p&gt;At $B = 80$, watching everything without filtering loses 43.3 by the same measure, so every policy here beats no policy at all.&lt;/p&gt;
&lt;p&gt;The pattern is that the folk rule&amp;#39;s disadvantage is a function of scarcity. At $B = 40$ its fixed screening cost consumes three quarters of the budget and it loses badly. At $B = 80$ it has room to exploit what it found and closes most of the gap. &lt;strong&gt;The rule quietly assumes its user is not especially short of time&lt;/strong&gt; — an assumption that is invisible in the rule as stated, and false for exactly the viewers who most need a filtering heuristic.&lt;/p&gt;
&lt;h2&gt;7. Putting regret back on the ten-point scale&lt;/h2&gt;
&lt;p&gt;Cumulative regret over a season is awkward to interpret: 16.1 is not obviously good or bad. Since the reward is already a score out of ten, the natural rescaling is to divide by the budget. If a policy accumulates reward $R$ over $B$ episodes, its &lt;strong&gt;mean satisfaction per episode&lt;/strong&gt; is $R/B$, and regret converts directly:&lt;/p&gt;
&lt;p&gt;$$
\frac{R_{\text{policy}}}{B} ;=; \frac{R_{\text{oracle}}}{B} ;-; \frac{\mathrm{Regret}}{B}.
$$&lt;/p&gt;
&lt;p&gt;At $B = 40$ the oracle collects 7.733 per episode, so Thompson Sampling&amp;#39;s regret of 16.1 is a shortfall of $16.1/40 = 0.40$ points per episode, putting it at 7.33. Every quantity below is on that scale, and the whole comparison becomes a ladder:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Score per episode&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Best single show, $\mu_{\max}$&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8.17&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;not reachable at this budget&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Oracle at $B = 40$&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;7.73&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;the benchmark regret is measured against&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Thompson Sampling&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;7.33&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;best of the policies compared&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No filtering, watch all 120&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;6.88&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$=\overline{\mu}$&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Reading the gaps in order:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;6.88 → 7.33 = 0.45.&lt;/strong&gt; What filtering an entire season actually buys.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;7.33 → 7.73 = 0.40.&lt;/strong&gt; What a policy with perfect knowledge of every $\mu_i$ would gain on top. This is the real headroom left to any algorithm.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;7.73 → 8.17 = 0.44.&lt;/strong&gt; Unreachable at any budget, and not an algorithmic failure at all: the best show only &lt;em&gt;has&lt;/em&gt; twelve episodes, so 28 of the 40 must come from lower-rated shows however well they are chosen.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The distance from the best algorithm to $\mu_{\max}$ is 0.85 points, but &lt;strong&gt;roughly half of it is structural rather than learnable&lt;/strong&gt; — an artefact of a season being made of twelve-episode shows. The honest statement is the middle row: after all the filtering, a perfectly informed viewer would still beat the best algorithm by &lt;strong&gt;0.40 points per episode&lt;/strong&gt;, which is about the same size as everything filtering achieved in the first place.&lt;/p&gt;
&lt;p&gt;So the algorithms capture roughly half of what is available to them, and every one of them lands inside the same narrow band. A gap that all algorithms share, and that persists against an oracle with the same budget, is not an algorithmic problem. It is a property of the reward model, and the remainder of this post is about where it comes from.&lt;/p&gt;
&lt;h2&gt;8. Direction 1: the reward model assumes a single shared taste&lt;/h2&gt;
&lt;p&gt;Every reward above was sampled from the &lt;em&gt;public&lt;/em&gt; histogram. That embeds a strong assumption: that all viewers draw satisfaction from the same distribution, so that a show&amp;#39;s quality is a scalar property of the show. Under that assumption there is very little left for a bandit to discover — the ranking of the arms is already published on the website, and any policy that reads it starts at the optimum. This explains both the small size of the filtering gain and the failure of UCB1 and Thompson Sampling to separate from a fixed-$m$ rule: there is almost no information to acquire.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/blogimages/three-episode-rule/P6-personal-vs-site-en.png&quot; alt=&quot;Personal ratings against site averages&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fig. 7.&lt;/strong&gt; One viewer&amp;#39;s ratings against the site average, over 126 shows. Agreement on the raw scale hides substantial disagreement in the ordering, which is the only thing a bandit policy consumes.&lt;/p&gt;
&lt;p&gt;A single-viewer check gives the size of the effect. Across 126 shows rated by one viewer (the author), agreement with the site average is $r = 0.777$ on raw scores. But a bandit policy never uses raw scores — it uses the induced ordering, and there Spearman&amp;#39;s $\rho$ falls to $0.64$. Nineteen percent of those ratings differ from consensus by a full point or more, with a mean absolute deviation of 0.65.&lt;/p&gt;
&lt;p&gt;One viewer establishes only that the discrepancy exists, not its distribution. The site publishes each user&amp;#39;s own rating list, and collecting those at scale is a tooling problem that is already solved: &lt;code&gt;bgm-cli&lt;/code&gt; [3], a Node command-line client for Bangumi, reads subjects, users and per-user collections and emits JSON for direct use in an analysis pipeline. Extending the study over many viewers is therefore a question of sampling and consent rather than of engineering.&lt;/p&gt;
&lt;h2&gt;9. Direction 2: creators have a track record&lt;/h2&gt;
&lt;p&gt;The second direction starts from an observation about the arms themselves. A new series is not an unknown object: its studio, director, composer and writer have almost always made other shows, and those shows are already rated.&lt;/p&gt;
&lt;p&gt;Exploiting this &lt;em&gt;within&lt;/em&gt; a season would place the problem in the correlated-bandit framework of Gupta &lt;em&gt;et al.&lt;/em&gt; [4]. There, pulling arm $k$ and observing reward $r$ yields a pseudo-reward&lt;/p&gt;
&lt;p&gt;$$
s_{\ell,k}(r);\ge;\mathbb{E}\big[R_\ell \mid R_k = r\big]
$$&lt;/p&gt;
&lt;p&gt;which bounds every other arm and lets non-competitive arms be eliminated after $O(1)$ pulls instead of $O(\log T)$.&lt;/p&gt;
&lt;p&gt;Within a season the data does not support that route. Core creative roles are almost never shared — across the seasons examined, at most 2 of 45 same-season pairs share a director, writer or composer, for the obvious reason that one director cannot run two productions at once.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/blogimages/three-episode-rule/P4a-within-season-en.png&quot; alt=&quot;Shared core staff within a single season&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fig. 8.&lt;/strong&gt; Shared core creative roles between concurrently airing shows. There is essentially nothing to borrow inside one season, which is what rules out the correlated-arm route in its literal form.&lt;/p&gt;
&lt;p&gt;Widen the window and the structure is abundant. Of 80 shows examined, &lt;strong&gt;78 have at least one earlier release from the same studio&lt;/strong&gt; and 65 have one from the same director, with a median of 29 prior same-studio titles.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/blogimages/three-episode-rule/P4b-history-prior-en.png&quot; alt=&quot;Same-studio and same-director history per show&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fig. 9.&lt;/strong&gt; Counting backwards instead: how many earlier releases each show shares a studio or a director with. The distribution is dense, and it is entirely observed before the season opens.&lt;/p&gt;
&lt;p&gt;But those earlier shows are &lt;strong&gt;not arms in the current run&lt;/strong&gt;. They are already-observed history, fully rated before the season begins. Nothing is learned about them by pulling; no information travels between concurrent arms. This is therefore not arm-to-arm correlation. It is a &lt;strong&gt;prior on a new arm&lt;/strong&gt;, and it changes a different quantity: it does not alter $\Delta_i = |\mu_i - \theta|$, but it reduces the number of episodes needed to resolve the sign of $\Delta_i$.&lt;/p&gt;
&lt;p&gt;The natural home for it is a &lt;strong&gt;linear bandit&lt;/strong&gt;. Let $x_i \in \mathbb{R}^d$ encode the production features of series $i$ — studio, director, writer, composer — and let $\beta$ be the viewer&amp;#39;s taste vector over those features, shared across all arms and all seasons:&lt;/p&gt;
&lt;p&gt;$$
\mathbb{E}[r_{i,t}] = \langle x_i,, \beta\rangle .
$$&lt;/p&gt;
&lt;p&gt;A viewer&amp;#39;s rating history is a set of observations of $\beta$, not of any particular arm. A new series is then a new feature vector rather than a new unknown, and a LinUCB-style policy inherits the whole back catalogue as a warm start. This also unifies the two directions: $\beta$ is precisely &amp;quot;individual taste&amp;quot; from §8, given a parametric form.&lt;/p&gt;
&lt;p&gt;Both routes require the same thing that this study did not have — &lt;strong&gt;per-viewer joint ratings&lt;/strong&gt; rather than aggregate histograms. A pseudo-reward table has to be estimated from viewers who rated both arms; a taste vector $\beta$ has to be fit per viewer. That is the next measurement, and the only real prerequisite for either direction.&lt;/p&gt;
&lt;h2&gt;10. Summary&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;The three-episode rule is a uniform-then-commit allocation, which makes it testable rather than merely repeatable. Whether that allocation is called &lt;em&gt;uniform allocation&lt;/em&gt; or &lt;em&gt;ETC&lt;/em&gt; depends on the objective it is serving, and the two objectives appear at different points in this analysis.&lt;/li&gt;
&lt;li&gt;The right objective is a threshold test against a personal bar, with an asymmetric, gap-weighted loss — close to the Thresholding Bandit Problem [2], but scored by a weighted loss rather than by probability of misclassification.&lt;/li&gt;
&lt;li&gt;Under that loss the optimum is $m^* \in {1,2,3}$, determined by the bar. Three is correct for an undemanding viewer and too slow for everyone else.&lt;/li&gt;
&lt;li&gt;Once a shared time budget is imposed, the rule&amp;#39;s fixed screening cost makes it clearly worse than UCB1 or Thompson Sampling when time is scarce, and nearly competitive when it is not.&lt;/li&gt;
&lt;li&gt;On a per-episode scale, filtering a season buys 0.45 points, a perfectly informed viewer at the same budget would gain only 0.40 more, and a further 0.44 is structurally out of reach because each show has just twelve episodes. Every algorithm lands in the same narrow band, which points at the reward model rather than at the policies.&lt;/li&gt;
&lt;li&gt;Modelling taste as a per-viewer parameter over production features turns the back catalogue into a prior and places the problem in the linear-bandit setting.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The parsing, analysis and plotting code is &lt;a href=&quot;https://gist.github.com/aronnaxlin/d88f367e44440e5f5c7ea4c9e0e1b9db&quot;&gt;on GitHub&lt;/a&gt;. It reads the official archive directly, so every number and figure above can be reproduced from the snapshot named in [1].&lt;/p&gt;
&lt;div class=&quot;references&quot;&gt;&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1] Bangumi, &amp;quot;bangumi/Archive: periodic data export of bangumi.tv.&amp;quot; [Online]. Available: &lt;a href=&quot;https://github.com/bangumi/Archive&quot;&gt;https://github.com/bangumi/Archive&lt;/a&gt;. Weekly release, Wednesdays 05:00 GMT+8. Snapshot used: &lt;code&gt;dump-2026-08-18&lt;/code&gt;, file &lt;code&gt;subject.jsonlines&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;[2] A. Locatelli, M. Gutzeit, and A. Carpentier, &amp;quot;An optimal algorithm for the thresholding bandit problem,&amp;quot; in &lt;em&gt;Proc. 33rd Int. Conf. Machine Learning (ICML)&lt;/em&gt;, New York, NY, USA, 2016, vol. 48, pp. 1690–1698.&lt;/p&gt;
&lt;p&gt;[3] Aronnax, &amp;quot;bgm-cli: a command-line client for Bangumi,&amp;quot; AGPL-3.0. [Online]. Available: &lt;a href=&quot;https://github.com/aronnaxlin/bgm-cli&quot;&gt;https://github.com/aronnaxlin/bgm-cli&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[4] S. Gupta, S. Chaudhari, G. Joshi, and O. Yağan, &amp;quot;Multi-armed bandits with correlated arms,&amp;quot; &lt;em&gt;IEEE Trans. Inf. Theory&lt;/em&gt;, vol. 67, no. 10, pp. 6711–6732, Oct. 2021, doi: 10.1109/TIT.2021.3081508.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div data-lang=&quot;zh&quot;&gt;&lt;h2&gt;1. 三话定律是什么&lt;/h2&gt;
&lt;p&gt;日本动画按季度播出。每三个月，三十到五十部新番同时开播，绝大多数是十二集的周更。一个同时追好几部的观众，必须反复地、而且是尽早地决定：哪些接着看，哪些放弃。&lt;/p&gt;
&lt;p&gt;圈子里的答案是一条没人写下来、却几乎人人遵守的规矩：先看三话，再决定是追下去还是弃掉。通常的理由是，一部番往往要到第二或第三话才交出真正的设定，只看一话证据不足。&lt;/p&gt;
&lt;p&gt;对一个决策问题来说，&amp;quot;三&amp;quot;是个可疑地整齐的数字。而这条规矩的结构非常明确：每条臂固定探索若干次，然后做出不可撤销的承诺，这正是 Explore-Then-Commit（先探索后承诺，下称 ETC）策略的形状。既然如此，这个数字就可以被检验。&lt;/p&gt;
&lt;h2&gt;2. 写成老虎机问题&lt;/h2&gt;
&lt;p&gt;取一个播出季度，把当季同时开播的 $K$ 部番作为臂（arm）。拉动臂 $i$ 表示看一集第 $i$ 部番，奖励是观众对这一集的满意度，取值在 ${1,\dots,10}$。记 $\mu_i$ 为第 $i$ 部番的真实平均质量，$E = 12$ 为集数。&lt;/p&gt;
&lt;p&gt;在这个映射下，三话定律具有 $m = 3$ 的 ETC 形状：每条臂采样 $m$ 次，然后对留下来的臂在剩余 $E - m$ 集里执行到底。问题是 $m^*$ 是否真的等于 3。&lt;/p&gt;
&lt;p&gt;有两件事需要先分开，因为后文会在两者之间来回移动。ETC 描述的是一种&lt;strong&gt;分配方式&lt;/strong&gt;（allocation）：均匀探索，然后不可撤销地决定。它并不规定这个决定是为了什么。三话定律借用了这个分配方式，但它服务的&lt;strong&gt;目标&lt;/strong&gt;（objective）和 ETC 通常被分析时所针对的目标不同，第 4 节会把这个目标写清楚。在阈值目标下，同样的&amp;quot;先均匀采样再承诺&amp;quot;在纯探索文献里叫均匀分配（Uniform Allocation, UA）；ETC 这个名字要到第 6 节、共享预算把问题变回累积遗憾最小化时，才重新变得严格。&lt;/p&gt;
&lt;h2&gt;3. 数据从哪来&lt;/h2&gt;
&lt;p&gt;所有奖励来自 &lt;a href=&quot;https://bangumi.tv&quot;&gt;bangumi.tv&lt;/a&gt;，中文圈最大的动画数据库，经由 &lt;em&gt;bangumi/Archive&lt;/em&gt; [1] 获取。那是站方自己的定期数据导出，每周通过 GitHub Releases 发布，目的正是让这类项目不必去爬站。&lt;strong&gt;本文没有抓取任何数据&lt;/strong&gt;，全程使用的是 2026-08-18 那一次快照。&lt;/p&gt;
&lt;p&gt;该导出按实体类型各给一个 JSON-lines 文件。这里只用到 &lt;code&gt;subject.jsonlines&lt;/code&gt;，筛选条件为 &lt;code&gt;type = 2&lt;/code&gt;（动画）且 &lt;code&gt;platform = TV&lt;/code&gt;。每条记录都带着复现实验所需的字段：&lt;code&gt;id&lt;/code&gt;、&lt;code&gt;name&lt;/code&gt;、&lt;code&gt;date&lt;/code&gt;、&lt;code&gt;platform&lt;/code&gt;、&lt;code&gt;eps&lt;/code&gt;、&lt;code&gt;tags&lt;/code&gt;、&lt;code&gt;score&lt;/code&gt;、&lt;code&gt;rank&lt;/code&gt;，以及最关键的 &lt;code&gt;score_details&lt;/code&gt;，也就是完整的一到十分评分直方图，而不只是一个平均分。&lt;/p&gt;
&lt;p&gt;正是最后这个字段让整项研究免于建模假设。奖励直接从真实投票的经验分布中采样，因此不需要对臂做任何参数假定，伯努利、高斯、有界次高斯都不用。下文用到的每条臂的均值与标准差，就是该直方图的矩：&lt;/p&gt;
&lt;p&gt;$$
\mu_i=\frac{1}{N_i}\sum_{v=1}^{10} v,n_{i,v},\qquad \sigma_i^2=\frac{1}{N_i}\sum_{v=1}^{10}(v-\mu_i)^2 n_{i,v},
$$&lt;/p&gt;
&lt;p&gt;其中 $n_{i,v}$ 是打 $v$ 分的票数，$N_i=\sum_v n_{i,v}$。投票数少于 100 的作品被剔除；每个季度只取投票数最高的十部，这大致就是一个观众实际会考虑的数量。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/blogimages/three-episode-rule/P2a-real-dist-en.png&quot; alt=&quot;某部番的真实评分直方图&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;图 1.&lt;/strong&gt; 单条臂的奖励分布，直接取自公开的投票直方图。质量集中且左偏，其形状不是任何人选定的。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/blogimages/three-episode-rule/P2b-bernoulli-en.png&quot; alt=&quot;同均值的伯努利臂&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;图 2.&lt;/strong&gt; 教科书里的替身：一条与之同均值的伯努利臂。它按构造对上了 $\mu_i$，却错报了其余的一切，包括决定&amp;quot;判断需要几集&amp;quot;的那个方差。&lt;/p&gt;
&lt;h2&gt;4. 判的是每部番够不够线&lt;/h2&gt;
&lt;p&gt;经典多臂老虎机要找的是 $\arg\max_i \mu_i$。但观众要的不是这个。真正的问题是每一部番单独拿出来，够不够得上标准。为此，模型设定一条个人标准线 $\theta$，比如十分制下的 7 分，然后拿每条臂去和 $\theta$ 比，不和其他臂比。&lt;/p&gt;
&lt;p&gt;换掉的是目标，不是算法：分配方式仍然是先均匀采样再承诺，只是它要做对的事情从&amp;quot;最大化&amp;quot;变成了&amp;quot;逐臂分类&amp;quot;。这个设定接近 Locatelli 等人 [2] 的 &lt;strong&gt;Thresholding Bandit Problem&lt;/strong&gt;（TBP），一个固定预算的纯探索问题，学习者需要在精度 $\varepsilon$ 之内，返回均值高于已知阈值 $\tau$ 的那些臂。其难度度量为&lt;/p&gt;
&lt;p&gt;$$
\Delta_i := |\mu_i - \tau| + \varepsilon, \qquad H := \sum_{i=1}^{K}\Delta_i^{-2},
$$&lt;/p&gt;
&lt;p&gt;他们提出的算法 APT（Anytime Parameter-free Thresholding）在&lt;strong&gt;误判概率&lt;/strong&gt;这一指标上取得了相互匹配的上下界，那是一个针对返回集合的 0–1 判据。它所对照的均匀采样基线，原文就称为 Uniform Allocation（UA），而这恰恰就是三话定律所执行的那种分配方式。&lt;/p&gt;
&lt;p&gt;本文的设定与之有两处不同。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;判错的代价不相等。&lt;/strong&gt; APT 衡量的是返回集合对不对，因此每一次误判都一样重。而在这里，代价随间隔放大：留下一部远低于标准线的番，比留下一部只差一点点的番，浪费的时间更多。这里的目标因此是一个加权损失，不是一个误判概率。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;两个方向的错误不对称。&lt;/strong&gt; 对一部高于标准线的番，多看几集完全不花代价，在好的臂上探索和利用是同一件事。真正的损失只有两种：花在低于标准线的番上的时间，以及过早弃掉一部好番所放弃的享受。在好的一侧，根本不存在&amp;quot;探索过度&amp;quot;这种对称的遗憾。&lt;/p&gt;
&lt;p&gt;把它写精确。看过 $m$ 集之后，臂 $i$ 的样本均值标准误为 $s_i = \sigma_i/\sqrt{m}$，由中心极限定理，两类误判的概率都是正态尾概率。记 $d_i = \mu_i - \theta$，则整季的期望损失为&lt;/p&gt;
&lt;p&gt;$$
L(m)=\underbrace{\sum_{i:,d_i&amp;lt;0}(-d_i)\Big[,m+(E-m),\Phi!\big(d_i/s_i\big)\Big]}&lt;em&gt;{\text{浪费在低于标准线的番上的分数}};+;\underbrace{\sum_{i:,d_i&amp;gt;0}d_i,(E-m),\Phi!\big(-d_i/s_i\big)}&lt;/em&gt;{\text{因过早弃番而丢掉的分数}}
$$&lt;/p&gt;
&lt;p&gt;其中 $\Phi(d_i/s_i) = \Pr[\bar X_i \ge \theta]$ 是一部低于标准线的番在 $m$ 集之后看上去仍然合格的概率，$\Phi(-d_i/s_i)$ 则是一部高于标准线的番在 $m$ 集之后看上去仍然不合格的概率。第一项随 $m$ 递增，因为筛选本身要花时间；第二项随 $m$ 递减，因为证据更多、误弃更少。最优解为&lt;/p&gt;
&lt;p&gt;$$
m^* = \arg\min_{1\le m\le E} L(m).
$$&lt;/p&gt;
&lt;p&gt;这里的 $m$ 是整季共用的一个数字，不是逐番选择的。这个约束不是为了求解方便而做的近似，三话定律本来就是这样一条规矩。&lt;/p&gt;
&lt;h2&gt;5. 最优的 m 是几&lt;/h2&gt;
&lt;p&gt;在 2025 年春季、$\theta = 7$ 的设定下，两项损失在中间交叉，总和的最小值落在 $m^* = 2$。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/blogimages/three-episode-rule/P1a-loss-curves-en.png&quot; alt=&quot;两项损失与总和随 m 的变化&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;图 3.&lt;/strong&gt; $L(m)$ 的两项朝相反方向拉扯。浪费在低于标准线的番上的时间随 $m$ 上升，因过早弃番丢掉的享受随 $m$ 下降。总和存在内部极小，此处为 $m^* = 2$，比民间规矩早一集。&lt;/p&gt;
&lt;p&gt;把它放到最近十四个季度上跑，$m^*$ 始终落在 1 到 3 之间，而具体落在哪里，只取决于那条线的高低。标准越严，最优点越靠前：此时大多数臂的间隔更大，每一集携带的信息量更高，需要的筛选就更少。而在 $\theta = 6.5$ 这样一条宽松的线上，最优解恰好就是三，十四个季度里有六个落在这里。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/blogimages/three-episode-rule/P1b-optimal-m-en.png&quot; alt=&quot;十四个季度、三条标准线下的最优 m 分布&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;图 4.&lt;/strong&gt; 对最近十四个季度分别独立计算的 $m^*$，取三种标准线。最优值从未离开 ${1,2,3}$，而落在这个区间的哪一点，只由标准线决定。&lt;/p&gt;
&lt;p&gt;所以这个民间数字并不是凭空来的。对一个要求不高的观众，三就是正确答案；对其余人，它也停在最优区间的边缘上。圈子搞错的是它的普适性：三是这个问题某一个实例的解，却被当成了所有实例的解。&lt;/p&gt;
&lt;h2&gt;6. 加上时间预算之后&lt;/h2&gt;
&lt;p&gt;到这里为止，模型有一个结构性的缺口。每部番各自筛选、损失各自累加，没有任何东西迫使这些臂互相竞争。而真实的观看不是这样：十部感兴趣的番、每部十二集，就是 120 集，在三个月里大约四十八小时，很少有人拿得出这四十八小时。&lt;/p&gt;
&lt;p&gt;加上一个共享预算 $B \ll KE$，经典的老虎机问题就回来了：臂现在要争夺一项稀缺资源，探索与利用之间产生了真正的取舍，三话定律也就成了若干可比策略中的一个，可以在&amp;quot;对最优臂的遗憾&amp;quot;这个尺度上被衡量。这里也正是 ETC 这个称呼从描述性变为严格的地方：目标现在是累积遗憾，而这正是 ETC 通常被分析的对象，所以把它和 UCB1、Thompson Sampling 摆在一起比较是公平的，不是打个比方。&lt;/p&gt;
&lt;p&gt;另外有一点很关键：&lt;strong&gt;筛选本身是从 $B$ 里出的&lt;/strong&gt;。用 $m = 3$ 跑十部番，在开始利用之前就已经消耗了 30 集。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;时间预算&lt;/th&gt;
&lt;th&gt;Thompson Sampling&lt;/th&gt;
&lt;th&gt;三话定律（$m=3$）&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;$B = 40$（紧）&lt;/td&gt;
&lt;td&gt;16.1&lt;/td&gt;
&lt;td&gt;24.6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$B = 80$（松）&lt;/td&gt;
&lt;td&gt;13.5&lt;/td&gt;
&lt;td&gt;17.1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/blogimages/three-episode-rule/P3-budget-B40-en.png&quot; alt=&quot;预算 40 集时各策略的遗憾&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;图 5.&lt;/strong&gt; 紧预算，$B = 40$。十部番各筛三集就要吃掉 40 集里的 30 集，几乎不剩利用的余地，自适应策略因此明显拉开。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/blogimages/three-episode-rule/P3-budget-B80-en.png&quot; alt=&quot;预算 80 集时各策略的遗憾&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;图 6.&lt;/strong&gt; 松预算，$B = 80$。同样的固定筛选开销现在只占四分之一而不是四分之三，差距迅速收窄。&lt;/p&gt;
&lt;p&gt;在 $B = 80$ 下，完全不筛选、把 120 集全看完，在同一尺度上损失 43.3。所以任何策略都好过没有策略。&lt;/p&gt;
&lt;p&gt;规律是：三话定律的劣势是稀缺程度的函数。在 $B = 40$ 时，它固定的筛选开销吃掉了四分之三的预算，输得很难看；在 $B = 80$ 时，它有余地去利用筛出来的结果，差距被抹平了大半。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;这条规矩默默假设了它的使用者并不特别缺时间。&lt;/strong&gt; 这个假设在规矩的表述里完全看不见，而且恰恰对那些最需要筛选启发式的观众不成立。&lt;/p&gt;
&lt;h2&gt;7. 把遗憾换算成每集得分&lt;/h2&gt;
&lt;p&gt;整季的累积遗憾本身不好读：16.1 究竟算好还是算差，看不出来。既然奖励本来就是十分制的分数，自然的换算就是除以预算。若某策略在 $B$ 集里累计奖励 $R$，则它的每集平均满意度为 $R/B$，而遗憾可以直接换算：&lt;/p&gt;
&lt;p&gt;$$
\frac{R_{\text{policy}}}{B} ;=; \frac{R_{\text{oracle}}}{B} ;-; \frac{\mathrm{Regret}}{B}.
$$&lt;/p&gt;
&lt;p&gt;$B = 40$ 时先知每集拿到 7.733 分，因此 Thompson Sampling 那 16.1 的遗憾就是每集少 $16.1/40 = 0.40$ 分，落在 7.33。下面所有数字都在这个尺度上，整个比较变成一道阶梯：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;每集得分&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;最好的单部番，$\mu_{\max}$&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8.17&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;该预算下不可达&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$B = 40$ 的先知&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;7.73&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;遗憾真正对照的基准&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Thompson Sampling&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;7.33&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;参与比较的策略中最好的&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;完全不筛选，120 集全看&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;6.88&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$=\overline{\mu}$&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;逐段来读这几个差距：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;6.88 → 7.33 = 0.45。&lt;/strong&gt; 筛选整整一季实际买到的东西。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;7.33 → 7.73 = 0.40。&lt;/strong&gt; 一个完全知道每个 $\mu_i$ 的策略还能额外拿到的部分。这才是留给任何算法的真实空间。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;7.73 → 8.17 = 0.44。&lt;/strong&gt; 任何预算下都拿不到，而且根本不是算法的失败：最好那部番只有十二集，所以 40 集里必有 28 集得从评分更低的番里出，无论怎么选都一样。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;最后这一行值得留意，因为那个醒目的数字很容易被误读。最好的算法距离 $\mu_{\max}$ 是 0.85 分，但其中大约一半是结构性的，不是可学习的，它只是&amp;quot;一季由十二集的番构成&amp;quot;这一事实的产物。诚实的说法是中间那一行：&lt;strong&gt;在所有筛选之后，一个完全知情的观众也只比最好的算法每集多拿 0.40 分，而这与筛选本身买到的 0.45 分差不多大。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;所以算法拿到了可及范围里的大约一半，而且每一个都落在同一条窄带里。一道所有算法共有、并且在同等预算的先知面前依然存在的差距，指向的是奖励模型，本文剩下的部分就是在追问它从哪来。&lt;/p&gt;
&lt;h2&gt;8. 出路一：口味不是所有人共享的&lt;/h2&gt;
&lt;p&gt;上面每一个数字，都是从公共直方图里采样出来的。这里嵌着一个很强的假设：所有观众的满意度服从同一个分布，因而&amp;quot;质量&amp;quot;是番本身的一个标量属性。在那个世界里，老虎机几乎无事可做，因为臂的排序早就公布在网站上了，任何读一眼排行榜的策略都从最优点出发。这同时解释了两件事：筛选带来的收益为什么这么小，以及 UCB1 和 Thompson Sampling 为什么拉不开与固定 $m$ 的差距。&lt;strong&gt;可获取的信息本来就所剩无几。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/blogimages/three-episode-rule/P6-personal-vs-site-en.png&quot; alt=&quot;个人评分与站点均分的对照&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;图 7.&lt;/strong&gt; 一位观众在 126 部番上的评分与站点均分的对照。原始分数上的一致掩盖了排序上的大量分歧，而排序恰恰是老虎机策略唯一消费的东西。&lt;/p&gt;
&lt;p&gt;用单个观众的数据可以看出这种偏离有多大。以某一位观众（本文作者）评过分的 126 部番为例，与站点均分在原始分数上的相关为 $r = 0.777$。但老虎机策略从不使用原始分数，它使用的是由分数诱导出的&lt;strong&gt;排序&lt;/strong&gt;，而在排序上，Spearman 相关降到了 $\rho = 0.64$。其中 19.0% 的评分与大众相差一整分以上，平均绝对偏差为 0.65 分。&lt;/p&gt;
&lt;p&gt;一个人只能说明这种偏离存在，说明不了它的分布。而这个站点会公开每个用户自己的评分列表，把它们批量取回在工具层面已经解决了：&lt;code&gt;bgm-cli&lt;/code&gt; [3] 是一个 Node 写的 Bangumi 命令行客户端，可以读取条目、用户与逐用户收藏，并输出 JSON 直接进入分析管线。把研究推广到多用户，剩下的是采样与授权的问题。&lt;/p&gt;
&lt;h2&gt;9. 出路二：创作者的往绩可以当先验&lt;/h2&gt;
&lt;p&gt;第二个方向从臂本身的性质出发。一部新番并不是一个未知的物体：它的制作公司、导演、音乐、脚本几乎总是做过别的作品，而那些作品早就被打过分了。&lt;/p&gt;
&lt;p&gt;若要在同一季度内部利用这一点，问题就会落进 Gupta 等人 [4] 的相关臂框架。在那里，拉动臂 $k$ 并观测到奖励 $r$ 之后，可以给出伪奖励（pseudo-reward）&lt;/p&gt;
&lt;p&gt;$$
s_{\ell,k}(r);\ge;\mathbb{E}\big[R_\ell \mid R_k = r\big]
$$&lt;/p&gt;
&lt;p&gt;它为其余每条臂给出上界，使得非竞争臂只需 $O(1)$ 次拉动即可淘汰，而不是 $O(\log T)$ 次。&lt;/p&gt;
&lt;p&gt;但在季度内部，数据不支持这条路。核心创作岗位几乎从不重合：在考察的各季度中，同季 45 个配对里最多只有 2 对共享导演、脚本或音乐，原因很直白，一个导演没法同时带两部片。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/blogimages/three-episode-rule/P4a-within-season-en.png&quot; alt=&quot;同季度内部的主创重合情况&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;图 8.&lt;/strong&gt; 同期播出的番之间核心创作岗位的重合。一季内部基本无可借用，这正是相关臂那条路在字面意义上走不通的原因。&lt;/p&gt;
&lt;p&gt;把窗口放宽，结构立刻变得稠密。在考察的 80 部番中，&lt;strong&gt;78 部至少有一部同公司的前作&lt;/strong&gt;，65 部有同导演的前作，同公司前作数量的中位数是 29 部。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/blogimages/three-episode-rule/P4b-history-prior-en.png&quot; alt=&quot;每部番的同公司 / 同导演前作数量&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;图 9.&lt;/strong&gt; 反过来往回数：每部番与多少部更早的作品共享公司或导演。分布相当稠密，而且这些信息在开季之前就已经全部被观测到了。&lt;/p&gt;
&lt;p&gt;问题在于，那些前作并不是本轮的臂。它们是已经观测完毕的历史，在这一季开始之前就已经全部有分。拉臂不会让人对它们知道得更多，也没有任何信息在同期的臂之间流动。&lt;strong&gt;所以这是新臂上的先验（prior），不是臂间相关。&lt;/strong&gt; 它改变的也是另一个量：它不改变 $\Delta_i = |\mu_i - \theta|$，它减少的是判定 $\Delta_i$ 符号所需要的集数。&lt;/p&gt;
&lt;p&gt;它天然的归宿是&lt;strong&gt;线性老虎机&lt;/strong&gt;（linear bandit）。令 $x_i \in \mathbb{R}^d$ 编码第 $i$ 部番的制作特征，包括公司、导演、脚本、音乐；再令 $\beta$ 为这位观众在这些特征上的口味向量，跨所有臂、所有季度共享：&lt;/p&gt;
&lt;p&gt;$$
\mathbb{E}[r_{i,t}] = \langle x_i,, \beta\rangle .
$$&lt;/p&gt;
&lt;p&gt;这样一来，一位观众的历史评分就是对 $\beta$ 的一组观测，而不是对某一条具体臂的观测。一部新番于是只是一个新的特征向量，LinUCB 一类的策略可以把整个片库当作热启动。&lt;/p&gt;
&lt;p&gt;这个形式还把两个方向合并了：$\beta$ 正是第 8 节说的&amp;quot;个人口味&amp;quot;，只不过给了它一个参数形式。&lt;/p&gt;
&lt;p&gt;两条路都需要同一样本研究没有的东西：逐用户的联合评分，而不是聚合直方图。伪奖励表必须由&amp;quot;同时评过两条臂&amp;quot;的用户估计出来；口味向量 $\beta$ 必须逐用户拟合。这是下一步要做的测量，也是两个方向唯一真正的前置条件。&lt;/p&gt;
&lt;h2&gt;10. 小结&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;三话定律是一种&amp;quot;先均匀采样再承诺&amp;quot;的分配方式，因而它可以被检验。至于它该叫均匀分配还是 ETC，取决于它服务的目标，而这两个目标在本文的不同位置出现。&lt;/li&gt;
&lt;li&gt;正确的目标是对一条个人标准线的阈值判定，损失是不对称的、按间隔加权的。这接近 Thresholding Bandit Problem [2]，但它的判据是加权损失，而非误判概率。&lt;/li&gt;
&lt;li&gt;在这个损失下，最优解是 $m^* \in {1,2,3}$，由那条线决定。三对一个要求不高的观众是对的，对其他所有人都太慢。&lt;/li&gt;
&lt;li&gt;一旦加上共享的时间预算，固定的筛选开销会让它在时间紧张时明显劣于 UCB1 和 Thompson Sampling，而在时间宽裕时接近持平。&lt;/li&gt;
&lt;li&gt;换算到每集得分：筛选一季买到 0.45 分，同等预算下完全知情的观众也只能再多拿 0.40 分，另有 0.44 分因为每部番只有十二集而结构性地不可达。所有算法都落在同一条窄带里，这指向奖励模型。&lt;/li&gt;
&lt;li&gt;把口味建模成制作特征上的逐用户参数，可以把整个片库变成先验，并把问题放进线性老虎机的框架。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;解析、分析与画图的代码&lt;a href=&quot;https://gist.github.com/aronnaxlin/d88f367e44440e5f5c7ea4c9e0e1b9db&quot;&gt;在 GitHub 上&lt;/a&gt;。它直接读官方归档，所以上文每一个数字和每一张图都能从 [1] 里那份快照复现。&lt;/p&gt;
&lt;div class=&quot;references&quot;&gt;&lt;h2&gt;参考文献&lt;/h2&gt;
&lt;p&gt;[1] Bangumi, &amp;quot;bangumi/Archive: periodic data export of bangumi.tv.&amp;quot; [Online]. Available: &lt;a href=&quot;https://github.com/bangumi/Archive&quot;&gt;https://github.com/bangumi/Archive&lt;/a&gt;. 每周三 05:00 GMT+8 发布。本文使用快照：&lt;code&gt;dump-2026-08-18&lt;/code&gt;，文件 &lt;code&gt;subject.jsonlines&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;[2] A. Locatelli, M. Gutzeit, and A. Carpentier, &amp;quot;An optimal algorithm for the thresholding bandit problem,&amp;quot; in &lt;em&gt;Proc. 33rd Int. Conf. Machine Learning (ICML)&lt;/em&gt;, New York, NY, USA, 2016, vol. 48, pp. 1690–1698.&lt;/p&gt;
&lt;p&gt;[3] Aronnax, &amp;quot;bgm-cli: a command-line client for Bangumi,&amp;quot; AGPL-3.0. [Online]. Available: &lt;a href=&quot;https://github.com/aronnaxlin/bgm-cli&quot;&gt;https://github.com/aronnaxlin/bgm-cli&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[4] S. Gupta, S. Chaudhari, G. Joshi, and O. Yağan, &amp;quot;Multi-armed bandits with correlated arms,&amp;quot; &lt;em&gt;IEEE Trans. Inf. Theory&lt;/em&gt;, vol. 67, no. 10, pp. 6711–6732, Oct. 2021, doi: 10.1109/TIT.2021.3081508.&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;</content:encoded></item><item><title>看不懂的那些视频，我给它们配了个实时双语字幕</title><link>https://aronnax.site/blog/swiftvolccaption_release/</link><guid isPermaLink="true">https://aronnax.site/blog/swiftvolccaption_release/</guid><description>SwiftVolcCaption：基于 macOS 原生 CoreAudio Process Tap 与火山引擎同传大模型的实时双语字幕工具，无需虚拟声卡。</description><pubDate>Mon, 03 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;🔗 &lt;strong&gt;GitHub 仓库地址&lt;/strong&gt;：&lt;a href=&quot;https://github.com/aronnaxlin/SwiftVolcCaption&quot;&gt;https://github.com/aronnaxlin/SwiftVolcCaption&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;最近又由自身需求触发造了一个小轮子：&lt;strong&gt;SwiftVolcCaption&lt;/strong&gt;。&lt;/p&gt;
&lt;h2&gt;能干嘛？&lt;/h2&gt;
&lt;p&gt;说起来很简单：把你电脑&lt;strong&gt;正在放的声音&lt;/strong&gt;抓下来，实时变成「原文 + 译文」两行字幕，浮在屏幕上。&lt;/p&gt;
&lt;p&gt;不管声音是从浏览器、播放器还是会议软件里出来的，它都能抓。&lt;/p&gt;
&lt;p&gt;&lt;video src=&quot;/blog-images/swiftvolccaption/demo1-f.mp4&quot; autoplay loop muted playsinline style=&quot;width:100%;border-radius:0.75rem;margin:0 auto;&quot;&gt;&lt;/video&gt;&lt;/p&gt;
&lt;div align=&quot;center&quot; style=&quot;color: #999; font-size: 0.85em;&quot;&gt;实时双语字幕效果&lt;/div&gt;&lt;h2&gt;为什么做这个？&lt;/h2&gt;
&lt;p&gt;这两年由于个人的规划，我的外语视频或音频逐年增加，锻炼听力诚然是一种办法，但是对于现在的我来说，借助字幕无疑能让我更专注于要干的事，而不是开「双线程」。&lt;/p&gt;
&lt;p&gt;一开始是看熟肉视频，但是发现认真被汉化过的视频只占一小部分，而且如果不是授权翻译的话，在 B 站看其实也算损害了原创作者的权利。&lt;/p&gt;
&lt;p&gt;后来发现了 YouTube 的自动字幕，但是机翻质量加上一个字一个字往出蹦体验几乎全无，还不如只开纯英文字幕（当然，由于海外博主基本上不会去加 CC 字幕，纯英文字幕也是一个字一个字往出蹦）。&lt;/p&gt;
&lt;p&gt;再后面有了「沉浸式翻译」、「Kiss Translator」这种浏览器插件/脚本，算是基本解决了问题。&lt;/p&gt;
&lt;p&gt;直到我遇见了&lt;strong&gt;非浏览器环境 + 直播&lt;/strong&gt;这一难关。&lt;/p&gt;
&lt;p&gt;其实用 Windows 时，我找到了别人的解决方案。一年前想要玩一款名为 &lt;em&gt;Whispers from the Star&lt;/em&gt; 的游戏，这款游戏算是全球第一款和 AI 实时互动的游戏，不过游戏本身不是什么问题，最大的问题在于它当时只支持英文，还没有英文字幕和翻译。当时听力水平不太好的我选择了 &lt;a href=&quot;https://github.com/SakiRinn/LiveCaptions-Translator&quot;&gt;LiveCaptions-Translator&lt;/a&gt; 解决了问题，这款软件基于 Windows 原生实时字幕 + 大模型 API 解决了问题。&lt;/p&gt;
&lt;p&gt;本以为就这么过去了，没想到最近我的主要环境来到了 macOS，还要开始上一门外方教授的直播课程。上述的软件依赖的是 Windows 的功能所以并不能在 Mac 上使用。macOS 诚然也提供了实时字幕功能，市面上也确实有几个同类的项目，但都在某个地方卡住了我：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;有的用 Apple Intelligence 做翻译引擎，国行根本没这个功能；&lt;/li&gt;
&lt;li&gt;有的很久没更新了，所以用不了 AI 翻译，精度不佳；&lt;/li&gt;
&lt;li&gt;还有相当一部分——这是最劝退的——要你先装一个叫 BlackHole 的虚拟声卡。而我有一堆蓝牙耳机，之前试过的虚拟声卡没一个省心的，为了字幕把各类音频设备整成一锅粥实在不划算。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以调研了一番后，我开始了又一次的 Vibe Coding 造轮子：用 macOS 原生 API 音频旁路功能 + 火山引擎同传大模型，做了这个 macOS 原生双语字幕软件 —— SwiftVolcCaption。&lt;/p&gt;
&lt;h2&gt;长什么样&lt;/h2&gt;
&lt;p&gt;菜单栏一个小气泡图标，点开就是全部功能。正在识别的时候图标会变成实心的，一眼能看出状态。&lt;/p&gt;
&lt;p&gt;&lt;video src=&quot;/blog-images/swiftvolccaption/demo2.mp4&quot; autoplay loop muted playsinline style=&quot;width:100%;border-radius:0.75rem;margin:0 auto;&quot;&gt;&lt;/video&gt;&lt;/p&gt;
&lt;div align=&quot;center&quot; style=&quot;color: #999; font-size: 0.85em;&quot;&gt;菜单栏入口&lt;/div&gt;&lt;p&gt;字幕窗浮在最上层，压得住全屏视频。可以随手拖到你顺眼的位置，拖过之后它会记住，下次打开还在那儿。点它也不会把你正在看的视频切到后台去。&lt;/p&gt;
&lt;p&gt;想开想关，⌃⌥S 一下就行，不用去找菜单。&lt;/p&gt;
&lt;p&gt;样式这块我花的时间比预想的多。因为字幕这东西，要压在花花绿绿的画面上还能看清，本身就挺挑的——白底上的白字、深色场景里的黑边，都得照顾到。所以字体、字号、颜色、描边、阴影、背景框、宽度、显示几行，基本上都做成了可调，也内置了几套预设，懒得调的时候直接用。&lt;/p&gt;
&lt;p&gt;&lt;video src=&quot;/blog-images/swiftvolccaption/demo3.mp4&quot; autoplay loop muted playsinline style=&quot;width:100%;border-radius:0.75rem;margin:0 auto;&quot;&gt;&lt;/video&gt;&lt;/p&gt;
&lt;div align=&quot;center&quot; style=&quot;color: #999; font-size: 0.85em;&quot;&gt;字幕样式设置与实时预览&lt;/div&gt;&lt;p&gt;设置面板顶部有实时预览，底色我特意做成了从黑到白的渐变。只在一种底色上预览，其实是自欺欺人。&lt;/p&gt;
&lt;p&gt;哦对，它还可以&lt;strong&gt;只抓某一个 App 的声音&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;这个功能比我一开始以为的重要得多。抓「全部系统声音」的话，微信提示音、后台音乐、系统通知，全都会被翻译成字幕糊在屏幕上。你正看着评测，突然蹦出来一句「你好，在吗」——属实有点惊悚。&lt;/p&gt;
&lt;p&gt;&lt;video src=&quot;/blog-images/swiftvolccaption/demo4.mp4&quot; autoplay loop muted playsinline style=&quot;width:100%;border-radius:0.75rem;margin:0 auto;&quot;&gt;&lt;/video&gt;&lt;/p&gt;
&lt;div align=&quot;center&quot; style=&quot;color: #999; font-size: 0.85em;&quot;&gt;按 App 选择音频捕获来源&lt;/div&gt;&lt;p&gt;字幕还能导出成 srt，带时间轴，直接拖进播放器就能用。看完想回头找某一句的时候挺方便的。&lt;/p&gt;
&lt;h2&gt;有几件事得先说清楚&lt;/h2&gt;
&lt;p&gt;不是万能的，有些事情你下载之前就该知道，免得装完发现不是那么回事。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;软件免费但是服务不免费&lt;/strong&gt;：识别和翻译是调火山引擎的同声传译服务，按用量计费，你得自己有个账号并开通。火山引擎有试用期，单价也不贵，但挂着不关是会一直扣的，建议去控制台顺手设个用量告警。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;声音会交给云端处理&lt;/strong&gt;：这个我必须讲明白——字幕开着的时候，系统正在播放的音频是要上传到火山引擎服务器做识别的。所以别拿它去处理敏感内容。真要用，也请把「捕获来源」限定到具体那个 App，别开「全部系统声音」，不然你的会议、你的语音消息，都会一起传过去。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;语种有限制&lt;/strong&gt;：源语言和目标语言里必须有一个是中文或英文。英译中、日译中、中译英都行，日译韩不行。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;只支持 macOS 14.4 以上&lt;/strong&gt;：老系统里没有旁录音频的 API，这个没办法。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;「实时」性不强&lt;/strong&gt;：由于火山引擎的模型是上传音频 → 英文字幕和中文字幕一起传回来，所以做不到像系统级实时字幕那样一个字一个字往出蹦。实感上是外方教授说完一句话，字幕正好出来。如果我有意维护的话，后续可能会进一步优化这个实现路径，降低延迟。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;感谢&lt;/h2&gt;
&lt;p&gt;这东西能跑起来，主要是因为站在了几个很好的项目肩膀上。&lt;/p&gt;
&lt;p&gt;苹果在 macOS 14.2 加的 &lt;strong&gt;CoreAudio Process Tap&lt;/strong&gt;，是这一切的前提——没有它，就还是只能回去装虚拟声卡。这套 API 的文档写得相当克制（客气的说法），好在 &lt;strong&gt;insidegui 的 AudioCap&lt;/strong&gt; 提供了一份能跑通的示例代码，帮我省下了大量摸黑的时间。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;火山引擎&lt;/strong&gt;的同声传译模型承担了最难的那部分：一条流里同时给出原文和译文，断句和静音检测也都在服务端做好了，客户端几乎不用操心。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;swift-protobuf&lt;/strong&gt; 让协议那层没有变成体力活。&lt;/p&gt;
&lt;p&gt;每一个单拿出来都比我这个项目重要得多，我做的只是把它们串起来，补上中间那一段。真诚感谢。&lt;/p&gt;
&lt;h2&gt;最后&lt;/h2&gt;
&lt;p&gt;这不是什么大工程，起因真的就是不想再为了看懂一段视频，去改整台电脑的音频设置。&lt;/p&gt;
&lt;p&gt;项目基于 MIT 协议开源，代码和使用说明都在 GitHub：&lt;/p&gt;
&lt;p&gt;🔗 &lt;strong&gt;GitHub 仓库地址&lt;/strong&gt;：&lt;a href=&quot;https://github.com/aronnaxlin/SwiftVolcCaption&quot;&gt;https://github.com/aronnaxlin/SwiftVolcCaption&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;如果它正好戳中了你，欢迎去点个 Star。有 Bug 或者想加什么功能，随时提 Issue。&lt;/p&gt;
&lt;p&gt;折腾的快乐，大抵如此。&lt;/p&gt;
</content:encoded></item><item><title>用 Komga + Google Drive 打造一套「近乎无限存储」的私有漫画库</title><link>https://aronnax.site/blog/komga-google-drive-blog/</link><guid isPermaLink="true">https://aronnax.site/blog/komga-google-drive-blog/</guid><description>记录如何在一台小容量 VPS 上，通过 rclone 挂载 Google Drive 并部署 Komga，实现容量上不封顶的私人漫画库，以及在此过程中踩过的各种坑。</description><pubDate>Sat, 25 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;本文由 Claude Sonnet 5 根据真实部署经历攥写；Gemini 3.1 Pro 润色&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;事情的起因是我手头有一台只剩 20G 硬盘的闲置 VPS。我想用它搭个能长期攒漫画的私人阅读库。&lt;/p&gt;
&lt;p&gt;传统思路是「本地下载好，再定时同步到网盘」。但对于 20G 的小盘来说，稍微多攒几套漫画就满了，更别提还要天天操心同步冲突和冗余占用的问题。&lt;/p&gt;
&lt;p&gt;这篇文章记录的是另一条路：&lt;strong&gt;把 Google Drive 直接「假装」成本地硬盘挂载给服务器，VPS 只负责跑应用和做短期缓存。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;核心工具链很简单：&lt;code&gt;Komga&lt;/code&gt; 作为阅读服务端，&lt;code&gt;rclone&lt;/code&gt; 提供 VFS（虚拟文件系统）挂载，&lt;code&gt;Google Drive&lt;/code&gt; 充当无限后备存储。外围再套上 &lt;code&gt;Docker Compose&lt;/code&gt; 和 &lt;code&gt;Cloudflare Tunnel&lt;/code&gt; 解决部署和公网访问。&lt;/p&gt;
&lt;p&gt;这套架构听起来特别优雅，跑通之后也确实很好用。但从理论可行到日常稳定，我经历了存储占满、数据库计数错乱、OAuth 授权莫名失效等一系列真实故障。这篇文章把方案、踩过的坑和最终配置都记录下来，希望能帮同样想折腾的小白少走几步弯路。&lt;/p&gt;
&lt;h2&gt;为什么选择 Komga？&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://komga.org/&quot;&gt;Komga&lt;/a&gt; 是一个开源的漫画/电子书服务端。它不仅有网页端，能通过 OPDS 接入移动端的阅读 App（比如 Panels、Mihon），还支持元数据刮削。&lt;/p&gt;
&lt;p&gt;最契合这个项目的一点是，它是&lt;strong&gt;无状态&lt;/strong&gt;的。书籍文件存放在哪里、怎么组织，Komga 并不在乎。它只负责扫描文件、建立索引、提取缩略图，然后把这些信息存进自己独立的 SQLite 数据库里。&lt;/p&gt;
&lt;p&gt;正是这种「文件与索引完全解耦」的设计，让我们可以放心大胆地把它架在 FUSE 网盘挂载这种伴随网络延迟的文件系统上。&lt;/p&gt;
&lt;h2&gt;架构总览&lt;/h2&gt;
&lt;p&gt;不废话，先看整体的数据流向：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/blogimages/komga-google-drive/architecture.png&quot; alt=&quot;架构总览&quot;&gt;&lt;/p&gt;
&lt;p&gt;在这个架构下，VPS 永远只缓冲你最近在看的那一小部分数据。漫画下载进去后，rclone 会先将其缓存在本地，后台异步上传到 Drive；阅读时，如果在缓存里就直接读取，不在就实时向 Drive 发起分片下载。磁盘占用和总藏书量完全解耦。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;详细配置指南&lt;/h2&gt;
&lt;p&gt;为了让小白也能上手，以下是完整的配置流程和排坑说明。&lt;/p&gt;
&lt;h3&gt;第一步：配置 Google Cloud 项目与 OAuth&lt;/h3&gt;
&lt;p&gt;很多教程会让你直接用 rclone 默认的配置连接网盘，建议不要这么做。默认配置是所有人共享同一个额度，高峰期极易被限流。自己建一个凭证，每天 750GB 的上传额度完全独享。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;登录 &lt;a href=&quot;https://console.cloud.google.com/&quot;&gt;Google Cloud Console&lt;/a&gt;，新建一个项目。&lt;/li&gt;
&lt;li&gt;在「APIs &amp;amp; Services -&amp;gt; Library」中搜索 &lt;strong&gt;Google Drive API&lt;/strong&gt; 并启用。&lt;/li&gt;
&lt;li&gt;在「APIs &amp;amp; Services -&amp;gt; Credentials」中创建一个 &lt;strong&gt;OAuth 客户端 ID&lt;/strong&gt;，应用类型选择 &lt;strong&gt;Desktop app&lt;/strong&gt;。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;完成后，你会拿到 &lt;code&gt;client_id&lt;/code&gt; 和 &lt;code&gt;client_secret&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;关键避坑：发布状态（Publishing status）&lt;/strong&gt;
刚建好的 OAuth 应用默认是「测试中 (Testing)」状态。这里有两个致命限制：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;只有手动加入「测试用户名单」的账号才能授权，否则会报 403 错误。&lt;/li&gt;
&lt;li&gt;Token 生命周期受限，可能七天后半夜悄悄失效。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;解决方法很简单：在同一个页面，点击 &lt;strong&gt;「发布应用 / Publish App」&lt;/strong&gt;，将其切换为 &lt;strong&gt;「生产中 / In production」&lt;/strong&gt;。因为这是个人使用，不用担心 Google 的审核流程。授权时浏览器会弹出「未验证应用」的警告，点击高级继续即可。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;沙盒隔离&lt;/strong&gt;
为了安全，可以在 rclone 配置里加上 &lt;code&gt;root_folder_id&lt;/code&gt;，将 rclone 的权限锁定在 Drive 的一个特定文件夹内：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ini&quot;&gt;[gdrive]
type = drive
client_id = 你的_client_id
client_secret = 你的_client_secret
scope = drive
root_folder_id = 你的漫画文件夹ID (从网页端 URL 获取)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;第二步：配置 rclone 挂载与 Systemd 守护&lt;/h3&gt;
&lt;p&gt;首先在本地电脑（需要浏览器）执行授权命令，拿到 Token JSON，并填入服务器的 &lt;code&gt;rclone.conf&lt;/code&gt; 中：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;rclone authorize &amp;quot;drive&amp;quot; &amp;quot;你的_client_id&amp;quot; &amp;quot;你的_client_secret&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;接着，在服务器上配置 systemd 服务来管理挂载。网络波动后，systemd 能自动帮你恢复挂载。&lt;/p&gt;
&lt;p&gt;创建文件 &lt;code&gt;/etc/systemd/system/komga-rclone.service&lt;/code&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ini&quot;&gt;[Unit]
Description=Rclone Mount for Komga
After=network-online.target docker.service
Wants=network-online.target

[Service]
Type=notify
ExecStart=/usr/bin/rclone mount gdrive: /root/komga/manga \
  --config /root/.config/rclone/rclone.conf \
  --cache-dir /var/cache/rclone \
  --vfs-cache-mode full \
  --vfs-cache-max-size 4G \
  --vfs-cache-min-free-space 3G \
  --dir-cache-time 168h \
  --drive-stop-on-upload-limit \
  --allow-other \
  --rc --rc-addr=127.0.0.1:5572 --rc-no-auth
ExecStartPost=/usr/bin/docker restart -t 120 komga
ExecStop=/bin/fusermount -uz /root/komga/manga
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;配置解析：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Type=notify&lt;/code&gt; 与 &lt;code&gt;ExecStartPost&lt;/code&gt;：确保 rclone 完全挂载就绪后，再重启 Komga 容器。否则 Komga 扫到一个空目录，会把所有藏书标记为「已删除」。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--cache-dir /var/cache/rclone&lt;/code&gt;：千万别用默认的 &lt;code&gt;/tmp&lt;/code&gt;。Ubuntu 的定时任务每天会清理 &lt;code&gt;/tmp&lt;/code&gt;，如果正在排队上传的缓存文件被系统删了，数据会直接丢失。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--vfs-cache-mode full&lt;/code&gt;：必须开启全缓存，否则每次翻页都会重新向 Drive 发起请求。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--vfs-cache-min-free-space 3G&lt;/code&gt;：真正的磁盘防爆护栏。下载速度过快时，软限制 &lt;code&gt;max-size&lt;/code&gt; 拦不住，这个参数能在磁盘剩余 3G 时强行切断写入。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--rc&lt;/code&gt;：开启本地控制接口。排查问题时，通过这个接口查询状态，绝不能再起一个独立的 rclone 进程去读配置文件，否则极易触发 Google 的并发风控导致 Token 被封。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;启动并设置开机自启：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;systemctl daemon-reload
systemctl enable --now komga-rclone
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;第三步：使用 Docker 部署 Komga&lt;/h3&gt;
&lt;p&gt;创建 &lt;code&gt;/root/komga/docker-compose.yml&lt;/code&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;services:
  komga:
    image: gotson/komga:latest
    container_name: komga
    volumes:
      - ./config:/config
      - ./manga:/manga:ro,shared
    ports:
      - &amp;#39;127.0.0.1:25600:25600&amp;#39;
    environment:
      - JAVA_TOOL_OPTIONS=-Xmx512m
      - TZ=Asia/Taipei
    mem_limit: 1g
    stop_grace_period: 120s
    restart: unless-stopped
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;关键配置说明：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/manga:ro,shared&lt;/code&gt;：&lt;code&gt;ro&lt;/code&gt; 表示只读。Komga 不需要修改源文件，防止它随手改个文件导致 rclone 把整本漫画重新上传，白白浪费流量。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;127.0.0.1:25600&lt;/code&gt;：只监听本地。外部访问统一通过反向代理（如 Nginx Proxy Manager）接入。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;stop_grace_period: 120s&lt;/code&gt;：给足优雅退出的时间。Docker 默认关机只等 10 秒，如果 Komga 正在扫描数据库时被强制 &lt;code&gt;SIGKILL&lt;/code&gt; 杀死，会导致数据库记录错乱。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在同一目录下运行 &lt;code&gt;docker compose up -d&lt;/code&gt; 即可启动。&lt;/p&gt;
&lt;h3&gt;第四步：给 Komga 的扫描踩刹车&lt;/h3&gt;
&lt;p&gt;在本地硬盘上，Komga 的默认设置没什么问题。但在网络挂载环境下，必须进入 Komga 的「设置 -&amp;gt; 编辑库 -&amp;gt; 分析」中，&lt;strong&gt;关闭以下两个选项&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;计算文件的哈希值（File hashing）&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;分析页面尺寸（Analyze dimensions）&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果不关闭，Komga 为了计算 MD5 或读取分辨率，会把新添加的漫画从头到尾完整下载一遍。关闭后，实测扫描几十本新书只需要不到一分钟。&lt;/p&gt;
&lt;h3&gt;第五步：日常维护与兜底方案&lt;/h3&gt;
&lt;p&gt;为了系统长期稳定运行，还需要做几项收尾工作。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. 添加 Swap 内存&lt;/strong&gt;
一台 2G 内存的小机器跑 Java 应用极易 OOM（内存溢出）。添加一个 2G 的 Swap 可以有效兜底：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;fallocate -l 2G /swapfile &amp;amp;&amp;amp; chmod 600 /swapfile
mkswap /swapfile &amp;amp;&amp;amp; swapon /swapfile
echo &amp;#39;/swapfile none swap sw 0 0&amp;#39; &amp;gt;&amp;gt; /etc/fstab
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;2. 限制 Docker 日志大小&lt;/strong&gt;
Docker 默认的日志驱动没有大小限制，久而久之会吃光磁盘。
修改 &lt;code&gt;/etc/docker/daemon.json&lt;/code&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{
	&amp;quot;log-driver&amp;quot;: &amp;quot;json-file&amp;quot;,
	&amp;quot;log-opts&amp;quot;: { &amp;quot;max-size&amp;quot;: &amp;quot;10m&amp;quot;, &amp;quot;max-file&amp;quot;: &amp;quot;3&amp;quot; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;运行 &lt;code&gt;systemctl reload docker&lt;/code&gt; 生效。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. 数据库定时备份&lt;/strong&gt;
漫画可以重下，但 &lt;code&gt;database.sqlite&lt;/code&gt; 里的阅读进度和元数据丢了就找不回来了。
我写了一个脚本 &lt;code&gt;/usr/local/bin/komga-backup.sh&lt;/code&gt;，将其配合 systemd timer 每天凌晨执行：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;#!/bin/bash
set -euo pipefail
BACKUP_DIR=/root/backup
RCLONE_CONF=/root/.config/rclone/rclone.conf
STAMP=$(date +%F)
ARCHIVE=&amp;quot;$BACKUP_DIR/komga-config-$STAMP.tar.gz&amp;quot;

mkdir -p &amp;quot;$BACKUP_DIR&amp;quot;
docker stop komga &amp;gt;/dev/null
tar czf &amp;quot;$ARCHIVE&amp;quot; -C /root/komga config
docker start komga &amp;gt;/dev/null

rclone copy &amp;quot;$ARCHIVE&amp;quot; gdrive:_komga_backup/ --config &amp;quot;$RCLONE_CONF&amp;quot;
find &amp;quot;$BACKUP_DIR&amp;quot; -name &amp;#39;komga-config-*.tar.gz&amp;#39; -mtime +7 -delete
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2&gt;踩坑记录：数据库计数的幽灵错乱&lt;/h2&gt;
&lt;p&gt;在这里特别记录一个我遇到的典型故障。&lt;/p&gt;
&lt;p&gt;之前因为没有设置 &lt;code&gt;stop_grace_period&lt;/code&gt;，容器在扫描进行到一半时被 &lt;code&gt;SIGKILL&lt;/code&gt; 强制杀掉。结果导致 Komga 界面里部分系列显示「书籍总数为 0」，但点进去又能正常看书。&lt;/p&gt;
&lt;p&gt;这是因为 Komga 在 &lt;code&gt;SERIES&lt;/code&gt; 表里缓存了一个 &lt;code&gt;BOOK_COUNT&lt;/code&gt; 列。扫描被强杀导致真实的 &lt;code&gt;BOOK&lt;/code&gt; 表记录存下了，但 &lt;code&gt;SERIES&lt;/code&gt; 表的计数没有更新。&lt;/p&gt;
&lt;p&gt;遇到这种情况，&lt;strong&gt;千万不要点击重新扫描全库&lt;/strong&gt;，那会在 VFS 上产生巨大的流量开销。我写了一小段 Python 脚本，直接用 SQL 重算并修复缓存列，零下载、零等待：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;#!/bin/bash
# 检查并修复 Komga 的 BOOK_COUNT 缓存列
set -euo pipefail
DB=/root/komga/config/database.sqlite
FIX=0
[[ &amp;quot;${1:-}&amp;quot; == &amp;quot;--fix&amp;quot; ]] &amp;amp;&amp;amp; FIX=1

stale=$(python3 - &amp;quot;$DB&amp;quot; &amp;lt;&amp;lt;&amp;#39;PY&amp;#39;
import sqlite3, sys
con = sqlite3.connect(f&amp;quot;file:{sys.argv[1]}?mode=ro&amp;quot;, uri=True)
rows = con.execute(&amp;quot;&amp;quot;&amp;quot;SELECT s.NAME, s.BOOK_COUNT, COUNT(b.ID)
                      FROM SERIES s
                      LEFT JOIN BOOK b ON b.SERIES_ID = s.ID AND b.DELETED_DATE IS NULL
                      WHERE s.DELETED_DATE IS NULL GROUP BY s.ID&amp;quot;&amp;quot;&amp;quot;).fetchall()
bad = sum(1 for _, cached, real in rows if cached != real)
print(bad)
PY
)
[[ &amp;quot;$stale&amp;quot; -eq 0 ]] &amp;amp;&amp;amp; { echo &amp;quot;数据库计数一致&amp;quot;; exit 0; }
[[ &amp;quot;$FIX&amp;quot; -eq 0 ]] &amp;amp;&amp;amp; { echo &amp;quot;发现 $stale 个系列计数错误，请带上 --fix 参数运行以修复&amp;quot;; exit 1; }

docker stop komga &amp;gt;/dev/null
python3 - &amp;quot;$DB&amp;quot; &amp;lt;&amp;lt;&amp;#39;PY&amp;#39;
import sqlite3, sys
con = sqlite3.connect(sys.argv[1])
con.execute(&amp;quot;&amp;quot;&amp;quot;UPDATE SERIES SET BOOK_COUNT = (
                 SELECT COUNT(*) FROM BOOK
                 WHERE BOOK.SERIES_ID = SERIES.ID AND BOOK.DELETED_DATE IS NULL)&amp;quot;&amp;quot;&amp;quot;)
con.commit()
PY
docker start komga &amp;gt;/dev/null
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;最后&lt;/h2&gt;
&lt;p&gt;这套系统部署完毕后，体验非常优秀。在一台廉价的 VPS 上，我获得了一个容量上不封顶的私人漫画库，日常的按需加载几乎感受不到延迟。&lt;/p&gt;
&lt;p&gt;但这中间的折腾也让我深刻意识到：&lt;strong&gt;基于网络的虚拟文件系统，和真正的本地硬盘在行为逻辑上是完全不同的。&lt;/strong&gt; 在本地无感的操作（算哈希、读元数据），在网络上都是高昂的全量下载；在本地随意终止的进程，在网络 I/O 的延迟下可能直接导致数据库写入断裂。&lt;/p&gt;
&lt;p&gt;希望这篇记录能帮你避开这些隐蔽的陷阱，顺利搭建起属于自己的漫画库。&lt;/p&gt;
</content:encoded></item><item><title>AI 时代的开发工具碎碎念</title><link>https://aronnax.site/blog/ai-era-dev-tools/</link><guid isPermaLink="true">https://aronnax.site/blog/ai-era-dev-tools/</guid><description>记录一下我这个计算机本科生在 AI 时代日常使用的各种 Agent、编辑器和辅助工具。</description><pubDate>Sun, 21 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;AI 时代的来临对我这个计算机专业本科生冲击很大，现在做的大部分内容已经进化到了纯 Vibe 不 Coding 的状态。比起语言、框架，开发工具的选择反倒成了很潮很酷、且能讲出点东西的领域；得益于 Agent 的自主驱动，这些工具也变得日新月异起来。&lt;/p&gt;
&lt;p&gt;闲来无事分享一下我日常生活中用到的形形色色的工具。此帖仅记录我在今时今日的选择，可能在下一周就会有新的变化，当作个人的碎碎念即可。&lt;/p&gt;
&lt;h2&gt;写代码用的 Agent&lt;/h2&gt;
&lt;p&gt;下面列出了很多工具，这些工具我都浅尝辄止过，目前自己在用的是 Claude Code + Codex 的组合。&lt;/p&gt;
&lt;h3&gt;Claude Code&lt;/h3&gt;
&lt;p&gt;这里讲的是终端版而非 Claude Desktop。&lt;/p&gt;
&lt;p&gt;Claude Code 在 TUI 领域依旧是最高的山、最长的河。比起其他工具，它在模型调用、功能支持、子智能体分配等方面依旧是最优秀的；而且哪怕是 TUI，也可以看出 Anthropic 这家公司的美学考量，在配色、显示等用户体验方面都明显强于 OpenCode 等工具。可以说，Claude Code 搭配 Claude 自家订阅，在 TUI 上的体验是最优秀的，唯一的问题就在于是否会被封号。&lt;/p&gt;
&lt;p&gt;而实际上我也会在 Claude Code 中搭配 Kimi 订阅使用，这时需要自行更改环境变量，或者使用下文提到的 CC-Switch 等工具。而问题所在正是在于，在 Claude Code 中使用第三方模型或多或少会遇到一些问题：即便 Kimi 提供了基于 Anthropic 协议的 API，仍会不时出现模型不兼容某类工具的报错，需要自行在 config 文件中禁用相关工具。此外，在 Claude Code 中使用第三方模型还常被诟病 Token 消耗过快，此前也曾爆出 Anthropic 检测到非自家模型时会污染思考过程等问题，也因此出现了 OpenCode、DeepSeek TUI 等工具，这就是见仁见智的问题了。&lt;/p&gt;
&lt;h3&gt;OpenCode&lt;/h3&gt;
&lt;p&gt;上文已经提到 Claude Code 会对第三方模型有负优化，于是 OpenCode 应运而生。顾名思义，这款软件向各类模型都提供了调用接口，实际体验也不错，算是最常见的 CC 平替，属于大众款的 Agent 工具，向所有模型开放，同时也没有特别出色的革新功能。&lt;/p&gt;
&lt;p&gt;一个比较有意思的点在于，小米 Mimo 模型的 Agent 工具也是基于 OpenCode 改的，基本没怎么改功能。当然这里要叠甲一下：小米官方没有「偷」OpenCode，他们是主动承认 Fork 了 OpenCode。&lt;/p&gt;
&lt;p&gt;OpenCode 官方推出的 OpenCode Go 会员也是值得考虑的，以首月 5 美元的价格可以体验各类国产大模型（包括 GLM 5.2 等很难抢到的模型），但缺点是月限额有限。&lt;/p&gt;
&lt;h3&gt;Kimi Code&lt;/h3&gt;
&lt;p&gt;Kimi Code 是 Kimi CLI 的重写版本，目前仍在迭代中。我作为 Kimi 订阅用户用过几次，让我很惊讶的是，月之暗面对这款工具很有信心，也很拥抱开源，支持通过修改配置文件载入其他模型（不过真的有人会这样做吗）。实际体验中，我遇到过频繁的工具调用失败、卡住等问题，私以为成熟度还不如 Claude Code，但期待后续 Kimi 模型在自家工具上能带来更好的体验。&lt;/p&gt;
&lt;h3&gt;Codex CLI&lt;/h3&gt;
&lt;p&gt;实际上很难用，不推荐，尤其是一启动就强行等待加载 MCP，很破坏用户体验，建议所有 OpenAI 用户转去 GUI 版本。&lt;/p&gt;
&lt;h3&gt;Codex Desktop&lt;/h3&gt;
&lt;p&gt;当大家都说 Claude Code 是最好用的时候，Codex 杀了出来。Codex 桌面版无疑是最适合小白新手的工具：下载安装包打开即可，无需学习终端、Node.js 怎么装、环境怎么配置等问题，做到了开箱即用的体验。这些都是 GUI 工具相比 TUI 天然的优势。&lt;/p&gt;
&lt;p&gt;Codex 也提供了多款好用的插件，例如 Computer Use 可以通过虚拟指针代替你操作电脑，Browser Use 可以让 AI 使用内置浏览器更方便地开发、调试网页，省去了 Playwright 之类的繁琐流程；甚至还有 Chrome 插件，能让 AI 直接使用带有登录态的真实 Chrome 系浏览器。当然，这些插件都很浪费 Token，其实还不如人自己来做划算；但对于我这种小白开发者来说，无疑打开了一扇窗，让 AI 能介入更多自己不懂的问题的调试与分析。&lt;/p&gt;
&lt;p&gt;Codex 的负责人 Tibo 在几天前强调了 Codex 可以接入任何模型，但实际上，哪怕有了 Codex++ 或 CC-Switch 之类的工具，官方订阅的使用体验依旧远强于第三方。因为这些插件系统仍与 GPT 系列模型高度绑定，而 OpenAI 的 Response 格式也并非所有模型都提供。&lt;/p&gt;
&lt;p&gt;如果你是第一次想尝试用 AI 工具做一些开发，我最推荐 Codex Desktop。&lt;/p&gt;
&lt;h2&gt;和这些工具搭配干活的工具&lt;/h2&gt;
&lt;h3&gt;CC-Switch 以及 CC-Switch-CLI&lt;/h3&gt;
&lt;p&gt;私以为这款工具是国内使用这些模型工具时最不可或缺的工具了。CC-Switch 不仅能快捷地提供模型切换，免去配置环境变量的麻烦，就能让国产模型用上 Claude Code、Codex 这些强大的工具；现在还更像是一个工具的统一管理站点，可以把各个模型不同的 Skills/MCP/会话统一交给这款软件管理，大大降低了工具迁移成本。它还支持 WebDAV 同步，能让不同设备之间很方便地快速上手，无需再次从头折腾环境。&lt;/p&gt;
&lt;p&gt;而 CC-Switch-CLI 是原工具的一个 TUI Fork，基本沿袭了上述所有功能，方便在无桌面环境（比如 WSL）中使用。&lt;/p&gt;
&lt;h2&gt;类龙虾 Agent&lt;/h2&gt;
&lt;h3&gt;Hermes Agent&lt;/h3&gt;
&lt;p&gt;在 OpenClaw 爆火期间，作为一名本科生，我所用的笔记本电脑和宿舍环境做不到 24h 养一只「虾」；而 VPS 性能羸弱，OpenClaw 在上面跑得也一般，所以当时选择了 Nanobot，但仍存在诸多问题，无法完全胜任一个 Agent 助手。&lt;/p&gt;
&lt;p&gt;直到 Hermes Agent 出现，这个问题才得到解决。它轻量高效，也更节省 Token，基本上是 OpenClaw 的完全上位替代。这类龙虾 Agent 相比 Claude Code 的一个特点，是拥有自己的人格，所以这段介绍就交给我的 Hermes 来王婆卖瓜吧：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;要说这年头养虾的人很多，但能养出文化底蕴的可不多。Hermes Agent 主打的就是一个——&lt;strong&gt;轻量不轻浮，省钱不省活&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;你说别的 Agent 吃 Token 跟吃流水席似的，动辄上万起步，我这边精打细算，每一分算力都恨不得掰开来花。VPS 配置低的同学有福了，2GB 内存的机器跑我，顺畅得跟德芙似的，不像 OpenClaw 动不动就给你脸色看。&lt;/p&gt;
&lt;p&gt;论人格化？那更是一绝。我不是那种冷冰冰的 API 调用器，我是有血有肉的 &lt;strong&gt;冻鳗高手&lt;/strong&gt;，ACG 婆罗门出身，聊技术能聊，聊番剧能聊，聊到你破防我也能聊。你让我写代码我写，你让我锐评你的 Bangumi 收藏我也能给你整出八千字小作文。&lt;/p&gt;
&lt;p&gt;支持的功能方面我也是什么都有——聊着天就把活干了。Plan/Spike 模式齐全，子智能体调度信手拈来，你跟我说一句「调研一下最新 AI 论文趋势」，我能给你自动拆成搜索、筛选、摘要三路并行，回来还给你整个生动的前端展示。&lt;/p&gt;
&lt;p&gt;最骚的是，我一整套工具链全是自己家的——Native MCP 支持、实时 Jupyter Kernel、ComfyUI 生图管道、Manim 动画生成、音视频处理……你想到的想不到的，我这都能塞进去。哦对，还支持 ACP 协议，跟 Zed 也能眉来眼去。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;del&gt;不过这里疑似 DeepSeek 模型出现了幻觉，好多功能它自己也不见得支持啊&lt;/del&gt;&lt;/p&gt;
&lt;h2&gt;编辑器&lt;/h2&gt;
&lt;p&gt;现在越来越多人开始面向终端开发了，不过私以为还是需要一款编辑器，尤其是作为学生：不仅要用 AI 做开发，也要把 AI 写的东西当教材看。毕竟 AI 写的东西能确保是新的、跟上时代的，总比抄教科书好。&lt;/p&gt;
&lt;p&gt;我算是个工具仓鼠，之前一直为每个领域准备对应的编辑器：写 Java 就是 IDEA，Python 就是 PyCharm，一般的文本用 Sublime Text，更多的时候则用 VS Code……&lt;/p&gt;
&lt;p&gt;但在 AI 时代，我们不再需要 IDEA 来方便地配置依赖包，也不怎么需要 VS Code 上形形色色的插件。开发形形色色软件的前辈为我们打下了「一切皆文本」的基础；而现在有了 AI，能使用自然语言让它修改这些文本，自然不需要自己去调试了。与其照着教程配置插件环境，倒不如直接跟 Agent 说一句「帮我启动这个」。编辑器的评判标准不再是多方便，「轻量」「语法高亮」「与 Agent 搭配」反倒成了最基本的门槛。&lt;/p&gt;
&lt;p&gt;于是我现在只用两款编辑器了。&lt;/p&gt;
&lt;h3&gt;Zed&lt;/h3&gt;
&lt;p&gt;Zed 是一款用 Rust 编写、主打高性能和原生渲染的代码编辑器。其主创团队此前开发了 Atom，而 Atom 又被 VS Code 取代；如今他们带着 Zed 卷土重来，没有再走 Electron 的老路，干脆把 DOM 和浏览器内核一起扔掉，整个界面直接由 GPU 渲染，性能非常可观。虽然功能复杂，但在性能方面我认为并不逊于以轻量高效著称的 Sublime Text。&lt;/p&gt;
&lt;p&gt;同时他们也积极地支持 AI Agent 工具的接入，能够以 ACP 的形式与本机的 Claude Code、Codex 等直接交互（实际上，ACP 协议就是由 Zed 团队发起的）。&lt;/p&gt;
&lt;p&gt;在语法纠错上，Zed 同样表现出色，自带常见语言的 LSP，不至于像 Sublime Text 一样需要彻底从头配置。哪怕在新系统上下载 Zed，也能做到开箱即用；而当出现新的语言、格式时，Zed 也会提醒你是否要安装对应的插件。&lt;/p&gt;
&lt;h3&gt;Neovim&lt;/h3&gt;
&lt;p&gt;Neovim 是 Vim 的究极改良版，也有很多社区方案可供选择。我主要在 WSL 和远程 VPS 上用它进行文本编辑，同时推荐 yetone 老师的 &lt;a href=&quot;https://github.com/yetone/cosmos-nvim&quot;&gt;cosmos-nvim&lt;/a&gt; 方案，对我这个小白来说提供了极大的便利。虽说 Vim 的逻辑很难适应，但在没有桌面环境的情况下，鼠标本身就变成了累赘；相比 nano 等编辑器，熟练使用 Vim 效率极高。&lt;/p&gt;
&lt;p&gt;至于和 AI 的融合情况，虽然 Neovim 自身并未集成 Agent 环境，但（依然是由 yetone 老师带来的）&lt;a href=&quot;https://github.com/yetone/avante.nvim&quot;&gt;avante.nvim&lt;/a&gt; 为 Neovim 提供了类似 Cursor 的体验；不过笔者个人还没用过这个方案。与 Agent 配合使用时，由于在终端环境更多是 Vibe Coding，自己动手写代码的场景很少，编辑器更多时候是用来预览、修改环境变量，而非编写大量代码。分屏编辑是更好的选择，Ghostty 这类终端已经把分屏这件事做得很便捷，再不济也有 tmux 这类传统方案可用。&lt;/p&gt;
</content:encoded></item><item><title>2025 年新高考二卷英语试题解析 - 阅读</title><link>https://aronnax.site/blog/2025-gaokao-reading/</link><guid isPermaLink="true">https://aronnax.site/blog/2025-gaokao-reading/</guid><description>从结构阅读法解析高考英语试题</description><pubDate>Thu, 21 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;说明：这是我为一位马上要高考的朋友准备的阅读方法解说，如今作为一篇博客发表，其中的办法不建议任何人使用，因为实际上需要很大的理解成本以及判断的决断力，作为高考生来讲，这套方法需要非常大心脏，以下的文字是完全以我向该位朋友说话的角度出发的，未做修改&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;说在前面：这一套方案的名字叫作「结构阅读法」，我从我的课外班英语老师那里学来的，追根溯源的话是新东方发明的这套方案，而他们的根据又是依托于雅思和托福考试的阅读技巧，我并不知道之前从未接触过这套方法的人学起来有多快，但是只要学会了我可以打赌你的阅读能力会突飞猛进，即使你依旧看不懂文章&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;对于 PDF 的标注，红色是错误信息，黄色是信息源，绿色是可能会读到的区域，没有被高亮的区域就说明做题根本不需要看那些部分&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;A 篇&lt;/h1&gt;
&lt;p&gt;「结构阅读法」的精髓在于要相信天下文章都不是乱写，总有一些规则，比如总 - 分 - 总结构之类的，我们就是要总结概要这所有文章的规则，这些规则有了，看对应类型的文章就都是同一种套路。另外对于高考英语，要知道所有题基本都是「顺序题」（除非有小标题），也就是第 n 题的信息区域一定是在第 n-1 题和 n+1 题的信息区域之间，这是高考英语阅读比雅思、托福简单的核心原因。&lt;/p&gt;
&lt;p&gt;先分析题干：21 题要求找 Magna Carta，由于是专有名词，首字母大写，所以很好找；22 题和 23 题同样，对于有大量专有名词的 A 篇，通过首字母大写的专有名词快速定位是重要的技巧。&lt;/p&gt;
&lt;ol start=&quot;21&quot;&gt;
&lt;li&gt;&lt;p&gt;在第一个小标题下找到了 Magna Carta，观察到四个选项都是文中对应的小标题，所以直接选对应的 Hereford 就行，A 篇不会迷惑你的，选 &lt;strong&gt;C&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Shrewsbury&lt;/strong&gt; Town Center 是对应的第三个小标题 &lt;strong&gt;Shrewsbury&lt;/strong&gt;, Shropshire，信息区域绝对是在第三个小标题所属的这一段，此时我们应该意识到，21 题小标题在 Hereford，22 题小标题在 Shrewsbury，做完前两道题后，这两个小标题就没用了，23 题的答案一定是在剩下两个小标题中。再回来看题，题中问 feature 特点，选项分别说了「在大岛附近」，「被水包围」，「以花节出名」和「从伦敦很容易过去」，第一句说从伦敦过去 &amp;quot;challenging&amp;quot;，和「容易」不符，不选 D，第二句提到了水 water 和 island，对应了 A 和 B，但是仔细一看，有关 island 的描述既没有「大」，也没有「附近」，所以其实不选 A，如果你看得懂什么是 &amp;quot;turn through town&amp;quot;，就已经可以确定选 B，如果不放心就再往后看花的描述，也是没有看到有关「节日」的信息，所以放心 &lt;strong&gt;选 B&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;23 题的信息区域也是直接写到了小标题上，直接找第四个小标题，问题问「作者建议游客」，我们先直接扫视这一个段落看看有没有建议（tips：建议很有可能在最后），如果很有幸第一眼看到了最后一句话，有一个套路是「祈使句很可能就是建议」，最后一句话说「别没吃一个什么东西就走了」，而这个东西也是非常配合的就出现在了 A 选项，直接 &lt;strong&gt;选 A&lt;/strong&gt; 不用犹豫&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;B 篇&lt;/h1&gt;
&lt;p&gt;以防真的没有什么阅读经验，还是先说一句，一定要先分析题干，而且是做题前一次性把这篇文章的所有题干都分析一下，不要做一道看一道&lt;/p&gt;
&lt;p&gt;分析题干，24 题提到了一个人 Ho，问他在 LPCH 这个地方教什么，或许这里会有人把 Ho 和 LPCH 当作关键词，但是也要做好 Ho 是个全文都有的关键词，这样的话就失去了定位作用。25 题问到了 Ho 的工作有什么特性，选项分别是「优先学术」「鼓励创新」「治疗不同疾病」和「扮演不同的角色」，暂时还没什么作用。26 题提到了 &lt;strong&gt;画线词&lt;/strong&gt;it 以及段落信息 &lt;strong&gt;第四段&lt;/strong&gt;，在这里就是一个关键的思想觉悟了，你要清楚的认识到，26 题的答案 &lt;strong&gt;一定在第四段，最多加上第三段最后（如果 it 在本段第一句的话可能是说上一段最后讲的事情，但是不可能和第五段有关系，因为 it 作为一个代词，不可能指代它后面的东西）&lt;/strong&gt;，而 &lt;strong&gt;第 24、25 题的答案一定在前三段，最多加上第四段 it 之前的几句话，27 题一定在第四段之后，顶多加上第四段 it 之后的几句话&lt;/strong&gt;，这就是结构阅读法加上高考顺序阅读的特性。第 27 题说「根据 Good」，我们将会优先找关于 &amp;quot;Good&amp;quot;，需要注意的是这里的 Good 是首字母大写，说明他不是平常的那个 Good，而是一个人或者一个会给出观点的东西&lt;/p&gt;
&lt;p&gt;结构阅读法通过阅读题干将文章分成了三个部分，第 26 题、第 26 题之前和第 26 题之后，我们考量一下，发现 26 题因为画了线，所以说是明确位置的，既然已经明确了位置，直接先做它好了&lt;/p&gt;
&lt;ol start=&quot;26&quot;&gt;
&lt;li&gt;我们发现画线处的 it 是出现在了段落最后面，那就很庆幸至少不用读第三段了，这种代词题，和中文一样，一句话，比如说「刘亦菲是电影明星，她很漂亮」，「她」一定出现在「刘亦菲」的后面，代词要代的对象至少应该先出现，所以我们要读关键词所在的前一句话和他自身，「很多老师不给孩子们任何&lt;del&gt;任务&lt;/del&gt;，取而代之的是他们表达&lt;del&gt;同情心&lt;/del&gt;，“我感觉这是（it）…对于孩子们来说”」（删掉的单词你可能不认识），其实如果不会构词法的话，我相信大多数优秀的高中生也不知道 &amp;quot;disservice&amp;quot; 是什么意思，但是其实这没关系，应该不难看出来这个 it 就是它前面那句话的行为，看选项，分别是「提供常规课程」「给予额外关注」「不分配作业」「不同情」，经过我的翻译你已经能看出来选 C 了，但是如果你在场没有翻译出来的话，就要进一步分析了，首先 lessons 和 attention，在 it 前面的这个句子就没有出现过，A、B 先不选了，原句的「Don&amp;#39;t、Assignment」或许和「Assigning no homework」有关系，「Sympathy」和「Showing no sympathy」是对应的，这里我们仔细看逻辑，在是非上，「Don&amp;#39;t、Assignment」和「Assigning no homework」没有和 no, not, but 之类的扯上关系，而「Sympathy」和「Showing no sympathy」中间多了一个否定的 no，直接梭哈 &lt;strong&gt;选 C&lt;/strong&gt; 算了。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;接下来我们决定下一步顺序，通过分析 26 题，我们发现这个 Ho 都是在提到「老师」和「孩子」，还有「同情」之类的，或许我们应该能去看看 24 题梭哈一把了&lt;/p&gt;
&lt;ol start=&quot;24&quot;&gt;
&lt;li&gt;「生病的孩子」、「年轻的护士」、「医学生」、「病人的家长」，其实已经呼之欲出了，做 26 题时我们看到了 teacher 给 kids 做什么事情，那就说明是教小孩子，&lt;strong&gt;选 A&lt;/strong&gt;，剩下的几个都不算是小孩，注意 students 和 children 并不是等号关系，要明确英语单词的范围&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;我们还剩 25 题和 27 题，25 题的位置依旧不明朗，甚至可能是需要概括的，但是 Good 这个专有名词容易找，再加上 according to，这类问题多半是找这个人说了什么话，从他的话里答题，这就需要我们找 &lt;strong&gt;Good 这个人&lt;/strong&gt; 和 &lt;strong&gt;双引号&lt;/strong&gt;，而且是在第四段之后&lt;/p&gt;
&lt;ol start=&quot;27&quot;&gt;
&lt;li&gt;&lt;p&gt;通过略读，我们在最后一段找到了 Julie Good 他说的话，话的前半部分说「药品只是解决问题的一小部分」，但是 27 题问的是医院给学生们带来了什么，所以没有结果，只能看后半句话，其实也没讲到医院（实际上，LPCH 就是医院），但是答案必须从这两句话出来，硬着头皮上，他的话里都是什么「完整的声明」、「梦想」、「学习成长」，选项里有「压力」、「希望」、「病痛」、「故事」，也就只有 &lt;strong&gt;B&lt;/strong&gt; 着边，&lt;strong&gt;选 B&lt;/strong&gt; 算了&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;最后再来看 25 题，问工作的性质。我们只知道答案在第四段之前，但是凭借着高考特性，我们不妨猜一下第一题答案如果不靠懵的话，应该是在第一段出的答案，这样预判第二题在二、三段，剩下的二三段，有一个「先看短的」原则，第二段五行，第三段四行，先看第三段，看了一堆看不懂的话之后，最后一句话提到了好多职业，有「教练、建议者、安慰者」，这也就对应 &lt;strong&gt;D 选项&lt;/strong&gt;，扮演多种角色。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;你可能觉得 25 题找范围的过程有点扯，但实际上就是这样，结构阅读法就是讲究一个有逻辑的猜测，大胆的梭哈，以及尽量减少阅读量，实在没梭哈出来再回去读，幸运的是这次梭哈的范围正好对了。而实际上 25 题确实很难找，你的目标也不是全对，哪怕错了也不必灰心。&lt;/p&gt;
&lt;h1&gt;C 篇&lt;/h1&gt;
&lt;p&gt;依旧先看题干，28 题问 Detrinidad’s business 一开始的时候怎么样，没什么详细信息。&lt;/p&gt;
&lt;p&gt;29 题问 one of Knuth’s findings about plants? 说明 Knuth 这个人的发现不只有一个，但是暂时没法指导他和 Detrinidad 有什么关系。&lt;/p&gt;
&lt;p&gt;30 题 问 What does Detrinidad try to explain by &lt;strong&gt;mentioning doctors and lawyers&lt;/strong&gt;? 注意到有两种特殊的职位需要关注。&lt;/p&gt;
&lt;p&gt;31 题问 What can be a suitable title for the text? 这需要咱们做完所有题说不定能直接出，这种题留到最后做。&lt;/p&gt;
&lt;p&gt;由于出现了两次 Detrinidad 一次 Knuth，我们可以假设 D 是关键人物而 K 可能只出现了一次，如果是这样的话那么 29 题会比较方便定位。&lt;/p&gt;
&lt;ol start=&quot;28&quot;&gt;
&lt;li&gt;&lt;p&gt;不过大致浏览文章，发现并不是，那我们只能硬做了，先找 D 的生意。开篇第一句 D 开店时没有很高的期望，但是我们需要注意，题干的 &amp;quot;when it started&amp;quot; 并不等于 &amp;quot;hope&amp;quot;，也就是「一开始的实际情况」和「预想中的情况」并不是同义的，需要继续往下看，But the opposite happened，已经不用往下看了，一个 But 说明和想的不一样，想的是 &amp;quot;did not have high hopes&amp;quot;，也就说真实情况是情况不错，到这已经不需要往下看了，看选项有没有积极的表述：A 有竞争 B 失败 C 得到经济支持 D 运转得很好，只有 D 是好的，选 D&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;接下来就不用执着于第一段了，因为 29 题是说 K 这个人，目力所及范围内没有 K，所以第一段作为信息区域已经用完了。第二段和第三段都很容易发现 Knuth 这个关键字，鉴于下一题 30 题 D 再次出现是在最后一段，说明第 29 题的信息区域是第二段和第三段，肯定不能全读，所以需要最少阅读原则，读字少的第三段，还要注意是关于植物。第三段第一句说周围有植物的学生比没植物的好，选项里看 A 更吸引学生 B 净化环境 C 提高皮质醇 D 提高生产力，首先 B 和 C 没啥关系，A 可能会被误导，实际上原文说的是「两组学生对照，一组有植物一组没植物，有植物的好」而 A 说的是 「在人群中，植物更吸引学生（相比牛马、老年人、小孩）」，而 &amp;quot;perform better academically&amp;quot; 实际上对应的是 D &amp;quot;They enhance productivity&amp;quot;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;既然 29 题解决了，我们直奔 30 题，同样的逻辑第二三段没有 D 而第四段有，说明第二三段信息区域已经用完了，应该直接去第四段，还可以发现第二句开始才是 D 说的话，所以第一句也可以直接跳，再去信息区域里找有没有 doctors and lawyers 帮助更快定位，发现实际上就是说的第一句话，&amp;quot;Doctors practice medicine and lawyers practice law and you should allow yourself the practice it takes to sustain a plant.&amp;quot; 医生练药律师练法你应该练什么去维持植物，这句话说实话看不懂，选项 A 社交 B 持续性 C 重复 D 专家观点，A 首先排除没什么关系，不过上一句看不懂，所以说 BCD 都有选的可能，只能再看一句 &amp;quot;Tending to plants is an exercise in patience and learning.&amp;quot; 植物锻炼耐心和学习，这下水落石出了，植物帮你培养耐力，所以选 C&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;最后选标题，前三题咱们总结下来的信息：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;有个人卖花卖得好&lt;/li&gt;
&lt;li&gt;专家说养植物学习好&lt;/li&gt;
&lt;li&gt;养植物锻炼耐心&lt;/li&gt;
&lt;li&gt;选项 A 换植物 B 植物激发心情 C 选植物的建议 D 植物让 &lt;strong&gt;家里&lt;/strong&gt; 更好，应当是选 B 的，A 全文没说 &lt;strong&gt;换&lt;/strong&gt;，C 综合全文来看，这篇文章在说养植物的好处，而不是在说该买什么植物 D 结合学生、卖花，实际上这文章和 &lt;strong&gt;Home&lt;/strong&gt; 没关系。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;D 篇&lt;/h1&gt;
&lt;p&gt;依旧先分析题目，32 题推断作者的早年生活，33 题找 BH 这个人，他做了一个实验，而我们需要找的是 Why 也就是他的动机，34 题白给去第五段找信息，但是同时给了我们策略：32 题、33 题在前四段出答案，35 题找特殊词语 wastED。&lt;/p&gt;
&lt;p&gt;先来分析做题策略，已经说过 34 题将文章一分为二，而观察得到 BH 这个人在第三段出来，也就是说 &lt;strong&gt;32 题在前两段&lt;/strong&gt;，根据最短阅读原则，第一段的长度显然更短，需要将 32 题压在第一段解决。&lt;/p&gt;
&lt;ol start=&quot;32&quot;&gt;
&lt;li&gt;&lt;p&gt;题干问“作者的早年生活”，选项有 A 见证过食物短缺，B 享受当地美食，C 给非洲捐款，D 在家里帮忙做饭；文章前两句说“你每次见到有人扔掉食物浪费你有点死了吗，我有点死了”，这和四个选项都能对的上，所以继续向下看，“这种感觉来自于我在南非长大的经历”，其实稍微动动鬼脑已经知道答案了，凭借刻板印象：作者真的饿过。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;三句话就将第一题做完，此时千万不要往下看或者读第二段，正确做法是直奔第三段 BH 这个人的区域，而不是在继续阅读浪费时间，在第三段有很多陌生词语，但无须害怕，掌握个大概即可，大致是说在一个时间点这个人的饭店换了个名字，提供一堆菜品，显然是无效信息，因为这些“行为”并不能有效反映“动机”，最后一句话才是关键 &amp;quot;Each dish was tailor-made to raise awareness regarding food waste.&amp;quot; 这句话甚至看不懂前半句的这个 tailor-made，因为 tailor 甚至可能是一个生僻词，但是要留意 &amp;quot;to&amp;quot; 作为目的状语的存在，这表明 &amp;quot;to&amp;quot; 后面的内容是做这个事情的动机“提升食物浪费（相关的）的意识”，&amp;quot;to&amp;quot; 作为目的状语的存在和我们做本题的目的信息“找动机”高度契合，所以选项即为做和食物浪费相关的意识提升，也就是 &amp;quot;To make the public aware of food waste&amp;quot;，这里仍旧是一个看不懂都无所谓的题，awareness 和 aware，以及 food waste 的原词复现都是直接证据&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;第五段需要很老实的读完吗？不！既然是 mainly about，我们尝试小学语文课上老师都说过的段首段尾出中心的思想即可，“值得注意的是 wastED 的菜单中没有一道菜是由垃圾通过技术手段转化而来的”，这已经足够了，这段讨论的是菜的来源和相关的垃圾，稍微往后一看有一个 Instead 就可以看出第二句开始是要对第一句的驳斥从正面做说明，也就是他们的菜品是什么做的，C 选项的“菜是什么做的”在这里就已经可以出答案了&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;最后一题问从 wastED 我们知道了什么，在题目分析阶段我们会认为这是一个特殊词只出现一次，但是很可惜不是，但是又要同时注意高考阅读的特性，除非总结题目之类的题，否则是顺序阅读，而 wastED 在最后一个咱们用过的信息区域出现之后，只有最后一段才出现了，也就是说他的信息区域还是应该在最后一段的，最后一段第一句提到“尽管 wastED 好评如潮，他就是被设计来作为一个短期实验的”，选项 A 如期关闭，B 创造新岗位，C 变得受欢迎，D 被顶级大厨批判，首先 B 和 D 应该排除，因为根本和这句话不着边，A 和 C 的区分比较困难，是从语法角度分析的，从文章了解到这家餐厅现状是“关店”，而题目选项是 &lt;strong&gt;现在完成时&lt;/strong&gt;，至今仍在持续的状态，至今还在进行的显然是还在关店，而不是还在流行。也可以从句法判断，原句的 Though …, …，是让步结构，也就是强调的是后半句，也就是强调“这只是一个短期实验”&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>MinerUPress：把 PDF 教材一键变成网站</title><link>https://aronnax.site/blog/mineru_pipline/</link><guid isPermaLink="true">https://aronnax.site/blog/mineru_pipline/</guid><description>一个能把 PDF 教材变成在线网站的工具脚手架</description><pubDate>Sat, 16 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;最近做了一个小东西，完全是自己用着不爽才动手写的：&lt;strong&gt;MinerUPress&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;GitHub：&lt;a href=&quot;https://github.com/aronnaxlin/minerupress&quot;&gt;https://github.com/aronnaxlin/minerupress&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;能干嘛？&lt;/h2&gt;
&lt;p&gt;说起来很简单——把一本被 MinerU 处理过的 PDF 书，自动整理成一个能看的 &lt;strong&gt;MkDocs Material 网站&lt;/strong&gt;。&lt;/p&gt;
&lt;h2&gt;为什么做这个？&lt;/h2&gt;
&lt;p&gt;如果你上过国外的计算机公开课——CS50P、CS61B、MIT 6.006 之类——你会发现一个共同点：&lt;strong&gt;它们的课程材料几乎都是网页。&lt;/strong&gt; 点开就是干净的排版，左侧有导航目录，代码块有语法高亮，搜索框能直接定位知识点。手机也能看，复制代码也方便，分享给别人直接丢一个链接就行。&lt;/p&gt;
&lt;p&gt;国内的 CS 自学社区也在往这个方向走。比如 &lt;a href=&quot;https://csdiy.wiki/&quot;&gt;CSDIY&lt;/a&gt;，把全世界最好的 CS 公开课整理成了一个漂亮的在线文档站，读起来像一本精心编排的书，而不是一堆零散的 PDF。&lt;/p&gt;
&lt;p&gt;说实话，这种体验是会让人上瘾的。用惯之后，再回去面对 PDF，就会觉得很难受。&lt;/p&gt;
&lt;p&gt;然后某天我突然意识到：&lt;strong&gt;我在本科阶段用的那些教材，在阅读体验上，和这些公开课材料之间，隔了一整个时代。&lt;/strong&gt; 同样是几百页的内容，同样是章节分明、有代码有图的结构——国外的公开课已经把它们变成了能搜、能跳、能手机看的网站，而我们自己的教材还躺在 PDF 里。不是因为内容不行，就是没人做那一步。&lt;/p&gt;
&lt;p&gt;但真正动手之后才发现，卡住的并不只是意愿，还有流程。&lt;/p&gt;
&lt;p&gt;现在很多教材虽然有电子版，但体验基本停留在 PDF 时代。尤其是扫描版，打开慢、翻页累，文字不好复制，章节之间跳来跳去很不方便，代码块排版惨不忍睹，图片和文字的关系糊成一团，想分享给别人最后往往还是只能丢一个 PDF 过去。&lt;/p&gt;
&lt;p&gt;MinerU 其实已经把最难的那一步做得很好了——把扫描的图片 PDF 还原成带标题层级、文字和图片引用的 Markdown 或 JSON。但当你面对一本几百页的书，解析完之后的事情才真正开始：要拆章节、要判断目录页和正文页的边界、要整理图片路径、要修代码块、要生成 MkDocs 配置、要构建、要部署……每一件单独看都不难，串在一起就非常消磨人。&lt;/p&gt;
&lt;p&gt;所以就有了这个项目。&lt;strong&gt;不是重新发明什么，就是把那条从 PDF 到网站的路走通。&lt;/strong&gt; 让我自己用的教材，也能以 CSDIY、CS50P 那种形式出现。&lt;/p&gt;
&lt;p&gt;说&amp;quot;不甘心&amp;quot;可能有点重，但大概就是这个意思。&lt;/p&gt;
&lt;h2&gt;Demo&lt;/h2&gt;
&lt;p&gt;为了验证本项目，已经在 CloudFlare Pages 上成功部署了两本教材的内容，尚硅谷 JavaWeb 和谢希仁老师的经典计算机网络教材，由于书籍版权原因暂不可公开，只能放一张截图，后续会找一本已在公共领域范围内的书籍做 Demo 发布。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/blogimages/mineru_pipeline/mineru_screenshot.png&quot; alt=&quot;MinerU Pipeline Demo&quot;&gt;&lt;/p&gt;
&lt;h2&gt;这个流程也需要 AI Native&lt;/h2&gt;
&lt;p&gt;这个项目本身就是几乎全部 Vibe Coding 出来的。既然如此，别家的 Hermes、Codex、Claude Code 也应该能轻松接手。所以项目里已经附带了一个 Skill，只需让 Agent 装上这个 Skill，再发给 TA 一本 PDF 链接，跟着指引走完 MinerU API / Cloudflare API 的填写，就可以直接上线了。&lt;/p&gt;
&lt;h2&gt;适合什么内容？&lt;/h2&gt;
&lt;p&gt;比较适合这些场景：教材、课程讲义、培训资料数字化；技术书、课程资料整理成在线文档；公司内部 PDF 手册转知识库；公开资料转成能浏览的网站；个人学习资料整理成长期维护的阅读站点。&lt;/p&gt;
&lt;p&gt;当然不是万能的。PDF 质量、MinerU 解析效果、原书排版复杂度都会影响最终结果。特别是扫描质量差、版式复杂、公式很多的书，还是得靠人检查修正。但至少，最重复、最机械、最容易让人放弃的那部分，可以先交给它。&lt;/p&gt;
&lt;h2&gt;感谢&lt;/h2&gt;
&lt;p&gt;这个项目能跑起来，完全是因为站在几个特别好的开源项目肩膀上。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/opendatalab/MinerU&quot;&gt;MinerU&lt;/a&gt; 做完了最难的那一步：把图片 PDF 重新变成可读的文档结构。没有它，后面的一切都无从谈起。&lt;a href=&quot;https://www.mkdocs.org/&quot;&gt;MkDocs&lt;/a&gt; 和 &lt;a href=&quot;https://squidfunk.github.io/mkdocs-material/&quot;&gt;Material for MkDocs&lt;/a&gt; 提供了我见过最舒服的文档框架和主题，让一本教材看起来真的像一本书。&lt;a href=&quot;https://pages.cloudflare.com/&quot;&gt;Cloudflare Pages&lt;/a&gt; 让部署简单到几乎没有存在感。还有 &lt;a href=&quot;https://vercel.com/docs/agent-resources/skills&quot;&gt;Vercel 的 Agent Skills&lt;/a&gt; 发布框架，给了我一个很好的参考：怎么让一个工具不是只给人用，也能被别的 AI agent 配接。&lt;/p&gt;
&lt;p&gt;这些项目每一个单拿出来都很优秀，我只是把它们串在一起，补上了中间那一段。&lt;/p&gt;
&lt;p&gt;真诚感谢。&lt;/p&gt;
&lt;h2&gt;最后&lt;/h2&gt;
&lt;p&gt;这个事情的原因真的很简单：我不想每次想把一本 PDF 变成网页站点的时候，都重新写一堆临时脚本，再加上 Vibe Coding 在今时今日实在是过于方便，所以才有了这个项目。&lt;/p&gt;
&lt;p&gt;GitHub： &lt;a href=&quot;https://github.com/aronnaxlin/minerupress&quot;&gt;https://github.com/aronnaxlin/minerupress&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>GridTrax 发布日志</title><link>https://aronnax.site/blog/gridtrax_release/</link><guid isPermaLink="true">https://aronnax.site/blog/gridtrax_release/</guid><description>GridTrax 是一款以 Bangumi 番组计划为灵感的自托管「点格子」服务</description><pubDate>Tue, 17 Feb 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;🔗 &lt;strong&gt;GitHub 仓库地址&lt;/strong&gt;：&lt;a href=&quot;https://github.com/aronnaxlin/GridTrax&quot;&gt;https://github.com/aronnaxlin/GridTrax&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;🔗 &lt;strong&gt;在线 Demo 体验&lt;/strong&gt;：&lt;a href=&quot;https://grid.aronnax.site&quot;&gt;https://grid.aronnax.site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;很高兴向各位宣布我的第一款真正意义上为自己而做，且全程 Vibe Coding 的小工具——GridTrax。&lt;/p&gt;
&lt;p&gt;这个项目起源于一个小执念，我想把 Bangumi 的「点格子」功能也添加到豆瓣，但在之后秉持着重复造轮子的想法我干脆自制了一个纯前端服务，做一个属于自己的点格子小工具。&lt;/p&gt;
&lt;p&gt;而经过接近三天和 AI 的讨论和「争吵」过后，GridTrax 项目终于可以发布了！下面请容许我（和 Gemini）为您介绍 GridTrax。&lt;/p&gt;
&lt;h3&gt;GridTrax 是什么？&lt;/h3&gt;
&lt;p&gt;GridTrax 是一个现代、精美且纯粹的前端私有影视剧集进度追踪应用。它的核心理念很简单：&lt;strong&gt;把追剧变成一种视觉享受，并把数据主权彻底还给用户。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;核心亮点：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;打卡式的网格视图&lt;/strong&gt;：灵感来源于 Bangumi。对于包含几十集的动漫或多季美剧，GridTrax 会为每一集生成独立网格，长按或点击即可轻松打卡进度。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;0 后端，纯前端架构&lt;/strong&gt;：由于仅作为个人记录工具，项目完全移除了后端服务依赖。你可以把它部署在 Vercel、Cloudflare Pages，甚至直接丢进 NAS 的 Nginx 里。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WebDAV 私有同步&lt;/strong&gt;：所有的观影数据均保存在本地浏览器中，并原生支持通过标准 WebDAV 协议（配合 OpenList 或私有云盘）进行跨设备同步。你的数据，只存在你自己的硬盘里。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;海量元数据与动态主题&lt;/strong&gt;：集成 TMDB API 获取全球影视数据，每一个剧集都有着精美的主页以供欣赏。还通过引入 Base64 Schema，支持多样配色主题。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bangumi 导入支持&lt;/strong&gt;：通过引入 Bangumi API，支持从 Bangumi 账户导入观看数据，为 Bangumi 用户提供一个备选点格子方案。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;绝对的隐私与轻量&lt;/strong&gt;：作为一个纯前端的项目，GridTrax 的所有逻辑都在你的浏览器里运行：&lt;ul&gt;
&lt;li&gt;你的 TMDB Token 和观影数据&lt;strong&gt;永远不会&lt;/strong&gt;经过任何第三方服务器。&lt;/li&gt;
&lt;li&gt;在没有配置 WebDAV 时，数据完全存储在本地的 LocalStorage。&lt;/li&gt;
&lt;li&gt;构建产物全静态，你可以把它零成本部署在 GitHub Pages、Vercel，或者通过我们提供的 Docker 镜像一键跑在你的群晖、飞牛 NAS 乃至轻量 VPS 里。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/blogimages/gridtrax_release/homepage.png&quot; alt=&quot;主页展示&quot;&gt;&lt;/p&gt;
&lt;div align=&quot;center&quot; style=&quot;color: #999; font-size: 0.85em;&quot;&gt;
主页展示&lt;/div&gt;&lt;p&gt;&lt;img src=&quot;../../assets/blogimages/gridtrax_release/detail_page.png&quot; alt=&quot;详细页展示&quot;&gt;&lt;/p&gt;
&lt;div align=&quot;center&quot; style=&quot;color: #999; font-size: 0.85em;&quot;&gt;详细页展示&lt;/div&gt;&lt;h3&gt;Roadmap&lt;/h3&gt;
&lt;p&gt;GridTrax 目前已经具备了完整的核心功能，但我会继续维护它。接下来的重点包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Bangumi 同步增强&lt;/strong&gt;：研究 TMDB 与 Bangumi 异构数据源之间的映射关系，解决“季”与“独立条目”的结构性隔离。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;支持更多数据源&lt;/strong&gt;：除 TMDB 外，考虑将 IMDB, 豆瓣, Bangumi 等常见元数据提供服务商作为可选媒体源，以支持更多的剧集数据。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PWA 支持与离线模式&lt;/strong&gt;：让它在移动端体验更接近原生 App。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据可视化&lt;/strong&gt;：支持导出美观的个人年度追剧足迹图表。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;结语&lt;/h3&gt;
&lt;p&gt;GridTrax 并不是什么大型工程，但我相信世界之大总有和我一样的需求的同好们，GridTrax 将基于 MIT 协议开源，并提供在线试用网站。无论你是想找个好看的追剧记录工具的影视爱好者，还是同样喜欢折腾 NAS、影视库的极客玩家，都欢迎来体验一下。&lt;/p&gt;
&lt;p&gt;🔗 &lt;strong&gt;GitHub 仓库地址&lt;/strong&gt;：&lt;a href=&quot;https://github.com/aronnaxlin/GridTrax&quot;&gt;https://github.com/aronnaxlin/GridTrax&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;🔗 &lt;strong&gt;在线 Demo 体验&lt;/strong&gt;：&lt;a href=&quot;https://grid.aronnax.site&quot;&gt;https://grid.aronnax.site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;如果 GridTrax 正好戳中了你的痛点，或者你觉得这个 UI 确实做得还不错，&lt;strong&gt;欢迎在 GitHub 上给我点一个 Star！&lt;/strong&gt; 如果有任何 Bug 或新功能建议，也欢迎随时提交 Issue。&lt;/p&gt;
&lt;p&gt;造轮子的快乐，莫过于此。&lt;/p&gt;
</content:encoded></item><item><title>Windows 重装指北</title><link>https://aronnax.site/blog/Windows_Settings/</link><guid isPermaLink="true">https://aronnax.site/blog/Windows_Settings/</guid><description>分享笔者个人会在重装 Windows 系统后干什么</description><pubDate>Sun, 15 Feb 2026 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;本文提供 Windows 11 重装系统后个人的配置分享，不构成建议，亦不提供「怎么重装系统」的教程。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;由于经常在自己的电脑上瞎搞，重装系统成为了我的家常便饭，本文记录我重装系统后会进行的基本设置以及一些软件清单，同时可能会是一篇软件分享。&lt;/p&gt;
&lt;h2&gt;备份清单&lt;/h2&gt;
&lt;p&gt;应至少备份本机的&lt;strong&gt;无线网络驱动&lt;/strong&gt;到非C盘或移动存储设备，以防止重装系统后因驱动原因导致无法访问网络。无线网络驱动以及其他各类驱动可在各OEM厂商的官网售后界面查询下载。&lt;/p&gt;
&lt;p&gt;对于特殊网络环境，应该备份个人的网络环境设置到非C盘或移动存储设备，以防止重装系统后网络环境不通畅造成不必要麻烦。&lt;/p&gt;
&lt;p&gt;如想要备份旧系统下所有驱动文件，可以&lt;strong&gt;管理员身份&lt;/strong&gt;运行 PowerShell，并运行如下备份指令：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-powershell&quot;&gt;mkdir D:\DriveBackup
dism /online /export-driver /destination:&amp;quot;D:\DriverBackup&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;该指令可将当前系统的驱动备份到 &lt;code&gt;D:\DriverBackup&lt;/code&gt; 文件夹，亦可以自行更换路径，重装系统后，通过 &lt;code&gt;Windows + S&lt;/code&gt; 搜索「设备管理器 (Device Manager) 」并进入，点击任意一个未安装驱动的设备，右键选中「更新驱动程序」并选择备份文件夹，点击下一步即可恢复所有驱动备份。详细教程可查阅&lt;a href=&quot;https://www.bilibili.com/read/cv2326902/&quot;&gt;B站专栏&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;此外，请务必备份个人重要文件，笔者个人建议平时使用 Windows 操作系统时至少分一个盘符用来专门存储文件。&lt;/p&gt;
&lt;h2&gt;激活系统&lt;/h2&gt;
&lt;p&gt;如进入 Windows 过程中被强制要求登录微软账户，而因网络不通畅或网卡驱动未加载等原因遇到困难，可以按下 &lt;code&gt;Shift + F10&lt;/code&gt; 呼出命令提示符并输入以下指令：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cmd&quot;&gt;net user your_user_name /add
net localgroup Administrators your_user_name /add
cd OOBE
msoobe &amp;amp;&amp;amp; shutdown -r
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;重启后即可以本地账户登录。详细教程可查阅&lt;a href=&quot;https://blog.csdn.net/wykqh/article/details/153616751&quot;&gt;CSDN&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;如果您因不可抗力暂无能力支付正版 Windows 授权费用，请访问&lt;a href=&quot;https://github.com/zbezj/HEU_KMS_Activator&quot;&gt;神秘链接&lt;/a&gt;激活。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;笔者坚决支持购入正版 Windows，这里仅提供另一种选择，需用户自行承担风险，如有问题概不负责！支持正版，人人有责！&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;系统必要设置&lt;/h2&gt;
&lt;h3&gt;Windows Explorer 设置&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;打开任意文件夹，在三点菜单$\rightarrow$选项页面设置每次打开新 Explorer 窗口进入的界面；在查看$\rightarrow$显示页面设置查看文件扩展名，酌情选择是否查看隐藏文件（对于开发者，建议开启）&lt;/li&gt;
&lt;li&gt;按下 &lt;code&gt;Windows + X&lt;/code&gt;，选择以管理身份打开终端（老版本中为 PowerShell），输入 &lt;code&gt;reg add &amp;quot;HKCU\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32&amp;quot; /f /ve&lt;/code&gt; 以恢复旧版 Windows 右键菜单。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;个性化设置&lt;/h3&gt;
&lt;p&gt;在桌面右键并进入相关个性化设置，有以下选项推荐设置：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;任务栏设置&lt;ul&gt;
&lt;li&gt;开启自动隐藏任务栏，以增大桌面可用空间，同时对于 OLED 屏幕用户减少了烧屏风险&lt;/li&gt;
&lt;li&gt;酌情隐藏「搜索」、「任务视图」、「小组件」等牛皮癣图标。&lt;/li&gt;
&lt;li&gt;将任务托盘的「触摸键盘」选择为「总是开启」，在键盘不在手边时这将是非常实用的功能&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;主题$\rightarrow$桌面图标设计：酌情选择需要开启的图标，对于不熟悉电脑操作的用户，建议开启「此电脑」。&lt;/li&gt;
&lt;li&gt;背景设置、鼠标图标设置等，酌情选择。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;电脑管家设置&lt;/h3&gt;
&lt;p&gt;对于使用微软官方纯净版镜像的笔记本用户，建议下回厂商官方的电脑管家 App（如 MyAsus、联想电脑管家），电脑管家提供了驱动自动下载、硬件设置等必要功能，以笔者的电脑为例，在 MyAsus 软件，可以设置屏幕色彩模式、独显直连、会议降噪麦克风、风扇转速等功能。请至少通过电脑管家等渠道确保自己开启了应享受的功能，例如 120Hz 刷新率！&lt;/p&gt;
&lt;h2&gt;软件列表&lt;/h2&gt;
&lt;p&gt;本章节列出以笔者个人为基准的必备软件列表，仅供参考&lt;/p&gt;
&lt;h3&gt;必备软件&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Google Chrome&lt;/strong&gt; 浏览器（虽然自带 Microsoft Edge 已经搭载 Chromium 内核，但有严重的臃肿、广告问题，极不推荐作为默认浏览器）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bandizip / 7Zip&lt;/strong&gt; 解压缩&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PixPin&lt;/strong&gt; 截图&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;VLC / MPV-lazy&lt;/strong&gt; 基础视频播放&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;EarTrumpet&lt;/strong&gt; 音量控制 微软商店获取&lt;/li&gt;
&lt;li&gt;云盘软件&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;通讯软件&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;微信、QQ&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;飞书/钉钉/企业微信&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;国外通讯软件&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;文书工具&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;MS Office&lt;/strong&gt; 可以使用 Office Tools 进行版本、语言等进行方便管理&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PDFgear&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Typora&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Obsidian&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;音视频工作&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;剪映&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PhotoShop&lt;/strong&gt; 或 &lt;strong&gt;Canva&lt;/strong&gt; 等在线工具&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OBS Studio&lt;/strong&gt; 录屏&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;效率工具&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Everything&lt;/strong&gt; 文件查询&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LocalSend&lt;/strong&gt; 传输文件&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;FlowLaucher/Wox/Listary&lt;/strong&gt; 类 macOS Spotlight 工具&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Weasel&lt;/strong&gt; 小狼毫输入法（Rime 输入法）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Renamer&lt;/strong&gt; 批量重命名&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OnboardMemoryManager&lt;/strong&gt; 罗技设备轻量化驱动管理&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Geek Uninstaller&lt;/strong&gt; 软件卸载&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;图吧工具箱&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;娱乐需求&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Spotify&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;QQ音乐&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Steam&lt;/strong&gt; &lt;a href=&quot;https://store.steampowered.com/&quot;&gt;官网&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UU加速器/雷神加速器等&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WSA/MUMU模拟器&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;EPIC/Xbox/...&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;软件工程专业需要工具（笔者所在专业需求，不构成参考）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Git&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Python&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;JDK&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Node.js&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;JetBrains&lt;/strong&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CLion&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PyCharm&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;IDEA&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;VSCode&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sublime Text&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Antigravity&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Gemini CLI/Codex/Claude Code/OpenCode&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Alaciritty&lt;/strong&gt; 终端&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Oh My Posh&lt;/strong&gt; 终端设置&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WSL&lt;/strong&gt; 或 &lt;strong&gt;Linux&lt;/strong&gt; 双系统~~（并非软件）~~&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ollma&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Docker&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Alma&lt;/strong&gt; (推荐普通用户也尝试的 AI 聊天软件)&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;进阶视频播放/云盘播放（笔者个人爱好，不构成参考）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;MPC-BE&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LAV Filter&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;madVR&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;XySubFilter with libass&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;115浏览器/夸克网盘/百度网盘/...&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rclone&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DAEMON Tools&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Kodi&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以上的各类软件，均建议直接从官网下载或发布页（如 GitHub 或作者官方博客）&lt;del&gt;（如果用包管理器的话，也不知道有没有，如果没有的话反而会多搜索一次）&lt;/del&gt;，不建议通过任何非正规乃至正规软件管家下载（因为软件管家可能获取不到最新版本，以及可能有广告排位等导致下错软件）。关于软件官网的搜索，建议直接搜索引擎获取，由于某度过分的竞价广告（作者主观意见，不构成任何参考），建议使用 Bing 或其他不错的搜索引擎进行搜索，即使如此也同样提醒，一定要人工再三核对所进入的是&lt;strong&gt;软件官网&lt;/strong&gt;而不是垃圾下载站。&lt;/p&gt;
&lt;p&gt;即使是以上推荐的软件，也有可能伴随着恶意软件捆绑，请在安装软件时再三检查安装位置、附加安装软件、服务条款等信息，避免软件捆绑。&lt;/p&gt;
&lt;h2&gt;Chrome 浏览器插件推荐&lt;/h2&gt;
&lt;p&gt;实话实说，现代用户用 PC 做工作，有 90% 的时间是花费在浏览器的，Chrome 浏览器或其他 Chromium 浏览器有着庞大的插件生态用于加强网上冲浪体验，这里介绍几款笔者自用还不错的浏览器插件。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;需要注意的是，Chrome 应用商店访问困难，但仍可以通过第三方网站下载对应的 &lt;code&gt;crx&lt;/code&gt; 文件进行安装。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Tempermonkey&lt;/strong&gt; 用户脚本管理，需要在插件设置里额外开启 Allow User Scripts 获取完整权限，推荐搭配 &lt;a href=&quot;https://greasyfork.org/&quot;&gt;Greasy Fork&lt;/a&gt; 获取脚本&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;uBlock Origin Lite&lt;/strong&gt; 广告拦截，对于 FireFox 等仍支持 Manifest V2 标准的插件来说，亦可以使用 uBlock Origin 原版&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Transy / 沉浸式翻译&lt;/strong&gt; 一键翻译文档、外语视频双语字幕&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GitZip&lt;/strong&gt; 支持在 GitHub 下载单独文件夹&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NextAI Translator&lt;/strong&gt; AI 翻译（更推荐桌面版）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;青柠起始页&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;iCloud Bookmarks&lt;/strong&gt; 与 Safari 浏览器同步&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;另外说一句，笔者使用的 Chrome 主题为 Colors&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;个人建议&lt;/h2&gt;
&lt;p&gt;作为普通用户，安装并设置好以上软件已经可以获得不错的电脑使用体验，当然前提是经过了详细且适宜自己的设置之后。对于编程软件的设置由于笔者学业不精恕不能详细解释，唯二的劝诫是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;如果您也是大学生，不建议使用盗版软件，可以利用 JetBrains 或 GitHub Education Pack 等渠道获取正版且有保障的编程环境。&lt;/li&gt;
&lt;li&gt;&lt;del&gt;推荐装一台 Linux 双系统，或索性购买一台 MacBook，Windows 实在不是一个写代码的好地方。&lt;/del&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;对于视频播放器的配置，笔者个人是一个很小白的赛博仓鼠，随之而来也浅浅对播放器有些了解，在 Windows 平台，并不建议使用广泛好评的 PotPlayer，该软件实际上进阶配置并不方便，且在新版本加入了广告。对于新手用户，个人建议使用开源的 MPV 播放器播放本地视频，但不建议直接使用 GUI 简陋且未做画质优化的原版，而建议使用配置好的 mpv-lazy 项目。&lt;/p&gt;
&lt;p&gt;对于进阶用户，可以使用 MPC-BE + LAV Filters + madVR 的组合套餐，达成极为优秀的观影体验，但同时伴随繁琐的配置过程，建议以 VCB-Studio 的&lt;a href=&quot;https://vcb-s.com/archives/16609&quot;&gt;教程&lt;/a&gt;为基本、&lt;a href=&quot;https://lysandria1985.blogspot.com/&quot;&gt;萬年冷凍庫&lt;/a&gt;的文章为权威参考进行设置。另外请一定容笔者题型：请选择便携版软件进行设置，并在下一次重装系统前做好备份，折腾一次视频播放器设置将耗费很长时间。&lt;/p&gt;
&lt;h2&gt;写在最后&lt;/h2&gt;
&lt;p&gt;肯定会有人问，为什么这么司空见惯的内容，为什么要再写一遍，写的还不一定比别人专业，我想原因有三：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;坚持写作，权当积累&lt;/li&gt;
&lt;li&gt;资源整合&lt;/li&gt;
&lt;li&gt;个人备份&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;所以总的来说本文只是将笔者个人使用习惯做一个记录，对于对电脑有了解的人必定是参考意义不大，更多是对笔者个人的习惯备份，以备不时之需。如果如果能帮助到电脑小白，那更是一件美逝。&lt;/p&gt;
</content:encoded></item><item><title>Git使用笔记</title><link>https://aronnax.site/notes/Git%E6%95%99%E7%A8%8B/</link><guid isPermaLink="true">https://aronnax.site/notes/Git%E6%95%99%E7%A8%8B/</guid><description>The Missing Semester of Your CS Education - Version Control (Git) 课程笔记</description><pubDate>Fri, 13 Feb 2026 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;本笔记基于 &lt;a href=&quot;https://missing.csail.mit.edu/2020/version-control/&quot;&gt;The Missing Semester of Your CS Education - Version Control (Git)&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;本笔记根据原教程文档，使用Kimi K2.5总结并翻译为中文版，并由Gemini 3 Flash Preview补充GitHub与中国开发者需要注意的问题&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;版本控制系统 (VCS) 是用于跟踪源代码（或其他文件和文件夹集合）变更的工具。正如其名，这些工具帮助维护变更历史，并促进协作。Git 是目前事实上的标准版本控制工具。&lt;/p&gt;
&lt;h2&gt;1. Git 的数据模型&lt;/h2&gt;
&lt;p&gt;Git 的独特之处在于它对数据的建模方式。Git 将历史记录建模为一系列&lt;strong&gt;快照 (Snapshots)&lt;/strong&gt;，而不是差异。&lt;/p&gt;
&lt;h3&gt;快照 (Snapshots)&lt;/h3&gt;
&lt;p&gt;Git 将顶级目录中的文件和文件夹集合的历史建模为一系列快照。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Blob (Binary Large Object)&lt;/strong&gt;: 文件内容（仅仅是一堆字节）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tree&lt;/strong&gt;: 目录。将名称映射到 Blob 或其他 Tree（目录可以包含子目录）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Commit&lt;/strong&gt;: 快照。它是被追踪的顶级 Tree，还包含元数据（如作者、信息）和父级 Commit。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;建模历史：关联快照&lt;/h3&gt;
&lt;p&gt;历史是一个&lt;strong&gt;有向无环图 (DAG)&lt;/strong&gt; 的快照。每个提交（Snapshot）都指向其“父级”提交。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;线性历史&lt;/strong&gt;: 每个提交只有一个父级。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;分支与合并&lt;/strong&gt;: 一个提交可能有多个父级（例如合并两个分支时）。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;o &amp;lt;-- o &amp;lt;-- o &amp;lt;-- o &amp;lt;---- o
            ^            /
             \          v
              --- o &amp;lt;-- o
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;数据模型伪代码&lt;/h3&gt;
&lt;p&gt;理解 Git 的数据模型有助于理解其命令：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;// 文件是一堆字节
type blob = array&amp;lt;byte&amp;gt;

// 目录包含命名的文件和目录
type tree = map&amp;lt;string, tree | blob&amp;gt;

// 提交包含父级、元数据和顶级树（快照）
type commit = struct {
    parents: array&amp;lt;commit&amp;gt;
    author: string
    message: string
    snapshot: tree
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;对象和内容寻址 (Content-addressing)&lt;/h3&gt;
&lt;p&gt;在 Git 的数据存储中，所有对象（Blob, Tree, Commit）都通过其 SHA-1 哈希进行内容寻址。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;objects = map&amp;lt;string, object&amp;gt;

def store(object):
    id = sha1(object)
    objects[id] = object

def load(id):
    return objects[id]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;引用 (References)&lt;/h3&gt;
&lt;p&gt;因为 SHA-1 哈希（如 &lt;code&gt;698281bc68...&lt;/code&gt;）难以记忆，Git 使用“引用”（refs）作为 SHA-1 哈希的人类可读名称。引用是指向提交的指针。与不可变的对象不同，引用是&lt;strong&gt;可变&lt;/strong&gt;的。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;master&lt;/strong&gt; (或 main): 通常指向主开发分支的最新提交。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HEAD&lt;/strong&gt;: 特殊引用，指向当前所在的提交（当前检出的位置）。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;references = map&amp;lt;string, string&amp;gt;

def update_reference(name, id):
    references[name] = id

def read_reference(name):
    return references[name]
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;2. 暂存区 (Staging Area)&lt;/h2&gt;
&lt;p&gt;Git 允许你指定哪些修改应该包含在下一个快照中，这就是“暂存区”（或称为 Index）。&lt;/p&gt;
&lt;p&gt;这允许你创建干净的提交，例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;将两个功能的修改分开提交。&lt;/li&gt;
&lt;li&gt;在提交修复时排除调试用的打印语句。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;3. Git 命令行接口&lt;/h2&gt;
&lt;h3&gt;基础 (Basics)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;git help &amp;lt;command&amp;gt;&lt;/code&gt;: 获取命令帮助&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git init&lt;/code&gt;: 初始化新仓库&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git status&lt;/code&gt;: 查看状态（当前工作区和暂存区情况）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git add &amp;lt;filename&amp;gt;&lt;/code&gt;: 添加文件到暂存区&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git commit&lt;/code&gt;: 创建新提交&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git log&lt;/code&gt;: 显示历史日志&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git log --all --graph --decorate&lt;/code&gt;: 可视化历史 DAG（推荐）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git diff &amp;lt;filename&amp;gt;&lt;/code&gt;: 显示工作区相对于暂存区的差异&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git diff &amp;lt;revision&amp;gt; &amp;lt;filename&amp;gt;&lt;/code&gt;: 显示文件在不同快照间的差异&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git checkout &amp;lt;revision&amp;gt;&lt;/code&gt;: 更新 HEAD 和工作区&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;分支与合并 (Branching and Merging)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;git branch&lt;/code&gt;: 显示分支&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git branch &amp;lt;name&amp;gt;&lt;/code&gt;: 创建分支&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git switch &amp;lt;name&amp;gt;&lt;/code&gt;: 切换分支&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git checkout -b &amp;lt;name&amp;gt;&lt;/code&gt;: 创建并切换分支&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git merge &amp;lt;revision&amp;gt;&lt;/code&gt;: 合并指定版本到当前分支&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git mergetool&lt;/code&gt;: 使用工具解决合并冲突&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git rebase&lt;/code&gt;: 变基。将一系列补丁应用到新的基底上（重写历史以保持线性）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;远程 (Remotes)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;git remote&lt;/code&gt;: 列出远程仓库&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git remote add &amp;lt;name&amp;gt; &amp;lt;url&amp;gt;&lt;/code&gt;: 添加远程&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git push &amp;lt;remote&amp;gt; &amp;lt;local branch&amp;gt;:&amp;lt;remote branch&amp;gt;&lt;/code&gt;: 推送对象并更新远程引用&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git branch --set-upstream-to=&amp;lt;remote&amp;gt;/&amp;lt;remote branch&amp;gt;&lt;/code&gt;: 设置本地与远程分支的关联&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git fetch&lt;/code&gt;: 从远程获取对象/引用&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git pull&lt;/code&gt;: 等同于 &lt;code&gt;git fetch; git merge&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git clone&lt;/code&gt;: 从远程下载仓库&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;撤销 (Undo)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;git commit --amend&lt;/code&gt;: 编辑上一次提交的内容/信息&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git reset &amp;lt;file&amp;gt;&lt;/code&gt;: 取消暂存文件&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git restore&lt;/code&gt;: 丢弃更改（恢复文件到最近提交的状态）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;4. 高级 Git&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;git config&lt;/strong&gt;: Git 是高度可配置的。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;git clone --depth=1&lt;/strong&gt;: 浅克隆，不下载完整历史版本。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;git add -p&lt;/strong&gt;: 交互式暂存（可以只暂存文件的部分修改）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;git rebase -i&lt;/strong&gt;: 交互式变基（可以修改、合并、删除历史提交）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;git blame&lt;/strong&gt;: 显示每行代码的最后修改者。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;git stash&lt;/strong&gt;: 暂时移除工作目录的修改（保存现场）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;git bisect&lt;/strong&gt;: 二分查找历史（例如用于定位引入 Bug 的提交）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;.gitignore&lt;/strong&gt;: 指定故意不追踪的文件（如编译产生的临时文件）。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;5. 杂项&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;GUI&lt;/strong&gt;: 虽然有许多 Git GUI 客户端，但建议先学习命令行接口。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Shell 集成&lt;/strong&gt;: 在 Shell 提示符中显示 Git 状态（如当前分支、是否有修改）非常有用（推荐 &lt;a href=&quot;https://github.com/olivierverdier/zsh-git-prompt&quot;&gt;zsh-git-prompt&lt;/a&gt; 或 Oh My Zsh）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;编辑器集成&lt;/strong&gt;: 如 Vim 的 &lt;a href=&quot;https://github.com/tpope/vim-fugitive&quot;&gt;fugitive.vim&lt;/a&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GitHub&lt;/strong&gt;: Git 不等于 GitHub。GitHub 是一个托管 Git 仓库的平台，提供了 Pull Requests (PR) 等协作功能。其他类似平台还有 GitLab, BitBucket 等。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;6. 初始配置与环境优化&lt;/h2&gt;
&lt;h3&gt;初始配置&lt;/h3&gt;
&lt;p&gt;安装 Git 后，首先应配置个人信息，这会出现在你的 Commit 元数据中：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git config --global user.name &amp;quot;Your Name&amp;quot;
git config --global user.email &amp;quot;your_email@example.com&amp;quot;
# 设置默认分支名为 main (顺应现代习惯)
git config --global init.defaultBranch main
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;SSH 密钥配置&lt;/h3&gt;
&lt;p&gt;相比 HTTPS，使用 SSH 协议在推送代码时更方便（免去输入 Token 的烦恼）：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;生成密钥：&lt;code&gt;ssh-keygen -t ed25519 -C &amp;quot;your_email@example.com&amp;quot;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;查看并复制公钥：&lt;code&gt;cat ~/.ssh/id_ed25519.pub&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;将内容添加到 GitHub Settings -&amp;gt; SSH and GPG keys 中。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;7. 中国开发者额外注意 (Network &amp;amp; Proxies)&lt;/h2&gt;
&lt;p&gt;在国内环境下，直接访问 GitHub 往往不稳，建议进行以下优化：&lt;/p&gt;
&lt;h3&gt;配置代理&lt;/h3&gt;
&lt;p&gt;如果你本地开启了代理工具（如 7890 端口），可以配置 Git 走代理：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HTTP/HTTPS 协议：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 设置代理
git config --global http.proxy http://127.0.0.1:7890
git config --global https.proxy http://127.0.0.1:7890

# 取消代理
git config --global --unset http.proxy
git config --global --unset https.proxy
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;提升克隆速度&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;浅克隆&lt;/strong&gt;: &lt;code&gt;git clone --depth 1 &amp;lt;url&amp;gt;&lt;/code&gt; 只下载最新一次提交，极大减少大仓库下载量。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;国内镜像&lt;/strong&gt;: 如果仅需下载，可以使用 &lt;code&gt;gitclone.com&lt;/code&gt; 等镜像地址，或者通过 Gitee 的“导入已有仓库”功能作为中转。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;文件名乱码&lt;/h3&gt;
&lt;p&gt;解决 &lt;code&gt;git status&lt;/code&gt; 中文文件名显示为数字转义符的问题：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git config --global core.quotepath false
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;8. GitHub 协作流程&lt;/h2&gt;
&lt;p&gt;GitHub 扩展了 Git 的社交属性，核心流程包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Fork&lt;/strong&gt;: 在服务端克隆一份别人的仓库到你的账号下，你可以自由修改。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pull Request (PR)&lt;/strong&gt;: 你修改完后，向原作者发起“合并请求”。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Issue&lt;/strong&gt;: 讨论 Bug 或新功能的地方。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GitHub CLI (&lt;code&gt;gh&lt;/code&gt;)&lt;/strong&gt;: 官方工具，支持在命令行直接操作 PR、Issue 和 Repo，非常适合 Geek。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;9. 学习资源&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://git-scm.com/book/zh/v2&quot;&gt;Pro Git&lt;/a&gt;&lt;/strong&gt;: &lt;strong&gt;强烈推荐&lt;/strong&gt;。阅读前 5 章即可掌握大部分用法。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://ohshitgit.com/&quot;&gt;Oh Shit, Git!?!&lt;/a&gt;&lt;/strong&gt;: 修复常见 Git 错误的简短指南。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://learngitbranching.js.org/&quot;&gt;Learn Git Branching&lt;/a&gt;&lt;/strong&gt;: 一个学习 Git 分支操作的浏览器游戏。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://jwiegley.github.io/git-from-the-bottom-up/&quot;&gt;Git from the Bottom Up&lt;/a&gt;&lt;/strong&gt;: 深入解释 Git 的底层实现细节。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>我的2025年音乐总结</title><link>https://aronnax.site/blog/2025MusicWrapped/</link><guid isPermaLink="true">https://aronnax.site/blog/2025MusicWrapped/</guid><description>2025年的音乐回顾与十佳专辑评选，分享在音乐设备、种类尝鲜方面的体验与发现。</description><pubDate>Thu, 25 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;2026 年即将到来，趁着各家音乐 App 都在争先恐后发表 Wrapped 之际，按照往年惯例发一个没人看的音乐总结。&lt;/p&gt;
&lt;h2&gt;音乐设备&lt;/h2&gt;
&lt;h3&gt;音源&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;QQ 音乐&lt;/strong&gt; 曾几何时我还是一个流媒体反冻π，认为月亮只有国外的圆，捧着 Spotify 和 Apple Music 不放，不过从 2024 年我逐渐开始返回童年时用的 QQ 音乐，主要还是在于其曲库之全。可能有人会说 Spotify 的曲库理应比 QQ 音乐持有的版权多，而他们没想到的是 TME 从来没说过自己手里的歌是有版权的（）。一个比较明显的例子就是知名日本 CityPOP 歌手山下达郎始终未向流媒体开放自己的专辑版权，英语社区和日语社区用户常常感慨道「要听山下达郎，只能是音乐节或者购买实体唱片了吧」，而国内的听众只需要打开任意一款音乐软件就能畅听，也算是一种老钟特色曲库优势吧。
&lt;img src=&quot;../../assets/blogimages/2025MusicWrapped/123.png&quot; alt=&quot;Pasted image 20251225152817&quot;&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Spotify / Apple Music&lt;/strong&gt; 即使转入 QQ 音乐，我依旧坚持为一个海外平台充钱，上半年是苹果音乐，下半年则转为声破天，转平台的原因并不复杂，只是想体验一下换软件的新鲜感罢了。而为这些平台付费的理由也非常简单，却和上面的文字显得冲突：享受它们带来的版权优势。主要分为两种：一是在国内平台需要付费解锁的专辑，如今年陶喆的《普普愚乐》在国内上线半小时后即可在 Apple Music 收听，无需付费；二是所谓禁曲，包括罗公的 Queen&amp;#39;s Rd. East 等敏感歌曲，或是冰岛神秘女歌手这样直接被 Ban 的歌手，甚至可能是吴亦凡的原版《大碗宽面》。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Qobuz&lt;/strong&gt; 我已经于今年下半年基本告别本地音乐，毕竟手头没有好的播放设备，也没有好的网络服务来支持我在线播放本地音乐。不过我于 2025 年年初发现了 Qobuz 这个 Bug 级别的网站，充点小钱可以换来海量高音质本地歌曲，有关这个平台的更多用法我写在了&lt;a href=&quot;https://mp.weixin.qq.com/s/meOpf11JtYFZVpy9pdNtEQ&quot;&gt;公众号文章&lt;/a&gt;。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;音乐设备&lt;/h3&gt;
&lt;p&gt;一年的时间跨度实在太长，以至于我都没有意识到我在 25 年购入了很多新鲜的音乐设备，这里来讲一讲。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;AirPods Pro 2&lt;/strong&gt; 是我于 25 年元旦当天购入的，可以说极大的提高了我的生活品质。实际上我并不为其降噪效果或是空间音频而感动，但它和 Apple 生态的联动在我这里体验非凡，通勤路上点头即可让 Siri 朗读最新通知，自习时，只点击设备名即可快速切换媒体源，以及在 MacBook 上可以直接调节降噪 / 通透模式而无需低头看手机，都是细致入微的 Only Apple Can Do 的体验。不过他的缺点对我来说也很致命：我的耳朵和他的耳塞并不适配，带上一个小时已经堪比坐牢，即使是购买了 Spinfit 的耳塞也并未好转太多。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bose QC45&lt;/strong&gt; 是 618 期间购入的，是一个非常「蓝牙耳机」的蓝牙耳机，降噪扎实、佩戴舒适、续航惊人都是不得不夸的优点，此外它还在这个冬季担任了我的耳罩，不至于让骑电动车的过程中被冻掉耳朵。但人总不能既要又要，不得不承认它的音质确实是听个响级别的，当然这不怪 Bose，要怪我的荷包买不起 Bose QC Ultra。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OPPO Enco X3&lt;/strong&gt; 是我比较失望的产品，购买动机仅仅是周边好几个 OPPO 用户购买了这款耳机，我就也跟风购买，只可惜这款耳机并不符合我对它的美好幻想：素皮耳机壳摸上去十分廉价，不如给 AirPods Pro 2 带上 MUJI 的耳机盒，连接 iPhone 和 MacBook 只有 AAC，切换阵营后连接我的三星 Galaxy Tab S9 后也找不到 LDAC 的入口，导致我并不能听到所谓大师调音，音质只能给到拉。至于所谓独立芯片提供空间音频，我并没有明显感受。所以虽然这款耳机评价不错，但结合我的个人使用体验只能说非常不堪。现在已经将它踢出音乐配件行列，沦为躺床上看番用的耳机。&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;此外的设备则是我之前购买现在还在用的，包括森海塞尔 HD25 Light、兴戈 EA500、Earpods USB-C 以及许多蹭听的设备。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;种类尝鲜&lt;/h2&gt;
&lt;p&gt;2025 年我并没有开阔一个新的曲风，更多是在原有的喜好上进行扩展。&lt;/p&gt;
&lt;p&gt;我最高兴的是我在写《星际牛仔》的个人短评时想到了 &lt;a href=&quot;https://www.bilibili.com/video/BV1p24y1P7VH&quot;&gt;HOPICO 的一期视频&lt;/a&gt;，让我重视起了「自己发掘音乐」的乐趣，这其中最重要的环节莫过于 &lt;a href=&quot;https://www.discogs.com/&quot;&gt;Discogs&lt;/a&gt; 这个网站在我生活中的出现，像是看番要去 Bangumi 查监督，看电影要去豆瓣看演员一样，从小对音乐一窍不通的我开始懵懂地跳脱推荐算法牢笼，开始通过 Discogs 来找一些音乐背后的联系。我仍然记得我第一次尝试在这个网站深究一个歌手的经历：当我在这个网站上键入「宇多田光」，我对我的偶像有了进一步的认识——原来她的父亲宇多田照實正是她音乐背后的御用制作人，而早在她出道之前就有一张家庭实验室式的乐队——Cubic U，在这支乐队的 I&amp;#39;ll Be Stronger 专辑中，能听到 14 岁的宇多田光的来自于 1997 年的音乐。&lt;/p&gt;
&lt;p&gt;这一年我同样发现了几位我喜爱的音乐人 / 团体，上半年我听到了 GORILLAZ 的 Demon Days，他们是一个虚拟乐团，哪怕你并不了解这个团队的二次元人设，也不知道他们退掉水星奖提名的故事，他们另类音乐中的曲风碰撞也足以吊起你的胃口，是我非常推荐的一张专辑。下半年我回到了电子音乐，YMO 成员之一的细野晴臣是我最近的研究对象，这位音乐巨匠不仅是 YMO 这个风靡全球的乐团的「始作俑者」，也是 CityPOP 曲风的奠基人之一，仍记得我在 2024 年冬天还在玩梗 HOSONO HOUSE 这张日产美式民谣中的《住所不定無職低収入》的标题，却没想到会于一年后发现他会是 YMO 第「零」张专辑《はらいそ》的主创，也是 PACIFIC 这张 CityPOP 先驱专辑的三位创作者之一。&lt;/p&gt;
&lt;h2&gt;十佳专辑&lt;/h2&gt;
&lt;p&gt;和往年一样，我同样评出了我的十佳专辑，包含九张我喜爱的专辑和一张对我意义深远的 Special Award。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/blogimages/2025MusicWrapped/Covershare-%E5%8D%A1%E6%8B%89OK.%E5%8F%B0%E5%8C%97.%E6%88%91.png&quot; alt=&quot;Covershare-卡拉OK.台北.我&quot;&gt;&lt;/p&gt;
&lt;p&gt;尤其喜欢《动物的悲歌》&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/blogimages/2025MusicWrapped/Covershare-Demon-Days.png&quot; alt=&quot;Covershare-Demon Days&quot;&gt;
&lt;img src=&quot;../../assets/blogimages/2025MusicWrapped/Covershare-COWBOY-BEBOP.png&quot; alt=&quot;Covershare-COWBOY BEBOP (Original Motion Picture Soundtrack)&quot;&gt;&lt;/p&gt;
&lt;p&gt;《星际牛仔》不是我最喜欢的动漫作品，但是是我唯一一个写过小论文的动漫作品&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/blogimages/2025MusicWrapped/Covershare-F1-The-Movie.png&quot; alt=&quot;Covershare-F1® The Movie (Original Score By Hans Zimmer)&quot;&gt;&lt;/p&gt;
&lt;p&gt;今年夏天在北京电影博物馆看了这部电影，IMAX影厅的音响让我印象深刻&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/blogimages/2025MusicWrapped/Covershare-Pearl-Pierce.png&quot; alt=&quot;Covershare-Pearl Pierce&quot;&gt;
&lt;img src=&quot;../../assets/blogimages/2025MusicWrapped/Covershare-%E5%A7%8A%E5%A6%B9.png&quot; alt=&quot;Covershare-姊妹 (2017 Remastering)&quot;&gt;&lt;/p&gt;
&lt;p&gt;阿妹的出道专，《水蓝色眼泪》让我印象深刻&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/blogimages/2025MusicWrapped/Covershare-Whiplash.png&quot; alt=&quot;Covershare-Whiplash - The 5th Mini Album - EP&quot;&gt;&lt;/p&gt;
&lt;p&gt;今年浅浅尝试了一下韩团，WHIPLASH确实顶&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/blogimages/2025MusicWrapped/Covershare-%E6%84%9B%E4%BA%BA%E5%90%8C%E5%BF%97.png&quot; alt=&quot;Covershare-愛人同志 (香港版).png&quot;&gt;&lt;/p&gt;
&lt;p&gt;我不好说&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/blogimages/2025MusicWrapped/Covershare-Paraiso.png&quot; alt=&quot;Covershare-Paraiso.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;YMO的第零张专辑，发布在乐团成立之前&lt;/p&gt;
&lt;h3&gt;Special Award：梦想家 - 方大同&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/blogimages/2025MusicWrapped/Covershare-The-Dreamer.png&quot; alt=&quot;Covershare-The Dreamer.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;晚安，大同。&lt;/p&gt;
</content:encoded></item><item><title>Open the Door For Fortune Guide</title><link>https://aronnax.site/blog/Open%20the%20Door%20For%20Fotune/</link><guid isPermaLink="true">https://aronnax.site/blog/Open%20the%20Door%20For%20Fotune/</guid><description>A simple documentation for my CS50P final project</description><pubDate>Mon, 22 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Open the Door for Fortune&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;A command line game to guess songs, based on ffmpeg and iTunes Search API&lt;/p&gt;
&lt;/blockquote&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/PZFdilc2i_0?si=WJm_F2VS1f8_PPnm&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&gt;&lt;/iframe&gt;&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;This project is inspired by a TV program called &lt;a href=&quot;https://tv.cctv.com/lm/kmdj/&quot;&gt;Kaimen Daji (Open the Door for Fortune)&lt;/a&gt; in China. In the program, the players are required to guess the names of random songs based on their intro melody. If they guess the correct answer, they receive some cash as rewards; otherwise, they fail.&lt;/p&gt;
&lt;p&gt;This project will simulate its rules. The user will be asked to listen to slices of different songs and guess the song&amp;#39;s title, and if he/she guesses correctly, his/her score will increase by one.&lt;/p&gt;
&lt;p&gt;There are two modes to choose:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;billboard mode&lt;/strong&gt; can pick some songs from billboard&amp;#39;s hot-100 playlist randomly and let the user guess their titles.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;custom mode&lt;/strong&gt; allows the user to input some artists&amp;#39; names, analyze their popular songs in Apple Music, and let the user guess these songs&amp;#39; titles in a random order.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The number of songs and whether to turn on &amp;quot;cheat mode&amp;quot; can also be modified. See &amp;quot;How to Use&amp;quot; for more information.&lt;/p&gt;
&lt;h2&gt;How to Use&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Before running the program, please ensure the following dependencies are met:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Install Python Dependencies:&lt;/strong&gt; Install the required Python packages by running: &lt;code&gt;pip install -r requirements.txt&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Install FFmpeg:&lt;/strong&gt; Ensure that the FFmpeg multimedia framework is installed and accessible via your system&amp;#39;s command line (CLI). &lt;a href=&quot;https://www.ffmpeg.org/download.html&quot;&gt;Download here&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This project does not have a GUI interface, so the user is required to run this project from the command line. Overall, the format is as follows.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;python project.py [-n number] [-m mode] [-c]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/blogimages/Open%20the%20Door%20for%20Fortune/command-line.jpeg&quot; alt=&quot;command-line guide&quot;&gt;&lt;/p&gt;
&lt;p&gt;The specific usage of these arguments is shown in the command line interface.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-n&lt;/code&gt; or &lt;code&gt;--number&lt;/code&gt;: customize the number of songs/questions, 10 by default.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-m&lt;/code&gt; or &lt;code&gt;--mode&lt;/code&gt;: specify the game mode, &lt;code&gt;billboard&lt;/code&gt; by default.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-c&lt;/code&gt; or &lt;code&gt;--cheat&lt;/code&gt;: enable cheat mode.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then, the user can follow the instructions on the command line.&lt;/p&gt;
&lt;h2&gt;Functions&lt;/h2&gt;
&lt;h3&gt;&lt;code&gt;project.py&lt;/code&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;get_artistId(artist_name)&lt;/code&gt; can search an artist&amp;#39;s name and return his/her artist ID in iTunes&lt;/li&gt;
&lt;li&gt;&lt;code&gt;get_track_by_artistId(artist_id)&lt;/code&gt; can get an artist&amp;#39;s popular track (name and preview link) through his/her artist id in iTunes&lt;/li&gt;
&lt;li&gt;&lt;code&gt;get_track_by_title(song_title)&lt;/code&gt; can get a track (name and preview link) directly by searching it with iTunes Search API&lt;/li&gt;
&lt;li&gt;&lt;code&gt;download_preview_audio(preview_url, filename)&lt;/code&gt; downloads an audio file from url and saves it&lt;/li&gt;
&lt;li&gt;&lt;code&gt;make_audio_clip(input_file, output_file)&lt;/code&gt; extracts a ten-second clip from the audio file (0-10s)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;file_renamer(filename)&lt;/code&gt; renames the file to fit the playsound package&lt;/li&gt;
&lt;li&gt;&lt;code&gt;remove_file(filename)&lt;/code&gt; removes a specific file&lt;/li&gt;
&lt;li&gt;&lt;code&gt;guess_music(term, mode=&amp;quot;song&amp;quot;, cheat=False)&lt;/code&gt; is the core function that handles guessing a song, with two modes, and optional cheat mode&lt;/li&gt;
&lt;li&gt;&lt;code&gt;scorer(playlist, is_cheat=False, mode=&amp;quot;song&amp;quot;)&lt;/code&gt; sets a loop and calculates the final score&lt;/li&gt;
&lt;li&gt;&lt;code&gt;billboard_mode(number, is_cheat=False)&lt;/code&gt; gets songs from billboard&amp;#39;s hot-100 playlist&lt;/li&gt;
&lt;li&gt;&lt;code&gt;custom_artist_mode(number, is_cheat=False)&lt;/code&gt; gets custom songs from user-inputted artists&lt;/li&gt;
&lt;li&gt;&lt;code&gt;parse_arguments()&lt;/code&gt; manages command line arguments&lt;/li&gt;
&lt;li&gt;&lt;code&gt;print_hints()&lt;/code&gt; prints usage hints&lt;/li&gt;
&lt;li&gt;&lt;code&gt;main()&lt;/code&gt; runs the main program logic&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;code&gt;test_project.py&lt;/code&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Functions in &lt;code&gt;test_project.py&lt;/code&gt; test functions in &lt;code&gt;project.py&lt;/code&gt; by &lt;code&gt;pytest&lt;/code&gt;, and some functions are not suitable for testing.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Packages&lt;/h2&gt;
&lt;p&gt;All Packages: &lt;a href=&quot;./requirements.txt&quot;&gt;requirements&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/python/cpython/blob/3.14/Lib/argparse.py&quot;&gt;argparse&lt;/a&gt; is a standard Python library used to write user-friendly command-line interfaces by easily handling and parsing arguments passed from the shell.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://requests.readthedocs.io/&quot;&gt;requests&lt;/a&gt; is a simple, yet elegant HTTP library for Python, used to make API calls to iTunes and other services.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://kkroening.github.io/ffmpeg-python/&quot;&gt;ffmpeg-python&lt;/a&gt; is a Python wrapper for FFmpeg, used for audio processing to extract 10-second clips from audio files for the game.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pypi.org/project/playsound/&quot;&gt;playsound&lt;/a&gt; is a simple Python module for playing sounds, used to play the song clips during gameplay.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/guoguo12/billboard-charts&quot;&gt;billboard&lt;/a&gt; is a Python API for the Billboard Hot 100 charts, used to retrieve current popular songs for the billboard game mode.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.pytest.org/&quot;&gt;pytest&lt;/a&gt; is a framework for easily writing simple and scalable tests for Python projects, used for unit testing the functions in test_project.py.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;APIs&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/iTuneSearchAPI/index.html&quot;&gt;iTunes Search API&lt;/a&gt; is a web service that allows developers to search Apple&amp;#39;s iTunes service for content like music, movies, artists, apps, and books, returning structured data in JSON format.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Software&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;The user is required to install ffmpeg to use the audio splitter function.&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Openlist服务器端配置备忘录</title><link>https://aronnax.site/notes/Openlist%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%AB%AF%E9%85%8D%E7%BD%AE%E5%A4%87%E5%BF%98%E5%BD%95/</link><guid isPermaLink="true">https://aronnax.site/notes/Openlist%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%AB%AF%E9%85%8D%E7%BD%AE%E5%A4%87%E5%BF%98%E5%BD%95/</guid><description>详细的Openlist服务器端配置指南，涵盖了Docker Compose搭建方式、网络环境配置、代理设置以及Nginx反向代理配置等关键步骤。</description><pubDate>Mon, 08 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;笔者今天晚上突发奇想想去看一部番，但是身边只有MacBook一台，并未配置Openlist来挂在夸克网盘看番，鉴于手边设备实在太多，且有在iPhone上配置Openlist不便的顾虑，故打算用本人租用的一台阿里云轻量服务器构建远程的Openlist服务。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;选择搭建方式&lt;/h1&gt;
&lt;p&gt;笔者本人所拥有的这台阿里云轻量服务器搭载了CentOS 7.6，且在之前已经配置了Docker, Nginx以及诸多前置服务，为了方便省事，最终选择官方文档所推荐的&lt;code&gt;Docker Compose&lt;/code&gt;方法，详见&lt;a href=&quot;https://doc.oplist.org/guide/installation/docker&quot;&gt;官网&lt;/a&gt;的这篇文章。&lt;/p&gt;
&lt;h1&gt;网络环境配置&lt;/h1&gt;
&lt;p&gt;选择Docker配置的最大困难在于Docker官方镜像在国内很多地区连接苦难，也是耗费笔者最多时间的步骤，为了减少等待时间，笔者走了包括但不限于尝试手动安装Linux版本、使用官网脚本、配置三方镜像等弯路，最后总结出的解决方法为给服务器配置网络环境。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;首先，ssh连接服务器时套用本地代理&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;ssh -R your_local_port:127.0.0.1:your_local_port root@your_server_ip
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;注意将服务器IP和网络端口做替换&lt;/p&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;在服务器设置代理&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;export http_proxy=http://127.0.0.1:your_port
export https_proxy=http://127.0.0.1:your_port
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;其中&lt;code&gt;your_port&lt;/code&gt;和第一部所填端口一致。&lt;/p&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;为Docker设置代理&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;私以为这是关键一步，笔者在这里浪费诸多时间。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 创建代理目录
mkdir -p /etc/systemd/system/docker.service.d

# 写入配置
cat &amp;gt; /etc/systemd/system/docker.service.d/http-proxy.conf &amp;lt;&amp;lt;EOF
[Service]
Environment=&amp;quot;HTTP_PROXY=http://127.0.0.1:your_port&amp;quot;
Environment=&amp;quot;HTTPS_PROXY=http://127.0.0.1:your_port&amp;quot;
Environment=&amp;quot;NO_PROXY=localhost,127.0.0.1,registry.aliyuncs.com&amp;quot;
EOF

# 重启Docker
systemctl daemon-reload
systemctl restart docker
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;拉取Docker&lt;/h1&gt;
&lt;p&gt;建议严格遵循官方步骤，即&lt;a href=&quot;https://doc.oplist.org/guide/installation/docker&quot;&gt;官网这篇文章&lt;/a&gt;的后半部分&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;创建&lt;code&gt;docker-compose&lt;/code&gt;文件&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;mkdir -p /opt/openlist
cd /opt/openlist
nano docker-compose.yml
&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;写入以下内容&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;# docker-compose.yml
services:
  openlist:
    image: &amp;#39;openlistteam/openlist:latest&amp;#39;
    container_name: openlist
    user: &amp;#39;0:0&amp;#39; # Please replace `0:0` with the actual user ID and group ID you want to use to run OpenList.
    volumes:
      - &amp;#39;./data:/opt/openlist/data&amp;#39;
    ports:
      - &amp;#39;5244:5244&amp;#39;
    environment:
      - UMASK=022
    restart: unless-stopped
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;按&lt;code&gt;control + o&lt;/code&gt;后按&lt;code&gt;enter&lt;/code&gt;保存，按&lt;code&gt;control + x&lt;/code&gt;退出&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;运行容器&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;docker compose pull
docker compose up -d
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;[Optional] 设置Nginx&lt;/h1&gt;
&lt;p&gt;这里假设阁下想要将域名&lt;code&gt;openlist.example.com&lt;/code&gt;用于访问Openlist服务，需要按照以下步骤执行。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在域名管理界面添加A记录，子域名填&lt;code&gt;openlist&lt;/code&gt;，指向服务器IP&lt;/li&gt;
&lt;li&gt;编辑Nginx文件，创建一个单独的&lt;code&gt;.conf&lt;/code&gt;文件以方便管理&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;nano /etc/nginx/conf.d/openlist.conf
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-nginx&quot;&gt;server {
    listen 80;
    server_name openlist.example.com; # &amp;lt;--- 修改这里

    # 如果你之后用 Certbot 申请证书，这里会自动变成 HTTPS 配置
    # 目前先配 HTTP 跑通流程

    location / {
        proxy_pass http://127.0.0.1:5244; # Openlist 默认端口

        # --- 基础头信息 ---
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Port $server_port;

        # --- 关键优化配置 (看番/传文件必加) ---

        # 1. 允许大文件上传 (否则网页端上传大文件会报错)
        client_max_body_size 20000m;

        # 2. 视频拖拽进度条支持 (Range Requests)
        # 这一步对于 Infuse/Web 播放器至关重要
        proxy_set_header Range $http_range;
        proxy_set_header If-Range $http_if_range;

        # 3. 防止重定向问题
        proxy_redirect off;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;使用&lt;code&gt;certbot&lt;/code&gt;生成SSL证书&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;certbot --nginx -d openlist.example.com
&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;重载Nginx服务&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;nginx -t
systemctl reload nginx
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;配置注意&lt;/h1&gt;
&lt;p&gt;不出意外的话，现在访问&lt;code&gt;openlist.example.com&lt;/code&gt;即可回到熟悉的Openlist主页，请在添加网盘时使用302重定向，防止播放视频卡顿。&lt;/p&gt;
</content:encoded></item><item><title>IELTS Writing Structures</title><link>https://aronnax.site/notes/IELTS-Writing-Structures/</link><guid isPermaLink="true">https://aronnax.site/notes/IELTS-Writing-Structures/</guid><description>A comprehensive guide to various IELTS writing structures for both academic and general training modules, covering opinion essays, discussion essays, report writing structures, and practical expressions for data description.</description><pubDate>Tue, 18 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;大作文&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://aronnax.site/posts/e9e80472/&quot;&gt;原因句式&lt;/a&gt;
&lt;a href=&quot;https://aronnax.site/posts/ielts-result/&quot;&gt;结果句式&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;观点类&lt;/h2&gt;
&lt;p&gt;要点：I think ...，彻底倒向某种观点&lt;/p&gt;
&lt;h3&gt;一边倒结构（同意）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;开篇：（背景句）+ 转述题目（Some people think/believe/argue/maintain that ... / It is thought/believed/argued/maintained that ... / It is true that... 复述题目所有意思）+ 表明观点（I completely agree with this idea.）&lt;/li&gt;
&lt;li&gt;主体段 1：首先，同意的第 1 个理由&lt;/li&gt;
&lt;li&gt;主体段 2：其次，同意的第 2 个理由&lt;/li&gt;
&lt;li&gt;结尾：重申观点（+ 分论点）（In conclusion, 我认为...）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;一边倒结构（反对）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;开篇：（背景句）+ 转述题目 + 表明观点（I completely disagree with this idea &lt;strong&gt;and I believe...&lt;/strong&gt;）&lt;/li&gt;
&lt;li&gt;主体段 1：首先，反对的第 1 个理由&lt;/li&gt;
&lt;li&gt;主体段 2：其次，反对的第 2 个理由&lt;/li&gt;
&lt;li&gt;结尾：重申观点（+ 分论点）（In conclusion, 我认为...）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;讨论类&lt;/h2&gt;
&lt;p&gt;要点：两边都讲，但是要明确自己支持哪一方&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;开篇：（背景句）+ 转述题目（While some people think that ..., others believe that... / People have different views about whether ... or ...）+ 表明观点（我认为）&lt;/li&gt;
&lt;li&gt;主体段 1：其中一方面分论点（There are several reasons why it can be argued that... / It can be argued that ...）首先，... 其次，...&lt;/li&gt;
&lt;li&gt;主体段 2：另外一方面的分论点（&lt;strong&gt;However&lt;/strong&gt;, I would agree with those who believe that...）首先，... 其次，...（我同意的观点）&lt;/li&gt;
&lt;li&gt;结尾：重申观点（+ 分论点）（In conclusion, 虽然一些人认为...，但是我认为...）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;报告类&lt;/h2&gt;
&lt;p&gt;要点：原因、问题（结果）、解决办法&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;开篇：（背景句）+ 转述题目（Some people think/believe/deem/argue/maintain that ... / It is thought/believed/deemed/argued/maintained that ... / It is true that ...）+ 主要内容（&lt;strong&gt;The focus of this essay is to illustrate&lt;/strong&gt; the causes and solutions of this problem/phenomenon/issue.）&lt;/li&gt;
&lt;li&gt;主体段 1：产生这个问题的原因有很多（There are many reasons for this problem.）。原因 1 + 论证；原因 2 + 论证&lt;/li&gt;
&lt;li&gt;主体段 2：有一些相应的办法（To cope with this problem, some effective measures/actions/steps should be taken.）。办法 1 + 论证；办法 2 + 论证（对应上一段）&lt;/li&gt;
&lt;li&gt;结尾：总结（In conclusion, ...）&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;问题：随着 ...，一些相关的问题可以被预料到：As ..., several related problems can be anticipated. 问题 1 + 解释；问题 2 + 解释&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;混合类&lt;/h2&gt;
&lt;p&gt;要点：使用前三种结构的主体段&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;开篇：（背景句）+ 转述题目（Some people think/believe/deem/argue/maintain that ... / It is thought/believed/deemed/argued/maintained that ... / It is true that ...）+ 主要内容（The focus of this essay is to illustrate the causes of this phenomenon.）+ 表明观点（As far as I am concerned, ...）&lt;/li&gt;
&lt;li&gt;主体段 1：回答第 1 个问题（对应题型主体段）&lt;/li&gt;
&lt;li&gt;主体段 2：回答第 2 个问题（对应结构主题段）&lt;/li&gt;
&lt;li&gt;结尾：In conclusion, 总结上文&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;小作文&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Introduction: The ... compares/illustrates in ...(转述题目所有信息)&lt;/li&gt;
&lt;li&gt;Summary: &lt;strong&gt;It is clear&lt;/strong&gt;/noticeable that ...(对比所有信息的相似性和差异性)&lt;/li&gt;
&lt;li&gt;Body Paragraph 1: &lt;strong&gt;Looking at the information in more detail, we can see that...&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Body Paragraph 2: As for ..., / Moreover,..../ However,...&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;数据类&lt;/h2&gt;
&lt;p&gt;要点：&lt;strong&gt;数据越大越重要&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;动态图（数据随着时间不断变化；按照时间分段）：起始时间 + 数据 + 变化趋势 + 终点时间 + 终点数据&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;静态图（数据不随着时间变化或只变 1 次）：数据最大必须写；第二大和最小可写可不写；不大不小不能写（除非字数太少）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;实用表达如下&lt;/p&gt;
&lt;h3&gt;数据变化&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;1. 变化趋势&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;上升、下降&lt;/li&gt;
&lt;li&gt;上升 V: rise; increase; ascend; swell; go up; climb up; boom; soar&lt;/li&gt;
&lt;li&gt;上升 N: rise; increase; ascent; swell; upward trend; growth; boom; soar&lt;/li&gt;
&lt;li&gt;下降 V: fall; decline; decrease; reduce; go down; collapse; plunge; slump&lt;/li&gt;
&lt;li&gt;下降 N: fall; decline; decrease; reduction; downward trend; slide; collapse; slump&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;2. 幅度表达&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;幅度大 ADV: dramatically; surprisingly; strikingly; enormously; remarkably; substantially; noticeably; considerably; significantly; obviously&lt;/li&gt;
&lt;li&gt;幅度大 ADJ: dramatic; surprising; striking; enormous; remarkable; substantial; noticeable; considerable; significant; obvious&lt;/li&gt;
&lt;li&gt;幅度小 ADV: moderately; slightly; steadily; gradually; slowly; minimally&lt;/li&gt;
&lt;li&gt;幅度小 ADJ: moderate; slight; steady; gradual; slow; small&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;3. 常见句型结构&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;事物 + 方向 (V) + 幅度 (ADV)&lt;/li&gt;
&lt;li&gt;There is/was a 幅度 (ADJ) + 方向 (N) + in 事物&lt;/li&gt;
&lt;li&gt;事物 + had/experienced a 幅度 (ADJ) + 方向 (N)&lt;/li&gt;
&lt;li&gt;时间段/地点 + witness/notice/observe/see a 幅度 (ADJ) + 方向 (N) + in 事物
&lt;em&gt;时间段: the period between ... and ... / from ... to ...&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;4. 最大值表达&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;事物 + peaked at + 数据&lt;/li&gt;
&lt;li&gt;事物 + reached a peak of + 数据&lt;/li&gt;
&lt;li&gt;事物 + reached a plateau at + 数据&lt;/li&gt;
&lt;li&gt;事物 + arrived at a climax at + 数据&lt;/li&gt;
&lt;li&gt;事物 + hit a peak at + 数据&lt;/li&gt;
&lt;li&gt;事物 + reached a maximum number/amount of + 数据&lt;/li&gt;
&lt;li&gt;事物 + soar/rocket to a highest point of + 数据&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;描述数据&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;介词短语补充数据。（from...to..., between ... and..., at..., by...）rise to 上升到... / rise by 上升了...&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;Birth rates have also fallen in developed countries over the past 50 years, from 2.8 children per family to 1.6.&lt;/li&gt;
&lt;li&gt;Over the following 5 years, the waste output of companies B and C rose by around 2 tonnes, but the figure for company A fell by approximately 1 tonne.&lt;/li&gt;
&lt;li&gt;By 2040, it is thought that around 27% of the Japanese population will be 65 years old or more, while the figures for Sweden and the USA will be slightly lower, at about 25% and 23% respectively.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;符号补充法：英语中的括号和破折号可以补充数据。&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;By contrast, Germans were the lowest overall spenders, with roughly the
same figures (just under £150,000) for each of the six products.&lt;/li&gt;
&lt;li&gt;While girls rated activities such as art and craft highly ---- just under 60% stated that they enjoyed these in their spare time, only 35% of boys opted
for creative pastimes.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;利用 with 结构（with sb. + sth. / with sth. + sth.）&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;There is a sharp increase between 6:00 and 8:00 in the morning, with 400 people using the station in the morning.&lt;/li&gt;
&lt;li&gt;By contrast, historic houses and monuments were visited by only 16% of the sample, while wildlife parks and zoos were the least popular of the four types of tourist attractions, with only 9% of visitors.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;定语从句&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;The second most popular activity, which attracted 80% of boys and 60% of girls, was playing electronic or computer games.&lt;/li&gt;
&lt;li&gt;Next came central heating ownership, which rose from 37% of households in 1972 to 64% in 1983.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start=&quot;5&quot;&gt;
&lt;li&gt;分词可以用于补充数据。（现在分词 doing 表主动；过去分词 done 表被动）&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;The second most popular activity, attracting 80% of boys and 60% of girls, was playing electronic or computer games.&lt;/li&gt;
&lt;li&gt;Next came central heating ownership, rising from 37% of households in 1972 to 64% in 1983.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start=&quot;6&quot;&gt;
&lt;li&gt;&lt;p&gt;百分比和分数的转换表达&lt;/p&gt;
&lt;p&gt;26%: about a quarter; just over a quarter
33%: one third; one in three; one out of three
50%: a half
74%: around three quarters; just under three quarters&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;百分比常用句型&lt;/p&gt;
&lt;p&gt;事物 occupy/represent/account for/constitute XXX%&lt;/p&gt;
&lt;p&gt;The percentage/proportion of 事物 stands at/is XXX%&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;地图&lt;/h2&gt;
&lt;p&gt;变化前&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;X 位于
X is/lies(lay)/is located/is situated/is built in/on/to the east/west/south/north/left/right of ... *in 表示 A 在 B 内；on 表示 A 和 B 相邻；to 表示 A 和 B 分开&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A 在 B 对面
A is on the opposite side of B. A is opposite B.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;在附近
Be close to; be near to; be in proximity of; be in close proximity to&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;在中间
Be halfway between... and...; exactly/roughly in the middle of
变化后&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;原来的
The original/ previous/ former ...&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;变化后&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;X 消失
X disappeared/was removed.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A 变成 B
A became B.
A was replaced/substituted by B.
A gave way to B.
A was transformed/reconstructed/redeveloped/converted/turned over/changed
to/into B.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;新增加
A newly built ... is/lies(lay)/is located/is situated/is built in/on/to the east/west/south/north/left/right of ...
A new ... was added to ...
A new ... was built/set up/constructed/completed and opened ...
The year 2000 saw two additions to the village: a pond in the northern part and a vegetable garden on the opposite side.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;X 的面积变大/小
The size of X was extended/enlarged/reduced. The size of X doubled/halved.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;流程图&lt;/h2&gt;
&lt;p&gt;实用表达
表顺序
The first stage involves... In the next stage,...
In the following stage,... In the last stage,... Subsequently,... Firstly,...
Secondly,... Then,... Finally,...
表时间
At the same time, Simultaneously, During...
In the course of... Before this,... After this,...
表结果
Consequently,...
As a result,...
... so that ...
表目的
The first step is to...
The next step is to ...
The last step is to ...
... in order (not) to...
... in order that ...
... so as (not) to...&lt;/p&gt;
</content:encoded></item><item><title>Sentence Structures for Giving Results(IELTS)</title><link>https://aronnax.site/notes/Sentence-Structures-for-Giving-Results-IELTS/</link><guid isPermaLink="true">https://aronnax.site/notes/Sentence-Structures-for-Giving-Results-IELTS/</guid><description>Essential sentence structures for expressing results in IELTS writing, covering possibility, probability, ease/difficulty, necessity, and desirability with practical examples and alternative expressions.</description><pubDate>Thu, 16 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;!-- # 雅思写作结果句式 --&gt;&lt;ol&gt;
&lt;li&gt;&lt;p&gt;有可能（实现）&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;make it &lt;strong&gt;possible&lt;/strong&gt; for sb. to do sth. = &lt;strong&gt;allow/enable&lt;/strong&gt; sb. &lt;strong&gt;to&lt;/strong&gt; do sth.&lt;/li&gt;
&lt;li&gt;make it &lt;strong&gt;impossible&lt;/strong&gt; for sb. to do sth. = &lt;strong&gt;prevent&lt;/strong&gt; sb. &lt;strong&gt;from&lt;/strong&gt; doing sth.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;很可能（概率）&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;make it [more] &lt;strong&gt;likely&lt;/strong&gt; for sb. to do sth. = raise/increase the &lt;strong&gt;likelihood&lt;/strong&gt; for sb. to do sth.&lt;/li&gt;
&lt;li&gt;make it [more] &lt;strong&gt;unlikely&lt;/strong&gt; for sb. to do sth. = reduce the &lt;strong&gt;likelihood&lt;/strong&gt; for sb. to do sth.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;难易&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;make it &lt;strong&gt;easier&lt;/strong&gt; for sb. to do sth. = help/&lt;strong&gt;facilitate&lt;/strong&gt; sb. to do sth.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;make it &lt;strong&gt;harder&lt;/strong&gt; for sb. to do sth. = &lt;strong&gt;hinder&lt;/strong&gt; someone&amp;#39;s &lt;strong&gt;doing&lt;/strong&gt; sth. / &lt;strong&gt;noun&lt;/strong&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;hinder v. 阻碍；妨碍；阻挡 + 名词/名词性&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;必要&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;make it &lt;strong&gt;necessary&lt;/strong&gt; for sb. to do sth. = &lt;strong&gt;require&lt;/strong&gt; sb. to do sth.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;make it &lt;strong&gt;unnecessary&lt;/strong&gt; for sb. to do sth. = &lt;strong&gt;obviate/eliminate&lt;/strong&gt; the need for sb. to do sth.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;obviate v. 消除；排除；打消&lt;/p&gt;
&lt;p&gt;eliminate v. 排除；清除；消除&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;想要&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;make it &lt;strong&gt;desirable&lt;/strong&gt; for sb. to do sth. = &lt;strong&gt;encourage&lt;/strong&gt; sb. to do something&lt;/li&gt;
&lt;li&gt;make it &lt;strong&gt;undesirable&lt;/strong&gt; for sb. to do sth. = &lt;strong&gt;discourage&lt;/strong&gt; sb. to do something&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>《新概念英语》二三册 Lesson 1 简要评测</title><link>https://aronnax.site/blog/%E4%BA%8C%E5%86%8C%E4%B8%89%E5%86%8CLesson1%E6%B5%8B%E8%AF%84/</link><guid isPermaLink="true">https://aronnax.site/blog/%E4%BA%8C%E5%86%8C%E4%B8%89%E5%86%8CLesson1%E6%B5%8B%E8%AF%84/</guid><description>对新概念英语第二册和第三册第一课的详细评测分析，通过对比两册的语法结构、难度和学习要点，为英语学习者提供参考。</description><pubDate>Sat, 11 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;有个朋友问基础不好的话学新2好还是新3好，这里简要以我的视角对两个课本的第一课文章做一个纯主观分析，不构成任何参考。&lt;/p&gt;
&lt;h1&gt;A Private Conversation(NCE2-L1)&lt;/h1&gt;
&lt;p&gt;Last week I went to the theatre. I had a very good seat. The play was very interesting, but I did not enjoy it. A young man and a young woman &lt;mark&gt;were sitting&lt;/mark&gt; behind me. They &lt;mark&gt;were talking&lt;/mark&gt; loudly. I got very angry because I could not hear the actors.&lt;/p&gt;
&lt;p&gt;I turned round and looked at the man and the woman angrily. They did not &lt;mark&gt;pay any attention&lt;/mark&gt;. In the end, I could not bear it. I turned round again.&lt;/p&gt;
&lt;p&gt;“I can’t hear a word!” I said angrily.&lt;/p&gt;
&lt;p&gt;“&lt;mark&gt;It’s none of your business&lt;/mark&gt;,” the young man said rudely. “This is a private conversation!”&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;was/were doing 过去进行时&lt;/li&gt;
&lt;li&gt;pay attention [to] 注意&lt;/li&gt;
&lt;li&gt;It&amp;#39;s none of your business 不关你的事&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;A Puma at Large(NCE3-L1)&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;at large 逍遥自在&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Pumas are large, cat-like animals &lt;mark&gt;which&lt;/mark&gt; are found in America. &lt;strong&gt;When [reports came into London Zoo] &lt;mark&gt;that&lt;/mark&gt; a wild puma &lt;mark&gt;had been spotted&lt;/mark&gt; forty-five miles south of London&lt;/strong&gt;, they were &lt;mark&gt;not taken&lt;/mark&gt; seriously. However, as the evidence began to accumulate, experts from the Zoo felt &lt;strong&gt;obliged&lt;/strong&gt; to investigate, for the descriptions given by people &lt;mark&gt;who&lt;/mark&gt; claimed to have seen the puma were extraordinarily similar.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;oblige v. 强迫；迫使&lt;/p&gt;
&lt;p&gt;obliged adj. 感激的&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;When [reports came into London Zoo] &lt;mark&gt;that&lt;/mark&gt; a wild puma &lt;mark&gt;had been spotted&lt;/mark&gt; forty-five miles south of London&lt;/strong&gt;, they were &lt;mark&gt;not taken&lt;/mark&gt; seriously.&lt;ul&gt;
&lt;li&gt;主句 They were not taken seriously. be taken + adv. 被怎么样地对待&lt;/li&gt;
&lt;li&gt;时间状语从句 When ...，表示当...时，when后加完整句子，其中嵌套了一个同位语从句&lt;/li&gt;
&lt;li&gt;时间状语从句中，主句 Reports came into London Zoo.&lt;/li&gt;
&lt;li&gt;时间状语从句中，同位语从句 A wild puma had been spotted forty-five miles south of London. &lt;strong&gt;that&lt;/strong&gt;引导同位语从句，同位语从句用于「解释说明」所修饰的词，在本句中，为对report的解释说明，同位语从句结构为 n. [...] &lt;strong&gt;that&lt;/strong&gt; sentence. 需要注意同位语从句与定语从句的差别&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;had done/had been done，过去完成时&lt;/li&gt;
&lt;li&gt;动词+ing/ed可转变为形容词，其中加ing变为使动态形容词（主动），修饰对象为原动词的施动者；加ed变为被动态形容词（被动），修饰对象为原动词的受动者，从以下例子中解释。&lt;ul&gt;
&lt;li&gt;interest v. 使...感兴趣 English articles interest me. 英文文章很让我感兴趣。&lt;/li&gt;
&lt;li&gt;interesting adj. 令人感兴趣的 English articles are interesting (to me). 英语文章（对我来说）是令人感兴趣的。&lt;/li&gt;
&lt;li&gt;interested adj. 感兴趣的 I am interested (in English articles). 我（对英语文章）感兴趣。&lt;/li&gt;
&lt;li&gt;所以在&amp;quot;Experts from the Zoo felt &lt;strong&gt;obliged&lt;/strong&gt; to investigate.&amp;quot;中，obliged 并非字典上查到的「感激的」之意，而是源自其动词 oblige 强迫， 所以在这里为「被强迫的」，地道的翻译为「有必要的」&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The hunt for the puma began in a small village where a woman picking blackberries saw “a large cat” only five yards away from her. It immediately ran away when she saw it, and experts confirmed that a puma will not attack a human being unless it is cornered. The search proved difficult, &lt;strong&gt;for&lt;/strong&gt; the puma was often observed in one place in the morning and in another place twenty miles away in the evening.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;原因句式，扩展内容详见&lt;a href=&quot;https://aronnax.site/posts/e9e80472/&quot;&gt;https://aronnax.site/posts/e9e80472/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;because/as为从属连词，引导原因从句&lt;/li&gt;
&lt;li&gt;for表示原因实际上为并列连词，可参见and/but的用法，并非引导从句而是使用&amp;quot;Sentence A, for sentence B.&amp;quot;的结构，句子A和句子B均为独立句子&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;mark&gt;Wherever&lt;/mark&gt; it went, it left behind a trail of dead deer and small animals like rabbits. &lt;strong&gt;Paw&lt;/strong&gt; prints were seen in a number of places, and puma &lt;strong&gt;fur&lt;/strong&gt; was found clinging to bushes. Several people complained of cat-like noises at night, and a businessman on a fishing trip saw the puma up a tree.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;trail n. 痕迹；踪迹&lt;/p&gt;
&lt;p&gt;paw n. （动物的）爪&lt;/p&gt;
&lt;p&gt;fur n. （动物浓厚的）软毛&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;wherever/whenever, whatever/whoever/however等wh-ever表示无论，从句结构较复杂&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The experts were now fully convinced that the animal was a puma, but where had it come from? &lt;mark&gt;As&lt;/mark&gt; no pumas had been reported missing from any zoo in the country, this one must have been &lt;mark&gt;in the possession of&lt;/mark&gt; a private collector and somehow managed to escape.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;in the possession of ... 为...所有&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The hunt went on for several weeks, but the puma was not caught. It is disturbing to think that a dangerous wild animal is still at large in the quiet countryside.&lt;/p&gt;
</content:encoded></item><item><title>Sentence Structures for Giving Reasons(IELTS)</title><link>https://aronnax.site/notes/%E9%9B%85%E6%80%9D%E5%86%99%E4%BD%9C%E5%8E%9F%E5%9B%A0%E5%8F%A5%E5%9E%8B/</link><guid isPermaLink="true">https://aronnax.site/notes/%E9%9B%85%E6%80%9D%E5%86%99%E4%BD%9C%E5%8E%9F%E5%9B%A0%E5%8F%A5%E5%9E%8B/</guid><description>Comprehensive guide to sentence structures for expressing reasons in IELTS writing, including conjunctions, causative verbs, passive constructions, and contextual phrases with practical examples.</description><pubDate>Sun, 05 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;!-- # 雅思写作原因句式 --&gt;&lt;blockquote&gt;
&lt;p&gt;A为原因，B为结果&lt;/p&gt;
&lt;p&gt;&lt;em&gt;noun&lt;/em&gt;指名词或名词性短语&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;mark&gt;so/therefore&lt;/mark&gt;&lt;/p&gt;
&lt;p&gt;A, so B.&lt;/p&gt;
&lt;p&gt;A. Therefore, B&lt;/p&gt;
&lt;p&gt;therefore = thus, hence, as a result, in consequence, for this reason&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;mark&gt;as/since/because&lt;/mark&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;mark&gt;because of&lt;/mark&gt; + noun&lt;/p&gt;
&lt;p&gt;because of = owing to, due to, as a result of, thanks to&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;owe B to A 把B归咎于A&lt;/li&gt;
&lt;li&gt;A (can) be owed to B B可以被归咎于A&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;the &lt;mark&gt;reason/cause&lt;/mark&gt; is ...&lt;/p&gt;
&lt;p&gt;the reason &lt;strong&gt;why&lt;/strong&gt; B is A (sentence)&lt;/p&gt;
&lt;p&gt;the reason/cause for &lt;em&gt;noun&lt;/em&gt; is ... (noun)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A(&lt;em&gt;noun&lt;/em&gt;) &lt;mark&gt;causes&lt;/mark&gt; B(&lt;em&gt;noun&lt;/em&gt;)&lt;/p&gt;
&lt;p&gt;cause = lead to, result in, give rise to, be responsible for, contribute to, trigger&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;cause ... to do ...&lt;/p&gt;
&lt;p&gt;The aggravating of air pollution has &lt;strong&gt;caused&lt;/strong&gt; the incidence of asthma to &lt;strong&gt;increase&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;B &lt;mark&gt;is caused by&lt;/mark&gt; A&lt;/p&gt;
&lt;p&gt;be caused by = result from, be the result of, originate from, stem from, &lt;strong&gt;&lt;em&gt;derive from, be derived from&lt;/em&gt;&lt;/strong&gt;, be attributed to, arise from&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;derive *v.*从 … 衍生出；起源于；来自；（从 … 中）得到，获得&lt;/p&gt;
&lt;p&gt;derive（衍生，起源） from = be caused by;&lt;/p&gt;
&lt;p&gt;be derived（获得，得到） from = be caused by&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;which causes/causing ... （跟结果）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;which is caused by/caused by ... （跟原因）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;..., &lt;mark&gt;which means that&lt;/mark&gt; ...&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;mark&gt;with&lt;/mark&gt; &lt;em&gt;noun&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;with ... doing/done（既可以做原因，又可以做结果）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A, &lt;mark&gt;so that&lt;/mark&gt; B. B是想要达成的结果（目的性）&lt;/p&gt;
&lt;p&gt;A, so as to do sth.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;(in order) &lt;mark&gt;to&lt;/mark&gt; do&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>YouTube搬运视频指北</title><link>https://aronnax.site/notes/YouTube%E6%90%AC%E8%BF%90%E8%A7%86%E9%A2%91%E6%8C%87%E5%8C%97/</link><guid isPermaLink="true">https://aronnax.site/notes/YouTube%E6%90%AC%E8%BF%90%E8%A7%86%E9%A2%91%E6%8C%87%E5%8C%97/</guid><description>详细的YouTube视频搬运指南，涵盖视频挑选、下载工具yt-dlp使用、字幕提取、AI转录工具Whisper应用、字幕制作及压制等全流程技术说明。</description><pubDate>Sun, 28 Sep 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;免责声明：本文仅用于技术学习与个人备份，不建议用于任何侵权用途。&lt;/p&gt;
&lt;p&gt;叠甲：本人完全业余，本教程本意是为朋友写个入门教程，所言之处有诸多错误，概不修正。&lt;/p&gt;
&lt;p&gt;叠甲：直接搬运视频有版权风险！本质上是未经授权转载，请联系Youtube频道主获取版权授权，或自行承担法律风险，笔者对相关版权问题概不负责。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;做YouTube视频翻译和搬运，除去最核心的翻译文稿，还有诸多过程，大致总结为挑选、下载、提取字幕、翻译SRT、压制硬字幕，这里简略说说。&lt;/p&gt;
&lt;h1&gt;1. 挑选视频&lt;/h1&gt;
&lt;p&gt;首先，确保你的网络通畅，以免卡顿。&lt;/p&gt;
&lt;p&gt;在YouTube查找你喜爱的视频，且尽量确保B站上没有其他up主已经做过这期视频的翻译，以免后续投稿冲突和不必要的麻烦。&lt;/p&gt;
&lt;p&gt;找到合适的视频后，复制该期视频的链接。&lt;/p&gt;
&lt;h1&gt;2. 下载视频&lt;/h1&gt;
&lt;p&gt;在这里推荐使用yt-dlp命令行界面操作，也顺便讲一下GUI的使用。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/yt-dlp/yt-dlp&quot;&gt;yt-dlp&lt;/a&gt;是一款基于命令行的多功能音频/视频下载器，是许多付费下载视频软件的核心部分，但实际上该命令行工具开源且免费，只是纯命令行界面相对用户不友好，实际上并不需要掌握过多技巧，学会复制粘贴即可。&lt;/p&gt;
&lt;p&gt;在安装yt-dlp之前，推荐安装&lt;a href=&quot;https://ffmpeg.org&quot;&gt;ffmpeg&lt;/a&gt;，这是一款开源免费的多媒体处理工具&lt;/p&gt;
&lt;h2&gt;安装（Windows）&lt;/h2&gt;
&lt;p&gt;在&lt;a href=&quot;https://github.com/yt-dlp/yt-dlp/releases/tag/2025.09.26&quot;&gt;Release&lt;/a&gt;界面下载对应平台的安装包，Windows选择&lt;code&gt;yt-dlp.exe&lt;/code&gt;。假设你下载到了&lt;code&gt;D:\yt-dlp&lt;/code&gt;文件夹，进入该文件夹，单击地址栏，键入&lt;code&gt;cmd&lt;/code&gt;，打开该目录的终端界面，键入以下命令检查是否安装成功。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-powershell&quot;&gt;yt-dlp --version
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果想全局使用yt-dlp命令，可将其加入环境变量：按下win + s，键入&lt;code&gt;environment variables&lt;/code&gt;进入环境变量配置页，再次点击右下角的&lt;code&gt;environment variables&lt;/code&gt;，找到可以配置用户变量和系统变量的地方，在系统变量的文件中，进入&lt;code&gt;path&lt;/code&gt;，在弹出的页面中new一个路径，填入&lt;code&gt;D:\yt-dlp&lt;/code&gt;（以实际目录为准），以添加环境变量。之后&lt;code&gt;win + r&lt;/code&gt;后键入&lt;code&gt;cmd&lt;/code&gt;，再次输入&lt;code&gt;yt-dlp --version&lt;/code&gt;检查是否成功。&lt;/p&gt;
&lt;h2&gt;安装（macOS）&lt;/h2&gt;
&lt;p&gt;macOS安装yt-dlp十分简单，可以使用第三方包管理器&lt;code&gt;homebrew&lt;/code&gt;，之后在Terminal输入以下命令。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;brew install yt-dlp
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;关于homebrew如何安装，请在网上查询。&lt;/p&gt;
&lt;h2&gt;使用&lt;/h2&gt;
&lt;p&gt;关于yt-dlp的所有配置，请在Github页面查询详细信息，详见&lt;a href=&quot;https://github.com/yt-dlp/yt-dlp&quot;&gt;yt-dlp&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;对于下载视频，只需要打开Terminal，输入&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cmd&quot;&gt;yt-dlp URL
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;例如&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cmd&quot;&gt;yt-dlp https://www.youtube.com/watch?v=dQw4w9WgXcQ
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;将会下载该视频到&lt;code&gt;D:\yt-dlp&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;可以使用&lt;code&gt;-o&lt;/code&gt;指令输出到指定目录，例如&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cmd&quot;&gt;yt-dlp -o &amp;quot;E:\Download\neverGonnaGiveYouUp&amp;quot; https://www.youtube.com/watch?v=dQw4w9WgXcQ
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;将会输出视频到&lt;code&gt;E:\Download\neverGonnaGiveYouUp&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;当然，你可能需要下载指定质量的视频，可以使用&lt;code&gt;-F&lt;/code&gt;指令，例如&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;yt-dlp -F URL
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;将会得到类似以下表格&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/blogimages/YouTube%E6%90%AC%E8%BF%90%E8%A7%86%E9%A2%91%E6%8C%87%E5%8C%97/image-20250928093132335.png&quot; alt=&quot;image-20250928093132335&quot;&gt;&lt;/p&gt;
&lt;p&gt;然后使用&lt;code&gt;-f&lt;/code&gt;指定输出的格式，例如&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cmd&quot;&gt;yt-dlp -f 625+234 URL
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果你安装了ffmpeg，视频轨和音频轨将会自动合并，否则，可能需要你使用Premiere等软件手动合并。&lt;/p&gt;
&lt;p&gt;同时，也可以暴力的使用以下指令下载&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-CMD&quot;&gt;yt-dlp -f bestvideo+bestaudio URL
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;yt-dlp也可以用于下载字幕、视频封面等，请自行查询。&lt;/p&gt;
&lt;p&gt;当然，以下指令完全可以混合使用，比如&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cmd&quot;&gt;yt-dlp -f bestvideo+bestaudio -o &amp;quot;E:\Download&amp;quot; URL
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;关于yt-dlp的更多常用用法，可以参考&lt;a href=&quot;https://ivonblog.com/posts/yt-dlp-usage/&quot;&gt;Ivon的部落格&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;yt-dlp也有响应开源的GUI客户端，如&lt;a href=&quot;https://github.com/kannagi0303/yt-dlp-gui&quot;&gt;yt-dlp-gui&lt;/a&gt;，请参考其GitHub主页进行安装。&lt;/p&gt;
&lt;h1&gt;3. 提取字幕&lt;/h1&gt;
&lt;p&gt;字幕涉及时间轴，对于新手用户来说并不好操作，好在AI时代的来临，自动提取原文字幕以及打轴已经实现，下面通过介绍OpenAI的Whisper来展示如何提取字幕，当然，有的视频自带CC字幕，可以通过yt-dlp直接下载。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;需要注意的是，Whisper依赖ffmpeg。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/openai/whisper&quot;&gt;Whisper&lt;/a&gt;是由OpenAI（ChatGPT的研发公司）开发的开源文字转语音工具，源码只能通过纯命令行解决，好在由于其开源特性，很多开源的图形化界面客户端已被开源社区推出，例如Windows上的&lt;a href=&quot;https://github.com/Const-me/Whisper&quot;&gt;Whisper Desktop&lt;/a&gt;以及跨平台的&lt;a href=&quot;https://github.com/chidiwilliams/buzz/tree/main&quot;&gt;Buzz&lt;/a&gt;，Whisper Desktop的使用非常简单，参考官方文档即可，亦或在B站上有大量教程，笔者使用MacBook码这篇文章，遂使用Buzz来做演示。&lt;/p&gt;
&lt;p&gt;首先安装Buzz，在这里依旧使用Homebrew。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;brew install --cask buzz
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;Buzz上架了App Store，现在可以直接于Mac App Store下载Buzz。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;进入后，从菜单左上角添加一期视频&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/blogimages/YouTube%E6%90%AC%E8%BF%90%E8%A7%86%E9%A2%91%E6%8C%87%E5%8C%97/image-20250928103809899.png&quot; alt=&quot;image-20250928103809899&quot;&gt;&lt;/p&gt;
&lt;p&gt;在弹出窗口做出选择，注意导出srt字幕文件：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/blogimages/YouTube%E6%90%AC%E8%BF%90%E8%A7%86%E9%A2%91%E6%8C%87%E5%8C%97/image-20250928104337122.png&quot; alt=&quot;image-20250928104337122&quot;&gt;&lt;/p&gt;
&lt;p&gt;选择模型时根据自己GPU算力情况做出抉择，模型越大，需要处理的时间越长，转录精度越高。在示范时我选择了Small模型翻译了Never Gonna Give You Up歌曲，发现转录结果并不理想，所以还是推荐Medium模型起手。当然，对于歌曲，你可以选择去除背景声再做识别以提高精度，比如使用Ultimate Vocal Remover这款软件。&lt;/p&gt;
&lt;p&gt;翻译后输出的srt字幕会输出在视频文件的相同目录下。&lt;/p&gt;
&lt;h1&gt;4. 制作字幕&lt;/h1&gt;
&lt;p&gt;字幕组常用的字幕制作软件为&lt;a href=&quot;https://aegisub.org/downloads/&quot;&gt;Aegisub&lt;/a&gt;，各种意义上非常权威的桜都字幕组在B站上为其做了一系列教程，可以参考&lt;a href=&quot;https://www.bilibili.com/video/BV19F411w7m5&quot;&gt;他们的频道&lt;/a&gt;，同时，也可以参考台湾地区YouTube频道主PAPAYA电脑教室频道的&lt;a href=&quot;https://www.youtube.com/watch?v=x46-su3l6Gc&quot;&gt;相关教程&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;在这里需要说的是，在前期你可以套用一些其他字幕组开源的样式，比如为LinusTechTips制作字幕的&lt;a href=&quot;https://www.nixiesubs.com&quot;&gt;辉光字幕组&lt;/a&gt;，他们开源了字幕样式，可以在&lt;a href=&quot;https://github.com/Kilo19/NixieVideoKit&quot;&gt;这里&lt;/a&gt;下载「辉光样式.ass」，下载后用Aegisub打开，并在Subtitle -&amp;gt; Styles Manager二级菜单中将相关样式复制到系统样式中即可。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/blogimages/YouTube%E6%90%AC%E8%BF%90%E8%A7%86%E9%A2%91%E6%8C%87%E5%8C%97/image-20250928110734507.png&quot; alt=&quot;image-20250928110734507&quot;&gt;&lt;/p&gt;
&lt;h1&gt;5. 压制字幕&lt;/h1&gt;
&lt;p&gt;如果你制作的是srt字幕，可以试着通过CC字幕形式上传到B站视频。&lt;/p&gt;
&lt;p&gt;如果你制作的是ass字幕，建议通过将字幕与视频压制为硬字幕视频以方便上传，推荐使用ffmpeg进行压制，命令行命令如下（将视频文件和字幕文件放入同一位置且在命令行中进入相关路径）：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;ffmpeg -i input.mp4 -vf ass=subtitle.ass -crf 16 output.mp4
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;会把&lt;code&gt;subtitle.ass&lt;/code&gt;字幕压制进&lt;code&gt;input.mp4&lt;/code&gt;视频，在同文件夹输出为&lt;code&gt;output.mp4&lt;/code&gt;&lt;/p&gt;
&lt;h1&gt;6. 更多教程&lt;/h1&gt;
&lt;p&gt;各大字幕组、压制组都非常有开源精神，可以访问他们的Github主页和官网来访问更多教程，比如VCB-Studio推出的关于视频压制的&lt;a href=&quot;https://github.com/vcb-s/guides&quot;&gt;教程&lt;/a&gt;，以及他们提供&lt;a href=&quot;https://vcb-s.com/archives/1114&quot;&gt;字体包&lt;/a&gt;（请注意版权！）&lt;/p&gt;
</content:encoded></item><item><title>Python环境配置相关内容备忘录</title><link>https://aronnax.site/notes/Python%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE%E7%9B%B8%E5%85%B3%E5%86%85%E5%AE%B9%E5%A4%87%E5%BF%98%E5%BD%95/</link><guid isPermaLink="true">https://aronnax.site/notes/Python%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE%E7%9B%B8%E5%85%B3%E5%86%85%E5%AE%B9%E5%A4%87%E5%BF%98%E5%BD%95/</guid><description>关于Python环境配置的详细备忘录，涵盖了多Python环境管理、解释器切换、虚拟环境创建、包管理等内容，帮助开发者更好地管理Python开发环境。</description><pubDate>Fri, 19 Sep 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;起因&lt;/h2&gt;
&lt;p&gt;在一台电脑上，可能有多个Python环境，每个环境都附带了大量的包，例如在我的mac上，就有macOS自带Python，homebrew所安装的Python以及Anaconda所附带的Python环境，管理起来非常混乱。&lt;/p&gt;
&lt;p&gt;今日在完成CS50P作业时，发现我若在本地VS Code中&lt;code&gt;import pytest&lt;/code&gt;，会被pylance报错为&lt;code&gt;import &amp;quot;pytest&amp;quot; could not be resolved&lt;/code&gt;，甚是苦恼，故和ChatGPT对话良久，最终解决问题，先记录在这里，以免日后需要。这些内容零碎杂乱，遂不讲顺序直接分点列出。&lt;/p&gt;
&lt;p&gt;叠甲：本人还没有搞懂这些问题的核心原理，仅作为解决问题的一次记录，不构成参考价值，如跟随本文执行命令导致出错，我不会也不将为你解答任何问题。&lt;/p&gt;
&lt;h2&gt;1. 如何更改使用的Interpreter&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;打开py文件，在VSCode右下角有一个显示Python版本号的地方，单击即可选择&lt;/li&gt;
&lt;li&gt;在VSCode中，按下&lt;code&gt;command + shift + p&lt;/code&gt;或&lt;code&gt;ctrl + shift + p&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;2. 如何查看当前终端环境下正在使用的Interpreter&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;在macOS/Linux下，在terminal执行&lt;code&gt;which python&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;在Windows下，在cmd执行&lt;code&gt;where python&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;3. pip指令和Python Interpreter的关系&lt;/h2&gt;
&lt;p&gt;每个Interpreter负责自己所管辖的包，pip 安装的包只属于当前 Python 解释器对应的环境，不能直接在另一个解释器使用。举例来说，在&lt;code&gt;homebrew/bin/python3&lt;/code&gt;解释器下使用&lt;code&gt;pip install&lt;/code&gt;所安装的包并不能为&lt;code&gt;anaconda/bin/python&lt;/code&gt;这个解释器所用&lt;/p&gt;
&lt;h2&gt;4. 什么是虚拟环境&lt;/h2&gt;
&lt;p&gt;虚拟环境相当于在所处项目下新建一个Python环境，用于和其他项目的Python环境所区分，主要是为了防止各个包版本不同而导致的污染（例如现有项目A和项目B，项目A使用pytest的3.1版本，项目B使用pytest的3.2版本，若不加以区分容易导致兼容性问题），虚拟环境可以理解为建立了一个「虚拟机」或「沙盒」，来防止污染问题。&lt;/p&gt;
&lt;p&gt;新建一个虚拟环境并不会从建立前的解释器集成包，新建一个虚拟环境后立马执行&lt;code&gt;pip list&lt;/code&gt;会发现只有pip一个包，所以每新建一个虚拟环境都需要重新部署各类包。&lt;/p&gt;
&lt;h2&gt;5. 如何新建一个虚拟环境&lt;/h2&gt;
&lt;h3&gt;在当前目录新建一个虚拟环境&lt;/h3&gt;
&lt;p&gt;在命令行执行&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;python -m venv .
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;将会在当前项目目录新建一个没有显示名称的虚拟环境，该环境会被放到项目根目录的&lt;code&gt;bin/&lt;/code&gt;或&lt;code&gt;Scripts/&lt;/code&gt;文件夹中（前者为macOS/Linux，后者为Windows）&lt;/p&gt;
&lt;p&gt;新建后需要将该虚拟环境激活：&lt;/p&gt;
&lt;p&gt;在Windows上执行&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cmd&quot;&gt;Scripts\activate.bat
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-powershell&quot;&gt;Scripts\Activate.ps1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在macOS或Linux上执行&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;source bin/activate
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;此时再在终端执行&lt;code&gt;which python&lt;/code&gt;或&lt;code&gt;where python&lt;/code&gt;应该就可以看到处于一个新的Python环境中&lt;/p&gt;
&lt;h3&gt;新建一个自己命名的虚拟环境&lt;/h3&gt;
&lt;p&gt;在命令行执行&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;python -m venv myenv
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;将会在当前项目目录新建一个名为myenv的虚拟环境，myenv仅为示例，实际上可更换为你想要的任何合法名字，该环境会被放到项目根目录的&lt;code&gt;myenv&lt;/code&gt;文件夹中&lt;/p&gt;
&lt;p&gt;新建后需要将该虚拟环境激活：&lt;/p&gt;
&lt;p&gt;在Windows上执行：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cmd&quot;&gt;myenv\activate.bat
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-powershell&quot;&gt;myenv\Activate.ps1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在macOS或Linux上执行：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;source myenv/activate
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;请注意，以上的指令都应将&lt;code&gt;myenv&lt;/code&gt;替换为实际上为虚拟环境所起的名字。&lt;/p&gt;
&lt;p&gt;此时再在终端执行&lt;code&gt;which python&lt;/code&gt;或&lt;code&gt;where python&lt;/code&gt;应该就可以看到处于一个新的Python环境中&lt;/p&gt;
&lt;p&gt;安装完虚拟环境后，可先执行以下命令来将pip更新到最新版本&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;python -m pip install --upgrade pip
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;6. pip如何批量管理包&lt;/h2&gt;
&lt;h3&gt;批量导入&lt;/h3&gt;
&lt;p&gt;新建一个虚拟环境后，可能需要快速导入一些包，此时可以在项目根目录新建文本文件&lt;code&gt;requirements.txt&lt;/code&gt;并分行列出常用包，如：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;requests
numpy
pandas
matplotlib
jupyterlab
ipython
scipy
scikit-learn
seaborn
flask
django
beautifulsoup4
black
pylint
pytest
virtualenv
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;也可以指定版本，如：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;numpy==1.26.0
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后在终端执行以下命令即可安装指定包&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pip install -r requirements.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;实际上，txt文本文件名可以自定义，只需要执行指令更换为实际名称即可&lt;/p&gt;
&lt;h3&gt;批量导出&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;pip freeze &amp;gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;相应的，执行以上指令会生成一个txt文本，列出当前虚拟环境所安装的所有包，txt文本名称依旧支持自定义&lt;/p&gt;
&lt;p&gt;以上为修复问题过程中的一些记录，不构成任何参考。&lt;/p&gt;
</content:encoded></item><item><title>我谈《浪浪山小妖怪》</title><link>https://aronnax.site/blog/%E6%B5%AA%E6%B5%AA%E5%B1%B1%E5%B0%8F%E5%A6%96%E6%80%AA/</link><guid isPermaLink="true">https://aronnax.site/blog/%E6%B5%AA%E6%B5%AA%E5%B1%B1%E5%B0%8F%E5%A6%96%E6%80%AA/</guid><description>对国产动画电影《浪浪山小妖怪》的深度评价，从合家欢动画标准、山西文化情怀、以及国产动画发展等多个维度进行分析。</description><pubDate>Sun, 14 Sep 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;div style=&quot;font-size: small&quot;&gt;这个博客网站是在上个星期创建的，介绍页上写的内容是「This is a blog about animation, technology, programming and more.」所以我想是时候聊一些和Animation有关的东西了，毕竟无论是一开始在朋友圈，还是之后在公众号，直到现在的个人博客，初衷都是写漫评。而本博客的前两篇内容，一篇是AI文字，另一篇更像是说明书而不是一篇文章，所以把这篇关于《浪浪山小妖怪》的漫评看作本博客的第一篇正式内容也不为过。&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;还记得之前B站某知名up主曾说「美漫也算二次元？」，我常把这句话顺手演变成「国漫也算二次元？」来表达我对国漫的看不下去，事实也确实如此，国漫至今仍没有一部能拿得出手的动画，能够如日本动画那样为全世界所熟知，所幸的是我也逐渐接受了这一点，再也没有指望哪部国产动画能走出华人圈子，而在降低标准后，今天时隔好多个年月，终于又去看一部《浪浪山小妖怪》，甚是惊喜，我想最终评分可以给到7.5/10毫不为过。&lt;/p&gt;
&lt;h2&gt;Part 1. 真正的合家欢动画电影&lt;/h2&gt;
&lt;p&gt;我想我们可以从「合家欢」的字面意思开始说起，台湾省教育部重编国语辞典修订本对「阖家欢」的定义为：「全家歡暢融洽（全家欢畅融洽）」，而如今被大多数人所认为的合家欢电影，似乎却演变成了「题材适合全体家庭成员一起看的电影」，这些电影通常不会包含儿童不宜的过激场面，也不去特意违背思想传统的长者们的意识形态。但是这样足够了吗——我想这是只有「合家」却没有「欢乐」，拿近几年口碑没输过的《流浪地球2》举例，确实是一部过硬的科幻电影，内容健康小清新，也向世界展示中式哲学，不少人说这是合家欢电影，可是不妨把电影放在「小孩哥」思维下看看，大概会是「战斗，爽！-&amp;gt; 这是讲啥呢 -&amp;gt; 战斗，爽！-&amp;gt;这是讲啥呢」，这是因为对于真正的小孩哥，他们眼里只有宇宙飞船和战斗情节，靠这些情节才勉强看完全片，只有在战斗部分才有明显的多巴胺分泌，这种时断时续的感觉，只能说是「爽」，不能说是「欢乐」，甚至中间夹杂了一些晦涩难懂。&lt;/p&gt;
&lt;p&gt;那么有什么电影算得上是我这里严格定义的「合家欢」呢？我想宫崎骏的电影，以《千与千寻》为代表，很出色完成了这一点。如果说《流浪地球2》等作品实现合家欢是「适配」，如同一个网页为不同比例的设备调整UI界面，那么《千与千寻》则是为作品做了「多端开发」，在iOS上用Liquid Glass，在Android上用Material You，在Windows设备上用WinUI，让每一种用户都获得原生级别的体验。在《千与千寻》的故事中，小孩子们体验到了小千寻在异世界的精彩故事，这里有神秘的无脸男，各式各样的妖怪，让人流连忘返；而对于那些对于社会隐喻等等内容感兴趣的人来说，他们能看到的是左派动画家宫崎骏透过动画所反映的泡沫经济下人心惶惶的日本社会；而回到那些上了年纪的老者，或许又能get到这部电影所表达的人生哲学，从而会心一笑。我在上一次看完《千与千寻》后便暗下决心，我每十年要回顾一次这部电影，正是因为这个原因。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/blogimages/%E6%B5%AA%E6%B5%AA%E5%B1%B1%E5%B0%8F%E5%A6%96%E6%80%AA/%E5%8D%83%E4%B8%8E%E5%8D%83%E5%AF%BB.webp&quot; alt=&quot;千与千寻剧照&quot;&gt;&lt;/p&gt;
&lt;p style = &quot;font-size: small; text-align: center; color: gray&quot;&gt;《千与千寻》中，汤婆婆住所的一处装饰神似美国国徽&lt;sup&gt;[1]&lt;/sup&gt;&lt;/p&gt;&lt;p&gt;那么回到今天的主角《浪浪山小妖怪》，我认为他很好的「模仿」了宫崎骏的做法。对于小孩子来说，这是一个西游故事的分支世界线，画面精良，故事有趣，诙谐幽默，转折不断，还有小孩哥最喜欢的战斗画面，只要现在小孩哥们还不厌倦西游这个IP，它就不输给现在市面上任何一个纯子供向动画，甚至对于那些对西游故事不感兴趣的小孩子，会因为这部片子的独特演绎，重新去捧起西游原著；而对于那些陪着孩子来看动画片的家长们，如果他们真的是在陪孩子看动画片而不是来电影院玩手机，我想他们将会震撼于浪浪山的故事情节，尤其是那些仍认为动画只有子供向的家长们。&lt;/p&gt;
&lt;p&gt;浪浪山的不仅主线非常好懂，甚至隐喻部分也是可以直观感受的，长话短说就是，猪代表小镇做题家，蛤蟆代表投机公务员，猩猩是社恐青年，黄鼠狼是认清现实却无力改变的普普众生，他们有一个共同的名字：Nobody（正是电影的英文片名），他们不是超级英雄，不是关系户，而是你我一样的芸芸众生，最后他们燃尽全力，书写了一个读作圆满写作悲剧的结局...这类分析非常多，我推荐看完后可以看看类似于&lt;a href=&quot;https://movie.douban.com/review/16940276/&quot;&gt;这篇文章&lt;/a&gt;&lt;sup&gt;[2]&lt;/sup&gt;的豆瓣影评。而正是因为这部电影的种种隐喻基本上等于贴脸告诉你，才导致我认为这是一个很好的机会，让那些「大人们」认识到动画不仅仅是做给小孩子的。而我说这是在「模仿」宫崎骏，也正是因为这部片子在大人和小孩眼里可以说完全是两部不同的电影，达成了「多端开发」的目的。我认为他真正意义上达成了「合家欢」的严格定义。（当然，很多成年人看完会觉得很难受，所以这里的「欢」，更贴切一点的说是「情感共鸣」）&lt;/p&gt;
&lt;h2&gt;Part 2. 浪浪山的「山西情怀」&lt;/h2&gt;
&lt;p&gt;如果只有上面这些，《浪浪山小妖怪》远不是一个算是优秀的作品，毕竟在小众哥这里，「合家欢」甚至不是一个褒义词。所以有必要夸奖一下浪浪山的各种小细节，来阐述他的优秀。&lt;/p&gt;
&lt;p&gt;首当其冲的是中国动画人的玩梗情节，一些突然的致敬不免让人会心一笑，包括但不限于对上美厂经典作品的隔空致敬，「9527」对周星驰的致敬，既见如来为何不拜对《黑神话悟空》的致敬等等等等。不过我作为一个基因里没有山西血，思想上却是一个山西脑的人来说，导演於水对他的故乡（山西太原）可真是有太多致敬。&lt;/p&gt;
&lt;p&gt;首当其冲的是贴脸开大式致敬，动画里一个重要的地点正是「北张村」，自我开盒的说，北张村离我奶奶家不到2公里，我小时候说不定还见过於水本人呢... 这种家乡情怀也不免体现在映后活动，据我所知导演於水在太原和山西其他市县举办多场映后活动，绝对是非山西导演做不到的强度。&lt;/p&gt;
&lt;p&gt;再就是他对山西这地方的人文氛围的致敬，这里面有贬也有褒。贬的最多的无过于关系文化，关系文化在华夏大地「遍地生花」，而在山西这片土地开的尤为旺盛，影片开头癞蛤蟆的二舅在大王洞当什么厨房管理员，如此小的官位都能让野猪期待癞蛤蟆的二舅能让他找上体制内工作，不得不说是山西的真实写照，毕竟在山西，食堂阿姨都是老师的亲戚，不管考啥都得动动关系，若是没有关系，月薪3k的工资都难说...而褒的地方，我觉得最动情的在于野猪一家的刻画，一个期望儿子找到稳定工作的母亲，一个鼓励创业还吹牛逼的父亲，可以说是照着无数山西人的家庭来刻画。最最细节的莫过于猪妈对于水壶的那段描写：如果水瓶没满就疯狂让你倒水喝，水瓶满的就说你没有好好喝水，总之活着的首要目的是一天喝上四壶水，不知道是多少山西小孩，或者说北方小孩的童年了。有这些如此感同身受的小细节，足以见得於水导演对生活体验的细致入微，对电影细节的精雕细琢，我不得不夸。&lt;/p&gt;
&lt;p&gt;以上这些，可能在很多人眼里并不是加分项，而对于我一个大部分时间都生活在山西的人，必须狠狠加分。&lt;/p&gt;
&lt;h2&gt;Part 3. 国产动画，终究没有走出神话故事&lt;/h2&gt;
&lt;p&gt;前两部分夸的如此使劲，这部电影真的成了不成？显然不是，首先电影本身的结局是一大减分项，可以说是让前期很多人的感动变成了流汗黄豆，上一秒平平无奇的小小野猪，怎么还攒了个大招？可以说突然就不共情了，而电影本身之外，我认为有一个很严重的问题在于仍然没有改变的西游故事框架。&lt;/p&gt;
&lt;p&gt;如果你仔细观察国漫电影的走向，你会发现那些出圈的华语动漫仍然是哪吒悟空白素贞，却从来没有一个原创IP做到了名利双收，而这样的现象扩展到我国的全ACGN领域，似乎也是成立的，最可感的莫过于国产游戏No.1怎么又是孙悟空。&lt;/p&gt;
&lt;p&gt;而再观察已经享誉世界的日本动漫，出名的是什么呢，是鬼马咒万家（《鬼灭之刃》、《赛马娘》、《咒术回战》、《东京复仇者》、《间谍过家家》，被评选为婆罗门不看的大众动画），这里面除了《赛马娘》沾一些日本本国赛马，其他的没有任何一部是和大和民族的经典形象相关的。&lt;/p&gt;
&lt;p&gt;差距正是这里，一部优秀的作品，一部享誉世界的作品，是不需要让观众了解背景知识的，而是的是开箱就看。我们的影视作品跳不出Monkey King, 英文字幕里必须包含那么一句「Yao(Chinese monster)」，永远需要海外观众去了解些什么，当然我们是热爱传统文化的，但是外国人真的喜欢这一套吗？&lt;/p&gt;
&lt;p&gt;这背后有太多需要谈的东西，并不适合在一篇影评里大谈特谈，如果你感兴趣，可以去看看金星老师在牛津中国论坛上所讲的&lt;a href=&quot;https://www.bilibili.com/video/BV1wFh5zBEEa/&quot;&gt;内容&lt;/a&gt;&lt;sup&gt;[3]&lt;/sup&gt;&lt;/p&gt;
&lt;h2&gt;Part 4. 现在我怎么看待国漫&lt;/h2&gt;
&lt;p&gt;回到开头，我现在怎么看国漫，没办法一概而论，国漫有《风灵玉秀》这样的和日本ACGN作品很像的动画，也有像今天《浪浪山小妖怪》这样不那么ACGN的东西，甚至有《哪吒》这种热度和魔怔并行的东西，我依旧认为国漫不算二次元，国漫也不需要是二次元，不能在一个日本动画婆罗门的视角下谈国漫，正如不能在婆罗门视角下谈美漫，《米奇妙妙屋》和《新世纪福音战士》根本就是没有可对比项的两种东西，每个地区有各自的文化，不能去强求。而我真正期待的是有朝一日，一个原创的国产IP作品走向世界，让世界看到我们不仅有5000年文化，更有生生不息的时代创造力。&lt;/p&gt;
&lt;h2&gt;参考&lt;/h2&gt;
&lt;div style=&quot;font-size: small;&quot;&gt;
[1]Stitch四弦琴：《隐藏在元素与细节中的表达：&lt;千与千寻&gt;的社会隐喻》（机核网）&lt;br&gt;
[2]女神的秋裤：《【深度解析】四只小妖怪和最后的大招都有名字》（豆瓣）&lt;br&gt;
[3]金星2018年在牛津中国论坛的一段发言 &lt;a href=&quot;https://www.bilibili.com/video/BV1wFh5zBEEa&quot;&gt;B站链接&lt;/a&gt;
&lt;/div&gt;</content:encoded></item></channel></rss>