保罗的小宇宙
type: channel
link: https://paugram.com/
description: Still single, still lonely.
items: 奇趣影棚项目 Vibe Coding 第一天问题记录
items: 失业后的一次前端面试经历
items: 威联通 NAS 使用 CloudFlared 远程访问
items: 记一次被街头诈骗的经历
items: 记一次升级 Nuxt 4 的诡异问题
items: 记一次移动端 Safari 调试踩坑
items: 记一次装机没有一次点亮的排查过程
items: 2024 年终总结
items: 将 MO3 音乐导出成 WAV/MP3/OGG 等格式
items: 该写好代码吗？写好了也可能变得不好了

奇趣影棚项目 Vibe Coding 第一天问题记录
type: item
date: 2026-06-18T08:46:00+00:00
description: 继续失业在家无所事事中，打算找点 Vibe Coding 能落地的实际业务，巩固一下后端和运维相关知识。看到之前认识的一摄影师哥们被公司集体裁员后，目前选择自己创业开影棚，于是在想能不能做一个这样的系统结合实际，于是便有了此项目。前几天冲凉想到之后初步规划过，写了一份约 2500 多字的文档，随后让 AI 输出了一份完整的「产品设计文档」和对应项目的「技术说明文档」，我再核实确认修改了细节。本文仅作过程和踩坑记录，不包含具体 Prompt 和对应的业务细节。项目背景制作一个影棚管理系统，主要面向于摄影工作室场景开发，包含官网（作品展示、预约影棚等）、管理后台（管理员维护）、后端三个项目。简要记录今天的 Vibe Coding 已经完成制作了官网、服务端、后台三端的核心代码，期间也确实遇到不少问题，这里简单记录一下。模型主要是采用 GPT-5.5，部分流程自动降为 Cursor 的 Composer 2.5。官网部分官网方面，我首先是另外找 AI 对话探讨得到一套靠谱的设计，最终得到结果如下，其实从生成结果来看，整体还不错，就是顶上那个菜单风格真的是有点太熟悉了，哈哈。整体风格： - 高级感 - 沉浸式 - 年轻化 - 二次元审美 - 作品驱动 - 内容社区风格 避免： - 企业官网风格 - 传统婚纱摄影网站 - 影楼宣传页 - 粉色二次元模板风 - 动漫论坛风格 参考风格： - Pinterest - Instagram - Behance - ArtStation - 小红书 - Linear - Raycast 视觉关键词： - Dark Mode First - Editorial Design - Cinematic - Immersive - Premium - Modern - Elegant - Gallery Focused - Large Typography - Minimal UI - Rich Photography Showcase后端部分后端方面，问题主要是 Prisma 的接入相关的坑比较大，还引出了一个 ESM 和 TypeScript 打包配置的问题。最开始遇到的问题是 PrismaClient 实例失效，直接报错找不到，排查后发现是 schema.prisma 的配置问题，需要指定 output 路径到当前项目下，它默认存的位置有问题，导致 TS 识别不到。这里基本对着 官方文档 接就能解决，AI 自己写的有问题。我自己写的是如下，只要放在当前项目内就行。generator client { provider = "prisma-client" output = "./generated" }Prisma 接入方式从 7x 版本后发生了变化，包括 seed.ts 文件，需要手动传递对应的适配器包过去才行，AI 这里就搞晕了，用了旧版本的写法，我的解决方式是直接把最新文档的链接甩过去让它修改，问题真的解决了吗... 并没有！import "dotenv/config"; import { Pool } from "pg"; import { PrismaPg } from "@prisma/adapter-pg"; // 这里必须写 .js 不然找不到文件 import { PrismaClient } from "./generated/client.js"; import * as bcrypt from "bcrypt"; const connectionString = process.env.DATABASE_URL; if (!connectionString) { throw new Error("DATABASE_URL is not set"); } const pool = new Pool({ connectionString }); const adapter = new PrismaPg(pool); const prisma = new PrismaClient({ adapter });此时报错提示找不到模块（错误信息被删了我也找不到了）这种 CommonJS 和 ESM 的打包问题，其实我自己也理解的不是很透彻，首先第一步 Prisma 要你在 package.json 里面增加 "type": "module" 就能使 NodeJS 认为当前包默认走 ESM 模式运行，因此你得确保构建后的产物也是 ESM 的代码（之前我有一个「小窝后端 Ext」项目是 KoaJS，用 ESBuild 构建成了 ESM 的 JS，就能直接运行，本质上就是 node index.js 这种执行方式），而 NestJS 自己有一套 CLI 工具，本质上是包装了一次 TSC，具体生成…

