java程式設計師進階:螞蟻金服的Spring經典面試題集錦,附答案
說起來開始進行面試是年前倒數第二週,上午9點,我還在去公司的公交上,突然收到螞蟻的面試電話,其實算不上真正的面試。面試官只是和我聊了下他們在做的事情(主要是做雙十一這裡大促的穩定性保障,偏中介軟體吧),說的很詳細,然後和我溝通了下是否有興趣,我表示有興趣,後面就收到正式面試的通知,最後沒選擇去螞蟻表示抱歉。

當時我自己也準備出去看看機會,順便看看自己的實力。當時我其實挺糾結的,一方面現在部門也正需要我,還是可以有一番作為的,另一方面覺得近一年來進步緩慢,沒有以前飛速進步的成就感了,而且業務和技術偏於穩定,加上自己也屬於那種比較懶散的人,骨子裡還是希望能夠突破現狀,持續在技術上有所精進。
一般問題
不同版本的 Spring Framework 有哪些主要功能?VersionFeatureSpring 2.5釋出於 2007 年。這是第一個支援註解的版本。Spring 3.0釋出於 2009 年。它完全利用了 Java5 中的改進,併為 JEE6 提供了支援。Spring 4.0釋出於 2013 年。這是第一個完全支援 JAVA8 的版本。
什麼是 Spring Framework?
- Spring 是一個開源應用框架,旨在降低應用程式開發的複雜度。
- 它是輕量級、鬆散耦合的。
- 它具有分層體系結構,允許使用者選擇元件,同時還為 J2EE 應用程式開發提供了一個有凝聚力的框架。
- 它可以整合其他框架,如 Structs、Hibernate、EJB 等,所以又稱為框架的框架。
列舉 Spring Framework 的優點。
- 由於 Spring Frameworks 的分層架構,使用者可以自由選擇自己需要的元件。
- Spring Framework 支援 POJO(Plain Old Java Object) 程式設計,從而具備持續整合和可測試性。
- 由於依賴注入和控制反轉,JDBC 得以簡化。
- 它是開源免費的。
Spring Framework 有哪些不同的功能?
- 輕量級 - Spring 在程式碼量和透明度方面都很輕便。
- IOC - 控制反轉
- AOP - 面向切面程式設計可以將應用業務邏輯和系統服務分離,以實現高內聚。
- 容器 - Spring 負責建立和管理物件(Bean)的生命週期和配置。
- MVC - 對 web 應用提供了高度可配置性,其他框架的整合也十分方便。
- 事務管理 - 提供了用於事務管理的通用抽象層。Spring 的事務支援也可用於容器較少的環境。
- JDBC 異常 - Spring 的 JDBC 抽象層提供了一個異常層次結構,簡化了錯誤處理策略。
Spring Framework 中有多少個模組,它們分別是什麼?

- Spring 核心容器 – 該層基本上是 Spring Framework 的核心。它包含以下模組:
- Spring Core
- Spring Bean
- SpEL (Spring Expression Language)
- Spring Context
- 資料訪問/整合 – 該層提供與資料庫互動的支援。它包含以下模組:
- JDBC (Java DataBase Connectivity)
- ORM (Object Relational Mapping)
- OXM (Object XML Mappers)
- JMS (Java Messaging Service)
- Transaction
- Web – 該層提供了建立 Web 應用程式的支援。它包含以下模組:
- Web
- Web – Servlet
- Web – Socket
- Web – Portlet
- AOP – 該層支援面向切面程式設計
- Instrumentation – 該層為類檢測和類載入器實現提供支援。
- Test – 該層為使用 JUnit 和 TestNG 進行測試提供支援。
- 幾個雜項模組 :
- Messaging – 該模組為 STOMP 提供支援。它還支援註解程式設計模型,該模型用於從 WebSocket 客戶端路由和處理 * STOMP 訊息。
- Aspects – 該模組為與 AspectJ 的整合提供支援。
什麼是 Spring 配置檔案?
Spring 配置檔案是 XML 檔案。該檔案主要包含類資訊。它描述了這些類是如何配置以及相互引入的。但是,XML 配置檔案冗長且更加乾淨。如果沒有正確規劃和編寫,那麼在大專案中管理變得非常困難。
Spring 應用程式有哪些不同元件?
Spring 應用一般有以下元件:
- 介面 - 定義功能。
- Bean 類 - 它包含屬性,setter 和 getter 方法,函式等。
- Spring 面向切面程式設計(AOP) - 提供面向切面程式設計的功能。
- Bean 配置檔案 - 包含類的資訊以及如何配置它們。
- 使用者程式 - 它使用介面。
使用 Spring 有哪些方式?
使用 Spring 有以下方式:
- 作為一個成熟的 Spring Web 應用程式。
- 作為第三方 Web 框架,使用 Spring Frameworks 中間層。
- 用於遠端使用。
- 作為企業級 Java Bean,它可以包裝現有的 POJO(Plain Old Java Objects)。
依賴注入(Ioc)
什麼是 Spring IOC 容器?
Spring 框架的核心是 Spring 容器。容器建立物件,將它們裝配在一起,配置它們並管理它們的完整生命週期。Spring 容器使用依賴注入來管理組成應用程式的元件。容器通過讀取提供的配置元資料來接收物件進行例項化,配置和組裝的指令。該元資料可以通過 XML,Java 註解或 Java 程式碼提供。

