MetaAPP 全栈(偏后端)AI 面试:Python 基础八问
- 轮次
- AI面试
- 时间
- 2026-09
- 来源
- 牛客网
《面试题目》
- 自我介绍
项目与经历
项目部分追问很深,一直问结果和数据——数据怎么来、怎么判断正确、拿到了什么结果
Python 基础
- Python 类和实例的区别
- 读取大文件为什么不一次性 read 全部内容
- try-except-finally 执行顺序
- Python 可变对象、不可变对象
*args与**kwargs- 深拷贝和浅拷贝区别
- 字典查找为什么快
- list 和 tuple 区别、适用场景
其他
- 职业性格选择题(无对错,保持前后答案一致)
《参考解析》
-
类与实例的区别:类是模板,定义了属性与方法;实例是按类创建出来的具体对象,各自持有独立的实例属性。类属性归全体实例共享(可变类属性被某个实例修改会互相影响,是常见坑),实例属性存在
__dict__里;方法是定义在类上的函数,通过实例调用时才绑定 self。追问常落到__init__与__new__的分工、以及继承时属性查找的 MRO 顺序。 -
大文件为什么不一次性 read:
read()会把整个文件读进内存,文件多大就占多大,几个 G 的文件直接把内存打满甚至 OOM;正确做法是分块读或按行迭代(for line in f),或者用read(size)配合循环处理。再补一层:文本文件按行迭代时 Python 内部有缓冲,性能并不差;如果是二进制文件要指定rb并按固定块大小流式处理,处理完即释放。 -
try-except-finally 的执行顺序:先执行 try,出现异常且匹配到对应 except 就跳到 except,无论是否发生异常 finally 都会执行;如果没有 except 匹配,异常在 finally 执行完之后继续向上抛。几个高频陷阱:try 里
return时 finally 仍会执行(且 finally 里的 return 会覆盖前面的返回值);else分支只在没有异常时执行;raise之后同一 try 块的后续语句不再执行。 -
可变对象与不可变对象:不可变的是 int、float、str、tuple、frozenset,可变的是 list、dict、set、bytearray。关键差异在于「修改」的语义——不可变对象「修改」实际是新建对象,所以能安全地当字典的键、做函数默认值;可变对象做默认参数会在多次调用间共享状态(经典的
def f(x, l=[])坑)。另外函数传参传的是对象引用,函数内对可变对象做原地修改会影响调用方。 -
*args与**kwargs:*args收集多余的位置参数成元组,**kwargs收集多余的关键字参数成字典;调用侧反过来用*和**做解包。要注意参数顺序(位置参数、默认参数、*args、关键字参数、**kwargs),以及 Python 3 里*单独出现表示其后参数必须用关键字传。这题常和装饰器一起考——写functools.wraps加*args, **kwargs透传是标准模板。 -
深浅拷贝的区别:浅拷贝(
copy.copy、list[:]、dict.copy)只复制最外层容器,内部嵌套对象仍是同一份引用,改嵌套内容两边都会变;深拷贝(copy.deepcopy)递归复制所有层级,两者完全独立。深拷贝的代价是慢,且遇到自引用结构要靠 memo 处理,循环引用也能正确复制。实际项目里更常见的是「根本不需要拷贝」,先想清楚是否要共享。 -
字典查找为什么快:底层是哈希表,查找是「算哈希 → 定位槽位 → 比较键」三步,平均 O(1)。冲突用开放定址(探测)解决,装填因子超过约 2/3 就扩容并重新散列。追问通常是「什么样的对象能做键」——必须可哈希(实现
__hash__与__eq__,且哈希值在生命周期内不变),所以 list、dict、set 不能当键,元组可以但内部元素也必须可哈希。 -
list 与 tuple 的区别与适用场景:list 可变、有增删改方法、占用内存略大;tuple 不可变、更省内存、创建更快、可哈希(元素可哈希时能当字典键),适合表达固定的记录(一条坐标、一行配置)。工程上还有一层语义差别:tuple 表示「这是一个整体,字段含义由位置决定」,list 表示「同类元素的集合」。用
namedtuple或 dataclass 会让位置语义更清楚。 -
AI 面试的准备方式:这类面试按固定题库逐题提问,答题节奏比临场发挥更重要。建议每问先给一句结论、再补一到两层细节,控制在 40–60 秒;同时把项目部分的「数据怎么来、怎么判断正确、结果是什么」提前写成量化口径,因为 AI 面会反复追问同类问题。这场 AI 面之后还有性格测评,作答时保持前后一致即可——测评本身没有对错,前后矛盾才是扣分项。