失业后的一次前端面试经历
type: item
date: 2026-06-09T15:44:00+00:00
description: 这次面试，主要还是对面主动联系为主，应该是看我写了 NextJS 和电商相关经历吧，他们认为和岗位比较匹配，于是得到了这次宝贵的面试经历。面试过程还是挺紧张刺激的，毕竟人家问到的，不一定你平时经常用。HR 面HR 面没有具体考察技术，但我看也问了不少涉及技术、协作相关的话题，和一般公司的人事还是有些不同，整体回答我感觉正常水平吧。以下回答都是在对话里面完成的，所以可以先思考再回答，并完整摘录。HR：你说说你工作的心得吗，之前工作的部门规模，参与其中的角色作用答：上家公司挺好的 是创业公司自营业务 大家相处起来氛围也很好 我们团队 20 人左右，我参与的项目里面 10 人这样。因为做了四年 我这边参与维护过的东西也多，就以近期的 AI 项目来说我这边主要是参与制作一个无限画布的功能，因为工期有一点紧，代码质量有一些不够好，我就去对这块做各种优化改进，以及最影响使用的一些性能问题吧 主要是涉及到 React 的组件渲染这块HR：因为公司的全技术都是老板做起来的，他比较喜欢直接开会对接工作，我们没有产品经理，需求大多是一起讨论、简单文档，原型和说明反而要技术这边编写。你之前有没有经历过没有产品、直接对接技术负责人/老板的工作模式？遇到需求比较模糊、不完整的时候，你一般怎么处理？答：有的 我第一份工作就是这样 当时在旅行社那边技术负责人就是和其他部门做对接 相当于是直接对接具体使用系统的人 不过当时这块的具体流程应该没有这么细 都是他们大佬带头开干 我这边做对接为主不过结合之前的工作经历 其实我们也并非每个开发任务都有很详细的产品文档，也有不少是口头需求 临时改动 不过都是针对用户反馈和数据去做的调整 这种需求模糊挺多的，一般分两种情况，一个是业务层面的，这就只能拉上级详细确认，另外一种是交互层面的，我会自己简单设计方案让产品看一下，或者他觉得有更好的方案，再决定用哪个更好的方案HR：今晚 8 点 45 分左右，进行技术面试，你时间上可以么答：可以HR：你期待工资多少？答：（想先了解上班时长）公司正常上班时间是？HR：10~7点，期间有1个小时休息，答：双休吗HR：是的答：也就是 12-1 点休息这样是吗HR：不是固定的，因为多数 11 点半左右开始开会到 1 点左右，你最近的工作时间和待遇如何答：之前工作时间都比较固定 早上也是 10 点这样，中午是休息 2 小时，晚上我一般 6 点半到七点走，看任务完成情况吧HR：我们每天会有 IT 技术会议，老板亲自带队跟进进度、同步需求、解决问题。需要你按时参会、主动汇报进度、主动反馈卡点。前后端错开开会，例如今天中午前端开，明天后端开HR：我们团队没有测试，所有功能都是开发自己自测、自己验收、自己保证上线质量。你平时开发完，有没有自测的习惯？一般会检查哪些内容？如果上线后出现自己没测出的问题，你会怎么处理？答：功能自测肯定是必须的 包括我每次提交代码之前 都会人工确认一次 确保不会把临时改动也带上去不过也得分情况比如说有些功能需要有多个前置步骤，可能就会跳过一部分主要测改动后的部分，如果时间允许的话肯定需要完整跑几次上线后出现问题的情况客观来说肯定会存在 不过因为代码合并产生的冲突导致的比较多 比如多个人在改同一个模块的情况下 所以每次合并的时候还是得确认清楚比较好 关于线上问题当时我们的方案是做 sentry 监听线上的报错信息，以及 clarity 跟踪用户的操作所以还有一种方案就是 尽可能拆出不同的项目 比如说商城是前台，管理业务时另外一个后台项目，这样也能确保不会相互影响前端这边有几位同事一起是吗HR：你是指什么？就是你说的前端开会HR：目前 IT 团队配置前 2 后 2，大家都会参与HR：你上一份薪资待遇如何？答：税前 xx-xx技术面技术面考察的知识点非常丰富，基本上简历上能问的都问了一遍，面试官还是很有水平的。简单复盘下来，有些问题我完全答对，有些回答不够直接明了但也答中关键点了，有些比如 Jenkins、Electron 相关的就确实是不太清楚，也着实是没有答上。以下回答部分为印象记忆，可能和实际有出入。面试官：http 1.1 2 3 的主要区别是什么答：印象中区别在于连接重用，之前用过 Lighthouse 提示我有些资源走的是 1.1，优化过面试官：1.1 和 2 呢答：没回答上复盘：这里主要区别的确是并发，1.1 和 2 的最大区别，而 3 增加了 QUIC，使用 UDP 协议AI 的回答挺详细的，这里分享出来记录 传送门面试官：这里不行不要紧，那这个浏览器内核有哪一些答：主要三个，Safari、Chrome、IE面试官：它们的内核是什么，这是浏览器答：Blink（Chrome），还有一个叫什么来着，Webkit（Safari）复盘：其实还有一个 Firefox 浏览…

