Java知识脑图

Java知识脑图,高频知识点整理。

集合

HashMap

  • jdk1.7版本,底层是数组+链表,元素的插入使用头插法,可能形成逆序或环形链表。
  • jdk1.8版本,底层是数组+链表+红黑树,元素的插入使用尾插法。
  • 扩容机制:LoadFactory默认0.75,创建空数组重新Hash。
  • resize线程不安全:多线程之间put操作的覆盖;形成环形链表,get时陷入死循环。
  • hash方法混合高低位,降低冲突概率。
  • 2的幂次:1.7判断n-1&hash进行计算位置,2的幂次减少Hash碰撞,1.8判断新增位计算位置;此外,元素能够均匀分布在数组上。
  • 重写equals必须重写HashCode。
  • Tips:结扩危哈幂

ConcurrentHashMap

  • 安全失败:迭代器在拷贝的集合遍历,对原集合的修改不会抛出异常。
  • jdk1.7版本,底层是数组+链表,使用Segment分段锁,继承了可重入锁ReentrantLock,尝试获取锁时存在竞争,自旋,阻塞。get方法没有用锁,但是高效且同步,元素和节点指针用volatile修饰。HashEntry封装键/值对。
  • jdk1.8版本,底层是数组+链表+红黑树,使用CAS和synchronized同步,CAS->自旋->sync。Node封装键/值对。
  • Tips:结安锁得元。

ArrayList

  • 底层是数组,查找访问速度快,增删效率低,线程不安全。

LinkedList

  • 底层是双向链表,增删效率高,查找访问速度慢,线程不安全。


基础

UDP

  • 无连接,发送数据之前不需要建立连接。
  • 传输效率高,不保证可靠交付。

TCP

  • 三次握手:SYN,seq -> SYN,ACK,seq,ack -> ACK,seq,ack。防止过期的连接再次传到被连接的主机。
  • 四次挥手:FIN,seq -> ACK,seq,ack -> FIN,ACK,seq,ack -> ACK,seq,ack。

  • 可靠传输:重排序,丢弃重复数据,应答机制,超时重发机制,流量控制,拥塞控制。

Http和Https

Http Https
80端口 443端口
明文传输 SSL加密传输
无证书 CA申请证书
无状态连接 加密传输,身份认证

BIO

  • 没有线程可用时阻塞等待连接和数据传输。
  • 处理并发:创建线程执行连接请求。
  • 耗资源。

NIO

  • Channel,Selector,ByteBuffer组成。
  • Channel注册到Selector后监听,判断返回值处理请求和数据。

AIO

  • 无需轮询,IO操作的状态改变后,系统会通知相应的线程处理。

粘包和拆包

  • Nagle优化算法封包。

  • 报文末尾加入换行符表示完整信息。

  • 消息头声明长度,根据长度获取报文。

  • 规定报文长度,不足部分空位补齐。

多路复用

  • Select:监听的fd数量限制,轮询。
  • Poll:大量fd的数组拷贝,无大小限制,水平触发。
  • Epoll:没有并发连接数量的限制,利用文件映射内存加速与内存空间的消息传递,水平触发和边缘触发。

序列化

  • 对象实现Serializable接口,转换为字节流便于在网络上传输和保存在本地文件。


多线程

Synchronized

  • 对象:对象头(Mark Word,Class Point,Monitor),实例信息,对齐填充。
  • 同步方法:读取ACC_SYNCHRONIZED标志位实现。
  • 同步代码块:monitorenter,monitorexit。
  • 偏向锁:一个线程常常获得同一个锁。轻量级锁:线程少,持有锁的时间短,自旋等待锁释放。重量锁:没有持有锁的线程阻塞,防止空转。
  • 锁优化:锁的升级,偏向锁(不会主动释放)比较对象头和线程的threadID检查线程是否存活升级,轻量级锁自旋升级,重量级锁阻塞没有锁的线程,防止CPU空转;锁粗化,避免频繁加锁;锁消除,逃逸分析去除没必要的锁。
  • 类锁:修饰静态方法。对象锁:修饰方法或代码块。两者不冲突。

ThreadLocal

  • 指定线程存储数据。set,get方法。
  • 内存泄漏:存在弱引用的map,释放threadlocal的强引用后,map里面的value没有被回收。解决方法:调用threadlocal的remove方法。
  • 解决的问题:适用变量在线程中隔离,在方法中共享的场景;减少了临界区的范围;减少了线程的切换。

