面試官常問的設計模式

2021-09-29 15:03:02 字數 4133 閱讀 9489

設計模式分為三大類:

建立型模式,共五種:

工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式。

結構型模式,共七種:

介面卡模式、裝飾器模式、**模式、外觀模式、橋接模式、組合模式、享元模式。

行為型模式,共十一種:

策略模式、模板方法模式、觀察者模式、迭代子模式、責任鏈模式、命令模式、備忘錄模式、狀態模式、訪問者模式、中介者模式、直譯器模式。

什麼叫單例模式?

指乙個類只有乙個例項,且該類能自行建立這個例項的一種模式。

例如,windows 中只能開啟乙個任務管理器,這樣可以避免因開啟多個任務管理器視窗而造成記憶體資源的浪 費,或出現各個視窗顯示內容的不一致等錯誤。

在計算機系統中,還有 windows 的**站、作業系統中的檔案系統、多執行緒中的執行緒池、顯示卡的驅動程式對 象、印表機的後台處理服務都是單例模式

單例模式有什麼特點?

1.單例類只有乙個例項物件;

2.該單例物件必須由單例類自行建立;

3.單例類對外提供乙個訪問該單例的全域性訪問點;

主要:餓漢式(執行緒安全,呼叫效率高,但是不能延時載入)

懶漢式(執行緒安全,呼叫效率不高,但是可以延時載入)

其他:雙重檢測鎖式(由於jvm底層內部模型原因,偶爾會出問題。不建議使用)

靜態內部類式(執行緒安全,呼叫效率高。但是可以延時載入)

列舉單例(執行緒安全,呼叫效率高,不能延時載入)

2、工廠模式:

簡單工廠模式:用來生產同一等級結構中的任意產品(對已有產品新增功能,需要修改源**)

雖然能通過工廠來建立物件,但是違反了開閉原則。一旦增加功能需要在原有基礎上修改**。

工廠方法模式:用來生產同一等級結構中的固定產品(支援增加任意產品,不用修改源**)

將工廠類調整為工廠介面,需要什麼型別的工廠就使用該類實現該工廠,建立相應的產品。

也叫(發布-訂閱模式)定義了一種一對多的依賴關係,讓多個觀察者物件同時監聽某乙個主題 物件,這個主題物件在狀態發生變化時,會通知所有觀察者物件。使它們能夠自動更新自己。

例如:發廣播,遊戲中大喇叭,群聊

jdk中提供了抽象主題和抽象觀察者的介面,我們可以使用這兩個介面來方便的定義自己的觀察者模式

為其他物件提供一種**以便控制對這個物件的訪問。

可以詳細控制訪問某個類(物件)的方法,在呼叫這個方法前作的前置處理(統一的流程**放到** 中 處理)。呼叫這個方法後做後置處理。

例如:明星的經紀人,租房的中介等等都是**

**模式分類:

1.靜態**(靜態定義**類,我們自己靜態定義的**類。比如我們自己定義乙個明星的經紀人類)

2.動態**(通過程式動態生成**類,該**類不是我們自己定義的。而是由程式自動生成)比較重要!!

面試官答:那你寫乙個執行緒安全的吧。

1.餓漢模式,執行緒安全

public

class

singleton

;private

static singleton instance =

newsingleton()

;public

static singleton getinstance()

}

將需要獲取的 instance 例項在類載入的時候就例項化完畢,由於類的載入機制,此時靜態變數的例項化只會執行一遍,所以可以保證此例項變數的唯一性。但是此時不具有延遲載入的特性。

面試官又問:執行緒安全還有其他寫法嗎?

我答:還可以使用 synchronized 來修飾 get 例項的方法(面試官沒讓我寫這個,但是我們還是給出懶漢模式的執行緒安全和不安全寫法)。

懶漢模式,執行緒不安全

public

class

singleton

;private

static singleton instance;

public

static singleton getinstance()

return instance;

}}

原來:懶漢模式指的是這個單例類在用的時候會延遲載入,但是這個單例類是執行緒不安全的,在多執行緒環境下很容易出現多個例項的情況。

