1. 程式人生 > 實用技巧 >面試題精選

面試題精選

資料型別

  1. java中基本資料型別各佔多少位元組?

    byte:1位元組

    short:2位元組

    int:4位元組

    long:8位元組

    float:4位元組

    char:2位元組

    double:8位元組

    boolean:1位

  2. &和&&的區別?

    &運算子有兩種用法:(1)按位與;(2)邏輯與。

    &&運算子是短路與運算

    &&左邊的表示式的值是false,右邊的表示式會被直接短路掉,不會進行運算

面向物件

  1. 面向物件的優點?

    易拓展,易維護

  2. 介面與抽象類的區別?

    凡是用abstract修飾的類都叫做抽象類

    抽象類可以有零個或多個抽象方法,也可以包含非抽象方法

    抽象類中可以沒有抽象方法,但是有抽象方法的類必須是抽象類,

    抽象類不能建立物件,必須由抽象類派生子類來實現

    介面是用interface修飾的類,介面只能被介面繼承

    接口裡面的方法只能是抽象方法

​ 接口裡面的變數只能是常量,(public static final)

​ 介面不能例項化,只能通過多型的方式來例項化

  1. 過載(overloading)與重寫(override)的區別

    方法過載:在一個類裡面,方法名一樣,引數列表不同,與返回值無關

​ 方法重寫:在繼承關係中,方法名一樣,,引數列表相同

  1. 面向過程與面向物件的區別

    面向過程是指,允許在程式中定義函式或者方法。也許你覺得奇怪,難道還有語言不能定義函式方法麼?早期的basic就不可以,只能用跳轉來實現函式呼叫。

    面向物件更近一步,允許你將“過程”(函式、方法)以及它們的上下文相關的資料封裝成物件,同時物件允許通過繼承和派生以及型別限定符限制開發者對它的一部分的進行訪問和修改。

集合框架

  1. 常用的集合類有哪些?

    • Collection介面的子介面包括:Set介面和List介面
    • Map介面的實現類主要有:HashMap、TreeMap、Hashtable、ConcurrentHashMap以及Properties等
    • Set介面的實現類主要有:HashSet、TreeSet、LinkedHashSet等
    • List介面的實現類主要有:ArrayList、LinkedList、Stack以及Vector等
  2. List,Set,Map三者的區別?

    Collection集合主要有List和Set兩大介面

    • List:一個有序(元素存入集合的順序和取出的順序一致)容器,元素可以重複,可以插入多個null元素,元素都有索引。常用的實現類有 ArrayList、LinkedList 和 Vector。
    • Set:一個無序(存入和取出順序有可能不一致)容器,不可以儲存重複元素,只允許存入一個null元素,必須保證元素唯一性。Set 介面常用實現類是 HashSet、LinkedHashSet 以及 TreeSet。

    Map是一個鍵值對集合,儲存鍵、值和之間的對映。 Key無序,唯一;value 不要求有序,允許重複。

    Map沒有繼承於Collection介面,從Map集合中檢索元素時,只要給出鍵物件,就會返回對應的值物件。

    Map 的常用實現類:HashMap、TreeMap、HashTable、LinkedHashMap、ConcurrentHashMap

  3. 集合框架底層資料結構

    • List
      • Arraylist: Object陣列
      • Vector: Object陣列
      • LinkedList: 雙向迴圈連結串列
    • Set
      • HashSet(無序,唯一):基於 HashMap 實現的,底層採用 HashMap 來儲存元素
      • LinkedHashSet: LinkedHashSet 繼承與 HashSet,並且其內部是通過 LinkedHashMap 來實現的。有點類似於我們之前說的LinkedHashMap 其內部是基於 Hashmap 實現一樣,不過還是有一點點區別的。
      • TreeSet(有序,唯一): 紅黑樹(自平衡的排序二叉樹。)
    • Map
      • HashMap: JDK1.8之前HashMap由陣列+連結串列組成的,陣列是HashMap的主體,連結串列則是主要為了解決雜湊衝突而存在的(“拉鍊法”解決衝突).JDK1.8以後在解決雜湊衝突時有了較大的變化,當連結串列長度大於閾值(預設為8)時,將連結串列轉化為紅黑樹,以減少搜尋時間
      • LinkedHashMap:LinkedHashMap 繼承自 HashMap,所以它的底層仍然是基於拉鍊式雜湊結構即由陣列和連結串列或紅黑樹組成。另外,LinkedHashMap 在上面結構的基礎上,增加了一條雙向連結串列,使得上面的結構可以保持鍵值對的插入順序。同時通過對連結串列進行相應的操作,實現了訪問順序相關邏輯。
      • HashTable: 陣列+連結串列組成的,陣列是 HashMap 的主體,連結串列則是主要為了解決雜湊衝突而存在的
      • TreeMap: 紅黑樹(自平衡的排序二叉樹)
  4. 哪些集合類是執行緒安全的?

    • vector:就比arraylist多了個同步化機制(執行緒安全),因為效率較低,現在已經不太建議使用。
    • statck:堆疊類,先進後出。
    • hashtable:就比hashmap多了個執行緒安全。
    • enumeration:列舉,相當於迭代器。
  5. ArrayList 和 LinkedList 的區別是什麼?

    • 資料結構實現:ArrayList 是動態陣列的資料結構實現,而 LinkedList 是雙向連結串列的資料結構實現。
    • 隨機訪問效率:ArrayList 比 LinkedList 在隨機訪問的時候效率要高,因為 LinkedList 是線性的資料儲存方式,所以需要移動指標從前往後依次查詢。
    • 增加和刪除效率:在非首尾的增加和刪除操作,LinkedList 要比 ArrayList 效率要高,因為 ArrayList 增刪操作要影響陣列內的其他資料的下標。
    • 記憶體空間佔用:LinkedList 比 ArrayList 更佔記憶體,因為 LinkedList 的節點除了儲存資料,還儲存了兩個引用,一個指向前一個元素,一個指向後一個元素。
    • 執行緒安全:ArrayList 和 LinkedList 都是不同步的,也就是不保證執行緒安全;

    綜合來說,在需要頻繁讀取集合中的元素時,更推薦使用 ArrayList,而在插入和刪除操作較多時,更推薦使用 LinkedList。

  6. ArrayList 和 Vector 的區別是什麼?

    這兩個類都實現了 List 介面(List 介面繼承了 Collection 介面),他們都是有序集合

    • 執行緒安全:Vector 使用了 Synchronized 來實現執行緒同步,是執行緒安全的,而 ArrayList 是非執行緒安全的。
    • 效能:ArrayList 在效能方面要優於 Vector。
    • 擴容:ArrayList 和 Vector 都會根據實際的需要動態的調整容量,只不過在 Vector 擴容每次會增加 1 倍,而 ArrayList 只會增加 50%。
  7. 說一下 HashSet 的實現原理?

    HashSet 是基於 HashMap 實現的,HashSet的值存放於HashMap的key上,HashMap的value統一為PRESENT,因此 HashSet 的實現比較簡單,相關 HashSet 的操作,基本上都是直接呼叫底層 HashMap 的相關方法來完成,HashSet 不允許重複的值。

  8. HashSet如何檢查重複?HashSet是如何保證資料不可重複的?

    向HashSet 中add ()元素時,判斷元素是否存在的依據,不僅要比較hash值,同時還要結合equles 方法比較。
    HashSet 中的add ()方法會使用HashMap 的put()方法。

    HashMap 的 key 是唯一的,由原始碼可以看出 HashSet 新增進去的值就是作為HashMap 的key,並且在HashMap中如果K/V相同時,會用新的V覆蓋掉舊的V,然後返回舊的V。所以不會重複

  9. hashCode()與equals()的相關規定

    1. 如果兩個物件相等,則hashcode一定也是相同的
    2. 兩個物件相等,對兩個equals方法返回true
    3. 兩個物件有相同的hashcode值,它們也不一定是相等的
    4. 綜上,equals方法被覆蓋過,則hashCode方法也必須被覆蓋
    5. hashCode()的預設行為是對堆上的物件產生獨特值。如果沒有重寫hashCode(),則該class的兩個物件無論如何都不會相等
  10. HashSet與HashMap的區別

    HashMap HashSet
    實現了Map介面 實現Set介面
    儲存鍵值對 僅儲存物件
    呼叫put()向map中新增元素 HashSet較HashMap來說比較慢
    HashMap使用鍵(Key)計算Hashcode HashSet使用成員物件來計算hashcode值,對於兩個物件來說hashcode可能相同,所以equals()方法用來判斷物件的相等性,如果兩個物件不同的話,那麼返回false
    HashMap相對於HashSet較快,因為它是使用唯一的鍵獲取物件 HashSet較HashMap來說比較慢
  11. BlockingQueue是什麼?

    Java.util.concurrent.BlockingQueue是一個佇列,在進行檢索或移除一個元素的時候,它會等待佇列變為非空;當在新增一個元素時,它會等待佇列中的可用空間。BlockingQueue介面是Java集合框架的一部分,主要用於實現生產者-消費者模式。我們不需要擔心等待生產者有可用的空間,或消費者有可用的物件,因為它都在BlockingQueue的實現類中被處理了。Java提供了集中BlockingQueue的實現

  12. Queue 中 poll()和 remove()有什麼區別?

    • 相同點:都是返回第一個元素,並在佇列中刪除返回的物件。
    • 不同點:如果沒有元素 poll()會返回 null,而 remove()會直接丟擲 NoSuchElementException 異常。
  13. 說一下 HashMap 的實現原理?

    HashMap 基於 Hash 演算法實現的

    1. 當我們往Hashmap中put元素時,利用key的hashCode重新hash計算出當前物件的元素在陣列中的下標
    2. 儲存時,如果出現hash值相同的key,此時有兩種情況。(1)如果key相同,則覆蓋原始值;(2)如果key不同(出現衝突),則將當前的key-value放入連結串列中
    3. 獲取時,直接找到hash值對應的下標,在進一步判斷key是否相同,從而找到對應值。
    4. 理解了以上過程就不難明白HashMap是如何解決hash衝突的問題,核心就是使用了陣列的儲存方式,然後將衝突的key的物件放入連結串列中,一旦發現衝突就在連結串列中做進一步的對比。

    需要注意Jdk 1.8中對HashMap的實現做了優化,當連結串列中的節點資料超過八個之後,該連結串列會轉為紅黑樹來提高查詢效率,從原來的O(n)到O(logn)

  14. HashMap在JDK1.7和JDK1.8中有哪些不同?HashMap的底層實現

    JDK1.8之前採用的是拉鍊法。拉鍊法:將連結串列和陣列相結合。也就是說建立一個連結串列陣列,陣列中每一格就是一個連結串列。若遇到雜湊衝突,則將衝突的值加到連結串列中即可。

    JDK1.8之後相比於之前的版本,jdk1.8在解決雜湊衝突時有了較大的變化,當連結串列長度大於閾值(預設為8)時,將連結串列轉化為紅黑樹,以減少搜尋時間。

    JDK1.8主要解決或優化了一下問題:

    1. resize 擴容優化
    2. 引入了紅黑樹,目的是避免單條連結串列過長而影響查詢效率,紅黑樹演算法請參考
    3. 解決了多執行緒死迴圈問題,但仍是非執行緒安全的,多執行緒時可能會造成資料丟失問題
    不同 JDK 1.7 JDK 1.8
    儲存結構 陣列 + 連結串列 陣列 + 連結串列 + 紅黑樹
    初始化方式 單獨函式:inflateTable() 直接整合到了擴容函式resize()
    hash值計算方式 擾動處理 = 9次擾動 = 4次位運算 + 5次異或運算 擾動處理 = 2次擾動 = 1次位運算 + 1次異或運算
    存放資料的規則 無衝突時,存放陣列;衝突時,存放連結串列 無衝突時,存放陣列;衝突 & 連結串列長度 < 8:存放單鏈表;衝突 & 連結串列長度 > 8:樹化並存放紅黑樹
    插入資料方式 頭插法(先講原位置的資料移到後1位,再插入資料到該位置) 尾插法(直接插入到連結串列尾部/紅黑樹)
    擴容後儲存位置的計算方式 全部按照原來方法進行計算(即hashCode ->> 擾動函式 ->> (h&length-1)) 按照擴容後的規律計算(即擴容後的位置=原位置 or 原位置 + 舊容量)
  15. HashMap的擴容操作是怎麼實現的?

    • 在jdk1.8中,resize方法是在hashmap中的鍵值對大於閥值時或者初始化時,就呼叫resize方法進行擴容;
    • 每次擴充套件的時候,都是擴充套件2倍;
    • 擴充套件後Node物件的位置要麼在原位置,要麼移動到原偏移量兩倍的位置。
  16. HashMap是怎麼解決雜湊衝突的?

    1. 使用鏈地址法(使用散列表)來連結擁有相同hash值的資料;
    2. 使用2次擾動函式(hash函式)來降低雜湊衝突的概率,使得資料分佈更平均;
    3. 引入紅黑樹進一步降低遍歷的時間複雜度,使得遍歷更快;
  17. HashMap 的長度為什麼是2的冪次方

    為了能讓 HashMap 存取高效,儘量較少碰撞,也就是要儘量把資料分配均勻,每個連結串列/紅黑樹長度大致相同。

    這個實現就是把資料存到哪個連結串列/紅黑樹中的演算法。

  18. HashMap 與 HashTable 有什麼區別?

  19. 執行緒安全: HashMap 是非執行緒安全的,HashTable 是執行緒安全的;HashTable 內部的方法基本都經過 synchronized 修飾。

  20. 效率: 因為執行緒安全的問題,HashMap 要比 HashTable 效率高一點。另外,HashTable 基本被淘汰,不要在程式碼中使用它;

  21. 對Null key 和Null value的支援: HashMap 中,null 可以作為鍵,這樣的鍵只有一個,可以有一個或多個鍵所對應的值為 null。但是在 HashTable 中 put 進的鍵值只要有一個 null,直接拋NullPointerException。

  22. **初始容量大小和每次擴充容量大小的不同 **: ①建立時如果不指定容量初始值,Hashtable 預設的初始大小為11,之後每次擴充,容量變為原來的2n+1。HashMap 預設的初始化大小為16。之後每次擴充,容量變為原來的2倍。②建立時如果給定了容量初始值,那麼 Hashtable 會直接使用你給定的大小,而 HashMap 會將其擴充為2的冪次方大小。也就是說 HashMap 總是使用2的冪作為雜湊表的大小,後面會介紹到為什麼是2的冪次方。

  23. 底層資料結構: JDK1.8 以後的 HashMap 在解決雜湊衝突時有了較大的變化,當連結串列長度大於閾值(預設為8)時,將連結串列轉化為紅黑樹,以減少搜尋時間。Hashtable 沒有這樣的機制。

  24. 推薦使用:在 Hashtable 的類註釋可以看到,Hashtable 是保留類不建議使用,推薦在單執行緒環境下使用 HashMap 替代,如果需要多執行緒使用則用 ConcurrentHashMap 替代。

  25. 如何決定使用 HashMap 還是 TreeMap?

    對於在Map中插入、刪除和定位元素這類操作,HashMap是最好的選擇。

    假如你需要對一個有序的key集合進行遍歷,TreeMap是更好的選擇。

  26. HashMap 和 ConcurrentHashMap 的區別

    1. ConcurrentHashMap在每一個分段上都用lock鎖進行保護,相對於HashTable的synchronized鎖的粒度更精細了一些,併發效能更好,而HashMap沒有鎖機制,不是執行緒安全的。
    2. HashMap的鍵值對允許有null,但是ConCurrentHashMap都不允許。
  27. Array 和 ArrayList 有何區別?

    • Array 可以儲存基本資料型別和物件,ArrayList 只能儲存物件。
    • Array 是指定固定大小的,而 ArrayList 大小是自動擴充套件的。
    • Array 內建方法沒有 ArrayList 多,比如 addAll、removeAll、iteration 等方法只有 ArrayList 有。
  28. 如何實現 Array 和 List 之間的轉換?

    • Array 轉 List: Arrays. asList(array) ;
    • List 轉 Array:List 的 toArray() 方法。

多執行緒

  1. 多執行緒有什麼用?

    • 發揮多核CPU的優勢
    • 防止阻塞
    • 便於建模
  2. 建立執行緒的方式

    • 繼承Thread類,重寫run方法,呼叫start執行

    • 實現Runnabel介面,實現run方法,建立Thread類物件,構造方法中傳遞Runnable介面的實現類物件,呼叫Thread類中的start方法

    • 實現Callable介面並傳入引用資料型別,實現call方法,建立適配類FutureTask傳遞Callable的實現類物件,建立Thread類物件,構造方法中傳遞FutureTask介面的實現類物件,呼叫Thread類中的start方法

  3. start()方法和run()方法的區別

    只有呼叫了start()方法,才會表現出多執行緒的特性,不同執行緒的run()方法裡面的程式碼交替執行。

    如果只是呼叫run()方法,那麼程式碼還是同步執行的,必須等待一個執行緒的run()方法裡面的程式碼全部執行完畢之後,另外一個執行緒才可以執行其run()方法裡面的程式碼。

  4. Runnable介面和Callable介面的區別

    Runnable介面中的run()方法的返回值是void,它做的事情只是純粹地去執行run()方法中的程式碼而已;Callable介面中的call()方法是有返回值的,是一個泛型,和Future、FutureTask配合可以用來獲取非同步執行的結果。

  5. 什麼是執行緒安全

    如果你的程式碼在多執行緒下執行和在單執行緒下執行永遠都能獲得一樣的結果,那麼你的程式碼就是執行緒安全的。

  6. 如何在兩個執行緒之間共享資料

    通過線上程之間共享物件就可以了,然後通過wait/notify/notifyAll、await/signal/signalAll進行喚起和等待,比方說阻塞佇列BlockingQueue就是為執行緒之間共享資料而設計的

  7. sleep方法和wait方法有什麼區別

    sleep方法和wait方法都可以用來放棄CPU一定的時間,不同點在於如果執行緒持有某個物件的監視器,sleep方法不會放棄這個物件的監視器,wait方法會放棄這個物件的監視器

  8. synchronized和ReentrantLock的區別

    • synchronized是關鍵字。
    • ReentrantLock是類,可以被繼承、可以有方法
  9. ConcurrentHashMap的併發度是什麼

    ConcurrentHashMap的併發度就是segment的大小,預設為16,這意味著最多同時可以有16條執行緒操作ConcurrentHashMap,這也是ConcurrentHashMap對比Hashtable的最大優勢

  10. ReadWriteLock是什麼

    ReadWriteLock是一個讀寫鎖介面,ReentrantReadWriteLock是ReadWriteLock介面的一個具體實現,實現了讀寫的分離,讀鎖是共享的,寫鎖是獨佔的,讀和讀之間不會互斥,讀和寫、寫和讀、寫和寫之間才會互斥,提升了讀寫的效能。

  11. 怎麼喚醒一個阻塞的執行緒

    如果執行緒是因為呼叫了wait()、sleep()或者join()方法而導致的阻塞,可以中斷執行緒,並且通過丟擲InterruptedException來喚醒它;如果執行緒遇到了IO阻塞,無能為力,因為IO是作業系統實現的,Java程式碼並沒有辦法直接接觸到作業系統。

  12. 什麼是樂觀鎖和悲觀鎖

    • 樂觀鎖:就像它的名字一樣,對於併發間操作產生的執行緒安全問題持樂觀狀態,樂觀鎖認為競爭不總是會發生,因此它不需要持有鎖,將比較-替換這兩個動作作為一個原子操作嘗試去修改記憶體中的變數,如果失敗則表示發生衝突,那麼就應該有相應的重試邏輯。
    • 悲觀鎖:還是像它的名字一樣,對於併發間操作產生的執行緒安全問題持悲觀狀態,悲觀鎖認為競爭總是會發生,因此每次對某資源進行操作時,都會持有一個獨佔的鎖,就像synchronized,不管三七二十一,直接上了鎖就操作資源了。