威联通 NAS 使用 CloudFlared 远程访问
type: item
date: 2026-05-19T08:29:00+00:00
description: 众所周知，威联通 NAS 内置的“内网穿透”服务在国内是有些问题的，myQNAPcloud 实际上是需要一个公网 IP 才能链接到他们家。此前博主使用的是「自建 FRP 服务器」方案来实现反向代理实现穿透，后续 Docker 一直没配置好且无法安装新的镜像，搁置了许久。其实问题本源在于国内访问 DockerHub 的网络环境并不友好，只需要简单配置下即可。这里博主使用的是几年前购买的 TS212P3 型号（也是当时入门买的最低配的）作为演示。本文章于 26.04.30 立坑，结果于 26.05.19 花了半天时间才写完...配置 Docker 源首先打开 ContainerStation，点击左侧「属性」菜单项，在右侧页面点击切换到「Registry 服务器」Tab。这里我们使用 https://docker.1panel.live 这个镜像源，确保国内的网络环境也能正常拉取镜像。获取镜像从 DockerHub 上获取 最新的镜像地址，这里我选择的是 latest-arm64 版本，因为 TS212P3 是 ARM 处理器的，并不支持传统 X86 的。docker pull cloudflare/cloudflared:latest-arm64这是正常的获取镜像的命令，但是我们需要替换成对应镜像源获取。点击 ContainerStation 左侧「镜像」菜单项，在右侧页面点击「提取」按钮，Registry 服务器选择我们刚创建的，「镜像文件名称」和「映像版本」分别输入 cloudflare/cloudflared 和 latest-arm64，点击「提取」。此时镜像已经拉取完成，我们前往 CloudFlare 后台开通 Tunnel 服务。连接 Tunnel登录到 CloudFlare 后台，点击「保护与连接 -> 联网 -> Tunnels (新)」左侧菜单项，在右侧页面点击「创建隧道」按钮，输入「隧道名称」，点击「创建隧道」。点击 Docker 选项，下面会出现你的启动指令以及对应 Token，这里直接复制出来。docker run cloudflare/cloudflared:latest tunnel --no-autoupdate run --token {你的 Token}回到刚刚获取镜像的 ContainerStation 界面，点击镜像右侧「+」按钮，在出现的弹窗里面修改「进入点」的命令，粘贴前面在 CloudFlare 后台拿到的启动指令，修改前面部分改成 cloudflared。点击「高级设置」，点击「网络」Tab 页，「网络模式」选择「Host」主机模式，最后点击「创建」。此时应该能创建成功并正常运行，在 CloudFlare 后台也会提示“您的隧道现已可以使用”。回到 CloudFlare 后台，找到刚创建的 Tunnel 实例，点击「添加路由」按钮，选择「已发布的应用程序」选项。之后指定自己的主域名和二级域名，在「服务 URL」处输入 http://localhost:5000此时访问你设置的对应 URL，应该就能正常访问 NAS 后台界面了。参考在 QNAP 中安装 CloudFlare Tunnel, 内外穿透到外网

