Java程序員9月面試季良心推薦——開源框架面試專題及答案

Java程序員9月面試季良心推薦——開源框架面試專題及答案

BeanFactory 和 ApplicationContext 有什麼區別

> BeanFactory 可以理解為含有 bean 集合的工廠類。BeanFactory 包含了種 bean 的定義, 以便在接收到客戶端請求時將對應的 bean 實例化。

> BeanFactory 還能在實例化對象的時生成協作類之間的關係。此舉將 bean 自身與 bean 客 戶端的配置中解放出來。BeanFactory 還包含了 bean 生命週期的控制,調用客戶端的初始化方法(initialization methods)和銷燬方法(destruction methods)。

> 從表面上看,application context 如同 bean factory 一樣具有 bean 定義、bean 關聯關係的設置,根據請求分發 bean 的功能。但 application context 在此基礎上還提供了其他的功能。

> 提供了支持國際化的文本消息

> 統一的資源文件讀取方式

> 已在監聽器中註冊的 bean 的事件

Spring Bean 的生命週期

> Spring Bean 的生命週期簡單易懂。在一個 bean 實例被初始化時,需要執行一系列的初始化操作以達到可用的狀態。同樣的,當一個 bean 不在被調用時需要進行相關的析構操作,並從 bean 容器中移除。

> Spring bean factory 負責管理在 spring 容器中被創建的 bean 的生命週期。Bean 的生命週期由兩組回調(call back)方法組成。

> 初始化之後調用的回調方法。

> 銷燬之前調用的回調方法。

> Spring 框架提供了以下四種方式來管理 bean 的生命週期事件:

> InitializingBean 和 DisposableBean 回調接口

> 針對特殊行為的其他 Aware 接口

> Bean 配置文件中的 Custom init()方法和 destroy()方法

> @PostConstruct 和@PreDestroy 註解方式

Spring IOC 如何實現

> Spring 中的 org.springframework.beans 包和 org.springframework.context 包構成了Spring 框架 IoC 容器的基礎。

> BeanFactory 接口提供了一個先進的配置機制,使得任何類型的對象的配置成為可能。 ApplicationContex 接口對 BeanFactory(是一個子接口)進行了擴展,在 BeanFactory 的 基礎上添加了其他功能,比如與 Spring 的 AOP 更容易集成,也提供了處理 message resource 的機制(用於國際化)、事件傳播以及應用層的特別配置,比如針對 Web 應用的 WebApplicationContext。

> org.springframework.beans.factory.BeanFactory 是 Spring IoC 容器的具體實現,用來包裝和管理前面提到的各種 bean。BeanFactory 接口是 Spring IoC 容器的核心接口。

說說 Spring AOP

> 面向切面編程,在我們的應用中,經常需要做一些事情,但是這些事情與核心業務無關,比如,要記錄所有 update*方法的執行時間時間,操作人等等信息,記錄到日誌,

> 通過 spring 的 AOP 技術,就可以在不修改 update*的代碼的情況下完成該需求。

Spring AOP 實現原理

> Spring AOP 中的動態代理主要有兩種方式,JDK 動態代理和 CGLIB 動態代理。JDK 動態代理通過反射來接收被代理的類,並且要求被代理的類必須實現一個接口。JDK 動態代理的核心是 InvocationHandler 接口和 Proxy 類。

> 如果目標類沒有實現接口,那麼 Spring AOP 會選擇使用 CGLIB 來動態代理目標類CGLIB (Code Generation Library),是一個代碼生成的類庫,可以在運行時動態的生成某個類的子類,注意,CGLIB 是通過繼承的方式做的動態代理,因此如果某個類被標記為 final,那麼它是無法使用 CGLIB 做動態代理的。

動態代理(cglib 與 JDK)

> JDK 動態代理類和委託類需要都實現同一個接口。也就是說只有實現了某個接口的類可以使用 Java 動態代理機制。但是,事實上使用中並不是遇到的所有類都會給你實現一個接口。因此,對於沒有實現接口的類,就不能使用該機制。而 CGLIB 則可以實現對類的動態代理。

Spring 事務實現方式

> 1、編碼方式

> 所謂編程式事務指的是通過編碼方式實現事務,即類似於 JDBC 編程實現事務管理。

> 聲明式事務管理又有兩種實現方式:基於 xml 配置文件的方式;另一個實在業務方法上進行@Transaction 註解,將事務規則應用到業務邏輯中

Spring 事務底層原理

> a、劃分處理單元——IOC

