- 博客(287)
- 收藏
- 关注
原创 Spring Boot 常用注解详解:@Slf4j、@RequestMapping、@Autowired/@Resource 对比
Slf4j:Lombok 注解,自动生成日志对象,简化日志代码@RequestMapping:Spring MVC 注解,映射请求路径到处理方法@Autowired 默认按类型注入,Spring 推荐@Resource 默认按名称注入,JDK 标准两者功能相似,但注入策略不同。
2025-12-30 22:35:29
821
1
原创 Hot 146 LRU Cache 实现详解
数据结构:HashMap + 双向链表虚拟节点:简化边界处理访问顺序:头部 = 最近使用,尾部 = 最近最少使用时间复杂度:所有操作 O(1)关键操作:get/put 时都要将节点移到头部这是一个经典的数据结构组合应用,在面试中经常出现。掌握这个实现,对理解缓存机制和数据结构设计很有帮助。
2025-12-29 22:17:07
759
原创 环形链表题型总结
核心思想快慢指针:用两个指针以不同速度遍历,如果有环会相遇哈希集合:记录访问过的节点,如果再次遇到说明有环选择方法空间要求高:用快慢指针(O(1) 空间)代码简单:用哈希集合(O(n) 空间)记忆要点快慢指针:slow 每次走1步,fast 每次走2步找环入口:相遇后,一个从头开始,一个从相遇点开始,同时移动数学关系:从相遇点到环入口的距离 = 从 head 到环入口的距离。
2025-12-25 15:16:21
801
原创 智谱AutoGLM云部署
圣诞节这天终于跑通了,看着手机自己打开设置、滑动页面、点击按钮……那种感觉太爽了!记录完毕,留作纪念~4.申请智谱API Key打开注册/登录 → 控制台 → API Keys → 创建新Key新用户有免费额度,够玩很久5.手机准备设置 → 我的设备 → 全部参数 → 连续点击版本号7次 → 开启开发者选项开发者选项 → 开启 USB 调试(和USB调试安全设置)用数据线连接电脑下拉通知栏 → USB连接方式 → 选择“文件传输(MTP)”6.电脑端连接手机(关键步骤)
2025-12-25 11:17:29
762
原创 简要总结 HashSet 和 HashMap(Java)
特性HashSetHashMap存储内容值(元素)键值对重复性不允许重复key 不允许重复时间复杂度O(1) 平均O(1) 平均主要用途去重、查找映射、计数常用方法。
2025-12-24 20:26:15
222
原创 算法边界情况处理套路总结
/ 返回类型根据题目要求选择return 0;// int类型return "";// String类型// List类型// 数组类型。
2025-12-14 19:56:01
180
原创 Feed流模式和三种实现方式
三,推拉结合 大v对于活跃粉丝 就直接推送到活跃粉丝收件箱 延迟极低 对于普通粉丝,需要的时候去大v的发件箱拉取就行了。对于僵尸粉 收件箱也不拉。二,推模式 用户发送消息时直接推送到所有粉丝的收件箱 延迟就极小了,但是如果有上千万上亿就不现实了。一,拉模式 用户收件箱不存储消息,每次都从发件箱拉取,十分耗时。
2025-12-11 15:25:26
134
原创 双端队列(Deque)
ArrayDeque,操作有:addLast/removeLast(尾部),addFirst/removeFirst(头部),peekFirst/peekLast 查看头尾元素但不移除。1) 先弹掉队头过期索引(peekFirst() <= i - k)2) 再弹掉队尾“劣势”索引(对应值 ≤ 当前值),保证值单调递减。4) 窗口形成后,队头即当前窗口最大值。3) 把当前索引加到队尾。
2025-12-09 21:17:17
175
原创 Integer.MIN_VALUE 是什么意思?
Integer.MIN_VALUE 是 Java 中 int 类型的最小值,等于 -2,147,483,648。在找最大值时,初始化为最小值,确保任何有效值都能更新它。这个经常在求最大值时出现。
2025-12-07 17:49:53
219
原创 Samba服务器部署指南
Samba 启动失败是因为缺少共享库 libwbclient.so.0,通常由 samba-libs 或 samba-common-libs 提供。库文件已找到,但路径不对。它在 /usr/lib64/samba/wbclient/libwbclient.so.0,系统默认找不到这个位置。下面的空三个空格 不能用tab 特别注意 path = /samba/share 等号前后都有空格。简单理解:Samba让Linux服务器变成“共享文件夹”作用:设置目录权限,让所有用户都能读写。作用:创建共享文件夹。
2025-12-04 10:52:11
867
原创 基于 Redis Pub/Sub 的消息队列
Pub/Sub 就像社区广播系统:广播室(发布者)对着喇叭广播,谁在现场收听(订阅者)就能同时听到。但广播不会重播,没听到的人就永远错过;广播室也不会记录谁听了、谁没听。基于 Redis Pub/Sub 的消息队列采用发布-订阅模式:发布者向频道发送消息,所有订阅该频道的消费者会实时收到,天然支持多生产者、多消费者。
2025-11-27 20:45:32
453
原创 Redis List 的消息队列
List 是有序结构,配合 LPUSH/RPOP 或 RPUSH/LPOP 可以保证先进先出。队列数据存在 Redis 中,而不是 Java 应用内存里,所以消息量大也不会挤爆 JVM。Redis 支持 AOF/RDB 等持久化方式,即使服务重启,消息也能恢复,减少丢失风险。如果消费者取出消息后还没处理完成就宕机,消息已经被移出队列,无法自动重试,需要额外处理。一个消息只能被一个消费者取走,缺乏多消费者协作、消费确认等高级功能,扩展能力有限。2.依托 Redis 的持久化机制,数据安全性较好。
2025-11-27 20:35:55
183
原创 阻塞队列及优缺点
阻塞队列(Blocking Queue)是一种线程安全的队列数据结构,提供在队列为空时自动阻塞消费者、队列满时自动阻塞生产者的机制,常用于生产者-消费者模型。典型实现有 Java 的 ArrayBlockingQueue、LinkedBlockingQueue 等,通过内置锁和条件变量实现阻塞与唤醒。阻塞队列就像银行排队取号:窗口只有一个位置,当窗口忙时,后面的人只能耐心排队等待轮到自己(被阻塞);一旦前面有人办完业务,排队系统自动放行下一个人继续办理,保证“先来先服务”。
2025-11-27 20:27:30
381
原创 什么是包装类?
包装类是将基本数据类型封装成对象的类,让基本类型也能以对象形式使用。特性基本类型包装类默认值有(如 int 是 0)null能否为 null❌ 不能✅ 可以泛型支持❌ 不支持✅ 支持性能⭐⭐⭐⭐⭐ 快⭐⭐⭐⭐ 稍慢内存占用小大(对象开销)
2025-11-25 13:38:56
385
原创 Hot 100 -283 移动零
这个过程其实就是“稳定压缩数组”:把非零元素稳定地压到前面,剩下的空间自然被填成 0。你可以把它类比成在纸上把所有非零写到上边,写过的位置往后空出来,再把空白处写 0。当我们把所有非零元素都放好后,数组剩下的位置自然应该是 0。与其再单独循环一次把末尾填 0,不如在移动过程中顺手把被“腾空”的位置设为 0,这样就无需二次遍历。换句话说,把它们依次塞到数组前面,这样顺序肯定没变。所以当我们“搬”了东西,就必须把原房间清空,不然就会出现重复的家具(非 0 数字)留在后面,导致结果不对。
2025-11-24 21:13:20
328
原创 秒杀优化—基于 Redis 完成秒杀下单
图片把“异步秒杀”拆成两段:Redis + Lua 做极速判断,后台队列做慢速落库,基于 Redis 完成秒杀下单核心思路。目标:把秒杀核心逻辑搬到 Redis 层,用 Lua 脚本实现“库存扣减 + 防一人多单”一体化,降低数据库压力。2.接口立即返回,主流程很快。3.异步落库(削峰填谷)
2025-11-24 18:29:56
264
原创 Redis主从同步不一致导致分布式锁失效”的风险
单节点 Redis 锁:主从延迟或节点宕机会导致锁丢失。MultiLock:像“加锁投票制度”,必须在多个节点都拿到锁才算成功,天然规避单点故障或主从不一致问题。一旦有节点失败,MultiLock 立即回滚其他节点锁,保证锁状态一致。所以图中的“多个 Redis 节点 + 主从同步”场景,正是 MultiLock 要解决的:通过“多节点同时加锁 + 全部成功才继续”的策略,避免因为某个节点挂掉或主从同步延迟造成的锁失效。
2025-11-24 17:52:07
326
原创 Redisson的multilock原理
Redisson 的 RedissonMultiLock(联合锁)是用来同时持有多把独立锁,从而兼顾多资源一致性的“打包锁”。它的工作原理可以分成“加锁”“释放”“故障处理”三个阶段。
2025-11-24 17:50:30
414
原创 Redisson的锁重试和WatchDog机制
3.分支:leaseTime 是否为 -1。2.判断 TTL 是否为 null。4.判断剩余等待时间是否 > 0。2.判断释放是否成功。
2025-11-24 16:52:08
781
原创 Redisson的可重入锁
Redisson 可重入锁就是:用 Redis 的 Hash 记录“哪个线程拿了锁 + 拿了几次”,拿锁时只允许同一个线程的重入次数自增,释放时次数自减到 0 才真正删除锁,从而在分布式环境里实现和 Java ReentrantLock 类似的行为。确实挺复杂,毕竟 Redisson 要在分布式环境里模拟 ReentrantLock 的行为,还要考虑线程标识、重入计数、自动续期、Redis 原子性等一堆细节。好消息是。
2025-11-24 16:16:26
404
原创 基于Redis的分布式锁
Lua 脚本将多条 Redis 命令打包成一个原子操作,在分布式锁等场景中可避免并发问题,保证数据一致性。5. 参数3:ID_PREFIX+Thread.currentThread().getId()这段代码在类加载时(静态初始化)创建一个 Redis Lua 脚本对象,用于释放分布式锁。使用 Lua 脚本释放分布式锁,通过线程 ID 标识确保只有锁的持有者才能释放。3.异常处理:业务超时或服务宕机 → 锁自动过期释放。3. 参数1:UNLOCK_SCRIPT。unlock.lua文件中的内容。
2025-11-22 12:22:32
1223
原创 Hot 100 -49. 字母异位词分组
先创建一个map集合,然后遍历字符串strs 获取到s 转化成字符数组 给字符数组排序之后如果是字母异位词的话,排序之后的值相等,即key相等 然后把相同的key放到同一个map集合中 即完成题目。
2025-11-20 20:10:09
259
原创 CountDownLatch(倒计时锁)
CountDownLatch 是让线程等待其他线程完成的一种简单工具常见用法:主线程等多个子线程执行完毕,再继续在这个测试中,用来等待 300 个 ID 生成任务全部完成,再统计耗时CountDownLatch 就像赛跑终点的计时员,手里有一把“倒计时牌”设置为 N:每当一个参赛者抵达,计时员把牌减 1;当牌数减到 0 时,表示所有参赛者都到齐,主裁判(等待线程)才可以宣布比赛结束并继续后续流程。技术上,它允许主线程先设置一个计数值,然后阻塞等待;
2025-11-17 20:57:25
454
原创 Redis全局id生成器
为实现唯一ID 不使用Redis自增的数值,符号位为0,代表ID永远是正数,31位,以秒为单位,2的31次方,为21亿秒,大概是69年,如果1s内下多单,后面的序列号也可以以示区分。
2025-11-17 18:52:41
162
原创 Function<ID,R> 详解
泛型/参数含义示例<R,ID>方法级泛型声明R返回类型ShopIDID 类型LongClass<R>类型信息Shop.class数据库查询函数。
2025-11-14 08:52:59
634
原创 Error: Public Key Retrieval is not allowed
这是 MySQL 8.0+ 的连接安全限制。需要在数据库连接 URL 最后添加 allowPublicKeyRetrieval=true 参数。
2025-11-12 14:47:51
160
原创 缓存击穿讲解
热点key失效引发缓存击穿,导致数据库压力激增。与缓存雪崩不同,击穿是单个热点key失效问题。解决方案包括永不过期策略和互斥锁机制(类似食堂排队打饭),通过限制并发查询保证一致性。逻辑过期策略允许使用旧数据(如参考过期公交线路图),牺牲强一致性换取系统可用性,适用于一致性要求不高的场景。两种方案各具优势:互斥锁实现简单但影响性能,逻辑过期则确保系统高可用。核心思路都是平衡数据一致性与系统性能。
2025-11-11 12:33:43
435
原创 缓存雪崩讲解
生活化类比:图书馆所有书架同时到期清空,大量读者同时涌向仓库,仓库瞬间过载。专业解释:用户请求的数据在缓存和数据库中都不存在,每次请求都穿透到数据库,给数据库带来压力。
2025-11-11 10:08:40
203
原创 缓存更新策略
有两种策略1.先删除缓存,再操作数据库(有缺点)正常:线程1先删除缓存,然后线程1更新数据库异常情况:线程1删除缓存之后,再线程1更新数据库之前,线程2查询缓存,因为缓存已经被删除,未命中,然后查询数据库,写入缓存。之后线程1执行了更新数据库的操作,此时发生了数据库与缓存不一致问题、发生情况:高 因为查询数据库是比较慢的2.先操作数据库,再删除缓存。正常:线程1查询缓存,未命中,查询数据库,然后写入缓存。
2025-11-10 11:45:47
343
原创 什么是缓存
缓存是数据交换的缓冲区(Cache)临时存储数据的地方读写性能较高简单理解:缓存 = 临时仓库- 把常用的东西放在临时仓库(缓存)- 需要时快速取用- 比从主仓库(数据库)取快很多。
2025-11-08 17:40:01
558
原创 计算机硬件基础
硬件作用类比CPU执行计算大脑内存临时存储桌面硬盘永久存储仓库主板连接硬件骨架显卡处理图形画师电源供电心脏CPU:执行计算的核心内存:临时存储,速度快硬盘:永久存储,容量大主板:连接所有硬件显卡:处理图形电源:供电CPU = 大脑(思考)内存 = 桌面(临时放东西)硬盘 = 仓库(永久存放)显卡 = 画师(画图)电源 = 心脏(供电)
2025-11-08 17:18:25
448
原创 UserDTO userDTO=BeanUtil.fillBeanWithMap(userMap,new UserDTO(),false);
BeanUtil 是工具类,fillBeanWithMap 是静态方法作用:把 Map 中的数据填充到 UserDTO 对象中参数:源 Map、目标对象、是否忽略错误返回:填充好的 UserDTO 对象BeanUtil.fillBeanWithMap = 工具类调用静态方法作用 = 把 Map 转成对象不需要创建对象,直接用类名调用。
2025-11-08 16:01:07
631
原创 stringRedisTemplate.opsForHash().entries
虽然看起来一样,但 Redis Hash 和 Java Map 是不同系统的数据结构entries() 的作用是把 Redis 的数据转换成 Java 能用的格式转换后,Java 代码才能直接操作这些数据这是不同系统之间数据交互的必要步骤Redis Hash = 银行里的钱(需要取出来)Java Map = 手里的现金(可以直接用)entries() = 从银行取钱(转换成现金)
2025-11-08 15:45:44
827
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