Python 面试题精选
所属阶段:附录
建议学习时间:持续复习
重要程度:⭐⭐⭐⭐⭐
一、基础语法(初级)
1.1 变量与数据类型
Q1:Python 有哪些基本数据类型?
python
# 数值类型
int_num = 42
float_num = 3.14
complex_num = 1 + 2j
# 字符串
string = "Hello Python"
# 布尔类型
bool_val = True
# 空值
none_val = None
# 容器类型
list_val = [1, 2, 3]
tuple_val = (1, 2, 3)
dict_val = {'key': 'value'}
set_val = {1, 2, 3}
Q2:可变类型 vs 不可变类型?
python
# 不可变类型(值不可修改)
immutable = (int, float, str, tuple, frozenset, bool, None)
# 可变类型(值可修改)
mutable = (list, dict, set, bytearray)
# 示例
s = "hello"
s[0] = 'H' # ❌ TypeError(字符串不可变)
lst = [1, 2, 3]
lst[0] = 10 # ✅ 可以修改
Q3:== 和 is 的区别?
python
a = [1, 2, 3]
b = [1, 2, 3]
c = a
print(a == b) # True(值相等)
print(a is b) # False(不是同一个对象)
print(a is c) # True(指向同一个对象)
# 小整数池
x = 256
y = 256
print(x is y) # True(-5 到 256 会被缓存)
x = 257
y = 257
print(x is y) # False(超出缓存范围)
1.2 字符串操作
Q4:字符串反转的几种方法?
python
s = "Hello World"
# 方法1:切片(最快)
reversed_s = s[::-1]
# 方法2:reversed() + join
reversed_s = ''.join(reversed(s))
# 方法3:循环
reversed_s = ''
for char in s:
reversed_s = char + reversed_s
Q5:字符串格式化的三种方式?
python
name = "Alice"
age = 30
# 方式1:% 格式化(旧)
s = "我是 %s,今年 %d 岁" % (name, age)
# 方式2:str.format()
s = "我是 {},今年 {} 岁".format(name, age)
s = "我是 {name},今年 {age} 岁".format(name=name, age=age)
# 方式3:f-string(推荐,Python 3.6+)
s = f"我是 {name},今年 {age} 岁"
s = f"明年我 {age + 1} 岁" # 支持表达式
二、数据结构(初中级)
2.1 列表
Q6:列表推导式 vs map/filter?
python
numbers = [1, 2, 3, 4, 5]
# 列表推导式(推荐)
squares = [x**2 for x in numbers]
evens = [x for x in numbers if x % 2 == 0]
# map + filter
squares = list(map(lambda x: x**2, numbers))
evens = list(filter(lambda x: x % 2 == 0, numbers))
Q7:如何拷贝列表?
python
original = [1, 2, [3, 4]]
# 浅拷贝
copy1 = original.copy()
copy2 = original[:]
copy3 = list(original)
# 深拷贝
import copy
deep = copy.deepcopy(original)
# 验证
copy1[2].append(5)
print(original) # [1, 2, [3, 4, 5]](内部列表被修改)
print(deep) # [1, 2, [3, 4]](独立副本)
2.2 字典
Q8:字典的 get() vs [] 访问?
python
d = {'name': 'Alice', 'age': 30}
# [] 访问
name = d['name'] # ✅ 'Alice'
email = d['email'] # ❌ KeyError
# get() 方法(推荐)
name = d.get('name') # ✅ 'Alice'
email = d.get('email') # ✅ None(不报错)
email = d.get('email', '未设置') # ✅ 提供默认值
Q9:如何合并两个字典?
python
d1 = {'a': 1, 'b': 2}
d2 = {'b': 3, 'c': 4}
# 方式1:update()
d1.update(d2) # {'a': 1, 'b': 3, 'c': 4}
# 方式2:** 解包
d3 = {**d1, **d2}
# 方式3:| 运算符(Python 3.9+)
d3 = d1 | d2
三、函数(中级)
3.1 参数传递
Q10:args 和 kwargs 的作用?*
python
def func(a, b, *args, **kwargs):
"""
a, b: 位置参数
*args: 额外位置参数(元组)
**kwargs: 关键字参数(字典)
"""
print(f"a={a}, b={b}")
print(f"args={args}")
print(f"kwargs={kwargs}")
func(1, 2, 3, 4, x=5, y=6)
# a=1, b=2
# args=(3, 4)
# kwargs={'x': 5, 'y': 6}
Q11:Python 是值传递还是引用传递?
python
def modify_immutable(x):
x = 100 # 创建新对象,不影响外部
def modify_mutable(lst):
lst.append(4) # 修改原对象
num = 10
modify_immutable(num)
print(num) # 10(未改变)
my_list = [1, 2, 3]
modify_mutable(my_list)
print(my_list) # [1, 2, 3, 4](被修改)
# 结论:Python 是"传对象引用"
# - 不可变对象:看起来像值传递
# - 可变对象:看起来像引用传递
3.2 闭包与装饰器
Q12:什么是闭包?
python
def outer(x):
def inner(y):
return x + y # inner 引用了 outer 的变量 x
return inner
add_5 = outer(5)
print(add_5(10)) # 15
# 闭包三要素:
# 1. 函数嵌套
# 2. 内部函数引用外部函数变量
# 3. 外部函数返回内部函数
Q13:写一个计时装饰器
python
import time
from functools import wraps
def timer(func):
@wraps(func)
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"{func.__name__} 耗时:{end - start:.4f}秒")
return result
return wrapper
@timer
def slow_function():
time.sleep(1)
return "完成"
slow_function()
# slow_function 耗时:1.0012秒
四、面向对象(中高级)
4.1 类与对象
Q14:类方法、静态方法、实例方法的区别?
python
class MyClass:
def instance_method(self):
"""实例方法:需要 self,可访问实例属性"""
return f"实例方法,self={self}"
@classmethod
def class_method(cls):
"""类方法:需要 cls,可访问类属性"""
return f"类方法,cls={cls}"
@staticmethod
def static_method():
"""静态方法:不需要 self/cls,像普通函数"""
return "静态方法"
obj = MyClass()
obj.instance_method() # 实例方法
MyClass.class_method() # 类方法
MyClass.static_method() # 静态方法
Q15:\\new\\ vs \\init\\?
python
class Singleton:
_instance = None
def __new__(cls):
"""创建对象实例(类方法)"""
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
def __init__(self):
"""初始化对象属性(实例方法)"""
self.value = 42
# 单例模式:始终返回同一个实例
s1 = Singleton()
s2 = Singleton()
print(s1 is s2) # True
4.2 魔术方法
Q16:常用魔术方法有哪些?
python
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
"""print() 调用"""
return f"Point({self.x}, {self.y})"
def __repr__(self):
"""交互式解释器显示"""
return f"Point(x={self.x}, y={self.y})"
def __eq__(self, other):
"""== 比较"""
return self.x == other.x and self.y == other.y
def __add__(self, other):
"""+ 运算符"""
return Point(self.x + other.x, self.y + other.y)
def __len__(self):
"""len() 调用"""
return int((self.x**2 + self.y**2) ** 0.5)
def __getitem__(self, index):
"""[] 索引"""
return [self.x, self.y][index]
p1 = Point(1, 2)
p2 = Point(3, 4)
print(p1 + p2) # Point(4, 6)
print(p1[0]) # 1
五、高级特性(高级)
5.1 生成器与迭代器
Q17:生成器 vs 列表?
python
# 列表:一次性创建所有元素(内存占用大)
squares_list = [x**2 for x in range(1000000)]
# 生成器:惰性求值(内存占用小)
squares_gen = (x**2 for x in range(1000000))
import sys
print(sys.getsizeof(squares_list)) # ~8MB
print(sys.getsizeof(squares_gen)) # ~120B
Q18:如何实现斐波那契数列生成器?
python
def fibonacci():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
fib = fibonacci()
print([next(fib) for _ in range(10)])
# [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
5.2 上下文管理器
Q19:实现一个计时上下文管理器
python
import time
class Timer:
def __enter__(self):
self.start = time.time()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.end = time.time()
print(f"耗时:{self.end - self.start:.4f}秒")
return False # 不抑制异常
with Timer():
time.sleep(1)
# 耗时:1.0012秒
5.3 元类
Q20:什么是元类?
python
# 元类:创建类的类
class Meta(type):
def __new__(mcs, name, bases, attrs):
# 自动为所有方法添加日志
for key, value in attrs.items():
if callable(value):
attrs[key] = log_decorator(value)
return super().__new__(mcs, name, bases, attrs)
class MyClass(metaclass=Meta):
def method(self):
return "执行方法"
# MyClass 的所有方法都会自动添加日志
六、并发编程(高级)
6.1 多线程
Q21:GIL 是什么?
GIL(Global Interpreter Lock,全局解释器锁)
- CPython 的内存管理机制,同一时刻只有一个线程执行 Python 字节码
- 影响:多线程无法利用多核 CPU(计算密集型)
- 不影响:IO 密集型任务(线程会释放 GIL)
Q22:如何实现线程安全的计数器?
python
import threading
class SafeCounter:
def __init__(self):
self.value = 0
self.lock = threading.Lock()
def increment(self):
with self.lock: # 加锁
self.value += 1
def get(self):
with self.lock:
return self.value
counter = SafeCounter()
threads = [
threading.Thread(target=counter.increment)
for _ in range(1000)
]
for t in threads:
t.start()
for t in threads:
t.join()
print(counter.get()) # 1000(线程安全)
6.2 异步编程
Q23:async/await 的作用?
python
import asyncio
# 同步版本(慢)
def fetch_sync():
time.sleep(1) # 模拟 IO
return "数据"
# 异步版本(快)
async def fetch_async():
await asyncio.sleep(1) # 异步 IO
return "数据"
async def main():
# 并发执行3个请求
tasks = [fetch_async() for _ in range(3)]
results = await asyncio.gather(*tasks)
return results
# 同步:3秒
# 异步:1秒
asyncio.run(main())
七、实战编程题
7.1 算法题
Q24:两数之和(LeetCode 1)
python
def two_sum(nums, target):
"""
输入:nums = [2, 7, 11, 15], target = 9
输出:[0, 1]
"""
seen = {}
for i, num in enumerate(nums):
complement = target - num
if complement in seen:
return [seen[complement], i]
seen[num] = i
return []
Q25:有效的括号(LeetCode 20)
python
def is_valid(s):
"""
输入:"({[]})"
输出:True
"""
stack = []
pairs = {'(': ')', '{': '}', '[': ']'}
for char in s:
if char in pairs:
stack.append(char)
elif not stack or pairs[stack.pop()] != char:
return False
return len(stack) == 0
Q26:反转链表(LeetCode 206)
python
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def reverse_list(head):
"""
输入:1 -> 2 -> 3 -> 4 -> 5
输出:5 -> 4 -> 3 -> 2 -> 1
"""
prev = None
current = head
while current:
next_node = current.next
current.next = prev
prev = current
current = next_node
return prev
7.2 实战题
Q27:实现 LRU 缓存
python
from collections import OrderedDict
class LRUCache:
def __init__(self, capacity):
self.cache = OrderedDict()
self.capacity = capacity
def get(self, key):
if key not in self.cache:
return -1
# 移到末尾(最近使用)
self.cache.move_to_end(key)
return self.cache[key]
def put(self, key, value):
if key in self.cache:
self.cache.move_to_end(key)
self.cache[key] = value
if len(self.cache) > self.capacity:
self.cache.popitem(last=False) # 删除最久未使用
# 使用
cache = LRUCache(2)
cache.put(1, 1)
cache.put(2, 2)
cache.get(1) # 返回 1
cache.put(3, 3) # 淘汰 key 2
cache.get(2) # 返回 -1
Q28:单例模式的实现
python
# 方式1:__new__ 方法
class Singleton:
_instance = None
def __new__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
# 方式2:装饰器
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:
pass
# 方式3:元类
class SingletonMeta(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super().__call__(*args, **kwargs)
return cls._instances[cls]
class MyClass(metaclass=SingletonMeta):
pass
八、性能与优化
Q29:如何优化 Python 代码性能?
python
# 1. 使用列表推导式代替循环
# ❌ 慢
result = []
for i in range(1000):
result.append(i**2)
# ✅ 快
result = [i**2 for i in range(1000)]
# 2. 使用生成器节省内存
# ❌ 内存占用大
squares = [i**2 for i in range(10000000)]
# ✅ 惰性求值
squares = (i**2 for i in range(10000000))
# 3. 使用内置函数
# ❌ 慢
result = []
for item in items:
if condition(item):
result.append(item)
# ✅ 快
result = list(filter(condition, items))
# 4. 使用 set 进行成员检查
# ❌ O(n)
if item in my_list:
pass
# ✅ O(1)
if item in my_set:
pass
# 5. 使用局部变量
# ❌ 慢(全局变量查找)
global_var = 10
def func():
for i in range(1000):
x = global_var + i
# ✅ 快(局部变量)
def func():
local_var = global_var
for i in range(1000):
x = local_var + i
Q30:如何分析 Python 代码性能?
python
import cProfile
import pstats
def slow_function():
total = 0
for i in range(1000000):
total += i
return total
# 性能分析
cProfile.run('slow_function()', 'profile_stats')
# 查看统计
stats = pstats.Stats('profile_stats')
stats.sort_stats('cumulative')
stats.print_stats(10)
九、高频考点速查
核心概念
| 概念 | 要点 |
|------|------|
| GIL | 全局解释器锁,限制多线程性能 |
| 鸭子类型 | 关注对象行为,不关注类型 |
| 装饰器 | 函数包装器,AOP 编程 |
| 生成器 | 惰性求值,节省内存 |
| 上下文管理器 | with 语句,资源管理 |
| 元类 | 类的类,控制类创建 |
数据结构时间复杂度
| 操作 | list | dict | set |
|------|------|------|-----|
| 访问 | O(1) | O(1) | - |
| 搜索 | O(n) | O(1) | O(1) |
| 插入 | O(1) 末尾
O(n) 中间 | O(1) | O(1) |
| 删除 | O(n) | O(1) | O(1) |
常用内置函数
python
# 序列操作
len(), sorted(), reversed(), enumerate(), zip()
# 类型转换
int(), str(), list(), dict(), set(), tuple()
# 数学运算
sum(), max(), min(), abs(), round(), pow()
# 高阶函数
map(), filter(), reduce(), any(), all()
# 对象操作
isinstance(), issubclass(), hasattr(), getattr(), setattr()
十、面试建议
✅ 面试技巧
1. STAR 法则回答问题
- Situation(情况)
- Task(任务)
- Action(行动)
- Result(结果)
2. 展示思考过程
- 先说思路,再写代码
- 考虑边界情况
- 分析时间/空间复杂度
3. 代码规范
- 使用有意义的变量名
- 添加必要注释
- 遵循 PEP 8 风格
📚 推荐学习资源
• 📖 书籍:《Python 编程:从入门到实践》、《流畅的 Python》
• 💻 刷题:LeetCode、牛客网、HackerRank
• 🎥 视频:廖雪峰 Python 教程、Real Python
• 🔧 实践:GitHub 开源项目、Kaggle 竞赛
🎯 学习路径
基础语法 (1周) → 数据结构 (2周) → 函数编程 (2周) →
面向对象 (2周) → 高级特性 (3周) → 刷题实战 (持续)
祝你面试成功!🎉
记住:代码能力 = 理论知识 + 刷题实践 + 项目经验