衝擊雙十一,我是怎麼拿下螞蟻金服的offer的,Java面試題分享

1、JVM面試題

1. 說說你對JVM內存模型的瞭解,每一個區的做用是什麼?

棧區前端

  • 棧分爲java虛擬機棧和本地方法棧
  • 重點是Java虛擬機棧,它是線程私有的,生命週期與線程相同。
  • 每一個方法執行都會建立一個棧幀,用於存放局部變量表,操做棧,動態連接,方法出口等。每一個方法從被調用,直到被執行完。對應着一個棧幀在虛擬機中從入棧到出棧的過程。
  • 一般說的棧就是指局部變量表部分,存放編譯期間可知的8種基本數據類型,及對象引用和指令地址。局部變量表是在編譯期間完成分配,當進入一個方法時,這個棧中的局部變量分配內存大小是肯定的。
  • 會有兩種異常StackOverFlowError和 OutOfMemoneyError。當線程請求棧深度大於虛擬機所容許的深度就會拋出StackOverFlowError錯誤;虛擬機棧動態擴展,當擴展沒法申請到足夠的內存空間時候,拋出OutOfMemoneyError。
  • 本地方法棧爲虛擬機使用到本地方法服務(native)

堆區java

  • 堆是被全部線程共享的一塊區域,在虛擬機啓動時建立,惟一目的存放對象實例。
  • 堆被劃分紅兩個不一樣的區域:新生代(Young)、老年代(Old)。
  • 新生代又被劃分爲三個區域:Eden和兩個倖存區(From survivor 和 To survivor)。
  • 新生代主要存儲新建立的對象和還沒有進入老年代的對象。老年代存儲通過屢次新生代GC(Minor GC)後仍然存活的對象。
  • 會有異常OutOfMemoneyError

方法區android

  • 被全部線程共享的區域,用於存放已被虛擬機加載的類信息,常量,靜態變量等數據。被Java虛擬機描述爲堆的一個邏輯部分。有時候也稱它爲永久代(permanment generation)
  • 垃圾回收不多光顧這個區域,不過也是須要回收的,主要針對常量池回收,類型卸載。
  • 常量池用於存放編譯期生成的各類字節碼和符號引用,常量池具備必定的動態性,裏面能夠存放編譯期生成的常量;運行期間的常量也能夠添加進入常量池中,好比string的intern()方法。

程序計數器ios

  • 當前線程所執行的行號指示器。經過改變計數器的值來肯定下一條指令,好比循環,分支,跳轉,異常處理,線程恢復等都是依賴計數器來完成。
  • Java虛擬機多線程是經過線程輪流切換並分配處理器執行時間的方式實現的。爲了線程切換能恢復到正確的位置,每條線程都須要一個獨立的程序計數器,因此它是線程私有的。
  • 惟一一塊Java虛擬機沒有規定任何OutofMemoryError的區塊。

2. JVM什麼狀況下會發生棧內存溢出

類的加載指的是將類的.class文件中的二進制數據讀入到內存中,將其放在運行時數據區的方法區內,而後在堆區建立一個java.lang.Class對象,用來封裝類在方法區內的數據結構。類的加載的最終產品是位於堆區中的Class對象,Class對象封裝了類在方法區內的數據結構,而且向Java程序員提供了訪問方法區內的數據結構的接口。程序員

3. 類的生命週期

類的生命週期包括這幾個部分,加載、鏈接、初始化、使用和卸載面試

  • 加載,查找並加載類的二進制數據,在Java堆中也建立一個java.lang.Class類的對象
  • 鏈接,鏈接又包含三塊內容:驗證、準備、初始化。1)驗證,文件格式、元數據、字節碼、符號引用驗證;2)準備,爲類的靜態變量分配內存,並將其初始化爲默認值;3)解析,把類中的符號引用轉換爲直接引用
  • 初始化,爲類的靜態變量賦予正確的初始值
  • 使用,new出對象程序中使用
  • 卸載,執行垃圾回收

