自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

lqbzlll的博客

欢迎大朋友,小朋友光临我的博客!

  • 博客(39)
  • 收藏
  • 关注

原创 ThreadPoolExecutor 任务被拒绝了:四种拒绝策略分别在什么场景下该用

当线程池核心线程满、队列满且最大线程数已达时,任务将被拒绝。四种内置策略中:AbortPolicy 适合需感知拒绝的场景;DiscardPolicy 适用于可丢失的任务;DiscardOldestPolicy 用于保留最新数据;CallerRunsPolicy 实现反压,但慎用于 Web 请求线程。自定义策略可用于日志记录、重试或转移至备用池。排查拒绝问题需监控线程池状态并手动计数拒绝任务。虚拟线程虽提升并发,但仍需关注拒绝策略以避免资源耗尽。

2026-11-03 15:22:14 152

原创 JDK 21 的 StructuredTaskScope 解决了什么问题?和 CompletableFuture 到底差在哪

JDK 21 的 StructuredTaskScope(JEP 453)解决了 CompletableFuture 在任务生命周期管理上的缺陷:异常处理分散、取消机制缺失、线程归属不透明。它通过结构化并发理念,确保子任务在作用域关闭时自动终止,实现“任务启动即绑定生命周期”。相比 CompletableFuture 需手动取消、异常传播不一致等问题,StructuredTaskScope 提供更安全、简洁的并行编程模型。其内置的 ShutdownOnSuccess 与 ShutdownOnFailure

2026-11-03 15:21:27 161

原创 Spring AI 2.0 的 Advisor 链到底改了什么?从 1.x 的工具调用黑盒到可拦截管线

Spring AI 2.0 将工具调用循环从 ChatModel 内部移至 Advisor 链,由 ToolCallingAdvisor 统一管理,实现可拦截、可扩展的工具调用流程。通过五个钩子方法(如 doBeforeCall、doAfterCall)支持审计、限流、动态工具注入等场景。相比 1.x 的黑盒行为,2.0 提升了可控性与一致性,便于生产环境集成与监控。

2026-11-03 15:20:43 496

原创 Redis 分布式锁到底有哪些边界?从 SETNX 到 Redisson 看每一层可能出什么问题

环境:Redis 7.x 单实例与 Sentinel 模式、Redisson 3.37.x、Spring Boot 3.4.x。文中代码和命令均在本地验证,不涉及不可考的生产事故。RedLock 部分只做机制说明,不推荐作为通用方案。

2026-11-02 16:57:47 257

原创 MySQL 慢查询日志开了但看不懂?从 slow_query_log 到 EXPLAIN ANALYZE 一步步定位

本文详解MySQL慢查询日志的开启与分析,涵盖配置验证、三种开启方式(动态变量、配置文件、工具分析)、日志解读及执行计划优化。重点解析EXPLAIN六关键列与EXPLAIN ANALYZE的实际执行数据对比,揭示全表扫描、函数索引失效、模糊匹配、类型转换等四大常见慢查询模式,并提供针对性优化方案,助力高效定位性能瓶颈。

2026-11-02 16:57:08 341

原创 第一次读 JVM GC 日志:逐段标注一份真实的 G1 输出,告诉你每行在说什么

本文以JDK 21的G1收集器为例,详解真实GC日志的逐行含义,涵盖Young GC、Mixed GC与Full GC的触发机制与关键指标。通过时间戳、堆变化、暂停时长等字段,揭示GC行为背后的内存回收逻辑。重点提炼四个核心监控指标:频率、暂停时间、回收效率与堆占用率,并给出调优建议与换收集器场景(如高停顿需求选ZGC,小堆选Shenandoah)。附带实用工具推荐,助力开发者快速诊断性能瓶颈。

2026-11-02 16:56:30 282

原创 Spring 的 @Transactional 为什么有时候不生效?8 种失效场景逐一验证

环境:Spring Boot 3.4.x、Spring Framework 6.2.x、MySQL 8.0.45、JDK 21。文中所有场景均在本地最小项目中复现并验证,不引用"线上事故"或不可考的经验。

