ThreadLocal(線程變量副本)
Synchronized實(shí)現(xiàn)內(nèi)存共享恬总,ThreadLocal為每個(gè)線程維護(hù)一個(gè)本地變量。
采用空間換時(shí)間,它用于線程間的數(shù)據(jù)隔離袁稽,為每一個(gè)使用該變量的線程提供一個(gè)副本分唾,每個(gè)線程都可以獨(dú)立地改變自己的副本抗碰,而不會(huì)和其他線程的副本沖突。
ThreadLocal類中維護(hù)一個(gè)Map绽乔,用于存儲(chǔ)每一個(gè)線程的變量副本改含,Map中元素的鍵為線程對(duì)象,而值為對(duì)應(yīng)線程的變量副本迄汛。
ThreadLocal在Spring中發(fā)揮著巨大的作用捍壤,在管理Request作用域中的Bean、事務(wù)管理鞍爱、任務(wù)調(diào)度鹃觉、AOP等模塊都出現(xiàn)了它的身影。
Spring中絕大部分Bean都可以聲明成Singleton作用域睹逃,采用ThreadLocal進(jìn)行封裝盗扇,因此有狀態(tài)的Bean就能夠以singleton的方式在多線程中正常工作了祷肯。
友情鏈接:深入研究java.lang.ThreadLocal類
Java內(nèi)存模型
Java虛擬機(jī)規(guī)范中將Java運(yùn)行時(shí)數(shù)據(jù)分為六種。
1.程序計(jì)數(shù)器:是一個(gè)數(shù)據(jù)結(jié)構(gòu)疗隶,用于保存當(dāng)前正常執(zhí)行的程序的內(nèi)存地址佑笋。Java虛擬機(jī)的多線程就是通過線程輪流切換并分配處理器時(shí)間來實(shí)現(xiàn)的,為了線程切換后能恢復(fù)到正確的位置斑鼻,每條線程都需要一個(gè)獨(dú)立的程序計(jì)數(shù)器蒋纬,互不影響,該區(qū)域?yàn)椤熬€程私有”坚弱。
2.Java虛擬機(jī)棧:線程私有的蜀备,與線程生命周期相同,用于存儲(chǔ)局部變量表荒叶,操作棧碾阁,方法返回值。局部變量表放著基本數(shù)據(jù)類型些楣,還有對(duì)象的引用脂凶。
3.本地方法棧:跟虛擬機(jī)棧很像,不過它是為虛擬機(jī)使用到的Native方法服務(wù)愁茁。
4.Java堆Heap:所有線程共享的一塊內(nèi)存區(qū)域艰猬,對(duì)象實(shí)例幾乎都在這分配內(nèi)存。
5.方法區(qū):各個(gè)線程共享的區(qū)域埋市,儲(chǔ)存虛擬機(jī)加載的類信息冠桃,常量,靜態(tài)變量道宅,編譯后的代碼食听。
6.運(yùn)行時(shí)常量池:代表運(yùn)行時(shí)每個(gè)class文件中的常量表。包括幾種常量:編譯時(shí)的數(shù)字常量污茵、方法或者域的引用樱报。
友情鏈接: Java中JVM虛擬機(jī)詳解
GC垃圾收集
“你能不能談?wù)劊琷ava GC是在什么時(shí)候泞当,對(duì)什么東西迹蛤,做了什么事情?”
在什么時(shí)候:
1.新生代有一個(gè)Eden區(qū)和兩個(gè)survivor區(qū)襟士,首先將對(duì)象放入Eden區(qū)盗飒,如果空間不足就向其中的一個(gè)survivor區(qū)上放,如果仍然放不下就會(huì)引發(fā)一次發(fā)生在新生代的minor GC陋桂,將存活的對(duì)象放入另一個(gè)survivor區(qū)中逆趣,然后清空Eden和之前的那個(gè)survivor區(qū)的內(nèi)存。在某次GC過程中嗜历,如果發(fā)現(xiàn)仍然又放不下的對(duì)象宣渗,就將這些對(duì)象放入老年代內(nèi)存里去抖所。
2.大對(duì)象以及長期存活的對(duì)象直接進(jìn)入老年區(qū)。
3.當(dāng)每次執(zhí)行minor GC的時(shí)候應(yīng)該對(duì)要晉升到老年代的對(duì)象進(jìn)行分析痕囱,如果這些馬上要到老年區(qū)的老年對(duì)象的大小超過了老年區(qū)的剩余大小田轧,那么執(zhí)行一次Full GC以盡可能地獲得老年區(qū)的空間。
對(duì)什么東西:
從GC Roots搜索不到鞍恢,而且經(jīng)過一次標(biāo)記清理之后仍沒有復(fù)活的對(duì)象傻粘。
做什么:
新生代:復(fù)制清理;
老年代:標(biāo)記-清除和標(biāo)記-壓縮算法有序;
永久代:存放Java中的類和加載類的類加載器本身。
GC Roots都有哪些:
- 虛擬機(jī)棧中的引用的對(duì)象
- 方法區(qū)中靜態(tài)屬性引用的對(duì)象岛请,常量引用的對(duì)象
- 本地方法棧中JNI(即一般說的Native方法)引用的對(duì)象旭寿。
友情鏈接:Java GC的那些事(上)
友情鏈接:Java GC的那些事(下)
友情鏈接:CMS垃圾收集器介紹
Synchronized 與Lock都是可重入鎖,同一個(gè)線程再次進(jìn)入同步代碼的時(shí)候.可以使用自己已經(jīng)獲取到的鎖崇败。
Synchronized是悲觀鎖機(jī)制盅称,獨(dú)占鎖。而Locks.ReentrantLock是后室,每次不加鎖而是假設(shè)沒有沖突而去完成某項(xiàng)操作缩膝,如果因?yàn)闆_突失敗就重試,直到成功為止岸霹。
ReentrantLock適用場景
- 某個(gè)線程在等待一個(gè)鎖的控制權(quán)的這段時(shí)間需要中斷
- 需要分開處理一些wait-notify疾层,ReentrantLock里面的Condition應(yīng)用,能夠控制notify哪個(gè)線程贡避,鎖可以綁定多個(gè)條件痛黎。
- 具有公平鎖功能,每個(gè)到來的線程都將排隊(duì)等候刮吧。
友情鏈接: Synchronized關(guān)鍵字湖饱、Lock,并解釋它們之間的區(qū)別
StringBuffer是線程安全的杀捻,每次操作字符串井厌,String會(huì)生成一個(gè)新的對(duì)象,而StringBuffer不會(huì)致讥;StringBuilder是非線程安全的
友情鏈接:String仅仆、StringBuffer與StringBuilder之間區(qū)別
fail-fast:機(jī)制是java集合(Collection)中的一種錯(cuò)誤機(jī)制。當(dāng)多個(gè)線程對(duì)同一個(gè)集合的內(nèi)容進(jìn)行操作時(shí)垢袱,就可能會(huì)產(chǎn)生fail-fast事件蝇恶。
例如:當(dāng)某一個(gè)線程A通過iterator去遍歷某集合的過程中,若該集合的內(nèi)容被其他線程所改變了惶桐;那么線程A訪問集合時(shí)撮弧,就會(huì)拋出ConcurrentModificationException異常潘懊,產(chǎn)生fail-fast事件
http://www.cnblogs.com/ygj0930/p/6543350.html
happens-before:如果兩個(gè)操作之間具有happens-before 關(guān)系,那么前一個(gè)操作的結(jié)果就會(huì)對(duì)后面一個(gè)操作可見贿衍。
1.程序順序規(guī)則:一個(gè)線程中的每個(gè)操作授舟,happens- before 于該線程中的任意后續(xù)操作。
2.監(jiān)視器鎖規(guī)則:對(duì)一個(gè)監(jiān)視器鎖的解鎖贸辈,happens- before 于隨后對(duì)這個(gè)監(jiān)視器鎖的加鎖释树。
3.volatile變量規(guī)則:對(duì)一個(gè)volatile域的寫,happens- before于任意后續(xù)對(duì)這個(gè)volatile域的讀擎淤。
4.傳遞性:如果A happens- before B奢啥,且B happens- before C,那么A happens- before C嘴拢。
5.線程啟動(dòng)規(guī)則:Thread對(duì)象的start()方法happens- before于此線程的每一個(gè)動(dòng)作桩盲。
Synchronized,Volatile和四個(gè)不同點(diǎn):
1 粒度不同,前者鎖對(duì)象和類席吴,后者針對(duì)變量
2 syn阻塞赌结,volatile線程不阻塞
3 syn保證三大特性(原子性、可見性以及有序性)孝冒,volatile不保證原子性
4 syn編譯器優(yōu)化柬姚,volatile不優(yōu)化
volatile具備兩種特性:
- 保證此變量對(duì)所有線程的可見性,指一條線程修改了這個(gè)變量的值庄涡,新值對(duì)于其他線程來說是可見的量承,但并不是多線程安全的。
- 禁止指令重排序優(yōu)化穴店。
Volatile如何保證內(nèi)存可見性:
1.當(dāng)寫一個(gè)volatile變量時(shí)宴合,JMM會(huì)把該線程對(duì)應(yīng)的本地內(nèi)存中的共享變量刷新到主內(nèi)存。
2.當(dāng)讀一個(gè)volatile變量時(shí)迹鹅,JMM會(huì)把該線程對(duì)應(yīng)的本地內(nèi)存置為無效卦洽。線程接下來將從主內(nèi)存中讀取共享變量。
同步:就是一個(gè)任務(wù)的完成需要依賴另外一個(gè)任務(wù)斜棚,只有等待被依賴的任務(wù)完成后阀蒂,依賴任務(wù)才能完成。
異步:不需要等待被依賴的任務(wù)完成弟蚀,只是通知被依賴的任務(wù)要完成什么工作蚤霞,只要自己任務(wù)完成了就算完成了,被依賴的任務(wù)是否完成會(huì)通知回來义钉。(異步的特點(diǎn)就是通知)昧绣。
打電話和發(fā)短信來比喻同步和異步操作。
阻塞:CPU停下來等一個(gè)慢的操作完成以后捶闸,才會(huì)接著完成其他的工作夜畴。
非阻塞:非阻塞就是在這個(gè)慢的執(zhí)行時(shí)拖刃,CPU去做其他工作,等這個(gè)慢的完成后贪绘,CPU才會(huì)接著完成后續(xù)的操作兑牡。
非阻塞會(huì)造成線程切換增加,增加CPU的使用時(shí)間能不能補(bǔ)償系統(tǒng)的切換成本需要考慮税灌。
友情鏈接:Java并發(fā)編程之volatile關(guān)鍵字解析
CAS(Compare And Swap) 無鎖算法:
CAS是樂觀鎖技術(shù)均函,當(dāng)多個(gè)線程嘗試使用CAS同時(shí)更新同一個(gè)變量時(shí),只有其中一個(gè)線程能更新變量的值菱涤,而其它線程都失敗苞也,失敗的線程并不會(huì)被掛起,而是被告知這次競爭中失敗粘秆,并可以再次嘗試如迟。CAS有3個(gè)操作數(shù),內(nèi)存值V翻擒,舊的預(yù)期值A(chǔ)氓涣,要修改的新值B牛哺。當(dāng)且僅當(dāng)預(yù)期值A(chǔ)和內(nèi)存值V相同時(shí)陋气,將內(nèi)存值V修改為B,否則什么都不做引润。
友情鏈接:非阻塞同步算法與CAS(Compare and Swap)無鎖算法
線程池的作用:
在程序啟動(dòng)的時(shí)候就創(chuàng)建若干線程來響應(yīng)處理巩趁,它們被稱為線程池,里面的線程叫工作線程
第一:降低資源消耗淳附。通過重復(fù)利用已創(chuàng)建的線程降低線程創(chuàng)建和銷毀造成的消耗议慰。
第二:提高響應(yīng)速度。當(dāng)任務(wù)到達(dá)時(shí)奴曙,任務(wù)可以不需要等到線程創(chuàng)建就能立即執(zhí)行别凹。
第三:提高線程的可管理性。
常用線程池:ExecutorService 是主要的實(shí)現(xiàn)類洽糟,其中常用的有
Executors.newSingleThreadPool(),newFixedThreadPool(),newcachedTheadPool(),newScheduledThreadPool()炉菲。
友情鏈接:線程池原理
友情鏈接:線程池原理解析
類加載器工作機(jī)制:
1.裝載:將Java二進(jìn)制代碼導(dǎo)入jvm中,生成Class文件坤溃。
2.連接:a)校驗(yàn):檢查載入Class文件數(shù)據(jù)的正確性 b)準(zhǔn)備:給類的靜態(tài)變量分配存儲(chǔ)空間 c)解析:將符號(hào)引用轉(zhuǎn)成直接引用
3:初始化:對(duì)類的靜態(tài)變量拍霜,靜態(tài)方法和靜態(tài)代碼塊執(zhí)行初始化工作。
雙親委派模型:類加載器收到類加載請(qǐng)求薪介,首先將請(qǐng)求委派給父類加載器完成
用戶自定義加載器->應(yīng)用程序加載器->擴(kuò)展類加載器->啟動(dòng)類加載器祠饺。
友情鏈接:深入理解Java虛擬機(jī)筆記---雙親委派模型
友情鏈接:JVM類加載的那些事
一致性哈希:
Memcahed緩存:
數(shù)據(jù)結(jié)構(gòu):key,value對(duì)
使用方法:get,put等方法
Redis數(shù)據(jù)結(jié)構(gòu): String—字符串(key-value 類型)
Hash—字典(hashmap) Redis的哈希結(jié)構(gòu)可以使你像在數(shù)據(jù)庫中更新一個(gè)屬性一樣只修改某一項(xiàng)屬性值
List—列表 實(shí)現(xiàn)消息隊(duì)列
Set—集合 利用唯一性
Sorted Set—有序集合 可以進(jìn)行排序
可以實(shí)現(xiàn)數(shù)據(jù)持久化
友情鏈接: Spring + Redis 實(shí)現(xiàn)數(shù)據(jù)的緩存
索引:B+汁政,B-,全文索引
Mysql的索引是一個(gè)數(shù)據(jù)結(jié)構(gòu)道偷,旨在使數(shù)據(jù)庫高效的查找數(shù)據(jù)缀旁。
常用的數(shù)據(jù)結(jié)構(gòu)是B+Tree,每個(gè)葉子節(jié)點(diǎn)不但存放了索引鍵的相關(guān)信息還增加了指向相鄰葉子節(jié)點(diǎn)的指針试疙,這樣就形成了帶有順序訪問指針的B+Tree诵棵,做這個(gè)優(yōu)化的目的是提高不同區(qū)間訪問的性能。
什么時(shí)候使用索引:
- 經(jīng)常出現(xiàn)在group by,order by和distinc關(guān)鍵字后面的字段
- 經(jīng)常與其他表進(jìn)行連接的表祝旷,在連接字段上應(yīng)該建立索引
- 經(jīng)常出現(xiàn)在Where子句中的字段
- 經(jīng)常出現(xiàn)用作查詢選擇的字段
友情鏈接:MySQL:InnoDB存儲(chǔ)引擎的B+樹索引算法
友情鏈接:MySQL索引背后的數(shù)據(jù)結(jié)構(gòu)及算法原理
Spring IOC (控制反轉(zhuǎn)履澳,依賴注入)
Spring支持三種依賴注入方式,分別是屬性(Setter方法)注入怀跛,構(gòu)造注入和接口注入距贷。
在Spring中,那些組成應(yīng)用的主體及由Spring IOC容器所管理的對(duì)象被稱之為Bean吻谋。
Spring的IOC容器通過反射的機(jī)制實(shí)例化Bean并建立Bean之間的依賴關(guān)系忠蝗。
簡單地講,Bean就是由Spring IOC容器初始化漓拾、裝配及被管理的對(duì)象阁最。
獲取Bean對(duì)象的過程,首先通過Resource加載配置文件并啟動(dòng)IOC容器骇两,然后通過getBean方法獲取bean對(duì)象速种,就可以調(diào)用他的方法。
Spring Bean的作用域:
Singleton:Spring IOC容器中只有一個(gè)共享的Bean實(shí)例低千,一般都是Singleton作用域配阵。
Prototype:每一個(gè)請(qǐng)求,會(huì)產(chǎn)生一個(gè)新的Bean實(shí)例示血。
Request:每一次http請(qǐng)求會(huì)產(chǎn)生一個(gè)新的Bean實(shí)例棋傍。
友情鏈接: Spring框架IOC容器和AOP解析
友情鏈接:淺談Spring框架注解的用法分析
友情鏈接:關(guān)于Spring的69個(gè)面試問答——終極列表
代理的共有優(yōu)點(diǎn):業(yè)務(wù)類只需要關(guān)注業(yè)務(wù)邏輯本身,保證了業(yè)務(wù)類的重用性难审。
Java靜態(tài)代理:
代理對(duì)象和目標(biāo)對(duì)象實(shí)現(xiàn)了相同的接口瘫拣,目標(biāo)對(duì)象作為代理對(duì)象的一個(gè)屬性,具體接口實(shí)現(xiàn)中告喊,代理對(duì)象可以在調(diào)用目標(biāo)對(duì)象相應(yīng)方法前后加上其他業(yè)務(wù)處理邏輯麸拄。
缺點(diǎn):一個(gè)代理類只能代理一個(gè)業(yè)務(wù)類。如果業(yè)務(wù)類增加方法時(shí)葱绒,相應(yīng)的代理類也要增加方法感帅。
Java動(dòng)態(tài)代理:
Java動(dòng)態(tài)代理是寫一個(gè)類實(shí)現(xiàn)InvocationHandler接口,重寫Invoke方法地淀,在Invoke方法可以進(jìn)行增強(qiáng)處理的邏輯的編寫失球,這個(gè)公共代理類在運(yùn)行的時(shí)候才能明確自己要代理的對(duì)象,同時(shí)可以實(shí)現(xiàn)該被代理類的方法的實(shí)現(xiàn),然后在實(shí)現(xiàn)類方法的時(shí)候可以進(jìn)行增強(qiáng)處理实苞。
實(shí)際上:代理對(duì)象的方法 = 增強(qiáng)處理 + 被代理對(duì)象的方法
JDK和CGLIB生成動(dòng)態(tài)代理類的區(qū)別:
JDK動(dòng)態(tài)代理只能針對(duì)實(shí)現(xiàn)了接口的類生成代理(實(shí)例化一個(gè)類)豺撑。此時(shí)代理對(duì)象和目標(biāo)對(duì)象實(shí)現(xiàn)了相同的接口,目標(biāo)對(duì)象作為代理對(duì)象的一個(gè)屬性黔牵,具體接口實(shí)現(xiàn)中聪轿,可以在調(diào)用目標(biāo)對(duì)象相應(yīng)方法前后加上其他業(yè)務(wù)處理邏輯
CGLIB是針對(duì)類實(shí)現(xiàn)代理,主要是對(duì)指定的類生成一個(gè)子類(沒有實(shí)例化一個(gè)類)猾浦,覆蓋其中的方法 陆错。
Spring AOP應(yīng)用場景
性能檢測,訪問控制金赦,日志管理音瓷,事務(wù)等。
默認(rèn)的策略是如果目標(biāo)類實(shí)現(xiàn)接口夹抗,則使用JDK動(dòng)態(tài)代理技術(shù)绳慎,如果目標(biāo)對(duì)象沒有實(shí)現(xiàn)接口,則默認(rèn)會(huì)采用CGLIB代理
SpringMVC運(yùn)行原理
- 客戶端請(qǐng)求提交到DispatcherServlet
- 由DispatcherServlet控制器查詢HandlerMapping漠烧,找到并分發(fā)到指定的Controller中杏愤。
- Controller調(diào)用業(yè)務(wù)邏輯處理后,返回ModelAndView
- DispatcherServlet查詢一個(gè)或多個(gè)ViewResoler視圖解析器已脓,找到ModelAndView指定的視圖
- 視圖負(fù)責(zé)將結(jié)果顯示到客戶端
友情鏈接:Spring:基于注解的Spring MVC(上)
友情鏈接: Spring:基于注解的Spring MVC(下)
友情鏈接:SpringMVC與Struts2區(qū)別與比較總結(jié)
友情鏈接:SpringMVC與Struts2的對(duì)比
一個(gè)Http請(qǐng)求
DNS域名解析 --> 發(fā)起TCP的三次握手 --> 建立TCP連接后發(fā)起http請(qǐng)求 --> 服務(wù)器響應(yīng)http請(qǐng)求珊楼,瀏覽器得到html代碼 --> 瀏覽器解析html代碼,并請(qǐng)求html代碼中的資源(如js摆舟、css亥曹、圖片等) --> 瀏覽器對(duì)頁面進(jìn)行渲染呈現(xiàn)給用戶
設(shè)計(jì)存儲(chǔ)海量數(shù)據(jù)的存儲(chǔ)系統(tǒng):設(shè)計(jì)一個(gè)叫“中間層”的一個(gè)邏輯層邓了,在這個(gè)層恨诱,將數(shù)據(jù)庫的海量數(shù)據(jù)抓出來,做成緩存骗炉,運(yùn)行在服務(wù)器的內(nèi)存中照宝,同理,當(dāng)有新的數(shù)據(jù)到來句葵,也先做成緩存厕鹃,再想辦法,持久化到數(shù)據(jù)庫中乍丈,這是一個(gè)簡單的思路剂碴。主要的步驟是負(fù)載均衡,將不同用戶的請(qǐng)求分發(fā)到不同的處理節(jié)點(diǎn)上轻专,然后先存入緩存忆矛,定時(shí)向主數(shù)據(jù)庫更新數(shù)據(jù)。讀寫的過程采用類似樂觀鎖的機(jī)制,可以一直讀(在寫數(shù)據(jù)的時(shí)候也可以)催训,但是每次讀的時(shí)候會(huì)有個(gè)版本的標(biāo)記洽议,如果本次讀的版本低于緩存的版本玲献,會(huì)重新讀數(shù)據(jù)硼端,這樣的情況并不多,可以忍受缤言。
友情鏈接: HTTP與HTTPS的區(qū)別
友情鏈接: HTTPS 為什么更安全采驻,先看這些
友情鏈接: HTTP請(qǐng)求報(bào)文和HTTP響應(yīng)報(bào)文
友情鏈接: HTTP 請(qǐng)求方式: GET和POST的比較
Session與Cookie:Cookie可以讓服務(wù)端跟蹤每個(gè)客戶端的訪問审胚,但是每次客戶端的訪問都必須傳回這些Cookie,如果Cookie很多礼旅,則無形的增加了客戶端與服務(wù)端的數(shù)據(jù)傳輸量菲盾,
而Session則很好地解決了這個(gè)問題,同一個(gè)客戶端每次和服務(wù)端交互時(shí)各淀,將數(shù)據(jù)存儲(chǔ)通過Session到服務(wù)端懒鉴,不需要每次都傳回所有的Cookie值,而是傳回一個(gè)ID碎浇,每個(gè)客戶端第一次訪問服務(wù)器生成的唯一的ID临谱,客戶端只要傳回這個(gè)ID就行了,這個(gè)ID通常為NAME為JSESSIONID的一個(gè)Cookie奴璃。這樣服務(wù)端就可以通過這個(gè)ID悉默,來將存儲(chǔ)到服務(wù)端的KV值取出了。
Session和Cookie的超時(shí)問題苟穆,Cookie的安全問題
分布式Session框架
- 配置服務(wù)器抄课,Zookeeper集群管理服務(wù)器可以統(tǒng)一管理所有服務(wù)器的配置文件
- 共享這些Session存儲(chǔ)在一個(gè)分布式緩存中,可以隨時(shí)寫入和讀取雳旅,而且性能要很好跟磨,如Memcache,Tair攒盈。
- 封裝一個(gè)類繼承自HttpSession抵拘,將session存入到這個(gè)類中然后再存入分布式緩存中
- 由于Cookie不能跨域訪問,要實(shí)現(xiàn)Session同步型豁,要同步SessionID寫到不同域名下僵蛛。
適配器模式:將一個(gè)接口適配到另一個(gè)接口,Java I/O中InputStreamReader將Reader類適配到InputStream迎变,從而實(shí)現(xiàn)了字節(jié)流到字符流的準(zhǔn)換充尉。
裝飾者模式:保持原來的接口,增強(qiáng)原來有的功能衣形。
FileInputStream 實(shí)現(xiàn)了InputStream的所有接口驼侠,BufferedInputStreams繼承自FileInputStream是具體的裝飾器實(shí)現(xiàn)者,將InputStream讀取的內(nèi)容保存在內(nèi)存中,而提高讀取的性能泪电。
Spring事務(wù)配置方法:
- 切點(diǎn)信息般妙,用于定位實(shí)施事物切面的業(yè)務(wù)類方法
- 控制事務(wù)行為的事務(wù)屬性,這些屬性包括事物隔離級(jí)別相速,事務(wù)傳播行為碟渺,超時(shí)時(shí)間,回滾規(guī)則突诬。
Spring通過aop/tx Schema 命名空間和@Transaction注解技術(shù)來進(jìn)行聲明式事物配置苫拍。
Mybatis
每一個(gè)Mybatis的應(yīng)用程序都以一個(gè)SqlSessionFactory對(duì)象的實(shí)例為核心。首先用字節(jié)流通過Resource將配置文件讀入旺隙,然后通過SqlSessionFactoryBuilder().build方法創(chuàng)建SqlSessionFactory绒极,然后再通過sqlSessionFactory.openSession()方法創(chuàng)建一個(gè)sqlSession為每一個(gè)數(shù)據(jù)庫事務(wù)服務(wù)。
經(jīng)歷了Mybatis初始化 -->創(chuàng)建SqlSession -->運(yùn)行SQL語句 返回結(jié)果三個(gè)過程
Servlet和Filter的區(qū)別:
整的流程是:Filter對(duì)用戶請(qǐng)求進(jìn)行預(yù)處理蔬捷,接著將請(qǐng)求交給Servlet進(jìn)行處理并生成響應(yīng)垄提,最后Filter再對(duì)服務(wù)器響應(yīng)進(jìn)行后處理。
Filter有如下幾個(gè)用處:
Filter可以進(jìn)行對(duì)特定的url請(qǐng)求和相應(yīng)做預(yù)處理和后處理周拐。
在HttpServletRequest到達(dá)Servlet之前铡俐,攔截客戶的HttpServletRequest。
根據(jù)需要檢查HttpServletRequest妥粟,也可以修改HttpServletRequest頭和數(shù)據(jù)审丘。
在HttpServletResponse到達(dá)客戶端之前,攔截HttpServletResponse勾给。
根據(jù)需要檢查HttpServletResponse滩报,也可以修改HttpServletResponse頭和數(shù)據(jù)。
實(shí)際上Filter和Servlet極其相似播急,區(qū)別只是Filter不能直接對(duì)用戶生成響應(yīng)脓钾。實(shí)際上Filter里doFilter()方法里的代碼就是從多個(gè)Servlet的service()方法里抽取的通用代碼,通過使用Filter可以實(shí)現(xiàn)更好的復(fù)用旅择。
Filter和Servlet的生命周期:
1.Filter在web服務(wù)器啟動(dòng)時(shí)初始化
2.如果某個(gè)Servlet配置了 <load-on-startup >1 </load-on-startup >惭笑,該Servlet也是在Tomcat(Servlet容器)啟動(dòng)時(shí)初始化侣姆。
3.如果Servlet沒有配置<load-on-startup >1 </load-on-startup >生真,該Servlet不會(huì)在Tomcat啟動(dòng)時(shí)初始化,而是在請(qǐng)求到來時(shí)初始化捺宗。
4.每次請(qǐng)求柱蟀, Request都會(huì)被初始化,響應(yīng)請(qǐng)求后蚜厉,請(qǐng)求被銷毀长已。
5.Servlet初始化后,將不會(huì)隨著請(qǐng)求的結(jié)束而注銷。
6.關(guān)閉Tomcat時(shí)术瓮,Servlet康聂、Filter依次被注銷。
HashMap與HashTable的區(qū)別胞四。
1恬汁、HashMap是非線程安全的,HashTable是線程安全的辜伟。
2氓侧、HashMap的鍵和值都允許有null值存在,而HashTable則不行导狡。
3约巷、因?yàn)榫€程安全的問題,HashMap效率比HashTable的要高旱捧。
HashMap的實(shí)現(xiàn)機(jī)制:
- 維護(hù)一個(gè)每個(gè)元素是一個(gè)鏈表的數(shù)組独郎,而且鏈表中的每個(gè)節(jié)點(diǎn)是一個(gè)Entry[]鍵值對(duì)的數(shù)據(jù)結(jié)構(gòu)。
- 實(shí)現(xiàn)了數(shù)組+鏈表的特性枚赡,查找快囚聚,插入刪除也快。
- 對(duì)于每個(gè)key,他對(duì)應(yīng)的數(shù)組索引下標(biāo)是 int i = hash(key.hashcode)&(len-1);
- 每個(gè)新加入的節(jié)點(diǎn)放在鏈表首标锄,然后該新加入的節(jié)點(diǎn)指向原鏈表首
HashMap和TreeMap區(qū)別
友情鏈接: Java中HashMap和TreeMap的區(qū)別深入理解
HashMap沖突
友情鏈接: HashMap沖突的解決方法以及原理分析
友情鏈接: HashMap的工作原理
友情鏈接: HashMap和Hashtable的區(qū)別
友情鏈接: 2種辦法讓HashMap線程安全
HashMap顽铸,ConcurrentHashMap與LinkedHashMap的區(qū)別
- ConcurrentHashMap是使用了鎖分段技術(shù)技術(shù)來保證線程安全的,鎖分段技術(shù):首先將數(shù)據(jù)分成一段一段的存儲(chǔ)料皇,然后給每一段數(shù)據(jù)配一把鎖谓松,當(dāng)一個(gè)線程占用鎖訪問其中一個(gè)段數(shù)據(jù)的時(shí)候,其他段的數(shù)據(jù)也能被其他線程訪問
- ConcurrentHashMap 是在每個(gè)段(segment)中線程安全的
- LinkedHashMap維護(hù)一個(gè)雙鏈表践剂,可以將里面的數(shù)據(jù)按寫入的順序讀出
ConcurrentHashMap應(yīng)用場景
1:ConcurrentHashMap的應(yīng)用場景是高并發(fā)鬼譬,但是并不能保證線程安全,而同步的HashMap和HashMap的是鎖住整個(gè)容器逊脯,而加鎖之后ConcurrentHashMap不需要鎖住整個(gè)容器优质,只需要鎖住對(duì)應(yīng)的Segment就好了,所以可以保證高并發(fā)同步訪問军洼,提升了效率巩螃。
2:可以多線程寫。
ConcurrentHashMap把HashMap分成若干個(gè)Segmenet
1.get時(shí)匕争,不加鎖避乏,先定位到segment然后在找到頭結(jié)點(diǎn)進(jìn)行讀取操作。而value是volatile變量甘桑,所以可以保證在競爭條件時(shí)保證讀取最新的值拍皮,如果讀到的value是null歹叮,則可能正在修改,那么久調(diào)用ReadValueUnderLock函數(shù)铆帽,加鎖保證讀到的數(shù)據(jù)是正確的咆耿。
2.Put時(shí)會(huì)加鎖,一律添加到hash鏈的頭部爹橱。
3.Remove時(shí)也會(huì)加鎖票灰,由于next是final類型不可改變,所以必須把刪除的節(jié)點(diǎn)之前的節(jié)點(diǎn)都復(fù)制一遍宅荤。
4.ConcurrentHashMap允許多個(gè)修改操作并發(fā)進(jìn)行屑迂,其關(guān)鍵在于使用了鎖分離技術(shù)。它使用了多個(gè)鎖來控制對(duì)Hash表的不同Segment進(jìn)行的修改冯键。
ConcurrentHashMap的應(yīng)用場景是高并發(fā)惹盼,但是并不能保證線程安全,而同步的HashMap和HashTable的是鎖住整個(gè)容器惫确,而加鎖之后ConcurrentHashMap不需要鎖住整個(gè)容器手报,只需要鎖住對(duì)應(yīng)的segment就好了,所以可以保證高并發(fā)同步訪問改化,提升了效率掩蛤。
友情鏈接:Java集合---ConcurrentHashMap原理分析
Vector和ArrayList的區(qū)別
友情鏈接:Java中Vector和ArrayList的區(qū)別
ExecutorService service = Executors....
ExecutorService service = new ThreadPoolExecutor()
ExecutorService service = new ScheduledThreadPoolExecutor();
ThreadPoolExecutor源碼分析
線程池本身的狀態(tài):
等待任務(wù)隊(duì)列和工作集:
線程池的主要狀態(tài)鎖:
線程池的存活時(shí)間和大小:
1.2 ThreadPoolExecutor 的內(nèi)部工作原理
有了以上定義好的數(shù)據(jù)陈肛,下面來看看內(nèi)部是如何實(shí)現(xiàn)的 揍鸟。 Doug Lea 的整個(gè)思路總結(jié)起來就是 5 句話:
- 如果當(dāng)前池大小 poolSize 小于 corePoolSize ,則創(chuàng)建新線程執(zhí)行任務(wù)句旱。
- 如果當(dāng)前池大小 poolSize 大于 corePoolSize 阳藻,且等待隊(duì)列未滿,則進(jìn)入等待隊(duì)列
- 如果當(dāng)前池大小 poolSize 大于 corePoolSize 且小于 maximumPoolSize 谈撒,且等待隊(duì)列已滿腥泥,則創(chuàng)建新線程執(zhí)行任務(wù)。
- 如果當(dāng)前池大小 poolSize 大于 corePoolSize 且大于 maximumPoolSize 啃匿,且等待隊(duì)列已滿蛔外,則調(diào)用拒絕策略來處理該任務(wù)。
- 線程池里的每個(gè)線程執(zhí)行完任務(wù)后不會(huì)立刻退出溯乒,而是會(huì)去檢查下等待隊(duì)列里是否還有線程任務(wù)需要執(zhí)行夹厌,如果在 keepAliveTime 里等不到新的任務(wù)了,那么線程就會(huì)退出橙数。
Executor包結(jié)構(gòu)
CopyOnWriteArrayList : 寫時(shí)加鎖尊流,當(dāng)添加一個(gè)元素的時(shí)候,將原來的容器進(jìn)行copy灯帮,復(fù)制出一個(gè)新的容器崖技,然后在新的容器里面寫,寫完之后再將原容器的引用指向新的容器钟哥,而讀的時(shí)候是讀舊容器的數(shù)據(jù)迎献,所以可以進(jìn)行并發(fā)的讀,但這是一種弱一致性的策略腻贰。
使用場景:CopyOnWriteArrayList適合使用在讀操作遠(yuǎn)遠(yuǎn)大于寫操作的場景里吁恍,比如緩存。
Linux常用命令:cd播演,cp冀瓦,mv,rm写烤,ps(進(jìn)程)翼闽,tar,cat(查看內(nèi)容)洲炊,chmod感局,vim,find暂衡,ls
死鎖的必要條件
- 互斥 至少有一個(gè)資源處于非共享狀態(tài)
- 占有并等待
- 非搶占
- 循環(huán)等待
解決死鎖询微,第一個(gè)是死鎖預(yù)防,就是不讓上面的四個(gè)條件同時(shí)成立狂巢。二是撑毛,合理分配資源。
三是使用銀行家算法唧领,如果該進(jìn)程請(qǐng)求的資源操作系統(tǒng)剩余量可以滿足代态,那么就分配。
進(jìn)程間的通信方式
- 管道( pipe ):管道是一種半雙工的通信方式疹吃,數(shù)據(jù)只能單向流動(dòng)蹦疑,而且只能在具有親緣關(guān)系的進(jìn)程間使用。進(jìn)程的親緣關(guān)系通常是指父子進(jìn)程關(guān)系萨驶。
- 有名管道 (named pipe) : 有名管道也是半雙工的通信方式歉摧,但是它允許無親緣關(guān)系進(jìn)程間的通信。
3.信號(hào)量( semophore ) : 信號(hào)量是一個(gè)計(jì)數(shù)器腔呜,可以用來控制多個(gè)進(jìn)程對(duì)共享資源的訪問叁温。它常作為一種鎖機(jī)制,防止某進(jìn)程正在訪問共享資源時(shí)核畴,其他進(jìn)程也訪問該資源膝但。因此,主要作為進(jìn)程間以及同一進(jìn)程內(nèi)不同線程之間的同步手段谤草。 - 消息隊(duì)列( message queue ) : 消息隊(duì)列是由消息的鏈表跟束,存放在內(nèi)核中并由消息隊(duì)列標(biāo)識(shí)符標(biāo)識(shí)莺奸。消息隊(duì)列克服了信號(hào)傳遞信息少、管道只能承載無格式字節(jié)流以及緩沖區(qū)大小受限等缺點(diǎn)冀宴。
5.信號(hào) ( sinal ) : 信號(hào)是一種比較復(fù)雜的通信方式灭贷,用于通知接收進(jìn)程某個(gè)事件已經(jīng)發(fā)生。
6.共享內(nèi)存( shared memory ) :共享內(nèi)存就是映射一段能被其他進(jìn)程所訪問的內(nèi)存略贮,這段共享內(nèi)存由一個(gè)進(jìn)程創(chuàng)建甚疟,但多個(gè)進(jìn)程都可以訪問。共享內(nèi)存是最快的 IPC 方式逃延,它是針對(duì)其他進(jìn)程間通信方式運(yùn)行效率低而專門設(shè)計(jì)的览妖。它往往與其他通信機(jī)制,如信號(hào)量揽祥,配合使用讽膏,來實(shí)現(xiàn)進(jìn)程間的同步和通信。
7.套接字( socket ) : 套解口也是一種進(jìn)程間通信機(jī)制盔然,與其他通信機(jī)制不同的是桅打,它可用于不同機(jī)器間的進(jìn)程通信。
計(jì)算機(jī)系統(tǒng)的層次存儲(chǔ)結(jié)構(gòu)詳解
數(shù)據(jù)庫事務(wù)是指作為單個(gè)邏輯工作單元執(zhí)行的一系列操作愈案。
友情鏈接:數(shù)據(jù)庫事務(wù)的四大特性以及事務(wù)的隔離級(jí)別
MySQL數(shù)據(jù)庫優(yōu)化總結(jié)
MySQL存儲(chǔ)引擎--MyISAM與InnoDB區(qū)別
Hibernate的一級(jí)緩存是由Session提供的挺尾,因此它只存在于Session的生命周期中,當(dāng)程序調(diào)用save(),update(),saveOrUpdate()等方法 及調(diào)用查詢接口list,filter,iterate時(shí)站绪,如Session緩存中還不存在相應(yīng)的對(duì)象遭铺,Hibernate會(huì)把該對(duì)象加入到一級(jí)緩存中,當(dāng)Session關(guān)閉的時(shí)候緩存也會(huì)消失恢准。
Hibernate的一級(jí)緩存是Session所內(nèi)置的魂挂,不能被卸載,也不能進(jìn)行任何配置一級(jí)緩存采用的是key-value的Map方式來實(shí)現(xiàn)的馁筐,在緩存實(shí)體對(duì)象時(shí)涂召,對(duì)象的主關(guān)鍵字ID是Map的key,實(shí)體對(duì)象就是對(duì)應(yīng)的值敏沉。
Hibernate二級(jí)緩存:把獲得的所有數(shù)據(jù)對(duì)象根據(jù)ID放入到第二級(jí)緩存中果正。Hibernate二級(jí)緩存策略,是針對(duì)于ID查詢的緩存策略盟迟,刪除秋泳、更新、增加數(shù)據(jù)的時(shí)候攒菠,同時(shí)更新緩存迫皱。
更新于2017/3/9
JVM(8):JVM知識(shí)點(diǎn)總覽-高級(jí)Java工程師面試必備
關(guān)于Java Collections的幾個(gè)常見問題
兩個(gè)棧實(shí)現(xiàn)隊(duì)列 兩個(gè)隊(duì)列實(shí)現(xiàn)棧
更新于2017/3/12
java collection.sort()根據(jù)時(shí)間排序list
更新于2017/3/13
具體更多資源可前往Java后端面試總結(jié)
各種Java面經(jīng)資源