程序猿阿星

其他

InnoDB原理篇:聊聊数据页变成索引这件事

定期分享有趣有料的精品原创文章!公众号后台回复回复"all"--领取100余本后端书籍回复"mj"--领取大厂面试资料回复"算法"--领取算法学习资料回复"001"--领取Spring
2022年2月23日
其他

InnoDB 对 Buffer Pool 的奇思妙想

本文读完需9分钟,速读仅需5分钟。前言大家好,我是阿星,又跟大家见面了。相信很多小伙伴在面试中都被问过「为什么要用缓存?」,大部分人都是回答:「减少数据库的磁盘IO压力」。但是MySQL真的有如此不堪吗?每次增删改查都要去走磁盘IO吗?今天就聊聊InnoDB对Buffer
2021年8月16日
其他

redo log与binlog间的破事

log与binlog两份日志之间的逻辑不一致,会出现什么问题?我们以update语句为例,假设id=2的记录,字段c值是0,把字段c值更新成1,SQL语句为update
2021年8月11日
其他

不会吧,不会吧,还有人不知道 binlog ?

log它是物理日志,记录内容是“在某个数据页上做了什么修改”,属于InnoDB存储引擎。而binlog是逻辑日志,记录内容是语句的原始逻辑,类似于“给ID=2这一行的c字段加1”,属于MySQL
2021年8月4日
其他

聊聊redo log是什么?

定期分享有趣有料的精品原创文章!非常感谢各位小哥哥小姐姐们能看到这里,原创不易,文章有帮助可以关注、点个赞、分享与评论,都是支持(莫要白嫖)!愿你我都能奔赴在各自想去的路上,我们下篇文章见。-
2021年7月28日
其他

浅谈 MySQL InnoDB 的内存组件

本文读完需7分钟,速读仅需4分钟。前言MySQL中执行一条SQL语句,相应表数据的读写都是由存储引擎去做(更新数据、查询数据)。在这个过程,存储引擎需要决策一些事情数据是从内存查还是从硬盘查数据是更新在内存,还是硬盘内存的数据什么时候同步到硬盘所以存储引擎会按照内部逻辑与内存、硬盘交互。我们可以按需选择存储引擎,比如常见的
2021年7月22日
其他

重学MySQL系列01-揭开面纱,显露架构

本文读完需10分钟,速读仅需6分钟。前言目前大部分的后端开发人员对MySQL的理解可能停留在一个黑盒子阶段。对MySQL基本使用没什么问题,比如建库、建表、建索引,执行各种增删改查。所有很多后端开发人员眼中的MySQL如下图所示导致在实际工作中碰到MySQL中死锁异常、SQL性能太差、异常报错等问题时,直接百度搜索。然后跟着博客捣鼓就解决了,可能自己都没搞明白里面的原理。为了解决这种知其然而不知其所以然的问题,阿星的重学MySQL系列会带着大家去探索MySQL底层原理的方方面面。这样大家碰到MySQL的一些异常或者问题时,能够直戳本质,快速地定位解决。连接管理系统(客户端)访问MySQL服务器前,做的第一件事就是建立TCP连接。经过三次握手建立连接成功后,MySQL服务器对TCP传输过来的账号密码做身份认证、权限获取。用户名或密码不对,会收到一个Access
2021年7月12日
其他

33张图剖析ReentrantReadWriteLock源码

