深演智能Java面經(jīng)

1.線程安全定義

當多個線程訪問某個類時衬廷,不管運行時環(huán)境采用何種調(diào)度方式或者這些線程將如何交替執(zhí)行蝶怔,并且在調(diào)用代碼中不需要任何額外的同步或協(xié)同,這個類都能表現(xiàn)出正確的行為,那么這個類就是線程安全的佛南。

2.Spring全家桶基本概念

Spring

Spring是一個開源容器框架,可以接管web層嵌言,業(yè)務(wù)層嗅回,dao層,持久層的組件呀页,并且可以配置各種bean,和維護bean與bean之間的關(guān)系妈拌。其核心就是控制反轉(zhuǎn)(IOC),和面向切面(AOP),簡單的說就是一個分層的輕量級開源框架。
為依賴注入、事務(wù)管理尘分、WEB應(yīng)用猜惋、數(shù)據(jù)訪問等提供了核心的支持

SpringMVC

Spring MVC屬于SpringFrameWork的后續(xù)產(chǎn)品,已經(jīng)融合在Spring Web Flow里面培愁。
SpringMVC是一種web層mvc框架著摔,用于替代servlet(處理|響應(yīng)請求,獲取表單參數(shù)定续,表單校驗等谍咆。SpringMVC是一個MVC的開源框架,SpringMVC=struts2+spring私股,springMVC就相當于是Struts2加上Spring的整合摹察。

Springboot

Springboot是一個微服務(wù)框架,延續(xù)了spring框架的核心思想IOC和AOP倡鲸,簡化了應(yīng)用的開發(fā)和部署供嚎。
Spring Boot是為了簡化Spring應(yīng)用的創(chuàng)建、運行峭状、調(diào)試克滴、部署等而出現(xiàn)的,使用它可以做到專注于Spring應(yīng)用的開發(fā)优床,而無需過多關(guān)注XML的配置劝赔。提供了一堆依賴打包,并已經(jīng)按照使用習(xí)慣解決了依賴問題--->約定大于配置胆敞。

spring springboot開發(fā)區(qū)別

spring framework的Java Web開發(fā)模式:

  1. pom文件中引入相關(guān)jar包着帽,包括spring、springmvc竿秆、redis启摄、mybaits、log4j幽钢、mysql-connector-java 等等相關(guān)jar ...
  2. 配置web.xml,Listener配置傅是、Filter配置匪燕、Servlet配置、log4j配置喧笔、error配置 ...
  3. 配置數(shù)據(jù)庫連接帽驯、配置spring事務(wù)
  4. 配置視圖解析器
  5. 開啟注解、自動掃描功能
  6. 配置完成后部署tomcat书闸、啟動調(diào)試

springboot的Java Web開發(fā)模式:

  1. pom.xml配置需要引用的相關(guān)jar包
  2. yml中配置數(shù)據(jù)源尼变,服務(wù)器,持久層
  3. springboot啟動類加相關(guān)注解

SpringClod

Spring Cloud事實上是一整套基于Spring Boot的微服務(wù)解決方案。它為開發(fā)者提供了很多工具嫌术,用于快速構(gòu)建分布式系統(tǒng)的一些通用模式哀澈,例如:配置管理、注冊中心度气、服務(wù)發(fā)現(xiàn)割按、限流、網(wǎng)關(guān)磷籍、鏈路追蹤等适荣。

3.如果讓你自己實現(xiàn)一個springboot怎樣實現(xiàn)

ConfigurationProperties和AutoConfiguration。因為Spring Boot堅信“約定大于配置”這一理念院领,所以我們使用ConfigurationProperties來保存我們的配置弛矛,并且這些配置都可以有一個默認值,即在我們沒有主動覆寫原始配置的情況下比然,默認值就會生效丈氓,這在很多情況下是非常有用的。除此之外谈秫,starter的ConfigurationProperties還使得所有的配置屬性被聚集到一個文件中(一般在resources目錄下的application.properties)扒寄,這樣我們就告別了Spring項目中XML地獄。

創(chuàng)建自己的springboot starter

如果你想要自己創(chuàng)建一個starter拟烫,那么基本上包含以下幾步

  1. 創(chuàng)建一個starter項目该编,關(guān)于項目的命名你可以參考這里
  2. 創(chuàng)建一個ConfigurationProperties用于保存你的配置信息(如果你的項目不使用配置信息則可以跳過這一步,不過這種情況非常少見)
  3. 創(chuàng)建一個AutoConfiguration硕淑,引用定義好的配置信息课竣;在AutoConfiguration中實現(xiàn)所有starter應(yīng)該完成的操作,并且把這個類加入spring.factories配置文件中進行聲明
  4. 打包項目置媳,之后在一個SpringBoot項目中引入該項目依賴于樟,然后就可以使用該starter了

4.JVM調(diào)優(yōu)工具使用經(jīng)驗

jstat查看內(nèi)存回收概況,實時查看各個分區(qū)的分配回收情況拇囊,jmap查看內(nèi)存棧迂曲,查看內(nèi)存中對象占用大小,jstack查看線程棧寥袭,死鎖路捧,性能瓶頸,某個線程使用cpu過高導(dǎo)致服務(wù)整體慢等都可以通過在這些命令輔助Linux命令看出來传黄。

5.volatile關(guān)鍵字

volatile的特性

可見性:對一個volatile變量的讀杰扫,總能獲取其他任意線程對該變量最后的寫入。

有序性:JMM會限制volatile變量相關(guān)的編譯器重排序和處理器重排序膘掰。

可見性的內(nèi)存語義

volatile寫的內(nèi)存語義:當寫入一個volatile變量的時候章姓,JMM將線程工作內(nèi)存中的該變量的值刷新到主內(nèi)存。

volatile讀的內(nèi)存語義:當讀取一個volatile變量的時候,JMM首先將該線程工作內(nèi)存中的這個變量設(shè)置為無效凡伊,迫使該線程重新從主內(nèi)存獲取最新的有效值零渐。

編譯器對于有序性重排序的限制

  1. volatile讀寫不能被更改順序
  2. 普通讀寫之前的volatile讀不能被重排序到后面
  3. 普通讀寫之后的volatile寫不能被重排序到前面

內(nèi)存屏障實現(xiàn)有序性

LoadLoad屏障

對于這樣的語句Load1; LoadLoad; Load2,在Load2及后續(xù)讀取操作要讀取的數(shù)據(jù)被訪問前窗声,保證Load1要讀取的數(shù)據(jù)被讀取完畢相恃。

StoreStore屏障

對于這樣的語句Store1; StoreStore; Store2,在Store2及后續(xù)寫入操作執(zhí)行前笨觅,保證Store1的寫入操作對其它處理器可見拦耐。

LoadStore屏障

對于這樣的語句Load1; LoadStore; Store2,在Store2及后續(xù)寫入操作被刷出前见剩,保證Load1要讀取的數(shù)據(jù)被讀取完畢杀糯。

StoreLoad屏障

對于這樣的語句Store1; StoreLoad; Load2,在Load2及后續(xù)所有讀取操作執(zhí)行前苍苞,保證Store1的寫入對所有處理器可見固翰。它的開銷是四種屏障中最大的。 在大多數(shù)處理器的實現(xiàn)中羹呵,這個屏障是個萬能屏障骂际,兼具其它三種內(nèi)存屏障的功能。

JMM內(nèi)存屏障的插入策略

volatile寫操作前面插入一個StoreStore屏障

對比StoreStore屏障的定義冈欢,這里的volatile寫是那個Store2,該屏障保證在volatile寫執(zhí)行之前歉铝,Store1的寫入操作對其他處理器可見,那么可以得出凑耻,該屏障不僅保證了Store1已經(jīng)執(zhí)行完畢(有序性)太示,也保證了可見性。

每個volatile寫操作的后面插入一個StoreLoad屏障

對比StoreLoad屏障的定義香浩,這里的volatile寫是那個Store1,該屏障也保證了有序性和可見性类缤。其他都是類似的。

每個volatile讀操作后面插入一個LoadLoad屏障邻吭。

每個volatile讀操作后面插入一個LoadStore屏障餐弱。

6.cas

cas用來保證操作的原子性操作

Unsafe類中的compareAndSwapInt,是一個native方法囱晴,該方法的實現(xiàn)位于unsafe.cpp中


cas.png

先想辦法拿到內(nèi)存地址岸裙,再通過Atomic::cmpxchg(x, addr, e)實現(xiàn)比較交換。e是原內(nèi)存值速缆,x為新值。這個函數(shù)在WindowsX86下實現(xiàn)如下:

inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) {
    int mp = os::isMP(); #判斷是否是多處理器
    _asm {
        mov edx, dest  #變量內(nèi)存位置放edx
        mov ecx, exchange_value  #要更新的值放ecx
        mov eax, compare_value #原內(nèi)存值放eax
        LOCK_IF_MP(mp) #決定是否Lock
        #這句是真正的CAS操作
        cmpxchg dword ptr [edx], ecx
        # dword ptr 將 [edx] 強制類型轉(zhuǎn)換成雙字
        # cmpxchg 將 eax 里 內(nèi)存原值 與(轉(zhuǎn)換后的)對象值 比較
        # 如果相等恩闻,就是沒別的線程在改變這個對象艺糜,那么這個線程就可以改了,將ecx值更新到這個對象。
    }
}

