大模型应用开发社招常考面经(python八股篇)(下)
14. 类型提示 + Pydantic
def add(a: int, b: int) -> int:
# 类型提示(运行时不强制)
return a + b
from pydantic import BaseModel # FastAPI 数据校验
class Item(BaseModel):
name: str
price: float = 0.0 # 默认值
tags: list[str] = []
item = Item(name="x", price="9.9") # 自动类型转换/校验
面试话术:类型提示的作用是让代码可读、IDE 能提示,运行时不做强制;而我在我的项目中使用了FastAPI 的 Pydantic BaseModel 做请求体校验、自动转换、生成文档。我在项目里用它定义所有 API 请求/响应模型。
15. 内存管理与垃圾回收
面试话术:CPython 内存管理核心有两个,引用计数和分代 GC。引用计数快但解决不了循环引用,分代 GC 定期扫描兜底。写代码时避免大循环引用结构。Python 用引用计数为主,分代垃圾回收处理循环引用。
相关概念,简单了解一下就行
引用计数:对象被引用次数归零立即回收——快但处理不了循环引用(A→B→A)
分代 GC:定期扫描(generation 0/1/2,越老扫描越少),处理循环引用
查看:
sys.getrefcount(x)、gc.collect()手动触发
del只是删引用,不保证立即回收
16. slots
class Point:
__slots__ = ('x', 'y') # 固定属性,不能动态加
def __init__(self, x, y): ...
p = Point(1, 2)
p.z = 3 # AttributeError
要点:省内存(省掉实例的 dict)、属性访问更快、限制动态属性。
17. init vs new
__new__:创建实例(类方法,先执行,返回实例)__init__:初始化实例(后执行)- 单例模式就是重写 new
代码块
class Singleton:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
18. functools.lru_cache
from functools import lru_cache
@lru_cache(maxsize=128) # 自动缓存函数结果
def fib(n):
return n if n < 2 else fib(n-1) + fib(n-2)
要点:函数式缓存——相同入参直接返回缓存结果;用于纯函数(无副作用)。
19. 元类(metaclass)
类的类指的是控制类的创建过程。
type是默认元类,class Foo(metaclass=MyMeta)指定。
要点:面试一般只考概念,知道「元类 = 类的类,控制类的创建行为」即可,不问实现。
20. f-string / 常用内置函数
name, score = "Alice", 95.678
f"{name} 得了 {score:.1f} 分" # Alice 得了 95.7 分
enumerate(lst) # 带索引遍历
zip(a, b) # 并行打包
sorted(lst, key=lambda x: x[1], reverse=True) # 按第二元素降序
any/all(lst) # 任一/全部为真
set(a) & set(b) # 交集 | 并集 - 差集
defaultdict / Counter # collections 常用
21. 全局变量修改 / global
count = 0
def inc():
global count # 不加 global 会报 UnboundLocalError
count += 1
22. + join
+,指的是将多个字符串直接拼接,而Join指的是根据指定分割符将字符串输出指定格式。
",".join(["a", "b", "c"]) # 比 + 循环快(+ 每次建新字符串)
23. Python 2 vs 3 区别
面试回答:python3相比于python2 有这些区别:print 函数化、整数除法(3 是浮点)、str 是 unicode、range 惰性
24.面试答题通用技巧
先给结论再展开:「一句话答案 + 为什么 + 我的实战」
不会的诚实说:「这个概念我没深入,但按我的理解是…… + 我项目里类似的是……」
代码题先说思路再写:「我打算三步:先……再……最后……」
画图辅助:复习异步/装饰器/内存时,搜索相关图片来展示
时间控制:单个问题 1-2 分钟,别超 3 分钟
附录 A:Python 基础函数速查(面试常考实操)
A1. 列表操作
lst = [5, 3, 8, 1, 3]
# 查询
lst[0] # 取第一个:5
lst[-1] # 取最后一个:3
lst[1:3] # 切片:[3, 8](含头不含尾)重点:左闭右开。有时候容易忘记,尤其是看到两个中括号会记成左闭右闭
lst.index(8) # 查找元素位置:2(不存在会报 ValueError)
lst.count(3) # 统计出现次数:2
3 in lst # 判断是否存在:True
# 增删改
lst.append(9) # 末尾添加
lst.insert(1, 99) # 指定位置插入
lst.extend([7,8]) # 批量添加
lst.pop() # 删除并返回最后一个
lst.pop(0) # 删除并返回指定位置
lst.remove(3) # 删除第一个匹配值
del lst[0] # 按位置删除
# 排序(高频!)
sorted(lst) # 返回新排序列表(不修改原列表)
sorted(lst, reverse=True) # 降序
lst.sort() # 原地排序(修改原列表)
sorted(lst, key=lambda x: abs(x)) # 按自定义规则排序
排序+排名的面试题(应届生可能会让你手撕,社招就别想了,没那么容易):
问题:① 列表 scores=[78,92,85,60,95] 找最高分最低分、降序排序、输出排名;② 列表去重且保持顺序;③ 两个列表合并求和。
代码给你们自己去背
# 1. 分数统计与排名
scores = [78, 92, 85, 60, 95]
sorted_scores = sorted(scores, reverse=True) # 降序
print(f"最高分: {max(scores)}, 最低分: {min(scores)}")
print(f"降序排序: {sorted_scores}")
print("排名:")
for i, score in enumerate(sorted_scores, 1):
print(f" 第{i}名: {score}分")
# 2. 列表去重且保持顺序
lst = [3, 1, 2, 3, 2, 4, 5, 1]
# dict.fromkeys 会自动去重并保持插入顺序(Python 3.7+)
unique = list(dict.fromkeys(lst))
print(f"去重后: {unique}")
# 3. 两个列表合并求和
a = [10, 20, 30]
b = [5, 15, 25]
total = sum(a + b) # 或 sum(a) + sum(b)
print(f"合并求和: {total}")
问题:给你一组字典scores = [("张三", 90), ("李四", 85), ("王五", 95)],内容是姓名和对应的Python程序设计分数,请你根据得分从高到低就行排序和输出。
```python
scores = [("张三", 90), ("李四", 85), ("王五", 95)]
ranked = sorted(scores, key=lambda x: x[1], reverse=True)
for i, (name, score) in enumerate(ranked, 1):
print(f"第{i}名:{name},{score}分")
# 输出:第1名:王五,95分 / 第2名:张三,90分 / 第3名:李四,85分
```
A2. 求和与统计
```python
sum([1, 2, 3]) # 6
sum(range(1, 101)) # 5050(1到100求和)
max([3, 7, 2]) # 7
min([3, 7, 2]) # 2
len([1, 2, 3]) # 3
abs(-5) # 5
round(3.14159, 2) # 3.14
```
A3. 字符串操作
```python
s = " Hello, World "
s.strip() # 去首尾空格
s.lower() / s.upper() # 转小写/大写
s.replace("World", "Python") # 替换
s.split(",") # 按逗号切分
",".join(["a","b"]) # 拼接:'a,b'(join 是 split 的反向)
s.startswith("He") # True
s.endswith("d") # True
len(s) # 长度
```
A4. 字典操作
```python
d = {"a": 1, "b": 2}
d["a"] # 1(不存在会 KeyError)
d.get("c", 0) # 0(安全取值,不存在返回默认值)
d.keys() / d.values() / d.items() # 键/值/键值对
d.update({"c": 3}) # 批量添加
d.pop("a") # 删除并返回值
d.setdefault("x", 10) # 不存在才设置
for k, v in d.items():
print(k, v)
```
A5. 集合操作
```python
a = {1, 2, 3}; b = {2, 3, 4}
a & b # 交集 {2, 3}
a | b # 并集 {1, 2, 3, 4}
a - b # 差集 {1}
a ^ b # 对称差 {1, 4}
```
A6. 常用内置函数
```python
enumerate(lst) # 带索引遍历
zip(a, b) # 并行打包成元组对
any([0, 0, 1]) # True(任一为真)
all([1, 1, 0]) # False(全部为真)
list(range(5)) # [0,1,2,3,4]
type(3) # <class 'int'>
isinstance(3, int) # True
```
A7. 文件操作(讲师必教)
```python
# 读
with open("a.txt", "r", encoding="utf-8") as f:
content = f.read() # 全读(小文件)
lines = f.readlines() # 读成行列表
for line in f: # 逐行读(大文件推荐,省内存)
print(line)
# 写
with open("b.txt", "w", encoding="utf-8") as f: # w覆盖 a追加
f.write("内容")
```
A8. 面试场景题速答
| 场景 | 答案 |
|---|---|
| 如何查询一个列表里有没有某元素? | x in lst,要位置用 lst.index(x) |
| 如何展示排名? | sorted(lst, reverse=True) 排序后 enumerate(..., 1) 编号 |
| 求一堆数的和? | sum(lst);条件求和用 sum(x for x in lst if x > 0) |
| 去掉列表重复元素? | list(set(lst))(注意会乱序);保序用 dict.fromkeys(lst) |
| 统计每个元素出现次数? | from collections import Counter; Counter(lst) |
| 字典按键/值排序? | 按键 sorted(d);按值 sorted(d.items(), key=lambda x: x[1]) |
| 反转字符串? | s[::-1];反转列表 lst[::-1] |
| 两个列表变字典? | dict(zip(keys, vals)) |
更多推荐

所有评论(0)