【面试宝典】Python 全栈面试实战

实验环境:华为云 ECS 服务器 ecs-5d9b-0001 (119.8.30.110)
操作系统:Ubuntu 24.04.4 LTS (Linux 6.8.0-106-generic)
Python版本:3.12.3
实验时间:2026-07-05
实验方式:所有代码均在 ECS 服务器上真实上机运行


目录

序号 章节 知识点
01 Python 数据类型 数据类型创建与操作、面试题
02 Python 函数和高阶函数 函数定义、高阶函数、装饰器
03 Python 包与模块、异常处理 模块导入、异常处理机制
04 Python 面向对象 OOP三大特性、魔术方法、内存管理
05 Python 并发编程 线程、协程、锁、GIL
06 Python 设计模式 单例、工厂、装饰器、观察者等
07 Python 数据库 SQLite/Redis/MongoDB
08 Python Web 框架 Flask/Django/FastAPI
09 Python 爬虫 HTTP请求、HTML解析、数据存储
10 Python 自动化测试 unittest/Mock/接口测试/Web测试

服务器环境信息

主机名: ecs-5d9b-0001
操作系统: Ubuntu 24.04.4 LTS
内核: Linux 6.8.0-106-generic x86_64
Python: 3.12.3
CPU: 8vCPUs (c6s.2xlarge.2)
内存: 16GiB
弹性公网IP: 119.8.30.110
私有IP: 192.168.0.186


01 Python 数据类型

知识点

1.Python中各种数据类型的创建和操作 2.Python中常见数据类型的面试题

简介

Python中的数据类型分为可变类型和不可变类型两大类。不可变类型包括int、float、str、tuple、bool、bytes;可变类型包括list、dict、set。理解它们的区别对于编写正确的Python代码至关重要。

实验源码

#!/usr/bin/env python3
"""
【面试宝典】Python 数据类型
知识点: 1.Python中各种数据类型的创建和操作 2.Python中常见数据类型的面试题
"""

print("=" * 70)
print("【面试宝典】Python 数据类型")
print("=" * 70)

# ============================================================
# 1. 不可变数据类型
# ============================================================
print("\n" + "=" * 70)
print("1. 不可变数据类型:int, float, str, tuple, bool, bytes")
print("=" * 70)

# 1.1 整数与浮点数
print("\n--- 1.1 整数与浮点数 ---")
a = 42
b = 3.14
c = True  # bool是int的子类
print(f"a = {a}, type = {type(a).__name__}")
print(f"b = {b}, type = {type(b).__name__}")
print(f"c = {c}, type = {type(c).__name__}")
print(f"isinstance(True, int) = {isinstance(True, int)}")  # 面试题: True是int的子类
print(f"True + True = {True + True}")  # 面试题: True+True=2

# 1.2 字符串
print("\n--- 1.2 字符串 ---")
s = "Hello, Python"
print(f"s = '{s}'")
print(f"s[::-1] = '{s[::-1]}'")  # 面试题: 字符串反转
print(f"s.upper() = '{s.upper()}'")
print(f"s.split(', ') = {s.split(', ')}")
print(f"''.join(['a', 'b', 'c']) = '{''.join(['a', 'b', 'c'])}'")

# 面试题: is vs ==
s1 = "hello"
s2 = "hello"
s3 = "".join(["hel", "lo"])
print(f"\ns1 = 'hello', s2 = 'hello', s3 = ''.join(['hel', 'lo'])")
print(f"s1 is s2 = {s1 is s2}")  # True - 字符串驻留
print(f"s1 is s3 = {s1 is s3}")  # 可能False - 动态拼接不驻留
print(f"s1 == s3 = {s1 == s3}")  # True - 值相等

# 1.3 元组
print("\n--- 1.3 元组 ---")
t = (1, 2, 3, [4, 5])
print(f"t = {t}")
# 面试题: 元组不可变,但元素是可变对象时可以修改
t[3].append(6)
print(f"t[3].append(6) -> t = {t}")
print("面试题: 元组不可变指的是元素的引用不可变,不是元素本身不可变")

# 面试题: 单元素元组
single = (1,)  # 注意逗号
not_tuple = (1)
print(f"\n(1,) type = {type(single).__name__}")  # tuple
print(f"(1) type = {type(not_tuple).__name__}")  # int - 不是元组!

# ============================================================
# 2. 可变数据类型
# ============================================================
print("\n" + "=" * 70)
print("2. 可变数据类型:list, dict, set")
print("=" * 70)

