轉:面試必備:《Java 最多見 200+ 面試題全解析》

Java 最多見 200+ 面試題全解析

Java 基礎

  1. JDK 和 JRE 有什麼區別?
    JDK是java的開發工具包,包含各類類庫,而且包含了JRE,javac是在JDK中的;
    JRE是java程序的運行環境,安裝過程當中自動添加PATHhtml

  2. == 和 equals 的區別是什麼?前端

    • 對於==,比較的是值是否相等,若是比較的是基本數據類型的變量,則直接比較其存儲的值是否相等,
      若是比較的是引用數據類型,則比較的是所指向的對象的地址值.
    • equals不能做用於基本數據類型,它比較的是是不是同一個對象
      若是沒有對equals方法進行重寫,則比較的是引用類型的變量所指向的對象的地址值.
      如String,Date等類對equals方法進行了重寫,比較的則是所指向的對象的內容
  3. 兩個對象的 hashCode()相同,則 equals()也必定爲 true,對嗎?
    首先,兩個對象equals相等,hashcode必定相等;可是hashcode相等時,equals不必定相等.
    其次,兩個不一樣的對象,由於可能存在哈希碰撞,因此hashcode多是相等的,可是顯然equals不爲true.
    還有就是,在object類中,euqals方法仍是用的==來判斷的,==對於對象而言比較的是地址值,因此equals相等
    hashcode必定同樣,反之就不必定了.java

  4. final 在 java 中有什麼做用?
    final關鍵字可做用於類,類屬性和方法;
    做用於類上時,該類不能被繼承
    做用於屬性時,該屬性不能被從新複製
    做用於方法時,該方法不能被重寫node

  5. java 中的 Math.round(-1.5) 等於多少?
    Math的round方法是四捨五入,若是參數是負數,則往大的數如,Math.round(-1.5)=-1mysql

  6. String 屬於基礎的數據類型嗎?
    不是,String是一個類,是引用數據類型.web

  7. java 中操做字符串都有哪些類?它們之間有什麼區別?
    有String,StringBuilder,StringBuffer面試

    1. String是不可變的,每次對String的操做都會產生一個String對象
    2. StringBuilder和StringBuffer是可變的,可以被屢次修改,並不會產生新的對象.
    3. StringBuilder是線程不安全的,StringBuffer是線程安全的.
    4. StringBuilder的處理速度比StringBuffer要快
  8. String str="i"與 String str=new String(「i」)同樣嗎?
    他們的值相等,用equals獲得true,可是他們是兩個對象,若是用==判斷返回false.
    且str="i"是直接在常量池中引用字符串,而new String(「i」)是在堆中根據i再建立一個對象.正則表達式

  9. 如何將字符串反轉?redis

    • 經過StringBuilder的reverse()方法能夠直接反轉
      StringBuilder sb = new StringBuilder("abc");
      sb.reverse().toString();
      12複製代碼
    • 經過String的toCharArray方法能夠得到字符串每個字符而且轉換爲字符數組
      而後循環從後往拼接便可
    • 遞歸的方法反轉(當只有一個字符時,返回原字符;當有兩個以上的字符時,返回結果爲第二個字符串開始的子串+第一個字符)
      public String reverseString(String str) {
      	if ((null == str) || str.length()<2) {
      		return str;
      	}
      	return reverseString(str.subString(1)) +str.charAt(0);
      }	
      123456複製代碼
  10. String 類的經常使用方法都有那些?
    charAt(int index)返回指定索引處的字符
    length()返回字符串長度
    split()根據給定的正則表達式拆分字符串
    toString()返回此對象自己算法

  11. 抽象類必需要有抽象方法嗎?
    抽象類能夠沒有抽象方法,可是若是一個類已經聲明爲抽象類,那麼它也不能再實例化,不能直接構造該類對象.

  12. 普通類和抽象類有哪些區別?

    1. 抽象類不能被實例化,普通類反之
    2. 抽象類的訪問權限限於public和protected,若是爲private的話,就不能被子類繼承了.
    3. 若是一個類繼承於抽象類,則它必須實現父類的抽象方法.若是不想實現,那麼子類也必須是抽象類.
  13. 抽象類能使用 final 修飾嗎?
    不能,final修飾的類是不能被繼承的,若是抽象類不能繼承,就沒有意義了.

  14. 接口和抽象類有什麼區別?

    1. 抽象類能夠有構造方法,接口不能有構造方法.
    2. 抽象類能夠包含非抽象方法,接口則不能.
    3. 抽象類方法訪問權限是public、protected,接口中只能是public.
    4. 只能單繼承,可是能夠多實現.
  15. java 中 IO 流分爲幾種?
    大的方面來講有兩種:字節流和字符流
    字節流繼承於InputStream、OutputStream
    字符流繼承於Reader、Writer

  16. BIO、NIO、AIO 有什麼區別?

    1. BIO表示同步阻塞式IO,交互方式是同步、阻塞方式,即客戶端有鏈接請求時服務端就須要啓動一個線程進行處理,
      若是這個鏈接不作任何事情會形成沒必要要的開支.
    2. NIO表示同步非阻塞IO,客戶端發送的鏈接請求都會註冊到多路複用器上,多路複用器輪詢到鏈接有I/O請求
      時才啓動一個線程處理.
    3. AIO表示異步非阻塞IO,客戶端的I/O請求都是由操做系統先完成IO操做後再通知服務器應用來啓動線程處理.
  17. Files的經常使用方法都有哪些?
    String getName():返回File對象所表示的文件名或文件路徑
    String getPath():返回File對象所對應的相對路徑
    boolean exists():判斷File對象的文件或者目錄是否存在
    boolean isDirectory():判斷File對象是不是目錄

容器

  1. java 容器都有哪些?
    String,數組以及java.util下面的集合類
    List:存放有序,列表存儲,元素可重複
    ArrayList LinkedList Vector
    Set:無序,元素不可重複
    HashSet TreeSet
    Map:無序,元素可重複
    HashMap TreeMap LinkedHashMap HashTable
  2. Collection 和 Collections 有什麼區別?
    Collection是集合類的一個頂級接口,它提供了對集合對象進行基本操做的通用接口方法.
    Collections是集合類的一個工具類,它提供了一系列的靜態方法,用於對集合中元素進行排序,搜索以及線程同步等操做.
  3. List、Set、Map 之間的區別是什麼?
    List: 能夠容許重複的對象;
    能夠插入多個null元素;
    有序,輸入順序就是輸出順序;
    Set: 不容許重複對象;
    無序,且只容許一個null對象;
    Map: 存儲鍵值對,只能有惟一的key,value能夠重複
    只能有一個null鍵
  4. HashMap 和 Hashtable 有什麼區別?
    一. HashMap能夠接受null鍵和值,HashTable不行
    二. HashTable是線程安全的,經過synchronized來保證,而HashMap線程不安全
    三. HashMap的迭代器是fail-fast迭代器,而HashTable的enumerator迭代器不是fail-fast.
  5. 如何決定使用 HashMap 仍是 TreeMap?
    HashMap基於散列表實現,適用於查詢頻繁的狀況
    TreeMap基於紅黑樹實現,適用於建立比較多的狀況.且TreeMap存儲數據是按照字母表的順序存儲的,
    若是對順序有要求也能夠選用TreeMap.
  6. 說一下 HashMap 的實現原理?
    數組+鏈表,初始16,75擴容,數據存在內部類Map.Entry中,其中包含key value hashcode和next.
  7. 說一下 HashSet 的實現原理?
    HashSet基於HashMap實現,默認構造函數是構造一個初始容量爲16的HashMap,全部放入HashSet
    集合的元素實際上由HashMap的key來保存,而value則保存了一個PRESENT的靜態Object對象,由於元素都保存在key
    中,因此才能不重複.
  8. ArrayList 和 LinkedList 的區別是什麼?
    1. ArrayList底層基於動態數組,LinkedList基於鏈表實現,底層是循環雙向鏈表
    2. 對於隨機訪問get和set,ArrayList優於LinkedList.
    3. 對於新增add和刪除remove,LinkedList比較快
  9. 如何實現數組和 List 之間的轉換?
    List轉數組:toArray()方法.在方法參數中指定原集合的長度的數組便可.
    數組轉List:Arrays的asList()方法.
  10. ArrayList 和 Vector 的區別是什麼?
    1. Vector的方法都是同步的,是線程安全的,ArrayList則不是.
    2. 在進行擴容的時候,Vector擴容至原來的一倍,ArrayList增長至原來的0.5倍.
  11. Array 和 ArrayList 有何區別?
    1. Array(數組)能夠包含基本數據類型和對象類型,ArrayList只能包含對象類型.
    2. ArrayList能夠自動擴容,Array則不行.
  12. 在 Queue 中 poll()和 remove()有什麼區別?
    Queue中,add方法和offer方法均可以添加元素,而remove和poll都是刪除隊列的頭元素,區別在於:
    add方法在隊列滿的狀況下拋異常,而offer方法則返回false.
    remove方法在隊列爲空時拋異常,poll方法將返回null.
  13. 哪些集合類是線程安全的?
    Vector HashTable ConcurrentHashMap
    Stack
  14. 迭代器 Iterator 是什麼?
    Iterator是個接口,它提供了不少對元素進行迭代的方法.迭代器能夠在迭代過程當中刪除
    底層集合的元素,能夠直接調用Iterator的remove()方法來刪除.
    由於在Conllection接口中定義了獲取集合迭代器的方法,因此每個集合都包括了能夠返回迭代器實例的方法.
  15. Iterator 怎麼使用?有什麼特色?
    每一個集合均可以用iterator()方法一個Iterator實例.
    使用next()方法獲取序列中的下一個元素,使用hasNext()方法檢查序列中是否有元素
    使用remove()方法將迭代器新返回的方法刪除.
    特色:Iterator將集合的遍歷和其底層的結構分離.
  16. Iterator 和 ListIterator 有什麼區別?
    ListIterator是Iterator的子接口,用於擴展Iterator.
    在Iterator中,咱們只能向前移動,沒法操縱或者修改集合中的元素.ListIterator彌補了這種缺點
    區別: 1.範圍不一樣,Iterator適用於全部集合,而ListIterator只適用於List及其子類
    2.ListIterator有add方法能夠添加元素,Iterator則不行.
    3.ListIterator能夠實現雙向遍歷,Iterator則不行.
    4.ListIterator能夠實現對象的修改,Iterator不行
    5.ListIterator能夠獲取集合中的全部,Iterator不行.
  17. 怎麼確保一個集合不能被修改?
    可使用Collections或者Guava來快速實現.如Collections.unmodifiableMap(xxxMap);

