Skip to main content

Python

一、基础与数据结构

  1. Python 中的变量是如何绑定内存对象的?
    1. 名称绑定机制:变量是名称,绑定到对象,而非值本身
    2. 动态类型: 变量可以随时绑定不同类型的对象。
    3. 引用计数: Python内部使用引用计数管理内存
    4. 对象复用: 小整数、短字符串等常用对象可能会被复用
    5. 一切皆对象: 函数、类、模块等都是对象,变量都只是引用
  2. Python 中浅拷贝和深拷贝的区别?
    1. 浅拷贝: 创建一个新对象,不复制嵌套对象,新对象中嵌套部分仍然只想原始对象中的引用
    2. 深拷贝: 创建一个新对象,并递归复制所有嵌套对象,新对象与原始对象完全独立。
  3. 如何判断两个变量是否引用同一个对象?
    • 使用is运算符(判断是否是同一个对象)
    • == 判断两个对象的值是否相等
  4. 请实现一个栈和队列的数据结构。
    # 栈先进后出
    Class Stack:
    def __init__(self):
    self._data = []

    def push(self, item):
    self._data.append(item)

    def pop(self):
    if self.is_empty():
    raise IndexError("pop from empty stack")
    return self._data.pop()

    def peek(self):
    if self.is_empty():
    raise IndexError("peek from empty stack")
    return self._data[-1]

    def is_empty(self):
    return len(self._data) == 0

    def size(self):
    return len(self._data)

    s = Stack()
    s.push(1)
    s.push(2)
    print(s.pop()) #2
    print(s.peek()) #1
    # 队列是先进先出
    from collections import deque
    Class Queue
    def __init__(self):
    self._data = deque()

    def enqueue(self, item):
    self._data.append(item)

    def dequeue(self):
    if self.is_empty():
    raise.IndexError("dequeue from empty queue")
    return self._data.popleft()

    def front(self):
    if self.is_empty():
    raise IndexError("peek from empty queue")
    return self._data[0]

    def is_empty(self):
    return self._data == 0

    def size(self):
    return len(self._data)
    q = Queue()
    q.enqueue(10)
    q.enqueue(20)
    print(q.dequeue()) # 10
    print(q.front()) # 20
  5. Python 中字符串是不可变类型,它是如何优化性能的?
    • 字符串驻留
    • 可哈希
    • 安全性
    • 内存复用
    • join优化拼接

二、函数与作用域

  1. Python 中的 LEGB 规则是什么?
    1. 什么是LEGB?
      顺序作用域类型描述
      LLocal当前函数内部的局部作用域
      EEnclosing外部嵌套函数的作用域(闭包)
      GGlobal当前模块的全局作用域
      BBuilt-inPython 内置作用域,如 len()print()
  2. globalnonlocal 有什么区别?
    1. global: 全局作用域,可修改目标变量
    2. nonlocal: 用于外层函数的局部作用域,用于闭包使用
  3. 解释闭包(closure)及其应用。
    1. 基础:闭包通常在函数式编程、装饰器、回调函数等使用
    2. 场景:
      • 延迟计算(懒加载)
      • 数据封装(私有变量)
      • 装饰器内部函数
  4. 编写一个函数缓存(memoization)装饰器
    • 用于缓存函数调用的记过,提高性能,适用于递归或重复计算的函数
  5. Python 中默认参数的陷阱及其避免方式?
    • 默认参数只在函数定义时被计算一次,尤其是可变类型(如list、dict),会导致多次调用函数时共用同一个对象。