Servlet

  1. 說一說Servlet生命週期

    初始化:Web容器載入servlet,呼叫init()方法

    處理請求:當請求到達時,執行其service()方法。service()自動派遣執行與請求相對應的doXXX(doGet或者doPost)方法。

    銷燬:服務結束,web容器會呼叫servlet的distroy()方法銷燬servlet。

  2. get提交和post提交有何區別

    • get一般用於從伺服器上獲取資料,post一般用於向伺服器傳送資料
    • 請求的時候引數的位置有區別,get的引數是拼接在url後面,使用者在瀏覽器位址列可以看到。post是放在http包的包體中。
    • 能提交的資料有區別,get方式能提交的資料只能是文字,且大小不超過1024個位元組,而post不僅可以提交文字還有二進位制檔案。
    • servlet在處理請求的時候分別對應使用doGet和doPost方式進行處理請求
  3. JSP與Servlet有什麼區別

    Servlet是伺服器端的程式,動態生成html頁面傳送到客戶端,但是這樣程式裡會有很多out.println(),java與html語言混在一起

    很亂,所以後來sun公司推出了JSP.其實JSP就是Servlet,每次執行的時候JSP都首先被編譯成servlet檔案,然後再被編譯成

    .class檔案執行。有了jsp,在MVC專案中servlet不再負責動態生成頁面,轉而去負責控制程式邏輯的作用,控制jsp與javabean

    之間的流轉。

  4. doGet與doPost方法的兩個引數是什麼

    HttpServletRequest:封裝了與請求相關的資訊

    HttpServletResponse:封裝了與響應相關的資訊

  5. forward和redirect的區別

    • 從位址列顯示來說
      • forward是伺服器請求資源,伺服器直接訪問目標地址的URL,把那個URL的響應內容讀取過來,然後把這些內容再發給瀏覽器.瀏覽器根本不知道伺服器傳送的內容從哪裡來的,所以它的位址列還是原來的地址.redirect是服務端根據邏輯,傳送一個狀態碼,告訴瀏覽器重新去請求那個地址.所以位址列顯示的是新的URL.
    • 從資料共享來說
      • forward:轉發頁面和轉發到的頁面可以共享request裡面的資料.
      • redirect:不能共享資料.

JSP

  1. JSP有哪些內建物件,作用是什麼?

    名稱 作用
    request 代表請求物件,主要用於接受客戶端通過HTTP協議連線傳輸到伺服器端的資料。
    response 代表響應物件,主要用於向客戶端傳送資料
    session 主要用於來分別儲存每個使用者資訊,與請求關聯的會話;
    pageContext 管理網頁屬性,為JSP頁面包裝頁面的上下文,管理對屬於JSP中特殊可見部分中已命名物件的訪問,它的建立和初始化都是由容器來完成的。
    application 伺服器啟動時建立,伺服器關閉時停止,為多個應用程式儲存資訊
    out 主要用於向客戶端輸出資料;
    config 程式碼片段配置物件,表示Servlet的配置。
    page 處理JSP網頁,是Object類的一個例項,指的是JSP實現類的例項,即它也是JSP本身,只有在JSP頁面範圍之內才是合法的。
    exception 處理JSP檔案執行時發生的錯誤和異常
  2. <%…%>和<%!…%>的區別

    <%…%>用於在JSP頁面中嵌入Java指令碼

    <%!…%>用於在JSP頁面中申明變數或方法,可以在該頁面中的<%…%>指令碼中呼叫,宣告的變數相當於Servlet中的定義的成員變數。

  3. jsp亂碼如何解決,給出三種以上的對應解決方案,並給出對應的程式案例

    • JSP頁面顯示亂碼
      • <%@ page contentType=”text/html; charset=gb2312″%>
    • 表單提交中文時出現亂碼
      • request.seCharacterEncoding(̶gb2312″)對請求進行統一編碼
    • 資料庫連接出現亂碼
      • 要涉及中文的地方全部是亂碼,解決辦法:在資料庫的資料庫URL中加上useUnicode=true&characterEncoding=GBK就OK了。
    • 通過過濾器完成
    • 在server.xml中的設定編碼格式

JDBC

  1. JDBC操作資料庫的步驟 ?

    1.註冊資料庫驅動。
    2.建立資料庫連線。
    3.建立一個Statement。
    4.執行SQL語句。
    5.處理結果集。
    6.關閉資料庫連線

  2. JDBC中的Statement 和PreparedStatement的區別?

    • PreparedStatement是預編譯的SQL語句,效率高於Statement。
    • PreparedStatement支援?操作符,相對於Statement更加靈活。
    • PreparedStatement可以防止SQL注入,安全性高於Statement。
  3. 說說資料庫連線池工作原理和實現方案?

    工作原理:JAVA EE伺服器啟動時會建立一定數量的池連線,並一直維持不少於此數目的池連線。客戶端程式需要連線時,池驅動程式會返回一個未使用的池連線並將其表記為忙。如果當前沒有空閒連線,池驅動程式就新建一定數量的連線,新建連線的數量有配置引數決定。當使用的池連線呼叫完成後,池驅動程式將此連線表記為空閒,其他呼叫就可以使用這個連線。
    實現方案:返回的Connection是原始Connection的代理,代理Connection的close方法,當呼叫close方法時,不是真正關連線,而是把它代理的Connection物件放回到連線池中,等待下一次重複利用。

  4. JDBC是如何實現Java程式和JDBC驅動的鬆耦合的?

    JDBC API使用Java的反射機制來實現Java程式和JDBC驅動的鬆耦合。所有操作都是通過JDBC介面完成的,而驅動只有在通過Class.forName反射機制來載入的時候才會出現。

  5. JDBC的DriverManager是用來做什麼的?

    JDBC的DriverManager是一個工廠類,我們通過它來建立資料庫連線。

    然後我們會把資料庫配置資訊傳成DriverManager.getConnection()方法,DriverManager會使用註冊到它裡面的驅動來獲取資料庫連線,並返回給呼叫的程式。

  6. execute,executeQuery,executeUpdate的區別是什麼?

    • Statement的execute(String query)方法用來執行任意的SQL查詢,如果查詢的結果是一個ResultSet,這個方法就返回true。如果結果不是ResultSet,比如insert或者update查詢,它就會返回false。我們可以通過它的getResultSet方法來獲取ResultSet,或者通過getUpdateCount()方法來獲取更新的記錄條數
    • Statement的executeQuery(String query)介面用來執行select查詢,並且返回ResultSet。即使查詢不到記錄返回的ResultSet也不會為null。我們通常使用executeQuery來執行查詢語句,這樣的話如果傳進來的是insert或者update語句的話,它會丟擲錯誤資訊為 “executeQuery method can not be used for update”的java.util.SQLException。
    • Statement的executeUpdate(String query)方法用來執行insert或者update/delete(DML)語句,或者 什麼也不返回DDL語句。返回值是int型別,如果是DML語句的話,它就是更新的條數,如果是DDL的話,就返回0。
  7. Statement中的getGeneratedKeys方法有什麼用?

    有的時候表會生成主鍵,這時候就可以用Statement的getGeneratedKeys()方法來獲取這個自動生成的主鍵的值了。

  8. 如何使用JDBC介面來呼叫儲存過程?

    儲存過程就是資料庫編譯好的一組SQL語句,可以通過JDBC介面來進行呼叫。

    我們可以通過JDBC的CallableStatement介面來在資料庫中執行儲存過程。

  9. JDBC的批處理是什麼,有什麼好處?

    有時候類似的查詢我們需要執行很多遍,比如從CSV檔案中載入資料到關係型資料庫的表裡。我們也知道,執行查詢可以用Statement或者PreparedStatement。除此之外,JDBC還提供了批處理的特性,有了它,我們可以在一次資料庫呼叫中執行多條查詢語句。

  10. JDBC的事務管理是什麼,為什麼需要它?

    預設情況下,我們建立的資料庫連線,是工作在自動提交的模式下的。這意味著只要我們執行完一條查詢語句,就會自動進行提交。因此我們的每條查詢,實際上都是一個事務,如果我們執行的是DML或者DDL,每條語句完成的時候,資料庫就已經完成修改了。

    有的時候我們希望由一組SQL查詢組成一個事務,如果它們都執行OK我們再進行提交,如果中途出現異常了,我們可以進行回滾。

    JDBC介面提供了一個setAutoCommit(boolean flag)方法,我們可以用它來關閉連線自動提交的特性。我們應該在需要手動提交時才關閉這個特性,不然的話事務不會自動提交,每次都得手動提交。資料庫通過表鎖來管理事務,這個操作非常消耗資源。因此我們應當完成操作後儘快的提交事務

  11. 如何回滾事務?

    通過Connection物件的rollback方法可以回滾事務。它會回滾這次事務中的所有修改操作,並釋放當前連線所持有的資料庫鎖。

