当前位置:

首页 > 编程开发 > 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
相关文章 更多
langgraph python guide中文入门教程详解
langgraph python guide中文入门教程详解

本篇LangGraph Python中文入门教程详解,系统梳理StateGraph状态机定义、节点编写、边与条件路由、检查点持久化(MemorySaver)等核心机制,提供从环境安装到完整循环智能体构建的代码示例与实操指导。

Windows 安装 Python:从官方入口到虚拟环境的可复现实践
Windows 安装 Python:从官方入口到虚拟环境的可复现实践

面向后端开发者,基于 Python 官方文档说明如何在 Windows 上安装 Python、创建 venv 虚拟环境及使用 pip 管理依赖。包含可复制命令、验证方法及工具选择边界,避免常见配置误区。

Windows系统Python安装教程:下载、勾选PATH及环境变量配置
Windows系统Python安装教程:下载、勾选PATH及环境变量配置

针对Windows初学者的Python安装实战指南。详细讲解如何从Python官网下载匹配架构的安装包,重点演示安装首屏勾选“Add python.exe to PATH”的关键操作,并提供使用python --version和py命令验证环境变量的具体步骤,帮助新手快速搭建开发环境并排查路径问题。

Python安装后怎么打开:使用IDLE或命令行启动解释器
Python安装后怎么打开:使用IDLE或命令行启动解释器

刚在Windows安装好Python却不知道如何启动?本文详细演示如何通过开始菜单找到并打开IDLE集成开发环境,以及如何在PowerShell或命令提示符中使用python和py命令启动交互式解释器、运行.py脚本文件。包含退出解释器的方法及常见启动问题排查,帮助初学者快速验证安装成功并开始编写代码。

了解Python编程领域中最好的就业行业
了解Python编程领域中最好的就业行业

了解Python编程领域中最好的就业行业导语:近年来,Python作为一种易学易用的编程语言,越来越受到企业和开发者的青睐。在Python编程领域中,有许多就业机会,涵盖了各个行业。本文将介绍一些Python编程领域中最好的就业行业,并提供相应的代码示例。数据科学和机器学习数据科学和机器学习是Python编程领域中最热门的行业之一。Python在数据科学和机

python处理csv文件的方法完整实用教程
python处理csv文件的方法完整实用教程

针对Python处理CSV文件时常见的编码报错、内存溢出和数据类型错误,本文对比标准库csv与Pandas库的适用场景,提供可复制的代码示例和因果排查思路,帮助开发者选择最优处理方案。

python字典怎么按值排序用sorted函数实现升降序
python字典怎么按值排序用sorted函数实现升降序

本文介绍如何使用Python的sorted函数对字典按值进行升序和降序排序,结合具体代码示例和应用场景,帮助读者理解排序逻辑及其在数据处理中的实际价值。

python正则匹配修改方法与代码实现教程
python正则匹配修改方法与代码实现教程

深入讲解Python中使用re.sub进行正则匹配与替换的技巧,涵盖基础语法、分组引用及回调函数应用,帮助开发者解决复杂字符串修改需求,提升代码效率与可维护性。

selenium中文安装包下载与安装教程
selenium中文安装包下载与安装教程

详解Selenium在Python环境下的安装步骤,包括使用pip安装库文件、下载对应版本的浏览器驱动以及验证安装是否成功,适合自动化测试初学者参考。

skyvern官网入口及中文版使用教程
skyvern官网入口及中文版使用教程

Skyvern是一款基于大语言模型的开源浏览器自动化框架,目前仅提供英文界面且无官方中文版。本文指导用户通过GitHub获取源码,使用Docker快速部署本地环境,并解释其如何通过DOM树解析与自然语言指令实现网页自动操作,同时提供针对中文用户的配置建议与替代方案。

查看更多
精品专题 更多
装机必备
装机必备

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

Windows
Windows

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

PDF教程
PDF教程

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

Mac软件 更多
Postman macOS版
Postman macOS版
Mac

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

Docker Desktop macOS版
Docker Desktop macOS版
Mac

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

Android Studio macOS版
Android Studio macOS版
Mac

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

WINDOWS 更多
PixPix 网页版
PixPix 网页版
Windows

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

Postman Windows版
Postman Windows版
Windows

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

Docker Desktop Windows版
Docker Desktop Windows版
Windows

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