4年开发二面美团最终败给:volatile关键字作用和原理这道面试题

简介: 一位6年工作经验的小伙伴,在某里二面的时候被问到“volatile”关键字。然后,就没有然后了…同样,还有一位4年的小伙伴,去某团面试也被问到“volatile 关键字“。然后,也没有然后了…volatile关键字是Java并发编程中的一个重要的关键字,这个问题确实问得比较底层了。难道大厂现在都这么卷了吗?那今天呢,我给大家分享一下我的理解,希望能够帮助到大家。

一位6年工作经验的小伙伴,在某里二面的时候被问到“volatile”关键字。然后,就没有然后了…


同样,还有一位4年的小伙伴,去某团面试也被问到“volatile 关键字“。然后,也没有然后了…


volatile关键字是Java并发编程中的一个重要的关键字,这个问题确实问得比较底层了。难道大厂现在都这么卷了吗?那今天呢,我给大家分享一下我的理解,希望能够帮助到大家。


另外,我准备了一份500页的PDF面试题解析配套文档,

如何获取? :

扫描文章底部二维码领取!

1、volatile的作用

volatile 关键字呢,有两个作用:

e89c5326a7f5b8308bf3e9c9eb6e6f4c.png

第1个,是可以保证在多线程环境下共享变量的可见性。

第2个,是可以屏蔽在多线程环境下CPU的指令重排。

下面,我给大家详细介绍一下可见性和屏蔽指令重排以及volatile的工作原理。

2、原理分析

先来看变量的可见性,简单来说,就是指当某一个线程对共享变量的修改,其他线程可以立刻看到修改之后的值。其实这个可见性问题,我认为本质上是由以下两个方面造成的。

首先是,CPU的高速缓存。在 CPU 里面设计了三级缓存去解决 CPU 运算效率和内存 IO 效率问题,但是有带来了缓存的一致性问题,而在多线程并行执行的情况下,缓存一致性就会导致可见性问题。

0a00e2a1ee6e0fe9283f9949a3a61bae.png

所以,对于增加了 volatile 关键字修饰的共享变量,JVM 虚拟机会自动增加一个#Lock 汇编指令,这个指令会根据 CPU 型号自动添加总线锁或/缓存锁。

我简单介绍一下这两种锁:

总线锁是锁定了 CPU 的前端总线,从而导致在同一时刻只能有一个线程去和内存通信,这样就避免了多线程并发造成的可见性。

缓存锁是对总线锁的优化,因为总线锁导致了 CPU 的使用效率大幅度下降,所以缓存锁只针对 CPU 三级缓存中的目标数据加锁,缓存锁是使用 MESI 缓存一致性来实现的。

然后,就是屏蔽指令重排,就是指屏蔽CPU指令重排序。意思是在多线程环境下,CPU指令的编写顺序和执行顺序不一致,从而导致可见性问题,为了提升 CPU 的利用率,CPU引入了StoreBuffer 机制,而这一种优化机制会导致 CPU 的乱序执行。当然为了避免这样的问题,CPU 提供了内存屏障指令,上层应用可以在合适的地方插入内存屏障来避免 CPU 指令重排序问题。而volatile就是通过设置内存屏障来禁止指令重排。

volatile内存屏障实现原理主要从以下两个方面来分析:

第1个是:volatile会在变量写操作的前后加入两个内存屏障,来保证前面的写指令和后面的读指令是有序的,如图所示:

093642cef1f579d48b34da2c5555d779.png

第2个是:volatile在变量的读操作后面插入两个指令,禁止后面的读指令和写指令重排序。,如图所示:

dc4d314802c033ada19b16efaac68613.png

volatile其实可以看作是轻量级的synchronized,虽然说volatile不能保证原子性,但是如果在多线程下的操作本身就是原子性操作(例如赋值操作),那么使用volatile会优于synchronized。以上就是我对volatile 关键字的理解。

并发编程是每个程序员必须要掌握好的领域,它里面涵盖的设计思想、和并发问题的解决思路、以及作为一个并发工具,都是非常值得深度研究的。

最后,我把往期分享的视频全部整理成了1份20W字的文档,希望能够以此来提高各位粉丝的通过率

ee90d9963df444db88b33d6e798a5b94.gif

我是被编程耽误的文艺Tom,只弹干货不掺水!你们的支持就是我最大的动力!关注我,面试不再难!

