Java常見面試題

Java常見面試題

1.JDK 和 JRE 有什麼區別?
JDK是JAVA開發環境也包括運行環境,JRE是JAVA運行環境。
2.== 和 equals 的區別是什麼?
==比較的是內存地址,equals比較的是內容。
分狀況:==分兩種狀況,一種是基本數據,一種是引用數據類型。
JAVA八種基本數據類型:byte short int long float double char boolean 比較值
JAVA三種引用數據類型:類、接口、數組 比較內存地址
String是一個類,因此是引用數據類型,故==比較內存地址。凡new都是開闢新地址。

加深:重寫equals,String類和Integer類,將equals變成了值比較。

3.兩個對象的 hashCode()相同,則 equals()也必定爲 true,對嗎?
不必定。通話、重地。

 

4.final 在 java 中有什麼做用?
final修飾類:該類不能被繼承。
final修飾方法:該方法不能被重寫。
final修飾屬性:該屬性不能被修改,就是常量。

5.java 中的 Math.round(-1.5) 等於多少?
注意:這是四啥五入取整,可是負數要注意取大的。比負1.5還大的整數是負一。

6.String 屬於基礎的數據類型嗎?
不屬於基本數據類型,它屬於引用數據類型。
JAVA八種基本數據類型:byte short int long float double char boolean 比較值
JAVA三種引用數據類型:類、接口、數組 比較內存地址

7.java 中操做字符串都有哪些類?它們之間有什麼區別?
String:操做副本
StringBuffer:線程安全,操做自己,多線程下使用。常常用。
StringBuilder:線程不安全,速度快。單線程下使用。

8.String str="i"與 String str=new String(「i」)同樣嗎?
不同,由於內存的分配方式不同。
String str="i"的方式,java 虛擬機會將其分配到常量池中;
而 String str=new String(「i」) 則會被分到堆內存中。

9.如何將字符串反轉?
使用 StringBuilder 或者 stringBuffer 的 reverse() 方法。

10.String 類的經常使用方法都有那些?
length() 字符串長度
trim() 去字符串兩邊空格
indexOf() 查找批定字符串位置
substring(a,b) 截取
charAt() 指定位置的字符
replace(a,b,c) 替換
toLowerCase() 轉小寫
toUpperCase() 轉大寫
getBytes() 轉字節數組
split() 分隔

11.抽象類必需要有抽象方法嗎?
抽象類中能夠沒有抽象方法,也能夠有抽象方法。

12.普通類和抽象類有哪些區別?
普通類中不能包含抽象方法,包含抽象的方法的必定是抽象類。
抽象類不能實例化(不能new),普通方法能夠實例化。


13.抽象類能使用 final 修飾嗎?
抽象類不能使用final修飾,由於被final修飾的類不能被繼承。
抽象類設計的目的是爲了被繼承,故與之矛盾,不能使用final修飾。

14.接口和抽象類有什麼區別?
接口的實現類用implements,抽象類的子類用extends。
接口中不能有構造方法,抽象類中能夠有構造方法。
抽象類中能夠有main方法,並能夠運行。接口不能夠。但能夠有靜態方法。
類是單繼承,一個類只能繼承一個類。
接口打破了單一繼承,一個類能夠實現多個接口,接口也能夠繼承多個接口。注意:接口不能實現接口。
接口用interface定義,抽象類用class定義。
接口中的方法默認都是公共的,抽象類中的方法訪問修飾符不限(四種public protected 不寫 private)

15.java 中 IO 流分爲幾種?
按流的方向能夠分爲輸入流和輸出流。
按流的類型能夠分爲字節流和字符流。1個字節等於8位,按8位以字節單位傳輸。1個字符等於2字符,故16位,以字符爲單位傳輸。

16.BIO、NIO、AIO 有什麼區別?
BIO 同步阻塞
NIO 同步非阻塞
AIO 異步非阻塞

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

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

18. java 容器都有哪些?
List
Set
Map
Vector
Collection

19.Collection 和 Collections 有什麼區別?
Collection是集合類的頂級接口,它包含了集合類的通用方法,它的直接接口有List和Set。
Collections是集合類的工具類,它包含了一系列的靜態方法,排序,查找。

20. List、Set、Map 之間的區別是什麼?
List 有序可重複,它的子類額ArrayList,LinkedList。
Set 無序不可重複,它的子類有HashSet,TreeSet。
Map 鍵值對,它個子類有HashMap,TreeMap。

21. HashMap 和 Hashtable 有什麼區別?
HashMap 同步,Hashtable 非同步
hashMap容許空鍵值,而hashTable不容許
hashMap去掉了HashTable 的contains方法,可是加上了containsValue()和containsKey()方法

22. 如何決定使用 HashMap 仍是 TreeMap?
對Map數據的增刪改查,添加、刪除、定位用HashMap.
對一個有序key的遍歷用TreeMap。

23. 說一下 HashMap 的實現原理?
HashMap是非同步。容許null鍵null值。無序。
HashMap數據結構基於數組和模擬指針。數組和鏈表的結合體。
在添加數據時,這個位置上有其它元素,以鏈表形式存放,
新加入的放在鏈頭,最早加入的放入鏈尾(洗盤子)
這個位置上沒有其它元素,直接放在該位置上。

須要注意Jdk 1.8中對HashMap的實現作了優化,當鏈表中的節點數據超過八個以後,
該鏈表會轉爲紅黑樹來提升查詢效率,從原來的O(n)到O(logn)

隊列:先進先出 FIFO
鏈表:後進先出 LIFO
FIFO: First in, First out.先進先出。
LIFO: Last in, First out.後進先出。


24. 說一下 HashSet 的實現原理?
HashSet底層由HashMap實現
HashSet的值存放於HashMap的key上
HashMap的value統一爲PRESENT

Java中HashSet的Value爲何存PRESENT而不是Null?
HashSet#add() 方法須要在加入新元素時返回 true,加入重複元素時返回 falseHashMap#add() 方法
返回的是上一次以同一 key 加入的 value若從未以該 key 加入任何數據,
則返回 null然而 HashMap 容許 null 做爲 value因此若是使用 null 做爲 value
利用 HashMap 當返回 null 的時候咱們就沒法得知 null 究竟意味着這個 key 是第一次加入仍是上一次使用了 null 做爲 value 加入

25. ArrayList 和 LinkedList 的區別是什麼?
最明顯的區別是 ArrrayList底層的數據結構是數組,支持隨機訪問,而 LinkedList 的底層數據結構是雙向循環鏈表,不支持隨機訪問。
使用下標訪問一個元素,ArrayList 的時間複雜度是 O(1),而 LinkedList 是 O(n)。

算法中的O(1), O(n),O(logn), O(nlogn)分別是什麼意思?
因爲平時接觸算法比較少,今天看資料看到了o(1),都不知道是什麼意思,百度以後才知道是什麼意思。
描述算法複雜度時,經常使用o(1), o(n), o(logn), o(nlogn)表示對應算法的時間複雜度,是算法的時空複雜度的表示。不只僅用於表示時間複雜度,也用於表示空間複雜度。 

O後面的括號中有一個函數,指明某個算法的耗時/耗空間與數據增加量之間的關係。其中的n表明輸入數據的量。 
好比時間複雜度爲O(n),就表明數據量增大幾倍,耗時也增大幾倍。好比常見的遍歷算法。再好比時間複雜度O(n^2),就表明數據量增大n倍時,耗時增大n的平方倍,這是比線性更高的時間複雜度。好比冒泡排序,就是典型的O(n^2)的算法,對n個數排序,須要掃描n×n次。 
再好比O(logn),當數據增大n倍時,耗時增大logn倍(這裏的log是以2爲底的,好比,當數據增大256倍時,耗時只增大8倍,是比線性還要低的時間複雜度)。二分查找就是O(logn)的算法,每找一次排除一半的可能,256個數據中查找只要找8次就能夠找到目標。 
O(nlogn)同理,就是n乘以logn,當數據增大256倍時,耗時增大256*8=2048倍。這個複雜度高於線性低於平方。歸併排序就是O(nlogn)的時間複雜度。 
O(1)就是最低的時空複雜度了,也就是耗時/耗空間與輸入數據大小無關,不管輸入數據增大多少倍,耗時/耗空間都不變。哈希算法就是典型的O(1)時間複雜度,不管數據規模多大,均可以在一次計算後找到目標(不考慮衝突的話)

26. 如何實現數組和 List 之間的轉換?
List轉換成爲數組:調用ArrayList的toArray方法。
數組轉換成爲List:調用Arrays的asList方法。

27. ArrayList 和 Vector 的區別是什麼?
Vector是同步的,而ArrayList不是。
在迭代的時候對列表進行改變,使用CopyOnWriteArrayList。
ArrayList比Vector快,它由於有同步,不會過載。
ArrayList更加通用,使用Collections工具類輕易地獲取同步列表和只讀列表。

28. Array 和 ArrayList 有何區別?
數組 和 ArrayList 有何區別?
Array能夠容納基本類型和對象,而ArrayList只能容納對象。
Array是指定大小後不可變的,而ArrayList大小是可變的。
Array沒有提供ArrayList那麼多功能,好比addAll、removeAll和iterator等。


29. 在 Queue 中 poll()和 remove()有什麼區別?
poll() 和 remove() 都是從隊列中取出一個元素。
poll() 在獲取元素失敗的時候會返回空,
remove() 失敗的時候會拋出異常。

30. 哪些集合類是線程安全的?
vector:
statck:
hashtable:
enumeration:

31. 迭代器 Iterator 是什麼?
迭代器是一種設計模式,它是一個對象,它能夠遍歷並選擇序列中的對象

32. Iterator 怎麼使用?有什麼特色?
Java中的Iterator功能比較簡單,而且只能單向移動:
(1) 使用方法iterator()要求容器返回一個Iterator。第一次調用Iterator的next()方法時,它返回序列的第一個元素。注意:iterator()方法是java.lang.Iterable接口,被Collection繼承。
(2) 使用next()得到序列中的下一個元素。
(3) 使用hasNext()檢查序列中是否還有元素。
(4) 使用remove()將迭代器新返回的元素刪除。 
Iterator是Java迭代器最簡單的實現,爲List設計的ListIterator具備更多的功能,它能夠從兩個方向遍歷List,也能夠從List中插入和刪除元素。


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("A");
Collection<String> unmlist = Collections.unmodifiableCollection(list);
unmlist. add("B"); // 運行時此行報錯
System. out. println(list.size());

35. 並行和併發有什麼區別?
並行是指兩個或者多個事件在同一時刻發生;而併發是指兩個或多個事件在同一時間間隔發生。
並行是在不一樣實體上的多個事件,併發是在同一實體上的多個事件。
在一臺處理器上「同時」處理多個任務,在多臺處理器上同時處理多個任務。如hadoop分佈式集羣。
因此併發編程的目標是充分的利用處理器的每個核,以達到最高的處理性能。

35.並行、併發、串行、分佈式是什麼意思?
並行(parallel)是指兩個或者多個事件在同一時刻發生; (線程/視頻)
而併發(Concurrent)是指兩個或多個事件在同一時間間隔發生;
串行(Sequential)A和B兩個任務運行在一個CPU線程上,在A任務執行完以前不能夠執行B。
分佈式(distributed)分佈式在並行處理的基礎上,強調任務正在執行的物理設備,
如處理器、內存等等硬件,在物理上是分開的。而並行計算是指在一臺計算機上的計算,在物理上不分開。

分佈式計算將任務分解成許多小的部分,分配給多臺計算機進行處理,
從而總體上節約了計算時間。Hadoop的MapReduce就是一種分佈式計算框架

補充:線程的五種狀態
一我的出生到死亡的過程。
線程:新建、就緒、運行、阻塞、死亡。
人 :出生 學習 工做 生病 昇天。

新建:new Thread()線程
就緒:可執行狀態 線程象.start() 隨時能夠被cpu調度執行
運行:得到了CPU的調度
阻塞:放棄了CPU使用權,從新排隊(就緒)
等待阻塞wait() 同步阻塞 synchronized 獲取同步鎖失敗
其它阻塞 sleep() join()
死亡:執行完了、異常退出

36.線程和進程的區別?
一個程序至少有一個進程。
一個進程至少有一個線程(主線程)。
進程在執行的過程當中擁有獨立的內存單元。
同一進程中的多個線程能夠併發執行。

進程是老大,線程是小弟。


37.守護線程是什麼?呆萌 daemon thread 保姆
它是一個服務線程,服務其它線程。

