- 博客(49)
- 收藏
- 关注
原创 AI 读了十万份文档,为什么还可能答错?聊聊 RAG、知识图谱和 LightRAG
因此一套组合可以是,Docling 解析文档,LightRAG 负责 Chunk 与图谱索引,BGE-M3 负责向量化,Qwen 或 DeepSeek 一类 LLM 负责关系抽取及问答,PostgreSQL 和 pgvector 负责存储。让大模型判断每个段落的主题边界,理论上很灵活,代价是额外的推理费用、处理时延,以及每次切分结果不一定完全一致。创建图谱时,LightRAG 通常先处理 Chunk,再调用 LLM 从其中抽取实体和关系,尝试归并重复实体,保留与来源文本的关联,然后把抽取结果写入图谱存储。
2026-10-09 15:21:37
347
原创 AI Coding 的第一步,是先想清楚你在干什么
新功能开发最容易犯的错误,是需求刚有一个雏形,就直接让 AI 开始写代码。现实中,很多开发者并没有专业产品经理长期配合,需求最初往往只有一句模糊的想法,例如“我想做一个 AI 自动生成研报的功能”或者“我想给现有系统加一个智能搜索”。这种情况下,正式进入开发之前,应该先把产品意图聊清楚。我更倾向于把这一阶段理解成“AI 产品经理”。它不只是帮你生成一份 PRD,而是通过连续追问,把用户是谁、要解决什么问题、核心场景是什么、边界在哪里这些内容逐渐收敛。PRD 可以是写出来的,也可以是聊出来的。
2026-09-24 11:26:50
368
原创 Redisson 分布式锁的底层原理,面试官听完都点头了
对比维度默认 RedissonLockRedLockRedis 节点单 Master(+Slave)多个独立 Master一致性保证最终一致性多数一致性Master 宕机可能丢失锁大多数节点健康即可性能高(1 次写)低(N/2+1 次写 + 网络开销)适用场景大多数业务金融、资损敏感场景很多人把 Redisson 默认实现和 RedLock 混为一谈,面试时一说到"主从一致"就说"用 RedLock"。实际上RedissonLock 默认不保证主从一致。
2026-07-22 16:53:33
249
1
原创 一个秒杀就把 MySQL 打挂了?我用 Redis + 异步削峰扛住了 100 倍流量
不要把 MySQL 当秒杀引擎。MySQL 的行锁和磁盘 IO 决定了它不适合做"热点写",让它做最终落库就够了。Redis + LUA 原子脚本做资格校验,把 3 万 QPS 降维到几百 TPS 的 DB 写入,延迟从 8 秒降到 12 毫秒。**异步削峰(阻塞队列 + 单线程消费者)**让数据库写入速率变得可控,完全避免死锁和雪崩。最终一致性 > 强一致性。秒杀不是银行转账,短暂的缓存和数据库不一致可以接受,但数据绝对不能丢。
2026-07-22 11:16:07
312
原创 别再手动封装List当队列了!Redis Stream消息队列,原理+实战一篇讲透
对比维度默认 RedissonLockRedLockRedis 节点单 Master(+Slave)多个独立 Master一致性保证最终一致性多数一致性Master 宕机可能丢失锁大多数节点健康即可性能高(1 次写)低(N/2+1 次写 + 网络开销)适用场景大多数业务金融、资损敏感场景很多人把 Redisson 默认实现和 RedLock 混为一谈,面试时一说到"主从一致"就说"用 RedLock"。实际上RedissonLock 默认不保证主从一致。
2026-07-22 11:13:55
385
2
原创 生产环境分布式锁踩坑实录:从 synchronized 失效到 Redlock,我画了 3 张图终于讲透了
生产环境分布式锁实现方案对比 本文系统梳理了分布式锁的演进过程,从单机锁失效问题到Redis分布式锁的4个版本演进,最终给出三种主流实现方案的对比: 核心演进点: synchronized失效原因(JVM进程隔离) Redis分布式锁演进(NX+TTL→唯一ID→Lua原子性→看门狗续期) 主从架构下的Redlock方案 Redis/ZK/MySQL三种方案对比 方案对比: 对比维度 Redis(Redisson) ZooKeeper(Curator) MySQL 性能 最高(内存操作) 中等(ZK写性能一
2026-07-21 11:07:44
155
原创 “乐观锁还是悲观锁“,三张图终于把多线程并发说透了
选锁第一原则:看写冲突概率。高 → 悲观锁;低 → 乐观锁synchronized 不是洪水猛兽:JDK 1.6 后有锁升级,低竞争下开销很小CAS 不是业务校验:它是 CPU 原子指令,保证读-比较-写不可分割一人一单最佳实践:数据库唯一约束比应用层锁更简单可靠生产环境常用组合:Redis 预扣库存(乐观 Lua)+ 数据库兜底(版本号)+ 唯一约束防重复。
2026-07-20 16:20:24
192
原创 缓存穿透、击穿、雪崩?别再死记硬背了,一文讲透Redis缓存三大难题
fill:#333;important;important;fill:none;color:#333;color:#333;important;fill:none;fill:#333;height:1em;低高业务场景一致性要求?Redis 内存淘汰更新 DB删除缓存下次读时回写配置 maxmemory-policy缓存更新:低一致性用 Redis 内存淘汰,高一致性用 Cache Aside(写 DB 删缓存)缓存穿透:优先缓存空值(0 成本改动),id 范围固定时上布隆过滤器。
2026-07-19 11:12:18
161
原创 别再背八股文了!Redis 缓存穿透、缓存雪崩?先搞懂这 30 行查询代码再说
文章摘要 本文通过剖析一段30行的Redis缓存查询代码,揭示了缓存穿透防护的核心原理。作者从实践出发,逐行拆解代码逻辑,包括Redis key命名规范、缓存命中判断、JSON序列化与反序列化等关键点。文章特别强调理解这段基础代码(Cache-Aside Pattern)比死记硬背"缓存穿透/雪崩"等概念更重要,并用时序图清晰展示了"先查缓存→未命中查DB→回写Redis"的完整流程。通过实际代码演示,帮助开发者真正掌握缓存机制的本质实现。
2026-07-18 16:30:42
205
原创 面试官问“登陆拦截器为啥写两个“?我给他画了张图,他当场说过了
前端存 token 到 localStorage,通过 Authorization 请求头发送——不走 cookie,自己控制Redis + UUID 方案的核心优势是服务端可控——可以踢人、可以活跃续期、可以实时变更用户信息ThreadLocal 是线程级别的变量隔离——拦截器把用户信息写进去,整个请求周期都能读"活跃用户永不过期"靠的是 RefreshTokenInterceptor——它拦截所有路径,永远放行。
2026-07-16 19:39:25
321
原创 Spring Boot 拦截器,我把学习踩坑过程画了张图
拦截器的位置:夹在 HandlerMapping 和 Controller 之间,比 Filter 更靠近业务层,适合做基于"用户"的校验。从 Session 只取必要字段,不要整坨 User 对象到处传——既防止泄漏,也避免 Session 序列化膨胀。ThreadLocal 必须 paired with remove(),在 afterCompletion() 里清理,这不是锦上添花,是必须做。配置拦截路径时别漏了静态资源放行——否则网页样式全挂,排查起来很匪夷所思。进阶思考。
2026-07-16 14:38:17
227
原创 Entity、DTO、Session 不就是三个「数据容器」吗?错!一个储物柜比喻让你彻底搞懂
Entity 是数据库的镜子——1:1 映射表结构,包含所有字段和 ORM 注解。它的生命周期属于 DAO 层。DTO 是接口的契约——只包含你想暴露的字段,与服务/控制器层同生命周期。它是你跟客户端之间的约定。Session 是用户的储物柜——它本身不是「数据」而是一个KV 存储空间。可以把 DTO 放进去,用来跨请求保存用户状态。最佳实践:DB 层用 Entity -> Service 层转成 DTO -> 需要跨请求的 DTO 塞进 Session。不要存 Entity,不要混用职责。
2026-07-14 17:54:14
370
原创 Service 和 Impl 到底谁写代码?写给对着分层结构发懵的小白
你盯着IDE里那一排包名——controller、service、mapper、entity——光标在UserController里闪了半天。你明明知道要"根据手机号查一个用户"。就这么简单一个需求,但你发现不知道该往哪写。“写在Controller里?应该不行吧…教程说Controller很薄。那Service里写?那为什么Service还有一个接口?我直接写一个类不行吗?impl又是什么东西?这些问题,教程里不会专门停下来跟你讲。你顺着视频敲一遍能跑,但换你自己写一个新接口,就懵了。
2026-07-14 17:36:00
561
原创 JavaWeb从0到1-DAY11.1-MyBatis入门(ii)
注解 XML 两把刀”。注解适合简单增删改查,XML 适合复杂 SQL——实际项目混合使用。#{}是默认选择、安全可靠,${}只在特殊场景用且严防注入。XML 映射靠三规则精准对应。DML 返回值判断操作是否生效。@Param帮多参数起名,建议始终写。配置文件开日志、配 XML 路径、开驼峰映射,省去大量麻烦。
2026-06-01 22:07:40
238
原创 写了 266 行 SKILL.md,Codex 死活不认——揪出 UTF-8 BOM 这个隐形杀手
团队规范要求所有 commit message 遵循格式。每次git commit都要手写,烦得不行。于是你写了 200 多行 SKILL.md,做了一个skill——输一段改动描述,自动生成规范的 commit message。写好、测试、放到,重启 Codex。敲下$git-commit "修了登录页token过期不刷新的bug"。Codex 回你一句「未找到该 skill」。你以为是触发词没写对,又把 description 里的关键词改了三版——gitcommit提交全塞进去。依旧不认。
2026-05-29 16:50:23
480
原创 Codex 用 DeepSeek 模型无法识图?一招接入千问 VL,让 AI 秒懂你的截图
某天你正在用 Codex,后端报了一长串异常,你懒得复制粘贴,直接截图甩给 AI。结果它回复:“我暂时看不到你发的图片内容——图片标签里没有可读取的路径。你能描述一下图片里是什么内容吗?你忍住摔键盘的冲动,老老实实打字描述。然后你又发了第二张、第三张截图,AI 直接开始"失忆"——上下文爆了,token 超限,前面的对话全白费。这不是你的问题,是模型的问题。DeepSeek-V4-Pro、DeepSeek-V4-Flash 这些模型天生没有 Vision 能力——它们只能读文字,看不懂图。
2026-05-29 15:01:43
10756
4
原创 JavaWeb从0到1-DAY11-MyBatis入门
MyBatis 是对 JDBC 的封装,解决硬编码、繁琐、资源浪费三大痛点。核心用法只需三步:在 application.properties 配好数据库连接 → 写一个带 @Mapper 的接口并标注 SQL → 用 @SpringBootTest 编写测试验证。底层靠动态代理让接口"自动拥有"实现类,靠连接池让数据库连接高效复用。掌握这章的五步入门流程,后面学增删改查就都是同一个套路了。
2026-05-29 14:19:54
403
原创 JavaWeb从0到1-DAY10-JDBC
JDBC 是 Java 操作数据库的底层基石。获取连接 → 发 SQL → 处理结果。记住六步编程框架,永远用 PreparedStatement,上线必配连接池,多表操作开事务。但实际开发中你不会手写这些——MyBatis、JPA 等框架已经帮你封装好了,它们底层调用的正是 JDBC。学好 JDBC 的意义不在于手写代码,而在于:当框架出问题时你知道底层发生了什么,看得懂报错,调得了性能。
2026-05-22 17:37:31
610
原创 JavaWeb从0到1-DAY9-三层架构、IOC 与 DI
Controller接收请求并响应数据,Service处理业务逻辑,Dao负责数据访问。三层架构体现了单一职责原则,也让代码更容易扩展和复用。IOC 把对象创建和管理交给容器,DI 让容器把依赖对象注入进来。@Autowired默认按类型注入,如果同类型 Bean 有多个,可以用@Primary@Qualifier或@Resource解决。
2026-05-19 17:20:44
404
原创 JavaWeb从0到1-DAY8-前后端交互(基础)
表示把/list请求交给当前方法处理。表示按逗号拆分字符串。表示把字符串转成整数。表示按指定格式把字符串转成时间对象。表示把集合中的每个元素转换后,再收集成新的集合。这一章的核心是理解前后端交互:前端通过 HTTP 请求地址,后端通过找到方法并执行。或决定返回值会作为响应数据返回,而不是当成页面名。后端可以读取资源文件或数据库,把数据封装成 Java 对象集合,再由 Spring 转成 JSON。前端最终拿到 JSON 数据并渲染页面。
2026-05-18 22:19:38
551
原创 JavaWeb从0到1-DAY7-HTTP 请求与响应处理
本章搞定了 Web 开发的“输入”与“输出”。Tomcat 负责脏活累活(解析和拼装协议报文),我们程序员只需要通过拿数据,通过或给结果。重点关注常用状态码,这是前后端沟通的“黑话”。
2026-05-15 16:01:49
682
原创 JavaWeb从0到1-DAY6-SpringBoot Web 入门
SpringBoot 是基于 Spring 的快速开发框架,核心目标是简化 Java Web 开发。SpringBoot 内嵌 Tomcat,因此运行 main 方法就能启动网站。Controller 用于处理请求,用于建立 URL 和 Java 方法的映射关系。SpringBoot 启动时会自动扫描组件并完成自动配置。本章最核心的本质就是:请求路径→ 找到方法→ 执行代码→ 返回结果。
2026-05-08 17:09:19
378
原创 JavaWeb从0到1-DAY5.1-Maven-JUnit
JUnit 是 Java 中常用的单元测试框架,用来测试方法是否按预期工作。测试方法不需要main,只要加上@Test,JUnit 测试引擎就能自动识别并执行。断言是单元测试的核心,判断结果是否相等,判断是否抛出指定异常,assertAll可以批量执行多个断言。测试代码应该放在,JUnit 依赖应该设置scope=test。企业开发中写测试不能只测正常情况,还要覆盖异常值和边界值。
2026-05-08 15:18:30
630
原创 JavaWeb从0到1-DAY5-Maven
Maven 是 Java 项目的构建和依赖管理工具,核心配置文件是pom.xml。Maven 坐标由groupIdartifactIdversion组成,用来唯一定位项目或依赖。依赖统一写在中,每一个具体依赖用表示。放源码,target放 Maven 生成的编译和打包结果。常用生命周期命令中,clean清理,compile编译,test测试,package打包,install安装到本地仓库。
2026-05-08 13:47:11
593
原创 JavaWeb从0到1-DAY4-AJAX
AJAX 的核心是让浏览器在不刷新整个页面的情况下和服务器交换数据。Axios 是对 AJAX 的封装,让发送 GET、POST 请求更简单。可以让异步请求代码更清晰,但请求本质仍然是异步。Vue 的mounted()会在页面挂载完成后自动执行,常用于页面加载时请求数据并渲染页面。mounted()触发请求,await等待结果,取出,赋值给 Vue 数据,页面自动更新。
2026-04-29 19:38:00
1003
原创 JavaWeb从0到1-DAY3.1- Vue(ii)
结论模板里绑定谁,data()中就要先有谁。原因Vue 需要明确的数据来源,否则它不知道这个变量从哪里来。通俗比喻或小例子表单像前台登记表,data()像后台数据库。前台要登记某项内容,后台得先有这个字段。v-else-if必须跟在v-if后面v-else必须跟在v-if或v-else-if后面不能单独写v-else是的简写。click是事件名。handleclearName是方法名。这一章的关键,是学会 Vue 里“数据怎么显示、条件怎么判断、列表怎么渲染、用户操作怎么处理”。
2026-04-27 22:20:44
417
原创 JavaWeb从0到1-DAY3- Vue(i)
/</div#app是 Vue 要接管的区域。是插值表达式,用来显示数据。Vue 使用前要先引入 Vue 库。创建应用的基本格式:data() {return {属性名: 属性值})挂载格式:app.mount('#选择器')插值表达式格式:{{ 数据名 }}Vue 是一套用于构建用户界面的渐进式 JavaScript 框架,本章重点是认识它并学会最基础的使用流程。用来创建应用,data()用来提供页面数据,mount()用来把应用挂到页面指定区域。#app。
2026-04-22 20:03:43
374
原创 JavaWeb从0到1-DAY2.1- JavaScript(ii)
事件源.addEventListener('事件类型', 处理函数);事件类型要写成字符串,比如'click'在里写的是'click',不是'onclick'这一章的核心,是理解“页面为什么能动起来”。事件是用户操作,事件监听是浏览器在事件发生时执行对应函数。JS 想操作页面,必须先通过document和找到 DOM 元素。是更推荐的事件绑定方式,常配合循环给多个元素批量绑定事件。模块化部分先记住结论:代码可以拆文件,export导出,import导入,模块脚本通常写。
2026-04-22 19:17:36
365
原创 JavaWeb从0到1-DAY2- JavaScript(i)
let****/****const取代var,常量首选const。函数推荐箭头函数,但对象方法慎用。JSON是带双引号的字符串,它是数据传输的“桥梁”。DOM找元素(querySelector) -> 改内容(innerText) -> 调样式(style)。
2026-04-21 21:46:42
348
原创 JavaWeb从0到1-DAY1.4-HTML-CSS快速入门(v)
h1盒子模型是 CSS 中非常重要的概念。页面中的每个元素都可以看成一个盒子。元素尺寸内边距边框外边距页面中的布局展示widtha标签必须重点记住hrefimg标签必须重点记住srcoption不能脱离select单独使用trthtd容易层级混乱div和span的使用场景容易混淆form的action和method容易记混input的功能主要由type决定HTML:掌握常见标签及其作用,知道页面内容如何组织CSS:掌握盒子模型和 Flex 布局,知道页面样式如何控制。
2026-04-15 20:56:35
1143
原创 JavaWeb从0到1-DAY1.3-HTML-CSS快速入门(iv)
从盒子模型开始,学习重点就从“认识标签”逐渐进入“理解布局和交互”。盒子模型帮助我们理解元素的结构和间距,Flex 布局帮助我们控制排列方式。表单解决数据采集问题,表格解决数据展示问题。只要把这些知识点的职责分清楚,后面做页面时就不会只会堆标签,而是能真正开始搭结构、控布局、收数据、展示数据。
2026-04-15 20:31:16
482
原创 JavaWeb从0到1-DAY1.2-HTML-CSS快速入门(iii)
这一章的核心是:网页正文不仅有标题和链接,还会有图片、视频和段落。img和video都依赖src找资源,所以路径写法非常关键。相对路径是项目里最常用的写法,./表示当前目录,../表示上一级目录。p适合写正文段落,div适合把一整块内容包起来统一管理样式。
2026-04-09 23:13:16
423
原创 JavaWeb从0到1-DAY1.1-HTML-CSS快速入门(ii)
这一章的核心是:先学会在 HTML 中写标题和超链接,再学会用 CSS 给页面加样式。超链接最常用的两个属性是href和target,前者管地址,后者管打开方式。CSS 有三种引入方式,其中外部样式最适合正式开发。id > class > 元素。说明:这份笔记是根据你本次提供的课程截图整理的,重点覆盖了标题标签、超链接、CSS 引入方式、颜色表示、color属性和三种基础选择器。如果老师后面还有补充更细的内容,比如更多样式属性、复合选择器、背景属性等,可以继续追加到后续笔记里。
2026-04-08 21:34:12
686
原创 JavaWeb从0到1-DAY1-HTML-CSS快速入门(i)
HTML 入门最重要的是先把网页的基本骨架记住,并分清head和body的作用。head主要放浏览器需要的信息,body放用户真正看到的内容。title决定标签页名称,img可以显示图片,图片是否显示常常取决于路径是否正确。再往后学习时,要一直记住:HTML 管结构,CSS 管样式,JavaScript 管行为。
2026-04-08 19:50:03
660
原创 JavaSE从0到1-DAY9-ArrayList
ArrayList是 Java 中最常用的集合之一,本质上是一个长度可变的容器。它和数组最大的区别是:数组定长,集合变长。使用ArrayList泛型、增删改查、遍历。另外要记住:集合里不能直接放基本数据类型,想放整数等数据时,要使用对应的包装类。这章学会后,后面很多数据存储、遍历、操作集合的代码都会更容易理解。
2026-04-07 17:52:23
395
原创 JavaSE从0到1-DAY8-String
String 是 Java 中最常用的类,核心特性是不可变性。比较字符串内容时必须用equals(),不能用==。String 的方法都返回新对象,必须用赋值语句接收。频繁拼接字符串时用 StringBuilder 提高性能。掌握 String 的常用方法(截取、替换、查找、转换等)和 StringBuilder 的使用,就能高效地处理字符串操作。
2026-04-02 22:18:39
334
原创 JavaSE从0到1-DAY7.1-内部类(ii)
本文总结了Java中三种内部类的关键知识点:静态内部类、局部内部类和匿名内部类。静态内部类不依赖外部类实例,可直接创建;局部内部类定义在方法内,只能访问final局部变量;匿名内部类没有名字,必须实现接口或继承类,适合一次性使用场景。文章通过代码示例和对比表格,清晰展示了各类的特点、使用方式和适用场景,最后总结了内部类的核心访问规则和创建方法。这些知识点对理解和使用Java内部类至关重要。
2026-04-01 21:07:43
190
原创 JavaSE从0到1-DAY7-内部类(i)
本文详细介绍了Java内部类的核心概念与使用场景。主要内容包括:1)内部类的作用是逻辑封装和访问控制,可访问外部类私有成员;2)内部类的四种分类(成员/静态/局部/匿名)及其特点;3)成员内部类与静态内部类的本质区别,前者依赖外部类实例且可访问所有成员,后者独立且只能访问静态成员;4)内部类实例化的两种方式;5)同名变量访问规则。通过汽车与发动机的生动比喻,帮助理解内部类与外部类的关系。文章还提供了清晰的对比表格和代码示例,系统梳理了内部类的关键知识点。
2026-04-01 17:52:55
502
原创 JavaSE从0到1-DAY6-接口
public interface 接口名 {// 常量(自动是 public static final)数据类型 常量名 = 值;// 抽象方法(自动是 public abstract)返回值类型 方法名(参数列表);要点说明定义规范和契约,定义必须实现的方法特点不能实例化,只有抽象方法和常量优势支持多实现,解决多继承问题用途定义能力、规范、契约。
2026-03-31 16:40:11
425
原创 JavaSE从0到1-DAY5-抽象类
抽象方法是没有方法体的方法,用abstract修饰,只有方法签名。// ✅ 正确:在抽象类中// ❌ 错误:在普通类中// 编译错误Adapter 模式是一种设计模式,用来解决这个问题:当一个抽象父类有很多抽象方法时,子类继承它就需要实现所有方法。但有时候子类只需要其中的几个方法,其他方法用不到。概念说明定义用 abstract 修饰的类特点不能实例化,必须有抽象方法意义规范子类行为,提供通用接口Adapter中间抽象类,对方法进行空实现。
2026-03-31 16:00:06
444
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