個人總結(jié)

  1. java 8中基本類型
    int byte short long char double float boolean
    4 1 2 8 2 8 4
    2.mysql 和oracle的數(shù)據(jù)庫事務(wù)
    數(shù)據(jù)庫事務(wù)的四大特性(acid): 原子性,一致性,隔離性,持久性
    不考慮數(shù)據(jù)庫事務(wù)的隔離性,會出現(xiàn)以下幾種并發(fā)問題。:
    臟讀: 一個事務(wù)讀取了另外一個事務(wù)未提交的數(shù)據(jù)。
    幻讀:是針對的一批數(shù)據(jù),比如update了一批數(shù)據(jù),但是此時剛好插入了一小數(shù)據(jù)。
    不可重復(fù)讀:多次事務(wù)讀取的結(jié)果不一致。是因為在讀取的過程中,其他事務(wù)修改了數(shù)據(jù),針對一條數(shù)據(jù)。
    數(shù)據(jù)庫的隔離級別:
    mysql的隔離級別 (默認是 可重復(fù)讀)
    read uncommitted 讀取未提交的事務(wù),讀取速度快,但是什么都不能解決
    read commit 讀取提交的事務(wù)結(jié)果, 可以防止臟讀
    reapeat read 可重復(fù)讀。 可避免臟讀,不可重復(fù)讀 。
    serializable 串行化,可避免所有的,但是效率低。
    oracle的隔離級別:
    read commit: 可避免臟讀 默認隔離級別
    seriailizable 串行化,可避免所有的
    oracle中有undo,所以它天生讀寫不阻塞,所以不會發(fā)生臟讀

undo也可稱之為數(shù)據(jù)庫的rollback數(shù)據(jù),它用戶確保數(shù)據(jù)的一致性,當執(zhí)行數(shù)據(jù)庫的DML時,事務(wù)操作前的數(shù)據(jù)稱為undo記錄,undo段用來保存事務(wù)所修改數(shù)據(jù)的的舊值,其中存儲著被修改數(shù)據(jù)塊的位置以及修改前數(shù)據(jù)
oracle undo
3 hashmap的原理以及currenthashmap的原理
主要說 currenthashmap 吧:
1.7 的時候使用 segment(extend retenLock) 鎖分段技術(shù) 一個hashmap中有16個segment數(shù)組,每個數(shù)組中又有hashEntry,是一種數(shù)組加鏈表的格式。
1.8的時候是使用cas以及synchronize的關(guān)鍵字來保證數(shù)據(jù)在并發(fā)時的安全性。 當數(shù)組的長度大于8 的時候轉(zhuǎn)換為紅黑樹。 紅黑樹的特點簡單來說是 根節(jié)點為黑的。

  1. cas aqs
    隊列同步器AbstractQueuedSynchronizer(以下簡稱同步器),是用來構(gòu)建鎖或者其他同步組件的基礎(chǔ)框架。

同步器包含兩個節(jié)點類型的應(yīng)用,一個指向頭節(jié)點,一個指向尾節(jié)點,未獲取到鎖的線程會創(chuàng)建節(jié)點線程安全(compareAndSetTail)的加入隊列尾部。同步隊列遵循FIFO,首節(jié)點是獲取同步狀態(tài)成功的節(jié)點
CAS,在Java并發(fā)應(yīng)用中通常指CompareAndSwap或CompareAndSet,即比較并交換
CAS是一個原子操作,它比較一個內(nèi)存位置的值并且只有相等時修改這個內(nèi)存位置的值為新的值,保證了新的值總是基于最新的信息計算的,如果有其他線程在這期間修改了這個值則CAS失敗。CAS返回是否成功或者內(nèi)存位置原來的值用于判斷是否CAS成功。
cas aqs 以及synchronize的實現(xiàn)原理

5 jvm
jvm的構(gòu)造:

6 數(shù)組遍歷
java.util包下的集合都是快速失?。╢ail-fast) 。java.util.currentutil下則是安全失敗(fail-safe)
比如ArrayList的iterator的迭代中。
fail-fast
這里只是判斷modCount!=expectedModCount。如果剛好相等。則不會異常。所以##不能依賴于這個異常是否拋出而進行并發(fā)操作的編程,這個異常只建議用于檢測并發(fā)修改的bug。
java.util.currentutil下的安全失敗,則是在遍歷的時候復(fù)制源集合。所以在遍歷過程中。源集合發(fā)生變化,不會影響到當前遍歷。

  1. 數(shù)據(jù)庫索引
    單列索引
    唯一索引
    組合索引(遵循“最左前綴”原則,把最常用作為檢索或排序的列放在最左,依次遞減)
    。 索引的實現(xiàn)原理,mysql
    BTree索引和B+Tree索引


    B+Tree索引
BTree索引

