【面试普通人VS高手系列】请简述一下伪共享的概念以及如何避免

一个工作5年的小伙伴,2个星期时间,去应聘了10多家公司,结果每次在技术面试环节,被技术原理难倒了。

他现在很尴尬, 简历投递出去就像石沉大海,基本没什么面试邀约。

技术能力的提升也不是一两天的事情,所以他现在特别焦虑。

于是,我从他遇到过的面试题里面抽出来一道,给大家分享一下。

“请简述一下伪共享的概念以及避免的方法”

对于这个问题,看看高手该怎么回答。

 部分高手面试文档已整理,需要的小伙伴可以扫描添加下方二维码

普通人:

额.................

高手:

对于这个问题,要从几个方面来回答。

首先,计算机工程师为了提高CPU的利用率,平衡CPU和内存之间的速度差异,在CPU里面设计了三级缓存。

CPU在向内存发起IO操作的时候,一次性会读取64个字节的数据作为一个缓存行,缓存到CPU的高速缓存里面。

在Java中一个long类型是8个字节,意味着一个缓存行可以存储8个long类型的变量。

这个设计是基于空间局部性原理来实现的,也就是说,如果一个存储器的位置被引用,那么将来它附近的位置也会被引用。

所以缓存行的设计对于CPU来说,可以有效的减少和内存的交互次数,从而避免了CPU的IO等待,以提升CPU的利用率。

正是因为这种缓存行的设计,导致如果多个线程修改同一个缓存行里面的多个独立变量的时候,基于缓存一致性协议,就会无意中影响了彼此的性能,这就是伪共享的问题。

像这样一种情况,CPU0上运行的线程想要更新变量X、CPU1上的线程想要更新变量Y,而X/Y/Z都在同一个缓存行里面。

每个线程都需要去竞争缓存行的所有权对变量做更新,基于缓存一致性协议。

一旦运行在某个CPU上的线程获得了所有权并执行了修改,就会导致其他CPU中的缓存行失效。

这就是伪共享问题的原理。

因为伪共享会问题导致缓存锁的竞争,所以在并发场景中的程序执行效率一定会收到较大的影响。

这个问题的解决办法有两个:

  1. 使用对齐填充,因为一个缓存行大小是64个字节,如果读取的目标数据小于64个字节,可以增加一些无意义的成员变量来填充。

  2. 在Java8里面,提供了@Contented注解,它也是通过缓存行填充来解决伪共享问题的,被@Contented注解声明的类或者字段,会被加载到独立的缓存行上。

已上就是我对这个问题的理解!

总结

在Netty里面,有大量用到对齐填充的方式来避免伪共享问题。

所以这并不是一个所谓超纲的问题,在我看来,多线程也好、数据结构算法也好、还是JVM,这是一个合格的Java程序员必须要掌握的基础。

我们习惯了在框架里面写代码,却忽略了各种成熟框架已经让Java程序员变得越来越普通。

本期的普通人VS高手面试系列就到这里结束了。

有任何不懂的技术面试题,欢迎随时私信我。

 部分高手面试文档已整理,需要的小伙伴可以扫描添加下方二维码

↓↓↓↓↓↓↓↓

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

跟着Mic学架构

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值