三、面向对象编程

  1. Python 中类变量与实例变量的区别?
    1. 类变量: 类体内、方法体外,被所有实例共享
    2. 实例变量: 通常在__init__中定义,每个实例独有,互不干扰。
  2. 如何实现抽象类和接口?有哪些用途?
    1. 使用abc模块中的ABC和@abstractmethod装饰器来定义抽象类和接口
  3. 如何使用 super() 调用父类方法?
    • super用来调用父类(或祖先类)的方法内置函数,用于多继承和子类重写方法时保留父类行为。
  4. Python 中 __slots__ 的作用是什么?
    • __slots__是一个用于限制实例属性的特殊机制
    • 作用:
      1. 节省内存
      2. 限制属性动态添加
  5. 请实现一个简单的事件派发系统(支持订阅和发布)
    class EventDispatcher:
    def __init__(self):
    self._listeners = {}

    def subscribe(self, event_name, callback):
    """订阅某个事件"""
    if event_name not in self._listeners:
    self._listeners[event_name] = []
    self._listeners[event_name].append(callback)

    def unsubscribe(self, event_name, callback):
    """取消订阅某个事件"""
    if event_name in self._listeners:
    self._listeners[event_name] = [cb for cb in self._listeners[event_name] if cb != callback]

    def dispatch(self, event_name, *args, **kwargs):
    """发布事件并传递数据给订阅者"""
    if event_name in self._listeners:
    for callback in self._listeners[event_name]:
    callback(*args, **kwargs)

    def on_user_registered(username):
    print(f"User registered: {username}")

    def on_send_welcome_email(username):
    print(f"Sending welcome email to {username}")

    # 创建事件派发器
    dispatcher = EventDispatcher()

    # 订阅事件
    dispatcher.subscribe("user_registered", on_user_registered)
    dispatcher.subscribe("user_registered", on_send_welcome_email)

    # 派发事件
    dispatcher.dispatch("user_registered", "Alice")
    # 输出:
    # User registered: Alice
    # Sending welcome email to Alice

    # 取消订阅
    dispatcher.unsubscribe("user_registered", on_user_registered)
    dispatcher.dispatch("user_registered", "Bob")
    # 输出:
    # Sending welcome email to Bob

四、模块与包管理

  1. __init__.py 的作用是什么?
    1. 将目标表示为包: 当一个目录包含__init__.py文件时,才会将该目录识别为一个"包",从而允许你用模块导入语法访问其中的模块
    2. 用途:
      1. 生命包
      2. 初始化逻辑
      3. 统一接口
      4. 保持兼容性
  2. Python 模块导入时的搜索路径如何确定?
    • 使用sys.path的构成
  3. 什么是相对导入和绝对导入?使用场景?
    • 绝对导入
      • 定义:使用模块的完整路径来导入模块,从项目的根包开始写起
      • 格式: 直接从顶层包开始写路径
    • 相对导入
      • 定义: 通过当前模块所在的包的位置,使用点(.)表示相对路径进行导入。
      • 格式:
        • .表示当前目录(当前包)
        • ..表示上一级包
        • ...表示上上级包,以此类推
  4. 如何使用 importlib 动态导入模块?
    # 字符串导入模块
    import importlib
    module_name = "math" # 也可以是自己项目里的模块名
    module = imortlib.import_module(module_name)
    print(module.sqrt(16)) # 4.0
    # 动态导入子模块
    mod = importlib.import_module("mypackage.submodule")

五、异常与上下文管理

  1. Python 中异常处理流程是怎样的?
    执行try块代码
    |
    出现异常? -----> 是 ----> 是否有匹配的except? ----> 是 ----> 执行except块
    | |
    否 否
    | |
    执行else块 异常向上层传播
    | |
    执行finally块 <---------------------- 直到捕获或程序终止
  2. 使用 contextlib 实现一个上下文管理器。
    import contextlib
    @contextlib.contextmanager
    def my_context():
    print("开始")
    try:
    yield
    finally:
    print("结束")

    with my_context():
    print("上下文中的代码执行")

    # 结果
    开始
    上下文中的代码执行
    结束