Lock

  • ReenTrantReadWriteLock: ReadLock的获取需要当前线程持有读(重入)/写(再次获取)锁,其他线程没有没有写锁;WriteLock的获取需要当前线程持有写锁,没有锁且CAS成功。写锁的个数为0才能认为锁释放成功。
  • ReentrantLock:非公平锁在调用lock后,会进行一次CAS抢锁,失败后和公平锁一样进入到tryAcquire方法,在该方法中,发现锁释放会再次CAS抢锁,公平锁会查看是否有线程在等待。
  • AQS(抽象队列同步器):核心机制基于CLH队列(不存在队列实例,仅存在节点关系)实现,将请求资源的线程封装成CLH队列的一个Node来实现锁的分配。实现共享资源state的获取和释放方式(acquire独享,acquireShared共享)定义独享(ReentrantLock)和共享(Semaphore)。
  • CAS:用CPU指令实现无锁的数据操作,提高效率。缺点:CAS长时间不成功会增加CPU开销;只能保证一个共享变量的原子操作,多个变量操作需要用到锁;ABA(AtomicStampedReference标志解决)。
  • StampedLock:乐观锁,相对于读写锁的改进在于,读的过程中允许线程获取写锁后写入。为了避免读取不一致的情况,需要判断读的过程中是否有写入。

volatile

  • MESI(缓存一致性协议):其他CPU存在变量副本时缓存行置为无效状态;锁bus;总线风暴,嗅探机制与CAS不断失败交互(部分使用Synchronized)。
  • 变量是volatile的,每次读变量都从内存中读取。
  • 可见性:线程修改变量值能立即同步到主内存,每次使用前从主内存中刷新。嗅探机制检查缓存是否过期,缓存行对应的内存地址修改则强制失效。
  • 有序性:禁止指令重排序;happens-before(volatile变量的写happens-before读);as-if-serial(单线程执行结果不变)。

线程池

  • 种类:newCachedThreadPool,newFixedThreadPool,newScheduledThreadPool,newSingleThreadExecutor。
  • 主要参数:核心线程数:线程进入工作队列,工作队列满时创建超过这个数量的线程;最大线程数空闲时间:线程数大于核心线程数时,未执行任务达到空闲时间则终止;缓冲队列:LinkedBlockingQueue;ArrayBlockingQueue;Synchronous。工厂方法:指定不同线程池类型;拒绝策略:缓存队列已满,线程达到上限。抛出异常,丢弃或丢弃最早的,重试;Hash表维护线程的引用;submit:使用future获取任务的执行结果。
  • 执行过程:核心线程->队列->最大线程->拒绝策略。
  • 运行状态:有volatile修饰的状态码;corePoolSize,maxPoolSize,largestPoolSize。
  • JUC: tools:工具类;executor:执行线程的工具;atomic:原子性包;locks:锁包;collections:线程安全的集合。
  • 线程间的通信:wait/notify机制;volatile修饰的全局变量;消息队列;事件。
  • ThreadLocal用于解决线程数据隔离问题。
  • 读写锁适用于读多写少的场景。
  • 生产者与消费者模式:锁;信号量;线程通信;阻塞队列。
  • 线程状态:新建,就绪,运行,阻塞,死亡。
  • CountDownLatch:原子计数器,调用CountDownLatch对象的countDown方法计数器为0时才执行await方法。
  • 垃圾清除算法:标记清除(老年代),扫描两次,空间碎片;标记复制(新生代);引用计数;标记整理。

JVM

JVM内存模型

  • 堆:对象。
  • 栈:局部变量,操作数栈,动态连接,方法的返回地址。
  • 方法区:常量,静态变量,类信息。
  • 本地方法栈:Native方法。
  • 程序计数器:字节码的访问地址。

类加载过程

  • 装载,链接(校验,准备,解析),初始化。

双亲委派机制

  • 父类加载,不重复加载。
  • 自定义–应用程序–扩展–启动。

分代回收

  • 新生代(Eden/s1/s2),老年代,永久代/元空间。
  • 晋升机制根据对象存活时间。

垃圾回收器

  • CMS:标记

  • G1

full gc

  • 老年代/永久代空间不足。
  • System.gc()方法。
  • 晋升老年代的大小大于老年代的剩余空间。

性能调优

  • 目的:减少gc,stw。
  • 方法:设置堆的最大最小值,调整新生代与老年代的比例,配置高可以设置并发收集算法。

