首頁  >  文章  >  Java  >  《面試八股文》之 Spring 18卷

《面試八股文》之 Spring 18卷

Java后端技术全栈
Java后端技术全栈轉載
2023-08-22 15:55:591185瀏覽

「《面試八股文》之Spring 18卷」 又新鮮出爐了,這次整理了一下關於spring 的面試題,網上也翻了翻關於spring 的面試題,匯總了一下,基本上都在這裡了,當然可能有些過於基本的概念我是直接整理到某一問當中了,就沒有單獨再開設一問,祝大家面試順利~



  • 1.spring 中都用到了哪些設計模式?

  • #2.spring 中有哪些核心模組?

  • 3.說一下你理解的IOC 是什麼?

  • 4.spring 中的IOC 容器有哪些?有什麼區別?

  • 5.那BeanFactory 和FactoryBean 又有什麼差別?

  • 6.@Repository、@Service、@Compent、@Controller它們有什麼差別?

  • 7.那麼DI 又是什麼?

  • 8.說說AOP 是什麼?

  • 9.動態代理程式和靜態代理程式有什麼差別?

  • 10.JDK 動態代理程式和CGLIB 代理程式有什麼不同?

  • 11.Spring AOP 和 AspectJ AOP 有什麼差別?

  • 12.spring 中Bean 的生命週期是怎樣的?

  • 13.spring 是怎麼解決循環依賴的?

  • #14.為什麼要使用三級緩存,二級快取不能解決嗎?

  • #15.@Autowired 和@Resource 有什麼區別?

  • 16.spring 事務隔離等級有哪些?

  • 17.spring 事務的傳播機制有哪些?

  • 18.springBoot 自動組裝原理?


#

1.spring 中都用到了哪些設計模式?

《面試八股文》之 Spring 18卷
  • 「1.工廠設計模式」: 例如透過BeanFactory 和ApplicationContext 來生產Bean 物件
  • 「2.代理程式設計模式」:  AOP的實作方式就是透過代理來實現,Spring主要是使用JDK 動態代理程式和CGLIB 代理程式
  • 「3.單例設計模式」: Spring 中的Bean預設都是單例的
  • “4.模板方法模式”: Spring 中jdbcTemplate 等以Template 結尾的對資料庫操作的類,都會使用到模板方法設計模式,一些通用的功能
  • 「5.包裝器設計模式」: 我們的專案需要連接多個資料庫,而且不同的客戶在每次訪問中根據需要會去訪問不同的資料庫。這個模式讓我們可以根據客戶的需求能夠動態切換不同的資料來源
  • 「6.觀察者模式」: Spring 事件驅動模型觀察者模式的
  • 「7.適配器模式」:Spring AOP 的增強或通知(Advice)使用到了適配器模式

#2.spring 中有哪些核心模組?

《面試八股文》之 Spring 18卷
  • #1.「Spring Core」:Spring核心,它是框架最基礎的部分,提供IOC和依賴注入DI特性
  • #2.「Spring Context」:Spring上下文容器,它是BeanFactory 功能加強的一個子介面
  • 3.「Spring Web」:它提供Web應用開發的支援
  • #4.「Spring MVC」:它針對Web應用中MVC思想的實作
  • 5.「Spring DAO」:提供對JDBC抽象層,簡化了JDBC編碼,同時,編碼更具有健壯性
  • #6.「Spring ORM」:它支援用於流行的ORM框架的整合,例如:Spring Hibernate、Spring iBatis、Spring JDO的整合等
  • 7.「Spring AOP」:即面向切面編程,它提供了與AOP聯盟相容的程式實作實作

#3.說一下你所理解的IOC 是什麼?

《面試八股文》之 Spring 18卷

#首先IOC 是一個「容器」,是用來裝載物件的,它的核心思想就是「控制反轉」

那麼究竟「什麼是控制反轉」?

控制反轉就是說,「把物件的控制權交給了spring,由spring 容器進行管理”,我們不進行任何操作

那麼為「什麼需要控制反轉」?

