关于Java面试,你应该准备这些知识点

马老师说过,员工的离职缘由不少,只有两点最真实:java

  • 钱,没给到位
  • 心,受委屈了

固然,我是想换个平台,换个方向,想清楚为何要跳槽,若是真的要跳槽,想要拿到一个理想的offer,除了运气,基本功也要足够的扎实,但愿下面的面试经验能给大家可以提供一些帮助。面试

项目经验

面试官在一开始会让你进行自我介绍,主要是想让你介绍一下本身作过的一些项目,看看你对这些项目的了解程度,由于不少人简历上写的项目并不是都是从头至尾都参与的,有些只是参与并实现了其中的一些模块而已,或是接手维护别人的项目,因此在你简历上所写的和面试过程当中所说的项目经验,你本身必须可以了解前因后果,由于面试官确定会根据你的项目描述,对项目中的实现原理,或为何要这样实现进行提问,这时不至于木讷住而不知如何做答,如此局面只会大大下降面试分。安全

场景对话:
面试官:(拿着简历)讲讲你最近作的这个项目数据结构

我:&……%¥#*&¥@%¥!,说了一大通(不知道面试官听进去多少,面试官会挑他会的进行提问)多线程

面试官:你说这个项目中用到了netty,能大概讲讲netty的线程模型么?并发

我:(幸亏我看过netty的源码)netty经过Reactor模型基于多路复用器接收并处理用户请求(能讲就多讲一点),内部实现了两个线程池,boss线程池和work线程池,其中boss线程池的线程负责处理请求的accept事件,当接收到accept事件的请求时,把对应的socket封装到一个NioSocketChannel中,并交给work线程池,其中work线程池负责请求的read和write事件(经过口述加画图的方式,把请求的执行过程大概描述了一遍,时间有限,也不可能把全部的细节都说完,挑重点讲,挑记忆深入的讲)socket

面试官:嗯,理解的还挺深刻的…那你在作这个项目时有没有遇到什么困难,或者是以为有挑战的地方?函数

我:(这时面试官想让你本身出题本身回答了,因此必定要回答,不回答就突显不出你这个项目了,要是这个问题没有准备过,只能临时发挥了,固然我就是属于临时发挥的)稍微想一下,由于以前确实碰到了这个问题,当时作这个项目时,对netty的不过熟悉,把请求的业务逻辑放在work线程池的线程中进行处理,进行压测的时候,发现qps老是上不去,后来看了源码以后才发现,因为业务逻辑的处理比较耗时,彻底占用了work线程池的资源,致使新的请求一直处于等待状态。性能

面试官:那最后是如何解决的?优化

我:最后把处理业务的逻辑封装成一个task提交给一个新建的业务线程池中执行,执行完以后由work线程池执行请求的write事件。

面试官:好的,你知道nio中selector可能触发bug么?

我:嗯,对的,selector的select方法,由于底层的epoll函数可能会发生空转,从而致使cpu100%。

面试官:那如何解决该问题?

我:这个问题在netty已经解决了,经过&^%&$^(把netty的解决方案说一遍)

面试官:嗯,对了,大家这个项目有给本身定指标么?

我:有的,&&…………¥¥##@,把本身项目的指标说了一通,如何进行AB实验,如何迭代优化指标

面试官:嗯,好的 ,项目的问题先到这里,咱们来考察一下java的基本点吧。

如上只是本人所作的一个项目,固然了,具体项目具体分析,也不是每一个面试官问的点都同样,若是面试官不懂netty,天然会挑别的问题进行提问,不过你也能够尝试着把问题往本身熟悉的方向去靠。

面试知识点

一、线程池

线程池的实现原理,这个知识点真的很重要,几乎每次面试都会被问到,通常的提问方式有以下几种:
一、“讲讲线程池的实现原理”
二、“线程池中的coreNum和maxNum有什么不一样”
三、“在不一样的业务场景中,线程池参数如何设置”

场景对话:
面试官:平时线程池用的多么?

我:嗯,个人

*
项目中就用到了

面试官:那好,你讲讲线程池的实现原理

我:(还好我以前看过源码,可是时间久远有点模糊了),能给我笔和纸么,我画图分析给你看看,&&¥&假设初始化一个线程池,核心线程数是5,最大线程数是10@@@

面试官:嗯,好的,你继续…

我:在纸上画了正方形,这个表明一个线程池,初始化的时候,里面是没有线程的

面试官:嗯,好的,你继续…

我:又画了一个细长的长方形,这个表明阻塞队列,一开始里面也是没有任务的

面试官:嗯,好的,你继续…

我:当来了一个任务时,在正方形中画了一个小圆圈,表明初始化了一个线程,若是再来一个任务,就再画一个圆圈,表示再初始化了一个线程,连续画了5个圆圈以后,若是第6个任务过来了…

面试官:嗯,好的,你继续…

我:这时会把第6个任务放到阻塞队列中..

面试官:嗯,而后呢?

我:如今线程池中不是有5个线程了么,若是其中一个线程空闲了,就会从阻塞队列中获取第6个任务,进行执行..

面试官:嗯,对的,那若是任务产生的速度比消费的速度快呢?

我:若是线程池的5个线程都在running状态,那么任务就先保存在阻塞队列中

面试官:若是队列满了,怎么办?

我:若是队列满了,咱们不是设置了最大线程数是10么,而线程池中只有5个线程,这时会新建一个线程去执行不能保存到阻塞队列的任务,而后我又在正方形中画了5个圆圈。