oom种类

  • 对象太多没有释放。
  • 线程创建太多没有释放。
  • fd太多,一个进程1024个fd。

逃逸分析

  • 依据:对象被赋值给堆中对象的字段或类的静态变量;位于不确定的代码中。

JVM调优的情况

  • 线程死锁

  • 锁竞争

  • CPU过高

  • 内存泄露


Spring

设计模式

  • 单例:一个Spring Bean容器(SpringContext)中仅有一个实例。
  • 工厂:封装了创建Bean的过程,不通过new而是通过工厂来获取对象。
  • 适配器:转换类的接口。场景:第三方登录自由适配。
  • 责任链:Handler定义处理请求的借口;ConcreteHandler选择处理请求或者传递请求给下家。场景:让一个以上的对象有机会处理某个请求。

源码(略)

Bean生命周期

创建

  • 实例化Bean。

  • 注入Bean ID,Bean Factory或者ApplicationContext。

  • 调用前置初始化方法postProcessBeforeInitialization。

  • 调用afterPropertiesSet方法。

  • 调用Bean自身的初始化方法。

  • 调用Bean的后置初始化方法postProceeAfterInitialization。

销毁

  • 调用DisposableBean的destroy方法。

  • 调用自身定制的destroy方法。

Bean作用域

类别 说明
singleton 每个IOC容器中仅存在一个Bean实例
prototype 每次从容器中调用Bean时,会返回新的实例
request 每次Http请求会创建一个新的Bean,作用域仅适用于WebApplicationContext
session 同一个session共享一个Bean,作用域仅适用于WebApplicationContext

循环依赖

  • 两个以上的Bean互相持有对方:构造器的循环依赖;属性的循环依赖。

  • 解决方法:先从一级缓存singletonObjects获取对象,若获取不到且对象正在创建中,则从二级缓存earlySingletonObjects中获取对象,若获取不到对象,则从三级缓存singletonFactory.getObjects()获取。

  • 关键:调用构造器,根据对象引用定位到堆中的对象,提前曝光对象。

父子容器

  • Spring父容器(包含mapper,service,dao等),SpringMVC子容器(包含controller等)。
  • 子容器可以访问父容器中的对象,父容器不能访问子容器中的对象。

事务实现原理

  • 划分处理单元IOC:用Spring中的IOC划分事务处理单元,将对事务的各种配置放到了IOC容器中。
  • AOP拦截需要进行事务处理的类:生成代理对象,通过TransactionIntercepter完成对代理方法的拦截,将事务处理的功能编织到拦截的方法中。读取IOC事务配置属性,转化为事务处理所需要的内部数据结构。
  • 事务的处理实现:委托给具体的事务处理器(TransactionManager)实现。

AOP

  • 优点:面向切面编程,扩展功能不通过修改源代码实现。

  • 静态AOP:编译期,切面以字节码的形式直接编译到目标字节码中。

  • 动态AOP:运行期,类加载后,为接口实现动态代理类,将切面植入到动态代理类中。

IOC

  • 优点:控制反转,对象的创建交给Spring配置。

  • 步骤:创建配置文件,配置要创建的对象类;创建工厂类,解析配置文件+反射。

