這是從網上看到的一套java面試題, 答案只是一個大概, 另外題目質量參差不齊, 斟酌參考(JVM的部分暫時沒有答案)
一、Java 基礎
- JDK 和 JRE 有什麼區別?
答: JDK(Java Development Kit)是java開發工具包, 是針對開發人員提供的一套開發環境, 其中包含了jre(程式執行環境,標準類庫class檔案)以及編譯器javac等一系列工具. JRE(Java Runtime Environment)是Java執行時環境, 針對生產環境釋出, 其中包含了JVM虛擬機器以及標準類庫的class檔案.
另外, JVM(Java Virtual Machine)Java虛擬機器, 將class位元組碼指令翻譯為機器指令, 是跨平臺的核心.
- == 和 equals 的區別是什麼?
答: == 可以用於值型別和物件型別, 可用於判定兩個值是否相等. 當用於引用型別時, 用來判定兩個物件地址, 即是否指向相同的記憶體空間. equals()方法的Object的預設實現使用==比較, 也就是說預設就是比較物件地址是否相等, 但類庫中的很多類, 包括包裝型別, String等均重寫了該方法. equals用來比較物件內容是否相等, 對於自定義型別, 可以重寫此方法實現物件自定義的比較邏輯, 這個邏輯一般要求比較嚴謹複雜,所以同時也要重寫hashCode()方法,畢竟如果能在實現中先使用hashCode比較可能會對效能有積極影響.
- 兩個物件的 hashCode()相同,則 equals()也一定為 true,對嗎?
答: 不對! hashCode()相同, 因為可能存在hash碰撞, 也可能導致不同的物件計算出相同的hash值. 另外, hashCode()和equals()方法都是Object物件的方法, 自定義型別可能會覆蓋也可能不覆蓋這兩個方法, 所以說他們一定為true是不對的. 一般而言, 如果equals()方法返回true, 則hashCode()的值相同, 反之不一定成立.
- final 在 java 中有什麼作用?
答: final 可以修飾域變數, 方法, 類. 修飾的域變數的值不能被重新賦值, 修飾的方法不能在子類中被重寫, 修飾的類不能被繼承. final是保證程式不被惡意篡改的手段.
final經常是static一起使用.
final的優點: 1.提示了效能, jvm和程式會快取變數, 方法是靜態繫結的; 2. 安全地在多執行緒環境下共享變數,沒有多餘開銷;
final變數一般要大寫, 區域性變數需要宣告時就賦值, 但域變數可以在建構函式, 初始化塊兒內賦值.
- java 中的 Math.round(-1.5) 等於多少?
答: 1 就近舍入也叫銀行家舍入. 方法是原值+0.5後下取整.
- String 屬於基礎的資料型別嗎?
答: 不屬於! 基本資料型別只有8種. boolean byte short int long float double char . String是引用型別, 並將其設定為final, String的具體字串值在常量池中存在.
- java 中操作字串都有哪些類?它們之間有什麼區別?
答: 除了基本的String, 還有StringBuidler和StringBuffer. String做字串操作時效率太低, 因為其不可變性, 可能會有大量物件建立而佔用大量記憶體. 而後兩者用來處理字串物件, 不同之處在於StringBuffer時執行緒安全的, StringBuilder為了效率考慮執行緒不安全.
- String str="i"與 String str=new String(“i”)一樣嗎?
答: 不一樣, 字串存在常量池中, 如果常量池中不存在, 則建立; 如果使用new 建立, 則需要在堆上建立String物件, 並在常量池中建立字串"i"(如果不存在的話).
- 如何將字串反轉?
答: 有若干方法, 最簡單的是使用StringBuilder#reverse()方法.
另外還有,(1).二分遞迴;(2),charAt()拼接字串;(3)陣列反轉拼接;(4)陣列字元首尾替換;(5)使用Stack
- String 類的常用方法都有那些?
答:
charAt(); compareTo();compareToIgnoreCase();concat();contains();static copyValueOf();endsWith();equals();equalsIgnoreCase(); static format(); getBytes();getChars(); indexOf(); isEmpty(); lastIndexOf();length();matchs();replace();replaceAll();replaceFirst();spilit();startsWith();subString();toCharArray();toLowerCase();toUpperCase();trim();valueOf();
;
- 抽象類必須要有抽象方法嗎?
答: 抽象類中的抽象方法不是必須的, 但抽象方法一定在抽象類中; 即使沒有抽象方法的抽象類也不能被例項化.
- 普通類和抽象類有哪些區別?
答: (1).抽象類不能被例項化;(2).抽象方法用abstract修飾且沒有實現;(3).有抽象方法的類必須宣告為抽象類;(4).抽象類的子類如果不是抽象類就必須實現抽象方法;(5).抽象方法不能為static;(6).抽象類可以有建構函式;
- 抽象類能使用 final 修飾嗎?
答: 不能! final的類不能被其他類繼承, 而抽象類中的方法必須被子類實現, 本身有衝突. 如果在idea中宣告, 編譯器會報非法組合的修飾符.
- 介面和抽象類有什麼區別?
答: (1).本質上抽象類是類Class,介面是完全不同的一種型別Interface;(2)介面不能有建構函式,抽象類可以有;(3).介面中的方法無修飾符(但其是public),介面中的方法可以被普通方法的修飾符修飾(抽象方法除外,不能是private,static);(4)介面可以被多繼承, 抽象類只能單繼承;(5)介面中的屬性預設是static final的,抽象類可以是任意;(6)1.8之前介面方法必須被實現類實現, 抽象類的抽象方法必須被子類實現,1.8之後介面可以有預設實現了;(7)抽象類可以有main方法,並可以執行;
- java 中 IO 流分為幾種?
答: 位元組流和字元流; 輸入流和輸出流;緩衝流和非緩衝流;
- BIO、NIO、AIO 有什麼區別?
答: BIO:阻塞IO; NIO: new io 又叫非阻塞IO, 多路複用器seletctor; AIO : 非同步IO. 參看:以Java的視角來聊聊BIO、NIO與AIO的區別
BIO 是同步阻塞IO, 讀寫操作由單獨的執行緒完成, 如果出現資源等待則執行緒被阻塞,作業系統級別來說會出現執行緒上下文切換, 導致效能開銷, 所以BIO適合少量讀寫操作, 不適合大量併發操作如web環境.
NIO 是同步非阻塞IO, NIO基於事件驅動, 目的就是解決BIO的高併發問題. NIO採用多路複用機制, 當有流需要讀寫時才使用執行緒處理, 否則不做操作.NIO抽象出Channal和Buffer的概念, 以及Selector, 而不針對Stream直接操作, 而是使用Buffer和Channel, Buffer中使用DirectByteBuffer效能更快, 因為這個類不使用java堆,直接使用系統介面申請記憶體,減少了資料複製轉移等操作的開銷,但也容易導致OOM. Selector多路複用的基礎類, 單執行緒處理多個Channel
AIO 是非同步非阻塞IO, java7釋出. 是在資料準備好之後通知執行緒處理的方式, 而不是NIO的輪訓, AIO是真正的同步, 底層呼叫了系統級別的API實現.
- File的常用方法都有哪些?
答:
canExecute();canRead();canWrite();compareTo();createNewFile();createTempFile();delete();deleteOnExit();equals();getAbsoluteFile();getFreeSpace();getName();getParent();getParentFile();getPath();isAbsolute();isDirectory();isFile();isHidden();lastModified();length();list();listFiles(),listRoots();mkdir();mkdirs();renameTo();setExecutable();setLastModified();setReadable();setWritable();toURI();
二、容器
- java 容器都有哪些?
答:
Array,String
,java.util
包下面的Collection,List,ArrayList,LinkedList,Vector,Stack,Map,HashMap,WeakHashMap,LinkedHashMap,HashTable,TreeTable,Set,HashSet,TreeSet,LinkedSet,Queue,
對應的併發容器類,阻塞容器類.
- Collection 和 Collections 有什麼區別?
答: Collection 是集合介面,提供了對集合物件最基本的通用介面方法. 定義了集合最大化統一操作方式. Collections 是一個工具類, 包含了各種集合操作的靜態方法, 這個類不能例項化, 只是一個工具類, 類似Arrays.
- List、Set、Map 之間的區別是什麼?
答: List是有序集合,元素可以重複, Set的元素不能重複,只允許一個null元素; List和Set都繼承自Collection; Map是鍵值對,鍵可以作為索引來查詢值, 可以有多個null值,但只有一個null鍵.
- HashMap 和 Hashtable 有什麼區別?
答: 簡單的說, HashTable 是執行緒安全的, HashMap 是執行緒不安全的, 也正因為此, HashMap的效率更高. 從內部實現看, HashMap和HashTable實現上幾乎完全相同, 只不過HashTable是用synchronized的. HashTable不允許null做鍵, HashMap允許null做鍵, 但僅允許一個.ConcurrentHashMap是HashTable的替代, 比後者具有更好擴充套件性.
- 如何決定使用 HashMap 還是 TreeMap?
答: 最大的區別是 TreeMap 是有序的, HashMap 並不能保證元素的順序. HashMap 繼承了AbstractMap,TreeMap繼承了SortedMap. HashMap適用於Map中插入,刪除和定位. TreeMap適用於按自然順序和自定義順序遍歷(key).
- 說一下 HashMap 的實現原理?
答: 基於1.8. HashMap的內部實現為一個陣列, 每個元素稱為桶bucket, 每個元素為Node, 包含key, value, Node型別的next, 還有個hash值. HashMap的初始容量是16, 預設填充因子是0.75, 當容量不夠時其擴容按N*2擴容. 當桶中元素不大於8時資料結構是個列表, 當大於是轉化為紅黑樹, 當紅黑樹元素小於6時退化為列表.
hash的方法和定位, 先對hash值計算, 方法是高16位與低16位異或運算, 然後用容量n-1與hash結果與運算, 算出下標.
resize 的處理, 因為容量都是2的N次冪, 所以調整size的時候可以原位不變, 在高位填充隨機的0或1. 即移動一個2次冪的位置. resize可以均勻的把衝突的節點分佈到新的桶中了.
- 說一下 HashSet 的實現原理?
答: HashSet 基於 HashMap實現. 但僅僅使用key來實現各種特性. 內部定義了一個假值用來操作.
- ArrayList 和 LinkedList 的區別是什麼?
答: ArrayList隨機訪問比較高效, LinkedList更適合做增加刪除修改操作. 分開來說, ArrayList是以陣列的方式實現, 能通過索引快速定位. LinkedList是連結串列, 每個元素儲存了前一節點和後一節點的引用.
- 如何實現陣列和 List 之間的轉換?
答: List#toArray()方法將List轉為陣列, new ArrayList(Arrays.asList()) 方法將陣列轉為List.
- ArrayList 和 Vector 的區別是什麼?
答: 都基於陣列實現, Vector出現較早,提供了執行緒安全性, ArrayList效率更高. Vector預設增長為原容量2倍, ArrayList預設增長為原容量1.5倍+1.
- Array 和 ArrayList 有何區別?
答: Array是陣列, ArrayList是列表實現了List介面. ArrayList可以動態擴容, Array的容量是固定的.
- 在 Queue 中 poll()和 remove()有什麼區別?
答: 當佇列為空時poll()會返回null, remove()則丟擲異常.
- 哪些集合類是執行緒安全的?
答: HashTable, Vector,Stack, concurrent包下面的集合類, ConcurrentHashMap,ConcurrentSkipListMap、ConcurrentSkipListSet、ConcurrentLinkedQueue、ConcurrentLinkedDeque等, CopyOnWriteArrayList, CopyOnWriteArraySet.
- 迭代器 Iterator 是什麼?
答: Iterator是個介面, 實現了該介面的類一般是集合類, 能夠遍歷集合中的元素. 迭代器是一種設計模式. Java中的Iterator只能單向移動, 包含的方法next(),hasNext(),remove(). 迭代器取代了原來的Enumeration介面.
- Iterator 怎麼使用?有什麼特點?
答:
while(iterator.hasNext()){...}
Iterator的特點是更加安全, 因為它可以確保在遍歷的集合元素被修改後丟擲ConcurrentModiicationException
- Iterator 和 ListIterator 有什麼區別?
答: ListIterator 擴充套件了 Iterator. 當然Iterator有的功能ListIterator就有. 但ListIterator新增了一些額外的功能, 比如新增,替換獲取前面或後面元素的索引位置. 另外, ListIterator是雙向的.
- 怎麼確保一個集合不能被修改?
答: 可以使用Collections類的靜態方法unmodifiableCollection()方法建立只讀集合. 任何改變集合的操作都將丟擲
java.lang.UnsupportedOperationException
三、多執行緒
- 並行和併發有什麼區別?
答: 並行是針對多核CPU的, 指多個任務可以同時分別在各自CPU上執行; 併發是指多個執行緒爭奪同一個CPU資源(時間片), 存在上下文切換. CPU一個時間點只能處理一個任務.
- 執行緒和程式的區別?
答: 執行緒是系統排程資源的最小單位, 程式是系統分配資源的最小單位, 一個程式包含至少一個程式, 一個程式包含至少一個執行緒.
- 守護執行緒是什麼?
答: 守護執行緒是針對使用者執行緒的, 使用者執行緒是程式啟動的執行緒, 守護執行緒一般是有JVM啟動, 但也不一定. 對於任何執行緒, 均可以在啟動前呼叫setDeamon(true)方法設定為守護執行緒.
- 建立執行緒有哪幾種方式?
答: Thread, Runnable, Callable
- 說一下 runnable 和 callable 有什麼區別?
答: callable有返回值, runnable沒有.
- 執行緒有哪些狀態?
答: NEW, RUNABLE, TERMINATED, BLOCKED, WAITING,TIMED_WAITING
- sleep() 和 wait() 有什麼區別?
答: (1).sleep()是執行緒方法,wait()是Object的方法;(2)sleep()超時後會繼續執行, wait()需要notify()或notifyAll()喚醒;(3)sleep()不放棄物件鎖,wait()會釋放物件鎖.
- notify()和 notifyAll()有什麼區別?
答: nodify()喚醒一個等待鎖的執行緒, 由JVM決定是哪個, nodifyAll()會通知所有等待鎖的執行緒, 這些執行緒會爭奪物件鎖, 搶到的持有鎖並繼續執行, 其他的繼續等待通知.
- 執行緒的 run()和 start()有什麼區別?
答: run()定義了執行緒執行的邏輯, start()方法用來啟動執行緒.run()可以執行多次.
- 建立執行緒池有哪幾種方式?
答:
java.util.concurrent.Executors
方法下的幾個靜態建立執行緒池的方法,newFixedThreadPool(), newWorkStealingPool(),newSingleThreadExecutor(),newCachedThreadPool(),newSingleThreadScheduledExecutor(),newScheduledThreadPool()
public ThreadPoolExecutor(int corePoolSize, //核心執行緒數
int maximumPoolSize, //最大執行緒數, 當核心執行緒達到最大, 且佇列滿之後新入隊的元素將開啟更多執行緒, 總數最大不超過這個值
long keepAliveTime, // 執行緒存活時間, 指核心執行緒外的執行緒
TimeUnit unit, //時間單位
BlockingQueue<Runnable> workQueue //執行緒佇列, 只有通過execute()方法呼叫的才會進入
) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
newSingleThreadExecutor()
corePoolSize=1 , maximumPoolSize=1 , keepAliveTime=0 , workQueue使用LinkedBlockingQueue
newCachedThreadPool()
corePoolSize=0 , maximumPoolSize=Integer.MAX_VALUE , keepAliveTime=60 , TimeUnit=SECONDS , workQueue使用 SynchronousQueue ; 同步佇列, 來即處理
newFixedThreadPool()
corePoolSize=maximumPoolSize=傳入的引數 , keepAliveTime=0 , workQueue使用 LinkedBlockingQueue ;
newWorkStealingPool()
使用ForkJoinPool
例項, 並行佇列,since 1.8
- 執行緒池都有哪些狀態?
答: RUNNING(正在執行), STOP(不接受新任務, 不再處理佇列中的任務, 中斷正在執行的執行緒), SHUTDOWN(不接受新任務, 但繼續佇列中的任務),TIDYING(所有任務均銷燬了, workcount=0, 執行緒池轉為此狀態時會啟動鉤子方法terminated),TERMINATED(teminated()執行結束)
RUNNING -> SHUTDOWN :
shutdown()
, 或者隱式在finalize()
(RUNNING or SHUTDOWN) -> STOP :shutdownNow()
SHUTDOWN -> TIDYING : 佇列和池均為空
STOP -> TIDYING : 池為空
TIDYING -> TERMINATED :terminated()
執行完
- 執行緒池中 submit()和 execute()方法有什麼區別?
答: execute()方法用來執行
Runnable
介面型別的任務, submit()可以接受Runnable
也可以接受Callable
.
- 在 java 程式中怎麼保證多執行緒的執行安全?
答: 使用鎖
Lock
, 以及執行緒安全的類java.util.concurrent
, 程式碼同步關鍵字synchronized
等
- 多執行緒鎖synchronized的升級原理是什麼?
答: synchronized是重量級鎖, 如果資源被佔用則當前執行緒進入阻塞佇列, 清空快取, 但很多時候剛剛掛起資源就釋放了, 也就是說資源徵用其實沒有想象的那麼頻繁, 一般資源總會被同一個執行緒佔用. 從1.6開始對其優化, 分為三種級別, 偏向鎖,輕量級鎖,重量級鎖. 參考Java併發——Synchronized關鍵字和鎖升級,詳細分析偏向鎖和輕量級鎖的升級
偏向鎖, 在物件頭設定標識位和threadid, 偏向鎖不會主動釋放鎖, 如果同一執行緒再次獲取, 則比較threadid, 相同則無需cas加鎖解鎖, 如果不一致則檢視物件頭中儲存的執行緒是否存活, 不存活則當前執行緒設定為偏向鎖, 存活則表明有多於一個執行緒競爭鎖, 此時鎖可能升級為輕量級鎖.
輕量級鎖: 對於多個執行緒爭用鎖, 但執行緒持有鎖時間不長的情景. 使用自旋一定次數來等待鎖釋放. 從而減少阻塞.
重量級鎖: 對於自旋一定時間的執行緒, 超出限制後鎖可能膨脹為重量級鎖, 由作業系統排程管理. 重量級鎖會阻塞執行緒, 防止CPU空轉.
鎖升級後不再降級, 但偏向鎖可以被重置為無鎖狀態.
- 什麼是死鎖?
答: 多個執行緒間互相等待對方釋放自己所需資源(鎖)的情況, 迴圈等待導致執行緒阻塞.
- 怎麼防止死鎖?
答: (1). 順序執行; (2).檢測死鎖; (3). 減小鎖粒度; (4).設定鎖超時時間
- ThreadLocal 是什麼?有哪些使用場景?
答: 執行緒本地變數, 為每個執行緒提供獨立的變數副本, 本執行緒修改的值不會影響到其他執行緒的同名變數.
如資料庫連結, session
- 說一下 synchronized 底層實現原理?
答: synchronized可以修飾程式碼塊, 方法, 靜態方法. 這三種情況實現不同. 對於程式碼塊, 在塊的開始和結束的地方虛擬機器分別會插入monitorenter和monitorexit指令, 必須成對出現, monitor是實現鎖的機制, 一個執行緒持有monitor, 其他執行緒就被掛起了. 對於方法, 虛擬機器會在方法表中為其設定access_flag狀態.
- synchronized 和 volatile 的區別是什麼?
答: synchronized用於方法和程式碼塊, volatile用於變數. valatile解決了變數在多執行緒環境下的可見性.synchronized解決了對臨界資源的訪問控制. volatile並不能保證原子性,synchronized能保證原子性; volatile不阻塞執行緒,synchronized會導致執行緒阻塞.volatile會防止指令重排.volatile效率更高.
- synchronized 和 Lock 有什麼區別?
答: synchronized是關鍵字, 封裝了java對鎖的實現. Lock是jdk提供的, 包含一系列預定義的類. synchronized內部實現加鎖解鎖, 異常時釋放鎖, Lock需要程式碼中呼叫相關方法, 不解鎖就不會釋放. Lock抽象可以讓程式設計師對鎖有更精細控制以及定製操作.
- synchronized 和 ReentrantLock 區別是什麼?
答: 參看54, 另外,ReentrantLock可以設定超時, 可被中斷.
- 說一下 atomic 的原理?
答: 其內部實現不是簡單的使用synchronized,而是一個更為高效的方式CAS (compare and swap) + volatile和native方法,從而避免了synchronized的高開銷,執行效率大為提升. 核心是
UnSafe
類, 直接通過作業系統API操作. atomic並非無阻塞, 而是阻塞不在程式,執行緒級別, 而是在底層上面.
四、反射
- 什麼是反射?
答: 反射是在程式執行時能夠動態獲取和操作物件的能力.
- 什麼是 java 序列化?什麼情況下需要序列化?
答: 序列化就是將物件轉化為能夠進行網路傳輸或儲存的資料格式. java的序列化需要物件實現serializable介面.
儲存物件檔案; 網路傳輸; 遠端方法呼叫.
- 動態代理是什麼?有哪些應用?
答: 動態代理是在執行時生成代理類. 比如原生的基於介面的代理或CGLib實現Spring 的AOP機制.
- 怎麼實現動態代理?
答: 基於java原生的介面方式的代理; 使用CGLib庫實現的基於類繼承的代理.
五、物件拷貝
- 為什麼要使用克隆?
答: 克隆是Java對原型模式的實現, 克隆省去了new的開銷, 同時可以儲存物件的狀態.
- 如何實現物件克隆?
答: (1).實現Cloneable介面並重寫clone()方法; (2).使用序列化反序列化實現克隆
- 深拷貝和淺拷貝區別是什麼?
答: 這就得區分java物件在記憶體中的儲存方式, 淺拷貝對於值型別,直接複製內容, 但對於引用型別, 只是複製了一份對真實物件的引用. 深拷貝就是需要將引用型別的變數內容也同時複製, 從而生成一個完全不同的物件.
六、Java Web
- jsp 和 servlet 有什麼區別?
答: jsp:java server page. 與asp,asp.net等一樣,是java生態的服務端動態頁面技術. servlet : server端小程式, 重在控制.事實上jsp就是在servlet基礎上實現的, 但更著重前端頁面.
- jsp 有哪些內建物件?作用分別是什麼?
答: request: 封裝客戶端請求, 可以接收引數; respose: 封裝服務端響應; pageContext: 頁面上下文; session: 會話資訊; application: 應用級別的物件; out: 服務端輸出流物件; config: 配置物件; page: JSP頁面; exception: 封裝頁面丟擲的異常.
- 說一下 jsp 的 4 種作用域?
答: (1).page : 本頁面相關的物件; (2). session: 代表一次會話作用域內的; (3).application: 應用程式級別的, 作用域最廣, 全域性, (4).request : 一次請求內
- session 和 cookie 有什麼區別?
答: session是服務端物件, cookie是儲存在客戶端瀏覽器特定目錄的; session理論上沒有容量限制,cookie不能太大, 也有個數限制; session更為安全, cookie有偽造的風險;session一般儲存在記憶體, 或記憶體資料庫中, 也可以存在關聯式資料庫;
- 說一下 session 的工作原理?
答: 使用者初次登陸網站後, 服務端會給客戶端響應新增session id, 之後客戶端每次請求均帶有這個id, 服務端獲取後通過此id找到對應的session物件.
- 如果客戶端禁止 cookie 能實現 session 還能用嗎?
答: 可以, session id 可能以請求引數或header之類的方式請求到客戶端.
- spring mvc 和 struts 的區別是什麼?
答: (不瞭解struts) 下面是搜尋到的答案.
(1). 攔截級別, struts是類級別的攔截, spring是方法級別攔截;(2). 資料獨立性: Spring mvc 方法之間基本獨立, 獨享request,response資料, 請求通過引數獲取, 返回ModelMap,方法之間不共享變數;struts2方法之間也獨立, 但所有action變數是共享的, 編碼和閱讀程式碼不友好.(3). 攔截機制, spring mvc 用的獨立的aop方式;struts2有自己框架的攔截機制;(4)對ajax的支援: spring mvc 更方便, 使用@ResponseBody註解可實現; struts2需要外掛或自定義;
- 如何避免 sql 注入?
答: PreparedStatement, 關鍵字或符號轉義, 過濾特殊字元
- 什麼是 XSS 攻擊,如何避免?
答: XSS: 跨站指令碼攻擊, 是攻擊者在web頁面植入js程式碼, 等頁面被瀏覽後程式碼執行從而達到攻擊目的. 避免方法是對使用者輸入的內容進行編碼, 過濾js等關鍵字.
- 什麼是 CSRF 攻擊,如何避免?
答: 跨站請求偽造, 是攻擊者盜用別人身份併傳送惡意請求進行欺騙的手段. 避免方法是: 驗證請求來源, 只接受同源的請求; 新增驗證碼; 使用token驗證.
七、異常
- throw 和 throws 的區別?
答: throw 是丟擲異常的關鍵字, 後面是一個異常例項;throws是表示方法可能會丟擲的異常, 後面是異常的類名, 用來方法前面上面.
- final、finally、finalize 有什麼區別?
答: final修飾變數, 方法, 類. 被修飾的表明不能被修改,重寫或繼承;finally是異常處理塊, 其中的程式碼必然執行;finalize是類的析構方法, 一般不需自己定義.
- try-catch-finally 中哪個部分可以省略?
答: try與其他二者之一必須成對存在.
- try-catch-finally 中,如果 catch 中 return 了,finally 還會執行嗎?
答: 會執行, finally中的程式碼不管什麼情況下, 必然會執行.
- 常見的異常類有哪些?
答: NullPointerException, ClassNotFoundException,IOExcption,IndexOutOfBoundsException,ClassCastException,NoSuchMethodException...
八、網路
- http 響應碼 301 和 302 代表的是什麼?有什麼區別?
答: 3XX 是跳轉響應碼. 301時永久跳轉, 對SEO友好, 302時臨時跳轉,可能會被攔截.
- forward 和 redirect 的區別?
答: forward會帶有原頁面請求, redirect相當於重新開啟一個頁面; redirect的位址列會變, forward則不會; forward效率要高點.
- 簡述 tcp 和 udp的區別?
答: 都是傳輸層協議.
tcp面向連結, udp非連結即可傳送資料; tcp提供可靠的資料傳輸,udp無法保證; tcp面向位元組流, udp面向報文; tcp傳輸效率低, udp傳輸快;
- tcp 為什麼要三次握手,兩次不行嗎?為什麼?
答: 兩次握手的話, 服務端發出確認訊號, 但客戶端未必會響應, 而此時連線以及建立, 但客戶端並不是真的需要服務端, 這就造成了資源浪費.
- 說一下 tcp 粘包是怎麼產生的?
答: 傳送端: 傳送端需要等緩衝區滿才傳送, 造成粘包; 接受端: 接受端不及時接受緩衝區的包, 造成多個包接受.
- OSI 的七層模型都有哪些?
答: 物理層, 資料鏈路層,網路層, 傳輸層,會話層,表現層,應用層.
- get 和 post 請求有哪些區別?
答: post比get更安全; get有限制, post沒限制; get位址列顯式, 可收藏;post不行.get 可快取;
- 如何實現跨域?
答: 反向代理如njinx; 服務端設定CORS為*; 單個介面設定@CrossOrigin; 使用jsonp;
- 說一下 JSONP 實現原理?
答: Json with Padding, 利用scrpt的src可以訪問不同源的特性, 載入遠端返回的js函式來執行.
九、設計模式
- 說一下你熟悉的設計模式?
答: 單例模式: 類自己管理自身的例項化, 節省資源; 工廠模式, 觀察者模式;代理模式, 模版方法, 策略模式, 生成器模式.
- 工廠方法和抽象工廠有什麼區別?
答: 抽象工廠用來生成一系列產品族, 工廠方法指示生成一種產品, 他們都支援增加產品. 簡單工廠更像是一種程式設計習慣, 用來管理產品的生成.
十、Spring/Spring MVC
- 為什麼要使用 spring?
答: Spring流行,生態完善, 特別是spring boot, spring cload簡化了開發和部署; spring 是各種框架的粘合劑; spring將設計儘量延遲, 開發者可以儘量晚地做決定, 比如修改配置即可替換某個類; Spring 容器更容易管理依賴; aop技術可以抽離切面; spring提供事務支援.
- 解釋一下什麼是 aop?
答: 面向切面程式設計, 通過java原生或cglib增強來實現. aop可以將一部分如事務, 日誌, 異常等統一的功能抽離, 統一維護.
- 解釋一下什麼是 ioc?
答: ioc是控制反轉, 是將原來類自身管理它依賴的方式替換為由容器統一管理, 這就將依賴做到很大程度解耦.
- spring 有哪些主要模組?
答: spring core 提供ioc; spring context ; dao, aop, web, mvc等.
- spring 常用的注入方式有哪些?
答: setter注入, 建構函式注入. 另外還有程式設計注入, 但這方式太原始, 並不只是spring的, 只能說它只是達成注入的一種方式.
- spring 中的 bean 是執行緒安全的嗎?
答: 預設的bean是單例的, spring 並不能保證bean的執行緒安全.
spring的bean大多是無狀態的, 所以大多情況下不存線上程不安全的問題. 但如果需要保持有狀態的bean, 就必須使用其他作業域了. 如prototype.
- spring 支援幾種 bean 的作用域?
答: 六種: singleton, prototype, session, request,application, websocket. 後面四種僅僅在web環境下.
- spring 自動裝配 bean 有哪些方式?
答: 四種方式, no 不使用, 通過ref等方式來完成; bytype 通過型別, byname 通過名字, constructor: 類似bytype只是應用於建構函式引數. bytype和byname可以組裝陣列.
- spring 事務實現方式有哪些? (垃圾問題)
答: 使用@Transaction的宣告式事務, 或編碼實現.
- 說一下 spring 的事務隔離?
答: 事務隔離機制: 未提交讀,提交讀,可重複讀, 序列化; spring的事務隔離與資料庫相同, 但還有個預設方式, 即使用資料庫使用的隔離級別.
- 說一下 spring mvc 執行流程?
答: 請求-> DispatcherServlet-> handlermaping-> handler(controller action)-> modelAndView-> viewResolver->view
- spring mvc 有哪些元件?
答: DispatcherServlet, HandlerMapping, ViewResolver, Controller, ModelAndView,LocaleResolver等.
- @RequestMapping 的作用是什麼?
答: 請求對映, 就是將http請求的特定url到特定的handler上.
- @Autowired 的作用是什麼?
答: 自動裝配, 使用該註解的欄位,方法,建構函式自動完成依賴注入. 減少了配置.
十一、Spring Boot/Spring Cloud
- 什麼是 spring boot?
答: Spring boot 是為了簡化Spring開發的, 簡化了spring程式的初始搭建和開發部署, 提供了開箱即用的開發體驗和一套非功能性元件, 可以做到幾乎沒有配置.
- 為什麼要用 spring boot?
答: 配置簡單; 獨立執行,有內建的web容器; 自動配置,極少的xml配置檔案; 快速搭建和部署;
- spring boot 核心配置檔案是什麼?
答: bootstrap.XX 和 application.XX
- spring boot 配置檔案有哪幾種型別?它們有什麼區別?
答: properties 和 yml 兩種格式的配置檔案, yml語法更嚴格, 可以減少錯誤, 但缺乏自由度, yml配置看起來有層次, 兩種方式各有優劣. yml不支援@PropertySource. 可以通過實現
PropertySourceFactory
介面來實現.
- spring boot 有哪些方式可以實現熱部署?
答: 開發時使用devtools, 配置中新增spring.devtools.restart.enabled=true; idea中配置自動編譯.
- jpa 和 hibernate 有什麼區別?
答: jpa時規範, java persistence api. hibernate是框架, 基於jpa實現.
- 什麼是 spring cloud?
答: 基於spring boot 實現的一系列框架的合集. 提供了分散式系統中非功能性的基礎實現, 如配置註冊中心, 路由, 熔斷, 負載均衡, 監控等. 只需要極少配置即可使用.
- spring cloud 斷路器的作用是什麼?
答: 當分散式架構中的服務單元發生故障時或其他原因如流量過載等原因時, 斷路器會根據設定的閥值判定正常服務或快速返回錯誤, 這樣可以防止服務長時間的等待, 從而防止故障蔓延.
- spring cloud 的核心元件有哪些?
答: Eureka, Feign, Ribbon, Hystrix,Zuul.
十二、Hibernate
- 為什麼要使用 hibernate?
答: hibernate是對jdbc的封裝, 簡化了訪問資料庫的重複程式碼; hibernate提供ORM實現, 簡化了DAO層的編碼; 具有資料庫可移植性; 快取提升了效率.
- 什麼是 ORM 框架?
答: Object Relation Mapping, 是將關聯式資料庫的表或檢視等對映為程式中的物件. 這樣可以簡化開發.
- hibernate 中如何在控制檯檢視列印的 sql 語句?
答: hibernate.show_SQL=true
- hibernate 有幾種查詢方式?
答: 原生SQL, HQL, 條件查詢Criteria.
- hibernate 實體類可以被定義為 final 嗎?
答: 可以, 但final的不能被繼承, 也就不能使用代理模式實現延遲關聯來提升效能了.
- 在 hibernate 中使用 Integer 和 int 做對映有什麼區別?
答: 物件和值, Integer可以為null.
- hibernate 是如何工作的?
答: 讀取解析配置檔案, 建立SessionFacotry, 開啟Session, 建立事務, 操作, 提交事務, 關閉Session, 關閉SessionFactory.
- get()和 load()的區別?
答: load()支援延遲載入, get()不支援; 沒有OID指定的物件, get()返回null, load返回代理物件.
- 說一下 hibernate 的快取機制?
答: 分為一級快取和二級快取; 一級快取是Session快取, Session作用域有效. 二級快取是application快取, 全域性有效, 並支援三方快取.
- hibernate 物件有哪些狀態?
答: 臨時狀態(不受Session管理), 持久化狀態(持久化到資料庫中的), 遊離狀態(Session關閉後的物件).
- 在 hibernate 中 getCurrentSession 和 openSession 的區別是什麼?
答: getCurrentSession() 繫結當前執行緒, openSession()不會; getCurrentSession()受事務管理, openSession()需要手動管理事務.
- hibernate 實體類必須要有無參建構函式嗎?為什麼?
答: 是的, hibernate使用反射例項化實體. 沒有無參構造會報異常.
十三、Mybatis
- mybatis 中 #{}和 ${}的區別是什麼?
答: #{} 是預編譯處理, ${}是字元替換. 使用#{}時, Mybatis會將其替換為?, 這樣可以防止SQL隱碼攻擊, 保證程式安全.
- mybatis 有幾種分頁方式?
答: 物理分頁和邏輯分頁. RowBounds使用邏輯分頁. 分頁外掛PageHelper或自定義分頁使用物理分頁.
- RowBounds 是一次性查詢全部結果嗎?為什麼?
答: 也不是, jdbc有個Fetch Size的設定, 只有當需要更多資料時, 它才會從資料庫查詢更多資料.
- mybatis 邏輯分頁和物理分頁的區別是什麼?
答: 邏輯分頁時在記憶體中進行, 一次查詢出很多資料, 在記憶體進行分頁, 這種方式佔用大量記憶體, 可能導致記憶體溢位; 物理分頁是直接查詢出所需資料, 在資料庫分頁, 這種分頁按需返回資料, 但資料庫壓力可能較大.
- mybatis 是否支援延遲載入?延遲載入的原理是什麼?
答: 支援. 可以設定lazyLoadingEnable=true啟用.
延遲載入是在使用例項的時候, 比如呼叫物件a.getName(), 如果發現a為null, 則載入a並返回. 延遲載入就是在使用時才去觸發查詢的SQL.
- 說一下 mybatis 的一級快取和二級快取?
答: 一級快取是基於PerpetualCache的HashMap本地快取, 生命週期與SQLSession相同, 可能會出現髒資料, 在session關閉或清空後快取失效. 預設開啟. 二級快取也是基於PerpetualCache的HashMap本地快取, 不同的是作用域為Mapper級別, 可以在多個Session間共享, 可以自定義快取如使用EhCache. 使用二級快取需要類實現Serializable介面.
查詢順序: 二級快取 --> 一級快取 --> 資料庫.
更新策略: 同一作用域下發生更新後, 預設該作用域下的select快取均clear.
- mybatis 和 hibernate 的區別有哪些?
答: Mybatis更靈活, 可以自己寫sql; 可移植性hibernate要好; 二級快取hibernate可以自行更換;
- mybatis 有哪些執行器(Executor)?
答: 有三種基本執行器: (1). SimpleExecutor: 每執行一次update或select就開啟一個statement物件, 用完立即關閉statement物件; (2). ReuseExecutor: 執行update,select, 以sql語句作為key查詢statement物件, 存在則使用, 不存在則建立, 用完存在Map以備後面再用. (3). BatchExecutor: 執行update, 將多個sql新增到批處理中, 等待統一執行, 它快取了多個statement物件, 等待統一處理.
- mybatis 分頁外掛的實現原理是什麼?
答: 攔截器實現, 攔截sql, 然後重寫為對應的分頁sql.
- mybatis 如何編寫一個自定義外掛?
答: (1). 外掛要實現interceptor介面
public interface Interceptor{
// 攔截的適合要執行的邏輯
Object intercept(Invocation invocation) throws Throwable;
// 用於封裝目標物件, 該方法返回物件本身或其代理, 可決定是否要進行攔截進而決定要返回什麼樣的物件.
Object plugin(Object target);
// 在MyBatis進行配置外掛的適合可以配置自定義相關屬性, 介面實現物件的引數配置.
void setProperties(Properties properties);
}
(2). 外掛應用的目標物件: Executor, StatementHandler,ParameterHandler, ResultSetHandler.
(3). 實現示例:
@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(); //方法引數
///....... 方法執行前的程式碼
Object result = invocation.proceed();
///........方法執行後的程式碼
return result;
}
public Object plugin(Object target){
return Plugin.wrap(target,this);
}
}
十四、RabbitMQ
- rabbitmq 的使用場景有哪些?
答: rabbitmq是目前比較流行的amqp訊息佇列, 適合使用的場景有: 1. 系統削峰填谷; 2. 延遲佇列; 3. 系統解耦.
- rabbitmq 有哪些重要的角色?
答: 問題問的是構成rabbitmq的系統角色, rabbitmq是生產者/消費者模式的結構. 因此分為生產者: 訊息的建立方, 負責傳送訊息到訊息伺服器; 消費者: 訊息接收方, 用於處理資料; 中介代理: 即rabbitmq本身, 用來接受訊息並按一定資料格式儲存, 併為消費者提供訊息.
- rabbitmq 有哪些重要的元件?
答:
- ConnectionFactory: 建議連結的工廠類
- Channal: 通道, 訊息通道
- Exchange: 交換器, 用於接收分配訊息
- Queue: 佇列, 用來儲存訊息
- RoutingKey: 路由鍵, 用來把生產者資料分配到交換機
- BindingKey: 用來把交換機的訊息繫結到佇列
- rabbitmq 中 vhost 的作用是什麼?
答: 類似資料庫的例項, 每個vhost有自己的一套佇列,交換機和繫結以及自己的許可權機制.
- rabbitmq 的訊息是怎麼傳送的?
答: 客戶端通過tcp連結到RabbitMQ伺服器, 一旦通過了認證, 客戶端和伺服器之間就建立了一條amqp通道, 通道是建立在真實tcp上的虛擬連結, amqp命令是通過通道發出去的, 每個通道都有一個唯一的id, 不論釋出還是訂閱均通過此通道完成.
- rabbitmq 怎麼保證訊息的穩定性?
答: 提供了事務支援; 可以將channel設定為confirm模式.
- rabbitmq 怎麼避免訊息丟失?
答: 把訊息持久化到磁碟, 保證重啟資料不丟失; 叢集中至少有個物理磁碟, 保證訊息落入磁碟.
- 要保證訊息持久化成功的條件有哪些?
答: 佇列queue必須設定持久化durable為true; 訊息推送投遞模式必須設定持久化, deliveryMode=2; 訊息已經到達持久化交換機; 訊息已經到達持久化佇列.
- rabbitmq 持久化有什麼缺點?
答: 持久化需要將資料寫入磁碟, 跟其他磁碟io的系統一樣,這樣會降低伺服器吞吐量, 降低效能.
- rabbitmq 有幾種廣播型別?
答: direct, 預設方式, 傳送訊息給訂閱方, 對於多個訂閱方採用輪詢的方式進行; headers, 效能較差, 此型別幾乎用不到; fanout, 分發模式, 分發給所有訂閱者; topic: 匹配訂閱, 可以使用正則匹配到訊息佇列, 能匹配到的都能接收到.
- rabbitmq 怎麼實現延遲訊息佇列?
答: 有兩種方式: 一是訊息過期後進入死信交換機, 再由交換機轉發到延遲消費佇列, 實現延遲功能; 二是使用delayed-message-exchange外掛實現延遲功能.
- rabbitmq 叢集有什麼用?
答: 高可用, 高容量
- rabbitmq 節點的型別有哪些?
答: 磁碟節點, 可持久化資料; 記憶體節點, 高效.
- rabbitmq 叢集搭建需要注意哪些問題?
答: 各節點之間用"-link"連線; 各節點使用erlang coolie值必須相同, 相當於金鑰, 用於認證; 整個叢集中必須包含一個磁碟節點.
- rabbitmq 每個節點是其他節點的完整拷貝嗎?為什麼?
答: 不是, 原因有二: 儲存空間和效能.
- rabbitmq 叢集中唯一一個磁碟節點崩潰了會發生什麼情況?
答: 叢集可以保持執行, 只是不能修改任何東西了. (1)不能建立佇列;(2)不能建立交換器;(3)不能建立繫結;(4)不能新增使用者;(5)不能更改許可權;(6)不能新增刪除節點.
- rabbitmq 對叢集節點停止順序有要求嗎?
答: 需要先關閉記憶體節點, 再關閉磁碟節點, 否則可能會導致資料丟失.
十五、Kafka
- kafka 可以脫離 zookeeper 單獨使用嗎?為什麼?
答: 不可以, kafka使用zookeeper協調管理kafka的節點伺服器.
- kafka 有幾種資料保留的策略?
答: 兩種: 按過期時間保留, 按儲存訊息大小保留.
- kafka 同時設定了 7 天和 10G 清除資料,到第五天的時候訊息達到了 10G,這個時候 kafka 將如何處理?
答: 兩個規則為或的關係, 只要一個滿足要求即清除資料.
- 什麼情況會導致 kafka 執行變慢?
答: 傻逼問題, 傻逼答案... cpu, io, 網路
- 使用 kafka 叢集需要注意什麼?
答: 叢集節點最好不要超過7個, 節點越多訊息複製需要的時間越長, 整個群組的吞吐量就越低. 叢集數為2N+1個較好. 超過一半故障叢集就不能用了, 單數容錯更高一點.
十六、Zookeeper
- zookeeper 是什麼?
答: zookeeper是分散式協調排程RPC框架, 它為分散式應用提供一致性服務, 包括配置註冊中心,域名服務,分散式鎖等.
資料採用樹形方式, 可以支援臨時和永久, 有序和無序兩種方式的任意組合.
- zookeeper 都有哪些功能?
答: 事件監聽, 檔案儲存; 適用的場景包括: 釋出訂閱,配置註冊中心, 命名服務, leader選舉, 負載均衡, 分散式佇列, 分散式鎖等.
- zookeeper 有幾種部署模式?
答: 單例項部署, 叢集部署.
- zookeeper 怎麼保證主從節點的狀態同步?
答: Zookeeper 的核心是原子廣播,這個機制保證了各個Server之間的同步。實現這個機制的協議叫做Zab協議。Zab協議有兩種模式,它們分別是恢復模式(選主)和廣播模式(同步)。當服務啟動或者在領導者崩潰後,Zab就進入了恢復模式,當領導者被選舉出來,且大多數Server完成了和 leader的狀態同步以後,恢復模式就結束了。狀態同步保證了leader和Server具有相同的系統狀態。
為了保證事務的順序一致性,zookeeper採用了遞增的事務id號(zxid)來標識事務。所有的提議(proposal)都在被提出的時候加上了zxid。實現中zxid是一個64位的數字,它高32位是epoch用來標識leader關係是否改變,每次一個leader被選出來,它都會有一個新的epoch,標識當前屬於那個leader的統治時期。低32位用於遞增計數。
- 叢集中為什麼要有主節點?
答: 分散式環境中, 有些業務邏輯只需要在叢集中的某臺伺服器執行, 這樣可以保證這些事務邏輯的原子性, 同時也保證只在一臺伺服器執行,這樣可以提高效能, 減少重複計算.等執行完成後結果被其他的節點共享.
- 叢集中有 3 臺伺服器,其中一個節點當機,這個時候 zookeeper 還可以使用嗎?
答: 可以使用, 一般叢集的機器節點數為2N+1, 只要有大於一半的伺服器線上即可正常提供服務, 三臺當機一臺依然有兩臺可用.
- 說一下 zookeeper 的通知機制?
答: zookeeper採用註冊/監聽方式, 使用
Watcher
來實現對節點和路徑事件的監控.
十七、MySql
- 資料庫的三正規化是什麼?
答: 1. 原子性, 每個欄位都只表示一個屬性; 2. 每個欄位均依賴於主鍵, 也就是一張表只表示一個物件; 3. 屬性不能傳遞依賴,也就是有傳遞依賴的地方要拆分為不同表;
- 一張自增表裡面總共有 7 條資料,刪除了最後 2 條資料,重啟 mysql 資料庫,又插入了一條資料,此時 id 是幾?
答: Innodb和myIASM兩種執行引擎的方式不同, Innodb會在記憶體中儲存表中的自增id, myiasm是在表中保留, 因此innodb重啟後會丟失最大id, 而會從現有表中計算所以結果為6, myiasm為8.
- 如何獲取當前資料庫版本?
答: select version()
- 說一下 ACID 是什麼?
答: ACID是資料庫事務的特性, A是atomicity, 即原子性, 原子性保證一個事務以一個整體邏輯執行, 要麼成功, 要麼失敗, 執行完成後不會發生中間狀態; C是consistency, 即一致性, 即事務執行開始和結束後, 資料的完整性沒有遭到破壞; I是Isolation, 隔離性, 多個併發的事務對資料來說不會因為交叉執行而導致資料不一致, 資料庫存在四個隔離級別, 分別解決不同程度的資料隔離;D 是 durability, 是永續性, 事務執行後對資料修改時永久的, 資料保持完成.
- char 和 varchar 的區別是什麼?
答: char是固定長度的, varchar是可變長度的,char可能會存在空間浪費的情況, varchar使用的空間是n+1, 其中有一個char單位用來儲存長度, 效能方法, char的效能要高一點,
- float 和 double 的區別是什麼?
答: 大小不同, float是4位元組的, double是8位元組的.
- mysql 的內連線、左連線、右連線有什麼區別?
答: 內連線是兩個表能匹配的資料, 左連線和右連線則分別以左表或右邊為主, 展示出左表或右表的資料, 對於匹配不到的, 右表或左表展示為null.
- mysql 索引是怎麼實現的?
答: mysql或其他資料庫的索引大多采用B+樹資料結構, B+樹本身就是有序結構, 可以達到二分法的效能.
- 怎麼驗證 mysql 的索引是否滿足需求?
答: explain 查詢語句, 檢視執行計劃
- 說一下資料庫的事務隔離?
答: MySql.ini配置檔案有預設的事務隔離配置, transaction-isolution=REPEATABLE-READ.
事務有四個級別的隔離方式, 分別為:
- READ-UNCOMMITED: 未提交讀, 隔離級別最低, 可能導致髒讀,幻讀,不可重複讀
- READ-COMMITED: 提交讀, 可能導致幻讀, 不可重複讀, 可以避免髒讀. 事務提交後其他事務才可見
- REPEATABLE-READ: 可重複讀, 會造成幻讀
- SERIALIZABLE: 序列化, 完全保證了事務是隔離的,但效能最低.
髒讀: 一個事務能讀取另一個事務未提交的資料; 不可重複讀: 一個事務內多次讀取同一個資料;幻讀: 同一事務多次讀取的資料不一致.
- 說一下 mysql 常用的引擎?
答: InnoDB: 提供了對資料庫的acid事務支援, 並提供行級鎖和外來鍵約束, 它設計的目標就是處理大資料容量的資料庫系統. 它會在啟動時建立緩衝池, 用來快取資料和索引. 但不支援全文索引, 啟動也比較慢. 不會儲存行數, 但併發環境下的讀取效率很高.
MyIASM: 預設引擎, 不提供事務支援, 不支援行鎖和外來鍵. 所以變更時會鎖表,效率比較低. 但其儲存了行數, 讀多餘寫的操作可以使用此搜尋引擎.
- 說一下 mysql 的行鎖和表鎖?
答: 行鎖是在資料變更時僅會在當前行加鎖, 其他行還是可以訪問的, 鎖的級別較小, 不容易發生阻塞.表鎖是變更時會對整個表加鎖, 效能低下, 不利於併發.
- 說一下樂觀鎖和悲觀鎖?
答: 樂觀鎖是預設沒有別的程式修改資料, 僅在提交更新時判定資料版本號是否與修改前一致; 悲觀鎖是預設認為資料在同一時間可能被其他程式修改, 因此先鎖定資料, 修改後釋放鎖.
- mysql 問題排查都有哪些手段?
答: show processlist, explain, 檢視日誌
- 如何做 mysql 的效能優化?
答: 索引, 合適的查詢語句, 表分割槽, 正確的搜尋引擎
十八、Redis
- redis 是什麼?都有哪些使用場景?
答: redis是一種nosql資料庫, 是用C實現的, 具有高效能, 單執行緒, 支援持久化, 支援叢集的高可用記憶體資料庫.
用來做資料庫, 快取, 訊息中介軟體
- redis 有哪些功能?
答: 複製, 叢集, 持久化, 事務, 分散式鎖,LUA指令碼, LRU
- redis 和 memecache 有什麼區別?
答: (1) 持久化的支援, 資料可靠性: redis可以做持久化, memcache是記憶體無法持久化; (2) 底層實現方面: redis利用單執行緒, memcache多執行緒, 可以使用多核CPU; (3). 資料結構方面: redis支援較多的資料結構, memcache僅僅是k-v結構;(4). 資料大小, 小於100kredis比較快, 大於100k,memcache較快, 但redis支援最大512M的資料, memcache最大為1M; (5)應用場景: memcache適合讀多寫少, 或資料比較大的物件,redis適合讀寫都很多, 比較複雜的資料結構.
- redis 為什麼是單執行緒的?
答: redis是基於記憶體操作的, CPU不會存在瓶頸, 既然CPU不是瓶頸, 單執行緒又很容易實現, 那麼redis自然就選擇用單執行緒了.
對於多個CPU的伺服器, 可以開多個redis例項來提高伺服器資源使用率. 注意: redis4.0 開始可能會有條件地在某些操作時使用多執行緒.
183.什麼是快取穿透?怎麼解決?
- redis 支援的資料型別有哪些?
答: String, Set, ZSet, List, Hash
不常見的有: Bitmaps,Hyperloglogs 和地理空間(Geospatial)索引半徑查詢
- redis 支援的 java 客戶端都有哪些?
答: Jedis, Redisson等, 官方推薦Redisson
- jedis 和 redisson 有哪些區別?
答: jedis是對原生redis的簡單封裝, redisson是官方推薦的客戶端程式, 除了基本的命令, 還有更豐富的資料結構以及鎖的實現.
- 怎麼保證快取和資料庫資料的一致性?
答: 更新時先刪除快取, 設定資料過期時間, 非同步更新資料.
- redis 持久化有幾種方式?
答: aof, rdb
aof是寫日誌方式, 是按指定策略通過日誌恢復資料的方式.
rdb是快照方式, 支援同步(save)和非同步方式(bgsave)儲存資料. save會阻塞服務, 直到儲存完成. bgsave不阻塞, 但可能執行期間的資料會發生丟失.
- redis 怎麼實現分散式鎖?
答: setNX命令, 返回1表示成功, 0位失敗.
- redis 分散式鎖有什麼缺陷?
答: 執行時間超過鎖超時時間時會導致併發問題.
- redis 如何做記憶體優化?
答: 儘量使用Redis的雜湊表, 把相關資訊放在雜湊表裡面, 而不是各個欄位單獨儲存, 這樣可以有效減少記憶體.
- redis 淘汰策略有哪些?
答: 六種, 分別是volatile-ttl, 過期的資料集中清除超時的;volatile-lru,過期的裡面清除不常用的資料;volatile-random,過期的資料裡面隨機清除; allkeys-random, allkeys-lru, 與上面一樣, 只是範圍為所有的資料集.no-enviction,禁止淘汰
- redis 常見的效能問題有哪些?該如何解決?
答: redis是在進行持久化的時候會導致效能問題. 寫記憶體快照會阻塞主執行緒, 當快照較大時會較長時間的導致服務暫停, 所有主伺服器最好不要寫快照. 主從複製的效能問題, 複製的速度和穩定性. 主從最好在一個區域網內.
十九、JVM
- 說一下 jvm 的主要組成部分?及其作用?
答:
- 類載入器(Class Loader) 用來將類檔案載入到記憶體.
- 執行引擎(Execution Engine) 用來解析指令, 提供給作業系統執行
- 本地方法介面(Native Interface) 一些Java無法完成的任務 (1)與環境外互動;(2)與作業系統互動;
- 執行時資料區(Runtime Data Area) 載入的程式和執行時的物件都儲存在這裡,主要分堆和棧, 這裡(特別是堆)也是GC的主要區域.
總的來說就是類載入器會將java程式碼轉化為位元組碼, 執行時區把位元組碼載入到記憶體, 為了呼叫作業系統功能, 執行引擎需要呼叫本地方法.
說一下 jvm 執行時資料區?
說一下堆疊的區別?
佇列和棧是什麼?有什麼區別?
什麼是雙親委派模型?
說一下類載入的執行過程?
怎麼判斷物件是否可以被回收?
java 中都有哪些引用型別?
說一下 jvm 有哪些垃圾回收演算法?
說一下 jvm 有哪些垃圾回收器?
詳細介紹一下 CMS 垃圾回收器?
新生代垃圾回收器和老生代垃圾回收器都有哪些?有什麼區別?
簡述分代垃圾回收器是怎麼工作的?
說一下 jvm 調優的工具?
常用的 jvm 調優的引數都有哪些?