跳到主要内容Python 工程师常见基础面试题 | 极客日志PythonAI算法
Python 工程师常见基础面试题
综述由AI生成Python 工程师常见基础面试题涵盖了语言特性、数据结构、内存管理、并发编程及设计模式等核心知识点。内容包含解释器类型、PEP8 规范、面向对象三大特性、可变与不可变数据类型辨析、迭代器与生成器区别、字典操作、多线程与多进程差异、HTTP 状态码、猴子补丁、垃圾回收机制、位运算符、二分查找实现、lambda 表达式、反射机制、列表去重方法、魔术函数、单例模式实现、自省方法、爬虫步骤、反爬虫策略、元组列表转换、日期获取及装饰器作用等三十个关键问题及其解答。
编程诗人19 浏览 Python 工程师常见基础面试题
本文整理了 Python 开发岗位面试中高频出现的三十个基础问题,涵盖语言特性、数据结构、内存管理、并发编程及设计模式等核心知识点。以下内容旨在帮助开发者系统复习 Python 基础知识,提升技术面试通过率。
一、Python 的特点和优点是什么?
Python 是一门动态解释性的强类型定义语言。编写代码时无需预先定义变量类型,但在运行时变量类型会被强制固定,且无需编译成二进制文件,直接在解释器环境中运行源代码即可。
主要优点包括:
- 解释性:Python 程序不需要编译成机器码,可以直接从源代码运行,便于调试和跨平台部署。
- 动态性:属于动态语言,在运行时可以改变对象的结构和属性。类似的动态语言还包括 PHP、Ruby、JavaScript 等。
- 面向对象:支持基于类和对象的编程范式。面向对象的三大核心特性为封装、继承和多态,所有代码逻辑均可通过类与对象实现。
- 语法简洁:遵循简单主义思想,代码可读性极高,良好的 Python 程序阅读体验接近自然英语段落,降低了学习门槛。
- 可扩展性:拥有极其丰富的标准库和第三方模块,覆盖文件 I/O、GUI 开发、网络编程、数据库访问、文本处理等绝大多数应用场景,并支持嵌入 C/C++ 代码。
二、什么是 PEP8?
PEP 是 Python Enhancement Proposal(Python 增强建议书)的缩写。PEP8 特指其中关于代码风格规范的文档,它定义了让 Python 代码更易读、更统一的编码标准。遵循 PEP8 规范有助于团队协作时保持代码风格一致,减少因格式差异导致的审查成本。
三、Python 解释器种类以及特点?
Python 作为解释型语言,依赖解释器执行。常见的解释器有以下几种:
- CPython:官方默认版本,用 C 语言开发。命令行输入
python 启动的即为 CPython。它是使用最广泛的标准实现。
- IPython:基于 CPython 的交互式增强解释器,提供自动补全、内省、历史命令记录等功能,适合开发和调试。
- PyPy:目标是提高执行速度。采用 JIT(即时编译)技术,将 Python 代码动态编译为机器码,显著加速计算密集型任务。
- Jython:运行在 Java 虚拟机上的 Python 解释器,可将 Python 代码编译为 Java 字节码,直接调用 Java 库。
- IronPython:运行在 .NET 平台上的 Python 解释器,可编译为 .NET 字节码,与 C# 等 .NET 语言互操作。
四、Python 面向对象三大特性?
- 封装:隐藏对象的内部属性和实现细节,仅对外暴露公共接口。在 Python 中,通常使用双下划线开头(如
__var)将属性设为私有。好处包括隔离变化、便于维护、提高复用性和安全性。
- 继承:允许创建新类(子类)以复用现有类(父类)的字段和方法。父类也称为基类或超类。继承实现了代码复用和扩展。
- 多态:指同一操作作用于不同对象产生不同行为。函数重写是多态的体现。Python 中多态表现为父类引用指向子类对象,调用方法时根据实际对象类型执行对应实现。
五、Python 中有几种数据类型?
Python 内置了多种数据类型,主要包括以下八种:
- Number(数字):int, float, complex 等。
- String(字符串):不可变序列。
- List(列表):可变有序序列。
- Tuple(元组):不可变有序序列。
- Dict(字典):可变键值对映射。
- Set(集合):无序不重复元素集。
- :True/False。
Boolean(布尔值)
None(空值):表示空对象。六、Python 变量、函数、类的命名规则?
- 不能以数字开头,建议避免使用中文。
- 必须以字母或下划线开头,可包含数字、字母和下划线,区分大小写。
- 不能使用 Python 保留关键字,命名应见名知意,推荐使用小写字母加下划线的 snake_case 风格。
七、Python 可变与不可变数据类型的区别?
判断依据是变量所指向的内存地址中的值是否可被修改。
- 不可变数据(3 个):Number(数字)、String(字符串)、Tuple(元组)。一旦创建,内容不可更改,修改会生成新对象。
- 可变数据(3 个):List(列表)、Dictionary(字典)、Set(集合)。创建后内容可在原内存地址上修改。
八、列举几个 Python 中的标准异常类?
Python 内置了丰富的异常体系,常见标准异常包括:
- BaseException:所有异常的基类。
- SystemExit:解释器请求退出。
- KeyboardInterrupt:用户中断执行(通常是 Ctrl+C)。
- Exception:常规错误的基类。
- StopIteration:迭代器没有更多元素。
- ValueError:传入无效参数。
- TypeError:类型错误。
- IndexError:索引超出范围。
- KeyError:字典键不存在。
- AttributeError:对象无此属性。
九、Python 中迭代器和生成器的区别?
生成器是一种特殊的迭代器。生成器能完成迭代器的所有功能,但通过 yield 关键字自动生成 __iter__() 和 next() 方法,代码更简洁高效。使用生成器表达式替代列表解析可节省大量内存。当生成器执行完毕时,会自动抛出 StopIteration 异常。
- 可迭代对象:列表、元组、字典、字符串等,可通过
iter() 转换为迭代器。
- 不可迭代对象:数字、布尔值等。
十、Python 字典以及基本操作
字典是 Python 中最常用的数据结构之一,用于存储具有映射关系的数据。它是一种可变容器模型,由键(key)值(value)对组成,也称为关联数组或哈希表。
- 格式:
{key1: value1, key2: value2}。
- 约束:键必须唯一且为不可变类型(数字、字符串、元组),值可以是任意类型。
- 访问:使用
dict[key] 访问,若键不存在会抛出 KeyError。
- 操作:支持增删改查、遍历、合并等操作。
十一、说说 Python 多线程与多进程的区别?
- 共享变量:多线程可共享全局变量;多进程内存独立,变量互不影响。
- 进程号:线程共享进程号;子进程拥有独立进程号。
- 内存空间:线程共享同一进程的内存空间;进程拥有独立内存空间。
- 通信:线程间可直接交流;进程间需通过 IPC(如队列、管道)通信。
- 创建开销:创建线程成本低;创建进程涉及克隆父进程,开销大。
- 控制:线程可操作同进程其他线程;进程只能操作子进程。
核心差异:在多进程中,同一变量每个进程有一份拷贝;多线程中所有线程共享同一份变量。由于 GIL(全局解释器锁)的存在,Python 多线程在 CPU 密集型任务中优势有限,多进程更适合 CPU 密集型,多线程适合 I/O 密集型。
十二、说说 Python 中 HTTP 常见响应状态码?
HTTP 状态码是服务器返回给客户端的三位数字代码,表示请求的处理结果。主要分为五类:
- 1xx:信息提示。
- 2xx:成功(如 200 OK)。
- 3xx:重定向(如 301 Moved Permanently)。
- 4xx:客户端错误(如 404 Not Found, 403 Forbidden)。
- 5xx:服务器错误(如 500 Internal Server Error)。
十三、Python 中猴子补丁是什么?
猴子补丁(Monkey Patching)是指在运行时动态修改类、模块或函数的行为。常用于在不修改源码的情况下修复 Bug 或添加功能。它仅在内存中生效,不影响原始源码文件,且只对当前运行的程序实例有效。需谨慎使用,以免破坏代码的可预测性。
十四、Python 中的垃圾回收机制?
Python 的内存管理主要依赖引用计数,辅以标记清除和分代回收。
- 引用计数:对象被引用次数归零时立即释放。
- 标记 - 清除:解决循环引用问题,定期扫描根对象可达性。
- 分代回收:将对象按存活时间分为三代,年轻代频繁扫描,老年代低频扫描,优化性能。
十五、Python 中的 6 种位运算符?
- 左移(<<):向左移位,低位补 0。
- 右移(>>):向右移位,高位补符号位。
- 按位与(&):两位均为 1 结果为 1。
- 按位或(|):两位均为 0 结果为 0。
- 按位取反(~):单目运算符,按位取反。
- 异或(^):相同为 0,不同为 1。
十六、Python 中实现二分查找的 2 种方法?
二分查找适用于有序数组,时间复杂度 O(log n)。
def binary_search_iterative(alist, item):
"""二分查找---循环版本"""
first = 0
last = len(alist) - 1
while first <= last:
mid = (first + last) // 2
if alist[mid] == item:
return True
elif item < alist[mid]:
last = mid - 1
else:
first = mid + 1
return False
if __name__ == "__main__":
a = [1, 5, 6, 10, 11, 13, 18, 37, 99]
print(binary_search_iterative(a, 18))
print(binary_search_iterative(a, 77))
def binary_search_recursive(alist, item):
"""二分查找---递归实现"""
n = len(alist)
if n > 0:
mid = n // 2
if item == alist[mid]:
return True
elif item < alist[mid]:
return binary_search_recursive(alist[:mid], item)
else:
return binary_search_recursive(alist[mid+1:], item)
else:
return False
if __name__ == "__main__":
a = [1, 5, 6, 10, 11, 13, 18, 37, 99]
print(binary_search_recursive(a, 37))
print(binary_search_recursive(a, 88))
十七、Python 中的 lambda 表达式?
Lambda 表达式用于定义匿名函数,即没有具体名称的函数。其函数体只能包含一条表达式语句,返回值即为该表达式的结果。适用于需要简单函数但不想费神命名的场景,如传递给 map、filter 等高阶函数。
十八、Python 中的反射?
反射机制允许在运行时动态确定对象类型,并通过字符串调用对象的属性、方法或导入模块。这是一种基于字符串的事件驱动机制。Python 支持的反射函数包括:
getattr(obj, name):获取属性。
setattr(obj, name, value):设置属性。
delattr(obj, name):删除属性。
eval(str):执行字符串表达式。
exec(str):执行字符串代码块。
importlib.import_module(name):动态导入模块。
十九、Python 删除 list 里的重复元素有几种方法?
- 使用 set:利用集合去重特性,但顺序可能丢失。
numList = [1, 1, 2, 3, 4, 5, 4]
print(list(set(numList)))
- 排序后扫描:先排序,从后向前扫描删除重复项,保留顺序。
- 使用字典:利用字典键唯一性。
a = [1, 2, 4, 2, 4]
c = list(dict.fromkeys(a).keys())
- append 方式:遍历列表,仅将未出现过的元素加入新列表。
- count + remove:统计频次,移除多余副本(效率较低)。
二十、Python 中的 new 和 init 的区别?
- new:静态方法,在实例创建之前调用,负责创建并返回实例对象。主要用于控制实例的创建过程。
- init:实例方法,在实例创建完成后调用,负责初始化对象属性。
区别:
__new__ 创造实例,__init__ 初始化实例。
二十一、Python 中的 help() 和 dir() 函数?
- help():显示文档字符串,查看模块、关键字、属性的使用说明。
- dir():列出指定对象的所有属性和方法,不带参数时列出当前作用域内的名称。
二十二、如何提高 Python 运行效率的技巧?
- 使用局部变量代替全局变量。
- 使用较新的 Python 版本以获得性能优化。
- 预编译常用代码。
- 使用生成器表达式替代列表解析以节省内存。
- 关键代码使用 C/C++ 扩展或外部功能包。
- 排序时使用
key 参数而非 lambda。
- 优化算法时间复杂度。
- 循环展开或减少循环内计算。
- 使用 Nuitka 等工具进行交叉编译。
二十三、Python 中的单例模式有几种实现方式?
- new 特殊方法:控制实例创建,确保只有一个实例。
- 装饰器:使用闭包缓存实例。
- 类装饰器:类似装饰器,但作为类修饰符。
- 元类:通过自定义元类控制类的实例化过程。
二十四、Python 实现自省的方法有哪些?
自省(Reflection)指程序在运行时检查自身结构的能力。常用方法包括:
type():判断对象类型。
dir():获取对象属性列表。
help():查看文档说明。
isinstance():判断是否为已知类型。
issubclass():判断继承关系。
hasattr():判断是否存在属性。
getattr() / setattr():获取/设置属性。
id():获取内存地址。
callable():判断是否可调用。
二十五、爬虫的基本步骤?
- 确定需求:明确要抓取的数据目标。
- 确定资源:分析目标网站的 URL 结构和 API。
- 获取数据:通过 HTTP 请求获取网页返回内容。
- 定位数据:使用正则、XPath 或 CSS 选择器提取数据。
- 存储数据:将清洗后的数据存储到数据库或文件中。
二十六、遇到的反爬虫策略以及解决方法?
- Headers 限制:自定义 User-Agent 和 Referer 模拟浏览器。
- IP 封禁:构建代理 IP 池,降低爬取频率。
- 动态加载:使用 Selenium 或 Playwright 模拟浏览器渲染 JS。
- 数据加密:逆向分析加密参数,构造签名。
- Cookie 验证:维护会话 Cookie,模拟登录状态。
- Referer 防盗链:伪造请求头中的 Referer 字段。
二十七、Python 里面如何实现 tuple 和 list 的转换?
- tuple 转 list:
list(tuple_obj)
- list 转 tuple:
tuple(list_obj)
两者均为内置构造函数,转换过程快速且安全。
二十八、魔法函数 call 怎么使用?
__call__ 使得对象实例可以像函数一样被调用。常用于实现类装饰器或回调对象。
class Bar:
def __init__(self, p1):
self.p1 = p1
def __call__(self, func):
def wrapper():
print("Starting", func.__name__)
print("p1=", self.p1)
func()
print("Ending", func.__name__)
return wrapper
@Bar("foo bar")
def hello():
print("Hello")
二十九、Python 如何获取当前日期?
import datetime
print(datetime.datetime.now())
三十、函数装饰器的作用?
装饰器本质上是一个高阶函数,用于在不修改原函数代码的前提下增加额外功能。常用于日志记录、性能测试、事务处理、缓存、权限校验等切面场景。它通过闭包机制抽离通用逻辑,提高代码复用率。
以上三十个问题涵盖了 Python 基础面试的核心考点,建议结合代码实践深入理解。
相关免费在线工具
- 加密/解密文本
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
- RSA密钥对生成器
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
- Mermaid 预览与可视化编辑
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
- 随机西班牙地址生成器
随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online
- Gemini 图片去水印
基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online
- curl 转代码
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online