Java 最常見 200+ 面試題全解析:面試必備(2019)

【說明】

原文地址:https://blog.csdn.net/u011665991/article/details/89206148

目錄

【說明】

適宜閱讀人羣

一、Java 基礎

二、容器

三、多線程

四、反射

五、對象拷貝

六、Java Web

七、異常

八、網絡

九、設計模式

十、Spring/Spring MVC

十一、Spring Boot/Spring Cloud

十二、Hibernate

十三、Mybatis

十四、RabbitMQ

未更新完成。。。。

十五、Kafka

十六、Zookeeper

十七、MySql

十八、Redis

十九、JVM


這篇文章多數答案都是出自網上,同時對很多文章進行閱讀和拼接,所以沒有寫明出處,有些感覺寫的不錯或者比較好理解的文章就附了一個連接,有很多答案不是很細緻,如果想細緻研究,每個問題可以延伸一篇篇幅很長的文章,所以需要單獨花時間去了解學習。其實面試題很多技術也沒有用過,從網上看一些文章,大體寫一下,可能會存在問題,後面有時間,我會將知識點系統看一篇,完善和補充,歡迎大家提意見

本文的主題,我們這份面試題,包含的內容了十九了模塊:Java 基礎、容器、多線程、反射、對象拷貝、Java Web 模塊、異常、網絡、設計模式、Spring/Spring MVC、Spring Boot/Spring Cloud、Hibernate、Mybatis、RabbitMQ、Kafka、Zookeeper、MySql、Redis、JVM 。如下圖所示:

 


適宜閱讀人羣

    需要面試的初/中/高級 java 程序員

    想要查漏補缺的人

    想要不斷完善和擴充自己 java 技術棧的人

    java 面試官


 

下面一起來看 208 道面試題,具體的內容。

一、Java 基礎

1.JDK 和 JRE 有什麼區別?

  • JDK:Java Development Kit 的簡稱,Java 開發工具包,提供了 Java 的開發環境和運行環境。
  • JRE:Java Runtime Environment 的簡稱,Java 運行環境,爲 Java 的運行提供了所需環境。

具體來說 JDK 其實包含了 JRE,同時還包含了編譯 Java 源碼的編譯器 Javac,還包含了很多 Java 程序調試和分析的工具。簡單來說:如果你需要運行 Java 程序,只需安裝 JRE 就可以了,如果你需要編寫 Java 程序,需要安裝 JDK

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

== 的作用

  • 基本類型:比較的是值是否相同。
  • 引用類型:比較的是引用是否相同。

equals 的作用:比較的都是值是否相同。

【代碼示例】

String x = "string";
String y = "string";
String z = new String("string");
System. out. println(x==y); // true
System. out. println(x==z); // false
System. out. println(x. equals(y)); // true
System. out. println(x. equals(z)); // true

【代碼解讀】

因爲 x 和 y 指向的是同一個引用,所以 == 也是 true,而 new String() 方法則重寫開闢了內存空間,所以 == 結果爲 false,而 equals 比較的一直是值,所以結果都爲 true。

3.兩個對象的 hashCode()相同,則 equals()也一定爲 true,對嗎?

不對,兩個對象的 hashCode() 相同,equals() 不一定 true。

【代碼示例】

String str1 = "通話";
String str2 = "重地";
System. out. println(String. format("str1:%d | str2:%d",  str1. hashCode(),str2. hashCode()));
System. out. println(str1. equals(str2));

【代碼結果】

str1:1179395 | str2:1179395
     
false

【代碼解讀】

      很顯然“通話”和“重地”的 hashCode() 相同,然而 equals() 則爲 false,因爲在散列表中,hashCode() 相等即兩個鍵值對的哈希值相等,然而哈希值相等,並不一定能得出鍵值對相等。

4.final 在 java 中有什麼作用?

  • final 修飾的類叫最終類,該類不能被繼承。
  • final 修飾的方法不能被重寫。
  • final 修飾的變量叫常量,常量必須初始化,初始化之後值就不能被修改。

5.java 中的 Math.round(-1.5) 等於多少?

   等於 -1,Math. round 四捨五入大於 0. 5 向上取整的。

6.String 屬於基礎的數據類型嗎?

  String 不屬於基礎類型,基礎類型有 8 種:byte、boolear、char、short、int、float、long、double,String 屬於對象。

7.java 中操作字符串都有哪些類?它們之間有什麼區別?

操作字符串的類有:String、StringBuffer、StringBuilder

String 和 StringBuffer、StringBuilder 的區別在於 :

String 聲明的是不可變的對象,每次操作都會生成新的 String 對象,然後將指針指向新的 String 對象,

而 StringBuffer、StringBuilder 可以在原有對象的基礎上進行操作,所以在經常改變字符串內容的情況下最好不要使用 String。

StringBuffer 和 StringBuilder 最大的區別在於:

  線程是否安全 性能 推薦使用場景
StringBuffer 線程安全 多線程環境
StringBuilder 非線程安全 單線程環境

 

8.String str="i"與 String str=new String(“i”)一樣嗎?

不一樣,因爲內存的分配方式不一樣。String str="i"的方式,Java 虛擬機會將其分配到常量池中;而 String str=new String("i") 則會被分到堆內存中。

9.如何將字符串反轉?

【代碼示例】

使用 StringBuilder 或者 stringBuffer 的 reverse() 方法。

// StringBuffer reverse
StringBuffer stringBuffer = new StringBuffer();
stringBuffer. append("abcdefg");
System. out. println(stringBuffer. reverse()); // gfedcba
// StringBuilder reverse
StringBuilder stringBuilder = new StringBuilder();
stringBuilder. append("abcdefg");
System. out. println(stringBuilder. reverse()); // gfedcba

10.String 類的常用方法都有那些?

indexOf():返回指定字符的索引。
charAt():返回指定索引處的字符。
replace():字符串替換。
trim():去除字符串兩端空白。
split():分割字符串,返回一個分割後的字符串數組。
getBytes():返回字符串的 byte 類型數組。
length():返回字符串長度。
toLowerCase():將字符串轉成小寫字母。
toUpperCase():將字符串轉成大寫字符。
substring():截取字符串。
equals():字符串比較。

11.抽象類必須要有抽象方法嗎?

不需要,抽象類不一定非要有抽象方法。

【代碼示例】

abstract class Cat {
    public static void sayHi() {
        System. out. println("hi~");
    }
}

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

  • 普通類不能包含抽象方法,抽象類可以包含抽象方法。
  • 抽象類不能直接實例化,普通類可以直接實例化。

13.抽象類能使用 final 修飾嗎?

不能,定義抽象類就是讓其他類繼承的,如果定義爲 final 該類就不能被繼承,這樣彼此就會產生矛盾,所以 final 不能修飾抽象類

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

  • 默認方法實現:抽象類可以有默認的方法實現;接口不能有默認的方法實現。
  • 實現:抽象類的子類使用 extends 來繼承;接口必須使用 implements 來實現接口。
  • 構造函數:抽象類可以有構造函數;接口不能有。
  • main 方法:抽象類可以有 main 方法,並且我們能運行它;接口不能有 main 方法。
  • 實現數量:類可以實現很多個接口;但是隻能繼承一個抽象類。
  • 訪問修飾符:接口中的方法默認使用 public 修飾;抽象類中的方法可以是任意訪問修飾符。

15.java 中 IO 流分爲幾種?

  • 按功能來分:輸入流(input)、輸出流(output)
  • 按類型來分:字節流和字符流。
  • 字節流和字符流的區別是:字節流按 8 位傳輸以字節爲單位輸入輸出數據,字符流按 16 位傳輸以字符爲單位輸入輸出數據。

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

  • BIO:Block IO 同步阻塞式 IO,就是我們平常使用的傳統 IO,它的特點是模式簡單使用方便,併發處理能力低。
  • NIO:New IO 同步非阻塞 IO,是傳統 IO 的升級,客戶端和服務器端通過 Channel(通道)通訊,實現了多路複用。
  • AIO:Asynchronous IO 是 NIO 的升級,也叫 NIO2,實現了異步非堵塞 IO ,異步 IO 的操作基於事件和回調機制。

17.Files的常用方法都有哪些?

  • Files. exists():檢測文件路徑是否存在。
  • Files. createFile():創建文件。
  • Files. createDirectory():創建文件夾。
  • Files. delete():刪除一個文件或目錄。
  • Files. copy():複製文件。
  • Files. move():移動文件。
  • Files. size():查看文件個數。
  • Files. read():讀取文件。
  • Files. write():寫入文件。

二、容器

18.java 容器都有哪些?

  • Collection
    • List
      • ArrayList
      • LinkedList
      • Vector
      • Stack
    • Set
      • HashSet
      • LinkedHashSet
      • TreeSet
  • Map
    • HashMap
      • LindedHashMap
    • TreeMap
    • ConcurrentHashMap
    • Hashtable

19.Collection 和 Collections 有什麼區別?

  • Collection 是一個集合接口,提供了對集合對象進行基本操作的通用接口方法,所有集合都是它的子類,比如 List、Set 等。
  • Collections 是一個包裝類,包含了很多靜態方法,不能被實例化,就像一個工具類,比如提供的排序方法: Collections. sort(list)

20.List、Set、Map 之間的區別是什麼?

List、Set、Map 的區別主要體現在兩個方面:元素是否有序、是否允許元素重複。

具體可以參考這篇文章:https://www.cnblogs.com/IvesHe/p/6108933.html

21.HashMap 和 Hashtable 有什麼區別?

  • 存儲:HashMap 運行 key 和 value 爲 null,而 Hashtable 不允許。
  • 線程安全:Hashtable 是線程安全的,而 HashMap 是非線程安全的。
  • 推薦使用:在 Hashtable 的類註釋可以看到,Hashtable 是保留類不建議使用,推薦在單線程環境下使用 HashMap 替代,如果需要多線程使用則用 ConcurrentHashMap 替代。

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

對於在 Map 中插入、刪除、定位一個元素這類操作,HashMap 是最好的選擇,因爲相對而言 HashMap 的插入會更快,但如果你要對一個 key 集合進行有序的遍歷,那 TreeMap 是更好的選擇

23.說一下 HashMap 的實現原理?

HashMap 基於 Hash 算法實現的,我們通過 put(key,value)存儲,get(key)來獲取。當傳入 key 時,HashMap 會根據 key. hashCode() 計算出 hash 值,根據 hash 值將 value 保存在 bucket 裏。當計算出的 hash 值相同時,我們稱之爲 hash 衝突,HashMap 的做法是用鏈表和紅黑樹存儲相同 hash 值的 value。當 hash 衝突的個數比較少時,使用鏈表否則使用紅黑樹。

24.說一下 HashSet 的實現原理?

HashSet 是基於 HashMap 實現的,HashSet 底層使用 HashMap 來保存所有元素,因此 HashSet 的實現比較簡單,相關 HashSet 的操作,基本上都是直接調用底層 HashMap 的相關方法來完成,HashSet 不允許重複的值。

25.ArrayList 和 LinkedList 的區別是什麼?

  • 數據結構實現:ArrayList 是動態數組的數據結構實現,而 LinkedList 是雙向鏈表的數據結構實現。
  • 隨機訪問效率:ArrayList 比 LinkedList 在隨機訪問的時候效率要高,因爲 LinkedList 是線性的數據存儲方式,所以需要移動指針從前往後依次查找。
  • 增加和刪除效率:在非首尾的增加和刪除操作,LinkedList 要比 ArrayList 效率要高,因爲 ArrayList 增刪操作要影響數組內的其他數據的下標。

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

26.如何實現數組和 List 之間的轉換?

  • 數組轉 List:使用 Arrays. asList(array) 進行轉換。
  • List 轉數組:使用 List 自帶的 toArray() 方法。

【代碼示例】

// list to array
List<String> list = new ArrayList<String>();
list. add("王磊");
list. add("的博客");
list. toArray();
// array to list
String[] array = new String[]{"王磊","的博客"};
Arrays. asList(array);

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

  • 線程安全:Vector 使用了 Synchronized 來實現線程同步,是線程安全的,而 ArrayList 是非線程安全的。
  • 性能:ArrayList 在性能方面要優於 Vector。
  • 擴容:ArrayList 和 Vector 都會根據實際的需要動態的調整容量,只不過在 Vector 擴容每次會增加 1 倍,而 ArrayList 只會增加 50%。