记一次被街头诈骗的经历
type: item
date: 2026-03-16T03:03:00+00:00
description: 列表的漫展圈年轻人比较多，特意做成了“瓜条”形式希望能被更多人看到。这里也提供了由 AI 改写的大众阅读版本，方便各位博友阅读，大致表达是相似的。大众版（AI 改写）受害者：博主骗子：自称"王艳"的一位阿姨简要说明：博主热心帮助一位陌生人借钱坐车，却遭遇诈骗。骗子自称是某物流公司的高层员工（生意人），说自己出差后将手机和钱包落在了司机车上，而自己是外地来的孤身一人，丈夫已离异且是限制高消费人员。实际上这些内容全部是编造的，她就是个骗子。事件经过3 月 13 日下班后，博主正常休息吃完晚饭，在回公司的路上遇到这位阿姨。她主动过来向博主问路，说自己要去一个很远的地方（深圳宝安机场）。博主正常打开地图给她简单指路，她表示自己没有手机没办法乘车和购票，需要抵达那个位置联系对应的送货司机。博主当时就问她为什么要去这么远的地方，她强调自己是做生意的，在某个物流公司工作（没听清具体名字），在附近谈客户。她还询问博主觉得在附近开一家店的潜力如何，博主表示附近的制造业工厂确实挺多，或许有这个需求（但博主并不是内行人员，她问博主这样的问题博主又该如何回答呢）。她还会用各种常见话题和博主套近乎，比如问博主年纪多大，是否有谈女朋友。等博主放松警惕后，她开始询问博主的行业、工作地点和薪资，以及是否是本地人、家乡在哪等（博主出于个人保护，都模糊回答了）。她说自己平常在南京发展，如果有机会博主去那边做客，她会请博主吃饭，还强调出门在外多一个朋友能多一份机遇（实际上这是博取信任的话术）。为了表示自己能还钱，她要加博主微信。那个微信号用的是一个男人的头像，博主当时就表示怀疑，但她说是和丈夫离婚了，这个号现在实际上是她在使用。她还说自己有个儿子做主播，月收入可达到 2W，表示自己是生意人不差这点钱还给博主。博主用支付宝给她换了现金后，打算给她拍照留存。她当即破防表示博主对她不信任，要求删除照片。博主表示现在骗子太多，这属于正常防范。删除照片后博主本以为事情结束了，但她仍不断用话术影响博主。博主出于好心最终还是借给了她。她当即表示感谢，并附上各种祝愿（祝你工作顺利，生意兴隆？）。她承诺第二天还钱，但实际并未归还。截止到这篇文章编写时间，微信好友申请依旧处于未通过状态。事后复盘：骗局中的疑点现在简单复盘一下，其实她全程的对话充满了各种套路和漏洞。博主此前也遇到过几次街头骗局并成功逃脱，无奈这次对方特别精明，博主着实是大意了。疑点一：打车方式不合理从最开始的问路就挺多问题了。她一直强调自己出差要公司报销打车的费用，必须要开发票，而打出租车不能提前支付，只能打表后结算费用。这样她就引导博主以现金支付。博主和她去了附近的一家便利店，店长当即表示无法提供这么大面额的现金（实际上店长可能已经在警示博主这个人有问题，让博主好好想想，但当时博主因工作疲惫没想到这个可能性）。疑点二：询问博主的工作安排因为博主已经说自己在工作了，她还询问博主明天还要不要上班。这实际上很有可能是担心自己骗了博主之后再次在附近作案会被抓获。因为是小额诈骗，警方一般是不予处理的。疑点三：不向儿子求助既然她都有收入这么高的儿子了，怎么不能直接求助他呢？这也是一个巨大的疑问。其实完全可以让博主用手机联系她儿子，然后即时转账，也就不存在借钱这么一回事了（当然她很有可能会用其他理由推辞，比如已经和儿子分家了什么的）。疑点四：情绪激动后的反向施压她情绪激动后还在强调自己的着装以及已经加了微信，表示自己是清白的，当即开始反向 PUA 博主，明显表示博主在冤枉普通人。“你把阿姨当作什么人了”“你这是在侮辱我”（实际上这也是一种洗脑话术，恶人先告状，继续利用了博主的善良）。微信号可以是假的，好友是可以不通过的，手机号也可以是空号，总之博主根本没有办法找到她。总结人在外地的身份是自己给的，今天她是企业员工，明天就可以是霸道总裁。所有的身份信息都无法核实。博主的这次经历再次向各位亲朋好友发出警钟：面对陌生人一定要提高警惕，对方可能会疯狂输出话术影响你的判断。如果来不及思考，则最好提出找警察或直接拒绝。瓜条版（原创）苦主热心帮助陌生人借钱坐车惨遭背刺苦主：匿了瓜主：自称“王艳”的一位阿姨省流版：苦主热心帮助陌生人借钱坐车惨遭背刺，瓜主称自己是某物流公司的高层员工（生意人），出差后将手机和钱包落在了司机车上，而自己是外地过来孤身一人，丈夫离异且是限制高消费人员。实则内容全部编造，骗子一个。事件经过苦主在 3 月 13 日下班后正常休息吃晚饭，回公司路上遇到瓜主表示要问路，说自己要去一个很远的地方（深圳宝安机场）。苦主也是正常打开地图简单指路，瓜主表示自己没有手机没办法乘车和购票，需要抵达该位置联系对应的送货司机。苦主当即问为什么要去这么远的地方，瓜主强调自己是做生意的，在某个物流公司（没听清），在附近谈客户，还询问我附近开一家店…

记一次升级 Nuxt 4 的诡异问题
type: item
date: 2026-03-07T09:57:00+00:00
description: 前几天 我将 Nuxt 从 3 升级到了 4，升级之后才发现有一个页面出现了异常，CSS 样式出现丢失。出现问题的 CSS 文件是 styles.module.less，它是一个 CSS Modules 形式的 Less 文件。对应组件的引入方式有些特别，是根据文章内容来渲染的。// 组件映射表 const componentMap: Record<string, Component> = { "photo-collection": PhotoCollection, }; // 渲染组件的函数 const renderComponent = (componentName: string, props: any) => { const Component = componentMap[componentName]; if (Component) { return h(Component, props); } // 如果组件不存在，返回错误提示 return h("blockquote", {}, `组件 ${componentName} 不存在`); };我依次尝试了一些改动，发现都没解决...重命名文件（styles.module.less -> photo-collection.module.less）修改文件内容（.collection 下样式只写一条 background 规则）将引入方式调整成 if 和 else 的形式generateScopedName 解决方案只好求助牛逼的 Claude Opus 4.6，初步排查原因是开发模式和生产模式下生产的 CSS Hash 不一致。找到根本原因了！客户端 JS bundle 用的哈希：_collection_f6c82_1服务端 SSR bundle 用的哈希：_collection_x8r5c_1CSS 文件 里的规则：._collection_f6c82_1（和客户端一致，和服务端不一致）这就是问题所在：CSS Module 的类名哈希在 SSR 构建和客户端构建之间不一致。具体表现：服务端渲染 HTML 时，生成的 class 是 _collection_x8r5c_1浏览器加载的 CSS 文件里只有 ._collection_f6c82_1 的规则两者对不上，样式完全不生效这与 componentMap 的写法无关，所有前面的方案当然也都没用——核心问题是 Vite 在 SSR 和 client 两次构建中，传给 CSS Modules 的 id（文件路径）不一致，导致哈希不同。修复方案是在 nuxt.config.ts 里显式配置 generateScopedName，让两次构建使用同样的规则生成类名，消除哈希不一致问题：export default defineNuxtConfig({ vite: { css: { modules: { generateScopedName(name: string, filename: string) { const normalizedPath = filename .replace(/\?.*$/, "") .replace(/\\/g, "/"); const relativePath = path.relative(process.cwd(), normalizedPath).replace(/\\/g, "/"); const hash = crypto .createHash("md5") .update(relativePath) .digest("hex") .slice(0, 5); return `_${name}_${hash}`; }, }, }, }, });总感觉这是一个很奇怪的修复方式，理论上 Vite 自己的配置都是经过验证的，自己魔改的配置越多，后续的升级只会更容易出现问题，想着能不能从其他方面再继续分析下其他的解决方法。修改后缀名方案我把这件事告诉给了 @Innei，先被他 PUA 了一遍怎么还在用这么古老的技术栈骂归骂，能有些解决问题的思路也好。他说他现在使用的“不古老”的方式是 vanilla-extract 这个库，看上去是类似 CSS in JS 的那种编写方式，但是实际背后处理返回的是一个 CSS 文件，看上去亮点主要是 TypeScript 友好。用 Less 有啥优势我说没有啥优势，只是好过全局 CSS 而已（因为是 CSS Modules 形式），当时没转过来指的是 Less 本身。选择 Less 主要是主题色盘的色值可以直接用函数生成，而不是自己算好再写上去。并且它有 CSS 嵌套功能，从小窝后台一直用了好几年，也没啥问题就一直在用。当然现在这些特性其实原生都有支持了，颜…