38.建立線程的幾種方式?
繼承Thread類 start()
實現Runnable接口 生寫run方法
Callable接口和Future建立線程 call

39.Runnable和Callable的區別
Runnable接口中的run方法沒返回值,純粹地執行run方法中的代碼而已。
Callable接口中的call方法有返回值,和Future/FutureTask接合使用。

40.線程有哪些狀態?
建立、就緒、運行、阻塞、死亡。

41.sleep和wait方法區別
sleep是Thread類的靜態法,讓調用線程進入睡眠狀態,讓出執行機會,
sleep(1000),等1000ms後醒來進入就緒。因爲是靜態方法不能改變對象鎖,
當synchronized塊調用了sleep方法,對象鎖沒有被釋放,其它線程沒法訪問。

wait()是Object類的方法,進入到一個和該對象的等待池,同時釋放對象鎖,其它
線程可以訪問,還能夠經過notify,notifyAll方法來喚醒。

42.notify()和notifyAll區別
notifyAll()方法(喚醒全部 wait 線程)或 notify()方法(只隨機喚醒一個 wait 線程)
優先級高的線程競爭到對象鎖的機率大,倘若某線程沒有競爭到該對象鎖,它還會留在鎖池中,
惟有線程再次調用 wait()方法,它纔會從新回到等待池中。
而競爭到對象鎖的線程則繼續往下執行,直到執行完了 synchronized 代碼塊,它會釋放掉該對象鎖,這時鎖池中的線程會繼續競爭該對象鎖。

43.線程的run和start方法有什麼區別
run方法寫具體的操做,經過Thread類的start()方法來啓動線程運行run方法。
只要調了start方法就啓動了run方法。

44.建立線程池有哪幾種方式
newFixedThreadPool(int nThreads) 固定長度線程池
newCachedThreadPool() 可緩存的線程池
newSingleThreadExecutor() 單線程線程池
newScheduledThreadPool(int corePoolSize) 固定長度能夠延時或定時執行

45.線程池都有哪些狀態
Running、ShutDown、Stop、Tidying、Terminated。

46.線程池submit和execute方法有什麼區別
接受的參數不一樣,submit有返回值,execute沒有。
submit異常處理容易

47.在Java程序中怎麼保證多線程的運行安全
三個方法:
原子性:互斥,同一時刻只能有一個線程對數據操做,方式atomic,synchronized
可見性:一個線程對主內存的修改能夠及時被其餘線程看到,方式synchronized,volatile
有序性:一個線程觀察其餘線程中的指令執行順序,因爲指令重排序,結果通常雜亂無序
能夠經過volatile、synchronized、lock保證有序性。

48.多線程鎖的升級原理是什麼?
Java中,鎖的四種狀態:級別從低到高:無狀態鎖,偏向鎖,輕量鎖,重量級鎖。
鎖能夠升級但不能降級。

49.什麼是死鎖?教室裏有一個掃把,A同窗和B學生同時搶着,各執己見。
死鎖是指兩個或兩個以上的進程在執行過程當中,
因爲競爭資源或者因爲彼此通訊而形成的一種阻塞的現象,
若無外力做用,它們都將沒法推動下去。
此時稱系統處於死鎖狀態或系統產生了死鎖,
這些永遠在互相等待的進程稱爲死鎖進程。
是操做系統層面的一個錯誤,是進程死鎖的簡稱。

50.怎麼防止死鎖?
死鎖的四個必要條件:
互斥條件
請求和保持條件
不可剝奪條件
環路等待條件

51.ThreadLocal是什麼,應用場景
Java提供ThreadLocal類來支持線程局部變量,是一種實現線程安全的方式。
可是在管理環境下(如 web 服務器)使用線程局部變量的時候要特別當心,在這種狀況下,工做線程的生命週期比任何應用變量的生命週期都要長。
任何線程局部變量一旦在工做完成後沒有釋放,Java 應用就存在內存泄露的風險。

52.說一下 synchronized 底層實現原理?
synchronized能夠保證方法或者代碼塊在運行時,同一時刻只有一個方法能夠進入到臨界區,同時它還能夠保證共享變量的內存可見性。
Java中每個對象均可以做爲鎖,這是synchronized實現同步的基礎:
普通同步方法,鎖是當前實例對象
靜態同步方法,鎖是當前類的class對象
同步方法塊,鎖是括號裏面的對象
53. synchronized 和 volatile 的區別是什麼?
volatile本質是在告訴jvm當前變量在寄存器(工做內存)中的值是不肯定的,須要從主存中讀取;synchronized則是鎖定當前變量,只有當前線程能夠訪問該變量,其餘線程被阻塞住。
volatile僅能使用在變量級別;synchronized則能夠使用在變量、方法、和類級別的。
volatile僅能實現變量的修改可見性,不能保證原子性;而synchronized則能夠保證變量的修改可見性和原子性。
volatile不會形成線程的阻塞;synchronized可能會形成線程的阻塞。
volatile標記的變量不會被編譯器優化;synchronized標記的變量能夠被編譯器優化。


54. synchronized 和 Lock 有什麼區別?
首先synchronized是java內置關鍵字,在jvm層面,Lock是個java類;
synchronized沒法判斷是否獲取鎖的狀態,Lock能夠判斷是否獲取到鎖;
synchronized會自動釋放鎖(a 線程執行完同步代碼會釋放鎖 ;b 線程執行過程當中發生異常會釋放鎖),Lock需在finally中手工釋放鎖(unlock()方法釋放鎖),不然容易形成線程死鎖;
用synchronized關鍵字的兩個線程1和線程2,若是當前線程1得到鎖,線程2線程等待。若是線程1阻塞,線程2則會一直等待下去,而Lock鎖就不必定會等待下去,若是嘗試獲取不到鎖,線程能夠不用一直等待就結束了;
synchronized的鎖可重入、不可中斷、非公平,而Lock鎖可重入、可判斷、可公平(二者皆可);
Lock鎖適合大量同步的代碼的同步問題,synchronized鎖適合代碼少許的同步問題。

55. synchronized 和 ReentrantLock 區別是什麼?
synchronized是和if、else、for、while同樣的關鍵字,ReentrantLock是類,這是兩者的本質區別。既然ReentrantLock是類,那麼它就提供了比synchronized更多更靈活的特性,能夠被繼承、能夠有方法、能夠有各類各樣的類變量,ReentrantLock比synchronized的擴展性體如今幾點上:
ReentrantLock能夠對獲取鎖的等待時間進行設置,這樣就避免了死鎖
ReentrantLock能夠獲取各類鎖的信息
ReentrantLock能夠靈活地實現多路通知
另外,兩者的鎖機制其實也是不同的:ReentrantLock底層調用的是Unsafe的park方法加鎖,synchronized操做的應該是對象頭中mark word。

56. 說一下 atomic 的原理?
Atomic包中的類基本的特性就是在多線程環境下,
當有多個線程同時對單個(包括基本類型及引用類型)變量進行操做時,
具備排他性,即當多個線程同時對該變量的值進行更新時,僅有一個線程能成功,
而未成功的線程能夠向自旋鎖同樣,繼續嘗試,一直等到執行成功。
這個裏面大量的方法調用都會存在安全隱患,須要當心使用,不然會致使嚴重的後果

57. 什麼是反射?
反射主要是指程序能夠訪問、檢測和修改它自己狀態或行爲的一種能力。
Java反射:在程序運行的過程當中,能夠知道類的全部屬性和方法,對而且操做的一種能力。

58. 什麼是 Java 序列化?什麼狀況下須要序列化?
Java 序列化就是將對象(各類對象的狀態)保存在內存中,而且還能夠讀取出來(反序列化)。
Java經過實現序列化接口來實現Serializable。
什麼狀況下須要序列化:
a)當你想把的內存中的對象狀態保存到一個文件中或者數據庫中時候;
b)當你想用套接字在網絡上傳送對象的時候;
c)當你想經過RMI傳輸對象的時候;

59. 動態代理是什麼?有哪些應用?
當想要給實現了某個接口的類中的方法,加一些額外的處理。
好比說加日誌,加事務等。能夠給這個類建立一個代理,
就是建立一個新的類,這個類不只包含原來類方法的功能,
並且還在原來的基礎上添加了額外處理的新類。
這個代理類並非定義好的,是動態生成的。具備解耦意義,靈活,擴展性強。

SpringAOP,Struts的攔截器
60.怎麼實現動態代理
首先必須定義一個接口,還要有一個InvocationHandler(將實現接口的類的對象傳遞給它)處理類。
再有一個工具類Proxy(習慣性將其稱爲代理類,由於調用他的newInstance()能夠產生代理對象,其實他只是一個產生代理對象的工具類)。
利用到InvocationHandler,拼接代理類源碼,
將其編譯生成代理類的二進制碼,利用加載器加載,
並將其實例化產生代理對象,最後返回。

61. 爲何要使用克隆?
想對一個對象進行處理,又想保留原有的數據進行接下來的操做,就須要克隆了。
Java語言中克隆針對的是類的實例。

62. 如何實現對象克隆?
有兩種方式:
• 實現Cloneable接口並重寫Object類中的clone()方法;
• 實現Serializable接口,經過對象的序列化和反序列化實現克隆,能夠實現真正的深度克隆
注意:基於序列化和反序列化實現的克隆不只僅是深度克隆,
更重要的是經過泛型限定,能夠檢查出要克隆的對象是否支持序列化,
這項檢查是編譯器完成的,不是在運行時拋出異常,
這種是方案明顯優於使用Object類的clone方法克隆對象。
讓問題在編譯的時候暴露出來老是好過把問題留到運行時。

63. 深拷貝和淺拷貝區別是什麼?
• 淺拷貝只是複製了對象的引用地址,兩個對象指向同一個內存地址,因此修改其中任意的值,
另外一個值都會隨之變化,這就是淺拷貝(例:assign())

• 深拷貝是將對象及值複製過來,兩個對象修改其中任意的值另外一個值不會改變,
這就是深拷貝(例:JSON.parse()和JSON.stringify(),
可是此方法沒法複製函數類型)

64. JSP 和 Servlet 有什麼區別?
JSP通過編譯以後就是Servlet,JVM識別Java源代碼不識別JSP,web容器將JSP編譯成
Java類。
JSP用於頁面展現充當視圖層,Servlet用於邏輯控制充當控制層。
Servlet中沒有內置對象,經過HttpServletRequest和HttpServletResponse來得到,
JSP中有九個內置對象。

65.JSP有哪些內置對象,做用分別是什麼
JSP有9個內置對象:
request:封裝客戶端的請求,其中包含來自GET或POST請求的參數;
response:封裝服務器對客戶端的響應;
pageContext:經過該對象能夠獲取其餘對象;
session:封裝用戶會話的對象;
application:封裝服務器運行環境的對象;
out:輸出服務器響應的輸出流對象;
config:Web應用的配置對象;
page:JSP頁面自己(至關於Java程序中的this);
exception:封裝頁面拋出異常的對象。

66.說一下JSP的四種做用域
JSP中的四種做用域包括page、request、session和application
page表明與一個頁面相關的對象和屬性。
request表明與Web客戶機發出的一個請求相關的對象和屬性。一個請求可能跨越多個頁面,涉及多個Web組件;須要在頁面顯示的臨時數據能夠置於此做用域。
session表明與某個用戶與服務器創建的一次會話相關的對象和屬性。跟某個用戶相關的數據應該放在用戶本身的session中。
application表明與整個Web應用程序相關的對象和屬性,它實質上是跨越整個Web應用程序,包括多個頁面、請求和會話的一個全局做用域。

67.Session和Cookie有什麼區別?URL重寫是什麼?
Session是在服務端保存的一個數據結構,用來跟蹤用戶的狀態,這個數據能夠保存在集羣、數據庫、文件中;
Cookie是客戶端保存用戶信息的一種機制,用來記錄用戶的一些信息,也是實現Session的一種方式。
當客戶端把cookie禁用了,那怎麼辦呢?!這個時候就須要使用URL重寫技術了。
URL重寫爲了頁面更有利於seo優化
response.encodeURL(「logoutServlet」);用於對超連接和action的表單提交進行重寫。

response.encodeRedirectURL("logoutServlet");用於對response.sendRedirect()的方法進行重寫。


68. 說一下 session 的工做原理?
其實session是一個存在服務器上的相似於一個散列表格的文件。
裏面存有咱們須要的信息,在咱們須要用的時候能夠從裏面取出來。
相似於一個大號的map吧,裏面的鍵存儲的是用戶的sessionid,
。這時就能夠從中取出對應的值了。