28.Array 和 ArrayList 有何區別?

  • Array 可以存儲基本數據類型和對象,ArrayList 只能存儲對象。
  • Array 是指定固定大小的,而 ArrayList 大小是自動擴展的。
  • Array 內置方法沒有 ArrayList 多,比如 addAll、removeAll、iteration 等方法只有 ArrayList 有。

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

  • 相同點:都是返回第一個元素,並在隊列中刪除返回的對象。
  • 不同點:如果沒有元素 poll()會返回 null,而 remove()會直接拋出 NoSuchElementException 異常。

【代碼示例】

Queue<String> queue = new LinkedList<String>();
queue. offer("string"); // add
System. out. println(queue. poll());
System. out. println(queue. remove());
System. out. println(queue. size());

30.哪些集合類是線程安全的?

Vector、Hashtable、Stack 都是線程安全的,而像 HashMap 則是非線程安全的,不過在 JDK 1.5 之後隨着 Java. util. concurrent 併發包的出現,它們也有了自己對應的線程安全類,比如 HashMap 對應的線程安全類就是 ConcurrentHashMap。

31.迭代器 Iterator 是什麼?

Iterator 接口提供遍歷任何 Collection 的接口。我們可以從一個 Collection 中使用迭代器方法來獲取迭代器實例。迭代器取代了 Java 集合框架中的 Enumeration,迭代器允許調用者在迭代過程中移除元素。

32.Iterator 怎麼使用?有什麼特點?

【代碼示例】

List<String> list = new ArrayList<>();
Iterator<String> it = list. iterator();
while(it. hasNext()){
  String obj = it. next();
  System. out. println(obj);
}

Iterator 的特點是更加安全,因爲它可以確保,在當前遍歷的集合元素被更改的時候,就會拋出 ConcurrentModificationException 異常。

33.Iterator 和 ListIterator 有什麼區別?

  • Iterator 可以遍歷 Set 和 List 集合,而 ListIterator 只能遍歷 List。
  • Iterator 只能單向遍歷,而 ListIterator 可以雙向遍歷(向前/後遍歷)。
  • ListIterator 從 Iterator 接口繼承,然後添加了一些額外的功能,比如添加一個元素、替換一個元素、獲取前面或後面元素的索引位置。

34.怎麼確保一個集合不能被修改?

可以使用 Collections. unmodifiableCollection(Collection c) 方法來創建一個只讀集合,這樣改變集合的任何操作都會拋出 Java. lang. UnsupportedOperationException 異常。

【代碼示例】

List<String> list = new ArrayList<>();
list. add("x");
Collection<String> clist = Collections. unmodifiableCollection(list);
clist. add("y"); // 運行時此行報錯
System. out. println(list. size());

 


三、多線程

35.並行和併發有什麼區別?

  • 並行:一個處理器同時處理多個任務。
  • 併發:多個處理器或多核處理器同時處理多個不同的任務。

36.線程和進程的區別?

一個程序下至少有一個進程,一個進程下至少有一個線程,一個進程下也可以有多個線程來增加程序的執行速度。

37.守護線程是什麼?

守護線程是運行在後臺的一種特殊進程。它獨立於控制終端並且週期性地執行某種任務或等待處理某些發生的事件。在 Java 中垃圾回收線程就是特殊的守護線程。

38.創建線程有哪幾種方式?

創建線程有三種方式:

  • 繼承 Thread 重新 run 方法;
  • 實現 Runnable 接口;
  • 實現 Callable 接口。

39.說一下 runnable 和 callable 有什麼區別?

runnable 沒有返回值,callable 可以拿到有返回值,callable 可以看作是 runnable 的補充。

40.線程有哪些狀態?

線程的狀態:

  • NEW 尚未啓動
  • RUNNABLE 正在執行中
  • BLOCKED 阻塞的(被同步鎖或者IO鎖阻塞)
  • WAITING 永久等待狀態
  • TIMED_WAITING 等待指定的時間重新被喚醒的狀態
  • TERMINATED 執行完成

41.sleep() 和 wait() 有什麼區別?

  • 類的不同:sleep() 來自 Thread,wait() 來自 Object。
  • 釋放鎖:sleep() 不釋放鎖;wait() 釋放鎖。
  • 用法不同:sleep() 時間到會自動恢復;wait() 可以使用 notify()/notifyAll()直接喚醒。

42.notify()和 notifyAll()有什麼區別?

notifyAll()會喚醒所有的線程,notify()之後喚醒一個線程。notifyAll() 調用後,會將全部線程由等待池移到鎖池,然後參與鎖的競爭,競爭成功則繼續執行,如果不成功則留在鎖池等待鎖被釋放後再次參與競爭。而 notify()只會喚醒一個線程,具體喚醒哪一個線程由虛擬機控制。

43.線程的 run()和 start()有什麼區別?

start() 方法用於啓動線程,run() 方法用於執行線程的運行時代碼。run() 可以重複調用,而 start() 只能調用一次。

44.創建線程池有哪幾種方式?

線程池創建有七種方式,最核心的是最後一種:

  • newSingleThreadExecutor():它的特點在於工作線程數目被限制爲 1,操作一個無界的工作隊列,所以它保證了所有任務的都是被順序執行,最多會有一個任務處於活動狀態,並且不允許使用者改動線程池實例,因此可以避免其改變線程數目;
  • newCachedThreadPool():它是一種用來處理大量短時間工作任務的線程池,具有幾個鮮明特點:它會試圖緩存線程並重用,當無緩存線程可用時,就會創建新的工作線程;如果線程閒置的時間超過 60 秒,則被終止並移出緩存;長時間閒置時,這種線程池,不會消耗什麼資源。其內部使用 SynchronousQueue 作爲工作隊列;
  • newFixedThreadPool(int nThreads):重用指定數目(nThreads)的線程,其背後使用的是無界的工作隊列,任何時候最多有 nThreads 個工作線程是活動的。這意味着,如果任務數量超過了活動隊列數目,將在工作隊列中等待空閒線程出現;如果有工作線程退出,將會有新的工作線程被創建,以補足指定的數目 nThreads;
  • newSingleThreadScheduledExecutor():創建單線程池,返回 ScheduledExecutorService,可以進行定時或週期性的工作調度;
  • newScheduledThreadPool(int corePoolSize):和newSingleThreadScheduledExecutor()類似,創建的是個 ScheduledExecutorService,可以進行定時或週期性的工作調度,區別在於單一工作線程還是多個工作線程;
  •  newWorkStealingPool(int parallelism):這是一個經常被人忽略的線程池,Java 8 才加入這個創建方法,其內部會構建ForkJoinPool,利用Work-Stealing算法,並行地處理任務,不保證處理順序;
  •  ThreadPoolExecutor():是最原始的線程池創建,上面1-3創建方式都是對ThreadPoolExecutor的封裝

45.線程池都有哪些狀態?

  •  RUNNING:這是最正常的狀態,接受新的任務,處理等待隊列中的任務。
  •  SHUTDOWN:不接受新的任務提交,但是會繼續處理等待隊列中的任務。
  • STOP:不接受新的任務提交,不再處理等待隊列中的任務,中斷正在執行任務的線程。
  • TIDYING:所有的任務都銷燬了,workCount 爲 0,線程池的狀態在轉換爲 TIDYING 狀態時,會執行鉤子方法 terminated()。
  • TERMINATED:terminated()方法結束後,線程池的狀態就會變成這個。

46.線程池中 submit()和 execute()方法有什麼區別?

  • execute():只能執行 Runnable 類型的任務。
  • submit():可以執行 Runnable 和 Callable 類型的任務。

Callable 類型的任務可以獲取執行的返回值,而 Runnable 執行無返回值。

47.在 java 程序中怎麼保證多線程的運行安全?

  • 方法一:使用安全類,比如 Java. util. concurrent 下的類。
  • 方法二:使用自動鎖 synchronized。
  • 方法三:使用手動鎖 Lock。

【手動鎖代碼示例】

Lock lock = new ReentrantLock();
lock. lock();
try {
    System. out. println("獲得鎖");
} catch (Exception e) {
    // TODO: handle exception
} finally {
    System. out. println("釋放鎖");
    lock. unlock();
}

48.多線程鎖的升級原理是什麼?

在鎖對象的對象頭裏面有一個 threadid 字段,在第一次訪問的時候 threadid 爲空,JVM 讓其持有偏向鎖,並將threadid 設置爲其線程 id,再次進入的時候會先判斷 threadid 是否尤其線程 id 一致,如果一致則可以直接使用,如果不一致,則升級偏向鎖爲輕量級鎖,通過自旋循環一定次數來獲取鎖,不會堵塞,執行一定次數之後就會升級爲重量級鎖,進入堵塞,整個過程就是鎖升級的原理。

鎖的升級的目的:在 Java 6 之後優化 synchronized 的實現方式,使用了偏向鎖升級爲輕量級鎖再升級到重量級鎖的方式,減低了鎖帶來的性能消耗。

鎖升級是爲了減低了鎖帶來的性能消耗。

49.什麼是死鎖?

當線程 A 持有獨佔鎖a,並嘗試去獲取獨佔鎖 b 的同時,線程 B 持有獨佔鎖 b,並嘗試獲取獨佔鎖 a 的情況下,就會發生 AB 兩個線程由於互相持有對方需要的鎖,而發生的阻塞現象,我們稱爲死鎖。

50.怎麼防止死鎖?

  • 儘量使用 tryLock(long timeout, TimeUnit unit)的方法(ReentrantLock、ReentrantReadWriteLock),設置超時時間,超時可以退出防止死鎖。
  • 儘量使用 Java. util. concurrent 併發類代替自己手寫鎖。
  • 儘量降低鎖的使用粒度,儘量不要幾個功能用同一把鎖。
  • 儘量減少同步的代碼塊。

51.ThreadLocal 是什麼?有哪些使用場景?

ThreadLocal 爲每個使用該變量的線程提供獨立的變量副本,所以每一個線程都可以獨立地改變自己的副本,而不會影響其它線程所對應的副本。

ThreadLocal 的經典使用場景是數據庫連接和 session 管理等。

52.說一下 synchronized 底層實現原理?

synchronized 是由一對 monitorenter/monitorexit 指令實現的,monitor 對象是同步的基本實現單元。在 Java 6 之前,monitor 的實現完全是依靠操作系統內部的互斥鎖,因爲需要進行用戶態到內核態的切換,所以同步操作是一個無差別的重量級操作,性能也很低。但在 Java 6 的時候,Java 虛擬機 對此進行了大刀闊斧地改進,提供了三種不同的 monitor 實現,也就是常說的三種不同的鎖:偏向鎖(Biased Locking)、輕量級鎖和重量級鎖,大大改進了其性能。

53.synchronized 和 volatile 的區別是什麼?

  • volatile 是變量修飾符;synchronized 是修飾類、方法、代碼段。
  • volatile 僅能實現變量的修改可見性,不能保證原子性;而 synchronized 則可以保證變量的修改可見性和原子性。
  • volatile 不會造成線程的阻塞;synchronized 可能會造成線程的阻塞。

54.synchronized 和 Lock 有什麼區別?

  • synchronized 可以給類、方法、代碼塊加鎖;而 lock 只能給代碼塊加鎖。
  • synchronized 不需要手動獲取鎖和釋放鎖,使用簡單,發生異常會自動釋放鎖,不會造成死鎖;而 lock 需要自己加鎖和釋放鎖,如果使用不當沒有 unLock()去釋放鎖就會造成死鎖。
  • 通過 Lock 可以知道有沒有成功獲取鎖,而 synchronized 卻無法辦到。

55.synchronized 和 ReentrantLock 區別是什麼?

synchronized 早期的實現比較低效,對比 ReentrantLock,大多數場景性能都相差較大,但是在 Java 6 中對 synchronized 進行了非常多的改進。

主要區別如下:

  •     ReentrantLock 使用起來比較靈活,但是必須有釋放鎖的配合動作;
  •     ReentrantLock 必須手動獲取與釋放鎖,而 synchronized 不需要手動釋放和開啓鎖;
  •     ReentrantLock 只適用於代碼塊鎖,而 synchronized 可用於修飾方法、代碼塊等。
  •     volatile 標記的變量不會被編譯器優化;synchronized 標記的變量可以被編譯器優化。
     

56.說一下 atomic 的原理?

atomic 主要利用 CAS (Compare And Wwap) 和 volatile 和 native 方法來保證原子操作,從而避免 synchronized 的高開銷,執行效率大爲提升。

 


四、反射

57.什麼是反射?

反射是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意一個方法和屬性;這種動態獲取的信息以及動態調用對象的方法的功能稱爲 Java 語言的反射機制。

58.什麼是 java 序列化?什麼情況下需要序列化?

