面試總結-整理新

基礎篇

基本功

一、Hashcode的做用,與 equal 有什麼區別?html

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

二、cloneable接口實現原理:只有實現了這個接口,才能夠調用Object的clone方法,不然CloneNotSupporteddExceptionjava

三、comparable與comparator的區別:前者是內部排序,後者是外部排序mysql

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

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

五、Error、Exception區別#git

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

六、Object有哪些公用方法web

  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 轉換成字符串,通常子類都有重寫,不然打印句柄。面試

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

  從JDK1.2版本開始,把對象的引用分爲四種級別,從而使程序能更加靈活的控制對象的生命週期。這四種級別由高到低依次爲:強引用、軟引用、弱引用和虛引用。
  1.強引用
    最廣泛的一種引用方式,如String s = "abc",變量s就是字符串「abc」的強引用,只要強引用存在,則垃圾回收器就不會回收這個對象。
  2.軟引用(SoftReference)
    用於描述還有用但非必須的對象,若是內存足夠,不回收,若是內存不足,則回收。通常用於實現內存敏感的高速緩存,軟引用能夠和引用隊列ReferenceQueue聯合使用,若是軟引用的對象被垃圾回收,JVM就會把這個軟引用加入到與之關聯的引用隊列中。
  3.弱引用(WeakReference)
    弱引用和軟引用大體相同,弱引用與軟引用的區別在於:只具備弱引用的對象擁有更短暫的生命週期。在垃圾回收器線程掃描它所管轄的內存區域的過程當中,一旦發現了只具備弱引用的對象,無論當前內存空間足夠與否,都會回收它的內存。
  4.虛引用(PhantomReference)
    就是形同虛設,與其餘幾種引用都不一樣,虛引用並不會決定對象的生命週期。若是一個對象僅持有虛引用,那麼它就和沒有任何引用同樣,在任什麼時候候均可能被垃圾回收器回收。 虛引用主要用來跟蹤對象被垃圾回收器回收的活動。
  虛引用與軟引用和弱引用的一個區別在於:
    虛引用必須和引用隊列 (ReferenceQueue)聯合使用。當垃圾回收器準備回收一個對象時,若是發現它還有虛引,就會在回收對象的內存以前,把這個虛引用加入到與之關聯的引用隊列中。

八、Java對象的生命週期

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

九、Java類的生命週期:加載------》鏈接(驗證-->準備-->解析)------》初始化------》使用------》卸載

九、一個類對象屬性發生改變時,如何讓調用者知道:Event事件機制

十、statement和preparedStatement的區別

十一、Arraylist的循環刪除問題:迭代的時候使用list.remove就會引發ConcurrentModificationException,由於迭代的時候mod是迭代開始時的快照,list.remove時修改了集合的mod,致使迭代時mod快照與集合mod比較不一致就異常了 

集合

 

一、HashMap的實現機制:

  維護一個每一個元素是一個鏈表的數組,並且鏈表中的每一個節點是一個Entry[]鍵值對的數據結構。
  實現了數組+鏈表(1.8新增紅黑樹)的特性,查找快,插入刪除也快。
  對於每一個key,他對應的數組索引下標是 int i = hash(key.hashcode)&(len-1);
  每一個新加入的節點放在鏈表首,而後該新加入的節點指向原鏈表首

二、HashMap的源碼,實現原理,JDK8中對HashMap作了怎樣的優化。:jdk8中hashmap在單鏈的基礎上,增長了單鏈超過定長(8)坍縮成紅黑樹,提升了新增和刪除節點的效率,提升了讀取節點的效率

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

六、HashMap 是線程安全的嗎,爲何不是線程安全的(最好畫圖說明多線程環境下不安全)?:1.7及之前高併發狀況下容易造成環,1.8中也有問題

七、HashMap 的擴容過程:默認初始值16,擴容因子0.75,擴容到原來兩倍

四、HashMap衝突:

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

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

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

  經過將 Key 的 hash 值與 length-1 進行 & 運算,實現了當前 Key 的定位,2 的冪次方能夠減小衝突(碰撞)的次數,提升 HashMap 查詢效率;
  若是 length 爲 2 的次冪 則 length-1 轉化爲二進制一定是 11111……的形式,在於 h 的二進制與操做效率會很是的快,並且空間不浪費;
  若是 length 不是 2 的次冪,好比 length 爲 15,則 length-1 爲 14,對應的二進制爲 1110,在於 h 與操做,最後一位都爲 0,而 0001,0011,0101,1001,1011,0111,1101 這幾個位置永遠都不能存放元素了,空間浪費至關大。
  更糟的是這種狀況中,數組能夠使用的位置比數組長度小了不少,這意味着進一步增長了碰撞的概率,減慢了查詢的效率!這樣就會形成空間的浪費。

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值,並且用與代替求模。

三、HashMap和TreeMap區別:

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

五、ConcurrentHashMap原理
  ConcurrentHashMap容許多個修改操做併發進行,其關鍵在於使用了鎖分離技術。它使用了多個鎖來控制對Hash表的不一樣Segment進行的修改。
    ConcurrentHashMap的應用場景是高併發,可是並不能保證線程安全,而同步的HashMap和HashTable的是鎖住整個容器,而加鎖以後ConcurrentHashMap不須要鎖住整個容器,只須要鎖住對應的segment就行了,因此能夠保證高併發同步訪問,提高了效率。 
  ConcurrentHashMap可以保證每一次調用都是原子操做,可是並不保證屢次調用之間也是原子操做。
  ConcurrentHashMap是使用了鎖分段技術技術來保證線程安全的,鎖分段技術:首先把HashMap分紅若干個Segmenet,而後給每一段數據配一把鎖,當一個線程佔用鎖訪問其中一個段數據的時候,其餘段的數據也能被其餘線程訪問
    1.get時,不加鎖,先定位到segment而後在找到頭結點進行讀取操做。而value是volatile變量,因此能夠保證在競爭條件時保證讀取最新的值,若是讀到的value是null,則可能正在修改,那麼就調用ReadValueUnderLock函數,加鎖保證讀到的數據是正確的。
    2.Put時會加鎖,一概添加到hash鏈的頭部。
    3.Remove時也會加鎖,因爲next是final類型不可改變,因此必須把刪除的節點以前的節點都複製一遍。
  在JDK8中對這種實現又進行了修改,JDK8中的ConcurrentHashmap基於CAS和TreeBin實現的,不須要對segment或者全局加鎖,只須要對單行枷鎖(hashCode相同),後邊的鏈表是鏈表加紅黑樹。對於單個值的修改使用CAS。

九、LinkedHashMap的原理及應用:LRU算法

十一、HashSet與TreeSet的比較
  1.TreeSet 是二叉樹實現的,Treeset中的數據是自動排好序的,不容許放入null值 。
  2.HashSet 是哈希表實現的,HashSet中的數據是無序的,能夠放入null,但只能放入一個null,二者中的值都不能重複,就如數據庫中惟一約束 。
  3.HashSet要求放入的對象必須實現HashCode()方法,放入的對象,是以hashcode碼做爲標識的,而具備相同內容的String對象,hashcode是同樣,因此放入的內容不能重複。可是同一個類的對象能夠放入不一樣的實例。
  適用場景分析:
    HashSet是基於Hash算法實現的,其性能一般都優於TreeSet。咱們一般都應該使用HashSet,在咱們須要排序的功能時,咱們才使用TreeSet。
十二、HashMap和ConcurrentHashMap的區別
  1。HashMap不是線程安全的,而ConcurrentHashMap是線程安全的。
  2。ConcurrentHashMap採用鎖分段技術,將整個Hash桶進行了分段segment,也就是將這個大的數組分紅了幾個小的片斷segment,並且每一個小的片斷segment上面都有鎖存在,那麼在插入元素的時候就須要先找到應該插入到哪個片斷segment,而後再在這個片斷上面進行插入,並且這裏還須要獲取segment鎖。
  3。ConcurrentHashMap讓鎖的粒度更精細一些,併發性能更好。