MySQL

  1. 資料庫三大正規化是什麼

    第一正規化:每個列都不可以再拆分。

    第二正規化:在第一正規化的基礎上,非主鍵列完全依賴於主鍵,而不能是依賴於主鍵的一部分。

    第三正規化:在第二正規化的基礎上,非主鍵列只依賴於主鍵,不依賴於其他非主鍵。

  2. MySQL儲存引擎MyISAM與InnoDB區別

    • Innodb引擎:Innodb引擎提供了對資料庫ACID事務的支援。並且還提供了行級鎖和外來鍵的約束。它的設計的目標就是處理大資料容量的資料庫系統。
    • MyIASM引擎(原本Mysql的預設引擎):不提供事務的支援,也不支援行級鎖和外來鍵。
    • MEMORY引擎:所有的資料都在記憶體中,資料的處理速度快,但是安全性不高。

    MyISAM與InnoDB區別

    MyISAM Innodb
    儲存結構 每張表被存放在三個檔案:frm-表格定義、MYD(MYData)-資料檔案、MYI(MYIndex)-索引檔案 所有的表都儲存在同一個資料檔案中(也可能是多個檔案,或者是獨立的表空間檔案),InnoDB表的大小隻受限於作業系統檔案的大小,一般為2GB
    儲存空間 MyISAM可被壓縮,儲存空間較小 InnoDB的表需要更多的記憶體和儲存,它會在主記憶體中建立其專用的緩衝池用於高速緩衝資料和索引
    可移植性、備份及恢復 由於MyISAM的資料是以檔案的形式儲存,所以在跨平臺的資料轉移中會很方便。在備份和恢復時可單獨針對某個表進行操作 免費的方案可以是拷貝資料檔案、備份 binlog,或者用 mysqldump,在資料量達到幾十G的時候就相對痛苦了
    檔案格式 資料和索引是分別儲存的,資料.MYD,索引.MYI 資料和索引是集中儲存的,.ibd
    記錄儲存順序 按記錄插入順序儲存 按主鍵大小有序插入
    外來鍵 不支援 支援
    事務 不支援 支援
    鎖支援(鎖是避免資源爭用的一個機制,MySQL鎖對使用者幾乎是透明的) 表級鎖定 行級鎖定、表級鎖定,鎖定力度小併發能力高
    SELECT MyISAM更優
    INSERT、UPDATE、DELETE InnoDB更優
    select count(*) myisam更快,因為myisam內部維護了一個計數器,可以直接調取。
    索引的實現方式 B+樹索引,myisam 是堆表 B+樹索引,Innodb 是索引組織表
    雜湊索引 不支援 支援
    全文索引 支援 不支援
    1. MyISAM索引與InnoDB索引的區別?
    • InnoDB索引是聚簇索引,MyISAM索引是非聚簇索引。
    • InnoDB的主鍵索引的葉子節點儲存著行資料,因此主鍵索引非常高效。
    • MyISAM索引的葉子節點儲存的是行資料地址,需要再定址一次才能得到資料。
    • InnoDB非主鍵索引的葉子節點儲存的是主鍵和其他帶索引的列資料,因此查詢時做到覆蓋索引會非常高效
    1. InnoDB引擎的4大特性

      • 插入緩衝(insert buffer)
      • 二次寫(double write)
      • 自適應雜湊索引(ahi)
      • 預讀(read ahead)
    2. 什麼是索引?

      索引是一種特殊的檔案(InnoDB資料表上的索引是表空間的一個組成部分),它們包含著對資料表裡所有記錄的引用指標。

      索引是一種資料結構。資料庫索引,是資料庫管理系統中一個排序的資料結構,以協助快速查詢、更新資料庫表中資料。索引的實現通常使用B樹及其變種B+樹。

    3. 索引有哪些優缺點?

      • 索引的優點
        • 可以大大加快資料的檢索速度,這也是建立索引的最主要的原因。
        • 通過使用索引,可以在查詢的過程中,使用優化隱藏器,提高系統的效能。
      • 索引的缺點
        • 時間方面:建立索引和維護索引要耗費時間,具體地,當對錶中的資料進行增加、刪除和修改的時候,索引也要動態的維護,會降低增/改/刪的執行效率;
        • 空間方面:索引需要佔物理空間。
    4. 索引有哪幾種類型?

      主鍵索引: 資料列不允許重複,不允許為NULL,一個表只能有一個主鍵。

      唯一索引: 資料列不允許重複,允許為NULL值,一個表允許多個列建立唯一索引。

      普通索引: 基本的索引型別,沒有唯一性的限制,允許為NULL值。

      全文索引: 是目前搜尋引擎使用的一種關鍵技術。

    5. 索引的資料結構(b樹,hash)

      索引的資料結構和具體儲存引擎的實現有關,在MySQL中使用較多的索引有Hash索引B+樹索引等,而我們經常使用的InnoDB儲存引擎的預設索引實現為:B+樹索引。對於雜湊索引來說,底層的資料結構就是雜湊表,因此在絕大多數需求為單條記錄查詢的時候,可以選擇雜湊索引,查詢效能最快;其餘大部分場景,建議選擇BTree索引。

      B樹索引

      mysql通過儲存引擎取資料,基本上90%的人用的就是InnoDB了,按照實現方式分,InnoDB的索引型別目前只有兩種:BTREE(B樹)索引和HASH索引。B樹索引是Mysql資料庫中使用最頻繁的索引型別,基本所有儲存引擎都支援BTree索引。通常我們說的索引不出意外指的就是(B樹)索引(實際是用B+樹實現的,因為在查看錶索引時,mysql一律列印BTREE,所以簡稱為B樹索引)

      B+tree性質:

      • n棵子tree的節點包含n個關鍵字,不用來儲存資料而是儲存資料的索引。
      • 所有的葉子結點中包含了全部關鍵字的資訊,及指向含這些關鍵字記錄的指標,且葉子結點本身依關鍵字的大小自小而大順序連結。
      • 所有的非終端結點可以看成是索引部分,結點中僅含其子樹中的最大(或最小)關鍵字。
      • B+ 樹中,資料物件的插入和刪除僅在葉節點上進行。
      • B+樹有2個頭指標,一個是樹的根節點,一個是最小關鍵碼的葉節點。

      雜湊索引

      簡要說下,類似於資料結構中簡單實現的HASH表一樣,當我們在mysql中用雜湊索引時,主要就是通過Hash演算法,將資料庫欄位資料轉換成定長的Hash值,與這條資料的行指標一併存入Hash表的對應位置;如果發生Hash碰撞,則在對應Hash鍵下以連結串列形式儲存。

    6. 索引的基本原理.

      索引用來快速地尋找那些具有特定值的記錄。如果沒有索引,一般來說執行查詢時遍歷整張表。

      索引的原理很簡單,就是把無序的資料變成有序的查詢

      1. 把建立了索引的列的內容進行排序
      2. 對排序結果生成倒排表
      3. 在倒排表內容上拼上資料地址鏈
      4. 在查詢的時候,先拿到倒排表內容,再取出資料地址鏈,從而拿到具體資料
    7. 索引演算法有哪些?

      索引演算法有 BTree演算法和Hash演算法

      BTree演算法

      BTree是最常用的mysql資料庫索引演算法,也是mysql預設的演算法。因為它不僅可以被用在=,>,>=,<,<=和between這些比較操作符上,而且還可以用於like操作符,只要它的查詢條件是一個不以萬用字元開頭的常量

      -- 只要它的查詢條件是一個不以萬用字元開頭的常量
      select * from user where name like 'jack%'; 
      -- 如果一萬用字元開頭,或者沒有使用常量,則不會使用索引,例如: 
      select * from user where name like '%jack'; 
      

      Hash演算法

      Hash Hash索引只能用於對等比較,例如=,<=>(相當於=)操作符。由於是一次定位資料,不像BTree索引需要從根節點到枝節點,最後才能訪問到頁節點這樣多次IO訪問,所以檢索效率遠高於BTree索引

    8. 建立索引的原則

      • 最左字首匹配原則,組合索引非常重要的原則,mysql會一直向右匹配直到遇到範圍查詢(>、<、between、like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)順序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引則都可以用到,a,b,d的順序可以任意調整。

      • 較頻繁作為查詢條件的欄位才去建立索引

      • 更新頻繁欄位不適合建立索引

      • 若是不能有效區分資料的列不適合做索引列(如性別,男女未知,最多也就三種,區分度實在太低)

      • 儘量的擴充套件索引,不要新建索引。比如表中已經有a的索引,現在要加(a,b)的索引,那麼只需要修改原來的索引即可。

      • 定義有外來鍵的資料列一定要建立索引。

      • 對於那些查詢中很少涉及的列,重複值比較多的列不要建立索引。

      • 對於定義為text、image和bit的資料型別的列不要建立索引。

    9. B樹和B+樹的區別

      • 在B樹中,你可以將鍵和值存放在內部節點和葉子節點;但在B+樹中,內部節點都是鍵,沒有值,葉子節點同時存放鍵和值。
      • B+樹的葉子節點有一條鏈相連,而B樹的葉子節點各自獨立。

    10. 使用B樹的好處

      B樹可以在內部節點同時儲存鍵和值,因此,把頻繁訪問的資料放在靠近根節點的地方將會大大提高熱點資料的查詢效率。這種特性使得B樹在特定資料重複多次查詢的場景中更加高效。

    11. 使用B+樹的好處

      由於B+樹的內部節點只存放鍵,不存放值,因此,一次讀取,可以在記憶體頁中獲取更多的鍵,有利於更快地縮小查詢範圍。 B+樹的葉節點由一條鏈相連,因此,當需要進行一次全資料遍歷的時候,B+樹只需要使用O(logN)時間找到最小的一個節點,然後通過鏈進行O(N)的順序遍歷即可。而B樹則需要對樹的每一層進行遍歷,這會需要更多的記憶體置換次數,因此也就需要花費更多的時間

    12. 資料庫為什麼使用B+樹而不是B樹

      • B樹只適合隨機檢索,而B+樹同時支援隨機檢索和順序檢索;
      • B+樹空間利用率更高,可減少I/O次數,磁碟讀寫代價更低。一般來說,索引本身也很大,不可能全部儲存在記憶體中,因此索引往往以索引檔案的形式儲存的磁碟上。這樣的話,索引查詢過程中就要產生磁碟I/O消耗。B+樹的內部結點並沒有指向關鍵字具體資訊的指標,只是作為索引使用,其內部結點比B樹小,盤塊能容納的結點中關鍵字數量更多,一次性讀入記憶體中可以查詢的關鍵字也就越多,相對的,IO讀寫次數也就降低了。而IO讀寫次數是影響索引檢索效率的最大因素;
      • B+樹的查詢效率更加穩定。B樹搜尋有可能會在非葉子結點結束,越靠近根節點的記錄查詢時間越短,只要找到關鍵字即可確定記錄的存在,其效能等價於在關鍵字全集內做一次二分查詢。而在B+樹中,順序檢索比較明顯,隨機檢索時,任何關鍵字的查詢都必須走一條從根節點到葉節點的路,所有關鍵字的查詢路徑長度相同,導致每一個關鍵字的查詢效率相當。
      • B-樹在提高了磁碟IO效能的同時並沒有解決元素遍歷的效率低下的問題。B+樹的葉子節點使用指標順序連線在一起,只要遍歷葉子節點就可以實現整棵樹的遍歷。而且在資料庫中基於範圍的查詢是非常頻繁的,而B樹不支援這樣的操作。
      • 增刪檔案(節點)時,效率更高。因為B+樹的葉子節點包含所有關鍵字,並以有序的連結串列結構儲存,這樣可很好提高增刪效率。
    13. 事物的四大特性(ACID)介紹一下?

      1. 原子性: 事務是最小的執行單位,不允許分割。事務的原子性確保動作要麼全部完成,要麼完全不起作用;
      2. 一致性: 執行事務前後,資料保持一致,多個事務對同一個資料讀取的結果是相同的;
      3. 隔離性: 併發訪問資料庫時,一個使用者的事務不被其他事務所幹擾,各併發事務之間資料庫是獨立的;
      4. 永續性: 一個事務被提交之後。它對資料庫中資料的改變是持久的,即使資料庫發生故障也不應該對其有任何影響。
    14. 什麼是髒讀?幻讀?不可重複讀?

      • 髒讀:某個事務已更新一份資料,另一個事務在此時讀取了同一份資料,由於某些原因,前一個RollBack了操作,則後一個事務所讀取的資料就會是不正確的。
      • 不可重複讀:在一個事務的兩次查詢之中資料不一致,這可能是兩次查詢過程中間插入了一個事務更新的原有的資料。
      • 幻讀:在一個事務的兩次查詢中資料筆數不一致,例如有一個事務查詢了幾列(Row)資料,而另一個事務卻在此時插入了新的幾列資料,先前的事務在接下來的查詢中,就會發現有幾列資料是它先前所沒有的。
    15. 什麼是事務的隔離級別?MySQL的預設隔離級別是什麼?

      為了達到事務的四大特性,資料庫定義了4種不同的事務隔離級別,由低到高依次為Read uncommitted、Read committed、Repeatable read、Serializable,這四個級別可以逐個解決髒讀、不可重複讀、幻讀這幾類問題。

      隔離級別 髒讀 不可重複讀 幻影讀
      READ-UNCOMMITTED
      READ-COMMITTED ×
      REPEATABLE-READ × ×
      SERIALIZABLE × × ×

      SQL 標準定義了四個隔離級別:

      • READ-UNCOMMITTED(讀取未提交): 最低的隔離級別,允許讀取尚未提交的資料變更,可能會導致髒讀、幻讀或不可重複讀
      • READ-COMMITTED(讀取已提交): 允許讀取併發事務已經提交的資料,可以阻止髒讀,但是幻讀或不可重複讀仍有可能發生
      • REPEATABLE-READ(可重複讀): 對同一欄位的多次讀取結果都是一致的,除非資料是被本身事務自己所修改,可以阻止髒讀和不可重複讀,但幻讀仍有可能發生
      • SERIALIZABLE(可序列化): 最高的隔離級別,完全服從ACID的隔離級別。所有的事務依次逐個執行,這樣事務之間就完全不可能產生干擾,也就是說,該級別可以防止髒讀、不可重複讀以及幻讀

      這裡需要注意的是:Mysql 預設採用的 可重複讀(REPEATABLE_READ)隔離級別

      Oracle 預設採用的 讀取已提交(READ_COMMITTED)隔離級別

      事務隔離機制的實現基於鎖機制和併發排程。其中併發排程使用的是MVVC(多版本併發控制),通過儲存修改的舊版本資訊來支援併發一致性讀和回滾等特性。

      因為隔離級別越低,事務請求的鎖越少,所以大部分資料庫系統的隔離級別都是READ-COMMITTED(讀取提交內容):,但是你要知道的是InnoDB 儲存引擎預設使用 REPEATABLE-READ(可重讀)並不會有任何效能損失。

      InnoDB 儲存引擎在 分散式事務 的情況下一般會用到SERIALIZABLE(可序列化)隔離級別。

    16. 對MySQL的鎖瞭解嗎

      當資料庫有併發事務的時候,可能會產生資料的不一致,這時候需要一些機制來保證訪問的次序,鎖機制就是這樣的一個機制。

    17. 隔離級別與鎖的關係

      在Read Uncommitted級別下,讀取資料不需要加共享鎖,這樣就不會跟被修改的資料上的排他鎖衝突

      在Read Committed級別下,讀操作需要加共享鎖,但是在語句執行完以後釋放共享鎖;

      在Repeatable Read級別下,讀操作需要加共享鎖,但是在事務提交之前並不釋放共享鎖,也就是必須等待事務執行完畢以後才釋放共享鎖。

      SERIALIZABLE 是限制性最強的隔離級別,因為該級別鎖定整個範圍的鍵,並一直持有鎖,直到事務完成。

    18. MyISAM和InnoDB儲存引擎使用的鎖

      • MyISAM採用表級鎖(table-level locking)。
      • InnoDB支援行級鎖(row-level locking)和表級鎖,預設為行級鎖

      行級鎖 行級鎖是Mysql中鎖定粒度最細的一種鎖,表示只針對當前操作的行進行加鎖。行級鎖能大大減少資料庫操作的衝突。其加鎖粒度最小,但加鎖的開銷也最大。行級鎖分為共享鎖 和 排他鎖。

      ​ 特點:開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖衝突的概率最低,併發度也最高。

      表級鎖 表級鎖是MySQL中鎖定粒度最大的一種鎖,表示對當前操作的整張表加鎖,它實現簡單,資源消耗較少,被大部分MySQL引擎支援。最常使用的MYISAM與INNODB都支援表級鎖定。表級鎖定分為表共享讀鎖(共享鎖)與表獨佔寫鎖(排他鎖)。

      ​ 特點:開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發出鎖衝突的概率最高,併發度最低。

      頁級鎖 頁級鎖是MySQL中鎖定粒度介於行級鎖和表級鎖中間的一種鎖。表級鎖速度快,但衝突多,行級衝突少,但速度慢。所以取了折衷的頁級,一次鎖定相鄰的一組記錄。

      ​ 特點:開銷和加鎖時間界於表鎖和行鎖之間;會出現死鎖;鎖定粒度界於表鎖和行鎖之間,併發度一般

    19. MySQL中InnoDB引擎的行鎖是怎麼實現的?

      InnoDB是基於索引來完成行鎖

      select * from tab_with_index where id = 1 for update;

      for update 可以根據條件來完成行鎖鎖定,並且 id 是有索引鍵的列

    20. 什麼是死鎖?怎麼解決?

      死鎖是指兩個或多個事務在同一資源上相互佔用,並請求鎖定對方的資源,從而導致惡性迴圈的現象。

      常見的解決死鎖的方法

      1. 如果不同程式會併發存取多個表,儘量約定以相同的順序訪問表,可以大大降低死鎖機會。
      2. 在同一個事務中,儘可能做到一次鎖定所需要的所有資源,減少死鎖產生概率;
      3. 對於非常容易產生死鎖的業務部分,可以嘗試使用升級鎖定顆粒度,通過表級鎖定來減少死鎖產生的概率;

      如果業務處理不好可以用分散式事務鎖或者使用樂觀鎖

    21. 資料庫的樂觀鎖和悲觀鎖是什麼?怎麼實現的?

      悲觀鎖:假定會發生併發衝突,遮蔽一切可能違反資料完整性的操作。在查詢完資料的時候就把事務鎖起來,直到提交事務。

      實現方式:使用資料庫中的鎖機制

      樂觀鎖:假設不會發生併發衝突,只在提交操作時檢查是否違反資料完整性。在修改資料的時候把事務鎖起來,通過version的方式來進行鎖定。

      實現方式:樂一般會使用版本號機制或CAS演算法實現。

    22. 大表怎麼優化?某個表有近千萬資料,CRUD比較慢,如何優化?分庫分表了是怎麼做的?分表分庫了有什麼問題?有用到中介軟體麼?他們的原理知道麼?

      1. 限定資料的範圍: 務必禁止不帶任何限制資料範圍條件的查詢語句。比如:我們當用戶在查詢訂單歷史的時候,我們可以控制在一個月的範圍內。;
      2. 讀/寫分離: 經典的資料庫拆分方案,主庫負責寫,從庫負責讀;
      3. 快取: 使用MySQL的快取,另外對重量級、更新少的資料可以考慮使用應用級別的快取;
    23. MySQL的複製原理以及流程

      主從複製:將主資料庫中的DDL和DML操作通過二進位制日誌(BINLOG)傳輸到從資料庫上,然後將這些日誌重新執行(重做);從而使得從資料庫的資料與主資料庫保持一致。

      主從複製的作用

      1. 主資料庫出現問題,可以切換到從資料庫。
      2. 可以進行資料庫層面的讀寫分離。
      3. 可以在從資料庫上進行日常備份。

      MySQL主從複製解決的問題

      • 資料分佈:隨意開始或停止複製,並在不同地理位置分佈資料備份
      • 負載均衡:降低單個伺服器的壓力
      • 高可用和故障切換:幫助應用程式避免單點失敗
      • 升級測試:可以用更高版本的MySQL作為從庫

      MySQL主從複製工作原理

      • 在主庫上把資料更高記錄到二進位制日誌
      • 從庫將主庫的日誌複製到自己的中繼日誌
      • 從庫讀取中繼日誌的事件,將其重放到從庫資料中