多線程

  1. 並行和併發有什麼區別?
    並行是多個事件同時進行,併發是多個事件在某一時間段內間隔發生.
    你吃飯吃到一半,電話來了,你停了下來接了電話,接完後繼續吃飯,這說明你支持併發。
    你吃飯吃到一半,電話來了,你一邊打電話一邊吃飯,這說明你支持並行。

  2. 線程和進程的區別?
    進程是操做系統資源分配的基本單位,線程是任務調度和執行的基本單位.
    進程有獨立的地址空間,一個進程崩潰後在保護模式下不會對其餘進程產生影響,而線程只是一個進程中的
    不一樣執行路徑,線程有本身的堆棧和局部變量.在操做系統中能同時運行多個進程,而在同一個進程內有多個
    線程同時執行.

  3. 守護線程是什麼?
    守護線程是服務其餘線程的,在java中,線程有兩種:守護線程和用戶線程.
    java中的jvm垃圾回收線程就是一個典型的守護線程.當用戶線程所有執行完,包括main線程也執行完畢,那麼
    jvm會自動退出,此時守護線程也就中止了.

  4. 建立線程有哪幾種方式?
    三種: 1. 繼承Thread類,重寫run方法,用子類實例調用start()方法;
    2. 實現Runnable接口並重寫run方法,建立Thread實例並傳入Runnable實例,代用Thread的start()方法
    3. 建立Callable接口的實現類,重寫call方法;
    構造此實現類的實例,將其做爲參數構造一個FutureTask類的實例;
    以FutureTask的實例爲參數構造一個Thread對象執行start()方法.
    第三種方式能夠容許有返回值,也能夠聲明拋出異常類.

  5. 說一下 runnable 和 callable 有什麼區別?
    runnable方式時,多個線程間能夠共享實例變量,callable方式則不行
    runnable方式沒有返回值,callable有返回值
    runnable方式run方法的異常只能在內部消化,callable的call()方法容許拋出異常

  6. 線程有哪些狀態?

    1. NEW 新建狀態,此時線程尚未運行線程中的代碼
    2. RUNNABLE 就緒狀態;處於就緒狀態的線程並不必定當即運行run方法,必須還要和其餘線程競爭CPU時間
    3. RUNNING 運行狀態;線程得到CPU時間後才進入運行狀態,開始執行run方法
    4. BLOCKED 阻塞狀態;線程運行過程當中會有各類緣由來進入阻塞狀態,如:調用sleep方法進入休眠;
      在IO操做中被阻塞;試圖獲得一個鎖,該鎖正被其餘線程持有;等待某個觸發條件.
      阻塞狀態的線程此時沒有結束,暫時讓出CPU時間給其餘線程.
    5. DEAD 死亡狀態;有兩個緣由致使線程死亡:第一是run方法正常退出天然死亡;第二是一個未捕獲的
      異常終止了run方法使線程死亡.
      爲了肯定線程在當前是否存活着(就是要麼是可運行的,要麼是被阻塞了),須要使用isAlive方法,若是是可運行或被阻塞,這個方法返回true;若是線程仍舊是new狀態且不是可運行的,或者線程死亡了,則返回false。
  7. sleep() 和 wait() 有什麼區別?

    1. sleep方法使Thread類的,而wait方法使Object類中的
    2. sleep方法使線程暫停指定的時間,讓出CPU給其餘線程,可是他的監控狀態依然保持着,時間到了之後會自動恢復運行狀態
      在這個過程當中,線程不會釋放同步對象鎖.
      而調用wait方法,線程會放棄對象鎖,進入等待隊列,待調用notify/notifyAll方法後纔會進入鎖池,獲取對象鎖後才進入運行狀態.
  8. notify()和 notifyAll()有什麼區別?
    notify()方法隨機喚醒一個wait線程到鎖池中去競爭鎖,而notifyAll方法喚醒全部wait線程到鎖池.
    notity()方法可能產生死鎖,notifyAll則不會.

  9. 線程的 run()和 start()有什麼區別?
    run()方法只是定義了線程的執行單元並不是直接開啓了線程資源,只有start()方法被調用,才能夠啓動一個線程.
    若是直接調用run方法,會被當成普通方法在main線程執行,並不會建立線程.
    44.建立線程池有哪幾種方式?
    java中的Executors能夠爲咱們建立現成的線程池,有如下幾種:

    1. newSingleThreadExecutor 建立一個單線程的線程池,它只有一個工做線程,操做無界工做隊列,能夠保證任務順序
    2. newFixedThreadPool 建立一個定長線程池,可控制線程最大併發數,超出的線程會在隊列中等待
    3. newCachedThreadPool 建立一個可緩存線程池,有空閒線程時會回收,可是任務過多,會一直建立,消耗資源
    4. newScheduledThreadPool 建立一個大小無線的線程池,此線程池支持定時以及週期性任務的需求.
      45.線程池都有哪些狀態?
    5. RUNNING:一旦被建立,就處於此狀態,能夠接受新任務以及對已經添加的任務進行處理.
    6. SHUTDOWN:此時不接收新任務,可是能夠處理已添加的任務
    7. STOP:此狀態不接收新任務,不處理已添加任務,而且會中斷正在處理的任務.
    8. TIDYING:當全部的任務已終止,ctl記錄的任務數變爲0,線程池會變成tidying狀態.當線程池變爲TIDYING狀態會執行terminated()方法.
      當線程池在SHUTDOWN狀態下,阻塞隊列爲空而且線程池中執行的任務也爲空時,就會由 SHUTDOWN -> TIDYING。
      當線程池在STOP狀態下,線程池中執行的任務爲空時,就會由STOP -> TIDYING。
    9. TERMINATED:線程池完全終止會變成這個狀態.當在TIDYING狀態,執行完terminated()函數後,就會由TIDYING狀態變爲TERMINATED狀態.
  10. 線程池中 submit()和 execute()方法有什麼區別?

    1. 接受參數不同,execute()方法接收Runnable類型的參數;submit()能夠接收runnable和callable類型的參數
    2. submit方法有返回值,返回一個Future類型的對象,execute方法沒有返回值.
    3. submit方法方便處理Exception異常.
  11. 在 java 程序中怎麼保證多線程的運行安全?

    1. 最簡單的方式是加入synchronized關鍵字,在共享數據語句中加入該關鍵字能夠在某一時段指揮讓一個線程執行,其餘線程不能執行.
    2. 使用鎖Lock
    3. redis?
  12. 多線程鎖的升級原理是什麼?
    在java中,鎖有三種狀態,級別從低到高依次爲:偏向鎖、輕量級鎖、重量級鎖,這幾個狀態會隨着競爭狀況逐漸升級,可是不能降級.
    先說爲何要有鎖升級:由於synchronized是重量級鎖,每次在進行鎖請求時,若是當前資源被其餘線程佔有,就要將當前線程阻塞,加入到阻塞隊列中而後
    清空當前線程的緩存,等到鎖釋放時再經過notify或者notifyAll方法喚醒當前線程,讓其處於就緒狀態.在這個過程當中是很是消耗資源的,並且有時候線程剛掛起,鎖就釋放了.
    而java的線程是映射到操做系統的原生線程之上的,每次線程的阻塞和喚醒都要在用戶態和核心態之間轉換,十分浪費資源.因此jvm對syncronized進行了優化,分爲三種鎖.

    1. 當鎖對象第一次被線程獲取的時候,虛擬機會將對象頭中的鎖標誌位設置成01,並將偏向鎖標誌設置爲1,線程經過CAS的方式將本身的ID值放到對象頭中.這樣每次該線程每次
      再進入鎖對象的時候不用任何的同步操做,直接比較當前鎖對象頭中是否是該線程的ID,若是是就能夠直接進入.當有其餘線程來嘗試獲取鎖的時候,發現偏向鎖標示是1,說明
      鎖已經被佔用,則會使用CAS將對象頭的偏向鎖指向當前線程.
      須要注意的是,偏向鎖使用一種等待競爭出現纔會釋放鎖的機制,當有其餘線程嘗試獲取鎖的時候,纔會釋放鎖.首先它會暫停擁有偏向鎖的線程,而後檢查持有偏向鎖的線程
      是否活着,若是不處於活動狀態,則將對象頭設置爲無鎖狀態;若是活着,那麼擁有偏向鎖的棧會被執行,遍歷偏向對象的鎖記錄,使之要麼恢復到無鎖要麼標記對象不適合做爲
      偏向鎖.最後喚醒暫停的線程.
    2. 假設線程1持有偏向鎖,線程2來競爭偏向鎖:
      一. 首先線程2會檢查偏向鎖標記,若是是1,說明是偏向鎖,那麼JVM會找到線程1看其是否還活着.
      二. 若是線程1已經執行完畢,那麼先將偏向鎖置爲0,對象頭設置爲無鎖的狀態,用CAS的方式嘗試將線程2的ID放入對象頭,此時鎖不升級,仍是偏向鎖.
      三. 若是線程1還活着,先暫停線程1,將鎖標誌位變爲00(輕量級鎖),而後在線程1的棧幀中開闢出一塊空間將對象頭的Mark word置換到線程1的棧幀中,而對象頭
      中存儲的是指向當前線程棧幀的指針.此時變爲輕量級鎖,線程1繼續執行,線程2採用CAS的方式嘗試獲取鎖.
    3. 輕量級鎖是經過CAS的方式嘗試獲取鎖對象,一旦失敗會先檢查對象頭中存儲的是不是指向當前線程棧幀的指針,若是是,就能夠獲取鎖對象,若是不是說明存在競爭那麼久
      膨脹成爲重量級鎖.
    4. 一旦有兩個以上的線程競爭鎖,輕量級鎖就會膨脹爲重量級鎖,鎖的狀態變爲10,此時對象頭中存儲的就是指向重量級鎖的棧幀的指針,並且其餘等待所的線程要進入阻塞狀態,
      等待重量級鎖釋放後被喚醒而後去競爭.重量級鎖是由操做系統來負責線程的調度,會消耗大量的系統資源.
  13. 什麼是死鎖?
    死鎖是指兩個或兩個以上的進程或線程在執行過程當中,因爭奪資源而形成的一種相互等待的過程,若是沒有外力做用,他們講沒法推動下去.

  14. 怎麼防止死鎖?

    1. 以肯定的順序獲取鎖
    2. 超時放棄.(Lock鎖中就使用了這種方式)
    3. 銀行家算法
  15. ThreadLocal 是什麼?有哪些使用場景?
    也成爲線程本地變量,ThreadLocal在每一個線程中對一個變量建立了一個副本,且在線程內部任何地方均可以使用,線程間互不影響.
    應用場景:spring的聲明式事物管理.

  16. 說一下 synchronized 底層實現原理?
    首先,每一個對象都有一個監視器鎖(monitor),當monitor被佔用時就會處於鎖定狀態,線程執行monitorenter指令時嘗試獲取monitor的全部權,過程以下:

    1. 若是monitor的進入數爲0,則線程進入monitor,將進入數設置爲1,該線程爲monitor的全部者
    2. 若是線程已經佔有monitor,只是從新進入,則進入數+1
    3. 若是其餘線程已經佔用了monitor,則該線程進入阻塞狀態,直到monitor的進入數爲0,再從新嘗試得到全部權
      執行monitorexit的線程必須是objectref所對應的monitor的全部者.指令執行時,monitor的進入數-1,若是減爲0,那麼線程退出monitor,再也不是持有者.
      在將synchronized代碼塊反編譯之後,咱們能夠發現調用了monitorenter和monitorexit指令.
      因此若是synchronized同步代碼塊,底層是調用monitor的兩個指令來實現鎖
      若是synchronized同步方法,底層是讀取運行時常量池的ACC_SYNCHRONIZED標誌來實現的.
  17. synchronized 和 volatile 的區別是什麼?

    1. volatile修飾的變量,jvm每次都從主內run讀取,不會從工做內存讀取
      而synchronized是鎖住當前變量,同一時刻只有一個線程能訪問當前變量.
    2. volatile只是做用於變量,synchronized能夠用在變量,方法中
    3. valatile僅能實現變量修改的可見性,沒法保證原子性.
      synchronized能夠實現變量修改的可見性和原子性.
  18. synchronized 和 Lock 有什麼區別?

    1. synchronized是java內置的關鍵字,Lock是個接口
    2. synchronized沒法判斷是否獲取鎖的狀態,Lock能夠判斷是否獲取到鎖.
    3. synchronized會自動釋放鎖,Lock須要手動釋放
    4. synchronized可重入(同一個類中兩個同步方法,獲取到鎖後不用每次都去獲取),不可中斷,非公平;Lock可判斷可公平.
    5. synchronized得到鎖的線程阻塞,其餘線程都會無線等待,Lock不會
  19. synchronized 和 ReentrantLock 區別是什麼?

    1. synchronized遇到異常不catch,鎖會自動釋放,ReentrantLock須要手動釋放
    2. synchronized是非公平鎖,ReentrantLock能夠實現公平鎖.
    3. 前者沒法獲取鎖的狀態,後者能夠tryLock()方法能夠返回是否得到了鎖.
  20. 說一下 atomic 的原理?
    atomic包用中的類能夠實現多線程環境下的變量操做,底層是調用CPU的CAS指令來進實現線程安全的.
    CAS,比較並操做,每次在set前,對比一下當前值和預期值是否同樣,同樣則set,不然認爲失敗,循環對比直到成功.