1三、HashTable和ConcurrentHashMap的區別
  它們均可以用於多線程的環境,可是當Hashtable的大小增長到必定的時候,性能會急劇降低,由於迭代時須要被鎖定很長的時間。由於ConcurrentHashMap引入了分割(segmentation),不論它變得多麼大,僅僅須要鎖定map的某個部分,而其它的線程不須要等到迭代完成才能訪問map。簡而言之,在迭代的過程當中,ConcurrentHashMap僅僅鎖定map的某個部分,而Hashtable則會鎖定整個map。

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

1五、TreeMap、HashMap、LindedHashMap的區別

  LinkedHashMap能夠保證HashMap集合有序,存入的順序和取出的順序一致。
  TreeMap實現SortMap接口,可以把它保存的記錄根據鍵排序,默認是按鍵值的升序排序,也能夠指定排序的比較器,當用Iterator遍歷TreeMap時,獲得的記錄是排過序的。
  HashMap不保證順序,即爲無序的,具備很快的訪問速度。 HashMap最多隻容許一條記錄的鍵爲Null;容許多條記錄的值爲 Null。 HashMap不支持線程的同步。

  咱們在開發的過程當中使用HashMap比較多,在Map中在Map 中插入、刪除和定位元素,HashMap 是最好的選擇。
  但若是您要按天然順序或自定義順序遍歷鍵,那麼TreeMap會更好。
  若是須要輸出的順序和輸入的相同,那麼用LinkedHashMap 能夠實現,它還能夠按讀取順序來排列。

 

十、Arraylist與LinkedList的比較
  1.ArrayList是實現了基於動態數組的數據結構,由於地址連續,一旦數據存儲好了,查詢操做效率會比較高(在內存裏是連着放的)。
  2.由於地址連續, ArrayList要移動數據,因此插入和刪除操做效率比較低。
  3.LinkedList基於鏈表的數據結構,地址是任意的,因此在開闢內存空間的時候不須要等一個連續的地址,對於新增和刪除操做add和remove,LinedList比較佔優點。
  4.由於LinkedList要移動指針,因此查詢操做性能比較低。
  適用場景分析:
    當須要對數據進行隨機訪問的狀況下選用ArrayList,當須要對數據進行屢次增長刪除修改時採用LinkedList。
十一、ArrayList與Vector的比較
  1.Vector的方法都是同步的,是線程安全的,而ArrayList的方法不是,因爲線程的同步必然要影響性能。所以,ArrayList的性能比Vector好。
  2.當Vector或ArrayList中的元素超過它的初始大小時,Vector會將它的容量翻倍,而ArrayList只增長50%的大小,這樣。ArrayList就有利於節約內存空間。
  3.大多數狀況不使用Vector,由於性能很差,可是它支持線程的同步,即某一時刻只有一個線程可以寫Vector,避免多線程同時寫而引發的不一致性。
  4.Vector能夠設置增加因子,而ArrayList不能夠。
  適用場景分析:
    1.Vector是線程同步的,因此它也是線程安全的,而ArrayList是線程異步的,是不安全的。若是不考慮到線程的安全因素,通常用ArrayList效率比較高。
    2.若是集合中的元素的數目大於目前集合數組的長度時,在集合中使用數據量比較大的數據,用Vector有必定的優點。

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

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

  1。Arrays.sort()
    該算法是一個通過調優的快速排序,此算法在不少數據集上提供N*log(N)的性能,這致使其餘快速排序會下降二次型性能。
  2。Collections.sort()
    該算法是一個通過修改的合併排序算法(其中,若是低子列表中的最高元素效益高子列表中的最低元素,則忽略合併)。此算法可提供保證的N*log(N)的性能,此實現將指定列表轉儲到一個數組中,而後再對數組進行排序,在重置數組中相應位置處每一個元素的列表上進行迭代。

1五、說說常見的集合有哪些吧?

  Map 接口和 Collection 接口是全部集合框架的父接口:
  Collection 接口的子接口包括:Set 接口和 List 接口;
  Map 接口的實現類主要有:HashMap、TreeMap、Hashtable、ConcurrentHashMap 以及 Properties 等;
  Set 接口的實現類主要有:HashSet、TreeSet、LinkedHashSet 等;
  List 接口的實現類主要有:ArrayList、LinkedList、Stack 以及 Vector 等。

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七、Java 集合的快速失敗機制 「fail-fast」
  它是 java 集合的一種錯誤檢測機制,當多個線程對集合進行結構上的改變的操做時,有可能會產生 fail-fast 機制。
  例如 :假設存在兩個線程(線程 一、線程 2),線程 1 經過 Iterator 在遍歷集合 A 中的元素,在某個時候線程 2 修改了集合 A 的結構(是結構上面的修改,而不是簡單的修改集合元素的內容),那麼這個時候程序就會拋出 ConcurrentModificationException 異常,從而產生 fail-fast 機制。
  緣由: 迭代器在遍歷時直接訪問集合中的內容,而且在遍歷過程當中使用一個 modCount 變量。集合在被遍歷期間若是內容發生變化,就會改變 modCount 的值。

  每當迭代器使用 hashNext()/next() 遍歷下一個元素以前,都會檢測 modCount 變量是否爲 expectedmodCount 值,是的話就返回遍歷;不然拋出異常,終止遍歷。
  解決辦法:
  在遍歷過程當中,全部涉及到改變 modCount 值得地方所有加上 synchronized;
  使用 CopyOnWriteArrayList 來替換 ArrayList。

 

多線程

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

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

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

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

 

7二、 如何避免死鎖?

7三、Java中活鎖和死鎖有什麼區別?餓死?:活鎖是都讓別人去獲取鎖,結果都不獲取鎖,解決方式爲只讓一我的釋放資源 | 死鎖是都本身去獲取鎖,結果都獲取不到鎖 | 餓死是任務一直獲取不到資源,解決爲採用隊列 

  

二、CountDownLatch,CyclicBarrier, Semaphore,Exchanger的原理

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

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

四、ThreadLocal(線程變量副本)

  Thread包含一個Map結構,key就是ThreadLocal變量,value就是變量值|使用時注意線程池狀況下,線程被複用的問題
  ThreadLocal在Spring中發揮着巨大的做用,在管理Request做用域中的Bean、事務管理、任務調度、AOP等模塊都出現了它的身影。
  Spring中絕大部分Bean均可以聲明成Singleton做用域,採用ThreadLocal進行封裝,所以有狀態的Bean就可以以singleton的方式在多線程中正常工做了。

五、Volatile和Synchronized四個不一樣點:

  1。粒度不一樣,前者針對變量 ,後者鎖對象和類
  2。syn阻塞,volatile線程不阻塞
  3。syn保證三大特性(可見性,原子性,有序性),volatile不保證原子性
  4。syn編譯器優化,volatile不優化

六、同步,異步,阻塞,非阻塞

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

9三、Volatile的特徵:
    A、禁止指令重排(有例外)
    B、可見性
  Volatile的內存語義:
    當寫一個volatile變量時,JMM會把線程對應的本地內存中的共享變量值刷新到主內存。
    當讀一個volatile變量時,JMM會把線程對應的本地內存置爲無效,線程接下來將從主內存中讀取共享變量。
  Volatile的重排序
    1。當第二個操做爲volatile寫操作時,無論第一個操做是什麼(普通讀寫或者volatile讀寫),都不能進行重排序。這個規則確保volatile寫以前的全部操做都不會被重排序到volatile以後;
    2。當第一個操做爲volatile讀操做時,無論第二個操做是什麼,都不能進行重排序。這個規則確保volatile讀以後的全部操做都不會被重排序到volatile以前;
    3。當第一個操做是volatile寫操做時,第二個操做是volatile讀操做,不能進行重排序。
  這個規則和前面兩個規則一塊兒構成了:兩個volatile變量操做不可以進行重排序;

  除以上三種狀況之外能夠進行重排序。
  好比:
    1。第一個操做是普通變量讀/寫,第二個是volatile變量的讀;
    2。第一個操做是volatile變量的寫,第二個是普通變量的讀/寫;

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

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

