最近有讀者投簡歷去一家小公司去面試的時候,和麪試官聊了一個小時的Java併發編程,整個過程已全記錄下來。面試的時候小心翼翼,如履薄冰,生怕說錯一句話,就錯失機會,擔心,面試緊張、卡殼。不知道大家有沒有這個問題?
面試過程
面試官:你知道CAS嗎,能跟我講講嗎?
我:CAS(Compare And Swap),比較並交換。整個AQS同步組件,Atomic原子類操作等等都是基於CAS實現的,甚至ConcurrentHashMap在JDK1.8版本中,也調整爲CAS+synchronized。可以說,CAS是整個JUC的基石。
CAS的實現方式其實不難。在CAS中有三個參數:內存值V、舊的預期值A、要更新的值B,當且僅當內存值V的值等於舊的預期值A時,纔會將內存值V的值修改爲B,否則什麼也不幹,是一種樂觀鎖。其僞代碼如下:
我:接着我舉了個AtomicInteger的例子,來給面試官闡述CAS的實現。
面試官:那CAS有什麼缺陷嗎?
我:CAS雖然高效的解決了原子問題,但是還是存在一些缺陷的,主要體現在三個方面:
1.循環時間太長:如果自旋CAS長時間不成功,則會給CPU帶來非常大的開銷,在JUC中,有些地方就會限制CAS自旋的次數。
2.只能保證一個共享變量原子操作:看了CAS的實現就知道這隻能針對一個共享變量,如果是多個共享變量就只能使用鎖了。或者把多個變量整成一個變量也可以用CAS。
3.ABA問題:CAS需要檢查操作值有沒有發生改變,如果沒有發生改變則更新,但是存在這樣一種情況:如果一個值原來是A,變成了B,然後又變成了A,那麼在CAS檢查的時候會發現沒有改變,但是實質上它已經發生了改變,這就是所謂的ABA問題。對於ABA問題的解決方案是加上版本號,即在每個變量都加上一個版本號,每次改變時加1,即A->B->A,變成1A->2B->3A。例如原子類中AtomicInteger會發生ABA問題,使用AtomicStampedReference可以解決ABA問題。
面試官:你能說下輕量級鎖嗎?
面試官:你先說下你對synchronized的瞭解。
面試官:什麼是原子操作?
面試官:什麼是Executors框架?
面試官:什麼是阻塞隊列?阻塞隊列的實現原理是什麼?如何使用阻塞隊列來實現生產者-消費者模型?
面試官:CycliBarriar和CountdownLatch有什麼區別?
面試官:Java中用到的線程調度算法是什麼?
我: 淦,年輕人不講武德
總結
面試的時候,開口第一句,面試官就知道你的水平了。你很多東西用過,但是並不懂底層原理,面試官一問,你就啞火了… 併發編程中涉及到的知識點其實挺多,工作多年的程序員,應該掌握哪些技術?如何才能在大廠面試中侃侃而談,在無數競爭對手中脫穎而出?
爲了給在工作和技術上遇到瓶頸的小夥伴找到發展方向,徹底要把這塊技術掌握好,分享這些併發學習筆記手冊及真題解析和配套視頻給有需要的小夥伴,這些學習資源都對Java併發核心解析得很透徹,還結合了面試真題。推薦大家免費學習:點擊這裏即可來免費獲取了
Java併發編程學習筆記
第一部分:線程基礎、線程之間的共享和協作
第二部分:線程的併發工具類
第三部分:原子操作CAS
第四部分:顯式鎖和AQS
第五部分:併發容器
第六部分:線程池
第七部分:併發安全
第八部分:實戰項目
第九部分:JMM和底層實現原理
第十部分:Java8新增的併發