AI 写的代码,我是这样 Review 的:一份不太体面的清单

AI 写的代码,我是这样 Review 的:一份不太体面的清单AI 生成的代码有一个很“坑人”的特点:它读起来太顺了 命名规整,注释齐全,结构对称,连日志格式都统一 人写的代码出问题,往往在外观上就有迹可循,比如命名乱、缩进歪、注释写着“TODO 先这样” AI 写的代码出问题,外表通常是光鲜的 这就导致一个很尴尬的局面:越是看起来没毛病的代码,我们越容易放松警惕 所以这篇想聊聊我自己 Review AI 代码时的一份清单 说它“不太体面”,是因为里面很多条看着很基础,甚至有点小心眼 但在我看来,Review AI 代码,恰恰需要一点小心眼 图片来源:John 'Pathfinder' Lester / Flickr(CC BY 2.0)
AI 写的代码,我是这样 Review 的:一份不太体面的清单2026-10-14鱼鱼

Agent 的人类确认点:哪些操作必须等人点头

Agent 的人类确认点:哪些操作必须等人点头把权限和预算都收紧之后,还剩一个问题:有些动作即使技术上 Agent 做得了,也不该让它独自按下 删除、推远程、改权限、对外部发消息——这类事一旦做错,回滚成本不对称 我把这类关卡叫做人类确认点(human gate):Agent 可以准备好方案和命令,但执行前必须等人点头 原则很土:能撤销的可自跑,难撤销的先问人 我不太用“重不重要”来划分,而用“做错了能否廉价撤销” 易撤销: 改工作区文件、跑只读测试、本地格式化、生成草稿文档 中等: 本地 commit、加依赖但未推送、改本地配置 难撤销: force push、删数据、改生产配置、对客户发信、扩大公网权限、不可逆迁移 易撤销的,默认自动;难撤销的,默认闸门
Agent 的人类确认点:哪些操作必须等人点头2026-10-14鱼鱼

Java中的协程(虚拟线程)探究

Java中的协程(虚拟线程)探究在Java最新的LTS版本 21中,终于实装了协程这一特性 当然,在这些诸如python、golang等轻量级语言中被称为协程的东西,在Java中有个全新的代号——虚拟线程,为了将协程与线程做区分,在Java21中,原Thread被称之为平台线程 下文中,将统一使用线程/协程的方式称呼 我们都知道,Java中引入了线程的概念,区别于系统中的进程 作为并发执行的最小单元,在一定的条件下,使用多个线程同时运作可以有效提高程序的运转效率 而线程这一能力源于系统本身而并非JVM 之所以说是在一定条件下,是因为受限于机器配置情况(CPU的运作机制、核心数),线程的同时运作并不能线性的提升运行性能,单个cpu并不能同时处理多线程任务,实际的运作方式是基于时间片分片,各个线程抢占式执行代码,这样能减少一些无效的io等待(例如网络io、磁盘io实际是会阻塞等待io结果),同时在多核心场景下也能有效利用cpu
Java中的协程(虚拟线程)探究2024-10-28鱼鱼

让 AI 起变量名和函数名,我留下的几条品味规矩

让 AI 起变量名和函数名,我留下的几条品味规矩命名一直是我写代码时最磨蹭的环节之一 名字起糊了,后面读代码的人(包括一个月后的我)会一直付税 AI 很擅长甩出一串候选名,也很容易甩出看起来专业、读起来空洞的名字 这篇文章记我让它起名时留下的几条规矩——不是语法规范全文,是品味上的取舍 我愿意让 AI 起名,前提是: 我已经能用一句话说明“这个东西在业务里干什么” 我要的是 3–5 个候选,不是一个“最佳答案” 最终选定权在我,尤其是会进公共 API、表字段、事件名的那些 一上来就说“给个好名字”,它常会给你 handleUserData、processInfo、manageService 这类语法正确但语义稀释的词 候选机模式能逼它发散,也逼我比较
让 AI 起变量名和函数名,我留下的几条品味规矩2026-10-14鱼鱼

使用RPC与Restful接口调用服务

