首页 > 其他分享 >设计模式面试点汇总

设计模式面试点汇总

时间:2022-12-01 08:00:11浏览次数:81  
标签:Singleton return INSTANCE 汇总 面试 static 单例 设计模式 public

设计模式面试点汇总

我们会在这里介绍我所涉及到的设计模式相关的面试点,本篇内容持续更新

我们会介绍下述设计模式的相关面试点:

  • 单例模式

单例模式

下面我们来介绍单例模式的相关面试点

五种单例模式实现方式

我们下面来介绍单例模式的五种实现方式

饿汉式

我们给出饿汉式构建单例模式的基本框架:

/*饿汉式*/

public class Singleton implements Serializable{
    
    // 首先我们需要拥有一个私有的构造方法(为了防止其他对象调用构造方法产生新对象)
    private Singleton(){
        
        // 这里我们需要做一个判断,如果已存在单例对象,且其他对象调用构造方法,直接报错(为了预防反射获得类然后新创对象)
        if( INSTANCE != null){
            throw new RuntimeException("单例对象不可重复创建");
        }
        
        System.out.println("private Singleton");
        
    }
    
    // 饿汉式:在加载类时就直接创建单例对象,我们这里直接用static创建一个静态单例对象(随着类加载创建单例对象)
    private static final Singleton INSTANCE = new Singleton();
    
    // 由于单例对象是private,我们需要一个公共方法获得对象
    public static Singleton getInstance(){
        return INSTANCE;
    }
    
    // 其他方法
    public static void otherMethod(){
        System.out.println("otherMethod");
    }
    
    // readResolve方法,用于阻止反序列化获得新对象
    public Object readResolve(){
        return INSTANCE:
    }
    
    // 需要注意:Unsafe类破坏单例对象是无法阻止的!!!
    
}

枚举饿汉式

我们给出枚举饿汉式构建单例模式的基本框架:

/*枚举*/

enum Sex{
    MALE,FAMALE;
}

/*枚举饿汉式*/

public enum Singleton{
    
    // 单例对象
    INSTANCE;
    
    // getStance方法
    public static Singleton getInstance(){
        return INSTANCE;
    }
    
    // 枚举方法自带 反射 反序列化 生成对象的阻止方法
    
    // 枚举方法也不能阻止Unsafe类生成对象
    
}

懒汉式

我们给出懒汉式构建单例模式的基本框架:

/*懒汉式*/

public class Singleton{
    
    // 首先我们需要一个构造方法
    private Singleton(){
        System.out.println("private Singleton");
    }
    
    // 懒汉式:该对象创建之后不赋值,等到使用时在进行赋值
    private static Singleton INSTANCE = null;
    
    // getStance:我们在获得 STANCE 对象时再进行赋值并且反馈(注意:需要加锁处理多线程问题)
    public static synchronized Singleton getStance(){
        // 首先判断是否存在,若不存在创建并返回,若存在直接返回
        if(INSTANCE == null){
            INSTANCE = new Singleton();
        }
        return INSTANCE;
    }
    
    // 其他方法
    public static void otherMethod(){
        System.out.println("otherMethod");
    }
    
}

DCL懒汉式

我们给出DCL懒汉式构建单例模式的基本框架:

/*DCL懒汉式*/

// DCL:Double Check Lock 双重检查锁

public class Singleton{
    
    private Singleton(){
        System.out.println("private Singleton");
    }
    
    // 这里需要加上volatile,为了保证语句的有序性
    // 在getStance的赋值操作中INSTANCE = new Singleton()语句属于init初始化和static初始化
    // 两者之间可能出现优化状态,可能导致先进行ISNTANCE赋值,再进行init初始化
    // 但是在这个间隙线程2可能会通过INSTANCE判断,然后直接返回INSTACE,这时返回的并不是完整体的INSTANCE,可能出错
    private static volatile Singleton INSTANCE = null;
    