# 2.1 列表
print("\n--- 2.1 列表 ---")
lst = [1, 2, 3, 4, 5]
print(f"lst = {lst}")
lst.append(6)
print(f"lst.append(6) -> {lst}")
lst.extend([7, 8])
print(f"lst.extend([7, 8]) -> {lst}")
lst.insert(0, 0)
print(f"lst.insert(0, 0) -> {lst}")
lst.pop()
print(f"lst.pop() -> {lst}")
lst.remove(0)
print(f"lst.remove(0) -> {lst}")

# 面试题: 列表推导式
squares = [x**2 for x in range(10)]
print(f"\n[x**2 for x in range(10)] = {squares}")

evens = [x for x in range(20) if x % 2 == 0]
print(f"[x for x in range(20) if x%2==0] = {evens}")

# 面试题: 浅拷贝 vs 深拷贝
import copy
original = [[1, 2], [3, 4]]
shallow = original.copy()  # 浅拷贝
deep = copy.deepcopy(original)  # 深拷贝
original[0][0] = 99
print(f"\noriginal = [[1,2],[3,4]]")
print(f"shallow = original.copy(); original[0][0]=99")
print(f"shallow = {shallow}")  # [[99, 2], [3, 4]] - 浅拷贝受影响
print(f"deep = {deep}")  # [[1, 2], [3, 4]] - 深拷贝不受影响

# 面试题: 列表相加
print(f"\n[1,2] + [3,4] = {[1,2] + [3,4]}")
print(f"[1,2] * 2 = {[1,2] * 2}")

# 2.2 字典
print("\n--- 2.2 字典 ---")
d = {"name": "Alice", "age": 30, "city": "Shenzhen"}
print(f"d = {d}")
print(f"d.keys() = {list(d.keys())}")
print(f"d.values() = {list(d.values())}")
print(f"d.items() = {list(d.items())}")
print(f"d.get('name') = {d.get('name')}")
print(f"d.get('email', 'N/A') = {d.get('email', 'N/A')}")  # 面试题: 安全获取

# 面试题: 字典推导式
reverse = {v: k for k, v in d.items()}
print(f"\n{{v: k for k, v in d.items()}} = {reverse}")

# 面试题: 字典排序 (注意: 混合类型不能直接比较, 需指定key为str)
sorted_d = dict(sorted(d.items(), key=lambda x: str(x[1])))
print(f"sorted by value (str key): {sorted_d}")

# 面试题: collections.defaultdict
from collections import defaultdict, Counter
words = ['apple', 'banana', 'apple', 'cherry', 'banana', 'apple']
word_count = defaultdict(int)
for w in words:
    word_count[w] += 1
print(f"\ndefaultdict word count: {dict(word_count)}")
print(f"Counter(words) = {dict(Counter(words))}")

# 面试题: 字典合并 (Python 3.9+)
d1 = {"a": 1, "b": 2}
d2 = {"c": 3, "d": 4}
merged = d1 | d2
print(f"\n{{'a':1,'b':2}} | {{'c':3,'d':4}} = {merged}")

# 2.3 集合
print("\n--- 2.3 集合 ---")
s1_set = {1, 2, 3, 4, 5}
s2_set = {4, 5, 6, 7, 8}
print(f"s1 = {s1_set}")
print(f"s2 = {s2_set}")
print(f"s1 | s2 (并集) = {s1_set | s2_set}")
print(f"s1 & s2 (交集) = {s1_set & s2_set}")
print(f"s1 - s2 (差集) = {s1_set - s2_set}")
print(f"s1 ^ s2 (对称差集) = {s1_set ^ s2_set}")

# 面试题: 集合去重
dup_list = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
print(f"\nlist(set([1,2,2,3,3,3,4,4,4,4])) = {list(set(dup_list))}")

# ============================================================
# 3. 常见面试题
# ============================================================
print("\n" + "=" * 70)
print("3. 常见面试题")
print("=" * 70)

# 面试题1: == vs is
print("\n--- 面试题1: == vs is ---")
a_list = [1, 2, 3]
b_list = [1, 2, 3]
c_list = a_list
print(f"a = [1,2,3], b = [1,2,3], c = a")
print(f"a == b: {a_list == b_list}")  # True - 值相等
print(f"a is b: {a_list is b_list}")  # False - 不同对象
print(f"a is c: {a_list is c_list}")  # True - 同一对象
print(f"id(a) = {id(a_list)}, id(b) = {id(b_list)}, id(c) = {id(c_list)}")

# 面试题2: 小整数池
print("\n--- 面试题2: 小整数池 [-5, 256] ---")
x = 256
y = 256
print(f"256 is 256: {x is y}")  # True
x = 257
y = 257
print(f"257 is 257: {x is y}")  # False (在交互模式下, 脚本中可能True)

