面試題-Spring和Springboot框架


前言

spring框架部分的題目,是我根據Java Guide的面試突擊版本V3.0再整理出來的,其中,我選擇了一些比較重要的問題,並重新做出相應回答,並添加了一些比較重要的問題,希望對大家起到一定的幫助。

系列文章:

面試題-Java基礎

面試題-Java集合

面試題-Java多線程基礎、實現工具和可見性保證

面試題-線程池和原子變量

面試題-Java虛擬機

面試題-計算機網絡1

面試題-計算機網絡-HTTP部分


Spring框架

  1. 什么是 Spring 框架?

    Spring是一種輕量級開發框架,旨在提高開發人員的開發效率以及系統的可維護性。我們說的Spring框架是很多模塊的集合,包括核心容器,數據訪問集成,web,AOP等等。

  2. @RestController vs @Controller和區別?

    單獨使用Controller時,適用於前后端不分離的應用,Controller返回一個model and view。

    RestController將返回數據寫入ResponseBody中,Controller+ResponseBody注解一起用和RestController是一樣的功能。

  3. 簡單說說你對IOC的理解

    IOC叫做控制反轉,控制反轉是一種設計思想,簡單來說就是,本來把程序員控制的流程交給框架控制,框架提供給程序員一些擴展點,程序員實現擴展點就可以方便的調用框架做需要的事情。

    SpringIoc容器是控制反轉設計思想的一種實現,程序員把管理對象生命周期的工作交給框架來做,通過配置文件或注解配置需要的對象,在使用的時候跟Spring容器要就可以了。

  4. 談談你對AOP的理解

    AOP是面向切面編程,通過把和業務無關,但是卻被很多業務模塊調用的系統功能封裝起來,減少系統的重復代碼,提高代碼的復用性並提高的系統的維護性。

    比如實際項目中,中間件組的web層代碼AOP框架規范是我制定的,統一處理異常,記錄日志等操作是放在這個AOP中的,具體用的是ControllerAdvice實現的。

  5. AOP的實現原理你了解嗎?簡單說說

    AOP的實現最核心的就是利用JDK的動態代理或者cglib實現,項目啟動時通過反射獲取相關的信息,在創建代理對象時,如果被代理對象實現了接口,就是用JDK動態代理,如果沒有實現接口,就使用cglib創建被代理對象的子類來實現代理。

  6. Spring的AOP和AspectJ的AOP有什么區別?

    二者都是AOP思想的實現,AspectJ的功能更加強大。

    • springAOP是基於運行時動態增強

    • AspectJ是編譯時操作字節碼增強,運行時更快

    項目中遇到無法使用Spring來管理對象這種情況時,就會考慮使用AspectJ來增強對象

  7. 為什么需要bean的作用域?

    spring容器需要管理對象的生命周期,spring通過scope作用域的概念給使用者對對象生命周期的更精細的控制。

  8. bean的作用域都有哪些?

    • singleton:單例,會一直存活直到容器關閉,spring默認的對象作用域是單例的
    • prototype:多實例,每次請求都會創建一個新的對象,交給使用方以后,spring就不負責管理對象的生命周期了
    • request:每次請求都創建一個實例,請求完畢后銷毀對象
    • session:每個session創建一個實例,session失效后銷毀對象實例
  9. Spring 中的單例 bean 的線程安全問題了解嗎?

    對單例bean的非靜態成員變量的讀寫會有線程安全問題。

    如果每個線程對成員變量的修改業務上沒有關聯,可以通過使用ThreadLocal來保存每個線程單獨的變量拷貝副本來實現線程安全。

  10. @Component 和 @Bean 的區別是什么?

    • 作用對象不同:component作用於類,bean作用於方法。
    • bean注解適用於引用第三方類庫的bean時使用,因為沒辦法使用component注解用於第三方類庫的源碼
  11. 將⼀個類聲明為Spring的 bean 的注解有哪些?

    • Component:通用注解
    • Service:Service層的注解
    • Controller:控制層的注解
    • Repository:DAO層的注解
  12. Spring 中的 bean ⽣命周期?

    • Spring先對bean進行實例化
    • Spring將值和引用注入到相關屬性中
    • 如果bean實現了相關的aware接口,spring就會調用set方法把相關需求的實例注入到bean中
    • 如果實現了 beanpostProcessor接口,會調用before方法
    • 如果有postConstruct注解,會調用注解的方法
    • 如果實現了InitialingBean接口,會調用afterPropertiesSet方法
    • 如果指定了init-method,會調用init-method
    • 最后調用beanpostProcessor的after方法
    • 銷毀前,會調用DispoableBean的destory方法
    • 如果指定了destroy-method,調用這個方法
    • 最后調用 preConstruct注解修飾的方法

    流程圖如下:

  1. 你知道spring MVC的工作原理嗎?

    • DispatcherServlet接收用戶的請求后,根據請求向處理器映射器查詢具體處理器
    • 處理器映射器返回對應的處理器鏈返回給dispatherServlet
    • dispatcherServlet會將請求發送給具體的處理器,並等待處理
    • 處理器處理完畢后,會返回邏輯視圖名和模型給前端控制器
    • 前端控制器根據邏輯視圖名向視圖解析器解析具體的視圖
    • 最后視圖負責根據模型數據渲染頁面,並返回給客戶端
  2. MVC的注解都用過什么?

    • RestController:指定控制器
    • RequestMapping,負責編寫具體的url,指定post方法,並指定返回內容類型
    • RequestBody:接收通過body傳遞過來的JSONObject數據參數
    • ControllerAdvice和ExceptionHandler:負責controller的全局異常處理
  3. Spring 框架中⽤到了哪些設計模式?

    • 單例模式:spring的bean作用域默認是單例的
    • 代理模式:AOP就是代理模式的實現
    • 工廠模式:applicationContext就是對象工廠
    • 觀察者模式:spring的事件機制就是觀察者模式的一個典型應用
  4. Spring 管理事務的⽅式有⼏種?

    • 編程式事務:硬編碼
    • 聲明式事務:
      • 基於XML
      • 基於注解
  5. Spring事務的隔離級別都有哪些,如何設置?

    和MySQL中的事務隔離級別一樣,有四種隔離級別可以設置,還有一種是使用數據庫的默認隔離級別

    在transactional注解中設置isolation屬性即可

  6. Spring中事務的傳播機制有哪些?

    事務的傳播機制指的是,如果事務方法互相調用,事務應該如何傳播,具體分為三大類:

    • 支持當前事務的:如果有事務,加入當前事務
    • 不支持當前事務的:如果有事務,掛起或者拋出異常
    • 其他情況:嵌套事務,父事務回滾,子事務也會回滾

