Spring Boot 面試,一個問題就幹趴下了!

純潔的微笑發表於2019-08-01

Spring Boot 面試,一個問題就幹趴下了!

隨著 Spring Boot 使用越來越廣泛,Spring Boot 已經成為 Java 程式設計師面試的知識點,很多同學對 Spring Boot 理解不是那麼深刻,經常就會被幾個連環跑給幹趴下了!

比如下面這一段的 Spring Boot 問答:

問:你覺得 Spring Boot 最大的優勢是什麼呢?

答:Spring Boot 的最大的優勢是“約定優於配置“。“約定優於配置“是一種軟體設計正規化,開發人員按照約定的方式來進行程式設計,可以減少軟體開發人員需做決定的數量,獲得簡單的好處,而又不失靈活性。

問:Spring Boot 中 “約定優於配置“的具體產品體現在哪裡。

答:Spring Boot Starter、Spring Boot Jpa 都是“約定優於配置“的一種體現。都是透過“約定優於配置“的設計思路來設計的,Spring Boot Starter 在啟動的過程中會根據約定的資訊對資源進行初始化;Spring Boot Jpa 透過約定的方式來自動生成 Sql ,避免大量無效程式碼編寫。具體詳細可以參考:Spring Boot 為什麼這麼火?

問:Spring Boot Starter 的工作原理是什麼?

答:Spring Boot  在啟動的時候會幹這幾件事情:

  1. Spring Boot 在啟動時會去依賴的 Starter 包中尋找 resources/META-INF/spring.factories 檔案,然後根據檔案中配置的 Jar 包去掃描專案所依賴的 Jar 包。

  2. 根據 spring.factories 配置載入 AutoConfigure 類

  3. 根據 @Conditional 註解的條件,進行自動配置並將 Bean 注入 Spring Context

總結一下,其實就是 Spring Boot 在啟動的時候,按照約定去讀取 Spring Boot Starter 的配置資訊,再根據配置資訊對資源進行初始化,並注入到 Spring 容器中。這樣 Spring Boot 啟動完畢後,就已經準備好了一切資源,使用過程中直接注入對應 Bean 資源即可。

這只是簡單的三連環問答,不知道有多少同學能夠完整的回答出來。

其實 Spring Boot 中有很多的技術點可以挖掘,今天給大家整理了十個高頻 Spring Boot 面試題,希望可以在後期的面試中幫助到大家。

一、Spring Boot 的自動配置是如何實現的?

Spring Boot 專案的啟動註解是:@SpringBootApplication,其實它就是由下面三個註解組成的:

  • @Configuration

  • @ComponentScan

  • @EnableAutoConfiguration

其中 @EnableAutoConfiguration 是實現自動配置的入口,該註解又透過 @Import 註解匯入了AutoConfigurationImportSelector,在該類中載入 META-INF/spring.factories 的配置資訊。然後篩選出以 EnableAutoConfiguration 為 key 的資料,載入到 IOC 容器中,實現自動配置功能!

二、什麼是嵌入式伺服器?我們為什麼要使用嵌入式伺服器呢?

思考一下在你的虛擬機器上部署應用程式需要些什麼。

第一步:安裝 Java

第二部:安裝 Web 或者是應用程式的伺服器(Tomat/Wbesphere/Weblogic 等等)

第三部:部署應用程式 war 包

如果我們想簡化這些步驟,應該如何做呢?

讓我們來思考如何使伺服器成為應用程式的一部分?

你只需要一個安裝了 Java 的虛擬機器,就可以直接在上面部署應用程式了,

是不是很爽?

這個想法是嵌入式伺服器的起源。

當我們建立一個可以部署的應用程式的時候,我們將會把伺服器(例如,tomcat)嵌入到可部署的伺服器中。

例如,對於一個 Spring Boot 應用程式來說,你可以生成一個包含 Embedded Tomcat 的應用程式 jar。你就可以像執行正常 Java 應用程式一樣來執行 web 應用程式了。

