自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 高并发下的锁选择:乐观锁 vs 悲观锁全面对比

读取数据 → 修改数据 → 验证版本号 → 如果验证通过则提交,否则重试或失败。假设并发冲突的概率很低,允许多个线程同时访问资源,只在提交时检查是否有冲突。假设并发冲突的概率很高,每次操作前先获取锁,确保独占访问。:Compare-And-Swap,比较并交换。冲突时需要重试,可能产生自旋开销。,后申请的线程可能先获取到锁。性能相对较低(需要维护队列)并发性能高,减少线程阻塞。吞吐量更高,减少线程切换。并发性能较低,线程阻塞。需要强一致性的金融系统。线程按申请顺序获取锁。不会出现线程饥饿现象。

2025-09-08 18:01:44 226

原创 Redis 的分布式锁

在单机应用中,我们可以使用 Java 的或等机制来保证线程安全。但在分布式系统下,应用部署在多台机器上,这些本地锁只能控制单进程内的线程同步,无法跨越多台机器。分布式锁就是一个在所有服务节点之间可见的、统一的“锁”。多个节点通过竞争这个全局锁,来获得对共享资源的独占访问权。Redis 因其高性能和单线程处理命令的特性,非常适合用来实现分布式锁。方面描述解决方案互斥性基本要求,同一时间只有一个客户端持有锁。使用SET ... NX避免死锁持有锁的客户端崩溃后,锁最终能被释放。设置过期时间PX避免误删。

2025-09-08 10:27:40 666

原创 RocketMQ为什么自研Nameserver而不用zookeeper?

特性对 RocketMQ 的适合度一致性模型CP(强一致性)AP(最终一致性)NS 胜出。MQ 路由信息不需要强一致。可用性选举期间不可写永远可写可读NS 胜出。高可用是 MQ 的生命线。架构复杂,有状态,需选举极简,无状态,对等NS 胜出。简单可靠,运维成本极低。性能写操作需同步,延迟较高纯内存操作,延迟极低NS 胜出。更轻量的心跳和注册机制。功能通用分布式协调为 MQ 元数据管理量身定制NS 胜出。没有多余功能,完美匹配。运维专业,复杂简单,轻量NS 胜出。开箱即用,无需额外维护。

2025-09-07 17:42:56 580

原创 消息队列的可靠性、顺序性怎么保证?

特性保证机制关键点可靠性1.持久化(队列+消息)2.确认机制(生产者Confirm + 消费者手动ACK)3.重试与死信队列(有限次重试,失败转移)形成一个从生产到消费的闭环保障,确保消息不丢失。顺序性1.全局有序(单队列单消费者,不推荐)2.局部有序(按Key哈希到同一队列 + 串行消费)通过牺牲一部分并行度(同一个Key的消息串行)来换取顺序性,是分布式系统下的实用设计。

2025-09-07 11:00:35 606

原创 垃圾收集器分类

单线程执行垃圾收集。:多线程并行执行垃圾收集。:执行 GC 时,暂停所有应用线程(Stop-The-World, STW)。:大部分 GC 工作与应用线程并发执行,只在某些阶段需要 STW。:在回收后会对存活对象进行压缩整理,消除内存碎片。:回收后不整理,会产生内存碎片。:将存活对象复制到另一块内存区域,本身也是一种整理。

2025-09-06 19:41:24 822

原创 LRU 算法和 LFU 算法有什么区别?

LRU vs LFU:本质是“时间”与“频率”的权衡。LRU更适合判断“最近谁有用”,LFU更适合判断“谁一直有用”。Redis的实现:两者都使用了lru字段,但用途截然不同。LRU用它存时间戳,LFU用它高存时间戳、低存频率值,并辅以概率递增和时间衰减机制,在有限的空间内巧妙地实现了高效的LFU算法。如何选择:如果你的业务模式是“最新访问的就是最热的”(如新闻feed),用LRU。如果你的业务有稳定的长效热点(如热门商品、明星资讯),用LFU能更好地抵抗扫描式查询带来的缓存污染。

2025-09-06 13:46:51 662

原创 聊聊MySQL事务:从入门到实践,确保数据的安全与一致

事务是数据库管理系统(DBMS)执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成。简单来说,事务就是一组要么全部成功、要么全部失败的SQL语句。尽量保持事务简短: 不要在事务里执行网络调用、RPC、或是复杂的业务逻辑计算,这会让事务长时间持有锁,导致并发性能急剧下降。明确判断并提交/回滚: 在代码中(如Java的JDBC、MyBatis,或PHP、Python等),一定要在逻辑结束时明确调用提交或回滚。理解隔离级别。

2025-09-05 20:39:46 596

原创 Synchronized 的锁升级过程

