每日十道面試題(三)
1. 講一下spring的ioc的理解?
ioc又叫做控制反轉,我們不再需要手動的去實例化對象,而是把我們設計好的bean交給ioc容器去控制,依賴注入就是很好的實現了控制反轉,不再自己去獲取資源**,ioc控制了外部資源的獲取包括對象資源和常量數據那些都可以從容器獲取**,有點像代理模式,我們把類A交給spring,spring管理所有對象,你怎麼創建我並不關心,但是我要用對象的時候,只需要spring提供即可,在以前我們是需要的時候就自己馬上實例創造一個然後用,太麻煩了
2. springmvc的執行流程?
- 所有前端的url地址映射進來都是先找DispatcherServlet,它是控制器負責請求分發
- 然後第二步HandlerMapping 處理器映射器**(中間商)**
- 根據url找Handler
- 將解析後的信息傳遞迴控制器
- 控制器將信息給處理器適配器(HandlerAdapter)
- 它決定適配到對應的處理器Controller
- 然後Controller將執行完返回的具體結果給適配器,比如返回的Model
- 然後將返回的邏輯視圖名,或者結果傳回控制器
- 如果是邏輯視圖名,就去調用ViewRESolver視圖解析它的視圖信息
- 將解析的視圖信息返回給控制器
- 根據視圖信息調用具體的視圖模板
- 展現視圖模板到前端
3. mybatis執行流程?原理
-
首先是Resource讀取全局配置文件,
-
然後就實例化SqlSessionFactoryBuilder構造器,抽象工廠模式,專門製造SqlSessionFactory,製造完就銷燬了
-
然後XMLConfigBuilder專門讀取xml配置文件信息
-
Configuration來配置讀取的xml信息,比較重要的是命名空間+方法名
-
配置完就可以SqlSessionFactory實例化,全局存在,比如一級緩存,提供後續便利
-
transactional事務管理,控制着事務
-
創建Executor,含有數據源信息
-
創建SqlSession,裏面包含了mapper的接口信息
-
實現CRUD,失敗就回滾,否則提交事務關閉SqlSession等
4. 說說對jdk1.7hashmap的理解和1.8的區別?
-
jdk1.7hashmap最拿手的就是數據結構是數組加鏈表,散列表形式,jdk1.8hashmap是數組加鏈表加紅黑樹,主要是優化擴容死鎖問題,死鎖在併發情況,指針地址改變就會發生
-
1.7的hashmap一上來就初始化16大小的空間,1.8只初始化加載因子都是0.75,但是隻有putval時纔會初始化16大小空間,有點類似懶加載
-
他們插入值都是先利用hash算出數組下標,然後再循環判斷鏈表上是否有重複值,有就替換返回原來的值,沒有就頭插法然後插入在頭部,然後頭部在數組上
-
查找方法的話,和put一樣,找不到返回null,找得到就返回對應的key
-
1.7hashMap利用hash高16位和低16位進行與運算,這是爲了保證散列性,不會太容易哈希碰撞,然後再利用算出的二次哈希值與table長度-1進行與運算,這是爲了保證低位都是二次哈希值的低位,這樣對應數組下標很準確,這裏就延申一個問題爲什麼數組長度都是冪等性,即使你初始化17也算作32,因爲保證了冪等性之後length-1才能保證低位是1,與運算找下標的步驟更準確,而且增加了散列性
-
1.8的紅黑樹是當鏈表長度超過了7之後會自動變成紅黑樹結構,當縮容爲6的時候又會轉爲鏈表,比較鏈表在長度短的時候效率比樹快,數據多的時候只是怕形成單鏈表所以採用紅黑樹而不用其它樹
5. 常用的幾種垃圾回收算法?之間的區別
引用計數法,實際上是通過在對象頭中分配一個空間來保存該對象被引用的次數,但是在環形數據循環引用的時候,那麼引用計數根本不會縮減,所以會造成內存泄漏,需要進行可達性分析判斷是否爲垃圾
複製算法:常用於新生區,適合那種存活率低的地方,因爲每次複製如果數據太大,實在太費時費力,每次複製都是一次全量檢查
標記清除算法: (兩次掃描)適合存活率大(老年區)內存碎片少的時候用,第一遍掃描標記我們
需要用到或者正在用的對象,第二遍然後清理其它的內存也就是沒標記的地方,但這樣清除容易造成坑坑窪窪,不連續的內存,有內存碎片,耗內存
標記清除整理:它實際上就是在標記清除的基礎上然後再掃描整理一遍排序,然後統一清理掉後面的不需要的垃圾,這樣可以形成連續的內存,所以內存碎片大的時候可以整理一下,
其實沒有最好的垃圾回收算法,我們目前最優是分代收集算法,用在合適的場景
6. 類加載的流程
**加載:**javac編譯的class字節碼文件由類加載器讀取二進制數據,在方法區創建一個Class的模板對象
鏈接:
- 驗證:驗證類是否合法,語言是否規範(雙親委派機制,沙箱安全機制)
- 準備:爲類的靜態成員方法區中分配內存,並設置默認初始值
- 解析:將符號引用解析爲直接引用
**初始化:**已經分配了內存,所以staic變量初始化,常量初始化,構造執行等
7. 說說都知道哪些異常?如何避免或者解決
OOM:堆內存不足,可以嘗試調大堆內存 xms ,但實際問題需要打印內存信息,如果是死鎖,那麼再調大也無濟於事
StatckOverFlow:棧內存不足,解決問題同上Xss調優,
併發修改異常: 每次進行操作集合的時候有個modcount會計算修改次數,然後iterator中會有個變量存值,然後如果沒有用iterator的remove方法的話就會導致modCount次數修改但是沒有存,導致iterator的modCount和集合的不一致就會拋出這個方法,一定要使用iterator來修改集合元素
等
8. 談一談springboot如何自動裝配的吧
這裏用個圖展示,碼字比較多
文檔:Springboot之Run方法解析.mindmap
鏈接:http://note.youdao.com/noteshare?id=c981f1d31d87cae4fab36287b1b66651
9. spring bean的生命週期
實例化 -> 屬性賦值 -> 初始化 -> 銷燬
-
設置bean的Aware
-
BeanPostProcessor.postProcessBeforeInitialization(Object bean, String beanName)
-
InitializingBean.afterPorpertiesSet
-
BeanPostProcessor.postProcessAfterInitialization(Object bean, String beanName)
-
SmartInitializingSingleton.afterSingletonsInstantiated
-
SmartLifecycle.start
-
bean已經在spring容器的管理下,可以做我們想做的事
-
SmartLifecycle.stop(Runnable callback)
-
DisposableBean.destroy()
10. springCloud的生態簡述一下重要的幾個組件的用處?
Zuul:路由網關,有效的安全隱藏了其它服務,保證了安全性,訪問過濾
Eureka service:註冊中心,裏面有一個註冊表,保存了各個服務所在的機器和端口號、Eurake Client:負責將這個服務的信息註冊到Eureka Server中
Feign:@FeignClient聲明式事務,註解結合restful風格,基於 Hystrix 和 Ribbon 聲明式服務調用組件
ribbion:客戶端負載均衡服務調用組件
**Config:**配置管理工具,支持 git 存儲配置實現應用外部配置化,支持遠程客戶端讀取配置並根據初始化參數啓動項目
基於 Hystrix 和 Ribbon 聲明式服務調用組件
ribbion:客戶端負載均衡服務調用組件
**Config:**配置管理工具,支持 git 存儲配置實現應用外部配置化,支持遠程客戶端讀取配置並根據初始化參數啓動項目