前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >设计模式面试点汇总

设计模式面试点汇总

作者头像
秋落雨微凉
发布于 2022-12-07 07:36:08
发布于 2022-12-07 07:36:08
24000
代码可运行
举报
运行总次数:0
代码可运行

设计模式面试点汇总

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

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

  • 单例模式

单例模式

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

五种单例模式实现方式

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

饿汉式

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/*饿汉式*/

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类破坏单例对象是无法阻止的!!!
    
}
枚举饿汉式

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/*枚举*/

enum Sex{
    MALEFAMALE;
}

/*枚举饿汉式*/

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/*懒汉式*/

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懒汉式构建单例模式的基本框架:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/*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");
    }
    
}
内部类懒汉式

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/*内部类懒汉式*/

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

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中使用单例模式的类:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/*饿汉式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
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-12-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
史上最全讲解单例模式以及分析源码中的应用
1、单例模式介绍所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法(静态方法)。比如Hibernate 的SessionFactory,它充当数据存储源的代理,并负责创建Session 对象。SessionFactory 并不是轻量级的,一般情况下,一个项目通常只需要一个SessionFactory 就够,这是就会使用到单例模式。2、单例模式的种类饿汉式(静态常量)饿汉式(静态代码块)懒汉式(线程不安全)懒汉式(线程安全,同步
小熊学Java
2022/09/04
3930
23设计模式之 --------- 单例模式
单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
默 语
2024/11/20
820
23设计模式之 --------- 单例模式
02.创建型:单例设计模式2
创建型:单例设计模式2目录介绍01.如何实现一个单例02.饿汉式实现方式03.懒汉式实现方式04.双重DCL校验模式05.静态内部类方式06.枚举方式单例07.容器实现单例模式01.如何实现一个单例介绍如何实现一个单例模式的文章已经有很多了,但为了保证内容的完整性,这里还是简单介绍一下几种经典实现方式。概括起来,要实现一个单例,我们需要关注的点无外乎下面几个:构造函数需要是 private 访问权限的,这样才能避免外部通过 new 创建实例;考虑对象创建时的线程安全问题;考虑是否支持延迟加载;考虑 getI
杨充
2022/09/08
2730
c 线程安全的单例模式-单例模式(6大类):如何保证线程安全?反射安全?序列化安全?
单例模式属于创建型模式,保证了单例类在系统中仅存在一个实例。能够避免频繁创建某个对象,在一定程度上可以减少内存占用。
宜轩
2022/12/29
5270
设计模式(一):Android 源码中的单例模式
单例模式(Singleton) 是最常见也最简单的设计模式,它的目的就是在全局只生成一个类的实例。
Frank909
2020/07/30
9530
设计模式(一):Android 源码中的单例模式
设计模式-单例模式
模式定义 确保一个类最多只有一个实例,并提供一个全局访问点。 单例模式分为饿汉式和懒汉式。 懒汉式单例模式:在类加载时不初始化。 饿汉式单例模式:在类加载时就完成了初始化,所以类加载比较慢,但获取对象的速度快。 饿汉式-线程安全 1 /** 2 * 饿汉式单例模式(线程安全) 3 */ 4 public class Singleton { 5 //static单例变量 6 private static Singleton singleton = new Singleton()
武培轩
2018/04/18
5580
图图细谈设计模式——单例模式
图图在为面试做准备,今天图图给大家细说一番单例模式。其实最简单的是工厂模式而不是单例(工厂后续会说)
一头小山猪
2020/04/10
3460
详解设计模式:单例模式
单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
栗筝i
2022/12/02
3850
设计模式系列 - 单例模式
我不知道大家工作或者面试时候遇到过单例模式没,面试的话我记得我当时在17年第一次实习的时候,就遇到了单例模式,面试官是我后来的leader,当时就让我手写单例,我记得我就写出了饿汉式,懒汉式,但是并没说出懒汉和饿汉的区别,当时他给我一通解释我才知道了其中的奥秘。
敖丙
2021/03/09
4930
设计模式系列 - 单例模式
02、人人都会设计模式--单例模式
一个男人只能有一个媳妇「正常情况」,一个人只能有一张嘴,通常一个公司只有一个 CEO ,一个狼群中只有一个狼王等等
TigerChain
2019/07/22
5140
02、人人都会设计模式--单例模式
设计模式-单例模式
单例模式是保证系统实例唯一性的重要手段。单例模式首先通过将类的实例化方法私有化来防止程序通过其他方式创建该类的实例,然后通过提供一个全局唯一获取该类实例的方法帮助用户获取类的实例,用户只需要也只能通过调用该方法获取类的实例。
别团等shy哥发育
2023/10/17
2910
摸鱼设计模式——单例模式
饿汉式单例,无论是否使用,都直接初始化。其缺点则是会浪费内存空间。因为假如整个实例都没有被使用,那么这个类依然会创建,这就白创建了。
摸鱼-Sitr
2021/01/04
6740
摸鱼设计模式——单例模式
Java设计模式之单例模式
这个模式是很有意思,而且比较简单,但是我还是要说因为它使用的是如此的广泛,如此的有人缘,单例就是单一、独苗的意思,那什么是独一份呢?你的思维是独一份,除此之外还有什么不能山寨的呢?我们举个比较难复制的对象:皇帝,中国的历史上很少出现两个皇帝并存的时期,是有,但不多,那我们就认为皇帝是个单例模式,在这个场景中,有皇帝,有大臣,大臣是天天要上朝参见皇帝的,今天参拜的皇帝应该和昨天、前天的一样(过渡期的不考虑,别找茬哦),大臣磕完头,抬头一看,嗨,还是昨天那个皇帝,单例模式,绝对的单例模式,先看类图:
CoderJed
2018/09/13
3800
Java设计模式之单例模式
设计模式-单例模式
单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。
Anymarvel
2018/10/22
3960
设计模式(二)单例模式Singleton(创建型)
几乎所有面向对象的程序中,总有一些类的对象需要是唯一的,例如,通过数据库句柄到数据库的连接是独占的。您希望在应用程序中共享数据库句柄,因为在保持连接打开或关闭时,它是一种开销。再如大家最经常用的IM,如QQ,在同一台电脑,一个帐号只能有唯一的登录。
黄规速
2022/04/14
2410
设计模式(二)单例模式Singleton(创建型)
设计模式 | 单例模式及典型应用
单例是最常见的设计模式之一,实现的方式非常多,同时需要注意的问题也非常多。要内容:
小旋锋
2019/01/21
1K0
设计模式 - 单例模式
不管怎么跑都是一个,但是 LazyMan = new LazyMan();在极端情况下是有问题的,因为他不是一个原子性操作。
断痕
2021/01/21
4020
设计模式 - 单例模式
钻钻 “单例” 的牛角尖
上篇文章 走进 JDK 之 Enum 提到过,枚举很适合用来实现单例模式。实际上,在 Effective Java 中也提到过(果然英雄所见略同):
路遥TM
2021/08/31
4560
设计模式(1)-单例模式
单例模式,是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例。即一个类只有一个对象实例。
秦子帅
2019/06/06
3950
设计模式(1)-单例模式
设计模式:单例模式
单例模式是一种 **创建型设计模式**,确保一个类 **只有一个实例**,并提供一个 **全局访问点** 来获取该实例。它的核心目标是控制对象的创建过程,避免资源重复占用或状态不一致。
用户11531739
2025/03/04
900
相关推荐
史上最全讲解单例模式以及分析源码中的应用
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文