自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

面試官超級喜歡問的CAS

開發(fā) 前端
如果對CAS完全不了解的同學(xué)建議先去看看相關(guān)的博客了解了基本的原理,再來看面試的時(shí)候如何解答。

[[433816]]

文末本文轉(zhuǎn)載自微信公眾號「程序員巴士」,作者tech-bus.七十一 。轉(zhuǎn)載本文請聯(lián)系程序員巴士公眾號。

 前言

自學(xué)了一年JAVA阿巴阿巴終于約到了面試,這次面試官讓她談?wù)剬AS的理解。

回去等通知

如果對CAS完全不了解的同學(xué)建議先去看看相關(guān)的博客了解了基本的原理,再來看面試的時(shí)候如何解答

面試官: 對CAS有了解嗎?可以講講嗎?

阿巴阿巴: 了解一些,CAS全稱Compare And Swap,也就是比較和交換。

阿巴阿巴: CAS的思想比較簡單,主要涉及到三個(gè)值:當(dāng)前內(nèi)存值V、預(yù)期值(舊的內(nèi)存值)O、即將更新的內(nèi)存值U,當(dāng)且僅當(dāng)預(yù)期值O與當(dāng)前內(nèi)存值V相等時(shí),將內(nèi)存值V修改為更新值U,并返回true,否則返回false。

面試官: 還有嘛?CAS的使用場景知道嗎?

阿巴阿巴: 額...應(yīng)該差不多了,CAS好像在并發(fā)包里使用到了。

面試官: 好,CAS有啥缺點(diǎn)嗎?

阿巴阿巴: 額....好..好像有個(gè)ABA的問題,好像是用AtomicStampedReference解決。

面試官: 還有其他缺點(diǎn)嗎?

阿巴阿巴: 額...記不太清了....

面試官: 行,那你這邊先回去等通知哈??

阿巴阿巴: 好的~

當(dāng)場發(fā)offer

面試官: CAS了解嗎?講講

阿巴阿巴: CAS全稱Compare and Swap,也就是比較和交換。

阿巴阿巴: CAS的思想比較簡單,主要涉及到三個(gè)值:當(dāng)前內(nèi)存值V、預(yù)期值(舊的內(nèi)存值)O、即將更新的內(nèi)存值U,當(dāng)且僅當(dāng)預(yù)期值O與當(dāng)前內(nèi)存值V相等時(shí),將內(nèi)存值V修改為更新值U,返回true,否則返回false。

阿巴阿巴: CAS主要使用在一些需要上鎖的場景充當(dāng)樂觀鎖解決方案,一般在一些簡單且要上鎖的操作但又不想引入鎖場景,這時(shí)候來使用CAS代替鎖。

阿巴阿巴: CAS主要涉及到三個(gè)問題:ABA問題、自旋帶來的消耗、CAS只能單變量

面試官: 可以詳細(xì)講一下這三個(gè)問題嗎?

阿巴阿巴: ABA問題是指有一個(gè)線程t1在進(jìn)行CAS操作時(shí),其他線程t2將變量A改成了B,然后又將其改成A,這時(shí)候t1發(fā)現(xiàn)A并沒有改變,因此進(jìn)行了交換操作,由于在交換操作進(jìn)行前變量A其實(shí)是有變化的,只不過最終又修改回A了,此A非彼A,這時(shí)候進(jìn)行交換操作在一些業(yè)務(wù)場景下很可能要出問題,要解決ABA問題有2種方案。

阿巴阿巴: 方案一:在對變量進(jìn)行操作的時(shí)候給變量加一個(gè)版本號,每次對變量操作都將版本號加1,常見在數(shù)據(jù)庫的樂觀鎖中可見。

阿巴阿巴: 方案二:Java提供了相應(yīng)的原子引用類AtomicStampedReference,它通過包裝[E,Integer]的元組來對對象標(biāo)記版本戳stamp,從而避免ABA問題。

阿巴阿巴: 自旋帶來的消耗CAS自旋如果很長時(shí)間都不成功,這會(huì)給CPU帶來很大的開銷

阿巴阿巴: 解決方案:1、代碼層面破壞掉for循環(huán),設(shè)置合適的循環(huán)次數(shù)。2、使用JVM能支持處理器提供的pause指令來提升效率,它可以延遲流水線執(zhí)行指令,避免消耗過多CPU資源。

阿巴阿巴: CAS只能單變量對于一個(gè)共享變量,可以使用CAS方式來保證原子操作,但是當(dāng)多個(gè)共享變量時(shí),那就無法使用CAS來保證原子性。JDK1.5開始,提供了AtomicReference類來保證引用對象之前的原子性,就可以把多個(gè)變量放在一個(gè)對象里來進(jìn)行CAS操作。

阿巴阿巴: 在JDK1.5中新增的java.util.concurrent(JUC),就是建立在CAS之上的,一般來說CAS這種樂觀鎖適合讀多寫少的場景。

面試官見阿巴阿巴對答如流,決定為難一下她。

面試官: 了解JMM嗎,講一下JMM。

阿巴阿巴: 知道一些,JMM是JAVA內(nèi)存模型(JAVA Memory Model),目的是為了屏蔽各種硬件和操作系統(tǒng)之間的內(nèi)存訪問差異,從而讓JAVA程序在各種平臺對內(nèi)存的訪問一致。