在依賴注入中,您不必建立物件,但必須描述如何建立它們。您不是直接在程式碼中將元件和服務連線在一起,而是描述配置檔案中哪些元件需要哪些服務。由 IoC 容器將它們裝配在一起。
可以通過多少種方式完成依賴注入?
通常,依賴注入可以通過三種方式完成,即:
- 建構函式注入
- setter 注入
- 介面注入 在 Spring Framework 中,僅使用建構函式和 setter 注入。
區分建構函式注入和 setter 注入。
建構函式注入setter 注入沒有部分注入有部分注入不會覆蓋 setter 屬性會覆蓋 setter 屬性任意修改都會建立一個新例項任意修改不會建立一個新例項適用於設定很多屬性適用於設定少量屬性
spring 中有多少種 IOC 容器?
- BeanFactory - BeanFactory 就像一個包含 bean 集合的工廠類。它會在客戶端要求時例項化 bean。
- ApplicationContext - ApplicationContext 介面擴充套件了 BeanFactory 介面。它在 BeanFactory 基礎上提供了一些額外的功能。
區分 BeanFactory 和 ApplicationContext。
BeanFactoryApplicationContext它使用懶載入它使用即時載入它使用語法顯式提供資源物件它自己建立和管理資源物件不支援國際化支援國際化不支援基於依賴的註解支援基於依賴的註解
列舉 IoC 的一些好處。
IoC 的一些好處是:
- 它將最小化應用程式中的程式碼量。
- 它將使您的應用程式易於測試,因為它不需要單元測試用例中的任何單例或 JNDI 查詢機制。
- 它以最小的影響和最少的侵入機制促進鬆耦合。
- 它支援即時的例項化和延遲載入服務。
Spring IoC 的實現機制。
Spring 中的 IoC 的實現原理就是工廠模式加反射機制。
示例:
interface Fruit { public abstract void eat(); } class Apple implements Fruit { public void eat(){ System.out.println("Apple"); } } class Orange implements Fruit { public void eat(){ System.out.println("Orange"); } } class Factory { public static Fruit getInstance(String ClassName) { Fruit f=null; try { f=(Fruit)Class.forName(ClassName).newInstance(); } catch (Exception e) { e.printStackTrace(); } return f; } } class Client { public static void main(String[] a) { Fruit f=Factory.getInstance("io.github.dunwu.spring.Apple"); if(f!=null){ f.eat(); } } } 複製程式碼
Beans
什麼是 spring bean?
- 它們是構成使用者應用程式主幹的物件。
- Bean 由 Spring IoC 容器管理。
- 它們由 Spring IoC 容器例項化,配置,裝配和管理。
- Bean 是基於使用者提供給容器的配置元資料建立。
spring 提供了哪些配置方式?
- 基於 xml 配置
bean 所需的依賴項和服務在 XML 格式的配置檔案中指定。這些配置檔案通常包含許多 bean 定義和特定於應用程式的配置選項。它們通常以 bean 標籤開頭。例如:
<bean id="studentbean" class="org.edureka.firstSpring.StudentBean"> <property name="name" value="Edureka"></property> </bean> 複製程式碼
- 基於註解配置
您可以通過在相關的類,方法或欄位宣告上使用註解,將 bean 配置為元件類本身,而不是使用 XML 來描述 bean 裝配。預設情況下,Spring 容器中未開啟註解裝配。因此,您需要在使用它之前在 Spring 配置檔案中啟用它。例如:
<beans> <context:annotation-config/> <!-- bean definitions go here --> </beans> 複製程式碼
- 基於 Java API 配置
Spring 的 Java 配置是通過使用 @Bean 和 @Configuration 來實現。
- @Bean 註解扮演與 元素相同的角色。
- @Configuration 類允許通過簡單地呼叫同一個類中的其他 @Bean 方法來定義 bean 間依賴關係。
例如:
@Configuration public class StudentConfig { @Bean public StudentBean myStudent() { return new StudentBean(); } } 複製程式碼
spring 支援集中 bean scope?
Spring bean 支援 5 種 scope:
- Singleton - 每個 Spring IoC 容器僅有一個單例項。
- Prototype - 每次請求都會產生一個新的例項。
- Request - 每一次 HTTP 請求都會產生一個新的例項,並且該 bean 僅在當前 HTTP 請求內有效。
- Session - 每一次 HTTP 請求都會產生一個新的 bean,同時該 bean 僅在當前 HTTP session 內有效。
- Global-session - 類似於標準的 HTTP Session 作用域,不過它僅僅在基於 portlet 的 web 應用中才有意義。Portlet 規範定義了全域性 Session 的概念,它被所有構成某個 portlet web 應用的各種不同的 portlet 所共享。在 global session 作用域中定義的 bean 被限定於全域性 portlet Session 的生命週期範圍內。如果你在 web 中使用 global session 作用域來標識 bean,那麼 web 會自動當成 session 型別來使用。
僅當用戶使用支援 Web 的 ApplicationContext 時,最後三個才可用。
spring bean 容器的生命週期是什麼樣的?
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?
只有將 bean 用作另一個 bean 的屬性時,才能將 bean 宣告為內部 bean。為了定義 bean,Spring 的基於 XML 的配置元資料在 或 中提供了 元素的使用。內部 bean 總是匿名的,它們總是作為原型。
例如,假設我們有一個 Student 類,其中引用了 Person 類。這裡我們將只建立一個 Person 類例項並在 Student 中使用它。
Student.java
public class Student { private Person person; //Setters and Getters } public class Person { private String name; private String address; //Setters and Getters } 複製程式碼
bean.xml
<bean id=“StudentBean" class="com.edureka.Student"> <property name="person"> <!--This is inner bean --> <bean class="com.edureka.Person"> <property name="name" value=“Scott"></property> <property name="address" value=“Bangalore"></property> </bean> </property> </bean> 複製程式碼
什麼是 spring 裝配
當 bean 在 Spring 容器中組合在一起時,它被稱為裝配或 bean 裝配。Spring 容器需要知道需要什麼 bean 以及容器應該如何使用依賴注入來將 bean 繫結在一起,同時裝配 bean。
自動裝配有哪些方式?
Spring 容器能夠自動裝配 bean。也就是說,可以通過檢查 BeanFactory 的內容讓 Spring 自動解析 bean 的協作者。
自動裝配的不同模式:
- no - 這是預設設定,表示沒有自動裝配。應使用顯式 bean 引用進行裝配。
- byName - 它根據 bean 的名稱注入物件依賴項。它匹配並裝配其屬性與 XML 檔案中由相同名稱定義的 bean。
- byType - 它根據型別注入物件依賴項。如果屬性的型別與 XML 檔案中的一個 bean 名稱匹配,則匹配並裝配屬性。
- 建構函式 - 它通過呼叫類的建構函式來注入依賴項。它有大量的引數。
- autodetect - 首先容器嘗試通過建構函式使用 autowire 裝配,如果不能,則嘗試通過 byType 自動裝配。
自動裝配有什麼侷限?
- 覆蓋的可能性 - 您始終可以使用 和 設定指定依賴項,這將覆蓋自動裝配。
- 基本元資料型別 - 簡單屬性(如原資料型別,字串和類)無法自動裝配。
- 令人困惑的性質 - 總是喜歡使用明確的裝配,因為自動裝配不太精確。
註解
你用過哪些重要的 Spring 註解?
- @Controller - 用於 Spring MVC 專案中的控制器類。
- @Service - 用於服務類。
- @RequestMapping - 用於在控制器處理程式方法中配置 URI 對映。
- @ResponseBody - 用於傳送 Object 作為響應,通常用於傳送 XML 或 JSON 資料作為響應。
- @PathVariable - 用於將動態值從 URI 對映到處理程式方法引數。
- @Autowired - 用於在 spring bean 中自動裝配依賴項。
- @Qualifier - 使用 @Autowired 註解,以避免在存在多個 bean 型別例項時出現混淆。
- @Scope - 用於配置 spring bean 的範圍。
- @Configuration,@ComponentScan和@Bean - 用於基於 java 的配置。
- @Aspect,@Before,@After,@Around,@Pointcut - 用於切面程式設計(AOP)。
如何在 spring 中啟動註解裝配?
預設情況下,Spring 容器中未開啟註解裝配。因此,要使用基於註解裝配,我們必須通過配置<context:annotation-config /> 元素在 Spring 配置檔案中啟用它。
@Component, @Controller, @Repository, @Service 有何區別?
- @Component:這將 java 類標記為 bean。它是任何 Spring 管理元件的通用構造型。spring * 的元件掃描機制現在可以將其拾取並將其拉入應用程式環境中。
- @Controller:這將一個類標記為 Spring Web MVC 控制器。標有它的 Bean 會自動匯入到 IoC 容器中。
- @Service:此註解是元件註解的特化。它不會對 @Component 註解提供任何其他行為。您可以在服務層類中使用 @Service 而不是 @Component,因為它以更好的方式指定了意圖。
- @Repository:這個註解是具有類似用途和功能的 @Component 註解的特化。它為 DAO 提供了額外的好處。它將 DAO 匯入 IoC 容器,並使未經檢查的異常有資格轉換為 Spring DataAccessException。
@Required 註解有什麼用?
@Required 應用於 bean 屬性 setter 方法。此註解僅指示必須在配置時使用 bean 定義中的顯式屬性值或使用自動裝配填充受影響的 bean 屬性。如果尚未填充受影響的 bean 屬性,則容器將丟擲 BeanInitializationException。
示例:
public class Employee { private String name; @Required public void setName(String name){ this.name=name; } public string getName(){ return name; } } 複製程式碼
@Autowired 註解有什麼用?
@Autowired 可以更準確地控制應該在何處以及如何進行自動裝配。此註解用於在 setter 方法,建構函式,具有任意名稱或多個引數的屬性或方法上自動裝配 bean。預設情況下,它是型別驅動的注入。
public class Employee { private String name; @Autowired public void setName(String name) { this.name=name; } public string getName(){ return name; } } 複製程式碼
@Qualifier 註解有什麼用?
當您建立多個相同型別的 bean 並希望僅使用屬性裝配其中一個 bean 時,您可以使用@Qualifier 註解和 @Autowired 通過指定應該裝配哪個確切的 bean 來消除歧義。
例如,這裡我們分別有兩個類,Employee 和 EmpAccount。在 EmpAccount 中,使用@Qualifier 指定了必須裝配 id 為 emp1 的 bean。
Employee.java
public class Employee { private String name; @Autowired public void setName(String name) { this.name=name; } public string getName() { return name; } } 複製程式碼
EmpAccount.java
public class EmpAccount { private Employee emp; @Autowired @Qualifier(emp1) public void showName() { System.out.println(“Employee name : ”+emp.getName); } } 複製程式碼
@RequestMapping 註解有什麼用?
@RequestMapping 註解用於將特定HTTP請求方法對映到將處理相應請求的控制器中的特定類/方法。此註解可應用於兩個級別:
- 類級別:對映請求的 URL
- 方法級別:對映 URL 以及 HTTP 請求方法