在面試通過通過單例模式來展示實例


    在面試初級和高級開發時,一般會問設計模式的問題。通常會讓寫下單例模式的實現方法,或者讓結合項目,說下用過的設計模式,在本文里,就將講述單例模式的多種寫法,以此告訴大家如何在面試中展示實力。

    如果在項目里,多個運行實例都會從同一個配置文件里讀取發送郵件的列表,那么我們就可以用單例模式來創建這個讀配置文件的類。我們先來看下單線程情況下單例模式的寫法。

1	public class MailListReader {
2	    private static MailListReader reader = null;
3	    private MailListReader(){}//構造函數私有
4	    //向外部開放一個公有的靜態函數來提供對象
5	    public static MailListReader getInstance() {
6	        if(reader == null)
7	           reader = new MailListReader();
8	        return reader;
9	    } 
10	    //提供郵件列表的方法
11	     List<String> provideList()
12	     { 省略提供郵件列表的代碼 }
13	}

    在上述的代碼里,我們可以看到實現單例模式的兩大要素,第一,第3行提供的構造函數是私有的,這樣外部代碼就無法通過調用構造函數來創建MailListReader對象。第二,會通過諸如第5行的代碼向外界提供read實例,而且在這個方法里,只有當read對象為null時,才創建並返回該對象。

    如果程序是運行在單線程環境下,那么上述實現方式確實能滿足單例的需求,但在多線程的情況下,出現多個線程同時調用getInstance方法,那么就無法保證單例了。

    確實,我們可以通過加synchronized來保證多線程場景里只有一個MailListReader對象被創建,代碼改寫如下。      

1	public class MailListReader {
2	    private static MailListReader reader = null;
3	    private MailListReader(){}//構造函數私有
4	     public static MailListReader getInstance() {
5	        Synchronized(MailListReader.class){
6	            if(reader == null)
7	               reader = new MailListReader();
8	        } 
9	        return reader;
10	    } 
11	    //省略提供郵件列表的方法 
12	}

    我們把第7行的new的動作包含在第5行的Synchronized代碼塊里,這樣這個new代碼在同一個時間段里只能被一個線程調用,多個線程同時到來時會出現排隊的情況,這樣效率有些低下。所以,我們還可以通過如下的“雙重檢查”的方式來兼顧線程安全和性能。      

1	public class MailListReader {
2	    private static MailListReader reader = null;
3	    private MailListReader(){}//構造函數私有
4	     public static MailListReader getInstance() {
5	        if(reader== null){
6	           synchronized (MailListReader.class){
7	             if(reader == null){
8	                 reader = new MailListReader ();
9	              }
10	            }
11	         }
12	         return reader;
13	    } 
14	    //省略提供郵件列表的方法 
15	}

    我們在getInstance方法里的第5和第7行兩個地方通過兩個if來檢查,這就是“雙重檢查”。這里我們在加鎖前做了一個是否為空的判斷。通過這個判斷我們能看到了是否有其它線程得到reader對象,這樣就可以避免第6行的鎖對象的操作,從而能避免多線程排隊的情況。

    大家完全可以通過你在項目中的實際案例,用單例模式來說明自己對設計模式的理解,而且可以由淺到深地一直講到“雙重檢查”方式,這樣面試官就能知道,你不僅知道這種模式最基本的寫法,還知道掌握如何在多線程中應用的高級技能,更為重要的是,大家能通過實際案例,向面試官說明你不僅知道理論,而會應用。  

    此外,在講完上述回答后,大家可以再往如下兩個方向擴展,第一可以繼續說,除了單例模式外,在我們項目里,還用到其它設計模式,然后再結合案例說明,或者再圍繞剛才單例模式里提到的線程安全,再擴展出去說,除了在單例模式外,在我們項目里還會考慮其它的線程並發因素,比如對一些多線程間都需要用的鍵值對緩存,我們是放入ConcurrentHashMap,(或者引出Lock,ThreadLocal等線程相關話題),然后再展開,這樣就可以繼續在自己熟悉的范圍內回答問題。

    大家可以想象下,如果初級開發一方面照此說辭,很好地證明了設計模式方面的能力,另一方面再通過准備加引導技術,不僅可以展示基礎技能 ,更能有效地展示諸如底層代碼等技能,這對成功通過面試大有好處。

 

    

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM