Skip to content

知识点

GIL(全局解释器锁)

GIL 是 Python(CPython)解释器中的全局解释器锁,确保同一时间只有一个线程可以执行 Python 字节码。

影响:

  • 多线程(threading 模块)在 CPU 密集型任务(如数学计算)中受限,不能并行地利用多核 CPU
  • 对于 I/O 密集型任务(如文件操作、网络请求等),多线程仍然可以提高效率,因为在 I/O 操作时线程会释放 GIL

解决方法:

  • 使用 multiprocessing 模块来创建多个进程,以实现真正的并行
  • 使用 GIL 之外的扩展模块,如 NumPy 或某些 C 扩展,它们可以绕过 GIL

迭代器和生成器

迭代器 实现了 __iter__()__next__() 方法的对象,支持逐个返回元素,直到元素耗尽时抛出 StopIteration 异常

生成器 是一种特殊的迭代器,是使用 yield 关键字定义的函数。生成器可以保存函数的运行状态,每次调用都会从上次中断的地方继续执行

区别:

  • 迭代器通过显式地定义类和方法构造,而生成器是更简洁的语法形式
  • 生成器会自动实现 __iter__()__next__() 方法,而迭代器需要手动实现

示例:

# 生成器示例
def my_generator():
    yield 1
    yield 2
    yield 3

gen = my_generator()
print(next(gen))  # 输出: 1

# 迭代器示例
class MyIterator:
    def __iter__(self):
        return self

    def __next__(self):
        if self.current > 3:
            raise StopIteration
        self.current += 1
        return self.current - 1

iter_obj = MyIterator()
iter_obj.current = 1
print(next(iter_obj))  # 输出: 1

方法类型

普通方法(实例方法)

  • 第一个参数必须是 self,用于表示实例
  • 可以访问实例对象的所有属性和方法

静态方法(@staticmethod)

  • 不接收隐式的 self 参数,也不接收 cls 参数
  • 是类中的普通函数,不能直接访问类或实例的属性和方法

类方法(@classmethod)

  • 第一个参数是 cls,表示类本身
  • 类方法可以访问类属性,或者通过类名操作类级别的信息

示例:

class MyClass:
    class_variable = "class_value"

    def instance_method(self):
        return "instance method called", self

    @classmethod
    def class_method(cls):
        return "class method called", cls

    @staticmethod
    def static_method():
        return "static method called"

# 使用实例调用普通方法
obj = MyClass()
print(obj.instance_method())

# 使用类调用类方法
print(MyClass.class_method())

# 使用类调用静态方法
print(MyClass.static_method())

装饰器

装饰器是 Python 中的一种设计模式,用于在函数运行前后扩展其功能,而不改变函数本身的实现。

核心原理: 将一个函数作为参数传递给另一个函数,然后返回一个新的函数

简单装饰器示例:

def logger(func):
    def wrapper(*args, **kwargs):
        print(f"Function {func.__name__} is being called with arguments: {args}, {kwargs}")
        result = func(*args, **kwargs)
        print(f"Function {func.__name__} returned: {result}")
        return result
    return wrapper

@logger
def add(a, b):
    return a + b

add(3, 5)

执行结果:

Function add is being called with arguments: (3, 5), {}
Function add returned: 8

垃圾回收机制

Python 使用自动垃圾回收机制回收不再使用的内存。

引用计数: 当对象的引用计数为 0 时,内存会被标记为可回收

循环引用问题:

  • 如果两个或多个对象相互引用但不被其他部分引用,比如 A 引用 B,B 引用 A,则它们的引用计数不会归 0,导致内存泄漏

解决方案:

  • Python 的垃圾回收器使用 "分代收集器" 来检测循环引用
  • 垃圾回收器会周期性地检查对象图,将不可达的循环对象也清除

示例:

import gc

class A:
    def __init__(self):
        self.ref = None

a = A()
b = A()
a.ref = b
b.ref = a

# 打破循环引用
del a
del b
gc.collect()  # 强制触发垃圾回收器

线程安全

在多线程环境中,可能会遇到多个线程同时访问共享资源的情况,从而导致线程安全问题。

解决方法: 使用锁(Lock)进行同步

示例:

import threading

counter = 0
lock = threading.Lock()

def increment():
    global counter
    # 使用锁保护临界区
    with lock:
        for _ in range(100000):
            counter += 1

threads = []
for _ in range(5):
    t = threading.Thread(target=increment)
    t.start()
    threads.append(t)

for t in threads:
    t.join()

print(counter)  # 确保线程安全,(可能输出 500000)

元类(metaclass)

元类是用于控制类的行为的 "类的类",通过定制元类可以影响类的创建过程。

核心概念:

  • 每个类本身也是对象,其类型就是元类(默认是 type
  • 自定义元类可以通过重写元类的 __new____init__ 方法,来定制类的实例化逻辑,属性检查,或者动态注入方法

典型应用场景:

  • 实现单例模式
  • 在类中自动添加某些属性
  • 检查类是否符合某些规则

示例:

class MyMeta(type):
    def __new__(cls, name, bases, dct):
        print(f"Creating class {name}")
        return super().__new__(cls, name, bases, dct)

class MyClass(metaclass=MyMeta):
    pass

# 输出: Creating class MyClass

性能优化

1. 选择合适的数据结构 使用 deque 替代列表,set 替代列表查找等

2. 使用生成器 避免创建庞大列表,改为按需生成数据

3. 内置函数 使用 mapfiltersum 等内置函数

4. 多线程和多进程 针对 I/O 密集型使用多线程,针对 CPU 密集型使用多进程

5. C 扩展库 使用 NumPycython 执行耗时计算

6. 避免过多的全局变量 减少作用域范围,加快变量查找

7. Profiling 和代码优化 使用工具(如 cProfileline_profiler)找出性能瓶颈,优化关键部分

挂载

主机:已存在的目录不会重新覆盖创建,之前的权限也不会改变
容器内:已存在的目录不会重新覆盖创建,之前的权限也不会改变

容器内修改目录权限会同步到主机


如果主机设置的只有root可读写,且容器非root运行。则读取挂载会报错