Python面试通关宝典|从基础到架构|核心考点与实战全解析【覆盖五大模块 | 80+核心考点 | 可运行代码示例 | 适配各级岗位】
·

文章目录
专业、易懂 | 代码可运行 | 覆盖基础与进阶核心考点
一、基础核心模块(必考,占比30%-40%)
1. Python基础语法
Python的核心特性及与其他语言的区别
- 解释型:代码逐行解释执行,无需编译,调试方便,但执行效率低于编译型语言(如C++、Java)。
- 面向对象:一切皆对象,支持封装、继承、多态,且支持多继承。
- 动态类型:变量无需声明类型,运行时自动确定,灵活但可能引入运行时错误。
- 跨平台:基于CPython解释器,可在Windows、Linux、macOS等系统上运行。
- 与Java/C++的区别:
- 变量:Python无类型声明,Java/C++需显式声明。
- 内存管理:Python自动垃圾回收,C++需手动管理。
- 多线程:Python有GIL(全局解释器锁),计算密集型多线程受限;Java/C++无此限制。
- 语法风格:Python强制缩进,代码简洁;Java/C++使用花括号。
变量与数据类型
- 整数(int):任意大小,仅受内存限制。
- 浮点数(float):双精度浮点数,注意浮点精度问题。
- 字符串(str):不可变序列,支持Unicode。
- 布尔值(bool):True/False,可与整数运算(True=1,False=0)。
- None:表示空值,常用于函数默认返回值或变量占位。
不可变类型 vs 可变类型(核心考点)
| 类型 | 不可变 | 可变 |
|---|---|---|
| 常见 | int, float, str, tuple | list, dict, set |
| 特点 | 修改会创建新对象 | 修改不会改变内存地址 |
# 不可变类型示例
a = 10
print(id(a)) # 140736123456
a += 1
print(id(a)) # 新地址,原对象不变
# 可变类型示例
lst = [1, 2, 3]
print(id(lst))
lst.append(4)
print(id(lst)) # 地址不变
- list与tuple:list可变,用于数据增删改;tuple不可变,用于固定数据(如配置、字典键)。
- dict与set:dict存储键值对,键必须不可变;set存储唯一元素,无序。两者底层都是哈希表。
运算符
- 算术:
+ - * / // % **(// 整除,** 幂) - 比较:
== != > < >= <=返回布尔值 - 逻辑:
and or not,具有短路特性:False and ...直接返回False;True or ...直接返回True - 赋值:
=以及复合赋值+=等 - 位运算:
& | ^ ~ << >>,用于整数二进制操作
# 短路示例
def expensive():
print("执行")
return True
if False and expensive(): # expensive不会被调用
pass
# 优先级:算术 > 比较 > 逻辑 > 赋值
result = 2 + 3 * 4 > 10 and 5 // 2 == 2 # (2+12)>10 and 2==2 -> True and True -> True
流程控制
# if-elif-else
score = 85
if score >= 90:
grade = 'A'
elif score >= 80:
grade = 'B'
else:
grade = 'C'
# for循环
for i in range(5): # 0..4
if i == 2:
continue # 跳过本次循环
if i == 4:
break # 终止循环
print(i)
# while循环
n = 3
while n > 0:
print(n)
n -= 1
# pass:空语句,占位
def todo():
pass
循环嵌套优化技巧:将内层循环中不变的运算提前提取,避免重复计算;使用局部变量加速。
字符串操作
s = " hello, world! "
print(s.strip()) # 去除两端空白
print(s.split(',')) # [' hello', ' world! ']
parts = ['a', 'b', 'c']
print('-'.join(parts)) # 'a-b-c'
print(s.replace('world', 'Python'))
print(s.find('hello')) # 2,找不到返回-1
print(s.index('hello')) # 2,找不到抛异常
# 切片 [start:stop:step]
print(s[2:7]) # 'hello'
print(s[::-1]) # 反转
# 字符串格式化:% 旧式,format(),f-string(推荐,Python 3.6+)
name = "Tom"
age = 25
print(f"Name: {name}, Age: {age}") # 最快、最直观
print("Name: {}, Age: {}".format(name, age))
print("Name: %s, Age: %d" % (name, age))
2. 容器数据结构
列表(list)
# 创建
lst = [1, 2, 3]
lst2 = list(range(5)) # [0,1,2,3,4]
# 增删改查
lst.append(4) # 末尾加
lst.insert(0, 0) # 指定位置插入
lst.extend([5,6]) # 合并
lst.pop() # 删除末尾并返回
lst.remove(2) # 删除第一个值为2的元素
lst[0] = 99 # 修改
# 排序
lst = [3,1,2]
lst.sort() # 原地排序,返回None
sorted(lst) # 返回新列表,原列表不变
# 列表推导式(更高效)
squares = [x**2 for x in range(10) if x % 2 == 0]
# 底层原理:动态数组,超出容量时自动扩容(通常扩容1.125倍或翻倍)
元组(tuple)
t = (1, 2, 3)
t2 = 1, 2, 3 # 括号可省略
single = (1,) # 单元素元组需加逗号
# 不可变特性:不可增删改,但元素若为可变对象,内部可修改
t3 = ([1,2], 3)
t3[0].append(3) # 允许,元组内列表id不变
# 元组拆包
a, b, c = t
first, *rest = [10,20,30,40] # first=10, rest=[20,30,40]
字典(dict)
# 创建
d = {'name': 'Alice', 'age': 20}
d2 = dict(name='Bob', age=25)
# 增删改查
d['score'] = 95 # 增加/修改
del d['age'] # 删除
print(d.get('gender', 'F')) # 安全获取,不存在返回默认值
print(d.items()) # 键值对视图
print(d.keys())
print(d.values())
# 底层哈希表:键必须可哈希(不可变类型),查找/插入平均O(1)
# Python 3.7+ 字典保持插入顺序,OrderedDict用于需要额外顺序方法的旧版本
from collections import OrderedDict
od = OrderedDict([('a',1), ('b',2)]) # 保持顺序
集合(set)
s = {1, 2, 3}
s2 = set([3,4,5])
s.add(6)
s.remove(3) # 不存在报错
s.discard(10) # 不存在不报错
# 集合运算
a = {1,2,3}; b = {3,4,5}
print(a | b) # 并集 {1,2,3,4,5}
print(a & b) # 交集 {3}
print(a - b) # 差集 {1,2}
print(a ^ b) # 对称差集 {1,2,4,5}
# 去重
names = ['a','b','a','c']
unique = list(set(names))
# 底层也是哈希表,元素必须可哈希
collections模块常用容器
from collections import defaultdict, deque, Counter, namedtuple
# defaultdict:提供默认值
dd = defaultdict(int) # 缺失键返回0
dd['count'] += 1
# deque:双端队列,高效头尾操作
dq = deque([1,2,3])
dq.appendleft(0) # 左侧添加
dq.popleft() # 左侧弹出
# Counter:计数器
cnt = Counter('abracadabra')
print(cnt.most_common(2)) # [('a',5), ('b',2)]
# namedtuple:轻量级数据类
Point = namedtuple('Point', ['x', 'y'])
p = Point(10, 20)
print(p.x, p.y)
3. 函数基础与进阶
函数定义与参数
def func(a, b=10, *args, c=20, **kwargs):
"""
a: 位置参数
b: 默认参数(必须放在位置参数后)
*args: 可变位置参数,接收元组
c: 关键字参数(需通过关键字传递)
**kwargs: 可变关键字参数,接收字典
"""
print(a, b, args, c, kwargs)
func(1, 2, 3, 4, c=30, name='Tom')
# 输出:1 2 (3,4) 30 {'name':'Tom'}
# 注意:默认参数是可变对象时会有陷阱
def add_item(item, lst=[]): # 错误示范:lst是共享的
lst.append(item)
return lst
print(add_item(1)) # [1]
print(add_item(2)) # [1,2] 预期[2]?实际共享了默认列表
# 正确做法
def add_item(item, lst=None):
if lst is None:
lst = []
lst.append(item)
return lst
返回值
def return_multi():
return 1, 2, 3 # 实际返回一个元组
x, y, z = return_multi() # 元组拆包
def no_return():
pass
print(no_return()) # None
闭包
条件:函数嵌套 + 内层函数引用外层变量 + 外层函数返回内层函数。
def outer(x):
def inner(y):
return x + y
return inner
add5 = outer(5)
print(add5(3)) # 8,x被保留在闭包中
装饰器
# 简单装饰器(本质:高阶函数+闭包)
def timer(func):
import time
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
print(f"耗时 {time.time()-start:.4f}s")
return result
return wrapper
@timer
def slow_func():
import time
time.sleep(0.5)
slow_func()
# 带参数装饰器
def repeat(times):
def decorator(func):
def wrapper(*args, **kwargs):
for _ in range(times):
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(3)
def greet():
print("Hello")
greet() # 打印三次
# 常用内置装饰器
class MyClass:
@staticmethod
def static_method(): pass # 无需self/cls
@classmethod
def class_method(cls): pass # 第一个参数为类
@property
def name(self): return self._name # 将方法转为属性
匿名函数(lambda)
# 语法:lambda 参数: 表达式
square = lambda x: x**2
# 常见应用:排序key
students = [('Tom', 20), ('Jerry', 18)]
students.sort(key=lambda s: s[1]) # 按年龄排序
# 与map/filter结合
nums = [1,2,3,4]
squared = list(map(lambda x: x**2, nums))
evens = list(filter(lambda x: x%2==0, nums))
作用域与global/nonlocal
x = 10 # 全局变量
def outer():
y = 20 # 外层变量
def inner():
nonlocal y # 修改外层变量
global x # 修改全局变量
y += 1
x += 1
inner()
print(y)
outer()
print(x)
4. 面向对象编程(OOP)
封装、继承、多态
# 封装:将数据和操作封装在类中
class Animal:
def __init__(self, name):
self.name = name # 实例属性
self._age = 0 # 单下划线:约定保护属性
self.__weight = 0 # 双下划线:名称修饰,避免子类覆盖
def speak(self): # 实例方法
raise NotImplementedError
@classmethod
def from_string(cls, s): # 类方法
return cls(s)
@staticmethod
def is_animal(): # 静态方法
return True
# 继承
class Dog(Animal):
def speak(self): # 多态:重写父类方法
return f"{self.name} says woof!"
class Cat(Animal):
def speak(self):
return f"{self.name} says meow!"
# 多态:同一接口不同实现
animals = [Dog("Buddy"), Cat("Kitty")]
for a in animals:
print(a.speak())
MRO与super()
class A: pass
class B(A): pass
class C(A): pass
class D(B, C): pass
print(D.__mro__) # (D, B, C, A, object) C3算法
class Parent:
def show(self):
print("Parent")
class Child(Parent):
def show(self):
super().show() # 调用父类方法
print("Child")
魔术方法
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
return f"({self.x},{self.y})"
def __repr__(self):
return f"Vector({self.x},{self.y})"
def __add__(self, other):
return Vector(self.x+other.x, self.y+other.y)
def __len__(self):
return 2
v1 = Vector(1,2)
v2 = Vector(3,4)
print(v1 + v2) # 调用__add__
print(len(v1)) # 2
@property属性装饰器
class Person:
def __init__(self, age):
self._age = age
@property
def age(self):
return self._age
@age.setter
def age(self, value):
if value < 0:
raise ValueError("Age cannot be negative")
self._age = value
p = Person(25)
print(p.age) # 像属性一样访问
p.age = 30 # 调用setter
二、进阶核心模块(高频考,占比25%-35%)
1. 模块与包
模块导入与搜索路径
# 导入方式
import math
from os import path
import sys as system
# 模块搜索路径
import sys
print(sys.path) # 列表:当前目录、PYTHONPATH、标准库、site-packages
# 动态添加路径
sys.path.append('/my/modules')
包的__init__.py
- Python 3.3+ 可以省略,但推荐保留以标识目录为包,并可执行初始化代码、控制
__all__。
# 目录结构
mypackage/
__init__.py
module1.py
module2.py
# __init__.py 内容
__all__ = ['module1'] # 控制 from package import * 的行为
print("Package initialized")
常用内置模块
# sys
import sys
print(sys.argv) # 命令行参数
sys.exit(0) # 退出程序
# os
import os
os.listdir('.') # 列出目录
os.path.join('a','b') # 路径拼接
os.environ.get('PATH') # 环境变量
# datetime
from datetime import datetime, timedelta
now = datetime.now()
delta = timedelta(days=1)
yesterday = now - delta
# json / pickle
import json
data = {'name': 'Tom'}
json_str = json.dumps(data)
obj = json.loads(json_str)
import pickle
with open('data.pkl', 'wb') as f:
pickle.dump(data, f) # 序列化,支持更多Python类型
with open('data.pkl', 'rb') as f:
restored = pickle.load(f)
# math
import math
math.sqrt(2), math.pi
第三方模块管理
pip install requests
pip uninstall requests
pip freeze > requirements.txt
2. 异常处理
异常与错误
- 语法错误:代码不符合语法,解释器无法运行。
- 运行时异常:语法正确,执行时出错,可被捕获。
try-except-else-finally
try:
n = int(input("输入数字: "))
result = 10 / n
except ValueError:
print("不是有效数字")
except ZeroDivisionError:
print("不能除以零")
except Exception as e: # 捕获其他所有异常,不推荐
print(f"未知错误: {e}")
else:
print(f"结果是 {result}") # 仅当try无异常时执行
finally:
print("无论是否异常都执行") # 常用于释放资源
raise与自定义异常
class ValidationError(Exception):
"""自定义异常"""
pass
def validate_age(age):
if age < 0:
raise ValidationError("年龄不能为负")
return age
try:
validate_age(-5)
except ValidationError as e:
print(e)
常见异常类型
| 异常 | 场景 |
|---|---|
SyntaxError | 语法错误 |
TypeError | 类型不匹配 |
ValueError | 值不正确 |
KeyError | 字典键不存在 |
IndexError | 序列索引越界 |
FileNotFoundError | 文件不存在 |
最佳实践
- 捕获具体异常,避免空
except:或except Exception:。 finally中释放资源(关闭文件、释放锁)。- 不要滥用异常,正常流程用条件判断。
3. 迭代器与生成器
可迭代对象 vs 迭代器
- 可迭代对象:实现了
__iter__方法,返回迭代器。如list, str, dict。 - 迭代器:实现了
__iter__和__next__方法,可被next()调用。
# 手动实现迭代器
class CountDown:
def __init__(self, start):
self.start = start
def __iter__(self):
return self
def __next__(self):
if self.start <= 0:
raise StopIteration
self.start -= 1
return self.start + 1
for i in CountDown(3):
print(i) # 3,2,1
生成器(yield)
def fibonacci(n):
a, b = 0, 1
for _ in range(n):
yield a
a, b = b, a + b
fib = fibonacci(5)
print(list(fib)) # [0,1,1,2,3]
# 生成器表达式(节省内存)
squares = (x**2 for x in range(1000000)) # 不立即生成全部,占内存极小
print(next(squares)) # 0
send()方法
def counter():
i = 0
while True:
val = yield i # yield接收send的值
if val is not None:
i = val
else:
i += 1
c = counter()
print(next(c)) # 0
print(c.send(10)) # 将10传给yield,然后继续,输出10
print(next(c)) # 11
4. 装饰器与上下文管理器
类装饰器
class CountCalls:
def __init__(self, func):
self.func = func
self.count = 0
def __call__(self, *args, **kwargs):
self.count += 1
return self.func(*args, **kwargs)
@CountCalls
def say_hello():
print("Hello")
say_hello()
say_hello()
print(say_hello.count) # 2
上下文管理器(with语句)
# 实现__enter__和__exit__
class ManagedFile:
def __init__(self, filename):
self.filename = filename
def __enter__(self):
self.file = open(self.filename, 'w')
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
if self.file:
self.file.close()
return False # 若返回True,则异常被抑制
with ManagedFile('test.txt') as f:
f.write('Hello')
# 使用contextmanager装饰器
from contextlib import contextmanager
@contextmanager
def managed_file(filename):
f = open(filename, 'w')
try:
yield f
finally:
f.close()
with managed_file('test2.txt') as f:
f.write('World')
常见应用场景
- 文件操作:
with open(...) as f - 数据库连接自动提交/回滚
- 线程锁自动释放:
with lock:
5. 内存管理与垃圾回收
引用计数
Python对象内部维护一个引用计数器,当计数为0时立即销毁。
import sys
a = [1,2,3]
print(sys.getrefcount(a)) # 2(a本身+getrefcount参数引用)
b = a
print(sys.getrefcount(a)) # 3
del b
print(sys.getrefcount(a)) # 2
垃圾回收(GC)
- 分代回收:处理循环引用(如两个对象互相引用)。Python将对象分为0、1、2三代,新对象在0代,经过一次GC幸存则升代,回收频率随代增高而降低。
- 标记-清除:GC的辅助算法,从根对象出发标记可达对象,清除未标记对象。
import gc
gc.disable() # 禁用GC(不推荐)
gc.enable()
gc.collect() # 手动触发垃圾回收
弱引用(weakref)
弱引用不增加引用计数,用于避免循环引用导致内存泄漏。
import weakref
class Node:
def __init__(self, value):
self.value = value
self.parent = None
self.children = []
parent = Node(1)
child = Node(2)
parent.children.append(child)
child.parent = weakref.ref(parent) # 弱引用,不增加引用计数
内存泄漏原因与避免
- 全局容器不断添加对象而不清理。
- 循环引用且类定义了
__del__(会干扰GC)。 - 缓存未设置大小限制。
检测工具:tracemalloc、memory_profiler、objgraph。
import tracemalloc
tracemalloc.start()
# ... 运行代码
snapshot = tracemalloc.take_snapshot()
top_stats = snapshot.statistics('lineno')
for stat in top_stats[:10]:
print(stat)
结语:以上内容覆盖了Python面试中80%以上的核心考点。建议读者动手运行每段代码,并尝试修改参数以加深理解。面试时除了能写出代码,还要能解释底层原理和设计选择。祝面试顺利!
三、实战应用模块(岗位相关,占比20%-30%)
1. 基础实战编程
字符串处理
# 字符串反转
s = "hello"
reversed_s = s[::-1] # "olleh"
# 字符串去重(保留顺序)
def remove_duplicates(s):
seen = set()
result = []
for ch in s:
if ch not in seen:
seen.add(ch)
result.append(ch)
return ''.join(result)
print(remove_duplicates("abracadabra")) # "abrcd"
# 统计字符出现次数
from collections import Counter
s = "abracadabra"
counter = Counter(s)
print(counter['a']) # 5
# 判断回文(忽略大小写和非字母数字)
def is_palindrome(s):
cleaned = ''.join(ch.lower() for ch in s if ch.isalnum())
return cleaned == cleaned[::-1]
print(is_palindrome("A man, a plan, a canal: Panama")) # True
# 拆分与拼接
s = "a,b,c"
parts = s.split(',') # ['a','b','c']
joined = '-'.join(parts) # "a-b-c"
列表/字典/集合操作
# 列表去重(保持顺序)
def list_deduplicate(lst):
seen = set()
return [x for x in lst if not (x in seen or seen.add(x))]
# 列表排序(自定义key)
students = [('Tom', 20), ('Jerry', 18), ('Spike', 22)]
students.sort(key=lambda x: x[1]) # 按年龄升序
# 列表合并
a = [1,2,3]; b = [4,5,6]
c = a + b # [1,2,3,4,5,6]
a.extend(b) # a变为[1,2,3,4,5,6]
# 字典按键/值排序
d = {'banana': 3, 'apple': 4, 'pear': 1}
# 按键排序
sorted_by_key = dict(sorted(d.items())) # {'apple':4, 'banana':3, 'pear':1}
# 按值排序
sorted_by_value = dict(sorted(d.items(), key=lambda item: item[1])) # {'pear':1, 'banana':3, 'apple':4}
# 集合运算实战(找出两个列表的共同元素)
list1 = [1,2,3,4]; list2 = [3,4,5,6]
common = set(list1) & set(list2) # {3,4}
算法基础
# 冒泡排序
def bubble_sort(arr):
n = len(arr)
for i in range(n-1):
swapped = False
for j in range(n-1-i):
if arr[j] > arr[j+1]:
arr[j], arr[j+1] = arr[j+1], arr[j]
swapped = True
if not swapped:
break
return arr
# 选择排序
def selection_sort(arr):
n = len(arr)
for i in range(n):
min_idx = i
for j in range(i+1, n):
if arr[j] < arr[min_idx]:
min_idx = j
arr[i], arr[min_idx] = arr[min_idx], arr[i]
return arr
# 插入排序
def insertion_sort(arr):
for i in range(1, len(arr)):
key = arr[i]
j = i-1
while j >= 0 and arr[j] > key:
arr[j+1] = arr[j]
j -= 1
arr[j+1] = key
return arr
# 二分查找(要求数组已排序)
def binary_search(arr, target):
left, right = 0, len(arr)-1
while left <= right:
mid = (left + right) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
arr = [2, 3, 5, 7, 11]
print(binary_search(arr, 5)) # 2
经典小题
# 斐波那契数列
# 递归(效率低,存在重复计算)
def fib_recursive(n):
if n <= 1:
return n
return fib_recursive(n-1) + fib_recursive(n-2)
# 迭代(动态规划,推荐)
def fib_iterative(n):
if n <= 1:
return n
a, b = 0, 1
for _ in range(2, n+1):
a, b = b, a+b
return b
# 生成器版本(节省内存)
def fib_generator(n):
a, b = 0, 1
for _ in range(n):
yield a
a, b = b, a+b
print(fib_iterative(10)) # 55
print(list(fib_generator(11))) # [0,1,1,2,3,5,8,13,21,34,55]
# 阶乘
def factorial(n):
result = 1
for i in range(2, n+1):
result *= i
return result
# 递归版
def factorial_rec(n):
return 1 if n <= 1 else n * factorial_rec(n-1)
# 素数判断
def is_prime(n):
if n < 2:
return False
for i in range(2, int(n**0.5)+1):
if n % i == 0:
return False
return True
# 最大公约数(辗转相除法)
def gcd(a, b):
while b:
a, b = b, a % b
return a
# 最小公倍数
def lcm(a, b):
return a * b // gcd(a, b)
print(gcd(48, 18)) # 6
print(lcm(12, 18)) # 36
2. 文件操作与数据处理
文件读写
# 文本文件读写
# 写入
with open('example.txt', 'w', encoding='utf-8') as f:
f.write('Hello, 世界!\n')
f.writelines(['第二行\n', '第三行'])
# 读取
with open('example.txt', 'r', encoding='utf-8') as f:
content = f.read() # 全部内容
# f.readline() 读一行,f.readlines() 读全部行到列表
# 二进制文件(如图片)
with open('image.jpg', 'rb') as src:
data = src.read()
with open('copy.jpg', 'wb') as dst:
dst.write(data)
# 编码问题处理
try:
with open('gbk_file.txt', 'r', encoding='gbk') as f:
print(f.read())
except UnicodeDecodeError:
# 尝试其他编码
with open('gbk_file.txt', 'r', encoding='gb18030') as f:
print(f.read())
文件操作进阶(os/shutil)
import os
import shutil
# 创建目录
os.makedirs('dir/subdir', exist_ok=True) # exist_ok避免目录已存在时报错
# 删除文件/目录
os.remove('file.txt')
os.rmdir('empty_dir') # 只能删除空目录
shutil.rmtree('non_empty_dir') # 递归删除非空目录
# 复制/移动文件
shutil.copy('src.txt', 'dst.txt')
shutil.move('old.txt', 'new_dir/new.txt')
# 遍历目录
for root, dirs, files in os.walk('.'):
for file in files:
print(os.path.join(root, file))
CSV文件读写
import csv
# 写入CSV
data = [
['name', 'age', 'city'],
['Alice', 25, 'New York'],
['Bob', 30, 'London']
]
with open('people.csv', 'w', newline='', encoding='utf-8') as f:
writer = csv.writer(f)
writer.writerows(data)
# 读取CSV
with open('people.csv', 'r', encoding='utf-8') as f:
reader = csv.reader(f)
for row in reader:
print(row) # ['name','age','city'] 等
# 使用DictReader/DictWriter(按列名操作)
with open('people.csv', 'r', encoding='utf-8') as f:
reader = csv.DictReader(f)
for row in reader:
print(row['name'], row['age'])
JSON/Pickle序列化
import json
import pickle
# JSON(跨语言,只支持基础类型)
data = {'name': 'Tom', 'age': 30, 'hobbies': ['reading', 'coding']}
json_str = json.dumps(data, ensure_ascii=False, indent=2) # 转为字符串
with open('data.json', 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
with open('data.json', 'r', encoding='utf-8') as f:
loaded = json.load(f)
# Pickle(Python专用,支持所有对象,但安全性低,不信任源不可用)
with open('data.pkl', 'wb') as f:
pickle.dump(data, f)
with open('data.pkl', 'rb') as f:
restored = pickle.load(f)
3. 多线程与多进程(后端/大数据岗位重点)
线程与进程的区别 + GIL
- 进程:资源分配单位,拥有独立内存空间,创建开销大,进程间通信复杂。
- 线程:CPU调度单位,共享进程内存,创建开销小,但需注意数据同步。
- GIL(全局解释器锁):CPython中同一时刻只允许一个线程执行Python字节码。因此多线程对CPU密集型任务无效,但对IO密集型任务(网络请求、文件读写)仍有优势,因为IO操作会释放GIL。
多线程(threading)
import threading
import time
def worker(name, delay):
print(f"线程 {name} 开始")
time.sleep(delay)
print(f"线程 {name} 结束")
# 创建线程
t1 = threading.Thread(target=worker, args=('A', 2))
t2 = threading.Thread(target=worker, args=('B', 1))
t1.start()
t2.start()
t1.join() # 等待t1完成
t2.join()
print("所有线程结束")
# 线程锁(避免竞态条件)
counter = 0
lock = threading.Lock()
def increment():
global counter
for _ in range(100000):
with lock: # 自动获取和释放锁
counter += 1
threads = [threading.Thread(target=increment) for _ in range(10)]
for t in threads:
t.start()
for t in threads:
t.join()
print(counter) # 1000000
多进程(multiprocessing)
from multiprocessing import Process, Pool, Queue
import os
def cpu_intensive(n):
"""CPU密集型任务:计算素数"""
count = 0
for i in range(2, n):
if all(i % j != 0 for j in range(2, int(i**0.5)+1)):
count += 1
return count
# 使用Process
def worker(q, n):
q.put(cpu_intensive(n))
if __name__ == '__main__':
q = Queue()
p = Process(target=worker, args=(q, 100000))
p.start()
result = q.get()
p.join()
print(result)
# 使用进程池(推荐)
if __name__ == '__main__':
with Pool(processes=4) as pool:
results = pool.map(cpu_intensive, [100000, 200000, 300000])
print(results)
协程(asyncio)
- 协程:用户态轻量级线程,单线程内实现并发,通过
async/await进行非阻塞等待。 - 优势:极高并发(成千上万连接),内存占用小,无锁竞争。
- 与多线程/多进程区别:协程是协作式调度(主动让出),多线程是抢占式;协程适合高IO密集型(如Web服务器、爬虫)。
import asyncio
async def fetch_data(delay, name):
print(f"开始获取 {name}")
await asyncio.sleep(delay) # 模拟IO操作,让出控制权
print(f"完成获取 {name}")
return f"{name} 的数据"
async def main():
# 并发执行多个协程
task1 = asyncio.create_task(fetch_data(2, "A"))
task2 = asyncio.create_task(fetch_data(1, "B"))
result1 = await task1
result2 = await task2
print(result1, result2)
# 运行协程
asyncio.run(main())
IO密集型 vs CPU密集型选型
| 任务类型 | 推荐方案 | 原因 |
|---|---|---|
| IO密集型(网络请求、文件读写、数据库查询) | 多线程 或 协程 | IO操作释放GIL,线程可并发;协程更轻量 |
| CPU密集型(计算、加密、图像处理) | 多进程 | 绕过GIL,利用多核CPU |
4. 框架相关(根据岗位侧重)
Web框架 - Flask
from flask import Flask, request, jsonify, render_template, Blueprint
app = Flask(__name__)
# 路由定义
@app.route('/')
def home():
return 'Hello, World!'
# 获取请求参数
@app.route('/user/<int:user_id>')
def get_user(user_id):
name = request.args.get('name', 'Guest')
return jsonify({'id': user_id, 'name': name})
# POST请求
@app.route('/data', methods=['POST'])
def handle_data():
data = request.get_json()
return jsonify({'received': data}), 201
# 模板渲染(需templates目录)
@app.route('/hello/<name>')
def hello(name):
return render_template('hello.html', name=name)
# 蓝图(模块化路由)
bp = Blueprint('admin', __name__, url_prefix='/admin')
@bp.route('/dashboard')
def dashboard():
return 'Admin Dashboard'
app.register_blueprint(bp)
# 中间件(请求前/后钩子)
@app.before_request
def before():
print("请求前执行")
if __name__ == '__main__':
app.run(debug=True)
Web框架 - Django(MTV架构简述)
# models.py(模型定义)
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=100)
email = models.EmailField()
class Book(models.Model):
title = models.CharField(max_length=200)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
price = models.DecimalField(max_digits=10, decimal_places=2)
# 查询操作
books = Book.objects.filter(price__lt=50).select_related('author') # 避免N+1
# views.py(视图)
from django.views.generic import ListView
from .models import Book
class BookListView(ListView):
model = Book
template_name = 'book_list.html'
context_object_name = 'books'
# urls.py(路由)
from django.urls import path
from .views import BookListView
urlpatterns = [
path('books/', BookListView.as_view(), name='book-list'),
]
数据科学框架 - NumPy
import numpy as np
# 数组创建
arr1 = np.array([1,2,3,4]) # 一维
arr2 = np.zeros((3,4)) # 3x4全0
arr3 = np.random.randn(2,3) # 标准正态分布
# 索引与切片
arr = np.arange(12).reshape(3,4)
print(arr[0, 1]) # 第0行第1列
print(arr[:, 2]) # 第2列
print(arr[1:, :2]) # 第1行以后,前两列
# 运算
a = np.array([1,2,3]); b = np.array([4,5,6])
print(a + b) # 逐元素加法
print(a * b) # 逐元素乘法
print(np.dot(a, b)) # 点积 1*4+2*5+3*6=32
# 统计
print(arr.mean(), arr.std(), arr.sum(axis=0)) # 沿列求和
数据科学框架 - Pandas
import pandas as pd
import numpy as np
# Series与DataFrame
s = pd.Series([1,2,3], index=['a','b','c'])
df = pd.DataFrame({
'name': ['Alice', 'Bob', 'Charlie'],
'age': [25, 30, 35],
'salary': [50000, 60000, 70000]
})
# 数据清洗
# 缺失值处理
df.loc[1, 'age'] = np.nan
print(df.isnull().sum())
df_filled = df.fillna(df['age'].mean()) # 用均值填充
# 去重
df.drop_duplicates(subset=['name'], keep='first', inplace=True)
# 数据筛选
high_salary = df[df['salary'] > 55000]
# 排序
df_sorted = df.sort_values('age', ascending=False)
# 分组统计
grouped = df.groupby('department')['salary'].mean()
# 实战:读取CSV并处理
df = pd.read_csv('data.csv')
df['new_col'] = df['col1'] + df['col2']
df.to_csv('output.csv', index=False)
5. 数据库操作
MySQL(pymysql)
import pymysql
# 连接数据库
conn = pymysql.connect(
host='localhost',
user='root',
password='123456',
database='testdb',
charset='utf8mb4'
)
try:
with conn.cursor() as cursor:
# 参数化查询(防SQL注入)
sql = "INSERT INTO users (name, age) VALUES (%s, %s)"
cursor.execute(sql, ('Tom', 25))
conn.commit()
# 查询
cursor.execute("SELECT id, name FROM users WHERE age > %s", (20,))
for row in cursor.fetchall():
print(row)
finally:
conn.close()
ORM框架 - SQLAlchemy(基础)
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
Base = declarative_base()
engine = create_engine('mysql+pymysql://root:123456@localhost/testdb')
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String(50))
age = Column(Integer)
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
# 增
user = User(name='Alice', age=28)
session.add(user)
session.commit()
# 查
users = session.query(User).filter(User.age > 25).all()
for u in users:
print(u.name)
# 改
session.query(User).filter_by(name='Alice').update({'age': 29})
session.commit()
# 删
session.query(User).filter_by(name='Alice').delete()
session.commit()
Redis(redis-py)
import redis
r = redis.Redis(host='localhost', port=6379, decode_responses=True)
# 字符串
r.set('key', 'value')
print(r.get('key')) # 'value'
# 哈希
r.hset('user:1', mapping={'name': 'Tom', 'age': 25})
print(r.hgetall('user:1'))
# 列表
r.rpush('mylist', 'a', 'b', 'c')
print(r.lrange('mylist', 0, -1))
# 设置过期时间(秒)
r.setex('temp', 10, 'expires in 10s')
MongoDB(pymongo)
from pymongo import MongoClient
client = MongoClient('mongodb://localhost:27017/')
db = client['testdb']
collection = db['users']
# 插入
doc = {'name': 'Bob', 'age': 30, 'skills': ['Python', 'MongoDB']}
result = collection.insert_one(doc)
print(result.inserted_id)
# 查询
user = collection.find_one({'name': 'Bob'})
print(user)
# 更新
collection.update_one({'name': 'Bob'}, {'$set': {'age': 31}})
# 删除
collection.delete_one({'name': 'Bob'})
总结:第三部分覆盖了Python面试中常见的实战题型,从基础算法、文件处理到并发编程、数据库操作和框架应用。建议读者针对自己的目标岗位,深入掌握相关模块(如后端岗位重点多线程/多进程、Web框架和数据库)。动手实践是巩固知识的最佳方式,祝面试顺利!
四、综合能力模块(加分项,占比5%-10%)
1. 代码优化
Python代码优化技巧
import timeit
import sys
# 1. 列表推导式替代for循环(更快、更简洁)
# 不推荐
squares = []
for i in range(10):
squares.append(i**2)
# 推荐
squares = [i**2 for i in range(10)]
# 2. 生成器节省内存(处理大数据集)
# 列表方式:占用大量内存
sum_squares_list = sum([i**2 for i in range(1000000)]) # 先生成全部列表
# 生成器方式:逐个计算,内存占用极小
sum_squares_gen = sum(i**2 for i in range(1000000)) # 生成器表达式
# 查看内存差异
print(sys.getsizeof([i for i in range(10000)])) # 约 87624 字节
print(sys.getsizeof((i for i in range(10000)))) # 约 112 字节
# 3. 避免冗余计算(将循环内不变的计算提取到外部)
# 不推荐
for i in range(100):
result = i * len([1,2,3,4,5]) # len每次都计算
# 推荐
length = len([1,2,3,4,5])
for i in range(100):
result = i * length
# 4. 合理使用内置函数(内置函数通常用C实现,效率高)
from functools import reduce
# 使用sum而非手动累加
nums = [1,2,3,4,5]
total = sum(nums) # 高效
# total = reduce(lambda a,b: a+b, nums) # 可读性差且较慢
# 使用any/all代替循环判断
if any(x > 10 for x in nums): # 遇到第一个True即停止
print("存在大于10的数")
# 使用map替代显式循环(简单转换时)
list(map(str, [1,2,3])) # ['1','2','3']
性能分析
# time模块:简单计时
import time
start = time.perf_counter() # 高精度计时
# 执行代码...
time.sleep(0.1)
end = time.perf_counter()
print(f"耗时: {end-start:.6f}秒")
# timeit模块:精确测量小段代码执行时间(自动重复多次)
import timeit
# 测试列表推导式 vs 显式循环
t1 = timeit.timeit('[i**2 for i in range(100)]', number=10000)
t2 = timeit.timeit('''
squares = []
for i in range(100):
squares.append(i**2)
''', number=10000)
print(f"列表推导式: {t1:.4f}s, 显式循环: {t2:.4f}s")
# cProfile模块:定位瓶颈函数
import cProfile
def slow_function():
total = 0
for i in range(1000000):
total += i ** 2
return total
# 在命令行运行:python -m cProfile my_script.py
# 或者在代码中:
cProfile.run('slow_function()') # 输出函数调用统计,找出耗时最多的函数
2. 项目经验与问题排查
日志分析(logging模块)
import logging
# 配置日志(生产环境推荐)
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('app.log', encoding='utf-8'), # 输出到文件
logging.StreamHandler() # 输出到控制台
]
)
logger = logging.getLogger(__name__)
# 使用不同级别
logger.debug("调试信息") # 开发时使用
logger.info("正常信息") # 记录关键操作
logger.warning("警告") # 潜在问题
logger.error("错误") # 运行时错误
logger.critical("严重错误") # 程序即将崩溃
# 异常信息完整记录
try:
1 / 0
except Exception as e:
logger.exception("捕获到异常") # 自动记录堆栈信息
线上Bug排查思路
- 复现问题:收集用户操作、环境信息、输入数据。
- 查看日志:按时间线搜索ERROR、WARNING级别日志,定位首个异常点。
- 添加临时诊断日志:在关键路径添加
logger.debug,发布后观察。 - 检查资源状态:CPU、内存、磁盘、网络连接、数据库连接池。
- 二分法定位代码块:注释或跳过可疑模块,缩小范围。
- 使用断言验证假设:
assert condition, "错误信息"。 - 回滚版本:如近期发版,对比差异。
# 异常排查技巧:捕获特定异常,获取详细信息
try:
with open('missing.txt') as f:
data = f.read()
except FileNotFoundError as e:
logger.error(f"文件不存在: {e}")
# 可尝试创建默认文件或返回默认值
except PermissionError as e:
logger.error(f"权限不足: {e}")
3. Python进阶特性与拓展
Python3与Python2的主要区别
| 特性 | Python2 | Python3 |
|---|---|---|
print "hello" | print("hello") 函数形式 | |
| 整数除法 | 5/2=2(截断) | 5/2=2.5,5//2=2 |
| 字符串 | 默认ASCII,u"中文"表示Unicode | 默认Unicode,b"bytes"表示字节串 |
| 异常捕获 | except Exception, e: | except Exception as e: |
| range | range返回列表,xrange返回生成器 | range返回可迭代对象(类似xrange) |
| 输入 | raw_input() | input() |
函数式编程(map、filter、reduce)
from functools import reduce
# map:对每个元素应用函数
nums = [1,2,3,4]
squared = list(map(lambda x: x**2, nums)) # [1,4,9,16]
# filter:筛选满足条件的元素
evens = list(filter(lambda x: x % 2 == 0, nums)) # [2,4]
# reduce:累积计算
product = reduce(lambda a,b: a*b, nums) # 1*2*3*4=24
# 列表推导式通常更Pythonic(可读性更好)
squared = [x**2 for x in nums]
evens = [x for x in nums if x % 2 == 0]
推导式大全
# 列表推导式
list_comp = [x*2 for x in range(10) if x % 2 == 0] # [0,4,8,12,16]
# 字典推导式
dict_comp = {x: x**2 for x in range(5)} # {0:0,1:1,2:4,3:9,4:16}
# 集合推导式
set_comp = {x%3 for x in range(10)} # {0,1,2}
上下文管理器高级用法
# 同时管理多个上下文
with open('in.txt') as inf, open('out.txt', 'w') as outf:
outf.write(inf.read())
# contextlib.closing:自动调用close()(适用于有close方法的对象)
from contextlib import closing
import urllib.request
with closing(urllib.request.urlopen('http://example.com')) as page:
content = page.read()
# contextlib.suppress:忽略指定异常
from contextlib import suppress
with suppress(FileNotFoundError):
os.remove('temp.txt') # 如果文件不存在,不报错
拓展知识速览
- RESTful API设计:使用HTTP方法(GET/POST/PUT/DELETE),资源用名词复数(/users),状态码规范(200成功、201创建、400错误请求、404未找到)。
- 接口测试(requests模块):
import requests
resp = requests.get('https://api.github.com/users/octocat')
print(resp.status_code, resp.json()['login'])
# POST JSON数据
resp = requests.post('https://httpbin.org/post', json={'key': 'value'})
- Docker容器基础:
Dockerfile定义环境,docker build -t myapp .,docker run -p 8080:80 myapp。 - Git版本控制:常用命令
git clone、git add、git commit -m、git push、git pull、git branch、git merge。
五、面试场景补充(适配不同岗位)
初级Python开发
- 重点模块:一、基础核心模块(全部) + 三.1 基础实战编程 + 二.2 异常处理 + 二.1 模块与包
- 典型面试题:
- 可变与不可变类型的区别
- 列表和元组的区别
*args和**kwargs的作用- 如何反转字符串、去重列表
try-except-else-finally执行顺序
- 学习建议:手写代码练习,理解原理而非死记硬背。
中级Python开发
- 重点模块:一(基础)+ 二(进阶核心全部)+ 三.1(基础编程)+ 三.3(多线程/多进程)+ 三.5(数据库操作)+ 三.4(根据岗位选框架)
- 典型面试题:
- 装饰器的实现原理和应用场景
- 生成器和迭代器的区别
- GIL是什么?如何规避其影响?
- 进程池和线程池的使用
- SQL注入如何防范?
- 如何设计一个简单的RESTful API?
- 学习建议:深入理解底层实现(如列表动态扩容、字典哈希冲突解决),多写多线程/多进程实例。
高级Python开发
- 重点模块:全模块覆盖 + 四、综合能力(特别是代码优化、项目经验、性能分析)
- 典型面试题:
- 如何定位和优化Python程序的性能瓶颈?
- 设计一个高并发的消息队列系统(结合asyncio、多进程)
- 如何解决Python内存泄漏问题?
- 项目中的技术选型考虑(为何选Flask而非Django?)
- 如何保证微服务架构下的数据一致性?
- 线上服务CPU飙升如何排查?
- 学习建议:阅读CPython源码片段,参与开源项目,积累架构设计和故障排查经验。
数据科学/数据分析岗位
- 重点模块:一(基础,侧重NumPy/Pandas相关)+ 三.4(numpy/pandas)+ 三.1(算法基础)+ 可视化(matplotlib/seaborn简述)
- 典型面试题:
- Pandas中
merge、concat、join的区别 - 如何处理缺失值(dropna、fillna、插值)?
- NumPy数组和Python列表的性能差异原因
- 如何用Pandas分组并计算多个聚合函数?
- 解释
groupby后的apply和transform区别
- Pandas中
- 学习建议:熟练掌握Pandas数据清洗和特征工程,配合可视化库展示分析结果。
Web开发岗位
- 重点模块:一、二(基础+进阶)+ 三.4(Flask/Django)+ 三.5(数据库)+ 三.3(多线程/协程用于IO密集型)+ RESTful API
- 典型面试题:
- Django的ORM如何避免N+1查询?(
select_related/prefetch_related) - Flask上下文(应用上下文、请求上下文)原理
- 如何实现JWT认证?
- 异步Web框架(FastAPI/Quart)与同步框架的区别
- 数据库索引优化和慢查询分析
- Django的ORM如何避免N+1查询?(
- 学习建议:独立完成一个小型Web项目(如博客系统、待办事项API),掌握部署(Nginx+Gunicorn/uWSGI)。
结语:本宝典从基础语法到高并发优化,从单机调试到分布式架构思路,全面覆盖了Python面试的考察维度。真正的掌握需要反复动手实践——让代码成为你的肌肉记忆。祝你在面试中从容应对,斩获心仪Offer!
🌟 感谢您耐心阅读到这里!
💡 如果本文对您有所启发欢迎:
👍 点赞📌 收藏 📤 分享给更多需要的伙伴。
🗣️ 期待在评论区看到您的想法, 共同进步。
🔔 关注我,持续获取更多干货内容~
🤗 我们下篇文章见~
更多推荐



所有评论(0)