自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 如何去阅读源码有些建议我想推荐给大家

当我们在读完一个类的代码的时候,一定要总结这个类的职责,明白这个类存在的意义。一般情况下一个类核心职责只有一个,遵循单一职责的设计原则。举个例子,在RocketMQ中有一个类MQClientAPIImpl。

2025-05-26 18:03:05 553

原创 Hutool常用工具类大全:Java开发者的效率神器

Hutool通过简洁的API解决了Java开发中的常见痛点,熟练掌握这些工具类可提升3倍以上的开发效率。

2025-05-26 17:40:39 199

原创 高并发下使用防重表做防重案例

其中表中的id可以用商品表的id,表中的name和model就是商品表的name和model,不过在这张防重表中增加了这两个字段的唯一索引。如果调用了同步添加商品的接口,这里非常关键的一点,是要返回已有数据的id,业务系统做后续操作,要拿这个id操作。如果业务上允许添加一批商品时,发现有重复的,直接抛异常,则可以提示用户:系统检测到重复的商品,请刷新页面重试。说实话,解决重复数据问题的方案挺多的,没有最好的方案,只有最适合业务场景的,最优的方案。之前提供的一个批量复制商品的接口,产生了重复的商品数据。

2025-05-26 17:34:02 177

原创 30个性能优化方案

不知道你在实际的项目开发中,有没有使用过固定值?throw new BusinessException("该用户不存在");其中1000L和该用户不存在是固定值,每次都是一样的。既然是固定值,我们为什么不把它们定义成静态常量呢?这样语义上更直观,方便统一管理和维护,更方便代码复用。...private static final String NOT_FOUND_MESSAGE = "该用户不存在";...使用关键字修饰静态常量,static表示静态的意思,即类变量,而final表示。

2025-05-23 09:43:33 853

原创 讲述 Kafka、RabbitMQ、RocketMQ 和 ActiveMQ 这 4 种消息队列的异同

消息队列是在消息的传输过程中保存消息的容器,用于接收消息并以文件的方式存储,一个消息队列可以被一个也可以被多个消费者消费,包含以下 3 元素:Producer:消息生产者,负责产生和发送消息到 Broker;Broker:消息处理中心,负责消息存储、确认、重试等,一般其中会包含多个 Queue;Consumer:消息消费者,负责从 Broker 中获取消息,并进行相应处理。

2025-05-23 09:15:31 762

原创 使用缓存的10条军规

问题类型推荐方案工具推荐缓存穿透空值缓存+布隆过滤器缓存雪崩随机TTL+熔断降级缓存击穿互斥锁+热点预加载数据一致性延迟双删+最终一致性最后忠告:缓存是把双刃剑,用得好是性能利器,用不好就是定时炸弹。当你准备引入缓存时,先问自己三个问题:真的需要缓存吗?缓存方案是否完整?有没有兜底措施?

2025-05-20 17:20:10 960

原创 记录一次git提交失败解决方案

此操作会触发合并冲突解决流程,需手动处理冲突文件后提交修改。

2025-05-14 22:39:40 264

原创 常用的Java工具库

在这篇文章中,我介绍了 Java 开发中 9 个非常实用的工具类,它们可以帮助我们提高开发效率,减少重复代码,并简化日常的开发任务。从集合操作到字符串处理,从对象操作到反射机制,再到数据加密和 HTTP 状态码处理,这些工具类提供了强大而灵活的功能,让我们能够更加专注于业务逻辑的实现,而不是底层细节的处理。

2025-05-14 17:58:46 910

原创 参数校验6大神功

有时候,Hibernate Validator框架或者其他校验框架定义的校验不满足需求,我们需要自定义校验规则。则可以自定义注解,实现ConstraintValidator接口,来实现具体的自定义的校验逻辑。自定义注解@Contact在字段上使用。String message() default "联系方式格式错误";Class<?Class<?// 校验逻辑实现(不要相信前端的下拉框!@Override六边形战士培养计划可通过动态修改错误信息。

2025-05-14 17:53:34 599

原创 SpringStateMachine

状态模式在生活场景中也是比较常见的。比如我们平时网购的订单状态变化,还有平时坐电梯,电梯状态的变化。在软件开发过程中,对于某一项的操作,可能存在不同的情况。通常处理多情况问题最直接的办法就是使用if...else或者switch...case条件语句进行判断。这种做法对于复杂状态的判断天然存在弊端:判断条件语句过于臃肿,可读性较差,不具备扩展性,维度难度也很大。

2025-05-14 17:34:19 883

原创 分享一个好用的IDEA插件

Smart Input Pro​

