Markdown 语法与外置标签写法汇总
Markdown 语法自带格式 参考:Markdown 语法图文全面详解(10 分钟学会) 注意:此页面偶尔会存在 CSS 冲突问题! 代码块 示例源码渲染演示\```sh # VSCode终端 hexo clean; hexo s hexo clean; hexo g; hexo d git add .; git commit -m "npm publish"; npm version patch; git push # Cmder终端 hexo clean && hexo s hexo clean && hexo g && hexo d git add . && git commit -m "npm publish" && npm version patch git push \```# VSCode终端 hexo clean; hexo s hexo clean; hexo g; hexo d git add .; git commit -m "npm publish"; npm ve...
提问的智慧
转载声明 以下内容皆由Asuna转自How-To-Ask-Questions-The-Smart-Way 纯作用于中国大陆境内加速访问,侵联删! 提问的智慧 How To Ask Questions The Smart Way Copyright © 2001,2006,2014 Eric S. Raymond, Rick Moen 本指南英文版版权为 Eric S. Raymond, Rick Moen 所有。 原文网址:http://www.catb.org/~esr/faqs/smart-questions.html Copyleft 2001 by D.H.Grand(nOBODY/Ginux), 2010 by Gasolin, 2015 by Ryan Wu 本中文指南是基于原文 3.10 版以及 2010 年由 Gasolin 所翻译版本的最新翻译; 协助指出翻译问题,请发 issue,或直接发 pull request 给我。 本文另有繁體中文版。 原文版本历史 声明 许多项目在他们网站的帮助文档中链接了本指南。这很好,这正是我们想要的用途。但如果你是该项...
八条线同时跑的时候,我在干什么
写这篇之前先看了一眼构建机:5 个 tmux 会话在跑,~/.local/state/ai-jobs 下面 372 个任务目录、3.1 GB,load average 2.90 而且一直在二到七之间飘。这台机器 128 核、开机四天半。数字是采样的一瞬间,写完这段又变了——这本身也是个说明。 同一时刻手上的项目:一个 Rust + SQL 的站点在改统计查询、一个 Next.js 应用在退役 service worker、一个 Bun + Hono 的服务在修隧道 origin、一个 Prisma + tRPC 的 monorepo、一个 C# 的游戏私服在补资料字段、一个 C/C++ 的 SDL3/WASM 移植、两个 Zola/Hexo 的文档站。~/Code 下 64 个目录、36 个 git 仓库。 这不是"我同时开了很多窗口"的那种并行。窗口谁都会开,难的是同时推进而不互相污染。 先说清楚为什么值得 单开一个项目的时候,AI 协作最贵的是等待:跑一次全量测试十分钟、等一次构建五分钟、等浏览器回归跑完。这段时间人能做的只有干等,或者切去看别的——一切...
合并之后 typecheck 是绿的
2aa1194ed,标题是「Merge latest main into zsf」。一个再普通不过的合并提交。 它把整套 Adjust 运行时删了。packages/api/src/adjust/ 下面 8 个文件里 7 个被整个删掉,diff --stat 是 4 行插入、292 行删除。 没有冲突。没有编译错误。CI 绿的。 删除是怎么混进来的 merge 的两个父是 e5051db93 和 93173a00b(main),merge base 是 e11e286ff。base 上这 8 个文件完好,git ls-tree 点名都在。 问题在于 zsf 那条线自己先把它们删了:那条线要做的是别的功能,Adjust 在它眼里是「main 上多出来的东西」,删掉之后本地更干净。于是合并的时候,git 面对的是「一边删除、一边没动」——按三方合并的规则,删除算 zsf 的改动,直接保留。 这不算回退,也不是冲突。 冲突至少会停下来问你。这种合并是默默生效的,提交信息里也只会写「Merge latest main」。 更巧的是,删除之后没有编译错误。因为同一批 commit 里,所...
隧道后面的服务器以为自己在 http 里
站是 Bun + Hono 写的,跑在容器里,对外走 Cloudflare Tunnel。五天前连着两个 bug(be15f5a、2ea4f53,中间隔八分钟),都是「把本地开发时的假设带进了这套拓扑」。 第一个:origin 是 http 隧道从公网把请求送进来的时候,到容器这一跳是 http。所以凡是靠 request.url 拿 origin 的地方,拿到的都是 http://...。 多数地方无所谓,有两处不行: cookie 的 Secure 属性、以及 OAuth 回调地址拼装——拼出来是 http 回调,回跳时浏览器按 https 算,对不上。 生成绝对 URL 给外面用(分享链接、邮件里的链接)——发出去是 http,用户点了要么被重定向要么直接不通。 Cloudflare 会带 x-forwarded-host、x-forwarded-proto。那就按它还原? 不行。x-forwarded-host 是客户端可以伪造的头部,直连容器端口的时候更是完全由请求方说了算。无条件信它,就多了一个能改 origin 的口子。 写了个 publicRequest(r...
让 Service Worker 自己下台
88b54539 refactor(web): retire service worker caching safely,1107 行删除、354 行新增。看数字像一次重构,实际上是给一个还活着的东西安排退场。 为什么想删 这个站是 Next.js 应用,之前用 Serwist 做 PWA 预缓存。问题慢慢显出来: 部署之后,浏览器里那份预缓存还在,用户拿到的是上一版 HTML 和上一版 JS。 缓存里的老 chunk 被清掉之后,页面引用它们,直接白屏。 出了问题只能在用户端「清缓存」,我们这边没有任何救济手段。 而它带来的好处越来越小:应用已经能正常安装(2026-10-30 我专门核对了 Google 现行的安装条件,早已不要求有 service worker),推送也没在用。剩下的只有"离线打开",代价是版本错配。 结论是退役掉缓存这一层。 但不能只是删注册 最直觉的做法是在页面里 navigator.serviceWorker.getRegistrations() 然后一个个 unregister()。 不够。unregister() 只是不...
把 EXISTS 从 FILTER 里拿出来之后
渠道统计的详情页要 1.5 秒。这在后台看板上不算灾难,但每次刷新都等一秒半,用的人是会记住的。 30 天窗口、24.6 万条点击的生产规模基准。详情页 1.51 秒、跨渠道总览 1.49 秒,分享页 0.85 秒——分享页是给投放方看的,白屏一秒半,观感很差。 问题不在数据量 先厘清「有效设备」这个词:独立设备里,点击后 30 分钟内真的落地了的。判据是一个叫 LANDED 的宏,核心是一句 EXISTS,查 0067 建的 idx_channel_pv_device(按设备 + 时间点)。 原来的写法是把 LANDED 塞进聚合的 FILTER 里: count(DISTINCT c.device_id) FILTER (WHERE NOT c.is_bot AND {LANDED}) AS valid_devices 看起来挺自然——FILTER 就是干这个的。但 EXISTS 在这里是关联子查询,规划器为它生成一个 SubPlan,也就是对每条真人点击各跑一次。30 天窗口 23 万次索引探查,光这一项就是 680 毫秒。 改成把整个「有效设备」抽成...
拿线上停机换来的那条注释
infra/migrations/0055_work_code_case_uniq.sql 的开头注释里有一段话,是拿一次真实的线上停机换来的。写它之前我先写了一个判断,然后这个判断被生产打回来了… 先把背景说清楚,不然那条注释看起来只是一段普通的谨慎啰嗦。 要修的不是「查不到」 0001_init.sql 给 work.code 的是裸 TEXT UNIQUE,也就是 UNIQUE (code),大小写敏感。而全站读端一律按 lower(code) = lower($1) 匹配。 两者错位的后果不是「查不到」,是同一部片在库里裂成两行。目录推送方 2026-08 那批把番号从 dass-966 改推成 DASS-966,upsert_work 的 ON CONFLICT (code) 没命中,于是新插一行。生产上真裂了三对:DASS-966、DSOD-009、START-597,2026-08-29 已经人工合并完了。 裂开后的症状也不是报错,是两类静默故障: 半份数据。老行握着 source_link、work_embedding、frame_embedding,新行只有...
把密钥挪出 _config.yml 之后,每条命令都得记得带上另一份配置
8 月 4 日早上的一串提交,主题是把博客配置里的敏感值清出去:百度/Bing 的推送 token、LLM 打标签的 api_key、文章加密分类的口令,全部移进 .gitignore 的 _config.local.yml,仓库里只留一份 _config.local.example.yml 模板。 同一天还做了三件相关的事:评论系统从 Twikoo+Waline 换成 Artalk、版权协议从 CC BY-NC-SA 4.0 改成 CC BY 4.0、给 AI 爬虫放行并生成 llms.txt。这篇记配置分层的代价,顺带记 GEO 和署名这两件。 去敏不是把值删掉 _config.yml 是公开的,密钥写在里面等于公开。但 Hexo 构建又需要真值,所以做法是分层: # _config.local.example.yml(进仓库) hexo_submit_urls_to_search_engine: baidu_token: "" bing_token: "" llm_tagging: api_key: "" encrypt: categories: ...
188 个播放器,0 个能响:一次主题升级暴露的旧故障
Butterfly 从 5.6.1 升到 5.7.0 的 release note 里写着一句:移除内置 APlayer/Meting 支持。升级完,aplayerInject 配置失效,layout/includes/third-party/aplayer.pug 和 plugins.yml 里的相关条目一起没了。 /music/ 有 188 个 <meting-js>,inject 里还有一个固定播放器。这些标签本身还在,脚本注入没了,页面上就是一排空的自定义元素。 按理说故事到这儿就是「升级弄坏了播放器,赶紧回滚或手写 inject」。但先测了一下基线,结果有点意外。 升级之前,其实已经是 0 个 meting-js 默认走 MetingJS 内置的后端 api.i-meto.com。它已经停止服务了,响应没有 CORS 头,浏览器的请求全部失败。也就是说,线上播放器早就一个都渲染不出来,只是没人特意去数。 主题升级不是罪魁,它只是把一块早就烂掉的地板掀开了。这个区分很重要:如果直接回滚版本,页面会回到「看起来有播放器代码、实际还是 0 个」的状态,然后继续以...