13八、synchronized 關鍵字:
  底層實現:
  進入時,執行 monitorenter,將計數器 +1,釋放鎖 monitorexit 時,計數器-1;
  當一個線程判斷到計數器爲 0 時,則當前鎖空閒,能夠佔用;反之,當前線程進入等待狀態。
  含義:(monitor 機制)
  Synchronized 是在加鎖,加對象鎖。對象鎖是一種重量鎖(monitor),synchronized 的鎖機制會根據線程競爭狀況在運行時會有偏向鎖(單一線程)、輕量鎖(多個線程訪問 synchronized 區域)、對象鎖(重量鎖,多個線程存在競爭的狀況)、自旋鎖等。
  該關鍵字是一個幾種鎖的封裝。

13九、synchronized鎖膨脹原理:自旋鎖?無鎖->偏向鎖->輕量級鎖(cas)->重量級鎖

3二、volatile 的實現原理?

3三、雙檢鎖DCL問題:線程安全問題,其餘線程獲取到的單例實例可能還未初始化完(happens-before原理引發的),解決方案爲單例實例改成volatile,或者不要採用懶加載,或者用枚舉,或者用holder模式

3六、CAS?CAS 有什麼缺陷,如何解決?:ABA問題,AtomicStampedReference經過版本號來解決

3七、ABA 問題:AtomicStampedReference經過版本號來解決

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

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

4一、AQS

4九、LockSupport工具

50、Condition接口及其實現原理

 

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

 

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)狀態。
  5。死亡(dead):線程run()、main() 方法執行結束,或者因異常退出了run()方法,則該線程結束生命週期。死亡的線程不可再次復生。

4一、Blocked和Waiting的區別 

4二、Java 內存模型?

 

3八、HashMap 的併發問題?

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

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

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

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

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

5一、Fork/Join框架的理解

13四、如何指定多個線程的執行順序?
  解析:面試官會給你舉個例子,如何讓 10 個線程按照順序打印 0123456789?(寫代碼實現)
  答:設定一個 orderNum,每一個線程執行結束以後,更新 orderNum,指明下一個要執行的線程。而且喚醒全部的等待線程。
  在每個線程的開始,要 while 判斷 orderNum 是否等於本身的要求值!!不是,則 wait,是則執行本線程。

13六、多線程產生死鎖的 4 個必要條件?
  互斥條件:一個資源每次只能被一個線程使用;
  請求與保持條件:一個線程因請求資源而阻塞時,對已得到的資源保持不放;
  不剝奪條件:進程已經得到的資源,在未使用完以前,不能強行剝奪;
  循環等待條件:若干線程之間造成一種頭尾相接的循環等待資源關係。

13七、如何避免死鎖?
  指定獲取鎖的順序,舉例以下:
  好比某個線程只有得到 A 鎖和 B 鎖才能對某資源進行操做,在多線程條件下,如何避免死鎖?
  得到鎖的順序是必定的,好比規定,只有得到 A 鎖的線程纔有資格獲取 B 鎖,按順序獲取鎖就能夠避免死鎖

13八、悲觀鎖和樂觀鎖的區別,怎麼實現
  悲觀鎖:一段執行邏輯加上悲觀鎖,不一樣線程同時執行時,只能有一個線程執行,其餘的線程在入口處等待,直到鎖被釋放。|select for update
  樂觀鎖:一段執行邏輯加上樂觀鎖,不一樣線程同時執行時,能夠同時進入執行,在最後更新數據的時候要檢查這些數據是否被其餘線程修改了(版本和執行初是否相同),沒有修改則進行更新,不然放棄本次操做。|版本號

 

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

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

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

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

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

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

七、線程池原理:

  等待任務隊列和工做集:

  

  線程池的主要狀態鎖:

  

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

  

  ThreadPoolExecutor 的內部工做原理

   1.若是當前池大小 poolSize 小於 corePoolSize ,則建立新線程執行任務。
   2.若是當前池大小 poolSize 大於 corePoolSize ,且等待隊列未滿,則進入等待隊列
   3.若是當前池大小 poolSize 大於 corePoolSize 且小於 maximumPoolSize ,且等待隊列已滿,則建立新線程執行任務。
   4.若是當前池大小 poolSize 大於 corePoolSize 且大於 maximumPoolSize ,且等待隊列已滿,則調用拒絕策略來處理該任務。
   5.線程池裏的每一個線程執行完任務後不會馬上退出,而是會去檢查下等待隊列裏是否還有線程任務須要執行,若是在 keepAliveTime 裏等不到新的任務了,那麼線程就會退出。

 

 

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

 

 

 

 

JVM

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

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

二、「你能不能談談,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方法)引用的對象。

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

1六、類加載爲何要使用雙親委派模式,有沒有什麼場景是打破了這個模式?:有,Thread.currentThread能夠設置classloader,以及osgi

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

5四、Java類加載的過程。

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

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

6五、Class.forName 和 ClassLoader.loadClass的區別 

 

四、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 經過參數的自動轉型來找到合適的辦法。

九、數組在內存中如何分配:簡單類型數組在棧上分配,引用類型在堆上分配

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

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

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

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

 

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

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

4四、JVM的內存結構。 

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

 

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

6九、垃圾回收算法有哪些?
  引用計數 :原理是此對象有一個引用,即增長一個計數,刪除一個引用則減小一個計數。垃圾回收時,只用收集計數爲 0 的對象。此算法最致命的是沒法處理循環引用的問題;
  標記-清除 :此算法執行分兩階段。第一階段從引用根節點開始標記全部被引用的對象,第二階段遍歷整個堆,把未標記的對象清除;此算法須要暫停整個應用,同時,會產生內存碎片;
  複製算法 :此算法把內存空間劃爲兩個相等的區域,每次只使用其中一個區域。垃圾回收時,遍歷當前使用區域,把正在使用中的對象複製到另一個區域中;此算法每次只處理正在使用中的對象,所以複製成本比較小,同時複製過去之後還能進行相應的內存整理,不會出現「碎片」 問題。固然,此算法的缺點也是很明顯的,就是須要兩倍內存空間;
  標記-整理 :此算法結合了 「標記-清除」 和 「複製」 兩個算法的優勢。也是分兩階段,第一階段從根節點開始標記全部被引用對象,第二階段遍歷整個堆,把清除未標記對象而且把存活對象 「壓縮」 到堆的其中一塊,按順序排放。此算法避免了 「標記-清除」 的碎片問題,同時也避免了 「複製」 算法的空間問題。

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

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

2一、各類回收算法

5三、Java是否能夠GC直接內存。:不能夠,是在ByteBuffer分配內存時設置了清理器

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

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

70、root 搜索算法中,哪些能夠做爲 root?
  被啓動類(bootstrap 加載器)加載的類和建立的對象;
  JavaStack 中的引用的對象 (棧內存中引用的對象);
  方法區中靜態引用指向的對象;
  方法區中常量引用指向的對象;
  Native 方法中 JNI 引用的對象。

7一、GC 何時開始?
  GC 常常發生的區域是堆區,堆區還能夠細分爲新生代、老年代,新生代還分爲一個 Eden 區和兩個 Survivor 區。
  對象優先在 Eden 中分配,當 Eden 中沒有足夠空間時,虛擬機將發生一次 Minor GC,由於 Java 大多數對象都是朝生夕滅,因此 Minor GC 很是頻繁,並且速度也很快;
  Full GC,發生在老年代的 GC,當老年代沒有足夠的空間時即發生 Full GC,發生 Full GC 通常都會有一次 Minor GC。
  大對象直接進入老年代,如很長的字符串數組,虛擬機提供一個;XX:PretenureSizeThreadhold 參數,令大於這個參數值的對象直接在老年代中分配,避免在 Eden 區和兩個 Survivor 區發生大量的內存拷貝;
  發生 Minor GC 時,虛擬機會檢測以前每次晉升到老年代的平均大小是否大於老年代的剩餘空間大小,若是大於,則進行一次 Full GC,若是小於,則查看 HandlePromotionFailure 設置是否容許擔保失敗,若是容許,那隻會進行一次 Minor GC,若是不容許,則改成進行一次 Full GC。

 

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

