自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(20)
  • 问答 (1)
  • 收藏
  • 关注

原创 CAP 0.0

CAP是分布式中的一个理论C(Consistency):一致性。多个节点上的数据是否强一致的A(Availability):可用性。即使某个节点出问题了,服务是否依然快速响应P(Partition Tolerance):分区容忍性。可以理解为容忍节点的网络延迟CAP理论认为上述三点无法全部满足,只能三选二。例子:Redis:AP,因为Redis的设计就是为了快,所以不管是持久化(后写日志)还是主从复制,都是一种异步的操作。MySQL:CP,MySQL的先写日志以及主从的ACK机制来保证数据一

2022-03-08 11:50:23 318

原创 mysql先写日志和redis后写日志

mysql强一致性,要通过日志保证数据的正确性。主要通过redo和bin,两阶段提交日志。redis后写是因为redis的日志不是强一致性的,redis的操作还要程序先判断是否正确,正确执行之后再写日志。而且内存操作很快,所以redis使用后写日志的策略。...

2021-08-17 22:06:54 425

原创 用唯一索引还是普通索引

change buffer当需要更新一个数据页时,如果数据页在内存中(buffer pool)就直接更新,而如果这个数据页还没有在内存中的话,在不影响数据一致性的前提下,InooDB会将这些更新操作缓存在change buffer中,这样就不需要从磁盘中读入这个数据页了。在下次查询需要访问这个数据页的时候,将数据页读入内存,然后执行change buffer中与这个页有关的操作。通过这种方式就能保证这个数据逻辑的正确性。当需要更新一个数据页时,如果数据页在内存中就直接更新,而如果这个数据页还没有在内存中的

2021-08-11 14:40:01 80

原创 MVCC小结

版本链事务中进行更新操作,都会被记录在undo日志中。记录的内容除了id之外还有事务id和下一条记录的指针等。READ COMMITTED —— 每次读取数据前都生成一个ReadView隔离级别为READ COMMITTED的事务,每次查询select操作时,会生成一个视图,生成视图的时候会判断目前哪些事务还处于活跃状态,即未提交,这个会保存在一个列表中,然后从版本链中从上至下找到第一条不在这个列表里的记录,即最后一条已经提交的记录。REPEATABLE READ —— 在第一次读取数据时生成一个

2021-08-10 19:15:19 78

原创 分代垃圾回收和mySQL的Buffer Pool

分代垃圾回收分代垃圾回收是通过对象不同的年龄,来使用不同的垃圾回收方式。大多数对象都是朝生夕死的,所以使用复制算法只需要复制很少的存活的对象,而对于老年代的对象,本身就是不容易被回收的,如果用复制算法反而需要复制大多数对象,所以老年代适合标记清除或者标记整理算法。buffer poolbuffer pool是InnoDB用来缓存页的一片连续内存。buffer pool的大小是有限的,InnoDB采用的是LRU算法来挺高缓存命中率。但是有两种情况:InnoDB提供了一个预读的服务,会提前加载其他

2021-08-10 01:32:55 129

原创 redis分布式锁

单点Redis原子命令加锁set key random_value NX PX 30000设置值的时候,放的是random_value值是ramdom_value是原因是为了更安全的释放锁:当某个线程阻塞,超过设置的锁的时间还持有锁,这时锁会被释放,如果这个线程后面直接删除锁,可能会把别人的锁删了,所以应该通过random_value来判断是否是自己的锁,并用lua脚本保证原子性。但是在集群模式下,当主从复制还没完成,master就宕机时,锁可能丢失,于是redis作者提出了redlock算法。

2021-08-04 13:32:35 111

原创 缓存和数据库一致性的总结