Java 序列化是爲了保存各種對象在內存中的狀態,並且可以把保存的對象狀態再讀出來。

以下情況需要使用 Java 序列化:

  • 想把的內存中的對象狀態保存到一個文件中或者數據庫中時候;
  • 想用套接字在網絡上傳送對象的時候;
  • 想通過RMI(遠程方法調用)傳輸對象的時候。

59.動態代理是什麼?有哪些應用?

動態代理是運行時動態生成代理類。

動態代理的應用有 spring aop、hibernate 數據查詢、測試框架的後端 mock、rpc,Java註解對象獲取等。

60.怎麼實現動態代理?

JDK 原生動態代理和 cglib 動態代理。JDK 原生動態代理是基於接口實現的,而 cglib 是基於繼承當前類的子類實現的。


五、對象拷貝

61.爲什麼要使用克隆?

克隆的對象可能包含一些已經修改過的屬性,而 new 出來的對象的屬性都還是初始化時候的值,所以當需要一個新的對象來保存當前對象的“狀態”就靠克隆方法了。

62.如何實現對象克隆?

  • 實現 Cloneable 接口並重寫 Object 類中的 clone() 方法。
  • 實現 Serializable 接口,通過對象的序列化和反序列化實現克隆,可以實現真正的深度克隆。

63.深拷貝和淺拷貝區別是什麼?

  • 淺克隆:當對象被複制時只複製它本身和其中包含的值類型的成員變量,而引用類型的成員對象並沒有複製。
  • 深克隆:除了對象本身被複制外,對象所包含的所有成員變量也將複製。

 


六、Java Web

64.jsp 和 servlet 有什麼區別?

JSP 是 servlet 技術的擴展,本質上就是 servlet 的簡易方式。servlet 和 JSP 最主要的不同點在於,servlet 的應用邏輯是在 Java 文件中,並且完全從表示層中的 html 裏分離開來,而 JSP 的情況是 Java 和 html 可以組合成一個擴展名爲 JSP 的文件。JSP 側重於視圖,servlet 主要用於控制邏輯。

65.jsp 有哪些內置對象?作用分別是什麼?

JSP 有 9 大內置對象:

  •     request:封裝客戶端的請求,其中包含來自 get 或 post 請求的參數;
  •     response:封裝服務器對客戶端的響應;
  •     pageContext:通過該對象可以獲取其他對象;
  •     session:封裝用戶會話的對象;
  •     application:封裝服務器運行環境的對象;
  •     out:輸出服務器響應的輸出流對象;
  •     config:Web 應用的配置對象;
  •     page:JSP 頁面本身(相當於 Java 程序中的 this);
  •     exception:封裝頁面拋出異常的對象。

66.說一下 jsp 的 4 種作用域?

  • page:代表與一個頁面相關的對象和屬性。
  • request:代表與客戶端發出的一個請求相關的對象和屬性。一個請求可能跨越多個頁面,涉及多個 Web 組件;需要在頁面顯示的臨時數據可以置於此作用域。
  • session:代表與某個用戶與服務器建立的一次會話相關的對象和屬性。跟某個用戶相關的數據應該放在用戶自己的 session 中。
  • application:代表與整個 Web 應用程序相關的對象和屬性,它實質上是跨越整個 Web 應用程序,包括多個頁面、請求和會話的一個全局作用域。

67.session 和 cookie 有什麼區別?

  • 存儲位置不同:session 存儲在服務器端;cookie 存儲在瀏覽器端。
  • 安全性不同:cookie 安全性一般,在瀏覽器存儲,可以被僞造和修改。
  • 容量和個數限制:cookie 有容量限制,每個站點下的 cookie 也有個數限制。
  • 存儲的多樣性:session 可以存儲在 Redis 中、數據庫中、應用程序中;而 cookie 只能存儲在瀏覽器中。

【分享】

cookie 的總數量沒有限制,但是每個域名的COOKIE 數量和每個COOKIE 的大小是有限制的!

  • IE 每個域名限制爲50 個。
  • Firefox 每個域名cookie 限制爲50 個。
  • Opera 每個域名cookie 限制爲30 個。
  • Safari/webkit 貌似沒有cookie 限制。但是假如cookie 很多,則會使header 大小超過服務器的處理的限制,導致錯誤發生。
  • 不同瀏覽器間每個cookie 文件大小也不同
  • Firefox 和safari 是4097 個字節,包括名(name)、值(value)和等號。
  • Opera 是4096 個字節,包括:名(name)、值(value)和等號。
  • IE 是4095 個字節,包括:名(name)、值(value)和等號。

68.說一下 session 的工作原理?

session 的工作原理是客戶端登錄完成之後,服務器會創建對應的 session,session 創建完之後,會把 session 的 id 發送給客戶端,客戶端再存儲到瀏覽器中。這樣客戶端每次訪問服務器時,都會帶着 sessionid,服務器拿到 sessionid 之後,在內存找到與之對應的 session 這樣就可以正常工作了。

69.如果客戶端禁止 cookie 能實現 session 還能用嗎?

可以用,session 只是依賴 cookie 存儲 sessionid,如果 cookie 被禁用了,可以使用 url 中添加 sessionid 的方式保證 session 能正常使用。

70.spring mvc 和 struts 的區別是什麼?

  • 攔截級別:struts2 是類級別的攔截;spring mvc 是方法級別的攔截。
  • 數據獨立性:spring mvc 的方法之間基本上獨立的,獨享 request 和 response 數據,請求數據通過參數獲取,處理結果通過 ModelMap 交回給框架,方法之間不共享變量;而 struts2 雖然方法之間也是獨立的,但其所有 action 變量是共享的,這不會影響程序運行,卻給我們編碼和讀程序時帶來了一定的麻煩。
  • 攔截機制:struts2 有以自己的 interceptor 機制,spring mvc 用的是獨立的 aop 方式,這樣導致struts2 的配置文件量比 spring mvc 大。
  • 對 ajax 的支持:spring mvc 集成了ajax,所有 ajax 使用很方便,只需要一個註解 @ResponseBody 就可以實現了;而 struts2 一般需要安裝插件或者自己寫代碼才行。

71.如何避免 sql 注入?

  • 使用預處理 PreparedStatement。
  • 使用正則表達式過濾掉字符中的特殊字符。

72.什麼是 XSS 攻擊,如何避免?

XSS 攻擊:即跨站腳本攻擊,它是 Web 程序中常見的漏洞。原理是攻擊者往 Web 頁面裏插入惡意的腳本代碼(css 代碼、Javascript 代碼等),當用戶瀏覽該頁面時,嵌入其中的腳本代碼會被執行,從而達到惡意攻擊用戶的目的,如盜取用戶 cookie、破壞頁面結構、重定向到其他網站等。

預防 XSS 的核心是必須對輸入的數據做過濾處理。

73.什麼是 CSRF 攻擊,如何避免?

CSRF:Cross-Site Request Forgery(中文:跨站請求僞造),可以理解爲攻擊者盜用了你的身份,以你的名義發送惡意請求,比如:以你名義發送郵件、發消息、購買商品,虛擬貨幣轉賬等。

防禦手段:

  •     驗證請求來源地址;
  •     關鍵操作添加驗證碼;
  •     在請求地址添加 token 並驗證。

七、異常

74.throw 和 throws 的區別?

  • throw:是真實拋出一個異常。
  • throws:是聲明可能會拋出一個異常。

75.final、finally、finalize 有什麼區別?

  • final:是修飾符,如果修飾類,此類不能被繼承;如果修飾方法和變量,則表示此方法和此變量不能在被改變,只能使用。
  • finally:是 try{} catch{} finally{} 最後一部分,表示不論發生任何情況都會執行,finally 部分可以省略,但如果 finally 部分存在,則一定會執行 finally 裏面的代碼。
  • finalize: 是 Object 類的一個方法,在垃圾收集器執行的時候會調用被回收對象的此方法。

76.try-catch-finally 中哪個部分可以省略?

try-catch-finally 其中 catch 和 finally 都可以被省略,但是不能同時省略,也就是說有 try 的時候,必須後面跟一個 catch 或者 finally。

77.try-catch-finally 中,如果 catch 中 return 了,finally 還會執行嗎?

finally 一定會執行,即使是 catch 中 return 了,catch 中的 return 會等 finally 中的代碼執行完之後,纔會執行。

78.常見的異常類有哪些?

  • NullPointerException 空指針異常
  • ClassNotFoundException 指定類不存在
  • NumberFormatException 字符串轉換爲數字異常
  • IndexOutOfBoundsException 數組下標越界異常
  • ClassCastException 數據類型轉換異常
  • FileNotFoundException 文件未找到異常
  • NoSuchMethodException 方法不存在異常
  • IOException IO 異常
  • SocketException Socket 異常
     

八、網絡

79.http 響應碼 301 和 302 代表的是什麼?有什麼區別?

301:永久重定向。

302:暫時重定向。

它們的區別是,301 對搜索引擎優化(SEO)更加有利;302 有被提示爲網絡攔截的風險。

【分享】

其他的一些常見的響應碼 可以參考之前的一篇文章:https://blog.csdn.net/u011665991/article/details/82458808

80.forward 和 redirect 的區別?

forward 是轉發 和 redirect 是重定向:

  •     地址欄 url 顯示:foward url 不會發生改變,redirect url 會發生改變;
  •     數據共享:forward 可以共享 request 裏的數據,redirect 不能共享;
  •     效率:forward 比 redirect 效率高。

81.簡述 tcp 和 udp的區別?

tcp 和 udp 是 OSI 模型中的運輸層中的協議。tcp 提供可靠的通信傳輸,而 udp 則常被用於讓廣播和細節控制交給應用的通信傳輸。

兩者的區別大致如下:

  •     tcp 面向連接,udp 面向非連接即發送數據前不需要建立鏈接;
  •     tcp 提供可靠的服務(數據傳輸),udp 無法保證;
  •     tcp 面向字節流,udp 面向報文;
  •     tcp 數據傳輸慢,udp 數據傳輸快;

82.tcp 爲什麼要三次握手,兩次不行嗎?爲什麼?

如果採用兩次握手,那麼只要服務器發出確認數據包就會建立連接,但由於客戶端此時並未響應服務器端的請求,那此時服務器端就會一直在等待客戶端,這樣服務器端就白白浪費了一定的資源。若採用三次握手,服務器端沒有收到來自客戶端的再此確認,則就會知道客戶端並沒有要求建立請求,就不會浪費服務器的資源

83.說一下 tcp 粘包是怎麼產生的?

tcp 粘包可能發生在發送端或者接收端,分別來看兩端各種產生粘包的原因:

  • 發送端粘包:發送端需要等緩衝區滿才發送出去,造成粘包;
  • 接收方粘包:接收方不及時接收緩衝區的包,造成多個包接收。

84.OSI 的七層模型都有哪些?

  • 物理層:利用傳輸介質爲數據鏈路層提供物理連接,實現比特流的透明傳輸。
  • 數據鏈路層:負責建立和管理節點間的鏈路。
  • 網絡層:通過路由選擇算法,爲報文或分組通過通信子網選擇最適當的路徑。
  • 傳輸層:向用戶提供可靠的端到端的差錯和流量控制,保證報文的正確傳輸。
  • 會話層:向兩個實體的表示層提供建立和使用連接的方法。
  • 表示層:處理用戶信息的表示問題,如編碼、數據格式轉換和加密解密等。
  • 應用層:直接向用戶提供服務,完成用戶希望在網絡上完成的各種工作。

85.get 和 post 請求有哪些區別?

  • get 請求會被瀏覽器主動緩存,而 post 不會。
  • GET使用URL或Cookie傳參,而POST將數據放在BODY中。
  • get 傳遞參數有大小限制,而 post 沒有。
  • post 參數傳輸更安全,get 的參數會明文限制在 url 上,post 不會。

說到get 和 post 請求有哪些區別,大多數同學都會想到這幾個標準答案,但是這三個答案是否是正確的還是有待商榷。

    1. GET使用URL或Cookie傳參,而POST將數據放在BODY中

GET和POST是由HTTP協議定義的。在HTTP協議中,Method和Data(URL, Body, Header)是正交的兩個概念,也就是說,使用哪個Method與應用層的數據如何傳輸是沒有相互關係的。

HTTP沒有要求,如果Method是POST數據就要放在BODY中。也沒有要求,如果Method是GET,數據(參數)就一定要放在URL中而不能放在BODY中。

那麼,網上流傳甚廣的這個說法是從何而來的呢?我在HTML標準中,找到了相似的描述。這和網上流傳的說法一致。但是這只是HTML標準對HTTP協議的用法的約定。怎麼能當成GET和POST的區別呢?