记一次移动端 Safari 调试踩坑
type: item
date: 2026-01-21T18:54:00+00:00
description: 最近在做公司项目一个 H5 版本的页面优化，合并到测试环境之后，在手机 Safari 下有部分样式问题，需要联机即时调试更快的解决，但在联机过程遇到了不少坑，这里简单记录一下问题和解决方法。如果想要在移动端真机上调试，就不能使用 localhost 这种地址了，使用局域网 IP 地址又有可能遇到请求后端 API 出现跨域的问题，我的解决方法是选择建立一个与测试、生产环境共享根域的二级域名（当然前提后端也允许了该二级域名的跨域行为），再路由器上设置 Hosts 连接到开发机的方案。比如 paul.me 是生产环境，local.paul.me 就是本地开发环境，强制指定 IP 到开发机，这样就能保留此前传递和获取登录态的逻辑代码访问失败问题起初在另外一台 Mac 电脑上直接访问开发机对应的页面，访问失败，使用 ping IP 则正常，未分析到具体原因，重新连接网络后得到了解决。重定向问题我在手机上打开本地调试地址后，发现会被强制使用 HTTPS，可我完全是本地服务，怎么可能会有重定向？通过搜索得知，这里使用到了一个叫 HSTS 的技术，因为访问生产环境的时候就是根域名，可能在根域名下存在 HSTS 记录，导致所有子域都会强制重定向一次。为什么有些浏览器我输入 http 他也会强制使用 https 我怎么判断是谁的行为在 iPhone 的 Safari 上，需要在 Safari 设置里面找到网站数据，将整个域名下的清空（包括登录态等均被删除），之后重新打开浏览器访问本地调试环境，就没遇到 307 跳转了。联机调试崩溃我原本想用电脑上的 iOS 模拟器来试试的，但是发现 Safari 的调试工具一直有问题，无论是“元素”还是“控制台”都是空白无内容的，重开多次均无效。后尝试使用 iPhone 13 真机调试，但是首次设置就遇到了登录态设置上去但没用的情况。最后我的解决方法是直接在控制台里面设置 Cookie，然后去调整 Cookie 对应的域名和 Path 值为 /，后续请求其他页面就没有掉登录态的情况。但是在我需要调试的关键页面，手机一打开就出现崩溃甚至闪退的情况。经过检查发现本地调试环境该页面的打包代码居然有 100MB+，可能就是这个原因导致的，手机直接不堪重负。因为该页面的路由完全和 PC 共享，仅仅只是一个 if 条件判断来返回手机版的页面，因此这里有完整打包的 PC 端的代码（屎山），目前我直接注释掉了 PC 端的代码，NextJS 自动给我去除掉了，JS 文件瞬间缩小到了 2MB，调试终于得以正常进行...样式问题记录简单来说就是有一个 button 元素，内部有一个 div 设置了 aspect-ratio: 1/1 强制设置比例，结果发现元素塌陷，并没有支撑起来。对于这个问题我发现有个最简单的办法，就是将元素替换成 div，就解决了。挺诡异的，我只知道 button 相较于 div 会有一个额外的 appearence 属性，但我修改它也并没有用。具体 Demo 可见 Safari 按钮高度问题这件事说明目前还是不能完全信任 AI 写出来的代码，依旧得自己充分验证才知道有没有问题。