我們想像一下,沒有控制反轉的時候,我們需要「自己去建立對象,配置對象」 ,也要「人工去處理物件與物件之間的各種複雜的依賴關係」,當一個工程的量起來之後,這種關係的維持是非常令人頭痛的,所以就有了控制反轉這個概念,將物件的建立、配置等一系列操作交給spring 去管理,我們在使用的時候只要去取就好了

4.spring 中的IOC 容器有哪些?有什麼區別?

spring 主要提供了“兩種IOC 容器”,一種是“BeanFactory 」,還有一種是「ApplicationContext」

它們的差別就在於,BeanFactory 「只提供了最基本的實例化物件和拿物件的功能」 ,而ApplicationContext 是繼承了BeanFactory 所衍生出來的產物,是其子類,它的作用更加的強大,例如支援註解注入、國際化等功能

5.那BeanFactory 和FactoryBean 又有什麼差別?

這兩個是「不同的產物」

「BeanFactory 是IOC容器」,是用來承載物件的

「FactoryBean 是一個介面」,為Bean 提供了更靈活的方式,透過代理一個Bean對象,對方法前後做一些操作。

6.@Repository、@Service、@Compent、@Controller它們有什麼區別?

這四個註解的 「本質都是一樣的,都是將被該註解標識的物件放入spring 容器當中,只是為了在使用上區分不同的應用分層」

#
  • @Repository:dao層
  • @Service:service層
  • @Controller:controller層
  • @Compent:其他不屬於以上三層的統一使用該註解

7.那麼DI 又是什麼?

DI 就是依賴注入,其實和IOC 大致相同,只不過是「同一個概念使用了不同的角度去闡述」

DI 所描述的「重點在於依賴」,我們說了「IOC 的核心功能就是在於程式執行時動態的向某個物件提供其他的依賴物件」,而這個功能就是靠DI 去完成的,例如我們需要注入一個物件A,而這個物件A 依賴一個物件B,那麼我們就需要把這個物件B 注入到物件A 中,這就是依賴注入

spring 中有三種注入方式

  • 介面注入
  • #建構子注入
  • ##set注入

8.說說AOP 是什麼?

AOP 意為:

「面向切面編程,透過預編譯方式和運行期間動態代理實現程式功能的統一維護的一種技術」

AOP 是

「OOP(物件導向程式設計) 的延續」,是 Spring 框架中的一個重要內容,是函數式程式設計的衍生範式。利用 AOP 可以對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度降低,提高程序的可重用性,同時提高了開發的效率。

「AOP 實作主要分為兩類:」

《面試八股文》之 Spring 18卷

  • 「靜態AOP 實作」,AOP 框架「在編譯階段」「靜態AOP 實作」
    ,AOP 框架
  • 「在編譯階段」
  • 對程式原始碼進行修改,產生了靜態的AOP 代理類別(產生的*.class 檔案已經被改掉了,需要使用特定的編譯器),例如AspectJ
    「動態AOP 實作」
    , AOP 框架
  • 「在運行階段」
對動態產生代理物件(在記憶體中以JDK 動態代理,或CGlib 動態地產生AOP 代理類別),如SpringAOP

#spring 中AOP 的實作是
「透過動態代理實現的」《面試八股文》之 Spring 18卷,如果實作了介面就會使用JDK 動態代理,否則就使用CGLIB 代理程式。

    「有5 種通知類型:」
  • 「@Before」
  • :在目標方法呼叫前去通知
  • “@AfterReturning”
  • :在目標方法回傳或異常後呼叫
  • “@AfterThrowing”
  • :在目標方法返回後呼叫
  • #“@After”
  • :在目標方法異常後呼叫
  • “@Around”
:將目標方法封裝起來,自己決定呼叫時機

9.動態代理程式和靜態代理有什麼差別?

###「靜態代理程式」######
  • 由程式設計師建立或由特定工具自動產生原始程式碼,再對其編譯。在程式運行前,代理類別的.class檔案就已經存在了
  • 靜態代理通常只代理一個類別
  • 靜態代理事先知道要代理的是什麼

「動態代理程式」

  • #在程式執行時,運用反射機制動態建立而成
  • 動態代理程式是代理程式一個介面下的多個實作類別
  • #動態代理程式不知道要代理什麼東西,只有在執行時才知道