类加载机制

  • 过程:1、加载:生成class对象;2、验证;3、准备:static变量分配内存和初始值;4、解析:符号引用替换为直接引用;5、初始化:父类没初始化需先初始化。(家宴准解出
  • 双亲委派机制:避免重复加载,安全。

Redis

数据结构

  • String
  • Hash
  • set
  • zset:有序的集合
  • List

常见命令

  • Keys:查询
  • setnx:设置
  • experie:设置过期时间(秒)

高可用

  • 持久化:RDB持久化:保存某个时间点的全量数据快照。AOF持久化:保存除了查询以外更新数据库状态的指令。
  • 同步策略:主从同步:初始化阶段全量同步,初始化之后增量同步;快照同步:将内存数据映射到硬盘,恢复较快。
  • 哨兵:监控:检查主服务器是否运行正常;提醒:发送故障通知;自动故障迁移:主从切换。脑裂:配置从机数量与延迟时间。
  • 集群:数据分散存储。一致性Hash算法(沿着hash环顺时针定位到服务器)解决节点的动态增减问题虚拟节点解决数据倾斜问题

常见问题

过期策略

  • 定时删除:创建定时器
  • 惰性删除:获取键时检查键是否过期,过期则删除。
  • 定期删除:每隔一段时间定期检查,删除过期键。

淘汰机制

  • LRU:最近最少使用的淘汰算法。

备用方案

限流

选择方案

扩展

多路IO复用

  • 基于react设计模式监听IO事件。

MySql

分库分表

  • 分库:数据库扩展到多个物理节点。

  • 分表:表分块保存到不同数据库中。

事务隔离级别

  • 未提交读:出现脏读。
  • 已提交读:不可重复读。
  • 可重复读:幻读。
  • 串行化。

索引

  • B+树:IO次数少,查询性能稳定,范围查询更简便。

  • Hash:等值查询。

  • SQL优化:explain分析;排除缓存;添加索引;覆盖索引避免回表 ; 合理安排联合索引的顺序;最左前缀原则

  • 聚集索引:索引的逻辑顺序与存储的物理顺序相同。

  • 非聚集索引:回表问题,覆盖索引解决。

  • 索引维护:更新索引统级信息,删除索引碎片。

  • 唯一索引:第一个满足就返回。

  • 普通索引:满足一直查询,直到不满足。

  • 页:Innodb存储的基本结构。头部数据保存两个指针分别指向上下页,主体数据关注数据和索引的存储。

  • 索引的更新:

唯一索引 普通索引
记录要更新的页在内存中 没有冲突则插入值 插入值
记录要更新的目标页不在内存中 读取到内存中,没有冲突则插入值 将更新记录在chang buffer中

MVCC

  • 隐藏列:事务ID,回滚指针。回滚指针指向事务ID。

  • read view(可见性判断):通过回滚指针取出事务ID,比较事务ID,保证获取的版本是当前最稳定的版本。

  • 全局锁:全局逻辑备份。
  • 表锁:读锁不互斥,写锁互斥。
  • 行锁:两阶段锁协议,所有事务分两阶段对事务进行加锁和解锁。
  • gap锁(间隙锁):防止同一事务的两次当前读出现幻读。除了唯一索引的唯一搜索外都会获取gap锁或next-key锁(行锁+间隙锁)。
  • 读写锁。
  • 死锁(两种解决办法):超时检测:等待知道超时;死锁检测:发现死锁主动回滚某个事务。
  • 热点行:死锁消耗CPU,可临时关闭。控制并发度。分治。
  • Innodb如何加锁:Record lock:对索引项加锁。Gap lock:对索引项之间的间隙加锁;Next-Key锁:前两种的组合。

log

  • undo log:回滚行记录到某个版本。
  • redo log:记录数据页的物理修改,恢复提交后的物理数据页。
  • binlog:记录数据库增删改,用于数据恢复。
  • 两段式提交:先更新redo log,redo log设置为prepare状态;再更新bin log,redo log设置为commit。目的是两份日志同步。
  • 数据库主从同步延迟:主数据库负责数据的写,更新到从数据库;多个从数据库负责数据的读取。

Zookeeper

Zab协议

  • 恢复模式:选出leader。
  • 广播模式:同步保证leader和follower的状态相同。

选举机制

  • 第一轮投票默认投给机制。
  • 编号越大的server选择权重越大。
  • 投票数大于半数则胜出。

过半机制

  • 一半以上的server同意proposal才能成功。
  • 保证了数据的一致性。

2pc事务提交

  • 客户端发起写请求。
  • 如果是follower节点接收到则返回给leader。
  • leader将请求转化为proposal广播分发给follower。
  • 超过一半的follower执行成功,leader再次发送commit,要求follower提交上一个proposal。
  • leader节点将数据同步给observer节点。
  • follower节点将数据返回给客户端。

如何保持数据一致?

  • Follower通过队列和zxid等顺序保证请求的处理顺序。


分布式锁

Zookeeper

  • Zookeeper的节点递增性,可以规定节点编号最小的那个获得锁。
  • 节点的监听机制可以保证占有锁的方式有序且高效。
  • 避免羊群效应(节点挂掉时,所有节点监听)。

Redis

  • Redisson框架中的类库实现,性能较高。

要解决的问题

  • 互斥性:任意时间只能有一个客户端获取锁。

  • 安全性:锁不能由其他客户端删除。

  • 死锁:机制避免。

  • 容错:宕机时仍能释放和获取锁。


Dobbo


RocketMQ


算法

贪心

分治

动态规划

快排

堆排

二叉树

链表反转

成环

跳楼梯


扩展知识

自我介绍

项目亮点