嵌入式伺服器就是我們的可執行單元包含伺服器的二進位制檔案(例如,tomcat.jar)。

三、微服務同時呼叫多個介面,怎麼支援事務的啊?

支援分散式事務,可以使用Spring Boot整合 Aatomikos來解決,但是我一般不建議這樣使用,因為使用分散式事務會增加請求的響應時間,影響系統的TPS。一般在實際工作中,會利用訊息的補償機制來處理分散式的事務。

四、shiro和oauth還有cas他們之間的關係是什麼?問下您公司許可權是如何設計,還有就是這幾個概念的區別。

cas和oauth是一個解決單點登入的元件,shiro主要是負責許可權安全方面的工作,所以功能點不一致。但往往需要單點登陸和許可權控制一起來使用,所以就有 cas+shiro或者oauth+shiro這樣的組合。

token一般是客戶端登入後服務端生成的令牌,每次訪問服務端會進行校驗,一般儲存到記憶體即可,也可以放到其他介質;redis可以做Session共享,如果前端web伺服器有幾臺負載,但是需要保持使用者登入的狀態,這場景使用比較常見。

我們公司使用oauth+shiro這樣的方式來做後臺許可權的管理,oauth負責多後臺統一登入認證,shiro負責給登入使用者賦予不同的訪問許可權。

五、各服務之間通訊,對Restful和Rpc這2種方式如何做選擇?

在傳統的SOA治理中,使用rpc的居多;Spring Cloud預設使用restful進行服務之間的通訊。rpc通訊效率會比restful要高一些,但是對於大多數公司來講,這點效率影響甚微。我建議使用restful這種方式,易於在不同語言實現的服務之間通訊。

六、怎麼設計無狀態服務?

對於無狀態服務,首先說一下什麼是狀態:如果一個資料需要被多個服務共享,才能完成一筆交易,那麼這個資料被稱為狀態。進而依賴這個“狀態”資料的服務被稱為有狀態服務,反之稱為無狀態服務。

那麼這個無狀態服務原則並不是說在微服務架構裡就不允許存在狀態,表達的真實意思是要把有狀態的業務服務改變為無狀態的計算類服務,那麼狀態資料也就相應的遷移到對應的“有狀態資料服務”中。

場景說明:例如我們以前在本地記憶體中建立的資料快取、Session快取,到現在的微服務架構中就應該把這些資料遷移到分散式快取中儲存,讓業務服務變成一個無狀態的計算節點。遷移後,就可以做到按需動態伸縮,微服務應用在執行時動態增刪節點,就不再需要考慮快取資料如何同步的問題。

七、Spring Cache 三種常用的快取註解和意義?

  • @Cacheable ,用來宣告方法是可快取,將結果儲存到快取中以便後續使用相同引數呼叫時不需執行實際的方法,直接從快取中取值。

  • @CachePut,使用 @CachePut 標註的方法在執行前,不會去檢查快取中是否存在之前執行過的結果,而是每次都會執行該方法,並將執行結果以鍵值對的形式存入指定的快取中。

  • @CacheEvict,是用來標註在需要清除快取元素的方法或類上的,當標記在一個類上時表示其中所有的方法的執行都會觸發快取的清除操作。

八、Spring Boot 如何設定支援跨域請求?

現代瀏覽器出於安全的考慮, HTTP 請求時必須遵守同源策略,否則就是跨域的 HTTP 請求,預設情況下是被禁止的,IP(域名)不同、或者埠不同、協議不同(比如 HTTP、HTTPS)都會造成跨域問題。

一般前端的解決方案有:

  1. 使用 JSONP 來支援跨域的請求,JSONP 實現跨域請求的原理簡單的說,就是動態建立<script>標籤,然後利用<script>的 SRC 不受同源策略約束來跨域獲取資料。缺點是需要後端配合輸出特定的返回資訊。

  2. 利用反應代理的機制來解決跨域的問題,前端請求的時候先將請求傳送到同源地址的後端,透過後端請求轉發來避免跨域的訪問。