而且,現代的Web Server都是支持GET中包含BODY這樣的請求。雖然這種請求不可能從瀏覽器發出,但是現在的Web Server又不是隻給瀏覽器用,已經完全地超出了HTML服務器的範疇了。

    2. GET方式提交的數據有長度限制,則POST的數據則可以非常大

先說結論:HTTP協議對GET和POST都沒有對長度的限制。HTTP協議明確地指出了,HTTP頭和Body都沒有長度的要求。

首先是"GET方式提交的數據有長度限制",如果我們使用GET通過URL提交數據,那麼GET可提交的數據量就跟URL的長度有直接關係了。而實際上,URL不存在參數上限的問題,HTTP協議規範沒有對URL長度進行限制。這個限制是特定的瀏覽器及服務器對它的限制。IE對URL長度的限制是2083字節(2K+35)。對於其他瀏覽器,如Netscape、FireFox等,理論上沒有長度限制,其限制取決於操作系統的支持。

注意這個限制是整個URL長度,而不僅僅是你的參數值數據長度。

POST也是一樣,POST是沒有大小限制的,HTTP協議規範也沒有對POST數據進行大小限制,起限制作用的是服務器的處理程序的處理能力。

當然,我們常說GET的URL會有長度上的限制這個說法是怎麼回事呢?雖然這個不是GET和POST的本質區別,但是我們也可以說說導致URL長度限制的兩方面的原因:

1. 瀏覽器。早期的瀏覽器會對URL長度做限制。而現在的具體限制是怎麼樣的,我自己沒有親測過,就不復制網上的說法啦。

2. 服務器。URL長了,對服務器處理也是一種負擔。原本一個會話就沒有多少數據,現在如果有人惡意地構造幾個M大小的URL,並不停地訪問你的服務器。服務器的最大併發數顯然會下降。另一種攻擊方式是,告訴服務器Content-Length是一個很大的數,然後只給服務器發一點兒數據,服務器你就傻等着去吧。哪怕你有超時設置,這種故意的次次訪問超時也能讓服務器吃不了兜着走。有鑑於此,多數服務器出於安全啦、穩定啦方面的考慮,會給URL長度加限制。但是這個限制是針對所有HTTP請求的,與GET、POST沒有關係。

    3. POST比GET安全,因爲數據在地址欄上不可見

這個說法其實也是基於上面的1,2兩點的基礎上來說的,我覺得沒什麼問題,但是需要明白爲什麼使用GET在地址欄上就不安全了,以及還有沒有其他原因說明“POST比GET安全”。

通過GET提交數據,用戶名和密碼將明文出現在URL上,因爲登錄頁面有可能被瀏覽器緩存,其他人查看瀏覽器的歷史紀錄,那麼別人就可以拿到你的賬號和密碼了,除此之外,使用GET提交數據還可能會造成Cross-site request forgery攻擊。

三、我的理解

“1. GET使用URL或Cookie傳參,而POST將數據放在BODY中”,這個是因爲HTTP協議用法的約定。並非它們的本身區別。

“2. GET方式提交的數據有長度限制,則POST的數據則可以非常大”,這個是因爲它們使用的操作系統和瀏覽器設置的不同引起的區別。也不是GET和POST本身的區別。

“3. POST比GET安全,因爲數據在地址欄上不可見”,這個說法沒毛病,但依然不是GET和POST本身的區別。

雖然這三點不是它們的本身區別,但至少是它們在使用上的區別,所以我在面試這個問題時,如果面試者能夠回答上面三點我基本會給個及格分。那麼你想不想要更高的分數?

四、終極區別

GET和POST最大的區別主要是GET請求是冪等性的,POST請求不是。這個是它們本質區別,上面的只是在使用上的區別。

    什麼是冪等性?冪等性是指一次和多次請求某一個資源應該具有同樣的副作用。簡單來說意味着對同一URL的多個請求應該返回同樣的結果。

正因爲它們有這樣的區別,所以不應該且不能用get請求做數據的增刪改這些有副作用的操作。因爲get請求是冪等的,在網絡不好的隧道中會嘗試重試。如果用get請求增數據,會有重複操作的風險,而這種重複操作可能會導致副作用(瀏覽器和操作系統並不知道你會用get請求去做增操作)。

五、我的建議

如果面試官問你這個問題時,我建議你說出上面三點,同時要說明那三點是它們在使用上的區別,當然也要把它們的終極區別給說出來。

PS:曾經有一個研讀了HTTP協議的人去一家公司面試,面試官問他這個問題時,他回答“GET是用於獲取數據的,POST一般用於將數據發給服務器。其他GET和POST沒什麼區別”,於是被刷了。

因爲有些面試官心中也只有那一個“標準答案”。


86.如何實現跨域?

實現跨域有以下幾種方案:

  • 服務器端運行跨域 設置 CORS 等於 *;
  • 在單個接口使用註解 @CrossOrigin 運行跨域;
  • 使用 jsonp 跨域;

87.說一下 JSONP 實現原理?

ajax請求受同源策略影響,不允許進行跨域請求,而script標籤src屬性中的鏈接卻可以訪問跨域的js腳本,利用這個特性,服務端不再返回JSON格式的數據,而是返回一段調用某個函數的js代碼,在src中進行了調用,這樣實現了跨域。

【分享】具體可以參考此文章:

https://blog.csdn.net/u011897301/article/details/52679486/

https://blog.csdn.net/u011897301/article/details/52679486/


九、設計模式

88.說一下你熟悉的設計模式?

一共23種設計模式!

引用《軟件祕笈-設計模式那點事》書籍:

按照目的來分,設計模式可以分爲創建型模式、結構型模式和行爲型模式。
創建型模式用來處理對象的創建過程;結構型模式用來處理類或者對象的組合;行爲型模式用來對類或對象怎樣交互和怎樣分配職責進行描述。

創建型模式用來處理對象的創建過程,主要包含以下5種設計模式:


結構型模式用來處理類或者對象的組合,主要包含以下7種設計模式:


行爲型模式用來對類或對象怎樣交互和怎樣分配職責進行描述,主要包含以下11種設計模式:

  • 責任鏈模式(Chain of Responsibility Pattern)
  • 命令模式(Command Pattern)
  • 解釋器模式(Interpreter Pattern)
  • 迭代器模式(Iterator Pattern)
  • 中介者模式(Mediator Pattern)
  • 備忘錄模式(Memento Pattern)
  • 觀察者模式(Observer Pattern)
  • 狀態模式(State Pattern)
  • 策略模式(Strategy Pattern)
  • 模板方法模式(Template Method Pattern)
  • 訪問者模式(Visitor Pattern)

舉兩個單例模式,其他的自己網上學習吧
單例模式實現1:

public class Singleton {
    // 類共享實例對象
    private static Singleton singleton = null;
    // 私有構造方法
    private Singleton() {
        System.out.println("-- this is Singleton!!!");
    }
    // 獲得單例方法
    public synchronized static Singleton getInstance() {
        // 判斷 共享對象是否爲null ,如何爲null則new一個新對象
        if (singleton == null) {
            singleton = new Singleton();
        }
        return singleton;
    }
}


單例模式實現2:

public class Singleton {
    // 類共享實例對象 實例化
    private static Singleton singleton = new Singleton();
    // 私有構造方法
    private Singleton() {
        System.out.println("-- this is Singleton!!!");
    }
    // 獲得單例方法
    public static Singleton getInstance() {
        // 直接返回共享對象
        return singleton;
    }
}

89.簡單工廠和抽象工廠有什麼區別?

工廠模式主要是爲創建對象提供了接口。工廠模式按照《Java與模式》中的提法分爲三類:

  • 1. 簡單工廠模式(Simple Factory)
  • 2. 工廠方法模式(Factory Method)
  • 3. 抽象工廠模式(Abstract Factory)

這三種模式從上到下逐步抽象,並且更具一般性。還有一種分類法,就是將簡單工廠模式看爲工廠方法模式的一種特例,兩個歸爲一類。兩者皆可,這本爲使用《Java與模式》的分類方法。
在什麼樣的情況下我們應該記得使用工廠模式呢?大體有兩點:

  • 1.在編碼時不能預見需要創建哪種類的實例。
  • 2.系統不應依賴於產品類實例如何被創建、組合和表達的細節

具體的可以參考這篇文章:https://www.cnblogs.com/zhangchenliang/p/3700820.html


十、Spring/Spring MVC

90.爲什麼要使用 spring?

Spring是一個輕量級的控制反轉(IoC)和麪向切面(AOP)的容器框架,它由Rod Johnson創建。它是爲了解決企業應用開發的複雜性而創建的。Spring使用基本的JavaBean來完成以前只可能由EJB完成的事情。

91.解釋一下什麼是 aop?

    AOP(Aspect-Oriented Programming)指一種程序設計範型,該範型以一種稱爲切面(aspect)的語言構造爲基礎,切面是一種新的模塊化機制,用來描述分散在對象、類或方法中的橫切關注點(crosscutting concern)。

    Spring提供了面向切面編程的豐富支持,允許通過分離應用的業務邏輯與系統級服務(例如審計(auditing)和事務(transaction)管理)進行內聚性的開發。應用對象只實現它們應該做的——完成業務邏輯——僅此而已。它們並不負責(甚至是意識)其它的系統級關注點,例如日誌或事務支持。

92.解釋一下什麼是 ioc?

       IoC就是(Inversion of Control),控制反轉。在Java開發中,IoC意味着將你設計好的類交給系統去控制,而不是在你的類內部控制。這稱爲控制反轉。

   Spring通過一種稱作控制反轉(IoC)的技術促進了鬆耦合。當應用了IoC,一個對象依賴的其它對象會通過被動的方式傳遞進來,而不是這個對象自己創建或者查找依賴對象。你可以認爲IoC與JNDI相反——不是對象從容器中查找依賴,而是容器在對象初始化時不等對象請求就主動將依賴傳遞給它。

93.spring 有哪些主要模塊?

Spring有七大模塊組成:

  • 核心容器(Spring Core)

  核心容器提供Spring框架的基本功能。Spring以bean的方式組織和管理Java應用中的各個組件及其關係。Spring使用BeanFactory來產生和管理Bean,它是工廠模式的實現。BeanFactory使用控制反轉(IoC)模式將應用的配置和依賴性規範與實際的應用程序代碼分開。

  • 應用上下文(Spring Context)

  Spring上下文是一個配置文件,向Spring框架提供上下文信息。Spring上下文包括企業服務,如JNDI、EJB、電子郵件、國際化、校驗和調度功能。

  • Spring面向切面編程(Spring AOP)

  通過配置管理特性,Spring AOP 模塊直接將面向方面的編程功能集成到了 Spring框架中。所以,可以很容易地使 Spring框架管理的任何對象支持 AOP。Spring AOP 模塊爲基於 Spring 的應用程序中的對象提供了事務管理服務。通過使用 Spring AOP,不用依賴 EJB 組件,就可以將聲明性事務管理集成到應用程序中。

  • JDBC和DAO模塊(Spring DAO)

  JDBC、DAO的抽象層提供了有意義的異常層次結構,可用該結構來管理異常處理,和不同數據庫供應商所拋出的錯誤信息。異常層次結構簡化了錯誤處理,並且極大的降低了需要編寫的代碼數量,比如打開和關閉鏈接。

  • 對象實體映射(Spring ORM)

  Spring框架插入了若干個ORM框架,從而提供了ORM對象的關係工具,其中包括了Hibernate、JDO和 IBatis SQL Map等,所有這些都遵從Spring的通用事物和DAO異常層次結構。

  • Web模塊(Spring Web)

  Web上下文模塊建立在應用程序上下文模塊之上,爲基於web的應用程序提供了上下文。所以Spring框架支持與Struts集成,web模塊還簡化了處理多部分請求以及將請求參數綁定到域對象的工作。

  • MVC模塊(Spring Web MVC)

  MVC框架是一個全功能的構建Web應用程序的MVC實現。通過策略接口,MVC框架變成爲高度可配置的。MVC容納了大量視圖技術,其中包括JSP、POI等,模型來有JavaBean來構成,存放於m當中,而視圖是一個街口,負責實現模型,控制器表示邏輯代碼,由c的事情。Spring框架的功能可以用在任何J2EE服務器當中,大多數功能也適用於不受管理的環境。Spring的核心要點就是支持不綁定到特定J2EE服務的可重用業務和數據的訪問的對象,毫無疑問這樣的對象可以在不同的J2EE環境,獨立應用程序和測試環境之間重用。

