面試總結-整理

基礎篇html

基本功前端

六、說說反射的用途及實現java

八、HTTP 請求的 GET 與 POST 方式的區別node

十、session 分佈式處理mysql

十二、MVC 設計思想react

1四、nginx

java自動裝箱拆箱深刻剖析
談談Java反射機制
如何寫一個不可變類?程序員

1七、Hashcode的做用,與 equal 有什麼區別?web

a.一樣用於鑑定2個對象是否相等的,java集合中有 list 和 set 兩類,其中 set不容許元素重複實現,那個這個不容許重複實現的方法,若是用 equal 去比較的話,若是存在1000個元素,你 new 一個新的元素出來,須要去調用1000次 equal 去逐個和他們比較是不是同一個對象,這樣會大大下降效率。hashcode其實是返回對象的存儲地址,若是這個位置上沒有元素,就把元素直接存儲在上面,若是這個位置上已經存在元素,這個時候纔去調用equal方法與新元素進行比較,相同的話就不存了,散列到其餘地址上。面試

http://blog.csdn.net/lijiecao0226/article/details/24609559

2四、cloneable接口實現原理

2五、異常分類以及處理機制

 3一、java中的異常:http://www.importnew.com/26613.html

3三、comparable與comparator的區別?

參考:http://www.cnblogs.com/szlbm/p/5504634.html

4二、.訪問控制符public,protected,private,以及默認的區別

private只有在本類中才能訪問;
public在任何地方都能訪問;
protected在同包內的類及包外的子類能訪問;
默認不寫在同包內能訪問。

4七、什麼是泛型、爲何要使用以及泛型擦除#

泛型,即「參數化類型」。
建立集合時就指定集合元素的類型,該集合只能保存其指定類型的元素,避免使用強制類型轉換。
Java編譯器生成的字節碼是不包涵泛型信息的,泛型類型信息將在編譯處理是被擦除,這個過程即類型擦除。泛型擦除能夠簡單的理解爲將泛型java代碼轉換爲普通java代碼,只不過編譯器更直接點,將泛型java代碼直接轉換成普通java字節碼。
類型擦除的主要過程以下:
1).將全部的泛型參數用其最左邊界(最頂級的父類型)類型替換。
2).移除全部的類型參數。

4八、.Error、Exception區別#

Error類和Exception類的父類都是throwable類,他們的區別是:
Error類通常是指與虛擬機相關的問題,如系統崩潰,虛擬機錯誤,內存空間不足,方法調用棧溢等。對於這類錯誤的致使的應用程序中斷,僅靠程序自己沒法恢復和和預防,遇到這樣的錯誤,建議讓程序終止。
Exception類表示程序能夠處理的異常,能夠捕獲且可能恢復。遇到這類異常,應該儘量處理異常,使程序恢復運行,而不該該隨意終止異常。

50、Java中如何實現代理機制(JDK、CGLIB)#

JDK動態代理:代理類和目標類實現了共同的接口,用到InvocationHandler接口。
CGLIB動態代理:代理類是目標類的子類,用到MethodInterceptor接口。

5三、equals與==的區別

使用==比較原生類型如:boolean、int、char等等,使用equals()比較對象。

一、==是判斷兩個變量或實例是否是指向同一個內存空間。 equals是判斷兩個變量或實例所指向的內存空間的值是否是相同。

二、==是指對內存地址進行比較。 equals()是對字符串的內容進行比較。

三、==指引用是否相同。 equals()指的是值是否相同。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public static void main(String[] args) {
 
        String a = new String("ab"); // a 爲一個引用
        String b = new String("ab"); // b爲另外一個引用,對象的內容同樣
        String aa = "ab"// 放在常量池中
        String bb = "ab"// 從常量池中查找
 
        System.out.println(aa == bb); // true
        System.out.println(a == b); // false,非同一對象
        System.out.println(a.equals(b)); // true
        System.out.println(42 == 42.0);  // true
    }
 
public static void main(String[] args) {
    Object obj1 = new Object();
    Object obj2 = new Object();
    System.out.println(obj1.equals(obj2));//false
    System.out.println(obj1==obj2);//false
    obj1=obj2;
    System.out.println(obj1==obj2);//true
    System.out.println(obj2==obj1);//true
}

5四、Object有哪些公用方法

Object是全部類的父類,任何類都默認繼承Object

clone 保護方法,實現對象的淺複製,只有實現了Cloneable接口才能夠調用該方法,不然拋出CloneNotSupportedException異常。

equals 在Object中與==是同樣的,子類通常須要重寫該方法。

hashCode 該方法用於哈希查找,重寫了equals方法通常都要重寫hashCode方法。這個方法在一些具備哈希功能的Collection中用到。

getClass final方法,得到運行時類型

wait 使當前線程等待該對象的鎖,當前線程必須是該對象的擁有者,也就是具備該對象的鎖。 wait() 方法一直等待,直到得到鎖或者被中斷。 wait(long timeout) 設定一個超時間隔,若是在規定時間內沒有得到鎖就返回。

調用該方法後當前線程進入睡眠狀態,直到如下事件發生

一、其餘線程調用了該對象的notify方法。 二、其餘線程調用了該對象的notifyAll方法。 三、其餘線程調用了interrupt中斷該線程。 四、時間間隔到了。 五、此時該線程就能夠被調度了,若是是被中斷的話就拋出一個InterruptedException異常。

notify 喚醒在該對象上等待的某個線程。

notifyAll 喚醒在該對象上等待的全部線程。

toString 轉換成字符串,通常子類都有重寫,不然打印句柄。

5五、Java的四種引用,強弱軟虛,用到的場景

從JDK1.2版本開始,把對象的引用分爲四種級別,從而使程序能更加靈活的控制對象的生命週期。這四種級別由高到低依次爲:強引用、軟引用、弱引用和虛引用。

一、強引用

最廣泛的一種引用方式,如String s = "abc",變量s就是字符串「abc」的強引用,只要強引用存在,則垃圾回收器就不會回收這個對象。

二、軟引用(SoftReference)

用於描述還有用但非必須的對象,若是內存足夠,不回收,若是內存不足,則回收。通常用於實現內存敏感的高速緩存,軟引用能夠和引用隊列ReferenceQueue聯合使用,若是軟引用的對象被垃圾回收,JVM就會把這個軟引用加入到與之關聯的引用隊列中。

三、弱引用(WeakReference)

弱引用和軟引用大體相同,弱引用與軟引用的區別在於:只具備弱引用的對象擁有更短暫的生命週期。在垃圾回收器線程掃描它所管轄的內存區域的過程當中,一旦發現了只具備弱引用的對象,無論當前內存空間足夠與否,都會回收它的內存。

四、虛引用(PhantomReference)

就是形同虛設,與其餘幾種引用都不一樣,虛引用並不會決定對象的生命週期。若是一個對象僅持有虛引用,那麼它就和沒有任何引用同樣,在任什麼時候候均可能被垃圾回收器回收。 虛引用主要用來跟蹤對象被垃圾回收器回收的活動。

虛引用與軟引用和弱引用的一個區別在於:

虛引用必須和引用隊列 (ReferenceQueue)聯合使用。當垃圾回收器準備回收一個對象時,若是發現它還有虛引,就會在回收對象的內存以前,把這個虛引用加入到與之關聯的引用隊列中。

5六、Hashcode的做用

http://blog.csdn.net/seu_calvin/article/details/52094115

一、HashCode的特性

(1)HashCode的存在主要是用於查找的快捷性,如Hashtable,HashMap等,HashCode常常用於肯定對象的存儲地址

(2)若是兩個對象相同,?equals方法必定返回true,而且這兩個對象的HashCode必定相同

(3)兩個對象的HashCode相同,並不必定表示兩個對象就相同,即equals()不必定爲true,只可以說明這兩個對象在一個散列存儲結構中。

(4)若是對象的equals方法被重寫,那麼對象的HashCode也儘可能重寫

二、HashCode做用

Java中的集合有兩類,一類是List,再有一類是Set。前者集合內的元素是有序的,元素能夠重複;後者元素無序,但元素不可重複

equals方法可用於保證元素不重複,但若是每增長一個元素就檢查一次,若集合中如今已經有1000個元素,那麼第1001個元素加入集合時,就要調用1000次equals方法。這顯然會大大下降效率。?因而,Java採用了哈希表的原理

哈希算法也稱爲散列算法,是將數據依特定算法直接指定到一個地址上。

這樣一來,當集合要添加新的元素時,先調用這個元素的HashCode方法,就一會兒能定位到它應該放置的物理位置上

(1)若是這個位置上沒有元素,它就能夠直接存儲在這個位置上,不用再進行任何比較了。

(2)若是這個位置上已經有元素了,就調用它的equals方法與新元素進行比較,相同的話就不存了。

(3)不相同的話,也就是發生了Hash key相同致使衝突的狀況,那麼就在這個Hash key的地方產生一個鏈表,將全部產生相同HashCode的對象放到這個單鏈表上去,串在一塊兒(不多出現)。

這樣一來實際調用equals方法的次數就大大下降了,幾乎只須要一兩次。

如何理解HashCode的做用:

從Object角度看,JVM每new一個Object,它都會將這個Object丟到一個Hash表中去,這樣的話,下次作Object的比較或者取這個對象的時候(讀取過程),它會根據對象的HashCode再從Hash表中取這個對象。這樣作的目的是提升取對象的效率。若HashCode相同再去調用equal。

三、HashCode實踐(如何用來查找)

HashCode是用於查找使用的,而equals是用於比較兩個對象是否相等的

(1)例如內存中有這樣的位置

0 1 2 3 4 5 6 7 

而我有個類,這個類有個字段叫ID,我要把這個類存放在以上8個位置之一,若是不用HashCode而任意存放,那麼當查找時就須要到這八個位置裏挨個去找,或者用二分法一類的算法。

但以上問題若是用HashCode就會使效率提升不少 定義咱們的HashCode爲ID%8,好比咱們的ID爲9,9除8的餘數爲1,那麼咱們就把該類存在1這個位置,若是ID是13,求得的餘數是5,那麼咱們就把該類放在5這個位置。依此類推。

(2)可是若是兩個類有相同的HashCode,例如9除以8和17除以8的餘數都是1,也就是說,咱們先經過?HashCode來判斷兩個類是否存放某個桶裏,但這個桶裏可能有不少類,那麼咱們就須要再經過equals在這個桶裏找到咱們要的類

請看下面這個例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class HashTest {
    private int i;
 
    public int getI() {
        return i;
    }
 
    public void setI(int i) {
        this.i = i;
    }
 
    public int hashCode() {
        return i % 10;
    }
 
    public final static void main(String[] args) {
        HashTest a = new HashTest();
        HashTest b = new HashTest();
        a.setI(1);
        b.setI(1);
        Set<HashTest> set = new HashSet<HashTest>();
        set.add(a);
        set.add(b);
        System.out.println(a.hashCode() == b.hashCode());
        System.out.println(a.equals(b));
        System.out.println(set);
    }
}

輸出結果爲:

1
2
3
true
False
[HashTest@1, HashTest@1]

以上這個示例,咱們只是重寫了HashCode方法,從上面的結果能夠看出,雖然兩個對象的HashCode相等,可是實際上兩個對象並非相等由於咱們沒有重寫equals方法,那麼就會調用Object默認的equals方法,顯示這是兩個不一樣的對象。

這裏咱們將生成的對象放到了HashSet中,而HashSet中只可以存放惟一的對象,也就是相同的(適用於equals方法)的對象只會存放一個,可是這裏其實是兩個對象ab都被放到了HashSet中,這樣HashSet就失去了他自己的意義了。

下面咱們繼續重寫equals方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public class HashTest {
    private int i;
 
    public int getI() {
        return i;
    }
 
    public void setI(int i) {
        this.i = i;
    }
 
    public boolean equals(Object object) {
        if (object == null) {
            return false;
        }
        if (object == this) {
            return true;
        }
        if (!(object instanceof HashTest)) {
            return false;
        }
        HashTest other = (HashTest) object;
        if (other.getI() == this.getI()) {
            return true;
        }
        return false;
    }
 
    public int hashCode() {
        return i % 10;
    }
 
    public final static void main(String[] args) {
        HashTest a = new HashTest();
        HashTest b = new HashTest();
        a.setI(1);
        b.setI(1);
        Set<HashTest> set = new HashSet<HashTest>();
        set.add(a);
        set.add(b);
        System.out.println(a.hashCode() == b.hashCode());
        System.out.println(a.equals(b));
        System.out.println(set);
    }
}

輸出結果以下所示。

從結果咱們能夠看出,如今兩個對象就徹底相等了,HashSet中也只存放了一份對象。

注意:

hashCode()只是簡單示例寫的,真正的生產換將不是這樣的

1
2
3
true
true
[HashTest@1]

HashMap的hashcode的做用

hashCode的存在主要是用於查找的快捷性,如Hashtable,HashMap等,hashCode是用來在散列存儲結構中肯定對象的存儲地址的。

若是兩個對象相同,就是適用於equals(java.lang.Object) 方法,那麼這兩個對象的hashCode必定要相同。

若是對象的equals方法被重寫,那麼對象的hashCode也儘可能重寫,而且產生hashCode使用的對象,必定要和equals方法中使用的一致,不然就會違反上面提到的第2點。

兩個對象的hashCode相同,並不必定表示兩個對象就相同,也就是不必定適用於equals(java.lang.Object) 方法,只可以說明這兩個對象在散列存儲結構中,如Hashtable,他們「存放在同一個籃子裏」。

何時須要重寫?

通常的地方不須要重載hashCode,只有當類須要放在HashTable、HashMap、HashSet等等hash結構的集合時纔會重載hashCode,那麼爲何要重載hashCode呢?

要比較兩個類的內容屬性值,是否相同時候,根據hashCode 重寫規則,重寫類的 指定字段的hashCode(),equals()方法。

例如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class EmpWorkCondition{
 
    /**
     * 員工ID
     */
    private Integer empId;
 
    /**
     * 員工服務總單數
     */
    private Integer orderSum;
 
    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        EmpWorkCondition that = (EmpWorkCondition) o;
        return Objects.equals(empId, that.empId);
    }
 
    @Override
    public int hashCode() {
        return Objects.hash(empId);
    }
 
    // 省略 getter setter
}

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public static void main(String[] args) {
 
    List<EmpWorkCondition> list1 = new ArrayList<EmpWorkCondition>();
 
    EmpWorkCondition emp1 = new EmpWorkCondition();
    emp1.setEmpId(100);
    emp1.setOrderSum(90000);
    list1.add(emp1);
 
    List<EmpWorkCondition> list2 = new ArrayList<EmpWorkCondition>();
 
    EmpWorkCondition emp2 = new EmpWorkCondition();
    emp2.setEmpId(100);
    list2.add(emp2);
 
    System.out.println(list1.contains(emp2));
 
}

輸出結果:true

上面的方法,作的事情就是,比較兩個集合中的,實體類對象屬性值,是否一致

OrderSum 不在比較範圍內,由於沒有重寫它的,equals()和hashCode()方法

爲何要重載equal方法?

由於Object的equal方法默認是兩個對象的引用的比較,意思就是指向同一內存,地址則相等,不然不相等;若是你如今須要利用對象裏面的值來判斷是否相等,則重載equal方法。

爲何重載hashCode方法?

通常的地方不須要重載hashCode,只有當類須要放在HashTable、HashMap、HashSet等等hash結構的集合時纔會重載hashCode,那麼爲何要重載hashCode呢?

若是你重寫了equals,好比說是基於對象的內容實現的,而保留hashCode的實現不變,那麼極可能某兩個對象明明是「相等」,而hashCode卻不同。

這樣,當你用其中的一個做爲鍵保存到hashMap、hasoTable或hashSet中,再以「相等的」找另外一個做爲鍵值去查找他們的時候,則根本找不到。

爲何equals()相等,hashCode就必定要相等,而hashCode相等,卻不要求equals相等?

一、由於是按照hashCode來訪問小內存塊,因此hashCode必須相等。 二、HashMap獲取一個對象是比較key的hashCode相等和equal爲true。

之因此hashCode相等,卻能夠equal不等,就好比ObjectA和ObjectB他們都有屬性name,那麼hashCode都以name計算,因此hashCode同樣,可是兩個對象屬於不一樣類型,因此equal爲false。

爲何須要hashCode?

一、經過hashCode能夠很快的查到小內存塊。 二、經過hashCode比較比equal方法快,當get時先比較hashCode,若是hashCode不一樣,直接返回false。

 

5九、Java對象的生命週期

答:建立階段 、 應用階段 、不可見階段 、不可達階段 、收集階段 、終結階段、 對象空間從新分配階段等等,具體參照:Java 對象的生命週期

6四、一個類對象屬性發生改變時,如何讓調用者知道?

答:Java event時間監聽  ,即在set方法改變屬性時,觸發 ,這種模式也能夠理解爲觀察者模式,具體查看:觀察者模式簡單案例和說明 

 

集合

八、HashMap 的工做原理及代碼實現

十、HashMap與HashTable的區別。

一、HashMap是非線程安全的,HashTable是線程安全的。
二、HashMap的鍵和值都容許有null值存在,而HashTable則不行。
三、由於線程安全的問題,HashMap效率比HashTable的要高。

HashMap的實現機制:

  1. 維護一個每一個元素是一個鏈表的數組,並且鏈表中的每一個節點是一個Entry[]鍵值對的數據結構。

  2. 實現了數組+鏈表的特性,查找快,插入刪除也快。

  3. 對於每一個key,他對應的數組索引下標是 int i = hash(key.hashcode)&(len-1);

  4. 每一個新加入的節點放在鏈表首,而後該新加入的節點指向原鏈表首

HashMap和TreeMap區別
友情連接: Java中HashMap和TreeMap的區別深刻理解

HashMap衝突
友情連接: HashMap衝突的解決方法以及原理分析

十一、HashMap,ConcurrentHashMap與LinkedHashMap的區別

  1. ConcurrentHashMap是使用了鎖分段技術技術來保證線程安全的,鎖分段技術:首先將數據分紅一段一段的存儲,而後給每一段數據配一把鎖,當一個線程佔用鎖訪問其中一個段數據的時候,其餘段的數據也能被其餘線程訪問

  2. ConcurrentHashMap 是在每一個段(segment)中線程安全的

  3. LinkedHashMap維護一個雙鏈表,能夠將裏面的數據按寫入的順序讀出

ConcurrentHashMap應用場景
1:ConcurrentHashMap的應用場景是高併發,可是並不能保證線程安全,而同步的HashMap和HashMap的是鎖住整個容器,而加鎖以後ConcurrentHashMap不須要鎖住整個容器,只須要鎖住對應的Segment就行了,因此能夠保證高併發同步訪問,提高了效率。
2:能夠多線程寫。
ConcurrentHashMap把HashMap分紅若干個Segmenet
1.get時,不加鎖,先定位到segment而後在找到頭結點進行讀取操做。而value是volatile變量,因此能夠保證在競爭條件時保證讀取最新的值,若是讀到的value是null,則可能正在修改,那麼就調用ReadValueUnderLock函數,加鎖保證讀到的數據是正確的。
2.Put時會加鎖,一概添加到hash鏈的頭部。
3.Remove時也會加鎖,因爲next是final類型不可改變,因此必須把刪除的節點以前的節點都複製一遍。
4.ConcurrentHashMap容許多個修改操做併發進行,其關鍵在於使用了鎖分離技術。它使用了多個鎖來控制對Hash表的不一樣Segment進行的修改。

ConcurrentHashMap的應用場景是高併發,可是並不能保證線程安全,而同步的HashMap和HashTable的是鎖住整個容器,而加鎖以後ConcurrentHashMap不須要鎖住整個容器,只須要鎖住對應的segment就行了,因此能夠保證高併發同步訪問,提高了效率。

ConcurrentHashMap可以保證每一次調用都是原子操做,可是並不保證屢次調用之間也是原子操做。
友情連接:Java集合—ConcurrentHashMap原理分析

 十二、

Vector和ArrayList的區別
友情連接:Java中Vector和ArrayList的區別

1四、

HashMap的底層實現,以後會問ConcurrentHashMap的底層實現;

2四、HashMap 是線程安全的嗎,爲何不是線程安全的(最好畫圖說明多線程環境下不安全)?

2五、HashMap 的擴容過程

2六、HashMap 1.7 與 1.8 的 區別,說明 1.8 作了哪些優化,如何優化的?

2九、LinkedHashMap的應用:LRU算法

31. ConcurrentHashMap的實現原理

A:它是一個對寫操做加了鎖的HashMap,不一樣的是它作了二次分割,元素被存儲在不一樣的桶裏,以見效鎖的數據範圍,提高性能。

在JDK8中對這種實現又進行了修改,JDK8中的ConcurrentHashmap基於CAS和TreeBin實現的,不須要對segment或者全局加鎖,只須要對單行枷鎖(hashCode相同),後邊的鏈表是鏈表加紅黑樹。對於單個值的修改使用CAS。

