日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

无招胜有招之spring _高频面试题

發布時間:2024/2/28 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 无招胜有招之spring _高频面试题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1、使用 Spring 框架的好處是什么?

1. 輕量:Spring 是輕量的,基本的版本大約 2MB。

2. 控制反轉:Spring 通過控制反轉實現了松散耦合,對象們給出它們的依賴,而不是創建或查找依賴的對象們。

3. 面向切面的編程(AOP):Spring 支持面向切面的編程,并且把應用業務邏輯和系統服務分開。

4. 容器:Spring 包含并管理應用中對象的生命周期和配置。

5. MVC框架:Spring 的 Web 框架是個精心設計的框架,是 Web 框架的一個很好的替代品。

6. 事務管理:Spring 提供一個持續的事務管理接口,可以擴展到上至本地事務下至全局事務(JTA)。

7. 異常處理:Spring 提供方便的 API 把具體技術相關的異常(比如由 JDBC,Hibernate or JDO 拋出的)轉化為一致的 unchecked 異常。

2、解釋下什么是 AOP?

AOP(Aspect-Oriented Programming,面向方面編程),可以說是 OOP(Object-Oriented Programing,面向對象編程)的補充和完善。OOP 引入封裝、繼承和多態性等概念來建立一種對象層次結構,用以模擬公共行為的一個集合。當我們需要為分散的對象引入公共行為的時候,OOP 則顯得無能為力。也就是說,OOP 允許你定義從上到下的關系,但并不適合定義從左到右的關系。例如日志功能。日志代碼往往水平地散布在所有對象層次中,而與它所散布到的對象的核心功能毫無關系。對于其他類型的代碼,如:安全性、異常處理和透明的持續性也是如此。這種散布在各處的無關的代碼被稱為橫切(cross-cutting)代碼,在 OOP 設計中,它導致了大量代碼的重復,而不利于各個模塊的重用。

而 AOP 技術則恰恰相反,它利用一種稱為“橫切”的技術,剖解開封裝的對象內部,并將那些影響了多個類的公共行為封裝到一個可重用模塊,并將其名為“Aspect”,即方面。所謂“方面”,簡單地說,就是將那些與業務無關,卻為業務模塊所共同調用的邏輯或責任封裝起來,便于減少系統的重復代碼,降低模塊間的耦合度,并有利于未來的可操作性和可維護性。AOP 代表的是一個橫向的關系,如果說“對象”是一個空心的圓柱體,其中封裝的是對象的屬性和行為;那么面向方面編程的方法,就仿佛一把利刃,將這些空心圓柱體剖開,以獲得其內部的消息。而剖開的切面,也就是所謂的“方面”了。然后它又以巧奪天功的妙手將這些剖開的切面復原,不留痕跡。

使用“橫切”技術,AOP 把軟件系統分為兩個部分:核心關注點和橫切關注點。業務處理的主要流程是核心關注點,與之關系不大的部分是橫切關注點。橫切關注點的一個特點是,它們經常發生在核心關注點的多處,而各處都基本相似。比如:權限認證、日志、事務處理。AOP 的作用在于分離系統中的各種關注點,將核心關注點和橫切關注點分離開來。

3、AOP 的代理有哪幾種方式?

AOP 思想的實現一般都是基于代理模式 ,在 Java?中一般采用 JDK 動態代理模式,但是我們都知道,JDK 動態代理模式只能代理接口而不能代理類。因此,Spring AOP 會按照下面兩種情況進行切換,因為 Spring AOP 同時支持 CGLIB、ASPECTJ、JDK 動態代理。

1. 如果目標對象的實現類實現了接口,Spring AOP 將會采用 JDK 動態代理來生成 AOP 代理類;

2. 如果目標對象的實現類沒有實現接口,Spring AOP 將會采用 CGLIB 來生成 AOP 代理類。不過這個選擇過程對開發者完全透明、開發者也無需關心。

4、怎么實現 JDK 動態代理?

JDK 動態代理最核心的一個接口和方法如下所示:

  • ?1. java.lang.reflect 包中的 InvocationHandler 接口:

public interface InvocationHandler { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable; }

對于被代理的類的操作都會由該接口中的 invoke 方法實現,其中的參數的含義分別是:

1. proxy:被代理的類的實例;
2. method:調用被代理的類的方法;
3. args:該方法需要的參數。

使用方法首先是需要實現該接口,并且我們可以在 invoke 方法中調用被代理類的方法并獲得返回值,自然也可以在調用該方法的前后去做一些額外的事情,從而實現動態代理。

  • 2. java.lang.reflect 包中的 Proxy 類中的 newProxyInstance 方法:

public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException

其中的參數含義如下:

1. loader:被代理的類的類加載器;

2. interfaces:被代理類的接口數組;