4. JVM對象分配規則

  • 對象優先分配在Eden區,若是Eden區沒有足夠的空間時,虛擬機執行一次Minor GC。
  • 大對象直接進入老年代(大對象是指須要大量連續內存空間的對象)。這樣作的目的是避免在Eden區和兩個Survivor區之間發生大量的內存拷貝(新生代採用複製算法收集內存)。
  • 長期存活的對象進入老年代。虛擬機爲每一個對象定義了一個年齡計數器,若是對象通過了1次Minor GC那麼對象會進入Survivor區,以後每通過一次Minor GC那麼對象的年齡加1,知道達到閥值對象進入老年區。
  • 動態判斷對象的年齡。若是Survivor區中相同年齡的全部對象大小的總和大於Survivor空間的一半,年齡大於或等於該年齡的對象能夠直接進入老年代。
  • 空間分配擔保。每次進行Minor GC時,JVM會計算Survivor區移至老年區的對象的平均大小,若是這個值大於老年區的剩餘值大小則進行一次Full GC,若是小於檢查HandlePromotionFailure設置,若是true則只進行Monitor GC,若是false則進行Full GC。

5. JVM如何判斷對象是否存活

判斷對象是否存活通常有兩種方式:算法

  • 引用計數:每一個對象有一個引用計數屬性,新增一個引用時計數加1,引用釋放時計數減1,計數爲0時能夠回收。此方法簡單,沒法解決對象相互循環引用的問題。
  • 可達性分析(Reachability Analysis):從GC Roots開始向下搜索,搜索所走過的路徑稱爲引用鏈。當一個對象到GC Roots沒有任何引用鏈相連時,則證實此對象是不可用的,不可達對象。

6. 介紹一下GC算法有哪些

GC最基礎的算法有三種:標記 -清除算法、複製算法、標記-壓縮算法,咱們經常使用的垃圾回收器通常都採用分代收集算法。spring

  • 標記 -清除算法,「標記-清除」(Mark-Sweep)算法,如它的名字同樣,算法分爲「標記」和「清除」兩個階段:首先標記出全部須要回收的對象,在標記完成後統一回收掉全部被標記的對象。
  • 複製算法,「複製」(Copying)的收集算法,它將可用內存按容量劃分爲大小相等的兩塊,每次只使用其中的一塊。當這一塊的內存用完了,就將還存活着的對象複製到另一塊上面,而後再把已使用過的內存空間一次清理掉。
  • 標記-壓縮算法,標記過程仍然與「標記-清除」算法同樣,但後續步驟不是直接對可回收對象進行清理,而是讓全部存活的對象都向一端移動,而後直接清理掉端邊界之外的內存
  • 分代收集算法,「分代收集」(Generational Collection)算法,把Java堆分爲新生代和老年代,這樣就能夠根據各個年代的特色採用最適當的收集算法。

7. JVM有哪些垃圾回收器

  • Serial收集器,串行收集器是最古老,最穩定以及效率高的收集器,可能會產生較長的停頓,只使用一個線程去回收。
  • ParNew收集器,ParNew收集器其實就是Serial收集器的多線程版本。
  • Parallel收集器,Parallel Scavenge收集器相似ParNew收集器,Parallel收集器更關注系統的吞吐量。
  • Parallel Old 收集器,Parallel Old是Parallel Scavenge收集器的老年代版本,使用多線程和「標記-整理」算法
  • CMS收集器,CMS(Concurrent Mark Sweep)收集器是一種以獲取最短回收停頓時間爲目標的收集器。
  • G1收集器,G1 (Garbage-First)是一款面向服務器的垃圾收集器,主要針對配備多顆處理器及大容量內存的機器. 以極高機率知足GC停頓時間要求的同時,還具有高吞吐量性能特徵

8. JVM經常使用調優命令

Sun JDK監控和故障處理命令有jps jstat jmap jhat jstack jinfosql

  • jps,JVM Process Status Tool,顯示指定系統內全部的HotSpot虛擬機進程。
  • jstat,JVM statistics Monitoring是用於監視虛擬機運行時狀態信息的命令,它能夠顯示出虛擬機進程中的類裝載、內存、垃圾收集、JIT編譯等運行數據。
  • jmap,JVM Memory Map命令用於生成heap dump文件
  • jhat,JVM Heap Analysis Tool命令是與jmap搭配使用,用來分析jmap生成的dump,jhat內置了一個微型的HTTP/HTML服務器,生成dump的分析結果後,能夠在瀏覽器中查看
  • jstack,用於生成java虛擬機當前時刻的線程快照。
  • jinfo,JVM Configuration info 這個命令做用是實時查看和調整虛擬機運行參數。

9. JVM經常使用性能調優參數

  • Xss:規定了每一個線程虛擬機棧的大小
  • Xms:堆的初始值
  • Xmx:堆能達到的最大值