六、函数式编程

  1. 什么是高阶函数?哪些是典型例子?
    1. 高阶函数(以函数为参数或返回函数的函数):
      1. 接受一个或多个函数作为参数
      2. 返回一个函数作为结果
  2. mapreducefilter 的用途和区别?
    1. map: 对iterable中的每个元素应用函数func,返回一个新的迭代器
    2. filter: 保留iterable中所有满足func(x)为True的元素
    3. reduce: 将iterable中的元素两两规约为一个值,需要从functools模块导入
  3. 什么是偏函数?如何用 functools.partial 实现?
    • 偏函数是指固定(预先设置)一个函数的部分参数,返回一个新的函数,这个新函数可以像原函数一样继续传入剩余的参数

七、并发与异步编程

  1. GIL 的存在意味着什么?
    • 全局解释器锁,是CPython中的一个机制,它对Python多线程的并行执行带来了重要的影响
    • 定义和作用: GIL是一个互斥锁,确保同一时刻只有一个线程在执行Python字节码
  2. 多线程适合什么场景?多进程又适合什么场景?
    • 多线程: IO密集型任务,轻量并发
    • 多进程: CPU密集型任务,充分利用多核
  3. 使用 threading.Lock() 实现线程安全计数器
    import threading
    class SafeCounter:
    def __init__(self):
    self.count = 0
    self.locak = threading.Lock()

    def increment(self):
    with self.lock:
    self.count += 1

    def get_count(self):
    with self.lock:
    return self.count
    def worker(counter, num_items):
    for _ in range(num_items):
    counter.increment()

    if __name__ == '__main__':
    counter = SafeCounter()
    threads = []
    for _ in range(10): # 启动10个线程
    t = threading.Thread(target=worker, args=(counter, 10000))
    threads.append(t)
    t.start()
    for t in threads:
    t.join()
    print("Final count is:", counter.get_count()) # 预期值应为 10 * 10000 = 100000
  4. Python 中的 Queue、Event、Semaphore 是做什么用的?
    1. Queue ———— 线程/进程安全的队列(用于通信):
      • 线程安全(queue.Queue)或进程安全(multiprocessing.Queue)的数据结构,常用于线程/进程之间的数据传递
        • 生产者-消费者模式
        • 线程/进程间通信
      from queue import Queue
      from threading import Thread

      q = Queue()

      def producer():
      for i in range(5):
      q.put(i)
      print(f"Produced {i}")

      def consumer():
      while True:
      item = q.get()
      if item is None:
      break
      print(f"Consumed {item}")
      q.task_done()

      t1 = Thread(target=producer)
      t2 = Thread(target=consumer)
      t1.start()
      t2.start()
      t1.join()
      q.put(None) # 结束信号
      t2.join()
    2. Event ———— 通知机制(用于线程同步)
      • .set(): 设置标志位True
      • .clear(): 清除标志位为False
      • .wait(timeout): 阻塞直到标志为True
      from threading import Thread, Event
      import time

      event = Event()

      def wait_for_event():
      print("Waiting for event...")
      event.wait()
      print("Event triggered!")

      Thread(target=wait_for_event).start()
      time.sleep(2)
      print("Sending event signal...")
      event.set()
    3. Semaphore — 控制并发数量(信号量)
      from threading import Thread, Semaphore
      import time
      sem = Semaphore(2)
      def limited_access(name):
      print(f"{name} waiting to enter...")
      with sem:
      print(f"{name} entered")
      time.sleep(2)
      print(f"{name} exiting")

      for i in range(5):
      Thread(target=limited_access, args=(f"Thread-{i}",)).start()