10.JDK 動態代理程式和CGLIB 代理程式有什麼差別?

JDK 動態代理程式時業務類別「必須要實作某個介面」,它是「基於反射的機制實現的」,產生一個實現同樣介面的一個代理類,然後透過重寫方法的方式,實現對程式碼的增強。

CGLIB 動態代理程式是使用字節碼處理框架ASM,其原理是透過字節碼技術為一個類別「建立子類,然後重寫父類的方法」,實現對程式碼的增強。

11.Spring AOP 和 AspectJ AOP 有什麼不同?

Spring AOP 是運行時增強,是透過「動態代理實作」

AspectJ AOP 是編譯時增強,需要特殊的編譯器才可以完成,是透過「修改程式碼來實現」的,支援「三種織入方式」

  • 「編譯時織入」:就是在編譯字節碼的時候織入相關代理類別
  • 「編譯後織入」:編譯完初始類別後發現需要AOP 增強,然後織入相關程式碼
  • 「類別載入時織入」 :指在載入器載入類別的時候織入
《面試八股文》之 Spring 18卷
編譯時、編譯後、類別載入時
主要差異 Spring AOP AspecjtJ AOP
#增強方式 在執行階段增強
#實作方式 動態代理程式 修改程式碼
編譯器 javac #特殊的編譯器ajc
效率 較低(運行時反射損耗效能) 較高
#執行時期
#######

12.spring 中Bean 的生命週期是怎樣的?

SpringBean 生命週期大致分為4個階段:

《面試八股文》之 Spring 18卷
  • 1.「實例化」,實例化該Bean 物件
  • 2.「填充屬性」,給該Bean 賦值
  • 3.「初始化」
    • 如果實作了Aware 接口,會透過其介面取得容器資源
    • 如果實作了BeanPostProcessor 接口,則會回調該介面的前置和後置處理增強
    • #如果配置了init-method 方法,]會執行該方法
  • #4.「銷毀」
    • 如果實作了DisposableBean 接口,則會回呼該介面的destroy 方法
    • 如果配置了destroy-method 方法,則會執行destroy -method 設定的方法

#13.spring 是怎麼解決循環依賴的?

《面試八股文》之 Spring 18卷

循環依賴就是說兩個物件相互依賴,形成了一個環形的呼叫連結

spring 使用三級快取去解決循環依賴的,其「核心邏輯就是把實例化和初始化的步驟分開,然後放入快取中」,供另一個物件呼叫

  • 「第一層快取」:用來保存實例化、初始化都完成的物件
  • 「第二級快取」:用來保存實例化完成,但是未初始化完成的物件
  • #「第三級快取」:用來保存一個物件工廠,提供一個匿名內部類,用於建立二級快取中的物件

#當A、B 兩個類別發生循環引用時大致流程

  • #1.A 完成實例化後,去「建立一個物件工廠,放入三級快取」當中
    • 如果A 被AOP 代理,那麼透過這個工廠取得到的就是A 代理後的物件
    • 如果A 沒有被AOP 代理,那麼這個工廠取得到的就是A 實例化的物件
  • 2.A 進行屬性注入時,去「建立B」
  • 3. B 進行屬性注入,需要A ,則「從三級快取去取A 工廠代理物件」並注入,然後刪除三級快取中的A 工廠,將A 物件放入二級快取
  • 4.B 完成後續屬性注入,直到初始化結束,將B 放入一級快取
  • ##5.
    「A 從一級快取中取到B 並且注入B”, 直到完成後續操作,將A 從二級快取刪除並且放入一級緩存,循環依賴結束

spring 解決循環依賴有兩個前提條件:

  • 1.「不全是建構器方式」的循環依賴(否則無法分離初始化和實例化的操作)
  • 2.「必須是單例」(否則無法保證是同一物件)

#14.為什麼要使用三級緩存,二級緩存不能解決嗎?

可以,三級緩存的功能是只有真正發生循環依賴的時候,才去提前生成代理對象,否則只會“創建一個工廠並將其放入到三級緩存”中,但是不會去通過這個工廠去真正創建物件。