    // 我们将这里的锁进行更改,之前我们将getStance方法上锁,所有进程调用均需要锁处理,效率较慢
    // 实际上,我们只有第一次创建时,需要上锁处理,所以我们采用双重检查锁,判定只有未赋值时进行锁处理
    public static Singleton getStance(){
        // 首先判断是否赋值,若没赋值,进入锁赋值判断阶段
        if(INSTANCE == null){
            // 需要锁处理:这里就是并发部分
            synchronized(Singleton.class){
                // 需要二次判断,因为当线程1进行赋值操作时,线程2可能已经通过了第一次null判断,到这里还需要重新判断
				if(INSTANCE == null){
                    // 赋值操作
            		INSTANCE = new Singleton();
        		}
            }
        }
        
        
        return INSTANCE;
    }
    
    public static void otherMethod(){
        System.out.println("otherMethod");
    }
    
}

内部类懒汉式

我们给出内部类懒汉式构建单例模式的基本框架:

/*内部类懒汉式*/

// 属于最简洁的一种懒汉式创建方式

public class Singleton{
    
    // 构造方法
    private Singleton(){
        System.out.println("private Singleton");
    }
    
    // 内部类,用于存储单例对象(static内部类会随着类加载而加载,其单例性由JVM控制)
    private static class Holder{
        // 内部元素只有当类使用时被创建
        static Singleton INSTANCE = new Singleton();
    }
    
    // get方法调用内部类的INSTANCE
    public static Singleton getInstance(){
        return Holder.INSATNCE;
    }
    
    public static void otherMethod(){
        System.out.println("otherMethod");
    }
    
}

五种单例模式JDK体现

我们简单介绍一下JDK中使用单例模式的类:

/*饿汉式Runtime*/

public class Runtime {
    
    // 单例对象,直接创建
    private static Runtime currentRuntime = new Runtime();

    // 直接返回单例对象
    public static Runtime getRuntime() {
        return currentRuntime;
    }
    
}

/*枚举饿汉式NaturalOrderComparator*/

class Comparators {
    private Comparators() {
        throw new AssertionError("no instances");
    }

    /**
     * Compares {@link Comparable} objects in natural order.
     *
     * @see Comparable
     */
    enum NaturalOrderComparator implements Comparator<Comparable<Object>> {
        INSTANCE;

        @Override
        public int compare(Comparable<Object> c1, Comparable<Object> c2) {
            return c1.compareTo(c2);
        }

        @Override
        public Comparator<Comparable<Object>> reversed() {
            return Comparator.reverseOrder();
        }
    }
}

/*DCL懒汉式System.Console*/

class System{
    
    // Console
    private static volatile Console cons = null;
    
    // Console双检索
    public static Console console() {
         if (cons == null) {
             synchronized (System.class) {
                 cons = sun.misc.SharedSecrets.getJavaIOAccess().console();
             }
         }
         return cons;
     }
    
}

/*内部类懒汉式Collections*/

class Conllections{
    
    // emptyNavigableMap对象
    public static final <K,V> NavigableMap<K,V> emptyNavigableMap() {
        return (NavigableMap<K,V>) UnmodifiableNavigableMap.EMPTY_NAVIGABLE_MAP;
    }

    /**
     * @serial include(内部类)
     */
    private static class EmptyMap<K,V>
        extends AbstractMap<K,V>
        implements Serializable
    {
        private static final long serialVersionUID = 6428348081105594320L;

        public int size()                          {return 0;}
        public boolean isEmpty()                   {return true;}
        public boolean containsKey(Object key)     {return false;}
        public boolean containsValue(Object value) {return false;}
        public V get(Object key)                   {return null;}
        public Set<K> keySet()                     {return emptySet();}
        public Collection<V> values()              {return emptySet();}
        public Set<Map.Entry<K,V>> entrySet()      {return emptySet();}

        public boolean equals(Object o) {
            return (o instanceof Map) && ((Map<?,?>)o).isEmpty();
        }

        public int hashCode()                      {return 0;}

        // Override default methods in Map
        @Override
        @SuppressWarnings("unchecked")
        public V getOrDefault(Object k, V defaultValue) {
            return defaultValue;
        }

        @Override
        public void forEach(BiConsumer<? super K, ? super V> action) {
            Objects.requireNonNull(action);
        }

        @Override
        public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
            Objects.requireNonNull(function);
        }