Spring

  1. 什麼是spring?

    Spring是一個輕量級Java開發框架,目的是為了解決企業級應用開發的業務邏輯層和其他各層的耦合問題。

    Spring可以做很多事情,它為企業級開發提供給了豐富的功能,但是這些功能的底層都依賴於它的兩個核心特性,也就是IOC控制反轉DI依賴注入和麵向切面程式設計AOP

  2. Spring 框架中都用到了哪些設計模式?

    1. 工廠模式:BeanFactory就是簡單工廠模式的體現,用來建立物件的例項;
    2. 單例模式:Bean預設為單例模式。
    3. 代理模式:Spring的AOP功能用到了JDK的動態代理和CGLIB位元組碼生成技術;
    4. 模板方法:用來解決程式碼重複的問題。比如. RestTemplate, JmsTemplate, JpaTemplate。
    5. 觀察者模式:定義物件鍵一種一對多的依賴關係,當一個物件的狀態發生改變時,所有依賴於它的物件都會得到通知被制動更新,如Spring中listener的實現–ApplicationListener。
  3. 詳細講解一下核心容器(spring context應用上下文) 模組

    這是基本的Spring模組,提供spring 框架的基礎功能,BeanFactory 是 任何以spring為基礎的應用的核心。Spring 框架建立在此模組之上,它使Spring成為一個容器。

    Bean 工廠是工廠模式的一個實現,提供了控制反轉功能,用來把應用的配置和依賴從真正的應用程式碼中分離。最常用的就是org.springframework.beans.factory.xml.XmlBeanFactory ,它根據XML檔案中的定義載入beans。該容器從XML 檔案讀取配置元資料並用它去建立一個完全配置的系統或應用。

  4. Spring 應用程式有哪些不同元件?

    • 介面 - 定義功能。
    • Bean 類 - 它包含屬性,setter 和 getter 方法,函式等。
    • Bean 配置檔案 - 包含類的資訊以及如何配置它們。
    • Spring 面向切面程式設計(AOP) - 提供面向切面程式設計的功能。
    • 使用者程式 - 它使用介面。
  5. 什麼是Spring IOC 容器?

    控制反轉即IOC,它把傳統上由程式程式碼直接操控的物件的呼叫權交給容器,通過容器來實現物件元件的裝配和管理。所謂的“控制反轉”概念就是對元件物件控制權的轉移,從程式程式碼本身轉移到了外部容器。

    Spring IOC 負責建立物件,管理物件(通過依賴注入(DI),裝配物件,配置物件,並且管理這些物件的整個生命週期。

  6. 控制反轉(IoC)有什麼作用

    解耦,由容器去維護具體的物件

  7. IOC的優點是什麼?

    • IOC 或 依賴注入把應用的程式碼量降到最低。
    • 它使應用容易測試,單元測試不再需要單例和JNDI查詢機制。
    • 最小的代價和最小的侵入性使鬆散耦合得以實現。
    • IOC容器支援載入服務時的餓漢式初始化和懶載入。
  8. BeanFactory 和 ApplicationContext有什麼區別?

    • BeanFactory和ApplicationContext是Spring的兩大核心介面,都可以當做Spring的容器。其中ApplicationContext是BeanFactory的子介面。

    • BeanFactory:是Spring裡面最底層的介面,包含了各種Bean的定義,讀取bean配置文件,管理bean的載入、例項化,控制bean的生命週期,維護bean之間的依賴關係。

    • ApplicationContext介面作為BeanFactory的派生,除了提供BeanFactory所具有的功能外,還提供了更完整的框架功能

    • 載入方式

      • BeanFactroy採用的是延遲載入形式來注入Bean的,即只有在使用到某個Bean時(呼叫getBean()),才對該Bean進行載入例項化
      • ApplicationContext,它是在容器啟動時,一次性建立了所有的Bean。
    • 建立方式

      • BeanFactory通常以程式設計的方式被建立,ApplicationContext還能以宣告的方式建立,如使用ContextLoader。
    • 註冊方式

      • BeanFactory和ApplicationContext都支援BeanPostProcessor、BeanFactoryPostProcessor的使用,但兩者之間的區別是:BeanFactory需要手動註冊,而ApplicationContext則是自動註冊。
  9. ApplicationContext通常的實現是什麼?

    FileSystemXmlApplicationContext :此容器從一個XML檔案中載入beans的定義,XML Bean 配置檔案的全路徑名必須提供給它的建構函式。

    ClassPathXmlApplicationContext:此容器也從一個XML檔案中載入beans的定義,這裡,你需要正確設定classpath因為這個容器將在classpath裡找bean配置。

    WebXmlApplicationContext:此容器載入一個XML檔案,此檔案定義了一個WEB應用的所有bean。

  10. 什麼是Spring的依賴注入?

    所謂依賴注入,即元件之間的依賴關係由容器在應用系統執行期來決定,也就是由容器動態地將某種依賴關係的目標物件例項注入到應用系統中的各個關聯的元件之中。

  11. 有哪些不同型別的依賴注入實現方式?

    依賴注入是時下最流行的IoC實現方式,依賴注入分為介面注入,Setter方法注入和構造器注入

  12. 構造器依賴注入和 Setter方法注入的區別

    建構函式注入 setter 注入
    沒有部分注入 有部分注入
    不會覆蓋 setter 屬性 會覆蓋 setter 屬性
    任意修改都會建立一個新例項 任意修改不會建立一個新例項
    適用於設定很多屬性 適用於設定少量屬性
  13. 什麼是Spring beans?

    Spring beans 是那些形成Spring應用的主幹的java物件。它們被Spring IOC容器初始化,裝配,和管理。這些beans通過容器中配置的元資料建立。

  14. 一個 Spring Bean 定義 包含什麼?

    一個Spring Bean 的定義包含容器必知的所有配置元資料,包括如何建立一個bean,它的生命週期詳情及它的依賴。

  15. 如何給Spring 容器提供配置元資料?Spring有幾種配置方式

    • XML配置檔案。
    • 基於註解的配置。
    • 基於java的配置。
  16. Spring支援的幾種bean的作用域

    • singleton : bean在每個Spring ioc 容器中只有一個例項。
    • prototype:一個bean的定義可以有多個例項。
    • request:每次http請求都會建立一個bean,該作用域僅在基於web的Spring ApplicationContext情形下有效。
    • session:在一個HTTP Session中,一個bean定義對應一個例項。該作用域僅在基於web的Spring ApplicationContext情形下有效。
    • global-session:在一個全域性的HTTP Session中,一個bean定義對應一個例項。該作用域僅在基於web的Spring ApplicationContext情形下有效。
  17. Spring框架中的單例bean是執行緒安全的嗎?

    不是,Spring框架中的單例bean不是執行緒安全的。

    spring 中的 bean 預設是單例模式,spring 框架並沒有對單例 bean 進行多執行緒的封裝處理。

  18. Spring如何處理執行緒併發問題?

    在一般情況下,只有無狀態的Bean才可以在多執行緒環境下共享,在Spring中,絕大部分Bean都可以宣告為singleton作用域,因為Spring對一些Bean中非執行緒安全狀態採用ThreadLocal進行處理,解決執行緒安全問題。

  19. 解釋Spring框架中bean的生命週期

    1. Spring對bean進行例項化;
    2. Spring將值和bean的引用注入到bean對應的屬性中;
    3. 如果bean實現了BeanNameAware介面,Spring將bean的ID傳遞給setBean-Name()方法;
    4. 如果bean實現了BeanFactoryAware介面,Spring將呼叫setBeanFactory()方法,將BeanFactory容器例項傳入;
    5. 如果bean實現了ApplicationContextAware介面,Spring將呼叫setApplicationContext()方法,將bean所在的應用上下文的引用傳入進來;
    6. 如果bean實現了BeanPostProcessor介面,Spring將呼叫它們的post-ProcessBeforeInitialization()方法;
    7. 如果bean實現了InitializingBean介面,Spring將呼叫它們的after-PropertiesSet()方法。類似地,如果bean使用initmethod聲明瞭初始化方法,該方法也會被呼叫;
    8. 如果bean實現了BeanPostProcessor介面,Spring將呼叫它們的post-ProcessAfterInitialization()方法;
    9. 此時,bean已經準備就緒,可以被應用程式使用了,它們將一直駐留在應用上下文中,直到該應用上下文被銷燬;
    10. 如果bean實現了DisposableBean介面,Spring將呼叫它的destroy()介面方法。同樣,如果bean使用destroy-method聲明瞭銷燬方法,該方法也會被呼叫。
    11. 現在你已經瞭解瞭如何建立和載入一個Spring容器。但是一個空的容器並沒有太大的價值,在你把東西放進去之前,它裡面什麼都沒有。為了從Spring的DI(依賴注入)中受益,我們必須將應用物件裝配進Spring容器中。
  20. Spring支援的事務管理型別, spring 事務實現方式有哪些?

    程式設計式事務管理:這意味你通過程式設計的方式管理事務,給你帶來極大的靈活性,但是難維護。

    宣告式事務管理:這意味著你可以將業務程式碼和事務管理分離,你只需用註解和XML配置來管理事務。

  21. 說一下Spring的事務傳播行為

    ① PROPAGATION_REQUIRED:如果當前沒有事務,就建立一個新事務,如果當前存在事務,就加入該事務,該設定是最常用的設定。

    ② PROPAGATION_SUPPORTS:支援當前事務,如果當前存在事務,就加入該事務,如果當前不存在事務,就以非事務執行。

    ③ PROPAGATION_MANDATORY:支援當前事務,如果當前存在事務,就加入該事務,如果當前不存在事務,就丟擲異常。

    ④ PROPAGATION_REQUIRES_NEW:建立新事務,無論當前存不存在事務,都建立新事務。

    ⑤ PROPAGATION_NOT_SUPPORTED:以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。

    ⑥ PROPAGATION_NEVER:以非事務方式執行,如果當前存在事務,則丟擲異常。

    ⑦ PROPAGATION_NESTED:如果當前存在事務,則在巢狀事務內執行。如果當前沒有事務,則按REQUIRED屬性執行。

  22. 說一下 spring 的事務隔離?

    spring 有五大隔離級別,預設值為 ISOLATION_DEFAULT(使用資料庫的設定),其他四個隔離級別和資料庫的隔離級別一致:

    1. ISOLATION_DEFAULT:用底層資料庫的設定隔離級別,資料庫設定的是什麼我就用什麼;
    2. ISOLATION_READ_UNCOMMITTED:未提交讀,最低隔離級別、事務未提交前,就可被其他事務讀取(會出現幻讀、髒讀、不可重複讀);
    3. ISOLATION_READ_COMMITTED:提交讀,一個事務提交後才能被其他事務讀取到(會造成幻讀、不可重複讀),SQL server 的預設級別;
    4. ISOLATION_REPEATABLE_READ:可重複讀,保證多次讀取同一個資料時,其值都和事務開始時候的內容是一致,禁止讀取到別的事務未提交的資料(會造成幻讀),MySQL 的預設級別;
    5. ISOLATION_SERIALIZABLE:序列化,代價最高最可靠的隔離級別,該隔離級別能防止髒讀、不可重複讀、幻讀。

    髒讀 :表示一個事務能夠讀取另一個事務中還未提交的資料。比如,某個事務嘗試插入記錄 A,此時該事務還未提交,然後另一個事務嘗試讀取到了記錄 A。

    不可重複讀 :是指在一個事務內,多次讀同一資料。

    幻讀 :指同一個事務內多次查詢返回的結果集不一樣。比如同一個事務 A 第一次查詢時候有 n 條記錄,但是第二次同等條件下查詢卻有 n+1 條記錄,這就好像產生了幻覺。發生幻讀的原因也是另外一個事務新增或者刪除或者修改了第一個事務結果集裡面的資料,同一個記錄的資料內容被修改了,所有資料行的記錄就變多或者變少了。

  23. 什麼是AOP

    AOP,一般稱為面向切面程式設計,作為面向物件的一種補充,用於將那些與業務無關,但卻對多個物件產生影響的公共行為和邏輯,抽取並封裝為一個可重用的模組,這個模組被命名為“切面”(Aspect),減少系統中的重複程式碼,降低了模組間的耦合度,同時提高了系統的可維護性。可用於許可權認證、日誌、事務處理等。

  24. Spring AOP and AspectJ AOP 有什麼區別?AOP 有哪些實現方式?

    AOP實現的關鍵在於 代理模式,AOP代理主要分為靜態代理和動態代理。靜態代理的代表為AspectJ;動態代理則以Spring AOP為代表。

    • AspectJ是靜態代理的增強,所謂靜態代理,就是AOP框架會在編譯階段生成AOP代理類,因此也稱為編譯時增強,他會在編譯階段將AspectJ(切面)織入到Java位元組碼中,執行的時候就是增強之後的AOP物件。

    • Spring AOP使用的動態代理,所謂的動態代理就是說AOP框架不會去修改位元組碼,而是每次執行時在記憶體中臨時為方法生成一個AOP物件,這個AOP物件包含了目標物件的全部方法,並且在特定的切點做了增強處理,並回調原物件的方法。

  25. JDK動態代理和CGLIB動態代理的區別

    • JDK動態代理只提供介面的代理,不支援類的代理。核心InvocationHandler介面和Proxy類,InvocationHandler 通過invoke()方法反射來呼叫目標類中的程式碼,動態地將橫切邏輯和業務編織在一起;接著,Proxy利用 InvocationHandler動態建立一個符合某一介面的的例項, 生成目標類的代理物件。
    • CGLIB,是一個程式碼生成的類庫,可以在執行時動態的生成指定類的一個子類物件,並覆蓋其中特定方法並新增增強程式碼,從而實現AOP。CGLIB是通過繼承的方式做的動態代理,因此如果某個類被標記為final,那麼它是無法使用CGLIB做動態代理的。

    靜態代理與動態代理區別在於生成AOP代理物件的時機不同,相對來說AspectJ的靜態代理方式具有更好的效能,但是AspectJ需要特定的編譯器進行處理,而Spring AOP則無需特定的編譯器處理。

  26. 解釋一下Spring AOP裡面的幾個名詞

    1. 切面(Aspect):切面是通知和切點的結合。通知和切點共同定義了切面的全部內容。 在Spring AOP中,切面可以使用通用類(基於模式的風格) 或者在普通類中以 @AspectJ 註解來實現。
    2. 連線點(Join point):指方法,在Spring AOP中,一個連線點 總是 代表一個方法的執行。 應用可能有數以千計的時機應用通知。這些時機被稱為連線點。連線點是在應用執行過程中能夠插入切面的一個點。這個點可以是呼叫方法時、丟擲異常時、甚至修改一個欄位時。切面程式碼可以利用這些點插入到應用的正常流程之中,並新增新的行為。
    3. 通知(Advice):在AOP術語中,切面的工作被稱為通知。
    4. 切入點(Pointcut):切點的定義會匹配通知所要織入的一個或多個連線點。我們通常使用明確的類和方法名稱,或是利用正則表示式定義所匹配的類和方法名稱來指定這些切點。
    5. 引入(Introduction):引入允許我們向現有類新增新方法或屬性。
    6. 目標物件(Target Object): 被一個或者多個切面(aspect)所通知(advise)的物件。它通常是一個代理物件。也有人把它叫做 被通知(adviced) 物件。 既然Spring AOP是通過執行時代理實現的,這個物件永遠是一個 被代理(proxied) 物件。
    7. 織入(Weaving):織入是把切面應用到目標物件並建立新的代理物件的過程。
  27. Spring通知有哪些型別?

    1. 前置通知(Before):在目標方法被呼叫之前呼叫通知功能;
    2. 後置通知(After):在目標方法完成之後呼叫通知,此時不會關心方法的輸出是什麼;
    3. 返回通知(After-returning ):在目標方法成功執行之後呼叫通知;
    4. 異常通知(After-throwing):在目標方法丟擲異常後呼叫通知;
    5. 環繞通知(Around):通知包裹了被通知的方法,在被通知的方法呼叫之前和呼叫之後執行自定義的行為。
  28. 請解釋下Spring的IOC

    所以控制反轉IoC(Inversion of Control)是說建立物件的控制權進行轉移,以前建立物件的主動權和建立時機是由自己把控的,而現在這種權力轉移到第三方,比如轉移交給了IoC容器,它就是一個專門用來建立物件的工廠,你要什麼物件,它就給你什麼物件,有了 IoC容器,依賴關係就變了,原先的依賴關係就沒了,它們都依賴IoC容器了,通過IoC容器來建立它們之間的關係。

  29. 將Spring配置到你的應用中共有幾種方法

    1. 基於xml配置
    2. 基於註解配置
    3. 基於java配置
  30. 什麼是基於XML配置

    SpringXML 配置的主要目的時候是使所有的 Spring 元件都可以用 xml 檔案的形式來進行配置。這 意味著不會出現其他的 Spring 配置型別, Spring 的 XML 配置方式是使用被 Spring 名稱空間的所支援的一系列的 XML 標籤來實現的。 Spring 有以下主要的名稱空間:context、beans、jdbc、tx、aop、mvc 和 aso。

  31. 什麼是基於java配置

    Spring 對 Java 配置的支援是由@Configuration 註解和@Bean 註解來實現的。由@Bean 註解 的方法將會例項化、配置和初始化一個 新物件,這個物件將由 Spring 的 IoC 容器來管理。 @Bean 宣告所起到的作用與 元素類似。被 @Configuration 所註解的類則表示這個類 的主要目的是作為 bean 定義的資源。被@Configuration 宣告的類可以通過在同一個類的 內部調 用@bean 方法來設定嵌入 bean 的依賴關係。

  32. 什麼是基於註解配置

    Spring 在 2.5 版本以後開始支援用註解的方式來配置依賴注入。可以用註解的方式來替代 XML 方 式的 bean 描述,可以將 bean 描述轉移到元件類的 內部,只需要在相關類上、方法上或者欄位聲 明上使用註解即可。註解注入將會被容器在 XML 注入之前被處理,所以後者會覆蓋掉前者對於同一 個屬性的處理結 果。
    註解裝配在 Spring 中是預設關閉的。所以需要在 Spring 檔案中配置一下才能使用基於註解的裝配 模式。

SpringMVC

  1. Spring MVC的主要元件?

    • 前端控制器 DispatcherServlet

      • 作用:接收請求、響應結果,相當於轉發器,有了DispatcherServlet 就減少了其它元件之間的耦合度。
    • 處理器對映器HandlerMapping

      • 作用:根據請求的URL來查詢Handler
    • 處理器介面卡HandlerAdapter

      • 作用:根據url對應的地址去執行Handler。處理器Handler(需要程式設計師開發)
    • 檢視解析器 ViewResolver

      • 作用:進行檢視的解析,根據檢視邏輯名解析成真正的檢視(view)
    • 檢視View

      • View是一個介面, 它的實現類支援不同的檢視型別(jsp,freemarker,pdf等等)
  2. 請描述Spring MVC的工作流程?描述一下 DispatcherServlet 的工作流程?

    1. 使用者傳送請求至前端控制器DispatcherServlet;
    2. DispatcherServlet收到請求後,呼叫HandlerMapping處理器對映器,請求獲取Handle;
    3. 處理器對映器根據請求url找到具體的處理器,生成處理器物件及處理器攔截器(如果有則生成)一併返回給DispatcherServlet;
    4. DispatcherServlet 呼叫 HandlerAdapter處理器介面卡;
    5. HandlerAdapter 經過適配呼叫 具體處理器(Handler,也叫後端控制器);
    6. Handler執行完成返回ModelAndView;
    7. HandlerAdapter將Handler執行結果ModelAndView返回給DispatcherServlet;
    8. DispatcherServlet將ModelAndView傳給ViewResolver檢視解析器進行解析;
    9. ViewResolver解析後返回具體View;
    10. DispatcherServlet對View進行渲染檢視
    11. DispatcherServlet響應使用者。

    前端控制器-->處理器對映器-->處理器介面卡-->處理器Controller-->ModelAndView-->檢視解析器-->View-->客戶端

  3. Spring MVC常用的註解有哪些?

    @RequestMapping:用於處理請求 url 對映的註解,可用於類或方法上。用於類上,則表示類中的所有響應請求的方法都是以該地址作為父路徑。

    @RequestBody:註解實現接收http請求的json資料,將json轉換為java物件。

    @ResponseBody:註解實現將conreoller方法返回物件轉化為json物件響應給客戶。

  4. Spring MVC中函式的返回值是什麼?

    返回值可以有很多型別,有String, ModelAndView。ModelAndView類把檢視和資料都合併的一起的,但一般用String比較好。

  5. Spring MVC裡面攔截器是怎麼寫的

    有兩種寫法,一種是實現HandlerInterceptor介面,另外一種是繼承介面卡類,接著在介面方法當中,實現處理邏輯;然後在Spring MVC的配置檔案中配置攔截器即可

Mybatis

  1. MyBatis程式設計步驟是什麼樣的?

    1. 建立SqlSessionFactory
    2. 通過SqlSessionFactory建立SqlSession
    3. 通過sqlsession執行資料庫操作
    4. 呼叫session.commit()提交事務
    5. 呼叫session.close()關閉會話
  2. 請說說MyBatis的工作原理

    1. 讀取 MyBatis 配置檔案:mybatis-config.xml 為 MyBatis 的全域性配置檔案,配置了 MyBatis 的執行環境等資訊,例如資料庫連線資訊。
    2. 載入對映檔案。對映檔案即 SQL 對映檔案,該檔案中配置了操作資料庫的 SQL 語句,需要在 MyBatis 配置檔案 mybatis-config.xml 中載入。mybatis-config.xml 檔案可以載入多個對映檔案,每個檔案對應資料庫中的一張表。
    3. 構造會話工廠:通過 MyBatis 的環境等配置資訊構建會話工廠 SqlSessionFactory。
    4. 建立會話物件:由會話工廠建立 SqlSession 物件,該物件中包含了執行 SQL 語句的所有方法。
    5. Executor 執行器:MyBatis 底層定義了一個 Executor 介面來操作資料庫,它將根據 SqlSession 傳遞的引數動態地生成需要執行的 SQL 語句,同時負責查詢快取的維護。
    6. MappedStatement 物件:在 Executor 介面的執行方法中有一個 MappedStatement 型別的引數,該引數是對對映資訊的封裝,用於儲存要對映的 SQL 語句的 id、引數等資訊。
    7. 輸入引數對映:輸入引數型別可以是 Map、List 等集合型別,也可以是基本資料型別和 POJO 型別。輸入引數對映過程類似於 JDBC 對 preparedStatement 物件設定引數的過程。
    8. 輸出結果對映:輸出結果型別可以是 Map、 List 等集合型別,也可以是基本資料型別和 POJO 型別。輸出結果對映過程類似於 JDBC 對結果集的解析過程。
  3. Mybatis都有哪些Executor執行器?它們之間的區別是什麼?

    Mybatis有三種基本的Executor執行器,SimpleExecutor、ReuseExecutor、BatchExecutor。

    SimpleExecutor:每執行一次update或select,就開啟一個Statement物件,用完立刻關閉Statement物件。

    ReuseExecutor:執行update或select,以sql作為key查詢Statement物件,存在就使用,不存在就建立,用完後,不關閉Statement物件,而是放置於Map<String, Statement>內,供下一次使用。簡言之,就是重複使用Statement物件。

    BatchExecutor:執行update(沒有select,JDBC批處理不支援select),將所有sql都新增到批處理中(addBatch()),等待統一執行(executeBatch()),它快取了多個Statement物件,每個Statement物件都是addBatch()完畢後,等待逐一執行executeBatch()批處理。與JDBC批處理相同。

    作用範圍:Executor的這些特點,都嚴格限制在SqlSession生命週期範圍內。

  4. Mybatis是否支援延遲載入?如果支援,它的實現原理是什麼?

    Mybatis僅支援association關聯物件和collection關聯集合物件的延遲載入,association指的就是一對一,collection指的就是一對多查詢。在Mybatis配置檔案中,可以配置是否啟用延遲載入lazyLoadingEnabled=true|false。

    它的原理是,使用CGLIB建立目標物件的代理物件,當呼叫目標方法時,進入攔截器方法,比如呼叫a.getB().getName(),攔截器invoke()方法發現a.getB()是null值,那麼就會單獨傳送事先儲存好的查詢關聯B物件的sql,把B查詢上來,然後呼叫a.setB(b),於是a的物件b屬性就有值了,接著完成a.getB().getName()方法的呼叫。這就是延遲載入的基本原理。

  5. #{}和${}的區別

    • #{}是佔位符,預編譯處理;${}是拼接符,字串替換,沒有預編譯處理。
    • Mybatis在處理#{}時,#{}傳入引數是以字串傳入,會將SQL中的#{}替換為?號,呼叫PreparedStatement的set方法來賦值。
    • Mybatis在處理時,是原值傳入,就是把{}時,是原值傳入,就是把時,是原值傳入,就是把{}替換成變數的值,相當於JDBC中的Statement編譯
    • 變數替換後,#{} 對應的變數自動加上單引號 ‘’;變數替換後,${} 對應的變數不會加上單引號 ‘’
    • #{} 可以有效的防止SQL注入,提高系統安全性;${} 不能防止SQL 注入
    • #{} 的變數替換是在DBMS 中;${} 的變數替換是在 DBMS 外
  6. 模糊查詢like語句該怎麼寫

    (1)'%${question}%'可能引起SQL注入,不推薦

    (2)"%"#{question}"%" 注意:因為#{…}解析成sql語句時候,會在變數外側自動加單引號’ ',所以這裡 % 需要使用雙引號" ",不能使用單引號 ’ ',不然會查不到任何結果。

    (3)CONCAT(’%’,#{question},’%’) 使用CONCAT()函式,推薦

    (4)使用bind標籤

    <select id="listUserLikeUsername" resultType="com.jourwon.pojo.User">
      <bind name="pattern" value="'%' + username + '%'" />
      select id,sex,age,username,password from person where username LIKE #{pattern}
    </select>
    
  7. 如何獲取生成的主鍵

    設定 useGeneratedKeys="true"

  8. Mybatis是如何將sql執行結果封裝為目標物件並返回的?都有哪些對映形式?

    第一種是使用<resultMap>標籤,逐一定義列名和物件屬性名之間的對映關係。

    第二種是使用sql列的別名功能,將列別名書寫為物件屬性名

  9. Xml對映檔案中,除了常見的select|insert|updae|delete標籤之外,還有哪些標籤?

    還有很多其他的標籤,<resultMap><parameterMap><sql><include><selectKey>,加上動態sql的9個標籤,trim|where|set|foreach|if|choose|when|otherwise|bind等,其中<sql>為sql片段標籤,通過<include>標籤引入sql片段,<selectKey>為不支援自增的主鍵生成策略標籤。

  10. MyBatis實現一對一,一對多有幾種方式,怎麼操作的?

    有聯合查詢和巢狀查詢。聯合查詢是幾個表聯合查詢,只查詢一次,通過在resultMap裡面的association,collection節點配置一對一,一對多的類就可以完成

    巢狀查詢是先查一個表,根據這個表裡面的結果的外來鍵id,去再另外一個表裡面查詢資料,也是通過配置association,collection,但另外一個表的查詢通過select節點配置。

  11. Mybatis動態sql是做什麼的?都有哪些動態sql?能簡述一下動態sql的執行原理不?

    Mybatis動態sql可以讓我們在Xml對映檔案內,以標籤的形式編寫動態sql,完成邏輯判斷和動態拼接sql的功能,Mybatis提供了9種動態sql標籤trim|where|set|foreach|if|choose|when|otherwise|bind。

    其執行原理為,使用OGNL從sql引數物件中計算表示式的值,根據表示式的值動態拼接sql,以此來完成動態sql的功能。

  12. Mybatis是如何進行分頁的?分頁外掛的原理是什麼?

    Mybatis使用RowBounds物件進行分頁,它是針對ResultSet結果集執行的記憶體分頁,而非物理分頁,可以在sql內直接書寫帶有物理分頁的引數來完成物理分頁功能,也可以使用分頁外掛來完成物理分頁。

    分頁外掛的基本原理是使用Mybatis提供的外掛介面,實現自定義外掛,在外掛的攔截方法內攔截待執行的sql,然後重寫sql,根據dialect方言,新增對應的物理分頁語句和物理分頁引數。

  13. Mybatis的一級、二級快取

    • 一級快取: 基於 PerpetualCache 的 HashMap 本地快取,其儲存作用域為 Session,當 Session flush 或 close 之後,該 Session 中的所有 Cache 就將清空,預設開啟一級快取。

    • 二級快取與一級快取其機制相同,預設也是採用 PerpetualCache,HashMap 儲存,不同在於其儲存作用域為 Mapper(Namespace),並且可自定義儲存源,如 Ehcache。預設不開啟二級快取,要開啟二級快取,使用二級快取屬性類需要實現Serializable序列化介面(可用來儲存物件的狀態),可在它的對映檔案中配置<cache/>

    • 對於快取資料更新機制,當某一個作用域(一級快取 Session/二級快取Namespaces)的進行了C/U/D 操作後,預設該作用域下所有 select 中的快取將被 clear。

SpringBoot

  1. Spring Boot 有哪些優點?

    1. 容易上手,提升開發效率,為 Spring 開發提供一個更快、更廣泛的入門體驗。
    2. 開箱即用,遠離繁瑣的配置。
    3. 提供了一系列大型專案通用的非業務性功能,例如:內嵌伺服器、安全管理、執行資料監控、執行狀況檢查和外部化配置等。
    4. 沒有程式碼生成,也不需要XML配置。
    5. 避免大量的 Maven 匯入和各種版本衝突。
  2. Spring Boot 的核心註解是哪個?它主要由哪幾個註解組成的?

    啟動類上面的註解是@SpringBootApplication,它也是 Spring Boot 的核心註解,主要組合包含了以下 3 個註解:

    • @SpringBootConfiguration:組合了 @Configuration 註解,實現配置檔案的功能。

    • @EnableAutoConfiguration:開啟自動配置的功能,也可以關閉某個自動配置的選項,如關閉資料來源自動配置功能: @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })。

    • @ComponentScan:Spring元件掃描。

  3. Spring Boot 自動配置原理是什麼?

    註解 @EnableAutoConfiguration, @Configuration, @ConditionalOnClass 就是自動配置的核心,

    @EnableAutoConfiguration 給容器匯入META-INF/spring.factories 裡定義的自動配置類。

    篩選有效的自動配置類。

    每一個自動配置類結合對應的 xxxProperties.java 讀取配置檔案進行自動配置功能

  4. 什麼是 YAML?

    YAML 是一種人類可讀的資料序列化語言。它通常用於配置檔案。與屬性檔案相比,如果我們想要在配置檔案中新增複雜的屬性,YAML 檔案就更加結構化,而且更少混淆。可以看出 YAML 具有分層配置資料。

  5. YAML 配置的優勢在哪裡 ?

    1. 配置有序,在一些特殊的場景下,配置有序很關鍵
    2. 支援陣列,陣列中的元素可以是基本資料型別也可以是物件
    3. 簡潔

    相比 properties 配置檔案,YAML 還有一個缺點,就是不支援 @PropertySource 註解匯入自定義的 YAML 配置。

  6. Spring Boot 是否可以使用 XML 配置 ?

    Spring Boot 推薦使用 Java 配置而非 XML 配置,但是 Spring Boot 中也可以使用 XML 配置,通過 @ImportResource 註解可以引入一個 XML 配置。

  7. spring boot 核心配置檔案是什麼?bootstrap.properties 和 application.properties 有何區別 ?

    • bootstrap (. yml 或者 . properties):boostrap 由父 ApplicationContext 載入的,比 applicaton 優先載入,配置在應用程式上下文的引導階段生效。一般來說我們在 Spring Cloud Config 或者 Nacos 中會用到它。且 boostrap 裡面的屬性不能被覆蓋;
    • application (. yml 或者 . properties): 由ApplicatonContext 載入,用於 spring boot 專案的自動化配置。
  8. 如何實現 Spring Boot 應用程式的安全性?

    為了實現 Spring Boot 的安全性,我們使用 spring-boot-starter-security 依賴項,並且必須新增安全配置。它只需要很少的程式碼。配置類將必須擴充套件WebSecurityConfigurerAdapter 並覆蓋其方法。

  9. Spring Boot 中如何解決跨域問題 ?

    跨域可以在前端通過 JSONP 來解決,但是 JSONP 只可以傳送 GET 請求,無法傳送其他型別的請求,在 RESTful 風格的應用中,就顯得非常雞肋,因此我們推薦在後端通過 (CORS,Cross-origin resource sharing) 來解決跨域問題。這種解決方案並非 Spring Boot 特有的,在傳統的 SSM 框架中,就可以通過 CORS 來解決跨域問題,只不過之前我們是在 XML 檔案中配置 CORS ,現在可以通過實現WebMvcConfigurer介面然後重寫addCorsMappings方法解決跨域問題。

    @Configuration
    public class CorsConfig implements WebMvcConfigurer {
    
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**")
                    .allowedOrigins("*")
                    .allowCredentials(true)
                    .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
                    .maxAge(3600);
        }
    
    }
    

    專案中前後端分離部署,所以需要解決跨域的問題。
    我們使用cookie存放使用者登入的資訊,在spring攔截器進行許可權控制,當權限不符合時,直接返回給使用者固定的json結果。
    當用戶登入以後,正常使用;當用戶退出登入狀態時或者token過期時,由於攔截器和跨域的順序有問題,出現了跨域的現象。
    我們知道一個http請求,先走filter,到達servlet後才進行攔截器的處理,如果我們把cors放在filter裡,就可以優先於許可權攔截器執行。

    @Configuration
    public class CorsConfig {
    
        @Bean
        public CorsFilter corsFilter() {
            CorsConfiguration corsConfiguration = new CorsConfiguration();
            corsConfiguration.addAllowedOrigin("*");
            corsConfiguration.addAllowedHeader("*");
            corsConfiguration.addAllowedMethod("*");
            corsConfiguration.setAllowCredentials(true);
            UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
            urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
            return new CorsFilter(urlBasedCorsConfigurationSource);
        }
    
    }
    
  10. spring-boot-starter-parent 有什麼用 ?

    1. 定義了 Java 編譯版本為 1.8 。
    2. 使用 UTF-8 格式編碼。
    3. 繼承自 spring-boot-dependencies,這個裡邊定義了依賴的版本,也正是因為繼承了這個依賴,所以我們在寫依賴時才不需要寫版本號。
    4. 執行打包操作的配置。
    5. 自動化的資源過濾。
    6. 自動化的外掛配置。
    7. 針對 application.properties 和 application.yml 的資源過濾,包括通過 profile 定義的不同環境的配置檔案,例如 application-dev.properties 和 application-dev.yml。
  11. 執行 Spring Boot 有哪幾種方式?

    1. 打包用命令或者放到容器中執行
    2. 用 Maven/ Gradle 外掛執行
    3. 直接執行 main 方法執行
  12. Spring Boot 中如何實現定時任務 ?

    定時任務也是一個常見的需求,Spring Boot 中對於定時任務的支援主要還是來自 Spring 框架。

    在 Spring Boot 中使用定時任務主要有兩種不同的方式,一個就是使用 Spring 中的 @Scheduled 註解,另一個則是使用第三方框架 Quartz。

    使用 Spring 中的 @Scheduled 的方式主要通過 @Scheduled 註解來實現。

    使用 Quartz ,則按照 Quartz 的方式,定義 Job 和 Trigger 即可。