大家好,我是阿星,今天是一篇硬核文,请各位读者大大们系好安全带,马上要发车了。晕车的朋友,可以先吃一颗阿星独家秘制的晕车药,童叟无欺,货真价实,还免费,白嫖党狂喜(16张图揭开AQS)。本文大纲如下纵观全局我的英文名叫ReentrantReadWriteLock(后面简称RRW),大家喜欢叫我读写锁,因为我常年混迹在读多写少的场景。读写锁规范作为合格的读写锁,先要有读锁与写锁才行。所以声明了ReadWriteLock接口,作为读写锁的基本规范。之后都是围绕着规范去实现读锁与写锁。读锁与写锁WriteLock与ReadLock就是读锁和写锁,它们是RRW实现ReadWriteLock接口的产物。但读锁、写锁也要遵守锁操作的基本规范。所以WriteLock与ReadLock都实现了Lock接口。那么WriteLock与ReadLock对Lock接口具体是如何实现的呢?自然是少不了我们的老朋友AQS了。AQS众所周知,要实现锁的基本操作,必须要仰仗AQS老大哥了。AQS(AbstractQueuedSynchronizer)抽象类定义了一套多线程访问共享资源的同步模板,解决了实现同步器时涉及的大量细节问题,能够极大地减少实现工作,用大白话来说,AQS为加锁和解锁过程提供了统一的模板函数,只有少量细节由子类自己决定。AQS简化流程图如下如果读者想深入AQS细节,可以看阿星的这篇文章:16张图揭开AQSSyncAQS为加锁和解锁过程提供了统一的模板函数,只有少量细节由子类自己决定,但是WriteLock与ReadLock没有直接去继承AQS。因为WriteLock与ReadLock觉得,自己还要去继承AQS实现一些两者可以公用的抽象函数,不仅麻烦,还有重复劳动。所以干脆单独提供一个对锁操作的类,由WriteLock与ReadLock持有使用,这个类叫Sync。Sync继承AQS实现了如下的核心抽象函数tryAcquirereleasetryAcquireSharedtryReleaseShared其中tryAcquire、release是为WriteLock写锁准备的。tryAcquireShared、tryReleaseShared是为ReadLock读锁准备的,这里阿星后面会说。上面说了Sync实现了一些AQS的核心抽象函数,但是Sync本身也有一些重要的内容,看看下面这段代码我们都知道AQS中维护了一个state状态变量,正常来说,维护读锁与写锁状态需要两个变量,但是为了节约资源,使用高低位切割实现state状态变量维护两种状态,即高16位表示读状态,低16位表示写状态。关于读写锁状态设计具体细节可以看阿星的文章:ReentrantReadWriteLock的位运算Sync中还定义了HoldCounter与ThreadLocalHoldCounterHoldCounter是用来记录读锁重入数的对象ThreadLocalHoldCounter是ThreadLocal变量,用来存放第一个获取读锁线程外的其他线程的读锁重入数对象如果读者对ThreadLocal不太熟悉,可以去看阿星的文章:
2021年6月30日
其他

【图解】透彻Java线程状态转换

大家好,我是阿星,好久不见,欢迎来到Java并发编程系列番外篇线程状态转换,内容通俗易懂,请放心食用。线程状态先来个开场四连问Java线程状态有几个?Java线程状态是如何转换?Java线程状态转换什么情况会进入锁的等待队列?Java线程状态转换什么情况会进入锁的同步队列?一提到Java线程状态,不少读者立马想到线程状态转换图,但细想,印象又不深刻,只记得有那么几个状态。再要你说出Java线程状态是如何转换的,脑子里可能就如下图一样,已经是一团浆糊了。别慌,阿星为了帮读者大大们理清楚上面的问题,会一步一步的把线程状态转换图给画出来,让读者大大们真正的理解Java线程状态转换。首先线程的状态可以分为6态或7态,具体状态如下6态New:新建状态Runnable:可运行状态Terminated:终止状态Waiting:等待状态TimedWaiting:超时等待状态Blocked:阻塞状态7态New:新建状态Ready:就绪状态Running:运行状态Terminated:终止状态Waiting:等待状态TimedWaiting:超时等待状态Blocked:阻塞状态其实6态与7态差别不大,只不过7态把Runnable可运行状态,拆解成了Ready就绪状态与Running运行状态。阿星以7态为例,来逐步讲解它们之间是如何转换的。新建状态(New)我们可以通过实现Runnable接口或继承Thread声明一个线程类,new一个实例后,线程就进入了新建状态。一个刚诞生的线程,处于新建状态。就绪状态(Ready)线程对象创建成功后,调用该线程的start()函数,线程进入就绪状态,该状态的线程进入可运行线程池中,等待获取C
2021年6月15日
其他

