- 博客(49)
- 收藏
- 关注
原创 Java面经
version 存在两个地方:Token 里 + Redis 里鉴权只比 version,不比 Token 字符串改密码 = version +1,旧 Token 全部作废Redis Key 不过期或长期,每次访问续期Key 删了 = 自动登出,重新登录即可。
2026-04-04 22:14:00
72
原创 队列的一些场景题以及处理方式
用分布式锁防并发,用数据库状态做幂等,用 CAS 做最终兜底,用手动 ACK 保证消息可靠性,用重试 + 死信避免死循环,从根源彻底防止消息重复消费。分布式锁防并发,状态幂等防重复,CAS 兜底防锁超时,三层防护层层兜底,从根源彻底杜绝消息重复消费。消息到 Broker 后,从内存 → 写入磁盘的过程。
2026-04-01 23:26:25
350
原创 JAVA面试问题
死信交换机、死信队列、延迟队列,全都是普通交换机、普通队列,没有特殊类型队列 → 交换机 = 指向(靠配置名字,跟 routing key 无关)交换机 → 队列 = 绑定(绑定时才带 routing key)routing key 只有生产者发消息时才有用,消费者根本不用管死信队列:业务队列指向死信交换机 → 死信交换机绑定死信队列(存死信用)延迟队列:自定义队列指向交换机 → 交换机绑定业务队列(过期后直接消费)一个交换机可以绑多个队列,绑的顺序无所谓,只看角色用途建一个普通队列。
2026-03-31 00:01:13
826
原创 Java动态代理和反射以及自定义异常类和全局异常处理器
反射能干三件最核心的事通过 Class 动态创建对象通过 Method 动态执行方法(核心就是invoke通过 Field 动态读写、填充字段遇到 private 怎么办?不管是私有字段、私有方法、私有构造器,反射默认无权访问,会报错作用是关闭权限检查,让反射可以强行操作私有成员Spring IOC 创建 Bean 靠什么?Spring 扫描类,读取字节码,拿到全部信息根据 Class,用反射创建对象,放进 IOC 容器(Map)依赖注入(@Autowired 填充字段)是怎么实现的?
2026-03-30 21:53:14
342
原创 事务失效的几种情况以及是为什么(详解)
MySQL 的 MyISAM 引擎就没有事务功能,不管你 Spring 事务怎么写、代理正不正常,都不可能回滚。只有 InnoDB 引擎才支持事务。你在事务方法里把异常 catch 住,又不往外抛,Spring 根本不知道出错了,就不会回滚。新开线程去调用事务方法,新线程拿不到原来的事务,也走不到事务上下文,事务直接失效。,继承你要拦截的那个类(比如 UserService)AOP 切面没被执行,事务、日志等增强逻辑直接失效。生效,没加的话注解等于白写。Spring 事务是。Spring 事务是。
2026-03-29 19:21:11
361
原创 Java小厂面经
循环依赖这种现象是怎么产生的(怎么解决)(是设计问题还是架构问题)有没有用过ai IDE,感觉有哪些地方它做的不好吗。遇到了哪些困难,感觉哪些地方的实现是困难的。异常怎么处理,有没有了解过全局异常处理器。cocounthashmap底层和扩容。key hash可以用来存储哪些数据。sql怎么进行优化的实习项目中。redis有哪几种数据类型。
2026-03-23 00:08:44
27
原创 对Langchain4j的补充以及与springAi的对比
开箱即用的AiServices,本身就支持大量自定义,一行配置就能改,不用重写逻辑// 自定义系统提示词,给Agent定专属的行为规范(比如你的代码生成规范).systemMessageProvider(ctx -> "你是一个专业的低代码平台开发助手,必须严格遵守以下规范:1. 生成的代码必须是Vue3+TS;2. 生成代码前必须先确认需求边界;3. 代码生成后必须先做语法校验,再执行后续操作...")// 自定义最大循环次数,防止死循环// 自定义超时时间。
2026-03-17 15:04:10
319
原创 解决并发的两种方法(没用到redis)(对上一期的补充)以及开启多个定时任务
那原本第 2 分钟、第 3 分钟该触发的任务,都会在队列里排队,等第一次的任务跑完,才会依次执行,完全不会并发跑,也不会跳过,最终导致任务执行时间完全错乱。意思就是假如说有A、B、C三个用户,A用户在用B用户得等A用户定时任务到期也就是定时任务执行完可是我们知道定时任务是有可能很长的,意思就是这段时间只能有A用户一个人使用这个定时任务,其它用户不管有多少个人成千上百也好都要等着它执行完。后续所有用户的定时任务,哪怕是 1 点半、2 点触发的,都会永远卡在队列里,永远不会执行,整个定时任务体系直接瘫痪。
2026-03-15 00:24:36
415
原创 对上一期零代码的补充
相当于:你开了 10 个独立的 Chrome 浏览器窗口(池子里有 10 个实例),10 个用户同时请求截图时,每人用一个窗口,互不干扰;相当于:每个线程绑定一个专属的 Chrome 浏览器窗口,线程 1 的窗口永远只能线程 1 用,线程 2 碰不到,自然不会出现 “A 的请求改了 B 的页面地址” 的问题。:将 COS 返回的图片访问 URL(Object URL)存入数据库的应用表中,实现 “应用信息 - 封面图地址” 的关联查询。这段代码看起来长其实都是一些配置,属于样板代码直接复制粘贴即可。
2026-03-14 23:29:24
384
原创 Crmeb.java项目理解(一)
就是一开始登录的时候执行这个然后存入数组中,每个用户的数组是隔离的,然后跟·那个注解里面的值进行校验,就是数组里面有没有那个注解括号里面的那个值如果有则放行如果没有则不放行此时就是校验 admin:combination:list这个值看数组里面有没有,他们在数据库中就是这样的存的,查出来放入数组中,然后这个注解就是进行判断校验数组里面有没有他这个括号里面的值如果有的话则通过。这个注解就是在实体类上加的,他是lombok的注解,它的作用就是省略了比较hashcode和equals比较的代码。
2026-03-10 23:03:20
345
原创 对langChain4j的补充
/ 流结束时清理(无论成功/失败/取消)});case VUE_PROJECT -> // 使用注入的组件实例case HTML, MULTI_FILE -> // 简单文本处理器不需要依赖注入case VUE_PROJECT -> // 使用注入的组件实例先看这一行。// 收集AI响应内容})// 流式响应完成后,添加AI消息到对话历史})// 如果AI回复失败,也要记录错误消息。
2026-03-09 21:39:44
438
原创 算法题中、前、后序遍历;电话号码的字母组合
下面就看这个例子就可以别看上面那个代码的测试用例:先来分析先把当前根节点用curr指向,第一步先把10入栈,然后指针移动到左子节点,也就是五然后在入栈因为循环的跳出条件是curr=null;然后再往左指就是2接着往左就是1,然后再往左此时curr=null,然后就跳出while循环,此时栈为{10,5,2,1}然后开始弹数据先弹1,此时数组为【1】
2026-03-08 19:09:04
178
原创 LangChain4j 的使用
流式生成:通过实现大模型逐 token 吐代码,直接适配 SSE 推送;配置核心:YAML 配好大模型地址 / 密钥,工厂类注入流式模型,AI 服务就能流式输出;解析核心:用正则提取 ``` 包裹的纯代码块,把 “自然语言 + 代码” 的混合文本变成结构化代码;和你项目的结合:你的智能体run()方法可以调用,返回的 Flux<String>推给前端,等流式结束后(doOnComplete)调用 CodeParser 解析出纯代码,完成 “生成→推送→解析” 全流程。@Autowired。
2026-03-06 16:02:54
439
原创 Mybits Flex自动生成代码
详情地址:https://mybatis-flex.com/zh/others/codegen.html。他们的区别就是在实体类那个表的注解名字不一样,一个是@TableName一个是@Table。相信大家一定用mybits plus用的很多但是这里有一个他的兄弟mbFlex。第一行就是使这个生成器知道数据库在哪里,这样才能读取相应的表然后生成相应的代码。下面那一行就是正常的模板了生成代码。这就是经典的配置了,配置连接池。它自带生成代码的功能。// 获取数据元信息。
2026-02-28 23:56:19
284
原创 20. 有效的括号21. 合并两个有序链表
(最近的左括号配最近的右括号)。然后进行一步步遍历:拿这个来举例子,"([])"。遍历一个(,然后栈里面就push一个 )在遍历【 此时栈里面就push一个 】 ,此时栈里面有 )和 】,顺序也是这样。在遍历】它只符合最后一个判断条件:if (stack.isEmpty() || stack.pop()!= c)注意:这行代码的顺序。
2026-02-28 20:40:19
614
原创 Mysql和MongoDB的日志
MongoDB 和 MySQL 一样靠日志保证持久化,但日志类型不同:核心是 Journal(对应 Redo Log),次要的是 Oplog(对应 BinLog),无 Undo Log;Journal 的工作逻辑和 Redo Log 一致:先写日志→改内存→崩溃后重放日志恢复;MongoDB 事务回滚不靠日志,靠内存临时快照,提交才刷盘,回滚直接丢弃快照。
2026-02-26 16:17:38
518
原创 Redis 8.6.0相比于之前有什么厉害之处
→ 存缓存、取缓存、删 key、设过期→→ Spring 官方原生 Redis 操作→→ 你可以→→→ 谁也替代不了它。
2026-02-22 15:37:26
742
原创 Minio的使用
这就是minio的用法非常的简单,如果不想用云服务器去存储照片什么信息的话就可以这样去存储。屏蔽了 HTTP 通信、签名认证、异常处理等底层细节,提供简单的业务 API;MinIO下载和安装 | 用于创建高性能对象存储的代码和下载内容。然后你在浏览器打开localhost:9001就能访问控制台了。是开发效率和代码健壮性的最优选择,避免重复造轮子和低级错误。MinIO 是独立服务,业务代码必须通过网络请求与其交互,命令因为我这个是在D盘下所以路径是这样的。这个配置的端口是9000。是官方封装的交互工具;
2026-02-22 12:01:10
359
原创 迭代器以及Hutool工具包
迭代器的使用分 3 步:获取迭代器 → 判断是否有下一个元素 → 获取元素 / 删除元素,核心 API 是:示例 2:遍历 Set(和 List 写法完全一致)示例 3:遍历 Map(先转成 Set 再用迭代器)Map 本身没有迭代器,需要先转成 /(推荐 ,效率更高):、迭代器的避坑点(新手必看) 必须先 hasNext (),再 next ():直接调用 next () 会导致 (没有下一个元素); remove () 只能在 next () 之后调用:没调用 next (
2026-02-19 22:36:21
747
原创 常见八股caffine
全新数据先进 1% 的 Window LRU,Window 满了淘汰尾部候选,和 Main Probation 尾部比频率(高则进 Main);Main 分 Probation(试用)和 Protected(保护),Probation 数据再访问就升级到 Protected,全程用 TinyLFU 统计频率做淘汰 PK,既防缓存污染又兼顾冷热数据。是一个百分比值,表示在存储引擎返回的行中,有多少比例的数据被服务层(Server 层)的条件过滤掉了。Caffeine 基于。的核心淘汰算法,融合。
2026-02-19 17:04:55
662
原创 Java面经
答:队列是否一直存在取决于队列是不是持久化的队列,如果是的话则一直存在不是的话就不是一直存在,比如说像rbmq,rocketmq这些中间件就是持久化存在的,启动时创建一次,然后就一直存在。像定时任务内部的内存队列(如 ThreadPoolExecutor),@Async的异步线程池,它们都是属于jvm层面的,每次启动会创建,每次关闭会销毁。:聚簇索引(主键索引)、二级索引(普通索引、唯一索引、联合索引)、全文索引等。索引一般有:B+树,hash索引,倒排索引,R树索引。
2026-02-18 21:08:26
535
原创 DFA RedissonLockAspect @SneakyThrows
/执行锁内的代码逻辑。),这会直接终止流程,不会执行后续的业务逻辑(也就是切面里的目标方法)。区别就是字典树是要顺着树去寻找,但是DFA可以跳跃,是跳跃着去寻找的。顾名思义redission分布式锁相关的切面,这样写就是为了方便简便。a-p-p(标记为一个单词app)-l-e(标记为一个单词)。用hutool工具类即可,它底层是基于字典树来实现的。这为什么会执行锁内逻辑呢,下面让我来逐一讲解。是函数式接口调用,对应切面里传入的。注解标记的目标方法)。
2026-02-11 16:44:25
560
原创 Cursor游标
不是 “跳过的条数”,哪怕有新数据插入,只要游标不变,查询范围就不会错。👉 核心原因:游标分页的 “起点” 是。还是上面的场景,结合。
2026-02-11 15:02:08
565
原创 @Cacheable注解 @CacheEvict注解@CachePut注解@Caching(组合多个缓存注解)@CacheConfig(统一配置缓存基础参数)@Cacheable 补充参数
是@Cacheable的 “配套注解”,核心解决缓存数据更新后的 “脏数据” 问题;核心参数和@Cacheable一致(cacheNames+key),确保精准清理对应缓存;相比手写缓存的remove操作,注解同样省略了 “查缓存 Key→删除 Key” 的模板代码,一键清理。@Cacheable 存缓存,@CacheEvict 清缓存,二者配合保证缓存数据最新✅。@Cacheable(存)、(删)、@CachePut(更)、(统一配置)、@Caching(组合);
2026-02-11 15:02:04
587
原创 枚举是什么为什么选择它以及进阶以及适配器模式
这里比较有亮点的是这个of,它就是相当于进行匹配,而不是一层一层的if去判断,这个时间复杂度是o(1)而遍历是o(n)所以这就是为什么用枚举。第三段代码不就是用了引入的那个对象吗,这就很像代理模式。这里相当于把这些给放入hashmap集合中。用一句通俗的话来说适配器模式很像代理模式。一开始就是先写一个接口来约束一下。这个对应的就是后面的那些文字。这个@Override。最后业务代码也是这样。对应的就是那个数字。
2026-02-10 19:14:42
330
原创 Dao层是什么作用有哪些
因为userapplymapper继承了BaseMapper<UserApply>并且userapply里面指定了@TableName("user_apply")这个表所以其有了mbplus的一些自带的crud。UserApplyMapper的功能然后里面又写了一些自定义的功能,然后这个dao层的作用就是把这些crud的一些复杂的实现给完善了一下然后用的时候更方便不需要每次都写了。我们在开发的时候一定用过ORM,而Mybits-plus为最常用的。这些看起来都够用了在日常的业务中,但是其实还是不够的。
2026-02-10 17:05:00
292
原创 每次创建新实例的方法
加@Scope("prototype")这个注解,这个是加在实现类也相当于是就是要注入的那个对象的那个类。因为我这里的这个对象是judgeAgent所以这样写,如果是对象名字为baby的话就。确实很简单直接new不用spring创建的对象。然后在控制器或者是要用这个对象的那个类加。每次请求获取新的 Agent 实例。然后在调用的那个方法里面写。
2026-01-30 23:59:44
56
原创 根据工具路由来选择需要的工具,以及mcp工具的注册
/ MCP 工具(由 spring-ai-starter-mcp-client-webflux 自动注入,可能为空)这种方法注册的mcp但是这种不推荐但是比较方便,这就是把mcp工具给注册进来,下面来看业务代码。正常情况下一般一个工具注册器就包含了所有的工具包括mcp工具,那为什么还要引入这个工具路由呢,其实有一些工具在特定的场景下是没有必要使用的,如果你使用了就会多消耗token但是还没有什么用,下面来看代码。// 未命中→全量工具。// 缓存命中:将数据注入上下文,明确告知大模型无需调用RAG。
2026-01-29 17:13:28
484
1
原创 最简便的判断热点key存入caffine
/ 缓存未命中时读文件,这个代码的意思就是把这个方法加入这个questionCache中,如果当用id传入并且在这个questionCache中没有查到相关的数据,就触发loadQuestionTextFromFile这个方法,这个方法就是读取相应的文本,然后caffine自动存入这个key为questionid的vaule中。.expireAfterWrite(30, TimeUnit.MINUTES) // 缓存30分钟过期。// ========== 核心存储(无冗余) ==========
2026-01-25 00:46:53
875
原创 Redis+JWT的安全保障以及redis令牌桶(登录或者注册时的措施)
来举一个最直观的例子:你的银行账号只能在一个地方登录,这就是单点登录,也就是说只允许有一个有效token。所以我们这次引用了redis来确保可以进行单点登录,并且还是双重防护。登录是直接删除旧的key,退出是直接删除key。key为登录登出和拦截器校验都是对这个key进行的操作,即用了单key又实现了单点操作。
2026-01-24 01:47:05
540
原创 Stream流式输出
这里可能会有人有疑问为什么要new对象,直接注入YuManus不可以吗,我来告诉你是不可以的,因为spring是单例bean所以YuManus只有一个对象,如果第一次用这个对象然后给他上下文了什么的数据,就是给这个对象里面的参数赋了值,那么当第二次调用这个接口的时候还会调用这个对象,他就会携带上一个调用这个接口的产生的数据的信息,所以不能共用一个所以需要从新new。主线程直接跳过中间的异步方法直接执行下面这一行,然后异步方法交给异步线程去执行,异步方法的执行时期是下面这个return执行完后执行。
2026-01-20 01:16:02
710
原创 智能体(Agent)构建智能体开发
i++) {log.info("现在是第"+currentStep+"最大"+maxSteps);// 单步执行String result="现在是第"+currentStep+"步结果是"+stepResult;这个就是不断地循环直到大模型满意就跳出把results返回。然后results就是给用户输出的信息。为止;补充:你每次调用工具后,ToolResponseMessage 里的最后一条信息,才是要展示给用户的内容。
2026-01-19 01:43:05
1054
原创 智能体构建
最大步数上限:人工预设的固定数值,是 “防无限循环的兜底规则”,判定逻辑是 “数值对比”,无模糊空间;任务完成:人工定义的 “客观达成条件”,是 “终止循环的理想规则”,判定逻辑是 “是否满足预设的目标信号”;两者都是人为提前设定的,模型 / 代码只会按这些规则执行,不会自己定义 “什么算完成 / 该停”。
2026-01-18 00:30:41
180
原创 Threadlocal有哪些应用场景,底层是如何实现的
如果 key 是强引用,那么即使你外面已经把 ThreadLocal 置为 null,Entry 还会强引用它,导致 ThreadLocal 永远无法被 GC,从而内存泄漏。所以 key 必须是弱引用,让 ThreadLocal 可以被正常回收。如果 value 是弱引用,那 GC 随时可能把它回收掉,你业务代码正在用的时候突然没了,直接 NPE。因为 key 是弱引用,会被 GC 回收变成 null。如果线程长期存活(比如线程池),这些 key=null 的 Entry 会越积越多,导致 OOM。
2026-01-17 00:29:13
240
原创 创建线程执行任务
运行结果如下:定义一个类然后继承Thread类就可以,然后在new这个类的对象然后调用start方法就是调用这个类的run方法。当你的任务非常简单,而且只需要执行一次,不需要考虑复用,也不需要实现其他接口时,继承Thread可以让代码更简洁。
2026-01-17 00:19:36
386
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