展开菜单
首页 精品内容 本月促销 装机必备 Windows PDF教程 macOS软件 IOS软件 Android AI 专题
全部分类

当前位置:

首页 > 编程开发 > Python常见100个经典面试问题总结(从入门到进阶)

Python常见100个经典面试问题总结(从入门到进阶)

Python面试中100个经典问题整理,涵盖基础语法、数据结构、函数、装饰器、异常、文件、迭代器、生成器、面向对象、并发、标准库、性能优化等,每个问题配示例代码与真实输出,便于边看边练,先思考问题再对照答案。

本文目录

    这里整理的是 Python 面试中常见的 100 个经典问题,覆盖了基础语法、数据结构、函数、装饰器、异常、文件、迭代器、生成器、面向对象、工程化、并发、标准库、性能优化等方方面面。每个问题都配上了示例代码和真实输出,方便大家边看边练。

    Python常见100个经典面试问题总结(从入门到进阶)

    前言

    Python 面试从来不是单纯看你会不会写语法,而是看你是否真正理解对象、数据结构、函数、异常、面向对象、装饰器、生成器、并发、性能、工程化以及那些常见的坑点。很多候选人代码能写出来,但只要一问到下面这些问题,就容易卡壳:

    • 为什么列表不能作为字典 key?
    • 装饰器什么时候执行?
    • is 和 == 有什么区别?
    • 线程、进程、协程怎么选?
    • GIL 到底影响什么?
    • 浅拷贝和深拷贝有什么区别?

    今天整理了 100 个 Python 高频面试问题,每个问题都配了一个小例子,方便边看边练。我个人建议的阅读方式是:先看问题,自己思考 30 秒,再看答案和代码。

    一、Python 基础语法与对象模型

    1. Python 是解释型语言吗?

    是的,Python 是解释型语言。它的代码由解释器执行源码或字节码,不需要像 C/C++ 那样提前编译成机器码。不过这不代表 Python 没有编译过程——.py 文件通常会先被编译成字节码,再由 Python 虚拟机执行。

    print("hello python")
    

    输出:

    hello python
    

    2. Python 中“一切皆对象”是什么意思?

    在 Python 里,变量、函数、类、模块、数字、字符串——所有这些都是对象。一个对象通常有三个重要特征:

    1. 身份:可以通过 id() 查看
    2. 类型:可以通过 type() 查看
    3. 值:对象保存的数据
    x = 100
    
    print(type(x))
    print(id(x))
    

    输出示例:

    
    140735568356104
    

    3. is 和 == 有什么区别?

    == 比较的是两个对象的值是否相等,而 is 比较的是两个变量是否引用同一个对象。

    a = [1, 2]
    b = [1, 2]
    
    print(a == b)
    print(a is b)
    

    输出:

    True
    False
    

    解释:

    虽然 a 和 b 的值一样,但它们是两个不同的列表对象。

    4. Python 中可变对象和不可变对象有什么区别?

    可变对象的值可以原地修改,例如:

    • list
    • dict
    • set

    不可变对象创建后不能直接修改,例如:

    • int
    • float
    • str
    • tuple
    a = [1, 2]
    a.append(3)
    print(a)
    
    s = "ab"
    s += "c"
    print(s)
    

    输出:

    [1, 2, 3]
    abc
    

    注意:字符串看起来被修改了,其实是创建了一个新的字符串对象。

    5. 为什么列表不能作为字典 key?

    因为列表是可变对象,哈希值不稳定,所以不能作为字典 key。字典的 key 必须是可哈希对象。常见可哈希对象包括:

    • 字符串
    • 数字
    • 元组
    • 布尔值
    d = {}
    
    # d[[1, 2]] = "value"  # TypeError: unhashable type: 'list'
    
    d[(1, 2)] = "value"
    
    print(d)
    

    输出:

    {(1, 2): 'value'}
    

    6. None 应该如何判断?

    推荐使用 is None,不要使用 == None。

    value = None
    
    if value is None:
        print("value is None")
    

    输出:

    value is None
    

    原因是 None 是一个单例对象,用 is 判断更准确。

    7. Python 的布尔值判断规则是什么?

    以下值通常会被判断为假:

    • None
    • False
    • 0
    • ""
    • []
    • {}
    • set()
    • tuple()
    values = ["", [], {}, 0, None, "python"]
    
    for v in values:
        print(bool(v))
    

    输出:

    False
    False
    False
    False
    False
    True
    

    8. and 和 or 返回的一定是布尔值吗?

    不一定。它们返回的是参与运算的对象本身。

    print(0 or "default")
    print("python" and "ok")
    

    输出:

    default
    ok
    

    这个特性经常用于默认值处理。

    9. Python 中变量需要声明类型吗?

    不需要。Python 是动态类型语言,变量名只是对象的引用。

    x = 1
    x = "hello"
    
    print(x)
    

    输出:

    hello
    

    10. Python 的类型注解会强制校验类型吗?

    不会。类型注解主要用于:

    • 提高代码可读性
    • 辅助 IDE 提示
    • 配合 mypy、pyright 等工具做静态检查

    Python 运行时默认不会强制校验类型。

    def add(a: int, b: int) -> int:
        return a + b
    
    print(add("1", "2"))
    

    输出:

    12
    

    虽然参数标注为 int,但运行时传入字符串也能执行。

    二、字符串、列表、元组、字典、集合

    11. 字符串如何反转?

    s = "python"
    
    print(s[::-1])
    

    输出:

    nohtyp
    

    12. 字符串拼接为什么推荐 join?

    循环中频繁使用 + 拼接字符串,会产生多个中间字符串对象,效率不高。大量字符串拼接时,推荐使用 join()。

    words = ["Python", "is", "good"]
    
    print(" ".join(words))
    

    输出:

    Python is good
    

    13. split() 和 strip() 有什么区别?

    split() 用于分割字符串,strip() 用于去除字符串首尾的空白或指定字符。

    s = "  a,b,c  "
    
    print(s.strip())
    print(s.strip().split(","))
    

    输出:

    a,b,c
    ['a', 'b', 'c']
    

    14. 列表推导式是什么?

    列表推导式是一种简洁的语法,用来生成列表。

    nums = [x * x for x in range(5)]
    
    print(nums)
    

    输出:

    [0, 1, 4, 9, 16]
    

    15. 列表推导式中如何加条件?

    nums = [x for x in range(10) if x % 2 == 0]
    
    print(nums)
    

    输出:

    [0, 2, 4, 6, 8]
    

    16. append() 和 extend() 有什么区别?

    append() 添加一个元素,extend() 则是展开可迭代对象后逐个添加。

    a = [1, 2]
    a.append([3, 4])
    print(a)
    
    b = [1, 2]
    b.extend([3, 4])
    print(b)
    

    输出:

    [1, 2, [3, 4]]
    [1, 2, 3, 4]
    

    17. list.sort() 和 sorted() 有什么区别?

    list.sort() 是原地排序,返回 None;而 sorted() 会返回一个新的列表。

    a = [3, 1, 2]
    
    b = sorted(a)
    
    print(a)
    print(b)
    
    a.sort()
    print(a)
    

    输出:

    [3, 1, 2]
    [1, 2, 3]
    [1, 2, 3]
    

    18. 元组一定不可变吗?

    元组本身不可变,但如果元组中包含可变对象,可变对象内部仍然可以修改。

    t = ([1, 2], "a")
    
    t[0].append(3)
    
    print(t)
    

    输出:

    ([1, 2, 3], 'a')
    

    19. 字典如何安全获取不存在的 key?

    使用 get() 方法。

    user = {"name": "vito"}
    
    print(user.get("age"))
    print(user.get("age", 18))
    

    输出:

    None
    18
    

    20. 字典如何遍历 key 和 value?

    user = {"name": "vito", "age": 18}
    
    for k, v in user.items():
        print(k, v)
    

    输出:

    name vito
    age 18
    

    21. 字典推导式是什么?

    d = {x: x * x for x in range(3)}
    
    print(d)
    

    输出:

    {0: 0, 1: 1, 2: 4}
    

    22. 集合有什么特点?

    集合的特点:

    1. 元素唯一
    2. 无序
    3. 适合去重
    4. 适合成员判断
    nums = [1, 2, 2, 3]
    
    print(set(nums))
    

    输出:

    {1, 2, 3}
    

    23. 集合常见运算有哪些?

    a = {1, 2, 3}
    b = {3, 4}
    
    print(a | b)
    print(a & b)
    print(a - b)
    

    输出:

    {1, 2, 3, 4}
    {3}
    {1, 2}
    

    24. 如何统计列表中元素出现次数?

    from collections import Counter
    
    items = ["a", "b", "a", "c", "b", "a"]
    
    print(Counter(items))
    

    输出:

    Counter({'a': 3, 'b': 2, 'c': 1})
    

    25. 如何取列表中间出现最多的元素?

    from collections import Counter
    
    items = ["a", "b", "a", "c", "b", "a"]
    
    print(Counter(items).most_common(1))
    

    输出:

    [('a', 3)]
    

    三、函数与参数

    26. Python 函数参数有哪些类型?

    常见参数类型包括:

    1. 位置参数
    2. 默认参数
    3. 关键字参数
    4. 可变位置参数 *args
    5. 可变关键字参数 **kwargs
    def demo(a, b=2, *args, **kwargs):
        print(a, b, args, kwargs)
    
    demo(1, 3, 4, 5, name="vito")
    

    输出:

    1 3 (4, 5) {'name': 'vito'}
    

    27. 默认参数有什么坑?

    默认参数只在函数定义时创建一次。如果默认参数是列表、字典等可变对象,可能导致数据被多次调用共享。

    def add_item(item, box=[]):
        box.append(item)
        return box
    
    print(add_item("a"))
    print(add_item("b"))
    

    输出:

    ['a']
    ['a', 'b']
    

    推荐写法:

    def add_item(item, box=None):
        if box is None:
            box = []
        box.append(item)
        return box
    
    print(add_item("a"))
    print(add_item("b"))
    

    输出:

    ['a']
    ['b']
    

    28. *args 是什么?

    *args 用于接收多余的位置参数,类型是元组。

    def total(*args):
        return sum(args)
    
    print(total(1, 2, 3))
    

    输出:

    6
    

    29. **kwargs 是什么?

    **kwargs 用于接收多余的关键字参数,类型是字典。

    def show(**kwargs):
        print(kwargs)
    
    show(name="vito", age=18)
    

    输出:

    {'name': 'vito', 'age': 18}
    

    30. Python 函数是对象吗?

    是的。函数可以赋值给变量,也可以作为参数传递。

    def hello():
        return "hello"
    
    f = hello
    
    print(f())
    

    输出:

    hello
    

    31. 什么是高阶函数?

    接收函数作为参数,或者返回函数的函数,称为高阶函数。

    def apply(func, value):
        return func(value)
    
    print(apply(abs, -10))
    

    输出:

    10
    

    32. lambda 表达式是什么?

    lambda 是匿名函数,适合简单逻辑。

    add = lambda a, b: a + b
    
    print(add(1, 2))
    

    输出:

    3
    

    实际项目中,不建议写过于复杂的 lambda。

    33. map() 怎么用?

    map() 会对可迭代对象中的每个元素应用函数。

    nums = [1, 2, 3]
    
    print(list(map(lambda x: x * 2, nums)))
    

    输出:

    [2, 4, 6]
    

    34. filter() 怎么用?

    filter() 用于过滤元素。

    nums = [1, 2, 3, 4]
    
    print(list(filter(lambda x: x % 2 == 0, nums)))
    

    输出:

    [2, 4]
    

    35. zip() 怎么用?

    zip() 会把多个可迭代对象按位置打包。

    names = ["a", "b"]
    scores = [90, 80]
    
    print(list(zip(names, scores)))
    

    输出:

    [('a', 90), ('b', 80)]
    

    四、作用域、闭包、装饰器

    36. Python 作用域查找规则是什么?

    Python 变量查找遵循 LEGB 规则:

    1. Local:局部作用域
    2. Enclosing:外层函数作用域
    3. Global:全局作用域
    4. Built-in:内置作用域
    x = "global"
    
    def outer():
        x = "outer"
    
        def inner():
            x = "inner"
            print(x)
    
        inner()
    
    outer()
    

    输出:

    inner
    

    37. global 有什么作用?

    global 用于在函数内部声明并修改全局变量。

    count = 0
    
    def inc():
        global count
        count += 1
    
    inc()
    
    print(count)
    

    输出:

    1
    

    38. nonlocal 有什么作用?

    nonlocal 用于修改外层函数作用域中的变量。

    def outer():
        count = 0
    
        def inner():
            nonlocal count
            count += 1
            return count
    
        return inner
    
    f = outer()
    
    print(f())
    print(f())
    

    输出:

    1
    2
    

    39. 什么是闭包?

    函数内部定义函数,并且内部函数引用了外部函数的变量,这种结构就是闭包。

    def make_multiplier(n):
        def mul(x):
            return x * n
    
        return mul
    
    double = make_multiplier(2)
    
    print(double(5))
    

    输出:

    10
    

    40. 什么是装饰器?

    装饰器本质上是一个函数,用于在不修改原函数代码的情况下增强功能。

    def log(func):
        def wrapper():
            print("before")
            func()
            print("after")
        return wrapper
    
    @log
    def hello():
        print("hello")
    
    hello()
    

    输出:

    before
    hello
    after
    

    41. 装饰器如何保留原函数信息?

    使用 functools.wraps。

    from functools import wraps
    
    def log(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            return func(*args, **kwargs)
        return wrapper
    
    @log
    def hello():
        """say hello"""
        print("hello")
    
    print(hello.__name__)
    print(hello.__doc__)
    

    输出:

    hello
    say hello
    

    42. 带参数的装饰器怎么写?

    from functools import wraps
    
    def repeat(n):
        def decorator(func):
            @wraps(func)
            def wrapper(*args, **kwargs):
                for _ in range(n):
                    func(*args, **kwargs)
            return wrapper
        return decorator
    
    @repeat(2)
    def say():
        print("hi")
    
    say()
    

    输出:

    hi
    hi
    

    五、异常处理

    43. Python 如何捕获异常?

    try:
        x = 1 / 0
    except ZeroDivisionError as e:
        print("error:", e)
    

    输出:

    error: division by zero
    

    44. try...except...else...finally 执行顺序是什么?

    else 在没有异常时执行,finally 无论是否异常都会执行。

    try:
        x = 10 / 2
    except ZeroDivisionError:
        print("except")
    else:
        print("else:", x)
    finally:
        print("finally")
    

    输出:

    else: 5.0
    finally
    

    45. 如何主动抛出异常?

    使用 raise。

    def check_age(age):
        if age < 0:
            raise ValueError("age cannot be negative")
        return age
    
    try:
        check_age(-1)
    except ValueError as e:
        print(e)
    

    输出:

    age cannot be negative
    

    46. 如何自定义异常?

    class BusinessError(Exception):
        pass
    
    raise BusinessError("业务异常")
    

    输出示例:

    BusinessError: 业务异常
    

    47. 为什么不要直接 except Exception: pass?

    因为这样会吞掉错误,导致问题隐藏,排查困难。

    try:
        int("abc")
    except Exception:
        print("发生异常,但这里至少要记录日志")
    

    输出:

    发生异常,但这里至少要记录日志
    

    六、文件、上下文管理器、迭代器、生成器

    48. 为什么推荐使用 with open()?

    with 会自动关闭文件,避免资源泄漏。

    with open("demo.txt", "w", encoding="utf-8") as f:
        f.write("hello")
    

    49. 什么是上下文管理器?

    实现了 __enter__ 和 __exit__ 方法的对象,就是上下文管理器。

    class Demo:
        def __enter__(self):
            print("enter")
            return self
    
        def __exit__(self, exc_type, exc, tb):
            print("exit")
    
    with Demo():
        print("running")
    

    输出:

    enter
    running
    exit
    

    50. 什么是迭代器?

    实现了 __iter__() 和 __next__() 的对象就是迭代器。

    nums = iter([1, 2, 3])
    
    print(next(nums))
    print(next(nums))
    

    输出:

    1
    2
    

    51. 什么是可迭代对象?

    能被 for 循环遍历的对象,就是可迭代对象。常见可迭代对象包括:

    • 列表
    • 元组
    • 字典
    • 字符串
    • 集合
    • 生成器
    for ch in "abc":
        print(ch)
    

    输出:

    a
    b
    c
    

    52. 什么是生成器?

    包含 yield 的函数会返回生成器。生成器会按需产生数据。

    def gen():
        yield 1
        yield 2
    
    g = gen()
    
    print(next(g))
    print(next(g))
    

    输出:

    1
    2
    

    53. 生成器有什么优点?

    生成器节省内存,适合处理大数据流。

    def numbers(n):
        for i in range(n):
            yield i
    
    for x in numbers(3):
        print(x)
    

    输出:

    0
    1
    2
    

    54. yield from 有什么作用?

    yield from 可以把子生成器的值交给外层生成器。

    def gen():
        yield from [1, 2, 3]
    
    print(list(gen()))
    

    输出:

    [1, 2, 3]
    

    55. 生成器表达式和列表推导式有什么区别?

    生成器表达式按需计算,列表推导式会一次性生成完整列表。

    g = (x * x for x in range(3))
    
    print(g)
    print(list(g))
    

    输出示例:

     at 0x...>
    [0, 1, 4]
    

    七、面向对象

    56. 类和对象有什么区别?

    类是模板,对象是类的实例。

    class User:
        pass
    
    u = User()
    
    print(type(u))
    

    输出:

    
    

    57. __init__ 是构造函数吗?

    严格来说,__init__ 是初始化方法,对象创建后会调用它。真正创建对象的是 __new__。

    class User:
        def __init__(self, name):
            self.name = name
    
    u = User("vito")
    
    print(u.name)
    

    输出:

    vito
    

    58. 实例属性和类属性有什么区别?

    实例属性属于对象,类属性属于类。

    class User:
        role = "tester"
    
    u1 = User()
    u2 = User()
    
    u1.name = "vito"
    
    print(u1.role)
    print(u2.role)
    print(u1.name)
    

    输出:

    tester
    tester
    vito
    

    59. 类方法、静态方法、实例方法有什么区别?

    实例方法默认接收 self,类方法默认接收 cls,静态方法不自动接收对象或类。

    class Demo:
        def ins(self):
            print("instance")
    
        @classmethod
        def cls_method(cls):
            print("class")
    
        @staticmethod
        def static_method():
            print("static")
    
    d = Demo()
    
    d.ins()
    Demo.cls_method()
    Demo.static_method()
    

    输出:

    instance
    class
    static
    

    60. 什么是继承?

    子类可以复用父类的属性和方法。

    class Animal:
        def speak(self):
            print("animal speak")
    
    class Dog(Animal):
        pass
    
    Dog().speak()
    

    输出:

    animal speak
    

    61. 什么是方法重写?

    子类重新定义父类方法,就是方法重写。

    class Animal:
        def speak(self):
            print("animal")
    
    class Dog(Animal):
        def speak(self):
            print("wang")
    
    Dog().speak()
    

    输出:

    wang
    

    62. super() 有什么作用?

    super() 用于调用父类方法。

    class Base:
        def hello(self):
            print("base hello")
    
    class Child(Base):
        def hello(self):
            super().hello()
            print("child hello")
    
    Child().hello()
    

    输出:

    base hello
    child hello
    

    63. Python 支持多继承吗?

    支持。方法解析顺序由 MRO 决定。

    class A:
        def hello(self):
            print("A")
    
    class B(A):
        pass
    
    class C(A):
        def hello(self):
            print("C")
    
    class D(B, C):
        pass
    
    D().hello()
    print(D.mro())
    

    输出示例:

    C
    [, , , , ]
    

    64. 什么是魔术方法?

    以双下划线开头和结尾的方法,例如:

    • __str__
    • __repr__
    • __len__
    • __call__
    • __enter__
    • __exit__
    class User:
        def __str__(self):
            return "User object"
    
    print(User())
    

    输出:

    User object
    

    65. __repr__ 和 __str__ 有什么区别?

    __str__ 面向用户,输出更友好;__repr__ 面向开发者和调试。

    class User:
        def __repr__(self):
            return "User(name='vito')"
    
    u = User()
    
    print(repr(u))
    

    输出:

    User(name='vito')
    

    66. @property 有什么作用?

    @property 可以把方法当属性访问,同时封装计算逻辑。

    class Circle:
        def __init__(self, r):
            self.r = r
    
        @property
        def area(self):
            return 3.14 * self.r * self.r
    
    c = Circle(2)
    
    print(c.area)
    

    输出:

    12.56
    

    67. 什么是 dataclass?

    dataclass 可以自动生成 __init__、__repr__ 等方法,适合定义数据类。

    from dataclasses import dataclass
    
    @dataclass
    class User:
        name: str
        age: int
    
    u = User("vito", 18)
    
    print(u)
    

    输出:

    User(name='vito', age=18)
    

    68. __slots__ 有什么作用?

    __slots__ 可以限制实例动态添加属性,同时也能减少内存开销。

    class User:
        __slots__ = ("name",)
    
    u = User()
    u.name = "vito"
    
    print(u.name)
    
    # u.age = 18  # AttributeError
    

    输出:

    vito
    

    八、模块、包、虚拟环境、工程化

    69. 模块和包有什么区别?

    一个 .py 文件就是一个模块。包含多个模块的目录加上 __init__.py 就可以作为一个包。

    # demo.py
    def hello():
        return "hello"
    

    使用:

    # import demo
    # print(demo.hello())
    

    70. if __name__ == "__main__" 有什么作用?

    判断当前文件是被直接运行,还是被其他模块导入。直接运行时执行 main(),导入时则不会。

    def main():
        print("running main")
    
    if __name__ == "__main__":
        main()
    

    直接运行输出:

    running main
    

    71. Python 如何管理第三方依赖?

    常用 pip 安装依赖,并推荐使用虚拟环境。

    python -m venv .venv
    source .venv/bin/activate
    pip install requests
    

    Windows PowerShell:

    python -m venv .venv
    ..venvScriptsActivate.ps1
    pip install requests
    

    72. requirements.txt 有什么用?

    requirements.txt 用于记录项目依赖,方便环境复现。

    requests==2.32.3
    pytest==8.3.2
    

    安装依赖:

    pip install -r requirements.txt
    

    73. pyproject.toml 是什么?

    pyproject.toml 是现代 Python 项目常见配置文件,可以配置项目信息、构建系统以及各种工具的设置。

    [project]
    name = "demo"
    version = "0.1.0"
    
    [tool.pytest.ini_options]
    testpaths = ["tests"]
    

    74. Python 如何读取环境变量?

    import os
    
    os.environ["APP_ENV"] = "dev"
    
    print(os.getenv("APP_ENV"))
    

    输出:

    dev
    

    75. __all__ 有什么作用?

    __all__ 用于控制 from module import * 时会导出哪些名字。

    __all__ = ["hello"]
    
    def hello():
        print("hello")
    
    def hidden():
        print("hidden")
    

    九、并发、线程、进程、协程

    76. 线程适合什么场景?

    线程适合 IO 密集型任务,例如网络请求、文件读写、数据库访问、接口调用等。

    import threading
    import time
    
    def task(name):
        time.sleep(1)
        print(name, "done")
    
    t1 = threading.Thread(target=task, args=("A",))
    t2 = threading.Thread(target=task, args=("B",))
    
    t1.start()
    t2.start()
    
    t1.join()
    t2.join()
    

    输出:

    A done
    B done
    

    77. 什么是 GIL?

    GIL 是 CPython 中的全局解释器锁。它会限制多个线程同时执行 Python 字节码,所以 CPU 密集型任务通常无法通过多线程获得明显性能提升。

    def cpu_task():
        return sum(i * i for i in range(100000))
    
    print(cpu_task())
    

    输出:

    333328333350000
    

    78. 进程适合什么场景?

    进程适合 CPU 密集型任务。多进程可以利用多核 CPU。

    from multiprocessing import Pool
    
    def square(x):
        return x * x
    
    if __name__ == "__main__":
        with Pool(2) as pool:
            print(pool.map(square, [1, 2, 3]))
    

    输出:

    [1, 4, 9]
    

    79. 为什么 Windows 下多进程要写 if __name__ == "__main__"?

    因为 Windows 创建子进程时会重新导入主模块,如果不加保护,可能导致子进程重复创建子进程。

    from multiprocessing import Process
    
    def hello():
        print("hello")
    
    if __name__ == "__main__":
        p = Process(target=hello)
        p.start()
        p.join()
    

    输出:

    hello
    

    80. 协程适合什么场景?

    协程适合高并发 IO 场景,例如网络请求、WebSocket、异步数据库、异步爬虫、高并发接口调用等。

    import asyncio
    
    async def main():
        print("start")
        await asyncio.sleep(1)
        print("end")
    
    asyncio.run(main())
    

    输出:

    start
    end
    

    81. async 和 await 是什么?

    async 用于定义协程函数,await 用于等待异步操作完成。

    import asyncio
    
    async def fetch():
        await asyncio.sleep(1)
        return "data"
    
    async def main():
        result = await fetch()
        print(result)
    
    asyncio.run(main())
    

    输出:

    data
    

    82. 如何并发运行多个协程?

    使用 asyncio.gather()。

    import asyncio
    
    async def task(name):
        await asyncio.sleep(1)
        return f"{name} done"
    
    async def main():
        result = await asyncio.gather(task("A"), task("B"))
        print(result)
    
    asyncio.run(main())
    

    输出:

    ['A done', 'B done']
    

    83. time.sleep() 和 asyncio.sleep() 有什么区别?

    time.sleep() 会阻塞当前线程,asyncio.sleep() 会让出事件循环,不阻塞其他协程。

    import asyncio
    
    async def task():
        await asyncio.sleep(1)
        print("done")
    
    asyncio.run(task())
    

    输出:

    done
    

    84. 如何避免多个线程同时修改共享数据?

    可以使用锁。

    import threading
    
    count = 0
    lock = threading.Lock()
    
    def inc():
        global count
        for _ in range(10000):
            with lock:
                count += 1
    
    threads = [threading.Thread(target=inc) for _ in range(2)]
    
    for t in threads:
        t.start()
    
    for t in threads:
        t.join()
    
    print(count)
    

    输出:

    20000
    

    十、常用标准库与实战能力

    85. collections.defaultdict 有什么用?

    defaultdict 可以给不存在的 key 自动创建默认值。

    from collections import defaultdict
    
    d = defaultdict(list)
    
    d["python"].append("good")
    
    print(d)
    

    输出:

    defaultdict(, {'python': ['good']})
    

    86. deque 适合什么场景?

    deque 是双端队列,适合从两端快速添加和删除元素。

    from collections import deque
    
    q = deque([1, 2])
    
    q.appendleft(0)
    q.append(3)
    
    print(q)
    

    输出:

    deque([0, 1, 2, 3])
    

    87. heapq 有什么用?

    heapq 可以实现堆,常用于 Top K、优先队列、小顶堆等场景。

    import heapq
    
    nums = [5, 1, 3]
    
    heapq.heapify(nums)
    
    print(heapq.heappop(nums))
    

    输出:

    1
    

    88. json.dumps() 和 json.loads() 有什么区别?

    json.dumps() 把 Python 对象转成 JSON 字符串,json.loads() 把 JSON 字符串转成 Python 对象。

    import json
    
    s = json.dumps({"name": "vito"}, ensure_ascii=False)
    print(s)
    
    obj = json.loads(s)
    print(obj["name"])
    

    输出:

    {"name": "vito"}
    vito
    

    89. 如何处理 Decimal 不能直接 JSON 序列化的问题?

    可以转换为字符串或浮点数。如果是金额、精度敏感场景,建议转换为字符串。

    import json
    from decimal import Decimal
    
    data = {"price": str(Decimal("10.50"))}
    
    print(json.dumps(data))
    

    输出:

    {"price": "10.50"}
    

    90. pathlib 相比 os.path 有什么好处?

    pathlib 是面向对象的路径处理方式,路径拼接更直观。

    from pathlib import Path
    
    p = Path("logs") / "app.log"
    
    print(p)
    

    输出:

    logs/app.log
    

    91. 如何读取 CSV 文件?

    import csv
    
    rows = [["name", "score"], ["vito", "90"]]
    
    with open("score.csv", "w", newline="", encoding="utf-8") as f:
        writer = csv.writer(f)
        writer.writerows(rows)
    
    with open("score.csv", encoding="utf-8") as f:
        reader = csv.DictReader(f)
        for row in reader:
            print(row)
    

    输出:

    {'name': 'vito', 'score': '90'}
    

    92. 如何记录日志?

    import logging
    
    logging.basicConfig(level=logging.INFO)
    
    logging.info("service started")
    

    输出示例:

    INFO:root:service started
    

    93. 如何写单元测试?

    def add(a, b):
        return a + b
    
    def test_add():
        assert add(1, 2) == 3
    

    使用 pytest 运行:

    pytest test_demo.py
    

    输出示例:

    1 passed in 0.01s
    

    94. pytest.raises 怎么用?

    import pytest
    
    def div(a, b):
        return a / b
    
    def test_div_zero():
        with pytest.raises(ZeroDivisionError):
            div(1, 0)
    

    输出示例:

    1 passed in 0.01s
    

    十一、性能、内存、编码规范

    95. 如何查看对象占用内存?

    import sys
    
    a = [1, 2, 3]
    
    print(sys.getsizeof(a))
    

    输出示例:

    88
    

    具体数值和 Python 版本、操作系统有关。

    96. 如何优化大列表处理?

    能用生成器就不要一次性创建大列表。

    total = sum(x * x for x in range(1000000))
    
    print(total)
    

    输出:

    333332833333500000
    

    97. 浅拷贝和深拷贝有什么区别?

    浅拷贝只复制外层对象,深拷贝会递归复制内部对象。

    import copy
    
    a = [[1, 2], [3, 4]]
    
    b = copy.copy(a)
    c = copy.deepcopy(a)
    
    a[0].append(99)
    
    print(b)
    print(c)
    

    输出:

    [[1, 2, 99], [3, 4]]
    [[1, 2], [3, 4]]
    

    98. with 为什么比手动 close() 更安全?

    因为即使中间发生异常,with 也会执行资源释放逻辑。

    try:
        with open("demo.txt", "r", encoding="utf-8") as f:
            print(f.read())
    except FileNotFoundError:
        print("file not found")
    

    输出示例:

    hello
    

    或者:

    file not found
    

    99. Python 代码规范主要看什么?

    常见关注点包括:命名清晰、函数不要太长、异常不要乱吞、不要写重复代码、复杂逻辑拆函数、遵循 PEP 8 风格、加必要的类型注解、加必要的单元测试。

    def calculate_total_price(price: float, count: int) -> float:
        return price * count
    
    print(calculate_total_price(9.9, 3))
    

    输出:

    29.700000000000003
    

    如果涉及金额,建议使用 Decimal。

    100. 面试中如何回答“你怎么提升 Python 代码质量”?

    可以从以下几个方面回答:使用类型注解提升可读性;使用 pytest 编写单元测试;使用 logging 记录关键日志;使用异常处理保证程序稳定;使用虚拟环境隔离依赖;使用 requirements.txt 或 pyproject.toml 管理依赖;使用 black、ruff、mypy 等工具做代码检查;使用 CI 流水线自动执行测试和代码扫描;复杂逻辑模块化;性能敏感代码做 profiling 分析。

    from typing import Sequence
    
    def a verage(nums: Sequence[float]) -> float:
        if not nums:
            raise ValueError("nums cannot be empty")
        return sum(nums) / len(nums)
    
    print(a verage([80, 90, 100]))
    

    输出:

    90.0
    

    十二、总结:Python 面试不是背答案,而是建立知识网络

    回过头来看,这 100 个问题其实可以归纳为 8 条主线:

    1. 基础语法:变量、对象、类型、真假判断
    2. 数据结构:字符串、列表、元组、字典、集合
    3. 函数能力:参数、闭包、装饰器、高阶函数
    4. 面向对象:类、继承、魔术方法、属性管理
    5. 异常与资源:异常捕获、上下文管理器、文件处理
    6. 并发模型:线程、进程、协程、GIL、锁
    7. 标准库:json、csv、pathlib、logging、collections
    8. 工程质量:虚拟环境、依赖管理、测试、类型注解、代码规范

    真正的面试重点不是“你是否见过这个问题”,而是你能否用清晰的语言说明原理,并写出可靠的小例子。最好的准备方式是:每个问题都自己敲一遍代码,观察真实输出,尝试修改参数和边界条件,主动制造异常场景,把问题串成知识体系。当你能把一个知识点讲清楚、写明白、举出例子,并能说出常见坑点时,面试基本就稳了一半。

    附:面试复习建议

    如果你准备 Python 面试,可以按下面顺序复习:

    第一阶段:基础语法

    重点掌握:变量、类型、判断、循环、字符串、列表、字典、集合。

    第二阶段:函数和对象

    重点掌握:参数传递、默认参数坑点、闭包、装饰器、类、继承、魔术方法。

    第三阶段:工程能力

    重点掌握:虚拟环境、pip、requirements.txt、pyproject.toml、日志、异常、单元测试。

    第四阶段:进阶能力

    重点掌握:迭代器、生成器、上下文管理器、多线程、多进程、协程、GIL、性能优化。

    第五阶段:项目表达

    面试时不要只说“我会 Python”,而要结合项目讲:我用 Python 做过什么、解决了什么问题、遇到过什么坑、如何排查问题、如何提升效率、如何保证代码质量。

    例如:

    我在自动化测试平台中使用 Python 编写接口测试脚本,通过 pytest 管理测试用例,结合 logging 输出关键日志,并使用 requests 封装接口调用。对于复杂业务场景,我会把公共逻辑抽成工具函数或类,同时通过 fixture 管理测试数据,提升了用例复用性和维护性。

    这样的回答,比单纯背语法更有说服力。

    参考方向

    本文内容主要围绕 Python 常见面试点整理,建议进一步阅读:Python 官方文档、Python Tutorial、Python Data Model、Python Standard Library、pytest 官方文档、Python Packaging 官方文档、asyncio 官方文档、threading 官方文档、multiprocessing 官方文档。

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发 Python
    相关文章 更多
    精品专题 更多
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    macOS软件

    正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

    IOS软件

    正软商城iOS软件专区,精选适用于iPhone和iPad的办公、学习、影音、设计、效率及AI应用,提供功能介绍、适用设备、系统要求和正版获取方式等信息。

    AI

    正软商城AI软件专区,汇集AI写作、AI绘画、AI视频、AI办公、AI编程、AI翻译、智能客服和数据分析等人工智能工具,提供功能介绍、适用平台、收费方式及正版购买信息。

    Mac软件 更多
    Postman macOS版
    Postman macOS版

    Postman是一套面向API全生命周期的开发与测试平台,可在Mac上发送和调试多种协议请求,管理集合、环境及认证信息,并完成脚本测试、模拟服务、监控、文档发布和团队协作。它适合开发、测试及运维人员使用,提供个人免费方案。

    Docker Desktop macOS版
    Docker Desktop macOS版

    Docker Desktop 是 Docker 官方为 Mac 提供的容器开发环境,集成 Docker Engine、命令行工具、Compose、Build、Kubernetes 与图形化管理界面。

    Android Studio macOS版
    Android Studio macOS版

    Android Studio 是 Google 面向安卓应用开发提供的官方集成开发环境,基于 IntelliJ IDEA 构建。它整合智能代码编辑、Gradle 构建、界面预览、设备模拟、性能分析、调试测试及 APK 分析等工具。

    Xcode macOS版
    Xcode macOS版

    Xcode 是苹果面向 Mac 提供的官方集成开发环境,将代码编辑、项目构建、SwiftUI 实时预览、设备模拟、自动化测试、断点调试、性能分析和应用分发整合在同一套工作流中,适合开发与维护 iPhone、iPad、Mac、Apple Wa

    JetBrains WebStorm macOS版
    JetBrains WebStorm macOS版

    JetBrains WebStorm 是面向 JavaScript、TypeScript 和现代 Web 技术的专业集成开发环境,可智能理解项目结构,提供代码补全、重构、错误检查、运行调试、测试及 Git 工具。

    PhpStorm macOS版
    PhpStorm macOS版

    PhpStorm 是 JetBrains 推出的专业 PHP 集成开发环境,可在 Mac 上完成代码编写、智能检查、重构、调试、测试和数据库管理。它支持主流 PHP 框架、Composer、Git、Docker 与远程解释器。

    JetBrains PyCharm macOS版
    JetBrains PyCharm macOS版

    JetBrains PyCharm 是面向 Python 开发者的集成开发环境,提供智能补全、代码检查、重构、调试、测试、版本控制及虚拟环境管理功能。Mac 版兼容 Intel 与 Apple 芯片,核心功能可免费使用。

    JetBrains IntelliJ IDEA macOS版
    JetBrains IntelliJ IDEA macOS版

    IntelliJ IDEA 是 JetBrains 推出的专业集成开发环境,重点服务于 Java、Kotlin 与 JVM 项目开发。软件集成代码补全、静态检查、重构、调试、测试、版本控制及构建工具,并可借助插件扩展语言和框架支持。

    Visual Studio Code macOS版
    Visual Studio Code macOS版

    Visual Studio Code 是微软提供的免费代码编辑器,支持 macOS,并为 Intel 与 Apple 芯片 Mac 提供适配版本。软件集代码编辑、调试、Git 源代码管理、集成终端和扩展市场于一体。

    REAPER macOS版
    REAPER macOS版

    REAPER是Cockos开发的数字音频工作站,提供多轨音频与MIDI录制、剪辑、处理、混音和母带制作工具。Mac版兼容Intel与Apple芯片,支持AU、VST、VST3、CLAP等插件格式,并提供高度可定制的工作流程。

    Adobe Audition macOS版
    Adobe Audition macOS版

    Adobe Audition 是面向播客、影视后期、音乐制作及内容创作者的专业音频工作站,提供波形精修、多轨录制与混音、频谱编辑、降噪修复、响度匹配和效果处理工具,并可与 Adobe Premiere 协同完成视频声音制作。

    Pro Tools macOS版
    Pro Tools macOS版

    Pro Tools 是 Avid 推出的专业数字音频工作站,覆盖多轨录音、无损剪辑、MIDI 编曲、插件处理、自动化混音及声音与画面同步等工作。它拥有 Intro、Artist、Studio 和 Ultimate 等方案。

    WINDOWS 更多
    PixPix 网页版
    PixPix 网页版

    PixPix 是面向品牌、卖家和内容团队的在线 AI 图片视频创作平台,提供图视频 Agent、无限画布、图片生成、视频生成、自然语言编辑及商品套图、产品精修和带货视频等电商工具。

    Postman Windows版
    Postman Windows版

    Postman 是面向 API 全生命周期的开发与协作平台。Windows 桌面版可用于构建和发送 HTTP、GraphQL、gRPC、WebSocket、MQTT 等请求,并提供环境变量、集合、脚本测试、模拟服务、监控、文档及团队工作区等

    Docker Desktop Windows版
    Docker Desktop Windows版

    Docker Desktop 为 Windows 开发者提供集成式容器环境,内置 Docker Engine、命令行工具、Compose、Build 与 Kubernetes 等组件,可在本机完成镜像构建、容器运行、日志查看和资源管理。

    Android Studio Windows版
    Android Studio Windows版

    Android Studio 是 Google 面向 Android 应用开发提供的官方集成开发环境,以 IntelliJ IDEA 为基础,集成智能代码编辑、Gradle 构建、设备模拟、界面预览、调试测试及性能分析工具,

    JetBrains WebStorm Windows版
    JetBrains WebStorm Windows版

    WebStorm 是 JetBrains 面向 JavaScript、TypeScript 和现代 Web 技术打造的集成开发环境。它提供项目级代码分析、智能补全、安全重构、导航搜索,并集成调试、测试、终端、Git 与常用前端工具,

    JetBrains PhpStorm Windows版
    JetBrains PhpStorm Windows版

    PhpStorm 是 JetBrains 面向 PHP 与现代 Web 开发打造的专业集成开发环境,提供代码补全、静态检查、重构、调试、测试、数据库、版本控制及前端语言支持。Windows 用户可直接下载安装程序,

    JetBrains PyCharm Windows版
    JetBrains PyCharm Windows版

    PyCharm 是 JetBrains 推出的 Python 集成开发环境,提供智能代码补全、错误检查、重构、调试、测试、Git、终端及 Jupyter Notebook 支持。统一版安装后可体验 30 天 Pro 功能,

    JetBrains IntelliJ IDEA Windows版
    JetBrains IntelliJ IDEA Windows版

    JetBrains IntelliJ IDEA 是以 Java、Kotlin 和 JVM 项目为核心的专业集成开发环境,提供智能补全、代码检查、安全重构、调试、测试、版本控制及构建工具集成。统一发行版的核心功能可免费用于商业和非商业项目,

    Visual Studio Code Windows版
    Visual Studio Code Windows版

    Visual Studio Code 是微软推出的免费代码编辑器,Windows 版集成智能补全、代码导航、调试、终端和版本控制,并可通过扩展添加语言、格式化及远程开发能力。它启动较快、配置灵活,

    REAPER Windows版
    REAPER Windows版

    REAPER 是 Cockos 推出的数字音频工作站,适用于录音、MIDI 编曲、音频编辑、混音、母带制作及声音设计。软件安装包小巧,支持多轨录制、灵活路由、自动化、第三方插件和脚本扩展,并提供完整功能的 60 天免费评估期。

    Adobe Audition Windows版
    Adobe Audition Windows版

    Adobe Audition 是面向播客、影视后期、广播与音乐制作的专业音频工作站,提供波形编辑、多轨混音、频谱分析、录音、降噪修复和效果处理等功能。Windows 版通过 Adobe Creative Cloud 安装和管理,

    Pro Tools Windows版
    Pro Tools Windows版

    Pro Tools 是 Avid 推出的专业数字音频工作站,提供多轨录音、音频剪辑、MIDI编曲、插件处理、自动化混音及影视声音制作能力。它适合音乐人、录音师、制作人和音频后期团队使用,并提供免费入门版、订阅方案及永久授权选择。