94.spring 常用的注入方式有哪些?

之前寫過一篇文章 常用的註解,有需要的可以參考:https://blog.csdn.net/u011665991/article/details/82460263

  • @Configuration把一個類作爲一個IoC容器,它的某個方法頭上如果註冊了@Bean,就會作爲這個Spring容器中的Bean。
  • @Scope註解 作用域
  • @Lazy(true) 表示延遲初始化
  • @Service用於標註業務層組件、
  • @Controller用於標註控制層組件(如struts中的action)
  • @Repository用於標註數據訪問組件,即DAO組件。
  • @Component泛指組件,當組件不好歸類的時候,我們可以使用這個註解進行標註。
  • @Scope用於指定scope作用域的(用在類上)
  • @PostConstruct用於指定初始化方法(用在方法上)
  • @PreDestory用於指定銷燬方法(用在方法上)
  • @DependsOn:定義Bean初始化及銷燬時的順序
  • @Primary:自動裝配時當出現多個Bean候選者時,被註解爲@Primary的Bean將作爲首選者,否則將拋出異常
  • @Autowired 默認按類型裝配,如果我們想使用按名稱裝配,可以結合@Qualifier註解一起使用。如下:
  • @Autowired @Qualifier("personDaoBean") 存在多個實例配合使用
  • @Resource默認按名稱裝配,當找不到與名稱匹配的bean纔會按類型裝配。
  • @PostConstruct 初始化註解
  • @PreDestroy 摧毀註解 默認 單例  啓動就加載
  • @Async異步方法調用

95.spring 中的 bean 是線程安全的嗎?

Spring框架並沒有對單例bean進行任何多線程的封裝處理。關於單例bean的線程安全和併發問題需要開發者自行去搞定。但實際上,大部分的Spring bean並沒有可變的狀態(比如Serview類和DAO類),所以在某種程度上說Spring的單例bean是線程安全的。如果你的bean有多種狀態的話(比如 View Model 對象),就需要自行保證線程安全。

最淺顯的解決辦法就是將多態bean的作用域由“singleton”變更爲“prototype”。

96.spring 支持幾種 bean 的作用域?

當通過spring容器創建一個Bean實例時,不僅可以完成Bean實例的實例化,還可以爲Bean指定特定的作用域。Spring支持如下5種作用域:

  • singleton:單例模式,在整個Spring IoC容器中,使用singleton定義的Bean將只有一個實例

  • prototype:原型模式,每次通過容器的getBean方法獲取prototype定義的Bean時,都將產生一個新的Bean實例

  • request:對於每次HTTP請求,使用request定義的Bean都將產生一個新實例,即每次HTTP請求將會產生不同的Bean實例。只有在Web應用中使用Spring時,該作用域纔有效

  • session:對於每次HTTP Session,使用session定義的Bean豆漿產生一個新實例。同樣只有在Web應用中使用Spring時,該作用域纔有效

  • globalsession:每個全局的HTTP Session,使用session定義的Bean都將產生一個新實例。典型情況下,僅在使用portlet context的時候有效。同樣只有在Web應用中使用Spring時,該作用域纔有效

  其中比較常用的是singleton和prototype兩種作用域。對於singleton作用域的Bean,每次請求該Bean都將獲得相同的實例。容器負責跟蹤Bean實例的狀態,負責維護Bean實例的生命週期行爲;如果一個Bean被設置成prototype作用域,程序每次請求該id的Bean,Spring都會新建一個Bean實例,然後返回給程序。在這種情況下,Spring容器僅僅使用new 關鍵字創建Bean實例,一旦創建成功,容器不在跟蹤實例,也不會維護Bean實例的狀態。

  如果不指定Bean的作用域,Spring默認使用singleton作用域。Java在創建Java實例時,需要進行內存申請;銷燬實例時,需要完成垃圾回收,這些工作都會導致系統開銷的增加。因此,prototype作用域Bean的創建、銷燬代價比較大。而singleton作用域的Bean實例一旦創建成功,可以重複使用。因此,除非必要,否則儘量避免將Bean被設置成prototype作用域。

97.spring 自動裝配 bean 有哪些方式?

  Spring中bean有三種裝配機制,分別是:

  • 1. 在xml中顯示配置;
  • 2. 在java中顯示配置;
  • 3. 隱式的bean發現機制和自動裝配。

【分享】

有需要的可以參考:https://blog.csdn.net/beirdu/article/details/78768606

98.spring 事務實現方式有哪些?

事務:事務邏輯上的一組操作,組成這組操作的各個邏輯單元,要麼一起成功,要麼一起失敗.比如,保證數據的運行不會說A給B錢,A錢給了B卻沒收到。

實現事務的三種方式:

  • 1.aspectJ AOP實現事務:
  • 2.事務代理工廠Bean實現事務:
  • 3.註解方式實現事務:

在需要進行事務的方法上增加一個註解“@Transactional(rollbackFor = MyExepction.class )”

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

  • 事務特性(4種):
    • 原子性 (atomicity):強調事務的不可分割.
    • 一致性 (consistency):事務的執行的前後數據的完整性保持一致.
    • 隔離性 (isolation):一個事務執行的過程中,不應該受到其他事務的干擾
    • 持久性(durability) :事務一旦結束,數據就持久到數據庫
  • 如果不考慮隔離性引發安全性問題:
    • 髒讀 :一個事務讀到了另一個事務的未提交的數據
    • 不可重複讀 :一個事務讀到了另一個事務已經提交的 update 的數據導致多次查詢結果不一致.
    • 虛幻讀 :一個事務讀到了另一個事務已經提交的 insert 的數據導致多次查詢結果不一致.
  • 解決讀問題: 設置事務隔離級別(5種)
    • DEFAULT 這是一個PlatfromTransactionManager默認的隔離級別,使用數據庫默認的事務隔離級別.
    • 未提交讀(read uncommited) :髒讀,不可重複讀,虛讀都有可能發生
    • 已提交讀 (read commited):避免髒讀。但是不可重複讀和虛讀有可能發生
    • 可重複讀 (repeatable read) :避免髒讀和不可重複讀.但是虛讀有可能發生.
    • 串行化的 (serializable) :避免以上所有讀問題.
    • Mysql 默認:可重複讀
    • Oracle 默認:讀已提交

  1. read uncommited:是最低的事務隔離級別,它允許另外一個事務可以看到這個事務未提交的數據。
  2. read commited:保證一個事物提交後才能被另外一個事務讀取。另外一個事務不能讀取該事物未提交的數據。
  3. repeatable read:這種事務隔離級別可以防止髒讀,不可重複讀。但是可能會出現幻象讀。它除了保證一個事務不能被另外一個事務讀取未提交的數據之外還避免了以下情況產生(不可重複讀)。
  4. serializable:這是花費最高代價但最可靠的事務隔離級別。事務被處理爲順序執行。除了防止髒讀,不可重複讀之外,還避免了幻象讀(避免三種)。
  • 事務的傳播行爲(7種)

PROPAGION_XXX :事務的傳播行爲

  • * 保證同一個事務中
    • PROPAGATION_REQUIRED 支持當前事務,如果不存在 就新建一個(默認)
    • PROPAGATION_SUPPORTS 支持當前事務,如果不存在,就不使用事務
    • PROPAGATION_MANDATORY 支持當前事務,如果不存在,拋出異常
  • * 保證沒有在同一個事務中
    • PROPAGATION_REQUIRES_NEW 如果有事務存在,掛起當前事務,創建一個新的事務
    • PROPAGATION_NOT_SUPPORTED 以非事務方式運行,如果有事務存在,掛起當前事務
    • PROPAGATION_NEVER 以非事務方式運行,如果有事務存在,拋出異常
    • PROPAGATION_NESTED 如果當前事務存在,則嵌套事務執行

100.說一下 spring mvc 運行流程?

流程 

  • 1、用戶發送請求至前端控制器DispatcherServlet 
  • 2、DispatcherServlet收到請求調用HandlerMapping處理器映射器。 
  • 3、處理器映射器找到具體的處理器,生成處理器對象及處理器攔截器(如果有則生成)一併返回給DispatcherServlet。 
  • 4、DispatcherServlet調用HandlerAdapter處理器適配器 
  • 5、HandlerAdapter經過適配調用具體的處理器(Controller,也叫後端控制器)。 
  • 6、Controller執行完成返回ModelAndView 
  • 7、HandlerAdapter將controller執行結果ModelAndView返回給DispatcherServlet 
  • 8、DispatcherServlet將ModelAndView傳給ViewReslover視圖解析器 
  • 9、ViewReslover解析後返回具體View 
  • 10、DispatcherServlet根據View進行渲染視圖(即將模型數據填充至視圖中)。 
  • 11、DispatcherServlet響應用戶

101.spring mvc 有哪些組件?

名稱 簡介
HandlerMapping 管理請求(request)和處理句柄(Handler)之間的映射關係
HandlerAdapter 處理句柄適配器,
1.每個HandlerAdapter包裝一個Handler,
2.HandlerAdapter主要用於隔離調用者DispatcherServlet和各式各樣的Handler
HandlerExceptionResolver 處理句柄異常解析器
ViewResolver 視圖解析器:根據視圖名稱和Locale解析爲具體View對象用來渲染頁面
RequestToViewNameTranslator 請求到視圖名稱的翻譯器:從request中獲取視圖名稱,作爲ViewResolver的補充
LocaleResolver Locale地區解析器
處理本地化/國際化語言相關,結合上下文和當前請求分析得到應該使用的Locale地區
ThemeResolver 主題解析器,處理UI主題(look and feel)相關
MultipartResolver Multipart上傳數據解析器
FlashMapManager 管理FlashMap結構的重定向參數

102.@RequestMapping 的作用是什麼?

@RequestMapping

RequestMapping是一個用來處理請求地址映射的註解,可用於類或方法上。

【分享】具體可以參考文章:https://www.cnblogs.com/qq78292959/p/3760560.html

103.@Autowired 的作用是什麼?

這個註解就是spring可以自動幫你把bean裏面引用的對象的setter/getter方法省略,它會自動幫你set/get。

<bean id="userDao" class="..."/>
<bean id="userService" class="...">
    <property name="userDao">
      <ref bean="userDao"/>
    </property>
</bean>

這樣你在userService裏面要做一個userDao的setter/getter方法。

但如果你用了@Autowired的話,你只需要在UserService的實現類中聲明即可。

@Autowired

private IUserDao userdao;

十一、Spring Boot/Spring Cloud

104.什麼是 spring boot?

 SpringBoot是一個框架,一種全新的編程規範,他的產生簡化了框架的使用,所謂簡化是指簡化了Spring衆多框架中所需的大量且繁瑣的配置文件,所以 SpringBoot是一個服務於框架的框架,服務範圍是簡化配置文件

105.爲什麼要用 spring boot?

最明顯的特點是,讓文件配置變的相當簡單、讓應用部署變的簡單(SpringBoot內置服務器,並裝備啓動類代碼),可以快速開啓一個Web容器進行開發

  •   (1)一個簡單的SpringBoot工程是不需要在pom.xml手動添加什麼配置的,如果與其他技術合用 比如postMan(文檔在線自動生成、開發功能測試的一套工具)、Swagger(文檔在線自動生成、開發功能測試的一套工具),則需要在pom.xml中添加依賴,由程序自動加載依賴jar包等配置文件。
  •   (2)我們之前在利用SSM或者SSH開發的時候,在resources中儲存各種對應框架的配置文件,而現在我們只需要一個配置文件即可,配置內容也大體有 服務器端口號、數據庫連接的地址、用戶名、密碼。這樣,雖然簡單 但在一定問題上而言,這也是極不安全的,將所有配置,放在一個文件裏,是很危險的,但對於一般項目而言並不會有太大影響。
  •    (3)在SpringBoot創建時會自動創建Bootdemo1Application啓動類,代表着本工程項目和服務器的啓動加載,在springBoot中是內含服務器的,所以不需手動配置Tomact,但注意端口號衝突問題。

106.spring boot 核心配置文件是什麼?

 核心配置文件是指在resources根目錄下的application.properties或application.yml配置文件,讀取這兩個配置文件的方法有兩種,都比較簡單

107.spring boot 配置文件有哪幾種類型?它們有什麼區別?

這裏我理解的是兩種類型 application.properties和application.yml

application.yml配置結構

spring:
 application:
  name: wxxcx mvc:
  view:
    prefix: /WEB-INF/jsp/ suffix: jsp

application.properties配置結構