如果是多處理器破停,LOCK_IF_MP(mp)為cmpxchg指令添加lock前綴翅楼。反之,就省略lock前綴真慢。(單處理器會不需要lock前綴提供的內(nèi)存屏障效果)

7.單例模式

  1. 懶漢餓漢
  2. 枚舉實現(xiàn)
  3. 雙重校驗

雙重校驗使用volatile關(guān)鍵字的原因

假如有兩個并發(fā)線程a毅臊、b,a線程主動調(diào)用了靜態(tài)方法getInstance()黑界,這時開始加載和初始化該類的靜態(tài)變量管嬉,b線程調(diào)用getInstance()并等待獲得同步鎖,當a線程初始化對象過程中朗鸠,到了第二階段即連接階段的準備步驟時蚯撩,靜態(tài)變量doubleKey 被賦予了一個默認值,但是這時還沒有進行初始化烛占,這時當a線程釋放鎖后胎挎,b線程判斷doubleKey != null忆家,則直接返回了一個沒有初始化的doubleKey 對象犹菇,問題就出現(xiàn)在這里了,b線程拿到的是一個被賦予了默認值但是未初始化的對象芽卿,剛剛可以通過鎖的檢索揭芍!

8.隔離級別

四種隔離級別,舉例說明

mysql的隔離級別實現(xiàn)