面試官極可能想聽到的是這樣,但這裏重要的是分治的概念。其實徹底可讓候選人嘗試本身去設計一個ConcurrentHashMap,而後引導他去拆分HashMap,這樣纔是正道啊。

32. TransferQueue的算法是什麼樣的,它和BlockingQueue有哪些不一樣

33. Arraylist與LinkedList的比較

一、ArrayList是實現了基於動態數組的數據結構,由於地址連續,一旦數據存儲好了,查詢操做效率會比較高(在內存裏是連着放的)。

二、由於地址連續, ArrayList要移動數據,因此插入和刪除操做效率比較低。   

三、LinkedList基於鏈表的數據結構,地址是任意的,因此在開闢內存空間的時候不須要等一個連續的地址,對於新增和刪除操做add和remove,LinedList比較佔優點。

四、由於LinkedList要移動指針,因此查詢操做性能比較低。

適用場景分析:

當須要對數據進行隨機訪問的狀況下選用ArrayList,當須要對數據進行屢次增長刪除修改時採用LinkedList。

34. ArrayList與Vector的比較

一、Vector的方法都是同步的,是線程安全的,而ArrayList的方法不是,因爲線程的同步必然要影響性能。所以,ArrayList的性能比Vector好。 
二、當Vector或ArrayList中的元素超過它的初始大小時,Vector會將它的容量翻倍,而ArrayList只增長50%的大小,這樣。ArrayList就有利於節約內存空間。

三、大多數狀況不使用Vector,由於性能很差,可是它支持線程的同步,即某一時刻只有一個線程可以寫Vector,避免多線程同時寫而引發的不一致性。

四、Vector能夠設置增加因子,而ArrayList不能夠。

適用場景分析:

一、Vector是線程同步的,因此它也是線程安全的,而ArrayList是線程異步的,是不安全的。若是不考慮到線程的安全因素,通常用ArrayList效率比較高。

二、若是集合中的元素的數目大於目前集合數組的長度時,在集合中使用數據量比較大的數據,用Vector有必定的優點。

35.HashSet與TreeSet的比較

1.TreeSet 是二叉樹實現的,Treeset中的數據是自動排好序的,不容許放入null值 。

2.HashSet 是哈希表實現的,HashSet中的數據是無序的,能夠放入null,但只能放入一個null,二者中的值都不能重複,就如數據庫中惟一約束 。

3.HashSet要求放入的對象必須實現HashCode()方法,放入的對象,是以hashcode碼做爲標識的,而具備相同內容的String對象,hashcode是同樣,因此放入的內容不能重複。可是同一個類的對象能夠放入不一樣的實例。

適用場景分析:

HashSet是基於Hash算法實現的,其性能一般都優於TreeSet。咱們一般都應該使用HashSet,在咱們須要排序的功能時,咱們才使用TreeSet。

36. HashMap和ConcurrentHashMap的區別

一、HashMap不是線程安全的,而ConcurrentHashMap是線程安全的。

二、ConcurrentHashMap採用鎖分段技術,將整個Hash桶進行了分段segment,也就是將這個大的數組分紅了幾個小的片斷segment,並且每一個小的片斷segment上面都有鎖存在,那麼在插入元素的時候就須要先找到應該插入到哪個片斷segment,而後再在這個片斷上面進行插入,並且這裏還須要獲取segment鎖。

三、ConcurrentHashMap讓鎖的粒度更精細一些,併發性能更好。

37. HashTable和ConcurrentHashMap的區別

它們均可以用於多線程的環境,可是當Hashtable的大小增長到必定的時候,性能會急劇降低,由於迭代時須要被鎖定很長的時間。由於ConcurrentHashMap引入了分割(segmentation),不論它變得多麼大,僅僅須要鎖定map的某個部分,而其它的線程不須要等到迭代完成才能訪問map。簡而言之,在迭代的過程當中,ConcurrentHashMap僅僅鎖定map的某個部分,而Hashtable則會鎖定整個map。

3六、java中的集合類:http://www.javashuo.com/article/p-xtnpuchz-bp.html

3七、HashMap與HashTable、ConcurrentHashMap區別:http://www.javashuo.com/article/p-shzydloe-gu.html

3九、Arrays和Collections 對於sort的不一樣實現原理?

一、Arrays.sort() 
該算法是一個通過調優的快速排序,此算法在不少數據集上提供N*log(N)的性能,這致使其餘快速排序會下降二次型性能。

二、Collections.sort() 
該算法是一個通過修改的合併排序算法(其中,若是低子列表中的最高元素效益高子列表中的最低元素,則忽略合併)。此算法可提供保證的N*log(N)的性能,此實現將指定列表轉儲到一個數組中,而後再對數組進行排序,在重置數組中相應位置處每一個元素的列表上進行迭代。

40、HashMap的源碼,實現原理,JDK8中對HashMap作了怎樣的優化。

4一、HaspMap擴容是怎樣擴容的,爲何都是2的N次冪的大小。

4三、極高併發下HashTable和ConcurrentHashMap哪一個性能更好,爲何,如何實現的。

4六、HashMap實現原理#
具體原理參考文章:
http://zhangshixi.iteye.com/blog/672697
http://www.admin10000.com/document/3322.html

4七、HashTable實現原理#
具體原理參考文章:
http://www.cnblogs.com/skywang12345/p/3310887.html
http://blog.csdn.net/chdjj/article/details/38581035

4八、HashMap和HashTable區別#
  1)HashTable的方法前面都有synchronized來同步,是線程安全的;HashMap未經同步,是非線程安全的。
  2)HashTable不容許null值(key和value都不能夠) ;HashMap容許null值(key和value均可以)。
  3)HashTable有一個contains(Object value)功能和containsValue(Object value)功能同樣。
  4)HashTable使用Enumeration進行遍歷;HashMap使用Iterator進行遍歷。
  5)HashTable中hash數組默認大小是11,增長的方式是old*2+1;HashMap中hash數組的默認大小是16,並且必定是2的指數。
  6)哈希值的使用不一樣,HashTable直接使用對象的hashCode; HashMap從新計算hash值,並且用與代替求模。

5二、.Concurrenthashmap實現原理#
具體原理參考文章:
http://www.cnblogs.com/ITtangtang/p/3948786.html
http://ifeve.com/concurrenthashmap/

5五、HashMap和HashTable的區別
https://segmentfault.com/a/1190000008101567

總結

JDK6,7中的ConcurrentHashmap主要使用Segment來實現減少鎖粒度,把HashMap分割成若干個Segment,在put的時候須要鎖住Segment,get時候不加鎖,使用volatile來保證可見性,當要統計全局時(好比size),首先會嘗試屢次計算modcount來肯定,這幾回嘗試中,是否有其餘線程進行了修改操做,若是沒有,則直接返回size。若是有,則須要依次鎖住全部的Segment來計算。

jdk7中ConcurrentHashmap中,當長度過長碰撞會很頻繁,鏈表的增改刪查操做都會消耗很長的時間,影響性能。

jdk8 中徹底重寫了concurrentHashmap,代碼量從原來的1000多行變成了 6000多 行,實現上也和原來的分段式存儲有很大的區別。

JDK8中採用的是位桶+鏈表/紅黑樹(有關紅黑樹請查看紅黑樹)的方式,也是非線程安全的。當某個位桶的鏈表的長度達到某個閥值的時候,這個鏈表就將轉換成紅黑樹。

JDK8中,當同一個hash值的節點數不小於8時,將再也不以單鏈表的形式存儲了,會被調整成一顆紅黑樹(上圖中null節點沒畫)。這就是JDK7與JDK8中HashMap實現的最大區別。

主要設計上的變化有如下幾點

1.jdk8不採用segment而採用node,鎖住node來實現減少鎖粒度。 2.設計了MOVED狀態 當resize的中過程當中 線程2還在put數據,線程2會幫助resize。 3.使用3個CAS操做來確保node的一些操做的原子性,這種方式代替了鎖。 4.sizeCtl的不一樣值來表明不一樣含義,起到了控制的做用。

至於爲何JDK8中使用synchronized而不是ReentrantLock,我猜是由於JDK8中對synchronized有了足夠的優化吧。

ConcurrentHashMap能徹底替代HashTable嗎
hashTable雖然性能上不如ConcurrentHashMap,但並不能徹底被取代,二者的迭代器的一致性不一樣的,hash table的迭代器是強一致性的,而concurrenthashmap是弱一致的。

ConcurrentHashMap的get,clear,iterator 都是弱一致性的。 Doug Lea 也將這個判斷留給用戶本身決定是否使用ConcurrentHashMap。

ConcurrentHashMap與HashTable均可以用於多線程的環境,可是當Hashtable的大小增長到必定的時候,性能會急劇降低,由於迭代時須要被鎖定很長的時間。由於ConcurrentHashMap引入了分割(segmentation),不論它變得多麼大,僅僅須要鎖定map的某個部分,而其它的線程不須要等到迭代完成才能訪問map。簡而言之,在迭代的過程當中,ConcurrentHashMap僅僅鎖定map的某個部分,而Hashtable則會鎖定整個map。

那麼既然ConcurrentHashMap那麼優秀,爲何還要有Hashtable的存在呢?ConcurrentHashMap能徹底替代HashTable嗎?

HashTable雖然性能上不如ConcurrentHashMap,但並不能徹底被取代,二者的迭代器的一致性不一樣的,HashTable的迭代器是強一致性的,而ConcurrentHashMap是弱一致的。 ConcurrentHashMap的get,clear,iterator 都是弱一致性的。 Doug Lea 也將這個判斷留給用戶本身決定是否使用ConcurrentHashMap。

那麼什麼是強一致性和弱一致性呢?

get方法是弱一致的,是什麼含義?可能你指望往ConcurrentHashMap底層數據結構中加入一個元素後,立馬能對get可見,但ConcurrentHashMap並不能如你所願。換句話說,put操做將一個元素加入到底層數據結構後,get可能在某段時間內還看不到這個元素,若不考慮內存模型,單從代碼邏輯上來看,倒是應該能夠看獲得的。

下面將結合代碼和java內存模型相關內容來分析下put/get方法。put方法咱們只需關注Segment#put,get方法只需關注Segment#get,在繼續以前,先要說明一下Segment裏有兩個volatile變量:count和table;HashEntry裏有一個volatile變量:value。

總結

ConcurrentHashMap的弱一致性主要是爲了提高效率,是一致性與效率之間的一種權衡。要成爲強一致性,就獲得處使用鎖,甚至是全局鎖,這就與Hashtable和同步的HashMap同樣了。

爲何HashMap是線程不安全的
HashMap 在併發執行 put 操做時會引發死循環,致使 CPU 利用率接近100%。由於多線程會致使 HashMap 的 Node 鏈表造成環形數據結構,一旦造成環形數據結構,Node 的 next 節點永遠不爲空,就會在獲取 Node 時產生死循環。

如何線程安全的使用HashMap
瞭解了 HashMap 爲何線程不安全,那如今看看如何線程安全的使用 HashMap。這個無非就是如下三種方式:

Hashtable ConcurrentHashMap Synchronized Map

Hashtable

例子

//Hashtable
Map<String, String> hashtable = new Hashtable<>();
//synchronizedMap
Map<String, String> synchronizedHashMap = Collections.synchronizedMap(new HashMap<String, String>());
//ConcurrentHashMap
Map<String, String> concurrentHashMap = new ConcurrentHashMap<>();
Hashtable
先稍微吐槽一下,爲啥命名不是 HashTable 啊,看着好難受無論了就裝做它叫HashTable 吧。這貨已經不經常使用了,就簡單說說吧。HashTable 源碼中是使用?synchronized?來保證線程安全的,好比下面的 get 方法和 put 方法:

public synchronized V get(Object key) {
// 省略實現
}
public synchronized V put(K key, V value) {
// 省略實現
}
因此當一個線程訪問 HashTable 的同步方法時,其餘線程若是也要訪問同步方法,會被阻塞住。舉個例子,當一個線程使用 put 方法時,另外一個線程不但不能夠使用 put 方法,連 get 方法都不能夠,好霸道啊!!!so~~,效率很低,如今基本不會選擇它了。

ConcurrentHashMap

ConcurrentHashMap 於 Java 7 的,和8有區別,在8中 CHM 摒棄了 Segment(鎖段)的概念,而是啓用了一種全新的方式實現,利用 CAS 算法,有時間會從新總結一下。

SynchronizedMap

synchronizedMap() 方法後會返回一個 SynchronizedMap 類的對象,而在 SynchronizedMap 類中使用了 synchronized 同步關鍵字來保證對 Map 的操做是線程安全的。

性能對比

這是要靠數聽說話的時代,因此不能只靠嘴說 CHM 快,它就快了。寫個測試用例,實際的比較一下這三種方式的效率(源碼來源),下面的代碼分別經過三種方式建立 Map 對象,使用 ExecutorService 來併發運行5個線程,每一個線程添加/獲取500K個元素。

Test started for: class java.util.Hashtable
2500K entried added/retrieved in 2018 ms
2500K entried added/retrieved in 1746 ms
2500K entried added/retrieved in 1806 ms
2500K entried added/retrieved in 1801 ms
2500K entried added/retrieved in 1804 ms
For class java.util.Hashtable the average time is 1835 ms

Test started for: class java.util.Collections$SynchronizedMap
2500K entried added/retrieved in 3041 ms
2500K entried added/retrieved in 1690 ms
2500K entried added/retrieved in 1740 ms
2500K entried added/retrieved in 1649 ms
2500K entried added/retrieved in 1696 ms
For class java.util.Collections$SynchronizedMap the average time is 1963 ms

Test started for: class java.util.concurrent.ConcurrentHashMap
2500K entried added/retrieved in 738 ms
2500K entried added/retrieved in 696 ms
2500K entried added/retrieved in 548 ms
2500K entried added/retrieved in 1447 ms
2500K entried added/retrieved in 531 ms
For class java.util.concurrent.ConcurrentHashMap the average time is 792 ms
ConcurrentHashMap 性能是明顯優於 Hashtable 和 SynchronizedMap 的,CHM 花費的時間比前兩個的一半還少。

多併發狀況下HashMap是否還會產生死循環
今天原本想看下了ConcurrentHashMap的源碼,ConcurrentHashMap是Java 5中支持高併發、高吞吐量的線程安全HashMap實現。

在看不少博客在介紹ConcurrentHashMap以前,都說HashMap適用於單線程訪問,這是由於HashMap的全部方法都沒有進行鎖同步,所以是線程不安全的,不只如此,當多線程訪問的時候還容易產生死循環。

雖然本身在前幾天的時候看過HashMap的源碼,感受思路啥啥的都還清楚,對於多線程訪問只知道HashMap是線程不安全的,可是不知道HashMap在多線程併發的狀況下會產生死循環呢,爲何會產生,何種狀況下才會產生死循環呢???

既然會產生死循環,爲何併發狀況下,仍是用ConcurrentHashMap。 jdk 好像有,可是Jdk8 已經修復了這個問題。

TreeMap、HashMap、LindedHashMap的區別
LinkedHashMap能夠保證HashMap集合有序,存入的順序和取出的順序一致。

TreeMap實現SortMap接口,可以把它保存的記錄根據鍵排序,默認是按鍵值的升序排序,也能夠指定排序的比較器,當用Iterator遍歷TreeMap時,獲得的記錄是排過序的。

HashMap不保證順序,即爲無序的,具備很快的訪問速度。 HashMap最多隻容許一條記錄的鍵爲Null;容許多條記錄的值爲 Null。 HashMap不支持線程的同步。

咱們在開發的過程當中使用HashMap比較多,在Map中在Map 中插入、刪除和定位元素,HashMap 是最好的選擇。

但若是您要按天然順序或自定義順序遍歷鍵,那麼TreeMap會更好。

若是須要輸出的順序和輸入的相同,那麼用LinkedHashMap 能夠實現,它還能夠按讀取順序來排列。

 

5七、Map或者HashMap的存儲原理

答:HashMap是由數組+鏈表的一個結構組成,具體參照:HashMap的實現原理

5九、說說常見的集合有哪些吧?

答:Map 接口和 Collection 接口是全部集合框架的父接口:

  1. Collection 接口的子接口包括:Set 接口和 List 接口;

  2. Map 接口的實現類主要有:HashMap、TreeMap、Hashtable、ConcurrentHashMap 以及 Properties 等;

  3. Set 接口的實現類主要有:HashSet、TreeSet、LinkedHashSet 等;

  4. List 接口的實現類主要有:ArrayList、LinkedList、Stack 以及 Vector 等。

6二、ConcurrentHashMap 和 Hashtable 的區別? (必問)

答:ConcurrentHashMap 結合了 HashMap 和 HashTable 兩者的優點。HashMap 沒有考慮同步,hashtable 考慮了同步的問題。可是 hashtable 在每次同步執行時都要鎖住整個結構。 ConcurrentHashMap 鎖的方式是稍微細粒度的。 ConcurrentHashMap 將 hash 表分爲 16 個桶(默認值),諸如 get,put,remove 等經常使用操做只鎖當前須要用到的桶。

面試官:ConcurrentHashMap 的具體實現知道嗎?

答:

  1. 該類包含兩個靜態內部類 HashEntry 和 Segment;前者用來封裝映射表的鍵值對,後者用來充當鎖的角色;

  2. Segment 是一種可重入的鎖 ReentrantLock,每一個 Segment 守護一個 HashEntry 數組裏得元素,當對 HashEntry 數組的數據進行修改時,必須首先得到對應的 Segment 鎖。

6三、HashMap 的長度爲何是 2 的冪次方?

答:

  1. 經過將 Key 的 hash 值與 length-1 進行 & 運算,實現了當前 Key 的定位,2 的冪次方能夠減小衝突(碰撞)的次數,提升 HashMap 查詢效率;

  2. 若是 length 爲 2 的次冪 則 length-1 轉化爲二進制一定是 11111……的形式,在於 h 的二進制與操做效率會很是的快,並且空間不浪費;

  3. 若是 length 不是 2 的次冪,好比 length 爲 15,則 length-1 爲 14,對應的二進制爲 1110,在於 h 與操做,最後一位都爲 0,而 0001,0011,0101,1001,1011,0111,1101 這幾個位置永遠都不能存放元素了,空間浪費至關大。

更糟的是這種狀況中,數組能夠使用的位置比數組長度小了不少,這意味着進一步增長了碰撞的概率,減慢了查詢的效率!這樣就會形成空間的浪費。

6五、List、Set 和 Map 的初始容量和加載因子

答:

1. List

  • ArrayList 的初始容量是 10;加載因子爲 0.5; 擴容增量:原容量的 0.5 倍 +1;一次擴容後長度爲 16。

  • Vector 初始容量爲 10,加載因子是 1。擴容增量:原容量的 1 倍,如 Vector 的容量爲 10,一次擴容後是容量爲 20。

2. Set

HashSet,初始容量爲 16,加載因子爲 0.75; 擴容增量:原容量的 1 倍; 如 HashSet 的容量爲 16,一次擴容後容量爲 32

3. Map

HashMap,初始容量 16,加載因子爲 0.75; 擴容增量:原容量的 1 倍; 如 HashMap 的容量爲 16,一次擴容後容量爲 32

6六、Comparable 接口和 Comparator 接口有什麼區別?

答:

  1. 前者簡單,可是若是須要從新定義比較類型時,須要修改源代碼。

  2. 後者不須要修改源代碼,自定義一個比較器,實現自定義的比較方法。

6七、Java 集合的快速失敗機制 「fail-fast」

答:它是 java 集合的一種錯誤檢測機制,當多個線程對集合進行結構上的改變的操做時,有可能會產生 fail-fast 機制。

例如 :假設存在兩個線程(線程 一、線程 2),線程 1 經過 Iterator 在遍歷集合 A 中的元素,在某個時候線程 2 修改了集合 A 的結構(是結構上面的修改,而不是簡單的修改集合元素的內容),那麼這個時候程序就會拋出 ConcurrentModificationException 異常,從而產生 fail-fast 機制。

緣由: 迭代器在遍歷時直接訪問集合中的內容,而且在遍歷過程當中使用一個 modCount 變量。集合在被遍歷期間若是內容發生變化,就會改變 modCount 的值。

每當迭代器使用 hashNext()/next() 遍歷下一個元素以前,都會檢測 modCount 變量是否爲 expectedmodCount 值,是的話就返回遍歷;不然拋出異常,終止遍歷。

解決辦法:

  1. 在遍歷過程當中,全部涉及到改變 modCount 值得地方所有加上 synchronized;

  2. 使用 CopyOnWriteArrayList 來替換 ArrayList。

小結:本小節是 Java 中關於集合的考察,是 Java 崗位面試中必考的知識點,除了應該掌握以上的問題,包括各個集合的底層實現也建議各位同窗閱讀,加深理解。

 

 

 

