自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 年度总结和寒假总结

寒假主要是刷面试题,力扣刷题。简历项目优化。开始准备面试相关,大多数都是本学期末看过的,重新复习一遍,通过看《并发编程的艺术》回顾了Java并发的相关知识,理解AQS原理并阅读了底层源码,上手实践了常用的并发包下的工具类,看了ThreadLocal相关源码,知道其如何实现线程私有。明白了锁分类以及Synchronized的锁升级机制。我通过看《Mysql实战45讲》巩固了mysql的知识,也接触到了之前遗漏的mysql的主从集群方面的知识;

2025-01-25 06:01:40 522

原创 类加载子系统

什么情况下需要自定义类加载器1.隔离加载类2.修改类加载的方式3.扩展加载源4.字节码加密,在类初始化时用自定义类加载器解密自定义类加载器实现步骤1.继承ClassLoader类、2.重写fineClass()方法而不是loadClass方法或者直接继承URLClassLoader类,不需要重写findclass方法,也不用编写获取字节码二进制流的方法。

2024-12-03 21:27:34 767

原创 MYSQL查询结果如何发送给客户端

如果客户端接收数据太慢,就会导致数据在socket send buffer 堆积,导致发送数据到客户端的线程进入等待,由于net_buffer数据没有发送出去,net_buffer一直没法清空,查询语句就要等待net_buffer清空才能继续执行,导致服务端查询速度变慢。2.如果链表空间满了,此时有个新的数据页要加进来,和普通LRU算法一样首先把链表尾部的数据页淘汰,不过这个新的数据页不是放在链表头部,而是放在old区的第一个位置。1.如果young的数据页被访问到了,和普通LRU算法一样,移到链表头部。

2024-11-14 22:12:12 609

原创 《MYSQL45讲》kill不掉的线程

kill query + 线程id :终止这个线程正在执行的语句kill connection + 线程id :关闭这个线程的连接,也会先停止这个线程正在执行的语句。这个connection可以缺省。本文讨论的情况是:使用了kill命令,却没有断开连接,show processlist命令执行结果中,被kill的线程显示killed,这个killed是什么意思?以及一些常见的命令误解。

2024-11-13 22:23:36 774

原创 《MYSQL45讲》误删数据怎么办

对误删数据分类的话,有1.delete 误删行2.drop table 或者truncate table 语句误删表3.使用drop database 误删数据库4.使用rm命令误删整个MYSQL实例。

2024-11-13 22:23:01 1226

原创 1111fxh,MYSQL加锁规则

事务A执行select * from t where id =7 lock in share mode,因为是在聚簇索引上,所以会直接定位到id=7的可能的位置,即使id=7这个行不存在,然后对id=7所在的区间加上next-key lock,也就是锁住(5,10] ,由于条件列是唯一索引,next-key lock退化成了间隙锁(5,10)。这条语句首先会用等值判断找到id=10 的记录,加上next-key lock (5,10],由于是唯一索引上的等值判断,所以退化成行锁id=10。

2024-11-11 18:49:44 1011

原创 MySQL是怎么保证高可用的?

因为statement或者mixup记录的是sql语句,如果执行一条insert语句,通常是不会填写主键的,这样就会导致本来应该在主库和备库的同一条数据,变成了主键id不同的两条数据。首先要等到seconds_behind_master值小于一个值时(如5s)把A设置成readonly,再等到seconds_behind_master=0时也就是主备数据一致时再把B的readonly设置成false,然后让请求都发到B上面。如果是可靠性为首要的,也就是数据不能丢失,不能数据不一致,那么就会印象可用性。

2024-11-06 22:19:22 558

原创 MYSQL备库的并行复制

备库在消费中转日志时,其实可以分多个线程同时对多个事务进行消费,但是要满足2个基本原则:1.涉及同一行数据的多个事务必须在同一个线程中执行,否则会导致数据不一致2.同一个事务不能被拆开。

2024-11-06 22:18:45 545

原创 力扣-最大子数组和

求的是连续子数组的最大和,就设f(i)为以i下标结尾的元素的连续子数组的最大和,f(i)只有2种情况,要么是nums[i]这一个数作为一段,要么就是f(i-1)+nums[i],因为要以i下标对应的元素结尾,所以比较得出较大值即可。初始化就是f(0) =nums[0],因为连续子数组至少包含一个元素。给定一个int数组,求出连续子数组的最大和。

2024-10-29 22:45:46 104

原创 力扣-最小覆盖子串

可以定义一个distance这样的int变量,当移动右指针后,如果此时右指针指向的字符在当前窗口中的个数严格小于t中所需要的个数,那么distance++。滑动窗口,初始时左右指针都指向s的第一个字符,对于每个遍历到的窗口,判断当前窗口是否包含了t中所需要的所有字符,不是的话就移动右指针,是的话就移动左指针。在移动左指针前,如果此时左指针指向的字符在当前窗口中的个数等于t中所需要的个数,那么distance--。给定一个字符串s,和目标字符串t,需要找出s中包含t中所有字符且长度最小子串,输出这个子串。

2024-10-29 22:44:45 337

原创 扫盲(索引存储)

说的都是Innodb引擎。

2024-10-28 21:34:54 623

原创 《MYSQL 实战45讲》 慢查询产生的原因

语句就被阻塞住了,因为它想关闭表,但是事务A的查询语句还没执行完,最后事务C中的 select * from t_19 where id=1;而第一个查询是快照读,而事务B的插入语句的结果对于事务A是不应该可见的(事务B未提交并且事务B在事务A开始后才开始),并且这个语句执行了太多次,每次都生成一个undolog条目,所以对于事务A来说,要一直根据undo log得到他能看到的数据版本,要不断回滚,这就导致了查询时间过长。这条查询语句时,一直不返回,检测processlist发现在等待flush。

2024-10-28 21:34:25 716

原创 《MYSQL实战45讲》为什么使用聚合函数会导致索引失效

这是因为trade_detail表的字符编码是utf8,而trade_log的字符编码是utf8mb4,驱动表是trade_log,trade_detail则是被驱动表,需要将trade_detail表的tradeid字段转码成utfmb4再比较,这样就相当于对于每个tradeid都需要先进行一次转码(使用了函数),这样破坏了索引树的有序性,所以优化器放弃使用索引树搜索,而走了全表。所以只需要扫描1+4=5行。第一行的执行计划是在tradelog表中找到id为2的记录,因为有主键索引,所以只需要扫描1行。

2024-10-27 19:17:14 1140

原创 《MYSQL 实战45讲》深入浅出ORDER BY底层

ORDER BY到底使用的是磁盘还是内存?使用的是快排还是归并还是优先队列?全表排序和rowid排序优化器是怎么选择的?

2024-10-27 19:15:39 1050

原创 《MYSQL 实战45讲》order by工作原理 10/27

MYSQL为每个线程设置了一块内存专门用来进行排序--sort buffer进行order by时就是首先根据查询条件(where)得出所有满足条件的记录,然后取出需要的值(select关键字后面的字段)到sort buffer,然后进行快排。一条查询排序语句select city,name,age from t where city='杭州' order by name limit 1000;city字段上有普通索引。

2024-10-27 19:12:20 874

原创 《MYSQL实战45讲》表数据删一半,为什么表文件大小不变?

注意到这里和MYsql5.5之前有个不同的点是,之前的B是创建的表,是在server创建的,而这里是创建的临时文件,是在innodb内部创建的。因为Online DDl依赖于inplace算法,在重建表时,如果是使用的COPY模式,那就会创建新的表来作为临时中间表,这会阻塞增删改查,而inplace可以不创建新的表,仅仅是创建临时文件。在数据页内的数据很紧凑的情况下(不是100,200,300而是1,2,3,4,5这种)首先创建一个临时表B,再将A中的数据一条一条按照顺序读写到表B中。

2024-10-24 20:19:04 763 1

原创 《MYSQL实战45讲》将脏页刷进磁盘时导致的性能抖动

