這兩種設計模式相對來講都偏冷門,本題可以回答好的話說明對設計模式有過深刻的瞭解,在面試偏業務的崗位上有加分mysql
先解釋二者概念:面試
再解釋二者核心區別和功能不一樣點:redis
最後解釋二者優缺點和各自使用場景:算法
若是問頁分裂問題,通常會在聚簇索引以後緊接着提出,若是沒有問,在回答完聚簇索引相關的概念後,要儘可能地給面試官帶出頁分裂的概念,體現出本身對這一塊的熟悉程度sql
數據庫索引底層使用B+樹來實現,若是插入不規則的數據(指不按key順序插入),會致使樹結構頻繁發生較大改變數據庫
在數據庫中,聚簇索引和非聚簇索引在頻繁插入不規律數據時,都會致使嚴重的頁分裂問題。mysql中一頁大小爲8k,是固定的:設計模式
本題主要用於考察面試者是否瞭解排序的概念,而不是僅僅背知識點。第一問不難,基本上知道穩定性的概念就能順勢推出其意義,第二問稍微有點難度,可是隻要真正瞭解穩定性的概念,就能想到一些解決辦法緩存
排序的穩定性指擁有相同關鍵字的記錄,在排序後的相對次序保持不變。由於有些數據在排序前的相對順序是有語義的,非穩定性排序會在排序後丟失這些語義,因此在這種場景下須要保證排序的穩定性bash
當必須使用非穩定性排序算法,且須要保證穩定性時,有兩種解決方案:服務器
實現原理很簡單,但前提是你主動去了解過
HashSet
內部維護了一個HashMap
類型的變量,其key值爲Set的元素類型,value爲Object類型
對全部添加到Set中的元素,HashSet會添加一個元素 => PRESENT
的鍵值對到HashMap中,這個PRESENT是HashSet中定義的一個普通的Object對象。由於HashMap中key相同的元素會相互覆蓋,因此保證了集合中沒有重複key值的元素存在
ACID的概念很簡單,可是想說清原理不容易,其中隔離性和持久性是重點。隔離性的要點是鎖機制,有的面試官會緊接着出一些場景題,須要提早準備;持久性的要點是
redo log
和binlog
,有的面試官會引伸到讀寫分離的數據一致性問題,也須要提早作好準備
A(原子性):原理是undo log
,即「撤銷日誌」。當事務對數據庫進行修改時,會生成對應的undo log,若是事務回滾,數據庫會使用undo log中的內容將數據修改到以前的狀態
C(一致性):經過數據庫自己(如外鍵等)和服務端的代碼邏輯層面共同保證
I(隔離性):經過數據庫鎖機制和MVCC來實現。鎖機制保證兩個事務的寫操做不會相互影響,MVCC保證一個事務的讀操做不會被其餘事務的寫操做影響
D(持久性):原理是redo log
和binlog
,當數據修改時,會在redo log中記錄此次操做(記錄的是物理數據,內容基於磁盤page),一般當事務提交時,會調用fsync對redo log進行刷盤(將數據寫入磁盤),若是mysql機器宕機,可使用redo log對數據進行恢復。同時binlog做爲二進制邏輯日誌也能夠用戶數據恢復
若是面試官問你這個問題,惟一的緣由就是他昨天臨睡前看到了這個知識點,因此就拿來考你(固然也有多是工做中確實用到)。本題單純的就是知識擴展,若是不會也不影響
stricpy
,即strict float point(精確浮點)
,只能用來修飾方法或類。被strictpy修飾的方法或類中全部的float/double表達式都嚴格遵循FP-strict的限制,全部表達式的結果都必須是IEEE-754對操做數預期的結果
strictpy能夠消除因硬件不一樣而帶來的浮點數計算差別,可是並不能避免相似0.05 + 0.01 != 0.06
這樣的狀況,因此在要求高精度浮點計算時,須要使用BigDecimal
fun1
相互阻塞的方法有哪幾個,爲何?public synchronized static void fun1() {
try {
Thread.sleep(2000);
} catch(Exception e) {
e.printStackTrace();
}
System.out.println("[同步-靜態方法-1]");
}
// -------------------------------------------------
public synchronized static void fun2() {
System.out.println("[同步-靜態方法-2]");
}
public static void fun3() {
System.out.println("[普通靜態方法]");
}
public void fun4() {
System.out.println("[普通方法]");
}
public void fun5() {
synchronized (Demo.class) {
System.out.println("[類同步-靜態方法]");
}
}
public void fun6() {
synchronized (this) {
System.out.println("[對象同步-方法]");
}
}
複製代碼
本題考察點是對
synchronized
關鍵字的掌握程度,有些人理論背的很熟,可是隨便丟個場景應用就懵了。因此在學一個知識點的時候,最起碼本身要動手寫幾行代碼跑一下看看
與fun1相互阻塞的方法是fun2和fun5
fun2是另外一個被synchronized修飾的方法,和fun1同屬一類,因此會相互阻塞
fun5中使用了類鎖,而synchronized在靜態方法上的鎖也屬於類鎖,因此也會相互阻塞
通常這種併發修改的場景,均可以用消息中間件來將並行轉串行解決,可是面試官一般還想要另外一種答案,因此最少要準備兩套方案。本題固然不止我下面列出的這兩種方案,只要合理便可
MUTLI
和WATCH
實現:在redis中設置一個key,而後WATCH這個key,經過MUTLI開啓事務,而後自增這個key的值,接着再執行真正的修改操做,最後使用EXEC提交事務。經過這種方法,若是發生多線程競爭,因爲WATCH機制,監聽到key值變化的線程會執行redis操做失敗本題應該算是偏常規的緩存題,可是有的面試官會把這三個場景放一塊兒說來故意迷惑你,因此要注意區分它們之間的不一樣點,千萬不要死記硬背,不然必定會搞混的
本題主要考察對mvc分層的理解程度,只要能把每一層的概念理解了,說個大概仍是沒問題的,即便不知道,舉幾個反例出來就能夠了