69. 若是客戶端禁止 cookie 能實現 session 還能用嗎?
Cookie與 Session,通常認爲是兩個獨立的東西,Session採用的是在服務器端保持狀態的方案,
而Cookie採用的是在客戶端保持狀態的方案。但爲何禁用Cookie就不能獲得Session呢?
由於Session是用Session ID來肯定當前對話所對應的服務器Session,
而Session ID是經過Cookie來傳遞的,禁用Cookie至關於失去了Session ID,也就得不到Session了。

70. spring mvc 和 struts 的區別是什麼?
攔截機制不一樣:Struts2,多例。有一套掛載機制。
SpringMVC是方法級別,線程安全。
底層框架不一樣:Struts2採用的是Filter實現(StrutsPrepareAndExecuteFilter),
SpringMVC是Servlet實現(DispatcherServlet前端控制器)
初始化時,早於Filter調用。
性能方面:SpringMVC性能優於Struts2。
配置方面:SpringMVC和Spring無縫對接,容易,安全性高於Struts2。

71.如何避免SQL注入:前臺,業務層,數據庫
PreparedStatement
使用正則表達式過濾傳入的參數
字符串過濾
JSP中調用該函數檢查是否包函非法字符
JSP頁面判斷代碼

72. 什麼是 XSS 攻擊,如何避免?
XSS攻擊又稱CSS,全稱Cross Site Script (跨站腳本攻擊),其原理是攻擊者向有XSS漏洞的網站中輸入惡意的 HTML 代碼,當用戶瀏覽該網站時,這段 HTML 代碼會自動執行,從而達到攻擊的目的。XSS 攻擊相似於 SQL 注入攻擊,SQL注入攻擊中以SQL語句做爲用戶輸入,從而達到查詢/修改/刪除數據的目的,而在xss攻擊中,經過插入惡意腳本,實現對用戶遊覽器的控制,獲取用戶的一些信息。XSS是 Web 程序中常見的漏洞,XSS 屬於被動式且用於客戶端的攻擊方式。
XSS防範的整體思路是:對輸入(和URL參數)進行過濾,對輸出進行編碼。

73. 什麼是 CSRF 攻擊,如何避免?
CSRF(Cross-site request forgery)也被稱爲 one-click attack或者 session riding,中文全稱是叫跨站請求僞造。通常來講,攻擊者經過僞造用戶的瀏覽器的請求,向訪問一個用戶本身曾經認證訪問過的網站發送出去,使目標網站接收並誤覺得是用戶的真實操做而去執行命令。經常使用於盜取帳號、轉帳、發送虛假消息等。攻擊者利用網站對請求的驗證漏洞而實現這樣的攻擊行爲,網站可以確認請求來源於用戶的瀏覽器,卻不能驗證請求是否源於用戶的真實意願下的操做行爲。
如何避免:
1. 驗證 HTTP Referer 字段
HTTP頭中的Referer字段記錄了該 HTTP 請求的來源地址。在一般狀況下,訪問一個安全受限頁面的請求來自於同一個網站,而若是黑客要對其實施 CSRF
攻擊,他通常只能在他本身的網站構造請求。所以,能夠經過驗證Referer值來防護CSRF 攻擊。
2. 使用驗證碼
關鍵操做頁面加上驗證碼,後臺收到請求後經過判斷驗證碼能夠防護CSRF。但這種方法對用戶不太友好。
3. 在請求地址中添加token並驗證
CSRF 攻擊之因此可以成功,是由於黑客能夠徹底僞造用戶的請求,該請求中全部的用戶驗證信息都是存在於cookie中,所以黑客能夠在不知道這些驗證信息的狀況下直接利用用戶本身的cookie 來經過安全驗證。要抵禦 CSRF,關鍵在於在請求中放入黑客所不能僞造的信息,而且該信息不存在於 cookie 之中。能夠在 HTTP 請求中以參數的形式加入一個隨機產生的 token,並在服務器端創建一個攔截器來驗證這個 token,若是請求中沒有token或者 token 內容不正確,則認爲多是 CSRF 攻擊而拒絕該請求。這種方法要比檢查 Referer 要安全一些,token 能夠在用戶登錄後產生並放於session之中,而後在每次請求時把token 從 session 中拿出,與請求中的 token 進行比對,但這種方法的難點在於如何把 token 以參數的形式加入請求。
對於 GET 請求,token 將附在請求地址以後,這樣 URL 就變成 http://url?csrftoken=tokenvalue。
而對於 POST 請求來講,要在 form 的最後加上 <input type="hidden" name="csrftoken" value="tokenvalue"/>,這樣就把token以參數的形式加入請求了。
4. 在HTTP 頭中自定義屬性並驗證
這種方法也是使用 token 並進行驗證,和上一種方法不一樣的是,這裏並非把 token 以參數的形式置於 HTTP 請求之中,而是把它放到 HTTP 頭中自定義的屬性裏。經過 XMLHttpRequest 這個類,能夠一次性給全部該類請求加上 csrftoken 這個 HTTP 頭屬性,並把 token 值放入其中。這樣解決了上種方法在請求中加入 token 的不便,同時,經過 XMLHttpRequest 請求的地址不會被記錄到瀏覽器的地址欄,也不用擔憂 token 會透過 Referer 泄露到其餘網站中去。

74. throw 和 throws 的區別?
throws是用來聲明一個方法可能拋出的全部異常信息,throws是將異常聲明可是不處理,而是將異常往上傳,誰調用我就交給誰處理。
而throw則是指拋出的一個具體的異常類型。

75. final、finally、finalize 有什麼區別?
final能夠修飾類、變量、方法,修飾類表示該類不能被繼承、修飾方法表示該方法不能被重寫、修飾變量表示該變量是一個常量不能被從新賦值。
finally通常做用在try-catch代碼塊中,在處理異常的時候,一般咱們將必定要執行的代碼方法finally代碼塊中,表示無論是否出現異常,該代碼塊都會執行,通常用來存放一些關閉資源的代碼。
finalize是一個方法,屬於Object類的一個方法,而Object類是全部類的父類,該方法通常由垃圾回收器來調用,當咱們調用System的gc()方法的時候,由垃圾回收器調用finalize(),回收垃圾。


76. try-catch-finally 中哪一個部分能夠省略?
try{}catch(){}
try{}catch(){}finally{}
try{}finally{}

try不能省,catch和finally必須存在一個,也能夠同時存在。
try裏面的代碼是有可能產生異常的代碼
catch是捕獲異常實例
finally不管如何都執行,主要用於釋放資源

77. try-catch-finally 中,若是 catch 中 return 了,finally 還會執行嗎?在以前仍是在以後?
答:會執行,finally在return 前執行。

78. 常見的異常類有哪些?
算術異常 ArithmeticException
空指針異常NullPointException
數組下標越界ArrayIndexOfOutBounds
文件讀寫異常IOException
數據庫異常SQLException
參數異常 IllegalArgumentException
文件找不到FileNotFoundException
類沒法轉ClassCastException
沒有這樣的方法 NoSuchMethodException

79. http 響應碼 301 和 302 表明的是什麼?有什麼區別?
HTTP狀態的編碼,都表明着某個URL發生了轉移。
URL統一資源定位符。
區別:
• 301 redirect: 301 表明永久性轉移(Permanently Moved)。
• 302 redirect: 302 表明暫時性轉移(Temporarily Moved )。

80. forward 和 redirect 的區別?
張三去買房,須要民政局的結婚證實。
forward 轉發 直接 張三去銀行貸款,銀行本身去查證張三是否結婚。
redirect重定向 間接 張三去銀行貸款,銀行說你去開結婚證實,張三去了民政局。

81. 簡述 tcp 和 udp的區別?
TCP傳輸控制協議:面向鏈接(靠譜) 必須有問有答。無差錯,不丟失,不重複,且按序到達;
UDP用戶數據報文協議:無鏈接(不太靠譜)UDP盡最大努力交付,即不保證可靠交付。

UDP具備較好的實時性,工做效率比TCP高,適用於對高速傳輸和實時性有較高的通訊或廣播通訊。

每一條TCP鏈接只能是點到點的;
UDP支持一對一,一對多,多對一和多對多的交互通訊。

TCP對系統資源要求較多,UDP對系統資源要求較少。

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

張三:喂
李四:聽到
張三:我也聽到你的聲音了

爲了實現可靠數據傳輸, TCP 協議的通訊雙方, 都必須維護一個序列號,
以標識發送出去的數據包中, 哪些是已經被對方收到的。
三次握手的過程便是通訊雙方相互告知序列號起始值, 並確認對方已經收到了序列號起始值的必經步驟。
若是隻是兩次握手, 至多隻有鏈接發起方的起始序列號能被確認, 另外一方選擇的序列號則得不到確認。

83. 說一下 tcp 粘包是怎麼產生的?
發送方產生粘包
發送緩衝區不止一個數據包
接收方產生粘包
接收緩衝區不止一個數據包

發送方產生粘包(發送的數據過小,要對小數據包合併)
採用TCP協議傳輸數據的客戶端與服務器常常是保持一個長鏈接的狀態(一次鏈接發一次數據不存在粘包),
雙方在鏈接不斷開的狀況下,能夠一直傳輸數據;
但當發送的數據包過於的小時,那麼TCP協議默認的會啓用Nagle算法,
將這些較小的數據包進行合併發送(緩衝區數據發送是一個堆壓的過程);
這個合併過程就是在發送緩衝區中進行的,也就是說數據發送出來它已是粘包的狀態了。

84. OSI 的七層模型都有哪些?
• 應用層:網絡服務與最終用戶的一個接口。
• 表示層:數據的表示、安全、壓縮。
• 會話層:創建、管理、終止會話。
• 傳輸層:定義傳輸數據的協議端口號,以及流控和差錯校驗。
• 網絡層:進行邏輯地址尋址,實現不一樣網絡之間的路徑選擇。
• 數據鏈路層:創建邏輯鏈接、進行硬件地址尋址、差錯校驗等功能。
• 物理層:創建、維護、斷開物理鏈接。

85. get 和 post 請求有哪些區別?
• GET在瀏覽器回退時是無害的,而POST會再次提交請求。
• GET產生的URL地址能夠被書籤(Bookmark),而POST不能夠。
• GET請求會被瀏覽器主動緩存(cache),而POST不會,除非手動設置。
• GET請求只能進行url編碼,而POST支持多種編碼方式。
• GET請求參數會被完整保留在瀏覽器歷史記錄裏,而POST中的參數不會被保留。
• GET請求在URL中傳送的參數是有長度限制的,而POST沒有。
• 參數的數據類型,GET只接受ASCII字符,而POST沒有限制。
• GET比POST更不安全,由於參數直接暴露在URL上,因此不能用來傳遞敏感信息。
• GET參數經過URL傳遞,POST放在Request body中。

86. 如何實現跨域?
方式一:圖片ping或script標籤跨域
圖片ping經常使用於跟蹤用戶點擊頁面或動態廣告曝光次數。
script標籤能夠獲得從其餘來源數據,這也是JSONP依賴的根據。
方式二:JSONP跨域
JSONP(JSON with Padding)是數據格式JSON的一種「使用模式」,可讓網頁從別的網域要數據。根據 XmlHttpRequest 對象受到同源策略的影響,而利用
• 只能使用Get請求
• 不能註冊success、error等事件監聽函數,不能很容易的肯定JSONP請求是否失敗
• JSONP是從其餘域中加載代碼執行,容易受到跨站請求僞造的攻擊,其安全性沒法確保
方式三:CORS
Cross-Origin Resource Sharing(CORS)跨域資源共享是一份瀏覽器技術的規範,提供了 Web 服務從不一樣域傳來沙盒腳本的方法,以避開瀏覽器的同源策略,確保安全的跨域數據傳輸。現代瀏覽器使用CORS在API容器如XMLHttpRequest來減小HTTP請求的風險來源。與 JSONP 不一樣,CORS 除了 GET 要求方法之外也支持其餘的 HTTP 要求。服務器通常須要增長以下響應頭的一種或幾種:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
Access-Control-Max-Age: 86400
跨域請求默認不會攜帶Cookie信息,若是須要攜帶,請配置下述參數:
"Access-Control-Allow-Credentials": true// Ajax設置"withCredentials": true
87.說一下 JSONP 實現原理?
jsonp 即 json+padding,動態建立script標籤,利用script標籤的src屬性能夠獲取任何域下的js腳本,
經過這個特性(也能夠說漏洞),服務器端再也不返回json格式,而是返回一段調用某個函數的js代碼,
在src中進行了調用,這樣實現了跨域。

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