使用RPC与Restful接口调用服务在SOA和微服务架构中,远程通信是无法避免的,最常用的远程通信有两种方式: restful的接口,使用Http通信 使用dubbo或是Spring Cloud组件进行 RPC协议远程调用,可选地使用socket通信 不同的人对 RPC调用会有不同的看法,甚至对rpc本身的理解都不甚相同,但我认为 RPC有两种倾向: 一为语义化的 RPC 没有统一的请求规范,数据格式在开发人员中很难达成一致,在使用传统Http调用时,交互的双方需要约定一份“API文档”以保证数据格式的唯一性,这样API格式本身就成为了一道大墙,耽误研发双方的时间 但如果服务间采用语义化 RPC进行交互,双方可能并不需要一份文档,只要一份约定好的代码,并以此作为双方的依赖,在请求时也仅仅是直接调用方法本身,如此强的语义性怎能让人不爱
使用RPC与Restful接口调用服务2021-01-13鱼鱼

排坑指南-异步操作HttpServletRequest丢失Cookie

排坑指南-异步操作HttpServletRequest丢失Cookie遇到了一个很奇怪的bug:请求鉴权失败,因为通过Request对象获取到的Cookie中没有数据 经过debug调用request.getCookies()方法返回了null值,但是header属性的cookie却能拿到用户的有效cookie(request.getHeader("cookie")),其中缘由,且慢慢道来 我们可以在web项目中通过Request对象很方便的获取Cookie对象: 但其内部实现其实有一层缓存逻辑,从名为"cookie"的请求头中读取并处理数据转为Cookie对象并不是个省时事,在org.apache.catalina.connector.Request类中可以看到如下代码实现:
排坑指南-异步操作HttpServletRequest丢失Cookie2020-11-11鱼鱼

给 Agent 一个草稿本:为什么 scratchpad 比全塞进 prompt 更稳

给 Agent 一个草稿本:为什么 scratchpad 比全塞进 prompt 更稳做长任务 Agent 时,我最早的做法特别朴素:把所有中间结果、计划、反思,一股脑追加进对话上下文 反正模型“看得见”,多写点总没错 错就错在“多写点” 上下文很快又脏又长:旧计划和新计划并存,失败的工具输出还在,模型开始引用过期结论,或者在同一段推理上打转 更麻烦的是,你很难回答一个基本问题——此刻 Agent 到底相信什么? 后来我给 Agent 加了一个显式的“草稿本”(scratchpad):工作记忆外置到一块可读写的状态里,prompt 里只放当前需要的摘要和指针 稳定性和可调试性都好了不少 这篇讲讲为什么,以及我怎么划分什么该进草稿本 1. 噪声淹没信号 工具返回动辄几千字,失败堆栈、HTML 片段、长 JSON,全进上下文
给 Agent 一个草稿本:为什么 scratchpad 比全塞进 prompt 更稳2026-10-14鱼鱼

Redis原理-源码解析:数据结构1 字符串操作&SDS及预分配的实现验证

Redis原理-源码解析:数据结构1 字符串操作&SDS及预分配的实现验证所有原理实现基于Redis版本6.0.9 SDS(Simple Dynamic String)简单动态字符串,是Redis中字符串所采取的数据结构,SDS并不是Redis的独创,只是被Redis采纳的一种数据结构,用以替换C语言原生的字符串类型:sds仓库传送门 使用方法与原生的C语言字符串类似,并能提供很多类似的API SDS经过了两个版本,目前的解析大都基于v1 v1版本的sds数据结构很简单: 比起C语言中单一的字符数组构成的字符串,sds具有以下优势: 存储了字符串长度,相比C语言遍历获取长度,将时间复杂度由O(n)变为O(1); 当SDS每次发生修改时,会为其分配冗余空间,在字符串空间小于1MB时,每次分配实际长度2倍的空间,而在大于1MB时则是分配多1MB的空间,是在空间不足时才会触发分配
Redis原理-源码解析:数据结构1 字符串操作&SDS及预分配的实现验证2020-11-16鱼鱼

把报错贴给 AI 之前,我先做的三件事

