扫盲——加密那些事
扫盲——加密那些事扫盲加密解密算法 日常开发中我们经常接触MD5算法,以此进行简单的文件完整性校验或者是后台密码验证,MD5是最常见也是最简单快捷的散列算法,常用于参数或文件完整性校验,譬如网络请求发起方与接收方分别对参数做MD5编码,一旦不一致便判断请求被篡改从而拒绝该请求,从而保证信息安全,编码后的字符串是编码前文本的一个简要梗概,因此它也被称作是信息摘要算法 这个算法的特点就是不可逆,只用于信息准确性和防篡改的校验,当然,MD5作为老牌的散列算法,很多经典的编码已经可以被反向解码出来(依靠正向的暴力穷举)以及被碰撞模仿(王小云院士团队的"破解"能够根据MD5编码后串码模拟原始消息,即使它可能与原信息不同),类似的还有SHA1,因此衍生了SHA224、SHA256、SHA512等更多安全的散列算法

2021-05-14鱼鱼
JVM源码解析(2) ContextClassLoader与ClassUtil.forName()方法浅析
JVM源码解析(2) ContextClassLoader与ClassUtil.forName()方法浅析在Spring获取Context的源代码中,我们看到了对ClassUtil的方法调用,通过给定ClassName和ClassLoader进行Class的加载: ClassUtil.forName是仅供于Spring内部使用的获取Class对象的方法,来看一下源码: 首先 对于缓存的Class一块,在类的静态块中就能看出其逻辑: 在上面的resolvePrimitiveClassName方法中,先对长度做了一个判断,因为较长的packagename会影响执行的性能: 最终加载Class依旧是通过ClassLoader的,先来看一下获取ClassLoader的方法实现: 此处优先使用了ContextClassLoader作为 类加载器而非默认的AppClassLoader,在JVM源码解析 从 Launcher类浅谈ClassLoader中,提到了关于 类加载器的相关知识,使用ContextClassLoader是为了弥补双亲委派加载机制的对于自定义 类加载器的缺憾:那些自定义的 类加载器并没有机会上场,在使用了AppClassLoader后我们的自定义ClassLoader所加载的Class是无法被加载进去的,使用ContextClassLoader,我们可以在定义线程时,通过Thread的init方法(子线程调用,私有方法)或是setContextClassLoader直接指定使用自定义的ClassLoader
![JVM源码解析(2) ContextClassLoader与ClassUtil.forName()方法浅析]()
2020-08-16鱼鱼
给 Agent 设超时和步数预算:别让它无限跑
给 Agent 设超时和步数预算:别让它无限跑第一次把 Agent 接到真实仓库时,我犯过一个很土的错:只盯着“它能不能做完”,没盯着“它最多能跑多久、最多能走几步” 结果某次工具调用卡在外部接口,它一边重试一边换策略,token 和墙钟时间一起烧,最后我手动杀掉,现场还一堆半成品文件 从那以后,我把超时和步数预算当成和权限同级的安全项 不是为了虐待 Agent,而是承认:自动化一旦没有硬上限,失败模式会从“报错”变成“悄悄耗尽” Agent 的轨迹很会制造希望:每一步都有日志,每一步都像在进步 可进步不等于收敛 常见假象包括: 同一类错误换着措辞重试 在几个文件间来回改,测试始终红 搜索范围越扩越大,上下文越来越脏

2026-10-14鱼鱼
浅析RPC框架Thrift
浅析RPC框架ThriftThrift是由Facebook开发的 RPC远程调用的框架,使用独有的Thrift协议进行可跨语言的远程调用 有点类似protobuf 无论使用何种语言,首先要准备Thrift编译环境,可以去官网下载相应的Thrift执行文件,下文均以Windows为例 下载后可以选择性的配置环境变量,最终在shell中可执行Thrift 在项目中,预先准备好libthrift依赖,maven写法: 例如: 定义一个testService.thrift(idl文件名不重要),一般都会定义在resources的thrift文件夹下: 这里定义了两个方法,分别返回字符串和int类型,在thrift的idl中,对于变量的定义如下:

2022-03-04鱼鱼
JVM源码解析 从Launcher类浅谈ClassLoader(类加载器及双亲委派)
JVM源码解析 从Launcher类浅谈ClassLoader(类加载器及双亲委派)首先普及ClassLoader的基础:所有的Java类都是由ClassLoader由class文件加载进内存的,对于一个类,其唯一标识就是类名+加载他的ClassLoader(亦即对于不同的 ClassLoader,即使是加载了同一个Class也不能互通,本质上是两个类),其基本的分类如下图: BootstrapClassLoader是一个特殊的ClassLoader,负责启动时加载jre的类库 并不继承于ClassLoader,因为是jvm逻辑的一部分; ExtClassLoader也会加载jre类库,但是会加载那些额外的扩展类库(jre\lib\ext目录),到这个级别的 类加载器已经可以直接在代码中使用了;