整體來講設計模式分爲三大類:

建立型模式,共五種:工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式。

結構型模式,共七種:適配器模式、裝飾器模式、代理模式、外觀模式、橋接模式、組合模式、享元模式。

行爲型模式,共十一種:策略模式、模板方法模式、觀察者模式、迭代子模式、責任鏈模式、命令模式、備忘錄模式、狀態模式、訪問者模式、中介者模式、解釋器模式。

其實還有兩類:併發型模式和線程池模式。

設計模式的六大原則
一、開閉原則(Open Close Principle)

開閉原則就是說對擴展開放,對修改關閉。在程序須要進行拓展的時候,不能去修改原有的代碼,實現一個熱插拔的效果。因此一句話歸納就是:爲了使程序的擴展性好,易於維護和升級。想要達到這樣的效果,咱們須要使用接口和抽象類,後面的具體設計中咱們會提到這點。

二、里氏代換原則(Liskov Substitution Principle)

里氏代換原則(Liskov Substitution Principle LSP)面向對象設計的基本原則之一。里氏代換原則中說,任何基類能夠出現的地方,子類必定能夠出現。LSP是繼承複用的基石,只有當衍生類能夠替換掉基類,軟件單位的功能不受到影響時,基類才能真正被複用,而衍生類也可以在基類的基礎上增長新的行爲。里氏代換原則是對「開-閉」原則的補充。實現「開-閉」原則的關鍵步驟就是抽象化。而基類與子類的繼承關係就是抽象化的具體實現,因此里氏代換原則是對實現抽象化的具體步驟的規範。—— From Baidu 百科

三、依賴倒轉原則(Dependence Inversion Principle)

這個是開閉原則的基礎,具體內容:真對接口編程,依賴於抽象而不依賴於具體。

四、接口隔離原則(Interface Segregation Principle)

這個原則的意思是:使用多個隔離的接口,比使用單個接口要好。仍是一個下降類之間的耦合度的意思,從這兒咱們看出,其實設計模式就是一個軟件的設計思想,從大型軟件架構出發,爲了升級和維護方便。因此上文中屢次出現:下降依賴,下降耦合。

五、迪米特法則(最少知道原則)(Demeter Principle)

爲何叫最少知道原則,就是說:一個實體應當儘可能少的與其餘實體之間發生相互做用,使得系統功能模塊相對獨立。

六、合成複用原則(Composite Reuse Principle)

原則是儘可能使用合成/聚合的方式,而不是使用繼承

89. 簡單工廠和抽象工廠有什麼區別?https://www.cnblogs.com/ldgg
簡單工廠:三個部分 工廠類、抽象產品、具體產品
麓谷汽車世界 車 寶馬、奔馳、奧迪
抽象工廠:產品樹和產品族
寶馬和奔馳是產品樹
寶馬跑車
奔馳跑車
奧迪跑車
產品族

90. 爲何要使用 spring?
1.流行,企業用的多。解決企業應用開發的複雜性。
2.輕量,發佈時文件小。1M左右。
3.控制反轉IOC和依賴注入DI實現解耦。
4.面向切面AOP,讓程序員更關注業務邏輯的代碼開發。如日誌事務的抽離。
5.能夠配置單例和多例。
6.配置在xml中輕易實現。

91. 解釋一下什麼是 aop?
面向方面的編程,是OOP的補充和完善。
採用橫切關注點思想,將應用邏輯和通用代碼分離,提升代碼利用。

92. 解釋一下什麼是 ioc?
控制反轉
思想是藉助於「第三方」實現對象解耦。
至關於粘合劑。

93. spring 有哪些主要模塊?
Beans
Core
Context
AOP
JDBC
Web
Servlet
94. spring 經常使用的注入方式有哪些?
set注入
構造注入
註解注入
95. spring 中的 bean 是線程安全的嗎?
不具有線程安全,具體結合scope的bean去設置。
prototype每次拿到的同一個bean不同。
singleton每次拿到的同一個bean同樣。

96. spring 支持幾種 bean 的做用域?
session、request、global session
singleton(單例)、non-singleton(也稱 prototype)
97. spring 自動裝配 bean 有哪些方式?
• 隱式的bean發現機制和自動裝配
• 在java代碼或者XML中進行顯示配置
98. spring 事務實現方式有哪些?
編程式事務 TransactionProxyFactoryBean
聲明式事務 Aspectj AOP
註解式事務@Transactional

99. 說一下 spring 的事務隔離?
• 髒讀:一個事務讀到另外一個事務未提交的更新數據。
• 幻讀:例如第一個事務對一個表中的數據進行了修改,好比這種修改涉及到表中的「所有數據行」。同時,第二個事務也修改這個表中的數據,這種修改是向表中插入「一行新數據」。那麼,之後就會發生操做第一個事務的用戶發現表中還存在沒有修改的數據行,就好象發生了幻覺同樣。
• 不可重複讀:比方說在同一個事務中前後執行兩條如出一轍的select語句,期間在這次事務中沒有執行過任何DDL語句,但前後獲得的結果不一致,這就是不可重複讀。
100. 說一下 spring mvc 運行流程?
用戶向服務器發送請求,請求被Spring 前端控制Servelt DispatcherServlet捕獲;
DispatcherServlet對請求URL進行解析,獲得請求資源標識符(URI)。而後根據該URI,調用HandlerMapping得到該Handler配置的全部相關的對象(包括Handler對象以及Handler對象對應的攔截器),最後以HandlerExecutionChain對象的形式返回;
DispatcherServlet 根據得到的Handler,選擇一個合適的HandlerAdapter;(附註:若是成功得到HandlerAdapter後,此時將開始執行攔截器的preHandler(…)方法)
提取Request中的模型數據,填充Handler入參,開始執行Handler(Controller)。在填充Handler的入參過程當中,根據你的配置,Spring將幫你作一些額外的工做:
一、HttpMessageConveter:將請求消息(如Json、xml等數據)轉換成一個對象,將對象轉換爲指定的響應信息
二、數據轉換:對請求消息進行數據轉換。如String轉換成Integer、Double等
三、數據根式化:對請求消息進行數據格式化。如將字符串轉換成格式化數字或格式化日期等
四、數據驗證:驗證數據的有效性(長度、格式等),驗證結果存儲到BindingResult或Error中
Handler執行完成後,向DispatcherServlet 返回一個ModelAndView對象;
根據返回的ModelAndView,選擇一個適合的ViewResolver(必須是已經註冊到Spring容器中的ViewResolver)返回給DispatcherServlet ;
ViewResolver 結合Model和View,來渲染視圖;
將渲染結果返回給客戶端。


101. spring mvc 有哪些組件?
• DispatcherServlet:中央控制器,把請求給轉發到具體的控制類
• Controller:具體處理請求的控制器
• HandlerMapping:映射處理器,負責映射中央處理器轉發給controller時的映射策略
• ModelAndView:服務層返回的數據和視圖層的封裝類
• ViewResolver:視圖解析器,解析具體的視圖
• Interceptors :攔截器,負責攔截咱們定義的請求而後作處理工做

102. @RequestMapping 的做用是什麼?
RequestMapping是一個用來處理請求地址映射的註解,可用於類或方法上。用於類上,表示類中的全部響應請求的方法都是以該地址做爲父路徑。
RequestMapping註解有六個屬性,下面咱們把她分紅三類進行說明。
value, method:
• value:指定請求的實際地址,指定的地址能夠是URI Template 模式(後面將會說明);
• method:指定請求的method類型, GET、POST、PUT、DELETE等;
consumes,produces
• consumes:指定處理請求的提交內容類型(Content-Type),例如application/json, text/html;
• produces:指定返回的內容類型,僅當request請求頭中的(Accept)類型中包含該指定類型才返回;
params,headers
• arams:指定request中必須包含某些參數值是,才讓該方法處理。
• headers:指定request中必須包含某些指定的header值,才能讓該方法處理請求。

103. @Autowired 的做用是什麼?
@Autowired 是一個註釋,它能夠對類成員變量、方法及構造函數進行標註,讓 spring 完成 bean 自動裝配的工做。
@Autowired 默認是按照類去匹配,配合 @Qualifier 指定按照名稱去裝配 bean。

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

105. 爲何要用 spring boot?
簡單、方便、高效

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

107. spring boot 配置文件有哪幾種類型?它們有什麼區別?
是properties文件和yml文件。
properties是鍵值對的寫法,直觀。
yml是層級關係的寫法,不容易看。
網上有許多相互轉換的工具,沒有什麼影響。

108. spring boot 有哪些方式能夠實現熱部署?
我經常使用的是:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
</configuration>
</plugin>
</plugins>
</ build>
未知
而後:使用 shift+ctrl+alt+"/" (IDEA中的快捷鍵) 選擇"Registry" 而後勾選 compiler.automake.allow.when.app.running

109. jpa 和 hibernate 有什麼區別?
JPA是一個通用的規範,
Hibernate實現了這個規範。

110. 什麼是 spring cloud?
屬於Spring家族。致力於分佈式系統、雲服務的框架。
經常使用的五大組件:
Eureka
Ribbon
Hystrix
Zuul
Feign

111. spring cloud 斷路器的做用是什麼?
防止雪崩效應,致使大批量服務器癱瘓,最終應用崩潰。
當請求到一個有問題的服務器時,會返回一個狀態給客戶端,告知客戶端,並嘗試自行修復,不讓其它客戶端訪問。

112. spring cloud 的核心組件有哪些?
1.Eureka 服務的註冊與發現
用RestTemplate
2.用Ribbon
實現負載均衡:多臺服務器處理用戶的請求(平均或均衡)
3.Hystrix斷路器(由)
防止雪崩,防止系統癱瘓。
4.Zuul 網關 相似Nginx反向代理。經過請求路徑標識達到請求指定服務器的目的。
5.feign,Feign 是一個聲明式的僞RPC(Remote Procedure Call 遠程過程調用)的REST客戶端,它用了基於接口的註解方式,很方便的客戶端配置。
取代了TestTemplate,讓用戶感受本身像在本地操做遠程方法。
6.分佈式配置config,配置合spring cloud bus實現動態配置更新。

Hibernate:全自動持久化框架
113.爲何要使用 hibernate?
簡化了JDBC操做。
是一個優秀的ORM實現,實現了JPA。
是使用JAVA反射機制。
性能好,輕量級,靈活。
支持各類關係數據庫,各類映射關係。

114. 什麼是 ORM 框架?
它是對象關係映射框架。
應用程序用實體來描述對象,數據庫用表來描述對象。
應用程序實體間有繼承和關聯關係,數據庫中沒法表述,此時須要中間層來描述,
ORM就是實現「將程序對象映射到關係數據庫中的數據。」(實體和表映射)

115. hibernate 中如何在控制檯查看打印的 sql 語句?
spring.jpa.properties.hibernate.show_sql=true         //控制檯是否打印
spring.jpa.properties.hibernate.format_sql=true        //格式化sql語句
spring.jpa.properties.hibernate.use_sql_comments=true //指出是什麼操做生成了該語句

116. hibernate 有幾種查詢方式?
HQL 查實體和屬性 區分大小寫 Hibernate查詢
SQL 查表和列 不區分 原生SQL查詢
Criteria QBC:條件查詢

117. hibernate 實體類能夠被定義爲 final 嗎?
能夠,但不建議。
緣由:影響性能。
爲何:一個類被定義爲final,Hibernate就沒法使用代理。
如何避免:讓實體類實現一個接口,接口中聲明瞭全部定義於實體類中的全部public的方法

118. 在 hibernate 中使用 Integer 和 int 作映射有什麼區別?
Integer是一個類,故能夠判斷是否爲空。
int是原始數據類型,默認值爲0。
Hibernate中OID爲Integer,若是爲null,能夠判斷一個對象是否是臨時的。
Hibernate中OID爲int型,那麼還要設置unsaved-value爲0。

119. hibernate 是如何工做的?
讀取Hibernate配置文件
讀取實體映射文件
建立工廠
建立會話
開啓事務
處理
提交事務
關閉會話
關閉工廠

120. get()和 load()的區別?
get()即時,沒有使用屬性也發出SQL
load()是延時,在使用時才發出SQL

121. 說一下 hibernate 的緩存機制?
一級緩存,二級緩存。
一級緩存就是 Session 級別的緩存,在事務範圍內有效是,內置的不能被卸載。
二級緩存是 SesionFactory級別的緩存,從應用啓動到應用結束有效。二級緩存用第三方插件,須要配置。
擴展:hibernate的二級緩存默認是不支持分佈式緩存的。使用 memcahe,redis等中央緩存來代替二級緩存。