多線程

一、建立線程的方式及實現:Thread,Runnable,Callable 

二、sleep() 、join()、yield()有什麼區別

三、說說 CountDownLatch 原理

四、說說 CyclicBarrier 原理

五、說說 Semaphore 原理

六、說說 Exchanger 原理

七、說說 CountDownLatch 與 CyclicBarrier 區別

九、講講線程池的實現原理

十、線程池的幾種方式

十一、線程的生命週期

十二、

ThreadLocal(線程變量副本)
Synchronized實現內存共享,ThreadLocal爲每一個線程維護一個本地變量。
採用空間換時間,它用於線程間的數據隔離,爲每個使用該變量的線程提供一個副本,每一個線程均可以獨立地改變本身的副本,而不會和其餘線程的副本衝突。
ThreadLocal類中維護一個Map,用於存儲每個線程的變量副本,Map中元素的鍵爲線程對象,而值爲對應線程的變量副本。
ThreadLocal在Spring中發揮着巨大的做用,在管理Request做用域中的Bean、事務管理、任務調度、AOP等模塊都出現了它的身影。
Spring中絕大部分Bean均可以聲明成Singleton做用域,採用ThreadLocal進行封裝,所以有狀態的Bean就可以以singleton的方式在多線程中正常工做了。
友情連接:深刻研究java.lang.ThreadLocal類

1四、

fail-fast:機制是java集合(Collection)中的一種錯誤機制。當多個線程對同一個集合的內容進行操做時,就可能會產生fail-fast事件。
例如:當某一個線程A經過iterator去遍歷某集合的過程當中,若該集合的內容被其餘線程所改變了;那麼線程A訪問集合時,就會拋出ConcurrentModificationException異常,產生fail-fast事件

1六、

Volatile和Synchronized四個不一樣點:
1 粒度不一樣,前者針對變量 ,後者鎖對象和類
2 syn阻塞,volatile線程不阻塞
3 syn保證三大特性,volatile不保證原子性
4 syn編譯器優化,volatile不優化 volatile具有兩種特性:

1.保證此變量對全部線程的可見性,指一條線程修改了這個變量的值,新值對於其餘線程來講是可見的,但並非多線程安全的。
2.禁止指令重排序優化。

Volatile如何保證內存可見性:

1.當寫一個volatile變量時,JMM會把該線程對應的本地內存中的共享變量刷新到主內存。
2.當讀一個volatile變量時,JMM會把該線程對應的本地內存置爲無效。線程接下來將從主內存中讀取共享變量。

同步:就是一個任務的完成須要依賴另一個任務,只有等待被依賴的任務完成後,依賴任務才能完成。
異步:不須要等待被依賴的任務完成,只是通知被依賴的任務要完成什麼工做,只要本身任務完成了就算完成了,被依賴的任務是否完成會通知回來。(異步的特色就是通知)。 打電話和發短信來比喻同步和異步操做。
阻塞:CPU停下來等一個慢的操做完成之後,纔會接着完成其餘的工做。
非阻塞:非阻塞就是在這個慢的執行時,CPU去作其餘工做,等這個慢的完成後,CPU纔會接着完成後續的操做。
非阻塞會形成線程切換增長,增長CPU的使用時間能不能補償系統的切換成本須要考慮。
友情連接:Java併發編程之volatile關鍵字解析

1七、

線程池的做用: 在程序啓動的時候就建立若干線程來響應處理,它們被稱爲線程池,裏面的線程叫工做線程
第一:下降資源消耗。經過重複利用已建立的線程下降線程建立和銷燬形成的消耗。
第二:提升響應速度。當任務到達時,任務能夠不須要等到線程建立就能當即執行。
第三:提升線程的可管理性。
經常使用線程池:ExecutorService 是主要的實現類,其中經常使用的有 Executors.newSingleThreadPool(),newFixedThreadPool(),newcachedTheadPool(),newScheduledThreadPool()。
友情連接:線程池原理
友情連接:線程池原理解析

1八、

ExecutorService service = Executors…. ExecutorService service = new ThreadPoolExecutor() ExecutorService service = new ScheduledThreadPoolExecutor();

ThreadPoolExecutor源碼分析

線程池自己的狀態:

等待任務隊列和工做集:

線程池的主要狀態鎖:

線程池的存活時間和大小:

1.2 ThreadPoolExecutor 的內部工做原理
有了以上定義好的數據,下面來看看內部是如何實現的 。 Doug Lea 的整個思路總結起來就是 5 句話:

  1. 若是當前池大小 poolSize 小於 corePoolSize ,則建立新線程執行任務。

  2. 若是當前池大小 poolSize 大於 corePoolSize ,且等待隊列未滿,則進入等待隊列

  3. 若是當前池大小 poolSize 大於 corePoolSize 且小於 maximumPoolSize ,且等待隊列已滿,則建立新線程執行任務。

  4. 若是當前池大小 poolSize 大於 corePoolSize 且大於 maximumPoolSize ,且等待隊列已滿,則調用拒絕策略來處理該任務。

  5. 線程池裏的每一個線程執行完任務後不會馬上退出,而是會去檢查下等待隊列裏是否還有線程任務須要執行,若是在 keepAliveTime 裏等不到新的任務了,那麼線程就會退出。

Executor包結構

CopyOnWriteArrayList : 寫時加鎖,當添加一個元素的時候,將原來的容器進行copy,複製出一個新的容器,而後在新的容器裏面寫,寫完以後再將原容器的引用指向新的容器,而讀的時候是讀舊容器的數據,因此能夠進行併發的讀,但這是一種弱一致性的策略。
使用場景:CopyOnWriteArrayList適合使用在讀操做遠遠大於寫操做的場景裏,好比緩存。

1九、

wait()和sleep()的區別

sleep來自Thread類,和wait來自Object類

調用sleep()方法的過程當中,線程不會釋放對象鎖。而 調用 wait 方法線程會釋放對象鎖

sleep睡眠後不出讓系統資源,wait讓出系統資源其餘線程能夠佔用CPU

sleep(milliseconds)須要指定一個睡眠時間,時間一到會自動喚醒

2二、wait和sleep的區別,必須理解;

2三、說說阻塞隊列的實現:能夠參考ArrayBlockingQueue的底層實現(鎖和同步都行);

2六、Excutors能夠產生哪些線程池;

2八、volatile關鍵字的用法:使多線程中的變量可見;

2九、多線程 
(1)實現線程同步: 
http://blog.csdn.net/zhaojw_420/article/details/67823750 
(2)生產者消費者問題: 
http://blog.csdn.net/zhaojw_420/article/details/67826902 
(3)線程安全 
(4)線程死鎖 
(5)Synchronize實現原理 
(7)happen-before規則: 
http://blog.csdn.net/zhaojw_420/article/details/70477874 
(8)線程池 
(9)DCL失效緣由以及解決辦法: 
http://blog.csdn.net/zhaojw_420/article/details/70477921 
(10)線程實現方式:Thread,Runable,Callable的區別

3一、synchronized 的實現原理以及鎖優化?

3二、volatile 的實現原理?

3五、怎麼實現全部線程在等待某個事件的發生纔會去執行?:CyclicBarrier

3六、CAS?CAS 有什麼缺陷,如何解決?

3七、synchronized 和 lock 有什麼區別?

3九、HashMap 的併發問題?

40、ConcurrenHashMap 介紹?1.8 中爲何要用紅黑樹?

4一、AQS

4二、Java 內存模型?

4三、如何保證多線程下 i++ 結果正確?:加鎖,或者用AtomicInteger

4四、線程池的種類,區別和使用場景?

4五、分析線程池的實現原理和線程的調度過程?

4六、線程池如何調優,最大數目如何確認?:有個公式

4七、ThreadLocal原理,用的時候須要注意什麼?:Thread包含一個Map結構,key就是ThreadLocal變量,value就是ThreadLocal值

4八、CountDownLatch 和 CyclicBarrier 的用法,以及相互之間的差異?:前者是等全部線程完成後另一個線程作一件事情,後者是等全部線程完成後一塊兒作一件事情

4九、LockSupport工具

50、Condition接口及其實現原理

5一、Fork/Join框架的理解

5二、分段鎖的原理,鎖力度減少的思考

5三、八種阻塞隊列以及各個阻塞隊列的特性

55. 多個線程同時讀寫,讀線程的數量遠遠⼤於寫線程,你認爲應該如何解決 併發的問題?你會選擇加什麼樣的鎖?:讀寫鎖

56. JAVA的AQS是否瞭解,它是⼲嘛的?:用來實現加鎖的

57. 除了synchronized關鍵字以外,你是怎麼來保障線程安全的?:Lock

58. 何時須要加volatile關鍵字?它能保證線程安全嗎?:須要可見性或者防止重排序的時候,只能保證可見性不能保證線程安全

59. 線程池內的線程若是所有忙,提交⼀個新的任務,會發⽣什麼?隊列所有 塞滿了以後,仍是忙,再提交會發⽣什麼?

60. Tomcat自己的參數你⼀般會怎麼調整?:調整線程池大小

61. synchronized關鍵字鎖住的是什麼東⻄?在字節碼中是怎麼表示的?在內 存中的對象上表現爲何?

62. wait/notify/notifyAll⽅法需不須要被包含在synchronized塊中?這是爲什 麼?:須要,不然會拋出異常

63. ExecutorService你⼀般是怎麼⽤的?是每一個service放⼀個仍是⼀個項⽬ ⾥⾯放⼀個?有什麼好處?:根據狀況來定,看是否須要隔離,仍是須要統一管理

6八、Thread 類中的start() 和 run() 方法有什麼區別?

6九、 Java中CyclicBarrier 和 CountDownLatch有什麼不一樣?

7二、 如何避免死鎖?

7三、Java中活鎖和死鎖有什麼區別?

7四、 Java中synchronized 和 ReentrantLock 有什麼不一樣?

7五、 Java中ConcurrentHashMap的併發度是什麼?

7六、 如何在Java中建立Immutable對象?:final,集合類的unmodified。。。

7七、 單例模式的雙檢鎖是什麼?

7八、寫出3條你遵循的多線程最佳實踐:線程池,使用jdk封裝的線程安全工具,使用concurrenthashmap代替hashtable

7九、經常使用的線程池模式以及不一樣線程池的使用場景

81. wait和sleep的區別

一、sleep()方法是屬於Thread類中的,而wait()方法,則是屬於Object類中的。

二、sleep()方法致使了程序暫停執行指定的時間,讓出cpu給其餘線程,可是他的監控狀態依然保持着,當指定的時間到了又會自動恢復運行狀態。因此在調用sleep()方法的過程當中,線程不會釋放對象鎖。

三、調用wait()方法的時候,線程會放棄對象鎖,進入等待此對象的等待鎖定池,只有針對此對象調用notify()方法後本線程才進入對象鎖定池準備獲取對象鎖進入運行狀態。

 

8三、多線程實現方式:http://www.javashuo.com/article/p-uawdyimt-ce.html 

8四、線程的狀態轉換:http://blog.csdn.net/sinat_36042530/article/details/52565296

8五、如何中止一個線程:http://www.javashuo.com/article/p-zntbvsla-ct.html

8六、什麼是線程安全:http://blog.csdn.net/ghevinn/article/details/37764791

8七、synchronized和lock的區別:http://blog.csdn.net/u012403290/article/details/64910926?locationNum=11&fps=1

8九、.java線程池:http://www.importnew.com/19011.html
90、.併發工具類:http://blog.csdn.net/sunxianghuang/article/details/52277394
9一、.併發容器類:http://blog.csdn.net/jianghuxiaojin/article/details/52006183

9三、Volatile的特徵:

A、禁止指令重排(有例外) 
B、可見性

Volatile的內存語義:

當寫一個volatile變量時,JMM會把線程對應的本地內存中的共享變量值刷新到主內存。

 

當讀一個volatile變量時,JMM會把線程對應的本地內存置爲無效,線程接下來將從主內存中讀取共享變量。

 

Volatile的重排序

一、當第二個操做爲volatile寫操作時,無論第一個操做是什麼(普通讀寫或者volatile讀寫),都不能進行重排序。這個規則確保volatile寫以前的全部操做都不會被重排序到volatile以後;

二、當第一個操做爲volatile讀操做時,無論第二個操做是什麼,都不能進行重排序。這個規則確保volatile讀以後的全部操做都不會被重排序到volatile以前;

三、當第一個操做是volatile寫操做時,第二個操做是volatile讀操做,不能進行重排序。

這個規則和前面兩個規則一塊兒構成了:兩個volatile變量操做不可以進行重排序;

除以上三種狀況之外能夠進行重排序。

好比:

一、第一個操做是普通變量讀/寫,第二個是volatile變量的讀; 
二、第一個操做是volatile變量的寫,第二個是普通變量的讀/寫;

 

9四、內存屏障/內存柵欄

內存屏障(Memory Barrier,或有時叫作內存柵欄,Memory Fence)是一種CPU指令,用於控制特定條件下的重排序和內存可見性問題。Java編譯器也會根據內存屏障的規則禁止重排序。(也就是讓一個CPU處理單元中的內存狀態對其它處理單元可見的一項技術。)

內存屏障能夠被分爲如下幾種類型:

LoadLoad屏障:對於這樣的語句Load1; LoadLoad; Load2,在Load2及後續讀取操做要讀取的數據被訪問前,保證Load1要讀取的數據被讀取完畢。

StoreStore屏障:對於這樣的語句Store1; StoreStore; Store2,在Store2及後續寫入操做執行前,保證Store1的寫入操做對其它處理器可見。

LoadStore屏障:對於這樣的語句Load1; LoadStore; Store2,在Store2及後續寫入操做被刷出前,保證Load1要讀取的數據被讀取完畢。

StoreLoad屏障:對於這樣的語句Store1; StoreLoad; Load2,在Load2及後續全部讀取操做執行前,保證Store1的寫入對全部處理器可見。它的開銷是四種屏障中最大的。

在大多數處理器的實現中,這個屏障是個萬能屏障,兼具其它三種內存屏障的功能。

內存屏障阻礙了CPU採用優化技術來下降內存操做延遲,必須考慮所以帶來的性能損失。爲了達到最佳性能,最好是把要解決的問題模塊化,這樣處理器能夠按單元執行任務,而後在任務單元的邊界放上全部須要的內存屏障。採用這個方法可讓處理器不受限的執行一個任務單元。合理的內存屏障組合還有一個好處是:緩衝區在第一次被刷後開銷會減小,由於再填充改緩衝區不須要額外工做了。

 

9五、happens-before原則

 

9六、

 

Java 線程有哪些狀態,這些狀態之間是如何轉化的?

 

  1. 新建(new):新建立了一個線程對象。

  2. 可運行(runnable):線程對象建立後,其餘線程(好比main線程)調用了該對象的start()方法。該狀態的線程位於可運行線程池中,等待被線程調度選中,獲取cpu 的使用權 。

  3. 運行(running):可運行狀態(runnable)的線程得到了cpu 時間片(timeslice) ,執行程序代碼。

  4. 阻塞(block):阻塞狀態是指線程由於某種緣由放棄了cpu 使用權,也即讓出了cpu timeslice,暫時中止運行。直到線程進入可運行(runnable)狀態,纔有機會再次得到cpu timeslice 轉到運行(running)狀態。阻塞的狀況分三種:

(一). 等待阻塞:運行(running)的線程執行o.wait()方法,JVM會把該線程放入等待隊列(waitting queue)中。

(二). 同步阻塞:運行(running)的線程在獲取對象的同步鎖時,若該同步鎖被別的線程佔用,則JVM會把該線程放入鎖池(lock pool)中。

(三). 其餘阻塞:運行(running)的線程執行Thread.sleep(long ms)或t.join()方法,或者發出了I/O請求時,JVM會把該線程置爲阻塞狀態。當sleep()狀態超時、join()等待線程終止或者超時、或者I/O處理完畢時,線程從新轉入可運行(runnable)狀態。

  1. 死亡(dead):線程run()、main() 方法執行結束,或者因異常退出了run()方法,則該線程結束生命週期。死亡的線程不可再次復生。

9七、

Java中CAS算法

參考:http://www.kancloud.cn/seaboat/java-concurrent/117870

9八、

Java線程間的通訊方式?

參考1:http://www.cnblogs.com/mengdd/archive/2013/02/20/2917956.html

參考2:http://www.jb51.net/article/84213.htm

100、Callable和Future的瞭解。
10一、線程池的參數有哪些,在線程池建立一個線程的過程。
10四、Lock接口有哪些實現類,使用場景是什麼。
10五、可重入鎖的用處及實現原理,寫時複製的過程,讀寫鎖,分段鎖(ConcurrentHashMap中的segment)。
10六、悲觀鎖,樂觀鎖,優缺點,CAS有什麼缺陷,該如何解決。
10七、ABC三個線程如何保證順序執行。:先標序號,循環檢測並wait,到序號了則執行

112.多線程的實現方式#

繼承Thread類、實現Runnable接口、使用ExecutorService、Callable、Future實現有返回結果的多線程。

11三、.線程的狀態轉換#

 

 

11四、.如何中止一個線程#
參考文章:
http://www.cnblogs.com/greta/p/5624839.html

11五、.什麼是線程安全#
線程安全就是多線程訪問同一代碼,不會產生不肯定的結果。

11六、.如何保證線程安全#
對非安全的代碼進行加鎖控制;
使用線程安全的類;
多線程併發狀況下,線程共享的變量改成方法級的局部變量。

11八、.synchronized和Lock的區別#
主要相同點:Lock能完成synchronized所實現的全部功能
主要不一樣點:Lock有比synchronized更精確的線程語義和更好的性能。Lock的鎖定是經過代碼實現的,而synchronized是在JVM層面上實現的,synchronized會自動釋放鎖,而Lock必定要求程序員手工釋放,而且必須在finally從句中釋放。Lock還有更強大的功能,例如,它的tryLock方法能夠非阻塞方式去拿鎖。Lock鎖的範圍有侷限性,塊範圍,而synchronized能夠鎖住塊、對象、類。

11九、.多線程如何進行信息交互#
void notify() 喚醒在此對象監視器上等待的單個線程。
void notifyAll() 喚醒在此對象監視器上等待的全部線程。
void wait() 致使當前的線程等待,直到其餘線程調用此對象的notify()方法或notifyAll()方法。
void wait(long timeout) 致使當前的線程等待,直到其餘線程調用此對象的notify()方法或notifyAll()方法,或者超過指定的時間量。
void wait(long timeout, int nanos) 致使當前的線程等待,直到其餘線程調用此對象的notify()方法或notifyAll()方法,或者其餘某個線程中斷當前線程,或者已超過某個實際時間量。

120、.sleep和wait的區別(考察的方向是是否會釋放鎖)#
sleep()方法是Thread類中方法,而wait()方法是Object類中的方法。
sleep()方法致使了程序暫停執行指定的時間,讓出cpu該其餘線程,可是他的監控狀態依然保持者,當指定的時間到了又會自動恢復運行狀態,在調用sleep()方法的過程當中,線程不會釋放對象鎖。而當調用wait()方法的時候,線程會放棄對象鎖,進入等待此對象的等待鎖定池,只有針對此對象調用notify()方法後本線程才進入對象鎖定池準備。

12五、.Java線程池技術及原理#
參考文章:
http://www.importnew.com/19011.html
http://www.cnblogs.com/dolphin0520/p/3932921.html

12六、.java併發包concurrent及經常使用的類#
這個內容有點多,參考文章:
併發包諸類概覽:http://www.raychase.net/1912
線程池:http://www.cnblogs.com/dolphin0520/p/3932921.html
鎖:http://www.cnblogs.com/dolphin0520/p/3923167.html
集合:http://www.cnblogs.com/huangfox/archive/2012/08/16/2642666.html

 12七、.volatile關鍵字#

用volatile修飾的變量,線程在每次使用變量的時候,都會讀取變量修改後的最的值。volatile很容易被誤用,用來進行原子性操做。
Java語言中的volatile變量能夠被看做是一種「程度較輕的
synchronized」;與
synchronized 塊相比,volatile 變量所需的編碼較少,而且運行時開銷也較少,可是它所能實現的功能也僅是synchronized的一部分。鎖提供了兩種主要特性:互斥(mutual
exclusion)和可見性(visibility)。互斥即一次只容許一個線程持有某個特定的鎖,所以可以使用該特性實現對共享數據的協調訪問協議,這樣,一次就只有一個線程可以使用該共享數據。可見性必須確保釋放鎖以前對共享數據作出的更改對於隨後得到該鎖的另外一個線程是可見的,若是沒有同步機制提供的這種可見性保證,線程看到的共享變量多是修改前的值或不一致的值,這將引起許多嚴重問題。Volatile變量具備synchronized的可見性特性,可是不具有原子特性。這就是說線程可以自動發現volatile
變量的最新值。
要使volatile變量提供理想的線程安全,必須同時知足下面兩個條件:對變量的寫操做不依賴於當前值;該變量沒有包含在具備其餘變量的不變式中。
第一個條件的限制使volatile變量不能用做線程安全計數器。雖然增量操做(x++)看上去相似一個單獨操做,實際上它是一個由讀取-修改-寫入操做序列組成的組合操做,必須以原子方式執行,而volatile不能提供必須的原子特性。實現正確的操做須要使x 的值在操做期間保持不變,而volatile
變量沒法實現這點。
每個線程運行時都有一個線程棧,線程棧保存了線程運行時候變量值信息。當線程訪問某一個對象時候值的時候,首先經過對象的引用找到對應在堆內存的變量的值,而後把堆內存變量的具體值load到線程本地內存中,創建一個變量副本,以後線程就再也不和對象在堆內存變量值有任何關係,而是直接修改副本變量的值,在修改完以後的某一個時刻(線程退出以前),自動把線程變量副本的值回寫到對象在堆中變量。這樣在堆中的對象的值就產生變化了。

 

 
 

 

read and load 從主存複製變量到當前工做內存
use and assign 執行代碼,改變共享變量值
store and write 用工做內存數據刷新主存相關內容
其中use and
assign 能夠屢次出現,可是這一些操做並非原子性,也就是在read load以後,若是主內存count變量發生修改以後,線程工做內存中的值因爲已經加載,不會產生對應的變化,因此計算出來的結果會和預期不同。

12八、簡單說說線程池的原理和實現

解答:線程原理及實現

130、另總結多線程相關面試題50道

13二、方法內部,如何實現更好的異步?

答:咱們知道異步其實就是讓另外一個線程去跑,那麼如何建立線程?  第一種直接new Thread ,第二種new 一個實現Runnable接口的實現類。 第三種,經過線程池來管理建立等 ,這裏說到更好的實現異步,那就是說咱們在方法內部避免頻繁的new 線程,就能夠考慮線程池了。 那麼線程池如何建立? 這裏能夠new 一個線程池,可是須要考慮單例,或者在程序初始啓東時,就建立一個線程池,讓他跑着,而後在具體方法的時候,經過線程池來建立線程,實現異步

13三、多線程和單線程的區別和聯繫:

答:

  1. 在單核 CPU 中,將 CPU 分爲很小的時間片,在每一時刻只能有一個線程在執行,是一種微觀上輪流佔用 CPU 的機制。

  2. 多線程會存在線程上下文切換,會致使程序執行速度變慢,即採用一個擁有兩個線程的進程執行所須要的時間比一個線程的進程執行兩次所須要的時間要多一些。

結論:即採用多線程不會提升程序的執行速度,反而會下降速度,可是對於用戶來講,能夠減小用戶的響應時間。

13四、如何指定多個線程的執行順序?

解析:面試官會給你舉個例子,如何讓 10 個線程按照順序打印 0123456789?(寫代碼實現)

答:

  1. 設定一個 orderNum,每一個線程執行結束以後,更新 orderNum,指明下一個要執行的線程。而且喚醒全部的等待線程。

  2. 在每個線程的開始,要 while 判斷 orderNum 是否等於本身的要求值!!不是,則 wait,是則執行本線程。

 

13六、多線程產生死鎖的 4 個必要條件?

答:

  1. 互斥條件:一個資源每次只能被一個線程使用;

  2. 請求與保持條件:一個線程因請求資源而阻塞時,對已得到的資源保持不放;

  3. 不剝奪條件:進程已經得到的資源,在未使用完以前,不能強行剝奪;

  4. 循環等待條件:若干線程之間造成一種頭尾相接的循環等待資源關係。

面試官:如何避免死鎖?(常常接着問這個問題哦~)

答:指定獲取鎖的順序,舉例以下:

  1. 好比某個線程只有得到 A 鎖和 B 鎖才能對某資源進行操做,在多線程條件下,如何避免死鎖?

  2. 得到鎖的順序是必定的,好比規定,只有得到 A 鎖的線程纔有資格獲取 B 鎖,按順序獲取鎖就能夠避免死鎖!!!

13七、sleep( ) 和 wait( n)、wait( ) 的區別:

答:

  1. sleep 方法:是 Thread 類的靜態方法,當前線程將睡眠 n 毫秒,線程進入阻塞狀態。當睡眠時間到了,會解除阻塞,進行可運行狀態,等待 CPU 的到來。睡眠不釋放鎖(若是有的話);

  2. wait 方法:是 Object 的方法,必須與 synchronized 關鍵字一塊兒使用,線程進入阻塞狀態,當 notify 或者 notifyall 被調用後,會解除阻塞。可是,只有從新佔用互斥鎖以後纔會進入可運行狀態。睡眠時,釋放互斥鎖。

13八、synchronized 關鍵字:

答:底層實現:

  1. 進入時,執行 monitorenter,將計數器 +1,釋放鎖 monitorexit 時,計數器-1;

  2. 當一個線程判斷到計數器爲 0 時,則當前鎖空閒,能夠佔用;反之,當前線程進入等待狀態。

含義:(monitor 機制)

Synchronized 是在加鎖,加對象鎖。對象鎖是一種重量鎖(monitor),synchronized 的鎖機制會根據線程競爭狀況在運行時會有偏向鎖(單一線程)、輕量鎖(多個線程訪問 synchronized 區域)、對象鎖(重量鎖,多個線程存在競爭的狀況)、自旋鎖等。

該關鍵字是一個幾種鎖的封裝。

13九、volatile 關鍵字

答:該關鍵字能夠保證可見性不保證原子性。

功能:

  1. 主內存和工做內存,直接與主內存產生交互,進行讀寫操做,保證可見性;

  2. 禁止 JVM 進行的指令重排序。

解析:關於指令重排序的問題,能夠查閱 DCL 雙檢鎖失效相關資料。 

 

鎖機制

一、說說線程安全問題

二、volatile 實現原理

三、synchronize 實現原理

四、synchronized 與 lock 的區別

五、CAS 樂觀鎖

六、ABA 問題

七、樂觀鎖的業務場景及實現方式

八、

Synchronized 與Lock都是可重入鎖,同一個線程再次進入同步代碼的時候.能夠使用本身已經獲取到的鎖。
Synchronized是悲觀鎖機制,獨佔鎖。而Locks.ReentrantLock是,每次不加鎖而是假設沒有衝突而去完成某項操做,若是由於衝突失敗就重試,直到成功爲止。 ReentrantLock適用場景

  1. 某個線程在等待一個鎖的控制權的這段時間須要中斷

  2. 須要分開處理一些wait-notify,ReentrantLock裏面的Condition應用,可以控制notify哪一個線程,鎖能夠綁定多個條件。

  3. 具備公平鎖功能,每一個到來的線程都將排隊等候。

友情連接: Synchronized關鍵字、Lock,並解釋它們之間的區別

九、

CAS(Compare And Swap) 無鎖算法: CAS是樂觀鎖技術,當多個線程嘗試使用CAS同時更新同一個變量時,只有其中一個線程能更新變量的值,而其它線程都失敗,失敗的線程並不會被掛起,而是被告知此次競爭中失敗,並能夠再次嘗試。CAS有3個操做數,內存值V,舊的預期值A,要修改的新值B。當且僅當預期值A和內存值V相同時,將內存值V修改成B,不然什麼都不作。
友情連接:非阻塞同步算法與CAS(Compare and Swap)無鎖算法

1三、悲觀鎖和樂觀鎖的區別,怎麼實現

悲觀鎖:一段執行邏輯加上悲觀鎖,不一樣線程同時執行時,只能有一個線程執行,其餘的線程在入口處等待,直到鎖被釋放。

樂觀鎖:一段執行邏輯加上樂觀鎖,不一樣線程同時執行時,能夠同時進入執行,在最後更新數據的時候要檢查這些數據是否被其餘線程修改了(版本和執行初是否相同),沒有修改則進行更新,不然放棄本次操做。

悲觀鎖的實現:

1
2
3
4
5
6
7
8
9
10
//0.開始事務
begin;/begin work;/start transaction; (三者選一就能夠)
//1.查詢出商品信息
select status from t_goods where id=1 for update;
//2.根據商品信息生成訂單
insert into t_orders (id,goods_id) values (null,1);
//3.修改商品status爲2
update t_goods set status=2;
//4.提交事務
commit;/commit work;

樂觀鎖的實現:

1
2
3
4
5
6
7
1.查詢出商品信息
select (status,status,version) from t_goods where id=#{id}
2.根據商品信息生成訂單
3.修改商品status爲2
update t_goods
set status=2,version=version+1
where id=#{id} and version=#{version};

 

 

 

 

 

JVM

一、

Java內存模型:
Java虛擬機規範中將Java運行時數據分爲六種。
1.程序計數器:是一個數據結構,用於保存當前正常執行的程序的內存地址。Java虛擬機的多線程就是經過線程輪流切換並分配處理器時間來實現的,爲了線程切換後能恢復到正確的位置,每條線程都須要一個獨立的程序計數器,互不影響,該區域爲「線程私有」。
2.Java虛擬機棧:線程私有的,與線程生命週期相同,用於存儲局部變量表,操做棧,方法返回值。局部變量表放着基本數據類型,還有對象的引用。
3.本地方法棧:跟虛擬機棧很像,不過它是爲虛擬機使用到的Native方法服務。
4.Java堆:全部線程共享的一塊內存區域,對象實例幾乎都在這分配內存。
5.方法區:各個線程共享的區域,儲存虛擬機加載的類信息,常量,靜態變量,編譯後的代碼。
6.運行時常量池:表明運行時每一個class文件中的常量表。包括幾種常量:編譯時的數字常量、方法或者域的引用。
友情連接: Java中JVM虛擬機詳解

二、

「你能不能談談,java GC是在何時,對什麼東西,作了什麼事情?」
在何時:
1.新生代有一個Eden區和兩個survivor區,首先將對象放入Eden區,若是空間不足就向其中的一個survivor區上放,若是仍然放不下就會引起一次發生在新生代的minor GC,將存活的對象放入另外一個survivor區中,而後清空Eden和以前的那個survivor區的內存。在某次GC過程當中,若是發現仍然又放不下的對象,就將這些對象放入老年代內存裏去。
2.大對象以及長期存活的對象直接進入老年區。
3.當每次執行minor GC的時候應該對要晉升到老年代的對象進行分析,若是這些立刻要到老年區的老年對象的大小超過了老年區的剩餘大小,那麼執行一次Full GC以儘量地得到老年區的空間。
對什麼東西:從GC Roots搜索不到,並且通過一次標記清理以後仍沒有復活的對象。
作什麼: 新生代:複製清理; 老年代:標記-清除和標記-壓縮算法; 永久代:存放Java中的類和加載類的類加載器自己。
GC Roots都有哪些: 1. 虛擬機棧中的引用的對象 2. 方法區中靜態屬性引用的對象,常量引用的對象 3. 本地方法棧中JNI(即通常說的Native方法)引用的對象。
友情連接:Java GC的那些事(上)
友情連接:Java GC的那些事(下)
友情連接:CMS垃圾收集器介紹

三、

類加載器工做機制:
1.裝載:將Java二進制代碼導入jvm中,生成Class文件。
2.鏈接:a)校驗:檢查載入Class文件數據的正確性 b)準備:給類的靜態變量分配存儲空間 c)解析:將符號引用轉成直接引用
3:初始化:對類的靜態變量,靜態方法和靜態代碼塊執行初始化工做。
雙親委派模型:類加載器收到類加載請求,首先將請求委派給父類加載器完成 用戶自定義加載器->應用程序加載器->擴展類加載器->啓動類加載器。
友情連接:深刻理解Java虛擬機筆記—雙親委派模型 
友情連接:JVM類加載的那些事
友情連接:JVM(1):Java 類的加載機制

四、

Java的四種引用,強弱軟虛,以及用到的場景

a.強引用:若是一個對象具備強引用,它就不會被垃圾回收器回收。即便當前內存空間不足,JVM也不會回收它,而是拋出 OutOfMemoryError 錯誤,使程序異常終止。若是想中斷強引用和某個對象之間的關聯,能夠顯式地將引用賦值爲null,這樣一來的話,JVM在合適的時間就會回收該對象。

b.軟引用:在使用軟引用時,若是內存的空間足夠,軟引用就能繼續被使用,而不會被垃圾回收器回收,只有在內存不足時,軟引用纔會被垃圾回收器回收。

c.弱引用:具備弱引用的對象擁有的生命週期更短暫。由於當 JVM 進行垃圾回收,一旦發現弱引用對象,不管當前內存空間是否充足,都會將弱引用回收。不過因爲垃圾回收器是一個優先級較低的線程,因此並不必定能迅速發現弱引用對象。

d.虛引用:顧名思義,就是形同虛設,若是一個對象僅持有虛引用,那麼它至關於沒有引用,在任什麼時候候均可能被垃圾回收器回收。

五、

JAVA 中堆和棧的區別,說下java 的內存機制

a.基本數據類型比變量和對象的引用都是在棧分配的

b.堆內存用來存放由new建立的對象和數組

c.類變量(static修飾的變量),程序在一加載的時候就在堆中爲類變量分配內存,堆中的內存地址存放在棧中

d.實例變量:當你使用java關鍵字new的時候,系統在堆中開闢並不必定是連續的空間分配給變量,是根據零散的堆內存地址,經過哈希算法換算爲一長串數字以表徵這個變量在堆中的」物理位置」,實例變量的生命週期–當實例變量的引用丟失後,將被GC(垃圾回收器)列入可回收「名單」中,但並非立刻就釋放堆中內存

e.局部變量: 由聲明在某方法,或某代碼段裏(好比for循環),執行到它的時候在棧中開闢內存,當局部變量一但脫離做用域,內存當即釋放

六、JAVA多態的實現原理

a.抽象的來說,多態的意思就是同一消息能夠根據發送對象的不一樣而採用多種不一樣的行爲方式。(發送消息就是函數調用)

b.實現的原理是動態綁定,程序調用的方法在運行期才動態綁定,追溯源碼能夠發現,JVM 經過參數的自動轉型來找到合適的辦法。

七、JVM的內存結構,JVM的算法;

九、數組在內存中如何分配:基本類型數組在棧上分配,對象類型在堆上分配

七、java中常說的堆和棧,分別是什麼數據結構;另外,爲何要分爲堆和棧來存儲數據。

八、Java虛擬機 
(1)組成以及各部分做用: 
http://blog.csdn.net/zhaojw_420/article/details/70477953 
(2)類加載器——ClassLoader: 
http://blog.csdn.net/zhaojw_420/article/details/53373898 
(3)類加載器的父親委託機制深度詳解: 
http://blog.csdn.net/zhaojw_420/article/details/53284225 
(4)JVM調優: 
http://blog.csdn.net/zhaojw_420/article/details/70527138 
(5)垃圾回收: 
http://blog.csdn.net/zhaojw_420/article/details/70527232

 九、Java內存模型 
http://blog.csdn.net/zhaojw_420/article/details/70477903

十二、講講什麼狀況下回出現內存溢出,內存泄漏?

1三、說說Java線程棧

1四、JVM 年輕代到年老代的晉升過程的判斷條件是什麼呢?

1五、JVM 出現 fullGC 很頻繁,怎麼去線上排查問題?

1六、類加載爲何要使用雙親委派模式,有沒有什麼場景是打破了這個模式?

1七、類的實例化順序:先父類,再子類

1八、JVM垃圾回收機制,什麼時候觸發MinorGC等操做:eden區沒法爲對象分配空間

1九、JVM 中一次完整的 GC 流程(從 ygc 到 fgc)是怎樣的

20、各類回收器,各自優缺點,重點CMS、G1

2一、各類回收算法

2二、OOM錯誤,stackoverflow錯誤,permgen space錯誤

2三、Java中有哪些多線程同步的手段

這個問題也能夠延伸出不少知識,synchronized的實現原理、synchronized中的鎖膨脹、爲何有時候使用volatile能夠帶來更好的性能、悲觀鎖&樂觀鎖的概念、新一代的基於Lock的鎖機制,更甚者可能會問到Java的內存模型(JMM)。

24. 你知道哪些或者大家線上使⽤什麼GC策略? 它有什麼優點,適⽤於什麼 場景?

25. JAVA類加載器包括⼏種?它們之間的⽗⼦關係是怎麼樣的?雙親委派機 制是什麼意思?有什麼好處?

26. 如何⾃定義⼀個類加載器?你使⽤過哪些或者你在什麼場景下須要⼀個⾃ 定義的類加載器嗎?

27. 堆內存設置的參數是什麼? 5. Perm Space中保存什麼數據? 會引發OutOfMemory嗎? 6. 作gc時,⼀個對象在內存各個Space中被移動的順序是什麼?

28. 你有沒有遇到過OutOfMemory問題?你是怎麼來處理這個問題的?處理過程當中有哪些收穫?

29. 1.8以後Perm Space有哪些變更? MetaSpace⼤⼩默認是⽆限的麼? 仍是大家會經過什麼⽅式來指定⼤⼩?:不是,默認20M,XX:MetaspaceSize=200m;-XX:MaxMetaspaceSize=256m

30. Jstack是⼲什麼的? Jstat呢? 若是線上程序週期性地出現卡頓,你懷疑多是gc致使的,你會怎麼來排查這個問題?線程⽇志⼀般你會看其中的什麼 部分?:jstack查看線程堆棧|查看fullgc/minor時間和頻率|線程日誌通常看blocked-->waiting-->timed_waiting

31. StackOverFlow異常有沒有遇到過?⼀般你猜想會在什麼狀況下被觸發?如何指定⼀個線程的堆棧⼤⼩?⼀般大家寫多少?:xss來指定

32. JVM的內存結構

根據 JVM 規範,JVM 內存共分爲虛擬機棧、堆、方法區、程序計數器、本地方法棧五個部分。

一、Java虛擬機棧:

線程私有;每一個方法在執行的時候會建立一個棧幀,存儲了局部變量表,操做數棧,動態鏈接,方法返回地址等;每一個方法從調用到執行完畢,對應一個棧幀在虛擬機棧中的入棧和出棧。

二、堆:

線程共享;被全部線程共享的一塊內存區域,在虛擬機啓動時建立,用於存放對象實例。

三、方法區:

線程共享;被全部線程共享的一塊內存區域;用於存儲已被虛擬機加載的類信息,常量,靜態變量等。

四、程序計數器:

線程私有;是當前線程所執行的字節碼的行號指示器,每條線程都要有一個獨立的程序計數器,這類內存也稱爲「線程私有」的內存。

五、本地方法棧:

線程私有;主要爲虛擬機使用到的Native方法服務。

 3四、 數組在內存中如何分配

一、簡單的值類型的數組,每一個數組成員是一個引用(指針),引用到棧上的空間(由於值類型變量的內存分配在棧上)

二、引用類型,類類型的數組,每一個數組成員還是一個引用(指針),引用到堆上的空間(由於類的實例的內存分配在堆上)

3五、請寫一段棧溢出、堆溢出的代碼

遞歸調用能夠致使棧溢出
不斷建立對象能夠致使堆溢出 

3六、java中常說的堆和棧,分別是什麼數據結構;另外,爲何要分爲堆和棧來存儲數據

爲何要劃分堆和棧

一、從軟件設計的角度看,棧表明了處理邏輯,而堆表明了數據。這樣分開,使得處理邏輯更爲清晰。

二、堆與棧的分離,使得堆中的內容能夠被多個棧共享。一方面這種共享提供了一種有效的數據交互方式(如:共享內存),另外一方面,堆中的共享常量和緩存能夠被全部棧訪問,節省了空間。

三、棧由於運行時的須要,好比保存系統運行的上下文,須要進行地址段的劃分。因爲棧只能向上增加,所以就會限制住棧存儲內容的能力。而堆不一樣,堆中的對象是能夠根據須要動態增加的,所以棧和堆的拆分,使得動態增加成爲可能,相應棧中只需記錄堆中的一個地址便可。

四、體現了Java面向對象這一核心特色(也能夠繼續說一些本身的理解)

3七、.Jvm垃圾收集器與內存分配策略:http://www.importnew.com/23035.html
3八、.Jvm運行和類加載過程:http://www.javashuo.com/article/p-updqgwok-dd.html
3九、.Jvm字節碼執行:http://blog.csdn.net/u012077981/article/details/40156391
40、.java內存模型:http://blog.csdn.net/suifeng3051/article/details/52611310;
  http://www.hao124.net/article/49  

4一、

Java8的內存分代改進

參考:http://blog.csdn.net/chlu113/article/details/51890469

4二、對Java內存模型的理解以及其在併發當中的做用?

參考:http://www.cnblogs.com/_popc/p/6096517.html

4三、Java中堆內存和棧內存區別?

參考:http://www.cnblogs.com/whgw/archive/2011/09/29/2194997.html

4四、JVM的內存結構。

4五、JVM方法棧的工做過程,方法棧和本地方法棧有什麼區別。

4六、JVM的棧中引用如何和堆中的對象產生關聯。

4七、能夠了解一下逃逸分析技術。

4八、GC的常見算法,CMS以及G1的垃圾回收過程,CMS的各個階段哪兩個是Stop the world的,CMS會不會產生碎片,G1的優點。

4九、標記清除和標記整理算法的理解以及優缺點。

50、eden survivor區的比例,爲何是這個比例,eden survivor的工做過程。

5一、JVM如何判斷一個對象是否該被GC,能夠視爲root的都有哪幾種類型。

5二、強軟弱虛引用的區別以及GC對他們執行怎樣的操做。

5三、Java是否能夠GC直接內存。

5四、Java類加載的過程。

5五、雙親委派模型的過程以及優點。

5六、經常使用的JVM調優參數。

5七、dump文件的分析。

5八、Java有沒有主動觸發GC的方式(沒有)。

5九、內存溢出和內存泄漏的區別#
內存溢出是指程序在申請內存時,沒有足夠的內存空間供其使用,出現out of
memory。
內存泄漏是指分配出去的內存再也不使用,可是沒法回收。

60、Java內存模型及各個區域的OOM,如何重現OOM#
這部份內容很重要,詳細閱讀《深刻理解Java虛擬機》,也能夠詳細閱讀這篇文章http://hllvm.group.iteye.com/group/wiki/2857-JVM

6一、出現OOM如何解決#
一. 可經過命令按期抓取heap dump或者啓動參數OOM時自動抓取heap dump文件。
二. 經過對比多個heap dump,以及heap dump的內容,分析代碼找出內存佔用最多的地方。
三. 分析佔用的內存對象,是不是由於錯誤致使的內存未及時釋放,或者數據過多致使的內存溢出。

6三、Java內存管理及回收算法#
閱讀這篇文章:http://www.cnblogs.com/hnrainll/archive/2013/11/06/3410042.html

6四、Java類加載器及如何加載類(雙親委派)#
閱讀文章:
https://www.ibm.com/developerworks/cn/java/j-lo-classloader/(推薦)
http://blog.csdn.net/zhoudaxia/article/details/35824249

 6五、 JVM結構原理、GC工做機制詳解

答:具體參照:JVM結構、GC工做機制詳解     ,說到GC,記住兩點:一、GC是負責回收全部無任何引用對象的內存空間。 注意:垃圾回收回收的是無任何引用的對象佔據的內存空間而不是對象自己,二、GC回收機制的兩種算法,a、引用計數法  b、可達性分析算法(  這裏的可達性,你們能夠看基礎2 Java對象的什麼週期),至於更詳細的GC算法介紹,你們能夠參考:Java GC機制算法

6六、談談你對JVM的理解?

答: Java語言的一個很是重要的特色就是與平臺的無關性。而使用Java虛擬機是實現這一特色的關鍵。Java編譯器只要面向JVM,生成JVM能理解的代碼或字節碼文件。Java源文件經編譯成字節碼程序,經過JVM將每一條指令翻譯成不一樣平臺機器碼,經過特定平臺運行。

JVM執行程序的過程 :I.加載。class文件   ,II.管理並分配內存  ,III.執行垃圾收集

JRE(java運行時環境)由JVM構造的java程序的運行環境 

 

具體詳情:JVM原理和調優

 

既然是 Java 開發面試,那麼對 JVM 的考察固然也是必須的,面試官通常會問你對 JVM 有了解嗎?

我一般都會把我所瞭解的都說一遍,包括:JVM 內存劃分、JVM 垃圾回收的含義,有哪些 GC 算法,年輕代和老年代各自的特色通通闡述一遍。

6七、JVM 內存劃分:

  1. 方法區(線程共享):常量、靜態變量、JIT(即時編譯器) 編譯後的代碼也都在方法區;

  2. 堆內存(線程共享):垃圾回收的主要場所;

  3. 程序計數器: 當前線程執行的字節碼的位置指示器;

  4. 虛擬機棧(棧內存):保存局部變量、基本數據類型變量以及堆內存中某個對象的引用變量;

  5. 本地方法棧 :爲 JVM 提供使用 native 方法的服務。

6八、相似-Xms、-Xmn 這些參數的含義:

答:

堆內存分配:

  1. JVM 初始分配的內存由-Xms 指定,默認是物理內存的 1/64;

  2. JVM 最大分配的內存由-Xmx 指定,默認是物理內存的 1/4;

  3. 默認空餘堆內存小於 40% 時,JVM 就會增大堆直到-Xmx 的最大限制;空餘堆內存大於 70% 時,JVM 會減小堆直到 -Xms 的最小限制;

  4. 所以服務器通常設置-Xms、-Xmx 相等以免在每次 GC 後調整堆的大小。對象的堆內存由稱爲垃圾回收器的自動內存管理系統回收。

非堆內存分配:

  1. JVM 使用-XX:PermSize 設置非堆內存初始值,默認是物理內存的 1/64;

  2. 由 XX:MaxPermSize 設置最大非堆內存的大小,默認是物理內存的 1/4;

  3. -Xmn2G:設置年輕代大小爲 2G;

  4. -XX:SurvivorRatio,設置年輕代中 Eden 區與 Survivor 區的比值。

6九、垃圾回收算法有哪些?

答:

  1. 引用計數 :原理是此對象有一個引用,即增長一個計數,刪除一個引用則減小一個計數。垃圾回收時,只用收集計數爲 0 的對象。此算法最致命的是沒法處理循環引用的問題;

  2. 標記-清除 :此算法執行分兩階段。第一階段從引用根節點開始標記全部被引用的對象,第二階段遍歷整個堆,把未標記的對象清除;

此算法須要暫停整個應用,同時,會產生內存碎片;

  1. 複製算法 :此算法把內存空間劃爲兩個相等的區域,每次只使用其中一個區域。垃圾回收時,遍歷當前使用區域,把正在使用中的對象複製到另一個區域中;

此算法每次只處理正在使用中的對象,所以複製成本比較小,同時複製過去之後還能進行相應的內存整理,不會出現 「碎片」 問題。固然,此算法的缺點也是很明顯的,就是須要兩倍內存空間;

  1. 標記-整理 :此算法結合了 「標記-清除」 和 「複製」 兩個算法的優勢。也是分兩階段,第一階段從根節點開始標記全部被引用對象,第二階段遍歷整個堆,把清除未標記對象而且把存活對象 「壓縮」 到堆的其中一塊,按順序排放。

此算法避免了 「標記-清除」 的碎片問題,同時也避免了 「複製」 算法的空間問題。

70、root 搜索算法中,哪些能夠做爲 root?

答:

  • 被啓動類(bootstrap 加載器)加載的類和建立的對象;

  • JavaStack 中的引用的對象 (棧內存中引用的對象);

  • 方法區中靜態引用指向的對象;

  • 方法區中常量引用指向的對象;

  • Native 方法中 JNI 引用的對象。

7一、GC 何時開始?

答:GC 常常發生的區域是堆區,堆區還能夠細分爲新生代、老年代,新生代還分爲一個 Eden 區和兩個 Survivor 區。

  1. 對象優先在 Eden 中分配,當 Eden 中沒有足夠空間時,虛擬機將發生一次 Minor GC,由於 Java 大多數對象都是朝生夕滅,因此 Minor GC 很是頻繁,並且速度也很快;

  2. Full GC,發生在老年代的 GC,當老年代沒有足夠的空間時即發生 Full GC,發生 Full GC 通常都會有一次 Minor GC。

大對象直接進入老年代,如很長的字符串數組,虛擬機提供一個;XX:PretenureSizeThreadhold 參數,令大於這個參數值的對象直接在老年代中分配,避免在 Eden 區和兩個 Survivor 區發生大量的內存拷貝;

  1. 發生 Minor GC 時,虛擬機會檢測以前每次晉升到老年代的平均大小是否大於老年代的剩餘空間大小,若是大於,則進行一次 Full GC,若是小於,則查看 HandlePromotionFailure 設置是否容許擔保失敗,若是容許,那隻會進行一次 Minor GC,若是不容許,則改成進行一次 Full GC。

7二、內存泄漏和內存溢出

答:

概念:

  1. 內存溢出指的是內存不夠用了;

  2. 內存泄漏是指對象可達,可是沒用了。即本該被 GC 回收的對象並無被回收;

  3. 內存泄露是致使內存溢出的緣由之一;內存泄露積累起來將致使內存溢出。

內存泄漏的緣由分析:

  1. 長生命週期的對象引用短生命週期的對象;

  2. 沒有將無用對象置爲 null。

小結:本小節涉及到 JVM 虛擬機,包括對內存的管理等知識,相對較深。除了以上問題,面試官會繼續問你一些比較深的問題,可能也是爲了看看你的極限在哪裏吧。

好比:內存調優、內存管理,是否遇到過內存泄漏的實際案例、是否真正關心過內存等。因爲本人實際項目經驗不足,這些深層次問題並無接觸過,各位有須要能夠上網查閱。

 

 

IO/NIO

一、bio,nio,aio的區別;

二、nio框架:dubbo的實現原理;

三、京東內部的jsf是使用的什麼協議通信:可參見dubbo的協議;

五、http://blog.csdn.net/zhaojw_420/article/details/70526695

六、BIO、NIO和AIO的區別

Java BIO : 同步並阻塞,服務器實現模式爲一個鏈接一個線程,即客戶端有鏈接請求時服務器端就須要啓動一個線程進行處理,若是這個鏈接不作任何事情會形成沒必要要的線程開銷,固然能夠經過線程池機制改善。

Java NIO : 同步非阻塞,服務器實現模式爲一個請求一個線程,即客戶端發送的鏈接請求都會註冊到多路複用器上,多路複用器輪詢到鏈接有I/O請求時才啓動一個線程進行處理。

Java AIO: 異步非阻塞,服務器實現模式爲一個有效請求一個線程,客戶端的I/O請求都是由OS先完成了再通知服務器應用去啓動線程進行處理。

NIO比BIO的改善之處是把一些無效的鏈接擋在了啓動線程以前,減小了這部分資源的浪費(由於咱們都知道每建立一個線程,就要爲這個線程分配必定的內存空間)

AIO比NIO的進一步改善之處是將一些暫時可能無效的請求擋在了啓動線程以前,好比在NIO的處理方式中,當一個請求來的話,開啓線程進行處理,但這個請求所須要的資源尚未就緒,此時必須等待後端的應用資源,這時線程就被阻塞了。

適用場景分析:

 BIO方式適用於鏈接數目比較小且固定的架構,這種方式對服務器資源要求比較高,併發侷限於應用中,JDK1.4之前的惟一選擇,但程序直觀簡單易理解,如以前在Apache中使用。

 NIO方式適用於鏈接數目多且鏈接比較短(輕操做)的架構,好比聊天服務器,併發侷限於應用中,編程比較複雜,JDK1.4開始支持,如在 Nginx,Netty中使用。

 AIO方式使用於鏈接數目多且鏈接比較長(重操做)的架構,好比相冊服務器,充分調用OS參與併發操做,編程比較複雜,JDK7開始支持,在成長中,Netty曾經使用過,後來放棄。

七、NIO、BIO與AIO:http://blog.51cto.com/stevex/1284437

九、.Java中的NIO,BIO,AIO分別是什麼#
BIO:同步並阻塞,服務器實現模式爲一個鏈接一個線程,即客戶端有鏈接請求時服務器端就須要啓動一個線程進行處理,若是這個鏈接不作任何事情會形成沒必要要的線程開銷,固然能夠經過線程池機制改善。BIO方式適用於鏈接數目比較小且固定的架構,這種方式對服務器資源要求比較高,併發侷限於應用中,JDK1.4之前的惟一選擇,但程序直觀簡單易理解。
NIO:同步非阻塞,服務器實現模式爲一個請求一個線程,即客戶端發送的鏈接請求都會註冊到多路複用器上,多路複用器輪詢到鏈接有I/O請求時才啓動一個線程進行處理。NIO方式適用於鏈接數目多且鏈接比較短(輕操做)的架構,好比聊天服務器,併發侷限於應用中,編程比較複雜,JDK1.4開始支持。
AIO:異步非阻塞,服務器實現模式爲一個有效請求一個線程,客戶端的I/O請求都是由OS先完成了再通知服務器應用去啓動線程進行處理.AIO方式使用於鏈接數目多且鏈接比較長(重操做)的架構,好比相冊服務器,充分調用OS參與併發操做,編程比較複雜,JDK7開始支持。

十、IO和NIO區別#
一.IO是面向流的,NIO是面向緩衝區的。
二.IO的各類流是阻塞的,NIO是非阻塞模式。
三.Java NIO的選擇器容許一個單獨的線程來監視多個輸入通道,你能夠註冊多個通道使用一個選擇器,而後使用一個單獨的線程來「選擇」通道:這些通道里已經有能夠處理的輸入,或者選擇已準備寫入的通道。這種選擇機制,使得一個單獨的線程很容易來管理多個通道。

1三、Java?IO與NIO

NIO是爲了彌補IO操做的不足而誕生的,NIO的一些新特性有:非阻塞I/O,選擇器,緩衝以及管道。管道(Channel),緩衝(Buffer) ,選擇器( Selector)是其主要特徵。

概念解釋

Channel——管道實際上就像傳統IO中的流,到任何目的地(或來自任何地方)的全部數據都必須經過一個 Channel 對象。一個 Buffer 實質上是一個容器對象。

每一種基本 Java 類型都有一種緩衝區類型:

ByteBuffer——byte
CharBuffer——char
ShortBuffer——short
IntBuffer——int
LongBuffer——long
FloatBuffer——float
DoubleBuffer——double
Selector——選擇器用於監聽多個管道的事件,使用傳統的阻塞IO時咱們能夠方便的知道何時能夠進行讀寫,而使用非阻塞通道,咱們須要一些方法來知道何時通道準備好了,選擇器正是爲這個須要而誕生的。

NIO和傳統的IO有什麼區別呢?

IO是面向流的,NIO是面向塊(緩衝區)的。

IO面向流的操做一次一個字節地處理數據。一個輸入流產生一個字節的數據,一個輸出流消費一個字節的數據。,致使了數據的讀取和寫入效率不佳。

NIO面向塊的操做在一步中產生或者消費一個數據塊。按塊處理數據比按(流式的)字節處理數據要快得多,同時數據讀取到一個它稍後處理的緩衝區,須要時可在緩衝區中先後移動。這就增長了處理過程當中的靈活性。通俗來講,NIO採起了「預讀」的方式,當你讀取某一部分數據時,他就會猜想你下一步可能會讀取的數據而預先緩衝下來。

IO是阻塞的,NIO是非阻塞的

對於傳統的IO,當一個線程調用read() 或 write()時,該線程被阻塞,直到有一些數據被讀取,或數據徹底寫入。該線程在此期間不能再幹任何事情了。

而對於NIO,使用一個線程發送讀取數據請求,沒有獲得響應以前,線程是空閒的,此時線程能夠去執行別的任務,而不是像IO中那樣只能等待響應完成。

NIO和IO適用場景

NIO是爲彌補傳統IO的不足而誕生的,可是尺有所短寸有所長,NIO也有缺點,由於NIO是面向緩衝區的操做,每一次的數據處理都是對緩衝區進行的,那麼就會有一個問題,在數據處理以前必需要判斷緩衝區的數據是否完整或者已經讀取完畢,若是沒有,假設數據只讀取了一部分,那麼對不完整的數據處理沒有任何意義。因此每次數據處理以前都要檢測緩衝區數據。

那麼NIO和IO各適用的場景是什麼呢?

若是須要管理同時打開的成千上萬個鏈接,這些鏈接每次只是發送少許的數據,例如聊天服務器,這時候用NIO處理數據多是個很好的選擇。

而若是隻有少許的鏈接,而這些鏈接每次要發送大量的數據,這時候傳統的IO更合適。使用哪一種處理數據,須要在數據的響應等待時間和檢查緩衝區數據的時間上做比較來權衡選擇。

通俗解釋,最後,對於NIO和傳統IO

有一個網友講的生動的例子:

之前的流老是堵塞的,一個線程只要對它進行操做,其它操做就會被堵塞,也就至關於水管沒有閥門,你伸手接水的時候,無論水到了沒有,你就都只能耗在接水(流)上。

nio的Channel的加入,至關於增長了水龍頭(有閥門),雖然一個時刻也只能接一個水管的水,但依賴輪換策略,在水量不大的時候,各個水管裏流出來的水,均可以獲得妥

善接納,這個關鍵之處就是增長了一個接水工,也就是Selector,他負責協調,也就是看哪根水管有水了的話,在當前水管的水接到必定程度的時候,就切換一下:臨時關上當

前水龍頭,試着打開另外一個水龍頭(看看有沒有水)。

當其餘人須要用水的時候,不是直接去接水,而是事前提了一個水桶給接水工,這個水桶就是Buffer。也就是,其餘人雖然也可能要等,但不會在現場等,而是回家等,能夠作

其它事去,水接滿了,接水工會通知他們。

這其實也是很是接近當前社會分工細化的現實,也是統分利用現有資源達到併發效果的一種很經濟的手段,而不是動不動就來個並行處理,雖然那樣是最簡單的,但也是最浪費資源的方式。

 

算法

 一、TreeMap如何插入數據:二叉樹的左旋,右旋,雙旋;

二、個排序以後的數組,插入數據,能夠使用什麼方法?答:二分法;問:時間複雜度是多少?

三、平衡二叉樹的時間複雜度;

四、Hash算法和二叉樹算法分別何時用;

五、圖的廣度優先算法和深度優先算法:詳見jvm中垃圾回收實現;

六、鏈表,棧,隊列,二叉樹: 
http://blog.csdn.net/zhaojw_420/article/details/68485474 

七、八大排序算法: 
八、查找算法

九、.隊列:http://blog.csdn.net/javazejian/article/details/53375004
十、.堆棧:http://blog.csdn.net/javazejian/article/details/53362993
十一、.鏈表:http://blog.csdn.net/jianyuerensheng/article/details/51200274
十二、.樹:[二叉樹]http://blog.csdn.net/javazejian/article/details/53727333
 [B樹]http://blog.csdn.net/liuquan0071/article/details/50521032
 [哈夫曼樹]http://blog.csdn.net/axi295309066/article/details/54019807
1三、.(圖)廣度優先、深度優先:https://segmentfault.com/a/1190000002685939
1四、.常見排序算法:https://www.cnblogs.com/qqzy168/archive/2013/08/03/3219201.html
1五、.常見查找算法:http://blog.csdn.net/wqc_csdn/article/details/52691019
1六、.hash原理:http://blog.csdn.net/tanggao1314/article/details/51457585
1七、.hashmap實現:http://www.javashuo.com/article/p-kjwdvdbc-ke.html

 1八、B+樹

