现在的位置: 首页 > 综合 > 正文

wed前端求职Java面试官最爱问的volatile关键字

2019年11月12日 综合 ⁄ 共 1571字 ⁄ 字号 评论关闭

  wed前端Java在求职的过程中难免会被hr各种提问,那么这些面试官最喜欢问那些问题呢?经过这些面试官的反复提问这些问题后,你是否思考过为什么他们那么爱问这些问题呢?如果作为面试官是否也拿这些问题来作为切入点呢?

  为什么爱问volatile关键字

  爱问volatile关键字的面试官,大多数情况下都是有一定功底的,因为volatile作为切入点,往底层走可以切入Java内存模型(JMM),往并发方向走又可接切入Java并发编程,当然,再深入追究,JVM的底层操作、字节码的操作、单例都可以牵扯出来。

  所以说懂的人提问题都是有门道的。那么,先整体来看看volatile关键字都设计到哪些点:内存可见性(JMM特性)、原子性(JMM特性)、禁止指令重排、线程并发、与synchronized的区别……再往深层次挖,可能就涉及到字节码、JVM等。

  不过值得庆幸的是,如果你已经学习了微信公众号“程序新视界”JVM系列的文章,上面的知识点已经不是什么问题了,权当是复习了。那么,下面就以面试官提问的形式,在不看答案的情况下,尝试回答,看看学习效果如何。夺命连环问,开始……

  面试官:说说volatile关键字的特性

  被volatile修饰的共享变量,就具有了以下两点特性:

  保证了不同线程对该变量操作的内存可见性;

  禁止指令重排序;

  回答的很好,点出了volatile关键字两大特性。针对该两大特性继续深入。

  面试官:提到JMM和可见性,能说说JMM的其他特性吗

  我们知道JMM除了可见性,还有原子性和有序性。

  原子性即一个操作或一系列是不可中断的。即使是在多个线程的情况下,操作一旦开始,就不会被其他线程干扰。

  比如,对于一个静态变量int x两条线程同时对其赋值,线程A赋值为1,而线程B赋值为2,不管线程如何运行,最终x的值要么是1,要么是2,线程A和线程B间的操作是没有干扰的,这就是原子性操作,不可被中断的。

  在Java内存模型中有序性可归纳为这样一句话:如果在本线程内观察,所有操作都是有序的,如果在一个线程中观察另一个线程,所有操作都是无序的。

  有序性是指对于单线程的执行代码,执行是按顺序依次进行的。但在多线程环境中,则可能出现乱序现象,因为在编译过程会出现“指令重排”,重排后的指令与原指令的顺序未必一致。

  因此,上面归纳的前半句指的是线程内保证串行语义执行,后半句则指指“令重排现”象和“工作内存与主内存同步延迟”现象。

  面试官:还能举出其他例子说明volatile的作用吗

  可举单例模式的实现,典型的双重检查锁定(DCL):

  这是一种懒汉的单例模式,使用时才创建对象,而且为了避免初始化操作的指令重排序,给instance加上了volatile。

  为什么用了synchronized还要用volatile?具体来说就是synchronized虽然保证了原子性,但却没有保证指令重排序的正确性,会出现A线程执行初始化,但可能因为构造函数里面的操作太多了,所以A线程的instance实例还没有造出来,但已经被赋值了(即代码中2操作,先分配内存空间后构建对象)。

  而B线程这时过来了(代码1操作,发现instance不为null),错以为instance已经被实例化出来,一用才发现instance尚未被初始化。要知道我们的线程虽然可以保证原子性,但程序可能是在多核CPU上执行。

  然,针对volatile关键字还有其他方面的拓展,比如讲到JMM时可拓展到JMM与Java内存模型的区别,讲到原子性时可扩展到如何查看class字节码,讲到并发可扩展到线程并发的方法面面。

  其实,不仅面试如此,在学习知识时也可以参考这种面试思维,多问几个为什么。将一个点,通过为什么拓展成一个知识网。

抱歉!评论已关闭.