成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

面試官所認(rèn)為的單例模式

codeKK / 2718人閱讀

摘要:防止指令重排序防止時指令重排序?qū)е缕渌€程獲取到未初始化完的對象。枚舉類默認(rèn)枚舉實例的創(chuàng)建是線程安全的,所以不需要擔(dān)心線程安全的問題。

單例模式是23種GOF模式中最簡單,也是最經(jīng)常出現(xiàn)的一種設(shè)計模式,也是面試官最常愛考的一種模式,為什么呢?
因為單例模式足夠簡單,編寫一個單例模式代碼幾分鐘就能搞定,所以設(shè)計模式中面試官通常會選取單例模式作為出題。
下面把單例模式分幾個點,分別說說哪些地方面試官能考你?

單例模式的意義
通常面試官會很籠統(tǒng)的問你,什么是單例模式?單例模式用來解決了什么痛點?沒有單例模式我們會怎么辦?單例模式他有什么缺點嗎?

單例模式是最簡單的設(shè)計模式之一,屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對象的方式,確保只有單個對象被創(chuàng)建。這個設(shè)計模式主要目的是想在整個系統(tǒng)中只能出現(xiàn)類的一個實例,即一個類只有一個對象。
單例模式的解決的痛點就是節(jié)約資源,節(jié)省時間從兩個方面看:

1.由于頻繁使用的對象,可以省略創(chuàng)建對象所花費的時間,這對于那些重量級的對象而言,是很重要的.

2.因為不需要頻繁創(chuàng)建對象,我們的GC壓力也減輕了,而在GC中會有STW(stop the world),從這一方面也節(jié)約了GC的時間
單例模式的缺點:簡單的單例模式設(shè)計開發(fā)都比較簡單,但是復(fù)雜的單例模式需要考慮線程安全等并發(fā)問題,引入了部分復(fù)雜度。

擴展:從你的回答中能進(jìn)行哪些擴展呢?我們談到了GC,有可能這時候就會問你GC,STW等知識。談缺點的時候談到了復(fù)雜的單例模式,
這個時候可能會問你讓你設(shè)計一個優(yōu)秀的單例模式你會怎么設(shè)計,會怎么實現(xiàn)?

單例模式的設(shè)計
通常這里面試官會問你單例模式怎么設(shè)計,需要看重哪些方面?一般來說單例模式有哪些實現(xiàn)方式?

設(shè)計單例模式的時候一般需要考慮幾種因素:

-線程安全
-延遲加載
-代碼安全:如防止序列化攻擊,防止反射攻擊(防止反射進(jìn)行私有方法調(diào)用)
-性能因素

一般來說,我們?nèi)ゾW(wǎng)上百度去搜大概有7,8種實現(xiàn),,下面列舉一下需要重點知道的
餓漢,懶漢(線程安全,線程非安全),雙重檢查(DCL)(重點),內(nèi)部類,以及枚舉(重點),

擴展:我們上面說到了各個模式的實現(xiàn),這個時候很有可能會叫你手寫各個模式的代碼。當(dāng)然也有可能會問你線程安全,代碼安全等知識。

餓漢模式

餓漢模式的代碼如下:

public class Singleton {
    private static Singleton instance = new Singleton();
    private Singleton(){}
    public static Singleton getInstance(){
        return instance;
    }
}

餓漢模式代碼比較簡單,對象在類中被定義為private static,通過getInstance(),通過java的classLoader機制保證了單例對象唯一。
擴展:

有可能會問instance什么時候被初始化?

Singleton類被加載的時候就會被初始化,java虛擬機規(guī)范雖然沒有強制性約束在什么時候開始類加載過程,但是對于類的初始化,虛擬機規(guī)范則嚴(yán)格規(guī)定了有且只有四種情況必須立即對類進(jìn)行初始化,遇到new、getStatic、putStatic或invokeStatic這4條字節(jié)碼指令時,如果類沒有進(jìn)行過初始化,則需要先觸發(fā)其初始化。 生成這4條指令最常見的java代碼場景是:1)使用new關(guān)鍵字實例化對象2)讀取一個類的靜態(tài)字段(被final修飾、已在編譯期把結(jié)果放在常量池的靜態(tài)字段除外)3)設(shè)置一個類的靜態(tài)字段(被final修飾、已在編譯期把結(jié)果放在常量池的靜態(tài)字段除外)4)調(diào)用一個類的靜態(tài)方法

class的生命周期?

class的生命周期一般來說會經(jīng)歷加載、連接、初始化、使用、和卸載五個階段

class的加載機制

這里可以聊下classloader的雙親委派模型。

雙重檢查DCL
public class Singleton {  
    private volatile static Singleton singleton;  
    private Singleton (){}  
    public static Singleton getSingleton() {  
    if (singleton == null) {  
        synchronized (Singleton.class) {  
        if (singleton == null) {  
            singleton = new Singleton();  
        }  
        }  
    }  
    return singleton;  
    }  
}  

synchronized同步塊里面能夠保證只創(chuàng)建一個對象。但是通過在synchronized的外面增加一層判斷,就可以在對象一經(jīng)創(chuàng)建以后,不再進(jìn)入synchronized同步塊。這種方案不僅減小了鎖的粒度,保證了線程安全,性能方面也得到了大幅提升。

同時這里要注意一定要說volatile,這個很關(guān)鍵,volatile一般用于多線程的可見性,但是這里是用來防止指令重排序的。

擴展:

為什么需要volatile?volatile有什么用?

首先要回答可見性,這個是毋庸質(zhì)疑的,然后可能又會考到j(luò)ava內(nèi)存模型。

