一、Java
1.Java 集合框架
1 Map
- 基本字段信息
- 默认最大容量
- 负载因子
- 哈希桶(无法反序列化)
- 哈希表结构
- 节点结构(Node)
- 扰动函数 hash() 取模运算
- resize() 扩容两步走 1 依据旧tab容量和阈值,对当前tab的扩容操作 2 遍历旧tab迁移至新tab
- putVal()
- 下标的取模运算 hash & length -1
- 哈希冲突
- 尾插法
- 如何认定hash冲突
2 Collection
2.Java 并发
1 基本概念
- 线程安全性
- 线程安全性实现方式
- 互斥同步
- 非阻塞同步
- 无同步方案(对象不共享/线程本地变量/不可变对象) 2 锁理论
- 自旋锁
- 简单自旋锁
- 排队自旋锁
- CLH锁
- MCS锁
- 偏向锁
- 可重入锁
- CAS导致Cache一致性流量问题 3 线程实现
- Thread
- Runnable
- Callable 4 原生同步
- 同步代码块
- synchronized 偏向锁
- wait
- notify
- notifyAll
- 其他线程方法
- join
让其他线程先执行,执行完毕之后,再执行当前线程 - yield
理解为将线程置为runnable状态,等待cpu重新调度 - sleep
阻塞当前线程,但是不会释放锁 - wait
阻塞当前线程,并释放锁
- join
- 原生锁优化
- 锁粗化(升级)
- 锁清除
- 轻量级锁
- 偏向锁
- 自旋锁与自适应锁
- 重量级锁(操作系统层级)
- volatile
- 可见性
- 防止指令重排 5 juc多线程支持体系
- lock
- Lock -- RentranceLock
- Condition
- ReadWriteLock -- RentranceReadWriteLock
- atomic
- collections
- executor
- tool
- 实现关键
- AbstractQueueSynchronizer(AQS)
- LockSupport.park/unpark
3.Java 虚拟机
一 JVM概念
1 编译执行过程
二 Java内存区域
1 运行时数据区
2 虚拟机对象
三 垃圾收集器与内存分配策略
1 可达性分析
- 可作为root节点的对象 (口诀:两区两栈)
- 本地方法栈引用对象
- 虚拟机栈(栈帧中本地变量表)中引用对象
- 方法区静态字段引用对象
- 方法区常量引用对象
- gc算法
- 标记-清除
- 复制
- 标记-整理
- 分代回收
4 gc回收器 - Serial收集器
- ParNew收集器
- Parallel Scavenge收集器
- Serial Old收集器
- Parallel Old收集器
- CMS 收集器
- 初始标记
- 并发标记
- 重新标记
- 并发清除
- 该收集器的优缺点
- G1 收集器
5 内存分配与回收策略
- 优先Eden区分配
- 大对象怎么分配
- 长期存活对象怎么处理
- 空间分配担保机制
四、虚拟机类加载机制
1 类加载过程
2 类加载器
五、Java内存模型与线程
1 Java内存模型
2 Java与线程
六、线程安全与锁优化
1 线程安全
2 锁优化
4.Java IO
1 Java BIO
- 字节流
- InputStream
- OutputStream
- 字符流
1 Java NIO
- 基本概念&模型
- Channel
- Buffer
- Selector
5.Java 基础知识
1 Java 泛型
-
Java泛型类
-
Java泛型接口
-
Java泛型方法
-
Java泛型擦除
- 原理
在编译过程中,类型变量的信息是能拿到的。所以,set方法在编译器可以做类型检查,非法类型不能通过编译。但是对于get方法,由于擦除机制,运行时的实际引用类型为Object类型。为了“还原”返回结果的类型,编译器在get之后添加了类型转换。所以,在GenericHolder.class文件main方法主体第18行有一处类型转换的逻辑。它是编译器自动帮我们加进去的。
- 原理
-
Java泛型通配符
- 上界通配符 <? extends T>
- 下界通配符 <? super T>
- PECS原则
- 上界<? extends T>不能往里存,只能往外取,适合频繁往外面读取内容的场景
- 下界<? super T>不影响往里存,但往外取只能放在Object对象里,适合经常往里面插入数据的场景
- 无限通配符<?>
2 Java 反射
3 Java 注解
4 Java 异常
-
Error
-
非受检异常
-
概念
RuntimeException及其子类都统称为非受检查异常 -
范围
- NullPointExecrption、NumberFormatException(字符串转换为数字)
- ArrayIndexOutOfBoundsException(数组越界)、ClassCastException(类型转换错误)
- ArithmeticException(算术错误)
-
-
受检异常
-
概念
编译器在编译时,对于受检异常必须进行try...catch或throws处理,否则无法通过编译 -
范围
- SQLException
- ClassNotFoundException
- IO操作、线程操作中的异常等等
-
-
异常限制
-
规则一:
子类在重写父类抛出异常的方法时,要么不抛出异常,要么抛出与父类方法相同的异常或该异常的子类。如果被重写的父类方法只抛出受检异常,则子类重写的方法可以抛出非受检异常。 -
规则二:
子类在重写父类抛出异常的方法时,如果实现了有相同方法签名的接口且接口中的该方法也有异常声明,则子类重写的方法要么不抛出异常,要么抛出父类中被重写方法声明异常与接口中被实现方法声明异常的交集。
-
-
构造器中的异常
-
背景:
如果一个构造器中就发生异常了,那我们如何处理才能正确的清呢?也许你会说使用finally啊,它不是一定会执行的吗?这可不一定,如果构造器在其执行过程中遇到了异常,这时候对象的某些部分还没有正确的初始化,而这时候却会在finally中对其进行清理,显然这样会出问题的。 -
原则: 对于在构造器阶段可能会抛出异常,并且要求清理的类,最安全的方式是使用嵌套的try子句。(try中有try)
-
5 Java 序列化
-
概念
将对象表示成一系列有序字节,Java提供了将对象写入流和从流中恢复对象的方法。对象能包含其它的对象,而其它的对象又可以包含另外的对象。Java序列化能够自动的处理嵌套的对象。 -
意义
序列化机制允许将实现序列化的Java对象转换位字节序列,这些字节序列可以保存在磁盘上,或通过网络传输,以达到以后恢复成原来的对象。序列化机制使得对象可以脱离程序的运行而独立存在。 -
transient关键字
-
serialVersionUID
二、Web开发框架
1.Mybatis
1 MyBatis初始化过程
2 Mybatis缓存
- 一级缓存
-
SESSION 在一个MyBatis会话中执行的所有语句,都会共享这一个缓存
-
STATEMENT 可以理解为缓存只对当前执行的这一个
Statement有效 -
Executor
-
Cache接口
- CacheKey
-
总结
- MyBatis一级缓存的生命周期和SqlSession一致。
- MyBatis一级缓存内部设计简单,只是一个没有容量限定的HashMap,在缓存的功能性上有所欠缺。
- MyBatis的一级缓存最大范围是SqlSession内部,有多个SqlSession或者分布式的环境下,数据库写操作会引起脏数据,建议设定缓存级别为Statement。
-
- 二级缓存 二级缓存开启后,同一个namespace下的所有操作语句,都影响着同一个Cache,即二级缓存被多个SqlSession共享,是一个全局的变量。
当开启缓存后,数据的查询执行的流程就是 二级缓存 -> 一级缓存 -> 数据库。
- 总结
-
MyBatis的二级缓存相对于一级缓存来说,实现了
SqlSession之间缓存数据的共享,同时粒度更加的细,能够到namespace级别,通过Cache接口实现类不同的组合,对Cache的可控性也更强。 -
MyBatis在多表查询时,极大可能会出现脏数据,有设计上的缺陷,安全使用二级缓存的条件比较苛刻。
-
在分布式环境下,由于默认的MyBatis Cache实现都是基于本地的,分布式环境下必然会出现读取到脏数据,需要使用集中式缓存将MyBatis的Cache接口实现,有一定的开发成本,直接使用Redis、Memcached等分布式缓存可能成本更低,安全性也更高。
-
2.Spring
三、数据库
1.MySQL
- 事务
- 事务概念
事务是一系列操作组成的工作单元,该工作单元内的操作是不可分割的,即要么所有操作都做,要么所有操作都不做,这就是事务。
理解一:事务可以看做是一次大的活动,它由不同的小活动组成,这些活动要么全部成功,要么全部失败。
理解二:事务可以看做是一个大的操作,它由一系列操作组成,这些操作要么全部成功,要么全部失败。
- 事务分类
- 本地事务
由于应用主要靠关系数据库来控制事务,而数据库通常和应用在同一个服务器,所以基于关系型数据库的事务又被称为本地事务
- 数据库事务
在计算机系统中,更多的是通过关系型数据库来控制事务,这是利用数据库本身的事务特性来实现的,因此叫数据库事务
- 分布式事务
分布式系统会把一个应用系统拆分为可独立部署的多个服务,因此需要服务与服务之间远程之间远程协作才能完成事务操作, 这种分布式系统环境下由不同的服务之间通过网络协作完成事务称为分布式事务。
-
事务特性
-
A(Atomicity):原子性,指事务是一个不可分割的工作单位,事务中的操作要么全部成功,要么全部失败。比如在同一个事务中的SQL语句,要么全部执行成功,要么全部执行失败
-
C(Consistency):一致性,事务必须使数据库从一个一致性状态变换到另外一个一致性状态
-
I(Isolation):隔离性,多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
-
D(Durability):持久性,一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。
-
-
事务隔离级别(针对隔离性)
- 读未提交
- 读已提交
- 可重复读
- 串行化
-
如何实现持久化
- Buffer Pool(将B+树中叶子节点数据,即页,读入Buffer Pool) 所有更改操作在Buffer Pool完成
- 脏页刷回
- 更新操作同步会记录redo_log_buffer, 再由fsync()写入redo_log
- 总结:同步写日志,异步写数据文件
2 数据库引擎 InnoDB
- 特性
- 支持事务
- 支持外键
- 支持MVCC
- 支持行级锁
- 不会记录行数,需要全表扫描
3 数据库索引
- 索引数据结构
- B+树索引
- 具体的数据结构
- 聚簇索引 底层数据结构
- 辅助索引 底层数据结构与聚簇索引的区别(叶子节点)
- 索引覆盖
- 如何避免回表查询
- B+树索引
4 数据库日志
- redo_log
- undo_log
- bin_log
5 InnoDB 如何实现MVCC
- 事务Id(trx_id),版本号
- 回滚指针(roll_point) 形成版本链
- 过程原理
- 事务创建时,形成快照
6 锁机制 - 锁分类:读锁/写锁,行锁/表锁/页面锁 - InnoDB - 行锁 - 表锁
7 分库分区分表
8 主从复制
2.分布式数据库
四、算法
1.基本排序算法
- O(n^2)
- 冒泡排序(基本原理及其优化手段,记下标,flag)
- 选择排序(基本原理,两层for循环,每次找出最大元素下标,外层for循环交换)
- 插入排序(基本原理,如同打牌,从第二个元素开始,两层for循环,外层用于插入合适的位置,内层用于找出合适的位置)
- O(nlogn)
- 堆排序(完全二叉树的知识点,三个步骤)
- 1 构建大顶堆,
- 2 大顶堆堆顶调至末尾
- 3 调整大顶堆
- 4 要点1:对于完全二叉树中的第 i 个数,它的左子节点下标:left = 2i + 1
- 5 要点2:对于完全二叉树中的第 i 个数,它的右子节点下标:right = left + 1
- 6 要点3:对于有 n 个元素的完全二叉树(n≥2),它的最后一个非叶子结点的下标:n/2 - 1
- 快速排序
- 归并排序
- 堆排序(完全二叉树的知识点,三个步骤)
- O(n)
- 计数排序
- 基数排序
2.动态规划
3.刷题心得
- 树
- 三种遍历
- 前、中、后序 递归模板
- 层序遍历
- 借助队列,层序输出及其变形(锯齿、逆向等)
- 借助集合
- HashSet记录节点值做遍历
- 二叉搜索树特性
- 二叉树的构建
- 三种遍历
- 链表
- 快慢指针
五、数据结构
1.数组
2.栈
3.链表
4.队列
5.树
6.图
7.哈希表
六、中间件
1.消息中间件
1 消息中间件概念
2 消息中间件意义
3 常见的消息中间件
- Kafka
- RocketMq
2.缓存中间件
1 Redis
- 数据结构与对象
- SDS
- 链表
- 字典
- 跳跃表
- 整数集合
- 压缩列表
- 对象
- 数据库
- 键的过期时间或生存时间
- 过期键删除策略
- 定时删除
- 惰性删除
- 定期删除
- Redis过期键删除策略
- 惰性删除
- 定期删除
2 分布式锁
- 基于Redis分布式锁
- 实现原理
- 实现方案
- 集群环境与单机环境下实现要点
- Redission/RedLock算法
- 数据库
- ZooKeeper
3.限流工具
- 常见限流算法
- 计数器(存在临界问题)
- 滑动窗口(细分周期,按时滑动,解决临界问题)
- 漏桶算法(任意流入,固定流出)
- 令牌桶算法
- 常见限流中间件
- Sentinel
4.熔断工具
- Spring Cloud Hystrix