一. Spring
1. 談談你對Spring的理解
關鍵點面試
- 企業框架,目前最流行,沒有之一
- AOP、IOC、Spring MVC
2. Spring中用到了哪些設計模式
- 工廠模式,好比 BeanFactory
- 代理模式,在Aop實現中用到了JDK的動態代理
- 單例模式,Bean的建立默認就是單利的
3. IoC的啓動過程
- Resource文件的定位,即找到bean的配置文件
- 經過特定的reader解析該bean配置文件,抽象成beanDefinition類
- 將beanDefinition向容器註冊,寫入到一個大的HashMap中
4. BeanFactory 和 ApplicationContext 區別
- 功能,BeanFactory負責讀取bean配置,管理bean的加載,實例化,維護bean之間的依賴關係,負責bean的聲明週期;ApplicationContext除了提供上述BeanFactory所能提供的功能以外,還提供了國際化支持、資源訪問、事件傳遞、隊Web的支持等功能
- BeanFactroy採用的是延遲加載形式來注入Bean的,即只有在使用到某個Bean時(調用getBean()),纔對該Bean進行加載實例化;而ApplicationContext則相反,它是在容器啓動時,一次性建立了全部的Bean。
- BeanFactory和ApplicationContext都支持BeanPostProcessor、BeanFactoryPostProcessor的使用,但二者之間的區別是:BeanFactory須要手動註冊,而ApplicationContext則是自動註冊
5. Bean 的生命週期
- 實例化一個Bean,也就是咱們一般說的new
- 按照Spring上下文對實例化的Bean進行配置,也就是IOC注入
- 若是這個Bean實現了BeanNameAware接口,會調用它實現的setBeanName(String beanId)方法,此處傳遞的是Spring配置文件中Bean的ID
- 若是這個Bean實現了BeanFactoryAware接口,會調用它實現的setBeanFactory(),傳遞的是Spring工廠自己(能夠用這個方法獲取到其餘Bean)
- 若是這個Bean實現了ApplicationContextAware接口,會調用setApplicationContext(ApplicationContext)方法,傳入Spring上下文,該方式一樣能夠實現步驟4,但比4更好,覺得ApplicationContext是BeanFactory的子接口,有更多的實現方法
- 若是這個Bean關聯了BeanPostProcessor接口,將會調用postProcessBeforeInitialization(Object obj, String s)方法,BeanPostProcessor常常被用做是Bean內容的更改,而且因爲這個是在Bean初始化結束時調用After方法,也可用於內存或緩存技術
- 若是這個Bean在Spring配置文件中配置了init-method屬性會自動調用其配置的初始化方法
- 若是這個Bean關聯了BeanPostProcessor接口,將會調用postAfterInitialization(Object obj, String s)方法 注意:以上工做完成之後就能夠用這個Bean了,那這個Bean是一個single的,因此通常狀況下咱們調用同一個ID的Bean會是在內容地址相同的實例
- 當Bean再也不須要時,會通過清理階段,若是Bean實現了DisposableBean接口,會調用其實現的destroy方法
- 最後,若是這個Bean的Spring配置中配置了destroy-method屬性,會自動調用其配置的銷燬方法
6. Bean的做用域
- singleton(默認): 在Spring的IoC容器中只存在一個對象實例,全部該對象的引用都共享這個實例。Spring 容器只會建立該bean定義的惟一實例,這個實例會被保存到緩存中,而且對該bean的全部後續請求和引用都將返回該緩存中的對象實例,通常狀況下,無狀態的bean使用該scope。
- prototype:每次對該bean的請求都會建立一個新的實例,通常狀況下,有狀態的bean使用該scope。
- request:每次http請求將會有各自的bean實例,相似於prototype。
- session:在一個http session中,一個bean定義對應一個bean實例。
- global session:在一個全局的http session中,一個bean定義對應一個bean實例。典型狀況下,僅在使用portlet context的時候有效。
7. AOP
實現原理:默認,接口基於JDK動態代理,類爲cglib算法
注意事項sql
- 嵌套失效問題
- final類直接報錯問題(動態代理的實現原理)
8. Spring MVC
請求過程設計模式
- 用戶請求DispatchServlet
- DispatchServlet根據請求路徑調用具體HandlerMapping返回一個HandlerExcutionChain
- DispatchServlet調用HandlerAdapter適配器
- HandlerAdapter調用具體的Handler處理業務
- Handler處理結束返回一個具體的ModelAndView給適配器
- 適配器將ModelAndView給DispatchServlet
- DispatchServlet把視圖名稱給ViewResolver視圖解析器
- ViewResolver返回一個具體的視圖給DispatchServlet
- 渲染視圖,展現給用戶
二. JVM
1. 內存劃分
JVM規範,將內存分爲 程序計數器、Java棧,也叫虛擬機棧、本地方法棧、方法區、堆緩存
- 程序計數器 程序指令保存,從當前指令到下一個指令,從程序計數器獲取下一個指令的地址,直到執行全部的指令;線程私有
- Java棧(虛擬機棧) 保存方法棧幀,當調用一個方法,則新建立一個棧幀,當前的方法始終保持在棧幀的頂部;線程私有
- 本地方法棧 保存本地方法棧幀,當調用一個本地方法,則新建立一個棧幀,當前的方法始終保持在棧幀的頂部;線程私有
- 方法區 保存類信息、靜態常量、常量;線程共享
- 堆 保存對象,最最主要的垃圾收集之處;線程共享
2. 對象存活
- 引用計數算法:對對象引用進行計數,引用則計數器 +1,引用失效 -1;計數爲 0 時候認爲不在引用,能夠進行回收;不能處理對象循環引用問題
- 可達性分析算法:主要採起此方式,採用虛擬機棧、類引用對象、常量對象、本地方法引用對象做爲根,判斷對象到根是否存在引用關係,不可達則認爲不在引用,能夠進行回收;
3. GC回收算法
- 標記-清除算法:對要回收的對象,先進行標誌,後進行清除,你懂得;可是,久之,會存在內存不連續,好比,一次垃圾回收,回收了,(0,1)和(0,3)和(0,5)三個位置,可是沒有回收(0,2)和(0,4),那下次的內存,就沒法使用(0,1)-(0,5)的連續空間;
- 複製算法:爲改進上面的內存碎片問題而產生,對內存分爲兩部分,交替回收其中一部分,存活的對象複製到另外一部分空間,你懂得;可是,有點浪費,好比,內存分爲,(0,1)-(0,3)和(0,3)-(0,5)兩個部分,某次回收(0,1)-(0,3)空間,將存活對象拷貝到(0,3)-(0,5),然後在(0,1)-(0,3)分配對象;
- 標記-整理算法:爲改進上面的內存浪費問題而產生,對要回收的對象,先進行標誌,後進行清除,你懂得,而後,將存活的對象,進行整理,移動到邊界位置,似的剩餘空間連續;好比,一次垃圾回收,回收了,(0,1)和(0,3)和(0,5)三個位置,可是沒有回收(0,2)和(0,4),而後,將(0,2)和(0,4)移動到(0,1)和(0,2),使得(0,3)-(0,5)的空間連續;
4. 類加載過程
jvm中class類的加載過程,大體分爲這幾個步驟session
- 加載(load)
- 根據全類名,加載類的二進制字節流
- 將字節流轉存方法區
- 生成Class對象做爲訪問入口
- 驗證(verify)
- class文件的格式驗證,驗證是否符合JVM規範
- class中的元數據驗證,驗證是否符合Java規範
- class的字節碼驗證,驗證數據流控制流不會危害JVM環境
- 準備(prepare)
- 給變量分配內存
- 初始化零值(好比int默認爲0,boolean默認爲false)
- final變量直接賦值
- 解析
- 符號引用變爲直接引用
- 類、字段、方法、接口方法解析
- 初始化
- 初始化變量
- 構造函數
- static塊
5. 雙親委派機制
Java中,大概有三種類型加載器,啓動類加載器(Bootstrap)<- 標準擴展類加載器(Extension)<- 應用程序類加載器(Application )<- 上下文類加載器(Custom),從右到左,儘可能父類進行加載,當父類沒法進行加載時候,纔會使用子類進行加載多線程
- 意義
- 防止同一個JVM,內存中出現兩份class二進制字節碼
- 加載過程
- 從已加載的類查找是否已經存在,存在不須要再次加載
- 若不存在,則去parent中查找,存在不須要再次加載
- 若不存在,遞歸在parent中查找,直到找到爲止
- 若找遍全部parent均不存在,且當前加載器已經沒有parent加載器,則調用當前類加載器的findClass方法,若是能加載,結束
- 若是不能,則遞歸返回child類加載器,繼續調用findClass方法,若是能加載,結束
- 若是找遍全部child的findClass方法,仍是不能加載,則拋出異常
- 破壞雙親委派機制
- 將parent設爲null
- 重寫load(String,boolean)方法,改變類的查找機制。
三. 多線程
1. 死鎖的四個條件
2. 檢查死鎖
3. volatile
- JMM
- 內存可見性
- 防止指令重排序
- 不能保證原子性
4. synchronized
做用架構
用法併發
注意點app
- 當一個線程在訪問對象的 synchronized 方法,由於對象只有一把鎖,其餘線程沒法獲取該對象的鎖,因此沒法訪問該對象的其餘synchronized實例方法,可是其餘線程仍是能夠訪問該實例對象的其餘非synchronized方法
- 實現原理爲,對象監視器,Monitor
5. volatile vs synchronized vs lock
- 來源差別:volatile、synchronized爲Java關鍵字; lock是Java類
- 代價開銷:volatile不是鎖,代價最小; lock是通常基於AQS,相對比synchronized代價小; synchronized代價最大
- 簡單性:volatile、synchronized爲Java關鍵字,JVM全權幫忙維護,只要咱們能正確使用,不須要咱們太多關心維護; lock是Java類,有不少方法能夠調用,靈活性最好,可是須要本身控制鎖的獲取、釋放
6. 進程間通訊
- 管道pipe
- 命名管道FIFO
- 消息隊列MessageQueue
- 共享存儲SharedMemory
- 信號量Semaphore
- 套接字Socket
- 信號 ( sinal )
7. 原子操做類
寫在最後
限於篇幅,本文只收錄Spring、JVM、多線程的部分面試題;完整的面試題包含Kafka、Mysql、Tomcat、Docker、Spring、MyBatis、Nginx、Netty、Dubbo、Redis、Netty、Spring cloud、分佈式、高併發、性能調優、微服務等架構技。筆者已經整理打包好了!
須要的朋友點擊下方傳送門, 便可免費領取面試資料和視頻學習資料
如下是部分面試題截圖