2020-11-28鱼鱼
提示词工程与上下文工程:让模型看到“对的信息”
提示词工程与上下文工程:让模型看到“对的信息”写 Agent 时,很多人把精力放在“提示词怎么写得更花哨”上 实际上,更影响效果的往往是:在每一步,模型的上下文里究竟放了什么 这就是近来常被提起的“上下文工程(Context Engineering)” 本文先区分提示词工程与上下文工程,再讲系统提示的结构、上下文的选择/压缩/隔离/外置四种手段,提供一个带 token 预算的上下文组装器(Python)与结构化输出校验(Python + Java),最后总结常见错误、检查清单与 FAQ 上下文窗口里的六个组成部分 很多团队有过这样的经历:换了更强的模型,效果只提升了一点;而把检索结果排序调整了一下、把冗长的工具输出裁剪了一下,效果反而明显改善

2026-10-14鱼鱼
AI 编程工程化迭代中的混沌风险:从规格熵到四个工程控制面
AI 编程工程化迭代中的混沌风险:从规格熵到四个工程控制面过去两年,我们团队把 AI 编程工具真正用进了日常研发:补全式的 Copilot、IDE 里的对话助手,以及能自己读写文件、跑命令的 Agent 收益是实打实的,样板代码、单元测试、脚本、联调、陌生框架的第一版实现,速度都明显提升 但用得越深,我越确信一件事:AI 工程化迭代最危险的地方,不是它“不会写代码”,而是它太会写了 在缺少稳定工程约束的时候,它会持续、高速地产出“单独看都挺合理,放在一起却彼此矛盾”的局部方案 这些矛盾的方案不会立刻表现为一个 Bug 它们表现为一种缓慢累积的混乱:同一个纠正反复被推翻,数据库越改越别扭,代码里一个概念长出两三个名字,线上出事时拼不出一条完整的因果链

2026-10-14鱼鱼
算法:Trie(前缀树、字典树)
算法:Trie(前缀树、字典树)前缀树(Trie,又称字典树)是一种功能倾向性很强的数据结构,通过对词汇的前缀做数结构,很容易实现查询、前缀词推荐系统,例如,我们将如下多个单词放入树结构中: [apple,bat,bee,cat,cap,car],最终生成的前缀树结构为 通过深度递归,我们很容易用较小的时间复杂度判断出符合前缀的单词在不在 假设Trie的字符集范围是固定的,并且范围不大,例如是上面的纯英文字符,假设忽略大小写总共为26个,可以选择使用桶结构进行存储,即每一个Node都是一个长度为26的bucket数组 这样看来,Trie的结构并不复杂,只通过循环不断提高深度进行遍历即可 假定字符集的范围是未知的,或者范围很大(比如中文汉字),就要放弃使用bucket结构,而是通过一个Map维护,这里使用树结构TreeMap,key为相应节点的字符

2021-01-19鱼鱼
数据库使用指南:MySQL 与 PostgreSQL,一份写给后端开发者的实战手册
数据库使用指南:MySQL 与 PostgreSQL,一份写给后端开发者的实战手册大多数后端工程师和数据库打交道的方式,是这样演进的:先学会 CREATE TABLE 和 SELECT,再被某次线上慢查询教育一遍,接着是死锁、主从延迟、大表加字段锁住业务、误删数据找不到备份……每一次事故,都是对数据库“知识债”的一次还款 这篇文章希望把这些债务提前梳理一遍:不是 DBA 手册,而是写业务代码的人需要知道的那一部分,同时把 MySQL(InnoDB 引擎)和 PostgreSQL 放在一起讲,因为在实际工作中,你很可能两个都会遇到,而且两者的差异恰恰是很多坑的来源 全文按照一个后端项目从“选型”到“上线运维”的顺序展开: 选型与建模:怎么在 MySQL 和 PostgreSQL 之间做选择;表结构、主键、数据类型、时间、字符集、范式与反范式、软删除、唯一约束

2026-10-14鱼鱼
Agent 的工具调用日志:出了问题我先看哪几行
Agent 的工具调用日志:出了问题我先看哪几行Agent 一跑起来,日志可以很热闹:思考摘要、工具名、参数、返回、重试、最终回答……出了问题时,若从头通读,既慢又容易被模型的“自信叙述”带偏 我逐渐养成一个习惯:先不看它怎么说,先看它调用了什么、参数是否离谱、返回是否被误解 这篇文章记我排查 Agent 故障时的日志阅读顺序 偏工程经验,不是某家产品的官方手册 失败时我最想看的其实不是最终答复 答复是渲染后的故事,故事会把中间的错误抹平 更常见的情况是: 所以我把最终答案降级成线索,把工具轨迹升级成证据 图:先证据后故事:工具轨迹优先于最终答复(原创示意图) 只看序列:读文件 → 搜代码 → 改文件 → 跑测试 这种骨架

2026-10-14鱼鱼
AI大模型定价对比
AI大模型定价对比https://open.bigmodel.cn/pricing 火山方舟也提供端点(GLM3 0.001) https://openai.com/ja-JP/api/pricing/ 出入价格不一样 官网和火山都有 另外有免费版本的

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

2026-10-14鱼鱼