3. invocationHandler:調用處理器類的對象實例。

該方法會返回一個被修改過的類的實例,從而可以自由的調用該實例的方法。

5、AOP 的基本概念:切面、連接點、切入點等?

1. 切面(Aspect):官方的抽象定義為“一個關注點的模塊化,這個關注點可能會橫切多個對象”。

2. 連接點(Joinpoint):程序執行過程中的某一行為。

3. 通知(Advice):“切面”對于某個“連接點”所產生的動作。

4. 切入點(Pointcut):匹配連接點的斷言,在 AOP 中通知和一個切入點表達式關聯。

5. 目標對象(Target Object):被一個或者多個切面所通知的對象。

6. AOP 代理(AOP Proxy):在 Spring AOP 中有兩種代理方式,JDK 動態代理和 CGLIB 代理。

6、通知類型(Advice)型(Advice)有哪些?

1.?前置通知(Before advice):在某連接點(JoinPoint)之前執行的通知,但這個通知不能阻止連接點前的執行。ApplicationContext 中在 <aop:aspect> 里面使用 <aop:before> 元素進行聲明;

2.?后置通知(After advice):當某連接點退出的時候執行的通知(不論是正常返回還是異常退出)。ApplicationContext 中在 <aop:aspect> 里面使用 <aop:after> 元素進行聲明。

