· Vibe Notes
灵感 · 片段 · 当下
短的、随性的、像 tweet / moment 一样的笔记。
不追求完整,只捕捉当下的一个念头。
2026 · 06 月
15 则- ✦ 06-27
写得最顺的文章都是「不写不行」的
周五晚,写完本周第三篇博客,发现一个真理:写得最顺的文章都不是「要写」的,是「不写不行」的。 这种「不写不行」的感觉很难描述——它不是灵感突发,更像是某种内部压力在临界点之上。要么写下来,要么焦虑得没法做别的事。区别于「想写」,前者是欲望,后者是需求。 回头看过去那些让我写得煎熬的题目,往往是「应该写」而不是「必须写」的。前者有 deadline、有 KPI、有一份外部期待压在头上;后者只有自己,但分量更重。所以我现在判断一个选题值不值得做,标准只有一个:不写会不会堵得慌。 堵得慌就写。写不出来就先放着,放着还堵就再写。这套流程听起来像废话,但它解决了一个具体的问题——把「写不写得出来」的焦虑从「写得好不好」之前剥离出去。一旦告诉自己「写不出来就先放着」,大脑的反感会瞬间下降 70%。 另一个观察是:让我「不写不行」的话题,往往是某个领域里我反复踩坑、反复思考过的事。半年里写过三遍类似的笔记,每一遍的视角都不同。最初的版本是情绪宣泄,第二版是方法论总结,第三版才开始有自己的判断。这种「对同一件事的反复琢磨」,不是我在重复自己,而是这个主题本来就值得写三遍。 相比之下,那种「写完就再也不想看」的笔记,往往是蹭热点的应景之作。当时写的时候确实觉得有趣,但热度过去之后,自己都不愿意回头点开。所以我现在愿意花更多时间等待「不写不行」的那个瞬间——哪怕一年只等来十次,也比每月硬写三十篇更值得。 2026 年这种「不写不行」的频率在变高。一部分原因是 AI 让「写出来」的成本降了很多——不需要从头写,AI 可以把脑子里模糊的想法快速整理成第一稿。剩下的就是「想清楚」的成本,而这恰恰是 AI 帮不上忙的部分。所以现在真正稀缺的不是写作能力,而是「想清楚一个值得写的问题」的能力。这个能力只能靠长期踩坑、长期观察、长期跟某个主题纠缠来积累,没有任何 AI 工具能替代。
- ◡ 06-27
把 1.0 的所有 post 都重写了一遍
把 1.0 的所有 post 都重写了一遍。看着旧标题里的乱码,像在打扫前任房客留下的房间。 1.0 是一年前刚学 Astro 时搭的。当时对 View Transitions API 还一无所知,所有过渡都靠 CSS opacity 配合 setTimeout 硬写。Tag 系统半途而废,分类只有「tech」「life」「misc」三种,根本没法体现思考的颗粒度。文末的「相关阅读」是手动维护的,每次新写一篇文章都要回头改 5 个旧文章的链接。 重写不是否定过去——是承认那时候的我,确实只能做到那样。每一篇文章的旧标题都还在 git history 里存着,不会真删。它们是档案,不是负债。但看着它们,仍然会有一种轻微的不适感——那种「我那时候怎么写成这样」的不适,是成长的副作用。 倒是想到了一个更深的问题:博客的版本号,到底是给读者看的,还是给自己看的?我猜是后者。只有作者自己知道 v2 比 v1 多了哪些看不见的细节——比如这次多了一个把每个 vibe 自动写入 SQLite 的小工具,多了一个基于 FTS5 的站内搜索,多了一个不依赖第三方评论服务的自部署评论系统。读者只看到「新版变好看了」,但好看背后的工程量他们不会数。 1.0 到 2.0 的跨越里,最大的收获不是技术上从 Astro 4 升到 Astro 5(升级本身只花了半天),而是认知上的:「博客不是文章列表,是思考的外化」。每篇文章不只是 URL,是某个时间点我对某个问题的判断。判断会过期,但过期本身也有价值——它让我看到自己的思维是怎么演化的。 所以我没打算做 v3。不是因为 v2 已经完美,而是因为从 v2 到 v3 需要的不是再写一遍,而是去读自己 v2 里没读懂的那些主题,再写一篇新文章。版本号的更迭应该是思考的更迭,不是界面的更迭。 2026 年看整个个人博客生态的变化也印证了这一点。Astro 5 已经把 View Transitions API 做成了开箱即用的一行配置,SvelteKit、Next.js 也都跟上;FTS5 在 SQLite 3.9 之后已经成为标准模块;连 MCP 这种「让 AI agent 操作博客」的工具都是 2025 年底才出现的。一年前需要自己拼凑的能力,现在都是 baseline。这反过来又降低了重写的门槛——新版本和旧版本之间的「技术债差」在变小,「思考差」在变大。所以未来博客的版本号可能不再是「技术大改」的标记,而是「认知阶段」的标记。
- ✦ 06-26
Vibe Coding 这个词到底指什么
Vibe Coding 这个词到底指什么?我觉得是「让 AI 提速的部分更省力,让人该思考的部分更专注」。 这个词是 Andrej Karpathy 在 2025 年 2 月 2 日的 X(原 Twitter)推文里首次提出的,原话是:「There's a new kind of coding I call 'vibe coding', where you fully give in to the vibes, embrace exponentials, and forget that the code even exists.」他当时在用 Cursor 编辑器配合 Sonnet 模型,还用 SuperWhisper 语音输入,几乎不碰键盘。说白了,就是「让感觉驱动开发,让 AI 处理实现细节」。 2025 年 11 月,这个词被柯林斯词典(Collins Dictionary)评为年度词汇,说明它贯穿了 2025 一整年、被媒体和社交平台广泛使用、真实反映了一种语言演变。 但 2026 年的 vibe coding 已经跟 Karpathy 最初的定义有些距离了。Simon Willison 在 2026 年的 Heavybit 播客上说了一句让我印象深刻:「Vibe coding and agentic engineering are getting closer than I'd like.」——vibe coding 和 agentic engineering 正在以他「不太舒服」的方式融合到一起。Karpathy 自己在 2026 年 4 月 Sequoia Capital 的 AI Ascent 访谈里也说,2025 年 12 月是他的「投降点」——那段时间他发现模型输出「直接可用」,从最初只让模型写一点代码,到后来完全信任模型。 Karpathy 2026 年的具体动作是开源了 autoresearch(2026-03-06 发布,GitHub 一周破 5 万 star,整个项目只有约 630 行 Python),让一个 AI agent 在单 GPU 上自主跑 ML 实验。这背后的「Agentic Engineering」理念是:程序员的速度不再取决于「写多少代码」,而是取决于「能否正确指挥强大但会犯错的 Agent」。 我的用法比他们俩都克制:UI 块、样板代码、测试用例、类型签名——这些让 AI 写,省下来的注意力用在架构决策、命名美学、错误处理策略上。这些是 AI 写出来也要再被推翻重来的部分,因为它们依赖项目的上下文和作者的美学判断,AI 没有这个上下文。 所以我现在的判断标准是:这件事如果错了 AI 能自己看出来吗?能 → 让 AI 写;不能 → 我来写。架构错了 AI 不会知道,因为「错」的判断标准在我脑子里;UI 像素偏了 2px AI 也不会主动改,因为肉眼几乎看不出来。后者这种「能容忍的小错」就是 AI 提速的空间。 至于 vibe coding 在生产环境的边界,我的判断是:vibe coding 只能用于「用完就丢」的场景(toy project、prototype、scratchpad)。生产环境的代码必须我自己能完整 review。这条规矩让 vibe coding 保持「加速器」的作用,不让它变成「债务放大器」。
- ✦ 06-26
今天的咖啡特别苦,但代码写得特别顺
今天的咖啡特别苦。但代码写得特别顺。 咖啡的苦和代码的顺之间到底有没有关系?我没认真做过对照实验,但今天的对照很清晰:早上那杯意式浓缩明显比平时萃深了 5 秒,喝下去舌头涩涩的。但下午写 Drizzle schema migration 的时候,三小时没碰手机也没回一条消息。 一种解释是咖啡因足够 → 注意力聚焦 → 不分心。另一种解释是苦味刺激了某种应激反应,让我对「专注」的耐受度变高了。 更玄学的解释:苦味是大脑的「注意:你正在吃危险的东西」的信号,为了判断是否危险,大脑会自动屏蔽其他输入。于是世界只剩下这一件事。我倾向于相信第三种。所以以后写重要代码前,我会主动选一杯偏苦的。哪怕是心理暗示,有用就行。 但今天让我想得更深的是另一个问题:什么决定了「代码写得特别顺」这种状态?是咖啡吗?是天气吗?是早上睡得饱吗?把这些变量拆开看,似乎都不是充分条件——我有过同样的咖啡、同样的天气、同样的睡眠,但代码就是写不顺。 更可能的状态描述是:心里没有别的事。不是「没有别的事做」,是「没有别的事在心里占位」。今天能写顺,是因为早上处理完一件拖了三天的破事,下午大脑里终于腾出了完整的空。咖啡只是配合,不是主因。 这意味着「写顺」的功夫不在咖啡里,在每天早上那件「拖了三天的破事」里。每完成一件,那种「终于可以专心做下一件」的轻松感就是最好的咖啡因。所以我现在每天的优先级反而清晰了:早上第一件事不是写代码,是处理掉心里最堵的那件事——回一封该回的邮件、改一个该改的 bug、跟某个该聊的人聊一次。处理完,代码自然就顺了。 咖啡只是锦上添花。 2026 年还有个新变量:AI 工具的「上下文切换成本」。以前写代码时浏览器切到 Slack 看消息再切回来,注意力要 5 分钟才能恢复;现在 AI 助手能直接在 IDE 里帮你总结 Slack 长消息,省掉浏览器切换。今天能写顺 3 小时没碰手机,部分原因也是 AI 助手承担了「消息预处理」的活。咖啡 + AI 助手 + 处理完堵心事 = 三件事缺一不可的「写顺配方」。
- ✺ 06-25
SQLite FTS5 比我想象中强大
SQLite FTS5 比我想象中强大。一行 CREATE VIRTUAL TABLE 解决全文搜索,何必上 ES? 之前对 SQLite 的印象还停留在「嵌入式数据库,单文件,几十 MB 数据封顶」。直到给 MyBlog 接入 FTS5 做全文搜索——索引建好,查询写完,整个过程不到 30 分钟。相比之下,ES 需要 JVM、cluster 配置、shard 策略、analyzer pipeline,光是启动集群就够喝一壶。对个人博客这种量级(几千篇文章),ES 是用大炮打蚊子。 更让我意外的是 FTS5 的内置辅助函数——可以直接在 SQL 里高亮匹配片段,不用前端再写高亮逻辑。highlight(email, 2, "<b>", "</b>") 会在第 3 列里把匹配词用 b 标签包起来。snippet(email, 2, "<b>", "</b>", "...", 5) 则会返回包含匹配词的 5 个 token 片段,前后用省略号连起来。bm25() 排序也比想象中准,ORDER BY bm25(vibe_fts) 自动按相关度从高到低返回结果。 中文这边需要小心一点:默认的 unicode61 tokenizer 并不真正做中文分词,它对非 ASCII 字符大致按字符或简单的「连续非 ASCII 算一个 token」规则切,所以「今天天气很好」会被切成「今天天气很好」一个 token,而不是「今天 / 天气 / 很 / 好」。这意味着如果你存了一篇「今天天气很好」的文章,用户搜「天气」是搜不到的。解决办法有三种:换 simple tokenizer(按单字切,需要编译额外模块)、用 jieba 之类的中文分词插件先在应用层切好再写入、或者干脆接受「模糊搜索时不分词、精确搜索时 LIKE」的混合方案。 我选的是第三种——大部分站内搜索本来就是「用户大致记得某个词出现过」的模糊场景,单字切 + bm25 排序够用。真正的精确搜索用 LIKE '%keyword%' 配合索引列。如果数据量大到 LIKE 都慢,那就得认真考虑 jieba 了。 FTS5 还有一个经常被忽略的好处:它支持 INSERT/UPDATE/DELETE 触发器自动同步索引表。我给 vibe_notes 写了 4 个 trigger(AIUD 各一个),任何对 vibe_notes 的修改都会同步到 vibe_fts。从此不用在应用层手动维护「索引和数据一致性」这个永恒的烦恼。 如果数据量不上亿,单机 SQLite + FTS5 真的是被严重低估的方案。 2026 年的视角看,SQLite 还在继续进化:libSQL(Turso 的底层)已经把 SQLite 拓展到「边缘计算 + 嵌入式副本同步」的场景,能在 Cloudflare Workers 里跑、能跨区域复制。这意味着个人博客这种「单文件 SQLite」的范式,未来还能扩展到「全球分布、零运维」的边缘部署。再叠上 FTS5 和 AI 时代的 RAG(向量化 + 全文混合检索),SQLite 在个人开发者场景下的天花板还在被抬高。
- ◐ 06-24
笔记软件换了五六轮,最后回到纯文本 Markdown + Git
Notion、Obsidian、Logseq…… 笔记软件换了五六轮,最后回到纯文本 Markdown + Git。 每次换都是因为新软件承诺解决上一家的痛点:Notion 解决协作但锁死数据格式,导出要么是 zip 一堆嵌套 JSON,要么是 HTML 没法再用。Obsidian 解决本地化但插件生态混乱,质量参差不齐,每个新电脑都要重新装一遍那 20 个插件。Logseq 解决块引用但查询慢得像老牛,1000 条以上就有明显卡顿。结果换到最后,每个工具都留下了 1000+ 条笔记,但真正想找的时候,全都想不起来放在哪。 回到 Markdown + Git 的那天,我做了一件事:把五年里散落的笔记全部 cat 到一起,发现真正有价值的不到 300 条。剩下 1700 条,要么是会议纪要(已过期)、要么是读书摘抄(书都忘了)、要么是「明天要做」的清单(早就做了或早就不做)。这些不是「笔记」,是「思考的副产品」——它们在写下的时候有意义,但脱离上下文之后就是噪音。 工具有用,但工具不是答案。笔记的密度比笔记的数量重要 100 倍。 另一个让我坚定回归文本的原因,是版本控制。Git 给了我一个 Notion/Obsidian 都给不了的能力:每条笔记的修改历史。我能看到「2024-03-12 我对 React Server Components 的判断」和「2025-08-04 我对 RSC 的判断」,对照读一遍,思维的演化路径就出来了。Notion 有 page history,但它不是 git,没法 diff,没法 rebase,没法把某次「写错了的判断」彻底丢掉。 最后一个原因是:纯文本不会死。Notion 还在不在?Obsidian 还在不在?Logseq 还在不在?我不确定。但 .md 文件 50 年后还是 .md 文件,git 仓库 50 年后还是 git 仓库。这不是怀旧,是「减少被工具绑架」的风险。 所以现在的配置是:所有笔记 .md 写在 ~/notes/ 下,按年-月-日-主题命名,git commit 时机是「想法成型」的那一刻而不是「写完的那一刻」。搜索用 ripgrep + fzf,前者快,后者交互舒服。足够了。 2026 年的视角看,Karpathy 自己也提出了一个类似的概念叫「LLM Wiki」——把笔记当作「给未来 AI 读的文档」来组织,markdown + frontmatter + 严格的分类层级。这跟我现在的实践不谋而合:当 AI 助手能在 100ms 内帮你 cross-reference 五年前的某条笔记时,笔记的「机器可读性」比「人类可读性」更重要。所以我会更严格地用 YAML frontmatter 标注每条笔记的 tags、context、related_notes,让 AI 能精准定位。这也是为什么我不再用 Notion 这类「人类排版优先」的工具——它的数据结构对 AI 不友好。
- ◡ 06-24
下雨天适合重构
下雨天适合重构。代码像被雨洗过,结构更清晰。 不知道为什么,雨声特别适合长时间专注的体力活。可能是因为雨是白噪音的一种,能屏蔽楼上走路、邻居关门、楼下汽车这些突发性干扰。也可能是气压低的时候大脑供氧更稳定——这个我没查证,纯属瞎猜。 但有一个观察是真的:下雨天写 bug 修复的次数显著少于晴天。可能因为修复 bug 需要急,急的时候容易出错;而下雨天然让人慢下来,慢下来就不容易出 bug。 所以我现在的策略是:复杂重构排在下雨天,紧急 bug 修复排在大晴天。前者是体力活,需要长时间专注;后者是判断活,需要清晰的优先级和快速反应。两者需要的精神状态不同,硬要用同一个状态去做两边都做不好。 如果下雨天还在赶 deadline,那是项目管理的问题,不是天气的问题。 更神奇的是,雨声对「思考型任务」和「体力型任务」的影响不同。重构这种「先想清楚再动手」的任务适合雨天,因为雨声提供了思考的稳定背景。但「快速定位一个生产环境 bug」这种「先动手再想」的任务反而适合晴天,因为晴天让人更警觉、更愿意试错。 我甚至开始怀疑,雨声对大脑的影响可能不是「让人专注」,而是「让人慢下来」。这两个看起来像,但其实是反义。专注意味着高效运转,慢下来意味着低功耗冥想。重构需要的是后者,不是前者。我之前混淆了。 另一个相关观察是:深夜也适合重构。深夜和雨声的共同点是「世界安静下来」。当外界干扰降到极低的时候,大脑会自然进入一种「自己跟自己对话」的模式——这种模式恰好就是重构需要的。你不需要跟任何人沟通,只需要在脑子里把代码的不同方案跑一遍,挑一个最干净的写下去。 所以我现在的工作日历上,雨天和深夜默认是「Refactor Time」。其他时间留给 feature 和 bug fix。 2026 年还有个新变量:AI agent 能承担一部分「慢重构」的工作了。比如让 Claude Code 重构一个旧模块的命名规范、提取重复代码、加 type annotation——这些机械活它做起来比人快 5 倍,但需要人盯住方向。这意味着「雨天重构」的分工可以变了:人负责想清楚「重构的目标是什么」,agent 负责「执行重构」。这种分工反而让雨天更适合纯思考(决定方向),不必再被「机械执行」打断。
- ◌ 06-22
凌晨 3 点 debug 一个时区 bug
凌晨 3 点 debug 一个时区 bug。第 17 次觉得自己应该转行种地。 时区这种东西,本质上是一个「全球分布式系统对齐」问题。UTC 存、local 显、跨时区计算用 lib,每个点都正确,但组合起来总有某个边界 case 出问题——比如用户在 23:30 创建了一条笔记,应用层以为是今天,存到数据库用 UTC,结果到第二天 0:30 显示是「昨天」。 每次撞上时区 bug 都想:为什么不用单一时间?为什么不强制 UTC 显示?为什么不让用户自己选时区?但这些方案都有各自的代价。单一时间意味着所有用户看到的都是 UTC,体验差;强制 UTC 显示和单一时间本质一样;让用户选时区又增加了 onboarding 摩擦。 种地不会有时区 bug。种地的唯一时间是「季节」和「天气」,不需要精确到秒。所以 debug 失败时,种地的诱惑特别大。 但实际上种地凌晨 3 点也要起床给牛挤奶。所以这个逃避方向也不成立。 凌晨 3 点 debug 时区 bug 真正的危害不是「找不到答案」,而是「找到的错误答案」。人在极度疲惫时倾向于接受第一个看似合理的解释,不再继续追问。我那次找到的「修复」其实只是把 bug 从「23:30 的笔记显示昨天」改成了「00:30 的笔记显示明天」——问题的核心没有解决,只是把边界挪了一下。 事后看,正确的做法是:凌晨 3 点不应该 debug 时区 bug。时区这种东西需要的不是聪明,是清醒。改时区代码的窗口应该排在「睡了一觉、喝了咖啡、上午 10 点到下午 2 点」之间。任何其他时间碰它都是在赌运气。 所以我现在给自己立了一个规矩:晚上 12 点之后,不改任何跟时间、字符编码、并发锁相关的代码。这些是「bug 黑洞」领域,需要大脑满血才能对付。其他代码可以熬,这些不行。这条规矩让我的凌晨 3 点再也不需要了。 2026 年看,「凌晨 3 点 debug」这个场景已经被部分消解了——AI agent 能 7×24 帮你 debug,时区 bug 抛给 Claude Code + 把报错信息贴进去,它能比你更快地定位。但「把判断交给 AI」本身需要清醒——让 AI 在凌晨 3 点 debug,你大概率会接受它给的第一个「修复方案」而不追问;让 AI 在上午 10 点 debug,你才有精力去质疑它的方案。所以规矩要改成:凌晨 3 点不 debug 任何东西——人不行,AI 的输出也不行被人审核。
- ◐ 06-21
极简设计的反义词不是繁复
极简设计的反义词不是繁复,是「不克制」。 繁复可以是克制的——比如一个哥特式教堂的每一处浮雕都精确服务整体叙事,那是「繁复但不失控」。但常见的「繁」是失控的:多放一个图标、多加一个边框、多写一段说明,全是因为「不知道该删什么」。这种「繁」不是设计选择,是设计能力不足的遮羞布。 极简不是「少」,是「每一个元素都服务一个明确意图」。所以好的极简往往比繁复更难做,因为克制需要判断力,知道什么该留什么该走。 博客首页的 Hero 区我改了 12 版。第一版是「m y b l o g」八个字母横排,每个字母一种颜色,看起来很「设计感」。但用了一个月发现,这八个字母除了好看什么都没传达,反而让真正想找内容的读者迷路。 现在只剩一个衬线斜体的 myblog 标题 + 一行 slogan。克制,但每像素都有意义。 判断「该不该留」的标准其实很简单:删掉这个元素,谁会难过?如果答案是「没人会注意到」,删。如果答案是「作者自己」,但读者不会注意到,作者也得忍住。 我曾经纠结过要不要在文章页加一个「阅读进度条」。理性上知道它对长文有用,感性上觉得它会让页面变「吵」。最后没加——我自己的阅读体验里,进度条带来的「被打扰」感大于「知道读到哪了」的便利感。这种判断只能来自自己长期做读者的体感,不是来自设计理论。 另一个常用判断:加一个新元素之前,先问「我要解决什么具体问题?」如果答不上来,就是没必要的加法。「我想让页面更丰富」「我想试试看」都不是具体问题——这是创作者的贪欲,不是设计意图。 克制不是「什么都不做」,是「做的每一件事都有理由」。 2026 年的视角看,「克制」还多了一层含义:AI 时代的信息密度爆炸。一个页面塞进去 10 个 AI 推荐模块、5 个动态横幅、3 个浮动按钮,从「信息量」看是更丰富,从「注意力消耗」看是灾难。读者每天接收的信息量是 2010 年的 50 倍(仅中国日均 token 调用量就从 2024 年初的 1000 亿涨到 2026-03 的 140 万亿,涨了 1000 倍),他们的注意力是稀缺资源。极简设计在 2026 年不只是审美选择,是用户尊重——「我不要占用你宝贵的注意力」。
- ✕ 06-20
React Server Components 是 React 的未来吗
React Server Components 真的是 React 的未来吗?还是 Next.js 想让你买更多 Vercel 套餐? 老实说,RSC 这个东西我用过一段时间,体感是:它解决了一个真问题(首屏 JS 体积),但同时引入了一个新问题(mental model 复杂度)。Server Component 不能用 useState、不能用 onClick,要 client 渲染必须显式声明 'use client'——这套规则学习曲线不算陡,但踩坑时调试很烦。 补充一些背景:RSC 是 React 官方在 2020 年 12 月提出的(Dan Abramov 团队),跟 SSR 是不同的东西——SSR 输出的是 HTML,客户端 hydrate 后才有交互;RSC 输出的是组件树结构,客户端按需 hydrate 部分组件。RSC 的优势是「更小的 bundle、更快首屏、直接访问服务端资源」,代价是「组件边界必须显式声明,调试链路变长」。 它和 Next.js App Router 的关系是:Next.js 是目前对 RSC 支持最成熟的框架,但 RSC 本身不依赖 Next.js。React 团队明确说过 RSC 是 React 核心能力,理论上任何框架(Waku、RedwoodJS、甚至自己写一个)都能实现 RSC 协议。只是目前工程化最舒服的路径是 Next.js。 更让我警惕的是 Vercel 的商业模式:他们投了大量资源推广 RSC,而 RSC 的最佳部署体验只在 Vercel 自己平台上。虽然规范是开放的,但「开放的规范 + 唯一舒服的实现」是个老套路了。 2025-12 Next.js 16 发布,引入了需要显式开启的 Cache Components 和 Model Context Protocol(MCP)集成,进一步把开发者绑向 Vercel 平台。然后 2025 年底爆出了 CVE-2025-55182——一个影响 Next.js 14.3.0-canary.77 到 16.0.6 的严重安全漏洞,允许未授权攻击者通过 RSC payload 执行任意系统命令。这个 CVE 给所有「RSC = 默认安全」的宣传浇了一盆冷水:服务端组件执行用户输入是一个新的攻击面,应用层必须自己做严格过滤。 我的判断是:RSC 适合大型内容站(博客、电商、文档),不适合强交互应用(编辑器、看板、IM)。如果你站点 80% 是静态内容 + 偶尔交互,那 RSC 是真香;如果你站点 80% 是交互 + 偶尔静态,那引入 RSC 是给自己找麻烦。 不要因为「未来」两个字就上,得看你的场景当下需要什么。技术本身是真的好,但商业捆绑和安全风险是真的存在。你可以在不上 Vercel 的前提下用 RSC(用其他部署平台),但需要自己处理基础设施和额外的安全审查。这就是开源世界里永恒的权衡:规范开放、实现集中、风险自担。
- ◡ 06-19
「差不多就行」不是放弃,是知道哪些维度值得精确
「差不多就行」不是放弃,是知道哪些维度值得精确。 我的博客首页头像外圈,圆角是 12px。误差 0.5px 我都能看出来,但花 30 分钟把它调到完美 12.00px 没有任何意义——因为读者看不出。 但有些维度不能差不多:博客的内容、排版、可访问性、可读性。这些是「用户感知到」的维度,必须精确。 工程师很容易陷入一种「完美主义陷阱」:什么都要 100%,但 100% 是有边际成本的。把 80% 的精力花在用户能感知的 20% 上,剩下的 80% 维度做到 70%,总和收益最大。 所以我现在的判断标准变了:不是「这件事能不能做到 100%」,而是「做到 100% 后谁会注意到」。只有当答案是「用户」的时候,我才做到 100%。答案是「我自己」的时候,做到 70% 就够了。 这条原则带来的副作用是:我开始能更快地判断一件事值不值得做。以前我会花半天纠结一个 tooltip 的箭头方向,现在会在 5 秒内决定「做到 80% 不行就改回 70%」。这种决策速度的提升,让我的项目推进速度比之前快了至少 3 倍。 但这条原则有一个前提:你要真的能分清「什么是用户能感知的」和「什么是只有作者自己能感知的」。这两者的边界往往很模糊——有些作者觉得重要的细节,用户真的不在乎;有些作者觉得无关紧要的小事,用户其实很在意。 怎么分?最有效的方法是让真实的用户(不是你)看一遍,问他们注意到什么。问卷不靠谱,因为人会「事后合理化」自己没注意到的细节;观察靠谱,因为眼神不会说谎。 另一个方法是问自己:这个细节如果不完美,会让我下次打开自己的博客时感到不适吗?如果会,那就是「只有作者能感知」——做 70%。如果不会,那就不需要做。 「差不多就行」的精髓不是「偷懒」,是「把省下来的精力投入到真正重要的地方」。 2026 年这个原则有了新的边界条件:AI 让「做到 70%」的成本接近 0 了。一个按钮的 hover 效果、卡片阴影的层次、间距的呼吸感——这些过去需要设计师手动调的东西,现在让 AI 生成 5 个变体,10 秒就能挑一个。所以「做到 70%」的门槛被 AI 大幅降低了,「做到 100%」的必要性也相应降低了——因为 AI 帮你快速试错的成本太低,「永远 70% 凑合」和「快速迭代到 80% 再决定要不要 100%」的差距被拉平。这反过来更强化了「精确在重要维度、宽松在不重要的维度」的判断。
- ✺ 06-17
今天读完 Designing Data-Intensive Applications 第七章
今天读完 Designing Data-Intensive Applications 第七章。感觉脑子被开过光。 第七章讲的是 Transactions(事务)。具体内容包括 ACID 的语义细节、weak isolation level 的几种实现(read committed、snapshot isolation、serializable)、以及 serializable snapshot isolation(SSI)这种相对新的算法。 这本书我读了第三遍,每次读这章都有新理解——可能是因为前两遍没有实际踩过相关的坑。第三遍读的时候,我已经在项目里写过「read-modify-write」逻辑、踩过 lost update、debug 过 phantom read。所以这次读,每个概念都有具体的代码段对应到脑子里。 「书读三遍其义自见」是真的。但前提是中间要有足够多的实际操练,否则三遍读的都是同一个空脑子。 具体说几个这次读才真正理解的点: snapshot isolation 的本质是 MVCC(多版本并发控制),每个事务开始时拿一个 txid,所有写都打到新版本,读只读 txid 之前的可见版本。这种方式避免了 read-write 阻塞,代价是版本累积需要定期 GC。 SSI(serializable snapshot isolation)的精髓是检测「dangerous structures」——也就是事务之间形成的读写依赖环。一旦检测到环,就 abort 其中一个事务,让应用重试。这种方式比传统的 2PL(两阶段锁)吞吐高很多,因为读不阻塞写、写不阻塞读。 MySQL InnoDB 的默认隔离级别是「repeatable read」(其实更接近 snapshot isolation 而不是标准定义的 RR),PostgreSQL 是「read committed」。这两个默认值在分布式场景下都容易出 bug——尤其是「lost update」问题,必须用 SELECT FOR UPDATE 或者乐观锁显式处理。 打算接下来把第八章(分布式系统的问题:故障、网络延迟、时钟)也读一遍。但这次会带着自己的 MyBlog 做实验——故意在 4321 端口的 web 服务和 8787 端口的 api 服务之间模拟一次网络分区,看 commentCount 的乐观锁到底能不能扛住。 DDIA 这本书最大的价值不是它告诉你「应该用哪个技术」,而是它告诉你「为什么这些技术会在这个特定历史时刻出现」。理解了 origin,理解 trade-off,做技术选型时才有判断力。 补充背景:DDIA 第一版是 Martin Kleppmann 在 2017 年出版的,到 2026 年仍然是分布式系统领域被引用最多的书之一。中文翻译第二版的 GitHub 仓库(Vonng/ddia)2026 年 4 月还在持续更新,包括补充贡献者链接和勘误。这本书的「长寿」本身就是对「技术书要追新」这个常见误区的反驳——基础理论的保质期比任何框架都长 10 倍。
- ✦ 06-16
Cursor Composer + Claude Code 的组合
Cursor Composer 写 UI 块,Claude Code 改逻辑。组合起来是真的香。 之前一直纠结:「到底用 Cursor 还是 Claude Code?」试了几周发现这是个错误问题——它们解决的问题不一样。 Cursor 的 Composer 模式对 UI 编辑极其友好:选中一段 JSX,说「把这个按钮改成右上角悬浮样式、加阴影、hover 时缩放」,它能直接在当前文件里多文件改完,不需要上下文切换。代价是它对项目级重构一般,因为它看不到 git history 也不擅长 grep 整个仓库。 Claude Code 反过来:项目级重构、跨文件搜索、按 git diff 解释「这次提交改了哪些逻辑」,这些是它的强项。但写 UI 块不是它的舒适区,因为它的输入是文本流,不是结构化的 AST。 所以现在的流程是:UI 块(按钮、卡片、表格)→ Cursor Composer;逻辑改动(API、schema、middleware)→ Claude Code。两个工具在 IDE 里开两个窗口,互相补充。 工具的选择不是非此即彼,是看任务。 另一个 Karpathy 在 2025 年分享的洞察也印证了我的用法:他后来发现自己日常 LLM 辅助编程的主力(约 75%)其实只是 Cursor 编辑器里的 Tab 键代码补全,不是 Composer 也不是 Claude Code 这种「大动干戈」的方案。Tab 补全的好处是低风险、低打断——AI 一次只建议一行或几行,作者能完全掌控节奏。 所以我现在的工作流更进一步细分了:Tab 补全(70% 时间)→ Cursor Composer(20% 时间,UI 改动)→ Claude Code(10% 时间,项目级重构)。这个比例让我的「写代码」和「想清楚再写」的边界非常清晰。 Tab 补全的好处还有一层心理上的:它不打断 flow。Composer 一旦开启,作者就开始「等 AI 给结果」,flow 中断;Tab 补全是同步的,作者大脑还在主导,只是 AI 帮忙按了几次键。这种「AI 在你旁边但不接管」的协作模式,是最舒服的。 2026 年这个工具格局还在快速变化。Anthropic 2026-05 的「Code w/ Claude」大会直接把 vibe coding 和 agentic engineering 的融合作为主题;Cursor 出了 2.0;Claude Code 集成了 MCP(Model Context Protocol)生态,可以直接调用外部工具;国内字节跳动的 Trae、阿里 Qoder、美团 NoCode 都进入了 AI IDE 市场。但工具再多,我的判断标准没变:Tab 补全管细节、Composer 管 UI、Claude Code 管逻辑。三个工具的分工是基于任务性质,不是基于品牌。
- ◐ 06-14
写了一篇文章关于「Vibe Coding 是什么」
写了一篇文章关于「Vibe Coding 是什么」,发现写完我也没完全说清楚。也许这就是它该有的样子——边界模糊的实践。 写完之后我看了三遍,每次都问自己:「这真的是在解释一个东西,还是在解释我对这个东西的困惑?」最终答案是后者。 Vibe Coding 这个词从 Karpathy 2025 年 2 月提出到现在一年多,没有标准定义,每个人的用法都带自己项目的影子。我的用法是「AI 提速、AI 写样板、我专注做判断」;别人的用法可能是「完全不读 AI 写的代码、靠感觉接受或拒绝」、或者「用 AI 生成 prototype 但生产代码完全手写」。 当一个实践还没有沉淀成「标准定义」之前,写文章能做的就是诚实地记录「我自己的用法是什么」。所以那篇文章最终变成了我自己的 vibe coding 工作流,而非一份客观定义。 这可能是所有早期术语的共同命运:被命名、被传播、被每个人按自己的理解重新塑形,直到最终沉淀出某种共识。「云计算」「微服务」「区块链」都经历过这个过程。 写完之后还想到一个相关问题:vibe coding 和传统编程的边界到底在哪?我自己的判断是——如果 AI 写的代码出了 bug,作者能在合理时间内定位并修复,那就是 vibe coding;如果作者完全读不懂 AI 写的代码、bug 只能靠「让 AI 再试一次」解决,那就不是 vibe coding,是「AI 赌运气编程」。 后者的危险在于:技术债会指数级累积。每一次「让 AI 再试一次」都加一层抽象,每一层抽象都不在作者的理解范围内。一旦项目复杂度超过某个临界点,整个 codebase 就会变成「没人敢动」的黑盒。这是 vibe coding 最反直觉的副作用——它让人在短期内更快,长期内更慢。 2026 年这个边界更模糊了。Karpathy 自己 2026 年 4 月在 Sequoia AI Ascent 上说:「vibe coding 只是第一步,真正值得关注的是 Agentic coherent workflow,即智能体连续规划、执行、调试,并根据环境反馈自主修正。」换句话说,vibe coding 是「短循环的 vibe」,agentic engineering 是「长循环的 vibe」。两者本质是同一件事的不同时间尺度。所以我现在不纠结 vibe coding 的精确定义了——它在 2026 年已经自然演化成「AI 时代程序员该有的工作方式」的同义词。 我给自己立的那条规矩——vibe coding 只能用于「用完就丢」的场景、生产环境必须能完整 review——也跟着升级成:agentic engineering 可以用于生产环境,但人必须保持「读 AI diff、质疑 AI 方案」的习惯。AI 不再是「用完就丢」的工具,而是「永远有上级 review 的人」。
- ◡ 06-13
极光配色 #7c3aed + 紫黑渐变
极光配色 #7c3aed + 紫黑渐变,越看越耐看。 紫色在 RGB 色域里有个特别的位置——它是红和蓝的中间点,刺激感比红低,比蓝高,给人一种「温暖但不刺眼」的感觉。所以 #7c3aed(Tailwind 里的 violet-600,RGB 是 124, 58, 237)用作主题色,比纯红、纯蓝都好控制氛围。 紫黑渐变就更妙了:从 #0a0014 慢慢过渡到 #7c3aed,再过渡到 #2dd4bf(青绿),整个色域让人觉得像在极光下看夜空。不是极光是字面意思——是那种「自然现象里同时出现多种反差极大的颜色」的感觉。 我用这套配色做了 MyBlog v2 的整个视觉系统。Header 的 Logo、Hero 的标题渐变、按钮 hover 的高光、代码块的关键字——全是这套色域里的元素。一致性带来的好处是:用户进站 5 秒就能「感觉到」这是一个视觉上有主张的博客,而不是随便哪个 SaaS 模板。 颜色是会说话的设计语言。选什么颜色,就是在告诉读者「我是谁」。 但选颜色这件事被低估了。大部分博客(包括 v1 的我自己)的颜色选择是「白底黑字 + 一个随机强调色」,理由是「这样最保险」。保险没错,但保险也意味着无趣。读者每天看几十个白底黑字的网页,你的网页要脱颖而出,必须有「看第一眼就知道是你」的视觉锚点。 颜色就是这个锚点。它比 logo 更难模仿(logo 是形状,可以复刻;颜色是感受,需要长期塑造),也比排版更跨设备一致(排版在 mobile 和 desktop 上感受不同,颜色的核心色相是稳定的)。 选择 #7c3aed 而不是 #8b5cf6(Tailwind violet-500)的原因:500 太亮、600 太深中间的某个甜区。我自己画了 12 个 violet 渐变样本,找到了「视觉重量刚好」的色阶——背景深到不抢眼,文字浅到不刺眼,按钮亮到能点击。 颜色的对比度也是被忽略的细节。AA 标准要求文字和背景对比度 ≥ 4.5:1,AAA 标准要求 ≥ 7:1。但实际体验中,纯色背景 + 纯色文字会让眼睛疲劳。我用了「背景带极淡的紫色噪声 + 文字用 ink-soft 的米黄色」,对比度约 8:1,符合 AAA,长时间阅读也不会累。 最后一个细节:dark mode 和 light mode 的同一套颜色需要不同处理。dark mode 下 #7c3aed 直接作为强调色 OK,但 light mode 下 #7c3aed 作为背景文字会太暗、作为背景块又会太亮。所以 light mode 我用了 #ede9fe(violet-100)作为背景色,#6d28d9(violet-700)作为文字色——同一色相、不同明度,保留品牌一致性的同时保证可读性。 颜色是设计的语言。学会这门语言,比学任何一个框架都重要。 2026 年的视角看,颜色选择还有了「AI 主题适配」的新维度:我的博客被某些 AI 爬虫抓取后,会被自动生成「极简风」「霓虹风」「杂志风」等多种衍生主题,这时候 base 配色 #7c3aed 是否能 hold 住各种衍生风格就是关键。如果 base 色相选错(比如选 #ef4444 红),衍生主题一改就会显得不伦不类。紫色这种「中性偏暖」的色相反而是最稳健的 base——它既不被暖色主题压垮,也不被冷色主题冷掉。这种「跨风格的稳健性」是 2026 年设计的新考量。