SpringCloud

  1. 什麼是Spring Cloud

    微服務只是一種專案的架構方式,或者說是一種概念,Spring-Cloud便是對這種技術的實現,對微服務面臨的問題進行統一的封裝處理

    優點:

    • 產出於Spring大家族,Spring在企業級開發框架中無人能敵,來頭很大,可以保證後續的更新、完善
    • 元件豐富,功能齊全。Spring Cloud 為微服務架構提供了非常完整的支援。例如、配置管理、服務發現、斷路器、微服務閘道器等;
    • Spring Cloud 社群活躍度很高,教程很豐富,遇到問題很容易找到解決方案
    • 服務拆分粒度更細,耦合度比較低,有利於資源重複利用,有利於提高開發效率
    • 可以更精準的制定優化服務方案,提高系統的可維護性
    • 減輕團隊的成本,可以並行開發,不用關注其他人怎麼開發,先關注自己的開發
    • 微服務可以是跨平臺的,可以用任何一種語言開發
    • 適於網際網路時代,產品迭代週期更短

    缺點:

    • 微服務過多,治理成本高,不利於維護系統
    • 分散式系統開發的成本高(容錯,分散式事務等)對團隊挑戰大
  2. Spring Cloud Netflix

    Netflix OSS 開源元件整合,包括Eureka、Hystrix、Ribbon、Feign、Zuul等核心元件。

    • Eureka:服務治理元件,包括服務端的註冊中心和客戶端的服務發現機制;
    • Ribbon:負載均衡的服務呼叫元件,具有多種負載均衡呼叫策略;
    • Hystrix:服務容錯元件,實現了斷路器模式,為依賴服務的出錯和延遲提供了容錯能力;
    • Feign:基於Ribbon和Hystrix的宣告式服務呼叫元件;
    • Zuul:API閘道器元件,對請求提供路由及過濾功能。
  3. SpringBoot和SpringCloud的區別?

    SpringBoot專注於快速方便的開發單個個體微服務。

    SpringCloud是關注全域性的微服務協調整理治理框架,它將SpringBoot開發的一個個單體微服務整合並管理起來,

    為各個微服務之間提供,配置管理、服務發現、斷路器、路由、微代理、事件匯流排、全域性鎖、決策競選、分散式會話等等整合服務

    SpringBoot可以離開SpringCloud獨立使用開發專案, 但是SpringCloud離不開SpringBoot ,屬於依賴的關係

    SpringBoot專注於快速、方便的開發單個微服務個體,SpringCloud關注全域性的服務治理框架。

  4. Spring Cloud 和dubbo區別?

    • 服務呼叫方式 dubbo是RPC springcloud Rest Api

    • 註冊中心,dubbo 是zookeeper springcloud是eureka,也可以是zookeeper

    • 服務閘道器,dubbo本身沒有實現,只能通過其他第三方技術整合,springcloud有Zuul路由閘道器,作為路由伺服器,進行消費者的請求分發,springcloud支援斷路器,與git完美整合配置檔案支援版本控制,事物匯流排實現配置檔案的更新與服務自動裝配等等一系列的微服務架構要素。

  5. 什麼是Eureka

    Eureka作為SpringCloud的服務註冊功能伺服器,他是服務註冊中心,系統中的其他服務使用Eureka的客戶端將其連線到Eureka Service中,並且保持心跳,這樣工作人員可以通過Eureka Service來監控各個微服務是否執行正常。

  6. 什麼是Eureka的自我保護模式

    預設情況下,如果Eureka Service在一定時間內沒有接收到某個微服務的心跳,Eureka Service會進入自我保護模式,在該模式下Eureka Service會保護服務登錄檔中的資訊,不在刪除登錄檔中的資料,當網路故障恢復後,Eureka Servic 節點會自動退出自我保護模式

  7. Eureka和ZooKeeper都可以提供服務註冊與發現的功能,請說說兩個的區別

    1. ZooKeeper中的節點服務掛了就要選舉
      在選舉期間註冊服務癱瘓,雖然服務最終會恢復,但是選舉期間不可用的,
      選舉就是改微服務做了叢集,必須有一臺主其他的都是從
    2. Eureka各個節點是平等關係,伺服器掛了沒關係,只要有一臺Eureka就可以保證服務可用,資料都是最新的。
      如果查詢到的資料並不是最新的,就是因為Eureka的自我保護模式導致的
    3. Eureka本質上是一個工程,而ZooKeeper只是一個程序
    4. Eureka可以很好的應對因網路故障導致部分節點失去聯絡的情況,而不會像ZooKeeper 一樣使得整個註冊系統癱瘓
  8. 什麼是Zuul閘道器?

    Zuul是對SpringCloud提供的成熟對的路由方案,他會根據請求的路徑不同,閘道器會定位到指定的微服務,並代理請求到不同的微服務介面,他對外隱蔽了微服務的真正介面地址。

  9. 閘道器與過濾器有什麼區別

    閘道器是對所有服務的請求進行分析過濾,過濾器是對單個服務而言。

  10. Zuul與Nginx有什麼區別?

    Zuul是java語言實現的,主要為java服務提供閘道器服務,尤其在微服務架構中可以更加靈活的對閘道器進行操作。Nginx是使用C語言實現,效能高於Zuul,但是實現自定義操作需要熟悉lua語言,對程式設計師要求較高,可以使用Nginx做Zuul叢集。

  11. 既然Nginx可以實現閘道器?為什麼還需要使用Zuul框架

    Zuul是SpringCloud整合的閘道器,使用Java語言編寫,可以對SpringCloud架構提供更靈活的服務。

  12. Ribbon是什麼?

    • Ribbon是Netflix釋出的開源專案,主要功能是提供客戶端的軟體負載均衡演算法
    • Ribbon客戶端元件提供一系列完善的配置項,如連線超時,重試等。簡單的說,就是在配置檔案中列出後面所有的機器,Ribbon會自動的幫助你基於某種規則(如簡單輪詢,隨即連線等)去連線這些機器。我們也很容易使用Ribbon實現自定義的負載均衡演算法。
  13. Ribbon底層實現原理

    • Ribbon使用discoveryClient從註冊中心讀取目標服務資訊,對同一介面請求進行計數,使用%取餘演算法獲取目標服務叢集索引,返回獲取到的目標服務資訊。
  14. @LoadBalanced註解的作用

    開啟客戶端負載均衡。

  15. 什麼是 Hystrix?

    在分散式系統,我們一定會依賴各種服務,那麼這些個服務一定會出現失敗的情況,就會導致雪崩,Hystrix就是這樣的一個工具,防雪崩利器,它具有服務降級,服務熔斷,服務隔離,監控等一些防止雪崩的技術。

    Hystrix有四種防雪崩方式:

    • 服務降級:介面呼叫失敗就呼叫本地的方法返回一個空
    • 服務熔斷:介面呼叫失敗就會進入呼叫介面提前定義好的一個熔斷的方法,返回錯誤資訊
    • 服務隔離:隔離服務之間相互影響
    • 服務監控:在服務發生呼叫時,會將每秒請求數、成功請求數等執行指標記錄下來。
  16. 談談服務雪崩效應

    • 雪崩效應是在大型網際網路專案中,當某個服務發生宕機時,呼叫這個服務的其他服務也會發生宕機,大型專案的微服務之間的呼叫是互通的,這樣就會將服務的不可用逐步擴大到各個其他服務中,從而使整個專案的服務宕機崩潰.發生雪崩效應的原因有以下幾點:
      • 1.單個服務的程式碼存在bug.
      • 2請求訪問量激增導致服務發生崩潰(如大型商城的槍紅包,秒殺功能).
      • 3.伺服器的硬體故障也會導致部分服務不可用.
  17. 談談服務降級、熔斷、服務隔離

    • 服務降級:當客戶端請求伺服器端的時候,防止客戶端一直等待,不會處理業務邏輯程式碼,直接返回一個友好的提示給客戶端。
    • 服務熔斷:是在服務降級的基礎上更直接的一種保護方式,當在一個統計時間範圍內的請求失敗數量達到設定值或當前的請求錯誤率達到設定的錯誤率閾值時開啟斷路,之後的請求直接走fallback方法,在設定時間後嘗試恢復。
    • 服務隔離:是Hystrix為隔離的服務開啟一個獨立的執行緒池,這樣在高併發的情況下不會影響其他服務。服務隔離有執行緒池和訊號量兩種實現方式,一般使用執行緒池方式。
  18. 什麼是Feign?

    • Feign 是一個宣告web服務客戶端,這使得編寫web服務客戶端更容易
    • 他將我們需要呼叫的服務方法定義成抽象方法儲存在本地就可以了,不需要自己構建Http請求了,直接呼叫介面就行了,不過要注意,呼叫方法要和本地抽象方法的簽名完全一致。
  19. Ribbon和Feign呼叫服務的區別

    • 呼叫方式同:Ribbon需要我們自己構建Http請求,模擬Http請求然後通過RestTemplate發給其他服務,步驟相當繁瑣
    • 而Feign則是在Ribbon的基礎上進行了一次改進,採用介面的形式,將我們需要呼叫的服務方法定義成抽象方法儲存在本地就可以了,不需要自己構建Http請求了,直接呼叫介面就行了,不過要注意,呼叫方法要和本地抽象方法的簽名完全一致。
  20. 什麼是Spring Cloud Config?

    Spring Cloud Config為分散式系統中的外部配置提供伺服器和客戶端支援,可以方便的對微服務各個環境下的配置進行集中式管理。Spring Cloud Config分為Config Server和Config Client兩部分。Config Server負責讀取配置檔案,並且暴露Http API介面,Config Client通過呼叫Config Server的介面來讀取配置檔案。

  21. 什麼是Spring Cloud Gateway?

    • Spring Cloud Gateway是Spring Cloud官方推出的第二代閘道器框架,取代Zuul閘道器。閘道器作為流量的,在微服務系統中有著非常作用,閘道器常見的功能有路由轉發、許可權校驗、限流控制等作用。
    • 使用了一個RouteLocatorBuilder的bean去建立路由,除了建立路由RouteLocatorBuilder可以讓你新增各種predicates和filters,predicates斷言的意思,顧名思義就是根據具體的請求的規則,由具體的route去處理,filters是各種過濾器,用來對請求做各種判斷和修改。
  22. 什麼是RestTemplate?

    RestTemplate提供了多種便捷訪問遠端Http服務的方法,是一種簡單便捷的訪問restful服務模板類,是spring提供的用於訪問Rest服務的客戶端模板工具集

  23. 使用Ribbon實現客戶端負載均衡的消費者

    1、引入pom依賴

    2、啟動類Application類中的RestTemplate上加上@LoadBalanced註解即可