之后这个线程再次进入同步块时,不需要 CAS(Compare And Swap),直接判断自己是否是持有者即可,非常快。传统的重量级锁(OS 互斥量实现)效率低,频繁加锁解锁会导致性能下降。这时 JVM 会使用 操作系统 的互斥量(mutex),线程会被阻塞,等待操作系统调度。如果成功,表示获得锁;如果失败,说明竞争激烈,会进入重量级锁阶段。当另一个线程也来竞争这把锁时,偏向锁就会升级为轻量级锁。当一个线程第一次获取锁时,JVM 会在对象头中的。,CAS 自旋失败,锁会升级为。)时,锁会升级为重量级锁。

2025-09-05 12:01:41 447

原创 MVCC是如何工作的?

MVCC的中文翻译为多版本并发控制。它是一种数据库管理系统中常用的技术,用于高效地处理高并发场景下的读写操作,在保证数据一致性的同时,大幅提升性能。不为数据行加锁,而是为每个数据修改创建多个版本。特性解释全称多版本并发控制 (Multi-Version Concurrency Control)目的解决高并发下的读写冲突,提升数据库性能,无需加锁读。核心思想为数据保留多个历史版本,每个事务根据自己的“时间点”看到不同的数据快照。关键实现1. 数据行多版本2. 事务ID3. 数据可见性规则。

2025-09-04 18:56:46 649

原创 JVM 类加载过程

被动引用(如通过子类引用父类的静态字段)不会触发加载。文件格式验证、元数据验证、字节码验证、符号引用验证。检查字节码是否符合 JVM 规范(防止恶意代码)可能延迟到首次使用时解析(如动态绑定的方法)。常量(编译期已知)会直接赋实际值(如。首次主动使用类时(如。、访问静态字段/方法、反射等)。(如类名、方法名)转换为。方法(由编译器生成)。

2025-09-03 15:00:34 238

原创 MySQL 的索引分类和它们的应用场景

MySQL 索引可以分为:数据结构(B+Tree、Hash、R-Tree、全文)逻辑功能(普通、唯一、主键、全文)存储方式(聚簇、非聚簇)字段个数(单列、联合)

2025-09-02 19:13:14 548

原创 Redis的删除策略

当 Redis 进行内存淘汰时,会使用。

2025-09-02 10:17:17 676

原创 Redis持久化分为哪两种?

更高的数据安全性(丢数据少,特别是 always 模式),文件可读性强,方便恢复。

2025-09-01 14:27:24 292

原创 Redis的常见数据类型及其底层结构

数据结构特性常用操作典型应用场景String二进制安全,可自增SETGETINCRDECR缓存、计数器、分布式锁Hash适合存储对象,可单独操作字段HSETHGETHGETALL用户信息、商品信息等对象数据List有序、可重复、双向链表LPUSHRPOPLRANGE消息队列、最新列表、日志Set无序、元素唯一、支持集合运算SADDSMEMBERSSINTER标签、共同好友、抽奖Sorted Set有序、元素唯一、按分数排序ZADDZRANGEZREVRANK排行榜、优先级队列、带范围查。

2025-08-30 15:56:03 671

原创 Spring Boot的自动配置流程

简单来说,自动配置就是 Spring Boot 根据你项目中的实际情况(如引入的依赖、已有的配置、定义的 Bean),智能地推断并准备好你所需要的组件和配置。约定大于配置 (Convention Over Configuration)。你只需要告诉 Spring Boot 你想要什么(通过引入依赖),它就会自动帮你做好,而不是像传统 Spring 那样需要你手动配置每一个 Bean。Spring Boot 的自动配置是一个基于约定和条件判断的智能机制。

2025-08-24 11:25:27 909

原创 对Spring Bean 生命周期详解

简单来说,Spring Bean 生命周期就是Bean 从创建到销毁的全过程,由 Spring IoC 容器进行管理。Spring 在不同的阶段会调用特定的方法或接口,让开发者有机会在 Bean 的不同阶段进行自定义操作。Spring Bean 生命周期涉及实例化 → 属性注入 → Aware 接口 → 初始化 → 使用 → 销毁等环节。。可以在初始化前后进行增强,是 AOP 等核心机制的基础。

2025-08-17 19:06:42 847

原创 对Mybatis的Executor执行器种类的个人解读

每次执行 SQL 都会创建新的 PreparedStatement。:两条 INSERT 合并为一次网络请求,性能显著提升。:第二次查询复用预处理对象,减少数据库开销。对应的 PreparedStatement。:优化同SQL重复执行,减少预处理开销。主动使用 BatchExecutor。:两次查询均独立执行,无缓存优化。:默认选择,适合大多数查询场景。:批量操作神器,但需手动提交。)攒成一批,统一提交。,执行完后立即关闭。,其他情况默认即可。