10. Java內存模型中堆和棧的區別

  • 管理方式數據庫

    • 棧自動釋放,堆須要GC
  • 空間大小

    • 棧比堆小
  • 碎片相關

    • 棧產生的碎片遠小於堆
  • 分配方式

    • 棧支持靜態和動態分配,而堆僅支持動態分配
  • 效率

    • 棧的效率比堆高

11. JVM中有幾種類加載器

類加載器負責讀取 Java 字節代碼,並轉換成java.lang.Class類的一個實例;有如下幾張類加載去:

  • 啓動類加載器(Bootstrap ClassLoader):Java應用啓動時,加載$JAVA_HOME/lib或 -Xbootclasspath指定的路徑中的類文件;
  • 擴展類加載器(Extension ClassLoaser):由sun.misc.Launcher$ExtClassLoader實現,負責加載$JAVA_HOME/lib/ext或java.ext.dirs指定路徑的類庫;
  • 應用程序類加載器(Application ClassLoader):又稱系統類加載器,由sun.misc.Launcher$AppClassLoader實現,是ClassLoader.getSystemClassLoader()的返回值。
  • 自定義類加載器須要繼承抽象類ClassLoader,實現findClass方法,該方法會在loadClass調用的時候被調用,findClass默認會拋出異常。

    • findClass方法表示根據類名查找類對象
    • loadClass方法表示根據類名進行雙親委託模型進行類加載並返回類對象
    • loadClass方法表示根據類名進行雙親委託模型進行類加載並返回類對象

12. 什麼是雙親委派模型

  • 雙親委託模型的工做過程是:若是一個類加載器收到了類加載的請求,它首先不會本身去嘗試加載這個類,而是把這個請求委託給父類加載器(父子關係由組合(不是繼承)來實現)去完成,每個層次的類加載器都是如此, 所以全部的加載請求最終都應該傳送到頂層的啓動類加載器中,只有當父類加載器反饋本身沒法完成這個加載請求(它的搜索範圍中沒有找到所須要加載的類)時, 子加載器纔會嘗試本身去加載。
  • 使用雙親委託機制的好處是:

    • 避免同一個類被屢次加載;
    • 每一個加載器只能加載本身範圍內的類;

13. 類加載過程