Redis

  1. 什麼是Redis

    Redis是一個使用 C 語言編寫的,開源的高效能非關係型的鍵值對資料庫。

    Redis 可以儲存鍵和五種不同型別的值之間的對映。鍵的型別只能為字串,值支援五種資料型別:字串、列表、集合、散列表、有序集合。

    與傳統資料庫不同的是 Redis 的資料是存在記憶體中的,所以讀寫速度非常快,因此 redis 被廣泛應用於快取方向,每秒可以處理超過 10萬次讀寫操作,是已知效能最快的Key-Value DB。另外,Redis 也經常用來做分散式鎖。除此之外,Redis 支援事務 、持久化、LUA指令碼、LRU驅動事件、多種叢集方案。

  2. Redis有哪些優缺點

    優點

    • 讀寫效能優異, Redis能讀的速度是110000次/s,寫的速度是81000次/s。
    • 支援資料持久化,支援AOF和RDB兩種持久化方式。
    • 支援事務,Redis的所有操作都是原子性的,同時Redis還支援對幾個操作合併後的原子性執行。
    • 資料結構豐富,除了支援string型別的value外還支援hash、set、zset、list等資料結構。
    • 支援主從複製,主機會自動將資料同步到從機,可以進行讀寫分離。

    缺點

    • 資料庫容量受到實體記憶體的限制,不能用作海量資料的高效能讀寫,因此Redis適合的場景主要侷限在較小資料量的高效能操作和運算上。
    • Redis 不具備自動容錯和恢復功能,主機從機的宕機都會導致前端部分讀寫請求失敗,需要等待機器重啟或者手動切換前端的IP才能恢復。
    • 主機宕機,宕機前有部分資料未能及時同步到從機,切換IP後還會引入資料不一致的問題,降低了系統的可用性。
    • Redis 較難支援線上擴容,在叢集容量達到上限時線上擴容會變得很複雜。為避免這一問題,運維人員在系統上線時必須確保有足夠的空間,這對資源造成了很大的浪費。
  3. Redis有哪些資料型別

    Redis主要有5種資料型別,包括String,List,Set,Zset,Hash,滿足大部分的使用要求

    資料型別 可以儲存的值 操作 應用場景
    STRING 字串、整數或者浮點數 對整個字串或者字串的其中一部分執行操作 對整數和浮點數執行自增或者自減操作 做簡單的鍵值對快取
    LIST 列表 從兩端壓入或者彈出元素 對單個或者多個元素進行修剪, 只保留一個範圍內的元素 儲存一些列表型的資料結構,類似粉絲列表、文章的評論列表之類的資料
    SET 無序集合 新增、獲取、移除單個元素 檢查一個元素是否存在於集合中 計算交集、並集、差集 從集合裡面隨機獲取元素 交集、並集、差集的操作,比如交集,可以把兩個人的粉絲列表整一個交集
    HASH 包含鍵值對的無序散列表 新增、獲取、移除單個鍵值對 獲取所有鍵值對 檢查某個鍵是否存在 結構化的資料,比如一個物件
    ZSET 有序集合 新增、獲取、刪除元素 根據分值範圍或者成員來獲取元素 計算一個鍵的排名 去重但可以排序,如獲取排名前幾名的使用者
  4. 什麼是Redis持久化?

    持久化就是把記憶體的資料寫到磁碟中去,防止服務宕機了記憶體資料丟失。

  5. Redis 的持久化機制是什麼?各自的優缺點?

    Redis 提供兩種持久化機制 RDB(預設) 和 AOF 機制:

    RDB:是Redis DataBase縮寫快照

    RDB是Redis預設的持久化方式。按照一定的時間將記憶體的資料以快照的形式儲存到硬碟中,對應產生的資料檔案為dump.rdb。通過配置檔案中的save引數來定義快照的週期。

    RDB優點:

    • 1、只有一個檔案 dump.rdb,方便持久化。
    • 2、容災性好,一個檔案可以儲存到安全的磁碟。
    • 3、效能最大化,fork 子程序來完成寫操作,讓主程序繼續處理命令,所以是 IO 最大化。使用單獨子程序來進行持久化,主程序不會進行任何 IO 操作,保證了 redis 的高效能
    • 4.相對於資料集大時,比 AOF 的啟動效率更高。

    缺點:

    • 1、資料安全性低。RDB 是間隔一段時間進行持久化,如果持久化之間 redis 發生故障,會發生資料丟失。所以這種方式更適合資料要求不嚴謹的時候)
    • 2、AOF(Append-only file)持久化方式: 是指所有的命令列記錄以 redis 命令請 求協議的格式完全持久化儲存)儲存為 aof 檔案。

    AOF:持久化

    AOF持久化(即Append Only File持久化),則是將Redis執行的每次寫命令記錄到單獨的日誌檔案中,當重啟Redis會重新將持久化的日誌中檔案恢復資料。

    當兩種方式同時開啟時,資料恢復Redis會優先選擇AOF恢復。

    優點:

    • 1、資料安全,aof 持久化可以配置 appendfsync 屬性,有 always,每進行一次 命令操作就記錄到 aof 檔案中一次。
    • 2、通過 append 模式寫檔案,即使中途伺服器宕機,可以通過 redis-check-aof 工具解決資料一致性問題。
    • 3、AOF 機制的 rewrite 模式。AOF 檔案沒被 rewrite 之前(檔案過大時會對命令 進行合併重寫),可以刪除其中的某些命令(比如誤操作的 flushall))

    缺點:

    • 1、AOF 檔案比 RDB 檔案大,且恢復速度慢。
    • 2、資料集大的時候,比 rdb 啟動效率低。

    優缺點是什麼?

    • AOF檔案比RDB更新頻率高,優先使用AOF還原資料。
    • AOF比RDB更安全也更大
    • RDB效能比AOF好
    • 如果兩個都配了優先載入AOF
  6. 如何選擇合適的持久化方式

    • 一般來說, 如果想達到足以媲美PostgreSQL的資料安全性,Redis持久化資料和快取怎麼做擴容?你應該同時使用兩種持久化功能。在這種情況下,當 Redis 重啟的時候會優先載入AOF檔案來恢復原始的資料,因為在通常情況下AOF檔案儲存的資料集要比RDB檔案儲存的資料集要完整。
    • 如果你非常關心你的資料, 但仍然可以承受數分鐘以內的資料丟失,那麼你可以只使用RDB持久化。
    • 有很多使用者都只使用AOF持久化,但並不推薦這種方式,因為定時生成RDB快照(snapshot)非常便於進行資料庫備份, 並且 RDB 恢復資料集的速度也要比AOF恢復的速度要快,除此之外,使用RDB還可以避免AOF程式的bug。
    • 如果你只希望你的資料在伺服器執行的時候存在,你也可以不使用任何持久化方式
  7. Redis持久化資料和快取怎麼做擴容?

    • 如果Redis被當做快取使用,使用一致性雜湊實現動態擴容縮容。
    • 如果Redis被當做一個持久化儲存使用,必須使用固定的keys-to-nodes對映關係,節點的數量一旦確定不能變化。否則的話(即Redis節點需要動態變化的情況),必須使用可以在執行時進行資料再平衡的一套系統,而當前只有Redis叢集可以做到這樣。
  8. Redis的過期鍵的刪除策略

    過期策略通常有以下三種:

    • 定時過期:每個設定過期時間的key都需要建立一個定時器,到過期時間就會立即清除。該策略可以立即清除過期的資料,對記憶體很友好;但是會佔用大量的CPU資源去處理過期的資料,從而影響快取的響應時間和吞吐量。
    • 惰性過期:只有當訪問一個key時,才會判斷該key是否已過期,過期則清除。該策略可以最大化地節省CPU資源,卻對記憶體非常不友好。極端情況可能出現大量的過期key沒有再次被訪問,從而不會被清除,佔用大量記憶體。
    • 定期過期:每隔一定的時間,會掃描一定數量的資料庫的expires字典中一定數量的key,並清除其中已過期的key。該策略是前兩者的一個折中方案。通過調整定時掃描的時間間隔和每次掃描的限定耗時,可以在不同情況下使得CPU和記憶體資源達到最優的平衡效果。

    Redis中同時使用了惰性過期和定期過期兩種過期策略。

  9. 我們知道通過expire來設定key 的過期時間,那麼對過期的資料怎麼處理呢?

    除了快取伺服器自帶的快取失效策略之外(Redis預設的有6中策略可供選擇),我們還可以根據具體的業務需求進行自定義的快取淘汰,常見的策略有兩種:

    1. 定時去清理過期的快取;
    2. 當有使用者請求過來時,再判斷這個請求所用到的快取是否過期,過期的話就去底層系統得到新資料並更新快取。

    兩者各有優劣,第一種的缺點是維護大量快取的key是比較麻煩的,第二種的缺點就是每次使用者請求過來都要判斷快取失效,邏輯相對比較複雜!具體用哪種方案,大家可以根據自己的應用場景來權衡。

  10. Redis的記憶體淘汰策略有哪些

    Redis的記憶體淘汰策略是指在Redis的用於快取的記憶體不足時,怎麼處理需要新寫入且需要申請額外空間的資料。

    全域性的鍵空間選擇性移除

    • noeviction:當記憶體不足以容納新寫入資料時,新寫入操作會報錯。
    • allkeys-lru:當記憶體不足以容納新寫入資料時,在鍵空間中,移除最近最少使用的key。(這個是最常用的)
    • allkeys-random:當記憶體不足以容納新寫入資料時,在鍵空間中,隨機移除某個key。

    設定過期時間的鍵空間選擇性移除

    • volatile-lru:當記憶體不足以容納新寫入資料時,在設定了過期時間的鍵空間中,移除最近最少使用的key。
    • volatile-random:當記憶體不足以容納新寫入資料時,在設定了過期時間的鍵空間中,隨機移除某個key。
    • volatile-ttl:當記憶體不足以容納新寫入資料時,在設定了過期時間的鍵空間中,有更早過期時間的key優先移除。
  11. Redis事務的概念

    Redis 事務的本質是通過MULTI、EXEC、WATCH等一組命令的集合。事務支援一次執行多個命令,一個事務中所有命令都會被序列化。在事務執行過程,會按照順序序列化執行佇列中的命令,其他客戶端提交的命令請求不會插入到事務執行命令序列中。

    總結說:redis事務就是一次性、順序性、排他性的執行一個佇列中的一系列命令。

  12. Redis事務的三個階段

    1. 事務開始 MULTI
    2. 命令入隊
    3. 事務執行 EXEC

    事務執行過程中,如果服務端收到有EXEC、DISCARD、WATCH、MULTI之外的請求,將會把請求放入佇列中排隊

  13. Redis事務相關命令

    Redis事務功能是通過MULTI、EXEC、DISCARD和WATCH 四個原語實現的

    Redis會將一個事務中的所有命令序列化,然後按順序執行。

    1. redis 不支援回滾,“Redis 在事務失敗時不進行回滾,而是繼續執行餘下的命令”, 所以 Redis 的內部可以保持簡單且快速。
    2. 如果在一個事務中的命令出現錯誤,那麼所有的命令都不會執行
    3. 如果在一個事務中出現執行錯誤,那麼正確的命令會被執行
    • WATCH 命令是一個樂觀鎖,可以為 Redis 事務提供 check-and-set (CAS)行為。 可以監控一個或多個鍵,一旦其中有一個鍵被修改(或刪除),之後的事務就不會執行,監控一直持續到EXEC命令。
    • MULTI命令用於開啟一個事務,它總是返回OK。 MULTI執行之後,客戶端可以繼續向伺服器傳送任意多條命令,這些命令不會立即被執行,而是被放到一個佇列中,當EXEC命令被呼叫時,所有佇列中的命令才會被執行。
    • EXEC:執行所有事務塊內的命令。返回事務塊內所有命令的返回值,按命令執行的先後順序排列。 當操作被打斷時,返回空值 nil 。
    • 通過呼叫DISCARD,客戶端可以清空事務佇列,並放棄執行事務, 並且客戶端會從事務狀態中退出。
    • UNWATCH命令可以取消watch對所有key的監控。
  14. 事務管理(ACID)概述

    原子性(Atomicity)
    原子性是指事務是一個不可分割的工作單位,事務中的操作要麼都發生,要麼都不發生。

    一致性(Consistency)
    事務前後資料的完整性必須保持一致。

    隔離性(Isolation)
    多個事務併發執行時,一個事務的執行不應影響其他事務的執行

    永續性(Durability)
    永續性是指一個事務一旦被提交,它對資料庫中資料的改變就是永久性的,接下來即使資料庫發生故障也不應該對其有任何影響

    Redis的事務總是具有ACID中的一致性和隔離性,其他特性是不支援的。當伺服器執行在AOF持久化模式下,並且appendfsync選項的值為always時,事務也具有耐久性。

  15. Redis事務支援隔離性嗎

    Redis 是單程序程式,並且它保證在執行事務時,不會對事務進行中斷,事務可以執行直到執行完所有事務佇列中的命令為止。因此,Redis 的事務是總是帶有隔離性的

  16. 什麼是哨兵?

    sentinel,中文名是哨兵。哨兵是 redis 叢集機構中非常重要的一個元件,主要有以下功能:

    • 叢集監控:負責監控 redis master 和 slave 程序是否正常工作。
    • 訊息通知:如果某個 redis 例項有故障,那麼哨兵負責傳送訊息作為報警通知給管理員。
    • 故障轉移:如果 master node 掛掉了,會自動轉移到 slave node 上。
    • 配置中心:如果故障轉移發生了,通知 client 客戶端新的 master 地址。

    哨兵用於實現 redis 叢集的高可用,本身也是分散式的,作為一個哨兵叢集去執行,互相協同工作。

    • 故障轉移時,判斷一個 master node 是否宕機了,需要大部分的哨兵都同意才行,涉及到了分散式選舉的問題。
    • 即使部分哨兵節點掛掉了,哨兵叢集還是能正常工作的,因為如果一個作為高可用機制重要組成部分的故障轉移系統本身是單點的,那就很坑爹了。
  17. Redis 主從架構

    單機的 redis,能夠承載的 QPS 大概就在上萬到幾萬不等。對於快取來說,一般都是用來支撐讀高併發的。因此架構做成主從(master-slave)架構,一主多從,主負責寫,並且將資料複製到其它的 slave 節點,從節點負責讀。所有的讀請求全部走從節點。這樣也可以很輕鬆實現水平擴容,支撐讀高併發

    redis replication 的核心機制

    • redis 採用非同步方式複製資料到 slave 節點,不過 redis2.8 開始,slave node 會週期性地確認自己每次複製的資料量;
    • 一個 master node 是可以配置多個 slave node 的;
    • slave node 也可以連線其他的 slave node;
    • slave node 做複製的時候,不會 block master node 的正常工作;
    • slave node 在做複製的時候,也不會 block 對自己的查詢操作,它會用舊的資料集來提供服務;但是複製完成的時候,需要刪除舊資料集,載入新資料集,這個時候就會暫停對外服務了;
    • slave node 主要用來進行橫向擴容,做讀寫分離,擴容的 slave node 可以提高讀的吞吐量。

    redis 主從複製的核心原理

    當啟動一個 slave node 的時候,它會發送一個 PSYNC 命令給 master node。

    如果這是 slave node 初次連線到 master node,那麼會觸發一次 full resynchronization 全量複製。此時 master 會啟動一個後臺執行緒,開始生成一份 RDB 快照檔案,

    同時還會將從客戶端 client 新收到的所有寫命令快取在記憶體中。RDB 檔案生成完畢後, master 會將這個 RDB 傳送給 slave,slave 會先寫入本地磁碟,然後再從本地磁碟載入到記憶體中,

    接著 master 會將記憶體中快取的寫命令傳送到 slave,slave 也會同步這些資料。

    slave node 如果跟 master node 有網路故障,斷開了連線,會自動重連,連線之後 master node 僅會複製給 slave 部分缺少的資料。

    過程原理

    1. 當從庫和主庫建立MS關係後,會向主資料庫傳送SYNC命令
    2. 主庫接收到SYNC命令後會開始在後臺儲存快照(RDB持久化過程),並將期間接收到的寫命令快取起來
    3. 當快照完成後,主Redis會將快照檔案和所有快取的寫命令傳送給從Redis
    4. 從Redis接收到後,會載入快照檔案並且執行收到的快取的命令
    5. 之後,主Redis每當接收到寫命令時就會將命令傳送從Redis,從而保證資料的一致
  18. 說說Redis雜湊槽的概念?

    Redis叢集沒有使用一致性hash,而是引入了雜湊槽的概念,Redis叢集有16384個雜湊槽,每個key通過CRC16校驗後對16384取模來決定放置哪個槽,叢集的每個節點負責一部分hash槽。

  19. Redis叢集最大節點個數是多少?

    16384個

  20. Redis實現分散式鎖

    Redis為單程序單執行緒模式,採用佇列模式將併發訪問變成序列訪問,且多客戶端對Redis的連線並不存在競爭關係Redis中可以使用SETNX命令實現分散式鎖。

    當且僅當 key 不存在,將 key 的值設為 value。 若給定的 key 已經存在,則 SETNX 不做任何動作

    SETNX 是『SET if Not eXists』(如果不存在,則 SET)的簡寫。

    返回值:設定成功,返回 1 。設定失敗,返回 0 。

    使用SETNX完成同步鎖的流程及事項如下:

    使用SETNX命令獲取鎖,若返回0(key已存在,鎖已存在)則獲取失敗,反之獲取成功

    為了防止獲取鎖後程序出現異常,導致其他執行緒/程序呼叫SETNX命令總是返回0而進入死鎖狀態,需要為該key設定一個“合理”的過期時間

    釋放鎖,使用DEL命令將鎖資料刪除

  21. 快取雪崩

    快取雪崩是指快取同一時間大面積的失效,所以,後面的請求都會落到資料庫上,造成資料庫短時間內承受大量請求而崩掉。

    解決方案

    1. 快取資料的過期時間設定隨機,防止同一時間大量資料過期現象發生。
    2. 一般併發量不是特快取穿透別多的時候,使用最多的解決方案是加鎖排隊。
    3. 給每一個快取資料增加相應的快取標記,記錄快取的是否失效,如果快取標記失效,則更新資料快取。
  22. 快取穿透

    快取穿透是指快取和資料庫中都沒有的資料,導致所有的請求都落到資料庫上,造成資料庫短時間內承受大量請求而崩掉。

    解決方案

    1. 介面層增加校驗,如使用者鑑權校驗,id做基礎校驗,id<=0的直接攔截;
    2. 從快取取不到的資料,在資料庫中也沒有取到,這時也可以將key-value對寫為key-null,快取有效時間可以設定短點,如30秒(設定太長會導致正常情況也沒法使用)。這樣可以防止攻擊使用者反覆用同一個id暴力攻擊
    3. 採用布隆過濾器,將所有可能存在的資料雜湊到一個足夠大的 bitmap 中,一個一定不存在的資料會被這個 bitmap 攔截掉,從而避免了對底層儲存系統的查詢壓力
  23. 快取擊穿

    快取擊穿是指快取中沒有但資料庫中有的資料(一般是快取時間到期),這時由於併發使用者特別多,同時讀快取沒讀到資料,又同時去資料庫去取資料,引起資料庫壓力瞬間增大,造成過大壓力。和快取雪崩不同的是,快取擊穿指併發查同一條資料,快取雪崩是不同資料都過期了,很多資料都查不到從而查資料庫。

    解決方案

    1. 設定熱點資料永遠不過期。
    2. 加互斥鎖,互斥鎖
  24. 快取預熱

    快取預熱就是系統上線後,將相關的快取資料直接載入到快取系統。這樣就可以避免在使用者請求的時候,先查詢資料庫,然後再將資料快取的問題!使用者直接查詢事先被預熱的快取資料!

    解決方案

    1. 直接寫個快取重新整理頁面,上線時手工操作一下;
    2. 資料量不大,可以在專案啟動的時候自動進行載入;
    3. 定時重新整理快取;
  25. 快取降級

    當訪問量劇增、服務出現問題或非核心服務影響到核心流程的效能時,仍然需要保證服務還是可用的,即使是有損服務。系統可以根據一些關鍵資料進行自動降級,也可以配置開關實現人工降級。

    快取降級的最終目的是保證核心服務可用,即使是有損的。而且有些服務是無法降級的(如加入購物車、結算)。

    在進行降級之前要對系統進行梳理,看看系統是不是可以丟棄;從而梳理出哪些必須誓死保護,哪些可降級;比如可以參考日誌級別設定預案:

    1. 一般:比如有些服務偶爾因為網路抖動或者服務正在上線而超時,可以自動降級;
    2. 警告:有些服務在一段時間內成功率有波動(如在95~100%之間),可以自動降級或人工降級,併發送告警;
    3. 錯誤:比如可用率低於90%,或者資料庫連線池被打爆了,或者訪問量突然猛增到系統能承受的最大閥值,此時可以根據情況自動降級或者人工降級;
    4. 嚴重錯誤:比如因為特殊原因資料錯誤了,此時需要緊急人工降級。

    服務降級的目的,是為了防止Redis服務故障,導致資料庫跟著一起發生雪崩問題。因此,對於不重要的快取資料,可以採取服務降級策略,例如一個比較常見的做法就是,Redis出現問題,不去資料庫查詢,而是直接返回預設值給使用者。