後來 HTML5 支援了 CORS 協議。CORS 是一個 W3C 標準,全稱是”跨域資源共享”(Cross-origin resource sharing),允許瀏覽器向跨源伺服器,發出 XMLHttpRequest 請求,從而克服了 AJAX 只能同源使用的限制。它透過伺服器增加一個特殊的 Header[Access-Control-Allow-Origin]來告訴客戶端跨域的限制,如果瀏覽器支援 CORS、並且判斷 Origin 透過的話,就會允許 XMLHttpRequest 發起跨域請求。

前端使用了 CORS 協議,就需要後端設定支援非同源的請求,Spring Boot 設定支援非同源的請求有兩種方式。

第一,配置 CorsFilter。

@Configuration
public class GlobalCorsConfig {
    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
          config.addAllowedOrigin("*");
          config.setAllowCredentials(true);
          config.addAllowedMethod("*");
          config.addAllowedHeader("*");
          config.addExposedHeader("*");

        UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
        configSource.registerCorsConfiguration("/**", config);

        return new CorsFilter(configSource);
    }
}

需要配置上述的一段程式碼。第二種方式稍微簡單一些。

第二,在啟動類上新增:

public class Application extends WebMvcConfigurerAdapter {  

    @Override  
    public void addCorsMappings(CorsRegistry registry) {  

        registry.addMapping("/**")  
                .allowCredentials(true)  
                .allowedHeaders("*")  
                .allowedOrigins("*")  
                .allowedMethods("*");  

    }  
}  

九、JPA 和 Hibernate 有哪些區別?JPA 可以支援動態 SQL 嗎?

JPA本身是一種規範,它的本質是一種ORM規範(不是ORM框架,因為JPA並未提供ORM實現,只是制定了規範)因為JPA是一種規範,所以,只是提供了一些相關的介面,但是介面並不能直接使用,JPA底層需要某種JPA實現,Hibernate 是 JPA 的一個實現集。

JPA 是根據實體類的註解來建立對應的表和欄位,如果需要動態建立表或者欄位,需要動態構建對應的實體類,再重新呼叫Jpa重新整理整個Entity。動態SQL,mybatis支援的最好,jpa也可以支援,但是沒有Mybatis那麼靈活。

十、Spring 、Spring Boot 和 Spring Cloud 的關係?

Spring 最初最核心的兩大核心功能 Spring Ioc 和 Spring Aop 成就了 Spring,Spring 在這兩大核心的功能上不斷的發展,才有了 Spring 事務、Spring Mvc 等一系列偉大的產品,最終成就了 Spring 帝國,到了後期 Spring 幾乎可以解決企業開發中的所有問題。

Spring Boot 是在強大的 Spring 帝國生態基礎上面發展而來,發明 Spring Boot 不是為了取代 Spring ,是為了讓人們更容易的使用 Spring 。

Spring Cloud 是一系列框架的有序集合。它利用 Spring Boot 的開發便利性巧妙地簡化了分散式系統基礎設施的開發,如服務發現註冊、配置中心、訊息匯流排、負載均衡、斷路器、資料監控等,都可以用 Spring Boot 的開發風格做到一鍵啟動和部署。

Spring Cloud 是為了解決微服務架構中服務治理而提供的一系列功能的開發框架,並且 Spring Cloud 是完全基於 Spring Boot 而開發,Spring Cloud 利用 Spring Boot 特性整合了開源行業中優秀的元件,整體對外提供了一套在微服務架構中服務治理的解決方案。

用一組不太合理的包含關係來表達它們之間的關係。

Spring ioc/aop > Spring > Spring Boot > Spring Cloud

參考公號Java技術棧同名文章

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31499124/viewspace-2651183/,如需轉載,請註明出處,否則將追究法律責任。

相關文章