自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(30)
  • 收藏
  • 关注

原创 手写实现Redis分布式锁 + Redisson原理与最佳实践

本文详解手写Redis分布式锁的原理与问题,通过SETNX实现互斥、TTL防死锁、Value标识锁归属,并用Lua脚本保证释放锁的原子性。然而生产环境推荐使用Redisson,其具备可重入、锁重试及看门狗自动续期等高级特性,显著提升可靠性与易用性。

2026-10-04 23:39:33 186

原创 CAS乐观锁和悲观锁

本文介绍了CAS乐观锁与悲观锁在解决并发问题中的应用。乐观锁通过CompareAndSwap机制,在更新时验证数据未被修改,适用于库存扣减等场景;悲观锁则通过加锁确保线程串行执行,适用于一人一单等需保证唯一性的业务。结合使用乐观锁(扣库存)与悲观锁(防重复购买),可有效防止超卖和重复下单。代码示例展示了基于Spring Boot的秒杀优惠券领取逻辑,强调了intern()在单机锁中的作用,并指出集群环境下需使用Redis分布式锁。

2026-10-04 22:45:45 182

原创 Redis实现方案:更新策略、穿透、雪崩、击穿、工具封装

本文系统阐述了缓存的原理与应用,涵盖缓存更新策略(内存淘汰、超时剔除、主动更新)、缓存穿透(布隆过滤器、空对象缓存)、缓存击穿(互斥锁、逻辑过期)及缓存雪崩(随机TTL、集群部署)的解决方案。通过泛型工具封装实现通用查询,结合Redis API与Spring Data Redis,提升系统性能与稳定性,确保数据一致性,适用于高并发场景下的高效缓存管理。

2026-10-03 14:48:15 201

原创 基于Session和Redis实现登录对比

本文介绍了基于Session与Redis的登录实现机制。Session通过JSESSIONID在服务端保存会话状态,但存在集群共享问题;而Redis方案利用Token作为索引,将用户信息以Hash结构存储于Redis,支持多实例共享,提升可扩展性。登录流程包括生成验证码、校验、自动注册及登录状态持久化,通过拦截器结合ThreadLocal实现用户信息传递与权限校验。使用BeanUtil完成对象转换,确保数据安全与高效传输。相比JWT,Redis Token更便于主动失效管理,适合需要灵活控制登录状态的场景。

2026-09-29 18:48:04 151

原创 一文讲解SpringBoot启动流程,包含常见问题解析

本文系统阐述了SpringBoot配置优先级、Bean管理(作用域、生命周期、第三方Bean)、自动配置原理及自定义Starter的实现。重点解析了@SpringBootApplication的三大核心功能:组件扫描、自动配置与配置类声明;深入剖析自动配置流程,包括@EnableAutoConfiguration通过AutoConfiguration.imports加载候选配置类,并结合@Conditional系列注解按条件注册Bean。同时对比@Component与@Bean差异,明确IOC/DI概念,强

2026-09-25 17:01:20 278

原创 AOP:面向切面编程要点总结

本文介绍Spring AOP实现操作日志记录,通过@Around环绕通知结合@annotation注解,自动统计增删改接口的执行耗时,并将操作人ID、方法名、参数、返回值等信息存入数据库。利用ThreadLocal在Filter中解析JWT获取登录员工ID并存储,AOP中读取该值作为操作人,确保日志准确性。通过动态代理实现零侵入式增强,提升代码可维护性,适用于权限控制、日志记录等场景。

2026-09-24 19:10:34 213

原创 登陆认证:Token令牌技术&Filter过滤器&Intereptor

服务器查询(MyBatis)2.会话技术会话:会话跟踪:会话跟踪方案:Cookie工作流程:优点:缺点:Session工作流程:优点:缺点:概念:优点:缺点:需要自己编码实现JWT由三部分组成:JJWT:是Java实现JWT操作的工具库作用:JWT解析异常可能失败原因:作用:根据用户信息生成用户凭证 方法 作用 signWith() 设置签名算法和密钥 addClaims() 添加自定义数据

2026-09-20 21:29:37 163

原创 Java修行实录:网络编程——多人聊天室v2.0

功能:- 在线用户列表- 用户退出清理- 查看在线用户- 私聊。

2026-09-05 19:52:43 228

原创 Java修行实录:IO体系

java最底层这是所有IO的爸爸InputStream定义是抽象类,不能 new,因为不知道数据来自哪里?

2026-09-05 18:03:43 221

原创 Java修行实录:网络编程——多人聊天室v1.0

实现功能:- 多个客户端连接- 每个客户端独立线程- 服务器保存客户端列表- 消息广播。

2026-09-04 18:13:56 222

原创 Java修行实录:网络编程(1)

ServerSocket 是服务器端专门用于监听某个端口、接受客户端连接的客户端可以通过 Socket("ip",端口)来发起连接服务器端连接成功后也会accept()到一个Socket连接成功后,真正的数据收发是由双方的Socket完成的可以将Socket当作一次连接一个建立好的Socket可以拿到两个重要的东西:getInputStream() 和 getOutputStream()read()和write()可以从输入/输出流中读取/发送一个字节的int数据。