6八、相似-Xms、-Xmn 這些參數的含義:
  堆內存分配:
    JVM 初始分配的內存由-Xms 指定,默認是物理內存的 1/64;
    JVM 最大分配的內存由-Xmx 指定,默認是物理內存的 1/4;
    默認空餘堆內存小於 40% 時,JVM 就會增大堆直到-Xmx 的最大限制;空餘堆內存大於 70% 時,JVM 會減小堆直到 -Xms 的最小限制;
    所以服務器通常設置-Xms、-Xmx 相等以免在每次 GC 後調整堆的大小。對象的堆內存由稱爲垃圾回收器的自動內存管理系統回收。
  非堆內存分配:
    JVM 使用-XX:PermSize 設置非堆內存初始值,默認是物理內存的 1/64;
    由 XX:MaxPermSize 設置最大非堆內存的大小,默認是物理內存的 1/4;
    -Xmn2G:設置年輕代大小爲 2G;
    -XX:SurvivorRatio,設置年輕代中 Eden 區與 Survivor 區的比值。

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

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

5七、dump文件的分析。

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

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

  線程共享部分:方法區,又名永久代,無GC(常量池內存不足OOM)。堆區,分配時內存不足則OOM。

  線程私有部分:虛擬機棧,線程請求棧深度超過閾值則SOF,分配時內存不足OOM。本地方法棧,同虛擬機棧同樣。程序計數器,沒有OOM。

  直接內存,空間不足則OOM  

 

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

 

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

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

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

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

3五、請寫一段棧溢出、堆溢出的代碼
  遞歸調用能夠致使棧溢出
  不斷建立對象能夠致使堆溢出

 

 

 

 

 

 

NIO

二、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曾經使用過,後來放棄。

 三、Java IO與NIO

  NIO是爲了彌補IO操做的不足而誕生的,NIO的一些新特性有:非阻塞I/O,選擇器,緩衝以及管道。管道(Channel),緩衝(Buffer) ,選擇器( Selector)是其主要特徵。
  概念解釋
    Channel——管道實際上就像傳統IO中的流,到任何目的地(或來自任何地方)的全部數據都必須經過一個 Channel 對象。一個 Buffer 實質上是一個容器對象。
    Selector——選擇器用於監聽多個管道的事件,使用傳統的阻塞IO時咱們能夠方便的知道何時能夠進行讀寫,而使用非阻塞通道,咱們須要一些方法來知道何時通道準備好了,選擇器正是爲這個須要而誕生的。

    每一種基本 Java 類型都有一種緩衝區類型:
    ByteBuffer——byte
    CharBuffer——char
    ShortBuffer——short
    IntBuffer——int
    LongBuffer——long
    FloatBuffer——float
    DoubleBuffer——double
  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。也就是,其餘人雖然也可能要等,但不會在現場等,而是回家等,能夠作其它事去,水接滿了,接水工會通知他們。
  這其實也是很是接近當前社會分工細化的現實,也是統分利用現有資源達到併發效果的一種很經濟的手段,而不是動不動就來個並行處理,雖然那樣是最簡單的,但也是最浪費資源的方式。

四、Netty的Reactor模型

 

 

 

 

算法

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

  咱們把服務器集羣分紅n段,每一個服務器負責一段路由key。

  若是其中一臺掛了,只是影響這一段路由key失效,不影響其餘。

  若是要加一臺機器的話,咱們加在其中一個分段中,那麼這個分段也只有一小段路由key會失效,另一小段不影響。

  這樣就在很大程度上減少了影響範圍,主要應用在緩存集羣中

1八、B+樹:樹結構就是索引結構,採用B+樹跟磁盤有關,磁盤會預讀樹結點附近的數據,這樣就會很容易命中須要查詢的數據,而且減小了磁盤IO次數

2八、如何判斷一個單鏈表是否有環:採用list來存放全部元素,有重複則存在環|採用不一樣步長的指針來遍歷,步長較長的會遇上較短的

2九、紅黑樹:由於紅黑樹的結構能夠用不多的旋轉開銷就能完成插入和刪除,減少了紅黑樹結構的維護成本

  參考:https://blog.csdn.net/mmshixing/article/details/51692892

 

其餘 

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

  握手階段:C告訴S我要連接--->S回答C說已經準備好了--->C回答S說我收到你準備好了

  揮手階段:C告訴S我要斷開--->S回答C說我準備斷開了,可是等我發送完數據--->S告訴C說我發完最後一波數據了--->C回答S說我收到你最後一波數據

  揮手階段比握手階段多了一個服務端發送最後數據的過程

  詳解:https://blog.csdn.net/qzcsu/article/details/72861891

總共有四種狀態:主動創建鏈接、主動斷開鏈接、被動創建連和被動斷開鏈接
  兩兩組合仍是 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五、滑動窗口機制
  由發送方和接收方在三次握手階段,互相將本身的最大可接收的數據量告訴對方。也就是本身的數據接收緩衝池的大小。這樣對方能夠根據已發送的數據量來計算是否能夠接着發送。
在處理過程當中,當接收緩衝池的大小發生變化時,要給對方發送更新窗口大小的通知。

 

 

 

核心篇

數據存儲------(死鎖,索引,事務,優化,分庫分表,讀寫分離)

六、MySQL 遇到的死鎖問題

 參考:http://www.kissyu.org/2017/02/19/%E8%AE%B0%E5%BD%95%E4%B8%80%E6%AC%A1Mysql%E6%AD%BB%E9%94%81%E6%8E%92%E6%9F%A5%E8%BF%87%E7%A8%8B/

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

6一、產生死鎖的必要條件:互斥條件|請求與保持條件|不剝奪條件|循環等待條件
  參考http://blog.sina.com.cn/s/blog_5e3604840100ddgq.html

6二、死鎖預防:確保獲取鎖的順序一致
  參考http://blog.sina.com.cn/s/blog_5e3604840100ddgq.html

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

8五、如何解除死鎖狀態:查看在鎖的事務--->kill線程id

8七、MyISAM 和 InnoDB 的區別有哪些?:MyISAM 表不支持事務、不支持行級鎖、不支持外鍵。 InnoDB 表支持事務、支持行級鎖、支持外鍵

5四、各個數據庫引擎區別:http://www.jb51.net/article/38004.htm

 

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

八、數據庫索引的原理:B+樹

十、索引:B+,B-,全文索引

  Mysql的索引是一個數據結構,旨在使數據庫高效的查找數據。
  經常使用的數據結構是B+Tree,每一個葉子節點不但存放了索引鍵的相關信息還增長了指向相鄰葉子節點的指針,這樣就造成了帶有順序訪問指針的B+Tree,作這個優化的目的是提升不一樣區間訪問的性能。
十一、何時使用索引:
    常常出如今group by,order by和distinc關鍵字後面的字段
    常常與其餘表進行鏈接的表,在鏈接字段上應該創建索引
    常常出如今Where子句中的字段
    常常出現用做查詢選擇的字段

2三、mysql的索引分類:B+,hash;什麼狀況用什麼索引:hash索引不支持範圍查詢

30、組合索引,最左原則

3一、mysql 的表鎖、行鎖、頁鎖

3六、若是查詢很慢,你會想到的第⼀個⽅式是什麼?索引是⼲嘛的?:加索引,索引是爲數據保持了一個有序的映射,相似於TreeMap

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

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

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

5二、MySQL爲何使用B+樹做爲索引?:由於B+樹能夠預讀,減小磁盤IO次數,提升數據查詢速度

  參考:https://blog.csdn.net/bigtree_3721/article/details/73650601

5五、索引的使用注意事項:http://www.javashuo.com/article/p-cubihmaj-cn.html 

5八、索引的優缺點,什麼字段上創建索引:order by, where ,group by,distinct,join等字段

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

7一、數據庫索引的優缺點以及何時數據庫索引失效#:not in,!=不會命中索引

7二、當數據表中A、B字段作了組合索引,那麼單獨使用A或單獨使用B會有索引效果嗎?(使用like查詢如何有索引效果)
  答:A、B兩字段作組合索引的時候,誰在前面,誰在後面,若是A在前,那麼單獨使用A會有索引效果,單獨使用B則沒有,反之亦然。同理,使用like模糊查詢時,若是隻是使用前面%,那麼有索引效果,若是使用雙%號匹配,那麼則無索引效果

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

  索引 是對數據庫表中一列或多列的值進行排序的一種結構,使用索引可快速訪問數據庫表中的特定信息;
  底層數據結構是 B+ 樹;
  使用 B+ 樹的緣由:查找速度快、效率高,在查找的過程當中,每次都能拋棄掉一部分節點,減小遍歷個數。( 此時,你應該在白紙上畫出什麼是 B+ 樹 )
