学习之面试题:单例模式

什么是单例模式?

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

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

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

如何在 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 容器等技术逐渐成为更好的替代方案。

相关推荐
橙橙笔记8 分钟前
Python学习第三部分
开发语言·python·学习
weixin_4316004410 分钟前
Agent Workflow 学习向:最小拖拽画布,看得见地编排,再一键跑通
后端·学习·ai·dify
很楠爱上24 分钟前
从“AI 看合同”到可举证的合同决策链:CounterClause(对薄) 的架构设计与工程实践
人工智能·经验分享·python·学习·agent
爱奥尼欧27 分钟前
14.输出解析器-Pydantic与JSON
人工智能·学习·langchain·json
存在morning30 分钟前
【PySpark 学习笔记 四】DataFrame 进阶:窗口函数、高级聚合与复杂类型
笔记·学习
山甫aa1 小时前
日志技术 Logback + Slf4j —— 从零开始的 Web 后端学习
java·后端·学习·web·logback
炎武丶航1 小时前
汽车功能测试学习(2):LDW车道偏离预警
功能测试·学习·汽车
Logintern091 小时前
【AGV】openTCS学习
学习·物流·agv
wzq11_6661 小时前
云计算运维学习day22——Ansible-Roles
运维·学习·云计算
minglie11 小时前
espidf的esp32版的websocketServer
学习