MySQL默認使用rr的隔離級別

RR使用gap lock來解決幻讀問題

MySQL RR/RC區(qū)別

簡單來說蹬竖,semi-consistent read是read committed與consistent read兩者的結(jié)合沼沈。一個update語句,如果讀到一行已經(jīng)加鎖的記錄币厕,此時InnoDB返回記錄最近提交的版本列另,由MySQL上層判斷此版本是否滿足 update的where條件。若滿足(需要更新)旦装,則MySQL會重新發(fā)起一次讀操作页衙,此時會讀取行的最新版本(并加鎖)。semi-consistent read只會發(fā)生在read committed隔離級別下阴绢,或者是參數(shù)innodb_locks_unsafe_for_binlog被設(shè)置為true(該參數(shù)即將被廢棄)店乐。

對比RR隔離級別,update語句會使用當前讀呻袭,如果一行被鎖定了眨八,那么此時會被阻塞,發(fā)生鎖等待左电。而不會讀取最新的提交版本廉侧,然后來判斷是否符合where條件页响。

半一致性讀的優(yōu)點:
減少了update語句時行鎖的沖突;對于不滿足update更新條件的記錄段誊,可以提前放鎖闰蚕,減少并發(fā)沖突的概率。

9.什么時候OOM什么時候stackoverflow