# 面试题3: 可变默认参数
print("\n--- 面试题3: 可变默认参数陷阱 ---")
def append_to(element, target=[]):
    target.append(element)
    return target

print(f"append_to(1) = {append_to(1)}")
print(f"append_to(2) = {append_to(2)}")  # [1, 2] - 陷阱! 默认参数只创建一次
print("正确做法: 使用None作为默认值")

def append_to_safe(element, target=None):
    if target is None:
        target = []
    target.append(element)
    return target

print(f"append_to_safe(1) = {append_to_safe(1)}")
print(f"append_to_safe(2) = {append_to_safe(2)}")  # [2] - 正确

# 面试题4: 删除列表元素时的陷阱
print("\n--- 面试题4: 遍历时删除元素 ---")
lst = [1, 2, 3, 4, 5]
# 错误方式
# for i in lst:
#     if i % 2 == 0:
#         lst.remove(i)  # 会跳过元素!
# 正确方式: 遍历副本
for i in lst[:]:
    if i % 2 == 0:
        lst.remove(i)
print(f"删除偶数后: {lst}")

# 面试题5: 字典的键必须是可哈希的
print("\n--- 面试题5: 字典/集合的键必须可哈希 ---")
print(f"hash('hello') = {hash('hello')}")
print(f"hash(42) = {hash(42)}")
try:
    hash([1, 2, 3])
except TypeError as e:
    print(f"hash([1,2,3]) -> TypeError: {e}")
print("可变对象(list, dict, set)不可哈希,不能作为字典键")

# 面试题6: sorted vs list.sort
print("\n--- 面试题6: sorted vs list.sort ---")
nums = [3, 1, 4, 1, 5, 9, 2, 6]
sorted_nums = sorted(nums)  # 返回新列表
print(f"sorted(nums) = {sorted_nums}, nums = {nums}")
nums.sort()  # 原地排序
print(f"nums.sort() -> nums = {nums}")

# 面试题7: any() 和 all()
print("\n--- 面试题7: any() 和 all() ---")
print(f"any([0, '', None, False, 1]) = {any([0, '', None, False, 1])}")  # True
print(f"all([1, 2, 3, 0]) = {all([1, 2, 3, 0])}")  # False
print(f"all([1, 2, 3, 4]) = {all([1, 2, 3, 4])}")  # True

# 面试题8: zip函数
print("\n--- 面试题8: zip函数 ---")
names = ['Alice', 'Bob', 'Charlie']
ages = [25, 30, 35]
zipped = list(zip(names, ages))
print(f"zip(names, ages) = {zipped}")
unzipped = list(zip(*zipped))
print(f"zip(*zipped) = {unzipped}")

# 面试题9: 字符串格式化
print("\n--- 面试题9: 字符串格式化 ---")
name = "World"
print(f"f-string: Hello, {name}!")
print("format: Hello, {}!".format(name))
print("%%-style: Hello, %s!" % name)
# 面试题: 对齐
print(f"'{"center":^20}'")
print(f"'{"left":<20}'")
print(f"'{"right":>20}'")

# 面试题10: 数据类型转换
print("\n--- 面试题10: 数据类型转换 ---")
print(f"list('hello') = {list('hello')}")
print(f"set([1,1,2,2,3]) = {set([1,1,2,2,3])}")
print(f"dict([('a',1),('b',2)]) = {dict([('a',1),('b',2)])}")
print(f"tuple(range(5)) = {tuple(range(5))}")

print("\n" + "=" * 70)
print("数据类型实验完成!")
print("=" * 70)

上机输出(ECS服务器实际运行结果)

======================================================================
【面试宝典】Python 数据类型
======================================================================

======================================================================
1. 不可变数据类型:int, float, str, tuple, bool, bytes
======================================================================

--- 1.1 整数与浮点数 ---
a = 42, type = int
b = 3.14, type = float
c = True, type = bool
isinstance(True, int) = True
True + True = 2

--- 1.2 字符串 ---
s = 'Hello, Python'
s[::-1] = 'nohtyP ,olleH'
s.upper() = 'HELLO, PYTHON'
s.split(', ') = ['Hello', 'Python']
''.join(['a', 'b', 'c']) = 'abc'

s1 = 'hello', s2 = 'hello', s3 = ''.join(['hel', 'lo'])
s1 is s2 = True
s1 is s3 = False
s1 == s3 = True

--- 1.3 元组 ---
t = (1, 2, 3, [4, 5])
t[3].append(6) -> t = (1, 2, 3, [4, 5, 6])
面试题: 元组不可变指的是元素的引用不可变,不是元素本身不可变

(1,) type = tuple
(1) type = int

