这里记录一些面试中遇到的一些有意思的题目,与其说面试是一种考核,不妨每次把面试题当做一种巩固自己知识的机会,这里记录一下最近面试到的一些有意思的题目。
WARNING部分内容为了确保正确和真实性有向 GPT-5.2 求证以及修改、所以部分内容有 AI 生成痕迹。
Q:讲述一下异步:比如 async 对应的关键字
A:还有 await
有些公司还喜欢考异步和阻塞,异步和阻塞可以看作两个并不相关的维度和坐标。
这里就聊聊我们常见的同步和异步,由于 CPU 的执行速度可比 I/O 的吞吐快多了,所以为了节约大部分时间我们可以异步操作。同步操作可以当作写一个循环,固定一段时间去询问,“有没有读好数据 or 干好这个事啊?”。异步操作通过 await 可以直接去执行 await 后的函数,避免了等待。这下你可能有疑问了,那 await 不还是要去等待函数给个结果吗?不还是要等吗?这下我们引入一个协程的概念,这是一个应用态的东西,可以把他理解为寄生在线程里的一个物质,他的切换开销很少。实际上 await 这个协程被挂起了,这个线程下可能还会有其他协程在执行,CPU 并没有像同步那样傻傻的等待着函数返回结果并且过一段时间就回去看一眼,所以并没有被阻塞,也不算等。
Q:python 的 真多线程 和 假多线程
A:我提到了 threading ,但是 threading 是假多线程。
相信很多小伙伴这边也有一些疑惑,多线程的真假是何意味?其实这里可以提到一个 GIL(全局解释器锁)的东西,python 规定了同一时刻只能有一个线程来执行 python 的字节码,这就是为什么,我们即使开了多个 thread,CPU 的占还是 100%左右,那么什么是真多线程。这里提到的 multiprocessing 库,它的作用是可以起多个进程进行工作,从而实现一种真正的并行(parallelism),反之,我们刚刚讲到的 thread 也不过是并发(concurrency)罢了。
再往深了讲,可以提到 Linux 在创立子进程时的 fork(),而且 Windows 系统和 Linux 这边在创建进程时的底层操作也不太一样,开销也不太一样。在 AI 的提示下,python3.13 版本后有 —no-gil 的参数选择了,可以自行解开 GIL 锁。
Q:python 代码在底层的执行过程
A:这块儿真没了解过(反正跟 C 肯定不一样,python 是解释型的)
这里梳理一下 python 代码在运行前经过了哪些步骤,首先把 python 语句转换成 Token,这种 token 转换成一种 AST(abstract syntax tree),可以想象成一种代码执行的框架。随后生成字节码,一般是 pyc 后缀的文件名。(相信你也曾在运行某段代码或者项目时在__pycache__中有看到这类文件)随后在 pvm(python 的一种虚拟机,你同时也可以理解为什么 python 可以做到跨平台了),顺序执行。
NOTE你一定也好奇,目前主流的编程语言 python 明明被很多深度学习领域广泛使用,为什么大家会说他执行效率不高呢?
答案是:python 中封装了大量的对象开销以及动态类型检查,而且解释器本身也是一种消耗,加上上文提到的 GIL 锁的存在,所以比更底层的 C 语言这种相比,更冗余,简单操作的执行开销更大。但是,实际上很多深度学习库如 PyTorch 等底层都是 C 写的,python 不过是开发者用来调用 C API 而已。
Q:FastAPI 相关, FastAPI 如何处理错误
A:try/except,一般错误要么 raise 出来,要么写 logging。
如果要回答完善的话,建议参考 FastAPI Doc,这种纯八股就没啥意思了。