2025-05-07 14:26:49 228

原创 在高可用场景中,数据库会做主备,那么当主数据还没来的急同步到备数据库,主数据库挂掉了。这种场景如果是对数据一致性要求比较高的情况下,架构又该如果考虑,业务又该如何补偿呢

4.5 Slave服务器的IO线程获取到Master服务器上IO线程发送的日志内容、日志文件及位置点后,会将binlog日志内容依次写到Slave端自身的Relay Log(即中继日志)文件的最末端,并将新的binlog文件名和位置记录到master-info文件中,以便下一次读取master端新binlog日志时能告诉Master服务器从新binlog日志的指定文件及位置开始读取新的binlog日志内容。当I/O线程请求日志内容时,将此时的binlog名称和当前更新的位置同时传给slave的I/O线程。

2025-05-07 09:30:34 729

原创 mysql的binlog,redolog,undolog的区别

Binlog主要用于复制和数据恢复。Redo Log主要用于确保事务的持久性,特别是在系统崩溃后的恢复。Undo Log主要用于支持事务的原子性和实现MVCC,确保非阻塞的读取操作。每种日志都是为了解决数据库在特定场景下的不同需求而设计的,它们的组合使用保证了MySQL数据库的高可用性和数据一致性。

2025-04-21 14:14:23 266

原创 ReentrantLock

如果state=0即代表锁没有被其他线程占用,则设置当前锁的持有者为当前线程,该操作用CAS完成。如果不存在则直接将锁的所有者设置成当前线程,且更新状态state.= 0则代表锁正在被其他线程占用,执行第三步。如果state = 0即代表锁没有被其他线程占用,执行第二步。如果是0,代表刚好线程释放了锁,此时将锁的持有者设为自己。ReentrantLock有两种模式,一种是公平锁,一种是非公平锁。如果是,则给state + 1,获取锁。如果不是0,则查看线程持有者是不是自己。如果是则更新状态state的值。

2025-03-26 23:32:56 280

转载 数据库 MVCC

(2)事务A执行第一次查询操作,先生成 readView ,我们姑且称之为 readView_1,还未开始查询操作,事务B率先执行了更新操作,将数据进行了修改并提交,事务B结束,此时事务A第一次查询开始,但由于事务A已经生成了 readView_1 ,所以它不会读取到事务B修改过后的数据,读取到的是 readView_1 中事务B修改之前的数据,解决了脏读的问题;四个事务在对数据进行增删改查的时候,数据库就会给这四个事务的隐藏字段 trx_id 以自增的方式赋值,这里 假设分别赋值为 1,2,3,4。

2025-03-25 17:22:52 24

原创 JVM方法逃逸

根据对象逃逸的范围,可以分为方法逃逸和线程逃逸。当对象被方法外部的代码引用,生命周期超出了方法的范围,那么对象就必须分配在堆中,由垃圾收集器管理。比如说创建的对象被返回,那么这个对象就逃逸出当前方法了。再比如说,对象被另外一个线程引用,生命周期超出了当前线程,那么对象就必须分配在堆中,并且线程之间需要同步。对象被另外一个线程引用了,发生了线程逃逸。

2025-03-23 21:55:50 451

原创 InnDB的Buffer Pool

在调优方面,我们可以设置合理的 Buffer Pool 大小(通常为物理内存的 70%),并配置多个 Buffer Pool 实例(通过 innodb_buffer_pool_instances)来提升并发能力。Buffer Pool 是 InnoDB 存储引擎中的一个内存缓冲区,它会将数据以页(page)的单位保存在内存中,当查询请求需要读取数据时,优先从 Buffer Pool 获取数据,避免直接访问磁盘。通常采用改良的 LRU 算法来管理缓存页,也就是将最近最少使用的数据移出缓存,为新数据腾出空间。

2025-03-21 11:57:42 136

原创 跳表skiplist

Redis选择跳表而非B+树,核心原因在于‌内存场景下的性能平衡跳表以低实现复杂度、高效动态操作和内存友好性,完美适配Redis的高并发、高频更新需求‌。B+树的磁盘优化特性(如节点紧凑、减少I/O)在内存场景中无实际收益,反而因复杂逻辑降低性能‌。‌因此,B+树无法替代跳表在Redis ZSet中的作用‌。

2025-03-20 22:20:16 348

原创 Arrays.asList()问题

当你尝试执行这段代码时,会抛出 ‌UnsupportedOperationException‌ 异常。

2025-03-20 13:28:41 208

原创 RocketMq消息队列之保证消息不丢失问题