122. hibernate 對象有哪些狀態?
臨時狀態(瞬時狀態):new
持久狀態:save() saveOrUpdate()
脫管狀態:session.close()

123. 在 hibernate 中 getCurrentSession 和 openSession 的區別是什麼?
getCurrentSession()若是已經有session,那麼就用這個,若是沒有就開啓新的。
openSession,每次都會開啓新的session。

124.hibernate 實體類必需要有無參構造函數嗎?爲何?
必需要一個無參的構造函數。
Hibernate經過反射來構建對象,而且是調用其默認構造方法來實現。

MyBaits 半自動化框架,讓程序員更好的更靈活的使用sql

125.mybatis 中 #{}和 ${}的區別是什麼?
#{}是預編譯,至關於JDBC中的PreparedStatement問號佔位符。
${}是拼字符串,至關於JDBC中的Statement,有sql注入的風險。
#{}能夠防止sql注入。

126.mybatis 有幾種分頁方式?
數組分頁
sql分頁
攔截器分頁
RowBounds分頁
第三方插件分頁:如PageHelper

127.RowBounds 是一次性查詢所有結果嗎?爲何?
RowBounds 表面是在「全部」數據中檢索數據,其實並不是是一次性查詢出全部數據,
由於 MyBatis 是對 jdbc 的封裝,在 jdbc 驅動中有一個 Fetch Size 的配置,
它規定了每次最多從數據庫查詢多少條數據,假如你要查詢更多數據,
它會在你執行 next()的時候,去查詢更多的數據。
就比如你去自動取款機取 10000 元,但取款機每次最多能取 2500 元,因此你要取 4 次才能把錢取完。
只是對於 jdbc 來講,當你調用 next()的時候會自動幫你完成查詢工做。這樣作的好處能夠有效的防止內存溢出。

128.mybatis 邏輯分頁和物理分頁的區別是什麼?
物理分頁速度上並不必定快於邏輯分頁,邏輯分頁速度上也並不必定快於物理分頁。
物理分頁老是優於邏輯分頁:沒有必要將屬於數據庫端的壓力加諸到應用端來,
就算速度上存在優點,然而其它性能上的優勢足以彌補這個缺點

129.mybatis 是否支持延遲加載?延遲加載的原理是什麼?
支持,可是僅在配置了關聯關係的狀況下,而且設置了azyLoadingEnabled=true。
它的原理是,使用CGLIB建立目標對象的代理對象,當調用目標方法時,進入攔截器方法,
好比調用a.getB().getName(),攔截器invoke()方法發現a.getB()是null值,
那麼就會單獨發送事先保存好的查詢關聯B對象的sql,把B查詢上來,而後調用a.setB(b),
因而a的對象b屬性就有值了,接着完成a.getB().getName()方法的調用。這就是延遲加載的基本原理。

130.說一下 mybatis 的一級緩存和二級緩存?
一級緩存: 基於 PerpetualCache 的 HashMap 本地緩存,其存儲做用域爲 Session,當 Session flush 或 close 以後,該 Session 中的全部 Cache 就將清空,默認打開一級緩存。
二級緩存與一級緩存其機制相同,默認也是採用 PerpetualCache,HashMap 存儲,不一樣在於其存儲做用域爲 Mapper(Namespace),而且可自定義存儲源,如 Ehcache。默認不打開二級緩存,要開啓二級緩存,使用二級緩存屬性類須要實現Serializable序列化接口(可用來保存對象的狀態),可在它的映射文件中配置 ;
對於緩存數據更新機制,當某一個做用域(一級緩存 Session/二級緩存Namespaces)的進行了C/U/D 操做後,默認該做用域下全部 select 中的緩存將被 clear。

131.mybatis 和 hibernate 的區別有哪些?
(1)Mybatis和hibernate不一樣,它不徹底是一個ORM框架,由於MyBatis須要程序員本身編寫Sql語句。
(2)Mybatis直接編寫原生態sql,能夠嚴格控制sql執行性能,靈活度高,很是適合對關係數據模型要求不高的軟件開發,由於這類軟件需求變化頻繁,一但需求變化要求迅速輸出成果。可是靈活的前提是mybatis沒法作到數據庫無關性,若是須要實現支持多種數據庫的軟件,則須要自定義多套sql映射文件,工做量大。
(3)Hibernate對象/關係映射能力強,數據庫無關性好,對於關係模型要求高的軟件,若是用hibernate開發能夠節省不少代碼,提升效率。

132.mybatis 有哪些執行器(Executor)?
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批處理相同。

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

134.mybatis 如何編寫一個自定義插件?
blog.csdn.net/qq_30051265/article/details/80266434

RabbitMQ
135.rabbitmq 的使用場景有哪些?
https://www.cnblogs.com/zhao-yi/p/9299126.html
2.1 異步處理
場景說明:用戶註冊後,須要發註冊郵件和註冊短信,傳統的作法有兩種1.串行的方式;2.並行的方式
(1)串行方式:將註冊信息寫入數據庫後,發送註冊郵件,再發送註冊短信,以上三個任務所有完成後才返回給客戶端。這有一個問題是,郵件,短信並非必須的,它只是一個通知,而這種作法讓客戶端等待沒有必要等待的東西.
(2)並行方式:將註冊信息寫入數據庫後,發送郵件的同時,發送短信,以上三個任務完成後,返回給客戶端,並行的方式能提升處理的時間。
假設三個業務節點分別使用50ms,串行方式使用時間150ms,並行使用時間100ms。雖然並性已經提升的處理時間,可是,前面說過,郵件和短信對我正常的使用網站沒有任何影響,客戶端沒有必要等着其發送完成才顯示註冊成功,英愛是寫入數據庫後就返回.
(3)消息隊列
引入消息隊列後,把發送郵件,短信不是必須的業務邏輯異步處理
這裏寫圖片描述
由此能夠看出,引入消息隊列後,用戶的響應時間就等於寫入數據庫的時間+寫入消息隊列的時間(能夠忽略不計),引入消息隊列後處理後,響應時間是串行的3倍,是並行的2倍。

2.2 應用解耦
場景:雙11是購物狂節,用戶下單後,訂單系統須要通知庫存系統,傳統的作法就是訂單系統調用庫存系統的接口.
這種作法有一個缺點:
當庫存系統出現故障時,訂單就會失敗。(這樣馬雲將少賺好多好多錢^ ^)
訂單系統和庫存系統高耦合.
訂單系統:用戶下單後,訂單系統完成持久化處理,將消息寫入消息隊列,返回用戶訂單下單成功。

庫存系統:訂閱下單的消息,獲取下單消息,進行庫操做。
就算庫存系統出現故障,消息隊列也能保證消息的可靠投遞,不會致使消息丟失(馬雲這下高興了).

引入消息隊列

2.3 流量削峯
流量削峯通常在秒殺活動中應用普遍
場景:秒殺活動,通常會由於流量過大,致使應用掛掉,爲了解決這個問題,通常在應用前端加入消息隊列。
做用:
1.能夠控制活動人數,超過此必定閥值的訂單直接丟棄(我爲何秒殺一次都沒有成功過呢^^)
2.能夠緩解短期的高流量壓垮應用(應用程序按本身的最大處理能力獲取訂單)
這裏寫圖片描述
1.用戶的請求,服務器收到以後,首先寫入消息隊列,加入消息隊列長度超過最大值,則直接拋棄用戶請求或跳轉到錯誤頁面.
2.秒殺業務根據消息隊列中的請求信息,再作後續處理.

136.rabbitmq 有哪些重要的角色?
RabbitMQ 中重要的角色有:生產者、消費者和代理:
生產者:消息的建立者,負責建立和推送數據到消息服務器;
消費者:消息的接收方,用於處理數據和確認消息;
代理:就是 RabbitMQ 自己,用於扮演「快遞」的角色,自己不生產消息,只是扮演「快遞」的角色。

137.rabbitmq 有哪些重要的組件?
ConnectionFactory(鏈接管理器):應用程序與Rabbit之間創建鏈接的管理器,程序代碼中使用。
Channel(信道):消息推送使用的通道。
Exchange(交換器):用於接受、分配消息。
Queue(隊列):用於存儲生產者的消息。
RoutingKey(路由鍵):用於把生成者的數據分配到交換器上。
BindingKey(綁定鍵):用於把交換器的消息綁定到隊列上。

138.rabbitmq 中 vhost 的做用是什麼?
vhost 能夠理解爲虛擬 broker ,即 mini-RabbitMQ server。其內部均含有獨立的 queue、exchange 和 binding 等,但最最重要的是,其擁有獨立的權限系統,能夠作到 vhost 範圍的用戶控制。固然,從 RabbitMQ 的全局角度,vhost 能夠做爲不一樣權限隔離的手段(一個典型的例子就是不一樣的應用能夠跑在不一樣的 vhost 中)。

139.rabbitmq 的消息是怎麼發送的?
首先客戶端必須鏈接到 RabbitMQ 服務器才能發佈和消費消息,客戶端和 rabbit server 之間會建立一個 tcp 鏈接,一旦 tcp 打開並經過了認證(認證就是你發送給 rabbit 服務器的用戶名和密碼),你的客戶端和 RabbitMQ 就建立了一條 amqp 信道(channel),信道是建立在「真實」 tcp 上的虛擬鏈接,amqp 命令都是經過信道發送出去的,每一個信道都會有一個惟一的 id,不管是發佈消息,訂閱隊列都是經過這個信道完成的。

140.rabbitmq 怎麼保證消息的穩定性?
提供了事務的功能。
經過將 channel 設置爲 confirm(確認)模式。

141.rabbitmq 怎麼避免消息丟失?
消息持久化
ACK確認機制
設置集羣鏡像模式
消息補償機制

142.要保證消息持久化成功的條件有哪些?
聲明隊列必須設置持久化 durable 設置爲 true.
消息推送投遞模式必須設置持久化,deliveryMode 設置爲 2(持久)。
消息已經到達持久化交換器。
消息已經到達持久化隊列。
以上四個條件都知足才能保證消息持久化成功。

143.rabbitmq 持久化有什麼缺點?
持久化的缺地就是下降了服務器的吞吐量,由於使用的是磁盤而非內存存儲,從而下降了吞吐量。可儘可能使用 ssd 硬盤來緩解吞吐量的問題。

144.rabbitmq 有幾種廣播類型?
fanout: 全部bind到此exchange的queue均可以接收消息(純廣播,綁定到RabbitMQ的接受者都能收到消息);
direct: 經過routingKey和exchange決定的那個惟一的queue能夠接收消息;
topic:全部符合routingKey(此時能夠是一個表達式)的routingKey所bind的queue能夠接收消息;

145.rabbitmq 怎麼實現延遲消息隊列?
使用 RabbitMQ-delayed-message-exchange 插件實現延遲功能。
146.rabbitmq 集羣有什麼用?
集羣主要有如下兩個用途:
高可用:某個服務器出現問題,整個 RabbitMQ 還能夠繼續使用;
高容量:集羣能夠承載更多的消息量。
147.rabbitmq 節點的類型有哪些?
磁盤節點:消息會存儲到磁盤。
內存節點:消息都存儲在內存中,重啓服務器消息丟失,性能高於磁盤類型。

148.rabbitmq 集羣搭建須要注意哪些問題?
各節點之間使用「–link」鏈接,此屬性不能忽略。
各節點使用的 erlang cookie 值必須相同,此值至關於「祕鑰」的功能,用於各節點的認證。
整個集羣中必須包含一個磁盤節點。

149.rabbitmq 每一個節點是其餘節點的完整拷貝嗎?爲何?
不是,緣由有如下兩個:
存儲空間的考慮:若是每一個節點都擁有全部隊列的徹底拷貝,這樣新增節點不但沒有新增存儲空間,反而增長了更多的冗餘數據;
性能的考慮:若是每條消息都須要完整拷貝到每個集羣節點,那新增節點並無提高處理消息的能力,最可能是保持和單節點相同的性能甚至是更糟。

150.rabbitmq 集羣中惟一一個磁盤節點崩潰了會發生什麼狀況?
若是惟一磁盤的磁盤節點崩潰了,不能進行如下操做:
不能建立隊列
不能建立交換器
不能建立綁定
不能添加用戶
不能更改權限
不能添加和刪除集羣節點
惟一磁盤節點崩潰了,集羣是能夠保持運行的,但你不能更改任何東西。

