大厂面试题
2021-01-18 13:59:25 4 举报
AI智能生成
大厂面试题个人总结
作者其他创作
大纲/内容
大厂面试题
JUC 多线程及高并发
谈谈你对volatile 理解
是Java虚拟机提供的一个轻量级的同步机制
保证可见性
不保证原子性
禁止指令重排
简介
JMM(Java Memory Model) 本身是一种抽象的概念font color=\"#c41230\
JMM关于同步的规定
JMM
可见性
代码
原子性
被拆分为
如何解决原子性问题?
使用 JUC下面的 atomicInteger类
有序性
源代码 ->编译器优化的重排->指令并行重排 -> 内存系统的重排 -> 最终执行的指令
重排Case1
问题 语句4可以重排后变为第一条?
重排 Case2
重排 Case3
禁止指令重排的总结
volatile 实现了font color=\"#c41230\
线程安全性获得保证
单例模式 DCL代码
单例模拟 volatile 分析
instance =new SingletonDemo() 分为以下3步完成
memory = allocate()
instance(memory)
instance = memory
步骤2和步骤3font color=\"#c41230\
多线程环境下就有可能出现问题
font color=\"#c41230\
CAS你知道?
CAS是什么
atomicInteger.getAndIncrement()
Unsafe
代码验证
UnSafe
var1 : AtomicInteger 对象
var2 : 该对象值引用地址
var4 : 需要变动的数量
var5 : 用 var1 和var2 找出主内存中真实的数据
小总结
CAS(Compare And Set)
CAS 应用
CAS有三个操作数
CAS缺点
引出来ABA问题???
原子类 AtomicInteger 的ABA 问题谈谈? 原子更新引用知道?
ABA 问题怎么产生的
原子引用
java.util.concurrent.atomic Class AtomicReference<V>
ABA问题的解决
java.util.concurrent.atomic Class AtomicStampedReference<V>
公平锁和非公平锁
是什么
两者区别
区别如下
题外话
Java font color=\"#c41230\
Synchronized 也是一种非公平锁
可重入锁(有名递归锁)
是什么?
ReetranLock(显示锁) / Syncharonized(隐式锁) 就是一个典型的可重入锁
可重入锁最大的作用就是避免死锁
Synchronized 的重入的实现原理
每个锁对象拥有一个锁计数器和一个指向持有该锁的线程指针
ReetranLock 显示锁
Synchronized / ReetranLock
Case1
Case2
自旋锁 (skinlock)
Case
独占锁(写锁)/共享锁(读锁)/互斥锁
独占锁
共享锁
before Cache1
after Cache2
CountDownLatch / CycliBarrier /Semaphore 使用过?
CountDownLatchDemo
让一些线程阻塞直到另一些线程完成一系列操作后才被唤醒
使用font color=\"#c41230\
枚举类为
countDownLatch类
避免了 countDownLatch类大量的if else 的使用
CyclicBarrierDemo
Semaphore
阻塞队列知道?
参考JUC的 blockingQueue
synchronized 和 font color=\"#c41230\
原始构成
monitorexit
使用方法
等待是否可中断
加锁是否公平
synchronized 是非公平锁
锁绑定多个条件的condition
synchronized 没有
线程池用过? ThreadPoolExecutor 谈谈你的理解
参考JUC的线程池
线程池用过? 生产上你如何设置合理的参数
死锁编码及定位分析
产生死锁的原因
死锁代码
如何定位分析
在 jdk安装下的/lib/目录有这样两个
jps.exe
命令定位进程
jstack.exe
找到死锁查看
找出死锁位置
LockSupport
用于创建锁和其他同步类的基本线程阻塞原语。
LockSupport 类使用了一种名为 Permit(许可)的概念来做到font color=\"#c41230\
能干嘛
主要两个方法 park() 和 font color=\"#c41230\
在哪下
java.util.locks.LockSupport
线程等待唤醒机制(wait / niotify)
3种让线程等待和唤醒的方法
Object 类中的 wait 和notify 方法实现线程等待和唤醒
如果去掉 font color=\"#c41230\
Condition 接口中的 await 后 signal 方法实现线程的等待和唤醒
如果 注释掉 lock.lock(); 和 lock.unlock() 运行会出现什么问题?
传统的 synchronized 和 lock 实现等待唤醒通知的约束
LockSupport 类中的 park 等待和 unpark唤醒
正常和无锁块要求
重点说明
LockSupport 是用来创建锁和其它同步类的基本线程阻塞原语
LockSupport 提供 park() 和unpark() 方法实现阻塞线程和解除线程阻塞的过程
常见LockSupport 面试题
为什么先唤醒线程后阻塞线程?
AbstractQueueSynchronized 之AQS
前置知识
可重入锁
自旋锁
数据结构之链表
设计模式之模板设计模式
字面意思: 抽象的队列同步器
技术解释: 是用来构建锁或者其它同步器组件的font color=\"#c41230\
AQS为什么是JUC内容中最重要的基石
与AQS相关的
ReetranLock
CountDownLatch
ReetranReadWriteLock
...
进一步理解锁和同步器的关系
锁: 面向锁的使用者
同步器: 面向锁的实现者
加锁会导致阻塞
解释说明
既然说到了font color=\"#c41230\
AQS初识
AbstractQueuedSynchronizer
AQS内部体系架构
AQS自身
AQS 的int变量
AQS 的同步状态state 成员变量
类似银行办理业务窗口状态
AQS 的CLH 队列
CLH队列(三个大牛的名字组成) 为一个双向队列
类似银行候客区的等待顾客
state + CLH变种的双向队列
内部类Node(Node 类在AQS的内部)
Node 的int变量
Node的等待状态 waitState 成员变量
Node 类的讲解
共享 static final Node SHARED = new Node();
独占 static final Node EXCLUSIVE = null;
线程被取消了 static final int CANCELLED = 1;
后续线程需要被唤醒 static final int SIGNAL = -1;
等待condition唤醒 static final int CONDITION = -2;
共享式同步状态获取将会无条件地传播下去 static final int PROPAGATE = -3;
前置节点 volatile Node prev;
后置节点 volatile Node next;
节点排队的线程 volatile Thread thread;
AQS同步队列的基本结构
从我们的ReetranLock 开始源码解读AQS
Reetrantlock 的原理
从最简单的lock 方法开始看 公平锁和非公平锁
AQS 源码深度分析走起
lock()
acquire(1)
tryAcquire(arg)
addWaiter(Node.EXCLUSIVE)
调用addWaiter
enq入队操作
predecessor()
parkAndCheckInterrupt()
AQS方法 unlock()
JVM+GC 解析
JVM 垃圾回收的时候如何确定垃圾? 是否知道什么是GC Roots
什么是垃圾
简单的说就是内存中已经不再被使用到空间就是垃圾
引用计数法
枚举根节点做可达性分析(根搜索路径)
基本思路就是通过一系列名为 GC Roots 的对象作为起始点font color=\"#7dcdc2\
GC Roots 案例
Java 中可以作为GC Roots 的对象
方法区中的类静态属性引用的对象
方法区中常量引用的对象
本地方法栈中JNI(native 方法)引用的对象
你说你做过font color=\"#c41230\
JVM 的参数类型
标配参数
- version
-help
java -showversion
X参数(了解)
-Xint
解释执行
-Xcomp
第一次使用就编译成本地代码
-Xmixed
混合模式
XX参数
Boolean 类型
-XX:+或者-某个属性值
+表示开启
-表示关闭
是否打印GC收集细节
idea 设置
测试结果
是否使用串行垃圾回收器
和上面同理 默认是
-XX:-UseSerialGC
idea修改后再次访问
-XX:+UseSerialGC
KV 设值类型
-XX: 属性key=属性值value
案例
-XX:MetaspaceSize=12582912
MaxTenuringThreshold=15
jinfo -flag 配置项 进程编号
参考 GC 收集细节
jinfo -flags 12416
两个经典参数: -Xms 和 -Xmx
你如何解释
-Xms 等待于 -XX:initialHeapSize
-Xmx 等价于 -XX:MaxHeapSize
盘点家底---查看JVM默认值
-XX:+PrintFlagsInitial
主持要查看初始默认
java -XX:+PrintFlagsInitial
-XX:PrintFlagsFinal
主要查看修改更新
java -XX:+PrintFlagsFinal -version
其中结果出现的=和:=是什么意思
:= 人为改过或JVM加载不一样修改过加载值
MetaspaceSize = xxx
java -XX:+PrintFlagsFinal -XX:MetaspaceSize=512m
MetaspaceSize
:= 536870912
java -XX:+printCommandLineFlags
打印命令行参数
java -XX:+PrintCommandLineFlags -version
你平时工作用过的JVM 常用基本配置参数有哪些
-Xms
-Xmx
-Xss
设置单个线程font color=\"#c41230\
-Xmn
设置年轻代大小
-XX:MetaspaceSize
设置元空间
-XX:MetaspaceSize = 1024m
典型设置案例
-XX:PriontGCDetails
输出详细GC收集日志信息
GC
GC [DefNew(新生代): 1641K->320Kfont color=\"#16884a\
0.0016319 secs / 0.0038326 secs / 0.0067679 secs 表示GC消耗时间(秒)
1641K 和 569K 表示GC之前内存区域使用的内存容量
320K 和 556K 表示GC之后内存区域使用的内存容量
(3072K) 和 (6848K) 该内存区域总容量
user=0.01 新生代用户耗时
sys=0.00 系统耗时
real=0.01 secs 新生代实际耗时
GC / Full GC GC类型
FullGC
[Full GC[Tenured: 569K->556Kfont color=\"#16884a\
-XX:SurvivorRatio
-XX:NewRatio
-XX:MaxTenuringThreshold
设置垃圾最大年龄
整体架构
强引用(默认支持模式) ---Reference
软引用 --- SoftReference
对于只有软引用的对象来说 font color=\"#c41230\
弱引用 --- WeakReference
软引用 和弱引用的适用场景
假设一个应用需要读取大量的本地图片
如果每次读取图片都是从硬盘读取则会造成严重影响性能
如果一次性全部加载到内存中有可能造成内存溢出
此时使用软引用可以解决这个问题
font color=\"#0076b3\
HashMap 使用的是强引用就算SystemGC也不会被回收
WeakHashMap 使用的是弱引用System.gc 会被回收
虚引用 --- PhantomReference
虚拟用需要java.lang.PhantomReference
java.lang.ref.ReferenceQueue 被回收之前需要被引用队列保存下
GC Roots 四大引用小总结
请谈谈 你对OOM认识
java.lang.StackOverflowError
java.lang.OutOfMemoryError: Java heap space
java.lang.OutOfMemoryError: GC overhead limit exceeded
java.lang.OutOfMemoryError: Direct buffer memory
java.lang.OutOfMemoryError: unabale to create new native thread
Linux服务器级别调优
ulimit -u
修改 /etc/security/limits.d/xx-nproc.conf
java.lang.OutOfMemoryError: Metaspace
java -XX:+PrintFlagsInitial 查看元空间大小
永久代存放一下信息
虚拟机加载的类信息
常量池
静态变量
即使编译后的代码
△GC垃圾回收算法和font color=\"#c41230\
4种垃圾收集器
原理图
Serial --- 串行垃圾回收器
Parallel --- 并行垃圾回收器
CMS --- 并发垃圾回收器
G1 --- G1垃圾回收器
△怎么查看服务器默认的垃圾收集器是哪个? 生产上如何配置垃圾收集器的? 请你谈谈你对垃圾收集器的理解???
怎么查看默认的垃圾收集器是哪个?
-XX:+UseParallelGC
默认的垃圾收集器有哪些?
Java 的GC 回收类型主要有几种
UseSerialGC
UseParallelGC(默认)
UseConcMarkSweepGC
UseParallelNewGC
UseParallelOldGC
UseG1GC
垃圾收集器
参数预先说明
DefNew
Default New Generation
Tenured
Old
ParNew
Parallel New Generation
PSYoungGen
Parallel Scavenge
ParOldGen
Parallel Old Generalation
JVM 的 Server/Client 模式分别是什么意思
新生代
串行GC(Serial) / (Serial Copying)
对应参数是: -XX:+UserSerialGC
Case 代码验证
并行GC(ParNew)
常见对应JVM参数: font color=\"#c41230\
Case 案例
并行GC (Paralle ) /(Parallel Scavenge)
Paralle Scavenge 收集器类似 ParNew 也是font color=\"#c41230\
可控制的吞吐量 (font color=\"#0076b3\
常见JVM参数 : font color=\"#c41230\
Case案例
老年代
串行GC(Serial Old)/(Serial MSC)
并行GC(Parallel Old) / (Parallel MSC)
我们修改了老年代的UseParallelOldGC 这样新生代自动为我们设置了 ParallelScavenge
并发标记清除GC(CMS)
CMS 收集器(Concurrent Mark Sweep : 并发标记清除) 是一种以获取最短回收停顿时间为目标的收集器
4步过程
优点
并发收集底停顿
缺点
并发执行堆cpu资源压力比较大
采用的标记清除算法会导致大量的内存碎片
如何选择垃圾收集器??
-XX:+UseParalleGC / -XX:+UseParalleOldGC
-XX:+UseConcMarkSweepGC
△G1 垃圾收集器
以前垃圾收集器特点
年轻代和老年代是各自独立且连续的内存块
年轻代收集使用但 eden +so +s1 进行复制算法
老年代收集必须扫描整个老年代区域
都是以尽可能少而快速地执行GC为设计原则
G1( Garbage - First )是什么
整理空闲空间更快
需要更多的时间预测GC停顿的时间
不希望牺牲大量的吞吐性能
不需要更大的Java Heap
G1 特点
底层原理
Region 区域化垃圾收集器
这些Region 的一部分包含font color=\"#c41230\
G1回收步骤
G1 收集器4步骤
常用配置参数(了解)
-XX:+UseG1GC
采用 Garbage First (G1) 收集器
-XX:G1HeapRegionSize=n
此参数的默认值根据堆大小的人工进行确定。最小值为 1Mb 且最大值为 32Mb。
span style=\
设置最大GC 暂停时间。这是一个大概值,JVM 会尽可能的满足此值
-XX:InitiatingHeapOccupancyPercent=n
设置触发标记周期的 Java 堆占用率阈值。默认占用率是整个 Java 堆的 45%。默认值 45.
并发垃圾收集器使用的线程数。默认值因与 JVM 运行的平台而不同。
-XX:G1ReservePercent=n
设置作为空闲空间的预留内存百分比以降低晋升失败的可能性。默认值10
和CMS相比的优势
生产环境服务器变font color=\"#c41230\
整机 : top
top的精简版本 uptime
CPU : vmstat
- procs
-cpu
sy : 内核进程消耗的cpu 时间百分比
查看cpu 核信息
mpstat -P ALL 2
每个进程使用cpu 的用量分解信息
pidstat -u 1 -p 进程编号
内存: free
20%<应用程序可用内存/系统物理内存<70%内存基本够用
pidstat -p 进程号 -r 采样间隔秒数
硬盘: df
网盘IO: iostat
pidstat -d 采样间隔秒数 -p 进程号
网络IO: ifstat
△假如生产环境出现font color=\"#c41230\
结合Linux 和JDK命令一块分析
案例步骤
找出线程号 2361
参数解释
-m 显示所有的线程
-p pid 进程使用cpu 的时间
-o 该参数是用户自定义格式
https://tool.lu/hexconvert
jstack 2327(1步得到线程号)|grep 939[]进程号-4步骤] -A60[打印60行]
对于JDK 自带的JVM监控和性能分析工具用过哪些? 一般你是怎么使用的?
oracle官方文档/lib/
性能监控工具
jps(JVM Process Status Tools):虚拟机进程状况工具
jinfo(Configuration Info for java):Java配置信息工具
jmap(Memory Map for java):java内存映像工具
jstack(Stack Trace for java):java虚拟机自带的堆栈跟踪工具
github 骚操作
常用词含义
watch : 会持续受到该项目的动态
fork : 复制某个项目到自己的github 仓库中
star : 可以理解为点赞
clone : 将项目下载到本地
in 关键词限制搜索范围
公式: XXX 关键词 in:name 或 description 或 readme
XXX in:name
XXX in:description
XXX in:readme
可以组合使用
stars 或 fork 数量关键词去查找
公式 xxx关键字 stars 通配符
:> 或者 :>=
范围 数字1..数字2
查找springboot stars数大于等于5000的项目
查找forks 大于500的springcloud项目
查找fork 在100到200之间并且stars数在80到100之间的springboot项目
awesome 加强搜索
awesome 关键字
高亮显示一行代码
公式
1行
url地址+#L数字
多行
url地址+L数字1-L数字2
项目内搜索
英文t
搜索某个地区内的大佬
location:地区
language:语言
location:hangzhou language:java
java 基础
java字符串常量池
String 类的 intern()
考点? 为什么s1 == s1.intern 结果为true 而s2 == s2.intern() 结果为false
方法区和运行时常量池溢出
why
有一个初始化的Java 字符串(JDK 娘胎自带的) 在加载 sun.misc.Version 这个类的时候进入常量池
Open JDK1.8源码说明
http://hg.openjdk.java.net/jdk8/jdk8/jdk/
System 代码解析
initializeSystemClass
Version
类加载器和rt.jar --根加载器提前部署加载rt.jar
将jdk1.8源码 配置到idea 上
将下载的 openJdk1.8下载解压并放入idea 的sdk 的classpath 的+
两个数求和
https://leetcode-cn.com/problems/two-sum/
暴力破解法
map 解法
手写 LRU 算法--redis 最后一章
java中文在线文档
https://www.apiref.com/java11-zh/index.html
spring
spring 的aop 顺序
Aop 常用注解
@AfterReturning --返回后通知: 执行方法结束前执行(异常不执行)
面试题
说说你使用aop 中碰到的坑?
springboot 1.5.9版本案例
service
aspt
测试类
springboot 2.x.版本案例
spring 循环依赖
你解释一下spring中的三级缓存?
三级缓存分别是什么? 三个Map 有什么异同
如何检测是否存在循环依赖? 实际开发中见过循环依赖的异常?
什么是循环依赖?
两种注入方式对循环依赖的影响
结论: 我们AB循环依赖问题只要 A的注入方式是 setter 且 singleton 就不会有循环依赖问题
spring 容器循环依赖报错演示 BeanCurrentlyInCreationException
1)构造器方式注入
ServerA
ServerB
测试类
font color=\"#16884a\
重要 Code 案例演示 -- spring容器
默认单例 (singleton) 的场景是font color=\"#c41230\
重要结论 ( spring 内部通过 3级缓存来解决循环依赖)
DefaultSingletonBeanRegistry
singletonObjects(一级缓存)
存放已经经历了完整声明周期的Bean 对象
earlySingletonObjects(二级缓存)
singletonFactories(三级缓存)
存放可以生成Bean 的工厂
循环依赖 Debug
实例化 / 初始化
实例化
初始化属性填充
A/B 两对象在三级缓存中的迁移说明
总结 spring是如何解决循环依赖?
运行流程
Redis
安装redis6.0.10
中文官网
http://www.redis.cn/
以英文官网
https://redis.io/
redis 传统5大数据结构的落地应用
8大常用数据类型
list
set
zset
string
hash
bitmap(位图)
hyperloglog统计()
GEO(地理)
help @类型名词
String
最常用
set k v
get k v
mset k1 v1 k2 v2 ...
mget k1 k2 k3 ...
incr k
decr k
strlen k
分布式锁
setnx k v
set k v [EX seconds][PX milliseconds][NX|XX]
EX: key在多少秒之后过期
PX : key在多少毫秒之后过期
XX: 当key存在的时候覆盖key
应用场景
是否喜欢的文章
一次设置一个值
hset key field value
一次获取一个字段值
hget key field
设置多个值
hmset key field1 values1 field2 values2 ...
hmget key field1 field2 ...
获取所有字段
hgetall key
获取某个key内的全部数量
hlen key
删除一个key
hdel key
新增商品
hset shopcar userid 100 3344[产品id] 1
hset shopcar userid 100 3355[产品id] 1
增加商品数量
hincrby shopcat userid 100 3355[产品id] 1
商品总数
hlen shopcar userid 100
全部选择
hgetall shopcar userid 100
向左边添加元素
lpush key value ...
向右添加元素
rpush key values ...
查看列表
lrange key start stop
获取列表个数
llen key
引用场景
微信文章公众号 1:N
添加元素
sadd key member
删除元素
srem key member
获取集合中的所有元素
smembers key
判断元素是否在集合中
sismember key member
获取集合中的元素个数
scard key
srandmember key [数字]
spop key [数字]
集合运算
集合的差集运算A-B
属于A但不属于B的元素构成集合
sdiff key
集合的交集运算ANB
属于A也属于B共同拥有的元素构成的集合
sinter key
集合的并集运算U
属于A或者属于B 元素合并后的集合
sunion key
微信抽奖小程序
微信朋友圈点赞
微博好友关注社交关系
qq内退可能认识的人
向有序集合中加入一个元素和该元素的分数
zadd key score member
按照元素分数从小到大的顺序返回索引从 start 到 stop 之间的所有元素
zrange key start stop
获取指定分数范围的元素
zrangebyscope key min max
增加某个元素的分数
zincrby key incrment member
获取集合中元素的数量
zcard key
获取指定分数范围内的元素个数
zcount key min max
按照排名范围删除元素
zremrangebyrank key start stop
获取元素的排名
从小到大
zrank key member
从大到小
zrevrank key member
根据商品销售对商品进行排序显示
抖音热搜
redis做分布式锁的时候有什么需要注意的问题
那你准备怎么解决单点问题?
Case 案例(boot+redis)
建moudle
boot-redis1001
boot-redis1002
pom
yml
主启动
业务类
config
controller
小测试
http://localhost:1001/goods
上面的问题代码
如何解决呢?
用 synchronized 代码块把业务代码围起来[2.0版本程序]
如何产生问题
nginx 配置负载均衡 下面这2个微服务
使用jmeter 高并发模拟
就会产生一个商品被多卖2次
redis 分布式锁 setnx
3.0升级后的代码
解决
4.0版本程序
2使用 LUA脚本
redis 分布式锁如何实现续期?
集群+CAP 对比 zookeeper
redis -- AP
zookeeper -- CP
http://www.redis.cn/topics/distlock.html
修改config 代码
升级为10.0版本
redis 缓存过期淘汰策略
生产上你们的redis 内存不设置多少?
生产上如何配置? 一般推荐redis设置为内存为最大物理内存的3/4
查看redis 最大占用内存 redis.conf 文件
什么命令查看redis 内存使用情况
info memory
如果redis 内存满了你怎么办
redis 清理内存的方式? 定期删除和惰性删除了解过?
redis 的缓存淘汰策略
redis 的 LRU 了解过? 可否手写一个 LRU算法
redis 的LRU算法简介
0 条评论
回复 删除
下一页