8七、聚簇索引和非聚簇索引的區別?

 

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

  做爲單個邏輯工做單元執行的一系列操做,知足四大特性:
    原子性(Atomicity):事務做爲一個總體被執行 ,要麼所有執行,要麼所有不執行;
    一致性(Consistency):保證數據庫狀態從一個一致狀態轉變爲另外一個一致狀態;
    隔離性(Isolation):多個事務併發執行時,一個事務的執行不該影響其餘事務的執行;
    持久性(Durability):一個事務一旦提交,對數據庫的修改應該永久保存。

   Mysql的事物隔離級別?

    Read Uncommitted(讀取未提交內容)

    Read Committed(讀取提交內容)

    Repeatable Read(可重讀)

    Serializable(可串行化)

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

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

8五、事務的隔離級別有哪幾種?MySQL 事務默認隔離級別是哪一個?
  答:讀未提交、讀已提交、可重複讀和序列化。可重複讀。

 

十二、MySQL數據庫優化總結

1三、MYSQL 優化經常使用方法

5三、mysql優化經驗

  1。對查詢進行優化,應儘可能避免全表掃描,首先應考慮在 where 及 order by 涉及的列上創建索引。
  2。應儘可能避免在 where 子句中使用!=或<>操做符,不然引擎將放棄使用索引而進行全表掃描。
  3。儘可能使用數字型字段,若只含數值信息的字段儘可能不要設計爲字符型,這會下降查詢和鏈接的性能,並會增長存儲開銷。這是由於引擎在處理查詢和鏈接時會逐個比較字符串中每個字符,而對於數字型而言只須要比較一次就夠了。
  4。任何地方都不要使用 select * from t ,用具體的字段列表代替「*」,不要返回用不到的任何字段。
  5。避免頻繁建立和刪除臨時表,以減小系統表資源的消耗。諸如此類,等等等等......

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

7七、一條sql執行過長的時間,你如何優化,從哪些方面?
  1。查看sql是否涉及多表的聯表或者子查詢,若是有,看是否能進行業務拆分,相關字段冗餘或者合併成臨時表(業務和算法的優化)
  2。涉及鏈表的查詢,是否能進行分表查詢,單表查詢以後的結果進行字段整合
  3。若是以上兩種都不能操做,非要鏈表查詢,那麼考慮對相對應的查詢條件作索引。加快查詢速度
  4。針對數量大的表進行歷史表分離(如交易流水錶)
  5。數據庫主從分離,讀寫分離,下降讀寫針對同一表同時的壓力,至於主從同步,mysql有自帶的binlog實現 主從同步
  6。explain分析sql語句,查看執行計劃,分析索引是否用上,分析掃描行數等等
  7。查看mysql執行日誌,看看是否有其餘方面的問題

 

2八、mysql分頁有什麼優化

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

45. 大家的數據庫單表數據量是多少?⼀般多⼤的時候開始出現查詢性能急劇降低?:1000萬

4六、mysql的最大寫入速度?:7500(4G內存+20G硬盤+1個CPU,4核)

  

 

三、說說分庫與分表設計:用戶中心,經過用戶id(手機號索引表,郵箱索引表)路由打散到4個DB,每一個DB把表切分紅8張分表,一共有4×8=32張表

四、分庫與分錶帶來的分佈式困境與應對之策:分佈式事務,子查詢,關聯查詢,分頁查詢|分佈式事務中間件(分佈式事務),把全部分庫分表數據同步彙總到一個庫,在這個庫上進行操做(分頁查詢),拆分爲單表查詢(子查詢,關聯查詢)

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

  基於數據庫方案:auto_increment | 多個庫相同步長間隔auto_increment | 數據庫單條記錄+ID批量生成服務 | 數據庫單條記錄+ID批量生成服務+災備模式 | 數據庫單條記錄+去中心化ID批量生成服務

  基於中間件方案:Tair/Redis原子操做|

  本地化方案:UUID | 當前時間 | snowflake

1四、ObjectId 規則

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

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

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

5九、數據庫鏈接池。:原理?

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

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

 

 

1六、倒排索引

1七、聊聊 ElasticSearch 使用場景

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

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

 

 

緩存

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

 二、Redis 內部結構

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

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

 

四、Redis 持久化機制:rdb和aof

六、Redis 集羣方案與實現:

八、緩存奔潰:緩存過時,所有穿透到後端的狀況,能夠種一個緩存(60s)和一個緩存標識(30s),訪問的時候先訪問緩存標識,發現過時後觸發異步更新緩存,並返回當前60s的緩存

九、緩存降級:丟卒保帥,通常錯誤-->警告-->錯誤-->嚴重錯誤

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

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

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

2一、Redis緩存穿透,緩存雪崩:沒有命中緩存,方案有加鎖穿透並種緩存,異步種全量緩存,布隆過濾器

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

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

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

2五、Redis的緩存失效策略:按期刪除(隨機檢查刪除)+ 惰性刪除(get的時候再去檢查刪除)+ 內存淘汰機制(lru)

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

2七、Redis緩存分片:客戶端分片(jedis),基於代理的分片(codis),路由查詢(redis cluster)

  參考:https://www.jianshu.com/p/14835303b07e

3一、漸進式rehash過程?:同時持有兩個hash,逐漸遷移

3五、事務與事件:事件IO多路複用,reactor模型

3六、主從複製:

3七、啓動過程

3八、集羣

3九、redis哨兵機制

40、redis高可用方案:哨兵機制

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

4三、redis如何事務支持:https://www.cnblogs.com/kyrin/p/5967620.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集羣中找到存儲在哪裏。

  

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

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

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

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

 

 

消息隊列

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

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

四、消息的堆積解決思路

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

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

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

八、mq如何保證明時性;

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

 

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

 

 

框架篇

Spring

九、如何自定義註解實現功能:聲明註解,註解解析器

2一、BeanFactory 和 FactoryBean?:BeanFactory是Spring的bean容器,FactoryBean是工廠bean,能夠來生成Bean的一種Bean

1四、Spring Bean的做用域:
  Singleton:Spring IOC容器中只有一個共享的Bean實例,通常都是Singleton做用域。
  Prototype:每個請求,會產生一個新的Bean實例。
  Request:每一次http請求會產生一個新的Bean實例。

3六、 若是⼀個接⼝有2個不一樣的實現, 那麼怎麼來Autowire⼀個指定的實現?:Qualifier | @Autowire是byType,@Resource是ByName-->ByType

3七、 Spring的聲明式事務 @Transaction註解⼀般寫在什麼位置? 拋出了異常會⾃動回滾嗎?有沒有辦法控制不觸發回滾? | 通常在接口實現的方法上,會自動回滾,在註解上配置屬性noRollbackFor

3八、 若是想在某個Bean⽣成並裝配完畢後執⾏⾃⼰的邏輯,能夠什麼⽅式實現?:Intialization接口afterProperties方法

3九、SpringBoot沒有放到web容器⾥爲何能跑HTTP服務?:自帶嵌入式tomcat

4三、怎樣攔截SpringMVC的異常,而後作⾃定義的處理,⽐如打⽇志或者包裝成JSON

4五、struts2和springMVC的區別

4六、spring框架中須要引用哪些jar包,以及這些jar包的用途:spring-core,spring-bean,spring-context 

50、spring注入的幾種方式:@Setter,@Constructor,@Autowire,@Resource

90、Spring 的 IOC 和 AOP 有了解嗎?
  IOC:控制反轉,(解耦合)將對象間的依賴關係交給 Spring 容器,使用配置文件來建立所依賴的對象,由主動建立對象改成了被動方式;
  AOP:面向切面編程,將功能代碼從業務邏輯代碼中分離出來。

9一、AOP 的實現方式有哪幾種?如何選擇?(必考)