2025-08-10 17:54:27 317

原创 MyBatis Mapper接口工作原理详解

建立方法名(如"selectUsersByCondition")与SQL语句的映射关系。创建MapperMethod对象(包含SQL命令类型、方法签名等信息):根据namespace+方法名查找对应的SQL语句(XML或注解):MyBatis启动时为每个Mapper接口生成动态代理对象。1.通过namespace+方法名定位到XML中的SQL。:MapperProxy的invoke()方法拦截调用。:为什么接口方法能与XML配置对应?:将Java参数转换为SQL参数。:调用接口方法时被代理对象拦截。

2025-08-09 19:34:05 222

原创 揭秘CAS:无锁编程的原子性魔法

CAS就是通过不主动去加锁的方式来确保线程任务被执行时具有原子性。在硬件方面,通过指令来进行操作内存。在java中通过调用类的一系列方法。

2025-07-21 19:25:58 308

原创 线程池的核心配置参数和流程

线程池核心参数及其线程池的执行流程

2025-07-20 12:01:55 804

原创 对于线程池的状态的理解

线程池状态转换及存储机制解析:线程池通过5种状态(Running、Shutdown、Stop、Tidying、Terminated)管理线程生命周期。状态转换通过shutdown()/shutdownNow()触发,前者等待任务完成,后者立即中断。状态存储采用32位AtomicInteger,高3位记录状态(5种状态通过位移运算定义),低29位记录工作线程数。这种设计实现了线程状态和工作数量的高效统一管理,确保线程资源的合理分配和回收。

2025-07-19 11:54:52 230

原创 个人对于Java中线程池的看法

16, 核心线程的数量(保持存活的线程数量)5, 最大线程的数量60, 非核心线程存活时间TimeUnit.SECONDS, 存活时间的单位用于保存等待执行的任务的阻塞队列。

2025-07-14 19:03:31 260

原创 LeetCode 整数拆分

第二种为 j,dp[i-j],dp[i-j]表示,还可以继续进行拆分,继续计算对应的当前值的最大乘积。dp[0]和dp[1]是没有意义的 因为它们拆分出来的乘积 为 0。dp[i]表示,数字 i对应 的拆分的最大乘积。所以 i应该从 2开始进行计算 可拆分的最大值。),并使这些整数的乘积最大化。第一种 为 j 和 i-j。你可以获得的最大乘积。

2025-05-10 18:19:25 142

原创 深入理解 Java 中的 ArrayList

ArrayList 是 Java 集合框架中的一个类,实现了 `List` 接口。它基于动态数组实现,允许存储重复元素,并且元素是有序的(按插入顺序)。ArrayList是 Java 中最常用的集合类之一,它的实现基于动态数组,具有以下特点:随机访问速度快。尾部插入效率高。中间插入/删除效率低。需要额外的空间用于扩容。适合读取多、修改少的场景。不适合频繁插入/删除的场景希望这篇博客对你有所帮助!如果有任何问题或建议,欢迎在评论区留言讨论。

2025-03-01 17:55:06 484

原创 Integer的缓存池

在Integer类中存在着缓存池,而缓存池是什么呢?我们先来看一段代码和他对应的结果为啥会出现这样呢,这就是因为缓存池的存在,接下来我给大家解析一下这个缓存池的存在。

2025-02-08 23:32:40 935

原创 StringBuilder类的数据结构和扩容方式解读

StringBulider的底层同String一样都是一个字符数组,但是不同的是,StringBulider直接继承的,在这个父类中并没有使用final关键字进行定义这个字符数组,即它是一个可变的字符串,可以直接进行修改而不需要重新new一片空间并且指向该空间。那如何进行定义这个可变字符串呢//无参构造//有参构造,直接指定了空间大小。

2025-02-06 22:49:00 842

原创 String类的equals()的作用和源代码解读

equals()方法的由来继承自Object类,默认比较内存地址。重写equals()是为了根据对象的属性值判断相等性。equals()方法的源码解读默认实现包括:检查内存地址、检查null、检查类类型、强制类型转换、比较属性值。

2025-01-20 19:06:05 318 1

原创 String为什么是不可变的?

1.String不可变:任何对String的修改操作都会生成一个新的String对象,而不是修改原有的对象。2.内部数据结构:内部使用final类型的char数组数据结构的特点是不可变、线程安全、缓存哈希值。3.String方法:方法如`contains、`substring`、`charAt`等都会生成新的字符串对象,而不是修改原有的字符串。通过以上代码和解释,可以清楚地理解String的不可变性及其内部实现机制。

2025-01-19 19:31:22 1613 1

空空如也

空空如也

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

TA关注的人

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