反射

  1. 什麼是反射?
    在運行過程當中,對任何一個類,都能知道這個類的全部屬性和方法,對於任意一個對象,都能改變其屬性.
  2. 什麼是 java 序列化?什麼狀況下須要序列化?
    序列化就是一種用來處理對象流的機制,簡單來講,就是把對象存儲在某一個地方,硬盤或者網絡,即把對象的內容轉變爲字節序列.
    當想把內存中的對象狀態保存在一個文件或者數據庫,或者在網絡上傳輸的時候,就須要序列化,在java中須要實現Serializable接口.
  3. 動態代理是什麼?有哪些應用?
    動態代理是將對象中不一樣方法的調用從新定向到一個統一處理函數,作自定義的邏輯處理,可是調用者察覺不到.
    應用: Spring的AOP,事物,權限,日誌.RPC框架
  4. 怎麼實現動態代理?
    1. 利用JDK的反射機制實現
    2. 使用CGLIB代理.

對象拷貝

  1. 爲何要使用克隆?
    想要對一個對象進行處理,可是又想保留原有的數據,這時可使用克隆.
  2. 如何實現對象克隆?
    1. 實現Cloneable接口並重寫Object的clone()方法
    2. 實現Serializable接口,經過對象的序列化和反序列化實現深度克隆
  3. 深拷貝和淺拷貝區別是什麼?
    是否支持引用數據類型的成員變量的複製.

Java Web

  1. jsp 和 servlet 有什麼區別?
    1. jsp擅長表現頁面顯示,servlet擅長邏輯控制
    2. servlet沒有內置對象,jsp有內置對象
    3. servlet的應用邏輯在.java文件中,而jsp中,java和html組合爲一個.jsp文件.
    4. servlet在java代碼中嵌入html代碼,jsp是在html中嵌入java代碼
  2. jsp 有哪些內置對象?做用分別是什麼?
    jsp有9個內置對象:
    request 用戶端請求,此請求會包含來自GET/POST請求的參數
    response 網頁傳回用戶端的迴應
    pageContext 網頁的屬性是在這裏管理
    session 與請求有關的會話期
    application servlet正在執行的內容
    out 用來傳送回應的輸出
    config servlet的構架部件
    page JSP網頁自己
    exception 針對錯誤網頁,未捕捉的例外
  3. 說一下 jsp 的 4 種做用域?
    application:它的有效範圍是整個應用。整個應用是指從應用啓動.pplication裏的變量能夠被全部用戶共用。若是用戶甲的操做修改了application中的變量,用戶乙訪 問時獲得的是修改後的值。
    session:若是把變量放到session裏,就說明它的做用域是session,它的有效範圍是當前會話。所謂當前會話,就是指從用戶打開瀏覽器開始,到用戶關閉瀏覽器這中間 的過程。這個過程可能包含多個請求響應。也就是說,只要用戶不關瀏覽器,服務器就有辦法知道這些請求是一我的發起的,整個過程被稱爲一個會話(session)
    request:就說明它的做用域是request,它的有效範圍是當前請求週期。所謂請求週期,就是指從http請求發起,到服務器處理結束,返回響應的整個過程。在這個過 程中可能使用forward的方式跳轉了多個jsp頁面,在這些頁面裏你均可以使用這個變量。
    page:表明變量只能在當前頁面有效
  4. session 和 cookie 有什麼區別?
    1. 數據存放位置不一樣.session在服務器,cookie在客戶端瀏覽器
    2. 安全程度不一樣,別人能夠分析存放在本地的cookie進行cookie欺騙.
    3. 單個cookie保存的數據不能超過4k,而session是在服務器的,因此沒有限制
    4. cookie只能存儲string類型的數據,session能夠存儲對象.
  5. 說一下 session 的工做原理?
    當用戶第一次訪問一個服務器,服務器就會爲該用戶建立一個session,並生成一個和該session有關的session_id,
    這個id是惟一的,不可重複.這個id將會在本次響應中返回,保存在客戶端的cookie中,下次方法的時候,客戶端瀏覽器
    的cookie中含有session_id,服務器基於這個id就能夠識別該用戶.
  6. 若是客戶端禁止 cookie 能實現 session 還能用嗎?
    能夠,當cookie被禁用,咱們可使用"URL重寫"來使session生效,簡單來講就是將sessionid的信息做爲請求地址的一部分
    這樣服務器就能夠解析URL,獲得該sessionid,進而識別用戶.
  7. spring mvc 和 struts 的區別是什麼?
    1. mvc的入口是一個servlet,struts2的入口是一個filter
    2. mvc是單例的,struts2是多例的
    3. mvc面向方法開發,struts2面向類開發.
    4. struts2採用值棧存儲請求和響應數據,mvc經過參數解析器將request請求解析.
  8. 如何避免 sql 注入?
    1. 採用預編譯語句
    2. 使用正則過濾傳入的參數.
    3. 屏蔽不安全的字符
  9. 什麼是 XSS 攻擊,如何避免?
    XSS攻擊,即跨站腳本攻擊.是指攻擊者在用戶端注入惡意的可運行腳本,讓其在用戶瀏覽網頁時運行,從而經過腳原本得到用戶的信息.
    避免: 對用戶輸入和URL參數進行過濾,過濾掉腳本相關的內容
    對輸出進行編碼
  10. 什麼是 CSRF 攻擊,如何避免?
    CSRF攻擊也叫跨站請求僞造,攻擊者經過僞造用戶的瀏覽器請求,向用戶本身曾經認證過的網站發送,使目標網站誤覺得
    是用戶的真實操做而去執行命令.
    避免:1.令牌機制 2.token驗證

