- 博客(427)
- 收藏
- 关注
原创 @Transactional注解的失效场景
1. @Transactional 应用在非 public 修饰的方法上2. @Transactional 注解属性 propagation 设置错误这种失效是由于配置错误,若是错误的配置以下三种 propagation,事务将不会发生回滚。TransactionDefinition.PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。TransactionDefinition.PROPAGATION_NOT_SUPPORTE
2021-07-11 23:16:30 526
原创 ConcurrentHashMap原理
ConcurrentHashMap采用了非常精妙的"分段锁"策略,ConcurrentHashMap的主干是个Segment数组。static class Segment<K,V> extends ReentrantLock implements Serializablefinal Segment<K,V>[] segments; Segment继承了ReentrantLock,所以它就是一种可重入锁(ReentrantLock)。在Concurren...
2021-07-10 21:36:05 335 1
原创 hashmap原理
loadFactor:数据的增长因子,默认为0.75。在进行扩容操作会使用到。 threshold:允许的最大的存储的元素数量,通过length数组长度*loadFactor增长因子得出 modCount:记录内部结构发生变化的次数,put操作(覆盖值不计算)以及其他... size:实际存储的元素数量put方法final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boole...
2021-07-10 18:01:17 243
原创 简单实现一个lock
import java.lang.reflect.Field;import java.util.concurrent.ConcurrentLinkedQueue;import java.util.concurrent.locks.LockSupport;import sun.misc.Unsafe;public class MyLock { private static Unsafe unsafe; /** * 当前加锁状态,记录加锁的次数 */ .
2021-07-09 20:17:20 247
原创 CopyOnWriteArrayList
CopyOnWriteArrayList是ArrayList的线程安全版本,CopyOnWriteArrayList是在有写操作的时候会copy一份数据,然后写完再设置成新的数据。CopyOnWriteArrayList适用于读多写少的并发场景,CopyOnWriteArraySet是线程安全版本的Set实现,它的内部通过一个CopyOnWriteArrayList来代理读写等操作,使得CopyOnWriteArraySet表现出了和CopyOnWriteArrayList一致的并发行为,他...
2021-07-08 21:29:09 479
原创 ZAB协议
Paxos 虽然解决了分布式系统中,多个节点就某个值达成一致性的通信协议。但是还是引入了其他的问题。由于其每个节点,都可以提议提案,也可以批准提案。当有三个及以上的 proposer 在发送 prepare 请求后,很难有一个 proposer 收到半数以上的回复而不断地执行第一阶段的协议,在这种竞争下,会导致选举速度变慢。所以 zookeeper 在 paxos 的基础上,提出了 ZAB 协议,本质上是,只有一台机器能提议提案(Proposer),而这台机器的名称称之为...
2021-07-07 21:53:58 151
原创 Raft协议
基本名词节点状态 Leader(主节点):接受 client 更新请求,写入本地后,然后同步到其他副本中 Follower(从节点):从 Leader 中接受更新请求,然后写入本地日志文件。对客户端提供读请求 Candidate(候选节点):如果 follower 在一段时间内未收到 leader 心跳。则判断 leader 可能故障,发起选主提议。节点状态从 Follower 变为 Candidate 状态,直到选主结束 termId:任期号,时间被划分成一个个任期,每次选举后都会产生
2021-07-07 21:08:37 196
原创 Paxos协议
像 2PC 和 3PC 都需要引入一个协调者的角色,当协调者 down 掉之后,整个事务都无法提交,参与者的资源都出于锁定的状态,对于系统的影响是灾难性的,而且出现网络分区的情况,很有可能会出现数据不一致的情况。需要一种不用协调者角色,每个参与者来协调事务的机制。Paxos 协议是一个解决分布式系统中,多个节点之间就某个值(提案)达成一致(决议)的通信协议。它能够处理在少数节点离线的情况下,剩余的多数节点仍然能够达成一致。即每个节点,既是参与者,也是决策者...
2021-07-07 20:58:58 271
原创 3PC三阶段提交
阶段一:CanCommit事务询问。协调者向所有参与者发送包含事务内容的canCommit的请求,询问是否可以执行事务提交,并等待应答; 各参与者反馈事务询问。正常情况下,如果参与者认为可以顺利执行事务,则返回Yes,否则返回No。阶段二:PreCommit在本阶段,协调者会根据上一阶段的反馈情况来决定是否可以执行事务的PreCommit操作。有以下两种可能:执行事务预提交发送预提交请求。协调者向所有节点发出PreCommit请求,并进入prepared阶段; 事务...
2021-07-07 20:47:19 266
原创 2PC二阶段提交
2PC即Two-Phase Commit,二阶段提交。广泛应用在绝大部分关系型数据库,为了使得基于分布式架构的所有节点可以在进行事务处理时能够保持原子性和一致性。阶段一:提交事务请求事务询问。协调者向所有参与者发送事务内容,询问是否可以执行提交操作,并开始等待各参与者进行响应; 执行事务。各参与者节点,执行事务操作,并将Undo和Redo操作计入本机事务日志; 各参与者向协调者反馈事务问询的响应。成功执行返回Yes,否则返回No。阶段二:执行事务提交协调者在...
2021-07-07 20:23:50 328
原创 三次握手过程中有哪些不安全性
SYN洪泛攻击服务器处于SYN_Wait的状态: 1)伪装的IP向服务器发送一个SYN请求建立连接,然后服务器向该IP回复SYN和ACK,但是找不到该IP对应的主机,当超时时服务器收不到ACK会重复发送。当大量的攻击者请求建立连接时,服务器就会存在大量未完成三次握手的连接,服务器主机backlog被耗尽而不能响应其它连接。即SYN泛洪攻击(属于DOS的一种,发送大量的半连接请求,耗费CPU和内存资源,引起网络堵塞甚至系统瘫痪) 当你在服务器上看到大量的...
2021-07-06 16:03:37 665
原创 解决TIME_WAIT过多造成的问题
看到TIME_WAIT状态是在tcp断开链接时产生的,因为TCP连接是双向的,所以在关闭连接的时候,两个方向各自都需要关闭。先发FIN包的一方执行的是主动关闭;后发FIN包的一方执行的是被动关闭。主动关闭的一方会进入TIME_WAIT状态,并且在此状态停留两倍的MSL时长。 MSL指的是报文段的最大生存时间,如果报文段在网络活动了MSL时间,还没有被接收,那么会被丢弃。关于MSL的大小,RFC 7...
2021-07-05 21:18:05 5628 1
原创 a=a+b与a+=b有什么区别
+=操作符会进行隐式自动类型转换,此处a+=b隐式的将加操作的结果类型强制转换为持有结果的类型,而a=a+b则不会自动进行类型转换。如:byte a = 127;byte b = 127;b = a + b; // error : cannot convert from int to byteb += a; // ok(其实无论 a+b 的值为多少,编译器都会报错,因为 a+b 操作会将 a、b 提升为 int 类型,所以将 int 类型赋值给 byte 就会编译出错)...
2021-07-02 00:40:59 265
原创 面向对象五大基本原则
单一职责原则SRP(Single Responsibility Principle) 类的功能要单一,不能包罗万象,跟杂货铺似的。 开放封闭原则OCP(Open-Close Principle) 一个模块对于拓展是开放的,对于修改是封闭的,想要增加功能热烈欢迎,想要修改,哼,一万个不乐意。 里式替换原则LSP(the Liskov Substitution Principle LSP) 子类可以替换父类出现在父类能够出现的任何地方。比如你能代表你爸去你姥姥家干活。哈哈~~ ..
2021-07-02 00:29:46 110
原创 Spring 常⽤用的注⼊入⽅方式有哪些
1.构造器依赖注入:构造器依赖注入通过容器触发一个类的构造器来实现的,该类有一系列参数,每个参数代表一个对其他类的依赖。2.Setter方法注入:Setter方法注入是容器通过调用无参构造器或无参static工厂方法实例化匕ean之后,调用该bean的Setter方法,即实现了基于Setter的依赖注入。3.基于注解的注入:最好的解决方案是用构造器参数实现强制依赖,Setter方法实现可选依赖。...
2021-06-29 22:36:55 461
原创 redis缓存问题
什么是缓存穿透?怎么解决?缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,造成缓存穿透。解决办法:1、缓存空对象:如果一个查询返回的数据为空(不管是数据不存在,还是系统故障),我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。 缓存空对象带来的问题: 1.空值做了缓存,意昧着缓存中存了更多的键,需要更多的内存空间,比较有效...
2021-06-29 22:19:37 193
原创 Redis 为什什么这么快
1.完全基于内存,绝大部分请求是纯粹的内存操作,非常快速;2.数据结构简单,对数据操作也简单;3.采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗CpU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗;4.使用多路I/0复用模型,非阻塞旧。...
2021-06-29 22:15:14 104
原创 TCP三次握手/四次挥手
三次握手第一次握手:主机A发送位码为syn=1,随机产生seq number=1234567的数据包到服务器,主机B由SYN=1知道,A要求建立联机;第二次握手:主机B收到请求后要确认联机信息,向A发送ack number=(主机A的seq+1),syn=1,ack=1,随机产生seq=7654321的包第三次握手:主机A收到后检查ack number是否正确,即第一次发送的seq number+1,以及位码ack是否为1,若正确,主机A会再发送ack ...
2021-06-29 22:06:05 111
原创 Mybatis缓存
Mybatis中有一级缓存和二级缓存,默认情况下一级缓存是开启的,而且是不能关闭的。一级缓存是指SqlSession级别的缓存,当在同一个SqlSession中进行相同的SQL语句查询时,第二次以后的查询不会从数据库查询,而是直接从缓存中获取,一级缓存最多缓存1024条SQL。二级缓存是指可以跨SqlSession的缓存。是mapper级别的缓存,对于mapper级别的缓存不同的sqlsession是可以共享的。Mybatis的一级缓存第一次发出一个查询sql,sql...
2021-06-29 21:56:49 112
原创 什么是 AQS(抽象的队列同步器)
AbstractQueuedSynchronizer类如其名,抽象的队列式的同步器,AQS定义了一套多线程访问共享资源的同步器框架,许多同步类实现都依赖于它,如常用的ReentrantLock/Semaphore/CountDownLatch。它维护了一个volatile int state(代表共享资源)和一个FIFO线程等待队列(多线程争用资源被阻塞时会进入此队列)。这里volatile是核心关键词。state的访问方式有三种: getState() setSta...
2021-06-28 22:58:51 309
原创 线程上下文切换
上下文 是指某一时间点 CPU 寄存器和程序计数器的内容。引起线程上下文切换的原因1. 当前执行任务的时间片用完之后,系统CPU正常调度下一个任务;2. 当前执行任务碰到IO阻塞,调度器将此任务挂起,继续下一任务;3. 多个任务抢占锁资源,当前任务没有抢到锁资源,被调度器挂起,继续下一任务;4. 用户代码挂起当前任务,让出CPU时间;5. 硬件中断;...
2021-06-28 22:43:19 91
原创 JAVA中的各种锁
乐观锁乐观锁认为读多写少,遇到并发写的可能性低,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,采取在写时先读出当前版本号,然后加锁操作(比较跟上一次的版本号,如果一样则更新),如果失败则要重复读-比较-写的操作。 java中的乐观锁基本都是通过CAS操作实现的,CAS是一种更新的原子操作,比较当前值跟传入值是否一样,一样则更新,否则失败。悲观锁悲观锁认为写多,遇到并发写的可能性高,每次去拿数据的时候...
2021-06-28 22:37:30 335
原创 sleep与wait 区别
1. 对于sleep()方法,我们首先要知道该方法是属于Thread类中的。而wait()方法,则是属于Object类中的。2. sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态。3. 在调用sleep()方法的过程中,线程不会释放对象锁。4. 而当调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备获取对象锁进入运行状态。
2021-06-28 22:04:25 75
原创 线程池基本概念
通过Executors线程池工具类来使用:Executors.newSingleThreadExecutor():创建只有一个线程的线程池 Executors.newFixedThreadPool(int):创建固定线程的线程池 newScheduledThreadPool 创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行。 Executors.newCachedThreadPool():创建一个可缓存的线程池,线程数量随着处理业务数量变化。使用Executors.newCachedT
2021-06-28 21:54:29 69
原创 spring源码一 注册配置类
这里主要讲通过注解的方式去注册bean。从AnnotationConfigApplicationContext出发。看构造方法: public AnnotationConfigApplicationContext(Class<?>... componentClasses) { //调用无参构造函数,实现了GenericApplicationContext,会先调用GenericApplicationContext的构造函数 //父类的构造函数里面就是初始化Defau...
2021-06-28 20:45:52 203 1
原创 JAVA IO模型/NIO
阻塞IO模型最传统的一种IO模型,即在读写数据过程中会发生阻塞现象。当用户线程发出IO请求之后,内核会去查看数据是否就绪,如果没有就绪就会等待数据就绪,而用户线程就会处于阻塞状态,用户线程交出CPU。当数据就绪之后,内核会将数据拷贝到用户线程,并返回结果给用户线程,用户线程才解除block状态。典型的阻塞IO模型的例子为:data = socket.read();如果数据没有就绪,就会一直阻塞在read方法。非阻塞IO模型当用户线程发起一个read操作后,并不需要等待...
2021-06-28 10:36:57 82
原创 JVM内存模型
JVM 内存区域主要分为线程私有区域【程序计数器、虚拟机栈、本地方法区】、线程共享区域【JAVA堆、方法区】、直接内存。程序计数器(线程私有) 一块较小的内存空间, 是当前线程所执行的字节码的行号指示器,每条线程都要有一个独立的程序计数器,这类内存也称为“线程私有”的内存。 正在执行java方法的话,计数器记录的是虚拟机字节码指令的地址(当前指令的地址)。如果还是Native方法,则为空。 这个内存区域是唯一一个在虚拟机中没...
2021-06-26 00:38:55 89 1
原创 Spring 源码 Bean Definition 注册
Spring中调用一个BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry())方法把bean的definition描述注册。 public static void registerBeanDefinition( BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)...
2021-06-24 21:37:56 420 1
原创 ConCurrentHashMap在jdk1.8与1.7的变化
主要改变为:去除 Segment + HashEntry + Unsafe 的实现,改为 Synchronized + CAS + Node + Unsafe 的实现。Node 和 HashEntry 的内容一样,但是HashEntry是一个内部类。 用 Synchronized + CAS 代替 Segment ,这样锁的粒度更小了,并且不是每次都要加锁了,CAS尝试失败了在加锁。 put()方法中 初始化数组大小时,1.8不用加锁,将sizeCtl 这个变量置为-1,就表明table正在初始..
2021-06-24 19:15:57 285
原创 进程、线程之间的通信方式
一、进程间的通信方式管道( pipe ) 管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。 调用pipe函数,会在内核中开辟出一块缓冲区用来进行进程间通信,这块缓冲区称为管道,它有一个读端和一个写端。pipe函数接受一个参数,是包含两个整数的数组,如果调用成功,会通过pipefd[2]传出给用户程序两个文件描述符,需要注意pipefd[0]指向管道的读端, pipefd [1]指向管道的写端,那么此时这个管...
2021-06-24 11:32:31 1726
原创 Spring中@Component与@Bean的区别
Spring帮助我们管理Bean分为两个部分,一个是注册Bean,一个装配Bean。 完成这两个动作有三种方式,一种是使用自动配置的方式、一种是使用JavaConfig的方式,一种就是使用XML配置的方式。 @Component注解表明一个类会作为组件类,并告知Spring要为这个类创建bean。 @Bean注解告诉Spring这个方法将会返回一个对象,这个对象要注册为Spring应用上下文中的bean。通常方法体中包含了最终产生bean实例的逻辑。 @C...
2021-06-23 20:40:01 104
原创 ThreadLocal介绍
什么是ThreadLocal? ThreadLocal类顾名思义可以理解为线程本地变量。也就是说如果定义了一个ThreadLocal,每个线程往这个ThreadLocal中读写是线程隔离,互相之间不会影响的。它提供了一种将可变数据通过每个线程有自己的独立副本从而实现线程封闭的机制。它大致的实现思路是怎样的? Thread类有一个类型为ThreadLocal.ThreadLocalMap的实例变量threadLocals,也就是说每个线程有一个自己的ThreadLocalM...
2021-06-23 15:54:56 1504
原创 ArrayList和LinkedList
ArrayList和LinkedList在性能上各有优缺点,都有各自所适用的地方,总的说来可以描述如下:1.对ArrayList和LinkedList而言,在列表末尾增加一个元素所花的开销都是固定的。对ArrayList而言,主要是在内部数组中增加一项,指向所添加的元素,偶尔可能会导致对数组重新进行分配;而对LinkedList而言,这个开销是统一的,分配一个内部Entry对象。2.在ArrayList的中间插入或删除一个元素意味着这个列表中剩余的元素都会被移动;而在LinkedList的中间插入.
2021-06-23 10:26:37 61
原创 EXPLAIN用法和结果分析
idid相同,执行顺序由上至下 id不同,如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行 id相同不同,同时存在
2021-06-19 17:31:05 190
原创 MySQL的复制原理及流程
MySQL复制:为保证主服务器和从服务器的数据一致性,在向主服务器插入数据后,从服务器会自动将主服务器中修改的数据同步过来。主从复制的原理:主从复制主要有三个线程:binlog线程,I/O线程,SQL线程。binlog线程:负责将主服务器上的数据更改写入到二进制日志(Binary log)中。 I/O线程:负责从主服务器上读取二进制日志(Binary log),并写入从服务器的中继日志(Relay log)中。 SQL线程:负责读取中继日志,解析出主服务器中已经执行的数据更改并在从服务器中重
2021-06-19 17:07:55 663
原创 synchronized原理
1,JDK1.6之前synchronized是由一对monitor-enter和monitor-exit指令实现的。这对指令的实现是依靠操作系统内部的互斥锁来实现的,期间会涉及到用户态到内存态的切换,所以这个操作是一个重量级的操作,性能较低。2,JDK1.6之后JVM对synchronized进行了优化,改了三个经历的过程偏向锁-》轻量级锁-》重量级锁偏向锁:在锁对象保存一个thread-id字段,刚开始初始化为空,当第一次线程访问时,则将thread-id设置为当前线程id,此
2021-06-15 15:21:19 150 1
原创 谈谈Sleep和wait的区别
1,所属的类不同:sleep方法是定义在Thread上wait方法是定义在Object上2,对于锁资源的处理方式不同sleep不会释放锁wait会释放锁3,使用范围:sleep可以使用在任何代码块wait必须在同步方法或同步代码块执行4,与wait配套使用的方法void notify()Wakes up a single thread that is waiting on this object’s monitor.译:唤醒在此对象监视器上等待的单个线程void n
2021-06-15 15:00:37 131
原创 LinkedHashMap和HashMap的区别
主要关注几个点:1,初始化大小是16,如果事先知道数据量的大小,建议修改默认初始化大小。 减少扩容次数,提高性能 ,这是我一直会强调的点2,最大的装载因子默认是0.75,当HashMap中元素个数达到容量的0.75时,就会扩容。 容量是原先的两倍3,HashMap底层采用链表法来解决冲突。 但是存在一个问题,就是链表也可能会过长,影响性能于是JDK1.8,对HashMap做了进一步的优化,引入了红黑树。当链表长度超过8,且数组容量大于64时,链表就会转换为红黑树当红黑树的节点数量小于6时,会将
2021-06-15 11:40:34 164
原创 接口与抽象类的区别
相同点(1)都不能被实例化 (2)接口的实现类或抽象类的子类都只有实现了接口或抽象类中的方法后才能实例化。不同点(1)接口只有定义,不能有方法的实现,java 1.8中可以定义default方法体,而抽象类可以有定义与实现,方法可在抽象类中实现。(2)实现接口的关键字为implements,继承抽象类的关键字为extends。一个类可以实现多个接口,但一个类只能继承一个抽象类。所以,使用接口可以间接地实现多重继承。(3)接口强调特定功能的实现,而抽象类强调所属关系。(4)接口成...
2021-06-15 11:32:28 1112 1
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人