阿巴阿巴: 不僅如此,JMM還規(guī)定了所有的變量都存儲(chǔ)在主存中,每個(gè)線程都有自己獨(dú)立的工作空間,線程對變量的操作必須先從主存中讀取到自己的工作內(nèi)存中然后再進(jìn)行操作,最后回寫回主存。

阿巴阿巴: 關(guān)于主存和工作內(nèi)存的交互JAVA定義了八種操作來完成,且這些操作都是原子性的:lock、unlock、read、load、use、assign、store、write。

面試官: 不錯(cuò)不錯(cuò),那JMM是真實(shí)存在的嘛,和JVM內(nèi)存模型(JAVA 虛擬機(jī)內(nèi)存模型)是一樣的嘛?

阿巴阿巴: 不是真實(shí)存在的,JMM講的也只是一種模型,真實(shí)的實(shí)現(xiàn)可能還是和模型會(huì)有差異的。JMM和JVM是不一樣的,它們并不是同一個(gè)層次的劃分,基本上沒啥關(guān)系。

堆和方法區(qū)是線程共享的,虛擬機(jī)棧、本地方法棧、程序計(jì)數(shù)器是線程私有的。

程序計(jì)數(shù)器是這幾塊區(qū)域唯一一個(gè)不會(huì)發(fā)生OOM的區(qū)域。

面試官: 理解的還不錯(cuò)嘛,那你講講Volatile關(guān)鍵字唄。

阿巴阿巴: Volatile可以說是JAVA虛擬機(jī)提供的最輕量級的同步機(jī)制,當(dāng)一個(gè)變量被定義為volatile后,它將具備倆種特性,第一個(gè)是保證此變量對所有線程的可見性,即當(dāng)一個(gè)線程改變了這個(gè)變量的值后,其他線程能夠立即感知的到,雖然具有可見性,但是多線程在并發(fā)情況下對volatile修飾的變量進(jìn)行操作時(shí)是會(huì)有線程安全性的問題的。這是因?yàn)関olatile修飾的變量在各個(gè)線程工作內(nèi)存中是不存在一致性的,但是由于每次使用都要進(jìn)行刷新,導(dǎo)致執(zhí)行引擎看不到不一致的情況。

阿巴阿巴: Volatile修飾的變量的第二個(gè)特性是禁止指令重排序優(yōu)化,普通的變量僅僅會(huì)保證在該方法的執(zhí)行過程中所有依賴的賦值結(jié)果的地方都能夠獲取到正確的結(jié)果。而不能保證賦值的順序和代碼中的書寫順序一致。例如下面的DCL的單例模式。

  1. public class instance { 
  2.     private String str = ""
  3.  
  4.     private volatile static instance ins = null
  5.     /** 
  6.      * 構(gòu)造方法私有化 
  7.      */ 
  8.     private instance(){ 
  9.         str = "hi"
  10.     } 
  11.  
  12.     /** 
  13.      * DCL獲取單例 
  14.      * @return 
  15.      */ 
  16.     public static instance getinstance(){ 
  17.         if (ins == null){ 
  18.             synchronized (instance.class){ 
  19.                 if (ins == null){ 
  20.                     ins = new instance(); 
  21.                 } 
  22.             } 
  23.         } 
  24.         return ins; 
  25.     } 

阿巴阿巴: 如果上面ins變量不使用volatile變量進(jìn)行修飾,那么當(dāng)線程A在獲取了instance.class鎖后,對ins變量進(jìn)行 ins = new instance() 初始化時(shí),由于這是很多條指令,jvm可能會(huì)亂序執(zhí)行。這個(gè)時(shí)候如果線程B在執(zhí)行if (ins == null)時(shí),正常情況下,如果為true,說明需要獲取instance.class鎖,等待初始化。但是這時(shí)候,假設(shè)線程A再?zèng)]有對ins進(jìn)行初始化完,比如只分配了空間,對象還沒構(gòu)造完,但是已經(jīng)將引用返回了,這樣線程B得到的就是一個(gè)未能實(shí)例化完全的對象,從而發(fā)生異常。而加了volatile關(guān)鍵字后,如果實(shí)例還未初始化完成,那么它的引用是不會(huì)向外發(fā)布的,這樣即可避免異常的發(fā)生。

面試官: 不錯(cuò),你這塊都掌握的挺扎實(shí)的,明天可以來上班了。

阿巴阿巴: 好的??

 

責(zé)任編輯:武曉燕 來源: 程序員巴士
相關(guān)推薦

2021-12-25 22:31:10

MarkWord面試synchronize

2021-12-16 18:38:13

面試Synchronize

2021-12-02 18:20:25

算法垃圾回收

2024-03-25 11:03:38

Vue修飾符lazy

2022-01-05 08:56:20

Vue修飾符面試

2018-05-10 15:48:47

面試面試官Java

2020-07-28 00:58:20

IP地址子網(wǎng)TCP

2023-10-13 00:00:00

并發(fā)樂觀鎖CAS

2010-08-23 15:06:52

發(fā)問

2021-01-06 05:36:25

拉鏈表數(shù)倉數(shù)據(jù)

2022-01-05 09:55:26

asynawait前端

2018-01-19 10:43:06

Java面試官volatile關(guān)鍵字

2021-04-21 09:28:17

字節(jié)面試官SetTimeout

2024-06-04 07:38:10

2024-08-19 09:13:02

2010-10-27 11:07:45

面試官

2021-02-03 15:30:10

面試垃圾回收器前端

2025-03-10 03:00:00

CSSline字體

2023-06-13 07:04:27

2015-08-13 10:29:12

面試面試官
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號