異常

  1. throw 和 throws 的區別?
    throws:用來聲明一個方法可能拋出的全部異常信息,不會處理異常,只是將異常向上傳,交給調用者
    throw:拋出一個具體的異常類型.
    throws出如今方法聲頭,而throw出如今函數體
    throws表示出現異常的可能,並不必定會發生,throw則是拋出了一個存在的異常實例.

  2. final、finally、finalize 有什麼區別?
    final: 修飾類,表示該類不可繼承
    修飾方法,表示該方法不可重寫
    修飾變量,表示該變量不容許被修改
    finally:是保證代碼必定要被執行的一種機制.經常使用來關閉鏈接資源或者解鎖等.
    finalize:是Object的一個方法,它的目的是保證對象在被垃圾收集前完成特定資源的回收.1.9後已通過時.

  3. try-catch-finally 中哪一個部分能夠省略?
    catch能夠省略
    無論有沒有捕獲到異常,finally中的代碼都會被執行;
    finally是在return以後執行的,程序在執行完return以後,會將值保存起來,當執行完finally中的代碼以後再將return值返回
    若是finally中存在return,會致使最後返回的是finally中的值.

  4. try-catch-finally 中,若是 catch 中 return 了,finally 還會執行嗎?
    會執行,return的值會暫時保存.等到運行完finally中的代碼塊時纔會返回return的值

  5. 常見的異常類有哪些?
    空指針異常類型:NullPointerException
    類型強制轉換類型:ClassCastException
    數組下標越界異常:ArrayIndexOutOfBoundsException
    輸入輸出異常:IOException

網絡

  1. http 響應碼 301 和 302 表明的是什麼?有什麼區別?
    301和302都是HTTP請求的狀態碼,其中301表明永久性轉移,302表明暫時性轉移.
    301表明轉向前的網址不在了,就會把新的網址當作有效目標
    302只是表明臨時性重定向,舊的網址會保留.
  2. forward 和 redirect 的區別?
    forward:直接轉發,客戶端瀏覽器只發出一次請求,由第二個信息資源響應該請求,共享同一個request對象
    redirect:間接轉發,服務端響應第一次請求的時候,讓瀏覽器去訪問另一個URL,從而達到轉發的目的.本質上是兩次HTTP請求.
    forward地址欄不變,redirect地址欄改變
  3. 簡述 tcp 和 udp的區別?
    tcp基於鏈接,udp基於無鏈接
    tcp對系統資源要求高,udp少
    tcp基於字節流,udp基於數據報文
    tcp複雜,udp簡單
  4. tcp 爲何要三次握手,兩次不行嗎?爲何?
    1. 爲了實現可靠數據傳輸,TCP 協議的通訊雙方,都必須維護一個序列號以標識發送出去的數據包中哪些是已經被對方收到的。
      三次握手的過程便是通訊雙方相互告知序列號起始值,並確認對方已經收到了序列號起始值的必經步驟
    2. 若是隻是兩次握手,至多隻有鏈接發起方的起始序列號能被確認,另外一方選擇的序列號則得不到確認
  5. 說一下 tcp 粘包是怎麼產生的?
    TCP粘包是指發送方發送的若干包數據到接收方接收時粘成一包,從接收緩衝區看,後一包數據的頭緊接着前一包數據的尾。
    產生緣由:
    1. 發送方緣由:TCP默認會使用Nagle算法。而Nagle算法主要作兩件事:1)只有上一個分組獲得確認,纔會發送下一個分組;2)收集多個小分組,
      在一個確認到來時一塊兒發送。
    2. 接收方緣由:TCP接收到分組時,並不會馬上送至應用層處理,或者說,應用層並不必定會當即處理;實際上,TCP將收到的分組保存至接收緩存裏,
      而後應用程序主動從緩存裏讀收到的分組。這樣一來,若是TCP接收分組的速度大於應用程序讀分組的速度,多個包就會被存至緩存,
      應用程序讀時,就會讀到多個首尾相接粘到一塊兒的包
  6. OSI 的七層模型都有哪些?
    1:物理層 2:數據鏈層 3:網絡層 4:傳輸層 5:會話層 6:表示層 7:應用層
  7. get 和 post 請求有哪些區別?
    1.get產生一個TCP數據包,POST產生兩個
    2.get將數據放在url中能夠看到,post會放在html header中提交
    3.get數據大小有限制,最大1024字節,post沒有限制
  8. 如何實現跨域?
    1.JSONP技術
    2.CORS規範
    3.經過服務端實現
    4.websocket
  9. 說一下 JSONP 實現原理?
    JSONP原理是動態添加一個

設計模式

  1. 說一下你熟悉的設計模式?
    單例模式,裝飾者模式,代理模式,適配器模式,策略模式
  2. 簡單工廠和抽象工廠有什麼區別?
    簡單工廠只能生產同一等級結構中的任一產品
    抽象工廠用來生產不一樣產品族中的所有產品

Spring/Spring MVC

  1. 爲何要使用 spring?
    1. 方便解耦,能夠將對象間的依賴關係交給spring
    2. spring支持aop編程,能夠很方便的對程序進行監控,攔截
    3. 方便測試,支持junit
    4. 集成其餘框架比較方便
    5. 聲明式事務
  2. 解釋一下什麼是 aop?
    aop即面向切面編程,在原有功能的基礎上經過aop添加新的功能,而原有的功能並不知道新添加的功能.
    簡單來講,就是在某個類或者方法執行先後打個標記,聲明在執行到這裏以前要先執行什麼,以後執行什麼,插入了新的執行方法.
  3. 解釋一下什麼是 ioc?
    ioc控制反轉.即把建立對象和維護對象之間關係的權利交給spring容器去作,程序本身再也不維護.
    傳統:本身使用new 或者getInstance直接或者間接建立一個對象(高耦合,不易測試)
    spring:容器使用工廠模式爲了建立了所須要的對象,咱們不用本身建立,直接調用便可.
  4. spring 有哪些主要模塊?
    1. spring core: core是spring的核心類庫,它的全部功能都依賴於該類庫,主要實現IOC功能.
    2. AOP: spring aop提供了經常使用的攔截器供用戶配置.
    3. ORM: 該模塊提供對經常使用的ORM框架的管理和輔助支持.spring本身不實現ORM,只是對常見的ORM進行封裝管理
    4. DAO: spring提供對jdbc的支持,統一管理jdbc事物,並不對其進行實現
    5. WEB: 提供對經常使用框架,如struts2的支持,將spring的資源注入給這些框架,也能在這些框架的先後插入攔截器
    6. Context: 提供框架式的bean訪問方式,其餘程序能夠經過Context訪問spring的bean資源
    7. MVC: 提供一套輕量級的MVC實現,簡單方便.
  5. spring 經常使用的注入方式有哪些?
    1. 構造器注入:能夠在xml中經過constructor-arg標籤來注入一個對象到構造器中
    2. setter方法注入: 首先要配置被注入的bean,在該bean對應的類中,應該有要注入的對象屬性或者基本數據類型的屬性。
      例如:爲UserBiz類注入UserDAO,同時爲UserBiz注入基本數據類型String,那麼這時,
      就要爲UserDAO對象和String類型設置setter方法.,用於進行依賴注入。
    3. 註解注入:基於註解在xml文件中開啓註解掃描之後,就能夠在filed上使用註解@Autowired或者@Rsource來注入對象.
  6. spring 中的 bean 是線程安全的嗎?
    不是的,spring並無對單例bean作多線程的封裝.
  7. spring 支持幾種 bean 的做用域?
    1.singleton: 單例,默認做用域,在spring容器中此種類型的bean只有一個
    2.prototype: 原型,每次調用getBean方法就會產生一個新的實例.
    3.request: 每次HTTP請求都會產生不一樣的bean實例.
    4.session: 每次會話產生一個實例
    5.global-session: 全部會話共享一個實例
  8. spring 自動裝配 bean 有哪些方式?
    1.xml配置方式
    2.註解掃描方式
  9. spring 事務實現方式有哪些?
    1.編程式事務 容許用戶在代碼中精肯定義事務的邊界
    2.聲明式事務 基於AOP,將操做和事務管理分離.
  10. 說一下 spring 的事務隔離?
    隔離級別定義了一個事務可能受其餘併發事務影響的程度。
    spring設置了五種事務個例級別:
    1.ISOLATION_DEFAULT: 使用數據庫默認的隔離級別
    2.ISOLATION_READ_UNCOMMITTED: 最低的隔離級別,容許讀未提交的數據變動,可能會致使髒讀,幻讀或不可重複讀.
    3.ISOLATION_READ_COMMITTED: 容許讀取已經提交的數據,能夠阻止髒讀,可是幻讀和不可重複讀有可能發生.
    4.ISOLATION_REPEATABLE_READ: 保證了一個事務不能讀取另外一個未提交的數據.能夠避免不可重複讀和髒讀
    5.ISOLATION_SERIALIZABLE: 串行化,事務被處理爲順序執行,經過鎖定事務相關的數據庫來實現.
  11. 說一下 spring mvc 運行流程?
    1.用戶向服務器發送請求,被springMVC的前端控制器攔截(DispatcherServlet)
    2.前端控制器對請求的URL進行解析,獲得標識符URI,根據URI調用處理器映射器
    3.處理器映射器與該Handler有關的對象和攔截器信息返回給DispatcherServlet
    4.前端控制器根據得到的處理器信息,調用對應的處理器適配器HandlerAdapter處理數據
    5.處理器適配器提取request中的模型數據,開始執行Handler,在此以前還能夠作數據合適的轉換和數據驗證等.
    處理完成後向DispatcherServlet返回一個ModelAndView對象
    6.前端控制器根據ModelAndView選擇合適的視圖解析器ViewResolver處理數據
    7.視圖解析器根據model和view渲染視圖,將結果返回給客戶端
  12. spring mvc 有哪些組件?
  13. DispatcherServlet 前端控制器
  14. HandlerMapping 請求派發,創建請求和處理器的映射
  15. Controller 處理器
  16. ModelAndView 封裝模型和試圖信息
  17. ViewResolver 視圖處理器,定位頁面
  18. @RequestMapping 的做用是什麼?
    映射請求,指定哪些URL能夠被該處理器處理.
  19. @Autowired 的做用是什麼?
    根絕類型從容器中取出對象進行注入