图文并茂的聊聊ReentrantReadWriteLock的位运算

大家好,我是阿星,欢迎来到Java并发编程系列第六篇ReentrantReadWriteLock基础,今天我们来聊一聊读写状态的设计。我相信不少读者,在看JDK源码时,会看到位运算代码,可能有些人和阿星一样是转行的,缺乏计算机相关的基础知识,看的是一头雾水。导致有些人直接被劝退,也有些人选择理解字面上的意思,细节跳过。但是一颗疑惑的种子在我们心中埋了下来「为什么使用位运算就能达到这样的效果?」。恰好ReentrantReadWriteLock读写状态的设计用到了位运算,我们以此来展开今天的话题。一段位运算代码我们来到ReentrantReadWriteLock.Sync内部类,发现了这段代码(后面以RRW简称)
2021年5月25日
其他

通俗易懂的ReentrantLock,不懂你来砍我

前言自己开的坑,跪着也要填完,欢迎来到Java并发编程系列第五篇ReentrantLock,文章风格依然是图文并茂,通俗易懂,本文带读者们深入理解ReentrantLock设计思想。如果读过阿星写的前篇万字长文
2021年4月22日
其他

万长文字 | 16张图解开AbstractQueuedSynchronizer

前言Java并发编程系列第四篇AbstractQueuedSynchronizer,文章风格依然是图文并茂,通俗易懂,本文带读者们深入理解AbstractQueuedSynchronizer设计思想。内容大纲基础AbstractQueuedSynchronizer抽象同步队列简称A
2021年4月15日
其他

写给小白看的LockSupport

前言Java并发编程系列第三篇LockSupport,上一篇Synchronized文章中有提过,不推荐读者们使用Object的wait、notify、notifyAll等函数做多线程间的通信协同,使用LockSupport会是更好的选择,本篇就来谈谈LockSupport,也正好为下篇的A
2021年4月6日
自由知乎 自由微博
其他

13张图,深入理解Synchronized

前言Java并发编程系列第二篇Synchronized,文章风格依然是图文并茂,通俗易懂,本文带读者们由浅入深理解Synchronized,让读者们也能与面试官疯狂对线。在并发编程中Synchronized一直都是元老级的角色,Jdk
2021年3月25日
其他

由浅入深C A S,小白也能与BAT面试官对线

U会通过总线嗅探机制感知该共享变量是否发生变化,如果发生变化,让自己对应的共享变量缓存行失效,重新从内存读取最新的数据,缓存锁定是基于缓存一致性机制来实现的,因为缓存一致性机制会阻止两个以上C
2021年3月20日
其他

小白也能看懂的Java内存模型

前言Java并发编程系列开坑了,Java并发编程可以说是中高级研发工程师的必备素养,也是中高级岗位面试必问的问题,本系列就是为了带读者们系统的一步一步击破Java并发编程各个难点,打破屏障,在面试中所向披靡,拿到心仪的offer,Java并发编程系列文章依然采用图文并茂的风格,让小白也能秒懂。Java内存模型(Java
2021年3月9日
其他

什么是线程安全?一文带你深入理解

section),它是执行共享资源的代码片段,一定不能给多线程同时执行。所以我们希望这段代码是互斥(mutualexclusion)的,也就说执行临界区(critical
2021年1月18日
其他

保姆级教学,22张图揭开ThreadLocal

获取变量步骤如下获取当前线程获取当前线程的本地变量线程本地变量没有被创建,执行setInitialValue方法进行初始化,并返回value值线程本地变量存在,ThreadLocal计算成索引从
2021年1月5日
其他

进程、线程与协程傻傻分不清?一文带你吃透!

U就绪态(Ready):可运行,但因为其他进程正在运行而暂停停止阻塞状态(Blocked):该进程等待某个事件(比如IO读取)停止运行,这时,即使给它CPU控制权,它也无法运行上图状态转换流程C
2020年12月30日