2019JAVA面试
2020-12-23 11:03:39 0 举报
AI智能生成
java面试
作者其他创作
大纲/内容
1.前提知识+要求
2.Java基础
3.JUC多线程以及高并发
1.请谈谈你对volatile的理解
1.volatile是Java虚拟机体提供的轻量级的同步机制
1.1保证可见性
1.2不保证原子性
1.3禁止指令重排
2.谈谈JMM(Java内存模型)
2.1可见性
2.2原子性
n++在多线程下是非线程安全的,如何不加synchronized解决?
2.3volatileDemo代码演示可见性+原子性代码
2.4有序性
重排1
重排2
禁止指令重排小结
3.你在哪些地方用到过volatile?
3.1单例模式DCL代码
3.2单例模式volatile分析
2.CAS你知道吗?
1.比较并交换(Conmpare And Swap)
CASDemo代码
2.CAS底层原理?如果知道,谈谈你对UnSafe的理解
atomicInteger.getAndIncrement();(自旋锁)
使用了Unsafe类
CAS是什么
unsafe,getAndAddInt
底层汇编
简单版小结
3.CAS缺点
循环时间长开销很大
只能保证一个共享变量的原子操作
引出ABA问题??
3.谈谈原子类AtomicInteger的ABA问题?原子更新引用知道吗?
ABA问题是怎么产生的?
原子引用
时间戳原子引用
4.我们知道ArrayList是线程不安全的,请编写一个不安全的案例并给出解决方案。
解决方案一
限制不可以用Vetor和collections工具类,解决方案二
以上方法对其他集合也有效
5.公平锁/非公平锁/可重入锁/递归锁/自旋锁/谈谈你的理解?请手写一个自旋锁
公平和非公平锁
是什么
两者区别
题外话
可重入锁(又名递归锁)
是什么
ReentranLock/Synchronized就是一个典型的可重入锁
可重入锁最大的作用就是避免死锁
ReenterLockDemo
参考1
参考2
自旋锁
SpinLockDemo
独占锁(写锁)/共享锁(读锁)/互斥锁
ReadWriteLockDemo
6.CountDownLatch/CyclicBarrier/Semaphore使用过吗?
CountDownLatch
让一些线程阻塞直到另一些线程完成一系列操作后才被唤醒
CountDownLatch主要有两个方法,当一个或多个线程调用await方法时,调用线程会被阻塞。其他线程调用countDown方法会将计数器减1(调用countDown方法的线程不会阻塞),当计数器的值变为零时,因调用await方法被阻塞的线程会被唤醒,继续执行。
Count DownLatchDemo
CyclicBarrier
CyclicBarrier的字面意思是可循环使用的屏障。它要做的事情是,让一组线程到达一个屏障(也可以叫做同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活,线程进入屏障通过CyclicBarrier的await()方法。
CyclicBarrierDemo
Semaphore
信号量主要用于两个目的,一个是用于多个共享资源的互斥使用,用一个用于并发线程数的控制
SemaphoreDemo
7.阻塞队列知道吗
队列+阻塞队列
为什么要用?有什么好处?
BlockingQueue的核心方法
架构梳理+种类分析
架构介绍
种类分析
ArrayBlockingQueue:由数组结构组成的有界阻塞队列。
LinkedBlockingQueue:由链表结构组成的有界(但大小默认为Integer.MAX_VALUE)阻塞队列
PinorityBlockingQueue:支持优先级排序的无界阻塞队列。
DelayQueue:使用优先级队列实现的延迟无界阻塞队列。
SynchronousQueue不存储元素的阻塞队列,也就是单个元素的队列
理论
SynchronousQueueDemo
LinkedTransferQueue:由链表结构组成的无界阻塞队列。
LinkedBlockingDeque:由链表结构组成的双向阻塞队列。
用在哪里?
生产者消费者模式
传统版
ProdConsumer_TradtionDemo
阻塞队列版
ProdConsumer_BlockQueueDemo
线程池
消息中间件
Sychronized和lock有什么区别?用新的Lock有什么好处?举例说说
8.线程池用过吗?ThreadPoolExecutor谈谈你的理解
为什么使用线程池,优势
线程池如何使用?
架构说明
编码实现
了解
Executors.newScheduledThreadPool()
JDK1.8 Executors.newScheduledThreadPool(int)
java8新增,使用目前机器上可用的处理器作为它的并行级别
重点!(底层是什么)
Executors.newFixedThreadPool(integer);
执行长期的任务,性能好很多
Executors.newSingleThreadExecutor();
一个任务一个任务执行的场景
Executors.newCachedThreadPool()
适用:执行很多短期异步的小程序或者负载比较轻的服务器
ThreadPoolExecutor
线程池的几个重要参数介绍?
7大参数
int corePoolSize
线程池中的常驻核心线程数
int maximumPoolSize
线程池能够容纳同时执行的最大线程数,此值必须大于等于1
long keepAliveTime
多余的空闲线程的存活时间。线程池数量超过 core poolsize时,当空闲时间达到 keepAliveTime值时
多余空闲线程会被销毁直到只剩下 core Poolsize个线程为止
多余空闲线程会被销毁直到只剩下 core Poolsize个线程为止
TimeUnit unit
keepAliveTime的单位
BlockingQueue<Runnable> workQueue
任务队列,被提交但尚未被执行的任务。
ThreadFactory threadFactory
表示生成线程池中工作线程的线程工厂,用于创建线程一般用默认的即可
RejectedExecutionHandler handler
拒绝策略,表示当队列满了并且工作线程大于等于线程池的最大线程数(maximumpoolsize)时拒绝请求执行的策略
说说下线程池的底层工作原理?
9.线程池用过吗?生产上你如何设置合理参数?
线程池的拒绝策略你谈谈
是什么?
JDK内置的拒绝策略
AbortPolicyl(默认):直接抛出 Rejected Execution Exception异常阻止系统正常运行。
CallerRunsPolicy:"调用者运行"一种调节机制,该策略傚不会抛弃任务,也不会抛出异常,而是将某些任务回退到调用者,从而降低新任务的流量
Discardoldest polic:抛弃队列中等待最久的任务,然后把当前任务加入队中尝试再次提交当前仼务。
DiscardPolicy:直接丢弃任务,不予任何处理也不抛出异常。如果允许任务丢失,这是最好的一种方案。
以上内置拒绝策略均实现了RejectedExecutionHandler接口
你在工作中单一的/固定数的可变的三种创建线程池的方法,你用那个多?超级大坑
答案是一个都不用,我们生产上只能使用自定义的
Executors中JDK已经给你提供了,为什么不用?
你在工作中是如何使用线程池的,是否自定义过线程池使用
case
按照Executors中的照猫画虎就好了,就是最大线程数不要用Integer.MaxValue
合理配置线程池你是如何考虑的?
CPU密集型
IO密集型
1
2
10.死锁编码以及定位分析
是什么
产生死锁主要原因
系统资源不足
进程运行推进的顺序不合适
资源分配不当
代码
解决
JPS命令定位进程号
JSTACK找到死锁查看
11.Java里面的锁请谈谈你的理解,能说多少是多少。
4.JVM+GC解析
前提复习
JVM内存结构
JVM体系概述
JAVA8以后的JVM
GC作用域
常见垃圾回收算法
引用计数
复制
标记清除
标记整理
题目一
JVM垃圾回收的时候如何确定垃圾?是否知道什么是 GC Roots
什么是垃圾
简单的说就是内存中已经不再被使用到的空间就是垃圾
要进行垃圾回收,如何判断一个对象是否可以被回收?
引用计数法
枚举根节点做可达性分析(根搜索路径)
CASE
JAVA中可以作为GCRoot的对象
虚拟机栈(栈帧中的局部变量区,也叫做局部变量表)中引用的对象。
方法区中的类静态属性引用的对象。
方法区中常量引用的对象。
本地方法栈中N( Native方法)引用的对象。
你说你做过MM调优和参数配置,请问如何盘点查看JVM系统默认值
JVM的参数类型
标配参数
-version
-help
java -showversion
X参数(了解)
-Xint
解释执行
-Xcomp
第一次使用就编译成本地代码
-Xmixed
混合模式(先编译再执行)
XX参数
Boolean类型
公式
-XX:+或者-某个属性
+表示开启
-表示关闭
-表示关闭
case
是否打印GC收集细节
-XX:+PrintGCDetails
-XX:-PrintGCDetails
是否使用串行垃圾回收器
子主题
KV设值类型
公式
-XX:属性key=属性值value
case
-XX:MetaspaseSize=128m
-XX:MaxTenuringThreshould=15
jinfo举例,如何查看当前运行程序的配置
公式
jinfo -flag 配置项进程编号
case1
case2
case3
题外话(坑题)
两个经典的参数:-Xms和Xmx
这个你如何解释
-Xms
等价于-XX:InitialHeapSize
-Xmx
等价于-XX:MaxHeapSize
盘点家底查看JVM 默认值
-XX:+PrintFlagsInitial
主要查看初始默认值
公式
java -XX:PrintFlagsInitial -version
java -XX:+PrintFlagsInitial
case
-XX:+PrintFlagsFinal
主要查看修改更新过
公式
java -XX:PrintFlagsFinal; -version
java -XX:+PrintFlagsFinal
Case
PrintFlagsFinal举例,运行java命令的同时打印出参数
-XX:PrintCommandLineFlags
打印命令行参数
如何查看一个正在运行中的Java程序,它的某个jvm参数是否开启?具体值是多少?
jsp
jinfo -flag printGCDetails
你平时工作用过的JVM常用基本配置参数有哪些
基础知识复习
case
常用参数
-Xms
初始大小内存,默认为物理内存的1/64
等价于-XXInitialHeapSize
-Xmx
最大分配内存,默认为物理内存1/4
等价于-XX:MaxHeapSize
-Xss
设置单个线程栈的大小,一般默认为512k~1024K
等价于-XX:ThreadStackSize
-Xmn
设置年轻代大小(一般不用设置)
-XX:metaspaceSize
设置元空间大小
Xms10m -Xmx10m -XX:MetaspaceSize=1024 -XX:+PrintFlagsFinal
典型设置案例
-XX+PrintGCDetail
输出GC收集日志信息
GC
FullGC
-XXSurvivorRatio
设置新生代中eden和So/S1空间的比例
默认
XX: SurvivorRatio=8, Eden: SO: S 1=8: 1: 1
假如
XX: Survivor Ratio=4,Eden: SO: S1 =4: 1: 1
Survivorratio值就是设置eden区的比例占多少,so/s1相同
默认
XX: SurvivorRatio=8, Eden: SO: S 1=8: 1: 1
假如
XX: Survivor Ratio=4,Eden: SO: S1 =4: 1: 1
Survivorratio值就是设置eden区的比例占多少,so/s1相同
-XX:NewRatio
配置年轻代与老年代在堆结构的占比
默认
XX: NewRatio=2新生代占1,老年代2,年轻代占整个堆的1/3
假如
XX: NewRatio=4新生代占1,老年代4,年轻代占整个堆的1/5
NewRatio值就是设置老年代的占比,剩下的1给新生代
默认
XX: NewRatio=2新生代占1,老年代2,年轻代占整个堆的1/3
假如
XX: NewRatio=4新生代占1,老年代4,年轻代占整个堆的1/5
NewRatio值就是设置老年代的占比,剩下的1给新生代
-XX:MaxTenuringThreshold
强引用、软引用、弱引用、虚引用分别是什么
请谈谈你对OOM的认识
GC垃圾回收算法和垃圾收集器的关系?分别是什么请你谈谈
怎么查看服务器默认的垃圾收集器是那个?
生产上如何配置垃圾收集器的?
谈谈你对垃圾收集器的理解?
G1垃圾收集器
生产环境服务器变慢,诊断思路和性能评估谈谈?
假如生产环境出现CPU占用过高,请谈谈你的分析思路和定位
对于JDK自带的JVM监控和性能分析工具用过哪些?一般你是怎么用的?
题目二
其他
5.消息中间件MQ
6.NoSql数据库Redis
7.Spring原理
图片加载可能会很慢,请稍等。
8.Netty+RPC
9.网络通信与协议
10.数据库
11.SpringBoot+SpringCloud+Dubbo
12.项目
分支主题
收藏
0 条评论
下一页