Spring Boot/Spring Cloud

  1. 什麼是 spring boot?
    能夠認爲是一個服務於框架的框架,簡化了配置文件.整合了全部的框架
  2. 爲何要用 spring boot?
    開發速度快
    測試簡單
    配置簡單
    部署簡單
    能夠基於springboot來構建springcloud生態
  3. spring boot 核心配置文件是什麼?
    application和bootstrap,application配置文件主要用於SpringBoot項目的自動化配置.
    bootstrap配置文件在使用spring cloud配置時使用
  4. spring boot 配置文件有哪幾種類型?它們有什麼區別?
    兩種:properties和yml.區別是格式不一樣
  5. spring boot 有哪些方式能夠實現熱部署?
    兩種方式:1: Spring Loaded
    2: Spring-boot-devtools
  6. jpa 和 hibernate 有什麼區別?
    jpa是一種規範,提供了一些列操做數據庫的接口,本事不能直接使用
    hibernate是jpa的一種實現,是能夠直接使用操做數據庫的ORM框架
  7. 什麼是 spring cloud?
    springcloud是一個微服務框架,提供全套的分佈式系統解決方案,它爲微服務架構開發提供配置管理、服務治理、熔斷機制、智能路由
    控制總線等一系列的管理操做.
  8. spring cloud 斷路器的做用是什麼?
    在微服務架構中,存在不少的微服務,彼此之間存在依賴關係,當某個單元出現故障時,就會由於依賴關係致使整個系統的癱瘓.
    斷路器的做用是當某個微服務發生故障時,經過斷路器的故障監控,向調用方返回一個錯誤響應,使之不至於長時間等待,避免了故障在分佈式系統中的蔓延
  9. spring cloud 的核心組件有哪些?
    服務發現: Netflix Eureka
    客戶端負載均衡: Netflix Ribbon
    斷路器: Netflix Hystrix
    服務網關: Netflix Zuul
    分佈式配置: Spring cloud Config

Hibernate

  1. 爲何要使用 hibernate?
    1.對JDBC訪問數據庫的代碼作了大量的封裝,簡化開發
    2.性能好,支持各類關係數據庫.

  2. 什麼是 ORM 框架?
    ORM的意思是對象關係映射,它的做用是在關係型數據庫和業務實體對象之間作映射
    這樣咱們在操做具體業務對象的時候,就不須要去和具體的SQL語句打交道,只須要操做對象的屬性和方法.

  3. hibernate 中如何在控制檯查看打印的 sql 語句?
    在hibernate配置文件中配置hibernate.show_sql屬性

  4. hibernate 有幾種查詢方式?
    三種:HQL查詢 QBC查詢(也叫Criteria查詢) 本地SQL查詢

  5. hibernate 實體類能夠被定義爲 final 嗎?
    不能,由於hibernate使用代理方式在延遲加載的狀況下提升性能,若是定義爲final
    就不能繼承,也就沒法實現代理.

  6. 在 hibernate 中使用 Integer 和 int 作映射有什麼區別?
    1.若是數據庫返回字段值是null的話,int類型會報錯,Integer則不會

  7. hibernate 是如何工做的?

  8. 經過Configuration config = new Configuration().configure();解析配置文件

  9. 由hibernate.cfg.xml中的讀取並解析映射信息

  10. 經過SessionFactory sf = config.buildSessionFactory();//建立SessionFactory

  11. Session session = sf.openSession();//打開Sesssion

  12. Transaction tx = session.beginTransaction();//建立並啓動事務Transation

  13. persistent operate操做數據,持久化操做

  14. tx.commit();//提交事務

  15. 關閉session和sessionFactory

  16. get()和 load()的區別?

  17. get方式會直接觸發sql語句查出對象,load方式會使用延遲加載的機制加載這個對象,此時是個代理對象
    只保存實體對象的id值,只有用到其餘屬性的時候纔會調用sql查出來.

  18. 若是對象不存在,get方式會拋出空指針異常,load方式會拋出ObjectNotFoundException

  19. 說一下 hibernate 的緩存機制?
    hibernate爲了下降對數據庫訪問的頻率,加入了緩存機制.緩存內的數據是對物理數據庫數據的複製,
    應用程序在運行時,從緩存中讀寫數據.
    Hibernate的緩存包括兩大類:session一級緩存和sessionFactory二級緩存.一級緩存不可卸載.
    當根據ID查詢數據的時候,首先從session緩存中查,查不到,若是設置了二級緩存,那麼從二級緩存中查,
    若是都查不到,再查數據庫.將查到的數據按照ID放入緩存中,在刪除,更新,增長數據的時候更新緩存.

  20. hibernate 對象有哪些狀態?
    Hibernate對象有三種狀態

  21. Transient 瞬時態, 此時對象剛new出來,尚未save()

  22. Persistent 持久態, 調用了save方法或者遊離態的對象調用了update方法後會變成持久態
    若是對象是持久化對象時,那麼對該對象的任何修改,都會在提交事務時纔會與之進行比較

  23. 當調用了session.clear()方法,之後 對象就會變成遊離態

  24. 在 hibernate 中 getCurrentSession 和 openSession 的區別是什麼?

  25. 採用getCurrentSession()得到的session會綁定到當前線程,而openSession則不會

  26. getCurrentSession()得到的session在commit或者rollback後會自動關閉,而openSession必須手動關閉

  27. hibernate 實體類必需要有無參構造函數嗎?爲何?
    必需要有,覺得hibernate是經過反射的方式來得到對象實例的,此時會調用默認的無參構造.

Mybatis

  1. mybatis 中 #{}和 ${}的區別是什麼?

  2. 前者會將傳入的數據當成字符串,在以前加入雙引號,後者是直接將數據顯示在sql中

  3. 前者會當作佔位符,防sql注入,後者不能

  4. mybatis 有幾種分頁方式?
    兩種,一種是內存分頁,一種是物理分頁
    內存分頁: 一次性查詢出全部知足條件的數據,臨時保存在集合中,經過List的subList的方式獲取分頁數據.
    物理分頁: 藉助sql進行分頁或者利用攔截器分頁

  5. RowBounds 是一次性查詢所有結果嗎?爲何?
    不是,由於mybatis是對JDBC的封裝,在JDBC的驅動中有一個Fetch Size的配置,它規定了每次最多從數據庫查詢多少條數據.這樣作能夠防止內存溢出.

  6. mybatis 邏輯分頁和物理分頁的區別是什麼?

  7. 邏輯分頁一次性查詢不少數據,而後再結果中檢索分頁的數據,消耗內存.

  8. 物理分頁是從數據庫查詢指定條數的數據.

  9. mybatis 是否支持延遲加載?延遲加載的原理是什麼?
    支持,在配置文件的標籤中設置就能夠激活
    原理: 在調用的時候出發加載,而不是在初始化的時候加載信息.如a.getB().getName(),若是a.getB()的值爲null,會觸發保存好的關聯B對象的sql語句查詢出B,而後再調用getName().

  10. 說一下 mybatis 的一級緩存和二級緩存?

  11. 一級緩存是SqlSession級別的,在一個sqlsession中,第一次查詢緩存中是否有數據,沒有就會查詢數據庫,並將數據保存在一級緩存中.第二次去查的時候會直接從緩存中查詢.若是這中間sqlsession進行了commit操做則會清空緩存.

  12. 二級緩存是Mapper級別的,多個sqlsession共享,默認關閉.它基於Mapper文件的namespace,若是兩個mapper的namespace相同,那麼會共享緩存的數據.使用二級緩存要在配置文件中開啓,而且序列化po類.

  13. mybatis 和 hibernate 的區別有哪些?

  14. mybatis靈活,能夠寫sql,hibernate學習困難

  15. mybatis 有哪些執行器(Executor)?

  16. SimpleExecutor:每執行一次 update 或 select 就開啓一個 Statement 對象,用完馬上關閉 Statement 對象

  17. ReuseExecutor:執行update或select以SQL做爲key查找Statement對象,存在就使用,不存在就建立,用完後不關閉,能夠重複使用

  18. BatchExecutor:執行update(沒有select,jdbc批處理不支持select)時,將全部SQL都添加到批處理中(addBatch()),等待統一執行(executeBatch()),它緩存了多個Statement對象.

  19. mybatis 分頁插件的實現原理是什麼?
    分頁插件的基本原理是使用 MyBatis 提供的插件接口,實現自定義插件,在插件的攔截方法內攔截待執行的SQL,而後重寫SQL,根據dialect方言,添加對應的物理分頁語句和參數

  20. mybatis 如何編寫一個自定義插件?
    只需實現Interceptor接口,並指定要攔截的方法簽名
    @Intercepts({
    @Signature(
    type=Executor.class,method=「update」,args={ MappedStatement.class,Object.class })})
    public class ExamplePlugin implements Interceptor {
    public Object intercept(Invocation invocation) throws Throwable {
    //自定義實現
    return invocation.proceed();
    }
    public Object plugin(Object target){
    return Plugin.wrap(target,this)
    }
    public void setProperties(Properties properties){
    //傳入配置項
    String size = properties.getProperty(「size」);
    }
    }

<!-- mybatis-config.xml -->
<plugins>
    <plugin interceptor="org.mybatis.example.ExamplePlugin">
        <!-- 這裏的配置項就傳入setProperties方法中 -->
        <property name="size" value="100">
    </plugin>
</plugins>
1234567複製代碼

