导图社区 Java核心基础面试总结
Java核心基础面试总结,包括JVM,锁,多线程等等。
编辑于2021-01-08 18:16:45Java核心基础
JVM
内存管理
JVM的内存模型
线程私有
Java栈
和线程的生命周期相同
一个线程中,每调用一个方法创建一个栈桢(Stack Frame)
栈桢的结构
本地变量表Loacl Variable
操作数栈Operand Stack
对运行时常量池的引用 Runtime Constant Reference
异常
线程请求的栈深度超过JVM允许深度 StackOverflowError
若JVM允许动态扩展,若无法申请到足够内存 OutOfMemortError
本地方法栈
异常
线程请求的栈深度超过JVM允许深度 StackOverflowError
若JVM允许动态扩展,若无法申请到足够内存 OutOfMemortError
程序计数器(PC寄存器)
指向JVM字节码指令的地址
唯一一个无OOM的区域
线程共享
方法区
运行时常量池(1.7之前放在方法区)
1.8之后没有了----->元空间代替
Java堆
新生代(1/3)
eden(8/10)
from survivor(1/10)
to survivor(1/10)
老年代(2/3)
永久代(1.8之后没有)
常量池
运行时常量池(1.7之后)
字符串常量池
异常(OOM)
JVM的垃圾回收
如何判断对象已经死亡?
引用计数法(会有循环引用问题,不推荐)
可达性分析算法(根搜索算法)
以GC Roots作为起点向下搜索,当一个对象和任何GC Roots没有引用链相连(两次才回收)
GC Roots
VM栈中的引用
方法区中的静态引用
JNI(Java本地方法引用)
Java中的四种引用
强引用(可达状态,不可回收)
软引用(内存不足才会回收)
弱引用(无论内存是否充足都回收)
虚引用(不能单独使用,必须和引用队列联合使用,跟踪对象被垃圾回收的状态)
垃圾回收算法
标记清除
效率低,内存碎片多
标记复制
新生代(MinorGC)
标记整理
老年代 (MajorGC)
分代回收
垃圾回收器
新生代
Serial
单线程,标记复制
ParNew
多线程,标记复制(Serial多线程版)
Parallel Scavenge
多线程,标记复制,可控制吞吐量(ParNew升级版)
老年代
Serial Old
单线程,标记整理
Parallel Old
多线程,标记整理
CMS
多线程,标记清除,获取最短垃圾回收停顿时间
初始标记
并发标记
重新标记
并发清除
G1
多线程,标记整理,不产生内存碎片
区域划分和优先级区域回收机制,低停顿时间
参数
Xms:初始堆内存
Xmx:最大堆内存
Xmn:年轻代内存,Sun官方推荐配置为整个堆的3/8
-XX:+PrintGCDetails
-XX:SurvivorRatio=8 设置年轻代中Eden区与Survivor区的大小比值 1:1:8
-XX:PretenureSizeThreshold=xxx
-XX:MaxTenuringThreshold
-XX:-HandlePromotionFailure
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/dump 配置dump文件输出路径
-XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=512m 设置元空间大小
JVM内存状况分析工具
jps:虚拟机进程状况工具
jstat:虚拟机统计信息监视工具
jinfo:Java配置信息工具
jmap:Java内存映射工具
jstack:Java堆栈信息跟踪工具
VisualVM:多合一故障处理工具
MAT:dump文件分析
1、配置JVM参数,OOM时指定路径生成DUMP文件
2、
Java类的加载机制
Java代码的执行
1、 Java 源文件(.java)—->编译器(javac)—->字节码文件(.class)
2、 字节码文件(.class)—->JVM—->机器码
双亲委派模型
类加载器
Application ClassLoader
Extension ClassLoader
Bootstrap ClassLoader
执行流程
调用自身的findLoadedClass()去内存中寻找这个类,然后通过AppClassLoader,如果找不到则会调用其父类加载器,即ExtClassLoader同样去内存中寻找,如果找不到则会再通过父类加载器即BootStrap来寻找,如果都没有找到则会一层一层返回,即BootStrap通过它自身定义的加载路径加载,如果加载不到则会通过ExtClassLoader根据自身定义的加载路径加载,如果加载不到则会通过AppClassLoader加载。如果都加载不到,会报出ClassNotFund异常。
作用
保证了使用不同的类加载器终得到的都是同样一个Object对象
Java并发
线程池Executor(不能用这个创建)
newCachedThreadPool 可缓存
newFixedThreadPool固定线程数
newScheduledThreadPool定时
newSingleThreadExecutor单个线程
乐观锁和悲观锁
乐观锁CAS
CAS的缺点
循环时间太长
ABA问题
1.5之后提供了一个类AtomicStampedReference来解决ABA问题
JVM涉及的类
原子类
AtomicLong
AtomicInteger
Random
LockSupport.park()
ConcurrentHashMap
悲观锁
死锁
产生条件
1.互斥条件
2.请求与保持条件
3.不可剥夺条件
4.循环等待条件
如何避免死锁
银行家算法
AQS
设计模式
创建型
1. 工厂模式:由子类决定要创建的具体类是哪一个
2. 抽象工厂模式:允许客户创建对象的家族,而无需指定他们的具体类
3. 单例模式:确保有且只有一个对象被创建
单例模式解决高并发的问题:采用双检锁 (读写锁)
4. 原型模式:clone, 深拷贝,浅拷贝
5. 建造者模式:隐藏具体的建造过程及细节
结构型
1. 适配器模式:封装对象,并提供不同的接口
2. 装饰者模式:给对象附加不同的责任或功能
3. 外观模式:简化一群类的接口
4. 组合模式:客户用一致的方式处理对象集合和单个对象
5. 桥接模式:抽象与实现分离以实现不同的
6. 代理模式:你的经纪人
7. 享元模式:共享技术,支持大量细粒度的对象
行为型
1. 策略模式:封装可以互换的行为,并使用委托来决定要使用哪一个。
2. 观察者模式:让对象能够在状态改变时被通知
3. 模板方法模式:由子类决定如何实现一个算法中的步骤
4. 命令模式:封装请求成为对象
5. 状态模式:封装了基于状态的行为,并使用委托在行为之间切换
6. 迭代器模式:在对象的集合之间游走,而不暴露集合的实现
7. 责任链模式:和链表有点像,每个责任者都保存了要设置的下一个处理对象的指针或引用
8. 中介者模式:联合国,处理各国纠纷
9. 解释器模式:编译器
10. 备忘录模式: 游戏存档
11. 访问者模式:最复杂的模式,适用于数据结构相对稳定的系统
数据库
MySQL
索引
原理
聚簇索引(InnoDB )
将主键组织到一棵 B+树中, 而行数据就储存在叶子节点上, 若使用"where id = 1"这样的条件查找主键, 则按照 B+树的检索算法即可查找到对应的叶节点, 之后获得行数据。 若对 Name 列进行条件搜索, 则需要两个步骤:
第一步在辅助索引 B+树中检索 Name, 到达其叶子节点获取对应的主键。
第二步使用主键在主索引 B+树种再执行一次 B+树检索操作, 最终到达叶子节点即可获取整行数据。
非聚簇索引(MyISAM)
非聚簇索引的两棵 B+树看上去没什么不同, 节点 的结构完全一致只是存储的内容不同而已, 主键索引 B+树的节点存储了主键, 辅助键索引B+树存储了辅助键。 表数据存储在独立的地方, 这两颗 B+树的叶子节点都使用一个地址指向真正的表数据, 对于表数据来说, 这两个键没有任何差别。 由于索引树是独立的, 通过辅助键检索无需访问主键的索引树。
explain分析优化
select_type(查询中每个select子句的类型)
(1) SIMPLE(简单SELECT,不使用UNION或子查询等)
(2) PRIMARY(查询中若包含任何复杂的子部分,最外层的select被标记为PRIMARY)
(3) UNION(UNION中的第二个或后面的SELECT语句)
(4) DEPENDENT UNION(UNION中的第二个或后面的SELECT语句,取决于外面的查询)
(5) UNION RESULT(UNION的结果)
(6) SUBQUERY(子查询中的第一个SELECT)
(7) DEPENDENT SUBQUERY(子查询中的第一个SELECT,取决于外面的查询)
(8) DERIVED(派生表的SELECT, FROM子句的子查询)
(9) UNCACHEABLE SUBQUERY(一个子查询的结果不能被缓存,必须重新评估外链接的第一行)
type(MySQL在表中找到所需行的方式,又称“访问类型”)
ALL:Full Table Scan, MySQL将遍历全表以找到匹配的行
index: Full Index Scan,index与ALL区别为index类型只遍历索引树
range:只检索给定范围的行,使用一个索引来选择行(阿里要求最少)
ref: 表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值(阿里建议最好达到)
eq_ref: 类似ref,区别就在使用的索引是唯一索引,对于每个索引键值,表中只有一条记录匹配,简单来说,就是多表连接中使用primary key或者 unique key作为关联条件
const、system: 当MySQL对查询某部分进行优化,并转换为一个常量时,使用这些类型访问。如将主键置于where列表中,MySQL就能将该查询转换为一个常量,system是const类型的特例,当查询的表只有一行的情况下,使用system
NULL: MySQL在优化过程中分解语句,执行时甚至不用访问表或索引,例如从一个索引列里选取最小值可以通过单独索引查找完成。
possible_keys
MySQL能使用哪个索引在表中找到记录,查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询使用
Key
key列显示MySQL实际决定使用的键(索引)
key_len
表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度(key_len显示的值为索引字段的最大可能长度,并非实际使用长度,即key_len是根据表定义计算而得,不是通过表内检索出的) 不损失精确性的情况下,长度越短越好
ref
上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值
rows
MySQL根据表统计信息及索引选用情况,估算的找到所需的记录所需要读取的行数
Extra
Using where:列数据是从仅仅使用了索引中的信息而没有读取实际的行动的表返回的,这发生在对表的全部的请求列都是同一个索引的部分的时候,表示mysql服务器将在存储引擎检索行后再进行过滤
Using temporary:表示MySQL需要使用临时表来存储结果集,常见于排序和分组查询
Using filesort:MySQL中无法利用索引完成的排序操作称为“文件排序”
(如果出现以上的两种的红色的Using temporary和Using filesort说明效率低)
Using join buffer:改值强调了在获取连接条件时没有使用索引,并且需要连接缓冲区来存储中间结果。如果出现了这个值,那应该注意,根据查询的具体情况可能需要添加索引来改进能。
Impossible where:这个值强调了where语句会导致没有符合条件的行。
Select tables optimized away:这个值意味着仅通过使用索引,优化器可能仅从聚合函数结果中返回一行
主题