八、标准库与工具库模块

  1. collections 中常用的结构有哪些?如何用?
    1. namedtupe: 有字段名的元组(类字典 + 轻量对象)
      from collections import namedtuple

      Point = namedtuple('Point', ['x', 'y'])
      p = Point(1, 2)
      print(p.x, p.y) # 1 2
      print(p._asdict()) # {'x': 1, 'y': 2}
    2. deque ————双端队列(适合频繁插入/删除)
      from collections import deque
      d = deque([1, 2, 3])
      d.appendleft(0)
      d.append(4)
      print(d) # deque([0, 1, 2, 3, 4])
      d.pop() # 4
      d.popleft() # 0
    3. Counter ————多用途计数器
      from collections import Counter
      c = Counter('abracdafdasfdas')
      print(c) # Counter({'a': 5, 'd': 3, 'f': 2, 's': 2, 'b': 1, 'r': 1, 'c': 1})
      print(c.most_common(2)) # [('a', 5), ('d', 3)]
    4. OrderedDict ————记住顺序插入的字典
      from collections import OrderedDict
      od = OrderedDict()
      od['apple'] = 1
      od['banana'] = 2
      print(list(od.keys))
    5. defaultdict ———— 不存在的键返回默认值
      from collections import defaultdict
      d = defaultdict(int)
      d['a'] += 1
      print(d['a']) # 1
      print(d['b'])# 0(自动返回 int(),即 0)
    6. ChainMap ———— 多个字典合并视图(适合配置合并)
      from collections import ChainMap
      dict1 = {'a':1}
      dict2 = {'b':2, 'a':3}
      cm = ChainMap(dict1, dict2)
      print(cm['a']) # 1
      print(cm['b']) # 2
  2. 如何使用 itertools 实现组合/排列生成?
    1. permutations:所有元素的全排列或指定长度排列,有序
    2. combinations: 生成组合,如何无序,不能重复,r参数必须指定itertools.combinations(iterable, r)
    3. combinations_with_replacement: 允许元素重复选择(和顺序无关), itertools.combinations_with_replacement(iterable, r)
    4. product: 多项式排列,类似于嵌套循环,支持可重复排列
  3. 使用 datetime 实现一个倒计时器。
    import time
    from datetime import timedelta

    def countdown(seconds):
    while seconds:
    td = str(timedelta(seconds=seconds))
    print(f"\rCountdown: {td}", end="")
    time.sleep(1)
    seconds -= 1
    print("\rCountdown: 00:00:00 ✅ Time's up!")
    # 倒计时10秒
    countdown(10)
  4. subprocess 模块如何执行系统命令并获取结果?
    import subprocess
    result = subprocess.run(["ls", "-l"], capture_output=True, text=True)
    print("Return code:", result.returncode)
    print("STDOUT:\n", result.stdout)
    print("STDERR:\n", result.stderr)
    # capture_output=True 表示捕获标准输出和错误
    # text=True 表示以字符串形式返回(否则是bytes)
  5. pathlib 相比 os.path 有什么优势?
    • pathlib: 提供了PATH类,用对象方法替代了杂乱的函数式调用,不用处理分隔符"","/"
    • os.path: 需要处理不同系统的分隔符,

九、性能优化与调试

  1. 如何使用 timeit 测量函数性能?
    场景方法
    测量代码字符串执行时间timeit.timeit('code', number=N)
    测量函数执行时间(推荐)timeit.timeit(func, number=N)
    命令行快速测试python -m timeit 'expression'
    精细控制时间/自动选择次数timeit.Timer(...).autorange()

