java高频面试题持续更新中
2021-03-04 14:50:26 0 举报
AI智能生成
高频面试汇总
作者其他创作
大纲/内容
常见面试题
jvm
classForName("java.lang,String")和String classgetClassLoader()loadClass("jaca.lang.String")什么区别
手写下类加载器demo
线上发送频繁发送Full GC如何处理?CPU使用率过高怎么办?
介绍一下JVM内存模型?用过什么垃圾回收器
JVM老年代和新生代的比例?
YGC和FGC发生的具体场景
jstack,jmap,junil分别的意义?如何线上排查JVM的相关问题
新生代分几个区?是用什么算法进行垃圾回收?为什么使用这个算法?
讲讲类加载器机制,都有哪些类加载器,这些类加载器都加载了哪些文件?
JUC
线程池的工作原理,几个重要参数,然后分析几个参数线程池会怎么做,阻塞队列是什么?
Atomic类为什么用CAS而不是synchronized?
线程池的构造类的方法参数的具体意义
单机上一个线程池正在处理服务如果忽然断电怎么办?
使用无界阻塞队列会出现什么问题
线程池都有什么参数?底层如何实现的?
synchronized和lock什么区别?sychnize设么情况是对象锁?什么时候是全局锁为什么?
ThreadLocal是什么底层原理?如何实现?
volatile的工作原理?
reentrantlock实现原理,简单说下aqs
synchronized实现原理,monitor对象什么时候生成的?知道monitor的monitorenter和monitor两个怎么保证同步的嘛?或者说两个操作计算机底层是如何执行的
刚刚你提到了synchronized的优化过程,详细说一下偏向锁和轻量级锁有什么区别
线程池几个重要参数说一下,你们项目中如何根据实际场景设置参数,为什么cpu密集型设置线程少
Collection
java容器有哪些?那些是同步容器,哪些是并发容器
ArrayList和linkedList的插入和访问的时间复杂度
HashMap在什么情况下扩容,或者哪些操作会导致扩容
HashMap push方法的执行过程
HashMap检测到hash冲突后,将元素插入在链表的末尾还是开头?
1.8还采用了红黑树,讲讲红黑树的特性,为什么一定要用红黑树而不是AVL,B树之类的?
hashMap和hasTable底层实现什么区别?hashtable和concurrentHashTable呢?
HashMap和TreeMap有什么区别?底层数据结构是什么?
从集合开始,简单介绍一下常用的集合类,哪些是有序的,哪些是无序的
hashmap是如何寻址的,哈希碰撞后是如何存储数据的,1.8以后什么时候变成红黑树,说下红黑树原理,红黑树有什么好处
concurrentHashMap是如何实现线程安全的,一共有几个segment,java1.8后有优化concurrentHashMap吗?分段锁有什么坏处
Spring
详细描述SpringMvc处理请求流程?
Spring一个bean装配的过程?
接口如何处理重复请求?
java基础
java反射原理,注解原理?
Linux怎么查看系统负载情况?
请至少四种写法写一个单例模式
如何定位问题?如何解决说一下解决思路和处理方法
知道字节码嘛?字节码有哪些?Integer x=5,Integer y = 5,比较x=y都经过了哪些步骤?
知道osgi嘛?他是如何实现的
1.知识前提
2.Java基础
java字符串常量池
面试题
面试一
面试二
面试三
讲解
intern()
why
按照代码执行结果,java字符串答案为false
必然是两个不同的java,那另外一个java字符串如何加载进来的?
必然是两个不同的java,那另外一个java字符串如何加载进来的?
为什么?
有一个初始化的java字符串(jdk自带的),
在加载sum.misc.Version这个类的时候进入常量池
在加载sum.misc.Version这个类的时候进入常量池
OpenJDK8底层源码说明
地推步骤
system代码解析
类加载器和rt.jar
openJDK8
考点
intren()方法,判断true\false?
《深入裂解java虚拟机》书原题
字节跳动两数求和
面试题
给定一个数m,求大于该数的最小2的n次幂,返回n
leetCode的第一题tow-sum
字节跳动手写LRU算法
java三大特性
封装
继承
多态
线程
线程的状态
new
runnable-ready
runnable-runnig
blocked
waiting
timed_waiting
terminated
3.JUC多线程及高并发
①volatile是java虚拟机提供的轻量级同步机制
保证可见性
不保证原子性
机制指令重排
②JMM谈谈
规定
1线程解锁前,必须把共享变量的值刷新回主内存
2程序加锁前,必须把主内存的最新值刷新到为自己的工作内存
3加锁解锁是用一把锁
三大特性
1可见性
2原子性
3有序性
重排1
重排2
禁止指令重排
volatile如何实现禁止指令重排优化
内存屏障(Memory Barrier)
子主题
面试题
③你在哪些地方用过volatile?
单例模式CDL代码
子主题
④CAS你知道吗?
比较并交换
CAS底层原理?如果知道谈谈UnSafe的理解
CAS缺点
⑤ABA问题
什么是原子引用
如何解决aba问题
⑥ArrayList是线程不安全的,请编写一个不安全的案例并给出解决方案。
⑦公平锁\非公平锁\可重入锁\递归锁\自旋锁 谈谈你的理解,请手写一个自旋锁
公平锁和非公平锁
重入锁(递归锁)
独占锁\共享锁
子主题
⑧CountDownLatch\CyclicBarrier\Semaphore使用过吗?
CountDownLatch
让一些线程阻塞直到另一些线程完成一系列操作后被唤醒
CountDownLatch主要有两个方法,当一个或多个线程调用await方法时,调用线程会被阻塞
其他线程调用countDown()方法会将计数器-1,(调用countDown方法不会阻塞)
当计数器值清零时,因调用await方法被阻塞的线程会被唤醒,继续执行
其他线程调用countDown()方法会将计数器-1,(调用countDown方法不会阻塞)
当计数器值清零时,因调用await方法被阻塞的线程会被唤醒,继续执行
CyclicBarrier
Semaphore
⑨阻塞队列用过吗
BlockingQueue
ArrayBlockingQueue
LinkedBlockingQueue
PriorityBlockingQueue
DelayQueue
SynchronousQueue
LinkedTransferQueue
LinkedBlockingDeque
为什么需要BlockingQueue
架构
阻塞队列的核心方法
1、抛出异常
add
remove
element
2、特殊值
offer
peek
poll
3、阻塞
put
task
4、超时
offer(e,TimeUnit)
poll(timeUnit)
⑨Synchronized与新lock有什么区别,新Lock有什么好处?举例说明
原始构成:
1、synchronize是关键字属于JVM层面 monitor center(底层通过monitor对象来完成,其实wait\notify 等方法也依赖于monitor对象只有在同步块或方法中才能调用wait\notify等方法)
2、lock是具体类(java.util.concurrent.locks.Lock)是api层面的锁
1、synchronize是关键字属于JVM层面 monitor center(底层通过monitor对象来完成,其实wait\notify 等方法也依赖于monitor对象只有在同步块或方法中才能调用wait\notify等方法)
2、lock是具体类(java.util.concurrent.locks.Lock)是api层面的锁
使用方法:
1、Synchronized不需要用户去手动释放,当synchronized代码执行完后系统会自动让线程释放对锁的占用
2、ReentrantLock则需要用户手动释放锁,若没有主动释放锁,就可能导致出现死锁现象,严格需要Locl()和unLock()方法配合try\finally语句块来完成
1、Synchronized不需要用户去手动释放,当synchronized代码执行完后系统会自动让线程释放对锁的占用
2、ReentrantLock则需要用户手动释放锁,若没有主动释放锁,就可能导致出现死锁现象,严格需要Locl()和unLock()方法配合try\finally语句块来完成
等待是否可中断:
1、synchronized不可中断,除非抛出异常或者正常运行完成
2、ReentrantLock 可中断,1、设置超时时间trylock(long timeout,TimeUnit unit)
2、LockInterruptibly()放代码块中,调用interrupt()方法可中断
1、synchronized不可中断,除非抛出异常或者正常运行完成
2、ReentrantLock 可中断,1、设置超时时间trylock(long timeout,TimeUnit unit)
2、LockInterruptibly()放代码块中,调用interrupt()方法可中断
加锁是否公平
1、synchronize非公平锁
2、ReetrantLock两者都可以,默认非公平锁,构造方法可传入boolean值,true为公平锁,false为非公平锁
1、synchronize非公平锁
2、ReetrantLock两者都可以,默认非公平锁,构造方法可传入boolean值,true为公平锁,false为非公平锁
绑定多个条件Condition
1、synchronized没有
2、reentrantLock用来实现分组 唤醒需要唤醒的线程,而不像synchronized要么随机唤醒一个线程,要么全部唤醒
1、synchronized没有
2、reentrantLock用来实现分组 唤醒需要唤醒的线程,而不像synchronized要么随机唤醒一个线程,要么全部唤醒
⑩为什么要使用线程池
线程池七大主要参数
CoreThreadSize
MaxImumThreadSiz
KeepAliveTIme
TimeUtil
ThreadFactory
BlockingQueue
RejectedExecutionHandler
AboryPolicy
DicardPolicy
CallerRunsPolicy
DiscardOldestPolicy
线程池用过吗?ThreadPoolExecutor谈谈你的理解
线程池的拒绝队列
FixedThreadPool(给定数量的),SingleThreadExecutor(单个线程),CachedThreadPool(一个池N个处理线程)中你喜欢用哪一个?
线程池生产上你如何配置合理参数?
11死锁编码以及定位分析
产生死锁的主要原因
系统资源不足
进程运行推进
资源分配不当
测试代码
解决方法
jsp命令定位进程号
jstack找到死锁位置
12、重入锁
13、LockSupport
是一个类,属于java.util.concurrent包下的
线程等待唤醒机制(wait/notify)
三种线程等待唤醒的方法
synchronized
wait()
notity()
Lock
condition.await();
condition.signal();
LockSupport
park
unpark
差别
synchronized
其中wait和notify不能脱离 synchronized代码块
wait不能再notify后面(不能先唤醒在加锁,会出现锁未释放线程,唤醒的线程已经走到前面了)
只有notify和notifyAll只能随机唤醒一个或者全部唤醒,无法精确控制某个线程控制
Lock
必须要用lock,unlock组合
await必须在前signal之前
重点说明
面试题
为什么LockSupport可以先唤醒线程在阻塞线程?
为什么唤醒两次后阻塞两次,但最终结果还是阻塞?
14、AbstractQueueSynchronizer之AQS
前置内容!
公平锁非公平锁
可重入锁
LockSupport
自旋锁
数据结构链表
设计模式-模板设计模式
是什么?
抽象队列同步器
juc.util.concurrent.
juc.util.concurrent.
是用来构建锁和其他同步器组件的重量级基础架构及整个JUC体系的基石
通过内置的FIFO队列来完成对资源的获取和队列的工作,并且通过一个int类型变量表示持有锁的状态
通过内置的FIFO队列来完成对资源的获取和队列的工作,并且通过一个int类型变量表示持有锁的状态
AQS重要的原因
和AQS有关的
ReentrantLock
countDownLatch
ReentrantReadWriteLock
Semaphore
进一步理解锁合同器
锁
面向锁的使用者
定义了程序员与锁交互的使用层api,隐藏了实现细节,调用即可
同步器
面向锁的实现者
提出同一规范并简化锁的实现,屏蔽了同步状态管理、阻塞线程排队和通知、唤醒机制
AQS的原理
官方解释
有阻塞就需要排队,实现排队必须要有队列
ASA使用了一个volatile的int类型的成员变量来标识同步状态,通过内置的FIFO队列来完成资源获取的排队工作
将每条要去抢占资源的线程封装成一个Node节点来实现锁的分配,通过CAS完成对state值得修改。
将每条要去抢占资源的线程封装成一个Node节点来实现锁的分配,通过CAS完成对state值得修改。
实际上ReentrantLock、CountDownLatch等使用的图解
AQS源码解析
AQS自身
AQS的int变量
AQS的同步状态state成员变量
初始值为0,不为0即有人占用线程
银行帮里业务的受理窗口状态
0就是没有,自由状态
大于等于1,有人占用
ASQ的CLH队列
小总结
有阻塞就排队,实现排队用队列
state变量+CLH变种双端队列
AQS的Node
Node的int变量
Node的等待状态waitState成员变量
volatile int waitStatus;
解析
等候区其他线程(类似于顾客)的等待状态
队列中每个排队的个体就是一个Node
Node类的详解
从ReentrantLock开始解读AQS
Lock接口的实现类,基本都是通过【聚合】了一个【队列同步器】的子类完成线程访问控制
ReentrantLock的实现原理
公平锁 static final class FairSync extends Sync
非公平锁 static final class NonfairSync extends Sync
非公平锁与公平锁的区别
主要在于判断队列里是否有排队的 !hasQueuedPredecessors()
ReentrantLock基本三阶段
尝试加锁
加锁失败。线程进入队列
线程入队列后,进入阻塞状态
从ReentrantLock的lock和unlock开始
lock()
acquire()
tryAcquire()
addwaiter()
acquireQueued()
tryArquire(arg)
addWaiter(Node.EXCLUSIVE)
acquireQueued(addWaiter(Node.EXCLUSIVE),arg)
4.JVM+GC解析
简单复习
JVM体系概念
类加载器
运行时数据区
方法区
堆
伊甸园区
幸存区(0,1)
养老区
元空间
栈
本地方法栈
程序计数器
执行引擎
本地方法接口
java8后的JVM
GC的作用域
堆
方法区
常见的垃圾回收算法
标记清楚
引用计数
可达性分析
复制算法
标记整理
分代回收
面试题目1
1、JVM垃圾回收的时候如何确定垃圾?什么时GC roots
什么是垃圾?
内存中不在用到的空间,没有任何实例指向的内存空间(简单那说就是内存中不再被使用的空间就是垃圾)
要进行垃圾如何判断一个对象是否可以被回收?
引用计数法
GC roots:枚举根节点做可达性分析(根搜索路径)
case
子主题
拿一些对象可以作为GC roots对象
虚拟机栈(栈帧中的局部变量区,也叫做局部变量表)中引用的对象
方法区中的类静态引用的对象
方法区中常量引用的对象
本地方法栈中JNI(native方法)引用的对象。
子主题
2、你说你做过JVM调优和参数配置,请如何盘点查看JVM系统默认值
JVM的参数类型
标配参数
-version
-help
java -showversion
X参数
-Xint
-Xcomp
-Xmixed
XX参数
Boolean类型
公式
-XX:+ 或者-某个属性值
+代表开始
-表示关闭
-表示关闭
Case
jinfo -flag PrintGCDetails #ID
KV设值类型
公式
-XX:属性key=属性值value
case
-XX:MetaspaceSize=128m
-XX:MaxTenuringThreshold=15
jinfo举例,如何查看当前运行程序的配置
case
题外话(坑题)
两个经典参数
-Xms
等价于-XX:InitialHeapSize
-Xmx
等价于-XX:MaxHeapSize
盘点家底产看JVM默认值
-XX:+PrintFlagsInitial
主要查看jvm初始默认值
公式
java -XX:+PrintFlagsInitial
case
-XX:+PrintFlagsFinal
主要查看修改跟新值
公式
java -XX:+PrintFlagsFinal -version
case
PrintFlagsFinal距离,运行java命令的同时打印出参数
-XX:PrintCommandLineFlags
case
3、你平时工作用过的JVM常用基本参数有哪些?
-Xmx
-Xms
-Xmn
-Xss
case1
case2
-XX:MetaspaceSize
设置元空间大写
元空间的本质和永久代类似,都是对JVM规范中方法去的实现
不过元空间与永久代之间最大的区别在于:
元空间并不存在于虚拟机中,二十使用本地内存。
因此在默认情况下,元空间的大小受制于本地内存限制
不过元空间与永久代之间最大的区别在于:
元空间并不存在于虚拟机中,二十使用本地内存。
因此在默认情况下,元空间的大小受制于本地内存限制
-Xms1G -Xmx1G -XX:metaspaceSize=1G -XX:+PrintCommandLineFlags -XX:ThreadStackSize1G -XX:+PrintGCDetails -XX:+UseSerialGC
-XX:+PrintGCDetails
case
case2
-XX:SurvivorRatio
-XX:NewRatio
-XX:MaxTenuringThreshold
-XX:UseSerialGC
-XX:UseParallelGC
4、强引用、软引用、弱应用、虚引用
整体架构
强引用
读取图片
谈谈WeakHashMap?
软引用
弱引用
引用队列
5、请谈谈堆OOM的认识
java.lang.StackOverFlowError
java.lang.OutOrMemoryError:java heap space
java.lang.OutOfMemoryError: GC overhead limit exceeded
java.lang.OutOfMemoryError: Direct buffer memory
java.lang.OutOfMemoryError: unable to create new native thread
java.lang.OutOfMemoryError: metaspace
6、GC垃圾回收算法和垃圾收集器的关系,分别是什么请你谈谈
GC算法(引用计数/复制/标清/标整)是内存回收的方法论,垃圾回收器就是算法的落地实现
因为目前位置还没有完美的收集器出现,更加没有万能的收集器,只是针对具体应用最合适的收集器,进行分代收集
4中主要的垃圾回收器
Serial(串行垃圾回收器)
Parallel(并行垃圾回收器java8默认)
CMS(ConcMarkSweep并发垃圾回收器)
G1垃圾回收器
ZGC(java11后推出的)
7、怎么查看服务器默认的垃圾回收器?
生产上如何配置垃圾收集器?
谈谈你堆垃圾收集器的理解?
生产上如何配置垃圾收集器?
谈谈你堆垃圾收集器的理解?
怎么查看默认的垃圾回收器
java的GC类型主要有
UseSerialGC
UseParallelGC
UseConcMarkSweepGC
UsParNewGC
UseParallelOldGC
UseG1GC
垃圾收集器
部分参数预先说明
DefNew
default new generation
Tenured
old
ParNew
parallel New Generation
PSYounGen
Parallel Scavenge
ParOldGen
Parallel Old Generation
Server/client模式
7中GC
新生区
Serial Copying
Parallel Scavenge
ParNew
G1
老年代
Serial MSC(Serial Old)
Parallel Compaction
(parallel Old)
(parallel Old)
CMS
G1
新生代
串行GC(Serial)/(Serial Copying)
并行GC(ParNew)
并行回收GC(Parallel)/(parallel Scavenge)
老年代
串行GC(Serial Old)/(Serial Msc)
并发GC(Parallel Old)/(Parallel MSC)
并发标记清楚GC(CMS)
复习标记清楚
4步过程
初始标记(Initial Mark)
并发标记(concurrent Mark)
重新标记(remark)
并发清楚(concurrent sweep)
优缺点
java8以后的具体落地实现
如何选择垃圾回收器?
8、G1垃圾回收器
G1垃圾回收器横跨两区G1区和元空间
以前的垃圾回收器设计原则
年轻代和老年代是各自独立且连续的内存块
老年代收集使用单eden+s0+s1进行复制算法
老年代收集必须扫描整个老年代区域
都是以尽可能少儿快速的GC为设计原则
G1是什么?
特点
1、G1能充分利用多CPU、多核环境硬件优势,尽量缩短STW
2、G1整体采用标记-整理算法,局部通过复制算法,不会产生碎片
3、宏观上看G1之中不再区分年轻代和老年代,把内存划分成多个独立的子区域(Region),可以近似理解为一个围棋的棋盘
4、G1收集器里面讲整个的内存区都混合在一起了,但其本身依然在小范围内需要进行年轻代和老年代的区分,保留了新生代和老年代,但他们不再是物理隔离的,而是一部分Region的集合且不需要Region是连续的,也就是说依然会采用不同的GC方式来处理不同的区域。
5、G1虽然也是分带收集器,但整个内存分区不存在物理上的年轻代和老年代的区别,也不需要完全独立的Survivor(to spacs)堆做复制准备,G1只有逻辑上的分代概念,或者说每个分区都可以随G1的运行在不同代间前后切换。
底层原理
Region区域化垃圾收集器
最大的好处化整为零,避免全内存扫描,只需要按照区域来进行扫描
子主题
变化
回收步骤
初始标记
并发标记
最终标记
筛选回收
G1基本参数
-XX:+UseG1Gc
-XX:+G1HeapRegionSize=n
设置GC区域的代销,值是2的幂,范围1MB-32Mb,目标是根据最小的
-XX:MaxGCPauseMillis=n
最大GC的停顿时间,这个是个软目标,JVM尽可能(但不保证)停顿时间小于这个时间
-XX:InitiationHeapOccupacyPercent=n
对占用多少时触发GC,默认为45
-XX:COncGCThreads=n
并发GC使用的线程数
-XX:G1ReservePercent=n
设置作为空闲时间的预留内存百分比,以降低目标空间溢出的风险,默认值为10%
与CMS的相比的优势
1没有内存碎片
2可是设置预期停顿时间
9、生产服务器变慢,诊断思路和性能评估
整机:top
load avergae
三个值分别代表系统一分钟,五分钟,十五分钟的负载值,如果三数相加除以3超过60 则代表负载较高
不停按1
可以查看每个cpu的性能
uptime
top的精简版
CPU:vmstat
vmstat -n 2 3
一般vmstat工具使用是同通过两个数字来完成的,第一个参数是采样时间的时间间隔单位是秒,第二个是采样的次数
其中procs
r:运行和等待CPU时间切片的进程数,原则上1核的CPU的运行队列不要超过2,整个系统的运行队列不能超过总核数的两倍,否则代表压力过大
b等待资源的进程数,比如正在等待磁盘I\O网络I/O等
cpu
us:用户进程小号CPU的时间百分比,US值越高,用户进程消耗的CPU时间多,如果长期大于50%,优化程序
sy:内核进程消耗的CPU时间百分比
内存:free
硬盘:df
磁盘io:ipstat
网络io:ifstat
整体思路
第一
top
查看占用最高进程
第二
ps -mq ${PID} -o THREAD,tid,time
查询占用最高的进程的哪些线程使用高
第三
jsatck ${PID} |grep ${TID} -A60
10、git操作
常用词含义
work
会持续收到该项目的动态
fork
复制某个项目到自己的github仓库中
stat
收藏点赞
clone
讲项目下载至本地
follow
关注你感兴趣的作者,会受到他们的动态
5.消息中间件
Spring
IOC
AOP
AOP的常用注解
@Before
前置通知:执行目标方法前执行
@After
后置通知:方法执行后执行(始终执行,无论是否异常)
@AfterRunning
返回后通知:方法执行后通知,发生异常不执行
@AfterThrowing
返回后通知:方法执行后通知,未发生异常不执行
@Aroud
环绕通知:前后都通知
AOP顺序
循环依赖
TX
更新日志
更新日志
Spring事务管理
1数据库事务特性
ACID特性
原子性
一致性
隔离性
持久性
事务的隔离级别
oracle
read commit
mysql
repa
0 条评论
下一页