2026-09-03 19:05:32 218

原创 Java修行实录:基于线程池实现流水线多阶段任务

在实际业务中,一个任务通常不是一步完成的,而是要依次经过多个阶段为了提高并发能力,每个阶段分别配置线程池,让处于不同阶段的任务同时执行这种结构称为:线程池流水线本文的计算任务为:初始值:0A阶段:0 + 20 = 20B阶段:20 * 10 = 200C阶段:200 + 22 = 222最终结果如果是 222 的任务,可以认为任务正确执行完毕。

2026-06-03 13:52:57 222

原创 Java修行实录:线程池(2)

生产任务的速度是微秒级,创建线程的速度是毫秒级,生产任务比创建线程速度快,导致一个线程没创建完成,可能下一个任务就到了,导致线程池一口气多造了几个非核心线程。线程池的策略是优先将任务放入队列中,如果放不进去(队列爆满),触发创建非核心线程。疑惑1:核心线程3,队列容量15,为什么一次性提交20个任务,只有2个任务多余的情况下,创建了3个非核心线程?线程关闭时,要对所有线程发送中断信号,普通的 ArrayList 遍历极快,阻塞队列不适合这样遍历。疑惑3:为什么先用 offer(),后面用 put()?

2026-06-03 12:55:04 197

原创 Java修行实录:线程池(1)

线程池是一种多线程的处理形式。在程序启动时,会创建一定数量的线程放入池中等待任务,当有任务需要执行时,从池中取出一个空闲线程执行任务,任务执行结束后,线程会回到池中继续等待下一个任务。

2026-05-20 13:31:14 370

原创 AI辅助分析系统

创建一个支持 Spring AI 的 Spring Boot 的项目配置智谱模型API key在在src/main/java/com.example/aiassistant/ 创建一个新Calss,TestAiController声明这是一个REST控制器,会自动将返回结果序列化为JSON/文本声明一个final的ChatClient实例,通过构造器注入Spring AI会自动帮你配置好ChatClient.Builder。

2026-04-18 18:55:10 354

原创 Java修行实录:从零开始Java坦克大战(v3.0)

文章摘要: 本文介绍了坦克游戏开发中的关键技术实现:1)采用线程分离技术,将渲染与逻辑线程分开,通过延时避免CPU资源抢占;2)设计信息面板与游戏面板的界面布局;3)实现游戏暂停机制;4)开发坦克爆炸特效,包含11帧动画和音效播放;5)关卡系统支持多地图切换和通关判定;6)为坦克添加血条显示和血包拾取功能。这些技术通过合理的线程管理、UI布局和游戏逻辑设计,提升了游戏性能和用户体验。

2026-04-06 16:19:07 418

原创 Git本地项目上传GitHub使用指南

因为首次推送时使用了 -u 参数,以后直接 git push就行,不需要再写 orgin main。配置邮箱,邮箱使用GitHub账号关联的邮箱,提交记录会显示在你的GitHub贡献图上。如果 GitHub 仓库已经有文件(如 README.md),需要先拉取合并。SSH密钥用于安全的连接GitHub,避免每次都输入密码。-u 参数:建立本地分支与远程分支的跟踪关系。刷新GitHub网页,查看上传的网页。输入yes并回车,成功的会话显示。会显示所有未跟踪的文件(红色)main 参数:指定要推送的。

2026-03-30 20:59:21 416

原创 Java修行实录:从零开始Java坦克大战(v2.0)

坦克游戏v2.0新增了多项功能:1) 实现坦克方向控制(WASD键)和子弹朝向同步;2) 新增墙体碰撞检测系统,坦克与墙体碰撞会"顶牛",子弹碰到墙体会消失;3) 采用二维数组定义可自定义地图,支持墙体(1)和敌军坦克(*)标记;4) 创建敌军坦克类,实现随机移动和2%概率射击的AI行为。技术实现包括:1) 使用Direction枚举类管理移动方向;2) 通过Rectangle类的intersects()方法实现碰撞检测;3) 优化对象引用管理提升性能;4) 子弹系统根据发射方向确定初始位置和运动轨迹。项目

2026-03-30 18:18:13 422

原创 Java修行实录:从零开始Java坦克大战(v1.0)——我的多线程和OOP实战记录

本文介绍了基于OOP思想的坦克游戏开发过程。首先构建了游戏元素类继承体系:GameElement作为抽象基类,包含坐标、宽高等基础属性;Tank作为坦克基类继承GameElement;PlayerTank和Bullet分别实现玩家坦克和子弹功能。游戏采用双缓冲技术解决画面闪烁问题,通过GameLoopThread线程控制画面重绘和元素移动。键盘监听器GameListener实现WASD控制坦克移动和J键射击功能,采用观察者模式实现组件与监听器的解耦。文章详细阐述了类设计思路、游戏循环实现和事件处理机制,展示

2026-03-28 23:31:14 393

