【027期】Java設計模式面試題

開篇介紹

你們好,我是Java最全面試題庫提褲姐,今天這篇是Java設計模式,主要總結了設計模式相關的問題,在後續,會沿着第一篇開篇的知識線路一直總結下去,作到日更!若是我能作到百日百更,但願你也能夠跟着百日百刷,一百天養成一個好習慣。java

設計模式有哪些?

建立型面試

  • 工廠模式與抽象工廠模式 (Factory Pattern)(Abstract Factory Pattern)
  • 單例模式 (Singleton Pattern)
  • 建造者模式 (Builder Pattern)
  • 原型模式 (Prototype Pattern)

結構型設計模式

  • 適配器模式 (Adapter Pattern)
  • 裝飾器模式 (Decorator Pattern)
  • 橋接模式 (Bridge Pattern)
  • 外觀模式 (Facade Pattern)
  • 代理模式 (Proxy Pattern)
  • 過濾器模式 (Filter、Criteria Pattern)
  • 組合模式 (Composite Pattern)
  • 享元模式 (Flyweight Pattern)

行爲型安全

  • 責任鏈模式(Chain of Responsibility Pattern)
  • 觀察者模式(Observer Pattern)
  • 模板模式(Template Pattern)
  • 命令模式(Command Pattern)
  • 解釋器模式(Interpreter Pattern)
  • 迭代器模式(Iterator Pattern)
  • 中介者模式(Mediator Pattern)
  • 策略模式(Strategy Pattern)
  • 狀態模式(State Pattern)
  • 備忘錄模式(Memento Pattern)
  • 空對象模式(Null Object Pattern)

JDK 類庫經常使用的設計模式有哪些?

  • 工廠模式
  • 適配器模式
  • 代理模式
  • 單例模式
  • 裝飾器
  • 模板方法模式

Spring 中都使用了哪些設計模式?

  • 代理模式:在 AOP 中有使用
  • 單例模式:bean 默認是單例模式
  • 模板方法模式:jdbcTemplate
  • 工廠模式:BeanFactory
  • 觀察者模式:Spring 事件驅動模型就是觀察者模式很經典的一個應用,好比,ContextStartedEvent 就是 ApplicationContext 啓動後觸發的事件
  • 適配器模式:Spring MVC 中也是用到了適配器模式適配 Controller

Java中什麼叫單例設計模式?請用 Java 寫出線程安全的單例模式

單例模式重點在於在整個系統上共享一些建立時較耗資源的對象。整個應用中只維護一個特定類實例,它被全部組件共同使用。Java.lang.Runtime 是單例模式的經典例子。ide

靜態內部類:
JVM提供了同步控制功能:static final,利用JVM進行類加載的時候保證數據同步。
在內部類中建立對象實例,只要應用中不使用內部類,JVM就不會去加載該類,就不會建立咱們要建立的單例對象。性能

public class StaticInnerSingleton {
    private StaticInnerSingleton(){
    }
    /**
     * 在第一次加載StaticInnerSingleton時不會初始化instance,
     * 只在第一次調用了getInstance方法時,JVM纔會加載StaticInnerSingleton並初始化instance
     * @return
     */
    public static StaticInnerSingleton getInstance(){
        return SingletonHolder.instance;
    }
    //靜態內部類
    private static class SingletonHolder{
        private static final StaticInnerSingleton instance = new StaticInnerSingleton();
    }
}
優勢:JVM自己機制保證了線程安全,沒有性能缺陷。

枚舉:ui

public enum EnumSingleton {
    //定義一個枚舉的元素,它就是Singleton的一個實例
    INSTANCE;
    public void doSomething(){
    }
}
注意:若是在枚舉類中有其餘實例方法或實例變量,必須確保是線程安全的。

使用工廠模式最主要的好處是什麼?在哪裏使用?

工廠模式的最大好處是增長了建立對象時的封裝層次。若是你使用工廠來建立對象,以後你可使用更高級和更高性能的實現來替換原始的產品實現或類,這不須要在調用層作任何修改。this

什麼是觀察者設計模式(observer design pattern )?實現一個觀察者設計模式。

觀察者模式是定義對象間的一種一對多依賴關係,使得每當一個對象狀態發生改變時,其相關依賴對象皆獲得通知並被自動更新。觀察者模式又叫作發佈-訂閱(Publish/Subscribe)模式、模型-視圖(Model/View)模式、源-監聽器(Source/Listener)模式或從屬者(Dependents)模式線程

優勢
觀察者模式能夠實現表示層和數據邏輯層的分離,並定義了穩定的消息更新傳遞機制,抽象了更新接口,使得能夠有各類各樣不一樣的表示層做爲具體觀察者角色;
觀察者模式在觀察目標和觀察者之間創建一個抽象的耦合;
觀察者模式支持廣播通訊;
觀察者模式符合開閉原則(對拓展開放,對修改關閉)的要求。設計

缺點
若是一個觀察目標對象有不少直接和間接的觀察者的話,將全部的觀察者都通知到會花費不少時間;
若是在觀察者和觀察目標之間有循環依賴的話,觀察目標會觸發它們之間進行循環調用,可能致使系統崩潰;
觀察者模式沒有相應的機制讓觀察者知道所觀察的目標對象是怎麼發生變化的,而僅僅只是知道觀察目標發生了變化。

public class Subject {
   
   private List<Observer> observers 
      = new ArrayList<Observer>();
   private int state;
 
   public int getState() {
      return state;
   }
 
   public void setState(int state) {
      this.state = state;
      notifyAllObservers();
   }
 
   public void attach(Observer observer){
      observers.add(observer);      
   }
 
   public void notifyAllObservers(){
      for (Observer observer : observers) {
         observer.update();
      }
   }  
}
public abstract class Observer {
   protected Subject subject;
   public abstract void update();
}
public class BinaryObserver extends Observer{
 
   public BinaryObserver(Subject subject){
      this.subject = subject;
      this.subject.attach(this);
   }
 
   @Override
   public void update() {
      System.out.println( "Binary String: " 
      + Integer.toBinaryString( subject.getState() ) ); 
   }
}
public class OctalObserver extends Observer{
 
   public OctalObserver(Subject subject){
      this.subject = subject;
      this.subject.attach(this);
   }
 
   @Override
   public void update() {
     System.out.println( "Octal String: " 
     + Integer.toOctalString( subject.getState() ) ); 
   }
}
public class HexaObserver extends Observer{
 
   public HexaObserver(Subject subject){
      this.subject = subject;
      this.subject.attach(this);
   }
 
   @Override
   public void update() {
      System.out.println( "Hex String: " 
      + Integer.toHexString( subject.getState() ).toUpperCase() ); 
   }
}
public class ObserverPattern {
   public static void main(String[] args) {
      Subject subject = new Subject();
 
      new HexaObserver(subject);
      new OctalObserver(subject);
      new BinaryObserver(subject);
 
      System.out.println("First state change: 15");   
      subject.setState(15);
      System.out.println("Second state change: 10");  
      subject.setState(10);
   }
}
相關文章
相關標籤/搜索