当把一个脏页要刷进磁盘时,会判断这个脏页的邻居是否也是脏页,是的话也会一起刷盘,并且是连锁反应,这个邻居的邻居如果也是脏页,那么也会带着一起刷盘。当修改数据时,如果数据在内存中,就会直接在内存中修改,并且将操作记录在redolog中,这时就可以直接返回了。如果这样的话,每次读取数据到内存中时,都要判断这个磁盘中的文件是不是脏页,即redolog中有没有对应的操作。2.当内存空间不足,触发了缓存淘汰机制,而被淘汰的刚好是脏页,就必须先把脏页数据对应的redolog写入磁盘。1.当redolog 空间不足时,

2024-10-24 20:18:10 553

原创 《MYSQL实战45讲 》 怎么给字符串加索引

前缀索引还有一个缺点,就是索引树上存的是前缀而不是完整值,所有如果要查这个索引字段就必须回一次主键索引表,并且不管你的前缀是否覆盖了完整的值,都要回表,因为系统不知道你这个前缀是否覆盖了完整的值,所以必须回到主表再查一下。但是更重要的是要取区分度高的前缀,如果选了区分度低的前缀,这个索引的用处就不大了,比如说一个地区的身份证前6位是固定的,如果你的表里值负责一个地区的身份证,你选取前6位作为前缀索引的话,还是该扫描多少行就扫描多少行。索引使用流程,假设现在有字段email,对email建立索引。

2024-10-21 21:11:52 498

原创 《MYSQL实战45讲 》 优化器如何选择索引?

索引的基数也叫区分度,就是这个索引所在的字段上不同的值又多少个。mysql是通过采样统计的方法估算出各个索引的基数的,也就是抽查20个数据页,然后统计这些页面上该索引所在字段的不同值的个数,计算出平均值,然后乘以这个索引的页面数,就得到索引的基数。看起来选择a索引的话性能会更好,但是实际上优化器使用了b索引,错选的原因是优化器看到了后面的order by b 如果用b索引的话就避免排序了,因为索引的b+树节点本身就是有序的,如果先选择b索引来查,查出来的数据就是有序的,避免排序了。

2024-10-21 21:11:15 420

原创 短链接监控

【代码】短链接监控。

2024-10-18 15:17:54 155

原创 Mapstruct用法(代码示例)

return new BaseResult<>(200,"添加章节成功");//将chapter插入后的id赋值给taskpoint。

2024-10-16 19:54:56 192

原创 11. 盛最多水的容器 - 力扣(LeetCode)

双指针表示的是可以作为容器的两端的范围,也就是说,包括双指针在内的区域才能作为双指针,一开始双指针在最左端和最右端,因为还没做任何尝试,所以所有边都可以作为容器2端,然后初始时的双指针指向端的一边的那个双指针向另一个双指针移动,为什么移动短的那个,前面也说过了。这时,被移动的那个指针的移动前的位置再也不可能作为边界了,因为它再作为边界,对于移动前来说,它指向的是较短的那个长度,所以另外一个指针不管指向哪个线,min(h[i],h[j])都只会变小或者不变,不可能会变大。

2024-10-16 19:53:34 447

原创 NIO学习笔记

3.开启while循环,调用source文件的通道的read方法,将source文件读取到缓冲区,缓冲区调用flip方法翻转,然后调用destination文件的通道的write方法将缓冲区写入destination文件中去,再调用一次缓冲区的clear方法重置缓冲区的四个变量以及内容。缓冲区,NIO对数据的操作是利用Channel和基于Buffer进行的,Buffer是一个抽象类,用得比较多的实现类是ByteBuffer,缓冲区的2个重要操作是put和get。NIO是双全工,非阻塞的。

2024-10-14 20:51:08 1224

原创 Stream流 学习笔记

为了提高程序员对数组和集合的操作便利性而推出的操作--Stream流。

2024-10-14 20:50:29 623

原创 学习计划(大三上)