把报错贴给 AI 之前,我先做的三件事以前一看到红字堆栈,我的第一反应几乎是:全选、复制、粘贴进 AI 对话框,然后等它告诉我怎么改 说实话,这个习惯有一段时间挺好用 很多常见错误,它一眼就能看出来,比我自己翻文档快 可后来我发现,有一半以上“贴完还是修不好”的情况,并不是 AI 不行,而是我把一坨还没整理过的信息甩给了它 它只能在这坨信息上猜,猜错了也不奇怪 现在我会强迫自己先做三件小事,再决定要不要问、怎么问 这三件事加起来通常不超过五分钟,但后面少绕很多弯路 不是真的要自己把根因找出来,而是先回答两个很朴素的问题: 这条报错,我看得懂“是什么”吗?发生的位置,离我刚改的代码近吗? 很多堆栈很长,真正有用的往往就那么几行:异常类型、消息正文、以及“第一次进入我自己代码”的那一帧
把报错贴给 AI 之前,我先做的三件事2026-10-14鱼鱼

用 Java + Spring 搭一个简单的 Agent

用 Java + Spring 搭一个简单的 Agent作为 Java 爱好者,很多人会问:Agent 开发是不是只能用 Python?其实不是 Agent 的核心是“调用模型 + 执行工具 + 循环”,用 Java 同样可以优雅地实现,并且能直接复用 Spring 生态里的依赖注入、配置、监控等能力 本文会一步步搭出一个可以扩展的 Agent 骨架:定义工具接口与注册表、封装模型客户端、实现带保护的 Agent 循环、暴露 REST 接口与会话存储,最后给出监控、测试、常见坑与迭代路线 让 Agent 调用 Java 业务能力的两种思路 很多企业的后端系统本身就是 Java 写的:订单、库存、权限、审批流都在 Spring 服务里
用 Java + Spring 搭一个简单的 Agent2026-10-14鱼鱼

给仓库写一份 AGENTS.md:让 AI 编程助手少走弯路

给仓库写一份 AGENTS.md:让 AI 编程助手少走弯路用 AI 编程助手久了,你大概会有一种“祥林嫂”式的疲惫:每开一个新会话,就得把同样的话再说一遍 “我们用 pnpm,不是 npm ”“跑测试要加这个参数,不然会连真实数据库 ”“generated 目录下的代码是自动生成的,别改 ”“提交信息要按这个格式写 ” 说一次两次还好,说到第十次,就会开始怀疑人生 更糟糕的是,你偶尔忘了说,AI 就会理直气壮地按自己的默认习惯来,然后你再花时间收拾 解决这个问题的办法其实很朴素:把这些话写下来,放进仓库,让 AI 每次开工前自己读 这就是 AGENTS.md 要干的事 图片来源:rawpixel.com(CC0 1.0) 一句话:给 AI 看的 README
给仓库写一份 AGENTS.md:让 AI 编程助手少走弯路2026-10-14鱼鱼

用 AI 代替搜索引擎一阵子之后,我又把搜索框请了回来

用 AI 代替搜索引擎一阵子之后,我又把搜索框请了回来有一段时间,我几乎不打开搜索引擎了 遇到不会的东西,第一反应是切到 AI 对话框,把问题一贴,等它给我一段整理好的答案 说实话,这个体验太舒服了:不用在十个标签页之间来回翻,不用忍受广告和那种互相抄来抄去的“技术博客”,看不懂还可以接着追问,它也不会嫌我烦 那阵子我甚至跟同事开玩笑说,搜索框可以退休了 后来发生了几件小事,让我又把搜索框请了回来 现在我两样都用,只是分工比以前清楚多了 这篇就聊聊这个过程,没什么高深的东西,都是日常里的小体会 那天升级了一个依赖的小版本,项目启动直接报错 我把报错堆栈贴给 AI,它很快给了一个解释:大概是某个类加载顺序的问题,建议我调整一下配置,再加一个排除项
用 AI 代替搜索引擎一阵子之后,我又把搜索框请了回来2026-10-14鱼鱼
网站地图
1
首页 博客 {{screen}} 第 {{page}} 页
博客索引
{{blog.createDate}} ◔ {{blog.timeline}} 小头像 {{blog.author}} {{tag}}
{{blog.likeCount}}{{blog.commentCount}}
分类下暂时没有文章哦!
主题分类
{{taggroup.label}} 

{{tag.value}}