这份第四范式测试开发笔试题乍一看是某个AI公司的校招真题但它背后透露出的信息量很大一家以机器学习平台为核心业务的AI公司在招测试开发时到底想考什么这跟普通互联网公司的测试开发笔试题有什么区别先说结论别被AI公司这三个字吓到这份笔试题并没有满卷子都是机器学习公式推导反而是算法 测试思维 工程基础的经典组合但在用例设计题和部分算法题上会明显偏向数据、模型评测相关的场景。这篇文章不是原题复述而是我综合多位参加过那年校招的同学反馈结合自己这些年在AI公司做测试开发的经历把考点方向、典型题型和解题思路完整复盘一遍。无论你是准备校招的应届生还是想转行测试开发、想了解AI公司测试岗门槛的工程师这篇都能给你一个清晰的参照系。1. 招聘季的笔试卷子藏着公司对测试开发的真实定位1.1 为什么第四范式的笔试题会这样出第四范式的核心业务是机器学习平台和AI解决方案客户大多是金融、零售、能源这类传统行业。这种业务形态决定了它的测试开发岗位有几个特点既要测传统软件功能Web平台、API接口、管理后台也要测机器学习模型相关的内容离线评估、效果报表、上线监控。测的东西往往没有唯一正确答案尤其是模型效果类测试需要结合业务指标和数据分布来判断。测试开发不是纯手工点点点要搭建自动化框架、开发测试工具、写数据校验脚本所以代码能力必须过关。基于这些业务背景笔试的题目分布就很有针对性了——大约三成考通用算法和编码两成考测试思维和用例设计两成考计算机基础网络、数据库、操作系统一成半考机器学习基础概念剩下一成半是语言与工程能力。这个比例对准备任何一家AI或金融科技公司的测试开发岗都有参考价值。1.2 笔试时长与题型的常见配置从那年参加过笔试的同学反馈来看整体结构大致是时长90~120分钟纯线上笔试语言以C、Java、Python为主多数支持切换。题型单选/多选题覆盖计算机网络、操作系统、数据库、Python/Java基础2道左右编程题在线OJ判题外加1~2道用例设计或测试方案设计问答题人工阅卷。这里有个容易忽视的点主观问答题虽然没有OJ那样非对即错但它是拉开差距的关键。因为编程题大家都会刷而用例设计题能真实反映你有没有测试思维——这也是后面第3章重点展开的内容。1.3 测试开发与纯开发笔试的差异代码能力是门槛测试思维才见高下很多人会问测试开发的笔试题是不是比开发的简单从算法难度上看确实少了很多hard级别的动态规划或复杂图论考的还是以数组、字符串、链表、栈队列、简单二叉树为主。但在测试思维类题目上要求反而比开发岗高。开发岗笔试很少让你设计测试用例而测试开发的笔试题会直接给你一个功能模块让你从零开始列用例、画流程、覆盖异常场景。所以准备这份笔试题只刷LeetCode是不够的系统性地整理测试理论、用例设计方法和AI基础概念同样重要。2. 算法与代码题拆解在线OJ里的高频题型与易错点2.1 字符串和数组处理边界条件的陷阱以字符串转整数这类题为例考的不是你会不会调库而是处理异常边界的能力。典型要求是手动实现atoi函数需要考虑前置空格和正负号溢出超过int范围时返回最大值或最小值非法字符遇到第一个非数字字符时停止转换空字符串兜底。我见过不少代码大方向对但细节翻车的有人忘了处理 -42这种带空格的输入有人没判断溢出还有人在越界的处理上直接抛异常而不是按要求返回值。这类看起来简单但细节极多的题正是测试开发岗位最看重的——测的是你考虑问题的完备性。实际笔试时建议写一个输入输出辅助函数来快速自测def myAtoi(s: str) - int: s s.lstrip() if not s: return 0 sign 1 i 0 if s[0] in -: if s[0] -: sign -1 i 1 num 0 INT_MAX, INT_MIN 2**31 - 1, -2**31 while i len(s) and s[i].isdigit(): num num * 10 int(s[i]) if sign * num INT_MAX: return INT_MAX if sign * num INT_MIN: return INT_MIN i 1 return sign * num2.2 数据结构应用题LRU缓存的考场实现LRU缓存是近年笔试的高频考点因为它既能考察数据结构设计能力又能考察对复杂度的理解。这类题在LeetCode 146上有原型考察点集中在能否想到用哈希表 双向链表来达成O(1)的get和put链表节点的维护是否严谨get时要不要把节点移到头部put时要不要淘汰尾部节点是否注意了容量边界和重复key的更新场景。如果你只用了OrderedDict或者每次get都遍历列表很可能通不过大数据量的性能测试。常规模板是class LRUCache: def __init__(self, capacity: int): self.cap capacity self.dict {} self.head Node(0, 0) self.tail Node(0, 0) self.head.next self.tail self.tail.prev self.head def get(self, key: int) - int: if key in self.dict: node self.dict[key] self._remove(node) self._add(node) return node.value return -1 def put(self, key: int, value: int) - None: if key in self.dict: self._remove(self.dict[key]) node Node(key, value) self._add(node) self.dict[key] node if len(self.dict) self.cap: old self.head.next self._remove(old) del self.dict[old.key]写完之后记得在纸上手动模拟一下容量为2依次put(1,1)、put(2,2)、get(1)、put(3,3)看看是不是淘汰了key2。这类手推过程能帮你抓出指针维护上的逻辑错误。2.3 滑动窗口与经典查找比暴力解更优的拿分点最长无重复字符子串、两数之和、三数之和也都是高频考点。以最长无重复子串为例暴力解是O(n^2)但用滑动窗口哈希集合可以优化到O(n)。笔试时建议先写暴力解确保思路正确在性能用例超时后再优化这种策略在时间紧张时最稳妥。这里有一个很多人没意识到的细节在线OJ的判题环境通常会让多组测试用例同时跑你的程序如果写了while True或者input()读取要考虑输入是否有多余空格、是否需要处理EOF否则很容易出现本地运行正常、提交却WA的情况。每次提交前先检查读入方式是否覆盖了所有合法输入形态。3. 测试理论与用例设计题拉开分差的主观题3.1 从水杯测试到实际业务场景答题框架比灵光一现重要测试理论题里最经典的莫过于如何测试一个水杯但第四范式这类AI公司的笔试题不会直接问水杯而是会换成贴近业务的形式设计一个用户登录功能的测试用例、设计一个文件上传模块的测试用例、或者设计一个支付订单的测试方案。回答这类题的通用框架可以按六维拆解功能测试正常流程、异常流程、业务流程的组合比如支付成功、支付失败、订单重复提交。界面测试布局、文案、交互反馈、不同分辨率下的显示。性能测试并发数、响应时间、资源占用、接口超时处理。安全性测试越权访问、SQL注入、敏感信息加密、验证码暴力破解。兼容性测试不同浏览器/操作系统/设备、不同屏幕尺寸。异常场景断网、弱网、服务器异常、缓存穿透、幂等性。以用户登录为例一个合格的答题角度应该是这样铺开正常场景正确账号密码、记住登录状态、自动登录、多端互踢异常场景密码错误次数超过上限、账号被锁定、账号不存在、验证码过期、密码包含特殊字符安全场景登录接口是否限流、密码传输是否加密、token是否在退出后失效兼容性微信内置浏览器、PC端Chrome、iOS Safari、Android WebView性能验证码接口在高并发下能否扛住、登录接口的平均响应时间。我当时在实际笔试里吃过亏只写了功能用例没有覆盖异常和安全。后来总结出一个经验——任何用例设计题异常场景至少要占到全部用例的三分之一。因为面试官从用例设计就能看出你是只会验证Happy Path还是能预判线上事故的测试工程师。3.2 机器学习场景的用例设计题AI公司笔试题的差异化考点除了通用功能测试题AI公司还会出一些和模型评测相关的开放题。我印象比较深的一道类似题是给定一个图片分类模型如何设计一套完整的测试方案来评估它的上线质量这类题没有标准答案但一个有经验的测试开发应该拆成几个层面数据层面收集多少张测试图片、类别分布是否均衡、是否需要包含对抗样本和模糊样本、是否需要人工标注校验集。指标层面整体准确率、各类别精确率和召回率、F1、混淆矩阵分析、不同光照/角度条件下的分层指标。对比层面与线上基线模型的对比测试确定是否有明显回退。鲁棒性层面图像加噪、旋转、裁剪后的稳定性测试对异常输入全黑图片、二维码图片、非图片文件的处理能力。工程层面接口返回的置信度是否合理、推理延迟是否满足SLA、GPU显存是否泄漏、batch size变化时是否稳定。你看这其实就是把传统软件测试的兼容性、性能、异常场景翻译成了模型测试语言。如果你能提前准备一个这样的答题模板遇到AI相关的测试设计题会从容很多。3.3 从笔试题到面试测试思维可以被刻意训练笔试里的测试设计题面试环节也会继续深化。我见过很多候选人笔试写得不错但面试被问到这个用例发现问题后你怎么定位是前端还是后端的问题就卡住了。这说明他们对测试的理解停留在列用例层面缺少分层排查的思路。一个有效的刻意练习方法是每天选一个日常功能比如天气App、扫码支付、外卖下单用上述六维框架写下3~5条你觉得最重要的用例并追问自己这条用例如果失败了最可能挂在哪一层坚持两周你写测试设计题时的覆盖度和逻辑层次会有明显提升。这个训练不需要任何平台或课程用笔写在纸上就行。4. 机器学习基础题AI公司测试开发的附加题与送分题4.1 为什么测试开发也要懂机器学习概念很多人不理解我是去测软件的为什么要懂准确率、召回率、AUC原因很简单——AI公司交付的产品核心是模型和平台测试开发岗位要验证的不只是按钮能不能点还包括模型效果是否符合预期特征数据是否正确推荐结果有没有明显偏差。如果不了解机器学习的基础概念你连提测单都看不明白更别说设计验证方案了。所以笔试里出现这类选择题很正常关于过拟合与欠拟合、精确率与召回率、ROC曲线与AUC、梯度下降的作用等。它们不难都属于机器学习入门必学内容但如果你完全没准备确实会丢分。4.2 高频概念的通俗解释与常见考法过拟合与欠拟合过拟合是模型在训练集上表现很好、在测试集上表现差相当于把训练数据背下来了没有泛化能力。欠拟合则是模型过于简单连训练集都没学好。考点常给一个模型评估场景问你最可能是什么问题、怎么解决如增加正则化、增加数据量、降低模型复杂度、早停等。精确率与召回率一句话记忆法——精确率是你预测为正类的样本里有多少是对的召回率是实际正类样本里你找回了多少。在不平衡数据集下光看准确率没有意义比如1000个样本里只有1个异常全预测正常准确率也是99.9%。ROC与AUCAUC衡量模型把正样本排到负样本前面的能力AUC0.5相当于随机猜越接近1越好。它最大的优点是受类别不平衡影响小。考点常问在正负样本极不平衡的场景下评估二分类模型应该看什么指标答案通常是AUC或PR曲线而不是简单准确率。4.3 模型评估测试的实操思路从测试开发的实操视角看模型测试和传统功能测试有本质区别传统功能测试有明确的期望输出模型测试则是基于统计指标的判断。你不能说这个模型的准确率没到100%就是bug而是要去看它有没有达到业务准入线、有没有比线上旧模型有显著提升、在某些关键类别上有没有明显回退。我自己的一个经验是实际做模型评测时不能只盯整体指标。有一次我们上线一个推荐模型整体AUC比旧模型高了0.02看起来是正向的但按用户分层一拆发现新用户组的点击率明显下降。如果不是做了分层分析这个线上负向就被整体指标掩盖了。这就是测试开发在AI场景下的核心价值——发现被平均数掩盖的问题。如果在笔试里遇到如何评估一个模型是否适合上线试着从离线指标AUC、F1、分层指标、在线指标CTR、转化率、延迟、回退预案几个维度去答会显得非常完整。5. Python与工程能力考察代码习惯暴露你是不是好的测试开发5.1 Python基础高频概念与容易翻车的细节Python是测试开发最常用的语言笔试选择题里常考装饰器、生成器、深拷贝浅拷贝、列表推导式、is与的区别等基础概念。其中is与的区别几乎是必考is比较的是内存地址比较的是值。这个点看着简单但考得很细。另一个高频考点是可变对象作为函数默认参数。看这段代码def add_item(item, lst[]): lst.append(item) return lst print(add_item(1)) # [1] print(add_item(2)) # [1, 2]第二次调用时lst已经不是空列表了而是第一次调用后留下的[1]。因为默认参数在函数定义时就被创建且在多次调用中复用同一个对象。正确的做法是def add_item(item, lstNone): if lst is None: lst [] lst.append(item) return lst这种细节虽然不直接影响测试设计能力但能体现你的工程素养——一个连可变默认参数都没意识到的候选人写自动化脚本时很可能埋下难排查的坑。5.2 pytest与mock测试开发必须拿得出手的框架能力如果笔试有问答题或编程题涉及如何编写自动化测试pytest是绕不开的高频答案。需要掌握的不仅仅是写一个assert函数还包括fixture的使用用来做测试前置和后置比如建立数据库连接、创建临时文件、清理测试数据。和unittest的setUp/tearDown相比fixture的模块化程度更高按需使用不影响其他用例。parametrize参数化同一份逻辑用多组数据验证避免复制粘贴。mock的使用场景被测代码依赖外部API、支付接口、第三方服务时用mock模拟返回值确保单测本地可跑且不受网络影响。举个例子测试一个调用用户信息接口的函数时可以这样mockimport requests from unittest.mock import patch def get_username(user_id): resp requests.get(fhttps://api.example.com/user/{user_id}) return resp.json()[name] patch(requests.get) def test_get_username(mock_get): mock_get.return_value.json.return_value {name: Alice} assert get_username(1) Alice mock_get.assert_called_once()这类题目如果在笔试或面试答道会明显加分。因为它说明你不仅仅是会用测试框架还懂得如何隔离被测系统和外部依赖这正是自动化测试稳定性的关键。5.3 工程能力代码规范与日志习惯笔试虽然不会直接考你代码规范但阅卷时是有印象分的。比如变量命名是否有语义而不是a、b、c函数有没有拆分一个函数是否做了太多事情有没有写注释注释是否在说为什么而不是做了什么是否考虑了异常处理比如文件读取、网络请求时是否捕获了异常并打了日志。我在实际写自动化脚本时养成的一个习惯是每个测试步骤都输出一段包含上下文关键数据的日志比如请求的URL、入参、出参、耗时。这样测试一旦失败定位问题的时间能省一半以上。这个习惯如果你在笔试中以注释或日志的形式体现也会给面试官留下这个人有线上维护意识的印象。6. 计算机基础与数据库看似简单却最容易丢分的模块6.1 常考的网络题HTTP状态码和请求幂等性笔试选择题里网络模块的主要考点有HTTP状态码含义200成功、301/302重定向、400请求错误、401未认证、403禁止访问、404不存在、500服务器内部错误、502网关错误、503服务不可用。GET与POST的幂等性GET是幂等且安全的POST不是PUT一般设计为幂等但DELETE是幂等的。这个点经常被问而且容易和实际HTTP规范混淆要注意区分规范设计和实际实现。Cookie与SessionCookie存在客户端Session存在服务端。用户登录后服务端返回SessionID并写入Cookie后续请求带上它来识别用户身份。TCP三次握手与四次挥手常考为什么是三次握手原因是防止失效的连接请求到达服务端造成资源浪费。测试开发岗位虽然不写网络协议库但做接口测试、排查超时问题时刻离不开这些概念。6.2 数据库必考SQL的联表与聚合数据库相关题目中最常考的就是分组聚合和联表查询。给你两张表——订单表和用户表统计每个用户的订单数和消费总额。核心SQL结构大概是SELECT u.user_id, COUNT(o.order_id) AS order_cnt, SUM(o.amount) AS total_amount FROM user u LEFT JOIN order o ON u.user_id o.user_id GROUP BY u.user_id;这里有几个易错点内连接会漏掉没有订单的用户如果题目要求所有用户的统计必须用LEFT JOINCOUNT和SUM要区分空值语义没有订单时SUM返回NULL而不是0必要时用COALESCE(SUM(o.amount), 0)GROUP BY的字段必须与查询的非聚合字段一致。笔试里还有一类陷阱题是关于索引的比如一个查询在WHERE子句中对索引字段使用了函数如WHERE DATE(create_time) 2024-01-01这样会导致索引失效。从测试的角度你可以引申一下线上大数据量查询出现慢SQL时优先检查索引是否被函数包裹这属于性能测试的常见排查技巧。6.3 Linux命令测试环境排障的基本功Linux命令在笔试里通常以选择填空出现常见考点ps查看进程、grep文本过滤、awk列处理、tail -f实时查看日志、top资源监控、netstat查看端口占用。有一些考察方式比较贴近实际场景给一个线上问题描述选出排查命令的组合。这个模块不需要死记硬背关键是理解每个命令的适用场景。比如要查某个Java服务是否在运行且占用多少内存通常用ps -ef | grep java结合top要查服务端口8080被哪个进程占用用netstat -tlnp | grep 8080或lsof -i:8080。如果你没在Linux环境下实操过建议用虚拟机或云服务器下手动练几遍纯粹靠记忆很难应付活的场景题。7. 备考策略与时间安排两周冲刺还是提前三个月铺路7.1 针对不同基础的备考路线建议如果你是在校生准备秋招我的建议是不要把这份笔试题孤立地刷而是把它嵌入一个大框架第一周~第二周过一遍计算机网络、操作系统、数据库基础配合选择题刷题每天50道。第三周~第四周集中刷LeetCode热题100重点练数组、字符串、哈希表、链表、栈队列、二叉树这几个高频大类。测试开发岗不用追求hard题但medium题要熟练到20分钟内写出AC。第五周~第六周系统整理测试理论包括测试用例设计方法等价类、边界值、场景法、判定表、缺陷生命周期、测试流程需求评审、测试计划、用例评审、回归测试。这部分强烈建议亲手写几套用例再对照网上的优秀用例找差距。第七周~第八周重点补齐机器学习基础概念不需要会推导公式但要能说清楚每个指标的含义和应用场景。每周穿插手写SQL题至少10道Linux常用命令过一遍。如果你是非科班转测试开发时间线要拉长到4~6个月前两个月先补编程基础和计算机基础中间两个月练测试理论和自动化测试框架最后一个月刷真题和模拟面试。切忌一上来就刷LeetCode——没有数据结构基础硬刷题效率极低。7.2 考场上的时间分配策略以90分钟为例选择题控制在30分钟以内编程题每道控制在20~25分钟留至少15分钟给主观设计题。这个顺序可能和大多数人的习惯不一样——我更倾向先做编程题再做设计题因为编程题需要高度集中注意力放到最后容易因为疲劳而出错。设计题是文字性工作即使大脑有些疲劳也能输出结构化内容。如果编程题卡了超过25分钟果断跳过先把后续能拿的分拿稳。测试开发岗的笔试不是比谁解出最难的题而是比谁该拿的分一分没丢。7.3 从笔试延伸到面试的加分准备笔试只是第一关一般情况下通过笔试后一周内会约面试。面试环节通常会围绕笔试内容继续深挖笔试里你写的测试用例思路、你用过的自动化框架、你对某个线上问题排查的设想。因此在准备笔试时养成的习惯面试会直接受益。我特别建议准备一份项目/实验复盘文档列出你做过的最复杂的测试任务或开发任务用STAR法则写清楚背景、任务、行动、结果。面试官问你最有成就感的一个项目时你直接有结构地讲出来比临场组织语言强太多。这个准备动作不花太多时间但对面试通过的提升非常显著。写在最后刷题之外别忘了测试开发的本质整理这份笔试复盘的过程中我一直在想一个问题刷这么多题到底是为了什么答案是——为了通过一道筛选门但最终决定你能不能在这个岗位走远的是你对质量的理解深度。算法题训练的是逻辑严谨性测试设计题训练的是风险覆盖面AI基础题训练的是对新技术领域的快速理解能力这些加在一起才是一个测试开发工程师的完整画像。我遇到过不少候选人刷题很猛但问为什么要做接口自动化而不是全用UI自动化时答不上来。其实答案很朴素UI自动化成本高、稳定性差而接口测试更贴近业务逻辑层性价比更高。这种从成本和风险角度做技术决策的意识恰恰是笔试之外真正拉开差距的东西。如果你正在准备这类笔试最后送你一句我自己的经验把每一次刷题、每一道用例设计题都当作一次如果你来负责这个功能的质量你会怎么思考的练习而不是如何通过一场考试的应付。带着这个心态去准备你会发现笔试题突然变得有画面感了面试时谈吐也会自然得多。祝你顺利。