JDK扇谣、JRE螃征、JVM的區(qū)別
- JDK碍论,是Java開發(fā)工具包逗宁,用于開發(fā)Java程序,提供了編譯和運(yùn)行Java程序的各種工具和資源嫉到、類庫(kù)等
- JRE沃暗,Java程序的運(yùn)行環(huán)境,用于解釋執(zhí)行Java的字節(jié)碼文件屯碴,想要運(yùn)行Java程序必須要安裝JRE
- JVM描睦,Java虛擬機(jī),Java程序跨平臺(tái)的核心导而,負(fù)責(zé)解析和執(zhí)行字節(jié)碼文件
- JDK包含JRE忱叭,JRE包含JVM
重寫和重載的區(qū)別
- 重載隔崎,發(fā)生在同一個(gè)類中,方法名相同韵丑,參數(shù)列表不一致爵卒,與返回值無(wú)關(guān)
- 重寫,發(fā)生在父子類中撵彻,方法名和參數(shù)列表必須一致钓株,返回值和拋出的異常要小于等于父類,訪問(wèn)修飾符要大于等于父類陌僵,父類中的
private
方法不能被子類重寫
Java中的==和equals的區(qū)別
- ==
- 基本數(shù)據(jù)類型轴合,比較值是否相等
- 引用數(shù)據(jù)類型,比較的地址是否相等
- equals
- 未重寫前碗短,比較的是地址值
- 重寫后受葛,按照重寫的邏輯進(jìn)行比較
String、StringBuffer偎谁、StringBuilder的區(qū)別
String
代表字符串总滩,是一個(gè)final修飾的不可變類,一旦創(chuàng)建就不能修改巡雨。StringBuilder
是內(nèi)容可變的字符串容器闰渔,可以進(jìn)行字符串動(dòng)態(tài)增刪,它可以提高字符串操作的效率铐望。如果是多線程開發(fā)冈涧,會(huì)有線程安全問(wèn)題。StringBuffer
是內(nèi)容可變的字符串容器蝌以,可以進(jìn)行字符串動(dòng)態(tài)增刪炕舵,可以提高字符串操作的效率。它是線程安全的類跟畅,實(shí)現(xiàn)線程安全的方式是所有方法都加上synchronized,效率低溶推,不推薦使用徊件。
什么是單例模式,有實(shí)現(xiàn)幾種蒜危?
程序運(yùn)行中虱痕,同一個(gè)類的的實(shí)例只有一個(gè),就是單例模式辐赞。
- 懶漢式
- 餓漢式
- 餓漢式 + 鎖
- 餓漢式 + 雙重鎖
- 靜態(tài)內(nèi)部類實(shí)現(xiàn)單例
- 枚舉實(shí)現(xiàn)單例
- 靜態(tài)Map工廠實(shí)現(xiàn)單例
接口和抽象類的區(qū)別部翘?
- 抽象類,需要被類繼承响委。接口需要被類實(shí)現(xiàn)
- 接口中的變量只能是公共的靜態(tài)常量新思,而抽象類中的變量則可以是普通變量
- 接口可以繼承接口窖梁,可以多繼承,而抽象類只能單繼承
List和Map夹囚、Set的區(qū)別纵刘?
- List和Set都是單列集合,Map是雙列集合
- List存儲(chǔ)的元素是有序的荸哟,并且允許重復(fù)
- Set存儲(chǔ)的元素是無(wú)序的假哎,并且不允許重復(fù),HashSet依靠對(duì)象的hashCode和equals方法來(lái)確定元素位置鞍历,而TreeSet依靠元素實(shí)現(xiàn)Comparable接口或Compartor比較器確定位置
- Map存儲(chǔ)的元素是無(wú)序的舵抹,鍵是唯一的,不允許重復(fù)劣砍,而值是允許重復(fù)的
創(chuàng)建線程的方式有掏父?
- 繼承Thread類,重寫run方法
- 實(shí)現(xiàn)Runnable接口秆剪,重寫run方法赊淑。這種方式?jīng)]有返回值,不允許拋出編譯時(shí)異常
- 實(shí)現(xiàn)Callable接口仅讽,重寫call方法陶缺。這種方式有返回值,允許拋出編譯時(shí)異常
- 使用線程池創(chuàng)建線程
Ruanable和Callable的區(qū)別洁灵?
- Runnable接口的run方法沒(méi)有返回值饱岸,Callable接口的call方法有返回值,并且支持泛型
- Runnable接口的run方法不能拋出編譯時(shí)異常徽千,必須捕獲處理苫费。而Callable接口的call方法允許拋出編譯時(shí)異常
如何啟動(dòng)一個(gè)線程?調(diào)用start()和run()有什么區(qū)別双抽?
- 直接調(diào)用run()方法百框,只是在當(dāng)前線程調(diào)用了對(duì)象的普通方法,并不是開啟線程牍汹,run()方法運(yùn)行在調(diào)用方的線程中
- 調(diào)用start()方法铐维,則是讓jvm開啟一個(gè)線程,然后在新開啟的線程中調(diào)用run()方法慎菲,run()方法運(yùn)行在新線程中
線程有哪幾種狀態(tài)嫁蛇?狀態(tài)之間是怎么流轉(zhuǎn)的?
NEW:新建
RUNABLE:可運(yùn)行(就緒)
TERMINATED:結(jié)束
BLOCK:阻塞
WATING:無(wú)限等待
TIME_WATING:定時(shí)等待
線程Thread類對(duì)象被new后露该,就是
新建狀態(tài)
線程對(duì)象調(diào)用start()后就流轉(zhuǎn)為
可運(yùn)行狀態(tài)
睬棚,等待CPU調(diào)度線程的run()方法執(zhí)行完畢,線程就會(huì)流轉(zhuǎn)為
結(jié)束狀態(tài)
,然后線程被銷毀-
線程執(zhí)行到同步代碼塊時(shí)
- 如果沒(méi)有搶到鎖抑党,則進(jìn)入
阻塞狀態(tài)
- 如果搶到鎖包警,則可以繼續(xù)執(zhí)行
- 如果沒(méi)有搶到鎖抑党,則進(jìn)入
在阻塞狀態(tài)時(shí),如果重新?lián)尩芥i新荤,則回歸到
可運(yùn)行狀態(tài)
可運(yùn)行狀態(tài)時(shí)揽趾,如果調(diào)用了wait()方法,則進(jìn)入
無(wú)限等待狀態(tài)
苛骨,如果調(diào)用了sleep(timeount)或wait(timeout)則進(jìn)入定時(shí)等待狀態(tài)
當(dāng)另外一個(gè)線程調(diào)用了notify()或notifyAll()篱瞎,并且重新?lián)尩芥i后,則回歸到
可運(yùn)行狀態(tài)
如果是
定時(shí)等待狀態(tài)
痒芝,重新?lián)尩搅随i俐筋,則自動(dòng)回歸到可運(yùn)行狀態(tài)
wait()和sleep()的區(qū)別?
-
來(lái)自不同的類
- wait()來(lái)自O(shè)bject严衬,sleep()來(lái)自Thread
-
關(guān)于鎖的釋放
- wait()在等待過(guò)程中會(huì)釋放鎖
- sleep()在等待過(guò)程中不會(huì)釋放鎖
-
關(guān)于使用范圍
- wait()必須在同步代碼塊中調(diào)用
- sleep()可以在任何地方調(diào)用
-
是否需要捕獲異常
- wait()不需要捕獲異常
- sleep()需要捕獲異常
常用線程池種類
- newCacheThreadPool澄者,創(chuàng)建一個(gè)可進(jìn)行緩存,可重用的線程池
- newFixThreadTool请琳,創(chuàng)建一個(gè)固定線程的粱挡,可重用的線程池
- newSingleThreadExecutor,創(chuàng)建一個(gè)單工作線程的Executor俄精,它使用無(wú)界隊(duì)列询筏,該線程池最多執(zhí)行一個(gè)線程
- newSingleThreadScheduledExcutor,創(chuàng)建一個(gè)單工作線程的Executor竖慧,它可以延時(shí)執(zhí)行任務(wù)或定期執(zhí)行任務(wù)
- newScheduledThreadPool嫌套,創(chuàng)建一個(gè)線程池,它可延時(shí)執(zhí)行任務(wù)或定期執(zhí)行任務(wù)
- newWorkStealingPool圾旨,創(chuàng)建一個(gè)并行級(jí)別的線程池踱讨,并行級(jí)別決定了同一時(shí)刻最多有多少個(gè)線程在執(zhí)行,如果不傳并行級(jí)別參數(shù)砍的,那么默認(rèn)為當(dāng)前系統(tǒng)的CPU核心數(shù) * 2
線程池創(chuàng)建時(shí)的參數(shù)作用痹筛?以及執(zhí)行流程
- corePoolSize:核心線程數(shù)
- maxPoolSize:最大線程數(shù)
- keepAliveTime:空閑線程的空閑時(shí)間
- unit:空閑時(shí)間的時(shí)間單位
- workQueue:工作隊(duì)列,保存任務(wù)的阻塞隊(duì)列
- threadFactory:線程工廠
- handler:飽和策略(也叫拒絕策略)
ArrayList和LinkedList的區(qū)別
- ArrayList和LinkedList都實(shí)現(xiàn)了List接口挨约,都用于存儲(chǔ)元素味混,并提供對(duì)元素增刪查改的方法。
- ArrayList底層使用數(shù)組實(shí)現(xiàn)诫惭,它的查找速度很快,并且提供索引進(jìn)行訪問(wèn)元素的方法蔓挖,當(dāng)在尾部插入或刪除元素時(shí)夕土,耗時(shí)時(shí)間是一致的。但如果在中間添加或刪除元素時(shí),ArrayList需要移動(dòng)元素怨绣,就會(huì)比較耗時(shí)角溃。
- LinkedList的底層使用鏈表實(shí)現(xiàn),它的增刪元素只需要改變前后元素的前指針和后指針篮撑,所以效率比較高减细,而查找時(shí)需要移動(dòng)指針,相對(duì)效率會(huì)比較低赢笨。
- ArrayList的空間浪費(fèi)體現(xiàn)在它需要在尾部預(yù)留一定容量空間未蝌。而LinkedList的空間浪費(fèi)體現(xiàn)在每個(gè)元素都要有一個(gè)前指針和一個(gè)后指針。
數(shù)據(jù)庫(kù)的四大特性
- 原子性:多條指令要么同時(shí)成功茧妒,要么同時(shí)失敗
- 一致性:事務(wù)前和事務(wù)后萧吠,數(shù)據(jù)是一致的
- 隔離性:事務(wù)提交前,不會(huì)影響其他事務(wù)
- 持久性:事務(wù)提交后桐筏,就會(huì)永久存入磁盤
事務(wù)的隔離級(jí)別
- 讀未提交
- 讀已提交
- 可重復(fù)讀
- 可串行化
MyBatis的#{}
和${}
有什么區(qū)別纸型?
-
#
是一個(gè)占位符,$
是拼接符 -
#{}
梅忌,會(huì)將內(nèi)容替換為?號(hào)狰腌,使用預(yù)編譯,使用PreparedStatement來(lái)執(zhí)行SQL牧氮,可以防止SQL注入琼腔,提高安全性 -
${}
,是字符串拼接蹋笼,會(huì)有SQL注入的風(fēng)險(xiǎn)展姐,不能避免注入攻擊
MyBatis的resultType和resultMap的區(qū)別?
- 如果數(shù)據(jù)庫(kù)表的字段名和實(shí)體類的成員變量名一致剖毯,就可以使用resultType圾笨,MyBatis會(huì)自動(dòng)映射查詢結(jié)果到實(shí)體類中
- 如果不一致,那么則要使用resultMap逊谋,單獨(dú)配置2者的映射關(guān)系
MyBatis常用動(dòng)態(tài)SQL標(biāo)簽有哪些擂达?有什么作用?
-
<if>
標(biāo)簽胶滋,動(dòng)態(tài)SQL的多條件動(dòng)態(tài)拼接 -
<where>
標(biāo)簽板鬓,相當(dāng)于where條件,當(dāng)有條件時(shí)拼接上where關(guān)鍵字究恤,沒(méi)有條件時(shí)則不拼接(相當(dāng)于不需要使用 where 1 = 1 來(lái)保證SQL語(yǔ)法正確)俭令,可以去掉多余的and
或or
-
<foreach>
標(biāo)簽,遍歷傳入的集合或數(shù)組部宿,將遍歷的每一項(xiàng)拼接為一個(gè)字符串(例如在 IN 和 NOT IN 中使用) -
<sql>
和<include>
標(biāo)簽抄腔,sql標(biāo)簽可以把SQL的公共片段抽取瓢湃,例如查詢的字段列信息。include標(biāo)簽用于在SQL中引入sql標(biāo)簽的SQL片段赫蛇,復(fù)用SQL片段绵患,減少重復(fù)代碼 -
<set>
標(biāo)簽,相當(dāng)于set關(guān)鍵字悟耘,用于update語(yǔ)句中落蝙,能夠去掉多余的逗號(hào)(例如最后一個(gè)條件的逗號(hào))
Get請(qǐng)求和Post請(qǐng)求的區(qū)別
- Get請(qǐng)求不安全,它的請(qǐng)求參數(shù)在請(qǐng)求行中暂幼,會(huì)顯示在瀏覽器的地址欄筏勒,用戶是可見(jiàn)的,而Post的請(qǐng)求參數(shù)在請(qǐng)求體中粟誓,不會(huì)顯示在地址欄中奏寨,用戶不可見(jiàn),相對(duì)安全
- Get請(qǐng)求傳輸數(shù)據(jù)量小鹰服,由于不同的瀏覽器病瞳,限制URL的長(zhǎng)度不同,因?yàn)橄拗拼笮∫膊煌幔话阍?8kb以內(nèi)套菜。而Post請(qǐng)求默認(rèn)不限制大小,所以可以傳輸更多的數(shù)據(jù)
- Get請(qǐng)求限制數(shù)據(jù)必須為ASCII字符设易,而POST請(qǐng)求則支持整個(gè)ISO10646字符集
- Get請(qǐng)求沒(méi)有請(qǐng)求體逗柴,而Post請(qǐng)求有請(qǐng)求體,所以Get請(qǐng)求的效率更高顿肺,form表單默認(rèn)使用Get請(qǐng)求
- 總結(jié):傳輸非敏感數(shù)據(jù)戏溺,數(shù)據(jù)量小,使用Get請(qǐng)求屠尊。傳輸敏感數(shù)據(jù)旷祸,數(shù)據(jù)量大,使用Post請(qǐng)求
Servlet生命周期
- Servlet生命周期讼昆,就是Web服務(wù)器創(chuàng)建Servlet對(duì)象到銷毀的過(guò)程
- 生命周期方法有:init()初始化方法托享,service()處理請(qǐng)求方法,destroy銷毀方法
- init()初始化方法浸赫,創(chuàng)建Servlet對(duì)象時(shí)調(diào)用闰围,只會(huì)調(diào)用一次
- service()處理請(qǐng)求方法,每次請(qǐng)求該Servlet資源都會(huì)調(diào)用一次
- destroy()銷毀方法既峡,Web服務(wù)器關(guān)閉或重啟時(shí)調(diào)用羡榴,只會(huì)調(diào)用一次
- Servlet對(duì)象創(chuàng)建的時(shí)機(jī),在第一次訪問(wèn)該Servlet資源時(shí)創(chuàng)建运敢,它使用單例模式炕矮,所以只會(huì)創(chuàng)建一次么夫,節(jié)省內(nèi)存
- 通過(guò)配置load-on-startup參數(shù)者冤,就可以讓W(xué)eb服務(wù)器啟動(dòng)時(shí)肤视,就自動(dòng)創(chuàng)建該Servlet對(duì)象,提升用戶的訪問(wèn)速度
請(qǐng)求轉(zhuǎn)發(fā)和重定向的區(qū)別
- 請(qǐng)求轉(zhuǎn)發(fā)只有1次請(qǐng)求涉枫,而重定向會(huì)有2次請(qǐng)求
- 請(qǐng)求轉(zhuǎn)發(fā)不會(huì)改變?yōu)g覽器地址欄地址邢滑,而重定向會(huì)改變地址欄地址
- 請(qǐng)求轉(zhuǎn)發(fā)是服務(wù)器內(nèi)部跳轉(zhuǎn),而重定向是瀏覽器跳轉(zhuǎn)
- 請(qǐng)求轉(zhuǎn)發(fā)只能跳轉(zhuǎn)當(dāng)前項(xiàng)目?jī)?nèi)的資源愿汰,重定向可以跳轉(zhuǎn)任何資源困后,包括外部資源
- 請(qǐng)求轉(zhuǎn)發(fā)可以共享Request請(qǐng)求域內(nèi)的數(shù)據(jù),而重定向不可以
什么是HTTP協(xié)議衬廷,有什么特點(diǎn)和優(yōu)缺點(diǎn)摇予?
- HTTP協(xié)議,就是HyperText Transfer Protocol 超文本傳輸協(xié)議吗跋,規(guī)定了瀏覽器和服務(wù)器之間數(shù)據(jù)傳輸?shù)囊?guī)則
- 特點(diǎn):
- 基于TCP協(xié)議侧戴,面向連接,安全
- 基于請(qǐng)求-響應(yīng)模型跌宛,一次請(qǐng)求只有一次響應(yīng)
- 請(qǐng)求數(shù)據(jù)包括酗宋,請(qǐng)求行、請(qǐng)求頭疆拘、請(qǐng)求體
- 響應(yīng)數(shù)據(jù)報(bào)錯(cuò)蜕猫,響應(yīng)行、響應(yīng)頭哎迄、響應(yīng)體
- HTTP是無(wú)狀態(tài)的協(xié)議回右,對(duì)于事務(wù)處理沒(méi)有記憶能力,每次請(qǐng)求漱挚、響應(yīng)都是獨(dú)立的
- 優(yōu)點(diǎn):速度快
- 缺點(diǎn):多次請(qǐng)求間不能共享數(shù)據(jù)
Cookie和Session的區(qū)別翔烁?
- 存儲(chǔ)問(wèn)題不同
- Cookie存儲(chǔ)在瀏覽器,Session存儲(chǔ)在服務(wù)器
- 存儲(chǔ)容量不同
- 單個(gè)Cookie保存的數(shù)據(jù)只能<=4kb棱烂,一個(gè)網(wǎng)站一般能保存20~50個(gè)Cookie租漂,不同的瀏覽器也有區(qū)別
- Session沒(méi)有上限,受限于服務(wù)器的內(nèi)存
- 存儲(chǔ)方式的數(shù)據(jù)類型不同
- Cookie只能存儲(chǔ)字符串?dāng)?shù)據(jù)
- Session可以存儲(chǔ)任何類型的數(shù)據(jù)
- 隱私策略不同
- Cookie對(duì)客戶端是可見(jiàn)的颊糜,可能會(huì)出現(xiàn)篡改Cookie數(shù)據(jù)進(jìn)行欺騙哩治,所以它是不安全的
- Session因?yàn)槭谴鎯?chǔ)在服務(wù)器,不存在敏感信息泄露的風(fēng)險(xiǎn)
什么是Session的鈍化和活化衬鱼?
- 鈍化是指服務(wù)器正常關(guān)閉后业筏,Tomcat會(huì)自動(dòng)將Session數(shù)據(jù)寫入到磁盤,鈍化要求Session保存的數(shù)據(jù)必須實(shí)現(xiàn)Serializable序列化接口
- 活化是再次啟動(dòng)服務(wù)器后鸟赫,從磁盤中讀取文件蒜胖,加載數(shù)據(jù)到Session中
什么是Ajax消别,有什么優(yōu)勢(shì)?
- Ajax台谢,就是Asynchronous JavaScript And XML寻狂,異步的JavaScript和XML
- 由前端實(shí)現(xiàn)異步請(qǐng)求服務(wù)端接口,進(jìn)行通信交互
- 優(yōu)勢(shì):通過(guò)異步非阻塞方式進(jìn)行請(qǐng)求朋沮,用戶不需要等待蛇券,提升用戶體驗(yàn)
- 優(yōu)化了瀏覽器和服務(wù)器之間的傳輸,減少了不必要的數(shù)據(jù)往返樊拓,減少了帶寬占用纠亚,性能好(后端只返回?cái)?shù)據(jù),而不需要返回整個(gè)網(wǎng)頁(yè))
JavaWeb的三大組件及其作用
- Servlet:用于處理資源的請(qǐng)求和響應(yīng)
- Filter:過(guò)濾器筋夏,用于攔截請(qǐng)求蒂胞,以及統(tǒng)一操作每個(gè)請(qǐng)求的一些通用處理,例如權(quán)限控制条篷、統(tǒng)一編碼等
- Listener:監(jiān)聽器骗随,用于監(jiān)聽ServletContext、Request拥娄、Session的創(chuàng)建和銷毀蚊锹,以及這3個(gè)域?qū)ο笾袛?shù)據(jù)變化,數(shù)據(jù)變化時(shí)進(jìn)行額外的業(yè)務(wù)處理
JSP和Servlet的區(qū)別
相同點(diǎn)稚瘾,JSP編譯后牡昆,本質(zhì)就是一個(gè)Servlet,由于JVM只能識(shí)別Java類摊欠,所以需要Web服務(wù)器將JSP編譯為Servlet丢烘,當(dāng)請(qǐng)求到來(lái)時(shí),調(diào)用生命周期方法進(jìn)行處理
不同點(diǎn)些椒,JSP側(cè)重于視圖和展現(xiàn)數(shù)據(jù)播瞳,Servlet側(cè)重于邏輯控制和獲取數(shù)據(jù)
Spring的IOC、DI免糕、AOP分別是什么赢乓?IOC和DI有什么關(guān)系?
- IOC是控制反轉(zhuǎn)石窑,將對(duì)象的創(chuàng)建牌芋,交給Spring容器,不再親自new對(duì)象松逊,而是Spring根據(jù)我們的配置文件生成對(duì)象躺屁,當(dāng)我們需要對(duì)象時(shí),再通過(guò)IOC容器進(jìn)行獲取
- DI是依賴注入经宏,是運(yùn)行過(guò)程中犀暑,對(duì)IOC中的對(duì)象的成員屬性進(jìn)行賦值
- AOP是面向切面編程驯击,是將項(xiàng)目中非業(yè)務(wù)代碼的抽取,進(jìn)行最大程度的解耦耐亏,Spring的AOP使用JDK動(dòng)態(tài)代理徊都,或使用CGLIB進(jìn)行動(dòng)態(tài)代理
- IOC和DI的區(qū)別,IOC側(cè)重于對(duì)象的創(chuàng)建上的解耦苹熏,主要是將對(duì)象創(chuàng)建交給Spring容器碟贾。而DI側(cè)重于對(duì)象使用上的解耦,對(duì)象需要依賴哪些對(duì)象轨域,向IOC容器進(jìn)獲取
Spring的Bean作用域有哪些?每種作用域是怎樣的杀餐?
- Singleton干发,單例,是默認(rèn)的作用域史翘,IOC容器啟動(dòng)時(shí)就會(huì)創(chuàng)建該作用域的bean枉长,每個(gè)容器只有一個(gè)對(duì)象
- prototype,多例琼讽,每次向IOC容器獲取對(duì)象時(shí)必峰,都會(huì)創(chuàng)建一個(gè)新的bean對(duì)象
- request,在web工程中使用钻蹬,IOC容器會(huì)在每次Request請(qǐng)求時(shí)吼蚁,創(chuàng)建bean對(duì)象,并設(shè)置到request域中问欠,同一個(gè)request對(duì)象中共享一個(gè)bean對(duì)象肝匆,request結(jié)束中,bean就會(huì)銷毀
- session顺献,在web工程中使用旗国,IOC容器在每次會(huì)話開啟時(shí),創(chuàng)建bean對(duì)象注整,并設(shè)置到session域中能曾,同一個(gè)session會(huì)話中共享一個(gè)bean對(duì)象,會(huì)話結(jié)束后肿轨,bean對(duì)象就會(huì)銷毀
- global-session寿冕,在web工程中使用,在多臺(tái)web服務(wù)器中萝招,所有的session會(huì)話共享一個(gè)bean實(shí)例
Spring的對(duì)象默認(rèn)是單例還是多例蚂斤?單例bean存在線程安全問(wèn)題嗎?
- Spring的bean的默認(rèn)作用域是單例的槐沼,可以設(shè)置bean對(duì)象的scope為prototype則為多例
- 在多線程的情況下曙蒸,操作單例bean的成員屬性捌治,會(huì)有線程安全問(wèn)題
- 解決方案是避免在單例bean中定義成員變量,如果無(wú)法避免纽窟,則需要將成員屬性設(shè)置到ThreadLocal中
MyBatis編程步驟是怎樣的肖油?
- 導(dǎo)入MyBatis的依賴
- 編寫Mapper接口
- 編寫Mapper映射XML文件
- 執(zhí)行MyBatis的操作
- 創(chuàng)建SqlSessionFactory
- 通過(guò)該工廠類創(chuàng)建SqlSession
- 通過(guò)SqlSession的getMapper,創(chuàng)建Mapper接口的代理類臂港,并執(zhí)行數(shù)據(jù)庫(kù)操作
- SqlSession提交事務(wù)
- 關(guān)閉SqlSession森枪,釋放資源
談?wù)勀銓?duì)MyBatis的緩存機(jī)制的理解
- MyBatis有2級(jí)緩存
- 一級(jí)緩存是SqlSession級(jí)別的,默認(rèn)開啟
- 二級(jí)緩存是Mapper級(jí)別的审孽,默認(rèn)不開啟县袱,需要手動(dòng)開啟
- 一級(jí)緩存,是SqlSession級(jí)別的佑力,一個(gè)SqlSession范圍內(nèi)共享該緩存式散,第一次查詢時(shí)會(huì)將查詢結(jié)果緩存,第二個(gè)查詢直接返回緩存打颤。當(dāng)進(jìn)行增暴拄、刪、改编饺、提交事務(wù)時(shí)乖篷,就會(huì)清空一級(jí)緩存
- 二級(jí)緩存,是Mapper級(jí)別的透且,多個(gè)SqlSession都可以共享該緩存撕蔼,要使用二級(jí)緩存,需要做2個(gè)步驟
- 實(shí)體類實(shí)現(xiàn)Serializable序列化接口
- Mapper.xml中添加
<cache>
標(biāo)簽石蔗,才能開啟二級(jí)緩存
- 當(dāng)sqlSession執(zhí)行提交或關(guān)閉時(shí)罕邀,寫入緩存
- 執(zhí)行增、刪养距、改操作時(shí)顽馋,清空二級(jí)緩存
Spring中@Autowired和@Resource的區(qū)別
-
@Autowired
是Spring提供的根时,而@Resource
是javax包下的 -
@Autowired
默認(rèn)按類型匹配,而@Resource
默認(rèn)按名稱匹配 -
@Qualifier
需要和@Autowired
一起使用,而@Resource
可以單獨(dú)使用 - Java9及其以上版本真屯,
@Resource
已被刪除怕午,所以推薦使用@Qualifier
和@Autowired
Spring的事務(wù)傳播行為
spring事務(wù)的傳播行為說(shuō)的是扣猫,當(dāng)多個(gè)事務(wù)同時(shí)存在的時(shí)候革娄,Spring如何處理這些事務(wù)的行為。備注(方便記憶): propagation傳播
require必須的/support支持/mandatory 強(qiáng)制托管/requires-new 需要新建/ not -supported不支持/never從不/nested嵌套的
PROPAGATION_REQUIRED:如果當(dāng)前沒(méi)有事務(wù)束析,就創(chuàng)建一個(gè)新事務(wù)艳馒,如果當(dāng)前存在事務(wù),就加入該事務(wù),該設(shè)置是最常用的設(shè)置弄慰。
PROPAGATION_SUPPORTS:支持當(dāng)前事務(wù)第美,如果當(dāng)前存在事務(wù),就加入該事務(wù)陆爽,如果當(dāng)前不存在事務(wù)什往,就以非事務(wù)執(zhí)行。
PROPAGATION_MANDATORY:支持當(dāng)前事務(wù)慌闭,如果當(dāng)前存在事務(wù)别威,就加入該事務(wù),如果當(dāng)前不存在事務(wù)驴剔,就拋出異常省古。
PROPAGATION_REQUIRES_NEW:創(chuàng)建新事務(wù),無(wú)論當(dāng)前存不存在事務(wù)仔拟,都創(chuàng)建新事務(wù)衫樊。
PROPAGATION_NOT_SUPPORTED:以非事務(wù)方式執(zhí)行操作,如果當(dāng)前存在事務(wù)利花,就把當(dāng)前事務(wù)掛起。
PROPAGATION_NEVER:以非事務(wù)方式執(zhí)行载佳,如果當(dāng)前存在事務(wù)炒事,則拋出異常。
PROPAGATION_NESTED:如果當(dāng)前存在事務(wù)蔫慧,則在嵌套事務(wù)內(nèi)執(zhí)行挠乳。如果當(dāng)前沒(méi)有事務(wù),則按REQUIRED屬性執(zhí)行姑躲。
Spring的常用注解
-
IOC注解
- @Component(任何層) @Controller @Service @Repository(dao): 用于實(shí)例化對(duì)象
- @Scope : 設(shè)置Spring對(duì)象的作用域
- @PostConstruct睡扬、@PreDestroy : 用于設(shè)置Spring創(chuàng)建對(duì)象在對(duì)象創(chuàng)建之后和銷毀之前要執(zhí)行的方法
- @Bean: 表在方法上,用于將方法的返回值對(duì)象放入容器
-
DI注解
- @Value: 簡(jiǎn)單屬性的依賴注入
- @Autowired: 對(duì)象屬性的依賴注入
- @Qualifier: 要和@Autowired聯(lián)合使用,代表在按照類型匹配的基礎(chǔ)上黍析,再按照名稱匹配卖怜。
- @Resource 按照類型和屬性名稱依賴注入 @Resource =@Autowired+@Qualifier
- @ComponentScan: 組件掃描
-
AOP注解
- @Before 前置通知,會(huì)在運(yùn)行原有方法前面執(zhí)行
- @AfterReturning 后置通知阐枣,會(huì)在運(yùn)行原有方法后面執(zhí)行马靠,前提原有方法不發(fā)生異常。
- @AfterThrowing 異常通知蔼两,會(huì)在運(yùn)行原有方法發(fā)生異常的時(shí)候運(yùn)行
- @After 最終通知甩鳄,會(huì)在運(yùn)行原有方法后運(yùn)行, 無(wú)論原有方法是否發(fā)生異常都會(huì)運(yùn)行
- @Around 環(huán)繞通知额划,一個(gè)環(huán)繞就可以實(shí)現(xiàn)上面4個(gè)位置的增強(qiáng)
- @Aspect 標(biāo)識(shí)當(dāng)前類為切面類
- @Pointcut切入點(diǎn)表達(dá)式
-
事務(wù)注解
- @Transactional 此注解可以標(biāo)在類上妙啃,也可以標(biāo)在方法上,表示當(dāng)前類中的方法具有事務(wù)管理功能俊戳。
-
其他配置
- @PropertySource: 用于引入其它的properties配置文件
- @Import: 在一個(gè)配置類中導(dǎo)入其它配置類的內(nèi)容
- @Configuration: 被此注解標(biāo)注的類,會(huì)被Spring認(rèn)為是配置類揖赴。Spring在啟動(dòng)的時(shí)候會(huì)自動(dòng)掃描并加載所有配置類馆匿,然后將配置類中bean放入容器
Spring事務(wù)的實(shí)現(xiàn)方式和實(shí)現(xiàn)原理
- Spring事務(wù)的本質(zhì)其實(shí)就是
數(shù)據(jù)庫(kù)對(duì)事務(wù)
的支持,沒(méi)有數(shù)據(jù)庫(kù)的事務(wù)支持储笑,Spring是無(wú)法提供事務(wù)功能的甜熔。 - Spring事務(wù)會(huì)調(diào)用數(shù)據(jù)庫(kù)設(shè)置
手動(dòng)控制
事務(wù)set autocommit = 0
,之后通過(guò)commit
提交和ro11back
回滾突倍,數(shù)據(jù)庫(kù)底層是通過(guò)binlog
或者redolog
實(shí)現(xiàn)的腔稀。 - Spring事務(wù)實(shí)現(xiàn)主要有兩種方法
-
編程式
(編碼控制事務(wù)),使用Spring框架提供的事務(wù)管理器模板TransactionTemplate
相關(guān)的方法實(shí)現(xiàn)事務(wù)控制羽历,會(huì)造成代碼重復(fù)幾余焊虏。 -
聲明式
,利用注解@Transactiona
或者aop
配置
-
Spring中@Autowired和@Resource的區(qū)別
-
@Autowired
是Spring框架的秕磷,默認(rèn)按照byType
自動(dòng)裝配诵闭,@Resource
是javax包下的和jdk8及以下版本存在,默認(rèn)byName
自動(dòng)裝配 -
@Autowired
和@Qualifier
一起用可以自定義別名注入澎嚣,@Resource
可以單獨(dú)使用
Spring的Bean生命周期
-
簡(jiǎn)單版
- Spring的Bean生命周期疏尿,就是Bean的創(chuàng)建到銷毀的過(guò)程
- 初始化容器階段
- 創(chuàng)建Bean對(duì)象(內(nèi)存分配),執(zhí)行構(gòu)造方法
- 執(zhí)行屬性注入(set方法易桃、依賴注入)
- 執(zhí)行Bean的初始化方法
- 使用Bean
- 執(zhí)行業(yè)務(wù)操作
- 關(guān)閉容器
- 執(zhí)行Bean銷毀方法
-
復(fù)雜版
- Spring啟動(dòng)褥琐,查找并加載需要被Spring管理的bean,進(jìn)行Bean的實(shí)例化
- Bean實(shí)例化后對(duì)將Bean的依賴和值注入到Bean的屬性中
- 如果Bean實(shí)現(xiàn)了
BeanNameAware
接口的話晤郑,Spring將Bean的id傳遞給setBeanName()
方法 - 如里Bean實(shí)現(xiàn)了
BeanFactoryAware
接口的話敌呈,Spring將調(diào)用setBeanFactroy()
方法,將BeanFactroy容器實(shí)例傳入 - 如果Bean實(shí)現(xiàn)了
ApplicationContextAware
接口的話造寝,Spring將調(diào)用Bean的setApplicationContext()
方法磕洪,將Bean所在應(yīng)用上下文引用傳入進(jìn)來(lái) - 如果Bean實(shí)現(xiàn)了
BeanPostProcessor
接口,Spring就將調(diào)用他們的postProcessBeforelnitialization()
方法 - 如果Bean實(shí)現(xiàn)了
InitializingBean
接口诫龙,Spring將會(huì)調(diào)用他們的afterPropertiesSet
方法析显。類似的,如果Bean使用init-method
聲明了初始化方法赐稽,該方法也會(huì)被調(diào)用 - 如果Bean實(shí)現(xiàn)了
BeanPostProcessor
接口叫榕,Spring就將調(diào)用他們的postProcessAfterlnitialization()
萬(wàn)法 - 此時(shí),Bean已經(jīng)準(zhǔn)備就緒姊舵,可以被應(yīng)用程序使用了晰绎。他們將一直駐留在應(yīng)用上下文中,直到應(yīng)用上下文被銷毀
- 如果Bean實(shí)現(xiàn)了
DisposableBean
接口,Spring將調(diào)用它的destory()
接口方法括丁,同樣荞下,如果bean使用了destoy-method
聲明銷毀方法,該方法也會(huì)被調(diào)用
SpringMVC中攔截器的使用步驟?
- 攔截器尖昏,可以攔截器的方法仰税,可以做一些通用增強(qiáng)的功能
- 定義攔截器類
- SpringMVC為我們提供了攔截器規(guī)范的接口,創(chuàng)建一個(gè)類實(shí)現(xiàn)
HandTerInterceptor
抽诉,重寫接口中的抽象方法 -
preHandle
方法:在調(diào)用處理器之前調(diào)用該方法陨簇,如果該方法返回true則請(qǐng)求繼續(xù)向下進(jìn)行,否則請(qǐng)求不會(huì)繼續(xù)向下進(jìn)行迹淌,控制器也不會(huì)調(diào)用 -
afterCompletion
方法:在前端控制器渲染頁(yè)面河绽,完成之后調(diào)用此方法
SpringMVC的有哪些主要組件
- 前端控制器
Dispatcherservlet
:接收請(qǐng)求、響應(yīng)結(jié)果唉窃,相當(dāng)于轉(zhuǎn)發(fā)器耙饰,有了Dispatcherservlet
就減少了其它組件之間的耦合度 - 處理器映射器
HandlerMapping
:根據(jù)請(qǐng)求的URL來(lái)查找Handler
- 處理器適配器
HandlerAdapter
:負(fù)責(zé)執(zhí)行Handler
- 處理器
Handler
:處理業(yè)務(wù)邏輯的Java類(Contro1ler
類) - 視圖解析器
viewResolver
:進(jìn)行視圖的解析,根據(jù)視圖邏輯名將ModeTAndview
解析成真正的視圖 (view) 并跳轉(zhuǎn)到視圖頁(yè)面
SpringMVC和SpringBoot的關(guān)系
- SpringMVC纹份,提供了一種輕度耦合的方式來(lái)進(jìn)行Web開發(fā)苟跪,它是Spring的一個(gè)模塊,是一個(gè)Web層的框架
- SpringBoot蔓涧,實(shí)現(xiàn)了自動(dòng)配置件已,降低了Spring項(xiàng)目搭建的復(fù)雜度
- SpringBoot只是輔助簡(jiǎn)化Spring項(xiàng)目的搭建過(guò)程的,如果搭建的是Web項(xiàng)目元暴,Web層采用SpringMVC拨齐,那么SpringMVC的工作原理還是跟原來(lái)一樣,并沒(méi)有因?yàn)槭褂肧pringBoot而改變
SpringMVC各個(gè)組件的執(zhí)行流程
- 用戶發(fā)送請(qǐng)求到前端控制器
DispatchServlet
- 前端控制器
DispatchServlet
收到請(qǐng)求后昨寞,調(diào)用處理器映射器HandlerMapping
,進(jìn)行查找處理器Handler
- 處理器映射器
HandlerMapping
厦滤,根據(jù)URL找到具體的處理器Handler
援岩,以及對(duì)應(yīng)的攔截器HandlerIntercepter
,將它們一起返回給前端控制器DispatchServlet
- 前端控制器
DispatchServlet
掏导,調(diào)用處理器適配器HandlerAdapter
享怀,進(jìn)行處理 - 處理器適配器
HandlerAdapter
則調(diào)用處理器Handler
(也就是Controller)進(jìn)行處理,首先將請(qǐng)求參數(shù)映射到處理器的方法參數(shù)上趟咆,然后調(diào)用處理方法進(jìn)行處理添瓷,以及返回結(jié)果(ModelAndView
模型視圖對(duì)象),交回給前端控制器DispatchServlet
- 前端控制器
DispatchServlet
則將ModelAndView
模型視圖對(duì)象值纱,交給視圖解析器ViewReslover
鳞贷,視圖解析器則會(huì)解析視圖地址
,進(jìn)行請(qǐng)求轉(zhuǎn)發(fā)
跳轉(zhuǎn)到視圖頁(yè)面虐唠,使用視圖數(shù)據(jù)進(jìn)行渲染視圖搀愧,最后再渲染結(jié)果交回給前端控制器DispatchServlet
- 前端控制器
DispatchServlet
,將渲染結(jié)果返回給瀏覽器 - 如果是
異步請(qǐng)求
,返回JSON數(shù)據(jù)
咱筛,那么則不需要進(jìn)行視圖解析搓幌,直接將Json字符串
數(shù)據(jù)返回給瀏覽器
SpringMVC的常用注解
-
@RequestMapping
,用于處理所有請(qǐng)求類型的Url映射的注解迅箩「瘸睿可用于類上或方法上- 用于類上時(shí),表示該類的所有方法都是以該地址作為父路徑
- 用于方法上時(shí)饲趋,表示該方法能處理的資源路徑
-
@RequestMapping
還衍生出4個(gè)常用的注解-
@GetMapping
拐揭,該注解表示處理Get
請(qǐng)求 -
@PutMapping
,該注解表示處理Put
請(qǐng)求 -
@DeleeteMapping
篙贸,該注解表示處理Delete
請(qǐng)求 -
@PostMapping
投队,該注解表示處理Post
請(qǐng)求
-
-
@RequestBody
,該注解表示接收Http請(qǐng)求傳遞的json格式的請(qǐng)求體爵川,并將json格式請(qǐng)求體轉(zhuǎn)換為Java對(duì)象 -
@ResponseBody
敷鸦,該注解表示該controller方法返回的對(duì)象,會(huì)轉(zhuǎn)換為json字符串返回給客戶端 -
@PathVariable
寝贡,該注解表示方法綁定的url中的占位符參數(shù)到指定的方法參數(shù)扒披,通過(guò)@Pathvariable("要獲取的參數(shù)名")
來(lái)指定 -
@RequestParam
,該注解表示方法參數(shù)接收Http請(qǐng)求的參數(shù)之前圃泡,做一些限制-
value
屬性碟案,指定該方法參數(shù)接收哪一個(gè)請(qǐng)求參數(shù) -
required
屬性,指定該方法參數(shù)對(duì)應(yīng)的請(qǐng)求參數(shù)是否必傳 -
defaultValue
屬性颇蜡,當(dāng)該方法參數(shù)對(duì)應(yīng)的請(qǐng)求參數(shù)未傳時(shí)价说,參數(shù)的默認(rèn)值
-
-
@ControllerAdvice
,用于在類上风秤,表示該類是一個(gè)全局異常處理器類 -
@ExceptionHandler(Exception.class)
鳖目,用于異常處理器的方法上,表示該方法能處理的異常類型
SpringBoot的常用注解
- @SpringBootApplication注解缤弦,SpringBoot項(xiàng)目的核心注解领迈,每個(gè)SpringBoot啟動(dòng)類上都有,用于引導(dǎo)SpringBoot項(xiàng)目啟動(dòng)和加載
- @ComponentScan注解碍沐,用于掃描Spring的組件狸捅,并將其加入IOC容器
- @Configuration注解,聲明該類為配置類
- @ConditionOnClass注解累提,一般與@Configuration注解同時(shí)使用尘喝,項(xiàng)目導(dǎo)入@ConditionOnClass注解聲明的類時(shí),@Configuration配置類中刻恭,使用@Bean的方法才會(huì)被調(diào)用瞧省,才會(huì)構(gòu)建方法返回的對(duì)象
- @ControllerAdvice和@RestControllerAdvice扯夭,聲明該類為全局異常處理類
Spring框架中都用到了哪些設(shè)計(jì)模式
- 工廠模式,BeanFactory就是簡(jiǎn)單工廠的體現(xiàn)鞍匾,用來(lái)創(chuàng)建對(duì)象的實(shí)例
- 單例模式交洗,Bean默認(rèn)為單例模式
- 代理模式,Spring的AOP功能用到了JDK動(dòng)態(tài)代理與CGLIB動(dòng)態(tài)代理
- 模板模式橡淑,用于來(lái)解決代碼重復(fù)的問(wèn)題构拳,比如RestTemplate、JmsTemplate梁棠、JpaTemplate置森、TransactionTemplate
- 觀察模式,包含被觀察者與觀察者兩類對(duì)象符糊,一個(gè)被觀察者可以有若干個(gè)觀察者凫海,一旦被觀察者的狀態(tài)變化,所有觀察者都會(huì)得到通知男娄。Spring的事件驅(qū)動(dòng)模型就是觀察者模式的應(yīng)用行贪。Spring中的事件監(jiān)聽器的開發(fā),當(dāng)事件(被觀察者)發(fā)生時(shí)模闲,會(huì)自動(dòng)觸發(fā)監(jiān)聽器(觀察者)的運(yùn)行建瘫。例如Spring中的一種Listener,ApplicationListener
SpringBoot的優(yōu)勢(shì)
-
版本鎖定
尸折,解決的是maven依賴容易沖突的問(wèn)題啰脚,SpringBoot提供的父工程中集成了常用、且測(cè)試過(guò)的依賴庫(kù)版本 -
起步依賴
(簡(jiǎn)化配置依賴)实夹,提供了眾多的starter啟動(dòng)器橄浓,starter的依賴中集成了需要的依賴以及版本,進(jìn)行了統(tǒng)一的控制亮航,解決了某一個(gè)功能需要整合大量的jar包與依賴的問(wèn)題 -
自動(dòng)配置
(簡(jiǎn)化配置)贮配,解決了整合眾多框架與技術(shù)的配置文件、配置類過(guò)多的問(wèn)題塞赂,使用約定大于配置的思想,提供了大量的默認(rèn)配置 -
內(nèi)置Tomcat
(簡(jiǎn)化部署)昼蛀,通過(guò)內(nèi)置Tomcat部署與運(yùn)行宴猾,無(wú)需使用外置Tomcat即可直接運(yùn)行Web應(yīng)用 - 總結(jié):SpringBoot被稱為搭建Web應(yīng)用的腳手架,主要作用就是幫助開發(fā)者快速構(gòu)建一個(gè)龐大的Spring項(xiàng)目叼旋,并盡可能減少xml配置與配置類仇哆,做到開箱即用,快速上手夫植,讓開發(fā)者關(guān)注業(yè)務(wù)邏輯而非配置
說(shuō)一下SpringMVC的統(tǒng)一異常處理的思想和實(shí)現(xiàn)方式
- 使用SpringMVC后讹剔,我們的代碼將有SpringMVC來(lái)負(fù)責(zé)調(diào)用油讯,所以我們的代碼導(dǎo)致的異常,最終都會(huì)拋出到框架中延欠,然后由框架指定異常類來(lái)進(jìn)行統(tǒng)一處理
- 實(shí)現(xiàn)統(tǒng)一異常處理的方式:
- 方式一:創(chuàng)建一個(gè)類陌兑,作為自定義異常處理器,需要實(shí)現(xiàn)
HandlerExpcetionResolver
接口由捎,并實(shí)現(xiàn)接口里面的異常處理方法兔综,然后將這個(gè)類加入到IOC容器中 - 方式二:創(chuàng)建一個(gè)類,在類上使用
@ControllerAdvice
注解或RestControllerAdvice
狞玛,在類中定義異常處理方法软驰,并在處理方法上添加@ExceptionHandler
注解,在該注解上有一個(gè)value屬性心肪,用于指定這個(gè)異常處理方法能處理哪個(gè)類型的異常
- 方式一:創(chuàng)建一個(gè)類陌兑,作為自定義異常處理器,需要實(shí)現(xiàn)
在SpringMVC中锭亏,如果想通過(guò)請(qǐng)求轉(zhuǎn)發(fā)將數(shù)據(jù)傳遞到前臺(tái)頁(yè)面,有幾種寫法硬鞍?
- 方式一:直接使用reuqest域?qū)ο筮M(jìn)行數(shù)據(jù)傳遞
request.setAttirbuate("name", value);
- 方式二:使用Model類進(jìn)行傳值慧瘤,它的底層會(huì)將數(shù)據(jù)放入request域進(jìn)行數(shù)據(jù)的傳遞
model.addAttribuate("name", value);
- 方式三:使用ModelMap進(jìn)行傳值,底層會(huì)將數(shù)據(jù)放入request域進(jìn)行數(shù)據(jù)的傳遞
modelmap.put("name", value);
- 方式四:借用ModelAndView在其中設(shè)置數(shù)據(jù)和視圖
mv.addobject("name", value);
mv.setView("success");
return mv;
SpringBoot的啟動(dòng)器starter是什么膳凝?它的執(zhí)行原理碑隆?
- 什么是starter?
- starter啟動(dòng)器,可以通過(guò)啟動(dòng)器集成其他的技術(shù)蹬音,比如說(shuō):
web
上煤,mybatis
,redis
等著淆,可以提供對(duì)應(yīng)技術(shù)的開發(fā)和運(yùn)行環(huán)境 - 比如: pom中引入
spring-boot-starter-web
劫狠,就可以進(jìn)行web開發(fā)
- starter啟動(dòng)器,可以通過(guò)啟動(dòng)器集成其他的技術(shù)蹬音,比如說(shuō):
- starter執(zhí)行原理?
- SpringBoot在啟動(dòng)時(shí)永部,會(huì)掃描jar包中名為的
spring.factories
配置文件独泞,根據(jù)配置文件,加載自動(dòng)配置類苔埋,配置文件的格式為key=value
懦砂,value配置了很多需要Spring加載的類 - Spring會(huì)去加載這些自動(dòng)配置類,Spring讀取后组橄,就會(huì)創(chuàng)建這些類的對(duì)象荞膘,然后放到Spring容器中,后期就會(huì)Spring的容器中獲取這些對(duì)象
Redis的數(shù)據(jù)類型有哪些玉工?
Redis一共有5種數(shù)據(jù)類型:
- String羽资,字符串類型,最基礎(chǔ)的類型遵班,最常用
- Set屠升,可以存儲(chǔ)多個(gè)值潮改,無(wú)序,存儲(chǔ)的數(shù)據(jù)不可重復(fù)
- List腹暖,可以存儲(chǔ)多個(gè)值汇在,有序,存儲(chǔ)數(shù)據(jù)可以重復(fù)微服,存儲(chǔ)順序就是排序的順序趾疚,可以實(shí)現(xiàn)隊(duì)列和棧
- Hash Value,鍵值對(duì)以蕴,可以對(duì)里面的value靈活地修改
- SortSet(ZSet)糙麦,可以存儲(chǔ)多個(gè)值,有序丛肮,存儲(chǔ)元素不可重復(fù)赡磅,可以實(shí)現(xiàn)實(shí)時(shí)排序
SpringCloud常用組件
- Eureka:服務(wù)發(fā)現(xiàn)與注冊(cè),由Netfilx開源
- Nacos:服務(wù)發(fā)現(xiàn)與注冊(cè)宝与,以及配置中心的管理功能焚廊,由阿里巴巴開源
- SpringCloudGateway:微服務(wù)網(wǎng)關(guān),微服務(wù)統(tǒng)一路由习劫,統(tǒng)一鑒權(quán)咆瘟、跨域、限流等功能
- Feign:微服務(wù)之間遠(yuǎn)程過(guò)程調(diào)用诽里,由Netflix開源
- Ribbon:負(fù)載均衡組件袒餐,在網(wǎng)關(guān)路由和Feign遠(yuǎn)程過(guò)程調(diào)用中,底層都會(huì)使用到Ribbon實(shí)現(xiàn)負(fù)載均衡
Eureka與Nacos的區(qū)別谤狡?
- 共同點(diǎn)
- 都支持服務(wù)注冊(cè)與服務(wù)拉取
- 都提供服務(wù)提供者心跳方式進(jìn)行健康檢測(cè)(Eureka30秒一次灸眼,Nacos15秒一次)
- 區(qū)別
- Nacos支持服務(wù)端主動(dòng)檢測(cè)提供者的狀態(tài),臨時(shí)實(shí)例采用心跳機(jī)制墓懂,非臨時(shí)實(shí)例(常駐實(shí)例)采用主動(dòng)檢測(cè)機(jī)制
- 臨時(shí)實(shí)例心跳不正常會(huì)被剔除焰宣,而非臨時(shí)實(shí)例(常駐實(shí)例)則不會(huì)被剔除
- Nacos支持服務(wù)列表變更后,進(jìn)行消息推送捕仔,服務(wù)列表更新更及時(shí)(Eureka是每次發(fā)起遠(yuǎn)程調(diào)用時(shí)拉取匕积,Nacos則是定時(shí)更新)
- Eureka是短連接操作(每次拉取完,就斷開連接)榜跌,Nacos是長(zhǎng)連接操作(netty實(shí)現(xiàn)闸天,一直連接,每次拉取完斜做,不會(huì)斷開)
- Nacos還可以作為微服務(wù)的配置中心,Eureka則不能
Elasticsearch比MySQL的優(yōu)勢(shì)在哪里湾揽?(為什么要使用Elasticsearch瓤逼?)
- MySQL的海量數(shù)據(jù)時(shí)笼吟,搜索效率比較低,使用Like關(guān)鍵詞霸旗,如果%放左邊贷帮,執(zhí)行全表掃描,導(dǎo)致性能差诱告,而Elasticsearch采用倒排索引法檢測(cè)數(shù)據(jù)撵枢,從而效率更高
- MySQL的搜索功能比較弱,只有l(wèi)ike這種模糊搜索精居,而Elasticsearch擁有大量復(fù)雜場(chǎng)景搜索的API(高亮顯示锄禽,拼音搜索,地理位置檢索)靴姿,更加適合數(shù)據(jù)搜索場(chǎng)景
請(qǐng)說(shuō)說(shuō)Elasticsearch倒排索引原理沃但?
首先,Elasticsearch將文檔數(shù)據(jù)進(jìn)行索引構(gòu)建佛吓。將文檔數(shù)據(jù)需要分詞的字段內(nèi)容使用分詞器進(jìn)行分詞宵晚,并記錄每個(gè)詞條和原文檔的出現(xiàn)位置和出現(xiàn)頻率等信息,構(gòu)建出文檔的索引庫(kù)
然后维雇,用戶搜索時(shí)淤刃,可以對(duì)關(guān)鍵詞進(jìn)行分詞,使用分詞后詞條來(lái)匹配索引庫(kù)吱型,在索引庫(kù)匹配到記錄后逸贾,通過(guò)文檔位置和頻率信息,反查具體的文檔數(shù)據(jù)
請(qǐng)說(shuō)說(shuō)什么是分詞器唁影?ES有哪些常用的分詞器耕陷?
- 分詞器是Elasticsearch用于對(duì)內(nèi)容進(jìn)行分詞的工具(程序),Elasticsearch內(nèi)置許多分詞器据沈,默認(rèn)使用Standard標(biāo)準(zhǔn)分詞器哟沫,而標(biāo)準(zhǔn)分詞器對(duì)中文支持并不好友(因?yàn)樗鼘?duì)中文進(jìn)行單字分詞)
- 所以在開發(fā)中進(jìn)行中文分詞時(shí)使用第三方的ik分詞器,ik分詞器內(nèi)置有ik_smart和ik_max_word算法锌介,ik_smart是最小分詞器法嗜诀,ik_max_word是最細(xì)分詞法。
MySQL孔祸、Redis隆敢、MongoDB、Elasticsearch各自的優(yōu)勢(shì)崔慧?
- MySQL:是關(guān)系型數(shù)據(jù)庫(kù)拂蝎,磁盤。有復(fù)雜表關(guān)系(一對(duì)一惶室,一對(duì)多温自,多對(duì)多)玄货,并且有完善事務(wù)機(jī)制(ACID)。例如:用戶悼泌、訂單松捉、商品
- Redis: 非關(guān)系數(shù)據(jù)庫(kù),內(nèi)存馆里。Redis建議只存儲(chǔ)熱點(diǎn)(用戶查詢頻率極高)的數(shù)據(jù)隘世,且數(shù)據(jù)量相對(duì)小的數(shù)據(jù)。例如:秒殺的庫(kù)存量鸠踪、手機(jī)驗(yàn)證碼丙者、用戶token
- MongoDB: 非關(guān)系數(shù)據(jù)庫(kù),磁盤慢哈。MongoDB適合相對(duì)高頻擦寫(增刪改)的海量數(shù)據(jù)蔓钟。例如:評(píng)論
- Elasticsearch: 非關(guān)系數(shù)據(jù)庫(kù),磁盤卵贱。Elasticsearch適合海量數(shù)據(jù)的復(fù)雜檢索滥沫。例如:商品搜索
- 效率: Redis > MongoDB /Elasticsearch:> MySQL
請(qǐng)問(wèn)Elasticserach中的match和term檢索有什么區(qū)別?
- match:全文檢索键俱,分詞兰绣,用在text類型中
- 先對(duì)搜索內(nèi)容進(jìn)行分詞,得到詞條
- 使用詞條匹配倒排索引编振,得到文檔ID
- 再使用文檔ID缀辩,查詢具體的文檔記錄,進(jìn)行聚合(并集或交集)
- term:精確匹配踪央,不分詞臀玄,用在keyword、boolean畅蹂、日期健无、數(shù)值類型中
- 使用搜索內(nèi)容,使用搜索全文匹配索引庫(kù)液斜,得到文檔ID
- 使用文檔ID累贤,查詢具體的文檔記錄,進(jìn)行聚合(并集或交集)
請(qǐng)問(wèn)Elasticsearch如何實(shí)現(xiàn)搜索附近的景點(diǎn)少漆?
- 在景點(diǎn)表中臼膏,保存景點(diǎn)的經(jīng)度和緯度
- 前端將用戶的經(jīng)緯度坐標(biāo),上傳到后端服務(wù)中
- 后端根據(jù)用戶的經(jīng)緯度坐標(biāo)示损,使用Elasticserach的geo_distance渗磅,做升序排序,參數(shù)是地理坐標(biāo)、升序或降序排序
"sort": [
{
"_geo_distance": "22.57.113.88",
"order": "asc",
"unit": "km"
}
]
請(qǐng)問(wèn)在Elasticserach中始鱼,如何實(shí)現(xiàn)提升指定搜索結(jié)果的權(quán)重论巍?(類似百度搜索結(jié)果中的廣告競(jìng)價(jià)排名)
首先,Elasticsearch默認(rèn)情況下风响,使用BM25算法(5.1版本之前,使用TF-IDF算法)丹禀,計(jì)算_score得到算分状勤,按照計(jì)算排序。
-
TF-IDF算法:TF(詞頻) * IDF(逆文檔率)
- TF:詞頻双泪,詞條在文檔中出現(xiàn)的頻率
- IDF:逆文檔率持搜,計(jì)算詞條在所有文檔中的權(quán)重(出現(xiàn)越多文檔,權(quán)重越低焙矛,反之則越高)
BM25:是TF-IDF算法的升級(jí)版葫盼,單個(gè)詞條的算分有一個(gè)上限,不至于過(guò)高村斟,讓曲線更加平滑
如果希望改變指定結(jié)果的權(quán)重贫导,可以使用
function_score
函數(shù),進(jìn)行提分function_score函數(shù)大體有3部分:
1)原始查詢條件
2)過(guò)濾條件和權(quán)重分值蟆盹,過(guò)濾條件就是哪些部分的文檔需要提分
3)加權(quán)模式孩灯,對(duì)權(quán)重分值進(jìn)行sum、avg逾滥、相乘等規(guī)則
在Elasticsearch中峰档,如何實(shí)現(xiàn)景點(diǎn)拼音搜索
- 在Elasticsearch安裝拼音分詞插件
- 因?yàn)槠匆舴衷~器只是把詞的每個(gè)字進(jìn)行轉(zhuǎn)拼音,無(wú)法實(shí)現(xiàn)對(duì)一個(gè)詞進(jìn)行拼音轉(zhuǎn)換寨昙,不太滿足項(xiàng)目需求
- 這時(shí)就需要結(jié)合ik分詞器讥巡,進(jìn)行自定義分詞器
- 自定義分詞器,需要配置為先使用ik分詞器進(jìn)行中文分詞舔哪,然后再將這些詞進(jìn)行拼音分詞器欢顷,進(jìn)行轉(zhuǎn)換為拼音
- 但是在搜索中,為了避免中文轉(zhuǎn)為拼音進(jìn)行搜索尸红,所以搜索時(shí)還是使用ik分詞器進(jìn)行分詞吱涉,使用
search_analayzer
來(lái)指定,如:
"analyzer": "my_analyzer",
"search_analyzer": "ik_max_word"
在Elasticsearch中外里,如何實(shí)現(xiàn)搜索景點(diǎn)時(shí)怎爵,關(guān)鍵字高亮
- 在景點(diǎn)索引庫(kù)中,添加一個(gè)
completion
字段盅蝗,該字段的內(nèi)容是數(shù)組鳖链,在里面填充需要補(bǔ)充的數(shù)據(jù) - 在用戶搜索時(shí),每次輸入關(guān)鍵詞時(shí)丈钙,使用
suggest
搜索灶平,進(jìn)行suggestion
搜索,把結(jié)果列表返回給前端
GET /test/_search
{
"suggest":{
"title_suggest":{
"text":"s",
"completion":{
"field":"title",
"skip_duplicates":true,
"size":10
}
}
}
在Elasticserach中蚯涮,如何與MySQL進(jìn)行數(shù)據(jù)同步灌侣?
- 同步方式(不推薦)推捐,在對(duì)MySQL的數(shù)據(jù)進(jìn)行增刪改時(shí),同步調(diào)用ES更新數(shù)據(jù)侧啼,這種方式會(huì)導(dǎo)致整個(gè)增刪改功能的耗時(shí)增加牛柒,以及級(jí)聯(lián)失敗
- 異步方式,使用MQ發(fā)送異步消息痊乾,實(shí)現(xiàn)增量同步
- 在生產(chǎn)者(如后臺(tái)管理系統(tǒng))皮壁,的增刪改方法中,調(diào)用MQ發(fā)送消息哪审,帶上主鍵ID給MQ
- 在消費(fèi)者(如前臺(tái)服務(wù))蛾魄,編寫MQ消息監(jiān)聽類,針對(duì)增加湿滓、更新滴须、刪除消息,對(duì)ES進(jìn)行增刪改數(shù)據(jù)(這種方式茉稠,如果直接在數(shù)據(jù)庫(kù)中描馅,增刪改數(shù)據(jù),會(huì)導(dǎo)致ES和MySQL數(shù)據(jù)不一致)
- 使用阿里巴巴的Canal而线,監(jiān)聽MySQL的 bin log 日志铭污,同步增刪改到ES中,這種方式膀篮,對(duì)業(yè)務(wù)速度影響最小嘹狞,能更快的響應(yīng)用戶的請(qǐng)求,用戶體驗(yàn)更好誓竿,但編程方式稍微有些復(fù)雜磅网,而且Cannal只支持MySQL,如果數(shù)據(jù)換成Oracle數(shù)據(jù)庫(kù)筷屡,則不能支持
請(qǐng)問(wèn)Elasticserach的腦裂問(wèn)題涧偷,是如何產(chǎn)生?要如何解決毙死?
- 什么是腦裂燎潮?
- 一個(gè)Elasticserach集群中,出現(xiàn)了多個(gè)master主節(jié)點(diǎn)的情況扼倘,就被稱之為腦裂
- 腦裂是如何產(chǎn)生的确封?
- master主節(jié)點(diǎn)和slave從節(jié)點(diǎn),因網(wǎng)絡(luò)延遲、網(wǎng)絡(luò)阻塞爪喘、網(wǎng)絡(luò)故障等原因颜曾,導(dǎo)致slave從節(jié)點(diǎn)無(wú)法和master主節(jié)點(diǎn)通信
- master節(jié)點(diǎn),需要處理數(shù)據(jù)秉剑,也需要處理任務(wù)派發(fā)泛豪,復(fù)雜過(guò)重,導(dǎo)致出現(xiàn)假死
- Elasticserach的JVM內(nèi)存不足侦鹏,進(jìn)程出現(xiàn)無(wú)響應(yīng)
- 以上情況候址,都可能會(huì)導(dǎo)致master節(jié)點(diǎn)臨時(shí)丟失,導(dǎo)致slave從節(jié)點(diǎn)重新選舉master節(jié)點(diǎn)(重新選主)
- 如何解決种柑?
- 修改Elasticserach的節(jié)點(diǎn)通信的默認(rèn)超時(shí)時(shí)長(zhǎng),默認(rèn)為3秒匹耕,改長(zhǎng)一些
- master主節(jié)點(diǎn)職責(zé)分離聚请,master主節(jié)點(diǎn)不作為數(shù)據(jù)存儲(chǔ)節(jié)點(diǎn),
nodes.data=false
稳其,減輕主節(jié)點(diǎn)的工作量 - 加大Elasticserach的JVM內(nèi)存驶赏,默認(rèn)1個(gè)G,改大一點(diǎn)既鞠,最好為物理機(jī)器的內(nèi)存的一半
- 修改Elasticserach的選舉票數(shù)煤傍,默認(rèn)為3票就開始重新選主,改為
(備選節(jié)點(diǎn)數(shù) / 2)+ 1
嘱蛋,ES7默認(rèn)已經(jīng)改好蚯姆,ES6或ES5需要手動(dòng)修改一下這個(gè)值
SpringCloud和SpringCloudAlibaba有什么關(guān)系?
-
SpringCloud屬于Spring家族的成員
- 組件有:Eureka(注冊(cè)中心)洒敏、Gateway(網(wǎng)關(guān))龄恋、Feign(遠(yuǎn)程過(guò)程調(diào)用)、Ribbon(客戶端負(fù)載均衡)凶伙、Hystrix(熔斷器)郭毕、SpringCloudConfig(配置中心)、Sleuth(鏈路跟蹤)
- 依賴特點(diǎn):spring-cloud-starter-netflix 開頭
-
SpringCloudAlibaba屬于SpringCloud的一套組件
- 組件有:Nacos(注冊(cè)中心和配置中心)函荣、Sentinel(熔斷器)显押、Seata(分布式事務(wù))
- 依賴特點(diǎn):spring-cloud-starter-alibaba 開頭
Sentinel和Hystrix的區(qū)別?
- 隔離方式不同傻挂,Sentinel采用信號(hào)量(計(jì)數(shù)器)乘碑,而Hystrix支持線程池和信號(hào)量,默認(rèn)采用線程池踊谋,信號(hào)量性能比線程池好
- 熔斷策略不同蝉仇,Sentinel可以支持超時(shí)比例和異常比例,而Hystrix只支持異常比例
- 限流功能不同,Sentinel有豐富的限流功能(QPS轿衔、熱點(diǎn)參數(shù)沉迹、關(guān)聯(lián)模式、鏈路模式等)害驹,Hystrix限流功能非常弱
- 第三方框架整合方面鞭呕,Sentinel可以整合SpringCloud和Dubbo,Hystrix只能整合SpringCloud
介紹一下宛官,Sentinel的熔斷機(jī)制以及使用葫松?
- Sentinel的熔斷機(jī)制,主要有線程隔離和熔斷降級(jí)底洗,啟用步驟:
- yml配置文件中腋么,開啟Sentinel的線程隔離和熔斷降級(jí)功能,然后在Sentinel控制臺(tái)頁(yè)面中亥揖,加上隔離最大并發(fā)線程數(shù)或熔斷參數(shù)配置(統(tǒng)計(jì)時(shí)間珊擂,響應(yīng)超時(shí)時(shí)間,請(qǐng)求數(shù)费变,熔斷時(shí)間等)
- 接著摧扇,給Feign接口定制一個(gè)服務(wù)降級(jí)實(shí)現(xiàn)類,在隔離和熔斷發(fā)生后挚歧,給用戶返回友好提示信息
# application.yaml配置文件
feign:
sentinel:
enabled: true # 開啟sentinel支持
//Feign接口的服務(wù)降級(jí)實(shí)現(xiàn)類
public class UserClientFallbackFactory implements FallbackFactory<UserClient> {
@Override
public UserClient create(Throwable throwable) {
return new UserClient() {
@Override
public User findById(Long id) {
User user = new User();
user.setUsername("查無(wú)此人");
user.setAddress("查無(wú)地址");
return user;
}
};
}
}
- 線程隔離:在服務(wù)消費(fèi)方加入服務(wù)調(diào)用占用線程數(shù)統(tǒng)計(jì)扛稽,一旦超過(guò)線程數(shù)上限,則做服務(wù)降級(jí)(在服務(wù)消費(fèi)方定制一個(gè)降級(jí)處理方法滑负,定制失敗消息)
- 熔斷降級(jí):在服務(wù)消費(fèi)方加入超時(shí)或異常比例統(tǒng)計(jì)程序在张,該程序一旦統(tǒng)計(jì)超過(guò)比例,一旦比例超過(guò)閾值矮慕,則做服務(wù)降級(jí)(在服務(wù)消費(fèi)方定制一個(gè)降級(jí)處理方法瞧掺,定制失敗消息),熔斷有時(shí)長(zhǎng)凡傅,時(shí)間到達(dá)會(huì)嘗試請(qǐng)求1次辟狈,如果成功,則正常調(diào)用夏跷,如果失敗哼转,繼續(xù)熔斷
請(qǐng)解釋一下SpringCloud中Feign接口調(diào)用的過(guò)程/原理?
- Feign是聲明式Http客戶端槽华,F(xiàn)eign的接口寫在服務(wù)消費(fèi)者中壹蔓,當(dāng)我們依賴注入Feign的接口時(shí),會(huì)使用JDK動(dòng)態(tài)代理猫态,生成接口的實(shí)現(xiàn)類佣蓉。當(dāng)我們調(diào)用Feign接口中的方法時(shí)披摄,會(huì)攔截我們調(diào)用的方法,接著就會(huì)解析方法上的注解
- 例如會(huì)解析接口上的
@FeignClient注解
勇凭,獲取我們配置的服務(wù)名疚膊,F(xiàn)eign通過(guò)Ribbon從注冊(cè)中心nacos中,獲取到該服務(wù)的服務(wù)列表虾标,通過(guò)負(fù)載均衡算法寓盗,挑選出1個(gè),就可以拿到服務(wù)的ip和端口璧函,拼接成url - 接著傀蚌,會(huì)解析方法上的例如
@GetMapping
、@RequestParam
注解獲取到請(qǐng)求方法蘸吓、資源地址和請(qǐng)求參數(shù) - 最終通過(guò)
RestTemplate
善炫,發(fā)起http請(qǐng)求給服務(wù)提供者,服務(wù)提供者收到請(qǐng)求后库继,處理請(qǐng)求销部,返回響應(yīng)數(shù)據(jù),F(xiàn)eign就會(huì)使用Jackson制跟,將響應(yīng)的json數(shù)據(jù)轉(zhuǎn)換為java對(duì)象返回給我們
大概解釋一下熔斷器的執(zhí)行流程?
- 熔斷器是一個(gè)統(tǒng)計(jì)超時(shí)比例酱虎、異常比例的程序雨膨,它是放在服務(wù)消費(fèi)者中的,熔斷器有3個(gè)狀態(tài):關(guān)閉读串、開啟聊记、半開
- 當(dāng)服務(wù)消費(fèi)方的請(qǐng)求的超時(shí)比例或異常比例,沒(méi)有達(dá)到閾值時(shí)恢暖,熔斷器處于一個(gè)關(guān)閉狀態(tài)排监,請(qǐng)求可以正常通過(guò)
- 而當(dāng)超過(guò)了閾值后,熔斷器狀態(tài)處于開啟狀態(tài)杰捂,請(qǐng)求會(huì)被降級(jí)舆床,降級(jí)后,會(huì)執(zhí)行我們配置的Fallback接口嫁佳,我們返回一個(gè)對(duì)用戶友好的提示信息
- 然后挨队,熔斷器會(huì)等待一段時(shí)間,例如5秒蒿往,就會(huì)進(jìn)入半開狀態(tài)盛垦,會(huì)嘗試放行1個(gè)請(qǐng)求,如果請(qǐng)求成功瓤漏,那么熔斷器切換到關(guān)閉狀態(tài)腾夯,放行后續(xù)的請(qǐng)求颊埃,如果請(qǐng)求失敗,那么切換回開啟狀態(tài)蝶俱,繼續(xù)對(duì)請(qǐng)求進(jìn)行降級(jí)
說(shuō)一下CAP定理和BASE理論
CAP定理班利,C是值一致性,A指可用性跷乐,P指容錯(cuò)性
CAP定理肥败,在說(shuō)P必然存在的,C和A只能選擇一個(gè)特性愕提。在CAP定理馒稍,只存在CP或AP
-
BASE理論,是對(duì)CAP一種補(bǔ)充:
- BA指基本可用浅侨,S代表軟狀態(tài)纽谒,E代表最終一致性CAP定理說(shuō)如果選擇了一致性,就放棄了可用性如输,BASE理論說(shuō)選擇了一致性鼓黔,只是損失了部分可用,意味處于基本可用CAP定理說(shuō)- 如果選擇了可用性不见,就放棄了一致性澳化,BASE理論說(shuō)選擇了可用行,只是存在臨時(shí)的不一致狀態(tài)稳吮,這種臨時(shí)的不一致性稱為軟狀態(tài)缎谷,這種軟狀態(tài)過(guò)后達(dá)成最終一致性
請(qǐng)問(wèn)Seata的AT模式是AP還是CP?大概解釋Seata的AT模式的原理
- AT模式是一種AP模式(強(qiáng)可用灶似,弱一致性)
- Seata的AT模式的執(zhí)行濟(jì)程大概就這樣:Seata架構(gòu)中存在二大組件列林,TC (TC是事務(wù)協(xié)調(diào)者),TM (事務(wù)管理器)RM(資源管理器)
- 首先酪惭,由TM向TC發(fā)出開始全局事務(wù)的請(qǐng)求希痴,TC在全局事務(wù)表中記錄數(shù)據(jù)。接著春感,由TM通知各人的RM調(diào)度各自的分支務(wù)砌创,這時(shí)分支事務(wù)開始執(zhí)行啦,分支事務(wù)先向TC進(jìn)行注冊(cè)分支事務(wù)鲫懒,開始執(zhí)行SOL語(yǔ)句并提交纺铭,在SQL執(zhí)行的前后,AT模式會(huì)把更新記錄的前后數(shù)據(jù)保存到undo log日志表中作為數(shù)據(jù)快照刀疙,再上報(bào)事務(wù)執(zhí)行結(jié)果給TC舶赔。最后,TC收集到所有分支事務(wù)的執(zhí)行狀態(tài)谦秧,進(jìn)行分析竟纳,決定是否提交還是回滾撵溃,如果提交,則TC向所有RM發(fā)出刪除undo log日志記錄的請(qǐng)求.如果回滾锥累,則TC向所有RM發(fā)出讀取undo log數(shù)據(jù)快照做數(shù)據(jù)恢復(fù)的請(qǐng)求
- 在AT的執(zhí)行過(guò)程中缘挑,會(huì)有臟讀的情況存在,Seata考慮到了桶略,利用全局事務(wù)鎖表语淘,在每個(gè)分支務(wù)提交之前,判斷是否能獲取全局事務(wù)鎖決定是否提交际歼,這樣就控制臟寫
什么是樂(lè)觀鎖惶翻、悲觀鎖,他們有什么差別鹅心?
-
悲觀鎖:
- 總是假設(shè)最壞的情況吕粗,每次去拿數(shù)據(jù)的時(shí)候都認(rèn)為別人會(huì)修改,所以每次在拿數(shù)據(jù)的時(shí)候都會(huì)上鎖旭愧,這樣別人想拿這個(gè)數(shù)據(jù)就會(huì)阻塞直到它拿到鎖
- 悲觀鎖的應(yīng)用場(chǎng)景:關(guān)系數(shù)據(jù)庫(kù)的行級(jí)鎖和表級(jí)鎖等
樂(lè)觀鎖:總是假設(shè)最好的情況颅筋,每次去拿數(shù)據(jù)的時(shí)候都認(rèn)為別人不會(huì)修改,所以不會(huì)上鎖输枯,但是在更新的時(shí)候议泵,會(huì)判斷在此期間別人有沒(méi)有去更新這個(gè)數(shù)據(jù)。
樂(lè)觀鎖的實(shí)現(xiàn)方式:
可以使用版本號(hào)機(jī)制和CAS算法實(shí)現(xiàn)桃熄,在數(shù)據(jù)表中加入一個(gè)數(shù)版本號(hào)version字段先口,表示數(shù)據(jù)被修改的次數(shù),當(dāng)數(shù)據(jù)被修改時(shí)蜻拨,version的值會(huì)加一
當(dāng)線程A要重新更新數(shù)據(jù)值時(shí),在讀取數(shù)據(jù)的時(shí)候也會(huì)讀取version值桩引,在提交更新時(shí)缎讼,若剛才讀取到的vesion值與當(dāng)前數(shù)據(jù)庫(kù)中的version值相等才更新,否則重新更新操作坑匠,直到更新成功
-
悲觀鎖與樂(lè)觀鎖的應(yīng)用差別:
- 樂(lè)觀鎖適用于寫少讀多的場(chǎng)景血崭。這樣可以省去了鎖的開銷,加大了系統(tǒng)的整個(gè)吞吐量
- 悲觀鎖更適合讀少寫多的場(chǎng)景厘灼。因?yàn)槿绻趯懚嗟膱?chǎng)景下使用樂(lè)觀鎖夹纫,會(huì)導(dǎo)致應(yīng)用會(huì)不斷的進(jìn)行重試,這樣反倒是降低了性能设凹,所以一般寫多的場(chǎng)景下更適合使用悲觀鎖
MySQL的引擎有幾種舰讹?
- InnoDB: MySQL默認(rèn)存儲(chǔ)引擎,支持事務(wù)闪朱。支持行級(jí)鎖和表級(jí)鎖月匣。索引采用聚族索引(索引和數(shù)據(jù)存儲(chǔ)在一個(gè)文件钻洒,提升查詢性能)
- MyISAM: 不支持事務(wù)。僅僅支持表級(jí)鎖锄开。索引采用非聚簇索(索引和數(shù)據(jù)分開存儲(chǔ)素标,查詢性能差一些)
RabbitMQ和Kafka,各有什么優(yōu)缺點(diǎn)萍悴?
- RabbitMQ:
- 優(yōu)勢(shì):
- 支持語(yǔ)言非常廣
- 穩(wěn)定性很好头遭,采用Erlang語(yǔ)言開發(fā)
- 吞吐量不算低,萬(wàn)級(jí)
- RabbitMQ官方提供7種消息發(fā)送模式癣诱,開發(fā)者輕松選擇合適的模式進(jìn)行開發(fā)即可
- 缺點(diǎn):
- 采用Erlang计维,太小眾,研究源碼很難
- 優(yōu)勢(shì):
- Kafka:
- 優(yōu)勢(shì):
- 高吞吐量狡刘,百萬(wàn)級(jí)
- 穩(wěn)定性好享潜,采用zookeeper進(jìn)行注冊(cè) (Zookeep采用CP模式,高一致模式)
- 可以應(yīng)用在大數(shù)據(jù)數(shù)據(jù)處理領(lǐng)域 (KafkaStream)
- 缺點(diǎn):
- 支持的開發(fā)語(yǔ)言比較少
- 耦合zk嗅蔬,依賴zookeeper進(jìn)行注冊(cè)
- 優(yōu)勢(shì):
什么是事務(wù)剑按?
事務(wù)是一組原子操作單元,從數(shù)據(jù)庫(kù)角度來(lái)講澜术,就是一組SQL語(yǔ)句艺蝴,要么全部執(zhí)行,要么全部失敗鸟废,就是有其中一個(gè)指令執(zhí)行有錯(cuò)誤猜敢,那么撤銷前面執(zhí)行過(guò)的所有SQL指令
-
事務(wù)的特性
-
原子性
:即不可分割性,事務(wù)要么全部被執(zhí)行盒延,要么就全部不被執(zhí)行 -
一致性
:事務(wù)的執(zhí)行使得數(shù)據(jù)庫(kù)從一種正確狀態(tài)轉(zhuǎn)換成另一種正確狀態(tài) -
隔離性
:在事務(wù)正確提交之前缩擂,不允許把該事務(wù)對(duì)數(shù)據(jù)的任何改變提供給任何其他事務(wù) -
持久性
:事務(wù)正確提交后,其結(jié)果將永久保存在數(shù)據(jù)庫(kù)中添寺,即使在事務(wù)提交后有了其他故障胯盯,事務(wù)的處理結(jié)果也會(huì)得到保存。
-
事務(wù)的四大特性和隔離級(jí)別
- 讀未提交(read Uncommited)
- 在該隔離級(jí)別中计露,所有事務(wù)都可以讀取到別的事務(wù)未提交的數(shù)據(jù)博脑,會(huì)產(chǎn)生臟讀的問(wèn)題,在項(xiàng)目中基本不用票罐,安全性太差
- 讀已提交(read commited)
- 這是大多數(shù)的數(shù)據(jù)庫(kù)的默認(rèn)隔離級(jí)別叉趣,但不是MySQL的默認(rèn)隔離級(jí)別,這個(gè)隔離級(jí)別滿足了簡(jiǎn)單的隔離该押,一個(gè)事務(wù)只能看到已經(jīng)提交的事務(wù)所有的改變疗杉,所以避免了臟讀的問(wèn)題,但由于一個(gè)事務(wù)可以看到別的事務(wù)已經(jīng)提交的數(shù)據(jù)蚕礼,隨之而來(lái)產(chǎn)生了不可重復(fù)讀和虛讀的問(wèn)題
- 可重復(fù)讀(Repeatable read)
- 這是MySQL的默認(rèn)隔離級(jí)別乡数,它確保了一個(gè)事務(wù)并發(fā)讀取數(shù)據(jù)時(shí)椭蹄,能讀取到一樣的數(shù)據(jù)。不過(guò)理論上净赴,也導(dǎo)致了幻讀(Phantom Read)绳矩。簡(jiǎn)單的來(lái)講,幻讀指當(dāng)用戶讀取某一范圍的數(shù)據(jù)行時(shí)玖翅,另一個(gè)事務(wù)又在該范圍內(nèi)插入了新行翼馆,當(dāng)用戶再次讀取該范圍的數(shù)據(jù)行時(shí),會(huì)產(chǎn)生幻讀
- 可串行化(serializable)
- 事務(wù)的最高級(jí)別金度,它通過(guò)強(qiáng)制事務(wù)排序应媚,使之不可能互相沖突,從而解決幻讀問(wèn)題猜极。簡(jiǎn)單來(lái)講中姜,它是在每個(gè)讀的數(shù)據(jù)行上加上共享鎖,在這個(gè)級(jí)別跟伏,可能會(huì)導(dǎo)致大量的超時(shí)和鎖競(jìng)爭(zhēng)丢胚,一般為了提升程序的吞吐量,不會(huì)采用該級(jí)別
Redis的數(shù)據(jù)類型和持久化方式
Redis有5種數(shù)據(jù)類型
- String
- Set
- List
- Hash
- SortedSet(ZSet)
Redis的持久化方式
- 有2種方式受扳,分別是RDB和AOF携龟,RDB的原理是對(duì)整個(gè)內(nèi)存數(shù)據(jù)進(jìn)行快照備份,文件體積小勘高,而AOF峡蟋,原理是每條操作指令都會(huì)持久化到文件,導(dǎo)致文件體積比較大
- RDB的2次備份時(shí)間間隔最小是1分鐘华望,時(shí)間長(zhǎng)蕊蝗,容易導(dǎo)入數(shù)據(jù)丟失。而AOF的默認(rèn)間隔時(shí)間為1秒1次赖舟,時(shí)間短蓬戚,數(shù)據(jù)完整性高
- 但從數(shù)據(jù)恢復(fù)速度來(lái)講,RDB比AOF快建蹄,因?yàn)轶w積小