151.rabbitmq 對集羣節點中止順序有要求嗎?
中止服務:應當先關閉內存節點,再關閉磁盤節點。先關閉磁盤節點的話會致使沒法建立交換器、隊列、綁定關係,從而可能會致使數據丟失。
啓動服務:先啓動磁盤節點,再啓動內存節點。

Kafka
kafka 能夠脫離 zookeeper 單獨使用嗎?爲何?
kafka 不能脫離 zookeeper 單獨使用,由於 kafka 使用 zookeeper 管理和協調 kafka 的節點服務器。
153. kafka 有幾種數據保留的策略?
kafka 有兩種數據保存策略:按照過時時間保留和按照存儲的消息大小保留。
154. kafka 同時設置了 7 天和 10G 清除數據,到第五天的時候消息達到了 10G,這個時候 kafka 將如何處理?
這個時候 kafka 會執行數據清除工做,時間和大小不論那個知足條件,都會清空數據。
155. 什麼狀況會致使 kafka 運行變慢?
cpu 性能瓶頸
磁盤讀寫瓶頸
網絡瓶頸
156. 使用 kafka 集羣須要注意什麼?
集羣的數量不是越多越好,最好不要超過 7 個,由於節點越多,消息複製須要的時間就越長,整個羣組的吞吐量就越低。
集羣數量最好是單數,由於超過一半故障集羣就不能用了,設置爲單數容錯率更高。

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

MySql
1. 數據庫的三範式是什麼?
第一範式:強調的是列的原子性,即數據庫表的每一列都是不可分割的原子數據項。
第二範式:要求實體的屬性徹底依賴於主關鍵字。所謂徹底依賴是指不能存在僅依賴主關鍵字一部分的屬性。
第三範式:任何非主屬性不依賴於其它非主屬性。

165. 一張自增表裏面總共有 7 條數據,刪除了最後 2 條數據,重啓 mysql 數據庫,又插入了一條數據,此時 id 是幾?
表類型若是是 MyISAM ,那 id 就是 8。
表類型若是是 InnoDB,那 id 就是 6。
InnoDB 表只會把自增主鍵的最大 id 記錄在內存中,因此重啓以後會致使最大 id 丟失。
166. 如何獲取當前數據庫版本?
使用 select version() 獲取當前 MySQL 數據庫版本。
167. 說一下 ACID 是什麼?
Atomicity(原子性):一個事務(transaction)中的全部操做,或者所有完成,或者所有不完成,不會結束在中間某個環節。事務在執行過程當中發生錯誤,會被恢復(Rollback)到事務開始前的狀態,就像這個事務歷來沒有執行過同樣。即,事務不可分割、不可約簡。
Consistency(一致性):在事務開始以前和事務結束之後,數據庫的完整性沒有被破壞。這表示寫入的資料必須徹底符合全部的預設約束、觸發器、級聯回滾等。
Isolation(隔離性):數據庫容許多個併發事務同時對其數據進行讀寫和修改的能力,隔離性能夠防止多個事務併發執行時因爲交叉執行而致使數據的不一致。事務隔離分爲不一樣級別,包括讀未提交(Read uncommitted)、讀提交(read committed)、可重複讀(repeatable read)和串行化(Serializable)。
Durability(持久性):事務處理結束後,對數據的修改就是永久的,即使系統故障也不會丟失。
168. char 和 varchar 的區別是什麼?
char(n) :固定長度類型,好比訂閱 char(10),當你輸入"abc"三個字符的時候,它們佔的空間仍是 10 個字節,其餘 7 個是空字節。
char 優勢:效率高;缺點:佔用空間;適用場景:存儲密碼的 md5 值,固定長度的,使用 char 很是合適。
varchar(n) :可變長度,存儲的值是每一個值佔用的字節再加上一個用來記錄其長度的字節的長度。
因此,從空間上考慮 varcahr 比較合適;從效率上考慮 char 比較合適,兩者使用須要權衡。


169. float 和 double 的區別是什麼?
float 最多能夠存儲 8 位的十進制數,並在內存中佔 4 字節。
double 最可能夠存儲 16 位的十進制數,並在內存中佔 8 字節。
170. mysql 的內鏈接、左鏈接、右鏈接有什麼區別?
內鏈接關鍵字:inner join;左鏈接:left join;右鏈接:right join。
內鏈接是把匹配的關聯數據顯示出來;左鏈接是左邊的表所有顯示出來,右邊的表顯示出符合條件的數據;右鏈接正好相反。
171. mysql 索引是怎麼實現的?
索引是知足某種特定查找算法的數據結構,而這些數據結構會以某種方式指向數據,從而實現高效查找數據。
具體來講 MySQL 中的索引,不一樣的數據引擎實現有所不一樣,
但目前主流的數據庫引擎的索引都是 B+ 樹實現的,B+ 樹的搜索效率,(BTree一是平衡樹)
能夠到達二分法的性能,找到數據區域以後就找到了完整的數據結構了,全部索引的性能也是更好的。

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。
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 問題排查都有哪些手段?
使用 show processlist 命令查看當前全部鏈接信息。
使用 explain 命令查詢 SQL 語句執行計劃。
開啓慢查詢日誌,查看慢查詢的 SQL。
178. 如何作 mysql 的性能優化?
爲搜索字段建立索引。
避免使用 select *,列出須要查詢的字段。
垂直分割分表。
選擇正確的存儲引擎。

mysql 分庫分表(水平切割和垂直切割)
分表是分散數據庫壓力的好方法。
分表,最直白的意思,就是將一個表結構分爲多個表,而後,能夠再同一個庫裏,也能夠放到不一樣的庫。
固然,首先要知道什麼狀況下,才須要分表。我的以爲單表記錄條數達到百萬到千萬級別時就要使用分表了。

縱向分表
將原本能夠在同一個表的內容,人爲劃分爲多個表。(所謂的原本,是指按照關係型數據庫的第三範式要求,是應該在同一個表的。)
分表理由:根據數據的活躍度進行分離,(由於不一樣活躍的數據,處理方式是不一樣的)

案例:
對於一個博客系統,文章標題,做者,分類,建立時間等,是變化頻率慢,查詢次數多,並且最好有很好的實時性的數據,咱們把它叫作冷數據。而博客的瀏覽量,回覆數等,相似的統計信息,或者別的變化頻率比較高的數據,咱們把它叫作活躍數據。因此,在進行數據庫結構設計的時候,就應該考慮分表,首先是縱向分表的處理。
這樣縱向分表後:
首先存儲引擎的使用不一樣,冷數據使用MyIsam 能夠有更好的查詢數據。活躍數據,能夠使用Innodb ,能夠有更好的更新速度。
其次,對冷數據進行更多的從庫配置,由於更多的操做時查詢,這樣來加快查詢速度。對熱數據,能夠相對有更多的主庫的橫向分表處理。
其實,對於一些特殊的活躍數據,也能夠考慮使用memcache ,redis
之類的緩存,等累計到必定量再去更新數據庫。或者mongodb 一類的nosql 數據庫,這裏只是舉例,就先不說這個。

橫向分表
字面意思,就能夠看出來,是把大的表結構,橫向切割爲一樣結構的不一樣表,如,用戶信息表,user_1,user_2 等。表結構是徹底同樣,可是,根據某些特定的規則來劃分的表,如根據用戶ID來取模劃分。
分表理由:根據數據量的規模來劃分,保證單表的容量不會太大,從而來保證單表的查詢等處理能力。
案例:同上面的例子,博客系統。當博客的量達到很大時候,就應該採起橫向分割來下降每一個單表的壓力,來提高性能。例如博客的冷數據表,假如分爲100個表,當同時有100萬個用戶在瀏覽時,若是是單表的話,會進行100萬次請求,而如今分表後,就多是每一個表進行1萬個數據的請求(由於,不可能絕對的平均,只是假設),這樣壓力就下降了不少不少。


redis 是什麼?都有哪些使用場景?
Redis是一個開源的使用ANSI C語言編寫、支持網絡、可基於內存亦可持久化的日誌型、Key-Value數據庫,並提供多種語言的API。
Redis 使用場景:
數據高併發的讀寫
海量數據的讀寫
對擴展性要求高的數據
180. redis 有哪些功能?
數據緩存功能
分佈式鎖的功能
支持數據持久化
支持事務
支持消息隊列
181. redis 和 memecache 有什麼區別?
memecached全部的值均是簡單的字符串,redis做爲其替代者,支持更爲豐富的數據類型
redis的速度比memcached快不少
redis能夠持久化其數據

182. redis 爲何是單線程的?
cpu不是Redis的瓶頸,它受內存和帶寬的影響,單線程容易實現。

補充:nginx 和 nodejs 也都是高性能單線程的表明。

183. 什麼是緩存穿透?怎麼解決?
緩存穿透:指查詢一個必定不存在的數據,因爲緩存是不命中時須要從數據庫查詢,查不到數據則不寫入緩存,這將致使這個不存在的數據每次請求都要到數據庫去查詢,形成緩存穿透
解決方案:最簡單粗暴的方法若是一個查詢返回的數據爲空(無論是數據不存在,仍是系統故障),咱們就把這個空結果進行緩存,但它的過時時間會很短,最長不超過五分鐘。

184. redis 支持的數據類型有哪些?
string、list、hash、set、zset。
185. redis 支持的 java 客戶端都有哪些?
Redisson、Jedis、lettuce等等,官方推薦使用Redisson。

186. jedis 和 redisson 有哪些區別?
Jedis是Redis的Java實現的客戶端,其API提供了比較全面的Redis命令的支持。
Redisson實現了分佈式和可擴展的Java數據結構。
和Jedis相比,功能較爲簡單,不支持字符串操做,不支持排序、事務、管道、分區等Redis特性。
Redisson的宗旨是促進使用者對Redis的關注分離,從而讓使用者可以將精力更集中地放在處理業務邏輯上

187. 怎麼保證緩存和數據庫數據的一致性?
合理設置緩存的過時時間。
新增、更改、刪除數據庫操做時同步更新 Redis,能夠使用事物機制來保證數據的一致性。

188. redis 持久化有幾種方式?
RDB(Redis Database):指定的時間間隔能對你的數據進行快照存儲。
AOF(Append Only File):每個收到的寫命令都經過write函數追加到文件中。

189. redis 怎麼實現分佈式鎖?
Redis 分佈式鎖其實就是在系統裏面佔一個「坑」,其餘程序也要佔「坑」的時候,佔用成功了就能夠繼續執行,失敗了就只能放棄或稍後重試。
佔坑通常使用 setnx(set if not exists)指令,只容許被一個程序佔有,使用完調用 del 釋放鎖。

190. redis 分佈式鎖有什麼缺陷?
Redis 分佈式鎖不能解決超時的問題,分佈式鎖有一個超時時間,程序的執行若是超出了鎖的超時時間就會出現問題。

191. redis 如何作內存優化?
儘量使用散列表(hashes),散列表(是說散列表裏面存儲的數少)使用的內存很是小,
因此你應該儘量的將你的數據模型抽象到一個散列表裏面。
好比你的web系統中有一個用戶對象,不要爲這個用戶的名稱,姓氏,郵箱,密碼設置單獨的key,
而是應該把這個用戶的全部信息存儲到一張散列表裏面。

192. redis 淘汰策略有哪些?
1.已設置過時時間的數據集
最近最少使用淘汰策略
將要過時
任意淘汰
2.從數據集
最近最少使用淘汰策略
任意淘汰
禁止驅逐數據
193. redis 常見的性能問題有哪些?該如何解決?
主服務器寫內存快照,會阻塞主線程的工做,當快照比較大時對性能影響是很是大的,會間斷性暫停服務,因此主服務器最好不要寫內存快照。
Redis 主從複製的性能問題,爲了主從複製的速度和鏈接的穩定性,主從庫最好在同一個局域網內。

JVM
1. 說一下 jvm 的主要組成部分?及其做用?
類加載器(ClassLoader)
運行時數據區(Runtime Data Area)
執行引擎(Execution Engine)
本地庫接口(Native Interface)
組件的做用:首先經過類加載器(ClassLoader)會把 Java 代碼轉換成字節碼,運行時數據區(Runtime Data Area)再把字節碼加載到內存中,而字節碼文件只是 JVM 的一套指令集規範,並不能直接交給底層操做系統去執行,所以須要特定的命令解析器執行引擎(Execution Engine),將字節碼翻譯成底層系統指令,再交由 CPU 去執行,而這個過程當中須要調用其餘語言的本地庫接口(Native Interface)來實現整個程序的功能。