spring.application.name=wxxcx
server.port = 9000
server.context-path = /
server.tomcat.uri-encoding = UTF-8
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp

 

108.spring boot 有哪些方式可以實現熱部署?

SpringBoot熱部署方式一共有兩種,分別使用兩種不同的依賴

  SpringBoot 1.3後才擁有SpringBoot devtools熱部署

  ①:spring-boot-devtools   ②:Spring Loaded

  • 方式一: 在項目的pom文件中添加依賴:
<!--熱部署jar-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
</dependency>
  • 方式二: 在項目中添加如下代碼
<build>
        <plugins>
            <plugin>
                <!-- springBoot編譯插件-->
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <dependencies>
                    <!-- spring熱部署 -->
                    <!-- 該依賴在此處下載不下來,可以放置在build標籤外部下載完成後再粘貼進plugin中 -->
                    <dependency>
                        <groupId>org.springframework</groupId>
                        <artifactId>springloaded</artifactId>
                        <version>1.2.6.RELEASE</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>

添加完畢後需要使用mvn指令運行:

    首先找到IDEA中的Edit configurations ,然後進行如下操作:(點擊左上角的"+",然後選擇maven將出現右側面板,在紅色劃線部位輸入如圖所示指令,你可以爲該指令命名(此處命名爲MvnSpringBootRun))

    點擊保存將會在IDEA項目運行部位出現,點擊綠色箭頭運行即可

109.jpa 和 hibernate 有什麼區別?

簡單的可以理解爲:

  • Hibernate是JPA規範的一個具體實現
  • hibernate有JPA沒有的特性 
  • hibernate 的效率更快
  • JPA 有更好的移植性,通用性

【分享】

分享兩篇文章供大家參考:https://www.cnblogs.com/mosoner/p/9494250.html

http://baijiahao.baidu.com/s?id=1602675844799153392&wfr=spider&for=pc

110.什麼是 spring cloud?

  •  Spring Cloud是一個微服務框架,相比Dubbo等RPC框架, Spring Cloud提供的全套的分佈式系統解決方案。 
  • Spring Cloud對微服務基礎框架Netflix的多個開源組件進行了封裝,同時又實現了和雲端平臺以及和Spring Boot開發框架的集成。 
  •  Spring Cloud爲微服務架構開發涉及的配置管理,服務治理,熔斷機制,智能路由,微代理,控制總線,一次性token,全局一致性鎖,leader選舉,分佈式session,集羣狀態管理等操作提供了一種簡單的開發方式。
  •  Spring Cloud 爲開發者提供了快速構建分佈式系統的工具,開發者可以快速的啓動服務或構建應用、同時能夠快速和雲平臺資源進行對接。   

分享兩篇文章供大家參考:https://www.cnblogs.com/lexiaofei/p/6808152.html

https://blog.csdn.net/kkkloveyou/article/details/79210420

https://spring.io/projects/spring-cloud

111.spring cloud 斷路器的作用是什麼?

在分佈式環境下,特別是微服務結構的分佈式系統中, 一個軟件系統調用另外一個遠程系統是非常普遍的。這種遠程調用的被調用方可能是另外一個進程,或者是跨網路的另外一臺主機, 這種遠程的調用和進程的內部調用最大的區別是,遠程調用可能會失敗,或者掛起而沒有任何迴應,直到超時。更壞的情況是, 如果有多個調用者對同一個掛起的服務進行調用,那麼就很有可能的是一個服務的超時等待迅速蔓延到整個分佈式系統,引起連鎖反應, 從而消耗掉整個分佈式系統大量資源。最終可能導致系統癱瘓。

斷路器(Circuit Breaker)模式就是爲了防止在分佈式系統中出現這種瀑布似的連鎖反應導致的災難。

一旦某個電器出問題,爲了防止災難,電路的保險絲就會熔斷。斷路器類似於電路的保險絲, 實現思路非常簡單,可以將需要保護的遠程服務嗲用封裝起來,在內部監聽失敗次數, 一旦失敗次數達到某閥值後,所有後續對該服務的調用,斷路器截獲後都直接返回錯誤到調用方,而不會繼續調用已經出問題的服務, 從而達到保護調用方的目的, 整個系統也就不會出現因爲超時而產生的瀑布式連鎖反應。

分享一篇文章供大家參考:http://www.cnblogs.com/chry/p/7278853.html

112.spring cloud 的核心組件有哪些?

Spring Cloud由衆多子項目組成,如Spring Cloud Config、Spring Cloud Netflix、Spring Cloud Consul 等,提供了搭建分佈式系統及微服務常用的工具,如配置管理、服務發現、斷路器、智能路由、微代理、控制總線、一次性token、全局鎖、選主、分佈式會話和集羣狀態等,滿足了構建微服務所需的所有解決方案。

  • 服務發現——Netflix Eureka
  • 客服端負載均衡——Netflix Ribbon
  • 斷路器——Netflix Hystrix
  • 服務網關——Netflix Zuul
  • 分佈式配置——Spring Cloud Config

分享一篇文章供大家參考:https://blog.csdn.net/springML/article/details/82492643


十二、Hibernate

113.爲什麼要使用 hibernate?

114.什麼是 ORM 框架?

115.hibernate 中如何在控制檯查看打印的 sql 語句?

116.hibernate 有幾種查詢方式?

117.hibernate 實體類可以被定義爲 final 嗎?

118.在 hibernate 中使用 Integer 和 int 做映射有什麼區別?

119.hibernate 是如何工作的?

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

121.說一下 hibernate 的緩存機制?

122.hibernate 對象有哪些狀態?

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

124.hibernate 實體類必須要有無參構造函數嗎?爲什麼?

 


十三、Mybatis

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

  • 1. #將傳入的數據都當成一個字符串,會對自動傳入的數據加一個雙引號。如:order by #user_id#,如果傳入的值是111,那麼解析成sql時的值爲order by "111", 如果傳入的值是id,則解析成的sql爲order by "id".
  • 2. $將傳入的數據直接顯示生成在sql中。如:order by $user_id$,如果傳入的值是111,那麼解析成sql時的值爲order by user_id,  如果傳入的值是id,則解析成的sql爲order by id.
  • 3. #方式能夠很大程度防止sql注入。
  • 4.$方式無法防止Sql注入。
  • 5.$方式一般用於傳入數據庫對象,例如傳入表名.
  • 6.一般能用#的就別用$.
  • MyBatis排序時使用order by 動態參數時需要注意,用$而不是#

分享一篇文章供大家參考:https://www.cnblogs.com/baizhanshi/p/5778692.html

126.mybatis 有幾種分頁方式?

  • 1、數組分頁
  • 2、sql分頁
  • 3、攔截器分頁
  • 4、RowBounds分頁

當然現在也有很多分頁插件:比如PageHelper等

分享一篇文章供大家參考:https://www.cnblogs.com/baizhanshi/p/5778692.html

https://blog.csdn.net/chenbaige/article/details/70846902

127.RowBounds 是一次性查詢全部結果嗎?爲什麼?

是一次性查詢全部結果,只不過會根據參數丟掉一部分

分享一篇文章供大家參考:https://blog.csdn.net/u010077905/article/details/38469653

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

  •   1:邏輯分頁 雖然看起來實現了分頁的功能,但實際上是將查詢的所有結果放置在內存中,每次都從內存獲取。內存開銷比較大,在數據量比較小的情況下效率比物理分頁高;在數據量很大的情況下,內存開銷過大,容易內存溢出,不建議使用
  •   2:物理分頁 這種分頁方法從底層上就是每次只查詢對應條目數量的數據,內存開銷比較小,在數據量比較小的情況下效率比邏輯分頁還是低,在數據量很大的情況下,建議使用物理分頁

129.mybatis 是否支持延遲加載?延遲加載的原理是什麼?

 在mybatis 中默認沒有使用延遲加載 ,但是通過配置  <setting name="lazyLoadingEnabled" value="true"/>實現延遲加載

延遲加載的原理:動態代理:在Hibernate中,被動態代理的延遲對象是one方;many方還是第一個普通的一個對象;

分享幾篇文章供大家參考:http://www.cnblogs.com/trisaeyes/archive/2007/01/08/614996.html

                                            https://www.cnblogs.com/llynic/p/6377783.html

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

一級緩存是SqlSession級別的緩存。在操作數據庫時需要構造sqlSession對象,在對象中有一個數據結構用於存儲緩存數據。不同的sqlSession之間的緩存數據區域是互相不影響的。也就是他只能作用在同一個sqlSession中,不同的sqlSession中的緩存是互相不能讀取的

二級緩存是mapper級別的緩存,多個SqlSession去操作同一個Mapper的sql語句,多個SqlSession可以共用二級緩存,二級緩存是跨SqlSession的。二級緩存的作用範圍更大。

分享幾篇文章供大家參考:https://blog.csdn.net/weixin_36380516/article/details/73194758

                                          https://zhidao.baidu.com/question/140731349194225845.html

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

  •    Hibernate 框架 

        Hibernate是一個開放源代碼的對象關係映射框架,它對JDBC進行了非常輕量級的對象封裝,建立對象與數據庫表的映射。是一個全自動的、完全面向對象的持久層框架。

  •  Mybatis框架

        Mybatis是一個開源對象關係映射框架,原名:ibatis,2010年由谷歌接管以後更名。是一個半自動化的持久層框架。

  •     2.1 開發方面

        在項目開發過程當中,就速度而言:

            hibernate開發中,sql語句已經被封裝,直接可以使用,加快系統開發;

            Mybatis 屬於半自動化,sql需要手工完成,稍微繁瑣;

        但是,凡事都不是絕對的,如果對於龐大複雜的系統項目來說,發雜語句較多,選擇hibernate 就不是一個好方案。

  •     2.2 sql優化方面

        Hibernate 自動生成sql,有些語句較爲繁瑣,會多消耗一些性能;

        Mybatis 手動編寫sql,可以避免不需要的查詢,提高系統性能;

  •     2.3 對象管理比對

        Hibernate 是完整的對象-關係映射的框架,開發工程中,無需過多關注底層實現,只要去管理對象即可;

        Mybatis 需要自行管理 映射關係;

  •     2.4 緩存方面   
    <ul><li><strong>&nbsp; 相同點:</strong></li>
    	<li>&nbsp;Hibernate和Mybatis的二級緩存除了採用系統默認的緩存機制外,都可以通過實現你自己的緩存或爲其他第三方緩 &nbsp; &nbsp;存方案,創建適配器來完全覆蓋緩存行爲。</li>
    	<li><strong>不同點:</strong></li>
    	<li><strong>Hibernate的二級緩存配置在SessionFactory生成的配置文件中進行詳細配置,然後再在具體的表-對象映射中配置是那種緩存。</strong></li>
    	<li>MyBatis的二級緩存配置都是在每個具體的表-對象映射中進行詳細配置,這樣針對不同的表可以自定義不同的緩存機制。並且Mybatis可以在命名空間中共享相同的緩存配置和實例,通過Cache-ref來實現。</li>
    </ul></li>
    

比較:

  • Hibernate 具有良好的管理機制,用戶不需要關注SQL,如果二級緩存出現髒數據,系統會保存,;
  • Mybatis 在使用的時候要謹慎,避免緩存CAche 的使用。

Hibernate優勢

  • Hibernate的DAO層開發比MyBatis簡單,Mybatis需要維護SQL和結果映射。

  • Hibernate對對象的維護和緩存要比MyBatis好,對增刪改查的對象的維護要方便。

  • Hibernate數據庫移植性很好,MyBatis的數據庫移植性不好,不同的數據庫需要寫不同SQL。

  • Hibernate有更好的二級緩存機制,可以使用第三方緩存。MyBatis本身提供的緩存機制不佳。

Mybatis優勢

  • MyBatis可以進行更爲細緻的SQL優化,可以減少查詢字段。

  • MyBatis容易掌握,而Hibernate門檻較高。

一句話總結

  • Mybatis:小巧、方便、高效、簡單、直接、半自動化
  • Hibernate:強大、方便、高效、複雜、間接、全自動化

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

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

  • SimpleExecutor:每執行一次update或select,就開啓一個Statement對象,用完立刻關閉Statement對象。
  • ReuseExecutor:執行update或select,以sql作爲key查找Statement對象,存在就使用,不存在就創建,用完後,不關閉Statement對象,而是放置於Map內,供下一次使用。簡言之,就是重複使用Statement對象。
  • BatchExecutor:執行update(沒有select,JDBC批處理不支持select),將所有sql都添加到批處理中(addBatch()),等待統一執行(executeBatch()),它緩存了多個Statement對象,每個Statement對象都是addBatch()完畢後,等待逐一執行executeBatch()批處理。與JDBC批處理相同。

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