2026-11-01 10:26:13 309

原创 Spring Boot 开启虚拟线程后接口反而变慢了?4 个排查方向和对应修法

环境:Spring Boot 3.4.x / 4.1.x、JDK 21+、MySQL 8.x、Redis 7.x。文中排查思路基于本地复现和公开技术文档,不涉及不可考的生产事故。

2026-11-01 10:25:37 328

原创 JDK 25 的模式匹配到底改了什么?从 switch 到 Record 一次讲到位

JDK 25 正式引入完整的模式匹配特性,涵盖 instanceof、switch 及 Record Pattern。支持类型匹配、嵌套解构与 guard 条件,显著简化代码。结合 sealed 类,编译器可进行穷尽性检查,提升安全性和可维护性。无需预览标志,适用于生产环境,是 JDK 17 升级的核心语言改进。

2026-11-01 10:24:58 281

原创 开启虚拟线程后 HikariCP 连接池为什么反而被打满?从机制到配置一次讲清

虚拟线程让线程变得便宜,但数据库连接、Redis 连接、下游 HTTP 接口这些外部资源仍然昂贵。开启虚拟线程后,连接池不再是"线程数的映射",而是"数据库承载能力的映射"。配置思路要从"我的线程池有多大"切换到"我的数据库能接多少连接"。

2026-10-31 19:31:02 148

原创 ThreadLocal 在虚拟线程下为什么容易炸?ScopedValue 从机制上怎么解决

虚拟线程下,ThreadLocal因载体线程长期存活且虚拟线程海量创建,导致ThreadLocalMap中未清理的Entry持续积累,引发内存泄漏。而ScopedValue通过作用域绑定与自动回收机制,将上下文存储于栈帧关联结构,不依赖载体线程,实现无手动清理、零残留的上下文传递,从根本上解决该问题。

2026-10-31 19:28:23 202

原创 CVE-2026-91403 排查指南:Java JSSE 信任链漏洞的根因、影响范围和修复步骤

CVE-2026-91403 是 Java JSSE 组件中的高危信任链漏洞,因 eMudhra 8 组中间 CA 私钥被暴力破解(密钥值过小),导致攻击者可伪造合法证书劫持 TLS 连接。影响 Oracle JDK 8u511 及以上、OpenJDK 11.0.33 及以下等版本。修复路径为升级至修复版本或手动覆盖 blocked.certs 黑名单文件。Spring Boot 项目通常无需额外处理,但需检查自定义 TrustStore 及 SSLContext 配置。误区包括误信季度补丁已修复、认为内网

2026-10-31 19:27:34 590

原创 上下文工程实战:给 Agent 做上下文预算、压缩与分层,把长会话的成本和跑偏一起治住

本文通过纯JDK实现的上下文管理器,实战验证了四类长会话优化机制:压缩、分层、按需注入、工具瘦身。针对“越聊越贵、越聊越跑偏”问题,提出以“最小高信号集合”为核心策略,结合token估算、分层结构与动态裁剪,在不依赖外部库的前提下有效控制成本与精度衰减。实测表明,合理分层与压缩可降低90%以上冗余输入,显著提升长会话稳定性与经济性。

2026-10-19 15:18:09 469

原创 Java 堆 OOM 怎么复现又怎么定位?从 HeapDumpOnOutOfMemoryError 到 jmap -histo:live