        @Override
        public V putIfAbsent(K key, V value) {
            throw new UnsupportedOperationException();
        }

        @Override
        public boolean remove(Object key, Object value) {
            throw new UnsupportedOperationException();
        }

        @Override
        public boolean replace(K key, V oldValue, V newValue) {
            throw new UnsupportedOperationException();
        }

        @Override
        public V replace(K key, V value) {
            throw new UnsupportedOperationException();
        }

        @Override
        public V computeIfAbsent(K key,
                Function<? super K, ? extends V> mappingFunction) {
            throw new UnsupportedOperationException();
        }

        @Override
        public V computeIfPresent(K key,
                BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
            throw new UnsupportedOperationException();
        }

        @Override
        public V compute(K key,
                BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
            throw new UnsupportedOperationException();
        }

        @Override
        public V merge(K key, V value,
                BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
            throw new UnsupportedOperationException();
        }

        // Preserves singleton property
        private Object readResolve() {
            return EMPTY_MAP;
        }
    }
    
}

结束语

目前关于设计模式的面试点就到这里,该篇文章会持续更新~

附录

参考资料:

  1. 黑马Java八股文面试题视频教程:基础篇-56-单例模式_方式1_饿汉式_哔哩哔哩_bilibili

标签:Singleton,return,INSTANCE,汇总,面试,static,单例,设计模式,public
From: https://www.cnblogs.com/qiuluoyuweiliang/p/16940332.html

相关文章

  • 设计模式抽象工厂解析
    Provideaninterfaceforcreatingfamiliesofrelatedordependentobjectswithoutspecifyingtheirconcreteclasses.[[《DesignPatterns》]]Theabstractf......
  • 面试官本拿求素数搞我,但被我优雅的“回击“了(素数筛)
    前言现在的面试官,是无数开发者的梦魇,能够吊打面试官的属实不多,因为大部分面试官真的有那么那几下子。但在面试中,我们这些小生存者不能全盘否定只能单点突破—从某个问题上......
  • 实习面试复习
    商汤-上海IRDC-算法开发实习生根据面经复习手写Conv2dBN,LN/LSTM/GRU/Transformer一些基础手写conv2ddefcorr2d(X,K):n,m=X.shapeh,w=K.shape......
  • HashMap线程安全面试题(含答案)
    HashMap线程安全面试题(含答案)HashMap线程安全面试题(含答案)Java中平时用的最多的Map集合就是HashMap了,它是线程不安全的。看下面两个场景:1、当用在方法内的局部变量时,局部......
  • HeadFirst设计模式-模板方法模式
     模板方法模式:在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。   ***......
  • Spring 框架的设计理念与设计模式分析
     ​​https://github.com/javahongxi​​Spring作为现在最优秀的框架之一,已被广泛的使用并有很多文章分析它。本文将从另外一个视角试图剖析出Spring框架的作者设计Spring......
  • 求职指南!给数据开发的SQL面试准备路径!⛵
    ......
  • 打赌你无法解决这个Google面试题
    英文|  https://medium.com/free-code-camp/bet-you-cant-solve-this-google-interview-question-4a6e5a4dc8eeTechLead的问题在这个问题中,TechLead要求我们观察下面的......
  • 你必须要知道的JavaScript数据结构与面试题解答
    英文原文|https://dev.to/educative/7-javascript-data-structures-you-must-know-4k0m原文作者|RyanThelin和AmandaFawcett译文翻译|web前端开发(web_qdkf)解决编码......
  • 设计模式七个原则
    程序设计七大原则:1.单一职责原则设计的一个类应该专门的负责对应一件事情2.开放封闭原则一、开放封闭原则是面向对象所有原则的核心二、1.对功能扩展开放2.面向修改......