2026.3.10
Redis 为什么使用跳表而不是 B+ 树? B+树很耗费空间,而内存的空间是很宝贵的,相比之下跳表这种可控参数更合适 B+树的范围查询,通过跳表也可以实现 B+树在并发编程下的锁粒度更大 B+树比跳表更难维护和利用 Java 的类加载机制 加载 (Loading): 通过全限定名获取二进制字节流,在内存中生成 java.lang.Class 对象。 链接 (Linking): 验证: 确保字节码符合 JVM 规范,没有安全风险。 准备: 为静态变量分配内存并设置初始默认值(如 int 为 0)。注意:此时还没执行赋值动作。 解析: 将符号引用替换为直接引用(内存地址)。 初始化 (Initialization): 执行类构造器 <clinit>() 方法的过程,真正执行静态变量赋值和 static 代码块。 使用 (Using): 程序执行业务逻辑。 卸载 (Unloading):...
2026.3.8
索引的失效情况 sql层面:使用模糊查询、函数、计算、隐式转换、负向查询 系统层面:条件查询大于30%数据量,可能会优化为全表扫描 redis的应用常见 缓存:存ak、存业务数据 限流:滑动窗口(zset)、令牌桶(string) 消息队列(已优化)、分布式锁(Redisson) redis的内存淘汰和过期策略 过期策略:对于设置了过期时间的key进行的过期淘汰策略 惰性删除:key每次被访问都要先查看剩余时间,过期才删除 定时删除:按照频率依次检测剩余key的过期时间,淘汰过期key 内存淘汰:当内存不足时针对剩余key采取的策略 1. 不淘汰任何key,拒绝本次插入 2. 局部淘汰(针对设置了过期时间的key): 1. lru:淘汰使用次数最少的key 2. ttl:淘汰剩余过期时间最短的key 3. random:随机淘汰 3. 全局淘汰(针对所有key): 1. lru:淘汰使用次数最少的key 2. random:随机淘汰 jvm了解哪些参数,怎么设置? 分为标准参数、非标准参数、稳定参数。 一、内存配置 堆内存核心参数(-X...
2026.3.4
接口和抽象类的区别 接口是对行为的抽象,抽象类是对本质的抽象。一个类具有多种功能,可以实现多个方法,但它只能是“它”,只能继承一个类。使用习惯上,我们一般利用类实现代码的复用,利用接口实现代码的规范与解耦。 接口中的default 和 static方法有什么区别 default方法表示这是它的默认实现,如果你不重写这个方法,被调用时就按照默认的走;static表示这个方法归接口所有,你不需要实现。 final关键字的作用 final关键字可以修饰类(但不能修饰抽象类)、方法、变量。 如果修饰类,表示这个类无法继承。如果修饰方法,表示这个方法无法重写。修饰变量,表示这是一个常量。 不能修饰抽象类:抽象类是为了被继承,但是final会阻止他被继承 如何创建一个不可变对象 类声明为 final(不可继承); 所有成员变量声明为 private final; 不提供修改变量的 setter 方法; 通过构造器初始化时,如果是引用类型,要进行深拷贝(Deep...
2026.2.24
AQS队列 state关键字是类的volatile全局变量,0为无锁,1为占有,>1为重入次数。 “非公平锁”的实现并不依赖唤醒所有节点,永远只唤醒下一个节点。它的原理是新线程加入时不需要判断AQS队列情况,可以直接参与锁的竞争。 MySQL的索引 Hash表与B+树对比:Hash表的单点查询效率更高,但是面对频繁的范围查找时B+树的性能更突出,因为B+树天生支持范围查找,而Hash却只能全表扫描。 看门狗 锁未指定过期时间时(但是Rediison有一个默认过期时间),Redisson在后台开启一个定时任务,每隔一段时间向Redis发送一个Lua脚本为锁续期。 当线程宕机时这个定时任务不复存在,锁就会超时过期。
2026.2.14
LeetCode 138 随机数组的复制 给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。 构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random 指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点 。 例如,如果原链表中有 X 和 Y 两个节点,其中 X.random --> Y 。那么在复制链表中对应的两个节点 x 和 y ,同样有 x.random --> y 。 返回复制链表的头节点。 用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, random_index] 表示: val:一个表示 Node.val 的整数。 random_index:随机指针指向的节点索引(范围从 0 到 n-1);如果不指向任何节点,则为 null 。 你的代码 只 接受原链表的头节点 head...
消息队列小专题
今天详细学习了一下消息队列的幂等性与重复消费问题,其实是在AI的模拟面试的时候被狠狠diss了 😥 😥 我在实习的时候,这一条链路的业务大致是这样的,我们拿到模型实例返回的计费数据和日志数据,我们要把他们持久化进Mongo中,持久化操作肯定还是异步比较舒服,而且我们肯定不能在本地直接开启那么多线程直接去异步调用Mongo,这样性能会被浪费,我实习的项目选择的是kafka进行业务解耦,通过consumer去调用Mongo,我们本地只需要发消息就行了。 那么使用消息队列就必须面对几个经典问题,如何保证消息不丢失,如何解决幂等性问题,怎样监控消息堆积量(吓哭了 😰 😰 我们先简单了解一下消息队列的组成和原理(以kafka为例): 要理解 Kafka,必须先掌握这几个核心概念: Producer (生产者): 往记事本上写数据的人(比如你的 MaaS 计费服务)。 Consumer (消费者): 从记事本上读数据的人(比如你的 MongoDB 写入服务)。 Broker (代理/服务器): 存放记事本的服务器节点。 Topic (主题):...
CI/CD
主播最近也是get到一个新的爱好就是健身,可能最近会专门开一篇健身专题吧hahahh 😚 😚 博客荒废了好久,主要是主播实习结束完后给自己放了一个月的假,最近要收收心自律起来了...
m1kasaz的Netty笔记
BIO模型和NIO模型 两个模型都是很常见的Java网络模型 BIO模型:同步阻塞模型,一个线程专门负责一个连接,数据以流的形式传输 NIO模型:同步非阻塞模型,一个线程负责多个连接,其功能被多个组件分摊,Channel为双方提供双向的通信通道,读写数据都要通过Buffer,Selector可以实现高效的多路复用器 两个模型就好比不同餐厅的招待方式,BIO的餐厅就像一位服务员专门负责一桌客人,而且会一直等待客人的命令;NIO餐厅则是一位服务员负责多桌客人,而且只要你不点餐(数据没准备好),我就不会在你的桌前停留 BIO策略只适合连接数量不多,且连接时间较长的情况,过多的连接将导致线程数量过多导致OOM NIO策略下,一个线程被赋予处理多个请求的能力,并发量大大提高 NIO性能很高,为什么我们不直接使用它呢? 答:开发效率不高,使用NIO直接进行开发,开发者需要应付这些问题: Selector 的复杂性:Selector 是 NIO 的核心,但其使用方式反直觉。你需要在一个循环中轮询(select())事件,然后遍历 selected keys,并针对每个 key...
EXPLAIN关键字
前言 距离上次更新过去了差不多一个月,主要一直在忙八股和项目,然后就是投简历改简历,我觉得这是一个瓶颈期,因为一直没有正反馈,迷茫、焦虑,尤其是面对这样的环境,我希望好好沉下心,打好基础,没有机会就先沉淀,不知道过些日子,再回头看看自己写下的这段话,会有什么感想。 欲渡黄河冰塞川,将登太行雪满山:李白在《行路难·其一》中用此句,以渡河被冰堵塞、登山被雪阻挡,象征人生道路上仕途受阻,充满艰难险阻。 EXPLAIN Q:我们为什么要使用explain? A:帮助我们分析sql语句的执行过程 我们想要知道一条sql语句的执行时间可以这样操作: 1234567891011121314-- 1. 首先检查 profiling 功能是否开启,默认可能是关闭的SELECT @@profiling;-- 2. 如果为 0,则开启它SET profiling = 1;-- 3. 执行你的 SQL 语句SELECT * FROM your_table WHERE ...;-- 4. 查看所有已记录查询的列表及其总耗时SHOW PROFILES;-- 5. 查看上面列表中某个特定查询(比如...
MySQL索引优化
前言 我们知道MySQL的数据都存储在磁盘中,在执行SQL语句时需要对进行大量磁盘IO,这使得磁盘性能可能成为性能的瓶颈,这是我们不希望出现,或者说希望优化的。 索引基础知识 什么是索引 索引其实在我们的生活中普遍存在,比如查字典,我们知道先从目录开始查而不是去一页一页的找,字典里的目录就是索引的一种实现。 索引是数据库中有序存储特定列值的数据结构(如B+树、哈希表),通过缩小扫描范围实现高效查询。 索引有什么用 根据索引的本质其实也不难理解,使用索引在大部分情况下都能提高数据库的性能,包括但不限于提高查询速度,减少磁盘IO,减少分组和排序时间等等。为啥用索引就能"快"?...