摘要(≤150字): Java堆OOM需分“复现”与“定位”两步。复现时限小堆(如-Xmx96m)并用强引用持续创建对象,触发OOM。定位先用jmap -histo:live <pid>查看存活对象字节分布,直方图首行常为占内存最多的类型(如[B即byte[])。再通过-XX:+HeapDumpOnOutOfMemoryError生成heap dump,结合MAT分析引用链,定位泄漏根源。排查顺序:确认OOM类型 → 判断堆内外 → 区分泄漏与峰值。关键点:直方图仅显类型,需dump追引用;生产建议开启自动

2026-10-19 14:33:58 357

原创 ThreadLocal 在线程池里为什么会串数据?一次复现看懂复用和内存泄漏

环境:Windows 11、OpenJDK 11.0.32.1(Temurin),纯 JDK,用反射查看线程内部的 ThreadLocalMap说明:演示用一个单线程池保证多个任务落在同一线程上。反射查看在 JDK 11 会有"illegal reflective access"警告,属预期现象;结论只针对本机实测。

2026-10-18 10:02:24 267

原创 synchronized 的"锁升级"到底升了什么?直接读对象头看偏向锁、轻量级锁和重量级锁

本文通过 sun.misc.Unsafe 直接读取对象头 mark word,实证分析 synchronized 锁的“升级”机制。结果显示:锁状态由对象头低几位位字段决定,偏向锁并非必然升级路径——一旦撤销即永久失去可偏向性,轻量级锁仅在阻塞时才膨胀为重量级锁。调用 hashCode() 会禁用偏向锁。关键结论:JDK 15+ 默认关闭偏向锁,面试中“锁升级”应理解为竞争驱动的状态切换,而非固定阶梯。代码实践应避免用业务对象作锁,保持临界区短小以维持轻量级锁优势。

2026-10-18 10:01:05 427

原创 多 Agent 什么时候值得用:单 Agent、固定 Workflow、多 Agent 的一次成本实测

本实验通过模拟三种Agent架构在三类任务中的LLM调用次数与字符消耗,量化对比成本结构。结果表明:固定Workflow在任务形状已知时最经济;单Agent因上下文膨胀导致长链任务成本飙升;多Agent仅在拆解动态、子任务独立时回本。核心结论:选型应基于“拆解是否可预知”与“任务间是否依赖”,而非盲目追求多Agent。

2026-10-15 16:45:00 159

原创 Redis 缓存穿透、击穿、雪崩到底差在哪?一次本地复现把三种防护打出来

本文通过纯JDK模拟Redis缓存场景,实测复现缓存穿透、击穿、雪崩三类问题及防护效果:穿透因查询不存在数据导致100次请求全打库,空值缓存+布隆过滤器可降至1次;击穿因热点key失效引发50并发全回源,互斥锁+双重检查使DB调用从50降为1;雪崩由批量key同过期引发峰值200并发,TTL随机抖动将峰值压至4。三者成因各异,防护策略不可混用,需根据“数据是否存在”与“影响范围”精准选择。

2026-10-15 16:45:00 313

原创 Java 项目接大模型:Spring AI 和 LangChain4j 先比较什么(选型实测视角)

本文对比 Spring AI 与 LangChain4j 在 Java 项目中接入大模型的选型差异。结论:多数 Spring Boot 项目应选 Spring AI,因其深度集成 Spring 生态,配置管理、可观测性与维护成本更低;非 Spring 项目或需快速跟进新模型者可选 LangChain4j。两者在工具调用、结构化输出上功能对等,但抽象方式与生态绑定程度不同。关键差异在于“换模型成本”“框架耦合度”与“维护复杂性”。建议优先考虑技术栈一致性,避免过度依赖框架细节,保持业务层解耦。

2026-10-15 07:00:00 904 1

原创 MCP 接入本地工具:把线上消息摊开看握手、tools/call、权限和错误分层

本文通过纯JDK模拟MCP over stdio协议,揭示其核心通信流程:握手、工具发现、调用与错误分层。实测显示,权限必须在server侧强制校验,避免模型越权;错误分两层——协议错误走JSON-RPC error,执行失败(含权限拒绝)走result.content+isError=true,确保模型可自我修正。inputSchema是模型唯一工具说明书,直接影响调用准确性。虽为教学实验,但完整还原了真实MCP的六步消息交互,强调协议透明化对调试与安全的重要性。

2026-10-14 20:12:52 318

原创 Function Calling 参数为什么校验失败:从 Schema、类型到错误信息的完整排查

本文通过实测7类典型参数错误,系统梳理Function Calling中校验失败的根源。指出校验必须在服务端完成,分层处理解析、Schema与业务校验三类问题。强调错误信息需包含字段、期望类型、实际值及合法范围,以引导模型自我修正。提出Schema设计六项预防原则,避免枚举漂移、类型混淆等问题。核心结论:结构化错误反馈是提升模型输出准确率的关键路径。

2026-10-13 19:05:21 276

原创 不用框架手写一个最小 Agent 循环:最大步数、停止条件和失控熔断怎么设计

本文手写最小Agent循环,纯JDK实现无依赖,通过MockLLM保证可复现性。核心设计包括:最大步数兜底、重复调用检测(基于工具名+参数签名)、连续错误熔断、明确停止条件(FINAL输出)。实测四场景验证:正常任务四步完成,三种失控情况(无限循环、格式漂移、工具错误)均被有效拦截。强调生产级Agent的关键不在模型,而在循环外的保护机制,框架只是封装,骨架必须亲手掌握。

2026-10-13 19:03:47 520

原创 用 Java 手写一个最小 RAG:从文档切分、向量检索到 Prompt 拼接的完整链路

本文手写最小RAG链路:基于Java与Spring AI 2.0,实现文档切分、嵌入向量化、内存存储、相似度检索与Prompt拼接全流程。重点解析各环节设计要点,如按语义切块、嵌入模型选型、向量检索优化,并提供可运行示例。强调RAG本质是“知识外挂”,非提升模型智商,适用于私有数据增强生成场景,生产需接入向量数据库与重排策略。

2026-10-11 16:18:42 544

原创 Agent 评测不能只看最终答案:轨迹、工具调用和成本的多维度评估框架

Agent评测不能仅看最终答案,需构建结果、过程、成本三层次框架。结果层关注任务成功率与正确率;过程层通过轨迹分析工具选择、参数、步骤合理性及自我修正能力,定位问题根源;成本层评估耗时、token消耗与费用。结合LLM-as-Judge与自动化验证,避免“蒙对”假象。落地建议:拆解任务为子目标、部署状态验证、监控幻觉与冗余调用。警惕仅凭答案判断优劣的陷阱,方能实现可优化、可扩展的Agent系统。

2026-10-11 16:17:57 201

原创 MySQL 快照读和当前读有什么区别?一次 SELECT 与 SELECT … FOR UPDATE 的并发实测

在 MySQL REPEATABLE READ 隔离级别下,普通 SELECT 为快照读,不加锁且不读未提交数据,始终返回事务开始时的可见版本;而 SELECT ... FOR UPDATE 为当前读,需获取行锁,若目标行被其他事务锁定则等待,提交后读取最新已提交值。实验显示,当事务 B 更新但未提交时,A 的普通读仍返回旧值(100),而锁定读会阻塞并最终读到新值(600)。当前读并非“绕过 MVCC”,而是放弃快照、参与锁竞争并基于当前状态读取。需根据业务需求选择读取方式,锁定读适用于需要保证数据一致性

2026-10-09 11:05:44 63

原创 MySQL 可重复读到底重复在哪?RR 和 RC 的 ReadView 时机实测

MySQL可重复读(RR)的“重复”在于同一事务内首次一致性读时建立的ReadView被复用,后续普通SELECT均基于此快照,即使其他事务已提交更新也不可见。而读已提交(RC)每次普通SELECT都会重新创建ReadView,因此可能看到已提交的新值。START TRANSACTION不等于立即生成快照,真正触发在首次一致性读时。当前读(如UPDATE、SELECT FOR UPDATE)不使用快照,而是读取最新数据并加锁。

2026-10-09 11:00:04 692

原创 最左前缀原则到底约束了什么?联合索引、范围和 ORDER BY 的一次实测

最左前缀原则要求联合索引的使用必须从左侧起连续匹配。实验表明,缺少前导列时无法高效定位,仅能全索引扫描;范围查询会使后续列退化,无法继续缩小范围;ORDER BY 能利用索引顺序的前提是前缀列已等值固定;IN 条件生成多段范围,不保证全局有序,仍需 Using filesort。覆盖索引与 key_len 可辅助判断是否回表。设计索引时应结合查询模式验证实际执行路径。

2026-10-08 21:48:48 210 1

原创 MySQL 索引为什么会失效?用同一张表前后 EXPLAIN 定位原因

本文通过同一张10万行表的五类场景实验,揭示MySQL索引失效的五大原因:函数包裹索引列、前导百分号使LIKE无法定位、联合索引缺前导列、OR操作中一侧无索引、以及优化器因成本估算选择全表扫描。核心结论:索引是否生效需结合EXPLAIN分析访问类型、key与rows等字段,不能仅看“是否有索引”。关键修复策略是确保谓词可形成有效范围访问,避免破坏索引结构,并重视优化器的成本判断。

2026-10-08 21:44:05 358 2

原创 Spring Boot 4.1 的 API 版本控制:Header、Query、路径和 Media Type 到底怎么选

Spring Boot 4.1.1 内置支持基于请求头、查询参数、路径段和 Media Type 的 API 版本控制。通过 ApiVersionStrategy 统一解析并匹配版本,精确版本优先于范围版本(如 1.2+)。实验表明,1.1 和 1.5 精确匹配,1.3 命中 1.2+;缺失、非法或不支持版本均返回 400 错误。四种方式无优劣之分,需结合版本规范、兼容策略及网关、日志、文档协同设计,生产环境建议统一主方案。

2026-10-07 17:14:13 328

原创 Spring AI 工具调用不是反射一下就结束:用 2.0.1 跑通失败恢复与调用上限

Spring AI 2.0.1 工具调用非简单反射,而是完整执行链:从解析 Tool Call 到参数校验、工具执行、异常处理及 ToolResponseMessage 构造。实验验证:成功调用生成 [USER, ASSISTANT, TOOL] 历史;无工具或未知工具抛 IllegalStateException;非法参数触发模型修正,业务异常(如 IllegalArgumentException)可反馈给模型,但需控制重试。默认单工具最多调用 40 次,总上限 150 次,超限抛 ToolCallLim

2026-10-07 17:08:58 379

原创 Agent Skills 为什么不能只是“长提示词”:SKILL.md、按需加载和权限边界

Agent Skills 不能仅靠“长提示词”实现,其核心价值在于可发现、可校验、可渐进加载的结构化契约。通过 SKILL.md 的元数据(如 name、description)实现目录阶段轻量扫描,按需加载正文与资源,避免上下文膨胀。实验表明,合法命名与字段校验能提前暴露问题,脚本与权限分离确保安全执行。最小 Skill 应包含清晰触发条件、分层资源引用与明确工作流,真正实现“能加载、能复用、能授权”的工程化能力。

2026-10-06 17:22:39 661 1

原创 A2A 1.0 到底和 MCP 差在哪:从 Agent Card、Task 到 Java 最小互操作

A2A 1.0 与 MCP 核心差异在于:MCP 聚焦 Agent 调用工具,A2A 解决 Agent 间任务委托与状态追踪。A2A 通过 Agent Card 实现能力发现,以 Task 状态机管理长流程,支持上下文续接。实验验证了从卡片发现、消息发送到任务状态轮询的最小互操作链路,凸显其在跨代理协作中的可观察性与持续性价值。

2026-10-06 17:15:13 306 1

原创 HashMap 的容量为什么常用 2 的幂?

HashMap 容量为 2 的幂,使下标计算仅需位运算 (n-1) & hash,高效且避免负数下标。扩容时,通过 hash & oldCap 判断节点去向,只需判断高位即可完成搬迁,无需重新取模。高位扰动 h ^ (h >>> 16) 提升哈希分布均匀性。此设计优化性能,但非绝对,碰撞仍可能发生,也非所有哈希表必须遵循。

2026-10-05 14:43:45 387

原创 HashMap 的核心结构:从一次 put 看到扩容、桶迁移与树化边界

本文通过反射探针分析JDK 17中HashMap的put操作,揭示其核心机制:首次插入时懒加载数组(默认容量16),负载因子0.75触发扩容(16→32),而树化需满足桶内节点≥8且表容量≥64,否则优先扩容。容量保持2的幂以优化索引计算,扩容时利用位运算将旧桶分为两组,提升效率。实验仅反映JDK 17行为,不适用于其他版本或并发场景,实际使用应合理设置初始容量并避免哈希碰撞。

2026-10-05 14:35:14 200

原创 AI Agent 入门:新手和转行者先学什么,别一上来就啃框架

Agent 的非确定性很高,拿两次成功对话当结论没有说服力。项目一开始就准备 10 至 20 条测试输入,分别覆盖正常问题、边界问题、工具失败、检索不到、危险操作和超时。最低限度记录这些指标:任务完成率:多少条输入真正完成了目标。工具调用准确率:是否调用了正确工具,参数是否正确。引用命中率:RAG 场景中有没有给出来源,来源能不能支持答案。平均步骤、延迟和 token 成本:Agent 多走几步,费用和等待都会累加。失败类型:模型不会、工具报错、检索错误、权限拦截或代码异常。

2026-10-04 12:24:07 894

原创 线程池里的“幽灵数据”:ThreadLocal 用完不 remove,为什么下个请求还能看到?

在线程池复用线程的场景下,若未在请求结束后调用ThreadLocal.remove(),会导致下一个请求读取到前一个请求的残留数据,引发“数据串用”问题。原因在于ThreadLocal的值存储在线程自身的ThreadLocalMap中,而非ThreadLocal对象本身。即使ThreadLocal被回收,其对应的value仍可能因强引用而无法释放,造成内存泄漏风险。修复关键:在请求处理的最外层(如过滤器)使用try-finally确保clear()调用,避免上下文污染。同时需注意异步任务中的上下文传递与清理

2026-10-04 11:53:03 313

原创 黑马头条能写进简历吗?能,但别把它写成大厂项目

黑马头条可写进简历,但必须明确为“课程项目复现”或“个人实践”,避免虚构团队规模与线上数据。重点突出真实参与的模块(如异步审核、搜索同步、分布式事务),并附上日志、测试、压测等可验证成果。切忌照搬仓库中的“大厂项目”描述,面试官追问细节易露破绽。建议聚焦具体技术难点与解决方案,以真实证据体现能力,提升可信度与竞争力。

2026-10-03 19:00:38 405 1

原创 什么是零拷贝?别被“零”字骗了:一次讲透完整链路

零拷贝并非完全无复制,而是减少用户态与内核态间的数据拷贝及上下文切换。传统read+write涉及4次复制和4次切换,而sendfile、mmap+write、splice等通过页缓存共享或直接传输优化路径。Java的transferTo()仅是提示,是否真正零拷贝依赖操作系统实现,且仅在大块、静态数据传输中优势明显。实验表明其性能提升源于减少用户态循环,而非必然走高效内核路径。零拷贝不等于“零”复制,也不保证跨平台一致。

2026-10-03 18:54:53 321 2

原创 BIO、NIO、AIO 到底差在哪?从阻塞方式到代码模型一次理清

本文剖析BIO、NIO、AIO的本质区别,澄清“一连接一线程”“异步最快”等常见误解。核心在于区分“阻塞/非阻塞”(线程是否等待)与“同步/异步”(结果如何获取)。BIO以线程阻塞于accept/read为特征;NIO通过Selector轮询多个通道的就绪事件,实现单线程处理多连接;AIO则提交请求后立即返回,由回调或Future通知完成。三者并非性能递进,而是针对不同场景的设计选择。代码示例验证了三种模型在JDK 17下的最小实现与回显功能。

2026-10-02 16:38:21 359 1

【后端开发-简历模版】基于Spring Boot与MySQL的电商及考试系统性能优化:分布式架构下高并发场景SQL调优与缓存一致性实践

阅读建议:此资料适合作为Java后端开发者招聘面试的模版简历,仅供参考,自行修改

2026-10-04

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除