一 Spring
1.1 Spring IOC,AOP你的理解講一下以舒?
IOC趾痘,也經(jīng)常被稱為IOC容器,將之前手動new對象和手動對對象引用賦值稀轨,現(xiàn)在完全交給spring工廠扼脐。降低組件之間的耦合性。
AOP奋刽,面向切面編程瓦侮。是對面向?qū)ο蟮囊环N補(bǔ)充,將一些重復(fù)性代碼佣谐、業(yè)務(wù)無關(guān)的代碼抽取肚吏,提高代理利用率,減少對業(yè)務(wù)代碼的侵入狭魂。
1.2 Spring中Bean的生命周期(創(chuàng)建流程)是什么罚攀?
在容器進(jìn)行初始化時候,首先將definetion轉(zhuǎn)化為實例雌澄,然后進(jìn)行依賴注入(包含屬性和對象)斋泄,然后有前置處理器執(zhí)行前置處理器,如果配置了innit方法镐牺,執(zhí)行init方法炫掐。有后置處理器,然后執(zhí)行后置處理器睬涧。配置銷毀方法募胃,執(zhí)行銷毀方法。
1.3 Spring的作用域有哪些畦浓?
單例痹束、多例、一次請求創(chuàng)建一個對象讶请、每次會話創(chuàng)建一個對象祷嘶。
1.4 Spring對象屬性注入方式有哪些?
構(gòu)造方法、set方法抹蚀、靜態(tài)工廠
1.5 Spring怎么解決循環(huán)依賴(對象在三級緩存中的遷移過程)?
比如a和b進(jìn)行循環(huán)依賴了剿牺。
首先a進(jìn)行實例化,執(zhí)行g(shù)et环壤、doget、create钞诡、doCreate四個方法郑现,進(jìn)行對象a實例化,完成后將a放入三級緩存中荧降,然后進(jìn)行依賴注入接箫,判斷是否存在循環(huán)依賴。進(jìn)行對象B的注入朵诫,執(zhí)行g(shù)et辛友、doget。判斷是否存在閉環(huán)剪返,如果存在閉環(huán)废累,將對象a放進(jìn)二級緩存中,并將三級緩存中a對象銷毀脱盲。然后create邑滨、doCreate創(chuàng)建對象b,將對象a注入钱反。將對象b放進(jìn)一級緩存中掖看。然后回退到a對象注入b對象,將a對象移到一級緩存中面哥,這樣a對象依賴b對象哎壳,b對象依賴a對象。
1.6 Spring緩存是怎么實現(xiàn)的尚卫?
主要是2個注解 @Cacheable 和@CacheEvict 归榕。@Cacheable 可以用作類上和方法上。作用類上焕毫,將所有方法返回值放入緩存中蹲坷,作用在方法上,將方法的返回值放到緩存中邑飒。以參數(shù)為key
1.7 靜態(tài)代理和動態(tài)代理的區(qū)別循签,各自的優(yōu)點(diǎn)和缺點(diǎn)?
靜態(tài)代理是在編輯器就創(chuàng)建代理對象疙咸,執(zhí)行時候效率高县匠,但是靈活度差。動態(tài)代理在運(yùn)行時候,在內(nèi)存中創(chuàng)建代理對象乞旦,靈活度高贼穆,執(zhí)行時候慢。
1.8為什么JDK動態(tài)代理需要實現(xiàn)一個接口兰粉?
因為JDK動態(tài)代理的class文件已經(jīng)繼承了Proxy故痊,但是因為Java中單繼承,所以必須實現(xiàn)一個接口玖姑。
1.9 JDK動態(tài)代理和cglib動態(tài)代理的區(qū)別愕秫?既然有沒有實現(xiàn)接口都可以用CGLIB,為什么Spring還要使用JDK動態(tài)代理焰络?
JDK是基于接口實現(xiàn)動態(tài)代理戴甩,cglib是基于實現(xiàn)類進(jìn)行動態(tài)代理。
jdk動態(tài)代理是基于反射產(chǎn)生代理對象闪彼,cglib是基于AMS庫產(chǎn)生字節(jié)碼生成代理對象甜孤,在jdk1.6之前基于字節(jié)碼的動態(tài)代理效率高于cglib動態(tài)代理。但是jdk1.7和jdk1.8對jdk動態(tài)代理進(jìn)行優(yōu)化畏腕,在執(zhí)行次數(shù)較少情況下缴川,反射產(chǎn)生動態(tài)代理比cglib產(chǎn)生動態(tài)代理效率高。
1.10 除了Spring AOP還有什么AOP的實現(xiàn)方案嗎郊尝?
可以基于aspectj進(jìn)行動態(tài)代理二跋,是在編譯器就生成動態(tài)代理,啟動時候慢流昏,但是執(zhí)行時候效率高扎即。
1.11 Spring事務(wù)有幾種,實現(xiàn)的機(jī)制(@Transaction的底層原理)是什么,如果事務(wù)失敗后怎么辦况凉?
兩種:編程式事務(wù)谚鄙、聲明式事務(wù)。聲明式事務(wù)是基于aop刁绒,攔截執(zhí)行方法前后闷营,將事務(wù)編織到執(zhí)行方法中。在執(zhí)行方法前加上事務(wù)知市,執(zhí)行方法后加上事務(wù)提交和回滾傻盟。
@Transaction在bean進(jìn)行初始化,掃描到注解嫂丙,利用aop娘赴,攔截執(zhí)行方法前后,將事務(wù)編織到執(zhí)行方法中跟啤。
1.12 Spring事務(wù)傳播機(jī)制有哪些诽表?以及每一種機(jī)制事務(wù)管理員對事務(wù)協(xié)調(diào)員的影響唉锌?
7種:
required :事務(wù)管理員有事務(wù),事務(wù)協(xié)調(diào)員執(zhí)行事務(wù)竿奏。管理員無袄简,協(xié)調(diào)員自己創(chuàng)建。
requires_new:事務(wù)管理員是否有事務(wù)泛啸,協(xié)調(diào)員自己創(chuàng)建事務(wù)绿语。
support:管理員有事務(wù)協(xié)調(diào)員就用,管理員無事務(wù)協(xié)調(diào)員就不用候址。
no_support:管理員是否有事務(wù)汞舱,協(xié)調(diào)員都不用事務(wù)。
mandatory:管理員有事務(wù)就協(xié)調(diào)員使用事務(wù)宗雇,管理員無事務(wù)就報錯
never: 管理員沒有事務(wù)協(xié)調(diào)員不用事務(wù),管理員有事務(wù)報錯
nested: 回滾到指定位置莹规。
1.13 FactoryBean 和 BeanFactory 區(qū)別赔蒲?
FactoryBean 是一個對象,對bean進(jìn)行裝飾良漱。BeanFactory是spring工廠的頂級父類舞虱。
1.14 SpringMVC的工作原理?
瀏覽器發(fā)送url,前端控制器接受請求母市,然后轉(zhuǎn)發(fā)到執(zhí)行器映射器矾兜,然后執(zhí)行鏈給前端控制器,前端控制器請求給處理器適配器患久,適配器交給處理器進(jìn)行處理椅寺,然后modulAndView給前端控制器,前端控制器將modulAndView傳給視圖解析器蒋失,視圖解析器解析響應(yīng)給前端控制器View返帕。前端控制器將view傳給視圖渲染,視圖渲染好篙挽,通過前端控制器響應(yīng)給瀏覽器荆萤。
1.15 BeanFactory和Application區(qū)別
BeanFactory是工廠的頂級父類,定義了bean文件讀取铣卡、實例化链韭、維護(hù)對象的關(guān)系等。ApplicationContext除了繼承上述功能還包含國際化煮落、時間的監(jiān)聽等功能敞峭。
BeanFactory產(chǎn)生對象是懶加載,在獲取對象時候州邢,才開始去實例化對象儡陨,如果配置文件有問題褪子,在獲取時候才能發(fā)現(xiàn)問題。Application在初始化時候就創(chuàng)建對象骗村。編譯時候?qū)ε渲梦募M(jìn)行加檢查嫌褪、啟動慢,執(zhí)行效率好胚股。
二 Mybatis
2.1 MyBatis 中${}和#{}的區(qū)別笼痛?
#{}能防止sql注入問題,${}不能防止sql注入問題琅拌。因為#{}在sql進(jìn)行解析時候缨伊,進(jìn)行預(yù)編譯,#{}替換層进宝?占位符刻坊。${}在sql進(jìn)行解析時候,直接進(jìn)行參數(shù)替換党晋。
2.2 既然${}不安全谭胚,為什么還需要${},什么時候會用到它?
但是在sql中表名詞和order by進(jìn)行排序等未玻,需要的表名和字段名不需要’’包裹灾而,必須用${}。
2.3 為什么預(yù)編譯后能阻止sql注入?
進(jìn)行預(yù)編譯的時候扳剿,將mybatis將含有占位符的sql交給mysql進(jìn)行處理旁趟,對sql進(jìn)行解析和優(yōu)化。然后再進(jìn)行參數(shù)賦值庇绽。然后執(zhí)行锡搜,即在執(zhí)行時候不會對sql進(jìn)行編譯。
2.4 MyBatis的接口是怎么和XML文件聯(lián)系上的敛劝?
mybatis開始加載時余爆,xml配置文件加載成流,利用XParamPath解析器將流轉(zhuǎn)化為document對象夸盟。然后開始解析document對象蛾方,解析配置文件放到cofigeration。然后獲取sql的xml文件上陕,加載流桩砰,然后將流轉(zhuǎn)化為document。然后對sql的xml文件進(jìn)行解析释簿,并將sql封裝成Sqlsource對象亚隅,并封裝到cofigeration。然后SqlSessionFactoryBuiler根據(jù)cofigeration創(chuàng)建SqlSessionFactory庶溶,SqlSessionFactory再產(chǎn)生SqlSession對象煮纵。接口的查詢方法懂鸵,就是執(zhí)行代理對象的invork方法,最終執(zhí)行SqlSession的查詢方法即接口和xml文件建立聯(lián)系行疏。
2.5 MyBatis 執(zhí)行一個 Select 查詢的流程匆光?
實行查詢方法,進(jìn)入Executor的查詢方法酿联,取出SqlBould械念,如果開啟了二級緩存坦喘,使用CachingExecutor的查詢方法合住,先看二級緩存中是否有數(shù)據(jù)甜无,有直接返回,如果沒有調(diào)用被裝飾的SimpleExecutor,然后插敘一級緩存喳张,如果一級緩存中有數(shù)據(jù)直接響應(yīng)數(shù)據(jù)续镇,無數(shù)據(jù)然后進(jìn)行數(shù)據(jù)庫查詢。首先使用parameHandler對參數(shù)進(jìn)行設(shè)置销部,然后StatementHandler執(zhí)行sql磨取,ResultSetHandler對結(jié)果映射,響應(yīng)list集合柴墩。
2.6 Mybatis如何不使用MySQL語句,如何實現(xiàn)分頁?
使用RowBounds對象進(jìn)行分頁凫岖,對查詢的結(jié)果集再內(nèi)存中分頁江咳,即是非物理分頁。(RowBounds對象考察)
2.7 Mybatis如何實現(xiàn)一個插件哥放?
實現(xiàn)Mybatis的Interceptor接口歼指,重寫Interceptor方法。
2.8 Mybatis插件實現(xiàn)原理是什么甥雕?
在創(chuàng)建ParameHandler踩身、ResultSetHandler、StatementHandler社露、Executor等創(chuàng)建對象時挟阻,先獲取所有實現(xiàn)Interceptor接口,插件機(jī)制為四大對象創(chuàng)建代理對象峭弟,代理對象就可以攔截四大對象的每一個執(zhí)行附鸽。
2.9 Mybatis有哪些Executor?
CachingExecutor緩存器處理器(二級緩存)
BaseExecutor基礎(chǔ)處理器(一級緩存)
SimpleExecutor簡單處理器(默認(rèn)處理器)
ReseseExecutor可重用處理器
BathExecutor批量處理器。
2.10 Mybatis二級緩存機(jī)制瞒瘸?
一級緩存器基于hashMap坷备,作用域是session,默認(rèn)時開啟的情臭。
二級處理器基于hashMap省撑,作用域是namespace赌蔑,默認(rèn)是關(guān)閉的。在sql的xml文件配置<cache>標(biāo)簽開啟二級緩存竟秫。
在進(jìn)行新增娃惯、編輯、刪除會清理緩存鸿摇。
但是二級緩存和一級緩存和JVM內(nèi)存在一個地方石景,所以緩存過多影響性能。而且緩存在本地虛擬機(jī)中拙吉,會有分布式數(shù)據(jù)不一致問題潮孽。
2.11 Mybatis是否支持延遲加載?如果支持筷黔,它的實現(xiàn)原理是什么往史?
支持延遲加載,如關(guān)聯(lián)對象的查詢和關(guān)聯(lián)對象集合查詢佛舱。
利用cglib生成代理對象椎例,調(diào)用目標(biāo)方法,先進(jìn)入目標(biāo)方法的invork方法请祖。比如a.getB().getName(),執(zhí)行a.getB()订歪,發(fā)現(xiàn)b對象為空,然后獲取之前保存的sql,進(jìn)行查詢肆捕,然后對b進(jìn)行賦值刷晋,再調(diào)用getName()。完成慎陵。