如果使用二級快取解決循環依賴,意味著所有Bean 在實例化後就要完成AOP 代理,這樣「違背了Spring 設計的原則」,Spring 在設計之初是在Bean 生命週期的最後一步來完成AOP 代理,而不是在實例化後就立刻進行AOP 代理。

15.@Autowired 和@Resource 有什麼差別?

  • ##「@Resource是Java 自己的註解”,@Resource 有兩個屬性是比較重要的,分是name 和type;Spring 將@Resource 註解的name 屬性解析為bean 的名字,而type 屬性則解析為bean 的類型。所以如果使用 name 屬性,則使用 byName 的自動注入策略,而使用 type 屬性時則使用 byType 自動注入策略。如果既不指定 name 也不指定 type 屬性,這時將透過反射機制使用 byName 自動注入策略。

  • 「@Autowired 是spring 的註解」,是spring2.5 版本引入的,Autowired 只根據type 進行注入,“不會去匹配name”。如果涉及到 type 無法辨別注入物件時,那需要依賴 @Qualifier 或 @Primary 註解一起來修飾。

16.spring 交易隔離等級有哪些?

《面試八股文》之 Spring 18卷
  • DEFAULT:採用DB 預設的交易隔離等級
  • READ_UNCOMMITTED:讀取未提交
  • READ_COMMITTED:讀取已提交
  • REPEATABLE_READ:可重複讀取
  • SERIALIZABLE:序列化

《面試八股文》之 Spring 18卷
    • ##17.spring 交易的傳播機制有哪些?
      ################1.###「propagation_required」####### ############目前方法###「必須在一個具有事務的上下文中運行」###,如有客戶端有事務在進行,那麼被呼叫端將在該事務中運行,否則的話重新開啟一個事務。(如果被呼叫端發生異常,那麼呼叫端和被呼叫端事務都會回滾)
  • #2.「propagation_supports」
    • #目前方法不必需要有一個交易上下文,但是如果有一個交易的話,它也可以在這個交易中運行
  • 3.“propagation_mandatory”
    • #表示目前方法「必須在一個事務中運行」,如果沒有事務,將拋出例外
  • 4.「propagation_nested」
    • 如果目前方法正有一個事務在運行中,則該方法應該“運行在一個巢狀事務”中,被嵌套的事務可以獨立於被封裝的事務中進行提交或回滾。如果封裝事務存在,且外層事務拋出異常回滾,那麼內層事務必須回滾,反之,內層事務並不影響外層事務。如果封裝交易不存在,則同propagation_required的一樣
  • #5.「propagation_never」
    • 當方法務不應該在一個事務中運行,如果“存在一個事務,則拋出異常”
  • 6. “propagation_requires_new”
    • ###目前方法###“必須運行在它自己的交易中”###。一個新的事務將啟動,而且如果有一個現有的事務在運行的話,則這個方法將在運行期被掛起,直到新的事務提交或回滾才恢復執行。 ###############7.###「propagation_not_supported」##################方法不應該在一個交易中運作。「如果有一個交易正在運行,他將在運行期被掛起,直到這個事務提交或回滾才恢復執行」

18.springBoot 自動組裝原理?

《面試八股文》之 Spring 18卷
  • #1.容器在啟動的時候會呼叫EnableAutoConfigurationImportSelector.class 的selectImports方法「取得一個全面的常用BeanConfiguration 清單」

  • #2.之後會讀取spring-boot-

  • #2.之後會讀取spring-boot-
  • #2. autoconfigure.jar 下面的spring.factories,

    「取得所有的Spring 相關的Bean 的全限定名ClassName」
  • ##3.之後繼續「呼叫filter 來一一篩選」

    ,過濾掉一些我們不需要不符合條件的Bean
########4.最後把符合條件的BeanConfiguration 注入預設的EnableConfigurationPropertie 類別裡面的屬性值,並且###「注入到IOC 環境當中」###############

以上是《面試八股文》之 Spring 18卷的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:Java后端技术全栈。如有侵權,請聯絡admin@php.cn刪除