想要系統和全面的學習一下 Java,畢竟現在在學校也沒有學到啥有用的,那就想說從面試題開始吧,反正不就之後也要找工作。
想要系統和全面的學習一下 Java,畢竟現在在學校也沒有學到啥有用的,那就想說從面試題開始吧,反正不就之後也要找工作。LeetCode 對我來說還是太難了,但以後也一定要開一篇博客來學習 LeetCode 的。現在就從簡單的面試題開始(其實也不簡單。隨便在網上找了一個 Java 最常見的 200+ 面試題來參考,查漏補缺,一道一道的攻克!
Java 基礎#
1.JDK 和 JRE 有什麼區別?#
這個簡單,JDL 是 Java Development Kit Java 開發工具套裝,面向開發人員,包含 JRE 和 Java 工具 (javac 等) 以及 Java 基礎類庫。JRE 是 Java Runtime Environment。Java 運行環境。面向使用 java 的人。包含 jvm java 虛擬機和核心的類庫。
2.== 和 equals 的區別是什麼?#
首先 == 是比較運算符,equals 是 Object 類提供的方法。equals 可以被重寫 override, 也經常被重寫。在沒有被重寫的情況下,== 和 equals 是同等作用。當 equals 被重寫了就要具體分析。原理基本上就是 == 運算符比較的是基本類型的時候比較的是他們的值,引用類型的時候比較的是兩個變量的內存地址。equals 一般比較的內存地址指向的值。不能用於基本類型的比較。比較常見的就是 String 下的 equals 比較的是字符串是否相同。
對於 Integer 和 int 看以下的代碼就能回憶起差別
public static void main(String[] args) {
//-128 ~ +127 之間
Integer a = 5;
int b = 5;
Integer c = new Integer(5);
Integer d = 5;
System.out.println(a.equals(b));
System.out.println(a == b);
System.out.println(a.equals(c));
System.out.println(a == c);
System.out.println(a == d);
//-128 ~ +127 之外
a = 128;
b = 128;
c = new Integer(128);
d = 128;
System.out.println(a.equals(b));
System.out.println(a == b);
System.out.println(a.equals(c));
System.out.println(a == c);
System.out.println(a == d);
}
答案:
//-128 ~ +127 之間
True True True False True
//-128 ~ +127 之外
True True True False False
3. 兩個對象的 hashCode () 相同,則 equals () 也一定為 true,對嗎?#
首先是肯定不一定,因為兩個方法都可以被重寫,完全在於自己。
hashCode () 返回該對象的哈希碼值;equals () 返回兩個對象是否相等。但是對於 hashCode 和 equal 是方法是 Java 官方文檔有一些常規協定的 :
-
1、兩個對象用 equals () 比較返回 true,那麼兩個對象的 hashCode () 方法必須返回相同的結果。
-
2、兩個對象用 equals () 比較返回 false,不要求 hashCode () 方法也一定返回不同的值,但是最好返回不同值,以提高哈希表性能。
-
3、重寫 equals () 方法,必須重寫 hashCode () 方法,以保證 equals 方法相等時兩個對象 hashcode 返回相同的值。
4.final 在 java 中有什麼作用?#
-
修飾類不可以被繼承
-
修飾方法不能被 Override
-
修飾變量就是常量不能被賦值。
修飾基本數據類型數值不可以改變,修改引用數據類型不能改變地址,但是地址指向的數據可以被修改的。final 修飾變量的本質: final 修飾的變量會指向一塊固定的內存,這塊內存中的值不能改變.5.java 中的 Math.round (-1.5) 等於多少?#
答案是 -1, Round 函數是直接加 0.5 然後向下取整 - 1.5+0.5=-1 向下取整為 - 1。
-1.4+0.5=-0.9 向下取整 - 1。-1.6+0.5=-1.1 向下取整為 - 2
6.String 屬於基礎的數據類型嗎?#
明顯不屬於,String 是一個對象,引用類型的。Java 基礎類型只有:
byte -
8 位有符號的,以二進制補碼表示的整數
-
最小是 - 128(-2^7),最大是 127(2^7-1),默認值是 0
-
byte 類型用在大型數組中節約空間,主要代替整數,因為 byte 變量占用的空間只有 int 類型的四分之一
-
例子:byte a = 100,byte b = -50
short -
16 位有符號的,以二進制補碼表示的整數
-
最小值是 - 32768 (-2^15), 最大為 32767(2^15-1)默認值 0
-
short 變量所占空間是 int 的二分之一
-
例子:short s = 1000,short r = -20000
int -
32 位有符號的,以二進制補碼表示的整數
-
最小值為 - 2147483648(-2^31), 最大值為 2147483647(2^31-1)
-
默認值為 0 一般整型默認也為 0
long -
64 位有符號的,以二進制補碼表示的整數
-
最小值為(-2^63),最大值為(2^63-1),默認值為 0L
-
例子: long a = 100000L,Long b = -200000L
-
這種類型主要使用在需要比較大整數的系統上
float -
float 是單精度,32 位,符合 IEEE 754 標準的浮點數
-
float 在儲存大型浮點數組的時候可以節省內存
-
默認值為 0.0f,浮點數不能用來表示精確的值,如貨幣。
-
例子,float f1=0.2f
double -
double 是雙精度,64 位符合 IEEE 754 標準的浮點數
-
浮點數默認為 double,同樣不能表示精確的值
-
默認值為 0.0d
-
例子,double d1=0.2d。
boolean -
boolean 表示 1 位的信息
-
只有兩值,true OR false
-
默認值為 false
-
例子 boolean b = true
char -
char 類型是一個單一的 16 位 Unicode 字符
-
最小值是 \ u0000(就是 0)最大值為 \ uffff (65535)
-
char 可以儲存任何字符。
-
例子,char A=’A’;
以上基本類型信息整理自菜鳥教程7.java 中操作字符串都有哪些類?它們之間有什麼區別?#
三種都是以 char [] 形式保存的字符串。
-
String: 不支持修改,修改相當於重新創建一個對象。
-
StringBuffer:線程安全,多線程使用。沒必要使用。
-
StringBuilder:線程不安全,但是快,單線程使用。
8.String str=”i” 與 String str=new String (“i”) 一樣嗎?#
回到 2 號問題了,equals () 是相等的,但是做 == 運算結果是 false,因為 str=”i” 時 java 虛擬機將”i” 分配到常量池中,常量池中沒有重複元素,如果再有一個變量比如 str2=”i”,則將常量池中的”i” 的地址分配給 str2,沒有就在創建一個,而 new 一個對象則分配到堆內存中,即使值是相同的,但是地址不同。
9. 如何將字符串反轉?#
StringBuffer 和 StringBuilder 的 reverse () 方法。或者轉為 char 陣列做循環。
10.String 類的常用方法都有那些?#
-
int indexOf()
-
int length(String ch)
-
String subString (int beginIndex,int endIndex), 包前不包後
-
String trim()
-
boolean equals()
-
toLowerCase(),toUpperCase()
-
char charAt(int index)
-
String [] split (String regex, int limit) 第一個參數是分割依據,第二個是分割份數。
-
還有很多懶得寫了…. 很少用。
11. 抽象類必須要有抽象方法嗎?#
不是的,被 abstract 修飾的就是抽象類,可以不含有抽象方法,如果含有一個抽象方法就必須是抽象類。就算沒有抽象方法也不能被實例化。
12. 普通類和抽象類有哪些區別?#
普通類可以被實例化,抽象類不可以。抽象類的子類必須實現抽象類的所有抽象方法,除非這個子類也是抽象類。
13. 抽象類能使用 final 修飾嗎?#
absolutely NO ! 被 final 修飾不能被繼承,那抽象類的意思是啥?抽象類不就是要被繼承的嘛… 什麼鬼問題
14. 接口和抽象類有什麼區別?#
接口可以理解為抽象類的抽象,全都是抽象方法。一個類只能繼承一個抽象類,但是可以繼承多個接口。這不就實現多重繼承了麼….
15.java 中 IO 流分為幾種?#
終於到我的知識盲區了。。
輸入流,輸出流 繼續劃分字節流,字符流 續劃分節點流,處理流 -
輸入流
- 輸入字符流 Reader
- 節點流 FileReader,PipedReader,CharArrayReader
- 處理流 BufferedReader,InputStreamReader
- 輸入字節流 InputStream
- 節點流 FileInputSteam,PipedInputStream,ByteArrayInputStream
- 處理流 BufferedInputStream,DataInputStream,ObjectInputStream,SequenceInputStream
- 輸入字符流 Reader
-
輸出流
- 輸出字符流 Writer
- 節點流 FileWriter,PipedWriter,CharArrayWriter
- 處理流 BufferedWriter,OutputStreamWriter,PrintWriter
- 輸出字節流 OutputStream
- 節點流 FileOutputStream,PipedOutputStream,ByteArrayOutputStream
- 處理流 BufferedOutputStream,DataOutputStream,ObjectOutputStream,PrintStream
- 輸出字符流 Writer
16.BIO、NIO、AIO 有什麼區別?#
IO 的方式通常分為幾種,同步阻塞的 BIO、同步非阻塞的 NIO、異步非阻塞的 AIO。
也是盲區~查了資料也不是很懂,需要繼續深入了解一下了。
17.Files 的常用方法都有哪些?#
-
Files.exists () 檢測文件路徑是否存在
-
Files.creatFile () 創建文件
-
Files.ceratDirectory () 創建文件夾
-
Files.delete () 刪除文件
-
Files.copy () 複製文件
-
Files.move () 移動文件
-
Files.size () 查看文件個數
-
Files.read () 讀取文件
-
Files.write () 寫入文件
二、容器#
java 容器都有哪些?#
List、Set、Map,queue,stack;
Collection 和 Collections 有什麼區別?#
Collection 是集合的接口,比如 list,set 等就繼承於他,
Collections 是工具類(sort,addAll,max),創建空集合List、Set、Map 之間的區別是什麼?#
List 是一種有序列表,和數組差不多。按照放入順序存放。
Set 是儲存不重複元素集合,相當於只存 map 中的 key。
Map 是 key-value 鍵值對形式。HashMap 和 Hashtable 有什麼區別?#
HashMap 不同步,線程不安全,但是效率快。發布的晚 1.2 後才有
Hashtable 基本不用了 ,除了 Properties 是從 Hashtable 繼承的。而且沒用駝峰命名 哈哈哈如何決定使用 HashMap 還是 TreeMap?#
不需要對 key 排序用 HashMap, 需要用 TreeMap;
說一下 HashMap 的實現原理?#
HashMap 是數組加鏈表的方式實現的,對 key 進行 hashCode()運算得到一個哈希值和數組的長度做取餘運算的到索引也就是插入數組中的位置,用的是鏈表發處理哈西碰撞,就是遇到同一個索引的時候就看一下 key 值是否相同(equals),如果相同就說明通過 key 值一樣,就替換原來的 value 值。如果不一樣就放到這個鏈表的下一節點。
說一下 HashSet 的實現原理?#
就是對 HashMap 的封裝,放一個不變的 Object 當做 value
ArrayList 和 LinkedList 的區別是什麼?#
ArrayList 底層是數組實現的,LinkedList 是鏈表實現的。所以優缺點也很明顯。ArrayList 查快。LinkedList 增刪快。
如何實現數組和 List 之間的轉換?#
數組轉 List:Arrays.asList ()
List 轉數組: list.toArray ()ArrayList 和 Vector 的區別是什麼?#
Vector 線程安全的 list 基本不用了。
Array 和 ArrayList 有何區別?#
數組是能放基本數據類型和對象類型而且只能放一種,ArrayList 只能放對象類型但不使用泛型可以放多種類型的
ArrayList 是基於動態數組實現的,大小不固定,Array 固定。ArrayList 的擴容機制#
ArrayList 擴容的本質就是計算出新的擴容數組的 size 後實例化,並將原有數組內容複製到新數組中去。
在 Queue 中 poll () 和 remove () 有什麼區別?#
都是刪除並返回隊首元素,remove 要是隊列為空報錯(拋 NoSuchElementException 異常),但是 poll 會返回 false 或 null。
哪些集合類是線程安全的?#
Vector,Hashtable,Stack
迭代器 Iterator 是什麼?#
迭代器,遍歷集合用的工具
Iterator 怎麼使用?有什麼特點?#
next 下一个元素,hasNext 是否有下一个,remove 刪除返回的元素
Iterator 和 ListIterator 有什麼區別?#
Iterator 可以遍歷 set map list ListIterator 只能遍歷 List 但是可以前後遍歷。
怎麼確保一個集合不能被修改?#
Collections.unmodifiableList(List)
三、多線程#
並行和並發有什麼區別?#
-
並行:多個處理器同時處理多個不同的任務。這是物理上的同時發生。
-
並發:一個處理器可以同時處理多個任務。這是邏輯上的同時發生。
eg:並發:一個人同時吃三個蘋果。並行:三個人同時吃三個蘋果。線程和進程的區別?#
進程是一個任務,線程是進程的子任務。操作系統調度的最小任務單位是線程
守護線程是什麼?#
守護線程是指為其他線程服務的線程。在 JVM 中,所有非守護線程都執行完畢後,無論有沒有守護線程,虛擬機都會自動退出。
因此,JVM 退出時,不必關心守護線程是否已結束。創建線程有哪幾種方式?#
- 繼承 Thread 類創建線程類:從 Thread 派生一個自定義類,然後覆寫 run () 方法:
- 通過 Runnable 接口創建線程類:創建 Thread 實例時,傳入一個 Runnable 實例:
- 通過 Callable 和 Future 創建線程:
說一下 runnable 和 callable 有什麼區別?#
1、如上面代碼所示,callable 的核心是 call 方法,允許返回值,runnable 的核心是 run 方法,沒有返回值
-
2、call 方法可以拋出異常,但是 run 方法不行
3、因為 runnable 是 java1.1 就有了,所以他不存在返回值,後期在 java1.5 進行了優化,就出現了 callable,就有了返回值和抛異常
線程有哪些狀態?#
-
New:新創建的線程,尚未執行;
-
Runnable:運行中的線程,正在執行 run () 方法的 Java 代碼;
-
Blocked:運行中的線程,因為某些操作被阻塞而掛起;
-
Waiting:運行中的線程,因為某些操作在等待中;
-
Timed Waiting:運行中的線程,因為執行 sleep () 方法正在計時等待;
-
Terminated:線程已終止,因為 run () 方法執行完畢。
sleep () 和 wait () 有什麼區別?#
notify () 和 notifyAll () 有什麼區別?#
線程的 run () 和 start () 有什麼區別?#
創建線程池有哪幾種方式?#
線程池都有哪些狀態?#
線程池中 submit () 和 execute () 方法有什麼區別?#
在 java 程序中怎麼保證多線程的運行安全?#
多線程鎖的升級原理是什麼?#
什麼是死鎖?#
怎麼防止死鎖?#
ThreadLocal 是什麼?有哪些使用場景?#
說一下 synchronized 底層實現原理?#
synchronized 和 volatile 的區別是什麼?#
synchronized 和 Lock 有什麼區別?#
synchronized 和 ReentrantLock 區別是什麼?#
說一下 atomic 的原理?#
四、反射#
什麼是反射?#
反射就是 Reflection,Java 的反射是指程序在運行期可以拿到一個對象的所有信息。,為了解決在運行期,對某個實例一無所知的情況下,如何調用其方法。Reflection 是 Java 被視為動態(或準動態)語言的一個關鍵性質。這種通過 Class 實例獲取 class 信息的方法稱為反射(Reflection)。
什麼是 java 序列化?什麼情況下需要序列化?#
把對象放到 io 中,實現 serializable 接口
序列化是指把一個 Java 對象變成二進制內容,本質上就是一個 byte [] 陣列。動態代理是什麼?有哪些應用?#
JDK 提供的動態創建接口對象的方式,就叫動態代理。
不編寫實現類,直接在運行期創建某個 interface 的實例
通過 Proxy 創建代理對象,並將接口方法代理給了
InvocationHandler handler,動態代理的應用有 spring aop、hibernate 數據查詢、測試框架的後端 mock、rpc,Java 注解對象獲取等。怎麼實現動態代理?#
- 定義一個 InvocationHandler 實例,它負責實現接口的方法調用;
- 通過 Proxy.newProxyInstance () 創建 interface 實例,它需要 3 個參數:
- 使用的 ClassLoader,通常就是接口類的 ClassLoader;
- 需要實現的接口數組,至少需要傳入一個接口進去;
- 用來處理接口方法調用的 InvocationHandler 實例。
- 將返回的 Object 強制轉型為接口。
五、對象拷貝#
為什麼要使用克隆?#
如何實現對象克隆?#
實現 cloneable 接口,重寫 clone ();
深拷貝和淺拷貝區別是什麼?#
淺拷貝引用對象屬性指向原對象的內存地址;
深拷貝就是完全新的,引用的其他對象也被複製。
六、Java Web#
jsp 和 servlet 有什麼區別?#
jsp 代表的前台頁面,servlet 是服務端和瀏覽器的中間層,運行時 jsp 被 web 容器(tomcat)編譯成 servlet 了。
jsp 有哪些內置對象?作用分別是什麼?#
-
request 用戶端請求,此請求會包含來自 GET/POST 請求的參數
-
response 網頁傳回用戶端的回應
-
pageContext 網頁的屬性是在這裡管理
-
session 與請求有關的會話期
-
application servlet 正在執行的內容
-
out 用來傳送回應的輸出
-
config servlet 的構架部件
-
page JSP 網頁本身
-
exception 針對錯誤網頁,未捕捉的例外
說一下 jsp 的 4 種作用域?#
名稱 作用域 application 所有應用程序有效 session 當前整個會話有效 request 當前請求有效 page 當前頁面有效
session 和 cookie 有什麼區別?#
一般來說,cookie 記錄了 sessionid;session 服務器端,cookie 客戶端
說一下 session 的工作原理?#
當服務器創建完 session 對象後,會把 session 對象的 id 以 cookie 形式返回給客戶端。這樣,當用戶保持當前瀏覽器的情況下再去訪問服務器時,會把 session 的 id 傳給服務器,服務器根據 session 的 id 來為用戶提供相應的服務
如果客戶端禁止 cookie 能實現 session 還能用嗎?#
能,通過 url 傳 sessionid 即可
spring mvc 和 struts 的區別是什麼?#
如何避免 sql 注入?#
使用 PreparedStatement 用?做佔位符,或者使用具名變量的方式。
什麼是 XSS 攻擊,如何避免?#
什麼是 CSRF 攻擊,如何避免?#
七、異常#
throw 和 throws 的區別?#
throws 是方法後面的,表示這個方法可能拋出異常,在調用這個方法的時候就要 try catch 或者拋出異常,throw 是方法內用的一般在 catch 裡寫。
final、finally、finalize 有什麼區別?#
final 形容方法就是不可重寫,形容類不可繼承,形容變量就是常量。
finally 是 try catch 後面的
finalize () 是 object 中的一個方法,當 jvm 判斷一個對象死亡的時候掉他做最後掙扎 (比如重寫了這個方法把它重新引導 gc roots 上 GC 算法就不會回收它了)
try-catch-finally 中哪個部分可以省略?#
catch 和 finally 省略一個。
try-catch-finally 中,如果 catch 中 return 了,finally 還會執行嗎?#
會執行,會在 return 表達式之後執行。對其做改變的話也不變了。
常見的異常類有哪些?#
Error,runtime Exception,Exception 和 throw
八、網絡#
http 響應碼 301 和 302 代表的是什么?有什麼區別?#
301 redirect: 301 代表永久性轉移(Permanently Moved)
302 redirect: 302 代表暫時性轉移(Temporarily Moved )
forward 和 redirect 的區別?#
簡述 tcp 和 udp 的區別?#
TCP:面向連接的,可靠的,也就是不會丟失不會重複,按順序。三次握手。面向字節的
UDP:面向無連接,不可靠的。面向報文的。但是快,可以廣播
tcp 為什麼要三次握手,兩次不行嗎?為什麼?#
不行,兩次只能保證單向連接是通暢的,不能保證雙向都通。
說一下 tcp 粘包是怎麼產生的?#
應用程讀取緩存中的數據包的速度小於接收數據包的速度,緩存中的多個數據包會被應用程序當成一個包一次讀取。
OSI 的七層模型都有哪些?#
應用層
表示層
會話層
傳輸層
網絡層
數據鏈路層
物理層
get 和 post 請求有哪些區別?#
get 是從服務器上獲取數據,post 是向服務器傳送數據。
如何實現跨域?#
說一下 JSONP 實現原理?#
九、設計模式#
說一下你熟悉的設計模式?#
抽象工廠模式
簡單工廠和抽象工廠有什麼區別?#
簡單工廠處理複雜度較小的對象,抽象工廠處理複雜度較大的;
簡單工廠模式就是 實際的工廠 - 抽象類 - 實現不同的產品
抽象工廠就是 抽象工廠 - 不同的工廠 (實現不同產品族的產品)- 不同的產品(繼承於產品的抽象類)
十、Spring/Spring MVC#
為什麼要使用 spring?#
降低開發複雜度,方便集成其他框架,Mybatis,Hibernate,避免重複造輪子,專注於業務邏輯
支持 AOP,面向切面編程,把一些日誌啊,事物啊,安全等等和業務邏輯沒關的但是橫跨多個業務的組件單獨分離出來形成可重複使用的組件
解釋一下什麼是 aop?#
AOP 即 Aspect Oriented Program 面向切面編程
首先,在面向切面編程的思想裡,把功能分為核心業務功能,和周邊功能。
所謂的核心業務,比如登錄,增加數據,刪除數據都叫核心業務
所謂的周邊功能,比如性能統計,日誌,事務管理等等
周邊功能在 Spring 的面向切面編程 AOP 思想裡,即被定義為切面
在面向切面編程 AOP 的思想裡,核心業務功能和切面功能分別獨立進行開發
然後把切面功能和核心業務功能 “編織” 在一起,這就叫 AOP
解釋一下什麼是 ioc?#
控制翻轉
簡單說就是創建對象由以前的程序員自己 new 構造方法來調用,變成了交由 Spring 創建對象
spring 有哪些主要模塊?#
1.Spring Core
框架的最基礎的部分,提供 IOC 容器,對 bean 進行管理
2.Spring Context
基於 bean,提供上下文信息,擴展 JNDI,EJB, 電子郵件,國際化,校驗和調度等功能
3.Spring DAO
提供 JDBC 的抽象層,它可消除冗余的 JDBC 編碼和解析數據庫廠商特有的錯誤代碼,還提供了聲明性事物的管理方法。
4.Spring ORM
提供了 對象 / 關係 映射 APIs 的集成層。其中包括 JPA,JDO,Hibernate,MyBatis 等。
5.Spring AOP
提供了符合 AOP Alliance 規範的面向方面的編程實現
6.Spring Web
提供了基礎的 Web 開發的上下文信息,可與其他的 web 進行集成。
7.Spring MVC
提供了 Web 應用的 Model-View-Controller 全功能實現。
spring 常用的注入方式有哪些?#
構造方法注入,
setter 注入
注解注入
spring 中的 bean 是線程安全的嗎?#
容器本身沒有提供線程安全的策略,也就是不具備線程安全特性,要結合具體的 scope 的 Bean 去分析。
(bean 的作用域 scope:singleton、prototype,request、session、global session)
原型模式 prototype:每次創建一個新對象,各個線程用各個兒的,沒有共享自然沒有線程安全問題。
單例模式 singleton:如果是一個無狀態的 bean,也就是說調用這個 bean 不會改變狀態(字段屬性),那麼就是安全的。只有方法本身,對於有狀態的 bean 最簡單的改為原型模式即可。
Spring 創建的 bean 默認是 singleton 的,線程調用某個 bean 時,是持有一個 bean 對象的副本在自己的空間中,因為代碼執行的速度很快,所以棧幀的生存時間很短,瞬間生滅。所以局部變量無法被外部使用。當你調用這個 bean 對象的全局變量時,就會出現線程安全問題了 (這時候你需要把 bean 定義為 prototype 了)!
spring 支持幾種 bean 的作用域?#
-
singleton 模式:單例模式,在整個 Spring ioc 容器中,使用 singleton 定義的 bean 只有一個實例
-
prototype:原型模式,每次通過容器的 getbean 方法獲取的 prototype 定義的 bean 時都產生一個新的實例
-
只有在 web 應用中使用 Spring 時,request,session,global-session 作用域才有效 *
-
request:對於每次 HTTP 請求,使用 request 定義的 bean 都將產生一個實例,即每次 HTTP 請求都會產生不同的 bean 實例
-
session:同一個 Session 共享一個 bean 實例
-
global-session:同 session 作用域不同的是,所有的 session 共享一個實例
spring 自動裝配 bean 有哪些方式?#
spring 配置文件中 節點的 autowire 參數可以控制 bean 自動裝配的方式
-
default - 默認的方式和 “no” 方式一樣
-
no:默認方式,手動裝配方式,需要通過 設定 bean 的依賴關係
-
byName:根據 bean 的名字進行裝配,當一個 bean 的名稱和其他 bean 的屬性一致,則自動裝配
-
byType:根據 bean 的類型進行裝配,當一個 bean 的屬性類型與其他 bean 的屬性的数据類型一致,則自動裝配
-
constructor:根據構造器進行裝配,與 byType 類似,如果 bean 的構造器有與其他 bean 類型相同的屬性,則進行自動裝配
-
autodetect:如果有默認構造器,則以 constructor 方式進行裝配,否則以 byType 方式進行裝配
spring 事務實現方式有哪些?#
(1)編程式事務管理對基於 POJO 的應用來說是唯一選擇。我們需要在代碼中調用 beginTransaction ()、commit ()、rollback () 等事務管理相關的方法,這就是編程式事務管理。
(2)基於 TransactionProxyFactoryBean 的聲明式事務管理
(3)基於 @Transactional 的聲明式事務管理
(4)基於 Aspectj AOP 配置事務說一下 spring 的事務隔離?#
讀未提交;
讀提交;
可重複讀;
序列化;說一下 spring mvc 運行流程?#
- 用戶發送請求至前端控制器 DispatcherServlet
2.DispatcherServlet 收到請求調用處理器映射器 HandlerMapping。 - 處理器映射器根據請求 url 找到具體的處理器,生成處理器執行鏈 HandlerExecutionChain (包括處理器對象和處理器攔截器) 一並返回給 DispatcherServlet。
4.DispatcherServlet 根據處理器 Handler 獲取處理器適配器 HandlerAdapter 執行 HandlerAdapter 處理一系列的操作,如:參數封裝,數據格式轉換,數據驗證等操作 - 執行處理器 Handler (Controller,也叫頁面控制器)。
6.Handler 執行完成返回 ModelAndView
7.HandlerAdapter 將 Handler 執行結果 ModelAndView 返回到 DispatcherServlet
8.DispatcherServlet 將 ModelAndView 傳給 ViewReslover 視圖解析器
9.ViewReslover 解析後返回具體 View
10.DispatcherServlet 對 View 進行渲染視圖(即將模型數據 model 填充至視圖中)。
11.DispatcherServlet 響應用戶。
自我理解可以描述一下從 V 到 C 到 M 到 C 再到 V 的過程
spring mvc 有哪些組件?#
前端控制器 DispatcherServlet
處理器映射器 HanderMapping
處理器適配器 HaderAdapter
視圖解析器 ViewResolver
異常處理器 HandlerExceptionResolver
視圖組件 View
@RequestMapping 的作用是什麼?#
是一個用來處理請求地址映射的註解,可用於類或者方法上。用於類上,表示類中的所有響應請求的方法都是以該地址作為父路徑。
@Autowired 的作用是什麼?#
自動裝配註解:它可以對類成員變量、方法及構造函數進行標註,讓 spring 完成 bean 自動裝配的工作
十一、Spring Boot/Spring Cloud#
什麼是 spring boot?#
“springboot 就是 Spring 開源框架下的子項目,是 Spring 的一站式解決方案,主要是簡化了 spring 的使用難度,降低了對配置文件的要求,使得開發人員能夠更容易得上手。”
spring boot 就是一個大框架裡面包含了許許多多的東西,其中 spring 就是最核心的內容之一
為什麼要用 spring boot?#
簡化 Spring 的使用難度。集和各種框架,WEB 容器等
spring boot 核心配置文件是什麼?#
application.properties&&bootstrap.properties
application.yml&&bootstrap.yml
bootstrap 配置文件是系統級別的,用來加載外部配置,如配置中心的配置信息,也可以用來定義系統不會變化的屬性. bootstatp 文件的加載先於 application 文件
application 配置文件是應用級別的,是當前應用的配置文件
properties 是 key=value,bootstrap 是 key
spring boot 配置文件有哪幾種類型?它們有什麼區別?#
上個問題
spring boot 有哪些方式可以實現熱部署?#
使用調試模式 Debug 實現熱部署
spring-boot-devtools
Spring Loaded
JRebel
jpa 和 hibernate 有什麼區別?#
Hibernate ORM 是 JPA 規範的一個實現
Java Persistence API
JPA 是一個 Java 編程語言接口規範,它描述了使用標準 JAVA 平台和 JAVA 企業版本的關係型數據的管理。JPA API 是 JAVA 社區專家組關於 JSR220 的一部分,JPA2.0 是 JSR317 專家組的工作。
什麼是 spring cloud?#
Spring Cloud provides tools for developers to quickly build some of the common patterns in distributed systems (e.g. configuration management, service discovery, circuit breakers, intelligent routing, micro-proxy, control bus, one-time tokens, global locks, leadership election, distributed sessions, cluster state). Coordination of distributed systems leads to boiler plate patterns, and using Spring Cloud developers can quickly stand up services and applications that implement those patterns. They will work well in any distributed environment, including the developer’s own laptop, bare metal data centres, and managed platforms such as Cloud Foundry.
根據 Spring Cloud 的官方網站,Spring Cloud 為開發人員提供了快速構建分佈式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智能路由,領導選舉,分佈式會話,集群狀態)分佈式系統間的協作產生了一些樣板性的模式,開發者使用 Spring Cloud 就可以快速地構建基於這些模式的服務和應用。。
spring cloud 斷路器的作用是什麼?#
當一個服務調用另一個服務由於網絡原因或者自身原因出現問題時 調用者就會等待被調用者的響應 當更多的服務請求到這些資源時
導致更多的請求等待 這樣就會發生連鎖效應(雪崩效應) 斷路器就是解決這一問題。
spring cloud 的核心組件有哪些?#
-
服務發現 ——Netflix Eureka
一個 RESTful 服務,用來定位運行在 AWS 地區(Region)中的中間層服務。由兩個組件組成:Eureka 服務器和 Eureka 客戶端。Eureka 服務器用作服務註冊服務器。Eureka 客戶端是一個 java 客戶端,用來簡化與服務器的交互、作為輪詢負載均衡器,並提供服務的故障切換支持。Netflix 在其生產環境中使用的是另外的客戶端,它提供基於流量、資源利用率以及出錯狀態的加權負載均衡。
-
客服端負載均衡 ——Netflix Ribbon
Ribbon 客戶端組件提供一系列完善的配置選項,比如連接超時、重試、重試算法等。Ribbon 內置可插拔、可定制的負載均衡組件。
-
斷路器 ——Netflix Hystrix
斷路器可以防止一個應用程序多次試圖執行一個操作,即很可能失敗,允許它繼續而不等待故障恢復或者浪費 CPU 週期,而它確定該故障是持久的。斷路器模式也使應用程序能夠檢測故障是否已經解決。如果問題似乎已經得到糾正,應用程序可以嘗試調用操作
-
服務網關 ——Netflix Zuul
微服務網關,這個組件是負責網絡路由的。 -
Feign
基於 fegin 的動態代理機制,根據註解和選擇機器,拼接 Url 地址,發起請求,Feign 是一個聲明性的 Web 服務客戶端。它使編寫 Web 服務客戶端變得更容易。feigin 是一種模板化,聲明式的 http 客戶端,feign 可以通過註解綁定到接口上來簡化 Http 請求訪問。與當我們訪問別的服務端口的時候 大部分使用 httpclient 等請求進行調用不同,在 eureka 註冊的服務,我們可以使用 Feign 聲明接口的形式來進行相關服務的調用,並提供了失敗回退(其實是 Hystrix 組件的使用)。Feign 只是個便利的 rest 框架,簡化調用,最後還是通過 ribbon 在註冊服務器中找到服務實例,然後對請求進行分配。
十二、Hibernate#
為什麼要使用 hibernate?#
全自動 orm 框架
什麼是 ORM 框架?#
對象關係映射,將數據庫和代碼的實例聯繫起來
hibernate 中如何在控制台查看打印的 sql 語句?#
hibernate 有幾種查詢方式?#
hibernate 實體類可以被定義為 final 嗎?#
在 hibernate 中使用 Integer 和 int 做映射有什麼區別?#
hibernate 是如何工作的?#
get () 和 load () 的區別?#
說一下 hibernate 的緩存機制?#
hibernate 對象有哪些狀態?#
在 hibernate 中 getCurrentSession 和 openSession 的區別是什麼?#
hibernate 實體類必須要有無參構造函數嗎?為什麼?#
十三、Mybatis#
半自動 orm 框架
mybatis 中 #{} 和 ${} 的區別是什麼?#
#{} 代表的是佔位符?調用 PreparedStatement 的 set 方法來賦值。
${} 字符串替換,就是把 ${} 替換成變量的值。
使用 #{} 可以有效的避免 sql 注入,提高系統安全性,原因在於:預編譯機制,預編譯完成之後,SQL 的結構已經固定,即便用戶輸入非法參數,也不會對 SQL 的結構產生影響,從而避免了潛在的安全風險。mybatis 有幾種分頁方式?#
-
陣列分頁:查詢出所有放到 list 中然後截取 邏輯
-
sql 分頁:limit (); 物理
-
攔截器分頁:實現一個攔截器 物理
-
RowBounds 分頁:數據量小的時候 ;邏輯
RowBounds 是一次性查詢全部結果嗎?為什麼?#
表面上是查出所有,但其實是分次查詢出所有,基於 jdbc 進行的封裝,jdbc 驅動有個參數是 Fetch Size 配置,要查更多的話就調用了 next ();
mybatis 邏輯分頁和物理分頁的區別是什麼?#
邏輯分頁就是查出所有,然後在結果中分割分頁數據;
物理分頁就是查出來就是分好頁的。mybatis 是否支持延遲加載?延遲加載的原理是什麼?#
支持延遲加載,設置 lazyloadingEnable=true 即可開啟。
延遲加載的原理的是調用的時候觸發加載,而不是在初始化的時候就加載信息。 先從單表查詢、需要時再從關聯表去關聯查詢,大大提高數據庫性能。說一下 mybatis 的一级緩存和二級緩存?#
-
一级緩存:基於 PerpetualCache 的 HashMap 本地緩存,他的生命週期和 sqlsesiion 一致,有多個 session 或者分佈式環境中操作數據可能會有髒數據,當 Session flush 或 close 之後,該 Session 中的所有 Cache 就將清空,默認一级緩存是開啟的。
-
二級緩存:也是基於基於 PerpetualCache 的 HashMap 本地緩存,不同之處在於其存儲作用域為 Mapper 級別的,如果多個 sqlsession 要共用緩存就要開啟二級緩存。
-
緩存更新機制:當一個作用域 進行了 CUD 操作後,那麼默認作用域下的 select 都被 clear。
mybatis 和 hibernate 的區別有哪些?#
半 orm 和 完全 orm 框架。
mybatis 自己寫 sql 比較靈活,但是移植性差。 hibernate 可以用第三方的二級緩存。mybatis 有哪些執行器(Executor)?#
-
SimpleExecutor:每執行一次 update 或 select,就開啟一個 Statement 對象,用完立刻關閉 Statement 對象。
-
ReuseExecutor:執行 update 或 select,以 sql 作為 key 查找 Statement 對象,存在就使用,不存在就創建,用完後,不關閉 Statement 對象,而是放置於 Map 內,供下一次使用。簡言之,就是重複使用 Statement 對象。
-
BatchExecutor:批量執行器
mybatis 分頁插件的實現原理是什麼?#
(分頁插件 PageHelper 原理)[https://www.cnblogs.com/dengpengbo/p/10579631.html]
mybatis 如何編寫一個自定義插件?#
MyBatis 自定義插件針對 MyBatis 四大對象(Executor,StatementHandler,ParamentHandler,ResultSetHandler)進行攔截。MyBatis 插件要實現 Interceptor 接口
十四、RabbitMQ#
十五、Kafka#
kafka 可以脫離 zookeeper 單獨使用嗎?為什麼?#
不能,應為 kafka 需要 zookeeper 管理協調 kafka 的節點服務器,kafka 就是基於 zookeeper 協調的分佈式消息系統。
kafka 有幾種數據保留的策略?#
兩種,按照過期時間保留(默認為 7 天)和按照存儲的消息大小(1073741824)保留。
kafka 同時設置了 7 天和 10G 清除數據,到第五天的時候消息達到了 10G,這個時候 kafka 將如何處理?#
執行清除數據,無論哪個條件滿足,都会清除數據
什麼情況會導致 kafka 運行變慢?#
CPU, 性能瓶頸,磁碟讀寫瓶頸,網絡瓶頸。
使用 kafka 集群需要注意什麼?#
集群的數量不是越多越好,最好不要超過 7 個,因為節點越多,消息複製需要的時間就越長,整個群組的吞吐量就越低。 集群數量最好是單數,因為超過一半故障集群就不能用了,設置為單數容錯率更高。
kafka 如何保證數據不丟失#
kafka 可以保證分區消息的順序,同一個分區,先發送到 kafka 分區的消息,會被先消費掉。
kafka 是通過一個集群對外提供服務,只要是集群中多個副本中有一個副本是活躍的,那麼收到的消息就不會丟失。
主要需要保證三個地方數據不丟失
-
保證生產者數據不丟失
kafka 的 acks 機制,生產者客戶端設置 acks 參數為 0,1,all。0 代表生產者發出去就算成功了。1 代表 Partition leader 寫成功就成功了,設置為 all 的話就是還要要求 ISR 裡和 leader 保持同步的那些 partiation 也要寫成功才可以。 -
集群中 broker 數據不丟失
topic 按照 partition 分為不同數據(partition 0 ,partition 1)放在不同的 broker 上,這樣就保證了 topic 數據是分佈式存儲的,對於每一個 partition 都有相應的副本,其中有的是 partition 0 leader,partition 0 follower。顯而易見的是副本的數量不能超過 broker 的數量。 如果 leader 掛了,選一個 follower 當 leader。其中和 leader 保持同步的是 ISR,不保持同步的是 OSR, AR=ISR+OSR; -
消費者數據不丟失
通過 offset commit 機制來保證,kafka 自己記錄了每次消費的 offset 數值,下次繼續消費的時候,會接着上次的 offset 進行消費。消費者消費過程#
同一個消費者組的消費者可以消費同一個 topic 下不同的分區,但是同一個組內的消費者不能消費同一個分區,所以建議消費者組的 consumer 的數量與 partition 的數量一致!
為什麼要使用 KafKa,消息隊列的作用是什麼?#
-
削峰:用戶請求過