十、设计模式

  1. 单例模式
    # 使用类变量保存实例
    class Singleton:
    _instance = None

    def __new__(cls, *args, **kwargs):
    if cls._instance is None:
    cls._instance = super().__new__(cls)
    return cls._instance
    a = Singleton()
    b = Singleton()
    print(a is b) # True
    # 使用装饰器实现单例
    def singleton(cls):
    instances = {}
    def wrapper(*args, **kwargs):
    if cls not in instances:
    instances[cls] = cls(*args, **kwargs)
    return instances[cls]
    return wrapper
    @singleton
    class MyClass:
    pass
    a = MyClass()
    b = MyClass()
    print(a is b)
    # 元类方式实现单例
    class SingletonMeta(type):
    _instances = {}
    def __call__(self, *args, **kwargs):
    if self not in self._instances:
    self._instances[self] = super().__call__(*args, **kwargs)
    return self._instances[self]
    class MyClass1(metaclass=SingletonMeta):
    pass
    a = MyClass1()
    b = MyClass1()
    print(a is b) # True
  2. 实现观察者模式、策略模式、工厂模式。
    # 观察者模式
    # 订阅者
    from abc import ABC, abstractmethod
    class Subject():
    def __init__(self):
    self._observers = []
    def subscribe(self, observer):
    self._observers.append(observer)
    def unsubscribe(self, observer):
    self._observers.remove(observer)
    def notify(self, message):
    for observer in self._observers:
    observer.update(message)
    # 观察者
    class Observer(ABC):
    @abstractmethod
    def update(self, message):
    pass
    # 具体实现
    class ConcreateObserver(Observer):
    def __init__(self, name):
    self.name = name

    def update(self, message):
    print(f'{self.name} received message: {message}')
    # 调用
    subject = Subject()
    a = ConcreateObserver("ObserverA")
    b = ConcreateObserver("ObserverB")
    subject.subscribe(a)
    subject.subscribe(b)
    subject.notify("Event occurred")
    # 策略模式
    from abc import ABC, abstractmethod
    # 接口
    class Strategy(ABC):
    @abstractmethod
    def execute(self, a, b):
    pass
    # 具体策略
    class AddStrategy(Strategy):
    def execute(self, a, b):
    return a + b
    class SubStrategy(Strategy):
    def execute(self, a, b):
    return a - b
    # 使用上下文选择策略模式
    class Calculator:
    def __init__(self, strategy: Strategy):
    self.strategy = strategy
    def set_strategy(self, strategy: Strategy):
    self.strategy = strategy
    def calculate(self, a, b):
    return self.strategy.execute(a, b)
    # 调用
    clac = Calculator(AddStrategy())
    print(clac.calculate(3, 4))
    clac.set_strategy(SubStrategy())
    print(clac.calculate(3, 4))
    # 工厂模式
    from abc import ABC, abstractmethod
    class Shape(ABC):
    @abstractmethod
    def draw(self):
    pass
    class Circle(Shape):
    def draw(self):
    print("Drawing a circle")
    class Square(Shape):
    def draw(self):
    print("Drawing a square")
    class ShapeFactory:
    @staticmethod
    def create_shape(shape_type: str) -> Shape:
    if shape_type == 'circle':
    return Circle()
    elif shape_type == 'square':
    return Square()
    else:
    raise ValueError(f"Unknown shape type {shape_type}")
    shape = ShapeFactory.create_shape("circle")
    shape.draw() # 输出: Drawing a circle
  3. 使用装饰器模式为函数添加行为。
    # 装饰器
    # 类实现装饰器
    class MyDecorator:
    def __init__(self, func):
    self.func = func
    def __call__(self, *args, **kwargs):
    print("装饰器前操作")
    result = self.func(*args, **kwargs)
    print("装饰器后操作")
    return result
    @MyDecorator
    def say_hello(name):
    print(f"Hello, {name}!")
    say_hello("Alice")
    class Repeat:
    def __init__(self, times):
    self.times = times # 装饰器的参数
    def __call__(self, func):
    def wrapper(*args, **kwargs):
    for _ in range(self.times):
    func(*args, **kwargs)
    return wrapper
    @Repeat(3)
    def greet():
    print("Hello!")
    greet()
  4. 使用责任链模式组织业务逻辑流程。
    from typing import Optional
    class Handler:
    def __init__(self):
    self._next: Optional['Handler'] = None
    def set_next(self, handler: 'Handler') -> 'Handler':
    self._next = handler
    return handler
    def handler(self, request: dict):
    if self._next:
    return self._next.handler(request)
    return True
    class AuthHandler(Handler):
    def handler(self, request: dict):
    if not request.get("user"):
    print("认证失败:未提供用户信息")
    return False
    print("认证通过")
    return super().handler(request)
    class ValidateHandler(Handler):
    def handler(self, request: dict):
    if "data" not in request:
    print("校验失败:缺少参数")
    return False
    print("校验通过")
    return super().handler(request)
    class PermissionHandler(Handler):
    def handler(self, request: dict):
    if request.get("user") != "admin":
    print("权限不足")
    return False
    print("校验通过")
    return super().handler(request)
    auth = AuthHandler()
    validate = ValidateHandler()
    permission = PermissionHandler()
    auth.set_next(validate).set_next(permission)
    # 发起请求
    request = {"user": "admin", "data": {"id": 1}}
    result = auth.handler(request)
    print("请求处理结果:", result)

