什么情況下會發(fā)生死鎖
出現(xiàn)死鎖定页,有這四個必要條件:互斥條件、請求和保持杭煎、不可剝奪宫峦、循環(huán)等待
- 互斥條件: 一個資源每次只能被一個進(jìn)程使用玫鸟,即在一段時間內(nèi)某 資源僅為一個進(jìn)程所占有。此時若有其他進(jìn)程請求該資源妥曲,則請求進(jìn)程只能等待。
- 請求與保持條件: 進(jìn)程已經(jīng)保持了至少一個資源褂萧,但又提出了新的資源請求葵萎,而該資源 已被其他進(jìn)程占有,此時請求進(jìn)程被阻塞谎痢,但對自己已獲得的資源保持不放卷雕。
- 不可剝奪條件: 進(jìn)程所獲得的資源在未使用完畢之前,不能被其他進(jìn)程強行奪走滨嘱,即只能 由獲得該資源的進(jìn)程自己來釋放(只能是主動釋放)浸间。
- 循環(huán)等待條件: 若干進(jìn)程間形成首尾相接循環(huán)等待資源的關(guān)系
只要系統(tǒng)發(fā)生死鎖,這些條件必然成立躺彬,而只要上述條件之一不滿足梅惯,就不會發(fā)生死鎖
java模擬死鎖
public class DeadLockTest{
public static void main(String[] args) {
Thread t1 = new Thread(new DeadLock(1));
Thread t2 = new Thread(new DeadLock(2));
t1.start();
t2.start();
}
}
class DeadLock implements Runnable{
private int flag;
private static Object o1 = new Object();
private static Object o2 = new Object();
DeadLock(int _flag){
this.flag = _flag;
}
@Override
public void run() {
System.out.println("flag: " + flag);
if(flag == 1){
synchronized(o1){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized(o2){
System.out.println("1");
}
}
}
else if(flag == 2){
synchronized(o2){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized(o1){
System.out.println("2");
}
}
}
}
}
JVM gc算法
哪些對象該被GC铣减? 如果一個對象到GC Roots沒有任何引用鏈葫哗,該對象就是不可達(dá)對象,即可以被GC劣针。
一捺典、標(biāo)記清除算法(Mark-and-Sweep)
標(biāo)記清除算法是最基礎(chǔ)的收集算法,后面的算法都是基于該算法擴展的,分為兩個階段:
標(biāo)記階段(Mark phase):
從GC Roots出發(fā)牍陌,沿著引用鏈员咽,遇到對象就標(biāo)記該對象贝室,直到所有可達(dá)對象都被標(biāo)記。
清除階段(Sweep phase):
掃描整個heap档玻,回收那些在標(biāo)記階段未被標(biāo)記的對象的內(nèi)存
二误趴、停止復(fù)制算法(Stop-and-Copy)
停止復(fù)制算法將可用內(nèi)存分為等量的兩塊,每次只使用其中的一塊凉当,當(dāng)這一塊無法滿足新的內(nèi)存分配時看杭,即需要GC時,就掃描該塊模孩,將還存活的對象復(fù)制到另一塊上面贮缅,然后再把已使用過的內(nèi)存空間一次清理掉。
三块茁、標(biāo)記整理(壓縮)算法(Mark-and-Compact)
標(biāo)記整理算法和標(biāo)記清理算法類似桂肌,也分為兩個階段:
標(biāo)記階段(Mark):從GC Roots出發(fā),沿著引用鏈佩耳,遇到對象就標(biāo)記該對象谭跨,直到所有可達(dá)對象都被標(biāo)記答恶。
整理(壓縮)階段(Compact):把所有的存活對象往一端移萍诱,然后清理掉端邊界外的內(nèi)存裕坊。
注意:無論是哪種算法哪種收集器燕酷,在枚舉根節(jié)點時都是要停頓(停頓指得是暫停所有用戶線程),只是根據(jù)算法的不同以及收集器的不同該停頓時間的長短不同而已饵蒂。
MySQL存儲引擎有哪幾種酱讶,各有什么特點
TODO
redis如何從左向右刪除list元素
TODO
Spring MVC 一個請求處理流程
Spring工作流程描述
- 用戶向服務(wù)器發(fā)送請求泻肯,請求被Spring 前端控制Servelt DispatcherServlet捕獲;
- DispatcherServlet對請求URL進(jìn)行解析琉朽,得到請求資源標(biāo)識符(URI)稚铣。然后根據(jù)該URI,調(diào)用HandlerMapping獲得該Handler配置的所有相關(guān)的對象(包括Handler對象以及Handler對象對應(yīng)的攔截器)耕漱,最后以HandlerExecutionChain對象的形式返回曹锨;
- DispatcherServlet 根據(jù)獲得的Handler,選擇一個合適的HandlerAdapter齐鲤。(附注:如果成功獲得HandlerAdapter后椒楣,此時將開始執(zhí)行攔截器的preHandler(...)方法)
- 提取Request中的模型數(shù)據(jù),填充Handler入?yún)⑾牛_始執(zhí)行Handler(Controller)。 在填充Handler的入?yún)⑦^程中饲窿,根據(jù)你的配置焕蹄,Spring將幫你做一些額外的工作:
HttpMessageConveter: 將請求消息(如Json、xml等數(shù)據(jù))轉(zhuǎn)換成一個對象鸦泳,將對象轉(zhuǎn)換為指定的響應(yīng)信息
數(shù)據(jù)轉(zhuǎn)換:對請求消息進(jìn)行數(shù)據(jù)轉(zhuǎn)換永品。如String轉(zhuǎn)換成Integer鼎姐、Double等
數(shù)據(jù)根式化:對請求消息進(jìn)行數(shù)據(jù)格式化。 如將字符串轉(zhuǎn)換成格式化數(shù)字或格式化日期等
數(shù)據(jù)驗證: 驗證數(shù)據(jù)的有效性(長度喂走、格式等)谋作,驗證結(jié)果存儲到BindingResult或Error中- Handler執(zhí)行完成后,向DispatcherServlet 返回一個ModelAndView對象帖池;
- 根據(jù)返回的ModelAndView吭净,選擇一個適合的ViewResolver(必須是已經(jīng)注冊到Spring容器中的ViewResolver)返回給DispatcherServlet ;
- ViewResolver 結(jié)合Model和View囚巴,來渲染視圖
- 將渲染結(jié)果返回給客戶端友扰。
向zookeeper集群寫數(shù)據(jù)村怪,內(nèi)部流程
TODO