RabbitMQ

  1. rabbitmq 的使用場景有哪些?
  2. 搶購活動,削峯填谷,防止系統崩塌。
  3. 延遲信息處理,好比 10 分鐘以後給下單未付款的用戶發送郵件提醒。
  4. 解耦系統
  5. rabbitmq 有哪些重要的角色?
    生產者: 消息的建立者,負責建立和推送數據到消息服務器
    消費者: 消息的接收方,用於處理數據.
    代理: MQ自己.
  6. rabbitmq 有哪些重要的組件?
    ConnectionFactory(鏈接管理器):應用程序與Rabbit之間創建鏈接的管理器,程序代碼中使用。
    Channel(信道):消息推送使用的通道.
    Exchange(交換器):用於接受、分配消息.
    Queue(隊列):用於存儲生產者的消息.
    RoutingKey(路由鍵):用於把生成者的數據分配到交換器上.
    BindingKey(綁定鍵):用於把交換器的消息綁定到隊列上
  7. rabbitmq 中 vhost 的做用是什麼?
    每一個 RabbitMQ 都能建立不少 vhost,咱們稱之爲虛擬主機,每一個虛擬主機其實都是 mini 版的RabbitMQ,它擁有本身的隊列,交換器和綁定,擁有本身的權限機制。
  8. rabbitmq 的消息是怎麼發送的?
    首先客戶端必須鏈接到 RabbitMQ 服務器才能發佈和消費消息,客戶端和 rabbit server 之間會建立一個 tcp 鏈接,一旦 tcp 打開並經過了認證(認證就是你發送給 rabbit 服務器的用戶名和密碼),你的客戶端和 RabbitMQ 就建立了一條 amqp 信道(channel),信道是建立在「真實」 tcp 上的虛擬鏈接,amqp 命令都是經過信道發送出去的,每一個信道都會有一個惟一的 id,不管是發佈消息,訂閱隊列都是經過這個信道完成的。
  9. rabbitmq 怎麼保證消息的穩定性?
  10. 提供了事物功能
  11. 經過將 channel 設置爲 confirm(確認)模式。
    141.rabbitmq 怎麼避免消息丟失?
  12. 把消息持久化磁盤,保證服務器重啓消息不丟失。
  13. 每一個集羣中至少有一個物理磁盤,保證消息落入磁盤
  14. 要保證消息持久化成功的條件有哪些?
  15. 聲明隊列必須設置持久化 durable 設置爲 true.
  16. 消息推送投遞模式必須設置持久化,deliveryMode 設置爲 2(持久)。
  17. 消息已經到達持久化交換器。
  18. 消息已經到達持久化隊列。
    以上四個條件都知足才能保證消息持久化成功
  19. rabbitmq 持久化有什麼缺點?
    由於使用了磁盤來存儲而不是內存,因此下降了服務器的吞吐量.
  20. rabbitmq 有幾種廣播類型?
    direct(默認方式): 最基礎最簡單的模式,發送方把消息發送給訂閱方,若是有多個訂閱者,默認採起輪詢的方式進行消息發送。
    headers: 與 direct 相似,只是性能不好
    fanout(分發模式): 把消費分發給全部訂閱者
    topic: 匹配訂閱模式,使用正則匹配到消息隊列,能匹配到的都能接收到。
  21. rabbitmq 怎麼實現延遲消息隊列?
  22. 經過消息過時後進入死信交換器,再由交換器轉發到延遲消費隊列,實現延遲功能
  23. 使用 RabbitMQ-delayed-message-exchange 插件實現延遲功能。
  24. rabbitmq 集羣有什麼用?
    高可用:某個服務器出現問題,整個 RabbitMQ 還能夠繼續使用;
    高容量:集羣能夠承載更多的消息量。
  25. rabbitmq 節點的類型有哪些?
    磁盤節點:消息會存儲到磁盤
    內存節點:消息都存儲在內存中,重啓服務器消息丟失,性能高於磁盤類型
  26. rabbitmq 集羣搭建須要注意哪些問題?
  27. 各節點之間使用「–link」鏈接,此屬性不能忽略。
  28. 各節點使用的 erlang cookie 值必須相同,此值至關於「祕鑰」的功能,用於各節點的認證。
  29. 整個集羣中必須包含一個磁盤節點。
  30. rabbitmq 每一個節點是其餘節點的完整拷貝嗎?爲何?
    不是,緣由以下:
    存儲空間的考慮:若是每一個節點都擁有全部隊列的徹底拷貝,這樣新增節點不但沒有新增存儲空間,反而增長了更多的冗餘數據;
    性能的考慮:若是每條消息都須要完整拷貝到每個集羣節點,那新增節點並無提高處理消息的能力,最可能是保持和單節點相同的性能甚至是更糟。
  31. rabbitmq 集羣中惟一一個磁盤節點崩潰了會發生什麼狀況?
    惟一磁盤節點崩潰了,集羣是能夠保持運行的,但你不能更改任何東西。
    不能建立隊列
    不能建立交換器
    不能建立綁定
    不能添加用戶
    不能更改權限
    不能添加和刪除集羣節點
  32. rabbitmq 對集羣節點中止順序有要求嗎?
    有要求,應該先關閉內存節點,最後關閉磁盤節點,若是順序相反可能會形成消息丟失.
    十5、Kafka
  33. kafka 能夠脫離 zookeeper 單獨使用嗎?爲何?
    不能,由於zookeeper管理和協調kafka的節點服務器.
  34. kafka 有幾種數據保留的策略?
    兩種,一種是按照過時時間保留,一種是按照存儲消息的大小保留.
  35. kafka 同時設置了 7 天和 10G 清除數據,到第五天的時候消息達到了 10G,這個時候 kafka 將如何處理?
    會執行清除,時間和大小知足一個就會執行清除.
  36. 什麼狀況會致使 kafka 運行變慢?
    cpu 性能瓶頸
    磁盤讀寫瓶頸
    網絡瓶頸
  37. 使用 kafka 集羣須要注意什麼?
    集羣的數量不是越多越好,最好不要超過 7 個,由於節點越多,消息複製須要的時間就越長,整個羣組的吞吐量就越低。
    集羣數量最好是單數,由於超過一半故障集羣就不能用了,設置爲單數容錯率更高。

Zookeeper

  1. zookeeper 是什麼?
    zookeeper 是一個分佈式的,開放源碼的分佈式應用程序協調服務,是 hadoop 和 hbase 的重要組件,提供的功能包括:配置維護、域名服務、分佈式同步、組服務等。
  2. zookeeper 都有哪些功能?
    集羣管理:監控節點存活狀態、運行請求等
    主節點選舉:主節點掛掉了以後能夠從備用的節點開始新一輪選主,主節點選舉說的就是這個選舉的過程,使用 zookeeper 能夠協助完成這個過程。
    分佈式鎖:zookeeper 提供兩種鎖:獨佔鎖、共享鎖。獨佔鎖即一次只能有一個線程使用資源,共享鎖是讀鎖共享,讀寫互斥,便可以有多線線程同時讀同一個資源,若是要使用寫鎖也只能有一個線程使用。zookeeper能夠對分佈式鎖進行控制
  3. zookeeper 有幾種部署模式?
    三種:
    單機部署:一臺集羣上運行;
    集羣部署:多臺集羣運行;
    僞集羣部署:一臺集羣啓動多個 zookeeper 實例運行。
  4. zookeeper 怎麼保證主從節點的狀態同步?
    zookeeper 的核心是原子廣播,這個機制保證了各個 server 之間的同步。實現這個機制的協議叫作 zab 協議。zab 協議有兩種模式,分別是恢復模式(選主)和廣播模式(同步)。當服務啓動或者在領導者崩潰後,zab 就進入了恢復模式,當領導者被選舉出來,且大多數 server 完成了和 leader 的狀態同步之後,恢復模式就結束了。狀態同步保證了 leader 和 server 具備相同的系統狀態。
  5. 集羣中爲何要有主節點?
    在分佈式環境中,有些業務邏輯只須要集羣中的某一臺機器進行執行,其餘的機器能夠共享這個結果,這樣能夠大大減小重複計算,提升性能,因此就須要主節點。
  6. 集羣中有 3 臺服務器,其中一個節點宕機,這個時候 zookeeper 還可使用嗎?
    能夠繼續使用,單數服務器只要沒超過一半的服務器宕機就能夠繼續使用。
  7. 說一下 zookeeper 的通知機制?
    客戶端端會對某個 znode 創建一個 watcher 事件,當該 znode 發生變化時,這些客戶端會收到 zookeeper 的通知,而後客戶端能夠根據 znode 變化來作出業務上的改變。