我們的具體業務中,相關聯的業務都寫在了同一個service方法中,所以不存在事務的傳播機制問題

如果需要拆分方法,那么需要根據具體業務邏輯具體分析使用哪種事務

事務的傳播機制

  1. @Transactional(rollbackFor = Exception.class)注解了解嗎?

    了解,如果不這么配置,那么事務只會在運行時異常的時候才會回滾,我們也需要cover到非運行時異常的情況。

  2. Spring是如何管理bean的?

    Spring會讀取配置文件或者注解定義的bean信息,實例化為一個BeanDefinition,存入到一個List 中,然后利用反射實例化對象,存入一個Map<String,Object>中

  3. Bean的生命周期中的擴展點都有哪些?

    • Spring實例化
    • 依賴注入
    • 各種XXAware接口,注入相關實例
    • BeanPostProcessor
    • InitializingBean
    • DisposableBean
  4. Spring常見的注入方式有哪些?

    • 構造函數
    • set方法
    • 注解注入
  5. Spring是如何解決循環依賴的問題的?

    什么是循環依賴?循環依賴分為兩種,一種是構造器依賴,這種JVM會報錯;另一種是屬性依賴。Spring解決的是屬性循環依賴。
    Spring是通過遞歸來實例化bean和它依賴的bean的,直到bean中沒有依賴就會返回,然后反遞歸層層設置上屬性。這里有個關鍵點,如果是循環依賴,就會把沒有真實完成的類注入到對應類中。

  6. 哪幾種情況會引起事務失效?

    • this引用方法
    • private或者protected