答:JDK 動態代理實現和 cglib 實現。有接口定義則能夠使用jdk,沒有則用cglib。

   spring對aop的實現原理:ProxyFactoryBean | AbstractAutoProxyCreator | AspectJ語法 | XML方式

 

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

二、Spring Bean 的生命週期:

三、Spring IOC 如何實現:掃描源碼解析出BeanDefination,管理BeanDefination的依賴,反射生成Bean實例,根據BeanDefination的依賴注入bean

五、Spring AOP 實現原理:動態代理,攔截器

六、動態代理(cglib 與 JDK):有接口定義則能夠使用jdk,沒有則用cglib。

八、Spring 事務底層原理:底層是AOP實現的

十二、Spring 的單例實現原理:採用Map實現的單例

1三、Spring 框架中用到了哪些設計模式:工廠模式,觀察者模式,動態代理。。。

1七、SpringMVC運行原理
  1.客戶端請求提交到DispatcherServlet
  2.由DispatcherServlet控制器查詢HandlerMapping,找到並分發到指定的Controller中。
  3.Controller調用業務邏輯處理後,返回ModelAndView
  4.DispatcherServlet查詢一個或多個ViewResoler視圖解析器,找到ModelAndView指定的視圖
  5.視圖負責將結果顯示到客戶端

2四、Spring Bean 的生命週期,如何被管理的?

2五、Spring Bean 的加載過程是怎樣的?

2六、若是要你實現Spring AOP,請問怎麼實現?

2七、若是要你實現Spring IOC,你會注意哪些問題?:對象依賴管理,繼承,反射

2八、Spring 是如何管理事務的,事務管理機制?

2九、Spring 的不一樣事務傳播行爲有哪些,幹什麼用的?

    PROPAGATION_REQUIRED:外部沒有事務,就新開一個事務

    PROPAGATION_SUPPORTS:外部有事務,就用這個事物,沒有就算了

    PROPAGATION_MANDATORY:外部沒有事物,就不幹(異常)

    PROPAGATION_REQUIRES_NEW:無論外部有沒有事務,都新開獨立的一個事務

    PROPAGATION_NOT_SUPPORTED:無論外部有沒有事物,都不使用事務

    PROPAGATION_NEVER:外部有事務,就不幹(異常)

    PROPAGATION_NESTED:外部有事務,就新開一個子事務,savepoint

3二、Spring 循環注入的原理?:

3三、Spring AOP的理解,各個術語,他們是怎麼相互工做的?:Advice,PointCut,Advisor

3四、Spring 如何保證 Controller 併發的安全?:Spring針對Controller能夠配置scope,用來制定是request,session,prototype,仍是singleton

51. spring如何實現事物管理的:基於AOP實現的

52. springIOC和AOP的原理

55. springmvc的核心是什麼,請求的流程是怎麼處理的,控制反轉怎麼實現的
  核心:控制反轉和麪向切面
  請求處理流程:
    1。首先用戶發送請求到前端控制器,前端控制器根據請求信息(如URL)來決定選擇哪個頁面控制器進行處理並把請求委託給它,即之前的控制器的控制邏輯部分;
    2。頁面控制器接收到請求後,進行功能處理,首先須要收集和綁定請求參數到一個對象,並進行驗證,而後將命令對象委託給業務對象進行處理;處理完畢後返回一個ModelAndView(模型數據和邏輯視圖名);
    3。前端控制器收回控制權,而後根據返回的邏輯視圖名,選擇相應的視圖進行渲染,並把模型數據傳入以便視圖渲染;
    4。前端控制器再次收回控制權,將響應返回給用戶。
  控制反轉如何實現:
    咱們每次使用spring框架都要配置xml文件,這個xml配置了bean的id和class。
    spring中默認的bean爲單實例模式,經過bean的class引用反射機制能夠建立這個實例。
    所以,spring框架經過反射替咱們建立好了實例而且替咱們維護他們。
    A須要引用B類,spring框架就會經過xml把B實例的引用傳給了A的成員變量。

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的IOC有什麼優點。
6九、Spring如何維護它擁有的bean。:BeanDefination集合來管理。。

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五、Struts跟Spring mvc的優缺點,讓你選會如何選

解答:Spring MVC 與 Struts的區別

8六、簡單說說Spring 事務機制

解答:Spring事務機制

8九、Spring的原理

答:Spring的核心是IOC和AOP  ,IOC是依賴注入和控制反轉, 其注入方式可分爲set注入、構造器注入、接口注入等等。IOC就是一個容器,負責實例化、定位、配置應用程序中的對象及創建這些對象間的依賴。簡單理解就是:JAVA每一個業務邏輯處理至少須要兩個或者以上的對象協做進行工做,可是每一個對象在使用它的合做對象的時候,都須要頻繁的new 對象來實現,你就會發現,對象間的耦合度高了。而IOC的思想是:Spring容器來管理這些,對象只須要處理自己業務關係就行了。至於什麼是控制反轉,就是得到依賴對象的方式反轉了。
AOP呢,面向切面編程,最直接的體現就是Spring事物管理。至於Spring事物的相關資料,就不細說了,參考:Spring註解式事物管理

 90、JDK 動態代理如何實現?(加分點)

答:JDK 動態代理,只能對實現了接口的類生成代理,而不是針對類,該目標類型實現的接口都將被代理。原理是經過在運行期間建立一個接口的實現類來完成對目標對象的代理。

  1. 定義一個實現接口 InvocationHandler 的類;
  2. 經過構造函數,注入被代理類;
  3. 實現 invoke( Object proxy, Method method, Object[] args)方法;
  4. 在主函數中得到被代理類的類加載器;
  5. 使用 Proxy.newProxyInstance( ) 產生一個代理對象;
  6. 經過代理對象調用各類方法。

9二、Spring MVC 的核心控制器是什麼?消息處理流程有哪些?

答:核心控制器爲 DispatcherServlet。消息流程以下:

 

 

1五、代理的共有優勢:業務類只須要關注業務邏輯自己,保證了業務類的重用性。
  Java靜態代理:
    代理對象和目標對象實現了相同的接口,目標對象做爲代理對象的一個屬性,具體接口實現中,代理對象能夠在調用目標對象相應方法先後加上其餘業務處理邏輯。
    缺點:一個代理類只能代理一個業務類。若是業務類增長方法時,相應的代理類也要增長方法。
  Java動態代理:
    Java動態代理是寫一個類實現InvocationHandler接口,重寫Invoke方法,在Invoke方法能夠進行加強處理的邏輯的編寫,這個公共代理類在運行的時候才能明確本身要代理的對象,同時能夠實現該被代理類的方法的實現,而後在實現類方法的時候能夠進行加強處理。
  實際上:代理對象的方法 = 加強處理 + 被代理對象的方法
 

1六、JDK和CGLIB生成動態代理類的區別:
  JDK動態代理只能針對實現了接口的類生成代理(實例化一個類)。此時代理對象和目標對象實現了相同的接口,目標對象做爲代理對象的一個屬性,具體接口實現中,能夠在調用目標對象相應方法先後加上其餘業務處理邏輯
  CGLIB是針對類實現代理,主要是對指定的類生成一個子類(沒有實例化一個類),覆蓋其中的方法 。

 

1七、Spring AOP應用場景
  性能檢測,訪問控制,日誌管理,事務等。

8七、Spring 4.0新特性

解答:Spring4新特性

 

 

 

 

Netty

一、爲何選擇 Netty:由於netty是nio實現的,高併發的狀況下比mina表現要好

二、說說業務中,Netty 的使用場景:通訊組件,rpc通訊組件,mq通訊組件

三、原生的 NIO 在 JDK 1.7 版本存在 epoll bug:空轉,若是不到超時時間喚醒了,則記錄1次,超過512次則從新建立SelectionKey從新註冊全部事件

四、什麼是TCP 粘包/拆包:鏈路層對數據進行拆分數據包和合並數據包

五、TCP粘包/拆包的解決辦法:業務曾手動拆分數據包

七、說說 Netty 的零拷貝:內核態,不用在用戶態之間切換

1四、瞭解哪幾種序列化協議?包括使用場景和如何去選擇

1六、Netty的高性能表如今哪些方面:nio

18.NIO的組成?:Channel(通道),Selector(選擇器),ByteBuffer(各類緩衝器)