OOM的情況

  1. 給應(yīng)用程序分配的內(nèi)存不夠,只能通過增大內(nèi)存來解決.
  2. 內(nèi)存泄漏.有一部分內(nèi)存"無用"了,但是因為編碼問題導(dǎo)致的沒有被垃圾回收掉,產(chǎn)生了泄漏,最終導(dǎo)致了內(nèi)存溢出(OOM).

stackoverflow的情況

  1. 無限的遞歸,相當于你的參數(shù)無限多,那么棧放不下.
  2. 局部變量太大了,正常分配的椓幔空間(1M)不夠用.
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末没陡,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子索赏,更是在濱河造成了極大的恐慌盼玄,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件参滴,死亡現(xiàn)場離奇詭異强岸,居然都是意外死亡,警方通過查閱死者的電腦和手機砾赔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門蝌箍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人暴心,你說我怎么就攤上這事妓盲。” “怎么了专普?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵悯衬,是天一觀的道長。 經(jīng)常有香客問我檀夹,道長筋粗,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任炸渡,我火速辦了婚禮娜亿,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蚌堵。我一直安慰自己买决,他們只是感情好,可當我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布吼畏。 她就那樣靜靜地躺著督赤,像睡著了一般。 火紅的嫁衣襯著肌膚如雪泻蚊。 梳的紋絲不亂的頭發(fā)上躲舌,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天,我揣著相機與錄音性雄,去河邊找鬼孽糖。 笑死枯冈,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的办悟。 我是一名探鬼主播,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼滩褥,長吁一口氣:“原來是場噩夢啊……” “哼病蛉!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起瑰煎,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤铺然,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后酒甸,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體魄健,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年插勤,在試婚紗的時候發(fā)現(xiàn)自己被綠了沽瘦。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡农尖,死狀恐怖析恋,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情盛卡,我是刑警寧澤助隧,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站滑沧,受9級特大地震影響并村,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜滓技,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一哩牍、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧殖属,春花似錦姐叁、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至挠唆,卻和暖如春处窥,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背玄组。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工滔驾, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留谒麦,地道東北人。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓哆致,卻偏偏與公主長得像绕德,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子摊阀,可洞房花燭夜當晚...
    茶點故事閱讀 44,724評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 該文章屬于《Java并發(fā)編程》系列文章耻蛇,如果想了解更多,請點擊《Java并發(fā)編程之總目錄》 前言 在前面的文章中,...
    AndyJennifer閱讀 1,400評論 1 2
  • 目錄: 1. 指令重排 2. 順序一致性 3. volatile 4. final 1.指令重排 要了解指令重排胞此,...
    西部小籠包閱讀 746評論 0 1
  • 九種基本數(shù)據(jù)類型的大小臣咖,以及他們的封裝類。(1)九種基本數(shù)據(jù)類型和封裝類 (2)自動裝箱和自動拆箱 什么是自動裝箱...
    關(guān)瑋琳linSir閱讀 1,884評論 0 47
  • 第2章 java并發(fā)機制的底層實現(xiàn)原理 Java中所使用的并發(fā)機制依賴于JVM的實現(xiàn)和CPU的指令漱牵。 2.1 vo...
    kennethan閱讀 1,428評論 0 2
  • Java SE 基礎(chǔ): 封裝夺蛇、繼承、多態(tài) 封裝: 概念:就是把對象的屬性和操作(或服務(wù))結(jié)合為一個獨立的整體酣胀,并盡...
    Jayden_Cao閱讀 2,109評論 0 8