Redis
过期、热 Key 问题
Redis 集群最少节点数
Redis
MySQL
事务、隔离级别、索引结构
Spring
aop 原理
@Transaction 注意事项
- 默认 Rollbackfor 为 RuntimeException 和 Error, 其它异常事务不会回滚
- 非 public 方法上使用 @Transaction,不会使用代理类,因此不会开启事务
- 内部没有加 @Transaction 方法调用 @Transaction 方法,不会使用代理类,因些不会开启事务
HashMap
如果解决 hash 冲突的问题
- Java 1.7 使用链表
- Java 1.8 使用链表和红黑树解决,当链表元素大于8时转为红黑树,当小于等于8时红黑树转为链表 为啥小于 8 用链表 从性能上讲小于 8 用红黑树,性能上也不会有提升,反而增加了节点旋转的难度
ConcurrentHashMap
如何实现并发安全的
- Java 1.7 采用的分段锁 Segment + HashEntry+ CAS,默认 Segment 大小是 16
- 采用 数组 + CAS + synchronized, 初始化、扩容、初始化首节点时采用 CAS,插入元素到链表采用 synchronized 锁住数组上节点,1.8 相对于 1.7 锁粒度更小,查询效率O(logn)比链表 O(n) 快很多
线程池参数说明
ThreadPoolExecutor
有7个参数:
- coreSize 核心线程数,常驻于线程池内
- maxSize 最大线程数
- BlockingQueue 阻塞队列
- keepAliveTime 大于核心线程数的线程保留时间
- timeUnit 保留时间单位
- threadFactory 线程工厂,由线程工厂创建线程
- rejectExecutionHandler 拒绝策略,当线程数大于最大线程时,采用的拒绝策略,ThreadPoolExecutor 内部提供了4种拒绝策略,AbortPolicy 抛出 RejectedExecutionException 给调用端,CallRunerPolicy 由调用方线程来执行,DiscardPolicy 静默放弃任务, DiscardOldestPolicy 先放弃队列中最早的任务,再提交当前任务到线程池中
线程池设置经验
AQS
AbstractQueueSynchronized
抽象的队列同步器
Java 内存模型
JMM
java 内存模型,定义并发编程的一组规范,除了抽象线程与主内存之间的关系,还规范了Java 源代码转化 CPU 指令要遵守的原则,目的是简化多线程编程,增强程序跨平台的可移植性。
并发编程三个重要特性
- 原子性 各种
lock
与synchronized
保障原子性, 各种原子类通过cas
保障原子性 - 可见性
synchronized
volatile
保障获取最新的变更,保障可见性 - 有序性 happens-before 原则之一 如
volatile
来禁止指令重排,保障有序性
JVM 内存结构
Java 存储变量、方法调用栈保存的结构分布
- 堆区 所有的对象实例和数组的内存区,所有线程共享区
- 栈区(Java 虚拟机栈) 线程独占的区域,线程创建时会分配一个栈空间,包含局部变量、操作数栈、方法出入口,进入方法和会在栈区保存一个栈帧,方法执行完成后,栈帧会从栈中弹出
- 方法区 保存类信息、常量、静态变量 所有线程共享
- 本地方法区 与栈区(Java 虚拟机栈)功能类似,区别是保存本地方法的栈
- 程序计数器 当前线程所执行的字节码行号指示器
- 直接内存(堆外内存)
堆区结构 新生代(Survivor 1: Survivor 1: Edon 8), 老年代
JVM 启动参数
通过 man java 可以了解到相关的命令行参数,主要分为三类
-
标准参数,所有版本都支持
-
-X 非标准参数,有些版本不支持,有些支持 -Xmx 等同于 -XX:MaxHeapSize 最大堆大小 -Xmn heap 新生代大小
-
-XX: 高级运行时参数
-
-XX: 高级 JIT 编译参数
-
-XX: 高级服务能力参数
-
-XX: 垃圾回收参数