Java面试题
2019-07-17 11:52:57 5 举报
AI智能生成
java面试必备知识点
作者其他创作
大纲/内容
7.Spring原理
8.Netty+RPC
9.网络通信与协议
10.数据库
11.项目
Dubbo
注解
reference
Service
EnableDubbo
监控配置
dubbo.properties&属性加载顺序
启动检查
配置覆盖关系
版本号
高可用场景
zookeeper宕机与dubbo直连
集群下dubbo负载均衡配置
Random LoadBalance
RoundRobin LoadBalance
LeastActive
ConsistentHash
服务熔断与降级处理
服务降级
mock=force:return+null
mock=fail:return+null
集群容错
Failover Cluster
Failfast Cluster
Failsafe Cluster
Failback Cluster
Forking Cluster
Broadcast Cluster
集群模式配置
整合hystrix
@EnableHystrix
配置Provider端
配置Consumer端
rpc原理
RPC原理
netty通信原理
BIO:(Blocking IO)
NIO (Non-Blocking IO)
dubbo原理
框架设计
Rpc
config 配置层
proxy 服务代理层
registry 注册中心层
cluster 路由层
monitor 监控层
protocol 远程调用层
exchange 信息交换层
transport 网络传输层
serialize 数据序列化层
启动解析、加载配置信息
服务暴露
服务引用
服务调用
RocketMQ
架构图
安装
创建RocketMQ存储文件的目录
文件夹说明
conf目录配置文件说明
消费模式
DefaultMQPushConsumer
DefaultMQPullConsumer
队列数量
ack机制
LocalTransactionState
COMMIT_MESSAGE
ROLLBACK_MESSAGE
UNKNOW
ConsumeConcurrentlyStatus
CONSUME_SUCCESS
RECONSUME_LATER
messageDelayLevel
普通消息生产者
消息发送步骤
创建DefaultMQProducer
设置Namesrv地址
开启DefaultMQProducer
创建消息Message
发送消息
关闭DefaultMQProducer
控制台地址
普通消息消费者
消息监听步骤
创建DefaultMQPushConsumer
设置namesrv地址
设置subscribe,这里是要读取的主题信息
创建消息监听MessageListener
获取消息信息
返回消息读取状态
控制台运行结果
RocketMQ顺序消息
如何保证顺序
消息被发送时保持顺序
消息被存储时保持和发送的顺序一致
消息被消费时保持和存储的顺序一致
原理图
子主题 1
消息生产者
代码
消息消费者
代码
控制台
事务消息
事务消息流程
流程图
事务消息的成功投递是需要经历三个Topic
Half Topic
Op Half Topic
Real Topic
生产者
监听器TransactionListenerImpl
代码
消息发送对象TransactionProducer
消费者和普通消费者一样
代码
分布式事务流程
1.Prepared消息,会拿到消息的地址
2.执行本地事务
3.通过第一阶段拿到的地址去访问消息,并修改状态
流程图
消息广播/批量发送
生产者BroadcastingProducer
代码
消息消费者
代码
结果
RocketMQ集群
RocketMQ集群模式
单个Master
多个Master
多Master多Slave模式
异步复制
同步双写
主从搭建
环境准备
修改2台机器的/etc/hosts文件
安装配置(slave)
下载安装包
解压
创建存储文件的目录
替换配置
修改bin目录下配置文件
runbroker.sh
runserver.sh
主从配置
加了从节点的地址
修改broker-a-s.properties
配置文件
copy配置
重启服务
namesrv
broker
控制台配置
主从模式故障演练
master宕机收消息演示
master宕机发消息演示
双主双从
1.前提知识+要求
2.Java8基础
HashMap
红黑树
CurrentHashMap
metaSpace
Lambda
从匿名类到 Lambda 的转换
子主题 1
子主题 2
子主题 3
语法
需要函数式接口支持
语法1
语法2
类型判断
函数式接口
自定义函数式接口
作为参数传递 Lambda 表达式
Java 内置四大核心函数式接口
其他接口
例子
方法引用与构造器引用
方法引用
例子
构造器引用
数组引用
Stream API
什么是 Stream
三个步骤
创建Stream
由数组创建流
由值创建流
由函数创建流:创建无限流
中间操作
筛选与切片
排序
终止操作
查找与匹配
例子
归约
收集
方法与实例
分组
分区
例子
Optional
例子
并行流与串行流
Fork/Join 框架
Fork/Join 框架与传统线程池的区别
新时间日期 API
使用 LocalDate、 LocalTime、 LocalDateTime
Instant 时间戳
Duration 和 Period
日期的操纵
解析与格式化
时区的处理
与传统日期处理的转换
接口中的默认方法与静态方法
接口中的默认方法
类优先
静态方法
其他新特性
Optional 类
常用方法
重复注解与类型注解
CompletableFuture
由函数创建流:创建无限流
3.JUC多线程及高并发
1.谈谈你对volatile的理解
1.volatile是Java虚拟机提供的轻量级的同步机制
1.1保证可见性
1.2不保证原子性
1.3禁止指令重排
2.JMM你谈谈
2.1可见性
2.2原子性
2.3VolatileDemo代码演示可见性+原子性
2.4有序性
重排1
重排2
禁止指令重排小总结
3.你在哪些地方用过volatile?
3.1单例模式DCL代码
3.2单例模式volatile分析
2.CAS你知道吗
1.比较并交换
2.CAS底层原理?如果知道,谈谈比对Unsafe的理解
atomicInteger.getAndIncrement();
Unsafe
CAS是什么
unsafe.getAndAddInt
底层汇编
简单版小总结
3.CAS缺点
循环时间长开销大
只能保证一个共享变量的原子操作
引出来ABA问题???
通过原子引用解决ABA问题
3.原子类Atomiclnteger的ABA问题谈谈?原子更新引用知道吗?
ABA问题怎么产生的
原子引用
时间戳原子引用
AtomicStampledReference
ABADemo
4.我们知道ArrayList是线程不安全,请编写一个不安全的案例并给出解决方案
解决方案1:Vector、Collections.synchronizedList
限制不可以用Vector和Collections工具类解决方案2
new CopyOnWriteArrayList<>()
5.公平锁/非公平锁/可重入锁/递归锁/自旋锁谈谈你的理解?请手写一个自旋锁
公平锁和非公平锁
是什么
两者区别
题外话
可重入锁(又名递归锁)
是什么
ReentrantLock/Synchronized就是一个典型的可重入锁
可重入锁最大的作用是避免死锁
ReenterLockDemo
参考1
参考2
独占锁/共享锁
自旋锁
synchronized和lock有什么区别?用新的lock有什么好处?你举例说说
详见代码SyncAndReentrantLockDemo
6.CountDownLatch/CyclicBarrier/Semaphore
CountDownLatch
让一些线程阻塞直到另一个线程完成一系列操作后才被唤醒
CountDownLatch主要有两个方法,当一个或多个线程调用await方法时,调用线程会被阻塞。其他线程调用countDown方法会将计数器减1(调用CountDown方法的线程不会阻塞),当计数器的值变为0时,因调用await方法被阻塞的线程会被唤醒,继续执行。
CyclicBarrier
CyslicBarrier的字面意思是可循环(Cyclic)使用的屏障(Barrier)。它要做的事情是,让一组线程到达屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会打开门,所有被屏障拦截的线程才会继续干活,线程进入屏障通过CyclicBarrier的await()方法。
CyclicBarrierDemo
Semaphore
信号量主要用于两个目的,一个是用于多个共享资源的互斥使用,另一个用于并发线程数的控制。
SemaphoreDemo
争车位
代码
7.阻塞队列知道吗
队列+阻塞队列
为什么用?有什么好处?
BlockingQueue的核心方法
架构梳理+种类分析
架构介绍
种类分析
ArrayBlockingQueue:由数组结构组成的有界阻塞队列
LinkedBlockingQueue:由链表结构组成的有界(但大小默认值为Integer.MAX_VALUE)阻塞队列。
PriorityBlockingQueue:支持优先级排序的无界阻塞队列。
DelayQueue:使用优先级队列实现的延迟无界阻塞队列。
SynchronousQueue:不存储元素的阻塞队列,也即单个元素的队列。
理论
SychronousQueueDemo
LinkedTransferQueue:由链表结构组成的无界阻塞队列。
LinkedBlockingDeque:由链表结构组成的双向阻塞队列。
用在哪里
生产者消费者模式
传统版
ProdConsumer_TraditionDemo
阻塞队列版
ProdConsumer_BlockQueueDemo
线程池
消息中间件
8.线程池用过吗?ThreadPoolExecutor谈谈你的理解?
为什么用线程池,优势
线程池如何使用?
架构说明
编码实现
了解
Executors.newScheduledThreadPool()
java8新出
Executors.newWorkStealingPool(int)
java8新增,使用目前机器上可用的处理器作为它的并行级别
重点
Executors.newFixedThreadPool(int)
执行长期的任务,性能好很多
Executors.newSingleThreadExecutor()
一个任务一个任务执行的场景
Executors.newCachedThreadPool()
适用:执行很多短期异步的小程序或者负载较轻的服务器
ThreadPoolExcutor
线程池的几个重要参数介绍
7大参数
1.corePoolSize:线程池中的常驻核心线程数
2.maximumPoolSize:线程池能够容纳同时执行的最大线程数,此值必须大于等于1.
3.keepAliveTime:多余的空闲线程的存活时间。当前线程池数量超过corePoolSize时,当空闲时间达到keepAliveTime值时,多余空闲线程会被销毁直到只剩下corePoolSize个线程为止。
4.unit: keepAliveTime的单位
5.workQueue:任务队列,被提交但尚未被执行的任务。
6.threadFactory:表示生成线程池中工作线程的线程工厂,用于创建线程一般用默认的即可。
7.handler:拒绝策略,表示当队列满了并且工作线程大于等于线程池的最大线程数。
说说线程池的底层工作原理?
9.线程池用过吗?生产上你是如何设置合理参数?
线程池的拒绝策略你谈谈
是什么
JDK内置的拒绝策略
AbortPolicy(默认):直接跑出RejectedExecutionException异常阻止系统正常运行。
CallerRunsPolicy:“调用者运行”一种调节机制,该策略既不会抛弃任务,也不会抛出异常,而是将某些任务回退到调用者,从而降低新任务的流量。
DiscardOldestPolicy:抛弃队列中等待最久的任务,然后把当前任务加入队列中尝试再次提交当前任务。
DiscardPolicy:直接丢弃任务,不予任何处理也不抛出异常。如果允许任务丢失,这是最好的一种方案。
以上内置拒绝策略均实现了RejectedExecutionHandler接口
你在工作中单一的/固定数的/可变的单重创建线程池的方法,你用哪个多?超级大坑
答案是一个都不用,我们生产上只能使用自定义的
Executors中JDK已经给你提供了,为什么不用?
你在工作中是如何使用线程池的,是否自定义过线程池使用
Case:MyThreadPoolDemo
合理配置线程池你是如何考虑的?
CPU密集型
IO密集型
1
2
10.死锁编程及定位分析
是什么
产生死锁的主要原因
系统资源不足
进程运行推进的顺序不合适
资源分配不当
代码:DeadLockDemo
解决
jps命令定位进程号
jstack找到死锁查看
11.Java里面锁请谈谈你的理解,能说多少说多少
4.JVM+GC解析
前提复习
JVM内存结构
JVM体系概述
Java8以后的JVM
GC的作用域
常见的垃圾回收算法
引用计数
复制
标记清除
标记整理
节外生枝补充知识
题目1
1.JVM垃圾回收的时候如何确定垃圾?是否知道什么是GC Roots
什么是垃圾
内存中已经不再被使用到的空间就是垃圾
要进行垃圾回收,如何判断一个对象是否可以被回收?
引用计数法
枚举根节点做可达性分析(根搜索路径)
case
Java中可以作为GC Roots的对象
虚拟机栈(栈帧中的局部变量区,也叫做局部变量表)中引用的对象。
方法区中的类静态属性引用的对象。
方法区中常量引用的对象
本地方法栈中JNI(Native方法)引用的对象。
2.你说你做过JVM调优和参数配置,请问如何查看JVM系统默认值
JVM的参数类型
标配参数
-version
-help
java -showversion
x参数(了解)
-Xint:解释执行
-Xcomp:第一次使用就编译成本地代码
-Xmixed:混合模式
xx参数
Boolean类型
公式
-XX:+或者-某个属性值
+表示开启 -表示关闭
Case
是否打印GC收集细节
-XX:-PrintGCDetails
-XX:+PrintGCDetails
是否使用串行垃圾回收器
-XX:-UseSerialGC
-XX:UseSerialGC
KV设值类型
公式
-XX:属性key=属性值value
Case
-XX:MetaspaceSize=128m
-XX:MaxTenuringThreadhold=15
jinfo举例,如何查看当前运行程序的配置
题外话(坑题)
两个经典参数:-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:+PrintFlags -version
Case
PrintFlagsFinal举例,运行java命令的同时打印出参数
-XX:+PrintCommandLineFlags
3.你平时工作用过的JVM常用基本配置参数有哪些?
4.请谈谈你对OOM的认识?
java.lang.StackOverFlowError
Case:StackOverflowErrorDemo
java.lang.OutOfMemoryError:Java heap space
Case:JavaHeapSpaceDemo
java.lang.OutOfMemoryError:GC overhead limit exceeded
java.lang.OutOfMemoryError:Direct buffer memory
java.langOutOfMemoryError:Metaspace
使用java -XX:+PrintFlagsInitial命令查看本机的初始化参数,-XX:Metaspacesize为218103768(大约为20.8M)
java.lang.OutOfMemoryError:unable to create new native thread
非root用户登录linux系统测试
服务器级别调参调优
5.GC回收算法和垃圾收集器的关系?分别是什么请你谈谈
GC算法(引用计数/复制/标清/标整)是内存回收的方法论,垃圾收集器就是算法落地实现。
因为目前为止还没有完美的收集器出现,更加没有万能的收集器,知识针对具体应用最合适的收集器,进行分代收集。
4种主要垃圾收集器
串行垃圾回收器(Serial)
它为单线程环境设计且只使用一个线程进行垃圾回收,会暂停所有的用户线程。所以不适合服务器环境。
并行垃圾回收器(Parallel)
多个垃圾收集线程并行工作,此时用户线程是暂停的,适用于科学计算/大数据处理平台处理等弱交互场景。
并发垃圾回收器(CMS)
用户线程和垃圾收集线程同时执行(不一定是并行,可能交替执行),不需要停顿用户线程,使用对响应时间有要求的场景。
上述3个小总结,G1特殊后面说
GI垃圾回收器
G1垃圾回收器将堆内存分割成不同的区域然后并发的对其进行垃圾回收。
6.怎么查看服务器默认的垃圾收集器是哪个?生产上你是如何配置垃圾收集器的?谈谈你的理解?
怎么查看默认的垃圾收集器是哪个?
默认的垃圾收集器有哪些?
垃圾收集器
部分参数预先说明
DefNew
Default New Generation
Tenured
Old
ParNew
Parallel New Generation
PSYoungGen
Parallel Scavenge
ParOldGen
Parallel Old Generation
Server/Client模式分别是什么意思
新生代
串行GC(Serial)/(Serial Copying)
并行GC(ParNew)
并行回收GC(Parallel)/(Parallel Scavenge)
老年代
串行GC(Serial Old)/(Serial MSC)
并行GC(Parallel Old)/(Parallel MSC)
并发标记清除GC(CMS)
4步过程
初始标记(CMS initial mark)
并发标记(CMS concurrent mark)和用户线程一起
重新标记(CMS remark)
并发清除(CMS concurrent sweep)和用户线程一起
优缺点
优点
并发收集低停顿
缺点
并发执行,对CPU资源压力大
采用的标记清除算法会导致大量碎片
垃圾收集器配置代码总结
如何选择垃圾收集器
7.G1垃圾收集器
以前收集器特点
年轻代和老年代是各自独立且连续的内存块
年轻代收集使用单eden+S0+s进行复制算法
老年代收集必须扫描整个老年代区域
都是以尽可能少而快速地执行GC为设计原则。
G1是什么
底层原理
Region区域化垃圾收集器
最大好处是化整为零,避免全内存扫描,只需要按照区域来进行扫描即可。
回收步骤
4步过程
case案例
常用配置参数(了解)
-XX:+UseG1GC
-XX:G1HeapRegionSize=n:设置的G1区域的大小。值是2的幂,范围是1MB到32MB。目标是根据最小的Java堆大小划分出约2048个区域。
-XX:MaxGCPauseMillis=n:最大GC停顿时间,这是个软目标,JVM将尽可能(但不保证)停顿小于这个时间。
-XX:InitiatingHeapOccupancyPercent=n:堆占用了多少的时候就触发GC,默认为45
-XX:ConcGCThreads=n:并发GC使用的线程数。
-XX:G1ReservePercent=n:设置作为空闲的预留内存百分比,以降低目标空间溢出的风险,默认值是10%
和CMS相比的优势
小总结
8.强引用、软引用、弱引用、虚引用分别是什么?
整体架构
强引用(默认支持模式)
Case:StrongReferenceDemo
软引用
Case:SoftReferenceDemo
弱引用
Case:WeakReferenceDemo
软引用和所引用的使用场景
你知道所引用的话,能谈谈weakHashMap吗
Case:WeakHashMapDemo
虚引用
引用队列
case:ReferenceQueueDemo
case:PhantomReferenceDemo
GCRoots和四大引用小总结
9.生产环境服务器变慢,诊断思路和性能评估谈谈?
整机:top
uptime,系统性能命令的精简版
CPU:vmstat
vmstat
查看CPU(包含不限于)
查看额外
查看所有cpu核信息
mpstat -P ALL 2
每个进程使用cpu的用量分解信息
pidstat -u1 -p进程编号
内存:free
应用程序可用内存数
查看额外
pidstat -p 进程号 -r 采样间隔秒数
硬盘:df
查看磁盘剩余空间数
磁盘IO:iostat
磁盘I/O性能评估
查看额外
pidstat -d采样间隔秒数 -p 进程号
网络IO:ifstat
默认本地没有,下载ifstat
查看网络IO
10.假设生产环境出现CPU占用过高,请谈谈你的分析思路和定位
结合Linux和JDK命令一块分析
案例步骤
1.先用top命令找出CPU占比最高的
2.ps -ef或者jps进一步定位,得知是一个怎么样的一个后台程序惹事
3.定位到具体线程或者代码
ps -mp进程 -o THREAD,tid,time
参数解释
-m显示所有的线程
-p pid进程使用cpu的时间
-o该参数后是用户自定义格式
4.将需要的线程ID转换为16进制格式(英文小写格式)
printf "%x\n"有问题的线程ID
5.jstack进程ID | grep(16进制线程ID小写英文) -A60
11.对于JDK自带的JVM监控和性能分析工具用过哪些?一般你是怎么用的?
概览
性能监控工具
jps
官网
解释
Case
jinfo
jmap
jstat
jstack
12.github骚操作
stars或fork数量关键词去查找
公式
xxx关键词 star通配符
:>或者:>=
区间范围数字
数字1..数字2
查找stars数大于等于5000的springboot项目
springboot stars:>=5000
查找forks数大于500的springcloud项目
springcloud forks:>500
组合使用
查找fork在100到200之间并且stars数在80到100之间的springboot项目
springboot forks:100..200 stars:80..100
awesome加强搜索
公式
awesome关键字
awesome系列一般是用来学习、工具、书籍类相关的项目
搜索优秀的redis相关的项目,包括框架、教程等
高亮显示某一行代码
公式
1行
地址后面紧跟#L数字
多行
地址后面紧跟#L数字-L数字2
项目内搜索
英文t
搜索某个地区内的大佬
公式
location:地区
language:语言
地区北京的Java方向的用户
location:beijing language:java
5.消息中间件MQ
1.消息队列的主要作用是什么?
2.你项目好好的情况下,为什么引入消息队列?理由是什么?
3.项目里你们是怎么用消息队列的?
4.你在项目中是如何保证消息队列的高可用?
5.kafka、activemq、rabbitmq、rocketmq都有什么区别?
kafka
RocketMQ
RabbitMQ
6.MQ在高并发情况下假设队列满了如何防止消息丢失?
7.消费者消费消息,如何保证MQ幂等性
8.谈谈你对死信队列的理解
9.如果百万级别的消息积压了,你们如何处理?
10.你们为什么不用其他的MQ,最终选择了RocketMQ?
6.NoSQL数据库Redis
1.在你的项目中,哪些数据是数据库和redis缓存双写一份的?如何保持双写一致性?
2.系统上线,redis缓存系统如何部署
3.系统上线,redis缓存给多大的总内存?命中率有多高?抗住了多少QPS?数据流回源会有多少QPS?
4.热key大Value问题,某个key出现了热点缓存导致缓存集群中的某个机器负载过高?如何解决?
5.超大Value打满网卡的问题如何规避这样的问题?
6.你过往的工作经历中,是否出现过缓存集群事故?说说细节并说说高可用保障的方案
7.平时如何监控缓存集群的QPS和容量
8.缓存集群如何扩容?
9.说下redis的集群原理和选举机制
10.Key寻址算法都有哪些?
11.Redis线程模型现场画个图说说
12.Redis内存模型现场画个图说说
13.redis的底层数据结构小结多少?
15.你们怎么解决缓存击穿问题?
0 条评论
下一页