26.NIOEventLoopGroup源碼?

六、Netty 線程模型:Reactor模型

八、Netty 內部執行流程:

九、Netty 重連實現:在final裏重現鏈接

十一、Netty 的各大組件:

  Channel、EventLoop和ChannelFuture

  ChannelHandler和ChannelPipeline

  Bootstrapping

十二、Netty的線程模型:BossGroup,WorkerGroup

1三、TCP 粘包/拆包的緣由及解決方法

 

 

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

1七、Dubbo的底層實現原理和機制

2二、Dubbo的服務請求失敗怎麼處理:

  集羣容錯策略

  failover:失敗則嘗試訪問其餘provider

  failfast:失敗立馬返回

  failsafe:失敗直接忽略

  failback:失敗定時重發

  forking:並行調用多個provider,只要有一個返回則返回

  broadcast:全部provider都調一遍

4一、dubbo的組件有哪些,各有什麼做用。

  dubbo-rpc:提供rpc以及序列化功能

  dubbo-registry:提供服務註冊訂閱相關功能

  dubbo-remoting:提供rpc訪問通訊功能

4三、dubbo是如何利用接口就能夠通訊的。:動態代理,封裝了rpc,序列化,通訊等複雜性

五、說說 Dubbo 的實現原理:

  服務提供方暴露本身的服務,並註冊到zk上,服務消費者在zk上訂閱服務

  消費者訂閱到服務後,將客戶端訪問參數組裝成一個消息對象,加密傳輸到服務提供方,服務提供方解密參數並調用本地方法,將返回結果加密返回,客戶端再解密返回結果

 

 

 

 

微服務篇

微服務

一、先後端分離是如何作的:m站,先後端同窗統一制定好接口定義,APP前端同窗頁面展現效果,後端提供業務接口功能,並經過mtop平臺暴露給前端團隊使用

二、微服務哪些框架:eurke

三、你怎麼理解 RPC 框架:業務提供者暴露服務,並提供一個訪問地址,客戶端經過訪問地址訪問暴露的服務,涉及到數據傳輸和數據序列化 | 序列化、反序列化,IO傳輸,服務註冊和訂閱,服務路由

四、說說 RPC 的實現原理:客戶端調用 => 消息對象 => 數據加密 => 網絡傳輸 => 服務端數據解密成消息對象 => 服務端調用服務 => 返回結果數據加密 => 網絡傳輸回寫 => 客戶端解密成返回結果

  參考:https://liuzhengyang.github.io/2016/12/16/rpc-principle/

六、你怎麼理解 RESTful

七、說說如何設計一個良好的 API

  可讀性:一眼就能看出接口含義

  。。。

八、如何理解 RESTful API 的冪等性

   同一個請求訪問屢次系統的影響與訪問一次相同,好比查詢

九、如何保證接口的冪等性

  查詢,刪除,惟一索引校驗,token機制防止重複提交,訪問帶seq作惟一索引

十、說說 CAP 定理、 BASE 理論

十一、怎麼考慮數據一致性問題

  因爲分佈式環境下,CAP只能知足倆,因此能夠採用弱一致性的方案來解決一致性問題,好比彈外添加觀演人,採用談外異步更新到彈內,保證了分區容忍性和有效性,弱一致性方案

十二、說說最終一致性的實現方案

  好比數據同步,或者分庫分表數據彙總到一個庫

1三、你怎麼看待微服務

  

1四、微服務與 SOA 的區別

  

1五、如何拆分服務

  按照業務拆分,高內聚低耦合

1六、微服務如何進行數據庫管理

  

1七、如何應對微服務的鏈式調用異常:調用鏈路跟蹤,全鏈路日誌

1八、對於快速追蹤與定位問題

1九、微服務的安全

 

 

 

分佈式---------------zk,dubbo,消息中間件|分佈式session,分佈式鎖,分佈式事務,負載均衡,分庫分表,分佈式ID

一、談談業務中使用分佈式的場景

  業務層分佈出去造成分佈式服務,消息隊列分佈出去造成分佈式消息隊列,數據訪問分佈出去造成分佈式數據存儲。。。 

十一、zookeeper是什麼;

   分佈式協調服務,經常使用在分佈式系統中,屏蔽分佈式系統訪問底層的複雜配置

十二、zookeeper哪裏用到;

  分佈式服務的服務註冊+訂閱

1三、zookeeper的選主過程;:zab協議

1四、zookeeper集羣之間如何通信;

  zab協議  

1五、大家的zookeeper的節點加密是用的什麼方式;

2六、Zookeeper的用途,選舉的原理是什麼?

  分佈式協調服務,屏蔽分佈式訪問的複雜細節

2八、zookeeper原理和適用場景

2九、zookeeper watch機制

30、redis/zk節點宕機如何處理

3六、zookeeper的選舉策略

4二、zookeeper的負載均衡算法有哪些。?zk有負載均衡?zk在集羣負載均衡中的協調

    

1八、描述一個服務從發佈到被消費的詳細過程

  provider暴露服務,註冊服務到zk--》consumer訂閱在zk上訂閱服務

1九、分佈式系統怎麼作服務治理

  

20、接口的冪等性的概念

 

3三、用過哪些MQ,怎麼用的,和其餘mq比較有什麼優缺點,MQ的鏈接是線程安全的嗎

  ActiveMq,MetaQ,

3四、MQ系統的數據如何保證不丟失

  消息刷盤,消息消費確認

4六、消息隊列的原理和實現

4七、Redis實現消息隊列

  答:Redis實現消息隊列     、參考2

 

  

二、Session 分佈式方案:session複製,session粘連,session共享

九、分佈式Session框架
  配置服務器,Zookeeper集羣管理服務器能夠統一管理全部服務器的配置文件
  共享這些Session存儲在一個分佈式緩存中,能夠隨時寫入和讀取,並且性能要很好,如Memcache,Tair。
  封裝一個類繼承自HttpSession,將Session存入到這個類中而後再存入分佈式緩存中
  因爲Cookie不能跨域訪問,要實現Session同步,要同步SessionID寫到不一樣域名下。

40、分佈式session如何設計。

4四、集羣環境中,session如何實現共享

  1.Java集羣之session共享    

       二、session多服務器共享方案,還有一種方案就是使用一個固定的服務器專門保持session,其餘服務器共享

 

 

三、分佈式鎖的場景:彈內選座生成靜態頁,抽獎專題扣減名額和庫存

四、分佈是鎖的實現方案:zookeeper(臨時節點),redis(setnx)

1六、分佈式鎖的實現過程;:setnx成功則視爲獲取鎖成功,釋放鎖的時候刪除key

3九、分佈式鎖如何設計。

  redis中獲取鎖時,須要給鎖設置一個緩存過時時間,防止當前節點獲取到鎖後掛了,致使分佈式鎖沒法釋放
       釋放鎖時,須要確保獲取到鎖的狀況下,才能去刪除鎖節點

五、分佈式事務:TCC,1pc,2pc,3pc,txc

2四、對分佈式事務的理解:保證分佈式系統之間的數據一致性問題

3八、分佈式事務的控制。

 

六、集羣與負載均衡的算法與實現:dubbo負載均衡算法(roundrobin,random,leastactive,conisistenHash)

2五、如何實現負載均衡,有哪些算法能夠實現?

2三、重連機制會不會形成錯誤:有可能,好比接口超時重連,須要保證接口冪等性,不然對數據有影響

 

 

七、說說分庫與分表設計

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

2七、數據的垂直拆分水平拆分。:垂直拆分爲按照業務來拆分,水平拆分是把數據量不少的表拆分紅不少個小表,加快讀寫速度,提升性能

3五、列舉出你能想到的數據庫分庫分表策略;分庫分表後,如何解決全表查詢的問題

   策略:按照id取模分表,按照字符串hash分表

   將分庫分表的數據同步彙總到一個全量庫,在全量庫上全表查詢

3一、分佈式集羣下如何作到惟一序列號

  數據庫單條記錄+ID批量生成服務

3七、全局ID

 