Mybatis中如何指定使用哪一種Executor執行器?

答:在Mybatis配置文件中,可以指定默認的ExecutorType執行器類型,也可以手動給DefaultSqlSessionFactory的創建SqlSession的方法傳遞ExecutorType類型參數。

133.mybatis 分頁插件的實現原理是什麼?

實現原理: 就是在StatementHandler之前進行攔截,對MappedStatement進行一系列的操作(大致就是拼上分頁sql)

分享幾篇文章供大家參考:https://blog.csdn.net/tuesdayma/article/details/80166361

134.mybatis 如何編寫一個自定義插件?

 因爲本人目前沒有寫過自定義四插件,所以網上找了一篇文章供大家分享

https://www.jianshu.com/p/96ddaec4aea7


十四、RabbitMQ

135.rabbitmq 的使用場景有哪些?

  • 場景1:單發送單接收
  • 場景2:單發送多接收場景3:Publish/Subscribe
  • 場景3:Publish/Subscribe
  • 場景4:Routing (按路線發送接收)
  • 場景5:Topics (按topic發送接收)

分享幾篇文章供大家參考:https://www.cnblogs.com/luxiaoxun/p/3918054.html

136.rabbitmq 有哪些重要的角色?

  •     none
    • 1、不能訪問 management plugin
  •     management
    • 1、用戶可以通過AMQP做的任何事外加:
    • 2、列出自己可以通過AMQP登入的virtual hosts  
    • 3、查看自己的virtual hosts中的queues, exchanges 和 bindings
    • 4、查看和關閉自己的channels 和 connections
    • 5、查看有關自己的virtual hosts的“全局”的統計信息,包含其他用戶在這些virtual hosts中的活動。
  •     policymaker
    • 1、management可以做的任何事外加:
    • 2、查看、創建和刪除自己的virtual hosts所屬的policies和parameters
  •     monitoring
    • 1、management可以做的任何事外加:
    • 2、列出所有virtual hosts,包括他們不能登錄的virtual hosts
    • 3、查看其他用戶的connections和channels
    • 4、查看節點級別的數據如clustering和memory使用情況
    • 5、查看真正的關於所有virtual hosts的全局的統計信息
  •     administrator
    • 1、policymaker和monitoring可以做的任何事外加:
    • 2、創建和刪除virtual hosts
    • 3、查看、創建和刪除users
    • 4、查看創建和刪除permissions
    • 5、關閉其他用戶的connections

分享幾篇文章供大家參考:https://www.cnblogs.com/luxiaoxun/p/3918054.html

137.rabbitmq 有哪些重要的組件?

Spring AMQP 是基於 Spring 框架的AMQP消息解決方案,提供模板化的發送和接收消息的抽象層,提供基於消息驅動的 POJO的消息監聽等,很大程度上方便了我們進行相關程序的開發。

Message消息是當前模型中操縱的基本單位,它由Producer產生,經過路由轉發被Consumer所消費。它是生產者和消費者發送和處理的對象。消息頭是由一系列的可選屬性組成,這些屬性包括routing-key(路由鍵)、priority(相對於其他消息的優先權)、delivery-mode(指出該消息可能需要持久性存儲)等。

Exchange用來接收生產者發送的消息並將這些消息路由給服務器中的隊列。

Exchange包含4種類型:Direct, Topic, Fanout, Headers。不同的類型,他們如何處理綁定到隊列方面的行爲會有所不同。

  1. Direct類型: 允許一個隊列通過一個固定的Routing-key(通常是隊列的名字)進行綁定。 Direct交換器將消息根據其routing-key屬性投遞到包含對應key屬性的綁定器上。
  2. Topic類型: 支持消息的Routing-key用*或#的模式,進行綁定。*匹配一個單詞,#匹配0個或者多個單詞。例如,binding key *.user.# 匹配routing key爲 usd.user和eur.user.db,但是不匹配user.hello。
  3. Fanout類型:它只是將消息廣播到所有綁定到它的隊列中,而不考慮routing key的值。
  4. Header類型: 它根據應用程序消息的特定屬性進行匹配,這些消息可能在binding key中標記爲可選或者必選。

Queue隊列,它代表了Message Consumer接收消息的地方,它用來保存消息直到發送給消費者。Queue有以下一些重要的屬性。

  1. 持久性:如果啓用,隊列將會在消息協商器(Broker)重啓前都有效。
  2. 自動刪除:如果啓用,那麼隊列將會在所有的消費者停止使用之後自動刪除掉自身。
  3. 惰性:如果沒有聲明隊列,那麼在執行到使用的時候會導致異常,並不會主動聲明。
  4. 排他性:如果啓用,隊列只能被聲明它的消費者使用。

Binding綁定,生產者發送消息到Exchange,接收者從Queue接收消息,而綁定(Binging)是生產者和消費者消息傳遞的重要連接,它是連接生產者和消費者進行信息交流的關鍵。

簡單來說,RabbitMQ就是一個消息代理機制。它的工作就是接收和轉發消息。你可以把它當作是一個郵局:寄信人把信件放入郵箱,郵遞員就會把信件投遞到你的收件人處。在這個比喻中,RabbitMQ就扮演着郵箱、郵局以及郵遞員的角色。其中:

  • Exchange: 就是順豐和韻達。
  • routingkey: 就是郵件地址的概念.
  • queue: 就是郵箱接收軟件,但是可以接收多個地址的郵件,通過bind實現。
  • producer: 消息生產者,就是投遞消息的程序。
  • consumer:消息消費者,就是接受消息的程序。
  • channel:消息通道,在客戶端的每個連接裏,可建立多個channel,每個channel代表一個會話任務。
     

138.rabbitmq 中 vhost 的作用是什麼?

vhost本質上是一個mini版的RabbitMQ服務器,擁有自己的隊列、綁定、交換器和權限控制;

vhost通過在各個實例間提供邏輯上分離,允許你爲不同應用程序安全保密地運行數據;

RabbitMQ的Vhost主要是用來劃分不同業務模塊。不同業務模塊之間沒有信息交互。

Vhost之間相互完全隔離,不同Vhost之間無法共享Exchange和Queue。因此Vhost之間數據無法共享和分享。如果要實現這種功能,需要Vhost之間手動構建對應代碼邏輯。

分享幾篇文章供大家參考:https://www.cnblogs.com/zhengchunyuan/p/9253725.html

                                            https://www.rabbitmq.com/vhosts.html

139.rabbitmq 的消息是怎麼發送的?
RabbitMQ事務和Confirm發送方消息確認

分享幾篇文章供大家參考:https://www.cnblogs.com/vipstone/p/9295625.html

140.rabbitmq 怎麼保證消息的穩定性?

正常情況下,如果消息經過交換器進入隊列就可以完成消息的持久化,但如果消息在沒有到達broker之前出現意外,那就造成消息丟失,有沒有辦法可以解決這個問題?RabbitMQ有兩種方式來解決這個問題:

  1. 通過AMQP提供的事務機制實現;
  2. 使用發送者確認模式實現;

分享幾篇文章供大家參考:https://www.cnblogs.com/vipstone/p/9350075.html

141.rabbitmq 怎麼避免消息丟失?

  1. 消息持久化
  2. ACK確認機制
  3. 設置集羣鏡像模式
  4. 消息補償機制

分享幾篇文章供大家參考:https://blog.csdn.net/u011665991/article/details/89946185

142.要保證消息持久化成功的條件有哪些?

需要將queue,exchange和Message都持久化。

分享幾篇文章供大家參考:https://blog.csdn.net/u011665991/article/details/89946411

未更新完成。。。。

143.rabbitmq 持久化有什麼缺點?

144.rabbitmq 有幾種廣播類型?

145.rabbitmq 怎麼實現延遲消息隊列?

146.rabbitmq 集羣有什麼用?

147.rabbitmq 節點的類型有哪些?

148.rabbitmq 集羣搭建需要注意哪些問題?

149.rabbitmq 每個節點是其他節點的完整拷貝嗎?爲什麼?

150.rabbitmq 集羣中唯一一個磁盤節點崩潰了會發生什麼情況?

151.rabbitmq 對集羣節點停止順序有要求嗎?

 


十五、Kafka

152.kafka 可以脫離 zookeeper 單獨使用嗎?爲什麼?

153.kafka 有幾種數據保留的策略?

154.kafka 同時設置了 7 天和 10G 清除數據,到第五天的時候消息達到了 10G,這個時候 kafka 將如何處理?

155.什麼情況會導致 kafka 運行變慢?

156.使用 kafka 集羣需要注意什麼?

 


十六、Zookeeper

157.zookeeper 是什麼?

158.zookeeper 都有哪些功能?

159.zookeeper 有幾種部署模式?

160.zookeeper 怎麼保證主從節點的狀態同步?

161.集羣中爲什麼要有主節點?

162.集羣中有 3 臺服務器,其中一個節點宕機,這個時候 zookeeper 還可以使用嗎?

163.說一下 zookeeper 的通知機制?

 


十七、MySql

164.數據庫的三範式是什麼?

165.一張自增表裏面總共有 7 條數據,刪除了最後 2 條數據,重啓 mysql 數據庫,又插入了一條數據,此時 id 是幾?

166.如何獲取當前數據庫版本?

167.說一下 ACID 是什麼?

168.char 和 varchar 的區別是什麼?

169.float 和 double 的區別是什麼?

170.mysql 的內連接、左連接、右連接有什麼區別?

171.mysql 索引是怎麼實現的?

172.怎麼驗證 mysql 的索引是否滿足需求?

173.說一下數據庫的事務隔離?

174.說一下 mysql 常用的引擎?

175.說一下 mysql 的行鎖和表鎖?

176.說一下樂觀鎖和悲觀鎖?

177.mysql 問題排查都有哪些手段?

178.如何做 mysql 的性能優化?

 


十八、Redis

179.redis 是什麼?都有哪些使用場景?

Redis是一個基於內存的高性能開源的 key—value型 單線程 數據庫,支持string、list、set、zset和hash類型數據。

適用場景: 對擴展性要求高的數據

  1. 數據高併發的讀寫
  2. 海量數據的讀寫

不適場景:

  1. 需要事務支持(非關係型數據庫)
  2. 基於sql結構化查詢儲存,關係複雜

180.redis 有哪些功能?

  1. 全頁面緩存
  2. 順序排列
  3. 會話session存儲
  4. 隊列
  5. pub/sub

具體參考文章:https://blog.csdn.net/sinat_34496643/article/details/80077319

181.redis 和 memecache 有什麼區別?

  • redis相比memcached有哪些優勢?   

   (1) memcached所有的值均是簡單的字符串,redis作爲其替代者,支持更爲豐富的數據類型 
   (2) redis的速度比memcached快很多 (3) redis可以持久化其數據

  • Memcache與Redis的區別都有哪些?    

   1)、存儲方式 Memecache把數據全部存在內存之中,斷電後會掛掉,數據不能超過內存大小。 Redis有部份存在硬盤上,這樣能保證數據的持久性。 
   2)、數據支持類型 Memcache對數據類型支持相對簡單。 Redis有複雜的數據類型。 
   3)、使用底層模型不同 它們之間底層實現方式 以及與客戶端之間通信的應用協議不一樣。 Redis直接自己構建了VM 機制 ,因爲一般的系統調用系統函數的話,會浪費一定的時間去移動和請求。 

182.redis 爲什麼是單線程的?

   redis利用隊列技術將併發訪問變爲串行訪問,消除了傳統數據庫串行控制的開銷

183.什麼是緩存穿透?怎麼解決?

     緩存穿透是指查詢一個一定不存在的數據,由於緩存是不命中時需要從數據庫查詢,查不到數據則不寫入緩存,這將導致這個不存在的數據每次請求都要到數據庫去查詢,造成緩存穿透。

解決辦法:

     1.布隆過濾 2. 緩存空對象. 將 null 變成一個值.

具體參考文章:https://blog.csdn.net/u011665991/article/details/89956398

184.redis 支持的數據類型有哪些?

redis支持豐富的數據類型,從最基礎的string到複雜的常用到的數據結構都有支持:

  1. string:最基本的數據類型,二進制安全的字符串,最大512M。
  2. list:按照添加順序保持順序的字符串列表。
  3. set:無序的字符串集合,不存在重複的元素。
  4. sorted set:已排序的字符串集合。
  5. hash:key-value對的一種集合。
  6. bitmap:更細化的一種操作,以bit爲單位。
  7. hyperloglog:基於概率的數據結構。

