在本篇文章開始以前,我想先來回答一個問題:我爲何要寫這樣一篇關於面試的文章?緣由有三個:第一,我想爲每個爲夢想時刻準備着的「有心人」,盡一份本身的力量,提供一份高度精華的 Java 面試清單;第二,目前市面上的面試題不是答案不許確就是內容覆蓋面太窄,因此提供一份經典而又準確的面試題是很是有必要的;第三,本文會對部分面試題提供詳細解讀和代碼案例,讓讀者知其然並知其因此然,從而學到更多的知識。css
或許這份面試題還不足以囊括全部 Java 問題,但有了它,我相信你必定不會「敗」的很慘,由於有了它,足以應對目前市面上絕大部分的 Java 面試了,由於這篇文章不管是從深度仍是廣度上來說,都已經囊括了很是多的知識點了。html
凡事預則立,不預則廢。能讀到這裏的人,我相信都是這個世界上的「有心人」,仍是那句老話:上天不負有心人!我相信你的每一步努力,都會收穫意想不到的回報。node
適宜閱讀人羣nginx
閱讀建議程序員
本文會按技能模塊劃分文章段落,每一個模塊裏的內容,從易到難依次進行排序,各模塊之間不存在互相關聯的關係,讀者可選擇文章順序閱讀或者跳躍式閱讀。面試
包含的模塊ajax
本文分爲十九個模塊,分別是: Java 基礎、容器、多線程、反射、對象拷貝、Java Web 、異常、網絡、設計模式、Spring/Spring MVC、Spring Boot/Spring Cloud、Hibernate、MyBatis、RabbitMQ、Kafka、Zookeeper、MySQL、Redis、JVM ,以下圖所示:正則表達式
共包含 208 道面試題,本文的宗旨是爲讀者朋友們整理一份詳實而又權威的面試清單,下面一塊兒進入主題吧。算法
1. JDK 和 JRE 有什麼區別?spring
具體來講 JDK 其實包含了 JRE,同時還包含了編譯 Java 源碼的編譯器 Javac,還包含了不少 Java 程序調試和分析的工具。簡單來講:若是你須要運行 Java 程序,只需安裝 JRE 就能夠了,若是你須要編寫 Java 程序,須要安裝 JDK。
2. == 和 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。
equals 解讀
equals 本質上就是 ==,只不過 String 和 Integer 等重寫了 equals 方法,把它變成了值比較。看下面的代碼就明白了。
首先來看默認狀況下 equals 比較一個有相同值的對象,代碼以下:
class Cat {
public Cat(String name) {
this.name = name;
}
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Cat c1 = new Cat("王磊");
Cat c2 = new Cat("王磊");
System.out.println(c1.equals(c2)); // false
輸出結果出乎咱們的意料,居然是 false?這是怎麼回事,看了 equals 源碼就知道了,源碼以下:
public boolean equals(Object obj) {
return (this == obj);
}
原來 equals 本質上就是 ==。
那問題來了,兩個相同值的 String 對象,爲何返回的是 true?代碼以下:
String s1 = new String("老王");
String s2 = new String("老王");
System.out.println(s1.equals(s2)); // true
一樣的,當咱們進入 String 的 equals 方法,找到了答案,代碼以下:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
原來是 String 重寫了 Object 的 equals 方法,把引用比較改爲了值比較。
總結 :== 對於基本類型來講是值比較,對於引用類型來講是比較的是引用;而 equals 默認狀況下是引用比較,只是不少類從新了 equals 方法,好比 String、Integer 等把它變成了值比較,因此通常狀況下 equals 比較的是值是否相等。
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 中有什麼做用?
5. Java 中的 Math. round(-1. 5) 等於多少?
等於 -1,由於在數軸上取值時,中間值(0.5)向右取整,因此正 0.5 是往上取整,負 0.5 是直接捨棄。
6. String 屬於基礎的數據類型嗎?
String 不屬於基礎類型,基礎類型有 8 種:byte、boolean、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 是非線程安全的,但 StringBuilder 的性能卻高於 StringBuffer,因此在單線程環境下推薦使用 StringBuilder,多線程環境下推薦使用 StringBuffer。
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 類的經常使用方法都有那些?
11. 抽象類必需要有抽象方法嗎?
不須要,抽象類不必定非要有抽象方法。
示例代碼:
abstract class Cat {
public static void sayHi() {
System. out. println("hi~");
}
}
上面代碼,抽象類並無抽象方法但徹底能夠正常運行。
12. 普通類和抽象類有哪些區別?
13. 抽象類能使用 final 修飾嗎?
不能,定義抽象類就是讓其餘類繼承的,若是定義爲 final 該類就不能被繼承,這樣彼此就會產生矛盾,因此 final 不能修飾抽象類,以下圖所示,編輯器也會提示錯誤信息:
14. 接口和抽象類有什麼區別?
15. Java 中 IO 流分爲幾種?
按功能來分:輸入流(input)、輸出流(output)。
按類型來分:字節流和字符流。
字節流和字符流的區別是:字節流按 8 位傳輸以字節爲單位輸入輸出數據,字符流按 16 位傳輸以字符爲單位輸入輸出數據。
16. BIO、NIO、AIO 有什麼區別?
17. Files的經常使用方法都有哪些?
18. Java 容器都有哪些?
Java 容器分爲 Collection 和 Map 兩大類,其下又有不少子類,以下所示:
19. Collection 和 Collections 有什麼區別?
20. List、Set、Map 之間的區別是什麼?
List、Set、Map 的區別主要體如今兩個方面:元素是否有序、是否容許元素重複。
三者之間的區別,以下表:
21. HashMap 和 Hashtable 有什麼區別?
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。
26. 如何實現數組和 List 之間的轉換?
代碼示例:
// 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 的區別是什麼?
28. Array 和 ArrayList 有何區別?
29. 在 Queue 中 poll()和 remove()有什麼區別?
代碼示例:
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 怎麼使用?有什麼特色?
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 有什麼區別?
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. 建立線程有哪幾種方式?
建立線程有三種方式:
39. 說一下 runnable 和 callable 有什麼區別?
runnable 沒有返回值,callable 能夠拿到有返回值,callable 能夠看做是 runnable 的補充。
40. 線程有哪些狀態?
線程的狀態:
41. sleep() 和 wait() 有什麼區別?
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. 線程池都有哪些狀態?
46. 線程池中 submit() 和 execute() 方法有什麼區別?
Callable 類型的任務能夠獲取執行的返回值,而 Runnable 執行無返回值。
47. 在 Java 程序中怎麼保證多線程的運行安全?
手動鎖 Java 示例代碼以下:
Lock lock = new ReentrantLock();
lock. lock();
try {
System. out. println("得到鎖");
} catch (Exception e) {
// TODO: handle exception
} finally {
System. out. println("釋放鎖");
lock. unlock();
}
48. 多線程中 synchronized 鎖升級的原理是什麼?
synchronized 鎖升級原理:在鎖對象的對象頭裏面有一個 threadid 字段,在第一次訪問的時候 threadid 爲空,jvm 讓其持有偏向鎖,並將 threadid 設置爲其線程 id,再次進入的時候會先判斷 threadid 是否與其線程 id 一致,若是一致則能夠直接使用此對象,若是不一致,則升級偏向鎖爲輕量級鎖,經過自旋循環必定次數來獲取鎖,執行必定次數以後,若是尚未正常獲取到要使用的對象,此時就會把鎖從輕量級升級爲重量級鎖,此過程就構成了 synchronized 鎖的升級。
鎖的升級的目的:鎖升級是爲了減低了鎖帶來的性能消耗。在 Java 6 以後優化 synchronized 的實現方式,使用了偏向鎖升級爲輕量級鎖再升級到重量級鎖的方式,從而減低了鎖帶來的性能消耗。
49. 什麼是死鎖?
當線程 A 持有獨佔鎖a,並嘗試去獲取獨佔鎖 b 的同時,線程 B 持有獨佔鎖 b,並嘗試獲取獨佔鎖 a 的狀況下,就會發生 AB 兩個線程因爲互相持有對方須要的鎖,而發生的阻塞現象,咱們稱爲死鎖。
50. 怎麼防止死鎖?
51. ThreadLocal 是什麼?有哪些使用場景?
ThreadLocal 爲每一個使用該變量的線程提供獨立的變量副本,因此每個線程均可以獨立地改變本身的副本,而不會影響其它線程所對應的副本。
ThreadLocal 的經典使用場景是數據庫鏈接和 session 管理等。
52. 說一下 synchronized 底層實現原理?
synchronized 是由一對 monitorenter/monitorexit 指令實現的,monitor 對象是同步的基本實現單元。在 Java 6 以前,monitor 的實現徹底是依靠操做系統內部的互斥鎖,由於須要進行用戶態到內核態的切換,因此同步操做是一個無差異的重量級操做,性能也很低。但在 Java 6 的時候,Java 虛擬機 對此進行了大刀闊斧地改進,提供了三種不一樣的 monitor 實現,也就是常說的三種不一樣的鎖:偏向鎖(Biased Locking)、輕量級鎖和重量級鎖,大大改進了其性能。
53. synchronized 和 volatile 的區別是什麼?
54. synchronized 和 Lock 有什麼區別?
55. synchronized 和 ReentrantLock 區別是什麼?
synchronized 早期的實現比較低效,對比 ReentrantLock,大多數場景性能都相差較大,可是在 Java 6 中對 synchronized 進行了很是多的改進。
主要區別以下:
56. 說一下 atomic 的原理?
atomic 主要利用 CAS (Compare And Wwap) 和 volatile 和 native 方法來保證原子操做,從而避免 synchronized 的高開銷,執行效率大爲提高。
57. 什麼是反射?
反射是在運行狀態中,對於任意一個類,都可以知道這個類的全部屬性和方法;對於任意一個對象,都可以調用它的任意一個方法和屬性;這種動態獲取的信息以及動態調用對象的方法的功能稱爲 Java 語言的反射機制。
58. 什麼是 Java 序列化?什麼狀況下須要序列化?
Java 序列化是爲了保存各類對象在內存中的狀態,而且能夠把保存的對象狀態再讀出來。
如下狀況須要使用 Java 序列化:
59. 動態代理是什麼?有哪些應用?
動態代理是運行時動態生成代理類。
動態代理的應用有 spring aop、hibernate 數據查詢、測試框架的後端 mock、rpc,Java註解對象獲取等。
60. 怎麼實現動態代理?
JDK 原生動態代理和 cglib 動態代理。JDK 原生動態代理是基於接口實現的,而 cglib 是基於繼承當前類的子類實現的。
61. 爲何要使用克隆?
克隆的對象可能包含一些已經修改過的屬性,而 new 出來的對象的屬性都仍是初始化時候的值,因此當須要一個新的對象來保存當前對象的「狀態」就靠克隆方法了。
62. 如何實現對象克隆?
63. 深拷貝和淺拷貝區別是什麼?
64. JSP 和 servlet 有什麼區別?
JSP 是 servlet 技術的擴展,本質上就是 servlet 的簡易方式。servlet 和 JSP 最主要的不一樣點在於,servlet 的應用邏輯是在 Java 文件中,而且徹底從表示層中的 html 裏分離開來,而 JSP 的狀況是 Java 和 html 能夠組合成一個擴展名爲 JSP 的文件。JSP 側重於視圖,servlet 主要用於控制邏輯。
65. JSP 有哪些內置對象?做用分別是什麼?
JSP 有 9 大內置對象:
66. 說一下 JSP 的 4 種做用域?
67. session 和 cookie 有什麼區別?
68. 說一下 session 的工做原理?
session 的工做原理是客戶端登陸完成以後,服務器會建立對應的 session,session 建立完以後,會把 session 的 id 發送給客戶端,客戶端再存儲到瀏覽器中。這樣客戶端每次訪問服務器時,都會帶着 sessionid,服務器拿到 sessionid 以後,在內存找到與之對應的 session 這樣就能夠正常工做了。
69. 若是客戶端禁止 cookie 能實現 session 還能用嗎?
能夠用,session 只是依賴 cookie 存儲 sessionid,若是 cookie 被禁用了,可使用 url 中添加 sessionid 的方式保證 session 能正常使用。
70. spring mvc 和 struts 的區別是什麼?
71. 如何避免 SQL 注入?
72. 什麼是 XSS 攻擊,如何避免?
XSS 攻擊:即跨站腳本攻擊,它是 Web 程序中常見的漏洞。原理是攻擊者往 Web 頁面裏插入惡意的腳本代碼(css 代碼、Javascript 代碼等),當用戶瀏覽該頁面時,嵌入其中的腳本代碼會被執行,從而達到惡意攻擊用戶的目的,如盜取用戶 cookie、破壞頁面結構、重定向到其餘網站等。
預防 XSS 的核心是必須對輸入的數據作過濾處理。
73. 什麼是 CSRF 攻擊,如何避免?
CSRF:Cross-Site Request Forgery(中文:跨站請求僞造),能夠理解爲攻擊者盜用了你的身份,以你的名義發送惡意請求,好比:以你名義發送郵件、發消息、購買商品,虛擬貨幣轉帳等。
防護手段:
74. throw 和 throws 的區別?
75. final、finally、finalize 有什麼區別?
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. 常見的異常類有哪些?
79. http 響應碼 301 和 302 表明的是什麼?有什麼區別?
301:永久重定向。
302:暫時重定向。
它們的區別是,301 對搜索引擎優化(SEO)更加有利;302 有被提示爲網絡攔截的風險。
80. forward 和 redirect 的區別?
forward 是轉發 和 redirect 是重定向:
81. 簡述 tcp 和 udp的區別?
tcp 和 udp 是 OSI 模型中的運輸層中的協議。tcp 提供可靠的通訊傳輸,而 udp 則常被用於讓廣播和細節控制交給應用的通訊傳輸。
二者的區別大體以下:
82. tcp 爲何要三次握手,兩次不行嗎?爲何?
若是採用兩次握手,那麼只要服務器發出確認數據包就會創建鏈接,但因爲客戶端此時並未響應服務器端的請求,那此時服務器端就會一直在等待客戶端,這樣服務器端就白白浪費了必定的資源。若採用三次握手,服務器端沒有收到來自客戶端的再此確認,則就會知道客戶端並無要求創建請求,就不會浪費服務器的資源。
83. 說一下 tcp 粘包是怎麼產生的?
tcp 粘包可能發生在發送端或者接收端,分別來看兩端各類產生粘包的緣由:
84. OSI 的七層模型都有哪些?
85. get 和 post 請求有哪些區別?
86. 如何實現跨域?
實現跨域有如下幾種方案:
87. 說一下 JSONP 實現原理?
jsonp:JSON with Padding,它是利用script標籤的 src 鏈接能夠訪問不一樣源的特性,加載遠程返回的「JS 函數」來執行的。
88. 說一下你熟悉的設計模式?
89. 簡單工廠和抽象工廠有什麼區別?
90. 爲何要使用 spring?
91. 解釋一下什麼是 aop?
aop 是面向切面編程,經過預編譯方式和運行期動態代理實現程序功能的統一維護的一種技術。
簡單來講就是統一處理某一「切面」(類)的問題的編程思想,好比統一處理日誌、異常等。
92. 解釋一下什麼是 ioc?
ioc:Inversionof Control(中文:控制反轉)是 spring 的核心,對於 spring 框架來講,就是由 spring 來負責控制對象的生命週期和對象間的關係。
簡單來講,控制指的是當前對象對內部成員的控制權;控制反轉指的是,這種控制權不禁當前對象管理了,由其餘(類,第三方容器)來管理。
93. spring 有哪些主要模塊?
94. spring 經常使用的注入方式有哪些?
95. spring 中的 bean 是線程安全的嗎?
spring 中的 bean 默認是單例模式,spring 框架並無對單例 bean 進行多線程的封裝處理。
實際上大部分時候 spring bean 無狀態的(好比 dao 類),全部某種程度上來講 bean 也是安全的,但若是 bean 有狀態的話(好比 view model 對象),那就要開發者本身去保證線程安全了,最簡單的就是改變 bean 的做用域,把「singleton」變動爲「prototype」,這樣請求 bean 至關於 new Bean()了,因此就能夠保證線程安全了。
96. spring 支持幾種 bean 的做用域?
spring 支持 5 種做用域,以下:
注意: 使用 prototype 做用域須要慎重的思考,由於頻繁建立和銷燬 bean 會帶來很大的性能開銷。
97. spring 自動裝配 bean 有哪些方式?
98. spring 事務實現方式有哪些?
99. 說一下 spring 的事務隔離?
spring 有五大隔離級別,默認值爲 ISOLATION_DEFAULT(使用數據庫的設置),其餘四個隔離級別和數據庫的隔離級別一致:
ISOLATION_DEFAULT:用底層數據庫的設置隔離級別,數據庫設置的是什麼我就用什麼;
ISOLATIONREADUNCOMMITTED:未提交讀,最低隔離級別、事務未提交前,就可被其餘事務讀取(會出現幻讀、髒讀、不可重複讀);
ISOLATIONREADCOMMITTED:提交讀,一個事務提交後才能被其餘事務讀取到(會形成幻讀、不可重複讀),SQL server 的默認級別;
ISOLATIONREPEATABLEREAD:可重複讀,保證屢次讀取同一個數據時,其值都和事務開始時候的內容是一致,禁止讀取到別的事務未提交的數據(會形成幻讀),MySQL 的默認級別;
ISOLATION_SERIALIZABLE:序列化,代價最高最可靠的隔離級別,該隔離級別能防止髒讀、不可重複讀、幻讀。
髒讀 :表示一個事務可以讀取另外一個事務中還未提交的數據。好比,某個事務嘗試插入記錄 A,此時該事務還未提交,而後另外一個事務嘗試讀取到了記錄 A。
不可重複讀 :是指在一個事務內,屢次讀同一數據。
幻讀 :指同一個事務內屢次查詢返回的結果集不同。好比同一個事務 A 第一次查詢時候有 n 條記錄,可是第二次同等條件下查詢卻有 n+1 條記錄,這就好像產生了幻覺。發生幻讀的緣由也是另一個事務新增或者刪除或者修改了第一個事務結果集裏面的數據,同一個記錄的數據內容被修改了,全部數據行的記錄就變多或者變少了。
100. 說一下 spring mvc 運行流程?
101. spring mvc 有哪些組件?
102. @RequestMapping 的做用是什麼?
將 http 請求映射到相應的類/方法上。
103. @Autowired 的做用是什麼?
@Autowired 它能夠對類成員變量、方法及構造函數進行標註,完成自動裝配的工做,經過@Autowired 的使用來消除 set/get 方法。
104. 什麼是 spring boot?
spring boot 是爲 spring 服務的,是用來簡化新 spring 應用的初始搭建以及開發過程的。
105. 爲何要用 spring boot?
106. spring boot 核心配置文件是什麼?
spring boot 核心的兩個配置文件:
107. spring boot 配置文件有哪幾種類型?它們有什麼區別?
配置文件有 . properties 格式和 . yml 格式,它們主要的區別是書法風格不一樣。
. properties 配置以下:
spring. RabbitMQ. port=5672
. yml 配置以下:
spring:
RabbitMQ:
port: 5672
. yml 格式不支持 @PropertySource 註解導入。
108. spring boot 有哪些方式能夠實現熱部署?
109. jpa 和 hibernate 有什麼區別?
jpa 全稱 Java Persistence API,是 Java 持久化接口規範,hibernate 屬於 jpa 的具體實現。
110. 什麼是 spring cloud?
spring cloud 是一系列框架的有序集合。它利用 spring boot 的開發便利性巧妙地簡化了分佈式系統基礎設施的開發,如服務發現註冊、配置中心、消息總線、負載均衡、斷路器、數據監控等,均可以用 spring boot 的開發風格作到一鍵啓動和部署。
111. spring cloud 斷路器的做用是什麼?
在分佈式架構中,斷路器模式的做用也是相似的,當某個服務單元發生故障(相似用電器發生短路)以後,經過斷路器的故障監控(相似熔斷保險絲),向調用方返回一個錯誤響應,而不是長時間的等待。這樣就不會使得線程因調用故障服務被長時間佔用不釋放,避免了故障在分佈式系統中的蔓延。
112. spring cloud 的核心組件有哪些?
113. 爲何要使用 hibernate?
114. 什麼是 ORM 框架?
ORM(Object Relation Mapping)對象關係映射,是把數據庫中的關係數據映射成爲程序中的對象。
使用 ORM 的優勢:提升了開發效率下降了開發成本、開發更簡單更對象化、可移植更強。
115. hibernate 中如何在控制檯查看打印的 SQL 語句?
在 Config 裏面把 hibernate. show_SQL 設置爲 true 就能夠。但不建議開啓,開啓以後會下降程序的運行效率。
116. hibernate 有幾種查詢方式?
三種:hql、原生 SQL、條件查詢 Criteria。
117. hibernate 實體類能夠被定義爲 final 嗎?
實體類能夠定義爲 final 類,但這樣的話就不能使用 hibernate 代理模式下的延遲關聯提供性能了,因此不建議定義實體類爲 final。
118. 在 hibernate 中使用 Integer 和 int 作映射有什麼區別?
Integer 類型爲對象,它的值容許爲 null,而 int 屬於基礎數據類型,值不能爲 null。
119. hibernate 是如何工做的?
120. get()和 load()的區別?
121. 說一下 hibernate 的緩存機制?
hibernate 經常使用的緩存有一級緩存和二級緩存:
一級緩存:也叫 Session 緩存,只在 Session 做用範圍內有效,不須要用戶干涉,由 hibernate 自身維護,能夠經過:evict(object)清除 object 的緩存;clear()清除一級緩存中的全部緩存;flush()刷出緩存;
二級緩存:應用級別的緩存,在全部 Session 中都有效,支持配置第三方的緩存,如:EhCache。
122. hibernate 對象有哪些狀態?
123. 在 hibernate 中 getCurrentSession 和 openSession 的區別是什麼?
124. hibernate 實體類必需要有無參構造函數嗎?爲何?
hibernate 中每一個實體類必須提供一個無參構造函數,由於 hibernate 框架要使用 reflection api,經過調用 ClassnewInstance() 來建立實體類的實例,若是沒有無參的構造函數就會拋出異常。
125. MyBatis 中 #{}和 ${}的區別是什麼?
\#{}
是預編譯處理,${}
是字符替換。 在使用 #{}
時,MyBatis 會將 SQL 中的 #{}
替換成「?」,配合 PreparedStatement 的 set 方法賦值,這樣能夠有效的防止 SQL 注入,保證程序的運行安全。
126. MyBatis 有幾種分頁方式?
分頁方式:邏輯分頁和物理分頁。
邏輯分頁: 使用 MyBatis 自帶的 RowBounds 進行分頁,它是一次性查詢不少數據,而後在數據中再進行檢索。
物理分頁: 本身手寫 SQL 分頁或使用分頁插件 PageHelper,去數據庫查詢指定條數的分頁數據的形式。
127. RowBounds 是一次性查詢所有結果嗎?爲何?
RowBounds 表面是在「全部」數據中檢索數據,其實並不是是一次性查詢出全部數據,由於 MyBatis 是對 jdbc 的封裝,在 jdbc 驅動中有一個 Fetch Size 的配置,它規定了每次最多從數據庫查詢多少條數據,假如你要查詢更多數據,它會在你執行 next()的時候,去查詢更多的數據。就比如你去自動取款機取 10000 元,但取款機每次最多能取 2500 元,因此你要取 4 次才能把錢取完。只是對於 jdbc 來講,當你調用 next()的時候會自動幫你完成查詢工做。這樣作的好處能夠有效的防止內存溢出。
Fetch Size 官方相關文檔:http://t. cn/EfSE2g3
128. MyBatis 邏輯分頁和物理分頁的區別是什麼?
129. MyBatis 是否支持延遲加載?延遲加載的原理是什麼?
MyBatis 支持延遲加載,設置 lazyLoadingEnabled=true 便可。
延遲加載的原理的是調用的時候觸發加載,而不是在初始化的時候就加載信息。好比調用 a. getB(). getName(),這個時候發現 a. getB() 的值爲 null,此時會單獨觸發事先保存好的關聯 B 對象的 SQL,先查詢出來 B,而後再調用 a. setB(b),而這時候再調用 a. getB(). getName() 就有值了,這就是延遲加載的基本原理。
130. 說一下 MyBatis 的一級緩存和二級緩存?
開啓二級緩存數據查詢流程:二級緩存 -> 一級緩存 -> 數據庫。
緩存更新機制:當某一個做用域(一級緩存 Session/二級緩存 Mapper)進行了C/U/D 操做後,默認該做用域下全部 select 中的緩存將被 clear。
131. MyBatis 和 hibernate 的區別有哪些?
132. MyBatis 有哪些執行器(Executor)?
MyBatis 有三種基本的Executor執行器:
133. MyBatis 分頁插件的實現原理是什麼?
分頁插件的基本原理是使用 MyBatis 提供的插件接口,實現自定義插件,在插件的攔截方法內攔截待執行的 SQL,而後重寫 SQL,根據 dialect 方言,添加對應的物理分頁語句和物理分頁參數。
134. MyBatis 如何編寫一個自定義插件?
自定義插件實現原理
MyBatis 自定義插件針對 MyBatis 四大對象(Executor、StatementHandler、ParameterHandler、ResultSetHandler)進行攔截:
自定義插件實現關鍵
MyBatis 插件要實現 Interceptor 接口,接口包含的方法,以下:
public interface Interceptor {
Object intercept(Invocation invocation) throws Throwable;
Object plugin(Object target);
void setProperties(Properties properties);
}
自定義插件實現示例
官方插件實現:
@Intercepts({@Signature(type = Executor. class, method = "query",
args = {MappedStatement. class, Object. class, RowBounds. class, ResultHandler. class})})
public class TestInterceptor implements Interceptor {
public Object intercept(Invocation invocation) throws Throwable {
Object target = invocation. getTarget(); //被代理對象
Method method = invocation. getMethod(); //代理方法
Object[] args = invocation. getArgs(); //方法參數
// do something . . . . . . 方法攔截前執行代碼塊
Object result = invocation. proceed();
// do something . . . . . . . 方法攔截後執行代碼塊
return result;
}
public Object plugin(Object target) {
return Plugin. wrap(target, this);
}
}
135. RabbitMQ 的使用場景有哪些?
136. RabbitMQ 有哪些重要的角色?
RabbitMQ 中重要的角色有:生產者、消費者和代理:
137. RabbitMQ 有哪些重要的組件?
138. RabbitMQ 中 vhost 的做用是什麼?
vhost:每一個 RabbitMQ 都能建立不少 vhost,咱們稱之爲虛擬主機,每一個虛擬主機其實都是 mini 版的RabbitMQ,它擁有本身的隊列,交換器和綁定,擁有本身的權限機制。
139. RabbitMQ 的消息是怎麼發送的?
首先客戶端必須鏈接到 RabbitMQ 服務器才能發佈和消費消息,客戶端和 rabbit server 之間會建立一個 tcp 鏈接,一旦 tcp 打開並經過了認證(認證就是你發送給 rabbit 服務器的用戶名和密碼),你的客戶端和 RabbitMQ 就建立了一條 amqp 信道(channel),信道是建立在「真實」 tcp 上的虛擬鏈接,amqp 命令都是經過信道發送出去的,每一個信道都會有一個惟一的 id,不管是發佈消息,訂閱隊列都是經過這個信道完成的。
140. RabbitMQ 怎麼保證消息的穩定性?
141. RabbitMQ 怎麼避免消息丟失?
142. 要保證消息持久化成功的條件有哪些?
以上四個條件都知足才能保證消息持久化成功。
143. RabbitMQ 持久化有什麼缺點?
持久化的缺地就是下降了服務器的吞吐量,由於使用的是磁盤而非內存存儲,從而下降了吞吐量。可儘可能使用 ssd 硬盤來緩解吞吐量的問題。
144. RabbitMQ 有幾種廣播類型?
145. RabbitMQ 怎麼實現延遲消息隊列?
延遲隊列的實現有兩種方式:
146. RabbitMQ 集羣有什麼用?
集羣主要有如下兩個用途:
147. RabbitMQ 節點的類型有哪些?
148. RabbitMQ 集羣搭建須要注意哪些問題?
149. RabbitMQ 每一個節點是其餘節點的完整拷貝嗎?爲何?
不是,緣由有如下兩個:
150. RabbitMQ 集羣中惟一一個磁盤節點崩潰了會發生什麼狀況?
若是惟一磁盤的磁盤節點崩潰了,不能進行如下操做:
惟一磁盤節點崩潰了,集羣是能夠保持運行的,但你不能更改任何東西。
151. RabbitMQ 對集羣節點中止順序有要求嗎?
RabbitMQ 對集羣的中止的順序是有要求的,應該先關閉內存節點,最後再關閉磁盤節點。若是順序剛好相反的話,可能會形成消息的丟失。
152. kafka 能夠脫離 zookeeper 單獨使用嗎?爲何?
kafka 不能脫離 zookeeper 單獨使用,由於 kafka 使用 zookeeper 管理和協調 kafka 的節點服務器。
153. kafka 有幾種數據保留的策略?
kafka 有兩種數據保存策略:按照過時時間保留和按照存儲的消息大小保留。
154. kafka 同時設置了 7 天和 10G 清除數據,到第五天的時候消息達到了 10G,這個時候 kafka 將如何處理?
這個時候 kafka 會執行數據清除工做,時間和大小不論那個知足條件,都會清空數據。
155. 什麼狀況會致使 kafka 運行變慢?
156. 使用 kafka 集羣須要注意什麼?
157. zookeeper 是什麼?
zookeeper 是一個分佈式的,開放源碼的分佈式應用程序協調服務,是 google chubby 的開源實現,是 hadoop 和 hbase 的重要組件。它是一個爲分佈式應用提供一致性服務的軟件,提供的功能包括:配置維護、域名服務、分佈式同步、組服務等。
158. zookeeper 都有哪些功能?
159. zookeeper 有幾種部署模式?
zookeeper 有三種部署模式:
160. zookeeper 怎麼保證主從節點的狀態同步?
zookeeper 的核心是原子廣播,這個機制保證了各個 server 之間的同步。實現這個機制的協議叫作 zab 協議。 zab 協議有兩種模式,分別是恢復模式(選主)和廣播模式(同步)。當服務啓動或者在領導者崩潰後,zab 就進入了恢復模式,當領導者被選舉出來,且大多數 server 完成了和 leader 的狀態同步之後,恢復模式就結束了。狀態同步保證了 leader 和 server 具備相同的系統狀態。
161. 集羣中爲何要有主節點?
在分佈式環境中,有些業務邏輯只須要集羣中的某一臺機器進行執行,其餘的機器能夠共享這個結果,這樣能夠大大減小重複計算,提升性能,因此就須要主節點。
162. 集羣中有 3 臺服務器,其中一個節點宕機,這個時候 zookeeper 還可使用嗎?
能夠繼續使用,單數服務器只要沒超過一半的服務器宕機就能夠繼續使用。
163. 說一下 zookeeper 的通知機制?
客戶端端會對某個 znode 創建一個 watcher 事件,當該 znode 發生變化時,這些客戶端會收到 zookeeper 的通知,而後客戶端能夠根據 znode 變化來作出業務上的改變。
164. 數據庫的三範式是什麼?
165. 一張自增表裏面總共有 7 條數據,刪除了最後 2 條數據,重啓 MySQL 數據庫,又插入了一條數據,此時 id 是幾?
InnoDB 表只會把自增主鍵的最大 id 記錄在內存中,因此重啓以後會致使最大 id 丟失。
166. 如何獲取當前數據庫版本?
使用 select version() 獲取當前 MySQL 數據庫版本。
167. 說一下 ACID 是什麼?
168. char 和 varchar 的區別是什麼?
chat 優勢:效率高;缺點:佔用空間;適用場景:存儲密碼的 md5 值,固定長度的,使用 char 很是合適。
因此,從空間上考慮 varcahr 比較合適;從效率上考慮 char 比較合適,兩者使用須要權衡。
169. float 和 double 的區別是什麼?
170. MySQL 的內鏈接、左鏈接、右鏈接有什麼區別?
內鏈接關鍵字:inner join;左鏈接:left join;右鏈接:right join。
內鏈接是把匹配的關聯數據顯示出來;左鏈接是左邊的表所有顯示出來,右邊的表顯示出符合條件的數據;右鏈接正好相反。
171. MySQL 索引是怎麼實現的?
索引是知足某種特定查找算法的數據結構,而這些數據結構會以某種方式指向數據,從而實現高效查找數據。
具體來講 MySQL 中的索引,不一樣的數據引擎實現有所不一樣,但目前主流的數據庫引擎的索引都是 B+ 樹實現的,B+ 樹的搜索效率,能夠到達二分法的性能,找到數據區域以後就找到了完整的數據結構了,全部索引的性能也是更好的。
172. 怎麼驗證 MySQL 的索引是否知足需求?
使用 explain 查看 SQL 是如何執行查詢語句的,從而分析你的索引是否知足需求。
explain 語法:explain select * from table where type=1。
173. 說一下數據庫的事務隔離?
MySQL 的事務隔離是在 MySQL. ini 配置文件裏添加的,在文件的最後添加:
transaction-isolation = REPEATABLE-READ
可用的配置值:READ-UNCOMMITTED、READ-COMMITTED、REPEATABLE-READ、SERIALIZABLE。
髒讀 :表示一個事務可以讀取另外一個事務中還未提交的數據。好比,某個事務嘗試插入記錄 A,此時該事務還未提交,而後另外一個事務嘗試讀取到了記錄 A。
不可重複讀 :是指在一個事務內,屢次讀同一數據。
幻讀 :指同一個事務內屢次查詢返回的結果集不同。好比同一個事務 A 第一次查詢時候有 n 條記錄,可是第二次同等條件下查詢卻有 n+1 條記錄,這就好像產生了幻覺。發生幻讀的緣由也是另一個事務新增或者刪除或者修改了第一個事務結果集裏面的數據,同一個記錄的數據內容被修改了,全部數據行的記錄就變多或者變少了。
174. 說一下 MySQL 經常使用的引擎?
InnoDB 引擎:InnoDB 引擎提供了對數據庫 acid 事務的支持,而且還提供了行級鎖和外鍵的約束,它的設計的目標就是處理大數據容量的數據庫系統。MySQL 運行的時候,InnoDB 會在內存中創建緩衝池,用於緩衝數據和索引。可是該引擎是不支持全文搜索,同時啓動也比較的慢,它是不會保存表的行數的,因此當進行 select count(*) from table 指令的時候,須要進行掃描全表。因爲鎖的粒度小,寫操做是不會鎖定全表的,因此在併發度較高的場景下使用會提高效率的。
MyIASM 引擎:MySQL 的默認引擎,但不提供事務的支持,也不支持行級鎖和外鍵。所以當執行插入和更新語句時,即執行寫操做的時候須要鎖定這個表,因此會致使效率會下降。不過和 InnoDB 不一樣的是,MyIASM 引擎是保存了表的行數,因而當進行 select count(*) from table 語句時,能夠直接的讀取已經保存的值而不須要進行掃描全表。因此,若是表的讀操做遠遠多於寫操做時,而且不須要事務的支持的,能夠將 MyIASM 做爲數據庫引擎的首選。
175. 說一下 MySQL 的行鎖和表鎖?
MyISAM 只支持表鎖,InnoDB 支持表鎖和行鎖,默認爲行鎖。
176. 說一下樂觀鎖和悲觀鎖?
數據庫的樂觀鎖須要本身實現,在表裏面添加一個 version 字段,每次修改爲功值加 1,這樣每次修改的時候先對比一下,本身擁有的 version 和數據庫如今的 version 是否一致,若是不一致就不修改,這樣就實現了樂觀鎖。
177. MySQL 問題排查都有哪些手段?
178. 如何作 MySQL 的性能優化?
179. Redis 是什麼?都有哪些使用場景?
Redis 是一個使用 C 語言開發的高速緩存數據庫。
Redis 使用場景:
180. Redis 有哪些功能?
181. Redis 和 memcache 有什麼區別?
182. Redis 爲何是單線程的?
由於 cpu 不是 Redis 的瓶頸,Redis 的瓶頸最有多是機器內存或者網絡帶寬。既然單線程容易實現,並且 cpu 又不會成爲瓶頸,那就瓜熟蒂落地採用單線程的方案了。
關於 Redis 的性能,官方網站也有,普通筆記本輕鬆處理每秒幾十萬的請求。
並且單線程並不表明就慢 nginx 和 nodejs 也都是高性能單線程的表明。
183. 什麼是緩存穿透?怎麼解決?
緩存穿透:指查詢一個必定不存在的數據,因爲緩存是不命中時須要從數據庫查詢,查不到數據則不寫入緩存,這將致使這個不存在的數據每次請求都要到數據庫去查詢,形成緩存穿透。
解決方案:最簡單粗暴的方法若是一個查詢返回的數據爲空(無論是數據不存在,仍是系統故障),咱們就把這個空結果進行緩存,但它的過時時間會很短,最長不超過五分鐘。
184. Redis 支持的數據類型有哪些?
Redis 支持的數據類型:string(字符串)、list(列表)、hash(字典)、set(集合)、zset(有序集合)。
185. Redis 支持的 Java 客戶端都有哪些?
支持的 Java 客戶端有 Redisson、jedis、lettuce 等。
186. jedis 和 Redisson 有哪些區別?
187. 怎麼保證緩存和數據庫數據的一致性?
188. Redis 持久化有幾種方式?
Redis 的持久化有兩種方式,或者說有兩種策略:
189. Redis 怎麼實現分佈式鎖?
Redis 分佈式鎖其實就是在系統裏面佔一個「坑」,其餘程序也要佔「坑」的時候,佔用成功了就能夠繼續執行,失敗了就只能放棄或稍後重試。
佔坑通常使用 setnx(set if not exists)指令,只容許被一個程序佔有,使用完調用 del 釋放鎖。
190. Redis 分佈式鎖有什麼缺陷?
Redis 分佈式鎖不能解決超時的問題,分佈式鎖有一個超時時間,程序的執行若是超出了鎖的超時時間就會出現問題。
191. Redis 如何作內存優化?
儘可能使用 Redis 的散列表,把相關的信息放到散列表裏面存儲,而不是把每一個字段單獨存儲,這樣能夠有效的減小內存使用。好比將 Web 系統的用戶對象,應該放到散列表裏面再總體存儲到 Redis,而不是把用戶的姓名、年齡、密碼、郵箱等字段分別設置 key 進行存儲。
192. Redis 淘汰策略有哪些?
volatile-lru:從已設置過時時間的數據集(server. db[i]. expires)中挑選最近最少使用的數據淘汰。
volatile-ttl:從已設置過時時間的數據集(server. db[i]. expires)中挑選將要過時的數據淘汰。
volatile-random:從已設置過時時間的數據集(server. db[i]. expires)中任意選擇數據淘汰。
allkeys-lru:從數據集(server. db[i]. dict)中挑選最近最少使用的數據淘汰。
allkeys-random:從數據集(server. db[i]. dict)中任意選擇數據淘汰。
no-enviction(驅逐):禁止驅逐數據。
193. Redis 常見的性能問題有哪些?該如何解決?
194. 說一下 JVM 的主要組成部分?及其做用?
組件的做用: 首先經過類加載器(ClassLoader)會把 Java 代碼轉換成字節碼,運行時數據區(Runtime Data Area)再把字節碼加載到內存中,而字節碼文件只是 JVM 的一套指令集規範,並不能直接交個底層操做系統去執行,所以須要特定的命令解析器執行引擎(Execution Engine),將字節碼翻譯成底層系統指令,再交由 CPU 去執行,而這個過程當中須要調用其餘語言的本地庫接口(Native Interface)來實現整個程序的功能。
195. 說一下 JVM 運行時數據區?
不一樣虛擬機的運行時數據區可能略微有所不一樣,但都會聽從 Java 虛擬機規範, Java 虛擬機規範規定的區域分爲如下 5 個部分:
程序計數器(Program Counter Register):當前線程所執行的字節碼的行號指示器,字節碼解析器的工做是經過改變這個計數器的值,來選取下一條須要執行的字節碼指令,分支、循環、跳轉、異常處理、線程恢復等基礎功能,都須要依賴這個計數器來完成;
Java 虛擬機棧(Java Virtual Machine Stacks):用於存儲局部變量表、操做數棧、動態連接、方法出口等信息;
本地方法棧(Native Method Stack):與虛擬機棧的做用是同樣的,只不過虛擬機棧是服務 Java 方法的,而本地方法棧是爲虛擬機調用 Native 方法服務的;
Java 堆(Java Heap):Java 虛擬機中內存最大的一塊,是被全部線程共享的,幾乎全部的對象實例都在這裏分配內存;
方法區(Methed Area):用於存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯後的代碼等數據。
196. 說一下堆棧的區別?
197. 隊列和棧是什麼?有什麼區別?
隊列和棧都是被用來預存儲數據的。
隊列容許先進先出檢索元素,但也有例外的狀況,Deque 接口容許從兩端檢索元素。
棧和隊列很類似,但它運行對元素進行後進先出進行檢索。
198. 什麼是雙親委派模型?
在介紹雙親委派模型以前先說下類加載器。對於任意一個類,都須要由加載它的類加載器和這個類自己一同確立在 JVM 中的惟一性,每個類加載器,都有一個獨立的類名稱空間。類加載器就是根據指定全限定名稱將 class 文件加載到 JVM 內存,而後再轉化爲 class 對象。
類加載器分類:
雙親委派模型:若是一個類加載器收到了類加載的請求,它首先不會本身去加載這個類,而是把這個請求委派給父類加載器去完成,每一層的類加載器都是如此,這樣全部的加載請求都會被傳送到頂層的啓動類加載器中,只有當父加載沒法完成加載請求(它的搜索範圍中沒找到所需的類)時,子加載器纔會嘗試去加載類。
199. 說一下類裝載的執行過程?
類裝載分爲如下 5 個步驟:
200. 怎麼判斷對象是否能夠被回收?
通常有兩種方法來判斷:
201. Java 中都有哪些引用類型?
202. 說一下 JVM 有哪些垃圾回收算法?
203. 說一下 JVM 有哪些垃圾回收器?
204. 詳細介紹一下 CMS 垃圾回收器?
CMS 是英文 Concurrent Mark-Sweep 的簡稱,是以犧牲吞吐量爲代價來得到最短回收停頓時間的垃圾回收器。對於要求服務器響應速度的應用上,這種垃圾回收器很是適合。在啓動 JVM 的參數加上「-XX:+UseConcMarkSweepGC」來指定使用 CMS 垃圾回收器。
CMS 使用的是標記-清除的算法實現的,因此在 gc 的時候回產生大量的內存碎片,當剩餘內存不能知足程序運行要求時,系統將會出現 Concurrent Mode Failure,臨時 CMS 會採用 Serial Old 回收器進行垃圾清除,此時的性能將會被下降。
205. 新生代垃圾回收器和老生代垃圾回收器都有哪些?有什麼區別?
新生代垃圾回收器通常採用的是複製算法,複製算法的優勢是效率高,缺點是內存利用率低;老年代回收器通常採用的是標記-整理的算法進行垃圾回收。
206. 簡述分代垃圾回收器是怎麼工做的?
分代回收器有兩個分區:老生代和新生代,新生代默認的空間佔比總空間的 1/3,老生代的默認佔比是 2/3。
新生代使用的是複製算法,新生代裏有 3 個分區:Eden、To Survivor、From Survivor,它們的默認佔比是 8:1:1,它的執行流程以下:
每次在 From Survivor 到 To Survivor 移動時都存活的對象,年齡就 +1,當年齡到達 15(默認配置是 15)時,升級爲老生代。大對象也會直接進入老生代。
老生代當空間佔用到達某個值以後就會觸發全局垃圾收回,通常使用標記整理的執行算法。以上這些循環往復就構成了整個分代垃圾回收的總體執行流程。
207. 說一下 JVM 調優的工具?
JDK 自帶了不少監控工具,都位於 JDK 的 bin 目錄下,其中最經常使用的是 jconsole 和 jvisualvm 這兩款視圖監控工具。
208. 經常使用的 JVM 調優的參數都有哪些?
這不止是一份面試清單,更是一種「被指望的責任」,由於有無數個待面試着,但願從這篇文章中,找出通往指望公司的「鑰匙」,因此上面的每道選題都是結合我自身的經驗,於千萬個面試題中通過艱辛的兩週,一個題一個題篩選出來再校對好答案和格式作出來的,面試的答案也是再三斟酌,生怕誤人子弟是小,影響他人的「仕途」纔是大過,因此若有紕漏,還請讀者朋友們在評論區不吝指出。
也但願您能把這篇文章分享給更多的朋友,讓它幫助更多的人。
幫助他人,快樂本身,最後,感謝您的閱讀。