3.?返回后通知(After return advice :在某連接點正常完成后執行的通知,不包括拋出異常的情況。ApplicationContext 中在 <aop:aspect> 里面使用 <<after-returning>> 元素進行聲明。

4.?環繞通知(Around advice):包圍一個連接點的通知,類似 Web 中 Servlet規范中的 Filter 的 doFilter 方法。可以在方法的調用前后完成自定義的行為,也可以選擇不執行。ApplicationContext 中在 <aop:aspect> 里面使用 <aop:around> 元素進行聲明。

5.?拋出異常后通知(After throwing advice):在方法拋出異常退出時執行的通知。ApplicationContext 中在 <aop:aspect> 里面使用 <aop:after-throwing> 元素進行聲明。

7、談談你對 IOC 的理解?

?IOC 是 Inversion of Control 的縮寫,多數書籍翻譯成“控制反轉”。簡單來說就是把復雜系統分解成相互合作的對象,這些對象類通過封裝以后,內部實現對外部是透明的,從而降低了解決問題的復雜度,而且可以靈活地被重用和擴展。IOC 理論提出的觀點大體是這樣的:借助于“第三方”實現具有依賴關系的對象之間的解耦。如下圖:

由于引進了中間位置的“第三方”,也就是 IOC 容器,使得 A、B、C、D 這 4 個對象沒有了耦合關系,齒輪之間的傳動全部依靠“第三方”了,全部對象的控制權全部上繳給“第三方”IOC 容器,所以,IOC 容器成了整個系統的關鍵核心,它起到了一種類似“粘合劑”的作用,把系統中的所有對象粘合在一起發揮作用,如果沒有這個“粘合劑”,對象與對象之間會彼此失去聯系,這就是有人把 IOC 容器比喻成“粘合劑”的由來。  

把上圖中間的 IOC 容器拿掉,然后再來看看這套系統:

現在看到的畫面,就是我們要實現整個系統所需要完成的全部內容。這時候,A、B、C、D 這 4 個對象之間已經沒有了耦合關系,彼此毫無聯系,這樣的話,當你在實現 A 的時候,根本無須再去考慮 B、C 和 D了,對象之間的依賴關系已經降低到了最低程度。所以,如果真能實現 IOC 容器,對于系統開發而言,這將是一件多么美好的事情,參與開發的每一成員只要實現自己的類就可以了,跟別人沒有任何關系!

我們再來看看,控制反轉(IOC)到底為什么要起這么個名字?我們來對比一下:

軟件系統在沒有引入 IOC 容器之前,對象 A 依賴于對象 B,那么對象 A 在初始化或者運行到某一點的時候,自己必須主動去創建對象 B 或者使用已經創建的對象 B。無論是創建還是使用對象 B,控制權都在自己手上。

軟件系統在引入 IOC 容器之后,這種情形就完全改變了,由于 IOC 容器的加入,對象 A 與對象 B 之間失去了直接聯系,所以,當對象 A 運行到需要對象 B 的時候,IOC 容器會主動創建一個對象 B 注入到對象 A 需要的地方。

通過前后的對比,我們不難看出來:對象 A 獲得依賴對象 B 的過程,由主動行為變為了被動行為,控制權顛倒過來了,這就是“控制反轉”這個名稱的由來。

總的來說:

?IOC:就是由 Spring IOC 容器來負責對象的生命周期和對象之間的關系。

IOC其思想是反轉資源獲取的方向。類的對象創建及對象之間的關系從代碼中移植到配置文件中,由Spring配置文件(即:IOC容器)負責對象的創建及對象之間關系的管理。

8、Bean 的生命周期?

在傳統的 Java 應用中,bean 的生命周期很簡單,使用 Java 關鍵字 new 進行 Bean 的實例化,然后該 Bean 就能夠使用了。一旦 Bean 不再被使用,則由 Java 自動進行垃圾回收。

相比之下,Spring 管理 Bean 的生命周期就復雜多了,正確理解 Bean 的生命周期非常重要,因為 Spring 對 Bean 的管理可擴展性非常強,下面展示了一個 Bean 的構造過程:

?

1. Spring 啟動,查找并加載需要被 Spring 管理的 Bean,進行 Bean 的實例化;

2. Bean 實例化后,對 Bean 的引入和值注入到 Bean 的屬性中;

3. 如果 Bean 實現了 BeanNameAware 接口的話,Spring 將 Bean 的 Id 傳遞給 setBeanName() 方法;

4. 如果 Bean 實現了 BeanFactoryAware 接口的話,Spring 將調用 setBeanFactory() 方法,將 BeanFactory 容器實例傳入;

5. 如果 Bean 實現了 ApplicationContextAware 接口的話,Spring 將調用 Bean 的 setApplicationContext() 方法,將 Bean 所在應用上下文引用傳入進來;

6. 如果 Bean 實現了 BeanPostProcessor 接口,Spring 就將調用它們的 postProcessBeforeInitialization() 方法;

7. 如果 Bean 實現了 InitializingBean 接口,Spring 將調用它們的 afterPropertiesSet() 方法。類似地,如果 Bean 使用 init-method 聲明了初始化方法,該方法也會被調用;

8. 如果 Bean 實現了 BeanPostProcessor 接口,Spring 就將調用它們的 postProcessAfterInitialization() 方法;

9. 此時,Bean 已經準備就緒,可以被應用程序使用了。它們將一直駐留在應用上下文中,直到應用上下文被銷毀;

10. 如果 Bean 實現了 DisposableBean 接口,Spring 將調用它的 destory() 接口方法,同樣,如果 Bean 使用了 destory-method 聲明銷毀方法,該方法也會被調用。

9、Bean 的作用域?

1. singleton : 唯一 bean 實例,Spring 中的 bean 默認都是單例的;

2. prototype : 每次請求都會創建一個新的 bean 實例;

3. request:每一次 HTTP 請求都會產生一個新的 bean,該 bean 僅在當前 HTTP request 內有效;

4. session : 每一次 HTTP 請求都會產生一個新的 bean,該 bean 僅在當前 HTTP session 內有效;

5. global-session:全局 session 作用域,僅僅在基于 portlet 的 web 應用中才有意義,Spring5 已經沒有了。Portlet 是能夠生成語義代碼(例如:HTML)片段的小型 Java Web 插件。它們基于 portlet 容器,可以像 servlet 一樣處理 HTTP 請求。但是,與 servlet 不同,每個 portlet 都有不同的會話。

10、Spring 中的單例 Bean 的線程安全問題了解嗎?

大部分時候我們并沒有在系統中使用多線程,所以很少有人會關注這個問題。單例 bean 存在線程問題,主要是因為:當多個線程操作同一個對象的時候,對這個對象的非靜態成員變量的寫操作會存在線程安全問題。常見的有兩種解決辦法:

1. 在 Bean 對象中盡量避免定義可變的成員變量(不太現實)。

2. 在類中定義一個 ThreadLocal 成員變量,將需要的可變成員變量保存在 ThreadLocal 中(推薦的一種方式)。

11、談談你對 Spring 中的事物的理解?

事務是邏輯上的一組操作,要么都執行,要么都不執行。

  • 事務特性

原子性:事務是最小的執行單位,不允許分割。事務的原子性確保動作要么全部完成,要么完全不起作用;

一致性:執行事務前后,數據保持一致;

隔離性:并發訪問數據庫時,一個用戶的事物不被其他事物所干擾,各并發事務之間數據庫是獨立的;

持久性: 一個事務被提交之后。它對數據庫中數據的改變是持久的,即使數據庫發生故障也不應該對其有任何影響。

  • Spring 事務管理接口

1. PlatformTransactionManager:(平臺)事務管理器;

2. TransactionDefinition:事務定義信息(事務隔離級別、傳播行為、超時、只讀、回滾規則);

3. TransactionStatus:事務運行狀態;

所謂事務管理,其實就是“按照給定的事務規則來執行提交或者回滾操作”。

12、Spring 中的事務隔離級別?

TransactionDefinition 接口中定義了五個表示隔離級別的常量:

TransactionDefinition.ISOLATION_DEFAULT:使用后端數據庫默認的隔離級別,MySQL 默認采用的 REPEATABLE_READ 隔離級別 Oracle 默認采用的 READ_COMMITTED 隔離級別;

TransactionDefinition.ISOLATION_READ_UNCOMMITTED:最低的隔離級別,允許讀取尚未提交的數據變更,可能會導致臟讀、幻讀或不可重復讀;

TransactionDefinition.ISOLATION_READ_COMMITTED:允許讀取并發事務已經提交的數據,可以阻止臟讀,但是幻讀或不可重復讀仍有可能發生;

TransactionDefinition.ISOLATION_REPEATABLE_READ:對同一字段的多次讀取結果都是一致的,除非數據是被本身事務自己所修改,可以阻止臟讀和不可重復讀,但幻讀仍有可能發生;

TransactionDefinition.ISOLATION_SERIALIZABLE:最高的隔離級別,完全服從 ACID 的隔離級別。所有的事務依次逐個執行,這樣事務之間就完全不可能產生干擾,也就是說,該級別可以防止臟讀、不可重復讀以及幻讀。但是這將嚴重影響程序的性能。通常情況下也不會用到該級別。

13、Spring 中的事物傳播行為?

事務傳播行為是為了解決業務層方法之間互相調用的事務問題。當事務方法被另一個事務方法調用時,必須指定事務應該如何傳播。例如:方法可能繼續在現有事務中運行,也可能開啟一個新事務,并在自己的事務中運行。在 TransactionDefinition 定義中包括了如下幾個表示傳播行為的常量:

  • 支持當前事務的情況:

TransactionDefinition.PROPAGATION_REQUIRED:如果當前存在事務,則加入該事務;如果當前沒有事務,則創建一個新的事務;

TransactionDefinition.PROPAGATION_SUPPORTS:如果當前存在事務,則加入該事務;如果當前沒有事務,則以非事務的方式繼續運行;

TransactionDefinition.PROPAGATION_MANDATORY:如果當前存在事務,則加入該事務;如果當前沒有事務,則拋出異常。

  • 不支持當前事務的情況:

TransactionDefinition.PROPAGATION_REQUIRES_NEW:創建一個新的事務,如果當前存在事務,則把當前事務掛起;

TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事務方式運行,如果當前存在事務,則把當前事務掛起。

TransactionDefinition.PROPAGATION_NEVER:以非事務方式運行,如果當前存在事務,則拋出異常。

  • 其他情況:

TransactionDefinition.PROPAGATION_NESTED:如果當前存在事務,則創建一個事務作為當前事務的嵌套事務來運行;如果當前沒有事務,則該取值等價于 TransactionDefinition.PROPAGATION_REQUIRED。

14、Spring 常用的注入方式有哪些?

1. 構造器依賴注入:構造器依賴注入通過容器觸發一個類的構造器來實現的,該類有一系列參數,每個參數代表一個對其他類的依賴。

2. Setter 方法注入:Setter 方法注入是容器通過調用無參構造器或無參 static 工廠方法實例化 bean 之后,調用該 bean 的 Setter 方法,即實現了基于 Setter 的依賴注入。

3. 基于注解的注入:最好的解決方案是用構造器參數實現強制依賴,Setter 方法實現可選依賴。

15、Spring 框架中用到了哪些設計模式?

1. 工廠設計模式 : Spring 使用工廠模式通過 BeanFactory、ApplicationContext 創建 bean 對象;

2. 代理設計模式 : Spring AOP 功能的實現;

3. 單例設計模式 : Spring 中的 Bean 默認都是單例的;

4. 模板方法模式 : Spring 中 jdbcTemplate、hibernateTemplate 等以 Template 結尾的對數據庫操作的類,它們就使用到了模板模式;

5. 包裝器設計模式 : 我們的項目需要連接多個數據庫,而且不同的客戶在每次訪問中根據需要會去訪問不同的數據庫。這種模式讓我們可以根據客戶的需求能夠動態切換不同的數據源;

6. 觀察者模式:Spring 事件驅動模型就是觀察者模式很經典的一個應用;

7. 適配器模式:Spring AOP 的增強或通知(Advice)使用到了適配器模式、SpringMVC 中也是用到了適配器模式適配 Controller。

16、ApplicationContext 通常的實現有哪些?

1. FileSystemXmlApplicationContext:此容器從一個 XML 文件中加載beans 的定義,XML Bean 配置文件的全路徑名必須提供給它的構造函數。

2. ClassPathXmlApplicationContext:此容器也從一個 XML 文件中加載beans 的定義,這里,你需要正確設置 classpath 因為這個容器將在 classpath 里找 bean 配置。

3. WebXmlApplicationContext:此容器加載一個 XML 文件,此文件定義了一個 Web 應用的所有 bean。

總結

以上是生活随笔為你收集整理的无招胜有招之spring _高频面试题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。