记一次装机没有一次点亮的排查过程
type: item
date: 2026-01-05T10:18:00+00:00
description: 上周日我帮同事组装了一台主机，配件弄好之后一步一步安装，到最后发现按下电源键居然没有任何反应，我顿时有点慌了...配置单CPU：英特尔 酷睿 i5 12700KF主板：微星 B650M-A WIFI内存：阿斯加特 16+16G DDR4 3600硬盘：闪迪 西部数据 SN510C 1TB显卡：华硕 DUAL RTX 5060电源：微星 铜牌 650W A650BNL散热器：利民 PA120SE按道理主板这玩意也不会这么脆弱，除非从最开始压 CPU 就压坏了，那就确实是完全不可逆的了。参考了网上的一些视频，我最后总结了下面的排查方案和过程。硬件排查排查过程主要还是从硬件开始，首先是电源方面是否完全接到位，一个是主板的接口，一个是 CPU 的接口，这两个供电缺一不可。这里我看 CPU 部分主板有 8 + 4 Pin 的接口，而我只接了其中一部分，我首先把这里额外的 4 Pin 接上，这里的 4 Pin 似乎是给更高规格的 CPU 预留的，我也不是很确定接与不接是否可能有什么影响。接上后发现并没有用，和我自己的华硕主板不同的是他这款微星的主板并没有自带灯光，没启动电源之前没有任何明显的效果，我尝试插了个 USB 设备上去也是没电的，但有可能在首次启动之前它就是不会有任何供电的。接下来我在排查电源键的接线，是否可能接错，不排除线本身的问题的话可以试试螺丝刀短接一次电源部分（我之前就是没机箱这样裸板启动），结果我发现这也没有用。那么这里最大的嫌疑就是电源接口压根就不在这里，主板本身的安装说明写的位置不太清楚，我在网上搜同型号的主板安装教程，发现这里确实是接错位置了，接到了另外一处孔位一致的地方。这时我按下电源键，主板上的风扇灯亮起来了，这让我悬着的心放了下来，但是屏幕却始终黑屏，主板上的 Debug 灯也一直在亮，提示在 Boot 状态，为什么呢。这里我首先怀疑的是显卡，果不其然显卡的风扇被一处线头卡住了，但解决好之后也并不管用，可显卡风扇能转说明接线和电源肯定也是 OK 的，为什么呢？在我录制视频给 @提莫 看的时候，发现显示器突然就能亮了，非常的奇怪。并且能够正常的进入主板 BIOS 设置以及 Windows PE 系统。待我将 Windows 11 写入磁盘重启后，似乎它怎么重启都无法点亮。强制断电之后有概率能进去，但是提示系统损坏需要重新部署安装。我重新部署了一次系统镜像，重启后也是一样的问题，只要按下开机键之后就一直黑屏，似乎走到部署系统阶段之后就是稳定黑屏状态。现在的系统都是 UEFI 模式混合启动，从开机的瞬间就已经到系统层面了，这里有可能是软件问题导致的。软件排查我在网上搜索类似案例，得到的方案绝大多数都在说是电源问题，但有一个人的经验给了我非常大的帮助，说是装机不能使用 4K 屏幕。巧的是我去年确实就弄了一个 4K 显示器作为主力使用，客厅的电视也是 4K 的，就没有那种低分辨率的屏幕了啊，怎么办呢。死马当活马医，试了下客厅电视，结果能用，被电视识别成了 1080P 模式。安装 Windows 的界面也因此正常显示，虽然有花屏的情况（但我更怀疑是电视的问题，因为打开设置界面也是花的），在这里我只能说都 2025 年了，怎么这 Windows 内置的驱动还是这么垃圾，4K 显示器居然都不能原生支持...提莫：Windows 驱动太老了，因为默认的驱动是 CPU 软解，那个叫做 Microsoft 基本显示适配器来着？那个是 CPU 做的，因为没 5060 的驱动至此我在客厅电视完成了系统和驱动的安装，之后再插入到 4K 显示器操作，尝试了几次都能正常启动。后续安装了游戏《鸣潮》简单测试了一下性能和流畅度，4K 60 帧的刷新率还是轻轻松松。