懶漢模式,執行緒安全

public

class

singleton

;private

static singleton instance;

public

synchronized

static singleton getinstance()

return instance;

}}

原理:只要在上面的執行緒不安全模式下進行簡單的修改就可以程式設計執行緒安全的,將 getinstance 方法用 synchronized 修飾,確保同乙個時刻只能有乙個執行緒訪問此方法。

面試官問:(synchronized 的寫法明顯不是他想要考的點,他直接問我)

雙重校驗鎖的寫法了解嗎?

我答:了解。

雙重校驗鎖

public

class

singleton

;private

volatile

static singleton instance;

public

static singleton getinstance()

}}return instance;

}}

原理:雙重校驗鎖解決了餓漢模式下每次都要獲取 synchronized 同步鎖的問題。第一次校驗,會檢查變數是否已經被例項化,如果例項化了就不去爭取鎖了,直接返回。如果沒有第二次校驗,可能會出現兩個執行緒同時讀到例項為 null 的情況。此時第二校驗就需要加鎖區判斷例項是否為 null 了。

volatile 的作用是防止 jvm 指令重排導致出現錯誤,在某個執行緒建立單例物件時,在構造方法被呼叫前,就為該物件分配了記憶體空間並設定了預設值,此時就可以將分配的記憶體位址賦值給 instance 欄位了,但是它可能還沒有被初始化,此時另乙個物件來呼叫 getinstance,取到的就是狀態不正確的物件,volatile 能夠防止指令重排序。

在我寫出雙重校驗鎖的寫法後,面試官很滿意,但是這還沒有完,這個寫法衍生出了很多考點。

面試官問:如果不加第二次校驗會出什麼問題?

我答:多執行緒環境下獲取物件可能會出現空指標異常。

面試官問:volatile 關鍵字在這裡起到了什麼作用?

我答:(volatile 關鍵字是多執行緒最普遍的乙個考點,它能防止指令重排序和可見性)這裡主要是防止指令重排序,防止其中乙個執行緒在初始化這個物件沒結束時另乙個執行緒使用這個物件。

這個題不但考了設計模式,還衍生出了許多多執行緒方面的面試題。下面給出其他幾種寫法。

靜態內部類

public

class

singleton

;private

static

class

singleholder

public

static singleton getinstance()

}

原理:使用到了靜態內部類的特性,只有使用到 instance 例項的時候才會被初始化,同時用到了靜態變數的例項化機制確保全域性只有乙個例項,效能比較好。

列舉模式

public

enum singleton

}

列舉模式被認為是最安全最為有效的單例模式解決方案,解決了其他釋放方式通過反射方式獲取構造器、序列化等缺陷,它是在 jvm 層面實現的執行緒安全。

餓漢模式,變種

public

class

singleton

;private

static singleton instance = null;

static

public

static singleton getinstance()

}

面試官常問的集合框架問題(一)

有關集合框架問題 一 list 集合 1 迭代器的remove方法與集合的remove的區別?只需要了解迭代器在記憶體的執行 指標 迭代器與集合是兩個物件,如果說在迭代器中呼叫集合中的remove方法,會報currentmodifyexception錯誤。2 array與arraylist的有何區別...

面試官常問的 web前端 問題(四)

vue 兩大特點 響應式程式設計 元件化 vue 的優勢 輕量級框架 簡單易學 雙向資料繫結 元件化 檢視 資料和結構的分離 虛擬 dom 執行速度快 mvvm 是 model view viewmodel 的簡寫,模型 檢視 檢視模型。模型 指的是後端傳遞的資料 資料 json 檢視 指的是所看到...

面試官常問的 微服務 問題(二)

ps ef 或 ps aux kill 9 pid 注 先用 ps ef grep 查詢 pid kill 命令用於終止程序 9 強迫程序立即停止 linux中殺掉乙個程序可以用 kill 和 killall 命令 killall 命令用命令名字來殺死指定程序,而kill命令則是用程序pid來殺死程...