1九、快速排序,堆排序,插入排序(其實八大排序算法都應該瞭解

20、一致性Hash算法,一致性Hash算法的應用

2一、.深度優先和廣度優先算法#
推薦看書籍複習!可參考文章:
http://blog.163.com/zhoumhan_0351/blog/static/3995422720098342257387/
http://blog.163.com/zhoumhan_0351/blog/static/3995422720098711040303/
http://blog.csdn.net/andyelvis/article/details/1728378
http://driftcloudy.iteye.com/blog/782873

2二、排序算法及對應的時間複雜度和空間複雜度#
推薦看書籍複習!可參考文章:
http://www.cnblogs.com/liuling/p/2013-7-24-01.html
http://blog.csdn.net/cyuyanenen/article/details/51514443
http://blog.csdn.net/whuslei/article/details/6442755

2三、排序算法編碼實現#
參考http://www.cnblogs.com/liuling/p/2013-7-24-01.html

2四、.查找算法#
參考http://sanwen8.cn/p/142Wbu5.html

2五、.B+樹#
參考http://www.cnblogs.com/syxchina/archive/2011/03/02/2197251.html

2六、.KMP算法#
推薦閱讀數據複習!參考http://www.cnblogs.com/c-cloud/p/3224788.html

2七、.hash算法及經常使用的hash算法#
參考http://www.360doc.com/content/13/0409/14/10384031_277138819.shtml

2八、.如何判斷一個單鏈表是否有環#
參考文章:
http://www.jianshu.com/p/0e28d31600dd
http://my.oschina.net/u/2391658/blog/693277?p={{totalPage}}

30、談談紅黑樹

答:算法和數據結構一直是我薄弱之處,這方面說本身補吧,成效不大,這裏我就推薦一個:紅黑樹

3一、舉例說說幾個排序,並說明其排序原理

答:這裏我就不細說了,你們本身看看 Java實現幾種常見的排序算法

 

 

其餘

1四、tcp/ip協議簇;

1五、osi五層網絡協議;

1六、tcp,udp區別;

2三、進程通信的方式:消息隊列,共享內存,信號量,socket通信等;

2九、TCP的三次握手和四次揮手

30、單例模式,工廠模式,建造者模式,觀察者模式,適配器模式,代理模式等等

3二、Java8比Java7添加了什麼新的特性

A:Lambda、streams、接口默認方法……

3三、 Java自帶線程池判斷線程池是否已經結束運行的方法叫什麼:isShutdown和isTerminated。

3四、BlockingQueueCountDownLatchSemeaphore的使用場景

3六、 若是要從LinkedBlockingQueue中取出頭部對象,分別哪一個方法會返回null、拋錯、阻塞:take - 阻塞,poll - 返回null,remove - 拋錯

44. 說說http,https協議

HTTP:

是互聯網上應用最爲普遍的一種網絡協議,是一個客戶端和服務器端請求和應答的標準(TCP),用於從WWW服務器傳輸超文本到本地瀏覽器的傳輸協議,它能夠使瀏覽器更加高效,使網絡傳輸減小。

HTTPS:

是以安全爲目標的HTTP通道,簡單講是HTTP的安全版,即HTTP下加入SSL層,HTTPS的安全基礎是SSL,所以加密的詳細內容就須要SSL。

區別:

一、https協議須要到ca申請證書,通常免費證書較少,於是須要必定費用。

二、http是超文本傳輸協議,信息是明文傳輸,https則是具備安全性的ssl加密傳輸協議。

三、http和https使用的是徹底不一樣的鏈接方式,用的端口也不同,前者是80,後者是443。

四、http的鏈接很簡單,是無狀態的;HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網絡協議,比http協議安全。

45. 說說tcp/ip協議族

TCP/IP協議族是一個四層協議系統,自底而上分別是數據鏈路層、網絡層、傳輸層和應用層。每一層完成不一樣的功能,且經過若干協議來實現,上層協議使用下層協議提供的服務。

一、數據鏈路層負責幀數據的傳遞。

二、網絡層責數據怎樣傳遞過去。

三、傳輸層負責傳輸數據的控制(準確性、安全性)

四、應用層負責數據的展現和獲取。

 

4六、tcp五層網絡協議

物理層:

爲數據端設備提供傳送數據的通路,數據通路能夠是一個物理媒體,也能夠是多個物理媒體鏈接而成。

 數據鏈路層:

爲網絡層提供數據傳送服務。

 網絡層:

路由選擇和中繼、激活,終止網絡鏈接、在一條數據鏈路上覆用多條網絡鏈接,多采起分時複用技術 、差錯檢測與恢復、排序,流量控制、服務選擇、網絡管理 。

 傳輸層:

傳輸層是兩臺計算機通過網絡進行數據通訊時,第一個端到端的層次,具備緩衝做用。

 應用層:

應用層嚮應用程序提供服務

4七、TCP與UDP的區別

一、基於鏈接與無鏈接

二、TCP要求系統資源較多,UDP較少; 

三、UDP程序結構較簡單 

四、流模式(TCP)與數據報模式(UDP); 

五、TCP保證數據正確性,UDP可能丟包 

六、TCP保證數據順序,UDP不保證 

4九、TCP長鏈接和短鏈接:http://www.javashuo.com/article/p-vobwkkvc-dq.html
50、.TCP與UDP區別:http://blog.csdn.net/li_ning_/article/details/52117463
5一、.TCP三次握手四次揮手過程:http://www.javashuo.com/article/p-hvkgbelr-cs.html
5二、.http幾個重要概念:http://blog.csdn.net/drixe/article/details/1893558
5三、.http的報文結構:http://blog.csdn.net/zhangliang_571/article/details/23508953
5四、.GET/POST以及冪等性:http://blog.csdn.net/dongzhiquan/article/details/6113966
5五、.http request的幾種類型:http://www.javashuo.com/article/p-vfuhzuiq-dz.html
5六、.http幾個版本之間的區別:http://blog.csdn.net/zocojoker/article/details/53868639 

6六、一個ArrayList在循環過程當中刪除,會不會出問題,爲何。

6八、三次握手,四次揮手,爲何要四次揮手。
6九、長鏈接和短鏈接。

 7一、.OSI七層模型以及TCP/IP四層模型#

參考文章:
http://blog.csdn.net/sprintfwater/article/details/8751453
http://www.cnblogs.com/commanderzhu/p/4821555.html
http://blog.csdn.net/superjunjin/article/details/7841099

7三、.HTTP報文內容#
參考文章:
https://yq.aliyun.com/articles/44675
http://www.cnblogs.com/klguang/p/4618526.html
http://my.oschina.net/orgsky/blog/387759

7四、get提交和post提交的區別#
參考文章:
http://www.cnblogs.com/hyddd/archive/2009/03/31/1426026.html
http://www.jellythink.com/archives/806

7六、TCP的三次握手和四次揮手#
閱讀http://www.jianshu.com/p/f7d1010fa603

7七、.TCP和UDP區別#
參考http://www.cnblogs.com/bizhu/archive/2012/05/12/2497493.html

8三、Excption與Error包結構。OOM你遇到過哪些狀況,SO F你遇到過哪些狀況
Throwable是 Java 語言中全部錯誤或異常的超類。 Throwable包含兩個子類: Error 和 Exception 。它們一般用於指示發生了異常狀況。 Throwable包含了其線程建立時線程執行堆棧的快照,它提供了printStackTrace()等接口用於獲取堆棧跟蹤數據等信息。

Java將可拋出(Throwable)的結構分爲三種類型:

被檢查的異常(Checked Exception)。 運行時異常(RuntimeException)。 錯誤(Error)。

運行時異常RuntimeException

定義 : RuntimeException及其子類都被稱爲運行時異常。 特色 : Java編譯器不會檢查它 也就是說,當程序中可能出現這類異常時,假若既"沒有經過throws聲明拋出它",也"沒有用try-catch語句捕獲它",仍是會編譯經過。

例如,除數爲零時產生的ArithmeticException異常,數組越界時產生的IndexOutOfBoundsException異常,fail-fail機制產生的ConcurrentModificationException異常等,都屬於運行時異常。

堆內存溢出 OutOfMemoryError(OOM)

除了程序計數器外,虛擬機內存的其餘幾個運行時區域都有發生OutOfMemoryError(OOM)異常的可能。

Java Heap 溢出。 通常的異常信息:java.lang.OutOfMemoryError:Java heap spacess。 java堆用於存儲對象實例,咱們只要不斷的建立對象,而且保證GC Roots到對象之間有可達路徑來避免垃圾回收機制清除這些對象,就會在對象數量達到最大堆容量限制後產生內存溢出異常。

堆棧溢出 StackOverflow (SOF)

StackOverflowError 的定義: 當應用程序遞歸太深而發生堆棧溢出時,拋出該錯誤。 由於棧通常默認爲1-2m,一旦出現死循環或者是大量的遞歸調用,在不斷的壓棧過程當中,形成棧容量超過1m而致使溢出。

棧溢出的緣由:

遞歸調用。 大量循環或死循環。 全局變量是否過多。 數組、List、map數據過大。

8九、foreach與正常for循環效率對比

用for循環arrayList 10萬次花費時間:5毫秒。 用foreach循環arrayList 10萬次花費時間:7毫秒。 用for循環linkList 10萬次花費時間:4481毫秒。 用foreach循環linkList 10萬次花費時間:5毫秒。

循環ArrayList時,普通for循環比foreach循環花費的時間要少一點。 循環LinkList時,普通for循環比foreach循環花費的時間要多不少。

當我將循環次數提高到一百萬次的時候,循環ArrayList,普通for循環仍是比foreach要快一點;可是普通for循環在循環LinkList時,程序直接卡死。

ArrayList:ArrayList是採用數組的形式保存對象的,這種方式將對象放在連續的內存塊中,因此插入和刪除時比較麻煩,查詢比較方便。

LinkList:LinkList是將對象放在獨立的空間中,並且每一個空間中還保存下一個空間的索引,也就是數據結構中的鏈表結構,插入和刪除比較方便,可是查找很麻煩,要從第一個開始遍歷。

結論:

須要循環數組結構的數據時,建議使用普通for循環,由於for循環採用下標訪問,對於數組結構的數據來講,採用下標訪問比較好。

須要循環鏈表結構的數據時,必定不要使用普通for循環,這種作法很糟糕,數據量大的時候有可能會致使系統崩潰。

90、java反射的做用於原理
什麼是Java的反射呢?

Java 反射是可讓咱們在運行時,經過一個類的Class對象來獲取它獲取類的方法、屬性、父類、接口等類的內部信息的機制。

這種動態獲取信息以及動態調用對象的方法的功能稱爲JAVA的反射。

反射的做用?

反射就是:在任意一個方法裏:

1.若是我知道一個類的名稱/或者它的一個實例對象, 我就能把這個類的全部方法和變量的信息找出來(方法名,變量名,方法,修飾符,類型,方法參數等等全部信息)

2.若是我還明確知道這個類裏某個變量的名稱,我還能獲得這個變量當前的值。

3.固然,若是我明確知道這個類裏的某個方法名+參數個數類型,我還能經過傳遞參數來運行那個類裏的那個方法。

反射機制主要提供瞭如下功能:

在運行時判斷任意一個對象所屬的類。
在運行時構造任意一個類的對象。
在運行時判斷任意一個類所具備的成員變量和方法。
在運行時調用任意一個對象的方法。
生成動態代理。
9一、反射的原理?

JAVA語言編譯以後會生成一個.class文件,反射就是經過字節碼文件找到某一個類、類中的方法以及屬性等。

反射的實現API有哪些?

反射的實現主要藉助如下四個類:

Class:類的對象
Constructor:類的構造方法
Field:類中的屬性對象
Method:類中的方法對象
反射的實例

blog.csdn.net/xuefeng_yan…

www.cnblogs.com/zhaoyanjun/…

9二、泛型經常使用特色
List<String>可否轉爲List<Object>
不能夠強轉類型的

這個問題涉及到了,範型向上轉型 和 範型向下轉型問題。 List向上轉換至List(等價於List)會丟失String類的身份(String類型的特有接口)。 當須要由List向下轉型時,你的程序必須明確的知道將對象轉換成何種具體類型,否則這將是不安全的操做。

若是要強轉類型,Json 序列化轉型

List<String> str = new ArrayList<String>();
List<Object> obj= JSONObject.parseArray(JSONObject.toJSONString(str));
或者遍歷,或者克隆,可是取出來就是(Object)了,須要強轉,String 由於類型丟了。

9五、Java1.7與1.8,1.9,10 新特性

1.5

自動裝箱與拆箱
枚舉(經常使用來設計單例模式)
靜態導入
可變參數
內省
1.6

Web服務元數據
腳本語言支持
JTable的排序和過濾
更簡單,更強大的JAX-WS
輕量級Http Server
嵌入式數據庫 Derby
1.7

switch中能夠使用字串了
運用List tempList = new ArrayList<>(); 即泛型實例化類型自動推斷
語法上支持集合,而不必定是數組
新增一些取環境信息的工具方法
Boolean類型反轉,空指針安全,參與位運算
兩個char間的equals
安全的加減乘除
map集合支持併發請求,且能夠寫成 Map map = {name:"xxx",age:18};
1.8

容許在接口中有默認方法實現
Lambda表達式
函數式接口
方法和構造函數引用
Lambda的範圍
內置函數式接口
Streams
Parallel Streams
Map
時間日期API
Annotations
1.9

Jigsaw 項目;模塊化源碼
簡化進程API
輕量級 JSON API
錢和貨幣的API
改善鎖爭用機制
代碼分段緩存
智能Java編譯, 第二階段
HTTP 2.0客戶端
Kulla計劃: Java的REPL實現
10

本地變量類型推斷
統一JDK倉庫
垃圾回收器接口
G1的並行Full GC
應用程序類數據共享
ThreadLocal握手機制
設計模式:單例、工廠、適配器、責任鏈、觀察者等等
【示例】設計模式——單例模式、工廠模式、代理模式、觀察者模式、裝飾器模式

blog.csdn.net/learrrrrrrr…

菜鳥教程-設計模式

www.runoob.com/design-patt…

9六、什麼是設計模式

設計模式是一種解決方案,用於解決在軟件設計中廣泛存在的問題,是前輩們對以前軟件設計中反覆出現的問題的一個總結。

咱們學設計模式,是爲了學習如何合理的組織咱們的代碼,如何解耦,如何真正的達到對修改封閉對擴展開放的效果,而不是去背誦那些類的繼承模式,而後本身記不住,回過頭來就罵設計模式把你的代碼搞複雜了,要反設計模式。

設計模式的六大原則

開閉原則:實現熱插拔,提升擴展性。
里氏代換原則:實現抽象的規範,實現子父類互相替換;
依賴倒轉原則:針對接口編程,實現開閉原則的基礎;
接口隔離原則:下降耦合度,接口單獨設計,互相隔離;
迪米特法則,又稱不知道原則:功能模塊儘可能獨立;
合成複用原則:儘可能使用聚合,組合,而不是繼承;
一、開閉原則(Open Close Principle)

開閉原則的意思是:對擴展開放,對修改關閉。在程序須要進行拓展的時候,不能去修改原有的代碼,實現一個熱插拔的效果。簡言之,是爲了使程序的擴展性好,易於維護和升級。想要達到這樣的效果,咱們須要使用接口和抽象類,後面的具體設計中咱們會提到這點。

二、里氏代換原則(Liskov Substitution Principle)

里氏代換原則是面向對象設計的基本原則之一。 里氏代換原則中說,任何基類能夠出現的地方,子類必定能夠出現。LSP 是繼承複用的基石,只有當派生類能夠替換掉基類,且軟件單位的功能不受到影響時,基類才能真正被複用,而派生類也可以在基類的基礎上增長新的行爲。里氏代換原則是對開閉原則的補充。實現開閉原則的關鍵步驟就是抽象化,而基類與子類的繼承關係就是抽象化的具體實現,因此里氏代換原則是對實現抽象化的具體步驟的規範。

三、依賴倒轉原則(Dependence Inversion Principle)

這個原則是開閉原則的基礎,具體內容:針對接口編程,依賴於抽象而不依賴於具體。

四、接口隔離原則(Interface Segregation Principle)

這個原則的意思是:使用多個隔離的接口,比使用單個接口要好。它還有另一個意思是:下降類之間的耦合度。因而可知,其實設計模式就是從大型軟件架構出發、便於升級和維護的軟件設計思想,它強調下降依賴,下降耦合。

五、迪米特法則,又稱最少知道原則(Demeter Principle)

最少知道原則是指:一個實體應當儘可能少地與其餘實體之間發生相互做用,使得系統功能模塊相對獨立。

六、合成複用原則(Composite Reuse Principle)

合成複用原則是指:儘可能使用合成/聚合的方式,而不是使用繼承。

9八、數據庫存儲日期格式時,如何考慮時區轉換問題?

答:使用TimeStamp ,  緣由參照:Java編程中遇到的時區轉換問題

9九、HTTP協議,GET和POST 的區別

答:淺談HTTP中GET和POST的區別

100、單例模式有幾種? 如何優化?

解答:單例模式的7中用法

10一、如何看待設計模式,並簡單說說你對觀察者模式的理解

答:一、設計模式有神馬用     二、觀察者模式類圖及實現

10三、序列化的原理和做用

答:Serialization(序列化)是一種將對象以一連串的字節描述的過程;反序列化deserialization是一種將這些字節重建成一個對象的過程,主要用於HTTP或者WebService接口傳輸過程當中對象參數的傳播,具體可參看:Java序列化機制和原理 

網絡協議方面,考察最多的包括服務器和客戶端在三次握手、四次揮手過程當中的狀態變化;還有網絡擁塞控制,及其解決辦法等。

10四、三次握手、四次揮手示意圖:

總共有四種狀態:主動創建鏈接、主動斷開鏈接、被動創建連和被動斷開鏈接

兩兩組合仍是 4 種組合:

  1. 主動創建鏈接、主動斷開鏈接會經歷的狀態:
    SYNC_SENT——ESTABLISHED—-FIN_WAIT_1—-FIN_WAIT_2—-TIME_WAIT
  2. 主動創建鏈接、被動斷開鏈接會經歷的狀態:
    SYNC_SENT——ESTABLISHED—-CLOSE_WAIT—-LAST_ACK
  3. 被動創建鏈接、主動斷開鏈接會經歷的狀態:
    LISTEN—-SYN_RCVD—-ESTABLISHED—-FIN_WAIT_1—-FIN_WAIT_2—-TIME_WAIT
  4. 被動創建鏈接、被動斷開鏈接會經歷的狀態:
    LISTEN—-SYN_RCVD—-ESTABLISHED—-CLOSE_WAIT—-LAST_ACK

10五、滑動窗口機制

由發送方和接收方在三次握手階段,互相將本身的最大可接收的數據量告訴對方。也就是本身的數據接收緩衝池的大小。這樣對方能夠根據已發送的數據量來計算是否能夠接着發送。

在處理過程當中,當接收緩衝池的大小發生變化時,要給對方發送更新窗口大小的通知。

10六、擁塞避免機制

擁塞:對資源的需求超過了可用的資源。若網絡中許多資源同時供應不足,網絡的性能就要明顯變壞,整個網絡的吞吐量隨之負荷的增大而降低。

擁塞控制:防止過多的數據注入到網絡中,使得網絡中的路由器或鏈路不致過載。

擁塞控制方法:

  • 慢開始 + 擁塞避免;
  • 快重傳 + 快恢復。

10七、瀏覽器中輸入:「www.xxx.com」 以後都發生了什麼?請詳細闡述。

解析:經典的網絡協議問題。

答:

  1. 由域名→IP 地址
    尋找 IP 地址的過程依次通過了瀏覽器緩存、系統緩存、hosts 文件、路由器緩存、 遞歸搜索根域名服務器。
  2. 創建 TCP/IP 鏈接(三次握手具體過程)
  3. 由瀏覽器發送一個 HTTP 請求
  4. 通過路由器的轉發,經過服務器的防火牆,該 HTTP 請求到達了服務器
  5. 服務器處理該 HTTP 請求,返回一個 HTML 文件
  6. 瀏覽器解析該 HTML 文件,而且顯示在瀏覽器端
  7. 這裏須要注意:
  • HTTP 協議是一種基於 TCP/IP 的應用層協議,進行 HTTP 數據請求必須先創建 TCP/IP 鏈接
  • 能夠這樣理解:HTTP 是轎車,提供了封裝或者顯示數據的具體形式;Socket 是發動機,提供了網絡通訊的能力。
  • 兩個計算機之間的交流無非是兩個端口之間的數據通訊 , 具體的數據會以什麼樣的形式展示是以不一樣的應用層協議來定義的。

10八、常見 HTTP 狀態碼

  1. 1xx(臨時響應)
  2. 2xx(成功)
  3. 3xx(重定向):表示要完成請求須要進一步操做
  4. 4xx(錯誤):表示請求可能出錯,妨礙了服務器的處理
  5. 5xx(服務器錯誤):表示服務器在嘗試處理請求時發生內部錯誤
  6. 常見狀態碼:
  • 200(成功)
  • 304(未修改):自從上次請求後,請求的網頁未修改過。服務器返回此響應時,不會返回網頁內容
  • 401(未受權):請求要求身份驗證
  • 403(禁止):服務器拒絕請求
  • 404(未找到):服務器找不到請求的網頁

10九、TCP 和 UDP 的區別:

答:

  1. 回答發送數據前是否存在創建鏈接的過程;
  2. TCP過確認機制,丟包能夠重發,保證數據的正確性;UDP不保證正確性,只是單純的負責發送數據包;
  3. UDP 是面向報文的。發送方的 UDP 對應用程序交下來的報文,在添加首部後就向下交付給 IP 層。既不拆分,也不合並,而是保留這些報文的邊界,因 此,應用程序須要選擇合適的報文大小;
  4. UDP 的頭部,只有 8 個字節,相對於 TCP 頭部的 20 個字節信息包的額外開銷很小。

限於篇幅,更多網絡協議相關知識,請參閱個人博客:TCP/IP 協議面試常問知識點,傾心總結

小結:必須熟練掌握 TCP 和 UDP 的區別、三次握手和四次揮手的狀態切換,必考。

  

 

 

 

 

  


 

 

核心篇

數據存儲

一、MySQL 索引使用的注意事項

三、說說分庫與分表設計

四、分庫與分錶帶來的分佈式困境與應對之策

五、說說 SQL 優化之道

六、MySQL 遇到的死鎖問題

七、存儲引擎的 InnoDB 與 MyISAM

八、數據庫索引的原理

九、爲何要用 B-tree

十一、limit 20000 加載很慢怎麼解決:採用id排序,經過id來限制範圍

十二、選擇合適的分佈式主鍵方案

1三、選擇合適的數據存儲方案

1四、ObjectId 規則

1六、倒排索引

1七、聊聊 ElasticSearch 使用場景

1八、

索引:B+,B-,全文索引
Mysql的索引是一個數據結構,旨在使數據庫高效的查找數據。
經常使用的數據結構是B+Tree,每一個葉子節點不但存放了索引鍵的相關信息還增長了指向相鄰葉子節點的指針,這樣就造成了帶有順序訪問指針的B+Tree,作這個優化的目的是提升不一樣區間訪問的性能。
何時使用索引:

  1. 常常出如今group by,order by和distinc關鍵字後面的字段

  2. 常常與其餘表進行鏈接的表,在鏈接字段上應該創建索引

  3. 常常出如今Where子句中的字段

  4. 常常出現用做查詢選擇的字段

友情連接:MySQL:InnoDB存儲引擎的B+樹索引算法
友情連接:MySQL索引背後的數據結構及算法原理

1九、

數據庫事務是指做爲單個邏輯工做單元執行的一系列操做。

友情連接:數據庫事務的四大特性以及事務的隔離級別

20、

MySQL數據庫優化總結
MYSQL 優化經常使用方法
MySQL存儲引擎--MyISAM與InnoDB區別
關於SQL數據庫中的範式

2一、mysql優化經驗:

2三、mysql的索引分類:B+,hash;什麼狀況用什麼索引;

2四、mysql的存儲引擎有哪些,區別是什麼;

2五、說說事務的特性和隔離級別;

2六、mysql面試題: 
http://blog.csdn.net/zhaojw_420/article/details/70530664 
2七、sql優化: 
http://blog.csdn.net/zhaojw_420/article/details/70532017 

2八、mysql分頁有什麼優化

2九、悲觀鎖、樂觀鎖:版本號檢測爲樂觀鎖,其餘爲悲觀鎖

30、組合索引,最左原則

3一、mysql 的表鎖、行鎖

3三、mysql的索引分類:B+,hash;什麼狀況用什麼索引

3四、事務的特性和隔離級別

36. 若是查詢很慢,你會想到的第⼀個⽅式是什麼?索引是⼲嘛的?

37. 若是建了⼀個單列索引,查詢的時候查出2列,會⽤到這個單列索引嗎?:會

38. 若是建了⼀個包含多個列的索引,查詢的時候只⽤了第⼀列,能不能⽤上 這個索引?查三列呢?:最左原則

40. 怎麼看是否⽤到了某個索引?:explain執行計劃看type

45. 大家的數據庫單表數據量是多少?⼀般多⼤的時候開始出現查詢性能急 劇降低?:1000萬|mysql寫入速度是100k/s

47. 讀寫分離是怎麼作的?你認爲中間件會怎麼來操做?這樣操做跟事務有什麼關係?:mysql主從複製,讀所有打到從,寫所有打到主|中間件會解析sql分析讀寫操做|主從同步延遲引發的事務一致性問題?

14. 分庫分表有沒有作過?線上的遷移過程是怎麼樣的?如何肯定數據是正 確的?:在老庫上掛上精衛,訂閱精衛任務將數據寫入分庫分表

52. MySQL爲何使用B+樹做爲索引?

5三、msyql優化經驗

一、對查詢進行優化,應儘可能避免全表掃描,首先應考慮在 where 及 order by 涉及的列上創建索引。 

二、應儘可能避免在 where 子句中使用!=或<>操做符,不然引擎將放棄使用索引而進行全表掃描。 

三、儘可能使用數字型字段,若只含數值信息的字段儘可能不要設計爲字符型,這會下降查詢和鏈接的性能,並會增長存儲開銷。這是由於引擎在處理查詢和鏈接時會逐個比較字符串中每個字符,而對於數字型而言只須要比較一次就夠了。

四、任何地方都不要使用 select * from t ,用具體的字段列表代替「*」,不要返回用不到的任何字段。

五、避免頻繁建立和刪除臨時表,以減小系統表資源的消耗。諸如此類,等等等等......

5四、.各個數據庫引擎區別:http://www.jb51.net/article/38004.htm
5五、.索引的使用注意事項:http://www.javashuo.com/article/p-cubihmaj-cn.html 

5七、常見的數據庫優化手段

5八、索引的優缺點,什麼字段上創建索引:order by, where ,group by,distinct,join等字段
5九、數據庫鏈接池。:原理?

6一、產生死鎖的必要條件#
參考http://blog.sina.com.cn/s/blog_5e3604840100ddgq.html

6二、死鎖預防#
參考http://blog.sina.com.cn/s/blog_5e3604840100ddgq.html

6四、.數據庫事務隔離級別#

參考http://blog.csdn.net/fg2006/article/details/6937413

6五、.數據庫鏈接池的原理#
參考http://blog.csdn.net/shuaihj/article/details/14223015

6六、.樂觀鎖和悲觀鎖#
參考http://www.open-open.com/lib/view/open1452046967245.html

6七、.如何實現不一樣數據庫的數據查詢分頁#
參考http://blog.csdn.net/yztezhl/article/details/20489387

6九、.數據庫索引的實現(B+樹介紹、和B樹、R樹區別)#

參考文章:
http://blog.csdn.net/kennyrose/article/details/7532032
http://www.xuebuyuan.com/2216918.html

70、.SQL性能優化#
參考文章:
http://database.51cto.com/art/200904/118526.htm
http://www.cnblogs.com/rootq/archive/2008/11/17/1334727.html

7一、數據庫索引的優缺點以及何時數據庫索引失效#:not in,!=不會命中索引
參考文章:
http://www.cnblogs.com/mxmbk/articles/5226344.html
http://www.cnblogs.com/simplefrog/archive/2012/07/15/2592527.html
http://www.open-open.com/lib/view/open1418476492792.html
http://blog.csdn.net/colin_liu2009/article/details/7301089
http://www.cnblogs.com/hongfei/archive/2012/10/20/2732589.html 

7二、當數據表中A、B字段作了組合索引,那麼單獨使用A或單獨使用B會有索引效果嗎?(使用like查詢如何有索引效果)

答:看A、B兩字段作組合索引的時候,誰在前面,誰在後面,若是A在前,那麼單獨使用A會有索引效果,單獨使用B則沒有,反之亦然。同理,使用like模糊查詢時,若是隻是使用前面%,那麼有索引效果,若是使用雙%號匹配,那麼則無索引效果

 7三、mysql查詢字段區不區分大小寫?

解答:不區分,哪怕值也不區分

7四、簡單說說數據庫集羣和負載均衡、分佈式(我不懂這塊)

解答:數據庫負載均衡和集羣參考 ,參考2

7七、一條sql執行過長的時間,你如何優化,從哪些方面?

答:

一、查看sql是否涉及多表的聯表或者子查詢,若是有,看是否能進行業務拆分,相關字段冗餘或者合併成臨時表(業務和算法的優化)

二、涉及鏈表的查詢,是否能進行分表查詢,單表查詢以後的結果進行字段整合

三、若是以上兩種都不能操做,非要鏈表查詢,那麼考慮對相對應的查詢條件作索引。加快查詢速度

四、針對數量大的表進行歷史表分離(如交易流水錶)

五、數據庫主從分離,讀寫分離,下降讀寫針對同一表同時的壓力,至於主從同步,mysql有自帶的binlog實現 主從同步

六、explain分析sql語句,查看執行計劃,分析索引是否用上,分析掃描行數等等

七、查看mysql執行日誌,看看是否有其餘方面的問題

我的理解:從根本上來講,查詢慢是佔用mysql內存比較多,那麼能夠從這方面去酌手考慮

7八、Mysql的事物隔離級別?

答:Mysql的事物隔離級別 其實跟 Spring的事物隔離級別同樣,都是一、Read Uncommitted(讀取未提交內容), 二、Read Committed(讀取提交內容),三、Repeatable Read(可重讀),四、Serializable(可串行化)    具體參照:mysql事物隔離級別

7九、Mysql索引的原理

答:索引的做用你們都知道,就是加快查詢速度,可是原理,我說不上來,這裏直接看吧:Mysql索引工做原理

80、MySQL 和 MongoDB 的區別有哪些?如何選擇?

8一、MongoDB 的優缺點有哪些?

(ps 本人對這一塊不是很熟悉,就不附上參考答案了,請各位小夥伴自行學習哈~)

8二、據說過事務嗎?(必考)

答:做爲單個邏輯工做單元執行的一系列操做,知足四大特性:

  1. 原子性(Atomicity):事務做爲一個總體被執行 ,要麼所有執行,要麼所有不執行;

  2. 一致性(Consistency):保證數據庫狀態從一個一致狀態轉變爲另外一個一致狀態;

  3. 隔離性(Isolation):多個事務併發執行時,一個事務的執行不該影響其餘事務的執行;

  4. 持久性(Durability):一個事務一旦提交,對數據庫的修改應該永久保存。

8三、事務的併發問題有哪幾種?

答:丟失更新、髒讀、不可重複讀以及幻讀。

8四、數據庫中的鎖有哪幾種?
答:獨佔鎖、排他鎖以及更新鎖。

8五、事務的隔離級別有哪幾種?

答:讀未提交、讀已提交、可重複讀和序列化。

擴展問題:MySQL 事務默認隔離級別是哪一個?

答:可重複讀。

8六、數據庫的索引有什麼做用?(必考) 底層數據結構是什麼,爲何使用這種數據結構?

答:

  1. 索引 是對數據庫表中一列或多列的值進行排序的一種結構,使用索引可快速訪問數據庫表中的特定信息;

  2. 底層數據結構是 B+ 樹;

  3. 使用 B+ 樹的緣由:查找速度快、效率高,在查找的過程當中,每次都能拋棄掉一部分節點,減小遍歷個數。( 此時,你應該在白紙上畫出什麼是 B+ 樹 )

擴展問題:聚簇索引和非聚簇索引的區別?

8七、MyISAM 和 InnoDB 的區別有哪些?

答:

  • MyISAM 不支持事務,InnoDB 是事務類型的存儲引擎;

  • MyISAM 只支持表級鎖,BDB 支持頁級鎖和表級鎖,默認爲頁級鎖;而 InnoDB 支持行級鎖和表級鎖,默認爲行級鎖;

  • MyISAM 引擎不支持外鍵,InnoDB 支持外鍵;

  • MyISAM 引擎的表在大量高併發的讀寫下會常常出現表損壞的狀況;

  • 對於 count( ) 查詢來講 MyISAM 更有優點;

  • InnoDB 是爲處理巨大數據量時的最大性能設計,它的 CPU 效率多是任何其它基於磁盤的關係數據庫引擎所不能匹敵的;

  • MyISAM 支持全文索引(FULLTEXT),InnoDB 不支持;

  • MyISAM 引擎的表的查詢、更新、插入的效率要比 InnoDB 高。

最主要的區別是:MyISAM 表不支持事務、不支持行級鎖、不支持外鍵。 InnoDB 表支持事務、支持行級鎖、支持外鍵。(可直接回答這個)

 

 


 

緩存使用

一、Redis 有哪些類型

二、Redis 內部結構

三、聊聊 Redis 使用場景:緩存,隊列

四、Redis 持久化機制

五、Redis 如何實現持久化

六、Redis 集羣方案與實現

七、Redis 爲何是單線程的:緩存主要是io密集型,對cpu需求不大,因此單線程已經知足要求

八、緩存奔潰

九、緩存降級

十、使用緩存的合理性問題

十一、Redis數據結構:String,Hash,List,Set,Sorted Set

十二、redis和memcache的區別:數據結構不同|redis單線程|mc讀性能更高

1三、用redis作過什麼:cache,隊列

1四、redis是如何持久化的:rdb和aof

1五、redis集羣如何同步:數據複製,slave發起請求,master push數據

1六、redis的數據添加過程是怎樣的:哈希槽

1七、redis的淘汰策略有哪些:volatile-lru,volatile-ttl,volatile-random,allkeys-lru,allkeys-random,no-enviction

20、Redis用過哪些數據數據,以及Redis底層怎麼實現

2一、Redis緩存穿透,緩存雪崩

2二、如何使用Redis來實現分佈式鎖:setnx

2三、Redis的併發競爭問題,以及如何解決:樂觀鎖,watch

2四、Redis持久化的幾種方式,優缺點是什麼,怎麼實現的:aof(每一個操做一個腳本),rdb(定時全兩快照)

2五、Redis的緩存失效策略

2六、Redis集羣,高可用,原理

2七、Redis緩存分片

31.漸進式rehash過程?:同時持有兩個hash,逐漸遷移

32.rehash源碼?

34.redis aof源碼?

35.事務與事件:事件IO多路複用,reactor模型

36.主從複製:

37.啓動過程

38.集羣

4二、redis的兩個持久化策略:http://blog.csdn.net/u010785685/article/details/52366977

4三、.redis如何事務支持:http://www.javashuo.com/article/p-cjvuqfnz-eh.html
4四、.redis哨兵機制:http://blog.csdn.net/zbw18297786698/article/details/52891695
4五、.redis集羣方案:https://www.zhihu.com/question/21419897
4六、.redis主從同步策略:http://blog.csdn.net/sk199048/article/details/50725369

4六、redis是單線程的麼,全部的工做都是單線程麼。

4七、redis如何存儲一個String的:char數組
4九、redis的哨兵模式,一個key值如何在redis集羣中找到存儲在哪裏。
 

 

消息隊列

一、消息隊列的使用場景:異步,削峯|發郵件,發短信

二、消息的重發補償解決思路

三、消息的冪等性解決思路

四、消息的堆積解決思路

五、本身如何實現消息隊列

六、如何保證消息的有序性:根據業務id肯定路由到哪一個broker,保證同一個業務id路由到同一個broker

七、mq的原理是什麼:有點大。。均可以說;

八、mq如何保證明時性;

九、mq的持久化是怎麼作的;

 

框架篇

Spring

一、BeanFactory 和 ApplicationContext 有什麼區別:Application支持父子容器,支持web。。。

二、Spring Bean 的生命週期:

三、Spring IOC 如何實現

四、說說 Spring AOP

五、Spring AOP 實現原理

六、動態代理(cglib 與 JDK)

七、Spring 事務實現方式

八、Spring 事務底層原理

九、如何自定義註解實現功能

十、Spring MVC 運行流程

十一、Spring MVC 啓動流程

十二、Spring 的單例實現原理

1三、Spring 框架中用到了哪些設計模式

1四、Spring 其餘產品(Srping Boot、Spring Cloud、Spring Secuirity、Spring Data、Spring AMQP 等)

1五、

Spring IOC (控制反轉,依賴注入)
Spring支持三種依賴注入方式,分別是屬性(Setter方法)注入,構造注入和接口注入。
在Spring中,那些組成應用的主體及由Spring IOC容器所管理的對象被稱之爲Bean。
Spring的IOC容器經過反射的機制實例化Bean並創建Bean之間的依賴關係。
簡單地講,Bean就是由Spring IOC容器初始化、裝配及被管理的對象。
獲取Bean對象的過程,首先經過Resource加載配置文件並啓動IOC容器,而後經過getBean方法獲取bean對象,就能夠調用他的方法。
Spring Bean的做用域:
Singleton:Spring IOC容器中只有一個共享的Bean實例,通常都是Singleton做用域。
Prototype:每個請求,會產生一個新的Bean實例。
Request:每一次http請求會產生一個新的Bean實例。
友情連接: Spring框架IOC容器和AOP解析
友情連接:淺談Spring框架註解的用法分析
友情連接:關於Spring的69個面試問答——終極列表

1六、

代理的共有優勢:業務類只須要關注業務邏輯自己,保證了業務類的重用性。
Java靜態代理:
代理對象和目標對象實現了相同的接口,目標對象做爲代理對象的一個屬性,具體接口實現中,代理對象能夠在調用目標對象相應方法先後加上其餘業務處理邏輯。
缺點:一個代理類只能代理一個業務類。若是業務類增長方法時,相應的代理類也要增長方法。
Java動態代理:
Java動態代理是寫一個類實現InvocationHandler接口,重寫Invoke方法,在Invoke方法能夠進行加強處理的邏輯的編寫,這個公共代理類在運行的時候才能明確本身要代理的對象,同時能夠實現該被代理類的方法的實現,而後在實現類方法的時候能夠進行加強處理。
實際上:代理對象的方法 = 加強處理 + 被代理對象的方法

JDK和CGLIB生成動態代理類的區別:
JDK動態代理只能針對實現了接口的類生成代理(實例化一個類)。此時代理對象和目標對象實現了相同的接口,目標對象做爲代理對象的一個屬性,具體接口實現中,能夠在調用目標對象相應方法先後加上其餘業務處理邏輯
CGLIB是針對類實現代理,主要是對指定的類生成一個子類(沒有實例化一個類),覆蓋其中的方法 。
Spring AOP應用場景
性能檢測,訪問控制,日誌管理,事務等。
默認的策略是若是目標類實現接口,則使用JDK動態代理技術,若是目標對象沒有實現接口,則默認會採用CGLIB代理

1七、

SpringMVC運行原理

  1. 客戶端請求提交到DispatcherServlet

  2. 由DispatcherServlet控制器查詢HandlerMapping,找到並分發到指定的Controller中。

  3. Controller調用業務邏輯處理後,返回ModelAndView

  4. DispatcherServlet查詢一個或多個ViewResoler視圖解析器,找到ModelAndView指定的視圖

  5. 視圖負責將結果顯示到客戶端

友情連接:Spring:基於註解的Spring MVC(上)
友情連接: Spring:基於註解的Spring MVC(下) 
友情連接:SpringMVC與Struts2區別與比較總結
友情連接:SpringMVC與Struts2的對比

1八、

Spring事務配置方法:
1.切點信息,用於定位實施事物切面的業務類方法
2.控制事務行爲的事務屬性,這些屬性包括事物隔離級別,事務傳播行爲,超時時間,回滾規則。

Spring經過aop/tx Schema 命名空間和@Transaction註解技術來進行聲明式事物配置。

2一、BeanFactory 和 FactoryBean?

2二、Spring IOC 的理解,其初始化過程?

2三、BeanFactory 和 ApplicationContext?

2四、Spring Bean 的生命週期,如何被管理的?

2五、Spring Bean 的加載過程是怎樣的?

2六、若是要你實現Spring AOP,請問怎麼實現?

2七、若是要你實現Spring IOC,你會注意哪些問題?:對象依賴管理,繼承,反射

2八、Spring 是如何管理事務的,事務管理機制?

2九、Spring 的不一樣事務傳播行爲有哪些,幹什麼用的?

30、Spring 中用到了那些設計模式?:抽象工廠,動態代理,觀察者模式(Event)。。。

3二、Spring 循環注入的原理?

3三、Spring AOP的理解,各個術語,他們是怎麼相互工做的?

3四、Spring 如何保證 Controller 併發的安全?

35. 你有沒有⽤過Spring的AOP? 是⽤來⼲嘛的? ⼤概會怎麼使⽤?

36. 若是⼀個接⼝有2個不一樣的實現, 那麼怎麼來Autowire⼀個指定的實現?:Qualifier

37. Spring的聲明式事務 @Transaction註解⼀般寫在什麼位置? 拋出了異常會⾃動回滾嗎?有沒有辦法控制不觸發回滾?

38. 若是想在某個Bean⽣成並裝配完畢後執⾏⾃⼰的邏輯,能夠什麼⽅式實現?:Intialization接口afterProperties方法

39. SpringBoot沒有放到web容器⾥爲何能跑HTTP服務?:自帶嵌入式tomcat

40. SpringBoot中若是你想使⽤⾃定義的配置⽂件⽽不只僅是 application.properties,應該怎麼弄?

41. SpringMVC中RequestMapping能夠指定GET, POST⽅法麼?怎麼指定?

42. SpringMVC若是但願把輸出的Object(例如XXResult或者XXResponse)這 種包裝爲JSON輸出, 應該怎麼處理?

43. 怎樣攔截SpringMVC的異常,而後作⾃定義的處理,⽐如打⽇志或者包裝成JSON

45. .struts2和springMVC的區別

46. spring框架中須要引用哪些jar包,以及這些jar包的用途

50. spring注入的幾種方式

51. spring如何實現事物管理的

52. springIOC和AOP的原理

55. springmvc的核心是什麼,請求的流程是怎麼處理的,控制反轉怎麼實現的

核心:

控制反轉和麪向切面

請求處理流程:

一、首先用戶發送請求到前端控制器,前端控制器根據請求信息(如URL)來決定選擇哪個頁面控制器進行處理並把請求委託給它,即之前的控制器的控制邏輯部分;

二、頁面控制器接收到請求後,進行功能處理,首先須要收集和綁定請求參數到一個對象,並進行驗證,而後將命令對象委託給業務對象進行處理;處理完畢後返回一個ModelAndView(模型數據和邏輯視圖名);

三、前端控制器收回控制權,而後根據返回的邏輯視圖名,選擇相應的視圖進行渲染,並把模型數據傳入以便視圖渲染;

四、前端控制器再次收回控制權,將響應返回給用戶。

控制反轉如何實現:

咱們每次使用spring框架都要配置xml文件,這個xml配置了bean的id和class。

spring中默認的bean爲單實例模式,經過bean的class引用反射機制能夠建立這個實例。

所以,spring框架經過反射替咱們建立好了實例而且替咱們維護他們。

A須要引用B類,spring框架就會經過xml把B實例的引用傳給了A的成員變量。

5六、.spring的特色及好處:https://www.cnblogs.com/song1314/articles/4568379.html
5七、.spring的69面試題:http://www.javashuo.com/article/p-bucgmvli-es.html
5八、.spring簡化java開發複雜性的策略:http://blog.csdn.net/running_nz/article/details/54583100
5九、.spring循環依賴及解決辦法:http://blog.csdn.net/caomiao2006/article/details/46511123
60、.springmvc工做流程和原理:http://blog.csdn.net/liangzi_lucky/article/details/52459378
6一、.spring註解原理:http://blog.csdn.net/u010987379/article/details/52152795

 6二、

Spring AOP 實現原理?

參考 :http://blog.csdn.net/moreevan/article/details/11977115/

6三、@transactional註解在什麼狀況下會失效,爲何?:調用同一個類的方法的時候,spring容器經過aop提供爲bean提供事務管理功能,方法內部調用是調用的對象自己的方法,不是調用的spring容器的bean

6四、SpringMVC的Controller是如何將參數和前端傳來的數據一一對應的。
6五、Quartz是如何完成定時任務的。
6七、Spring使用了哪些設計模式。
6八、Spring的IOC有什麼優點。
6九、Spring如何維護它擁有的bean。

70、.Struts中請求處理過程#

參考文章http://www.cnblogs.com/liuling/p/2013-8-10-01.html

7一、.MVC概念#
參考文章http://www.cnblogs.com/scwyh/articles/1436802.html

7二、.Springmvc與Struts區別#
參考文章:
http://blog.csdn.net/tch918/article/details/38305395
http://blog.csdn.net/chenleixing/article/details/44570681

7六、.Springbean的加載過程(推薦看Spring的源碼)#
參考文章http://geeekr.com/read-spring-source-1-how-to-load-bean/

7七、.Springbean的實例化(推薦看Spring的源碼)#
參考文章http://geeekr.com/read-spring-source-two-beans-initialization/

7八、.Spring如何實現AOP和IOC(推薦看Spring的源碼)#
參考文章http://www.360doc.com/content/15/0116/21/12385684_441408260.shtml

7九、.Springbean注入方式#
參考文章http://blessht.iteye.com/blog/1162131

80、.Spring的事務管理#
這個主題的參考文章沒找到特別好的,http://blog.csdn.net/trigl/article/details/50968079這個還能夠。

8一、.Spring事務的傳播特性#
參考文章http://blog.csdn.net/lfsf802/article/details/9417095

80、.springmvc原理
參考文章http://blog.sina.com.cn/s/blog_7ef0a3fb0101po57.html

 8二、Spring 事務的隔離性,並說說每一個隔離性的區別

解答:Spring事務詳解

8三、Spring事務的傳播行爲,並說說每一個傳播行爲的區別

解答:Spring事務詳解

8五、Struts跟Spring mvc的優缺點,讓你選會如何選

解答:Spring MVC 與 Struts的區別

8六、簡單說說Spring 事務機制

解答:Spring事務機制

8七、Spring 4.0新特性

解答:Spring4新特性

8八、SpringMVC的原理以及返回數據如何渲染到jsp/html上?

答:Spring MVC的核心就是 DispatcherServlet , 一個請求通過 DispatcherServlet ,轉發給HandlerMapping ,而後經反射,對應 Controller及其裏面方法的@RequestMapping地址,最後經ModelAndView和ViewResoler返回給對應視圖  。  具體可參考:Spring MVC的工做原理

8九、Spring的原理

答:Spring的核心是IOC和AOP  ,IOC是依賴注入和控制反轉, 其注入方式可分爲set注入、構造器注入、接口注入等等。IOC就是一個容器,負責實例化、定位、配置應用程序中的對象及創建這些對象間的依賴。簡單理解就是:JAVA每一個業務邏輯處理至少須要兩個或者以上的對象協做進行工做,可是每一個對象在使用它的合做對象的時候,都須要頻繁的new 對象來實現,你就會發現,對象間的耦合度高了。而IOC的思想是:Spring容器來管理這些,對象只須要處理自己業務關係就行了。至於什麼是控制反轉,就是得到依賴對象的方式反轉了。
AOP呢,面向切面編程,最直接的體現就是Spring事物管理。至於Spring事物的相關資料,就不細說了,參考:Spring註解式事物管理

 

JavaWeb 開發經典的 3 層框架:Web 層、Service 層(業務邏輯層)和 Dao 層(數據訪問層)

  • Web 層:包含 JSP 和 Servlet 等與 Web 相關的內容;
  • 業務層:只關心業務邏輯;
  • 數據層:封裝了對數據庫的訪問細節。

Spring 知識點

90、Spring 的 IOC 和 AOP 有了解嗎?

答:

  • IOC:控制反轉,(解耦合)將對象間的依賴關係交給 Spring 容器,使用配置文件來建立所依賴的對象,由主動建立對象改成了被動方式;
  • AOP:面向切面編程,將功能代碼從業務邏輯代碼中分離出來。

9一、AOP 的實現方式有哪幾種?如何選擇?(必考)

答:JDK 動態代理實現和 cglib 實現。

選擇:

  1. 若是目標對象實現了接口,默認狀況下會採用 JDK 的動態代理實現 AOP,也能夠強制使用 cglib 實現 AOP;
  2. 若是目標對象沒有實現接口,必須採用 cglib 庫,Spring 會自動在 JDK 動態代理和 cglib 之間轉換。

擴展:JDK 動態代理如何實現?(加分點)

答:JDK 動態代理,只能對實現了接口的類生成代理,而不是針對類,該目標類型實現的接口都將被代理。原理是經過在運行期間建立一個接口的實現類來完成對目標對象的代理。

  1. 定義一個實現接口 InvocationHandler 的類;
  2. 經過構造函數,注入被代理類;
  3. 實現 invoke( Object proxy, Method method, Object[] args)方法;
  4. 在主函數中得到被代理類的類加載器;
  5. 使用 Proxy.newProxyInstance( ) 產生一個代理對象;
  6. 經過代理對象調用各類方法。

解析:關於 IOC 和 AOP 的詳細闡述,請各位參閱個人博客:Spring 核心 AOP(面向切面編程)總結,Spring 框架學習—控制反轉(IOC)

9二、Spring MVC 的核心控制器是什麼?消息處理流程有哪些?

答:核心控制器爲 DispatcherServlet。消息流程以下:

9三、其餘問題包括:重定向和轉發的區別、動態代理和靜態代理的區別等。

 

 

Netty

一、爲何選擇 Netty

二、說說業務中,Netty 的使用場景:通訊組件,rpc通訊組件,mq通訊組件

三、原生的 NIO 在 JDK 1.7 版本存在 epoll bug

四、什麼是TCP 粘包/拆包:鏈路層對數據進行拆分數據包和合並數據包

五、TCP粘包/拆包的解決辦法:業務曾手動拆分數據包

六、Netty 線程模型

七、說說 Netty 的零拷貝:內核態,不用在用戶態之間切換

八、Netty 內部執行流程

九、Netty 重連實現

十一、Netty 的各大組件

十二、Netty的線程模型

1三、TCP 粘包/拆包的緣由及解決方法

1四、瞭解哪幾種序列化協議?包括使用場景和如何去選擇

1六、Netty的高性能表如今哪些方面:nio

17.BIO、NIO和AIO的區別?

18.NIO的組成?

26.NIOEventLoopGroup源碼?

 

 

MyBatis

一、

Mybatis
每個Mybatis的應用程序都以一個SqlSessionFactory對象的實例爲核心。首先用字節流經過Resource將配置文件讀入,而後經過SqlSessionFactoryBuilder().build方法建立SqlSessionFactory,而後再經過SqlSessionFactory.openSession()方法建立一個SqlSession爲每個數據庫事務服務。
經歷了Mybatis初始化 –>建立SqlSession –>運行SQL語句,返回結果三個過程

三、mybatis如何處理結果集

MyBatis的結果集是經過反射來實現的。並非經過get/set方法。在實體類中不管是否認義get/set()方法,都是能夠接收到的。 

若是面試只是考你這個點的話就恭喜了。若是繼續深問流程,那就須要本身找一些源碼來閱讀了。

五、.mybatis分頁及分頁插件原理:http://blog.csdn.net/jaryle/article/details/52315565
六、.mybatis插件原理:http://blog.csdn.net/hupanfeng/article/details/9247379
七、.mybatis動態sql原理:http://www.importnew.com/24160.html
八、.mybatis延遲加載:http://blog.csdn.net/eson_15/article/details/51668523

九、Mybatis如何找到指定的Mapper的,如何完成查詢的。

 

Dubbo

1.什麼是rcp框架:http://www.javashuo.com/article/p-hpqomuon-ge.html
2.序列化方式方式及做用:http://blog.csdn.net/u012554102/article/details/51902697
3.dubbo底層協議實現:http://www.javashuo.com/article/p-kfsehtfq-gt.html
4.dubbo註冊中心如何設置:http://blog.csdn.net/u011659172/article/details/51491518
5.dubbo負載均衡的理解:http://www.javashuo.com/article/p-knztwfmj-gp.html
6.dubbo容錯機制:https://www.2cto.com/kf/201612/572681.html
7.服務調用超時的實現原理:http://www.javashuo.com/article/p-vasdlwnk-mv.html
8.服務註冊與發現的流程:http://doc.okbase.net/661116/archive/241946.html

 

微服務篇

微服務

一、先後端分離是如何作的

二、微服務哪些框架

三、你怎麼理解 RPC 框架

四、說說 RPC 的實現原理

五、說說 Dubbo 的實現原理

六、你怎麼理解 RESTful

七、說說如何設計一個良好的 API

八、如何理解 RESTful API 的冪等性

九、如何保證接口的冪等性

十、說說 CAP 定理、 BASE 理論

十一、怎麼考慮數據一致性問題

十二、說說最終一致性的實現方案

1三、你怎麼看待微服務

1四、微服務與 SOA 的區別

1五、如何拆分服務

1六、微服務如何進行數據庫管理

1七、如何應對微服務的鏈式調用異常:調用鏈路跟蹤,全鏈路日誌

1八、對於快速追蹤與定位問題

1九、微服務的安全

 

 
 

 

 

分佈式

一、談談業務中使用分佈式的場景

二、Session 分佈式方案

三、分佈式鎖的場景

四、分佈是鎖的實現方案

五、分佈式事務

六、集羣與負載均衡的算法與實現

七、說說分庫與分表設計

八、分庫與分錶帶來的分佈式困境與應對之策

 

 
 
九、

一致性哈希:
Memcahed緩存:
十、

分佈式Session框架

  1. 配置服務器,Zookeeper集羣管理服務器能夠統一管理全部服務器的配置文件
  2. 共享這些Session存儲在一個分佈式緩存中,能夠隨時寫入和讀取,並且性能要很好,如Memcache,Tair。
  3. 封裝一個類繼承自HttpSession,將Session存入到這個類中而後再存入分佈式緩存中
  4. 因爲Cookie不能跨域訪問,要實現Session同步,要同步SessionID寫到不一樣域名下。

十一、zookeeper是什麼;

十二、zookeeper哪裏用到;

1三、zookeeper的選主過程;:zab協議

1四、zookeeper集羣之間如何通信;

1五、大家的zookeeper的節點加密是用的什麼方式;

1六、分佈式鎖的實現過程;

1七、Dubbo的底層實現原理和機制

1八、描述一個服務從發佈到被消費的詳細過程

1九、分佈式系統怎麼作服務治理

20、接口的冪等性的概念

2一、消息中間件如何解決消息丟失問題

2二、Dubbo的服務請求失敗怎麼處理

2三、重連機制會不會形成錯誤

2四、對分佈式事務的理解

2五、如何實現負載均衡,有哪些算法能夠實現?

2六、Zookeeper的用途,選舉的原理是什麼?

2七、數據的垂直拆分水平拆分。

2八、zookeeper原理和適用場景

2九、zookeeper watch機制

30、redis/zk節點宕機如何處理

3一、分佈式集羣下如何作到惟一序列號

3三、用過哪些MQ,怎麼用的,和其餘mq比較有什麼優缺點,MQ的鏈接是線程安全的嗎

3四、MQ系統的數據如何保證不丟失

3五、列舉出你能想到的數據庫分庫分表策略;分庫分表後,如何解決全表查詢的問題

3六、zookeeper的選舉策略

3七、全局ID

3八、分佈式事務的控制。
3九、分佈式鎖如何設計。
40、分佈式session如何設計。
4一、dubbo的組件有哪些,各有什麼做用。
4二、zookeeper的負載均衡算法有哪些。
4三、dubbo是如何利用接口就能夠通訊的。

4四、集羣環境中,session如何實現共享

答:

一、Java集羣之session共享    

二、session多服務器共享方案,還有一種方案就是使用一個固定的服務器專門保持session,其餘服務器共享

4五、分佈式、集羣環境中,緩存如何刷新,如何保持同步?

答:

A、緩存如何刷新? 一、定時刷新  二、主動刷新覆蓋   ,每一個緩存框架都有自帶的刷新機制,或者說緩存失效機制,就拿Redis和 Ehcache舉例, 他們都有自帶的過時機制,另外主動刷新覆蓋時,只需獲取對應的key進行數據的覆蓋便可

B、緩存如何保持同步?  這個redis有自帶的集羣同步機制,即複製功能,具體參考:基於Redis分佈式緩存實現      ,Ehcache也有分佈式緩存同步的配置,只須要配置不一樣服務器地址便可,參照:Ehcache分佈式緩存同步

4六、消息隊列的原理和實現

解答:一、消息隊列原理     二、深刻淺出 消息隊列 ActiveMQ

4七、Redis實現消息隊列

答:Redis實現消息隊列     、參考2

4八、談談你對分佈式的理解

答:我的理解:分佈式就是把一個系統/業務 拆分紅多個子系統/子業務 去協同處理,這個過程就叫分佈式,具體的演變方式參考:Java分佈式應用技術架構介紹

 
 

 

 

安全&性能

安全問題

一、安全要素與 STRIDE 威脅

二、防範常見的 Web 攻擊

三、服務端通訊安全攻防

四、HTTPS 原理剖析

六、受權與認證

七、基於角色的訪問控制

八、基於數據的訪問控制

性能優化

一、性能指標有哪些

二、如何發現性能瓶頸

三、性能調優的常見手段

四、說說你在項目中如何進行性能調優

 

 
 

五、web如何項目優化

解答:這個我整理過一次,web項目性能優化(整理)

六、平常項目中,若是你接手,你準備從哪些方面調優?

答:這個呢首先是瞭解哪些須要優化,須要優化確定是項目性能遭遇瓶頸或者猜想即將遭遇了,咱們纔會去考慮優化。那麼怎麼優化?

a、擴容 ,擴容的理解,就是擴充服務器並行處理的能力,簡單來講就是加服務器,增長處理請求的能力,例如增長nginx 、tomcat等應用服務器的個數,或者物理服務器的個數,還有加大服務器帶寬等等,這裏考慮的是硬件方面

b、調優 ,調優,包括系統調優和代碼調優 。 系統調優就是說加快處理速度,好比咱們所提到的CDN、ehcache、redis等緩存技術,消息隊列等等,加快服務間的響應速度,增長系統吞吐量,避免併發,至於代碼調優,這些就須要多積累了,好比重構、工廠等, 數據庫調優的話這個我不是很懂,只知道索引和存儲過程,具體參考:Mysql數據庫調優21個最佳實踐  ,其餘數據庫調優方面就各位本身找找吧

 

 

 

工程篇

需求分析

一、你如何對需求原型進行理解和拆分

二、說說你對功能性需求的理解

三、說說你對非功能性需求的理解

四、你針對產品提出哪些交互和改進意見

五、你如何理解用戶痛點

設計能力

一、說說你在項目中使用過的 UML 圖

二、你如何考慮組件化

三、你如何考慮服務化

四、你如何進行領域建模

五、你如何劃分領域邊界

六、說說你項目中的領域建模

七、說說概要設計

設計模式

一、你項目中有使用哪些設計模式

二、說說經常使用開源框架中設計模式使用分析

三、說說你對設計原則的理解

四、23種設計模式的設計理念

五、設計模式之間的異同,例如策略模式與狀態模式的區別

六、設計模式之間的結合,例如策略模式+簡單工廠模式的實踐

七、設計模式的性能,例如單例模式哪一種性能更好。

業務工程

一、你係統中的先後端分離是如何作的

二、說說你的開發流程

三、你和團隊是如何溝通的

四、你如何進行代碼評審

五、說說你對技術與業務的理解

六、說說你在項目中常常遇到的 Exception

七、說說你在項目中遇到感受最難Bug,怎麼解決的

八、說說你在項目中遇到印象最深困難,怎麼解決的

九、你以爲大家項目還有哪些不足的地方

十、你是否遇到過 CPU 100% ,如何排查與解決

十一、你是否遇到過 內存 OOM ,如何排查與解決

十二、說說你對敏捷開發的實踐

1三、說說你對開發運維的實踐

1四、介紹下工做中的一個對本身最有價值的項目,以及在這個過程當中的角色

 

 

 

1五、重構過代碼沒有?說說經驗;

1六、一千萬的用戶實時排名如何實現;:流式計算

1七、五萬人併發搶票怎麼實現;:頁面靜態話+cdn,限流,緩存預熱,讀寫分離,分庫分表。。。

1八、大型網站應用之海量數據解決方案 
http://blog.csdn.net/zhaojw_420/article/details/70881230

1九、大型網站應用之高併發狀況下的解決方案 
http://blog.csdn.net/zhaojw_420/article/details/70881266

20、在一個千萬級的數據庫查尋中,如何提升查詢效率? :分庫分表,讀寫分離,創建索引
http://blog.csdn.net/zhaojw_420/article/details/69367682

2一、 用 wait-notify 寫一段代碼來解決生產者-消費者問題,更進一步,在分佈式的環境下怎麼解決

A:哈哈哈,咱們來寫段代碼吧……

wait()notify()都是線程間通訊的方法,能夠直接對線程的行爲進行操做。他們的本質實際上是傳遞生產者-消費者各自的消息,理解了這一點,那麼在分佈式環境下就很簡單了,只要找到一個第三方的能夠用來傳遞消息的媒介(Zookeeper、Redis、Kafka等)就能夠了。

22.、設計一個線程池

A:能夠參考Java線程池的理論與實踐

若是對JDK的線程池java.util.concurrent.ThreadPoolExecutor比較瞭解,能夠把一些簡單的特性放上去。若是不瞭解,能夠直接設計一個線程數組,而後加一些業務邏輯。所謂線程池,基本也就如此。

2三、 設計一個IOC容器

A:用反射,註解,還有IOC的理論

2五、

手機掃二維碼登陸是怎麼實現的?

參考:http://www.jianshu.com/p/7f072ac61763

2六、

如何保證RESTful API安全性 ?

參考: http://blog.csdn.net/ywk253100/article/details/25654101

2七、項目併發如何處理?(咱們是web項目)

解答:高併發量網站解決方案,另外,還有數據庫樂觀鎖,數據庫讀寫分離、使用消息隊列、多用存儲過程等等

 

2九、平臺上的圖片如何防盜鏈

解答:http下載防盜鏈原理:http協議的字段referer記錄來實現

30、如何區分上傳的圖片是否是木馬?

解答:一、看上傳的圖片後綴  二、如何後綴是篡改的,那麼每一個文件有個魔術數字  文件上傳-魔術數字

面試還會問到一些關於設計方案相關的問題,好比

3一、你的接口服務數據被人截包了,你如何防止數據惡意提交?

答:咱們能夠在接口傳輸參數裏面設置一個業務編號,這個編號用來區分是否重複提交。這樣即便數據被抓包了,對方也沒法區分每一個字段你的含義,這時,這個業務編號的做用就來了

3二、假設服務器常常宕機,你從哪些方面去排查問題?

答:先重啓,並開啓jvm輸出gc日誌||看是否是系統問題,若是不是則看是否是jvm問題,在看是否是oom,sof等

 

 

軟實力

一、說說你的亮點

二、說說你最近在看什麼書

三、說說你以爲最有意義的技術書籍

四、工做之餘作什麼事情

五、說說我的發展方向方面的思考

六、說說你認爲的服務端開發工程師應該具有哪些能力

七、說說你認爲的架構師是什麼樣的,架構師主要作什麼

八、說說你所理解的技術專家

相關文章
相關標籤/搜索