Solr

  1. solr與關係型資料庫的區別

    資料庫裡有簡單的基於萬用字元的文字模糊查詢,但這會導致全表掃描,效能很差,而Solr是把搜尋關鍵字儲存在一個倒排表裡,搜尋效能提高了N個數量級。但Solr建立索引速度相對較慢。

    Solr裡更新部分欄位(域)資料相對較慢,因為Solr裡更新只能先刪除再新增。而且在新增資料的可見性方面,資料庫能立馬可見,Solr近實時查詢的資料可見性則稍差些。

    Solr的魅力在於它靈活的Schema機制,由於Schema.xml約束比較寬鬆,你甚至可以認為Solr的Schema.xml只是個擺設,每個Document可以有任意個任意型別的域,而資料庫裡的表的欄位是提前限定的,且每一行記錄擁有的欄位數必須一致。

  2. 什麼是Solr

    Solr是一個高效能,採用Java5開發,基於Lucene的全文搜尋伺服器。同時對其進行了擴充套件,提供了比Lucene更為豐富的查詢語言,同時實現了可配置、可擴充套件並對查詢效能進行了優化,並且提供了一個完善的功能管理介面,是一款非常優秀的全文搜尋引擎。

  3. Elasticsearch 與 Solr 的比較

    1. 二者安裝都很簡單;
    2. Solr 利用 Zookeeper 進行分散式管理,而 Elasticsearch 自身帶有分散式協調管理功能;
    3. Solr 支援更多格式的資料,而 Elasticsearch 僅支援json檔案格式;
    4. Solr 官方提供的功能更多,而 Elasticsearch 本身更注重於核心功能,高階功能多有第三方外掛提供;
    5. Solr 在傳統的搜尋應用中表現好於 Elasticsearch,但在處理實時搜尋應用時效率明顯低於 Elasticsearch。
    6. Solr 是傳統搜尋應用的有力解決方案,但 Elasticsearch 更適用於新興的實時搜尋應用。
  4. IK分詞器原理

    本質上是詞典分詞,在記憶體中初始化一個詞典,然後在分詞過程中逐個讀取字元,和字典中的字元相匹配,把文件中的所有詞語拆分出來的過程

  5. Solr的索引查詢為什麼比資料庫要快

    Solr使用的是Lucene API實現的全文檢索。全文檢索本質上是查詢的索引。而資料庫中並不是所有的欄位都建立的索引,更何況如果使用like查詢時很大的可能是不使用索引,所以使用solr查詢時要比查資料庫快

  6. Solr的使用步驟

    1. Solr伺服器搭建,因為Solr是用java5開發的,所以需要JDK和Tomcat。搭建部署
    2. 搭建完成後,我們需要將要展示的欄位引入Solr的庫中。配置Spring與Solr結合,工程啟動的時候啟動Solr
    3. 將資料庫中的查詢內容匯入到Solr索引庫,這裡使用的是SpringDataSolr的客戶端實現的。具體使用可以參考API
    4. 建立搜尋服務,供客戶端呼叫。呼叫Solr,查詢內容,這中間有分頁功能的實現。Solr高亮顯示的實現。
    5. 客戶端接收頁面的請求引數,調用搜索服務,進行搜尋。
  7. Solr的域

    域的簡介:域相當於資料庫的表字段,使用者存放資料,因此使用者根據業務需要去定義相關的 Field
    (域),一般來說,每一種對應著一種資料,使用者對同一種資料進行相同的操作。

  8. Solr是解決什麼問題的?

    嚴格來說,lucene負責資料儲存,而solr只是一個引擎提供搜尋和插入而已,跟資料庫的直譯器一樣,有什麼好處呢,比如一個數據庫有一個欄位存了1000個字,你想從這些字裡面搜一個詞的時候,普通的資料庫只會讓你使用like去查詢,他會遍歷每個字去模糊匹配,效率很低,而且有些是無法查詢的,當然除了像一些特殊的資料庫帶有分詞,比如postgresql,那lucene做的事情就是分詞,然後去匹配分詞的詞中是否有你想搜的詞就好了,當然了,為了提高這種檢索效率和記憶體節省底層做了很複雜的事情,可以這麼簡單的認為,全文搜尋這件事情上資料庫是無法滿足的!

ElasticSearch

  1. 為什麼要使用Elasticsearch?

    因為在我們商城中的資料,將來會非常多,所以採用以往的模糊查詢,模糊查詢前置配置,會放棄索引,導致商品查詢是全表掃面,在百萬級別的資料庫中,效率非常低下,而我們使用ES做一個全文索引,我們將經常查詢的商品的某些欄位,比如說商品名,描述、價格還有id這些欄位我們放入我們索引庫裡,可以提高查詢速度。

  2. 詳細描述一下Elasticsearch索引文件的過程

    協調節點預設使用文件ID參與計算(也支援通過routing),以便為路由提供合適的分片。
      shard = hash(document_id) % (num_of_primary_shards)
      當分片所在的節點接收到來自協調節點的請求後,會將請求寫入到Memory Buffer,然後定時(預設是每隔1秒)寫入到Filesystem Cache,這個從Momery Buffer到Filesystem   Cache的過程就叫做refresh;
      當然在某些情況下,存在Momery Buffer和Filesystem Cache的資料可能會丟失,ES是通過translog的機制來保證資料的可靠性的。其實現機制是接收到請求後,同時也會寫入到translog中,當Filesystem cache中的資料寫入到磁碟中時,才會清除掉,這個過程叫做flush;
      在flush過程中,記憶體中的緩衝將被清除,內容被寫入一個新段,段的fsync將建立一個新的提交點,並將內容重新整理到磁碟,舊的translog將被刪除並開始一個新的translog。
      flush觸發的時機是定時觸發(預設30分鐘)或者translog變得太大(預設為512M)時;

  3. 詳細描述一下Elasticsearch更新和刪除文件的過程

    刪除和更新也都是寫操作,但是Elasticsearch中的文件是不可變的,因此不能被刪除或者改動以展示其變更;
      磁碟上的每個段都有一個相應的.del檔案。當刪除請求傳送後,文件並沒有真的被刪除,而是在.del檔案中被標記為刪除。該文件依然能匹配查詢,但是會在結果中被過濾掉。當段合併時,在.del檔案中被標記為刪除的文件將不會被寫入新段。
      在新的文件被建立時,Elasticsearch會為該文件指定一個版本號,當執行更新時,舊版本的文件在.del檔案中被標記為刪除,新版本的文件被索引到一個新段。舊版本的文件依然能匹配查詢,但是會在結果中被過濾掉。

  4. 在併發情況下,Elasticsearch如果保證讀寫一致?

    可以通過版本號使用樂觀併發控制,以確保新版本不會被舊版本覆蓋,由應用層來處理具體的衝突;
      另外對於寫操作,一致性級別支援quorum/one/all,預設為quorum,即只有當大多數分片可用時才允許寫操作。但即使大多數可用,也可能存在因為網路等原因導致寫入副本失敗,這樣該副本被認為故障,分片將會在一個不同的節點上重建。
      對於讀操作,可以設定replication為sync(預設),這使得操作在主分片和副本分片都完成後才會返回;如果設定replication為async時,也可以通過設定搜尋請求引數_preference為primary來查詢主分片,確保文件是最新版本。

  5. ElasticSearch中的叢集、節點、索引、文件、型別是什麼?

    • 群集是一個或多個節點(伺服器)的集合,它們共同儲存您的整個資料,並提供跨所有節點的聯合索引和搜尋功能。群集由唯一名稱標識,預設情況下為“elasticsearch”。此名稱很重要,因為如果節點設定為按名稱加入群集,則該節點只能是群集的一部分。
    • 節點是屬於叢集一部分的單個伺服器。它儲存資料並參與群集索引和搜尋功能。
    • 索引就像關係資料庫中的“資料庫”。它有一個定義多種型別的對映。索引是邏輯名稱空間,對映到一個或多個主分片,並且可以有零個或多個副本分片。 MySQL =>資料庫 ElasticSearch =>索引
    • 文件類似於關係資料庫中的一行。不同之處在於索引中的每個文件可以具有不同的結構(欄位),但是對於通用欄位應該具有相同的資料型別。 MySQL => Databases => Tables => Columns / Rows ElasticSearch => Indices => Types =>具有屬性的文件
    • 型別是索引的邏輯類別/分割槽,其語義完全取決於使用者。
  6. Elasticsearch中的倒排索引是什麼?

    倒排索引是搜尋引擎的核心。搜尋引擎的主要目標是在查詢發生搜尋條件的文件時提供快速搜尋。倒排索引是一種像資料結構一樣的雜湊圖,可將使用者從單詞導向文件或網頁。它是搜尋引擎的核心。其主要目標是快速搜尋從數百萬檔案中查詢資料。

  7. ElasticSearch中的分片是什麼?

    在大多數環境中,每個節點都在單獨的盒子或虛擬機器上執行。

    • 索引 - 在Elasticsearch中,索引是文件的集合。
    • 分片 -因為Elasticsearch是一個分散式搜尋引擎,所以索引通常被分割成分佈在多個節點上的被稱為分片的元素
  8. ElasticSearch中的副本是什麼?

    一個索引被分解成碎片以便於分發和擴充套件。副本是分片的副本。一個節點是一個屬於一個叢集的ElasticSearch的執行例項。一個叢集由一個或多個共享相同叢集名稱的節點組成。

  9. ElasticSearch中的分析器是什麼?

    在ElasticSearch中索引資料時,資料由為索引定義的Analyzer在內部進行轉換。 分析器由一個Tokenizer和零個或多個TokenFilter組成。編譯器可以在一個或多個CharFilter之前。分析模組允許您在邏輯名稱下注冊分析器,然後可以在對映定義或某些API中引用它們。

    Elasticsearch附帶了許多可以隨時使用的預建分析器。或者,您可以組合內建的字元過濾器,編譯器和過濾器器來建立自定義分析器。

  10. 什麼是ElasticSearch中的編譯器?

    編譯器用於將字串分解為術語或標記流。一個簡單的編譯器可能會將字串拆分為任何遇到空格或標點的地方。Elasticsearch有許多內建標記器,可用於構建自定義分析器。

  11. 啟用屬性,索引和儲存的用途是什麼?

    enabled屬性適用於各類ElasticSearch特定/建立領域,如index和size。使用者提供的欄位沒有“已啟用”屬性。 儲存意味著資料由Lucene儲存,如果詢問,將返回這些資料。

    儲存欄位不一定是可搜尋的。預設情況下,欄位不儲存,但原始檔是完整的。因為您希望使用預設值(這是有意義的),所以不要設定store屬性 該指數屬性用於搜尋。

    索引屬性只能用於搜尋。只有索引域可以進行搜尋。差異的原因是在分析期間對索引欄位進行了轉換,因此如果需要的話,您不能檢索原始資料。