4五、分佈式、集羣環境中,緩存如何刷新,如何保持同步?

  A、緩存如何刷新? 一、定時刷新  二、主動刷新覆蓋   ,每一個緩存框架都有自帶的刷新機制,或者說緩存失效機制,就拿Redis和 Ehcache舉例, 他們都有自帶的過時機制,另外主動刷新覆蓋時,只需獲取對應的key進行數據的覆蓋便可

  B、緩存如何保持同步?  這個redis有自帶的集羣同步機制,即複製功能,具體參考:基於Redis分佈式緩存實現      ,Ehcache也有分佈式緩存同步的配置,只須要配置不一樣服務器地址便可,參照:Ehcache分佈式緩存同步

4八、談談你對分佈式的理解

  我的理解:分佈式就是把一個系統/業務 拆分紅多個子系統/子業務 去協同處理,這個過程就叫分佈式,具體的演變方式參考:Java分佈式應用技術架構介紹

 

 

 

 

安全與性能篇

性能優化

一、性能指標有哪些

二、如何發現性能瓶頸

三、性能調優的常見手段

四、說說你在項目中如何進行性能調優

五、web如何項目優化

  解答:web項目性能優化(整理)

六、平常項目中,若是你接手,你準備從哪些方面調優?

  答:這個呢首先是瞭解哪些須要優化,須要優化確定是項目性能遭遇瓶頸或者猜想即將遭遇了,咱們纔會去考慮優化。那麼怎麼優化?

  a、擴容 ,擴容的理解,就是擴充服務器並行處理的能力,簡單來講就是加服務器,增長處理請求的能力,例如增長nginx 、tomcat等應用服務器的個數,或者物理服務器的個數,還有加大服務器帶寬等等,這裏考慮的是硬件方面

  b、調優 ,調優,包括系統調優和代碼調優 。 系統調優就是說加快處理速度,好比咱們所提到的CDN、ehcache、redis等緩存技術,消息隊列等等,加快服務間的響應速度,增長系統吞吐量,避免併發,至於代碼調優,這些就須要多積累了,好比重構、工廠等, 數據庫調優的話這個我不是很懂,只知道索引和存儲過程,具體參考:Mysql數據庫調優21個最佳實踐  ,其餘數據庫調優方面就各位本身找找吧

 

 

 

 

 

工程篇

需求分析

一、你如何對需求原型進行理解和拆分

二、說說你對功能性需求的理解

三、說說你對非功能性需求的理解

四、你針對產品提出哪些交互和改進意見

五、你如何理解用戶痛點

設計能力

一、說說你在項目中使用過的 UML 圖

二、你如何考慮組件化

三、你如何考慮服務化

四、你如何進行領域建模

五、你如何劃分領域邊界

六、說說你項目中的領域建模

七、說說概要設計

設計模式

一、你項目中有使用哪些設計模式

二、說說經常使用開源框架中設計模式使用分析

三、說說你對設計原則的理解

四、23種設計模式的設計理念

五、設計模式之間的異同,例如策略模式與狀態模式的區別

六、設計模式之間的結合,例如策略模式+簡單工廠模式的實踐

七、設計模式的性能,例如單例模式哪一種性能更好。

業務工程

一、你係統中的先後端分離是如何作的

二、說說你的開發流程

三、你和團隊是如何溝通的

四、你如何進行代碼評審

五、說說你對技術與業務的理解

六、說說你在項目中常常遇到的 Exception

七、說說你在項目中遇到感受最難Bug,怎麼解決的

八、說說你在項目中遇到印象最深困難,怎麼解決的

九、你以爲大家項目還有哪些不足的地方

十、你是否遇到過 CPU 100% ,如何排查與解決

十一、你是否遇到過 內存 OOM ,如何排查與解決

十二、說說你對敏捷開發的實踐

1三、說說你對開發運維的實踐

1四、介紹下工做中的一個對本身最有價值的項目,以及在這個過程當中的角色

1五、重構過代碼沒有?說說經驗;

 

場景

1六、一千萬的用戶實時排名如何實現;:zset的score特性(ZINCRBY修改score) 

1七、五萬人併發搶票怎麼實現;:反向代理,頁面靜態化+cdn,限流 | 動靜分離,冷熱分離,集羣+負載均衡,緩存,緩存預熱 | 讀寫分離,分庫分表,鏈接池

1八、大型網站應用之海量數據解決方案 
        http://blog.csdn.net/zhaojw_420/article/details/70881230

1九、大型網站應用之高併發狀況下的解決方案 
        http://blog.csdn.net/zhaojw_420/article/details/70881266

20、在一個千萬級的數據庫查尋中,如何提升查詢效率? :

  分庫分表,讀寫分離,創建索引

  或者

  創建索引,避免全表掃描 | 避免not in, !=之類,由於全表掃描|union all 替換 or,避免全表掃描(不一樣索引字段or)| like沒有知足最左原則也會全表掃描|where中使用參數,等號左邊使用表達式,函數也會全表掃描

  避免使用*返回無用的字段| exisits代替in

        http://blog.csdn.net/zhaojw_420/article/details/69367682

2一、用wait-notify 寫一段代碼來解決生產者-消費者問題,更進一步,在分佈式的環境下怎麼解決

  wait()和notify()都是線程間通訊的方法,能夠直接對線程的行爲進行操做。他們的本質實際上是傳遞生產者-消費者各自的消息,理解了這一點,那麼在分佈式環境下就很簡單了,只要找到一個第三方的能夠用來傳遞消息的媒介(Zookeeper、Redis、Kafka等)就能夠了。

  

 1 Object[] list = new Object[10];
 2 
 3 public void produce(){
 4         sychronized(list){
 5             while(true){
 6                if(list.size() >= 10){
 7                    list.wait();//等待消費者消費
 8                 }
 9              //work
10               list.add(new Object());
11               list.notify();//通知消費者
12             }
13         }   
14 }
15 
16 public void consume(){
17         sychronized(list){
18              while(true){
19                  if(list.size() <= 0){
20                       list.wait();//等待生產者生產
21                  }
22                 //work          
23                 list.remove(0);
24                 list.notify();//通知生產者
25              }   
26         }
27 }

 

  

22.、設計一個線程池

  A:能夠參考Java線程池的理論與實踐

  若是對JDK的線程池java.util.concurrent.ThreadPoolExecutor比較瞭解,能夠把一些簡單的特性放上去。若是不瞭解,能夠直接設計一個線程數組,而後加一些業務邏輯。所謂線程池,基本也就如此。

2三、 設計一個IOC容器
  A:用反射,註解,還有IOC的理論
2五、手機掃二維碼登陸是怎麼實現的?
  參考:http://www.jianshu.com/p/7f072ac61763
2六、如何保證RESTful API安全性 ?

  對客戶端作身份驗證:參數加簽,oauth協議

  對敏感數據加密,防止篡改:https

  身份認證以後的受權

  參考: http://blog.csdn.net/ywk253100/article/details/25654101

2七、項目併發如何處理?(咱們是web項目)

  解答:高併發量網站解決方案,另外,還有數據庫樂觀鎖,數據庫讀寫分離、使用消息隊列、多用存儲過程等等

2九、平臺上的圖片如何防盜鏈:refer字段

  解答: http下載防盜鏈原理:http協議的字段referer記錄來實現

30、如何區分上傳的圖片是否是木馬?

  解答:一、看上傳的圖片後綴  二、如何後綴是篡改的,那麼每一個文件有個魔術數字  文件上傳-魔術數字

3一、你的接口服務數據被人截包了,你如何防止數據惡意提交?

  答:咱們能夠在接口傳輸參數裏面設置一個業務編號,這個編號用來區分是否重複提交。這樣即便數據被抓包了,對方也沒法區分每一個字段你的含義,這時,這個業務編號的做用就來了

3二、假設服務器常常宕機,你從哪些方面去排查問題?

  答:先重啓,並開啓jvm輸出gc日誌||看是否是系統問題,若是不是則看是否是jvm問題,在看是否是oom,sof等

3三、下單3min還未支付,發短信提醒

  有兩種,一種是採用定時任務掃庫,時間不必定準確 | 一種是zset,score設置爲當前時間+3min,掃描zset發現時間到了,若是該訂單未支付,則發送短信

相關文章
相關標籤/搜索