相关文章
|
8天前
|
消息中间件 存储 缓存
大厂面试高频:Kafka 工作原理 ( 详细图解 )
本文详细解析了 Kafka 的核心架构和实现原理,消息中间件是亿级互联网架构的基石,大厂面试高频,非常重要,建议收藏。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:Kafka 工作原理 ( 详细图解 )
|
10天前
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
|
10天前
|
存储 安全 Java
面试高频:Synchronized 原理,建议收藏备用 !
本文详解Synchronized原理,包括其作用、使用方式、底层实现及锁升级机制。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
面试高频:Synchronized 原理,建议收藏备用 !
|
19天前
|
SQL 缓存 关系型数据库
美团面试:Mysql 有几级缓存? 每一级缓存,具体是什么?
在40岁老架构师尼恩的读者交流群中,近期有小伙伴因未能系统梳理MySQL缓存机制而在美团面试中失利。为此,尼恩对MySQL的缓存机制进行了系统化梳理,包括一级缓存(InnoDB缓存)和二级缓存(查询缓存)。同时,他还将这些知识点整理进《尼恩Java面试宝典PDF》V175版本,帮助大家提升技术水平,顺利通过面试。更多技术资料请关注公号【技术自由圈】。
美团面试:Mysql 有几级缓存? 每一级缓存,具体是什么?
|
8天前
|
存储 缓存 Java
大厂面试高频:Volatile 的实现原理 ( 图文详解 )
本文详解Volatile的实现原理(大厂面试高频,建议收藏),涵盖Java内存模型、可见性和有序性,以及Volatile的工作机制和源码案例。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:Volatile 的实现原理 ( 图文详解 )
|
1月前
|
算法 Java 数据库
美团面试:百亿级分片,如何设计基因算法?
40岁老架构师尼恩分享分库分表的基因算法设计,涵盖分片键选择、水平拆分策略及基因法优化查询效率等内容,助力面试者应对大厂技术面试,提高架构设计能力。
美团面试:百亿级分片,如何设计基因算法?
|
1月前
|
存储 监控 算法
美团面试:说说 G1垃圾回收 底层原理?说说你 JVM 调优的过程 ?
尼恩提示: G1垃圾回收 原理非常重要, 是面试的重点, 大家一定要好好掌握
美团面试:说说 G1垃圾回收 底层原理?说说你 JVM 调优的过程  ?
|
21天前
|
SQL 关系型数据库 MySQL
美团面试:Mysql如何选择最优 执行计划,为什么?
在40岁老架构师尼恩的读者交流群中,近期有小伙伴面试美团时遇到了关于MySQL执行计划的面试题:“MySQL如何选择最优执行计划,为什么?”由于缺乏系统化的准备,小伙伴未能给出满意的答案,面试失败。为此,尼恩为大家系统化地梳理了MySQL执行计划的相关知识,帮助大家提升技术水平,展示“技术肌肉”,让面试官“爱到不能自已”。相关内容已收录进《尼恩Java面试宝典PDF》V175版本,供大家参考学习。
|
1月前
|
负载均衡 算法 Java
蚂蚁面试:Nacos、Sentinel了解吗?Springcloud 核心底层原理,你知道多少?
40岁老架构师尼恩分享了关于SpringCloud核心组件的底层原理,特别是针对蚂蚁集团面试中常见的面试题进行了详细解析。内容涵盖了Nacos注册中心的AP/CP模式、Distro和Raft分布式协议、Sentinel的高可用组件、负载均衡组件的实现原理等。尼恩强调了系统化学习的重要性,推荐了《尼恩Java面试宝典PDF》等资料,帮助读者更好地准备面试,提高技术实力,最终实现“offer自由”。更多技术资料和指导,可关注公众号【技术自由圈】获取。
蚂蚁面试:Nacos、Sentinel了解吗?Springcloud 核心底层原理,你知道多少?
|
1月前
|
SQL 关系型数据库 MySQL
阿里面试:MYSQL 事务ACID,底层原理是什么? 具体是如何实现的?
尼恩,一位40岁的资深架构师,通过其丰富的经验和深厚的技術功底,为众多读者提供了宝贵的面试指导和技术分享。在他的读者交流群中,许多小伙伴获得了来自一线互联网企业的面试机会,并成功应对了诸如事务ACID特性实现、MVCC等相关面试题。尼恩特别整理了这些常见面试题的系统化解答,形成了《MVCC 学习圣经:一次穿透MYSQL MVCC》PDF文档,旨在帮助大家在面试中展示出扎实的技术功底,提高面试成功率。此外,他还编写了《尼恩Java面试宝典》等资料,涵盖了大量面试题和答案,帮助读者全面提升技术面试的表现。这些资料不仅内容详实,而且持续更新,是求职者备战技术面试的宝贵资源。
阿里面试:MYSQL 事务ACID,底层原理是什么? 具体是如何实现的?