8 myisam 和 innerdb的區(qū)別
從知乎上找找看

9 連接池
連接池的參數(shù)含義
連接池的拒絕策略

10,jvm的內(nèi)存劃分

  1. synchronize 的含義, 在synchronize的修飾在靜態(tài)類上的時候,代表鎖是類對象,而修飾非靜態(tài)方法的時候是對象的鎖

情況3:一個對象在兩個線程中分別調(diào)用一個靜態(tài)同步方法和一個非靜態(tài)同步方法

結(jié)果:不會產(chǎn)生互斥。

解釋:因為雖然是一個對象調(diào)用,但是兩個方法的鎖類型不同,調(diào)用的靜態(tài)方法實際上是類對象在調(diào)用,即這兩個方法產(chǎn)生的并不是同一個對象鎖,因此不會互斥,會并發(fā)執(zhí)行。

情況2:用一個類的靜態(tài)對象在兩個線程中調(diào)用靜態(tài)方法或非靜態(tài)方法

結(jié)果:會產(chǎn)生互斥。

解釋:因為是一個對象調(diào)用,同上
情況1:用類直接在兩個線程中調(diào)用兩個不同的同步方法

結(jié)果:會產(chǎn)生互斥。

解釋:因為對靜態(tài)對象加鎖實際上對類(.class)加鎖,類對象只有一個,可以理解為任何時候都只有一個空間,里面有N個房間,一把鎖,因此房間(同步方法)之間一定是互斥的。

注:上述情況和用單例模式聲明一個對象來調(diào)用非靜態(tài)方法的情況是一樣的,因為永遠就只有這一個對象。所以訪問同步方法之間一定是互斥的。
1.對象鎖鑰匙只能有一把才能互斥,才能保證共享變量的唯一性

2.在靜態(tài)方法上的鎖,和 實例方法上的鎖,默認不是同樣的,如果同步需要制定兩把鎖一樣。

3.關(guān)于同一個類的方法上的鎖,來自于調(diào)用該方法的對象,如果調(diào)用該方法的對象是相同的,那么鎖必然相同,否則就不相同。比如 new A().x() 和 new A().x(),對象不同,鎖不同,如果A的單利的,就能互斥。

4.靜態(tài)方法加鎖,能和所有其他靜態(tài)方法加鎖的 進行互斥

5.靜態(tài)方法加鎖,和xx.class 鎖效果一樣,直接屬于類的

synchronize 修飾對象

12 OOM 以及 Stack Overflow 會發(fā)生在什么地方
OOM以及Stack Overflow的引用
OOM:
內(nèi)存溢出: 指當程序需要申請內(nèi)存的時候卻發(fā)現(xiàn)沒有足夠的內(nèi)存,就會排除該異常。也就是內(nèi)存溢出。
內(nèi)存泄漏: 指當程序使用不當,把某一部分弄得不可用。
當在堆中創(chuàng)建了對象,后來沒有使用這個對象了,又沒有把整個對象的相關(guān)引用設(shè)為null。此時垃圾收集器會認為這個對象是需要的,就不會清理這部分內(nèi)存。這就會導致這部分內(nèi)存不可用。 所以內(nèi)存泄漏會導致可用的內(nèi)存減少,進而會導致內(nèi)存溢出。

方法區(qū)溢出

方法區(qū)是存放類的信息,而且很難被gc,只要加載了大量類,就有可能引起方法區(qū)溢出
這里將不做演示了,想試試的可以用cglib創(chuàng)建大量的代理類

堆溢出

堆是存放對象的地方,那么只要在堆中瘋狂的創(chuàng)建對象,那么堆就會發(fā)生內(nèi)存溢出。

//jvm參數(shù):-Xms20m -Xmx20m 
public class HeapOOMTest { 
public static void main(String[] args){ 
LinkedList xttblog=new LinkedList();//作為GC Root 
while(true){ 
xttblog.add(new HeapOOMTest());//瘋狂創(chuàng)建對象 
} 
} 
} 

-Xms20m -Xmx20m作用是將jvm的最小堆容量和最大堆容量都設(shè)定為20m,這樣就不會動態(tài)擴展jvm堆了
這段代碼瘋狂的創(chuàng)建對象,雖然對象沒有聲明變量名引用,但是將對象添加到隊列l(wèi)中,這樣隊列l(wèi)就持有了一份對象的引用
通過可達性算法(jvm判斷對象是否可被收集的算法)分析,隊列l(wèi)作為GC Root,每一個對象都是l的一個可達的節(jié)點,所以瘋狂創(chuàng)建的對象不會被收集,這就是內(nèi)存泄漏,這樣總有一天堆就溢出了。

運行結(jié)果:

Exception in thread “main” java.lang.OutOfMemoryError: Java heap space at java.util.LinkedList.linkLast(Unknown Source) at java.util.LinkedList.add(Unknown Source) at test.HeapOOMTest.main(HeapOOMTest.java:23)
程序發(fā)生內(nèi)存溢出,并提示發(fā)生在Java heap space

棧溢出

調(diào)用方法的時候,會在棧中入棧一個棧幀,如果當前棧的容量不足,就會發(fā)生棧溢出StackOverFlowError
那么只要瘋狂的調(diào)用方法,并且有意的不讓棧幀出棧就可以導致棧溢出了。


//jvm參數(shù):-Xss128k 
public class StackSOFTest { 
public void stackLeak(){ 
stackLeak();//遞歸,瘋狂的入棧,有意不讓出棧 
} 
public static void main(String[] args){ 
StackSOFTest s=new StackSOFTest(); 
s.stackLeak(); 
} 
} 

運行時常量池溢出

這里儲存的是一些常量、字面量。如果運行時常量池內(nèi)存不足,就會發(fā)生內(nèi)存溢出。從jdk1.7開始,運行時常量池移動到了堆中,所以如果堆的內(nèi)存不足,也會導致運行時常量池內(nèi)存溢出。

public class RuntimePoolOOM { 
public static void main(String[] args){ 
int i=1; 
//保持常量的引用,防止被fullgc收集 
LinkedList xttblog=new LinkedList(); 
while(true){ 
//將常量添加到常量池 
xttblog.add(String.valueOf(i++).intern()); 
} 
} 

這里用了鏈表去保存常量的引用,是因為防止被fullgc清理,因為fullgc會清理掉方法區(qū)和老年代
intern()方法是將常量添加到常量池中去,這樣運行時常量池一直都在增長,然后內(nèi)存溢出

工作中也有可能會遇上方法區(qū)溢出:

當多個項目都有相同jar包的時候,又都存放在WEB-INF\lib\下,這樣每個項目都會加載一遍jar包。會導致方法區(qū)中有大量相同類(被不同的類加載器所加載),又不會被gc掉。

解決方案

在應(yīng)用服務(wù)器中建立一個共享lib庫,把項目中常用重復(fù)的jar包存放在這里,項目從這里加載jar包,這樣就會大大減少類加載的數(shù)量,方法區(qū)也“瘦身”了
如果實在不能瘦身類的話,那可以擴大方法區(qū)的容量,給jvm指定參數(shù)-XX:MaxPermSize=xxxM

13 分布式下怎么保證接口的冪等性。
冪等性要求多次執(zhí)行得到的響應(yīng)一致,同時對實體狀態(tài)的影響一致
對于一些結(jié)果不是要求冪等性的。可以不做處理。
而一些必要的冪等性,都是需要做唯一的標識作區(qū)分的
如果對于執(zhí)行有要求順序的話,在直接更新之前需要校驗此時值和傳遞過來(要更新的)是否預(yù)期一樣。
14 GC fullGC 垃圾回收機制
參考 垃圾回收機制
參考 https://www.cnblogs.com/zhguang/p/3257367.html -- JVM

15 jvm加載的雙親委派模式原理

類加載:

jvm把描述類的數(shù)據(jù)從class文件加載到內(nèi)存,并對數(shù)據(jù)進行加載--轉(zhuǎn)換解析--初始化 最終成為jvm可以使用的java類型
類加載包含以下幾個流程 加載-->驗證-->準備-->解析-->初始化-->使用-->卸載


類加載過程

主動引用與被動引用

主動引用會觸發(fā)類初始化,被動引用不會觸發(fā)

類加載器

三種:
(啟動類加載器)根加載器(BootStrap classLoader): 加載 JAVA_HOME/lib/rt.jar,或被-Xbootclasspath參數(shù)指定路徑中的jar包
擴展加載器(Extension classLoader):加載JAVA_HOME/lib/ext包
系統(tǒng)加載器(application classLoader):加載classPath直接路徑下的jar包,一般來說,應(yīng)用程序中的類都與次加載器加載

雙親委派模式加載過程

若一個類加載器收到類加載請求,他首先不會自己嘗試去加載這個類,而是把這個請求委派給父類加載器去完成,每一層類加載器都是如此,所以所有請求都會傳送到頂層的BootStrap ClassLoader,只有當父類加載器反饋自己無法完成這個加載請求(它的搜索范圍沒找到),子加載器才會自己嘗試去加載

對于任意一個類,都需要由加載它的類加載器和這個類本身來一同確立其在Java虛擬機中的唯一性
當同一個類被不同加載器加載的時候,JVM認為它們不是同一個類

淺談雙親委派和破壞雙親委派
jvm類加載器以及雙親委派

16 分布式事務(wù)
分布式開放消息系統(tǒng)(RocketMQ)的原理與實踐
第一次有人把“分布式事務(wù)”講的這么簡單明了

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容