======================================================================
2. 可变数据类型:list, dict, set
======================================================================

--- 2.1 列表 ---
lst = [1, 2, 3, 4, 5]
lst.append(6) -> [1, 2, 3, 4, 5, 6]
lst.extend([7, 8]) -> [1, 2, 3, 4, 5, 6, 7, 8]
lst.insert(0, 0) -> [0, 1, 2, 3, 4, 5, 6, 7, 8]
lst.pop() -> [0, 1, 2, 3, 4, 5, 6, 7]
lst.remove(0) -> [1, 2, 3, 4, 5, 6, 7]

[x**2 for x in range(10)] = [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
[x for x in range(20) if x%2==0] = [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

original = [[1,2],[3,4]]
shallow = original.copy(); original[0][0]=99
shallow = [[99, 2], [3, 4]]
deep = [[1, 2], [3, 4]]

[1,2] + [3,4] = [1, 2, 3, 4]
[1,2] * 2 = [1, 2, 1, 2]

--- 2.2 字典 ---
d = {'name': 'Alice', 'age': 30, 'city': 'Shenzhen'}
d.keys() = ['name', 'age', 'city']
d.values() = ['Alice', 30, 'Shenzhen']
d.items() = [('name', 'Alice'), ('age', 30), ('city', 'Shenzhen')]
d.get('name') = Alice
d.get('email', 'N/A') = N/A

{v: k for k, v in d.items()} = {'Alice': 'name', 30: 'age', 'Shenzhen': 'city'}
sorted by value (str key): {'age': 30, 'name': 'Alice', 'city': 'Shenzhen'}

defaultdict word count: {'apple': 3, 'banana': 2, 'cherry': 1}
Counter(words) = {'apple': 3, 'banana': 2, 'cherry': 1}

{'a':1,'b':2} | {'c':3,'d':4} = {'a': 1, 'b': 2, 'c': 3, 'd': 4}

--- 2.3 集合 ---
s1 = {1, 2, 3, 4, 5}
s2 = {4, 5, 6, 7, 8}
s1 | s2 (并集) = {1, 2, 3, 4, 5, 6, 7, 8}
s1 & s2 (交集) = {4, 5}
s1 - s2 (差集) = {1, 2, 3}
s1 ^ s2 (对称差集) = {1, 2, 3, 6, 7, 8}

list(set([1,2,2,3,3,3,4,4,4,4])) = [1, 2, 3, 4]

======================================================================
3. 常见面试题
======================================================================

--- 面试题1: == vs is ---
a = [1,2,3], b = [1,2,3], c = a
a == b: True
a is b: False
a is c: True
id(a) = 139756020936064, id(b) = 139756020937408, id(c) = 139756020936064

--- 面试题2: 小整数池 [-5, 256] ---
256 is 256: True
257 is 257: True

--- 面试题3: 可变默认参数陷阱 ---
append_to(1) = [1]
append_to(2) = [1, 2]
正确做法: 使用None作为默认值
append_to_safe(1) = [1]
append_to_safe(2) = [2]

--- 面试题4: 遍历时删除元素 ---
删除偶数后: [1, 3, 5]

--- 面试题5: 字典/集合的键必须可哈希 ---
hash('hello') = 8407132732632832895
hash(42) = 42
hash([1,2,3]) -> TypeError: unhashable type: 'list'
可变对象(list, dict, set)不可哈希,不能作为字典键

--- 面试题6: sorted vs list.sort ---
sorted(nums) = [1, 1, 2, 3, 4, 5, 6, 9], nums = [3, 1, 4, 1, 5, 9, 2, 6]
nums.sort() -> nums = [1, 1, 2, 3, 4, 5, 6, 9]

--- 面试题7: any() 和 all() ---
any([0, '', None, False, 1]) = True
all([1, 2, 3, 0]) = False
all([1, 2, 3, 4]) = True

--- 面试题8: zip函数 ---
zip(names, ages) = [('Alice', 25), ('Bob', 30), ('Charlie', 35)]
zip(*zipped) = [('Alice', 'Bob', 'Charlie'), (25, 30, 35)]

--- 面试题9: 字符串格式化 ---
f-string: Hello, World!
format: Hello, World!
%-style: Hello, World!
'       center       '
'left                '
'               right'

--- 面试题10: 数据类型转换 ---
list('hello') = ['h', 'e', 'l', 'l', 'o']
set([1,1,2,2,3]) = {1, 2, 3}
dict([('a',1),('b',2)]) = {'a': 1, 'b': 2}
tuple(range(5)) = (0, 1, 2, 3, 4)

======================================================================
数据类型实验完成!
======================================================================



更多推荐