消息丢失可能存在的阶段有三个:生产阶段、存储阶段、消费阶段。

2025-03-18 22:30:25 313

转载 原子操作增强类LongAddr解析

LongAdder的基本思路就是分散热点,将value值分散到一个Cell数组中,不同线程会命中到数组的不同槽中,各个线程只对自己槽中的那个值进行CAS操作,这样热点就被分散了,冲突的概率就小很多。sum()会将所有Cell数组中的value和base累加作为返回值,核心的思想就是将之前AtomicLong一个value的更新压力分散到多个value中去,从而降级更新热点。base变量:非竞态条件下,直接累加到该变量上,Cell[]数组:竞态条件下,累加个各个线程自己的槽Cell[i]中。

2025-03-18 22:03:26 32

原创 JVM中STW解析

STW是JVM垃圾回收的核心机制,其设计平衡了内存回收的准确性与应用性能。通过选择并发收集器、优化堆参数及安全点策略,可显著降低STW对系统的影响‌。

2025-03-18 21:49:30 340

原创 CAS存在的问题以及解决方案

CAS 存在三个经典问题,ABA 问题、自旋开销大、只能操作一个变量等.ABA 问题指的是,一个值原来是 A,后来被改为 B,再后来又被改回 A,这时 CAS 会误认为这个值没有发生变化。可以使用版本号/时间戳的方式来解决 ABA 问题。比如说,每次变量更新时,不仅更新变量的值,还更新一个版本号。CAS 操作时,不仅比较变量的值,还比较版本号。Java 的 AtomicStampedReference 就增加了版本号,它会同时检查引用值和 stamp 是否都相等。

2025-03-18 21:24:15 201

原创 InnoDB的Buffer Pool

在调优方面,我们可以设置合理的 Buffer Pool 大小(通常为物理内存的 70%),并配置多个 Buffer Pool 实例(通过 innodb_buffer_pool_instances)来提升并发能力。Buffer Pool 是 InnoDB 存储引擎中的一个内存缓冲区,它会将数据以页(page)的单位保存在内存中,当查询请求需要读取数据时,优先从 Buffer Pool 获取数据,避免直接访问磁盘。通常采用改良的 LRU 算法来管理缓存页,也就是将最近最少使用的数据移出缓存,为新数据腾出空间。

2025-03-18 21:17:37 143

原创 transient关键字

transient是控制对象序列化行为的关键工具,适用于敏感数据保护、性能优化及资源管理场景。需注意其与静态变量的兼容性问题,必要时通过自定义序列化逻辑实现灵活控制‌。

2025-03-17 16:19:33 178

原创 volatile关键字

假如有两个线程,线程 1 执行 update 方法将 i 赋值为 100,一般情况下线程 1 会在自己的工作内存中完成赋值操作,但不会及时将新值刷新到主内存中。这个时候线程 2 执行 get 方法,首先会从主内存中读取 i 的值,然后加载到自己的工作内存中,此时读到 i 的值仍然是 50,再将 50 赋值给 j,最后返回 j 的值就是 50 了。原本期望返回 100,结果返回 50,这就是可见性问题,线程 1 对变量 i 进行了修改,线程 2 并没有立即看到 i 的新值。

2025-03-17 15:12:45 705

原创 实现ArrayList线程安全的方法

通俗的讲,CopyOnWrite 就是当我们往一个容器添加元素的时候,不直接往容器中添加,而是先复制出一个新的容器,然后在新的容器里添加元素,添加完之后,再将原容器的引用指向新的容器。多个线程在读的时候,不需要加锁,因为当前容器不会添加任何元素。,它是线程安全的 ArrayList,遵循写时复制的原则,每当对列表进行修改时,都会创建一个新副本,这个新副本会替换旧的列表,而对旧列表的所有读取操作仍然在原有的列表上进行.内部是用过synchronized关键字加锁来实现的,也可以直接使用。

2025-03-16 11:12:30 188

原创 ‌CAP 理论详解

