MySQL锁机制
MySQL锁机制概述锁是计算机协调多个进程或线程并发访问某一资源的机制。在程序开发中会存在多线程同步的问题,当多个线程并发访问某个数据的时候,尤其是针对一些敏感的数据(比如订单、金额等),我们就需要保证这个数据在任何时刻最多只有一个线程在访问,保证数据的完整性和一致性。在开发过程中加锁是为了保证数据的一致性,这个思想在数据库领域中同样很重要。
在数据库中,除传统的计算资源(如CPU、RAM、I/O等)的争用以外,数据也是一种供许多用户共享的资源。为保证数据的一致性,需要对并发操作进行控制 ,因此产生了 锁 。同时锁机制也为实现MySQL的各个隔离级别提供了保证。 锁冲突也是影响数据库并发访问性能 的一个重要因素。所以锁对数据库而言显得尤其重要,也更加复杂。
MySQL并发事务访问相同记录并发事务访问相同记录的情况大致可以划分为3种:
读-读即并发事务相继 读取相同的记录 。读取操作本身不会对记录有任何影响,并不会引起什么问题,所以允许这种情况的发生。
写-写在这种情况下会发生脏写的问题,任何一种隔离级别都不允许这种问题的发生。所以在多个未提交事务相继对一条记录做改动时,需要让它们排队执 ...
多版本并发控制
再谈隔离级别在MySQL中,默认的隔离级别是可重复读,可以解决脏读和不可重复读的问题,如果仅从定义的角度来看,它并不能解决幻读问题。如果我们想要解决幻读问题,就需要采用可串行化的方式,也就是将隔离级别提升到最高,但这样一来就会大幅降低数据库的事务并发能力
MVCC可以不采用锁机制,而是采用乐观锁的方式来解决不可重复读和幻读问题!
它可以在大多是情况下代替行级锁,降低系统的开销
隐藏字段和Undo Log版本链回顾一下undo日志的版本链,对于使用InnoDB存储引擎的表来说,它的聚簇索引记录中包含两个必要的隐藏列
trx_id:每次一个事务对某条聚簇索引记录进行改动时,都会把该事务的事务id赋值给trx_id隐藏列
roll_pointer:每次对某条聚簇索引记录进行改动时,都会把旧的版本写到undo日志中,然后这个隐藏列就相当于一个指针,可以通过他来找到该记录修改前的信息
举例:假设插入记录的事务id为8,那么此刻该记录的示意图如下所示:
insert undo只有在事务回滚时起作用,当事务提交后,该类型的undo日志就没用了,它占用的Undo Log Segment也会被系统回 ...
TCP四次挥手
TCP四次挥手 TCP 断开连接是通过四次挥手方式。
双方都可以主动断开连接,断开连接后主机中的「资源」将被释放,四次挥手的过程如下图:
客户端打算关闭连接,此时会发送一个 TCP 首部 FIN 标志位被置为 1 的报文,也即 FIN 报文,之后客户端进入 FIN_WAIT_1 状态。
服务端收到该报文后,就向客户端发送 ACK 应答报文,接着服务端进入 CLOSE_WAIT 状态。
客户端收到服务端的 ACK 应答报文后,之后进入 FIN_WAIT_2 状态。
等待服务端处理完数据后,也向客户端发送 FIN 报文,之后服务端进入 LAST_ACK 状态。
客户端收到服务端的 FIN 报文后,回一个 ACK 应答报文,之后进入 TIME_WAIT 状态
服务端收到了 ACK 应答报文后,就进入了 CLOSE 状态,至此服务端已经完成连接的关闭。
客户端在经过 2MSL 一段时间后,自动进入 CLOSE 状态,至此客户端也完成连接的关闭
这里一点需要注意是:主动关闭连接的,才有 TIME_WAIT 状态。
为什么挥手需要四次再来回顾下四次挥手双方发 FIN 包的过程,就能理解为什么 ...
Redis数据类型
Redis数据类型我们都知道 Redis 提供了丰富的数据类型,常见的有五种:String(字符串),Hash(哈希),List(列表),Set(集合)、Zset(有序集合)。
随着 Redis 版本的更新,后面又支持了四种数据类型: BitMap(2.2 版新增)、HyperLogLog(2.8 版新增)、GEO(3.2 版新增)、Stream(5.0 版新增)。
StringString 是最基本的 key-value 结构,key 是唯一标识,value 是具体的值,value其实不仅是字符串, 也可以是数字(整数或浮点数),value 最多可以容纳的数据长度是 512M。
内部实现String 类型的底层的数据结构实现主要是 int 和 SDS(简单动态字符串)。
应用场景缓存对象使用 String 来缓存对象有两种方式:
直接缓存整个对象的 JSON,命令例子: SET user:1 '{"name":"wereash", "age":18}'。
采用将 key 进行分离为 us ...
IP协议
IP协议概述IP协议是TCP/IP协议族的动力,它为上层协议提供无状态、无连接、不可靠的服务。
无状态(stateless)是指IP通信双方不同步传输数据的状态信息,因此所有IP数据报的发送、传输和接收都是相互独立、没有上下文关系的。这种服务最大的缺点是无法处理乱序和重复的IP数据报。
虽然IP数据报头部提供了一个标识字段(见后文)用以唯一标识一个IP数据报,但它是被用来处理IP分片和重组的,而不是用来指示接收顺序的。
无连接(connectionless)是指IP通信双方都不长久地维持对方的任何信息。这样,上层协议每次发送数据的时候,都必须明确指定对方的IP地址。
不可靠是指IP协议不能保证IP数据报准确地到达接收端,它只是承诺尽最大努力(best effort)。很多种情况都能导致IP数据报发送失败
IPV4头部结构
4位版本号(version)指定IP协议的版本。
4位头部长度(header length)标识该IP头部有多少个32 bit字(4字节)。因为4位最大能表示15,所以IP头部最长是60字节。
16位总长度(total length)是指整个IP数据报 ...
Redis数据结构
Redis数据结构
Joiner类
Joiner概述Joiner是Java中的一个工具类,用于连接字符串和集合
在Java开发中,经常会遇到连接字符串或集合的情况。例如,我们需要将多个字符串连接成一个完整的字符串,或者将一个集合中的元素连接一个字符串。
Joiner类位于com.google.common.base包中,使用前需要导入该包
下面是一个使用Joiner连接字符串的示例:
12345678import com.google.common.base.Joiner;public class Test{ public static void main(String[] args){ String result=Joiner.on(",").skipNulls().join("h","e","l","null","l","o"); System.out.println(result); }}// h,e,l ...
StringTable
StringTable基本特性
String:字符串使用一堆“”引起来表示
String声明为final的,不可被继承
String实现了Serializable接口:表示字符串时可支持序列化的。实现了Compareble接口:表示String可以比较大小
String在jdk及以前内部定义了final char[] value用于存储字符串。jdk9时改为byte[]
字符串常量池中是不会存储相同内容的字符串的
String的String Pool是固定大小的Hashtable,默认值大小长度是1009。如果放进String Pool的String非常多,就会造成Hash冲突,从而导致链表会很长,而链表长了后会直接造成的影响就是当调用String.intern时性能会大幅下降
使用-XX:StringTableSize可设置StringTable的长度
在jdk6中StringTable是固定的,就是1009的长度,所以如果常量池中的字符串过多就会导致效率下降很快。StringTableSize设置没有要求
在jdk7中,StringTable的长度默认值是60013,1009是 ...
RibbitMQ
RibbitMQ基本架构下图是RabbitMQ的基本架构
生产者(Producer):生产者是消息的发送方,负责产生发送消息到RabbitMQ。生产者通常将消息发送到交换机(Exchange).
交换机(Exchange):交换机是消息的分发中心,负责将接收到的消息路由到一个或多个队列中。它定义了消息的传递规则,可以根据规则将消息发送到一个或多个队列
直连交换机(Direct Exchange):将消息路由到与消息中的路由键(Routing Key)完全匹配的队列
主题交换机(Topic Exchange):根据通配符匹配路由键,将消息路由到一个或多个队列
扇出交换机(Fanout Exchange):将消息广播到所有交换机绑定的队列,忽略路由键
头部交换机(Header Exchange):根据消息头中的属性进行匹配,将消息路由到与消息匹配的队列
队列(Queue):队列是消息的存储区,用于存储生产者发送的消息。消息最终会被消费者从队列中取出并处理。每个队列都有一个名称,并且可以绑定到一个或多个交换机
消费者(Consumer):消费者是消息的接收方,负责从队列中获取消息并进 ...
Java数据类型
Java数据类型Java语言提供了八种基本类型。六种数字类型(四个整数型,两个浮点型),一种字符类型,还有一种布尔型。
byte
byte 数据类型是8位、有符号的,以二进制补码表示的整数
最小值是 -128(-2^7);
最大值是 127(2^7-1);
默认值是 0;
byte 类型用在大型数组中节约空间,主要代替整数,因为 byte 变量占用的空间只有 int 类型的四分之一;
例子:byte a = 100,byte b = -50。
short
short 数据类型是 16 位、有符号的以二进制补码表示的整数
最小值是 -32768(-2^15);
最大值是 32767(2^15 - 1);
short 数据类型也可以像 byte 那样节省空间。一个short变量是int型变量所占空间的二分之一;
默认值是 0;
例子:short s = 1000,short r = -20000。
int
int 数据类型是32位、有符号的以二进制补码表示的整数;
最小值是 -2,147,483,648(-2^31);
最大值是 2,147,483,647(2^31 - 1);
一般地 ...