主要有两种策略先更新db,后删缓存(有脏数据概率)先删缓存,后更新db(不保证一致性)策略一:先更新db,后删缓存最经典的缓存+数据库读写的模式,也叫 Cache Aside Pattern。存在读取脏数据的概率。线程1更新db,db刚被更新但是缓存还未删除时,这时线程2读的缓存是旧的数据。策略二:先删缓存,后更新db这种策略会有数据不一致的问题。线程1删除缓存,还没来得及更新db,这时线程2读缓存,发现缓存为空,去db里拿到旧的数据,并把旧数据写入缓存,线程1更新db。这样缓存里就是旧

2021-07-30 17:01:22 364

原创 io多路复用

博客https://mp.weixin.qq.com/s?__biz=MzUxODAzNDg4NQ==&mid=2247489558&idx=1&sn=7a96604032d28b8843ca89cb8c129154&scene=21#wechat_redirecthttps://mp.weixin.qq.com/s/px6-YnPEUCEqYIp_YHhDzgredis:epollnginx:epollnetty:可选的程序要调用IO,需

2021-07-14 16:02:39 65

原创 volatile原理

volatile 的底层实现原理是内存屏障,Memory Barrier(Memory Fence)对 volatile 变量的写指令后会加入写屏障对 volatile 变量的读指令前会加入读屏障保证可见性写屏障(sfence)保证在该屏障之前的,对共享变量的改动,都同步到主存当中public void actor2(I_Result r) { num = 2; ready = true; // ready是被volatile修饰的 ,赋值带写屏障 // 写屏

2021-07-02 21:58:33 68

原创 Java线程状态

五种状态五种状态的划分主要是从操作系统的层面进行划分的初始状态,仅仅是在语言层面上创建了线程对象,即Thead thread = new Thead();,还未与操作系统线程关联可运行状态,也称就绪状态,指该线程已经被创建,与操作系统相关联,等待cpu给它分配时间片就可运行运行状态,指线程获取了CPU时间片,正在运行当CPU时间片用完,线程会转换至【可运行状态】,等待 CPU再次分配时间片,会导致我们前面讲到的上下文切换阻塞状态如果调用了阻塞API,如BIO读写文件,那么线程实际上

2021-07-01 21:02:04 70

原创 synchronized

对象实例的结构对象实例包含对象头:包含Mark Word和Klass Point。实例数据:数据信息,如变量、方法、父类信息等。对齐补充:虚拟机要求对象起始地址必须是8字节的整数倍,对其补充不是必须存在的。对象头以 32 位虚拟机为例,普通对象的对象头结构如下,其中的Klass Word为指针,指向对应的Class对象:数组对象的对象头:Mark WordMonitor是用c++写的,数据结构如下:ObjectMonitor() { _header = N

2021-06-30 19:31:00 67

原创 自旋锁的小总结

因为在很多应用场景下,共享资源的锁定状态只会持续很短的一段时间,所以如果频繁的挂起唤醒线程,开销很大。因此可以用自旋锁来避免线程上下文切换。但是自旋锁会一直持有CPU,死循环,所以如果共享资源的访问时间很久,会带来性能的浪费。因此自旋的时间等待时间必须有限度,默认是十次,可以通过参数更改。自适应自旋:动态优化自旋锁的自旋时间。比如在同一个锁对象上,自旋等待刚刚成功获得过锁,并且持有锁的线程正在运行中,那么虚拟机就会认为这次自旋也很有可能再次成功,进而允许自旋等待持续相对更长的时间,比如持续100次忙循.

2021-06-21 15:24:56 78

原创 交替打印三个线程

public class Demo { public static void main(String[] args) { ShareData sd = new ShareData(); new Thread(() -> { for (int i = 0; i < 10; i++) sd.printA(); }, "A").start(); new Thread(()

2021-06-13 18:44:45 47

原创 JVM类加载

生命周期加载连接(验证、准备、解析)初始化使用卸载1.加载类加载过程的第一步,主要完成下面 3 件事情:通过全类名获取定义此类的二进制字节流(通过全类名读取文件字节流)将字节流所代表的静态存储结构转换为方法区的运行时数据结构(将类模板放入方法区)在内存中生成一个代表该类的 Class 对象,作为方法区这些数据的访问入口(在堆中生成一个Class对象,指向方法区中类的模板)2.链接验证:确保Class文件是符合JVM规范的。准备:给静态变量分配内存空间和设置初始值。只是

2021-06-10 20:15:02 41

原创 JVM垃圾回收,并发出现“对象消失”问题

三色标记黑色:这个对象的所有引用都已经扫描过灰色:该对象至少有一个引用未必扫描过(未扫描完)白色:尚未被扫描过的对象两个条件同时满足的时候会出现“对象消失”问题插入了一条或多条从黑色对象到白色对象的新引用删除了全部从灰色对象到白色对象的直接或间接引用解决方法两种解决方法,都是通过写屏障实现的。方法一,增量更新:当黑色对象插入新的指向白色对象的引用时,把这个新的引用记录下来,等并发标记结束之后,再扫描一次这个记录。比如用一个队列记录下来。可以理解为,黑色对象一旦新插入白色对象的引用

2021-06-10 18:59:04 574

原创 JVM调优

调优目的减少GC次数,避免OOM。Full GC频繁可能的原因:大对象直接进入老年代老年代太小设置的晋升次数太小,导致对象很容易进到老年代元空间满了(考虑动态加载了类)…根据GC日志和dump文件来排查定位 0.0CMS-XX:CMSInitiatingOccupancyFraction=percent(设置老年代并发回收的时机。一般设为70%~80%,剩下留给浮动垃圾。)避免浮动垃圾过多,自动转成串行垃圾回收器。。...

2021-06-08 23:26:14 48

原创 刷题整理 - 递归和树

22、括号生成https://leetcode-cn.com/problems/generate-parentheses/怎么检验合法性:左括号随时可以加,只要不超过个数右括号的个数必须小于等于左括号个数这是递归,不是回溯。递归只需要每次往下走一层,回溯还需要剪枝class Solution { List<String> result = new ArrayList<>(); public List<String> generateParent

2021-06-08 19:55:29 54

原创 字符串常量池、Class常量池、运行时常量池

字符串(String)常量池字符串常量池存在方法区。方法区是逻辑概念,在JDK1.7中,字符串常量池被移到了堆中。保存的是String对象。每个JVM中都只会维护一份。是所有的类共享的。Class常量池.class文件中保存的字面量和符号引用。每个class文件独有一份。运行时常量池分为动态常量和静态常量。每个class文件独有一份。动态常量:保存在Class常量池中的常量,JVM要加载到运行时常量池才能运行。静态常量:分为String常量和数字常量。小的数字(Short)保存在Class常

2021-06-07 19:05:21 128

原创 JVM空间分配担保机制

在Minor GC之前,JVM会检查老年代最大可用的连续空间是否大于新生代所有对象总空间,如果这个条件成立,那这一次Minor GC可以确保是安全的。如果不成立,JVM会检查-XX:HandlePromotionFailure参数。如果开启-XX:HandlePromotionFailure,JVM会检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小,如果大于,将尝试进行一次有风险的Minor GC。如果小于平均值,或者没开启-XX:HandlePromotionFailure,将进.

2021-05-22 14:59:33 481

原创 判断JVM对象是否死亡

引用计数法存在循环引用问题。Redis是通过循环引用判断对象是否死亡的。可达性分析从GC Roots向下不可达时,证明此对象是不可能再使用的。GC Roots的对象:JVM栈中的对象。本地方法栈(native方法)中的对象。方法区中静态引用的对象,如static final修饰的对象。方法区中常量引用的对象,如字符串常量池里的引用。被同步锁(synchronized)持有的对象。…引用类型传统的“引用”定义:如果reference类型的数据中存储的数值代表的是另外一块内存的起始

2021-05-19 15:33:49 79

空空如也

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

TA关注的人

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