CAP 理论揭示了分布式系统的核心矛盾,指导开发者在设计时根据业务需求(如强一致性 vs 高可用性)进行合理取舍‌12。实际应用中需结合最终一致性、超时重试等机制,在动态环境中平衡 CAP 三要素‌。‌artition Tolerance)三者中,系统最多只能同时满足两项‌12。CAP 理论是分布式系统设计的核心原则,指出在一致性(‌。‌vailability)、分区容错性(‌。‌onsistency)、可用性(‌。

2025-03-15 14:31:11 558

原创 jmap命令详解

jmap(Java Memory Map)是 JDK 自带的工具,用于分析 Java 堆内存的分布和对象信息。以下是jmap。

2025-03-15 14:08:53 701

原创 jstat 命令详解

jstat(JVM Statistics Monitoring Tool)是 JDK 自带的轻量级监控工具,用于实时采集 JVM 内存、GC 事件、类加载等运行状态数据,帮助开发者快速诊断性能瓶颈‌12。值从 70% → 85% → 95% 持续上升,可能存在内存泄漏‌13。显示各内存区域的使用百分比及 GC 事件统计,适合快速查看内存压力。‌:若 Eden 区快速填满(如每秒增加 200MB),可增大。显示各内存区域的具体容量(单位:KB)及使用量。(年轻代大小)降低 GC 频率‌35。

2025-03-15 13:59:35 346

原创 常用JVM调优命令

‌:集成化诊断工具(JDK 7+ 支持),支持查询 JVM 参数、生成堆/线程快照等。‌:列出当前系统中所有 Java 进程的进程 ID 和主类名称。‌:生成 Java 进程的线程快照,用于诊断死锁或线程阻塞问题。‌:实时监控内存、类加载和垃圾回收状态。关键词,查看持有锁的线程堆栈信息。‌:生成堆内存快照和对象分布统计。

2025-03-15 13:22:10 441

原创 场景题 - 现有系统能否扛住压力暴增100倍

优化层面技术方案典型工具/框架流量管控限流熔断、异步队列、服务降级JVM优化堆内存调优、G1/ZGC算法、内存泄漏分析Arthas/JVM参数调优MySQL优化分库分表、索引优化、InnoDB参数调整缓存多级缓存(本地+分布式)通过以上综合优化,系统可逐步实现从单机到分布式、从同步到异步的改造,支撑百万级并发场景‌。

2025-03-15 11:59:01 362

原创 记录工作中优惠券系统设计

优惠券系统设计

2025-03-14 15:03:50 179

原创 并发编程学习大纲

并发编程大纲

2025-03-14 14:00:19 407

原创 JVM学习大纲记录

jvm大纲

2025-03-14 13:54:54 339

原创 项目中常用的SQL优化

这样的语句,普通索引是无法满足查询需求的。如果连接方式是inner join,在没有其他过滤条件的情况下MySQL会自动选择小表作为驱动表,但是left join在驱动表的选择上遵循的是左边驱动右边的原则,即left join左边的表名为驱动表。区分in和exists主要是造成了驱动顺序的改变(这是性能变化的关键),如果是exists,那么以外层表为驱动表,先被访问,如果是IN,那么先执行子查询。优化的方法如下:可以取前一页的最大行数的id,然后根据这个最大的id来限制下一页的起点。type列,连接类型。

2025-03-13 15:57:57 980

原创 网络系统之零拷贝

1.DMA技术。

2025-03-13 15:52:58 783

原创 jvm垃圾回收过程

新生代:主要采用复制算法,回收速度快,频率高,适合生命周期短的对象。老年代:主要采用标记-整理算法,回收速度相对较慢,频率低,适合生命周期长的对象。不同的垃圾回收器(如Serial、Parallel、CMS、G1等)在实现上述算法时会有一些差异,可以根据具体的应用场景选择合适的垃圾回收器。

2025-03-13 15:22:36 303

原创 垃圾回收器种类

此外,还有一些特定于新生代或老年代的收集器,如ParNew(适用于新生代,与Parallel Scavenge类似但实现有所不同,常用于需要CMS配合的场景)、●优点:注重吞吐量(即减少GC总时间),适用于后台处理任务和注重吞吐量的应用‌。○‌特点‌:支持 TB 级内存,STW 时间极短(<10ms),并发处理‌。●使用标记-复制算法(新生代)和标记-整理算法(老年代)‌。○‌适用场景‌:超大内存、超低延迟场景(如金融交易系统)‌。●并行、并发和分布式的垃圾收集器,适用于大型应用程序‌。

2025-03-13 15:02:02 253

原创 垃圾收集器应该如何选择

如果优先考虑应用程序的峰值性能,并且没有时间要求,或者可以接受 1 秒或更长的停顿时间,可以选择 Parallel 收集器。如果应用程序只需要一个很小的内存空间(大约 100 MB),或者对停顿时间没有特殊的要求,可以选择 Serial 收集器。如果响应时间比吞吐量优先级高,或者垃圾收集暂停必须保持在大约 1 秒以内,可以选择 CMS/ G1 收集器。如果响应时间是高优先级的,或者堆空间比较大,可以选择 ZGC 收集器。

2025-03-13 14:52:53 73

空空如也

空空如也

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

TA关注的人

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