- 博客(53)
- 收藏
- 关注
原创 LinkedList添加和删除方法的源码分析超详细
下面我们看第二次添加的过程 ,最终还是执行linkLast方法,只不过此时的last指向第一个节点,所以l也指向第一个节点,然后创建一个新节点将l传入,所以新节点中的prev指向第一个节点,接着将last的指向改为新节点。由于此时的l不为null,所以进入else,将首节点中的next执向新节点。这是add方法真正的底层逻辑,首先将last值赋给l节点,此时的l为null,然后再创建新节点的时候将l作为前向指针传入,将节点中的next指针也赋值为null,之后让last节点指向新节点。
2024-08-24 18:42:18
316
原创 Vector底层扩容机制超详细
先说结论如果我们使用无参构造器,则初始化容量为10,注意这里要和 ArrayList区分开来,ArrayList是初始化容量为0,第一次添加的时候扩容为10并且每次添加元素的时候都会进行是否需要扩容的判断。容量满之后按照2倍进行扩容,如果在创建时指定了容量大小则扩容时直接按照2倍。这是一个三元运算符,前面我们看到capacityIncrement被赋值为0,所以这里返回oldCapacity,所以新数组的容量为原来的2倍。add方法中的逻辑和ArrayList中的差不多。这里将我们的容量初始化为10。
2024-08-24 12:09:07
256
原创 ArrayList底层扩容机制详解保姆级
当我们new之后elementData是空的 ,只有执行add方法后才会初始化容量,在add方法中会判断时候需要扩容,这个判断是每次执行add方法时都要判断的,由此我们可以看出ArrayList 的效率并不高。我们对下面代码进行debug,当我们使用无参构造器时,也就是没用指定ArrayList的容量的时候他他是空的,当我们第一次添加的时候才会扩容为10,当容量满之后每次会以1.5倍进行扩容。modCount是用来记录集合被修改的次数,为了防止多个线程同时操作同一个集合。
2024-08-23 18:59:27
210
原创 什么是逃逸分析
在java虚拟机中,对象是在java堆中分配内存的,这是一个普遍的常识。但是,有一种特殊情况,那就是如果经过逃逸分析(escape analysis)后发现,一个对象并没有,逃逸出方法的话,那么就可能被优化成栈上分配。这样就无需在堆上分配内存,也无须进行垃圾回收了。这也是最常见的堆外存储技术。这段蓝色的代码中将创建的 sb 引用作为返回值返回,那么其它线程就有可能拿到这个变量,因为堆是所有线程共享的这就叫发生了逃逸。
2024-08-20 18:12:27
670
原创 有关对象实例化过程
2.1 如果堆空间是规整的就采用指针碰撞的方式分配,指针的一边是使用过的内存,指针的另一边是空闲的空间,如果分配内存就将指针往空闲的那个方向移动。2.2 如果堆空间是不规则的会采用空闲列表法分配,虚拟机会维护一个列表记载了哪些内存是空闲的,分配时从列表中找一个充足的空间存放对象。1.判断对象的对应的类是否加载,如果未加载则在双亲委派模式的机制下进行加载,如果找到则生成对应的class对象否则报错。4 初始化分配到的空间,给对象中的属性进行默认初始化。3 处理安全并发问题。5 设置对象的对象头。
2024-08-20 17:46:25
520
原创 jvm运行时数据区一(结合尚硅谷课程总结超详细)
即只有当前正在执行的方法的栈(栈顶栈帧)是有效的,这个栈帧被称为当前栈帧(currentframe),与当前栈帧相对应的方法就是当前方法 (currentmethod),定义这个方法的类就是当前类( 类(current class)执行引擎运行的所有字节码指令只针对当前栈帧进行操作。如果当前方法调用了其他方法,方法返回之际,当前栈帧会传回此方法的执行结果给前一个栈帧,接着,虚拟机会丢弃当前栈帧,使得前一个栈帧重新成为当前栈帧。每个线程都有自己的栈,栈中的数据都是以栈帧(stack frame)的格式存在。
2024-08-11 23:53:30
183
原创 MySQL主从复制保姆级教程(学习笔记)
主库出现问题,可以切换到从库提供服务实现读写分离,降低主库的房屋内压力可以再从库中执行备份,避免备份期间影响主库服务。
2024-08-07 11:17:32
247
原创 MySQL中的日志
错误日志是MySQL中最重要的日志之一默认是开启的,它记录了MySQL启动和停止时,以及入伍再运行过程中发发生任何严重错误时的相关信息,当数据库出现任何故障无法正常运行时可以查看此日志。作用:灾难时的数据恢复、MySQL的主从复制、在MySQL8中默认二进制日志是开启的。二进制日志记录了所有的DDL语句和DML语句除(select,show)。默认是关闭的,需要修改/etc/my.cnf文件。
2024-08-07 11:09:28
269
原创 Redisson看门狗机制和mulitLock原理保姆级别
创建了一个ExpirationEntry对象,并放入hashmap中,key为他的名字,vale为他自己,只有当这个entry实体不存才的时候才会放入map中,这样保证了每次放入的都是新的entry实体然后将它加入线程中,如果它是第一次创建则会执行renewExpiration完成续约。首先获取entry名字和线程id。最后的if逻辑是为了保证所有锁的过期时间是一致的,过期时间是从获取锁成功后就开始减少,防止第一把锁的过期时间短而最后一把锁的过期时间长,最后返回true直到所有锁被成功获取。
2024-08-06 19:19:53
1466
原创 Redisson中重试机制源码保姆级别(基于黑马视频)
先将等待时间换为毫秒,获取当前时间,获取当前线程id,然后开始尝试获取锁,如果获取失败会返回空,获取成功会返回剩余有效期System.currentTimeMillis() - current计算获取锁所消耗的时间。来等待订阅的获取结果,如果失败的话会被异常捕获,经过一些操作最终返回false,获取成功后又会计算剩余等待时间。如果还剩余则进入while循环尝试再次获取锁,后续又会进入if判断等待消息订阅结果,然后计算剩余等待时间如果充足则继续循环,否则返回false退出。
2024-08-06 19:03:41
234
原创 Redisson可重入锁原理(基于黑马视频总结,保姆级)
上一篇文章我们基于redis的set nx ex 命令以及Lua脚本实现了基本的分布式锁,但是还存在一下几点问题。于是又引出了redisson。
2024-08-06 18:59:03
446
原创 集群下的线程并发安全问题(秒杀下单业务)
当jvm进行垃圾回收时,如果线程一此时刚好判断完成准备释放,那么会阻塞线程从而使锁超时释放,当线程二去获取锁使会成功,当阻塞结束,线程一会执行释放锁,由于判断已经完成,所以会将线程二的锁删除。线程一获取锁成功,但是由于业务阻塞导致锁超时释放,此时线程二来获取锁可以成功获取,当线程二开始执行时线程一正好完成业务了,此时它会释放锁,这时的锁已被线程二获取这样它就会把线程二的锁释放掉,线程三也可以来获取锁会导致并发安全问题。在上一篇我们使用了乐观锁解决超卖问题,悲观锁保证了一人一单。封装了获取锁和释放锁的方法。
2024-08-06 11:47:38
772
原创 了解MVCC
redo log保证了事务的持久性undo log保证了事务的原子性redo log+undo log保证了事务的一致性MVCC+锁保证了事务的隔离性。
2024-08-05 18:20:11
620
原创 事务的原理(学习笔记)
如果没有redo log 我们在执行完增删改查语句后会将脏页直接刷新到磁盘中,此时用户事务已经提交,一旦刷新失败则无法修复数据。如果不适用redo log 还会存在性能问题,事务中的一组操作都是随机操作数据页,涉及到大量随机磁盘IO,而日志都是顺序追加,是顺序磁盘IO这种机制也被叫做WAL。redo log中的日志文件是循环写入的,已经成功刷新磁盘中的数据对应的日志就没什么用了。用于记录被修改前的信息,它与redo log 不一样它是逻辑日志。
2024-08-05 16:40:40
290
原创 InnoDB引擎
段:分为数据段,索引段,回滚段,InnoDB是索引组织表,数据段就是B+树的叶子节点,索引段即为B+树的非叶子节点,段用来管理多个Extent(区)页:是InnoDB存储引擎管理磁盘管理的最小单元,每个页默认大小为16KB,为了保证页的连续性,InnoDB默认每次从磁盘中申请4-5个区。区:表空间的单元结构,每个分区的大小为1M,默认情况下,InnoDB存储引擎页大小为16K,即一个区中一共有64个连续的页。表空间也就是ibd文件,一个MySQL实例可以对应多个表空间,用于存储记录,索引等数据。
2024-08-05 16:36:22
263
原创 基于redis实现优惠劵秒杀下单功能(结合黑马视频总结)
基础业务逻辑初步实现当多个线程同时进行时可能出现超卖问题,同一个用户可能出现重复下单问题可以使用乐观锁或者悲观锁解决乐观锁又分为两种版本号法和CAS法在每次扣减库存时对版本号也进行修改,假设线程1来查询库存和版本号,都为1,接着判断库存是否大于0,判断成立,执行扣减语句,set stock = stock - 1 ,version = version + 1 where id= 10 and version = 1;
2024-08-03 13:09:42
1304
原创 基于Redis实现全局唯一id
如何将这三部分合在一起作为long返回呢?答案是使用位运算,我们可以这样想,将时间戳 左移32位,低位都补0正好空出了序列号的位置,将序列号位置与自增长count进行与运算就可。id的组成分为三部分:符号位,时间戳,序列号。高可用,唯一性,高性能,递增性,安全性。全局id生成器需要满足一下特点。
2024-08-03 11:10:32
349
原创 springboot中第三方bean绑定属性
使用@ConfigurationProperties注解将配置文件与实体类中的属性对应。解除使用@ConfigurationProperties的注释警告。同时@ConfigurationProperties支持宽松绑定。
2024-08-02 10:42:18
209
原创 基于Redis实现的登录验证
负责刷新token的拦截器。负责验证是否登录的拦截器。未优化:用户在登录后只有在访问需要拦截的路径token才会刷新访问未拦截的路径,token不会刷新,会导致token失效优化:为了能够一直触发刷新token有效期的动作,我们需要添加一个拦截器,第一个拦截器负责token刷新拦截一切路径,只要用户登录后只要一直访问页面,token就会一致刷新,第二个拦截器则负责验证用户是否登录。
2024-08-02 09:40:26
492
原创 缓存击穿
缓存击穿问题也叫热点key问题,指的是一个被高并发访问并且缓存重建业务较为复杂的key突然失效了,大量的请求会到达数据库给数据库带来巨大的冲击。
2024-08-01 12:45:57
449
原创 添加缓存的相关策略以及缓存的主动更新
假设线程A先删除缓存然后操作数据库,此时线程B来查询缓存没有命中,然后查询数据库查询到数据后写入缓存此时缓存与数据库数据一致假设A线程先删除缓存,此时线程B来查询缓存未命中,就会查询数据库(旧数据)并写入缓存,此时数据库与缓存的数据不一致
2024-07-31 17:31:34
315
原创 MySQL中的触发器
触发器是与表有关的数据库对象,在insert/update/delete之前或者之后,触发并执行触发器中定义的sql语句集合,触发器的这种特性可以协助应用在数据库端确保数据的完整性,日志记录,数据校验等操作使用别名OLD和NEW来引用触发器中发生变化的记录内容,这和其它数据库是相似的,目前触发器只支持行级触发,不支持语句级触发。
2024-07-27 18:54:47
205
原创 Git简单介绍及常用命令一
有两种状态 untracked 和 tracked。为了更好的学习,我们需要了解一些git相关的概念。git的安装教程可以参考。
2024-07-26 19:07:43
334
原创 MySQL中的视图
视图是一种虚拟存在的表,视图中的数据并不在数据库中实际存在,行和列中数据来自自定义视图的查询中使用的表,并且是在使用视图时动态生成的通俗来讲,视图只保存了查询的sql逻辑,不保存查询的结果,视图中的实际数据是来自后面的select语句。
2024-07-26 11:56:30
424
原创 SQL优化
当数据量多时,我们可以批量插入数据,手动提交事务,按照主键顺序插入来提高sql的执行效率过程。当有大量数据时即使用 insert进行批量插入效率也并不高,此时就需要使用MySQL的load指令进行插入。如果主键乱序插入可能会出现页分裂现象。主键设计需要满足一下几个原则。
2024-07-25 22:58:03
320
原创 MySQL中的索引使用
假设我们的联合索引为 profession age status 这三个字段,那么status这个字段的索引会失效。如果索引了多列(联合索引),要遵守最左前缀法则,查询从索引的最左列开始,且不跳过索引中的列,联合索引中,出现范围查询(>
2024-07-24 23:15:49
307
原创 SQL性能分析
show profile 能够在做sql优化时帮助我们了解时间都花费在哪里并且通过having_profiling参数,能够看到当前MySQL是否支持profile操作。慢查询日志记录了所有执行时间超过指定参数(long_query_time,单位:秒,默认10秒)的所有sql语句的日志。MySQL 的慢查询日志默认没有开启,需要在MySQL的配置文件(/etc/my.cnf)中配置。设置完毕后重启服务进行测试。
2024-07-23 23:29:11
185
1
原创 MYSQL中的索引
索引(index)是帮助Mysql高效获取数据的数据结构(有序)。在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式应用(指向)数据,这样就可以在这些数据结构上实现高级查找算法,这就是索引。
2024-07-23 22:46:05
419
原创 事务的优点
最近学习事务的相关知识,打算总结一下它的优点1.数据的一致性:事务可以确保一组操作要么全部成功要么全部失败。这样可以保证数据的一致性,避免了在一组操作中出现部分操作成功而部分操作失败的情况。2. 数据的完整性:事务可以将一组操作当作一个逻辑单元,这样可以保证数据库中的数据一直处于有效和完整的状态。在事务中,可以定义一些约束条件和验证规则,确保数据的完整性。3. 并发控制:在并发环境下,多个用户或应用程序可能同时对数据库进行读写操作。
2023-07-26 22:38:34
387
原创 MySQL数据库入门
utf8_bin 这个是区分大小写的。这是用命令行的方式备份数据库,需要在DOS下以管理员的身份进行运行。最近学习了MySQL的初级,相关的指令较多所以总结梳理一下。注意这里不需要再写 -B否则会认为后面的都是数据库,就会报错。这个指令是用来启动Windows下的MySQL服务的。通过上面的指令进入到mysql中执行下面的指令。这个是创建一个名为db01的数据库。恢复文件是需要在MySQL中执行。查看当前创建的数据库的详细信息。这个是删除db01数据库。以上就是和数据库相关的操作。用来查看有哪些数据库。
2023-07-10 16:01:14
83
1
原创 反射相关的类
3.使用Class类的forName()方法获取class对象:可以使用Class类的 forName() 方法来获取指定类的class对象。2.使用对象的getClass()方法获取class对象:对于已经创建的对象,可以使用该对象的 getClass() 方法来获取其对应的class对象。getParameterTypes():获取构造方法的参数类型,返回一个Class数组,可以通过Class类的方法获取参数类型的信息。它提供了一些常用的方法来获取类的信息和操作类的属性。
2023-07-05 19:01:59
83
原创 java中反射机制
反射机制在java中是非常重要的,我们在后续学习相关框架的时候一定会用到,通过反射我们可以在不修改源代码的情况下控制程序。这是类加载的三个阶段,需要注意的是最后一个初始化的是静态成员,因为静态成员是和类相关联的。缺点是:使用效率会有影响,可以使用setAccessible()方法进行优化。反射的优点是:使用更加灵活,可以动态的使用和创建对象。上面是java程序的三个阶段。
2023-07-05 17:43:11
68
原创 Tcp编程
第二个相对复杂一点,客户端发送一个想要下载的文件给服务端,服务端接收后开始查找,如果有就返回,否则返回默认文件,客户端收到返回后开始下载到本地。下面是两个小案例,第一个是客户端给服务端发送要下载的图片路径,客户端在收到后完成下载。Tcp是网络编程中使用最多的一种,因为他可靠也能传输数据量大的文件。
2023-06-23 14:25:26
89
1
原创 udp编程
相比与Tcp,Udp的优点就是发送速度快,但是确不可靠,因为它是将数据封装成包进行传,不需要建立连接。因此它在数据发送结束时无需释放资源。它不适合传输大量数据,每个数据包的大小需要控制在64k以内。下面是它的简单案例,发送端给接收端发送hello,receive。接收端收到后回复,hello,send。今天看了Udp编程的相关内容简单记录一下。
2023-06-23 10:46:43
77
1
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人