MySql

  1. 數據庫的三範式是什麼?
    第一範式:強調的是列的原子性,即數據庫表的每一列都是不可分割的原子數據項。
    第二範式:要求實體的屬性徹底依賴於主關鍵字。所謂徹底依賴是指不能存在僅依賴主關鍵字一部分的屬性。
    第三範式:任何非主屬性不依賴於其它非主屬性
  2. 一張自增表裏面總共有 7 條數據,刪除了最後 2 條數據,重啓 mysql 數據庫,又插入了一條數據,此時 id 是幾?
    表類型若是是 MyISAM ,那 id 就是 8。
    表類型若是是 InnoDB,那 id 就是 6。
    InnoDB 表只會把自增主鍵的最大 id 記錄在內存中,因此重啓以後會致使最大 id 丟失。
  3. 如何獲取當前數據庫版本?
    使用 select version() 獲取當前 MySQL 數據庫版本。
  4. 說一下 ACID 是什麼?
    Atomicity(原子性) 一個事務(transaction)中的全部操做,或者所有完成,或者所有不完成,不會結束在中間某個環節。事務在執行過程當中發生錯誤,會被恢復(Rollback)到事務開始前的狀態,就像這個事務歷來沒有執行過同樣。即,事務不可分割、不可約簡。
    Consistency(一致性) 在事務開始以前和事務結束之後,數據庫的完整性沒有被破壞。這表示寫入的資料必須徹底符合全部的預設約束、觸發器、級聯回滾等。
    Isolation(隔離性) 數據庫容許多個併發事務同時對其數據進行讀寫和修改的能力,隔離性能夠防止多個事務併發執行時因爲交叉執行而致使數據的不一致。事務隔離分爲不一樣級別,包括讀未提交(Read uncommitted)、讀提交(read committed)、可重複讀(repeatable read)和串行化(Serializable)。
    Durability(持久性) 事務處理結束後,對數據的修改就是永久的,即使系統故障也不會丟失。
  5. char 和 varchar 的區別是什麼?
    char固定長度,好比char(10) 當輸入abc三個字符時,他們佔的空間仍是10個字節,其餘7個字節是空的.
    chat 優勢:效率高;缺點:佔用空間;適用場景:存儲密碼的 md5 值,固定長度的,使用 char 很是合適。
    varchar(n) :可變長度,存儲的值是每一個值佔用的字節再加上一個用來記錄其長度的字節的長度。
  6. float 和 double 的區別是什麼?
    float 最多能夠存儲 8 位的十進制數,並在內存中佔 4 字節。
    double 最可能夠存儲 16 位的十進制數,並在內存中佔 8 字節。
  7. mysql 的內鏈接、左鏈接、右鏈接有什麼區別?
  8. 關鍵字不同. 內鏈接關鍵字:inner join;左鏈接:left join;右鏈接:right join。
  9. 內鏈接是把匹配的關聯數據顯示出來;左鏈接是左邊的表所有顯示出來,右邊的表顯示出符合條件的數據;右鏈接正好相反。
  10. mysql 索引是怎麼實現的?
    索引是知足某種特定查找算法的數據結構,而這些數據結構會以某種方式指向數據,從而實現高效查找數據。
    具體來講 MySQL 中的索引,不一樣的數據引擎實現有所不一樣,但目前主流的數據庫引擎的索引都是 B+ 樹實現的,B+ 樹的搜索效率,能夠到達二分法的性能,找到數據區域以後就找到了完整的數據結構了,全部索引的性能也是更好的。
  11. 怎麼驗證 mysql 的索引是否知足需求?
    使用 explain 查看 SQL 是如何執行查詢語句的,從而分析你的索引是否知足需求。
    explain 語法:explain select * from table where type=1。
  12. 說一下數據庫的事務隔離?
    MySQL 的事務隔離是在 MySQL. ini 配置文件裏添加的,在文件的最後添加:
    transaction-isolation = REPEATABLE-READ
    可用的配置值:READ-UNCOMMITTED、READ-COMMITTED、REPEATABLE-READ、SERIALIZABLE。
  13. 說一下 mysql 經常使用的引擎?
    InnoDB 引擎:InnoDB 引擎提供了對數據庫 acid 事務的支持,而且還提供了行級鎖和外鍵的約束,它的設計的目標就是處理大數據容量的數據庫系統。MySQL 運行的時候,InnoDB 會在內存中創建緩衝池,用於緩衝數據和索引。可是該引擎是不支持全文搜索,同時啓動也比較的慢,它是不會保存表的行數的,因此當進行 select count(
    ) from table 指令的時候,須要進行掃描全表。因爲鎖的粒度小,寫操做是不會鎖定全表的,因此在併發度較高的場景下使用會提高效率的。
    MyIASM 引擎:MySQL 的默認引擎,但不提供事務的支持,也不支持行級鎖和外鍵。所以當執行插入和更新語句時,即執行寫操做的時候須要鎖定這個表,因此會致使效率會下降。不過和 InnoDB 不一樣的是,MyIASM 引擎是保存了表的行數,因而當進行 select count(
    ) from table 語句時,能夠直接的讀取已經保存的值而不須要進行掃描全表。因此,若是表的讀操做遠遠多於寫操做時,而且不須要事務的支持的,能夠將 MyIASM 做爲數據庫引擎的首選。
  14. 說一下 mysql 的行鎖和表鎖?
    表級鎖:開銷小,加鎖快,不會出現死鎖。鎖定粒度大,發生鎖衝突的機率最高,併發量最低
    行級鎖:開銷大,加鎖慢,會出現死鎖。鎖力度小,發生鎖衝突的機率小,併發度最高。
  15. 說一下樂觀鎖和悲觀鎖?
    樂觀鎖:每次去拿數據的時候都認爲別人不會修改,因此不會上鎖,可是在提交更新的時候會判斷一下在此期間別人有沒有去更新這個數據。
    悲觀鎖:每次去拿數據的時候都認爲別人會修改,因此每次在拿數據的時候都會上鎖,這樣別人想拿這個數據就會阻止,直到這個鎖被釋放。
    數據庫的樂觀鎖須要本身實現,在表裏面添加一個 version 字段,每次修改爲功值加 1,這樣每次修改的時候先對比一下,本身擁有的 version 和數據庫如今的 version 是否一致,若是不一致就不修改,這樣就實現了樂觀鎖。
  16. mysql 問題排查都有哪些手段?
    使用 show processlist 命令查看當前全部鏈接信息。
    使用 explain 命令查詢 SQL 語句執行計劃。
    開啓慢查詢日誌,查看慢查詢的 SQL。
  17. 如何作 mysql 的性能優化?
    爲搜索字段建立索引。
    避免使用 select *,列出須要查詢的字段。
    垂直分割分表。
    選擇正確的存儲引擎。
    十8、Redis
  18. redis 是什麼?都有哪些使用場景?
    Redis 是一個使用 C 語言開發的高速緩存數據庫。
    記錄帖子點贊數、點擊數、評論數;
    緩存近期熱帖;
    緩存文章詳情信息;
    記錄用戶會話信息。
  19. redis 有哪些功能?
    數據緩存功能
    分佈式鎖的功能
    支持數據持久化
    支持事務
    支持消息隊列
  20. redis 和 memecache 有什麼區別?
    存儲方式不一樣:memcache 把數據所有存在內存之中,斷電後會掛掉,數據不能超過內存大小;Redis 有部份存在硬盤上,這樣能保證數據的持久性。
    數據支持類型:memcache 對數據類型支持相對簡單;Redis 有複雜的數據類型
    value 值大小不一樣:Redis 最大能夠達到 1gb;memcache 只有 1mb。
  21. redis 爲何是單線程的?
    由於 cpu 不是 Redis 的瓶頸,Redis 的瓶頸最有多是機器內存或者網絡帶寬。既然單線程容易實現,並且 cpu 又不會成爲瓶頸,那就瓜熟蒂落地採用單線程的方案了。
  22. 什麼是緩存穿透?怎麼解決?
    緩存穿透:指查詢一個必定不存在的數據,因爲緩存是不命中時須要從數據庫查詢,查不到數據則不寫入緩存,這將致使這個不存在的數據每次請求都要到數據庫去查詢,形成緩存穿透。
    解決方案:最簡單粗暴的方法若是一個查詢返回的數據爲空(無論是數據不存在,仍是系統故障),咱們就把這個空結果進行緩存,但它的過時時間會很短,最長不超過五分鐘。
  23. redis 支持的數據類型有哪些?
    edis 支持的數據類型:string(字符串)、list(列表)、hash(字典)、set(集合)、zset(有序集合)。
  24. redis 支持的 java 客戶端都有哪些?
    支持的 Java 客戶端有 Redisson、jedis、lettuce 等。
  25. jedis 和 redisson 有哪些區別?
    jedis:提供了比較全面的 Redis 命令的支持。
    Redisson:實現了分佈式和可擴展的 Java 數據結構,與 jedis 相比 Redisson 的功能相對簡單,不支持排序、事務、管道、分區等 Redis 特性。
  26. 怎麼保證緩存和數據庫數據的一致性?
    合理設置緩存的過時時間
    新增、更改、刪除數據庫操做時同步更新 Redis,可使用事物機制來保證數據的一致性。
  27. redis 持久化有幾種方式?
    RDB(Redis Database):指定的時間間隔能對你的數據進行快照存儲。
    AOF(Append Only File):每個收到的寫命令都經過write函數追加到文件中。
    189.redis 怎麼實現分佈式鎖?
    Redis 分佈式鎖其實就是在系統裏面佔一個「坑」,其餘程序也要佔「坑」的時候,佔用成功了就能夠繼續執行,失敗了就只能放棄或稍後重試。
    通常使用 setnx(set if not exists)指令,只容許被一個程序佔有,使用完調用 del 釋放鎖。
  28. redis 分佈式鎖有什麼缺陷?
    Redis 分佈式鎖不能解決超時的問題,分佈式鎖有一個超時時間,程序的執行若是超出了鎖的超時時間就會出現問題。
  29. redis 如何作內存優化?
    儘可能使用 Redis 的散列表,把相關的信息放到散列表裏面存儲,而不是把每一個字段單獨存儲,這樣能夠有效的減小內存使用。好比將 Web 系統的用戶對象,應該放到散列表裏面再總體存儲到 Redis,而不是把用戶的姓名、年齡、密碼、郵箱等字段分別設置 key 進行存儲。
  30. redis 淘汰策略有哪些?
    volatile-lru:從已設置過時時間的數據集(server. db[i]. expires)中挑選最近最少使用的數據淘汰。
    volatile-ttl:從已設置過時時間的數據集(server. db[i]. expires)中挑選將要過時的數據淘汰。
    volatile-random:從已設置過時時間的數據集(server. db[i]. expires)中任意選擇數據淘汰。
    allkeys-lru:從數據集(server. db[i]. dict)中挑選最近最少使用的數據淘汰。
    allkeys-random:從數據集(server. db[i]. dict)中任意選擇數據淘汰。
    no-enviction(驅逐):禁止驅逐數據。
  31. redis 常見的性能問題有哪些?該如何解決?
    主服務器寫內存快照,會阻塞主線程的工做,當快照比較大時對性能影響是很是大的,會間斷性暫停服務,因此主服務器最好不要寫內存快照。
    Redis 主從複製的性能問題,爲了主從複製的速度和鏈接的穩定性,主從庫最好在同一個局域網內。

