
简介这是一份面向 Python 求职者与基础学习者的面试知识点速查 PDF聚焦生成器、迭代器、列表与元组、字典实现、GIL 全局解释器锁、Py2/Py3 差异、可变与不可变对象、闭包与装饰器等高频问题以问答形式给出精炼结论与代码示例适合笔试面试前快速回顾。资源仅含 1 个 PDF 文件压缩包约 304KB体积轻巧可随时在手机或电脑上查阅目前已有 13637 人学习下载。除核心八股外内容还延伸到 list/dict 底层存储原理、多线程与多核 CPU 的关系、元类的定义与使用场景等进阶话题并配有 fib 生成器、计时装饰器、迭代器判断等常见片段能帮助读者把零散知识点串成体系补足易被追问的细节。PDF 按问题组织内容从内置电池概念到多线程 GIL 均有涉及适合系统性梳理与考前冲刺。1. Python 八股文.pdf 的本质把知识压缩成可检索的索引很多候选人手里都有一份 Python 八股文.pdf里面罗列着 GIL、装饰器、迭代器、MRO 这类高频问题。可现实是背完这份 PDF 的人往往能在选择题里拿高分却在面试现场被一句“你能举个例子吗”卡住。原因很简单八股文只给了“最常用的结论”没给你“结论背后的推导链”。这篇文章不是让你再背一遍而是让你把这份 PDF 当成一个入口看清每个知识点被拿出来问的真实动机知道怎么整理、怎么验证、怎么把它讲成面试官愿意听到的答案。适合正在准备 Python 岗位的求职者也适合想系统梳理基础概念的初级开发。读完你会得到一套从“背”走向“用”的方法。2. 拆开 Python 八股文四块必考地基与它们的底层逻辑整份 PDF 看似散乱其实知识点都压在四个地基上对象模型、函数语法糖、面向对象体系、并发与内存管理。任何一个追问最后都会落到这四个域里。下面按域拆开每个都给最小示例和面试官真正的考察点。2.1 对象模型与内建容器is与只是开胃菜先看最经典的一段a [1, 2] b [1, 2] print(a is b) # False两个列表对象不同 print(a b) # True值相同 c 256 d 256 print(c is d) # True小整数被缓存为单例 e 257 f 257 print(e is f) # 通常 False超出缓存范围创建新对象is比较的是对象身份内存地址比较的是值。小整数从 -5 到 256 会被解释器缓存成单例所以c is d返回 True超出这个范围每次字面量都会创建新对象e is f一般返回 False。这里“一般”是因为不同解释器、不同运行方式交互式命令行和脚本文件对整数字面量的复用策略不完全一致八股文里如果只写“257 是 False”就容易翻车。面试官把这个放在第一题看的是你分不分得清“值相等”和“对象相同”这两个维度。如果你能进一步说出“in做容器查找时靠__eq__dict的 key 额外还要算__hash__”说明你对对象模型有整体认识。很多容器相关的坑都来自这里把可变对象放进set会报TypeError因为列表不可哈希自定义类不重写__hash__就放进字典两个“相等”的实例会被当作两个 key。另一处高频点是“可变默认参数”。我在整理 PDF 时专门把这个例子放了一页def add_item(item, cache[]): # 默认参数在定义时只创建一次 cache.append(item) return cache print(add_item(1)) # [1] print(add_item(2)) # [1, 2]共享了同一个列表默认参数在函数定义时只求值一次cache指向同一个列表对象所以多次调用会累积。修法要么用None再在函数体内创建新列表要么用cache: list | None None。这个考的不是语法而是“对象什么时候创建、什么时候被共享”的执行模型。所以整理这块时我建议你在每个知识条目下固定写四行一句话结论最小代码片段内存/对象层面的原因一个能直接用于生产的修正写法这样 PDF 就不是背的而是排查问题时的索引。2.2 函数语法糖装饰器、生成器、上下文管理器这三个概念在 PDF 里常被分到不同小节但在运行时本质上都依赖“函数对象可以被保存和传递”这一事实。装饰器是闭包的典型应用import functools import time def elapsed(func): functools.wraps(func) # 保留原函数的元信息 def wrapper(*args, **kwargs): start time.perf_counter() result func(*args, **kwargs) print(f{func.__name__} cost {time.perf_counter() - start:.4f}s) return result return wrapper elapsed # 等价于 sleep_a_little elapsed(sleep_a_little) def sleep_a_little(): time.sleep(0.1) sleep_a_little()elapsed等价于sleep_a_little elapsed(sleep_a_little)。wrapper捕获了外层的func这就是闭包。functools.wraps会把原来函数的__name__、__doc__复制到wrapper上否则被装饰后函数名会变成wrapper八股文里如果不提这一点面试追问“装饰器对函数元信息的影响”就会卡住。参数说明*args收集位置参数**kwargs收集关键字参数这样装饰器才能包住任意签名的函数。time.perf_counter()提供高精度计时。这段代码可以直接保存成decorator_demo.py运行不需要外部依赖。生成器的考点更偏向状态保存def fibonacci(): a, b 0, 1 while True: yield a # 暂停并保存当前状态 a, b b, a b fib fibonacci() # 此时函数体不会执行 for _ in range(5): print(next(fib)) # 输出 0 1 1 2 3yield会把函数变成生成器对象next()每次从上次暂停的地方继续。和一次性返回列表相比生成器不保存完整序列适合流式处理大文件。面试官通常会让“手写一个生成器”你要能说出“函数体里只要有yield调用函数时不会执行函数体只返回生成器对象”。上下文管理器则考察“资源释放”的执行顺序class ManagedFile: def __init__(self, filename, mode): self.filename filename self.mode mode def __enter__(self): # 进入 with 块时调用 self.file open(self.filename, self.mode) return self.file def __exit__(self, exc_type, exc_value, traceback): self.file.close() return False # False 表示不抑制异常 with ManagedFile(hello.txt, w) as f: f.write(hello)__exit__返回False表示异常不会被吞掉如果返回True异常会被抑制这通常是八股文里的隐藏考点。with能保证即使写入过程抛异常也会调用__exit__这就是“资源安全”的关键。这三个例子放在同一节是因为面试官经常把它们混在“Python 的函数式能力”里考。你整理 PDF 时建议把“闭包、惰性求值、资源释放”三者的触发场景对比成表格比如“装饰器是外层函数返回内层函数生成器是函数执行变成状态机上下文管理器是协议方法保证清理”。2.3 面向对象与继承MRO、super、__slots__菱形继承是必考class A: def who(self): print(A) class B(A): def who(self): print(B) super().who() # 按 MRO 找下一个类 class C(A): def who(self): print(C) super().who() class D(B, C): pass d D() d.who()输出顺序是B C A而不是B A。因为 Python 用 C3 线性化算法计算 MROD的 MRO 是D - B - C - A - object。super()不是“父类”而是按 MRO 的下一个类继续查找。如果你在整理这份 PDF 时只写“super()用于调用父类方法”面试官一追问“那 C 的who为什么会被调用”就答错了。代码逻辑说明B.who中调用super().who()它按D的 MRO 找B后面的类也就是C。所以打印完B后进入C.who打印C后再调到A.who。想要验证 MRO可以直接打印D.__mro__输出会是一串类对象这也应该写进你的 PDF 示例。__slots__常被当作“优化手段”考class Point: __slots__ (x, y) # 固定允许的属性名 def __init__(self, x, y): self.x x self.y y p Point(1, 2) # p.z 3 # AttributeError没有 __dict__ 支持普通实例会有一个__dict__来存储实例属性__slots__用固定长度描述符替代它所以不能添加新属性但能显著降低内存占用。注意如果类存在__slots__又没有在基类加__slots__子类仍然会生成__dict__。这一条属于典型的“知道结论但不知道边界”PDF 里需要专门标注。面向对象这块八股文常考“__new__和__init__的区别”“抽象基类怎么用”“类变量和实例变量的查找顺序”。你可以把每个问题都写成“代码 输出 MRO/查找链”的结构面试官稍稍深挖你就能顺着查表讲出来。2.4 并发与内存管理GIL、引用计数与垃圾回收GIL 是 Python 八股文里存在感最强的概念。代码演示比纯背诵更直观import threading import time counter 0 def add(): global counter for _ in range(1000000): counter 1 # 读、加、写三步并非原子操作 threads [threading.Thread(targetadd) for _ in range(2)] start time.time() for t in threads: t.start() for t in threads: t.join() print(counter, time.time() - start)在官方解释器中这个程序运行后counter通常不是 2000000甚至可能出现随机值。原因不只是 GIL还有不是原子操作它要经过“读、加、写”三步两个线程可能在中间交错。哪怕有 GIL线程切换也可能发生在字节码指令之间所以仍然要加锁。GIL 的全称是全局解释器锁它让同一进程里同一时刻只有一个线程能执行 Python 字节码。引入它的初衷是保护内存管理——官方解释器用引用计数管理对象如果不加全局锁多个线程同时修改引用计数会导致内存错误。代价是无法利用多核做 CPU 密集并行。因此八股文的标准结论是I/O 密集用多线程CPU 密集用多进程。内存管理这块引用计数是主导每个对象有一个计数被引用就加一删除就减一减到零就回收。循环引用需要靠gc模块来清理。你可以用gc.get_objects()看当前对象数用sys.getrefcount查看引用计数但这些属于“验货手段”不要在面试现场现查。到这里你应该能发现四块地基相互关联对象模型解释is闭包解释装饰器MRO 解释继承GIL 解释并发。PDF 里的问题只是入口真正值钱的是你能把这些问题串成一张网。3. 从零整理自己的 Python 八股文.pdf骨架、示例与导出我见过不少人的八股文 PDF 是从网上随便下载的排版很好但内容庞杂背了半个月还是记不住。更好的做法是按自己习惯整理。下面是我常用的流程从 Markdown 骨架到可验证的示例再到导出设置。3.1 用目录和标签搭骨架让知识点可检索不要在 PDF 里做成“问答列表”要做到“问题能被定位”。我一般先用 Markdown 建一个骨架# Python 八股文知识库 ## 1 对象模型 ### 1.1 与 is - 一句话结论 - 代码示例 - 底层原因 - 常见追问 ## 2 函数进阶 ### 2.1 装饰器 - 一句话结论 - 代码示例 - 底层原因 - 常见追问 ## 3 面向对象 ### 3.1 MRO - 一句话结论 - 代码示例 - 底层原因 - 常见追问 ## 4 并发与内存 ### 4.1 GIL - 一句话结论 - 代码示例 - 底层原因 - 常见追问这个结构的好处是每个知识点固定四段复习时只看“一句话结论”理解时看“底层原因”面试前重点看“代码示例”。你还可以在最前面用一个表格登记“掌握程度”知识点结论示例底层掌握度 与 is已了解已运行未深究60%表格里的掌握度每周更新一次不熟悉的知识点单独抽出来重写。用标签分类也很有效在标题后加[高频]、[易忘]、[版本敏感]导出 PDF 后能通过目录快速过滤。3.2 给每个知识点配上能独立运行的示例并自动验证八股文 PDF 最怕代码跑不通。我的做法是在写出示例后用一个脚本扫描全文代码块检查语法是否能通过编译。下面这个脚本可以放在你的整理目录里每次更新 Markdown 后跑一遍import pathlib import re def check_code_blocks(md_path: str) - list[str]: text pathlib.Path(md_path).read_text(encodingutf-8) blocks re.findall(rpython\n(.*?), text, re.S) problems [] for index, code in enumerate(blocks): try: compile(code, fblock_{index}, exec) # 只编译不执行 except SyntaxError as exc: problems.append(fBlock {index} line {exc.lineno}: {exc.msg}) return problems if __name__ __main__: errors check_code_blocks(python_bagu.md) if errors: print(Syntax errors found:) for e in errors: print(e) else: print(All python blocks are compilable.)逻辑说明re.findall用非贪婪匹配抓取所有python到之间的文本re.S让.能匹配换行。compile只做语法编译不执行代码避免你为了验证某段代码意外触发文件写入或网络请求。如果你想做更严的“运行验证”可以在compile后调用exec但必须在沙箱环境里并且确认代码没有外部副作用。参数说明md_path是你的 Markdown 文件路径index是代码块在文档里的顺序号exc.lineno是出错行号方便定位。这个脚本不需要第三方库Python 3.8 以上都能跑。跑完如果提示All python blocks are compilable.才能进入导出步骤。3.3 导出 PDF 时重点调三处目录、代码高亮、字体换行内容整理好后导出 PDF 不是简单点一下“打印”。以下三个设置直接影响复习体验设置项建议值原因目录生成可跳转的书签目录面试前按章节快速定位代码高亮选择 Python 语法高亮变量与关键字更容易分辨字体/换行中文字体 代码块自动换行避免代码被截断中文不显示为方框具体操作因工具而异但大方向是先导出 HTML 再转 PDF或在 Markdown 编辑器里选择“导出 PDF”并打开“包含目录”开关。如果你对排版有强迫症可以在导出前检查两点第一所有代码块的缩进是否统一第二横向长度超过 80 字符的代码是否被换行PDF 不会像编辑器那样给你横向滚动条。导出后别急着结束做一次“用户测试”用阅读器搜索“GIL”看能不能直接跳到对应页。我通常还会在 PDF 里加一页“索引表”列出每个知识点的页码这样在面试候场里翻起来最快。3.4 把答案改写成自己的话避免“背错版本”整理 PDF 时最忌讳直接复制别人总结的语言。八股文之所以叫八股文就是因为语言高度模板化面试官一听就知道你在背。我的习惯是每看到一个知识点先照着代码运行一遍然后关掉原文用自己的话写一遍解释。写完和原文对比如果发现表述不清说明你还没懂。比如“GIL”的标准解释是“全局解释器锁限制同一时刻只有一个线程执行字节码”。用自己的话可以是“官方解释器为了让内存管理不被多线程搞乱给解释器加了一把大锁这把锁让 Python 线程无法在多个 CPU 核上同时算代码”。后者更像人话也更接近面试官想要的答案。这样整理出的 PDF 才有个人色彩你在面试现场回忆时会直接想起自己写的比喻而不是背一串定义。4. Python 八股文复习避坑四个让背题失效的真实问题“背题翻车”不是努力不够而是方法踩了坑。下面四条是我整理和复习时踩过的每一条都对应“现象→原因→解决”。4.1 现象背了所有答案面试官一追问就卡壳很多人把 PDF 从头到尾背了一遍面试官问“defaultdict和dict的区别”能秒答但继续问“为什么defaultdict能在访问不存在 key 时不抛异常”就愣住了。原因是八股文只给了结论没给结论建立在哪个机制上。defaultdict之所以不抛异常是因为它重写了__missing__方法普通dict访问不存在的 key 时__getitem__会先触发__missing__如果不存在该方法再抛KeyError。你只要把“__missing__”这个底层钩子说出来面试官就知道你懂的是机制而不是死记。from collections import defaultdict d defaultdict(list) d[group].append(1) print(d[group]) # [1] print(d[nokey]) # []自动调用 __missing__ 生成默认值解决整理 PDF 时在每个知识点后面加一行“最深层的一个钩子是什么”。比如对应__eq__in对应__contains__with对应__enter__/__exit__for对应__iter__/__next__背熟这些钩子追问就变成你主动展示的素材。4.2 现象把 Python 2 和 Python 3 的行为混着讲我在一份旧八股文 PDF 里看到过“dict.keys()返回列表”这在 Python 2 是对的在 Python 3 返回视图对象。如果你面试时说“keys 返回列表”面试官直接就能判断你资料过时。类似还有print是语句还是函数、range返回列表还是迭代器、字符串默认编码等等。原因不是你不懂而是资料没标注版本。解决在 PDF 首页写清“以 Python 3.x 为主差异点单独提示”。每个涉及版本行为的知识点在标题后用[Py3]或[Py2/3差异]标记。复习到input/raw_input这类问题时主动对比一下新老写法并说一句“如果是 Python 3应该用input返回字符串Python 2 的input会做 eval有安全风险”。4.3 现象示例代码跑不通或者复制后报 NameError很多 PDF 里的代码为了排版省略了导入语句例如直接写read_csv(data.csv)却不写导入和数据来源或者用了自定义变量但不给定义。你照抄运行后报错会怀疑是自己环境坏了其实只是示例不自包含。面试时如果照搬这种片段还会给面试官留下“你根本没跑过代码”的印象。解决在整理 PDF 时所有示例遵循“自包含”原则导入放最前变量在同一段定义完整尽量只用标准库。然后跑一遍我在 3.2 节给的检查脚本至少保证语法可编译。更严格的一步是真实执行一次确认输出和你在 PDF 里写的一致。如果确实依赖第三方库在代码块上方用一句话说明“需要安装某库”但不要为了演示去背一堆外部依赖。4.4 现象只看不写面试时手写代码出洋相八股文 PDF 是静态资料复习时很容易陷入“眼睛看懂了”的错觉。我见过 A 同学把装饰器原理倒背如流面试官让他手写一个完整装饰器他写不出闭包的返回结构。原因就是手写和阅读用的脑区不同看得懂不代表写得出来。解决每周抽 3 个知识点用文本编辑器打开一个空白文件不参考 PDF 从头写代码。写完再和 PDF 对照。如果你能用笔在纸上写出def decorator(func): def wrapper(*args, **kwargs): ... return wrapper这样的整体结构再去面试才稳。另一个实操方案是让朋友帮忙抽题你直接在白板上写写完再讲一遍。这个过程痛苦但比对着 PDF 默读有效得多。5. 用“一分钟讲题法”把八股文变成面试答案PDF 整理完剩下一步是“把知识讲出来”。我试过最有效的方式是“一分钟讲题法”随机抽一个知识点给自己一分钟用三句话说清楚——它是什么、为什么存在、怎么用。拿 GIL 举例你的三句可以是GIL 是官方解释器里的全局锁它保证同一时刻只有一个线程在执行 Python 字节码。它的存在是为了保护引用计数和内存管理避免多线程同时操作对象导致内存错误。所以 CPU 密集任务用多进程绕开 GILI/O 密集任务用多线程依然有收益。这三句话不能照背要边想边说。我个人的习惯是打开手机录音讲完回放。如果哪句话出现“呃”“那个”超过两次说明这个知识点还没形成肌肉记忆。回放时重点听因果连接词是“因为...所以...”还是“反正就是这样”。这个方法也可以用于验证 PDF 里的表述。当你把一分钟录音转成文字对照 PDF 原文你会发现很多地方 PDF 用的是书面语而你说出的是口语。口语才是面试时的表达方式。所以我在整理 PDF 时会把一些关键条目改成口语化的“我来说一遍”版本。比如装饰器我会在 PDF 里写“装饰器就是把一个函数传给另一个函数内层函数把它包起来再返回新函数。用只是省去手动赋值的语法糖。”这句话比“装饰器是一个接受函数并返回新函数的可调用对象”更适合面试现场。最后分享一个教训我曾经把整份 PDF 背得滚瓜烂熟结果面试官让我“解释下with怎么保证文件一定被关闭”我只说了“因为__exit__会被调用”没能讲清“就算中途异常解释器也会保证调用__exit__把清理推进栈里”。后来我用一分钟讲题法把所有涉及资源释放的知识点重练了一遍才真正补上这块。整理八股文 PDF 不是终点把它讲成自己的话才是。希望帮到你。本文还有配套的精品资源点击获取