Python面试高频题:机器人岗位常考的Python知识点,你都会吗
Python系列终于到了最后一篇。前面从基础语法讲到数据分析、深度学习,覆盖了机器人开发中Python的主要应用场景。今天做个收尾——把面试中最常考的Python知识点梳理一遍,帮你查漏补缺。
先说个面试场景。
面试官问:"Python的装饰器是什么?你在项目里用过吗?"
我当时说了句"就是那个@符号的东西",然后就没下文了。
面试官等了几秒,看我没有补充,就换了个话题。后来复盘才知道,这道题答成这样基本就凉了。装饰器是Python面试的高频考点,不会说也得背一个。
今天把机器人岗位面试中最常考的Python知识点整理出来,每个都结合机器人场景讲,帮你高效复习。
GIL:为什么Python多线程不快
面试官问:"Python的多线程为什么不能利用多核?"
答案是GIL——全局解释器锁。CPython(最常用的Python实现)有一个全局锁,同一时刻只有一个线程能执行Python字节码。所以即使你开了10个线程,同一时刻也只有一个在跑。
这对机器人开发有什么影响?如果你的任务是CPU密集型的——比如点云处理、矩阵运算——多线程不会加速,反而可能更慢(线程切换有开销)。解决办法是用multiprocessing模块,每个进程有独立的GIL。
但如果是IO密集型的——比如同时从多个传感器读数据、同时请求多个服务——多线程还是有效的,因为IO操作会释放GIL。
面试时如果能说出"CPU密集型用多进程,IO密集型用多线程",基本就过关了。再进一步可以说concurrent.futures的ProcessPoolExecutor和ThreadPoolExecutor,用起来很方便。
装饰器:面试必考的知识点
装饰器本质上是一个接受函数并返回函数的高阶函数。用@语法糖简化写法。
import time
def timer(func):
def wrapper(*args, **kwargs):
start = time.perf_counter()
result = func(*args, **kwargs)
elapsed = time.perf_counter() - start
print(f"{func.__name__} 耗时: {elapsed:.3f}s")
return result
return wrapper
@timer
def plan_path(start, goal):
# 路径规划算法
time.sleep(0.5) # 模拟计算
return [start, goal]
plan_path((0,0), (1,1)) # 输出:plan_path 耗时: 0.501s
在机器人项目中,装饰器的常见用途包括:给函数加计时(性能分析)、加重试逻辑(网络通信不可靠时)、加日志记录。
面试时如果被问到,至少能说出"装饰器是一个接受函数作为参数、返回新函数的函数",然后举一个实际用途。如果能手写一个简单的装饰器,那就很加分了。
生成器:处理大数据的利器
面试官问:"如果有一个10GB的日志文件,你怎么用Python处理?内存只有4GB。"
答案是生成器。生成器不会一次性把所有数据加载到内存,而是每次产出一个元素:
def read_large_file(filepath):
with open(filepath) as f:
for line in f:
yield line.strip()
# 使用
for line in read_large_file('huge_log.txt'):
if 'ERROR' in line:
process_error(line)
yield关键字让函数变成生成器。每次调用next()时,函数从上次暂停的地方继续执行,直到遇到下一个yield。
在机器人领域,生成器常用于流式处理传感器数据。比如激光雷达每秒产生10帧数据,你不需要把所有帧都存在内存里,用生成器一帧一帧处理就行。
上下文管理器:with语句的原理
面试官问:"with语句的原理是什么?能不能自己实现一个?"
with语句背后是上下文管理器协议——__enter__和__exit__两个魔术方法。
class RobotConnection:
def __init__(self, robot_ip):
self.ip = robot_ip
def __enter__(self):
print(f"连接到 {self.ip}")
self.conn = connect(self.ip)
return self.conn
def __exit__(self, exc_type, exc_val, exc_tb):
print("断开连接")
self.conn.close()
return False # 不抑制异常
# 使用
with RobotConnection('192.168.1.100') as conn:
conn.send_command('move_forward')
最常见的上下文管理器是文件操作——with open()确保文件用完后自动关闭。在机器人项目中,硬件连接、数据库连接、ROS2节点的生命周期管理都可以用上下文管理器来简化。
列表推导式 vs map/filter
面试官问:"列表推导式和map/filter哪个更好?"
功能上两者可以互相替代,但Python社区更推荐列表推导式——可读性更好。
# 列表推导式
successes = [r for r in results if r['success']]
times = [r['cycle_time'] for r in results]
# 等价的map/filter
successes = list(filter(lambda r: r['success'], results))
times = list(map(lambda r: r['cycle_time'], results))
列表推导式更直观,而且通常更快(因为不用调用lambda函数)。但map/filter在处理已有函数时更简洁:list(map(str, numbers))比[str(n) for n in numbers]更短。
面试时两种写法都写出来,说说各自的优缺点,面试官会觉得你对Python理解得比较深入。
深拷贝和浅拷贝
面试官问:"a = [1, [2, 3]]; b = a; b[0] = 10; b[1].append(4)。a是什么?"
答案是[10, [2, 3, 4]]。因为b = a只是引用赋值,a和b指向同一个列表。
如果是浅拷贝b = a.copy(),b[0] = 10不会影响a,但b[1].append(4)会影响——因为嵌套的列表还是共享的。
深拷贝b = copy.deepcopy(a)则完全独立,修改b不会影响a。
在机器人项目中处理传感器数据时,这个问题经常出现。比如你拿到一个位姿列表,想修改其中一份但不影响原始数据——这时候必须用深拷贝。
高频考点之GIL与多进程
Python面试几乎必问GIL(全局解释器锁)。简单说,GIL使得同一时刻只有一个线程执行Python字节码,所以CPU密集型任务用多线程并不能真正并行。解决方案是用multiprocessing模块,每个进程有独立的GIL。在机器人项目中,感知和处理流水线适合用多进程,而IO密集型任务比如网络通信用多线程或asyncio就够了。
补充一个面试常问的点:装饰器的原理。本质上装饰器就是一个接受函数作为参数并返回新函数的高阶函数,理解了这个概念,闭包、回调等知识点就都串起来了。
给正在准备面试的你
Python系列15篇到此结束。从Python定位、基础语法、数据结构、面向对象、文件处理,到NumPy、Matplotlib、ROS2混合编程、测试、数据分析、PyTorch、脚本自动化、Jupyter,最后到面试高频题——基本覆盖了机器人岗位面试中Python相关的所有考点。
面试前把这几篇过一遍,每个知识点能用自己的话解释清楚、举出实际项目中的例子,Python这块就稳了。
下篇进入Linux与开发工具系列。第一篇聊Ubuntu安装与配置——你的第一个ROS开发环境。
如果这篇文章对你有帮助,欢迎点赞、在看、转发三连。 你的支持是我持续更新的最大动力。
「机器人软件开发面试·从入门到精通」连载系列 上一篇:第79篇 Jupyter Notebook——算法调试和实验记录的最佳实践 下一篇预告:第81篇 Ubuntu安装与配置——你的第一个ROS开发环境
有任何问题欢迎评论区留言,我会尽量回复。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐



所有评论(0)