JVM

  1. 說一下 jvm 的主要組成部分?及其做用?
    類加載器(ClassLoader)
    運行時數據區(Runtime Data Area)
    執行引擎(Execution Engine)
    本地庫接口(Native Interface)
    首先經過類加載器(ClassLoader)會把 Java 代碼轉換成字節碼,運行時數據區(Runtime Data Area)再把字節碼加載到內存中,而字節碼文件只是 JVM 的一套指令集規範,並不能直接交個底層操做系統去執行,所以須要特定的命令解析器執行引擎(Execution Engine),將字節碼翻譯成底層系統指令,再交由 CPU 去執行,而這個過程當中須要調用其餘語言的本地庫接口(Native Interface)來實現整個程序的功能。
  2. 說一下 jvm 運行時數據區?
    不一樣虛擬機的運行時數據區可能略微有所不一樣,但都會聽從 Java 虛擬機規範, Java 虛擬機規範規定的區域分爲如下 5 個部分:
    程序計數器(Program Counter Register):當前線程所執行的字節碼的行號指示器,字節碼解析器的工做是經過改變這個計數器的值,來選取下一條須要執行的字節碼指令,分支、循環、跳轉、異常處理、線程恢復等基礎功能,都須要依賴這個計數器來完成
    Java 虛擬機棧(Java Virtual Machine Stacks):用於存儲局部變量表、操做數棧、動態連接、方法出口等信息;
    本地方法棧(Native Method Stack):與虛擬機棧的做用是同樣的,只不過虛擬機棧是服務 Java 方法的,而本地方法棧是爲虛擬機調用 Native 方法服務的
    Java 堆(Java Heap):Java 虛擬機中內存最大的一塊,是被全部線程共享的,幾乎全部的對象實例都在這裏分配內存;
    方法區(Methed Area):用於存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯後的代碼等數據。
  3. 說一下堆棧的區別?
    功能方面:堆是用來存放對象的,棧是用來執行程序的。
    共享性:堆是線程共享的,棧是線程私有的。
    空間大小:堆大小遠遠大於棧。
  4. 隊列和棧是什麼?有什麼區別?
    隊列和棧都是被用來預存儲數據的。
    隊列容許先進先出檢索元素,但也有例外的狀況,Deque 接口容許從兩端檢索元素。
    棧和隊列很類似,但它運行對元素進行後進先出進行檢索。
  5. 什麼是雙親委派模型?
    在介紹雙親委派模型以前先說下類加載器。對於任意一個類,都須要由加載它的類加載器和這個類自己一同確立在 JVM 中的惟一性,每個類加載器,都有一個獨立的類名稱空間。類加載器就是根據指定全限定名稱將 class 文件加載到 JVM 內存,而後再轉化爲 class 對象。
    啓動類加載器(Bootstrap ClassLoader),是虛擬機自身的一部分,用來加載Java_HOME/lib/目錄中的,或者被 -Xbootclasspath 參數所指定的路徑中而且被虛擬機識別的類庫;
    擴展類加載器(Extension ClassLoader):負責加載\lib\ext目錄或Java. ext. dirs系統變量指定的路徑中的全部類庫;
    應用程序類加載器(Application ClassLoader)。負責加載用戶類路徑(classpath)上的指定類庫,咱們能夠直接使用這個類加載器。通常狀況,若是咱們沒有自定義類加載器默認就是用這個加載器。
    雙親委派模型:若是一個類加載器收到了類加載的請求,它首先不會本身去加載這個類,而是把這個請求委派給父類加載器去完成,每一層的類加載器都是如此,這樣全部的加載請求都會被傳送到頂層的啓動類加載器中,只有當父加載沒法完成加載請求(它的搜索範圍中沒找到所需的類)時,子加載器纔會嘗試去加載類。
  6. 說一下類加載的執行過程?
    加載:根據查找路徑找到相應的 class 文件而後導入;
    檢查:檢查加載的 class 文件的正確性;
    準備:給類中的靜態變量分配內存空間;
    解析:虛擬機將常量池中的符號引用替換成直接引用的過程。符號引用就理解爲一個標示,而在直接引用直接指向內存中的地址
    初始化:對靜態變量和靜態代碼塊執行初始化工做。
  7. 怎麼判斷對象是否能夠被回收?
    通常有兩種方法來判斷:
    引用計數器:爲每一個對象建立一個引用計數,有對象引用時計數器 +1,引用被釋放時計數 -1,當計數器爲 0 時就能夠被回收。它有一個缺點不能解決循環引用的問題;
    可達性分析:從 GC Roots 開始向下搜索,搜索所走過的路徑稱爲引用鏈。當一個對象到 GC Roots 沒有任何引用鏈相連時,則證實此對象是能夠被回收的。
  8. java 中都有哪些引用類型?
    強引用:發生 gc 的時候不會被回收
    軟引用:有用但不是必須的對象,在發生內存溢出以前會被回收。
    弱引用:有用但不是必須的對象,在下一次GC時會被回收。
    虛引用(幽靈引用/幻影引用):沒法經過虛引用得到對象,用 PhantomReference 實現虛引用,虛引用的用途是在 gc 時返回一個通知。
  9. 說一下 jvm 有哪些垃圾回收算法?
    標記-清除算法:標記無用對象,而後進行清除回收。缺點:效率不高,沒法清除垃圾碎片。
    標記-整理算法:標記無用對象,讓全部存活的對象都向一端移動,而後直接清除掉端邊界之外的內存。
    複製算法:按照容量劃分二個大小相等的內存區域,當一塊用完的時候將活着的對象複製到另外一塊上,而後再把已使用的內存空間一次清理掉。缺點:內存使用率不高,只有原來的一半。
    分代算法:根據對象存活週期的不一樣將內存劃分爲幾塊,通常是新生代和老年代,新生代基本採用複製算法,老年代採用標記整理算法。
  10. 說一下 jvm 有哪些垃圾回收器?
    Serial:最先的單線程串行垃圾回收器。
    Serial Old:Serial 垃圾回收器的老年版本,一樣也是單線程的,能夠做爲 CMS 垃圾回收器的備選預案。
    ParNew:是 Serial 的多線程版本。
    Parallel 和 ParNew 收集器相似是多線程的,但 Parallel 是吞吐量優先的收集器,能夠犧牲等待時間換取系統的吞吐量。
    Parallel Old 是 Parallel 老生代版本,Parallel 使用的是複製的內存回收算法,Parallel Old 使用的是標記-整理的內存回收算法。
    CMS:一種以得到最短停頓時間爲目標的收集器,很是適用 B/S 系統。
    G1:一種兼顧吞吐量和停頓時間的 GC 實現,是 JDK 9 之後的默認 GC 選項。
  11. 詳細介紹一下 CMS 垃圾回收器?
    CMS 是英文 Concurrent Mark-Sweep 的簡稱,是以犧牲吞吐量爲代價來得到最短回收停頓時間的垃圾回收器。對於要求服務器響應速度的應用上,這種垃圾回收器很是適合。在啓動 JVM 的參數加上「-XX:+UseConcMarkSweepGC」來指定使用 CMS 垃圾回收器。
    CMS 使用的是標記-清除的算法實現的,因此在 gc 的時候回產生大量的內存碎片,當剩餘內存不能知足程序運行要求時,系統將會出現 Concurrent Mode Failure,臨時 CMS 會採用 Serial Old 回收器進行垃圾清除,此時的性能將會被下降。
  12. 新生代垃圾回收器和老生代垃圾回收器都有哪些?有什麼區別?
    新生代回收器:Serial、ParNew、Parallel Scavenge
    老年代回收器:Serial Old、Parallel Old、CMS
    整堆回收器:G1
  13. 簡述分代垃圾回收器是怎麼工做的?
    分代回收器有兩個分區:老生代和新生代,新生代默認的空間佔比總空間的 1/3,老生代的默認佔比是 2/3。
    新生代使用的是複製算法,新生代裏有 3 個分區:Eden、To Survivor、From Survivor,它們的默認佔比是 8:1:1,它的執行流程以下:
    把 Eden + From Survivor 存活的對象放入 To Survivor 區;
    清空 Eden 和 From Survivor 分區;
    From Survivor 和 To Survivor 分區交換,From Survivor 變 To Survivor,To Survivor 變 From Survivor。
    每次在 From Survivor 到 To Survivor 移動時都存活的對象,年齡就 +1,當年齡到達 15(默認配置是 15)時,升級爲老生代。大對象也會直接進入老生代。
    老生代當空間佔用到達某個值以後就會觸發全局垃圾收回,通常使用標記整理的執行算法。以上這些循環往復就構成了整個分代垃圾回收的總體執行流程。
  14. 說一下 jvm 調優的工具?
    jconsole:用於對 JVM 中的內存、線程和類等進行監控;
    jvisualvm:JDK 自帶的全能分析工具,能夠分析:內存快照、線程快照、程序死鎖、監控內存的變化、gc 變化等。
  15. 經常使用的 jvm 調優的參數都有哪些?
    -Xms2g:初始化推大小爲 2g;
    -Xmx2g:堆最大內存爲 2g;
    -XX:NewRatio=4:設置年輕的和老年代的內存比例爲 1:4
    -XX:SurvivorRatio=8:設置新生代 Eden 和 Survivor 比例爲 8:2;
    –XX:+UseParNewGC:指定使用 ParNew + Serial Old 垃圾回收器組合;
    -XX:+UseParallelOldGC:指定使用 ParNew + ParNew Old 垃圾回收器組合;
    -XX:+UseConcMarkSweepGC:指定使用 CMS + Serial Old 垃圾回收器組合;
    -XX:+PrintGC:開啓打印 gc 信息;
    -XX:+PrintGCDetails:打印 gc 詳細信息。
  1. CAS的缺點.
    java中的Atomic類能夠保證對數據操做的原子性.
    好比i++這種操做,可使用AtomicInteger類來保證
    在AtomicInteger類的getAndIncrement()方法中,使用了CAS的思想
    底層依靠Unsafe來實現的.
    缺點: 1.循環時間長,開銷大
    2.只能保證一個共享變量的原子操做
    3.會出現ABA問題
  2. ABA問題是什麼?如何規避?好比兩個線程a和b, 他們都從主內存中拷貝一個int i = 5進行操做.其中由於線程b的邏輯比較簡單,先將i變成了8,此時,a線程尚未運行完,在這個時候b線程又將i變成了5.此時a線程進行CAS自旋發現i=5,沒有變化,所以進行了更新.可是在這個中間,變量i是有變化的.如何解決ABA問題?------------------對值的修改加版本號(相似時間戳)就能夠解決.可使用j.u.c中的AtomicStampedReference來解決.AtomicStampedReference採用原子引用+版本的號的方式,在構造AtomincStamicRefrence的時候能夠指定多個參數,包含要包括的引用,還有初始版本號,在使用的時候要指按期望的版本號和要修改的版本號
相關文章
相關標籤/搜索