原创 VideoMamba:Pipeline过程记录(UA-DETRAC数据集)

os.path.join('folder', 'subfolder', 'file.txt') # 输出: 'folder/subfolder/file.txt'(Unix)或 'folder\\subfolder\\file.txt'(Windows)将路径拆分为元组,tailos.path.split('/home/user/file.txt') # 输出: ('/home/user', 'file.txt')拆分路径的扩展名,返回元组(ext包含点号)

2026-03-27 11:45:58 512

原创 Java修行实录:阻塞队列(实现生产者-消费者模型)

阻塞队列和普通队列的区别在于:线程安全和队列边界状态的处理上。

2026-03-26 11:54:23 413

原创 Java修行实录:揭秘Java Object类的核心机制

Java泛型信息只存在于编译阶段,Java在编译后会去掉所有的泛型信息,一旦编译成Class字节码,所有泛型标签(<String>,<Integer>)全部被擦除,替换为他们的边界Class对象不携带泛型参数信息1.编译前// 编译前(你写的代码)2.编译后// 编译后(JVM看到的字节码,概念上)public class Example { // <T> 没了!// T 被擦除为 Object。

2026-03-17 12:52:41 396

原创 Java修行实录:多线程与并发编程

flag标志位是线程td2和td3共享的变量,在线程td2启动进入循环后,拿到了flag=true的副本,然后一直死循环,接下来启动td3线程,对变量flag进行修改,但是td2一直拿的是副本的flag,值没有及时更新,要解决共享变量的及时更新问题,就用到volatile修饰变量。Thread.sleep(1000):让主线程阻塞1000ms(1s),在start()后,只是启动子线程,不会阻塞主线程,所以主线程会继续执行后面的代码(printIn),此方法仅适合用于临时调试。

2026-02-04 18:17:11 1027

原创 Java修行实录——哈希表HashMap

/存入新节点size++;if (!hash映射到index时,计算方式为 index = hash & (table.length - 1),效果等同于 hash % table.legnth (只有table.length 是 2的幂情况下)懒加载:首次put时初始化数组,避免无用内存分。

2026-01-18 17:32:53 619

原创 Java修行实录:线性表——链表LinkedList(含头尾指针)

同动态数组,实现接口CList<E>定义CNode结点:data;next;构造函数CLinkedLIst<E>的属性和构造方法包含head 和 rear,对数据进行头部和尾部的添加和删除操作时,需要特殊处理,更新指针head和rear此处的head必须实例化,确保后续操作有一个有效的对象基础构造方法:在属性定义中,head 已经初始化,在CNode<E> 的构造函数中,已经将head.next和head.data初始化为null,所以直接让rear=head即可。

2026-01-06 14:43:39 887

原创 Java修行实录:线性表——动态数组ArrayList

在调用toArray()之前,先创建一个新的数组nv,传入nv和Clone实例的同时,重写clone方法(传入一个数,返回一个相同的大小的数),再用for循环打印出来数组每一个值,实现了arrayList复制到nv中,修改nv的值不会影响原arrayList的值。对于数组中的元素 e ,只需要执行count++计数,不用做移动,指针向后移处理下一个元素,对于其他非e元素,向前移动count值大小的距离,这样只需一轮遍历即可完成删除,时间复杂度为O(n);Object:具体的类,是所有Java类的超类。

2026-01-03 18:21:22 836

原创 Java修行实录:接口、抽象类与类

抽象类用于封装一系列紧密相关的类的共同状态和通用行为,当你需要定义一种本质上的类别,并共享代码和状态时,用抽象类。int age;// 构造方法,子类初始化// 具体方法System.out.println("------用户信息-------");System.out.println("姓名:"+this.name);System.out.println("年龄:"+this.age);// 抽象方法抽象类也可以继承一个类(extends)int age;

2025-12-03 19:43:58 423

原创 Java修行实录:面向对象——封装

封装的作用:把类中的属性和行为都包装在一起,并通过访问控制来保护数据,防止外部直接访问或修改内部状态。

2025-11-25 20:09:41 298

原创 Java修行实录:单例模式和工厂模式

先创建一个 null 实例,null不占用内存,直到外部调用时,才 new 一个实例,延迟加载。,延迟加载,节省资源,线程不安全(多线程加载时,需要加同步),天生线程安全,但是占用资源(即使不使用时),常用于对象创建复杂或需要参数化的场景。

2025-11-24 23:27:02 340

原创 Java修行实录:从数据类型到面向对象编程

本文介绍了变量和数据类型的基本概念。变量是数据的代称,创建时需要指定数据类型并分配内存空间。基本数据类型包括整型、浮点型、字符型和布尔型,而引用类型存储的是数据地址。文章详细说明了Java中整型变量的规范写法,强调使用后缀L来明确长整型。同时解释了String等引用类型的存储机制和指针压缩技术。最后通过People类的示例,展示了对象比较时引用地址和属性值的区别,说明基本数据类型比较值本身,而引用类型比较内存地址。

2025-11-22 18:25:08 412

空空如也

空空如也

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

TA关注的人

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