2024 年终总结
type: item
date: 2025-09-11T16:55:00+00:00
description: 这篇总结酝酿的时间也挺长了，主要还是写了不少去漫展的事情。今年主要加强了在摄影方面的技能点，写码方面没有以前那么上进，已有项目的维护不多，也没有开新项目了。阅读指南：本文内容较长，图片数量也比较多，流量预警！如果速度较慢可以尝试使用科学上网！如果是博客和项目相关可直接往下阅读，漫展相关可直接点击 传送门项目与开源新版小窝前台3 月末，我酝酿了几个月的新版设计风格，正式上线。主要使用了 Vue 3 + Nuxt 框架来开发，依旧是手搓组件和功能，虽说旧版依旧还保留着，只是前端部分已经不再维护了。此后都在不断优化各种小细节，这些改动我认为比较值得列出来：4/12：背包页设备点击可查看详情4/13：在首页和歌单页以波形动画形式，展示当前播放的音乐5/28：获取表情数据更换为 setting/list 新接口，并改为状态管理存储初始值Nuxt 和 Pinia 集成度不错，能直接初始化值到 Store 里6/15：修改 SEO 关键词，解决 SVGO 砍掉动画的问题，更新滚动条样式这个修改记录了一个比较奇葩的问题7/27：新增在读详情快照页，调整在读页面布局给在读增加了快照功能，以对抗链接可能失效的问题9/8：相册单独的灯箱组件，展示照片 EXIF 详细参数为相册单独制作了一个灯箱组件，算是正式把相册“专业化”了，摄影佬的那种感觉。12/24：优化日记列表页媒体过多的阅读体验，默认折叠显示剩余图片数量这条记录的更改几乎都在使用 AI 编写代码，当然样式细节还是由本人优化小窝后端基本上都是以服务前端为主的改动，也是简单挑出一些值得列出来的：2/18：新增在读功能2/27：增加 useTokenPermission 授权方案，在读增加接口支持 Token 授权给插件做了一个类似“授权码”的机制，不需要登录即可执行某些接口的操作3/27：尝试解决 B 站视频不能获取的问题B 站再一次更新了 API 的校验，参考网上的方案尝试解决4/14：API 请求错误显示成 JSON询问 AI 用了一种兜底的方案，防止 PHP 逻辑出错打印出非 JSON 格式的内容4/21：修复路由 GET 的参数只带一个问号去请求会把问号当成请求名称的一部分的问题4/21：新增追番进度更新接口通过插件来实施更新追番进度，数据维护更自动化了5/7：引入 Composer 和 PHPMailer芜湖，终于在 PHP 上使用包管理器引入第三方代码了5/10：基础页面的 Sitemap 功能，后续需要补上日记、项目的目前博客的流量依旧远大于小窝，增加 Sitemap 功能或许能让小窝的收录比之前更好？5/27：增加判断是否有丢失源文件的媒体接口之前不是因为我误操作丢失过很长一段时间的图片么，这个接口是进一步检查缺失问题的，目前 404 的媒体应该减少到 30 条以内了7/27：完善在读接口的快照参数配合前端完成快照功能7/27：新增快照内容转存图片资源的接口就是提取快照里的图片转存一份到服务器上，不然可能会有防盗链的问题，不过后台并没有此功能的入口9/19：兼容 PHP89 月 12 日购买了 Bandwagon 的服务器，全新配置了一套 PHP 8 的环境，之后修复适配详见 尝试配置 OneInstack 环境失败，开始手工配置9/20：不知道为什么查表结果不是 string 而是 int 了，先改了吧不知道是升级了 PHP 版本还是 Medoo，返回数据类型变了导致我的判断出错了9/21：修改跨域相关设置，允许我的网站访问后台地址更换成二级域名来部署了，又遇到了一些新的问题尝试解决11/20：概括 RSS 日记中事情实际发生的时间主要是让 Follow 订阅的用户能了解原文的实际发生时间小窝后台1/11：批量上传媒体，未上传完毕阻拦跳转其他页面1/11：批量上传媒体，中间出现错误会直接结束循环并提示错误，可重新编辑上传队列1/14：分页器仅显示部分页码1/20：修复通知组件动画异常问题这就涉及到 React 的渲染机制了，如果 key 使用 index 则是原地重新 document.createElement 了（猜测）反过来至少用时间戳+随机字符串定义一个唯一值，则动画正常，不会因为其中一个元素消失重新播放2/19：新增在读功能2/29：在读字段扩展，增加作者、站点名、标签3/5：杂项内容修改保存前校验 JSON 格式是否合法5/30：useRequest Hooks 新增缓存功能虽然只是函数名称作为键名，主要是给相册分类使用6/12：新增精选媒体功能7/12：页面新增插图参数8/21：编辑在读文章快照内容9/21：增加跨域允许设置 Cookie 相关逻辑12/6：日记音乐播放器改为全局，页眉可控制（AI 写的12/11：存储音乐播放列表功能小窝工具箱插件在去年的总结里…