面试官:那若是线程池中的线程数达到10个了,阻塞队列也满了,怎么办?

我:这种状况经过自定义reject函数去处理这里任务了,舒了一口去,觉得问完了…

面试官:好的,那若是运行一段时间以后,阻塞队列中的任务也执行完了,线程池中的线程会怎么样?

我:…这个好像超过核心线程数的线程会在空闲一段时间内自动回收…由于有点不记得这个逻辑了,回答的有点虚…

面试官:好的,那这种状况在什么场景下会发生?

我:(有时候真是笨啊,不少东西都知道,可是在面试的时候一紧张,全忘记)这个…那个…我好像没有遇到过这样的状况

面试官:嗯,好的,你回去以后再好好想一想

我:……..

我竟然忘记了秒杀这个场景

二、锁的实现

在关于锁的面试过程当中,通常主要问Synchronized和ReentrantLock的实现原理,更有甚者会问读写锁。

场景对话:
面试官:都了解Java中的什么锁?

我:好比Synchronized和ReentrantLock…读写锁用的很少,就没研究了(我就怕被问读写锁,由于一直没去看)

面试官:那好,你先说说Synchronized的实现原理吧

我:嗯,Synchronized是JVM实现的一种锁,其中锁的获取和释放分别是monitorenter和monitorexit指令,该锁在实现上分为了偏向锁、轻量级锁和重量级锁,其中偏向锁在1.6是默认开启的,轻量级锁在多线程竞争的状况下会膨胀成重量级锁,有关锁的数据都保存在对象头中…&&@@#,(嗯,说了一大堆,面试官也没打断我)

面试官:哦,嗯,理解的还挺透彻,那你说说ReentrantLock的实现吧…

我:ReentrantLock是基于AQS实现的

面试官:什么是AQS?

我:在AQS内部会保存一个状态变量state,经过CAS修改该变量的值,修改为功的线程表示获取到该锁,没有修改为功,或者发现状态state已是加锁状态,则经过一个Waiter对象封装线程,添加到等待队列中,并挂起等待被唤醒&&&$$(又说了一堆)

面试官:能说说CAS的实现原理么?

我:CAS是经过unsafe类的compareAndSwap方法实现的(内心得意的一笑)

面试官:哦,好的,那你知道这个方法的参数的含义的么?

我:(这是在逼我啊…努力的回想,由于我真的看过啊)我想一想啊,这个方法看的时间有点久远了,第一个参数是要修改的对象,第二个参数是对象中要修改变量的偏移量,第三个参数是修改以前的值,第四个参数是预想修改后的值….(说出来以后都有点佩服本身,这个都记得,不过面试官好像仍是不愿放过我…)

面试官:嗯,对的,那你知道操做系统级别是如何实现的么?

我:(我去你大爷…)我只记得X86中有一个cmp开头的指令,具体的我忘记了…

面试官:嗯,好,你知道CAS指令有什么缺点么

我:哦,CAS的缺点是存在ABA问题

面试官:怎么讲?

我:就是一个变量V,若是变量V初次读取的时候是A,而且在准备赋值的时候检查到它仍然是A,那能说明它的值没有被其余线程修改过了吗?若是在这段期间它的值曾经被改为了B,而后又改回A,那CAS操做就会误认为它历来没有被修改过。

面试官:那怎么解决?

我:(有完没完了啊…个人内心是崩溃的)针对这种状况,java并发包中提供了一个带有标记的原子引用类”AtomicStampedReference”,它能够经过控制变量值的版原本保证CAS的正确性。

面试官:嗯,好的,这个问题到此为止,咱们再看看别的

我:….我能喝口水么

三、ConcurrentHashMap

当考察数据结构时,面试官一开始会问HashMap的实现原理,当你说出HashMap并不是线程安全以后,会让你本身引出ConcurrentHashMap,接着就可能开始以下的对话。

场景对话:
面试官:谈谈ConcurrentHashMap实现原理

我:@#¥@@基于分段锁的%%¥#@#¥,可是1.8以后改变实现方式了

面试官:1.8啥方式

我:把1.8的实现原理说了一通,其中提到了红黑树…

面试官:能讲下红黑树的概念吗

我:红黑树是一种二叉树,而且是平衡……%……¥……,

面试官:能讲下红黑树的。。。。。

我:打住,别问了,红黑树我只知道他是二叉树,比其余树多一个属性,其余的我都不知道
面试官:好的,那换个,你知道它的size方法是如何实现的么?

我:size方法?是想要获得Map中的元素个数么?

面试官:对的….

我:我记得好像size方法返回是不许确的,平时也不会用到这个方法…

面试官:若是你以为size方法返回值不许确,那若是让你本身实现,你以为应该怎么实现呢?

我:…@#¥@@…两眼一黑

我:等等,让我想一想…..应该能够用AtomicInteger变量进行记录…嗯,对的,每次插入或删除的时候,操做这个变量,我得意的一笑…

面试官:哦,是么,那若是我以为这个AtomicInteger这个变量性能很差,还能再优化么?

我:懵逼脸…(当时竟然把volitile变量给忘记了)…好像没有了,我想不出来了…

面试官:哦,那回头你再看看源码吧,jdk中已经实现了…

我:哦,是么….

面试官:那今天的面试到此结束,咱们后面会通知你。

相关文章
相关标签/搜索