🏠 HomeLab:中年男人之友
未读中年男人的三大爱好:充电头、NAS、软路由。这三大爱好不仅为我们的生活带来了便利,也成为了我们生活的一部分(🤡)。 作为一个软件开发者,我一直梦想着拥有自己的服务器,而 NAS 和软路由则是我通往这个梦想的桥梁。 自从购买了我的第一台 NAS 以来,便打开了一扇新世界的大门。NAS,即网络附加存储(Network Attached Storage),它不仅提供了一个安全的数据存储解决方案,还让我能够实现数据的备份和共享。随着时间的推移,我陆续购买了其他硬件产品,如软路由器、服务器等,逐步搭建起了属于我的 HomeLab。 今天,我想和大家分享一下我搭建 HomeLab 的过程,希望能够帮助到那些同样有志于搭建 HomeLab 的朋友。在接下来的博客文章中,我将详细介绍如何选购合适的 NAS 设备、软路由器以及服务器,并分享我在搭建过程中遇到的挑战和解决方案。 HomeLab 并非遥不可及,只要我们用心去探索和实践,就能开启属于自己的个人云端实验室之旅。让我们一起学习、交流和成长,共同打造一个属于我们的数字王国。 前提说明虽然关于 HomeLab 的文章已经很多了,但我还是想记录下自 ...
背景其实需求很简单,就是想在 hammerspoon 里加个功能:当我连着公司的 iHome WiFi 时,鼠标高亮用 home.png;到了别的地方换成 work.png。WiFi 名大概长这样:ihome.6500.5g、ihome.ax9000.5g 这种。 踩坑过程第一次尝试:hs.wifi.currentNetwork()想着这不是很简单嘛,搜了一下官方文档,直接调 hs.wifi.currentNetwork() 不就行了: 12local ssid = hs.wifi.currentNetwork()print("当前 WiFi ssid:", ssid) 结果一跑,nil,啥也没打印出来。加点打印确认一下: 1当前 WiFi ssid: nil 行吧,这条路走不通。 尝试 airport 命令Mac 上传统获取 WiFi 信息的方式是 airport 命令: 12/usr/local/bin/airport -I/System/Library/PrivateFrameworks/Apple80211.framework/Versions/ ...
一份文档, 两类读者我维护 Zeka Stack 这套开源框架已经几年了, 它做的事情和大部分公司里的 Spring Boot 脚手架差不多 —— 一堆 cubo-*-spring-boot-starter, 每个 Starter 提供自动配置、统一的异常 / 响应 / 日志 / 配置语义, 让业务项目少写样板代码、多走规范轨道。 过去几年, 我一直把这件事看成”给开发者写文档”。Starter 写完之后, 配套一份 README.md、几个示例工程、一份 docs/ 目录, 同事或开源用户引入 starter, 翻一翻文档, 就能上手。 但去年开始, 我越来越清楚地意识到一件事: 文档的读者变了。过去文档只给开发者看, 现在 AI 也是一种用户 —— 而且会是越来越主要的那种。当业务项目里的同事让 Cursor / Claude Code 写一段 REST Controller 的时候, AI 不会去翻我的 README, 也不知道我这个 starter 自动装了哪些 Bean, 不知道哪些 Bean 可以覆盖、哪些不应该绕过, 不知道 ...
🛠️ 开发工具与插件
未读作为一个天天泡在终端里的开发者,我对 Gemini CLI 这类 AI 编程助手是有依赖的。但问题来了——我之前订阅的 Gemini 即将到期,偏偏因为学生认证的限制没法续订。于是我用另一个账号重新订阅了 Gemini Pro,这下手头就有了两个付费账号。两个账号放着不用太浪费,但在不同项目间手动切换实在折腾:关掉当前任务、切换认证凭据、重新跑命令,节奏一断思路也跟着断了。gcam(Gemini CLI Account Manager) 就是来解决这个问题的——它让你的多个账号组成一个池子,需要时自动切换,整个过程对使用者完全透明。项目落地页在 gcam.dong4j.site。 背景:为什么需要多账号管理Gemini CLI 的付费订阅(Google AI Pro)每天大约有 1500 次请求配额,每分钟也有请求频率限制。对于日常开发来说这个量通常够用,但当你像我一样因为续订限制而持有两个付费账号时,手动管理就变成了一个麻烦事——更不用说在多个项目间频繁切换的场景了。 手动切换账号的流程本身并不复杂:改个配置、重新认证一下就好。但问题在于它把一个本该自动化的决策强加给了使用者。你得 ...
翻车现场我自己写过的 Agent Skill, 现在回头数, 大概在十几份的量级。这十几份里面, 至少有一半在写下来的当下就是错的。 举几个典型: name 字段写得很随意, 跟父目录名对不上 —— Agent 加载的时候按目录名走, 但匹配按 name 走, 我调了快一小时才发现 skill 根本没被识别。description 写成 “helper” 或者 “tool” 就交差了, 等到真的去用, Agent 完全不知道该在什么场景触发它, 因为没有任何触发短语 (“use when”, “when to use” 之类), AI 看了等于没看。一段 rm -rf 当时只是放在正文里当示意, 完全没想到 Agent 会把它当成可以执行的步骤直接跑。一段 references/api-design.md 的 link 引用我写完之后忘了真的把文件建出来。还有一个最尴尬的, 我把 api_key="sk-..." 直接硬编码到 skill 里某个示例脚本, 然后 push 到了开源仓库。 每一条都是低级错误, 每一条都是”如果有人在 IDE 里提醒我一句, ...
🤖 AI:人工智障
未读背景最近在找工作。 我觉得自己的简历写得还算可以——项目经历、技术栈、工作职责,该写的都写了。但 BOSS 上投出去,十有七八已读不回。姑且不说「HR 只是占坑不拉屎」,我更偏向于: 简历是不是写得不够 match JD? 我倾向于相信:一份简历应该「面向 JD 定制」,而不是用同一份简历广撒网。所以每次投递之前,我都会根据 JD 重排技能关键词、调整项目侧重点。但问题是:如果每个公司都这么手动来,工作量太大了。 另一方面,我有个习惯——投递之前会先去意向公司的官网看看,顺便试用一下他们的产品,然后用一些合理的技术手段了解一下公司用的技术栈,甚至看看有没有什么常见的漏洞。这些信息对写简历有帮助,但收集起来是个体力活儿。 所以我想:能不能把这些重复劳动自动化? 每次看到感兴趣的 JD,跑一条命令,自动生成一套材料:公司调研、JD 匹配分析、定制简历、打招呼话术、面试追问——全部搞定。 前提:个人 Wiki 知识库但这里有个前提:如果想让 AI 生成有质量的定制简历,AI 必须「了解你」。如果只是让 LLM 从零开始编,它要么瞎编,要么写出来的东西跟市面上千篇一律的简历没什么区别。 我的 ...
背景最近我一直在重新思考一个问题:在 AI 已经可以大量生成代码的今天,Spring Boot Starter 这类工程脚手架的价值还剩下什么? 过去做 Starter,主要是为了减少重复配置。开发者引入一个依赖,就能获得自动配置、默认 Bean、统一异常处理、统一响应模型、消息队列封装、接口文档集成等能力。它解决的是“少写样板代码”和“统一工程规范”的问题。 但现在 AI 已经能很快生成 Controller、Service、DTO、Mapper,甚至配置文件和测试代码。单纯减少样板代码,已经不再是框架最核心的竞争力。 真正的问题变成了:AI 写出来的代码,是否理解你的工程体系? 它知道项目为什么要用统一响应模型吗?它知道某个 Starter 已经自动装配了哪些 Bean 吗?它知道哪些 Bean 可以覆盖,哪些不应该绕过吗?它知道同一个组件下 Servlet Starter 和 Reactive Starter 应该怎么选吗?它知道团队约定的异常处理、配置方式、日志方式和扩展边界吗? 如果 AI 不知道这些,它写得越快,偏离工程规范的速度也越快。 这也是我在思考 Zeka Sta ...
统一管理本地 Code Agent 全局规则:从 AGENTS.md 到 Synology Drive 同步最近一段时间,我在本地同时使用了几类 Code Agent 工具,比如 Codex CLI、Claude Code、opencode、Gemini CLI,再加上平时也会用 Cursor。这些工具确实能显著提升开发效率,但用得越多,一个问题也越明显: Agent 很强,但如果没有稳定的规则约束,它很容易“过度发挥”。 比如: 让它给一个实现建议,它直接开始改代码; 明明只是一个小需求,它生成一堆复杂抽象; 原本只需要局部修改,它顺手重构了一大片; 新增文件没有注释,没有上下文说明; 不同工具之间行为不一致,同一个需求在 Claude Code、Codex、Gemini 里表现完全不同; 一个工具记得“先给方案再修改”,另一个工具上来就落盘。 这些问题单看都不大,但在日常工程开发里会不断累积成摩擦:你需要反复提醒、反复纠偏、反复 review AI 生成的无关改动。 于是我今天做了一次整理:把多个 Code Agent 工具的全局规则统一起来,放到一个可同步的全局规则文 ...
🔥 效能提升
未读背景在 IDEA 或其他开发工具里,生成 Git 提交记录已经是一件很简单的事情。 比如我在 IDEA 里会用 IntelliAI Changelog 插件,点一下图标,就可以让 AI 根据当前变更生成一条比较准确的 commit message。对日常开发来说,这个体验很顺手:不用手动翻 diff,也不用纠结这次到底该写 fix、docs 还是 chore。 但到了终端里,事情就稍微麻烦一点。 我本机有不少本地仓库,不全是正式项目。有些是 Surge 配置,有些是 Wiki 知识库,有些是博客依赖目录,还有一些是个人小工具。它们都用 Git 记录变更历史,但我不想每个仓库都手写提交记录。 一开始最直接的办法,是把 staged diff 丢给 Claude: 12345678git diff --cached | claude -p '根据 git diff 生成一条中文 Conventional Commit message。只输出 commit message,不要解释。格式:<type>(<scope>): <subject>&l ...
🤖 AI:人工智障
未读原帖链接:https://x.com/dotey/status/2052929093461528903?s=20 使用 Claude Code:HTML 难以置信的奇效【译】 原文: Markdown 已经成为 AI 智能体 (AI Agent) 与我们沟通时最常用的文件格式。它简单、便携、具备一定的富文本 (Rich text) 能力,而且极其容易进行人工修改。你甚至会发现,Claude 已经变得极其擅长在 Markdown 文件里用 ASCII (美国信息交换标准代码,这里指用纯文本符号拼凑成图表) 字符来画图了。 但是,随着 AI 智能体变得越来越强大,我开始觉得 Markdown 变成了一种束缚。面对动辄上百行的 Markdown 文件,我根本没有耐心读下去。我想要更丰富的视觉展现、明亮的色彩和直观的图表,而且希望能够轻松地把它们分享给团队。 另外,我现在越来越少亲自去编辑这些文件了。我更多是把它们当作需求文档 (Specs)、参考资料或是头脑风暴的输出结果。即使需要修改,我通常也是直接写提示词 (Prompt) 让 Claude 去改。这就让 Markdown 最核 ...
我的 AI Native 开发者画像(2026) 基于 196 天的本地 Claude Code + Codex 对话数据自动生成 · 2026-05-08T15:18:22+08:00默认对外分享版:项目名已匿名,敏感字段已清洗。 一览 在 196 天里完成 481 次 Claude sessions + 296 次 Codex threads,共 1.9万 条 Claude 消息 日均产出:20.69 commits / 8.1万 行代码变动 / 28.23 GitHub contributions 同时维护 18 个本地仓库,横跨 74 类语言/文件扩展 同期 GitHub:2,155 commits / 1 PRs / 30 issues / 2,682 总贡献 本地 git:1,966 commits / +5.24M / -2.46M AI 投入:27.24M Claude 新付费 token + 1.46B Codex token;复用 215.98M 缓存(占 Claude I& ...
🖥️ 基础设施与运维
未读背景最近我在看博客 CDN 访问日志时,发现静态资源的访问量异常增多。 一开始只是觉得有点不对劲:博客本身访问量没有明显上涨,但 CDN 流量消耗却比平时快了不少。继续往日志里翻,发现大量请求都来自一个叫 YisouSpider 的爬虫,而且请求的还不是文章页面,而是博客里那些 JS、CSS 静态资源。 这篇文章记录一下完整的排查过程、问题原因,以及最后为什么我把拦截规则放到了 CDN 层,而不是只在源站 Nginx 里处理。 问题现象在 Nginx / CDN 访问日志里,可以看到大量类似下面的请求: 12320260507164510 124.239.12.111 cdn.dong4j.site /source/static/index-imgloaded.css 1379 1069 2 200 https://blog.dong4j.site/ 215 "YisouSpider" "(null)" GET HTTPS miss 5833520260507164510 116.132.218.241 cdn.dong4j. ...
🧱 后端开发与架构
未读背景随着业务不断扩展,系统服务数量和访问压力持续增长,当前整体架构已逐步暴露出性能瓶颈与资源竞争等问题,影响了核心业务的稳定性和扩展性。系统采用微服务架构,目前共计 17 个微服务,分布在多个业务域中,运行一段时间后主要暴露出以下典型问题: 部分核心服务资源占用高,影响其他服务的稳定运行; 统计类服务存在大量复杂查询,导致数据库压力集中,查询响应缓慢; 存在分布式事务、大事务与表锁并发问题,在高峰期容易造成请求阻塞或死锁; 缺乏读写分离、异步化、缓存等优化手段,导致部分非关键路径也占用大量系统资源; 系统在监控、限流、容灾等方面存在不足,缺乏针对高并发场景的应对策略。 为全面提升系统性能与稳定性,我们计划从架构优化、数据库治理、慢 SQL 缓解、中间件调优、Spring Boot 优化、连接池/线程池、异步请求等多个方面,逐步推进整改工作,以提高系统稳定性与高并发要求。 项目基础情况技术架构: Spring Cloud Alibaba 微服务架构基础框架: RuoYi 微服务框架核心业务: 用工需求发布、派工管理、支付结算、数据统计 技术架构技术栈 后端: Spri ...
🧱 后端开发与架构
未读验证码是用来干什么的验证码的核心作用就一个:提高自动化滥用的成本。 让机器不能以极低成本去暴力枚举。说白了就是让非法的请求尽早被拦截,不要让它打到数据库。 这个定义反过来也成立:如果一个验证码实现,不能在前置阶段拦截非法请求,而是让请求先查一次数据库再校验验证码,那它就没起到验证码的作用。 不幸的是,我们的验证码实现就是这样。 先查数据库,再校验验证码验证码校验逻辑在网关的一个 Filter 中实现。简化的流程是这样的: 123收到登录请求 → 判断用户名是不是手机号 → 是:跳过用户查询,直接用手机号校验验证码 否:先通过用户名查询用户信息(DB 查询!) → 再校验验证码 关键代码(脱敏后): 1234567891011121314151617if (!Validator.isMobile(username)) { // 通过帐号查询手机号(登陆名不一定是手机号) CompletableFuture<Response<LoginUser<?>>> completableFuture = Comple ...




