>由於 spring 解決的問題是對單個數據庫進行局部事務處理的,具體的實現首相用 spring中的 IOC 劃分了事務處理單元。並且將對事務的各種配置放到了 ioc 容器中(設置事務管理器,設置事務的傳播特性及隔離機制)。

> b、AOP 攔截需要進行事務處理的類

> Spring 事務處理模塊是通過 AOP 功能來實現聲明式事務處理的,具體操作(比如事務實行的配置和讀取,事務對象的抽象),用 TransactionProxyFactoryBean 接口來使用 AOP功能,生成 proxy 代理對象,通過 TransactionInterceptor 完成對代理方法的攔截,將事務處理的功能編織到攔截的方法中。讀取 ioc 容器事務配置屬性,轉化為 spring 事務處理需要的內部數據結構(TransactionAttributeSourceAdvisor),轉化為TransactionAttribute 表示的數據對象。

> c、對事物處理實現(事務的生成、提交、回滾、掛起)

> spring 委託給具體的事務處理器實現。實現了一個抽象和適配。適配的具體事務處理器:DataSource 數據源支持、hibernate 數據源事務處理支持、JDO 數據源事務處理支持,JPA、JTA 數據源事務處理支持。這些支持都是通過設計PlatformTransactionManager、AbstractPlatforTransaction 一系列事務處理的支持。 為常用數據源支持提供了一系列的 TransactionManager。

> d、結合

> PlatformTransactionManager 實現了 TransactionInterception 接口,讓其與TransactionProxyFactoryBean 結合起來,形成一個 Spring 聲明式事務處理的設計體系。

如何自定義註解實現功能

> 創建自定義註解和創建一個接口相似,但是註解的 interface 關鍵字需要以@符號開頭。

> 註解方法不能帶有參數;

> 註解方法返回值類型限定為:基本類型、String、Enums、Annotation 或者是這些類型的數組;

> 註解方法可以有默認值;

> 註解本身能夠包含元註解,元註解被用來註解其它註解。

Spring MVC 運行流程

> 1.spring mvc 將所有的請求都提交給 DispatcherServlet,它會委託應用系統的其他模塊負責對請求 進行真正的處理工作。

> 2.DispatcherServlet 查詢一個或多個 HandlerMapping,找到處理請求的 Controller.

> 3.DispatcherServlet 請請求提交到目標 Controller

> 4.Controller 進行業務邏輯處理後,會返回一個 ModelAndView

> 5.Dispathcher 查詢一個或多個 ViewResolver 視圖解析器,找到 ModelAndView 對象指定 的視圖對象

> 6.視圖對象負責渲染返回給客戶端。

Spring MVC 啟動流程

> 在 web.xml 文件中給 Spring MVC 的 Servlet 配置了 load-on-startup,所以程序啟動的

> 時候會初始化 Spring MVC,在 HttpServletBean 中將配置的 contextConfigLocation

> 屬性設置到 Servlet 中,然後在 FrameworkServlet 中創建了 WebApplicationContext,

> DispatcherServlet 根據 contextConfigLocation 配置的 classpath 下的 xml 文件初始化 了

> Spring MVC 總的組件。

Spring 的單例實現原理

> Spring 對 Bean 實例的創建是採用單例註冊表的方式進行實現的,而這個註冊表的緩存是 ConcurrentHashMap 對象。

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

> 代理模式—在 AOP 和 remoting 中被用的比較多。

> 單例模式—在 spring 配置文件中定義的 bean 默認為單例模式。

> 模板方法—用來解決代碼重複的問題。比如. RestTemplate, JmsTemplate, JpaTemplate。

> 前端控制器—Spring 提供了 DispatcherServlet 來對請求進行分發。

> 視圖幫助(View Helper )—Spring 提供了一系列的 JSP 標籤,高效宏來輔助將分散的代碼整合在視圖裡。

> 依賴注入—貫穿於 BeanFactory / ApplicationContext 接口的核心理念。

> 工廠模式—BeanFactory 用來創建對象的實例。

Netty

為什麼選擇 Netty

> 1) API 使用簡單,開發門檻低;

> 2) 功能強大,預置了多種編解碼功能,支持多種主流協議;

> 3) 定製能力強,可以通過 ChannelHandler 對通信框架進行靈活的擴展;

> 4) 性能高,通過與其它業界主流的 NIO 框架對比,Netty 的綜合性能最優;

> 5) 成熟、穩定,Netty 修復了已經發現的所有 JDK NIO BUG,業務開發人員不需要再為NIO 的 BUG 而煩惱;

