@牛客人品酱 攒人品!!!分享一波自己的面经,希望对大家有所帮助,⛽️!!!
爱奇艺的笔试做的比较久了,做完后应该是有十多天吧,开始约面试,整体来说流程有点小慢,不过我一面后第二天就约了二面,后续推荐流程害比较快。
8.24日 30min 无手撕
1.自我介绍
2.java中产生死锁的原因?
首先可以先说一下什么是死锁?然后说一下死锁产生的四个条件,在说一下如何避免死锁,尽量有一定的逻辑思维。
3.java中如何解决死锁的?
这个问题是在上一个问题的基础上问的。
4.syn锁升级的过程?
偏向锁-》轻量级锁-》重量级锁
锁一共有四种状态,级别从低到高依次是:无锁状态、偏向锁状态、轻量级锁状态和重量级锁状态,这几个状态随着竞争情况逐渐升级。为了提高获得锁和释放锁的效率,锁可以升级但不能降级,意味着偏向锁升级为轻量级锁后不能降级为偏向锁。
(1).偏向锁
当一个线程访问同步块并获取锁时,会在对象头和栈帧的锁记录里存储偏向的线程ID,以后该线程在进入和退出同步块时不需要进行CAS操作来加锁和解锁,只需测试Mark Word里线程ID是否为当前线程。如果测试成功,表示线程已经获得了锁。如果测试失败,则需要判断偏向锁的标识。如果标识被设置为0(表示当前是无锁状态),则使用CAS竞争锁;如果标识设置成1(表示当前是偏向锁状态),则尝试使用CAS将对象头的偏向锁指向当前线程,触发偏向锁的撤销。偏向锁只有在竞争出现才会释放锁。当其他线程尝试竞争偏向锁时,程序到达全局安全点后(没有正在执行的代码),它会查看Java对象头中记录的线程是否存活,如果没有存活,那么锁对象被重置为无锁状态,其它线程可以竞争将其设置为偏向锁;如果存活,那么立刻查找该线程的栈帧信息,如果还是需要继续持有这个锁对象,那么暂停当前线程,撤销偏向锁,升级为轻量级锁,如果线程1不再使用该锁对象,那么将锁对象状态设为无锁状态,重新偏向新的线程。
(2).轻量级锁
线程在执行同步块之前,JVM会先在当前线程的栈帧中创建用于存储锁记录的空间,并将对象头的MarkWord复制到锁记录中,即Displaced Mark Word。然后线程会尝试使用CAS将对象头中的Mark Word替换为指向锁记录的指针。如果成功,当前线程获得锁。如果失败,表示其他线程在竞争锁,当前线程使用自旋来获取锁。当自旋次数达到一定次数时,锁就会升级为重量级锁。
轻量级锁解锁时,会使用CAS操作将Displaced Mark Word替换回到对象头,如果成功,表示没有竞争发生。如果失败,表示当前锁存在竞争,锁已经被升级为重量级锁,则会释放锁并唤醒等待的线程。
(1).偏向锁
当一个线程访问同步块并获取锁时,会在对象头和栈帧的锁记录里存储偏向的线程ID,以后该线程在进入和退出同步块时不需要进行CAS操作来加锁和解锁,只需测试Mark Word里线程ID是否为当前线程。如果测试成功,表示线程已经获得了锁。如果测试失败,则需要判断偏向锁的标识。如果标识被设置为0(表示当前是无锁状态),则使用CAS竞争锁;如果标识设置成1(表示当前是偏向锁状态),则尝试使用CAS将对象头的偏向锁指向当前线程,触发偏向锁的撤销。偏向锁只有在竞争出现才会释放锁。当其他线程尝试竞争偏向锁时,程序到达全局安全点后(没有正在执行的代码),它会查看Java对象头中记录的线程是否存活,如果没有存活,那么锁对象被重置为无锁状态,其它线程可以竞争将其设置为偏向锁;如果存活,那么立刻查找该线程的栈帧信息,如果还是需要继续持有这个锁对象,那么暂停当前线程,撤销偏向锁,升级为轻量级锁,如果线程1不再使用该锁对象,那么将锁对象状态设为无锁状态,重新偏向新的线程。
(2).轻量级锁
线程在执行同步块之前,JVM会先在当前线程的栈帧中创建用于存储锁记录的空间,并将对象头的MarkWord复制到锁记录中,即Displaced Mark Word。然后线程会尝试使用CAS将对象头中的Mark Word替换为指向锁记录的指针。如果成功,当前线程获得锁。如果失败,表示其他线程在竞争锁,当前线程使用自旋来获取锁。当自旋次数达到一定次数时,锁就会升级为重量级锁。
轻量级锁解锁时,会使用CAS操作将Displaced Mark Word替换回到对象头,如果成功,表示没有竞争发生。如果失败,表示当前锁存在竞争,锁已经被升级为重量级锁,则会释放锁并唤醒等待的线程。
5.reentrantlock有用到过吗?
可以从这里引出AQS,如果自己看过AQS源码的话,肯定是一个加分项,如果自己对AQS了解的不多,那就可以说自己了解的不是很深入,但是建议这快好好看看,毕竟也是高频问题,甚至有的时候面试官可能会有一些场景题,然后问你如何解决。一般都是多线程的场景题,甚至有的会让你写多线程的题目。
6.说说syn和reentrantlock的区别?
(1)等待可中断 (2)可以实现公平锁 (3)可以绑定多个condition条件等 (4)一个api层面的,一个jvm层面的。
7.aqs原理说一下
建议去看看一些源码,网上有些人写的博客还是不错的,也可以去看看《Java并发编程之美》
8.spring中的ioc说一下
有时间和精力的同学可以去看看spring的源码,尤其ioc这块,这里面就包含一些常问的问题
(1)ioc说一下你的理解
(2)bean的生命周期
(3)bean的循环依赖问题
(4)aop的问题
(5)动态代理的实现方式
(6)spring中用到的设计模式
(7)spring的默认单例模式是线程安全的吗?
(8)spring 的注入方式
(9)等等。。。有些公司问的很细!
9.redis常见的数据结构?
除了知道五种常见的以外,还有几个特殊的数据结构最好也说一下,另外就是基本数据结构的应用场景。
高频问题:
(1)有没有去看过redis的string类型是如何实现的
(2)zset底层如何实现的?
(3)zset底层为什么不用红黑树或者二叉树之类的
(4)zset源码有没有看过
10.zset的底层实现
11.redis集群方式,都有什么区别
几种常见的集群,你项目里用到过吗?
12.redis的数据一致性问题?
经典的问题!!!
13.rabbitmq了解吗?
(1)消息队列的应用场景
(2)如何解决消息的不重复性
(3)如何解决消息的不丢失
(4)有没有对比过其他消息中间件
14.rabbitmq如何实现数据的不重复性?
15.mysql的隔离级别
经典必问问题
(1)每种隔离级别会产生什么问题
(2)innodb默认的隔离级别,会产生什么问题?如何解决的?
(3)为什么不用最高的隔离级别呢?
16.说说幻读问题?
17.一条慢sql怎么优化
常问问题!!!
慢 SQL 语句的几种常见诱因
1. 无索引、索引失效导致慢查询
2. 锁等待
3. 不恰当的 SQL 语句
优化 SQL 语句的步骤
1. 通过 EXPLAIN 分析 SQL 执行计划
假设现在我们使用 EXPLAIN 命令查看当前 SQL 是否使用了索引,先通过 SQL EXPLAIN
导出相应的执行计划如下:
2. 通过 Show Profile 分析 SQL 执行性能
上述通过 EXPLAIN 分析执行计划,仅仅是停留在分析 SQL 的外部的执行情况,如果我们
想要深入到 MySQL 内核中,从执行线程的状态和时间来分析的话,这个时候我们就可以
选择 Profile。
Profile 除了可以分析执行线程的状态和时间,还支持进一步选择 ALL、CPU、MEMORY、
BLOCK IO、CONTEXT SWITCHES 等类型来查询 SQL 语句在不同系统资源上所消耗的时
间。
整体面试体验还行,下周四二面,希望二面顺利,欢迎大家一起讨论技术问题!!!
全部评论
(2) 回帖