十一、高级主题

  1. Python 的元类(metaclass)是什么?能干什么?
    1. 元类是什么:

      • 示例是由类创建的
      • 类是由元类创建的
    2. 作用:

      1. 控制类的创建行为(比如修改类属性、注入方法等)
      2. 实现自动注册机制(如插件系统、ORM模型注册等)
      3. 校验类是符合某种规则(如是否实现某种方法、变量)
      4. 代码增强(自动添加装饰器、日志等)
      名称描述
      实例由类创建的对象
      由元类创建,定义实例的行为
      元类控制类的创建过程(默认是 type
      作用动态控制类结构、注册、增强逻辑等
  2. 描述 CPython 的内存管理机制。
    1. 总体机制概览CPython使用私有的内存管理机制,其核心包括:
      模块/机制作用说明
      引用计数主机制,自动管理对象的生命周期。
      垃圾回收(GC)用于处理引用计数无法检测的“循环引用”。
      内存池(PyMalloc)避免频繁向操作系统申请/释放内存,提高性能。
      ┌─────────────┐
      │ Python对象 │
      └─────────────┘
      ┌────────────┼─────────────┐
      ▼ ▼
      引用计数(主) 垃圾回收 GC(辅)
      ┌──────────┴──────────┐
      ▼ ▼
      循环引用检查 分代回收策略(0/1/2)
  3. Python 中的协程与 greenlet 的区别?
    1. 基本定义
      对比点协程(Coroutine)greenlet
      核心模块asyncio(Python3.5+内建)greenlet(第三方库)
      本质使用 awaitasync def 的异步函数更底层的“微线程”切换
      调度方式事件循环调度(自动)手动切换(程序员控制)
      是否标准库✅ 是(asyncio❌ 不是(需安装:pip install greenlet
  4. 什么是 monkey patch?有何风险?
    1. 什么是猴子补丁
      • 在运行时修改或替换类、模块、函数的行为。
      • 不需要访问或修改原始定义文件。

实战类:

  1. 实现一个 LRU 缓存装饰器。
    from collections import OrderedDict
    from functools import wraps
    def lru_cache(maxsize=128):
    def decorator(func):
    cache = OrderedDict()
    @wraps(func)
    def wrapper(*args):
    if args in cache:
    cache.move_to_end(args) # 标记为最近使用
    return cache[args]
    result = func(*args)
    cache[args] = result
    if len(cache) > maxsize:
    cache.popitem(last=False) # 移除最久未使用
    return result
    return wrapper
    return decorator
    # 调用:
    @lru_cache(maxsize=3)
    def slow_square(n):
    print(f"Computing square({n})")
    return n * n
    print(slow_square(2))
    print(slow_square(3))
    print(slow_square(2)) # 命中缓存
    print(slow_square(4))
    print(slow_square(5)) # 会触发淘汰旧的缓存
  2. 实现一个简单的任务调度器。
    import time
    import threading
    class TaskScheduler:
    def __init__(self):
    self.tasks = []
    self.running = False
    def add_task(self, func, delay, repeat=False):
    '''
    注册任务
    :param func:要执行的函数
    :param delay:延迟(秒)
    :param repeat:是否重复执行(周期性任务)
    :return:
    '''
    task = {
    'func': func,
    'delay': delay,
    'repeat': repeat,
    }
    self.tasks.append(task)
    def _run_task(self, task):
    task['func']()
    if task['repeat'] and self.running:
    task['timer'] = threading.Timer(task['delay'], self._run_task, [task])
    task['timer'].start()
    def start(self):
    self.running = True
    for task in self.tasks:
    task['timer'] = threading.Timer(task['delay'], self._run_task, [task])
    task['timer'].start()
    def stop(self):
    self.running = False
    for task in self.tasks:
    if task['timer']:
    task['timer'].cancel()
    def say_hello():
    print(f"Hello! Time: {time.strftime('%X')}")
    def print_heartbeat():
    print(f"Heartbeat at {time.strftime('%X')}")
    scheduler = TaskScheduler()
    scheduler.add_task(say_hello, delay=2, repeat=False) # 执行一次
    scheduler.add_task(print_heartbeat, delay=1, repeat=True) # 每秒执行一次
    print("任务调度器启动")
    scheduler.start()
    # 运行 5 秒后停止调度器
    time.sleep(5)
    scheduler.stop()
    print("调度器已停止")
  3. 编写一个支持插件加载的命令行工具。
    • 基础命令行功能(支持argparse)
    • 插件为Python脚本,可动态加载
    • 插件定义自己的命令和处理逻辑
  4. 实现一个带访问统计的 Web API 装饰器。
    from flask import Flask, jsonify, request
    from functools import wraps
    app = Flask(__name__)
    # 全局访问计数器
    visit_counts = {}
    def count_visit(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
    route = request.endpoint
    visit_counts[route] = visit_counts.get(route, 0) + 1
    return func(*args, **kwargs)
    return wrapper
    @app.route('/hello')
    @count_visit
    def hello():
    return "hello, visitor!"
    @app.route('/visits')
    def visits():
    return jsonify(visit_counts)
    if __name__ == '__main__':
    app.run(debug=True)
  5. 实现一个简易 ORM(对象关系映射)模型。

1. 数据结构与算法

  1. 解释Python中的列表、元组、集合和字典的区别及适用场景。
    1. 列表:有序、增删改频繁、索引查找、可变元素、支持重复元素(队列、堆栈等)
    2. 元组:不可变、有序、包含任意类型、保持插入顺序、支持重复元素(存储不便元素,常量集合等)
    3. 集合: 无序、可变、元素必须是哈希、不支持索引访问,只能迭代(适合判断成员是否存在、集合运算(交集、并集、差集))
    4. 字典: 可变、键是哈希类型,保持插入顺序,键可以重复值不行,快速查找(JSON数据结构等,引用与各种数据映射)
  2. 实现一个函数,找出一个字符串中第一个不重复的字符,时间复杂度要求O(n)。
    def first_non_repeating_char(s:str):
    char_count = {}

    # 第一次遍历,统计字符频率
    for ch in s:
    char_count[ch] = char_count.get(ch, 0) + 1
    # 第二次遍历
    for ch in s:
    if char_count[ch] ==1:
    return ch
    return None; # 没有不重复字符时返回None

2. Python语言特性

  1. 什么是Python的生成器(generator),和迭代器(iterator)有什么区别?
    1. 迭代器
      • 迭代器是一个实现了迭代协议的对象
      • 迭代协议要求对象必须实现两个方法
        • __iter__(): 返回迭代器本身
        • __next__(): 返回序列的下一个元素,如果没有元素则抛出StopIteration异常
    2. 生成器
      • 带有yield关键字的函数,每次遇到yield暂停,返回一个值,下次从暂停处继续执行.
      • 生成器函数调用后返回一个生成器对象(生成器是迭代器的一种)