Springboot

  1. 什么是Springboot?

    Springboot簡化了使用Spring的難度,使開發者能快速上手,具體表現在:

    • 節省了繁重的配置
    • 提供了各種starter啟動器
  2. Spring Boot 的核心注解是哪個?它主要由哪幾個注解組成的?

    SpringbootApplicaition是Springboot的啟動類注解,也是核心注解,它是由下面三個注解組成的:

    • ComponentScan:組件掃描,將組件注冊到容器中
    • EnableAutoConfiguration:打開自動配置,根據類路徑中jar包是否存在來決定是否開啟某個默認配置,用exclude可以關閉某個默認配置
    • SpringBootConfiguration: 相當於Configuration,是一個配置類,會被ComponentScan注解掃描到
  3. 什么是 JavaConfig?

    JavaConfig是在 Spring 3.0 開始從一個獨立的項目並入到 Spring 中的,通過純Java方法來配置Springg容器,可以避免使用XML。

  4. Spring Boot 自動配置原理是什么?

    • Springboot啟動的時候會通過@EnableAutoConfiguration注解開啟自動配置,並找到META-INF/spring.factories中的所有自動配置類,並對其進行加載。
    • 自動配置類都是以AutoConfiguration結尾的,里面包含一個關鍵性注解EnableConfigurationProperties,這個注解可以把配置了ConfigurationProperties注解的類注入到容器中,這個類可以接收application.properties中配置的配置信息。
  5. YML配置文件的優勢在哪里?

    yml格式的配置文件有着可讀性更強的樹型結構,但是因為yml配置文件需要過多的考慮格式問題,我們項目組還是使用properties配置文件。

  6. Spring Boot 是否可以使用 XML 配置 ?

    可以使用,但是Springboot推薦使用java配置。如果一定要使用的話,可以使用@importResource注解引入一個XML配置

  7. 什么是 Spring Profiles?

    我們的環境分為開發驗證和生產環境,沒有profile的概念時,需要手動維護多個配置文件,然后進行替換,使用Profile時,可以定義單個配置文件,並定義名稱為application-dev.properties,application-verify.properties和application-prod.properties,在總配置文件中指定spring.active.profile為對應的配置文件后綴即可。同樣的道理,也可以基於Profile注解實現不同環境注入不同的bean到容器中。

  8. 如何重新加載 Spring Boot 上的更改,而無需重新啟動服務器?Spring Boot項目如何熱部署?

    使用spring-boot-devtools可以實現熱部署,具體操作時,需要在idea中開啟自動build項目選項,並在配置文件中增加熱部署相關的配置項,比如spring.devtools.restart.enabled設置為true。

  9. Spring Boot 中的 starter 到底是什么 ?

    starter的作用簡單來說有下面兩個:

    • 方便引入相關依賴
    • 自動配置各模塊需要的屬性,這里的原理和第四個問題,自動配置原理那個問題是一樣的
  10. spring-boot-starter-parent 有什么用 ?

    這個是springboot工程的父級依賴,我覺得最核心的就是定義了各種版本號,這樣我們在自己的項目中就不需要寫版本號了。其他的功能還有比如默認使用Java8,使用UTF-8編碼等等。

  11. 不適用spring-boot-starter-parent,如果創建springboot項目?

    一般來說,這種場景可能出現在該模塊已經有了一個父模塊存在,無法再引入parent,這種場景下可以在父模塊中使用dependacyManagement來實現引入sprintboot

  12. Spring Boot 打成的 jar 和普通的 jar 有什么區別 ?

    boot打成的jar不能作為普通的jar被其他項目引用,因為普通可引用的jar解壓后就是包名,而Springboot的jar是放在Boot-INF/classes下的。如果一定要引用,那么也可以在pom文件中增加配置,將springboot打成兩個jar,一個可執行,一個可引用。SpringBoot打包可執行可依賴的jar包

  13. 運行 Spring Boot 有哪幾種方式?

    • 打jar包用java命令或者打war包用容器執行
    • main方法直接執行
    • maven的插件也可以運行: mvn spring-boot:run
  14. 讓你寫個starter 你會怎么寫?

    • 編寫自己的Properties配置類和需要提供的核心服務類XXService
    • 編寫AutoConfig類。
      • 通過EnableAutoConfiguration開啟自動配置並且注入Properties類的實例;通過@Bean注冊核心服務類到容器中,構造函數相關參數就是Properties類中提供的
      • 通過Condition類控制相關的條件
    • 在META-INF/spring.factories文件,里面寫入key為一個特別長的配置,value為AutoConfig類的全路徑名
      參考資料


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM