- 博客(20)
- 收藏
- 关注
原创 LRU缓存(手写双向链表和哈希表)
本文介绍了LRU(最近最少使用)缓存策略的Java实现方案,采用哈希表+双向循环链表的数据结构组合,确保get和put操作的时间复杂度均为O(1)。核心设计包括:哈希表用于快速查找键值对;双向循环链表维护访问顺序,最近访问的数据置于链表头部;通过虚拟头节点简化操作;当缓存超限时自动移除尾部最久未使用的数据。文章提供了完整的Java实现代码,包含节点类定义、缓存初始化、数据存取等核心方法,并详细说明了各方法的操作逻辑,为需要实现高效缓存机制的开发者提供了实用参考。
2026-04-25 14:22:05
63
原创 RabbitMq高级篇
本文摘要:文章详细探讨了RabbitMQ消息可靠性的保障机制,从生产者、MQ到消费者三个层面提出解决方案。生产者方面通过重试机制和确认机制确保消息投递;MQ层面采用持久化、惰性队列等方式防止消息丢失;消费者端通过确认机制、重试策略和幂等处理保证消息正确消费。同时介绍了延迟消息的实现方式(死信交换机和插件)及其在订单超时场景的应用,并提出了多级延迟检测的优化方案,有效平衡系统资源利用与业务需求。
2026-03-12 11:15:43
500
原创 RabbitMQ基础篇学习
本文介绍了RabbitMQ在Spring AMQP中的实现方式。同步调用时效性强但扩展性差,而异步调用具有解耦、高性能等优势。通过Spring-rabbit模块,可以使用@Bean注解声明交换机和队列,并实现三种消息模式:fanout广播、direct定向路由和topic主题匹配。文中展示了测试用例代码,包括消息发送和监听实现,以及使用Jackson替代默认JDK序列化的配置方法。最后提供了RabbitMQ的YML配置和Maven依赖说明,重点说明了prefetch参数对消息消费速率的控制作用。
2026-03-12 11:14:05
192
原创 黑马点评分布式锁的学习
摘要:本文介绍了基于Redis实现分布式锁的方案,解决多Tomcat环境下synchronized锁失效的问题。通过Redis的setnx命令实现互斥锁,设置锁有效期防止死锁,并使用UUID+线程ID作为唯一标识避免误删。针对解锁时判断和删除操作的非原子性问题,采用Lua脚本保证操作原子性。具体实现包括:1) 获取锁时设置唯一标识和超时时间;2) 释放锁时通过Lua脚本先验证标识再删除;3) 使用Spring的DefaultRedisScript加载执行Lua脚本。该方案有效解决了分布式环境下的并发控制问题
2026-02-04 23:31:36
74
原创 黑马点评优惠卷秒杀的学习
本文介绍了秒杀系统中订单生成与库存扣减的实现方案。订单号生成采用Redis分布式ID生成器,结合时间戳和序列号,通过位运算提高效率。库存扣减使用乐观锁保证原子性,通过版本号或CAS机制防止超卖。针对一人一单限制,采用synchronized对用户ID加锁,并通过获取代理对象解决事务失效问题。系统实现了订单生成、库存扣减、一人一单校验等核心功能,同时考虑了分布式环境下的锁机制和事务一致性。
2026-02-04 22:31:26
635
原创 啥是redis的雪崩,缓存击穿,缓存穿透
本文介绍了Redis常见的三种缓存问题及解决方案。缓存雪崩是由于大量key同时失效或Redis宕机导致数据库压力激增,可通过随机TTL、多级缓存和降级限流解决;缓存穿透是查询不存在的数据导致请求穿透到数据库,可采用缓存空对象或布隆过滤器;缓存击穿是热点key失效引发高并发冲击数据库,解决方案包括互斥锁(重建缓存时加锁)和逻辑过期(返回旧数据同时异步重建)。这些方法有效保障了系统在高并发场景下的稳定性。
2026-02-02 12:22:28
261
原创 黑马点评-缓存的学习(1)
本文介绍了缓存的基本概念及其在Java项目中的应用,重点分析了三种缓存策略(内存淘汰、过期淘汰、主动更新)的适用场景。详细讲解了主动更新的三种实现方案(CacheAside、Read/WriteThrough、WriteBack)及其优缺点,推荐使用CacheAside模式。针对常见问题,文章提出了解决方案:直接删除缓存而非更新;先操作数据库再删除缓存;通过事务或分布式事务保证操作的原子性。这些策略和方案能有效平衡系统性能和一致性需求。
2026-02-02 12:05:53
268
原创 git的常见操作
本文介绍了Git常用命令及操作流程,包括:1)查看分支、暂存和提交代码;2)创建和切换分支;3)本地分支合并到主分支;4)推送本地分支到远程仓库;5)主分支与远程分支的同步与合并;6)拉取远程分支到本地。这些命令涵盖了Git日常开发中的基本操作流程,帮助开发者高效管理代码版本和协作开发。
2026-01-30 16:17:08
229
原创 黑马点评项目学习-短信登录
本文介绍了基于Redis实现短信验证码校验功能的开发流程。首先分析了传统Session方式在多Tomcat部署时存在的共享问题,提出使用Redis存储验证码和用户信息的解决方案。文章详细讲解了ThreadLocal的使用及其内存泄漏风险,并展示了封装ThreadLocal的工具类UserHolder。在具体实现部分,描述了短信发送、登录注册、用户校验等功能的代码逻辑,重点说明了如何用Redis替代Session存储验证码和用户数据。最后,通过设计双重拦截器(RefreshTokenInterceptor和L
2026-01-28 20:06:51
725
原创 redis学习-SpringDataRedis
本文介绍了Spring Data Redis的基本使用,重点讲解了RedisTemplate和StringRedisTemplate两种操作Redis的方式。通过Spring Boot集成Redis,详细展示了依赖配置、yml文件设置和RedisTemplate的自定义序列化方法。文章对比了自动序列化(使用GenericJackson2JsonRedisSerializer)和手动序列化(使用ObjectMapper)两种方式的优缺点,指出自动序列化虽然方便但内存开销较大,而手动序列化能有效降低内存消耗。最
2026-01-27 22:38:10
682
原创 redis客户端-jedis
本文介绍了Redis客户端的概念及其与Redis的区别,重点讲解了Java语言中常用的Jedis客户端。Jedis通过Redis命令作为方法名,简单易用但不支持线程安全,需配合连接池使用。文章详细演示了Jedis的基本操作(字符串、哈希)和连接池配置方法,包括最大连接数、空闲连接数等参数设置。通过JedisPool获取连接后,操作方式与单例Jedis相同,且关闭连接时实际是将连接归还给连接池而非销毁。文中还提及Lettuce和Redisson两个客户端的特性,为后续SpringDataRedis集成做准备。
2026-01-27 21:58:24
329
原创 并发编程-线程状态
摘要:线程状态分析可从操作系统和Java两个层面理解。操作系统角度分为初始、可运行、运行、阻塞和终止5种状态;Java的Thread.Status类则细化为NEW、RUNNABLE(包含OS三种状态)、BLOCKED、WAITING、TIMED_WAITING和TERMINATED。示例代码展示了各状态转换:t1(NEW)、t2(RUNNABLE)、t3(TERMINATED)、t4(TIMED_WAITING)、t5(WAITING)、t6(BLOCKED),其中BLOCKED状态因锁竞争产生,WAITI
2026-01-25 12:50:44
448
原创 并发编程-两阶段终止模式
两阶段终止模式是一种线程终止机制,它允许线程在被中断时有机会完成必要的清理工作。该模式通过检查中断标志位来判断线程是否需要终止:若线程在执行任务时被中断,则直接终止;若在sleep状态被中断,则需要重新设置中断标志,并在下次循环中处理终止逻辑。这种模式常用于服务器后台监控程序,通过循环配合sleep既能持续监控又避免过度占用CPU资源。示例代码展示了如何实现该模式,包括正常执行监控任务和异常中断时的处理流程。
2026-01-24 21:31:39
441
原创 并发编程-线程中常见的方法API和守护线程
摘要:本文详细讲解了Java多线程编程中的关键方法。start()方法会创建新线程执行任务,而run()方法则是同步执行;sleep()使线程进入阻塞状态,yield()让线程回到就绪状态;interrupt()方法设置打断标记,但sleep/wait/join被打断后会清除标记;线程优先级(setPriority)可影响调度机会但不保证顺序;join()方法实现线程同步等待;守护线程(setDaemon)会在用户线程结束时自动终止。这些方法在多线程编程中各有特点和适用场景。
2026-01-24 21:18:22
776
原创 入门算法-单调栈
本文通过LeetCode每日温度问题讲解单调栈的两种实现方式。第一种从左往右遍历,维护栈中元素单调递减,遇到比栈顶大的温度时弹出栈顶元素并计算天数差。第二种从右往左遍历,保持栈单调递增,遇到高温时弹出较小元素。两种方法都利用栈的单调性高效解决问题,时间复杂度均为O(n),空间复杂度O(n)。核心区别在于遍历方向不同导致栈的单调性相反,但都通过维护单调性来快速找到下一个更高温度的天数间隔。
2026-01-23 14:31:37
428
原创 并发编程-线程运行原理
摘要:JVM内存区域包括栈、堆和方法区。线程运行时分配独立栈内存,由多个栈帧组成对应方法调用。示例代码展示了方法调用时栈帧的创建与销毁过程,包括局部变量表、程序计数器等结构。线程上下文切换由时间片用完、GC、优先级或主动调用方法触发,涉及保存线程状态(程序计数器、栈帧信息)并恢复另一线程状态,频繁切换会影响性能。
2026-01-22 17:12:02
884
原创 并发编程-如何创建线程
但是通过lambda表达式进行简化,因为runnable接口只有一个方法run可以通过lambda表达式进行简化。但是FutureTask需要配合callable进行创建线程任务,因为task需要一个返回的泛型。因为FutureTask的底层也实现了runnable接口所以可以配合thread进行创建线程。3,通过FutureTask配合Thread进行创建线程。2,通过runnable接口进行创建线程。1,直接通过thread进行创建线程。
2026-01-21 23:59:26
382
原创 并发编程的基本概括(线程,进程,并发,并行等)
摘要:进程是程序运行的实例,负责管理内存和I/O操作,而线程是进程内的执行单元。进程间通信较复杂,线程通信更简单且轻量。单核CPU通过时间片轮转实现线程并发,多核CPU可实现并行执行。异步调用通过分离任务提高效率,多线程在多核环境下能充分利用CPU资源。单核CPU的多线程主要用于任务切换,而非效率提升。IO操作虽不占用CPU,但阻塞IO会限制线程利用率,需通过非阻塞和异步IO优化。
2026-01-20 15:30:14
1114
原创 二维前缀和算法
首先啥是二维前缀和,二维前缀和就是二维数组中num[i][j]到num[0][0]的矩阵和,这个就是二位前缀和。其实很简单,就是求出二位前缀和数组,然后对其判断是否小于等于k然后ans++就行了,是不是非常简单,哈哈哈。对其进行初始化,然后你就能解决lc中的一道简单的中等题了。然后给你一个二维数组的坐标请你求出,矩阵的元素和。然后你就能解决一道lc上的一道非常简单的中等题。首先我们要进行初始化二维前缀和。
2026-01-16 16:22:18
270
原创 大二Java实习生寒假初面一(已过)
3,问题三对于一个分布式项目,有两台服务器,服务正式上线的时候,由用户反馈,有一个功能有时候可以使用,有时候页面会报500的错误,这个功能使用时,会由a服务器去调用b服务器的方法或者接口去实现,请问可能是哪出现了问题,你该如何去解决。回答:问题原因 sql查询效率太低了,线程竞争和锁的逻辑处理不当,redis缓存环节出现了问题(可能是redis雪崩或者是redis击穿)大量的key或者是热点key失调。回答:可能的原因 1,b服务负载过高或者是资源不足 cpu,内存等满了,无法响应请求,线程池耗尽。
2026-01-16 16:02:20
353
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