195. 說一下 jvm 運行時數據區?
程序計數器
虛擬機棧
本地方法棧

方法區

有的區域隨着虛擬機進程的啓動而存在,有的區域則依賴用戶進程的啓動和結束而建立和銷燬。

196.說一下堆棧的區別?
棧內存存儲的是局部變量而堆內存存儲的是實體;
棧內存的更新速度要快於堆內存,由於局部變量的生命週期很短;
棧內存存放的變量生命週期一旦結束就會被釋放,而堆內存存放的實體會被垃圾回收機制不定時的回收。

197.隊列和棧是什麼?有什麼區別?
隊列和棧都是被用來預存儲數據的。
隊列容許先進先出檢索元素,但也有例外的狀況,Deque 接口容許從兩端檢索元素。
棧和隊列很類似,但它運行對元素進行後進先出進行檢索。

火車過隧道,洗盤子

198. 什麼是雙親委派模型?
雙親委派模型:若是一個類加載器收到了類加載的請求,它首先不會本身去加載這個類,而是把這個請求委派給父類加載器去完成,每一層的類加載器都是如此,這樣全部的加載請求都會被傳送到頂層的啓動類加載器中,只有當父加載沒法完成加載請求(它的搜索範圍中沒找到所需的類)時,子加載器纔會嘗試去加載類。

199. 說一下類加載的執行過程?
加載:根據查找路徑找到相應的 class 文件而後導入;
檢查:檢查加載的 class 文件的正確性;
準備:給類中的靜態變量分配內存空間;
解析:虛擬機將常量池中的符號引用替換成直接引用的過程。符號引用就理解爲一個標示,而在直接引用直接指向內存中的地址;
初始化:對靜態變量和靜態代碼塊執行初始化工做。

200. 怎麼判斷對象是否能夠被回收?
通常有兩種方法來判斷:
引用計數器:爲每一個對象建立一個引用計數,有對象引用時計數器 +1,引用被釋放時計數 -1,當計數器爲 0 時就能夠被回收。它有一個缺點不能解決循環引用的問題;
可達性分析:從 GC Roots 開始向下搜索,搜索所走過的路徑稱爲引用鏈。當一個對象到 GC Roots 沒有任何引用鏈相連時,則證實此對象是能夠被回收的。

201. java 中都有哪些引用類型?
https://blog.csdn.net/sinat_21118695/article/details/82392028
強引用
軟引用
弱引用
虛引用(幽靈引用/幻影引用)

202. 說一下 jvm 有哪些垃圾回收算法?
https://blog.csdn.net/wuzhiwei549/article/details/80563134
標記-清除算法
標記-整理算法
複製算法
分代算法

203. 說一下 jvm 有哪些垃圾回收器?
Serial:最先的單線程串行垃圾回收器。
Serial Old:Serial 垃圾回收器的老年版本,一樣也是單線程的,能夠做爲 CMS 垃圾回收器的備選預案。
ParNew:是 Serial 的多線程版本。
Parallel 和 ParNew 收集器相似是多線程的,但 Parallel 是吞吐量優先的收集器,能夠犧牲等待時間換取系統的吞吐量。
Parallel Old 是 Parallel 老生代版本,Parallel 使用的是複製的內存回收算法,Parallel Old 使用的是標記-整理的內存回收算法。
CMS:一種以得到最短停頓時間爲目標的收集器,很是適用 B/S 系統。
G1:一種兼顧吞吐量和停頓時間的 GC 實現,是 JDK 9 之後的默認 GC 選項。

204. 詳細介紹一下 CMS 垃圾回收器?
CMS 是英文 Concurrent Mark-Sweep 的簡稱,是以犧牲吞吐量爲代價來得到最短回收停頓時間的垃圾回收器。對於要求服務器響應速度的應用上,這種垃圾回收器很是適合。在啓動 JVM 的參數加上「-XX:+UseConcMarkSweepGC」來指定使用 CMS 垃圾回收器。
CMS 使用的是標記-清除的算法實現的,因此在 gc 的時候會產生大量的內存碎片,當剩餘內存不能知足程序運行要求時,系統將會出現 Concurrent Mode Failure,臨時 CMS 會採用 Serial Old 回收器進行垃圾清除,此時的性能將會被下降。

205.新生代垃圾回收器和老生代垃圾回收器都有哪些?有什麼區別?
新生代回收器:Serial、ParNew、Parallel Scavenge
老年代回收器:Serial Old、Parallel Old、CMS
整堆回收器:G1
新生代垃圾回收器通常採用的是複製算法,複製算法的優勢是效率高,缺點是內存利用率低;老年代回收器通常採用的是標記-整理的算法進行垃圾回收。

206. 簡述分代垃圾回收器是怎麼工做的?
分代回收器有兩個分區:老生代和新生代,新生代默認的空間佔比總空間的 1/3,老生代的默認佔比是 2/3。
老生代當空間佔用到達某個值以後就會觸發全局垃圾收回,通常使用標記整理的執行算法。

207. 說一下 jvm 調優的工具?
JDK 自帶了不少監控工具,都位於 JDK 的 bin 目錄下,其中最經常使用的是 jconsole 和 jvisualvm 這兩款視圖監控工具。
jconsole:用於對 JVM 中的內存、線程和類等進行監控;
jvisualvm:JDK 自帶的全能分析工具,能夠分析:內存快照、線程快照、程序死鎖、監控內存的變化、gc 變化等。

208. 經常使用的 jvm 調優的參數都有哪些?
-Xms2g:初始化推大小爲 2g;
-Xmx2g:堆最大內存爲 2g;
-XX:NewRatio=4:設置年輕的和老年代的內存比例爲 1:4;
-XX:SurvivorRatio=8:設置新生代 Eden 和 Survivor 比例爲 8:2;–XX:+UseParNewGC:指定使用 ParNew + Serial Old 垃圾回收器組合;
-XX:+UseParallelOldGC:指定使用 ParNew + ParNew Old 垃圾回收器組合;
-XX:+UseConcMarkSweepGC:指定使用 CMS + Serial Old 垃圾回收器組合;
-XX:+PrintGC:開啓打印 gc 信息;
-XX:+PrintGCDetails:打印 gc 詳細信息。


補充-Springboot+SpringCloud
209.什麼是SpringBoot?
Spring Boot是由Pivotal團隊提供的全新框架,其設計目的是用來簡化新Spring應用的初始搭建以及開發過程。該框架使用了特定的方式來進行配置,從而使開發人員再也不須要定義樣板化的配置。
Spring Boot是Spring開源組織下的子項目,是Spring組件一站式解決方案,主要是簡化了使用Spring的難度,簡省了繁重的配置,提供了各類啓動器,開發者能快速上手。

210.SpringBoot經常使用的starter
一、spring-boot-starter-web(嵌入Tomcat和web開發須要的servlet和jsp支持)
二、spring-boot-starter-data-jpa(數據庫支持)
三、spring-boot-starter-data-Redis(Redis支持)
四、spring-boot-starter-data-solr(solr搜索應用框架支持)
五、mybatis-spring-boot-starter(第三方mybatis集成starter)

211.SpringBoot自動配置原理
一、@EnableAutoConfiguration這個註解會"猜"你將如何配置spring,前提是你已經添加了jar依賴項,若是spring-boot-starter-web已經添加Tomcat和SpringMVC,這個註釋就會自動假設您在開發一個web應用程序並添加相應的spring配置,會自動去maven中讀取每一個starter中的spring.factories文件,該文件裏配置了全部須要被建立spring容器中bean
二、在main方法中加上@SpringBootApplication和@EnableAutoConfiguration

212.SpringBoot starter工做原理
一、SpringBoot在啓動時掃描項目依賴的jar包,尋找包含spring.factories文件的jar
二、根據spring.factories配置加載AutoConfigure
三、根據@Conditional註解的條件,進行自動配置並將bean注入到Spring Context

213.SpringBoot的優勢
一、減小開發、測試時間和努力
二、使用JavaConfig有助於避免使用XML
三、避免大量的maven導入和各類版本衝突
四、提供意見發展方法
五、經過提供默認值快速開始開發
六、沒有單獨的web服務器須要,這就意味着再也不須要啓動Tomcat、Glassfish或其餘任何東西
七、須要更少的配置,由於沒有web.xml文件。只需添加用@Configuration註釋的類,而後添加用@Bean註釋的方法,Spring將自動加載對象並像之前同樣對其進行管理。甚至能夠將@Autowired添加到bean方法中,以使用Spring自動裝入須要的依賴關係中

214.Springcloud解決那些問題
配置管理、(註冊中心eureka、zk)、服務發現、服務註冊、斷路器、路由策略、全局鎖、分佈式會話、客戶端調用、接口網關(zuul)、服務管理系統.

215.SpringBoot與Springcloud
一、SpringBoot簡化了xml配置,快速整合框架
二、Springcloud是一套微服務解決方案—RPC遠程調用
三、關係Springcloud依賴與SpringBoot(web組件用的SpringMVC),爲何Springcloud會依賴與SpringBoot?由於Springcloud寫接口就是SpringMVC接口
四、SpringBootproperties和yml中能夠使用${random}設置一些隨機值

215.服務的調用
restTemplate、feign(均使用httpClient技術),負載均衡ribbon

216.服務調用的原理
服務首先註冊到註冊中心eureka中(註冊一個名字經過名字調用)

217.負載均衡
ribbon,先去註冊中心取到對應的服務,而後交給我ribbon

218.配置詳解
一、eureka.client.register-with-eureka:是否向註冊中心註冊本身,註冊爲true反之爲false
二、eureka.client.fetch-registry:是否須要去檢索服務,檢索爲true反之爲false
三、eureka.client.serviceUrl.defaultZone : 指定服務註冊中心的地址

219.Eureka
一、eureka可分爲三個角色:服務發現者、服務註冊者、註冊發現中心,可是這三個角色並不和實際部署的模型是一對一的關係
二、全部的網絡通訊都是基於http(s)協議的
三、Eureka和AWS是緊密結合的,不管是配置仍是源碼,好比Region、zone…,Region能夠經過配置文件進行配置,若是不配置默認使用us-east-1。一樣Zone也能夠配置,若不配置默認使用defaultZone

220.高可用配置
Eureka server 的高可用實際上就是將本身做爲服務向其餘服務註冊中心註冊本身,這樣就能夠造成一組互相註冊的服務註冊中心,以實現服務清單的互相同步,達到高可用效果。

221.微服務
之前全部的代碼都放在同一個工程中、部署在同一個服務器、同一項目的不一樣模塊不一樣功能互相搶佔資源,微服務就是將工程根據不一樣的業務規則拆分紅微服務,部署在不一樣的服務器上,服務之間相互調用,java中有的微服務有dubbo(只能用來作微服務)、springcloud( 提供了服務的發現、斷路器等)。

222.微服務的特色
按業務劃分爲一個獨立運行的程序,即服務單元
服務之間經過HTTP協議相互通訊
自動化部署
能夠用不一樣的編程語言
能夠用不一樣的存儲技術
服務集中化管理
微服務是一個分佈式系統


223.微服務的優點
一、將一個複雜的業務拆分爲若干小的業務,將複雜的業務簡單化,新人只須要了解他所接管的服務的代碼,減小了新人的學習成本。
二、因爲微服務是分佈式服務,服務於服務之間沒有任何耦合。微服務系統的微服務單元具備很強的橫向拓展能力。
三、服務於服務之間採用HTTP網絡通訊協議來通訊,單個服務內部高度耦合,服務與服務之間徹底獨立,無耦合。這使得微服務能夠採用任何的開發語言和技術來實現,提升開發效率、下降開發成本。
四、微服務是按照業務進行拆分的,並有堅實的服務邊界,若要重寫某一業務代碼,不需瞭解因此業務,重寫簡單。
五、微服務的每一個服務單元是獨立部署的,即獨立運行在某個進程中,微服務的修改和部署對其餘服務沒有影響。
六、微服務在CAP理論中採用的AP架構,具備高可用分區容錯特色。高可用主要體如今系統7x24不間斷服務,他要求系統有大量的服務器集羣,從而提升系統的負載能力。分區容錯也使得系統更加健壯。

