• 【Java面试】快手面试遭遇滑铁卢:Java中的单例模式如何实现 满分回答快拿走


    “在Java中实现单例模式有哪些方法”!

    屏幕前的你们,是不是感觉这个问题很简单。

    但是实际上,有一个同学曾经去快手面试的时候,被更进一步问到。

    写一个性能最好的单例模式,结果很显然就没有回答出来

    大家好,我是Mic,一个工作了14年的Java程序员

    这个问题,面试官想考察什么呢?

    考察目的

    这是属于设计模式里面的一个问题。

    我们知道Java有23种设计模式,但是真正在实际开发中,能够熟练使用设计模式的人很少。

    很多人说没有场景,但其实只是因为他们只理解了设计模式的概念。

    这个问题考察求职者对于设计模式的理解和应用。

    本质上还是考察基本功,当然,针对不同工作年限,考察的深度不同。

    对于刚工作的同学,只需要了解什么是单例以及如何写出一个单例就行

    对于工作年限较长的同学,还需要考察单例模式的性能、以及避免破坏单例的情况等

    问题解析

    单例模式,就是一个类在任何情况下绝对只有一个实例,并且提供一个全局访问点来获取该实例。

    要实现单例,至少需要满足两个点:

    • 私有化构造方法,防止被外部实例化造成多实例问题

    • 提供一个静态方位作为全局访问点来获取唯一的实例对象

    在Java里面,至少有6种方法来实现单例。

    第一种,是最简单的实现,通过延迟加载的方式进行实例化,并且增加了同步锁机制避免多线程环境下的线程安全问题。

    但是这种加锁会造成性能问题,而且同步锁只有在第一次实例化的时候才产生作用,后续不需要。

    于是有了第二种改进方案,通过双重检查锁的方式,减少了锁的范围来提升性能

    第三种,通过饿汉式实现单例。

    这种方式在类加载的时候就触发了实例化,从而避免了多线程同步问题。

    还有一种与这个方式类似的实现通过在静态块里面实例化,而静态块是在类加载的时候触发执行的,所以也只会执行一次。

    上面两种方式,都是在类加载的时候初始化,没有达到延迟加载的效果,当然本身影响不大,但是

    其实还是可以更进一步优化,就是可以在使用的时候去触发初始化。

    像这种写法,把INSTANCE写在一个静态内部类里面,由于静态内部类只有调用静态内部类的方法,静态域,或者构造方法的时候才会加载静态内部类。

    所以当Singleton被加载的时候不会初始化INSTANCE,从而实现了延迟加载。

    另外,我们还可以使用枚举类来实现。

    这种写法既能避免多线程同步问题,又能防止反序列化重新创建新对象,也是一个比较好的方案。

    当然,除了这些方案以外,也许还有更多的写法,只需要满足单例模式的特性就行了。

    高手:

    我认为可以通过3种方式来实现单例,第一种是通过双重检查锁的方式,它是一种线程安全并且是延迟实例化的方式,但是因为加锁,所以会有性能上的影响。

    第二种是通过静态内部类的方式实现,它也是一种延迟实例化,由于它是静态内部类,所以只会使用的时候加载一次,不存在线程安全问题。

    第三种是通过枚举类的方式实现,它既是线程安全的,又能防止反序列化导致破坏单例问题。

    但是,多线程、克隆、反序列化、反射,都有可能会造成单例的破坏。

    而我认为,通过枚举的方式实现单例,是能够解决所有可能被破坏的情况。

    总结

    下次面试的时候遇到这个问题,大家知道怎么回答了吗?

    如果你喜欢我的作品,记得点赞收藏加关注哦!!!

    另外,我将所有Java面试系列制作成了完整的面试文档。它的便捷之处在于,可以通过检索的方式,找到你想要的面试题,目前已经更新200期,总计超过20W字!

    【想领取面试文档的小伙伴可以点击文章底部名片无套路免费赠送给大家!】

    需要高手面试文档面试文档的小伙伴可以扫描下方二维码
    ↓↓↓↓↓↓↓↓↓↓↓↓↓

  • 相关阅读:
    使用VCPKG编译并使用Qt5
    SSM框架学习记录-Spring_day01
    java boolean占用内存是多少
    计算机毕业设计ssm二手房纪经人房屋管理系统85bvk系统+程序+源码+lw+远程部署
    Java面向对象设计 - Java泛型约束
    SpringBoot+Mybaits搭建通用管理系统实例十:基础增删改查功能实现下
    如何查看Pyinstaller生成的exe程序使用的是哪个Python虚拟环境?
    【IoT】卫朋:6000+ 字解读 | 2022年产品人必备的7个产品管理工具(1.0版)
    2023-9-1-虚拟网卡学习
    【JAVA】LinkedList与链表(Part1)
  • 原文地址:https://blog.csdn.net/q331464542/article/details/127105881