学习之面试题:单例模式

什么是单例模式?

单例模式是一种设计模式,它保证一个类仅有一个实例,并提供一个全局访问点用于访问该实例。其主要目的是控制共享资源的访问。

为什么我们需要单例模式?

单例模式可以用于控制资源的消耗,避免频繁创建和销毁对象,同时也可以简化系统配置,使得某些类的对象在整个系统中具有唯一的实例,比如日志对象、数据库连接等。

如何在 Python 中实现单例模式?

python 复制代码
下面是一些常见的实现方式:

方法一:使用模块
Python 模块本身就是单例的,所以在一个模块中定义的类可以被多个脚本共享。

方法二:使用 __new__ 方法
重写类的 __new__ 方法来控制实例的创建过程,确保只创建一次实例。

class Singleton(object):
    _instance = None

    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
        return cls._instance

singleton_instance = Singleton()


方法三:使用装饰器
可以创建一个装饰器来管理单例逻辑。

def singleton(cls):
    instances = {}
    def get_instance(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    return get_instance

@singleton
class MyClass(object):
    pass

my_instance = MyClass()
方法四:使用元类(MetaClass)
利用Python的元编程特性来控制类的行为。

class Singleton(type):
    _instances = {}
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
        return cls._instances[cls]

class MyClass(metaclass=Singleton):
    pass

my_instance = MyClass()


方法五:使用线程局部存储(Thread Local Storage)
如果需要在多线程环境中使用单例,可以考虑使用 threading.local 来保证线程安全。


import threading

class Singleton(object):
    _instance_lock = threading.Lock()
    _instance = None

    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            with cls._instance_lock:
                if not cls._instance:
                    cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
        return cls._instance

singleton_instance = Singleton()

在多线程环境中如何保证单例模式的安全性?

在多线程环境中,为了防止多个线程同时进入 if instance is None 判断条件的情况,可以使用锁机制(如 threading.Lock() 或 threading.RLock())来确保线程安全。

单例模式有哪些优缺点?

优点:

控制实例的产生,节省系统资源。

提供了一个全局访问点,方便获取对象实例。

缺点:

违背了单一职责原则,将类的实例化与业务逻辑混在一起。

增加了系统的复杂度,降低了程序的可测试性。

过度使用会导致系统难以理解和维护。

你能给出一个简单的单例模式实现的例子吗?

python 复制代码
Python
深色版本
class Singleton:
    _instance = None

    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance

# 使用例子
s1 = Singleton()
s2 = Singleton()
assert s1 is s2

单例模式是否适用于所有情况?

不一定,单例模式的应用场景有限,通常用于那些需要频繁访问且创建成本较高的对象。在现代软件开发中,依赖注入和 IoC 容器等技术逐渐成为更好的替代方案。

相关推荐
西岸行者5 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意5 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码6 天前
嵌入式学习路线
学习
毛小茛6 天前
计算机系统概论——校验码
学习
babe小鑫6 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms6 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下6 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。6 天前
2026.2.25监控学习
学习
im_AMBER6 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J6 天前
从“Hello World“ 开始 C++
c语言·c++·学习