将 MO3 音乐导出成 WAV/MP3/OGG 等格式
type: item
date: 2025-08-31T13:20:00+00:00
description: 近期开始回忆杀状态，在 Steam 上购买并游玩了一些以前玩过的经典小游戏，其中包括来自 PopCap 宝开出品的《吞食鱼：2》。可能人老了吧，新的游戏都玩不动了，要么烧脑要么太肝，还是这种休闲小游戏玩法简单又上头！当时这部作品也有人将它翻译成《大鱼吃小鱼》，其中“吞食鱼”这个说法来源自《幻想游戏》系列。它也推出过很多“不同版本”的续集（其实就是一个整合包），汇聚了很多来自不同厂商的休闲游戏。游戏玩到了，BGM 也在反复洗脑了，那么如何将游戏里面的音乐提取出来继续听呢。了解博主过去黑历史的朋友应该知道，当时老喜欢用各种方式去提取各种游戏的资源素材了，其中《摩尔庄园》、《疯狂农场》等游戏都是我的常顾对象，收集各种游戏的 BGM 并且偶尔拿出来播放算是我的一个小众爱好。我找到了当年的一些素材提取工具（文件的修改日期为 2015 年，实际可能更早），其中有一款工具叫做 XMPlay，它可以用于 MO3 音乐的播放和提取。MO3 是一种音频文件格式，主要用于模块化音乐，类似于其他 MOD 格式（如 IT、XM、S3M 等）。它由 Ian Luck 为 BASSMOD 引擎开发，MO3 文件的一个显著特点是它使用 MP3 或 Ogg Vorbis 格式来编码音频样本，这使得文件体积相对较小，同时能够保持较高的音质参考：MO3 是什么格式，为什么现在几乎没人使用了对于模块化音乐，我的理解就是它将每一个音乐节拍的声音都作为一个片段存储，播放过程则是将所有片段循环复用，有点类似于 MID 音频格式，但是 MID 格式外放出来的音色受操作系统、播放软件等的影响较大时隔已久，我甚至都忘记了当年是怎么使用它提取音乐了，一番研究后总算是找到了办法。顺带一提，我 Google 之后得到的结果往往都是要你付费购买某些软件，几乎没什么中文文章提到过这些东西，看来确实有些小众啊，那么我就水一篇文章简单记录一下首先从 un4seen 下载并打开 XMPlay 播放器，这里我使用的旧版本，界面稍微比较复古。正常打开一首 MO3 音乐播放（吞食鱼游戏目录下有个 music 文件夹里面就是），此时从播放器主界面右键 -> Options -> Output -> Output Device 选择 "WAV Writer" -> Apply此时点击音乐播放按钮，就会弹出对应的另存为界面，依次确认导出，所有的音乐都会导出成功。如果想直接导出成 mp3、flac 和 ogg 格式，则需要下载对应的 CLI 工具，比如 Output Device 选择 "Encoder - LAME" 则是导出 mp3，需要先使用 winget 安装 lame 编码器winget install lame如果导出的音乐存在部分内容丢失或中断的情况，可能是因为你在播放器已经开始播放了，点击“停止播放”按钮再试一次即可目前博主已知使用 MO3 格式作为背景音乐解决方案的游戏包括：吞食鱼：2（Feeding Frenzy）幻幻球（Peggle）仓鼠球（Hamster Ball）理论上多数同期游戏都采用了这个方案，性价比特别高，比存储完整的 MP3、OGG 等格式都小，保真度还高。可惜从宝开《植物大战僵尸》等作品开始，都采用了 PAK 打包普通的音乐格式，此方案不再流行，也算是时代的眼泪了吧！

该写好代码吗？写好了也可能变得不好了
type: item
date: 2025-06-09T03:52:00+00:00
description: 最近同事分享了一篇文章：《该写好代码吗？我也迷茫了。写的代码好被替代，写的代码差到处救火》，引发了我的思考。我问了问他的看法，是写好还是不写好呢。答案可以说是意料之中，“正常写就好”。他觉得正常写也会有 Bug，代码也不会很糟糕。确实是这样，因为即便你当时认为写好了，这需求变化速度实在太快，后续很有可能就不能满足需求了，就产生了所谓的 Bug。这让我很自然的联想到我现在在公司做的 Felo 搜索 项目，确切来说它现在的定位已经渐渐不是一个纯粹的搜索网站了，而是各种 AI 工具的混合体，主要竞争对手是 Perplexity、Genspark、天工 等。前端方面我的评价是基本上已经乱的一锅粥，原先的逻辑很多不能满足现在的需求，就是一个超级缝合怪，既要 Perplexity 的那种搜索总结功能，又要 Genspark 的 Agent 型对话交互模式... 两种完全定位不同的东西被强行融合到了一起。但是换个角度来说，大公司做的东西不也是堆屎山么，不见得有多好，除非推倒重新开发。我们现在 996，就是飞快的加功能，老大天天都想发布新版本，怎么可能愿意干这种事？最近我们在做的 AI 生成 PPT 功能也差不多是这样子，越演越烈，产品交互方面并不统一，此前 PPT 是一个独立页面，任意入口点击后打开新窗口生成，之后是独立一套交互流程。而现在为了兼容“PPT Agent”模式（单独一个工具页，通过上传文档什么的触发创建一条记录），强行让其他入口套用它的逻辑。作为对比，和它入口旁边的同级功能，思维导图、智能图形，目前都不会单独创建新的记录（虽然它们也各自有一个 Agent 模式）。原先交互：打开一条搜索记录，找到生成的 PPT，打开独立页面现在交互：上述入口保留，生成的 PPT 会产生单独一条搜索记录，生成成功后则点击直接打开独立页面，并且作为 PPT 其入口还不在“文档库”里面，很迷后续需求还说得兼容之前搜索的逻辑，把原先那套模式给搬到新的 UI 上面，主打一个“抄谁不像谁”，代码逻辑的耦合性实在太强，很难想象之后要产生多少 Bug... 只能感慨地说一声，现在它已经彻头彻尾变成了“Felopark”了，这样的架构，代码也不太可能能写得多好了。所以回到最前面的话题，写代码正常发挥即可。至于可替代性什么的，只要你的能力不差，去哪里都会发光发亮不是么。