防止指令重排序: 防止new Singleton時指令重排序?qū)е缕渌€程獲取到未初始化完的對象。instance = new Singleton()這句,這并非是一個原子操作,事實上在 JVM 中這句話大概做了下面 3 件事情。1.給 instance 分配內(nèi)存2.調(diào)用 Singleton 的構(gòu)造函數(shù)來初始化成員變量3.將instance對象指向分配的內(nèi)存空間(執(zhí)行完這步 instance 就為非 null 了)

但是在 JVM 的即時編譯器中存在指令重排序的優(yōu)化。也就是說上面的第二步和第三步的順序是不能保證的,最終的執(zhí)行順序可能是 1-2-3 也可能是 1-3-2。如果是后者,則在 3 執(zhí)行完畢、2 未執(zhí)行之前,被線程二搶占了,這時 instance 已經(jīng)是非 null 了(但卻沒有初始化),所以線程二會直接返回 instance,然后使用,然后報錯。

順便也可以說下volatie原理用內(nèi)存屏障

講講synchronized和volatile的區(qū)別

這里可以從synchroized能保證原子性,volatile不能保證說起,以及講下synchroized是重量級鎖,甚至可以所以下他和Lock的區(qū)別等等。

線程安全一般怎么實現(xiàn)的?

互斥同步。如lock,synchroized

非阻塞同步。如cas。

不同步。如threadLocal,局部變量。

枚舉類
public enum Singleton{
    INSTANCE;
}

默認(rèn)枚舉實例的創(chuàng)建是線程安全的,所以不需要擔(dān)心線程安全的問題。同時他也是《Effective Java》中推薦的模式。最后通過枚舉類,他能自動避免序列化/反序列化攻擊,以及反射攻擊(枚舉類不能通過反射生成)。

總結(jié)

單例模式雖然看起來簡單,但是設(shè)計的Java基礎(chǔ)知識非常多,如static修飾符、synchronized修飾符、volatile修飾符、enum等。這里的每一個知識點都可以變成面試官下手的考點,而單例只是作為一個引子,考到最后看你到底掌握了多少。看你的廣度和深度到底是怎么樣的。

如果這篇文章對你有幫助,想要了解更多?;蛘呦胍?對1的交流。請關(guān)注下方公眾號吧。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/76415.html

相關(guān)文章

  • java面試題:java中單例設(shè)計模式及兩種實現(xiàn)方法的代碼舉例

    摘要:面試時經(jīng)常會問到關(guān)于單例設(shè)計模式,因為它能考察的知識點較多且在開發(fā)中經(jīng)常用到。那我就來說一說我對于單例設(shè)計模式的一些淺見。還有另一種實現(xiàn)方法稱為懶漢式。但以上代碼會出現(xiàn)線程安全問題。 Java面試時經(jīng)常會問到關(guān)于單例設(shè)計模式,因為它能考察的知識點較多且在開發(fā)中經(jīng)常用到。那我就來說一說我對于單例設(shè)計模式的一些淺見。首先,在Java中,什么是單例呢?就是保證類在內(nèi)存中只有一個對象。那么問題...

    dadong 評論0 收藏0
  • 又被面試官問設(shè)計模式了,我真的是

    摘要:面試官要不你來手寫下單例模式唄候選者單例模式一般會有好幾種寫法候選者餓漢式簡單懶漢式在方法聲明時加鎖雙重檢驗加鎖進(jìn)階懶漢式靜態(tài)內(nèi)部類優(yōu)雅懶漢式枚舉候選者所謂餓漢式指的就是還沒被用到,就直接初始化了對象。面試官:我看你的簡歷寫著熟悉常見的設(shè)計模式,要不你來簡單聊聊你熟悉哪幾個吧?候選者:常見的工廠模式、代理模式、模板方法模式、責(zé)任鏈模式、單例模式、包裝設(shè)計模式、策略模式等都是有所了解的候選者:...

    不知名網(wǎng)友 評論0 收藏0
  • 面試官問我:什么是JavaScript閉包,我該如何回答

    摘要:到底什么是閉包這個問題在面試是時候經(jīng)常都會被問,很多小白一聽就懵逼了,不知道如何回答好。上面這么說閉包是一種特殊的對象。閉包的注意事項通常,函數(shù)的作用域及其所有變量都會在函數(shù)執(zhí)行結(jié)束后被銷毀。從而使用閉包模塊化代碼,減少全局變量的污染。 閉包,有人說它是一種設(shè)計理念,有人說所有的函數(shù)都是閉包。到底什么是閉包?這個問題在面試是時候經(jīng)常都會被問,很多小白一聽就懵逼了,不知道如何回答好。這個...

    BenCHou 評論0 收藏0
  • 每日一道面試題(第三期)---一般什么情況下會導(dǎo)致內(nèi)存泄漏問題

    摘要:顯而易見的,當(dāng)這個是的時,就不存在內(nèi)存泄漏的問題。這個我在第一期自定義如何有效保證內(nèi)存泄漏問題已經(jīng)說得很明白了。 零零碎碎的東西總是記不長久,僅僅學(xué)習(xí)別人的文章也只是他人咀嚼后留下的殘渣。無意中發(fā)現(xiàn)了這個每日一道面試題,想了想如果只是簡單地去思考,那么不僅會收效甚微,甚至難一點的題目自己可能都懶得去想,堅持不下來。所以不如把每一次的思考、理解以及別人的見解記錄下來。不僅加深自己的理解,更要激...

    番茄西紅柿 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<