深入学习RocketMQ底层(博客)总结Java并发编程的艺术。学习JVM(博客文章)学习JVM(博客文章)图解TCP/IP 4章。学习JVM(博客文章)图解TCP/IP 4章。复习mysql45讲。复习mysql45讲。

2024-09-08 22:00:45 315

原创 在IntelliJ IDEA中,快速找到控制类(Controller类)中所有的方法,可以通过以下几种方式实现:

在IntelliJ IDEA中,快速找到控制类(Controller类)中所有的方法,可以通过以下几种方式实现:

2024-08-07 19:26:01 1267

原创 spring源码 循环依赖

实例化后存到三级缓存中,进行属性注入,B里面只有A类型的a这一个属性,依次查询一二三级缓存,然后在第三级缓存中查询到A,得到A的工厂,调用getObject()方法得到只进行了实例化的a,将a赋值给B,再进行初始化,此时B已经创建完成,将B赋值给A的b属性,A进行初始化,此时A也创建完成。A有属性b,B有属性a,创建A时对b属性赋值需要有b对象,如果没有b就创建,但是创建B又需要对属性a赋值,这样就构成了循环依赖。A中只有B类型的b这一个属性,和创建A时一样,还是。

2024-07-30 21:25:40 1316 2

原创 spring源码 bean的生命周期

初始化:先对自定义属性赋值(populateBean方法内用set方法进行赋值),再对容器对象属性赋值(检测aware相关接口并设置依赖),这里aware的作用是提供一个统一判断的标记:即没实现aware接口的对象就是属性都是自己定义的,实现了aware接口的属性值是容器对象,需要调用容器的getset方法来设置属性(invokeAwareMethods里面做统一判断)。如果不设计这样一个aware接口,就需要在每个属性被赋值时都判断一下 当前属性是否是容器对象。

2024-07-30 21:22:11 1105

原创 java集合

Map接口和Collection接口并列,Collection接口是单列,而Map接口是双列,用于保存具有映射关系的数据:Key - Value;Key 和 Value 可以是任何引用类型的数据Key不可以重复,Value可以重复Map 的 Key 可以为 null,value 也可以为 null,但 key 为 null 只能有一个;Key 和 Value 之间存在单向一对一关系,即通过指定的 Key 总能找到对应的 Value但不能直接通过Value找到Key。

2024-04-03 17:26:22 910

原创 《高性能MYSQL》-- 查询性能优化

查询性能优化深刻地理解MySQL如何真正地执行查询,并明白高效和低效的原因何在。

2024-03-05 10:27:03 1223

原创 《高性能MYSQL》--高性能的索引策略,总结索引类型

在多列上独立地创建多个单列索引,这种做法不太好,触发你许多查询都是基于单个列进行的,否则在创建了多列索引的情况下进行以多个列作为条件的查询时,mysql会进行索引合并,查询能够同时使用两个单列索引进行扫 描,并将结果进行合并。有一种特殊情况,如果前面的列为常量的时候,ORDER BY子句中的列也可以不满足索引 的最左前缀的要求。在列储存的值长度过长,可以选择固定长度的前缀来作为前缀索引,这样能提高系统的性能,需要注意的是前缀索引的选择性要与原来的大致相等。7. 二级索引访问需要两次索引查找,而不是一次。

2024-03-05 10:26:21 1053

原创 《高性能MYSQL》——选择优化的数据结构

VARCHAR用于存长度可变的字符串(比固定长度的类型更加省空间),它除了存这个字符串以外还会使用1个字节或者2个字节去存这个字符串的长度(如果列的最大长度小于或等于 255字节,则只使用1字节表示,否则使用2字节),并且VARCHAR类型不会把数据后面跟的空格删除。更小的数据类型通常更快,因为它们占用的磁盘、内存和CPU缓存的空间更少,并且处理时需要的CPU周 期也更少。如果索引有多个列,就会按照列的顺序进行排序,对于2行数据,如果在索引中的第一个列这2行数据相对,就开始比较第二列,,,依次进行下去。

2024-03-03 16:41:06 1137

原创 《高性能MYSQL》-架构,锁,事务