類從被加載到虛擬機內存中開始,到卸載出內存爲止,它的整個生命週期包括:加載(Loading)、驗證(Verification)、準備(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸載(Unloading)7個階段。其中準備、驗證、解析3個部分統稱爲鏈接(Linking)

加載、驗證、準備、初始化和卸載這5個階段的順序是肯定的,類的加載過程必須按照這種順序循序漸進地開始,而解析階段則不必定:它在某些狀況下能夠在初始化階段以後再開始,這是爲了支持Java語言的運行時綁定(也稱爲動態綁定或晚期綁定)。如下陳述的內容都已HotSpot爲基準。

14. 棧溢出的緣由

  • 是否有遞歸調用
  • 是否有大量循環或死循環
  • 全局變量是否過多
  • 數組、List、map數據是否過大

15. 方法區溢出的緣由

  • 動態生成大量Class
  • 大量JSP或動態產生JSP文件(JSP第一次運行時須要編譯爲Java類)

2、消息中間件面試題

1. 說說RabbitMQ的結構

  • Brocker:消息隊列服務器實體。
  • Exchange:消息交換機,用於接收、分配消息。指定消息按什麼規則,路由到哪一個隊列。
  • Queue:消息隊列,用於存儲生產者的消息。每一個消息都會被投入到一個或者多個隊列裏。
  • Binding Key:綁定關鍵字,用於把交換器的消息綁定到隊列中,它的做用是把exchange和queue按照路由規則binding起來。
  • Routing Key:路由關鍵字,用於把生產者的數據分配到交換器上。exchange根據這個關鍵字進行消息投遞。
  • Vhost:虛擬主機,一個broker裏能夠開設多個vhost,用做不用用戶的權限分離。
  • Producer:消息生產者,就是投遞消息的程序。
  • Consumer:消息消費者,就是接受消息的程序。
  • Channel:信道,消息推送使用的通道。可創建多個channel,每一個channel表明一個會話任務。

2. RabbitMQ交換器種類

  • Direct exchange(直連交換機):直連型交換機(direct exchange)是根據消息攜帶的路由鍵(routing key)將消息投遞給對應隊列的,步驟以下:

    • 將一個隊列綁定到某個交換機上,同時賦予該綁定一個路由鍵(routing key)
    • 當一個攜帶着路由值爲R的消息被髮送給直連交換機時,交換機會把它路由給綁定值一樣爲R的隊列。
  • Fanout exchange(扇型交換機):扇型交換機(funout exchange)將消息路由給綁定到它身上的全部隊列。不一樣於直連交換機,路由鍵在此類型上不啓任務做用。若是N個隊列綁定到某個扇型交換機上,當有消息發送給此扇型交換機時,交換機會將消息的發送給這全部的N個隊列
  • Topic exchange(主題交換機):主題交換機(topic exchanges)中,隊列經過路由鍵綁定到交換機上,而後,交換機根據消息裏的路由值,將消息路由給一個或多個綁定隊列。

    • 扇型交換機和主題交換機異同:
    • 對於扇型交換機路由鍵是沒有意義的,只要有消息,它都發送到它綁定的全部隊列上
    • 對於主題交換機,路由規則由路由鍵決定,只有知足路由鍵的規則,消息才能夠路由到對應的隊列上
  • Headers exchange(頭交換機):相似主題交換機,可是頭交換機使用多個消息屬性來代替路由鍵創建路由規則。經過判斷消息頭的值可否與指定的綁定相匹配來確立路由規則。 此交換機有個重要參數:」x-match」。

    • 當」x-match」爲「any」時,消息頭的任意一個值被匹配就能夠知足條件
    • 當」x-match」設置爲「all」的時候,就須要消息頭的全部值都匹配成功

3. RabbitMQ隊列與消費者的關係

  • 一個隊列能夠綁定多個消費者;
  • 隊列分發消息將以輪詢的方式分發,每條消息只會分發給一個訂閱的消費者;
  • 消費者收到消息以後默認是自動確認,能夠設置手動確認,保證消費者消費了消息。

4. 如何保證消息的順序性

  • RabbitMQ

    • 拆分多個queue,每一個queue一個consumer,就是多一些queue而已
    • 一個queue可是對應一個consumer,而後這個consumer內部用內存隊列作排隊,而後分發給底層不一樣的worker來處理
  • kafka

    • 一個topic,一個partition,一個consumer,內部單線程消費,寫N個內存queue,而後N個線程分別消費一個內存queue便可

3、數據庫面試題

1. InnoDB中的事務隔離級別

SQL標準中的事務四種隔離級別

  • 未提交讀(Read Uncommitted):可能出現髒讀(可能讀取到其餘會話中未提交事務修改的數據)、不可重複讀、幻讀
  • 提交讀(Read Committed):只能讀取到已經提交的數據。Oracle等多數數據庫默認都是該級別 (不重複讀)
  • 可重複讀(Repeated Read):可重複讀。在同一個事務內的查詢都是事務開始時刻一致的,InnoDB默認級別。在SQL標準中,該隔離級別消除了不可重複讀,可是還存在幻象讀
  • 串行讀(Serializable):徹底串行化的讀,每次讀都須要得到表級共享鎖,讀寫相互都會阻塞

2. 解釋下髒讀、不可重複讀、幻讀

  • 髒讀:指當一個事務正字訪問數據,而且對數據進行了修改,而這種數據尚未提交到數據庫中,這時,另一個事務也訪問這個數據,而後使用了這個數據。由於這個數據尚未提交那麼另一個事務讀取到的這個數據咱們稱之爲髒數據。依據髒數據所作的操做肯能是不正確的。
  • 不可重複讀:指在一個事務內,屢次讀同一數據。在這個事務尚未執行結束,另一個事務也訪問該同一數據,那麼在第一個事務中的兩次讀取數據之間,因爲第二個事務的修改第一個事務兩次讀到的數據多是不同的,這樣就發生了在一個事物內兩次連續讀到的數據是不同的,這種狀況被稱爲是不可重複讀。
  • 幻讀:一個事務前後讀取一個範圍的記錄,但兩次讀取的紀錄數不一樣,咱們稱之爲幻象讀(兩次執行同一條 select 語句會出現不一樣的結果,第二次讀會增長一數據行,並無說這兩次執行是在同一個事務中)

3. MyISAM和InnoDB二者之間的區別

InnoDB是一個事務型的存儲引擎,支持回滾,設計目標是處理大數量數據時提供高性能的服務,它在運行時會在內存中創建緩衝池,用於緩衝數據和索引。

優勢

  • 支持事務處理、ACID事務特性;
  • 實現了SQL標準的四種隔離級別;
  • 支持行級鎖和外鍵約束;
  • 能夠利用事務日誌進行數據恢復。
  • 鎖級別爲行鎖,行鎖優勢是適用於高併發的頻繁表修改,高併發是性能優於 MyISAM。缺點是系統消耗較大。
  • 索引不只緩存自身,也緩存數據,相比 MyISAM 須要更大的內存。

缺點

  • 由於它沒有保存表的行數,當使用COUNT統計時會掃描全表。

MyISAM 是 MySQL 5.5.5 以前的默認引擎,它的設計目標是快速讀取。

優勢

  • 高性能讀取;
  • 由於它保存了表的行數,當使用COUNT統計時不會掃描全表;

缺點

  • 鎖級別爲表鎖,表鎖優勢是開銷小,加鎖快;缺點是鎖粒度大,發生鎖衝動機率較高,容納併發能力低,這個引擎適合查詢爲主的業務。
  • 此引擎不支持事務,也不支持外鍵。
  • INSERT和UPDATE操做須要鎖定整個表;
  • 它存儲表的行數,因而COUNT時只須要直接讀取已經保存好的值而不須要進行全表掃描。

適用場景

  • MyISAM適合:

    • 作不少count 的計算;
    • 插入不頻繁,查詢很是頻繁;
    • 沒有事務。
  • InnoDB適合:

    • 可靠性要求比較高,或者要求事務;
    • 表更新和查詢都至關的頻繁,而且表鎖定的機會比較大的狀況

4. 說說事務的四種特性(ACID)

  • 原子性(Atomicity):一個事務必須被視爲一個不可分割的最小工做單元,整個事務中的全部操做要麼所有提交成功,要麼所有失敗回滾,對於一個事務來講,不能夠只執行其中的一部分操做。
  • 一致性(Consistency):數據庫老是從一個一致性的狀態轉到另外一個一致性的狀態。 拿轉帳來講,假設用戶A和用戶B二者的錢加起來一共是5000,那麼無論A和B之間如何轉帳,轉幾回帳,事務結束後兩個用戶的錢加起來應該還得是5000,這就是事務一致性。
  • 隔離性(Isolation):一般來講,一個事務所作的修改在最終提交以前,對其餘事務是不可見的。
  • 持久性(Durability):一旦事務提交,則其所作的修改就會永久的保存到數據庫中。不會由於系統故障等狀況而丟失所作的修改。

4、NoSQL面試題

1. Memcache和Redis的區別

Memcache

  • 支持簡單數據類型
  • 不支持數據持久化存儲
  • 不支持主從
  • 不支持分片

Redis

  • 數據類型豐富
  • 支持數據磁盤持久化存儲
  • 支持主從
  • 支持分片

2. 爲何Redis能這麼快

  • 徹底基於內存,絕大部分請求是純粹的內存操做,執行效率高
  • 數據結構簡單,對數據操做也簡單
  • 使用多路I/O複用模型,非阻塞IO
  • 採用單線程,單線程也能處理高併發請求,想多核也能夠啓動多實例

3. 說說你用過的Redis的數據類型

  • String:最基本的數據類型,二進制安全
  • Hash:String元素組成的字典,適合用於存儲對象
  • List:列表,按照String元素插入順序排序
  • Set:String元素組成的無序集合,經過Hash表實現,不容許重複
  • Sorted Set:經過分數來爲集合中的成員進行從小到大的排序
  • 用於計數的HyperLogLog(非重點,前面五個儘可能說出來)

4. 如何經過Redis實現分佈式鎖

SET key value [EX seconds] [PX milliseconds] [NX|XX]

  • EX seconds:設置鍵的過時時間爲second秒
  • PX milliseconds:設置鍵的過時時間爲millisecond毫秒
  • NX:只在鍵不存在時,纔對鍵進行設置操做
  • XX:只在鍵已經存在時,纔對鍵進行設置操做
  • SET操做成功完成時,返回OK,不然返回nil

5. Redis中大量的key同時過時的注意事項

  • 現象:集中過時,因爲清楚大量的key很耗時,會出現短暫的卡頓現象
  • 解決方案:在設置key的過時時間的時候,給每一個key加上隨機值

6. 如何使用Redis作異步隊列

使用List做爲隊列,RPUSH生產消息,LPOP消費消息

缺點:沒有等待隊列裏面有值就直接消費

解決方案

  • 能夠經過在應用層引入Sleep機制去調用LPOP重試
  • BLPOP key [key ...] timeout:阻塞直到隊列有消息或者超時,缺點是隻能供一個消費者消費
  • pub/sub:主題訂閱者模式,缺點:消息的發佈是無狀態的,沒法保證可達

5、分佈式面試題

1. 說說SpringCloud的工做原理

Spring Cloud是一個全家桶式的技術棧,包含了不少組件,其中比較核心的有Eureka、Ribbon、Feign、Hystrix、Zuul這幾個組件。

  • Eureka是微服務架構中的註冊中心,專門負責服務的註冊與發現。每一個服務中都有一個Eureka Client組件,這個組件專門負責將這個服務的信息註冊到Eureka Server中。說白了,就是告訴Eureka Server,本身在哪臺機器上,監聽着哪一個端口。而Eureka Server是一個註冊中心,裏面有一個註冊表,保存了各服務所在的機器和端口號。服務調用者調用對應服務時,它的Eureka Client組件會找Eureka Server查找對應的服務信息進行調用,而後就能夠把這些相關信息從Eureka Server的註冊表中拉取到本身本地緩存起來,方便下次調用。

    • Eureka Client:負責將這個服務的信息註冊到Eureka Server中
    • Eureka Server:註冊中心,裏面有一個註冊表,保存了各個服務所在的機器和端口號
  • Feign基於動態代理機制,根據註解和選擇的機器,拼接請求URL地址,發起請求。Feign的一個關鍵機制就是使用了動態代理。

    • 首先,若是你對某個接口定義了@FeignClient註解,Feign就會針對這個接口建立一個動態代理
    • 接着你要是調用那個接口,本質就是會調用 Feign建立的動態代理,這是核心中的核心
    • Feign的動態代理會根據你在接口上的@RequestMapping等註解,來動態構造出你要請求的服務的地址
    • 最後針對這個地址,發起請求、解析響應
  • Ribbon的做用是負載均衡,會幫你在每次請求時選擇一臺機器,均勻的把請求分發到各個機器上。Ribbon的負載均衡默認使用的最經典的Round Robin輪詢算法。並且,Ribbon是和Feign以及Eureka緊密協做,完成工做的。

    • 首先Ribbon從 Eureka Client裏獲取到對應的服務註冊表,即知道了全部的服務都部署在了哪些機器上,在監聽哪些端口號
    • 而後Ribbon就可使用默認的Round Robin輪詢算法,從中選擇一臺機器
    • Feign就會針對這臺機器,構造併發起請求
  • Hystrix是隔離、熔斷以及降級的一個框架,發起請求是經過Hystrix的線程池來走的,不一樣的服務走不一樣的線程池,實現了不一樣服務調用的隔離,避免了服務雪崩的問題
  • Zuul就是微服務網關,這個組件是負責網絡路由的。通常微服務架構中都必然會設計一個網關在裏面,像android、ios、pc前端、微信小程序、H5等等,不用去關心後端有幾百個服務,就知道有一個網關,全部請求都往網關走,網關會根據請求中的一些特徵,將請求轉發給後端的各個服務。並且有了網關以後,能夠作統一的降級、限流、認證受權、安全等功能。

2. Eureka的心跳時間

  • Eureka的客戶端默認每隔30s會向eureka服務端更新實例,註冊中心也會定時進行檢查,發現某個實例默認90s內沒有再收到心跳,會註銷此實例。可是這些時間間隔是可配置的。
  • 不過註冊中心還有一個保護模式,在這個保護模式下,他會認爲是網絡問題,不會註銷任何過時的實例

3. Eureka的缺點

  • 不知足CAP的一致性
  • 中止維護了,2.0以後不開源

4. 說說分佈式事務有哪些解決方案

  • 基於XA協議的兩階段提交方案

    • 第一階段是表決階段,全部參與者都將本事務可否成功的信息反饋發給協調者;第二階段是執行階段,協調者根據全部參與者的反饋,通知全部參與者,步調一致地在全部分支上提交或者回滾。
    • 缺點:兩階段提交方案鎖定資源時間長,對性能影響很大,基本不適合解決微服務事務問題。
  • TCC方案

    • TCC方案實際上是兩階段提交的一種改進。其將整個業務邏輯的每一個分支顯式的分紅了Try、Confirm、Cancel三個操做。Try部分完成業務的準備工做,confirm部分完成業務的提交,cancel部分完成事務的回滾。
    • 事務開始時,業務應用會向事務協調器註冊啓動事務。以後業務應用會調用全部服務的try接口,完成一階段準備。以後事務協調器會根據try接口返回狀況,決定調用confirm接口或者cancel接口。若是接口調用失敗,會進行重試。

      • 缺點:一、對應用的侵入性強。業務邏輯的每一個分支都須要實現try、confirm、cancel三個操做,應用侵入性較強,改形成本高。 二、實現難度較大。須要按照網絡狀態、系統故障等不一樣的失敗緣由實現不一樣的回滾策略。爲了知足一致性的要求,confirm和cancel接口必須實現冪等。
  • 基於可靠消息的最終一致性方案

    • 消息一致性方案是經過消息中間件保證上、下游應用數據操做的一致性。基本思路是將本地操做和發送消息放在一個事務中,保證本地操做和消息發送要麼二者都成功或者都失敗。下游應用向消息系統訂閱該消息,收到消息後執行相應操做。
    • 消息方案從本質上講是將分佈式事務轉換爲兩個本地事務,而後依靠下游業務的重試機制達到最終一致性。基於消息的最終一致性方案對應用侵入性也很高,應用須要進行大量業務改造,成本較高。
  • GTS

    • GTS是一款分佈式事務中間件,由阿里巴巴中間件部門研發,能夠爲微服務架構中的分佈式事務提供一站式解決方案。
    • 優勢:性能超強、應用侵入性極低、完整解決方案、容錯能力強

5. rpc和http的區別

  • RPC主要是基於TCP/IP協議,而HTTP服務主要是基於HTTP協議
  • RPC要比http更快,雖然底層都是socket,可是http協議的信息每每比較臃腫
  • RPC實現較爲複雜,http相對比較簡單
  • 靈活性來看,http更勝一籌,由於它不關心實現細節,跨平臺、跨語言。
  • 若是對效率要求更高,而且開發過程使用統一的技術棧,那麼用RPC仍是不錯的。
  • 若是須要更加靈活,跨語言、跨平臺,顯然http更合適

6、經常使用框架面試題

1. 說說Spring事務什麼狀況下才會回滾

當所攔截的方法有指定異常拋出,事務纔會自動進行回滾。默認狀況下是捕獲到方法的RuntimeException異常,也就是說拋出只要屬於運行時的異常(即RuntimeException及其子類)都能回滾;但當拋出一個不屬於運行時異常時,事務是不會回滾的。若是是其餘異常想要實現回滾,能夠進行配置。

2. 說說Spring事務的傳播屬性

事務的傳播性通常在事務嵌套時候使用,好比在事務A裏面調用了另一個使用事務的方法,那麼這倆個事務是各自做爲獨立的事務執行提交,仍是內層的事務合併到外層的事務一塊提交那,這就是事務傳播性要肯定的問題。spring支持7種事務傳播行爲:

  • PROPAGATION_REQUIRED – 支持當前事務,若是當前沒有事務,就新建一個事務。這是最多見的選擇。
  • PROPAGATION_SUPPORTS – 支持當前事務,若是當前沒有事務,就以非事務方式執行。
  • PROPAGATION_MANDATORY – 支持當前事務,若是當前沒有事務,就拋出異常。
  • PROPAGATION_REQUIRES_NEW – 新建事務,若是當前存在事務,把當前事務掛起。
  • PROPAGATION_NOT_SUPPORTED – 以非事務方式執行操做,若是當前存在事務,就把當前事務掛起。
  • PROPAGATION_NEVER – 以非事務方式執行,若是當前存在事務,則拋出異常。
  • PROPAGATION_NESTED – 若是當前存在事務,則在嵌套事務內執行。若是當前沒有事務,則進行與PROPAGATION_REQUIRED相似的操做。

備註:經常使用的兩個事務傳播屬性是1和4,即PROPAGATION_REQUIRED,PROPAGATION_REQUIRES_NEW

3. 說說Spring事務的隔離性

事務的隔離性是指多個事務併發執行的時候相互之間不受到彼此的干擾。

事務的隔離級別也分爲四種,由低到高依次分別爲:read uncommited(讀未提交)、read commited(讀提交)、read repeatable(讀重複)、serializable(序列化),這四個級別能夠逐個解決髒讀、不可重複讀、幻讀這幾類問題。

  • read uncommited:是最低的事務隔離級別,它容許另一個事務能夠看到這個事務未提交的數據。
  • read commited:保證一個事物提交後才能被另一個事務讀取。另一個事務不能讀取該事物未提交的數據。
  • repeatable read:這種事務隔離級別能夠防止髒讀,不可重複讀。可是可能會出現幻象讀。它除了保證一個事務不能被另一個事務讀取未提交的數據以外還避免瞭如下狀況產生(不可重複讀)。
  • serializable:這是花費最高代價但最可靠的事務隔離級別。事務被處理爲順序執行。除了防止髒讀,不可重複讀以外,還避免了幻讀。
  • DEFAULT 這是一個PlatfromTransactionManager默認的隔離級別,使用數據庫默認的事務隔離級別.

4. 說說Spring事務的特性

事務特性分爲四個:原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持續性(Durability)簡稱ACID。

  • 原子性(Atomicity):事務是數據庫邏輯工做單元,事務中包含的操做要麼都執行成功,要麼都執行失敗。
  • 一致性(Consistency):事務執行的結果必須是使數據庫數據從一個一致性狀態變到另一種一致性狀態。當事務執行成功後就說數據庫處於一致性狀態。若是在執行過程當中發生錯誤,這些未完成事務對數據庫所作的修改有一部分已寫入物理數據庫,這是數據庫就處於不一致狀態。
  • 隔離性(Isolation):一個事務的執行過程當中不能影響到其餘事務的執行,即一個事務內部的操做及使用的數據對其餘事務是隔離的,併發執行各個事務之間無不干擾。
  • 持續性(Durability):即一個事務執一旦提交,它對數據庫數據的改變是永久性的。以後的其它操做不該該對其執行結果有任何影響。

5. 說說你對SpringIOC容器的理解

SpringIOC負責建立對象,管理對象(經過依賴注入(DI),裝配對象,配置對象,而且管理這些對象的整個生命週期。

6. 什麼是Spring的依賴注入

依賴注入,是IOC的一個方面。這概念是說你不用建立對象,而只須要描述它如何被建立。你不在代碼裏直接組裝你的組件和服務,可是要在配置文件裏描述哪些組件須要哪些服務,以後一個容器(IOC容器)負責把他們組裝起來。

7. IOC(依賴注入)方式

  • 構造器依賴注入:構造器依賴注入經過容器觸發一個類的構造器來實現的,該類有一系列參數,每一個參數表明一個對其餘類的依賴。
  • Setter方法注入:Setter方法注入是容器經過調用無參構造器或無參static工廠方法實例化bean以後,調用該bean的setter方法,即實現了基於setter的依賴注入。
  • 用構造器參數實現強制依賴,setter方法實現可選依賴。

8. Springboot啓動過程

  • 構造SpringApplication的實例
  • 調用SpringApplication.run()方法

    • 構造SpringApplicationRunListeners 實例
    • 發佈ApplicationStartedEvent事件
    • SpringApplicationRunListeners 實例準備環境信息
    • 建立ApplicationContext對象
    • ApplicationContext實例準備環境信息
    • 刷新的上下文

9. spring的bean的生命週期

  • Spring 容器根據配置中的 bean 定義中實例化 bean。
  • Spring 使用依賴注入填充全部屬性,如 bean 中所定義的配置。
  • 若是 bean 實現 BeanNameAware 接口,則工廠經過傳遞 bean 的 ID 來調用 setBeanName()。
  • 若是 bean 實現 BeanFactoryAware 接口,工廠經過傳遞自身的實例來調用 setBeanFactory()。
  • 若是存在與 bean 關聯的任何 BeanPostProcessors,則調用 preProcessBeforeInitialization() 方法。
  • 若是爲 bean 指定了 init 方法( 的 init-method 屬性),那麼將調用它。
  • 最後,若是存在與 bean 關聯的任何 BeanPostProcessors,則將調用 postProcessAfterInitialization() 方法。
  • 若是 bean 實現 DisposableBean 接口,當 spring 容器關閉時,會調用 destory()。
  • 若是爲 bean 指定了 destroy 方法( 的 destroy-method 屬性),那麼將調用它。
咱們這裏描述的是應用Spring上下文Bean的生命週期,若是應用Spring的工廠也就是BeanFactory的話去掉第5步就Ok了。

11. spring事件的實現原理,寫出經常使用的幾個事件

寫在最後

本次面試題分享到此爲止,限於篇幅,無法在這裏給你們分享更多的面試題; 以前不少粉絲一直私信我讓我整理一些面試題,近些天終於整理好了,筆者整理了一份包含Kafka、Mysql、Tomcat、Docker、Spring、MyBatis、Nginx、Netty、Dubbo、Redis、Netty、Spring cloud、分佈式、高併發、性能調優、微服務等架構技術的面試題和部分視頻學習資料;

須要的朋友點擊下方傳送門, 便可免費領取面試資料和視頻學習資料

傳送門

如下是部分面試題截圖

相關文章
相關標籤/搜索