> 6) 社區活躍,版本迭代週期短,發現的 BUG 可以被及時修復,同時,更多的新功能會被加入;

> 7) 經歷了大規模的商業應用考驗,質量已經得到驗證。在互聯網、大數據、網絡遊戲、企業應用、電信軟件等眾多行業得到成功商用,證明了它可以完全滿足不同行業的商業應用。

> 正是因為這些優點,Netty 逐漸成為 Java NIO 編程的首選框架。

說說業務中,Netty 的使用場景

> 構建高性能、低時延的各種 Java 中間件,例如 MQ、分佈式服務框架、ESB 消息總線等,Netty 主要作為基礎通信框架提供高性能、低時延的通信服務;

> 公有或者私有協議棧的基礎通信框架,例如可以基於 Netty 構建異步、高性能WebSocket 協議棧;

> 各領域應用,例如大數據、遊戲等,Netty 作為高性能的通信框架用於內部各模塊的數據分發、傳輸和彙總等,實現模塊之間高性能通信。原生的 NIO 在 JDK 1.7 版本存在 epoll bug

> 它會導致 Selector 空輪詢,最終導致 CPU 100%。官方聲稱在 JDK 1.6 版本的 update18 修復了該問題,但是直到 JDK 1.7 版本該問題仍舊存在,只不過該 BUG 發生概率降低了一些而已,它並沒有得到根本性解決。

什麼是 TCP 粘包/拆包

> 1、要發送的數據大於 TCP 發送緩衝區剩餘空間大小,將會發生拆包。

> 2、待發送數據大於 MSS(最大報文長度),TCP 在傳輸前將進行拆包。

> 3、要發送的數據小於 TCP 發送緩衝區的大小,TCP 將多次寫入緩衝區的數據一次發送出去,將會發生粘包。

> 4、接收數據端的應用層沒有及時讀取接收緩衝區中的數據,將發生粘包。

TCP 粘包/拆包的解決辦法

> 1、發送端給每個數據包添加包首部,首部中應該至少包含數據包的長度,這樣接收端在接收到數據後,通過讀取包首部的長度字段,便知道每一個數據包的實際長度了。

> 2、發送端將每個數據包封裝為固定長度(不夠的可以通過補 0 填充),這樣接收端每次從接收緩衝區中讀取固定長度的數據就自然而然的把每個數據包拆分開來。

> 3、可以在數據包之間設置邊界,如添加特殊符號,這樣,接收端通過這個邊界就可以將不同的數據包拆分開。

Netty 線程模型

> 首先,Netty 使用 EventLoop 來處理連接上的讀寫事件,而一個連接上的所有請求都保證在一個 EventLoop 中被處理,一個 EventLoop 中只有一個 Thread,所以也就實現了一個連接上的所有事件只會在一個線程中被執行。一個 EventLoopGroup 包含多個 EventLoop,可 以把一個 EventLoop 當做是 Reactor 線程模型中的一個線程,而一個 EventLoopGroup 類似於一個 ExecutorService

說說 Netty 的零拷貝

> “零拷貝”是指計算機操作的過程中,CPU 不需要為數據在內存之間的拷貝消耗資源。而它通常是指計算機在網絡上發送文件時,不需要將文件內容拷貝到用戶空間(User Space)而直接在內核空間(Kernel Space)中傳輸到網絡的方式。

Netty 內部執行流程

> 1. Netty 的接收和發送 ByteBuffer 採用 DIRECT BUFFERS,使用堆外直接內存進行Socket 讀寫,不需要進行字節緩衝區的二次拷貝。如果使用傳統的堆內存(HEAP BUFFERS)進行 Socket 讀寫,JVM 會將堆內存 Buffer 拷貝一份到直接內存中,然後才寫入Socket 中。相比於堆外直接內存,消息在發送過程中多了一次緩衝區的內存拷貝。

> 2. Netty 提供了組合 Buffer 對象,可以聚合多個 ByteBuffer 對象,用戶可以像操作一個 Buffer 那樣方便的對組合 Buffer 進行操作,避免了傳統通過內存拷貝的方式將幾個小Buffer 合併成一個大的 Buffer。

> 3. Netty 的文件傳輸採用了 transferTo 方法,它可以直接將文件緩衝區的數據發送到

最後

關注我+私信【資料】,免費獲取最新整理的資料。

部分截圖如下:

Java程序員9月面試季良心推薦——開源框架面試專題及答案


分享到:


相關文章: