网络时延、异步IO、Pipeline

网络时延、异步IO、Pipeline通过使用多线程是能提高网络延迟带来的负面效应的,也就是在IO密集型的应用中(尤其是网络IO密集应用中),通过异步操作或能显著提高性能,本篇讨论相关问题 并不是异步(多线程)定能提高性能,有这种讨论也是发现经常有人会滥用多线程 通常会有一种说法:如果想要采用多线程的来执行一段任务,为了提高性能,假设服务器中有N个核心,推荐在CPU密集型的应用中启用N个线程,而在IO密集型的任务中启用2*N个线程 本人不是很认同此种说法,他只能代表一个大致的度量,在实际应用中几乎可以说完全不准确,一般来说,权衡系统资源与性能后,前者可能需要更少的线程数,而后者根据实际情况也许适宜分配更多的线程数 这个概念大家一般都不是很陌生,在此再次科普下:所谓IO密集型任务,即是任务的资源消耗多集中在系统IO上,这里的IO本来包括磁盘IO和网络IO等,但是磁盘IO涉及文件句柄操作等系统限制不在本篇讨论,所以此篇文章所提主要指网络IO,高网络IO也是绝大多数web应用的特性
网络时延、异步IO、Pipeline2021-04-21鱼鱼

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

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

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

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

让 AI 帮我把项目升到 Spring Boot 3:它扛了体力活,也埋了几个坑

让 AI 帮我把项目升到 Spring Boot 3:它扛了体力活,也埋了几个坑我们组有个内部服务,一直跑在 Spring Boot 2 上 2.x 早就停止开源免费维护了,安全扫描隔三岔五报一堆依赖漏洞,升级这件事拖了很久,终于排到了我头上 这次我决定全程拉着 AI 一起干 前后大概用了一周多(中间还穿插着别的需求),最后顺利上线 回头看,AI 确实帮我扛了大部分体力活,但也有几个坑是它挖的,或者至少是它没提醒我的 这篇把过程和教训记下来,给同样准备升级的同学参考 先声明:下面说的都是我们这个项目的情况,每个项目的依赖和历史包袱不一样,具体以 Spring 官方的迁移指南为准 一开始我问 AI:“把这个项目从 Spring Boot 2 升到 3,需要改什么?”它给了一份清单,大方向没错:Java 版本要 17 以上、javax 包要换成 jakarta、Spring Security 的配置写法变了,等等
让 AI 帮我把项目升到 Spring Boot 3:它扛了体力活,也埋了几个坑2026-10-14鱼鱼

改了一句系统提示词,Agent 就变了个样:我开始给提示词做版本管理

改了一句系统提示词,Agent 就变了个样:我开始给提示词做版本管理先说一次让我印象很深的翻车 我维护着一个内部用的小 Agent,帮同事查工单、查日志、整理排查结论 有段时间有人反馈它“太啰嗦”,每次回答都要铺垫好几段 我就去后台的配置里,在系统提示词末尾加了一句:“回答尽量简洁 ” 改完自己试了两个问题,回答确实短了,挺满意,就没再管 过了几天,陆续有同事说它“变笨了”:以前问它某个工单的状态,它会先调用查询工具,再基于查到的结果回答;现在它经常不查,直接根据对话里的只言片语给个结论 还有一个多步骤的排查任务,它以前会一步步来,现在倾向于一步跳到结论 我一开始完全没往那句“尽量简洁”上想,在日志里找了半天别的原因 更尴尬的是,我想看看“几天前的提示词长什么样”,发现做不到——提示词存在配置后台,直接在线改,改完就覆盖了,没有历史
改了一句系统提示词,Agent 就变了个样:我开始给提示词做版本管理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鱼鱼

MySQL tips

MySQL tips一些日常接触到的MySQL优化tips,比较散乱 假设有一个用户表,对于一句很简单的查询语句: 假设name与age字段均有单列索引,容易想到的是,MySQL应该会分别走两次索引,并将其结合起来,EXPLAIN也是如此,大多数时候MySQL会进行优化,我们可能会看到EXPLAIN的结果中有Using union或Using soft union,这是MySQL针对OR做了隐性的优化,但当SQL复杂或数据极端情况下,这一语句极容易变成全表扫描,偶尔使用联合索引可能解决问题,更多情况则是MySQL“昏了头”,即使OR条件均涉及数据条数不多,依旧没能在查询语句中使用索引,此时应调整为UNION语句(可以权衡一下重复及顺序是否有影响,可以使用更快的UNION ALL):
MySQL tips2021-01-13鱼鱼

RAG 在 Coding Agent 里:什么时候有用,什么时候添乱

RAG 在 Coding Agent 里:什么时候有用,什么时候添乱一提到让 Agent “懂我们的代码库”,很多人的第一反应是上 RAG:把仓库切块、嵌入、丢进向量库,提问时先检索再生成 听起来理所当然,我自己也做过 用下来的感受是:RAG 在 coding agent 里不是默认答案,而是一种有代价的缓存与索引策略 用对了能省上下文、提高命中;用错了会检索到似是而非的片段,把模型带进沟里 这篇文章想尽量说人话:哪些场景我愿意上 RAG,哪些场景我宁愿用“直接读文件 / 搜符号 / 开测试”的工具,以及怎么判断它在添乱 图片来源:原创示意图 Coding Agent 跟“企业内部知识问答”不一样 它通常已经有这些能力: 列出目录、按路径读文件;
RAG 在 Coding Agent 里:什么时候有用,什么时候添乱2026-10-14鱼鱼

Agent 的 Token 账单怎么省:Prompt Caching、上下文瘦身与模型分级

Agent 的 Token 账单怎么省:Prompt Caching、上下文瘦身与模型分级做 Agent 的人,大概都经历过这么一个时刻:功能调通了,效果也还行,兴冲冲地跑了一批真实任务,然后打开账单页面,沉默了 同样是调用大模型,Agent 为什么比普通聊天贵这么多?钱都花在哪了?能不能在不明显影响效果的前提下省下来?这篇文章想把这笔账算清楚,再聊几种我觉得性价比最高的省钱办法 先声明一下:各家模型的价格和缓存规则变得很快,文中涉及的具体规则,以我写作时(2026 年 10 月)看到的官方文档为准,你落地之前最好再核对一遍 思路是通用的,数字请以官方为准 图片来源:Negative Space / StockSnap(CC0 1.0) 普通聊天,一问一答,输入的就是你的问题加上一些历史
Agent 的 Token 账单怎么省:Prompt Caching、上下文瘦身与模型分级2026-10-14鱼鱼

长任务 Agent 的上下文压缩:摘要什么、丢什么、什么必须原样留着

长任务 Agent 的上下文压缩:摘要什么、丢什么、什么必须原样留着我自己写的那个编程 Agent,最早只用来做一些小改动,十几轮对话就结束了,上下文从来不是问题 后来我开始让它做跨很多文件的迁移,比如把一批旧接口的调用换成新接口 这种任务一跑就是几十轮:读文件、搜索、改代码、跑测试、看报错、再改 每一轮的工具输出都往上下文里堆,没多久就逼近了模型的上下文上限 于是我做了第一版“压缩”:上下文超过某个阈值,就让模型把之前的历史总结成一段话,然后用这段总结替换掉原来的历史,继续往下跑 听起来很合理,跑起来问题一大堆 这篇就讲讲我前后几次改动的过程,以及现在比较稳定的做法 都是在我自己这个 Agent 上摸索出来的经验,换个场景未必完全适用 第一版用的是自由发挥式的摘要,提示大概就是“请总结上面的对话,保留重要信息”
长任务 Agent 的上下文压缩:摘要什么、丢什么、什么必须原样留着2026-10-14鱼鱼

算法:递归

算法:递归递归算法主要寻找: 终止条件:递归的尽头 单级递归的行为:在一次递归里要做的事情 返回值:每次迭代要return的东西 例如 首先,假定方法是已经实现的 终止条件为:当当前节点(传了空节点)或下一节点(传了单节点)为空,则无需反转返回当前节点 递归行为:假定之后的节点均已实现反转,则需要将已经反转的尾部的next变为当前节点,而当前节点由于是第一个节点,其next为null 此处注意在反转前需要先留存反转后的尾部; 返回值:返回反转后的头结点
算法:递归2020-06-24鱼鱼

浅谈代理-动态代理

浅谈代理-动态代理我们可以很轻松的实现一个简单的代理 实现静态代理是个很简单的事情,最基础的代理只需要定义一个接口(虽然不是必要,但这显然才是标准的设计)、一个被代理类和一个代理类,例如: 定义一个接口: 一个实现类: 和一个代理类: 实际使用时,我们是去调用HelloWorldProxy的方法,其将作为HelloWorld的代理实现 此种方式直接实现的代理太过于死板,因为每一种代理行为都要制定一个代理类,我们熟知的很多基于代理的实现(譬如AOP、事务)显然不可能用静态代理的方式针对每一处类切点都覆写一个代理类,这种时候就需要动态代理 我们所熟知的相当多的框架均基于动态代理开发,JDK本身基于反射(java.lang.reflect)提供了动态代理,我们只需定义代理的行为,而对于代理类的范围并不是固定值
浅谈代理-动态代理2020-10-13鱼鱼
网站地图
1
首页 博客 {{screen}} 第 {{page}} 页
博客索引
{{blog.createDate}} ◔ {{blog.timeline}} 小头像 {{blog.author}} {{tag}}
{{blog.likeCount}}{{blog.commentCount}}
分类下暂时没有文章哦!
主题分类
{{taggroup.label}} 

{{tag.value}}