224.微服務的不足
一、微服務的複雜度:構建一個微服務比較複雜,服務與服務之間經過HTTP協議或其餘消息傳遞機制通訊,開發者要選出最佳的通訊機制,並解決網絡服務差時帶來的風險。
二、分佈式事物:將事物分紅多階段提交,若是一階段某一節點失敗仍會致使數據不正確。若是事物涉及的節點不少,某一節點的網絡出現異常會致使整個事務處於阻塞狀態,大大下降數據庫的性能。
三、服務劃分:將一個完整的系統拆分紅不少個服務,是一件很是困難的事,由於這涉及了具體的業務場景
四、服務部署:最佳部署容器Docker
微服務和SOA的關係:
微服務相對於和ESB聯繫在一塊兒的SOA輕便敏捷的多,微服務將複雜的業務組件化,也是一種面向服務思想的體現。對於微服務來講,它是SOA的一種體現,可是它比ESB實現的SOA更加輕便、敏捷和簡單。

225.微服務和SOA的關係
微服務相對於和ESB聯繫在一塊兒的SOA輕便敏捷的多,微服務將複雜的業務組件化,也是一種面向服務思想的體現。對於微服務來講,它是SOA的一種體現,可是它比ESB實現的SOA更加輕便、敏捷和簡單。

226.springcloud如何實現服務註冊與發現
服務發佈時指定對應的服務名(IP地址和端口號),將服務註冊到註冊中心(eureka和zookeeper),可是這一切是Springcloud自動實現的,只須要在SpringBoot的啓動類上加上@EnableDisscoveryClient註解,同一服務修改端口就能夠啓動多個實例調用方法:傳遞服務名稱經過註冊中心獲取全部的可用實例,經過負載均衡策略(Ribbon和Feign)調用對應的服務

227.Ribbon和Feign的區別
Ribbon添加的maven依賴是spring-starter-ribbon,使用@RibbonClient(value=「服務名稱」)使用RestTemplate調用遠程服務對應的方法,
Feign添加的maven依賴是spring-starter-feign,服務提供方提供對外接口,調用方使用,在接口上使用FeignClient(「指定服務名」),
具體區別:
一、啓動類使用的註解不一樣,Ribbon使用的是@RibbonClient,Feign使用的是@EnableFeignClients
二、服務的指定位置不一樣,Ribbon是在@RibbonClient註解上聲明,Feign則是在定義抽象方法的接口中使用@FeignClient聲明
三、調用方式不一樣,Ribbon須要本身構建http請求,模擬http請求而後使用RestTemplate發送給其餘服務,步驟比較繁瑣。Feign則是在Ribbon的基礎上進行了一次改進,採用接口調用的方式,將須要調用的其餘服務的方法定義成抽象方法便可,不須要本身構建http請求,不過要注意的是抽象方法的註解、方法簽名要和提供方的徹底一致。


228.雪崩效應
分佈式系統中的服務通訊依賴於網絡,網絡很差,必然會對分佈式系統帶來很大的影響。在分佈式系統中,服務之間相互依賴,若是一個服務之間出現了故障或者網絡延遲,在高併發的狀況下,會致使線程阻塞,在很短的時間內該服務的線程資源會消耗殆盡,最終使得該服務不可用。因爲服務的相互依賴,可能會致使整個系統的不可用,這就是「雪崩效應」。爲了防止此類事件的發生,分佈式系統必然要採起相應的措施,如熔斷機制(Springcloud採用的是Hystrix)

229.熔斷機制
一、當一個服務出現故障時,請求失敗次數超過設定的閥值(默認50)以後,該服務就會開啓熔斷器,以後該服務就不進行任何業務邏輯操做,執行快速失敗,直接返回請求失敗的信息。其餘依賴於該服務的服務就不會由於得不到響應而形成線程阻塞,這是除了該服務和依賴於該服務的部分功能不可用外,其餘功能正常。
二、熔斷器還有一個自我修復機制,當一個服務熔斷後,通過一段時間(5s)半打開熔斷器。半打開的熔斷器會檢查一部分請求(只能有一個請求)是否正常,其餘請求執行快速失敗,檢查的請求若是響應成功,則可判斷該服務正常了,就可關閉該服務的熔斷器,反之則繼續打開熔斷器。這種自我熔斷機制和自我修復機制能夠使程序更加健壯、也能夠爲開發和運維減小不少沒必要要的工做。
三、熔斷組件每每會提供一系列的監控,如:服務可用與否、熔斷器是否被打開、目前的吞吐量、網絡延遲狀態的監控等,從而可讓開發人員和運維人員的瞭解服務的情況。

230.Eureka基礎架構
1>、服務註冊中心:Eureka提供的服務端,提供服務註冊與發現的功能
1>>、失效剔除:對於那些非正常下線的服務實例(內存溢出、網絡故障致使的),服務註冊中心不能收到「服務下線」的請求,爲了將這些沒法提供服務的實例從服務列表中剔除,Eureka Server在啓動的時候會建立一個定時任務,默認每隔一段時間(默認60s)將當前清單中超時(默認90s)沒有續約的服務剔除出去。
2>>、自我保護:Eureka Server 在運行期間,會統計心跳失敗的比例在15分鐘以內是否低於85%,若是出現低於的狀況(生產環境因爲網絡不穩定會致使),Eureka Server會降當前的實例註冊信息保護起來,讓這些實例不過時,儘量保護這些註冊信息,可是在這保護期間內實例出現問題,那麼客戶端就很容易拿到實際上已經不存在的服務實例,會出現調用失敗的狀況,因此客戶端必須有容錯機制,好比能夠使用請求重試、斷路器等機制。
在本地進行開發時能夠使用 eureka.server.enable-self-preseervation=false參數來關閉保護機制,以確保註冊中心能夠將不可用的實例剔除。

2>、服務提供者:提供服務的應用,能夠是SpringBoot應用也能夠是其餘的技術平臺且遵循Eureka通訊機制的應用。他將本身提供的服務註冊到Eureka,以供其餘應用發現,(如:service層)
1>>、服務註冊:服務提供者在啓動的時候會經過發送Rest請求的方式將本身註冊到Eureka Server(服務註冊中心)中,同時帶上自身服務的一些元數據,Eureka Server 接收到這個Rest請求後,將元數據存儲在一個雙層結構Map中,第一層的key是服務名,第二層key是具體服務的實例名
2>>、服務同步:如有兩個或兩個以上的Eureka Server(服務註冊中心)時,他們之間是互相註冊的,當服務提供者發送註冊請求到一個服務註冊中心時,它會將該請求轉發到集羣中相連的其餘註冊中心,從而實現註冊中心間的服務同步,這樣服務提供者的服務信息能夠經過任意一臺服務中心獲取到
3>>、服務續約:在註冊完服務以後,服務提供者會維護一個心跳來持續告訴Eureka Server:「我還活着」,以防止Eureka Server的「剔除任務」將該服務實例從服務列表中排除出去。配置:eureka.instance.lease-renewal-in-seconds=30(續約任務的調用間隔時間,默認30秒,也就是每隔30秒向服務端發送一次心跳,證實本身依然存活),eureka.instance.lease-expiration-duration-in-seconds=90(服務失效時間,默認90秒,也就是告訴服務端,若是90秒以內沒有給你發送心跳就證實我「死」了,將我剔除)

3>、服務消費者:消費者應用從服務註冊中心獲取服務列表,從而使消費者能夠知道去何處調用其所須要的服務,如:Ribbon實現消費方式、Feign實現消費方式
1>>、獲取服務:當啓動服務消費者的時候,它會發送一個Rest請求給註冊中心,獲取上面註冊的服務清單,Eureka Server會維護一份只讀的服務清單來返回給客戶端,而且每三十秒更新一次
2>>、服務調用:在服務消費者獲取到服務清單後,經過服務名能夠得到具體提供服務的實例名和該實例的元信息,採用Ribbon實現負載均衡
3>>、服務下線:當服務實例進行正常的關閉操做時,它會觸發一個服務下線的Rest請求給Eureka Server,告訴服務註冊中心「我要下線了」。服務端接收到請求以後,將該服務狀態設置爲下線,並把下線時間傳播出去。


231.Eureka和zookeeper均可以提供服務註冊與發現的功能,二者的區別
Zookeeper保證了CP(C:一致性,P:分區容錯性),Eureka保證了AP(A:高可用,P:分區容錯)
一、Zookeeper-----當向註冊中心查詢服務列表時,咱們能夠容忍註冊中心返回的是幾分鐘之前的信息,但不能容忍直接down掉不可用的。也就是說服務註冊功能對高可用性要求比較高,可是zk會出現這樣的一種狀況,當master節點由於網絡故障與其餘節點失去聯繫時,剩餘的節點會從新選leader。問題在於,選取leader的時間過長(30~120s),且選取期間zk集羣都不可用,這樣就會致使選取期間註冊服務癱瘓。在雲部署的環境下,因網絡問題使得zk集羣失去master節點是較大機率會發生的事,雖然服務最終恢復,可是漫長的選擇時間致使的註冊長期不可用是不能容忍的
二、Eureka則看明白這一點,所以再設計的優先保證了高可用性。Eureka各個節點都是平等的,幾個節點掛掉不會影響到正常節點的工做,剩餘的節點依然能夠提供註冊和查詢服務。而Eureka的客戶端再向某個Eureka註冊時若是發現鏈接失敗,則會自動切換至其餘節點,只要有一臺Eureka還在,就能保證註冊服務的可用(保證可用性),只不過查到的信息可能不是最新的(不保證一致性)。除此以外Eureka還有一種自我保護機制,若是在15分鐘內超過85%的節點都沒有正常心跳,那麼Eureka就認爲客戶端與註冊中心出現了網絡故障,此時就會出現如下幾種狀況:
1>、Eureka再也不從註冊列表移除由於長時間沒收到心跳而應該過時的服務
2>、Eureka仍然可以接受新服務的註冊和查詢請求,可是不會被同步到其它節點上(保證當前節點可用)
3>、當網絡穩定時,當前實例新的註冊信息會被同步到其它節點中
Eureka還有客戶端緩存功能(Eureka分爲客戶端程序和服務器端程序兩個部分,客戶端程序負責向外提供註冊與發現服務接口)。因此即使Eureka集羣中全部節點都失效,或者發生網絡分隔故障致使客戶端不能訪問任何一臺Eureka服務器;Eureka服務的消費者任然能夠經過Eureka客戶端緩存來獲取全部的服務註冊信息。甚至最極端的環境下,全部正常的Eureka節點都不對請求產生響應也沒有更好的服務器解決方案來解決這種問題時;得益於Eureka的客戶端緩存技術,消費者服務仍然能夠經過Eureka客戶端查詢與獲取註冊服務信息,這點很重要,所以Eureka能夠很好的應對網絡故障致使部分節點失去聯繫的狀況,而不像Zookeeper那樣使整個註冊服務癱瘓。

232.CAP理論
一、Consistency:指數據的強一致性。若是寫入某個數據成功,以後讀取,讀到的都是新寫入的數據;若是寫入失敗,讀到的都不是寫入失敗的數據。
二、Availability:指服務的可用性
三、Partition-tolerance:指分區容錯

233.Ribbon和Nginx的區別
Nginx性能好,但Ribbon能夠剔除不健康節點,Nginx剔除比較麻煩,Ribbon是客戶端負載均衡,Nginx是服務端負載均衡

234.服務註冊與發現
服務註冊就是向服務註冊中心註冊一個服務實例,服務提供者將本身的服務信息(服務名、IP地址等)告知註冊中心。服務發現是服務消費另外一個服務時,註冊中心將服務的實例返回給服務消費者,一個服務既是服務提供者又是服務消費者。
服務註冊中心健康檢查機制,當一個服務實例註冊成功之後,會定時向註冊中心發送一個心跳證實本身可用,若中止發送心跳證實服務不可用將會別剔除。若過段時間繼續想註冊中心提供心跳,將會從新加入服務註冊中心列表中。

235.服務的負載均衡
爲何要用:微服務是將業務代碼拆分爲不少小的服務單元,服務之間的相互調用經過HTTP協議來調用,爲了保證服務的高可用,服務單元每每都是集羣化部署的,那麼消費者該調用那個服務提供者的實例呢?
介紹:服務消費者集成負載均衡組件,該組件會向服務消費者獲取服務註冊列表信息,並隔一段時間從新刷新獲取列表。當服務消費者消費服務時,負載均衡組件獲取服務提供者全部實例的註冊信息,並經過必定的負載均衡策略(能夠本身配置)選擇一個服務提供者實例,向該實例進行服務消費,這樣就實現了負載均衡。



236.Redis集羣搭建的三種方式
https://blog.csdn.net/e3002/article/details/100691472
相關文章
相關標籤/搜索