這些衆多的數據類型,主要是爲了支持各種場景的需要,當然每種類型都有不同的時間複雜度。其實這些複雜的數據結構相當於之前在《解讀REST》這個系列博客基於網絡應用的架構風格中介紹到的遠程數據訪問(Remote Data Access = RDA)的具體實現,即通過在服務器上執行一組標準的操作命令,在服務端之間得到想要的縮小後的結果集,從而簡化客戶端的使用,也可以提高網絡性能。比如如果沒有list這種數據結構,你就只能把list存成一個string,客戶端拿到完整的list,操作後再完整的提交給redis,會產生很大的浪費。

185.redis 支持的 java 客戶端都有哪些?

Redisson,Jedis,lettuce等等,官方推薦使用Redisson。

186.jedis 和 redisson 有哪些區別?

  • Jedis api 在線網址:http://tool.oschina.net/uploads/apidocs/redis/clients/jedis/Jedis.html
  • redisson 官網地址:https://redisson.org/
  • redisson git項目地址:https://github.com/redisson/redisson
  • lettuce 官網地址:https://lettuce.io/
  • lettuce git項目地址:https://github.com/lettuce-io/lettuce-core

概念:

  Jedis:是Redis的Java實現客戶端,提供了比較全面的Redis命令的支持,

  Redisson:實現了分佈式和可擴展的Java數據結構。

  Lettuce:高級Redis客戶端,用於線程安全同步,異步和響應使用,支持集羣,Sentinel,管道和編碼器。

優點:

  Jedis:比較全面的提供了Redis的操作特性

  Redisson:促使使用者對Redis的關注分離,提供很多分佈式相關操作服務,例如,分佈式鎖,分佈式集合,可通過Redis支持延遲隊列

  Lettuce:主要在一些分佈式緩存框架上使用比較多

可伸縮:

Jedis:使用阻塞的I/O,且其方法調用都是同步的,程序流需要等到sockets處理完I/O才能執行,不支持異步。Jedis客戶端實例不是線程安全的,所以需要通過連接池來使用Jedis。

Redisson:基於Netty框架的事件驅動的通信層,其方法調用是異步的。Redisson的API是線程安全的,所以可以操作單個Redisson連接來完成各種操作

Lettuce:基於Netty框架的事件驅動的通信層,其方法調用是異步的。Lettuce的API是線程安全的,所以可以操作單個Lettuce連接來完成各種操作

結論:

建議使用:Jedis + Redisson

187.怎麼保證緩存和數據庫數據的一致性?

  1. 對刪除緩存進行重試,數據的一致性要求越高,我越是重試得快。
  2. 定期全量更新,簡單地說,就是我定期把緩存全部清掉,然後再全量加載。
  3. 給所有的緩存一個失效期。

分享幾篇文章供大家參考:https://blog.csdn.net/u011665991/article/details/89954298

188.redis 持久化有幾種方式?

  • RDB:RDB 持久化機制,是對 redis 中的數據執行週期性的持久化。
  • AOF:AOF 機制對每條寫入命令作爲日誌,以 append-only 的模式寫入一個日誌文件中,在 redis 重啓的時候,可以通過回放 AOF 日誌中的寫入指令來重新構建整個數據集。

補充:

通過 RDB 或 AOF,都可以將 redis 內存中的數據給持久化到磁盤上面來,然後可以將這些數據備份到別的地方去,比如說阿里雲等雲服務。

如果 redis 掛了,服務器上的內存和磁盤上的數據都丟了,可以從雲服務上拷貝回來之前的數據,放到指定的目錄中,然後重新啓動 redis,redis 就會自動根據持久化數據文件中的數據,去恢復內存中的數據,繼續對外提供服務。

如果同時使用 RDB 和 AOF 兩種持久化機制,那麼在 redis 重啓的時候,會使用 AOF 來重新構建數據,因爲 AOF 中的數據更加完整。

RDB 優缺點

  •     RDB會生成多個數據文件,每個數據文件都代表了某一個時刻中 redis 的數據,這種多個數據文件的方式,非常適合做冷備,可以將這種完整的數據文件發送到一些遠程的安全存儲上去,比如說 Amazon 的 S3 雲服務上去,在國內可以是阿里雲的 ODPS 分佈式存儲上,以預定好的備份策略來定期備份redis中的數據。
  •     RDB 對 redis 對外提供的讀寫服務,影響非常小,可以讓 redis 保持高性能,因爲 redis 主進程只需要 fork 一個子進程,讓子進程執行磁盤 IO 操作來進行 RDB 持久化即可。
  •     相對於 AOF 持久化機制來說,直接基於 RDB 數據文件來重啓和恢復 redis 進程,更加快速。
  •     如果想要在 redis 故障時,儘可能少的丟失數據,那麼 RDB 沒有 AOF 好。一般來說,RDB 數據快照文件,都是每隔 5 分鐘,或者更長時間生成一次,這個時候就得接受一旦 redis 進程宕機,那麼會丟失最近 5 分鐘的數據。
  •     RDB 每次在 fork 子進程來執行 RDB 快照數據文件生成的時候,如果數據文件特別大,可能會導致對客戶端提供的服務暫停數毫秒,或者甚至數秒。

AOF 優缺點

  •     AOF 可以更好的保護數據不丟失,一般 AOF 會每隔 1 秒,通過一個後臺線程執行一次fsync操作,最多丟失 1 秒鐘的數據。
  •     AOF 日誌文件以 append-only 模式寫入,所以沒有任何磁盤尋址的開銷,寫入性能非常高,而且文件不容易破損,即使文件尾部破損,也很容易修復。
  •     AOF 日誌文件即使過大的時候,出現後臺重寫操作,也不會影響客戶端的讀寫。因爲在 rewrite log 的時候,會對其中的指導進行壓縮,創建出一份需要恢復數據的最小日誌出來。再創建新日誌文件的時候,老的日誌文件還是照常寫入。當新的 merge 後的日誌文件 ready 的時候,再交換新老日誌文件即可。
  •     AOF 日誌文件的命令通過非常可讀的方式進行記錄,這個特性非常適合做災難性的誤刪除的緊急恢復。比如某人不小心用 flushall 命令清空了所有數據,只要這個時候後臺 rewrite 還沒有發生,那麼就可以立即拷貝 AOF 文件,將最後一條 flushall 命令給刪了,然後再將該 AOF 文件放回去,就可以通過恢復機制,自動恢復所有數據。
  •     對於同一份數據來說,AOF 日誌文件通常比 RDB 數據快照文件更大。
  •     AOF 開啓後,支持的寫 QPS 會比 RDB 支持的寫 QPS 低,因爲 AOF 一般會配置成每秒 fsync 一次日誌文件,當然,每秒一次 fsync,性能也還是很高的。(如果實時寫入,那麼 QPS 會大降,redis 性能會大大降低)
  •     以前 AOF 發生過 bug,就是通過 AOF 記錄的日誌,進行數據恢復的時候,沒有恢復一模一樣的數據出來。所以說,類似 AOF 這種較爲複雜的基於命令日誌/merge/回放的方式,比基於 RDB 每次持久化一份完整的數據快照文件的方式,更加脆弱一些,容易有 bug。不過 AOF 就是爲了避免 rewrite 過程導致的 bug,因此每次 rewrite 並不是基於舊的指令日誌進行 merge 的,而是基於當時內存中的數據進行指令的重新構建,這樣健壯性會好很多。

RDB和AOF到底該如何選擇

    不要僅僅使用 RDB,因爲那樣會導致你丟失很多數據
    也不要僅僅使用 AOF,因爲那樣有兩個問題,第一,你通過 AOF 做冷備,沒有 RDB 做冷備,來的恢復速度更快; 第二,RDB 每次簡單粗暴生成數據快照,更加健壯,可以避免 AOF 這種複雜的備份和恢復機制的 bug。
    redis 支持同時開啓開啓兩種持久化方式,我們可以綜合使用 AOF 和 RDB 兩種持久化機制,用 AOF 來保證數據不丟失,作爲數據恢復的第一選擇; 用 RDB 來做不同程度的冷備,在 AOF 文件都丟失或損壞不可用的時候,還可以使用 RDB 來進行快速的數據恢復。
分享幾篇文章供大家參考:https://blog.csdn.net/yinxiangbing/article/details/48627997

189.redis 怎麼實現分佈式鎖?

官方推薦採用Redlock算法,即使用string類型,加鎖的時候給的一個具體的key,然後設置一個隨機的值;取消鎖的時候用使用lua腳本來先執行獲取比較,然後再刪除key。具體的命令如下:

SET resource_name my_random_value NX PX 30000

if redis.call(“get”,KEYS[1]) == ARGV[1] then
return redis.call(“del”,KEYS[1])
else
return 0
end

190.redis 分佈式鎖有什麼缺陷?

(一)緩存和數據庫雙寫一致性問題
(二)緩存雪崩問題
(三)緩存擊穿問題
(四)緩存的併發競爭問題

分享幾篇文章供大家參考:

191.redis 如何做內存優化?

1. 關閉 Redis 的虛擬內存[VM]功能,即 redis.conf 中 vm-enabled = no
2. 設置 redis.conf 中 maxmemory ,用於告知 Redis 當使用了多少物理內存後拒絕繼續寫入的請求,可防止 Redis 性能降低甚至崩潰
3.可爲指定的數據類型設置內存使用規則,從而提高對應數據類型的內存使用效率

  •     Hash 在 redis.conf 中有以下兩個屬性,任意一個超出設定值,則會使用 HashMap 存值
    •         hash-max-zipmap-entires 64 表示當 value 中的 map 數量在 64 個以下時,實際使用 zipmap 存儲值
    •         hash-max-zipmap-value 512 表示當 value 中的 map 每個成員值長度小於 512 字節時,實際使用 zipmap 存儲值
  •     List 在 redis.conf 中也有以下兩個屬性
    •         list-max-ziplist-entires 64
    •         list-max-ziplist-value 512

4. 在 Redis 的源代碼中有一行宏定義 REDIS-SHARED-INTEGERS = 10000 ,修改該值可以改變 Redis 存儲數值類型的內存開銷

192.redis 淘汰策略有哪些?

  • noeviction:當內存限制達到,誰也不刪除,返回錯誤。
  • allkeys-lru:嘗試回收最少使用的鍵,使得新添加的數據有空間存放。
  • volatile-lru:嘗試回收最少使用的鍵,但僅限於在過期集合的鍵,使得新添加的數據有空間存放。
  • allkey-random:回收隨機的鍵,使得新添加的數據有空間存放。
  • volatile-random:回收隨機的鍵,使得新添加的數據有空間存放,但僅限於過期集合的鍵。
  • volatile-ttl:回收在過期集合的鍵,並且優先回收存貨時間較短的鍵,使得新添加的數據有空間存放。

193.redis 常見的性能問題有哪些?該如何解決?

  1. Master寫內存快照,save命令調度rdbSave函數,會阻塞主線程的工作,當快照比較大時對性能影響是非常大的,會間斷性暫停服務,所以Master最好不要寫內存快照。
  2. Master AOF持久化,如果不重寫AOF文件,這個持久化方式對性能的影響是最小的,但是AOF文件會不斷增大,AOF文件過大會影響Master重啓的恢復速度。Master最好不要做任何持久化工作,包括內存快照和AOF日誌文件,特別是不要啓用內存快照做持久化,如果數據比較關鍵,某個Slave開啓AOF備份數據,策略爲每秒同步一次。
  3. Master調用BGREWRITEAOF重寫AOF文件,AOF在重寫的時候會佔大量的CPU和內存資源,導致服務load過高,出現短暫服務暫停現象。
  4. Redis主從複製的性能問題,爲了主從複製的速度和連接的穩定性,Slave和Master最好在同一個局域網內

 


十九、JVM

194.說一下 jvm 的主要組成部分?及其作用?

195.說一下 jvm 運行時數據區?

196.說一下堆棧的區別?

197.隊列和棧是什麼?有什麼區別?

198.什麼是雙親委派模型?

199.說一下類加載的執行過程?

200.怎麼判斷對象是否可以被回收?

201.java 中都有哪些引用類型?

202.說一下 jvm 有哪些垃圾回收算法?

203.說一下 jvm 有哪些垃圾回收器?

204.詳細介紹一下 CMS 垃圾回收器?

205.新生代垃圾回收器和老生代垃圾回收器都有哪些?有什麼區別?

206.簡述分代垃圾回收器是怎麼工作的?

207.說一下 jvm 調優的工具?

208.常用的 jvm 調優的參數都有哪些?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章