之所以出现快照读的情况,是基于提高并发性能的考虑,快照读的实现是基于多版本并发控制,即 MVCC ,可以认为 MVCC 是行锁的一个变种,但它在很多情况下,避免了加锁操作,降低了开销;Read View是在进行快照读(即不加锁的select)时生成的,可以简单理解为含有3个用来判断应该读取该行数据的哪个版本的指标,根据这三个指标来判断应该使用哪个版本。第二层,包含了mysql大部分的核心功能,查询解析,分析,优化,以及所有的内置函数(例如,日期,时间函数),还有存储过程,触发器,视图等都是在这一次实现的。

2024-03-03 16:40:03 1507

原创 Redis原理篇(List底层结构与源码详解)

当redis客户端与服务端连接成功后,客户端就会被封装成一个client对象,里面包含了用户对redis的命令。比如说" LPUSH key k1 k2" 就是客户端的一个命令,redis会把 LPUSH ,key,k1,k2放在一个argv[]数组里面。argv[0] 是LPUSH,argv[1] 是key ,argv[2]是k1,argv[3]是k2返回的是robj (即RedisObject)再来看下面这串代码,表示前面的lookupkeyWrite()返回值是null,就是该key没有对应一个

2024-01-21 11:28:21 661

原创 Redis原理篇(String)

String 有三种编码方式 type是类型,表示该类型是String类型encoding是编码方式,表示当前是String的RAW编码方式ptr指针指向一个SDS(动态字符串)对象当要存的字符串长度小于44个字节时,String的编码方式会转变成EMBSTR编码此时RedisObject的头部分与SDS会是一段连续的内存空间因为当字符串长度小于44字节时,ReidsObject的大小小于64字节,而内存分片函数每次分片的内存空间都是2的n次方,64就刚刚好,不会产生内存碎片。当存储的字节是整数值,并且在最

2024-01-21 09:58:28 658

原创 Redis原理篇(RedisObject)

2024-01-21 09:33:06 494

原创 Redis原理篇(SkipList)

本质是双端链表,只不过在正向遍历时可以不一个一个遍历,而是可以跳着遍历。怎么实现的呢,下面是SkipList源码意义:跳表zskiplist里面有头指针和尾指针,节点数量,最大索引层级意义:跳表的每个节点zskiplistNode 里面有ele(节点存储的值,sds是动态字符串类型)每个节点有个score权值,用来排序和查找,查找的时候将要查找的值先用与生成score一样的算法生成待查的score值,然后再根据每个节点的score值来查找该值指向前一个节点的指针,注意,在倒序遍历时不能跳表zskiplist

2024-01-20 22:23:03 638

原创 Redis原理篇(QuickList)

QuickList的出现是为了解决ZipList所存在的一些问题。

2024-01-20 19:22:35 499

原创 Redis原理篇(ZipList压缩列表)

ZipList是一种特殊的“双向链表”,但其实并不是链表,而是一段连续的内存空间,可以在任意一端进行压入/弹出操作。并且该操作的时间复杂度是O(1)结构如下图:现在对每一个部分进行解释:zlbytes:存该压缩列表的总字节数,byte即字节zltail:存最后一个节点到压缩列表的其实地址之间的字节数zllen:存的是总entry的个数entry:即节点zlend:压缩列表的结束标志,并且值是固定的:0xff这里补充一点进制基础:(1) 0x表示这是16进制数;

2024-01-20 16:33:03 1984

原创 Redis原理篇(Dict的收缩扩容机制和渐进式rehash)

Redis是一种键值型数据库,其中键与值的映射关系就是Dict实现的。Dict通过三部分组成:哈希表(DictHashTable),哈希节点(DictEntry),字典(Dict)其中哈希表的底层是数组(发生冲突时扩展成链表),用来存放哈希节点。下面是哈希表和哈希节点的源码dictEntry **table是哈希表的数组,每个元素都是一个指向dictEntry结构体的指针。这里使用双指针**的原因是为了实现动态数组。size是哈希表的大小。

2024-01-08 21:56:19 1506

空空如也

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

TA关注的人

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