Nginx

  1. 什麼是Nginx?

    Nginx是一個 輕量級/高效能的反向代理Web伺服器,他實現非常高效的反向代理、負載平衡,他可以處理2-3萬併發連線數,官方監測能支援5萬併發,現在中國使用nginx網站使用者有很多,例如:新浪、網易、 騰訊等。

  2. 為什麼要用Nginx?

    • 跨平臺、配置簡單、方向代理、高併發連線:處理2-3萬併發連線數,官方監測能支援5萬併發,記憶體消耗小:開啟10個nginx才佔150M記憶體 ,nginx處理靜態檔案好,耗費記憶體少,
    • 而且Nginx內建的健康檢查功能:如果有一個伺服器宕機,會做一個健康檢查,再發送的請求就不會發送到宕機的伺服器了。重新將請求提交到其他的節點上。
    • 使用Nginx的話還能:
      1. 節省寬頻:支援GZIP壓縮,可以新增瀏覽器本地快取
      2. 穩定性高:宕機的概率非常小
      3. 接收使用者請求是非同步的
  3. 為什麼Nginx效能這麼高?

    因為他的事件處理機制:非同步非阻塞事件處理機制:運用了epoll模型,提供了一個佇列,排隊解決

  4. Nginx怎麼處理請求的?

    nginx接收一個請求後,首先由listen和server_name指令匹配server模組,再匹配server模組裡的location,location就是實際地址

     server {            						# 第一個Server區塊開始,表示一個獨立的虛擬主機站點
            listen       80;      					# 提供服務的埠,預設80
            server_name  localhost;       			# 提供服務的域名主機名
            location / {            				# 第一個location區塊開始
                root   html;       				# 站點的根目錄,相當於Nginx的安裝目錄
                index  index.html index.htm;      	# 預設的首頁檔案,多個用空格分開
            }    
    
  5. 什麼是正向代理和反向代理?

    1. 正向代理就是一個人傳送一個請求直接就到達了目標的伺服器
    2. 反方代理就是請求統一被Nginx接收,nginx反向代理伺服器接收到之後,按照一定的規 則分發給了後端的業務處理伺服器進行處理了
  6. 使用反向代理伺服器的優點是什麼?

    反向代理伺服器可以隱藏源伺服器的存在和特徵。它充當網際網路雲和web伺服器之間的中間層。這對於安全方面來說是很好的,特別是當您使用web託管服務時。

  7. Nginx的優缺點?

    • 優點:
      1. 佔記憶體小,可實現高併發連線,處理響應快
      2. 可實現http伺服器、虛擬主機、方向代理、負載均衡
      3. Nginx配置簡單
      4. 可以不暴露正式的伺服器IP地址
    • 缺點:
      動態處理差:nginx處理靜態檔案好,耗費記憶體少,但是處理動態頁面則很雞肋,現在一般前端用nginx作為反向代理抗住壓力,
  8. Nginx應用場景?

    1. http伺服器。Nginx是一個http服務可以獨立提供http服務。可以做網頁靜態伺服器。
    2. 虛擬主機。可以實現在一臺伺服器虛擬出多個網站,例如個人網站使用的虛擬機器。
    3. 反向代理,負載均衡。當網站的訪問量達到一定程度後,單臺伺服器不能滿足使用者的請求時,需要用多臺伺服器叢集可以使用nginx做反向代理。並且多臺伺服器可以平均分擔負載,不會應為某臺伺服器負載高宕機而某臺伺服器閒置的情況。
    4. nginz 中也可以配置安全管理、比如可以使用Nginx搭建API介面閘道器,對每個介面服務進行攔截。
  9. 如何用Nginx解決前端跨域問題?

    ​ 使用Nginx轉發請求。把跨域的介面寫成調本域的介面,然後將這些介面轉發到真正的請求地址

  10. location的作用是什麼?

    location指令的作用是根據使用者請求的URI來執行不同的應用,也就是根據使用者請求的網站URL進行匹配,匹配成功即進行相關的操作。

  11. location的語法能說出來嗎?

    注意:~ 代表自己輸入的英文字母

    匹配符 匹配規則 優先順序
    = 精確匹配 1
    ^~ 以某個字串開頭 2
    ~ 區分大小寫的正則匹配 3
    ~* 不區分大小寫的正則匹配 4
    !~ 區分大小寫不匹配的正則 5
    !~* 不區分大小寫不匹配的正則 6
    / 通用匹配,任何請求都會匹配到 7
  12. 限流怎麼做的?

    • Nginx限流就是限制使用者請求速度,防止伺服器受不了
    • 限流有3種
      1. 正常限制訪問頻率(正常流量)
      2. 突發限制訪問頻率(突發流量)
      3. 限制併發連線數
    • Nginx的限流都是基於漏桶流演算法,底下會說道什麼是桶銅流

Dubbo&Zookeeper

  1. dubbo服務負載均衡有哪些策略?

    隨機,按權重設定隨機概率。在一個截面上碰撞的概率高,但呼叫量越大分佈越均勻,而且按概率使用權重後也比較均勻,有利於動態調整提供者權重。(權重可以在dubbo管控臺配置)

    輪循,按公約後的權重設定輪循比率。存在慢的提供者累積請求問題,比如:第二臺機器很慢,但沒掛,當請求調到第二臺時就卡在那,久而久之,所有請求都卡在調到第二臺上。

    最少活躍呼叫數,相同活躍數的隨機,活躍數指呼叫前後計數差。使慢的提供者收到更少請求,因為越慢的提供者的呼叫前後計數差會越大。

    一致性Hash,相同引數的請求總是發到同一提供者。當某一臺提供者掛時,原本發往該提供者的請求,基於虛擬節點,平攤到其它提供者,不會引起劇烈變動。

  2. Dubbo在安全機制方面是如何解決的

    Dubbo通過Token令牌防止使用者繞過註冊中心直連,然後在註冊中心上管理授權。Dubbo還提供服務黑白名單,來控制服務所允許的呼叫方。

  3. ZooKeeper是什麼?

    ooKeeper是一個 分散式 的,開放原始碼的分散式 應用程式協調服務 ,是Google的Chubby一個開源的實現, 它是 叢集的管理者 , 監視著叢集中各個節點的狀態根據節點提交的反饋進行下一步合理操作 。最終,將簡單易 用的介面和效能高效、功能穩定的系統提供給使用者。 客戶端的 讀請求 可以被叢集中的 任意一臺機器處理 ,如果讀請求在節點上註冊了監聽器,這個監聽器也是由所 連線的zookeeper機器來處理。對於 寫請求 ,這些請求會同 時發給其他 zookeeper 機器並且達成一致後,請 求才會返回成功 。因此,隨著 zookeeper 的叢集機器增多,讀請求的吞吐會提高但是寫請求的吞吐會下降 。 有序性是zookeeper中非常重要的一個特性,所有的 更新都是全域性有序的 ,每個更新都有一個 唯一的時間戳 , 這個時間戳稱為 zxid ( Zookeeper Transaction Id ) 。而 讀請求只會相對於更新有序 ,也就是讀請求的返回 結果中會帶有這個 zookeeper 最新的 zxid 。

  4. ZooKeeper提供了什麼?

    1、 檔案系統 2、 通知機制

  5. Zookeeper檔案系統

    Zookeeper提供一個多層級的節點名稱空間(節點稱為znode)。與檔案系統不同的是,這些節點 都可以設定 關聯的資料 ,而檔案系統中只有檔案節點可以存放資料而目錄節點不行。Zookeeper為了保證高吞吐和低延 遲,在記憶體中維護了這個樹狀的目錄結構,這種特性使得Zookeeper 不能用於存放大量的資料 ,每個節點的存 放資料上限為 1M 。

  6. Zookeeper通知機制

    client端會對某個znode建立一個watcher 事件 ,當該znode發生變化時,這些client會收到zk的通知, 然後client可以根據znode變化來做出業務上的改變等。

  7. Zookeeper做了什麼?

    1、命名服務 2、配置管理 3、叢集管理 4、分散式鎖 5、佇列管理

  8. Zookeeper工作原理

    Zookeeper 的核心是 原子廣播 ,這個機制保證了 各個 Server 之間的同步 。實現這個機制的協議叫做Zab 協議 。Zab協議有兩種模式,它們分別是 恢復模式(選主) 和 廣播模式(同步) 。當服務啟動或者在領導者崩潰 後,Zab就進入了恢復模式,當領導者被選舉出來,且大多數Server完成了和 leader的狀態同步以後,恢復 模式就結束了。狀態同步保證了leader和Server具有相同的系統狀態。

  9. zookeeper是如何保證事務的順序一致性的?

    zookeeper採用了 遞增的事務 Id 來標識,所有的proposal(提議)都在被提出的時候加上了zxid,zxid實際 上是一個64位的數字,高32位是epoch(時期; 紀元; 世; 新時代)用來標識leader是否發生改變,如果有 新的leader產生出來,epoch會自增, 低 32 位用來遞增計數 。當新產生proposal的時候,會依據資料庫的 兩階段過程,首先會向其他的server發出事務執行請求,如果超過半數的機器都能執行並且能夠成功,那麼就 會開始執行。

  10. Zookeeper同步流程

    選完Leader以後,zk就進入狀態同步過程。
    1、Leader等待server連線;
    2、Follower連線leader,將最大的zxid傳送給leader;
    3、Leader根據follower的zxid確定同步點;
    4、完成同步後通知follower 已經成為uptodate狀態;
    5、Follower收到uptodate訊息後,又可以重新接受client的請求進行服務了。

  11. zookeeper負載均衡和nginx負載均衡區別

    zk的負載均衡是可以調控,nginx只是能調權重,其他需要可控的都需要自己寫外掛;但是nginx的吞吐量比 zk大很多,應該說按業務選擇用哪種方式。

  12. Dubbo 支援哪些協議,每種協議的應用場景,優缺點?

    • dubbo: 單一長連線和 NIO 非同步通訊,適合大併發小資料量的服務呼叫, 以及消費者遠大於提供者。傳輸協議 TCP,非同步,Hessian 序列化。
    • rmi: 採用 JDK 標準的 rmi 協議實現,傳輸引數和返回引數物件需要實現 Serializable 介面,使用 java 標準序列化機制,使用阻塞式短連線,傳輸數 據包大小混合,消費者和提供者個數差不多,可傳檔案,傳輸協議 TCP。 多個短連線,TCP 協議傳輸,同步傳輸,適用常規的遠端服務呼叫和 rmi 互 操作。在依賴低版本的 Common-Collections 包,java 序列化存在安全漏洞。
    • webservice: 基於 WebService 的遠端呼叫協議,整合 CXF 實現,提供和 原生 WebService 的互操作。多個短連線,基於 HTTP 傳輸,同步傳輸,適 用系統整合和跨語言呼叫。
    • http: 基於 Http 表單提交的遠端呼叫協議,使用 Spring 的 HttpInvoke 實 現。多個短連線,傳輸協議 HTTP,傳入引數大小混合,提供者個數多於消 費者,需要給應用程式和瀏覽器 JS 調。
    • hessian: 整合 Hessian 服務,基於 HTTP 通訊,採用 Servlet 暴露服務, Dubbo 內嵌 Jetty 作為伺服器時預設實現,提供與 Hession 服務互操作。多 個短連線,同步 HTTP 傳輸,Hessian 序列化,傳入引數較大,提供者大於 消費者,提供者壓力較大,可傳檔案。
    • memcache: 基於 memcached 實現的 RPC 協議。
    • redis: 基於 redis 實現的 RPC 協議。
  13. Dubbo 超時時間怎樣設定?

    1. 服務提供者端設定超時時間,在 Dubbo 的使用者文件中,推薦如果能在服務 端多配置就儘量多配置,因為服務提供者比消費者更清楚自己提供的服務特性。
    2. 服務消費者端設定超時時間,如果在消費者端設定了超時時間,以消費者端 為主,即優先順序更高。因為服務呼叫方設定超時時間控制性更靈活。如果消 費方超時,服務端執行緒不會定製,會產生警告。
  14. Dubbo 有些哪些註冊中心?

    • Multicast 註冊中心: Multicast 註冊中心不需要任何中心節點,只要廣播地 址,就能進行服務註冊和發現。基於網路中組播傳輸實現;
    • Zookeeper 註冊中心: 基於分散式協調系統 Zookeeper 實現,採用 Zookeeper 的 watch 機制實現資料變更;
    • redis 註冊中心: 基於 redis 實現,採用 key/Map 儲存,住 key 儲存服務名 和型別,Map 中 key 儲存服務 URL,value 服務過期時間。基於 redis 的發 布/訂閱模式通知資料變更;
    • Simple 註冊中心
  15. Dubbo 叢集的負載均衡有哪些策略

    1. Random LoadBalance: 隨機選取提供者策略,有利於動態調整提供者權 重。截面碰撞率高,呼叫次數越多,分佈越均勻;
    2. RoundRobin LoadBalance: 輪循選取提供者策略,平均分佈,但是存在請 求累積的問題;
    3. LeastActive LoadBalance: 最少活躍呼叫策略,解決慢提供者接收更少的 請求;
    4. ConstantHash LoadBalance: 一致性 Hash 策略,使相同引數請求總是發 到同一提供者,一臺機器宕機,可以基於虛擬節點,分攤至其他提供者,避 免引起提供者的劇烈變動
  16. Dubbo是什麼?

    Dubbo 是一個分散式、高效能、透明化的 RPC 服務框架,提供服務自動註冊、自動發現等高效服務治理方案, 可以和Spring框架無縫整合。

  17. Dubbo的核心功能?

    1. Remoting:網路通訊框架,提供對多種NIO框架抽象封裝,包括
      “同步轉非同步”和“請求-響應”模式的資訊交換方式。
    2. Cluster:服務框架,提供基於介面方法的透明遠端過程呼叫,包括多
      協議支援,以及軟負載均衡,失敗容錯,地址路由,動態配置等叢集
      支援。
    3. Registry:服務註冊,基於註冊中心目錄服務,使服務消費方能動態
      的查詢服務提供方,使地址透明,使服務提供方可以平滑增加或減少
      機器。
  18. Dubbo的核心元件?

  19. Dubbo服務註冊與發現的流程?

    1. Provider(提供者)繫結指定埠並啟動服務
    2. 指供者連線註冊中心,併發本機IP、埠、應用資訊和提供服務資訊
      傳送至註冊中心儲存
    3. Consumer(消費者),連線註冊中心 ,併發送應用資訊、所求服務信
      息至註冊中心
    4. 註冊中心根據 消費 者所求服務資訊匹配對應的提供者列表傳送至
      Consumer 應用快取。
    5. Consumer 在發起遠端呼叫時基於快取的消費者列表擇其一發起調
      用。
    6. Provider 狀態變更會實時通知註冊中心、在由註冊中心實時推送至
      Consumer
  20. Dubbo的架構設計?

    1. 服務介面層(Service):該層是與實際業務邏輯相關的,根據服務提
      供方和服務消費方的業務設計對應的介面和實現
    2. 配置層(Config):對外配置介面,以ServiceConfig和
      ReferenceConfig為中心。
    3. 服務代理層(Proxy):服務介面透明代理,生成服務的客戶端Stub
      和伺服器端Skeleton。
    4. 服務註冊層(Registry):封裝服務地址的註冊與發現,以服務URL
      為中心。
    5. 叢集層(Cluster):封裝多個提供者的路由及負載均衡,並橋接註冊
      中心,以Invoker為中心。
    6. 監控層(Monitor):RPC呼叫次數和呼叫時間監控。
    7. 遠端呼叫層(Protocol):封將RPC呼叫,以Invocation和Result
      為中心,擴充套件介面為Protocol、Invoker和Exporter。
    8. 資訊交換層(Exchange):封裝請求響應模式,同步轉非同步,以
      Request和Response為中心。
    9. 網路傳輸層(Transport):抽象mina和netty為統一介面,以
      Message為中心。
  21. Dubbo與Spring的關係?

Dubbo採用全Spring配置方式,透明化接入應用,對應用沒有任何API侵入,只需用Spring載入Dubbo的配置即可,Dubbo基於Spring的Schema擴充套件進行載入。
  1. Dubbo 和 Dubbox 之間的區別?

    dubbox 基於 dubbo 上做了一些擴充套件,如加了服務可 restful 呼叫,更新了開源元件等。

  2. Dubbo和Spring Cloud的關係?

    Dubbo 是 SOA 時代的產物,它的關注點主要在於服務的呼叫,流量分發、流量監控和熔斷。而 Spring Cloud 誕生於微服務架構時代,考慮的是微服務治理的方方面面,另外由於依託了 Spirng、Spirng Boot 的優勢之上,兩個框架在開始目標就不一致,Dubbo 定位服務治理、Spirng Cloud 是一個生態。

  3. Dubbo和Spring Cloud的區別?

    • 最大的區別:Dubbo底層是使用Netty這樣的NIO框架,是基於TCP協議傳輸的,配合以Hession序列化完成RPC通訊。
    • 而SpringCloud是基於Http協議+Rest介面呼叫遠端過程的通訊,相對來說,Http請求會有更大的報文,佔的頻寬也會更多。但是REST相比RPC更為靈活,服務提供方和呼叫方的依賴只依靠一紙契約,不存在程式碼級別的強依賴。

FastDFS

  1. FastDFS執行流程

    把檔案從client寫入tracker,tracker先去storage獲取ip地址和埠號,storage會生成id,把檔案存入磁碟,瀏覽器獲取時通過nginx做反向代理,然後瀏覽器才能用fastDFS工作原理

  2. fastDFS工作原理

    FastDFS架構包括 Tracker server和Storageserver。
    客戶端請求Tracker server進行檔案上傳、下載,通過Tracker server排程最終由Storage server完成檔案上傳和下載。

  3. Tracker的作用

    1. Tracker Server作用是負載均衡和排程,
    2. 通過Tracker server在檔案上傳時可以根據一些策略找到Storage server提 供檔案上傳服務。
    3. 可以將tracker稱為追蹤伺服器或排程伺服器。

    叢集:

    FastDFS叢集中的Tracker server可以有多臺
    Tracker server之間是相互平等關係同時提供服務.
    客戶端請求Tracker server採用輪詢方式,如果請求的tracker無法提供服務則換另一個tracker。

  4. Storage的作用

    Storage Server作用是檔案儲存,客戶端上傳的檔案最終儲存在Storage伺服器上

    叢集:

    Storage叢集採用了分組儲存方式。storage叢集由一個或多個組構成,叢集儲存總容量為叢集中所有組的儲存容 量之和
    一個組由一臺或多臺儲存伺服器組成,組內的Storage server之間是平等關係,
    不同組的Storage server 之間不會相互通訊
    同組內的Storage server之間會相互連線進行檔案同步,從而保證同組內每個storage上的檔案 完全一致的
    一個組的儲存容量為該組內的儲存伺服器容量最小的那個

  5. 採用分組儲存方式的好處

    靈活、可控性較強。比如上傳檔案時,可以由客戶端直接指定上傳到的組也可以由 tracker進行排程選擇。
    一個分組的儲存伺服器訪問壓力較大時,可以在該組增加儲存伺服器來擴充服務能力(縱向 擴容)
    當系統容量不足時,可以增加組來擴充儲存容量(橫向擴容)。

Linux

  1. 絕對路徑用什麼符號表示?當前目錄、上層目錄用什麼表示?主目錄用什麼表示? 切換目錄用什麼命令?

    絕對路徑: 如/etc/init.d
    當前目錄和上層目錄: ./ ../
    主目錄: ~/
    切換目錄: cd

  2. 怎麼檢視當前程序?怎麼執行退出?怎麼檢視當前路徑?

    檢視當前程序: ps
    執行退出: exit
    檢視當前路徑: pwd

  3. 怎麼清屏?怎麼退出當前命令?怎麼執行睡眠?怎麼檢視當前使用者 id?檢視指定幫助用什麼命令?

    清屏: clear
    退出當前命令: ctrl+c 徹底退出
    執行睡眠 : ctrl+z 掛起當前程序fg 恢復後臺
    檢視當前使用者 id: ”id“:檢視顯示目前登陸賬戶的 uid 和 gid 及所屬分組及使用者名稱
    檢視指定幫助: 如 man adduser 這個很全 而且有例子; adduser --help 這個告訴你一些常用引數; info adduesr;

  4. Ls 命令執行什麼功能? 可以帶哪些引數,有什麼區別?

    ls 執行的功能: 列出指定目錄中的目錄,以及檔案
    哪些引數以及區別: a 所有檔案l 詳細資訊,包括大小位元組數,可讀可寫可執行的許可權等

  5. 目錄建立用什麼命令?建立檔案用什麼命令?複製檔案用什麼命令?

    建立目錄: mkdir
    建立檔案:典型的如 touch,vi 也可以建立檔案,其實只要向一個不存在的檔案輸出,都會建立檔案
    複製檔案: cp 7. 檔案許可權修改用什麼命令?格式是怎麼樣的?
    檔案許可權修改: chmod

  6. 檢視檔案內容有哪些命令可以使用?

    vi 檔名 #編輯方式檢視,可修改
    cat 檔名 #顯示全部檔案內容
    more 檔名 #分頁顯示檔案內容
    less 檔名 #與 more 相似,更好的是可以往前翻頁
    tail 檔名 #僅檢視尾部,還可以指定行數
    head 檔名 #僅檢視頭部,還可以指定行數

  7. **搜尋檔案用什麼命令? 格式是怎麼樣的? **

    find <指定目錄> <指定條件> <指定動作>

    whereis 加引數與檔名

    locate 只加檔名

    find 直接搜尋磁碟,較慢。

    find / -name "string*"

  8. 使用什麼命令檢視用過的命令列表?

    history

  9. Linux檢視日誌命令的幾種方式

    • tail
    • head
    • grep
    • sed
    • cat
    • tac (反向列示)

Docker

  1. 什麼是Docker?

    Docker是一個容器化平臺,它以容器的形式將你的應用程式及所有的依賴項打包在一起,以確保你的應用程式在任何環境中無縫執行。

  2. 什麼是Docker映象?

    Docker映象是Docker容器的原始碼,Docker映象用於闖將容器,使用Build命令建立映象。

  3. 什麼是Docker容器?

    Docker容器包括應用程式及所有的依賴項,作為作業系統的獨立程序執行。

  4. Docker容器有幾種狀態?

    四種狀態:執行、已停止、重新啟動、已退出。

  5. DockerFile中最常見的指定是什麼?

    指令 備註
    FROM 指定基礎映象
    LABEL 功能為映象指定標籤
    RUN 執行指定命令
    CMD 容器啟動時要執行的命令
  6. DockerFile中的命令COPY和ADD命令有什麼區別?

    COPY和ADD的區別時COPY的SRC只能是本地檔案,其他用法一致。

  7. Docker的常用命令?

    命令 備註
    docker pull 拉去或更新指定的映象
    docker push 將映象推送到遠端倉庫
    docker rm 刪除容器
    docker rmi 刪除映象
    docker images 列出所有映象
    docker ps 列出所有容器
  8. 容器與主機之間的資料拷貝命令?

    Docker cp命令用於窮奇與主機之間的資料拷貝

    • 主機到哦容器:docker cp /www 96f7f14e99ab:/www/
    • 容器到主機:docker cp 96f7f14e99ab:/www /tmp
  9. 如何批量清理臨時映象檔案?

    可以使用sudo docker rmi $(sudo docker images -q -f danging=true)命令

  10. 如何檢視映象支援的環境變數?

    使用sudo docker run IMAGE env

  11. 構建docker映象應該遵循哪些原則?

    1. 儘量選取滿足需求但較小的基礎系統映象,建議選擇debian:wheezy映象,僅有86MB大小。
    2. 清理編譯生成檔案、安裝包的快取等臨時檔案。
    3. 安裝哥哥軟體時候要指定準確的版本號,並避免引入不需要的依賴。
    4. 從安全的角度考慮,應用盡量使用系統的庫和依賴。
    5. 使用dockerfile建立映象時候要新增.dockerignore檔案或使用乾淨的工作目錄。
  12. 容器退出後,通過docker ps命令檢視不到,資料會丟失麼?

    容器退出後會處於終止(exited)狀態,此時可以通過docker ps -a檢視,其中資料不會丟失,還可以通過docker start來啟動,只要刪除容器才會清除資料。

  13. 如何停止所有正在執行的容器?

    docker kill $(sudo docker ps -q)

  14. 如何清理批量後臺停止容器?

    docker rm$(sudo docker ps -a -q)

  15. 如何臨時退出一個正在互動的容器的終端,而不終止它?

    按Ctrl+p,後按Ctrl+q,如果按Ctrl+c會使容器內的應用程序終止,進而會使容器終止。

  16. 很多應用容器都是預設後臺執行的,怎麼檢視他們的輸出和日誌資訊?

    使用docker logs,後面跟容器的名稱或者ID資訊

  17. Docker的配置檔案放在那裡。如何修改配置?

    Ubuntu系統下Docker的配置檔案是/etc/default/docker,CentOS系統配置檔案存放在/etc/sysconfig/docker。

  18. 如何更改docker的預設儲存設定?

    Docker的預設存放位置是/var/lib/docker,如果希望將docker的本地檔案儲存到其他分割槽,可以使用Linux軟連線的方式來做。