
2019年秋招的时候我做过小米这套测试开发笔试题A。说实话当时做题的感觉是“题目不难但每个板块都在暗暗埋坑”。后来工作几年自己也参与过校招出题和面试再回头看这套题才慢慢咂摸出出题人想考核的东西其实非常清晰理论基础、工程习惯还有最容易被忽略的测试思维。今天把这套题完整拆一遍不只是为了回忆更是因为它的知识结构在现在的测试开发笔试里依然被大量复用。无论你是在准备大厂秋招、社招跳槽还是单纯想从功能测试转测试开发这份拆解都值得仔细看一遍。1. 这套卷子背后的招聘逻辑2019年的小米到底在挑什么人1.1 为什么一份三年前的笔试题还有参考价值很多人看到年份会觉得“2019年的题太旧了现在不考这些了吧”。如果你这么想大概率会错过真正重要的东西。校招笔试和招聘本身有很强的延续性它不像技术栈迭代那么快核心计算机基础、逻辑思维、测试设计方法这些是十年都不会变的。2019年恰好是小样AIoT战略铺开、大量招人的阶段测试开发需求量很大所以这套题非常能代表“大厂在招测试开发时最关注什么”。哪怕放到现在你在牛客网搜一圈也能看到大量相似风格的题目只是换了层新皮。1.2 出题人视角测试开发不是“会点点点的测试”也不是“只会写业务的后端”很多应聘者对测试开发岗位的理解有偏差。有人说测试开发就是功能测试加一点自动化脚本有人说测试开发是写代码能力弱化版的开发。这两种认知在笔试里会死得很难看。小米这套题的设计逻辑明摆着是想招“有开发功底的测试工程化人员”。它的考察维度横跨两大块一是计算机通用基础包括数据结构、操作系统、网络、数据库、编程语言这决定了你有没有能力去读代码、写工具、定位问题二是测试专业能力包括测试用例设计、测试流程、异常场景分析这决定了你脑子里有没有“质量风险”这根弦。这其实是一个双重漏斗。第一层刷掉“只背题但不懂原理”的应试者第二层刷掉“只会写代码但完全没有测试敏感度”的开发思维者。两个能力必须同时在线缺一个都进不了下一轮。1.3 从岗位现实倒推考察点测试开发日常在干什么如果不理解岗位日常就很难理解为什么题目是这么分布的。我当时工作后总结过测试开发的核心日常无非四件事把测试需求转化成可执行的测试方案设计和执行高效、有覆盖率的用例开发自动化测试工具或平台提升测试效率在项目上线前对风险进行整体评估推进问题闭环。这四件日常对应到这套笔试题里就是测试方案对应测试设计题和简答题用例覆盖率和异常思维对应客观题里那些“看似都会、一做就错”的细节题自动化工具能力对应编程题风险评估则藏在每一道需要你“多说几句”的分析题里。2. 题型结构复盘每类题目背后都在卡哪种能力2.1 客观题覆盖范围极广但深度并不离谱这套卷子的客观题单选、多选、填空主要分布在计算机基础上。我根据记忆和当年整理的考点帮大家归类了大致分布比例考察方向高频考点大概占比数据结构与算法数组、链表、栈、队列、二叉树遍历、排序复杂度25%操作系统进程与线程、死锁、内存管理、进程通信15%计算机网络TCP/UDP、HTTP状态码、三次握手、DNS15%数据库SQL查询、索引失效场景、事务隔离级别10%编程语言数组指针关系、内存分配、面向对象特性20%Linux/测试基础常用命令、测试流程、缺陷生命周期15%这个比例今天看起来也基本合理。客观题的特点就是“广撒网”它不指望你每道题都满分但如果你在某一类题目上大面积丢分说明你的知识栈有明显短板。对测试开发来说短板意味着在实际工作中遇到对应领域的问题时你可能连思路都没有。2.2 简答题与测试设计题拉开差距的核心板块这套卷子不是单纯的“客观题编程题”组合中间的简答题和设计题才是真正决定你能不能进面试的环节。典型的形式有给一个具体功能模块让你设计测试用例给一个线上故障场景让你分析排查思路给一段代码片段让你指出潜在问题并设计验证方案。这类题没有标准答案但判分有明确逻辑看你有没有分类思维能不能按功能、性能、安全、兼容、异常等维度系统展开看你有没有边界意识能不能想到空数据、极端值、并发冲突看你有没有工程判断力能不能区分哪些用例优先级更高。大多数人答这类题时最容易犯的毛病就是想到一条写一条毫无逻辑。这种答案在阅卷人眼里等同于没思路。后面我会专门用一节来演示什么叫“结构化的测试设计答案”。2.3 编程题题量不大但暗中考察工程习惯编程题一般控制在两到三道难度在中级偏下基本不会出超级难的动态规划或复杂的树形DP。但有一个关键点这些题表面上考算法实际上考的是你能不能写出“干净、正确、有防御性”的代码。比如数组越界、空指针、格式化输入、极端元素大多数人不是不会算法而是挂在细节上。我当时做题有个很重要的心态把编程题当成“你在这个团队里提交的第一段代码”来写。变量名要有意义、逻辑要分段清晰、边界条件要处理完整。面试官从笔试代码里不仅看你会不会做这道题更看你有没有基本的代码洁癖。3. 客观题高频考点深挖为什么这些“八股文”绕不过去3.1 数组与指针C系语言考点里常有Java方向则换了个马甲热词里反复出现“数组和指针笔试题”说明这是整个笔试题生态里的高频常客。在小米这套题里也不例外。它核心要考的是两个层次第一层次你知不知道数组名和指针的关系、sizeof对数组和指针的差异、指针加减运算的实际含义第二层次你能不能把一个数组操作问题放到内存模型里去想而不是死记结论。举个例子C语言里int arr[10]sizeof(arr)是40字节但把它传进函数后sizeof(arr)变成了8字节64位系统下的指针大小。很多人觉得这是“坑”其实它考核的就是“数组在作为函数参数时会退化为指针”这个底层机制。Java方向虽然没有指针语法但类似的思想并没有消失只是换了一个马甲比如String和char[]的区别、引用传递与值传递、Integer的缓存范围-128到127。这些题本质上都在问同一个问题你知不知道内存里发生了什么对测试开发来说这不是咬文嚼字而是排查线上问题时必备的底层认知。你写的每一个自动化用例背后都有一块真实的内存区域在执行你的逻辑看不懂它出了问题你都不知道去哪里抓。3.2 数据结构与算法选填栈队列哈希是“测试工具思维”的地基客观题里的数据结构题目一般不会太难但考得相当灵活。常见的出题方式是把数据结构放到具体场景中给你一段代码分析它的时间复杂度给你括号匹配的变体问栈的入栈出栈顺序给你哈希表的冲突处理过程问查找的平均复杂度或者给你一个二叉树的前中后序遍历结果让你还原树的形态。这些考点为什么对测试开发重要因为你在写自动化测试框架、做流量录制回放、处理测试数据时天天都在跟这些数据结构打交道。队列可以用来做异步任务调度模型栈可以用来匹配括号、处理嵌套结构哈希表是断言结果集时的首选结构。我曾经在团队里带过一位刚毕业的同学他写接口自动化脚本时为了判断两个列表是否相等直接两层 for 循环暴力比对数据量一大就卡死。后来我跟他讲先把两个列表转成哈希集合再比对时间复杂度从 O(n²) 降到 O(n)。这就是笔试里那些“数据结构题”的实战意义。3.3 操作系统、计算机网络、数据库测试开发定位问题时的三把刀操作系统这块频率最高的是进程与线程的区别、死锁的四个必要条件、进程间通信方式。这些概念纯粹是“八股”但你没背熟的话遇到性能测试相关问题时会完全懵。比如压测时 CPU 飙高你要能判断是线程上下文切换太频繁了还是代码里有死循环。没有操作系统基础你连排查方向都没有。网络部分TCP 三次握手、四次挥手、HTTP 状态码是绝对重点。有一类经典题是“访问一个网站从输入 URL 到页面加载完成经历了哪些过程”这道题几乎每年都会以各种形态出现。它考察的是全链路的网络理解DNS 解析、TCP 连接、HTTP 请求、服务端处理、响应返回、浏览器渲染。对测试开发而言这不仅是笔试更是日常定位 bug 的完整思路框架。数据库考察点集中在 SQL 编写、索引失效、事务隔离级别。测试开发必须会写 SQL因为你要造数据、查数据、清理数据这些全是基本功。索引失效的典型场景比如在索引列上使用函数、隐式类型转换、like %xx 开头模糊查询这些知识点几乎每套笔试题都有。不光是为了应付笔试你写测试数据查询语句时如果连索引生效条件都不懂连一个生产环境的数据核对需求都做不好。3.4 Linux命令和日志排查看起来送分实际送命很多人对 Linux 命令题不以为意觉得背几个命令就行。但这套题里的 Linux 题目非常贴近真实工作场景比如线上日志文件一直在增大你怎么找到占用磁盘最大的目录服务接口偶发超时你怎么查看网络连接状态某个端口被占用你怎么定位是哪个进程这些场景对应的命令组合是df -h先看磁盘整体情况du -sh *逐层定位大目录lsof -i :8080或netstat -tunlp | grep 8080定位端口占用top、free查 CPU 和内存tail -f看实时日志。每一个都不是孤立的命令而是排查问题的完整链路。这类题不考你背了多少命令考的是你能不能像侦察兵一样顺藤摸瓜。4. 测试设计题分数真正的分水岭4.1 为什么说客观题拉不开差距设计题才是客观题大家背背八股文都能混个差不多但测试设计题不是背出来的。阅卷人能从你的答题结构里一眼看出你是有测试经验的还是纯刷题背答案的。最典型的例子就是“电梯测试题”。这道题被说烂了但每年还是有一大批人答得乱七八糟。普通答案是按楼层按键是否正常、电梯门开关是否正常、超重报警是否正常、不同楼层按键响应是否正确。这种答案就是“想到哪写到哪”没有框架、没有优先级、没有边界感。稍微好一点的答案会分类功能测试楼层选择、开关门、楼层显示、性能测试载重上限、运行速度、高峰期响应时间、安全性测试超载保护、停电应急、门夹人检测、兼容性测试不同品牌电梯控制器协议、易用性测试按键高度、盲文标识。这样答已经有结构了但还不够因为你还是没有体现测试设计的“工程决策”能力。高分答案会在分类的基础上再加两样东西场景流和优先级。场景流就是按照角色生命周期来设计用例比如“用户从一楼进入电梯→选择10楼→电梯上行→到达10楼→开门→用户离开”每经过一个节点列出对应的验证点。优先级就是明确标注哪些用例是 P0、P1、P2比如“电梯在运行中开门”就是 P0因为涉及人身安全“电梯广告屏播放流畅度”是 P2因为不影响核心功能。4.2 一个完整案例推演扫码支付自动售货机的测试设计为了让你看清楚什么叫“结构化设计”我拆一个当年笔试常见的变体题扫码支付自动售货机。这题比电梯更贴近互联网业务也更能考察你对前后端、支付链路、异常处理的理解。拿到题之后先在草稿纸上画一条主流程用户扫码→选择商品→创建订单→发起支付→支付成功回调→出货→交易完成记录。基于这条主流程分类展开功能测试扫码后能不能正确识别商品并展示库存余额不足或支付失败时会不会停止出货支付成功但未出货的情况怎么处理取消支付后订单状态是否正确退款流程是否可用。接口与数据测试支付回调重复通知时系统能不能保证幂等避免重复出货订单金额与实际扣款是否一致并发扫码购买同一件剩余库存为1的商品会不会出现超卖断网、弱网、支付中途退出App状态是否一致。异常测试售货机出货卡住怎么办超时后有没有自动重试或退款支付成功后机器断电重启后订单状态怎么恢复库存扣减了但出货口没有货用户投诉入口怎么处理。安全和兼容性不同品牌手机扫码兼容性二维码被替换的风险支付金额参数篡改是否能被后端校验拦截。安全性测试点在笔试里非常加分因为说明你有“坏用户视角”这也是测试开发区别于普通测试的重要价值。你能想到“用户把商品金额改成0.01元去支付”这种风险阅卷人就会觉得你有实战经验。然后按优先级排序P0 是支付确认与出货的一致性问题P1 是超卖、重复出货、退款异常P2 是弱网提示、用户体验细节。这样的答案才叫“设计”而不是“罗列”。4.3 用例设计方法论在笔试中如何落地光有框架还不够笔试时还要表现出对方法论的理解让阅卷人看到你“懂测试”而不是“碰巧想到了”。最常用的方法是等价类划分——把输入数据分成有效等价类和无效等价类每个等价类取一个代表值去测试。比如登录密码长度6-20位有效等价类是7位、15位这种无效等价类是5位、21位。用这个方法的目的是用最少的用例覆盖尽可能多的场景。边界值分析——在等价类的基础上专门测试边界及其左右两侧的值。还是密码长度的例子要测6位、7位、20位、21位因为经验表明错误高发区就在边界附近写代码时最容易挂掉的条件就是和写混。场景法——从一个完整的用户操作流程出发设计用例覆盖主流程、备选流程和异常流程。这是我最推荐在笔试答案里体现的方法因为面试官看到的不是一个一个孤立的功能点而是你脑子里有一条完整的用户路径。错误推测法——依靠经验预测系统可能在哪些地方出错。比如支付金额为0、商品库存为负数、并发请求重复提交、时间字段跨越闰秒等。这类测试点在笔试中很能体现“经验感”。在写答案的时候不要直接堆术语而是先写一条“我按什么思路分类”再把术语自然嵌进用例描述里。比如“我对支付金额字段做等价类划分并选取0元、负数、极大值做边界验证”。这样既显专业又不生硬。4.4 如何让答案看起来比实际经验更深一层很多人觉得自己没有真实测试经验笔试设计题会吃亏。其实不是的你完全可以通过“思维方式”来弥补“经验不足”。阅卷人想看到的不是你有没有测过售货机而是你能不能把未知的事物拆解成已知的系统模块。一个技巧是答题时先亮出你的分析维度。不管题目是电梯、登录框、支付接口还是智能音箱你都可以先说“我会从功能、性能、安全、兼容、异常、易用性六个维度来分析”。这个开头一写出来你的答案已经超过了60%的人。再一个技巧是每个维度下面不用写太多条但每条都要“带原因”。比如“我要测试网络断开时的支付行为因为在弱网环境下支付请求可能已经发出但客户端没收到响应这时要验证服务端是否会重复扣款”。带上原因说明你想到了背后的逻辑而不是硬凑。这种“原因意识”是高级测试设计题的核心也是面试官最爱追问的地方。5. 编程题先写测试用例再写实现5.1 拿到编程题的第一件事不是写代码而是设计用例这是我从这套卷子最大的收获。当时编程题第一题印象很深给定一个整数数组判断是否存在重复元素。这题简单但是很多人写完之后就交卷了丢分丢在没做防御性处理。我看到题的第一反应是先把测试用例列在草稿纸上。输入[1, 2, 3, 4]期望输出 false输入[1, 2, 3, 1]期望输出 true输入[]期望输出 false输入[null, 1, null]期望输出 true输入[2147483647, -2147483648]期望输出 false把这些列完你再看代码思路会异常清晰核心逻辑用哈希集合判断遍历数组如果集合里已存在就返回 true否则加入集合。同时你会在编码时自然处理空数组和极端值。这个习惯为什么这么重要因为测试开发的工作本质就是“先想清楚验证手段再动手实现”。你写自动化测试框架是这样写测试工具是这样做性能压测脚本也是这样。如果你在笔试时就能展现这个习惯哪怕代码有小瑕疵面试官也愿意给你机会。5.2 一道高频链表反转题的完整作答演示编程题里经常出现链表反转因为它可以很好地考察指针操作能力。我们来完整演示一下在一张白纸上怎么答这道题。题目反转一个单链表。输入1 - 2 - 3 - 4 - 5输出5 - 4 - 3 - 2 - 1我个人推荐迭代法简洁易写class ListNode: def __init__(self, val0, nextNone): self.val val self.next next def reverseList(head: ListNode) - ListNode: prev None curr head while curr: next_node curr.next # 保存下一个节点 curr.next prev # 当前节点指向前一个节点 prev curr # prev 前移 curr next_node # curr 前移 return prev这道题必须注意的两点一是next_node curr.next要写在curr.next prev之前否则链表就断了二是循环结束后要返回prev如果返回curr你已经指向了None。这其实就是典型的边界问题写代码时脑子里要时刻想着“当前指针指向哪里”。笔试时我还会在代码下面附一句自测用例的逻辑说明空链表返回 None只有一个节点返回它本身5 个节点的链表反转后首尾互换。这样做的意思是告诉阅卷人我不光会写代码我还会验证自己的代码。这个动作在测试开发的笔试里加分极其明显。5.3 如何用测试思维给代码找bug编程题写完不是终点检查才是。我总结了一个“自查三部曲”第一步看边界。你的代码能不能处理输入为空、长度为1、元素值重复、元素值极大极小这些情况可以在草稿纸旁边快速列出你看过的几个边界用例并标注“已考虑”。第二步看异常路径。如果题目涉及数组下标、指针移动就要仔细检查有没有越界可能。比如二分查找的left (right - left) // 2比(left right) // 2更安全就是为了防止整型溢出。第三步看时间空间复杂度。如果题目有数据规模提示比如n 10^5那你尽量不要用 O(n²) 的暴力解法面试官会关注你的复杂度分析习惯。哪怕你的暴力解法能通过测试也建议在注释里注明“这里可以优化为 O(n)”展示你有性能意识。这三个步骤就是测试中的“边界值、异常场景、性能风险”在代码自查上的映射。我一个做了十年测试开发的感受是代码能力其实可以通过刻意练习快速提高但“写完代码愿意主动自查并发现潜在问题”的习惯需要长期养成。笔试里能体现这一步的人非常少。5.4 让代码看起来“有工程经验”的细节除了正确性代码的“颜值”也很重要。阅卷人看到你的代码第一眼就会形成“这个人有没有工程素养”的判断。几个我特别在意的细节变量名要有语义len、curr、node是没问题的但a、b、temp1这类就很劝退函数尽量只做一件事主逻辑拆成小函数让人一眼能看懂你的思路关键逻辑写注释但不要每行都注释只在容易出错的地方说明意图。比如在反转链表那段代码里我在next_node curr.next这一行写注释“先保存下一个节点防止链表断裂”这样就比一大段注释更精准。这些细节不会直接决定你的分数但当你和其他人错得差不多的时候这些就是“隐性加分项”。6. 从这套卷子反推出来的备考路线图6.1 把考点分成“背下来的”和“练出来的”做完这套题之后我最大的收获不是“我掌握了多少题”而是“我建立了测试开发的整个知识图谱”。备考时我建议你参照这个思路把所有考点分成两类。一类是背下来的八股文包括网络协议的状态码、TCP握手流程、死锁条件、索引失效场景、JVM内存区域划分、Linux常用命令这些没有太多理解门槛核心就是反复记忆和默写。我建议你整理一份自己的知识卡每周过一遍考前集中突击。网络上各种“测试开发面试题八股文”汇总可以作为起点但一定要动手整理成自己的版本才有记忆效果。另一类是练出来的思维题包括算法编程、测试设计、场景分析、异常排查。这些没有捷径只能通过刷题、复盘、模拟实战来提升。算法部分每天坚持一两道不用追求难题但要追求“做对、写干净、能讲清复杂度”。测试设计部分每天挑一个日常事物练手比如地铁闸机、智能门锁、文件上传、搜索推荐逼自己在15分钟内写出一份结构完整的测试方案。6.2 三个月复习计划我建议你这样分配如果你现在距离秋招还有三个月可以参考这个节奏阶段时间重点内容输出物第一阶段第1-4周计算机基础补强操作系统、网络、数据库知识卡各一份第二阶段第5-8周数据结构与算法强化每天两道算法题按链表、数组、树、栈、队列、动态规划等专题逐类突破第三阶段第9-10周测试理论项目复盘测试用例设计模板、常见业务场景的测试方案第四阶段第11-12周模拟笔试错题回顾每周至少两套完整模拟题回归所有错题第一阶段最容易轻视。很多人一上来就刷题结果操作系统和网络基础不牢客观题大面积丢分。实际情况是客观题占比30%-40%是保底的分数基础不牢很吃亏。所以基础期一定要踏实不要为了刷题而跳过。第三阶段很多人不知道该做什么。这里有两条路可选如果你有实习或项目经历把项目里你做过的测试工作完整复盘一遍包括需求评审、用例设计、缺陷跟踪、测试报告输出如果没项目经验可以自己找一个开源项目比如在本地部署一个开源商城给它写核心模块的测试用例并跑通接口测试。这个过程中遇到的每一个问题都会成为你笔试设计题的素材。6.3 完整做一个小项目是最好的“笔试外挂”我在查相关信息时看到一条热词叫“用opencode开发一个项目从需求到设计到开发到测试”这其实点破了一个非常重要的备考策略不要只盯着笔试题准备要亲手从头到尾做一个小项目。哪怕是一个很小的工具只要你经历了“需求→设计→开发→测试”的完整闭环你脑子里对质量风险的理解就会完全不同。具体做法建议找一个你日常工作中高频重复的场景比如“接口自动化测试平台”“批量文件重命名工具”“CI流水线中的冒烟测试脚本”用你熟悉的语言把它实现出来并给它配套完整的测试用例。这样你手上就有了一份可以写进简历的项目经历笔试时所有跟测试流程、测试工具、测试数据相关的问题你都能拿真实经历去答。我当时自己做过一个小项目公司内部有个模块每次发版都要人工验证20条核心流程我就写了一个自动化回归脚本把验证时间从半天缩短到15分钟。这个项目在后续所有面试里都是我的“保命项目”。笔试里凡是涉及“测试流程怎么优化”“自动化落地难点”的题我都可以拿它来讲故事讲细节讲踩坑讲数据比任何背出来的答案都有说服力。6.4 刷题平台与错题本效率翻倍的两个细节刷题不要盲目海量刷要带目的。算法题推荐在LeetCode或牛客网上按数据结构和题目类型打标签刷每类刷20-30题就够应付大部分测试开发的笔试难度。测试理论题和场景题牛客网上有大量真实面经和笔经花一个下午集中收集整理成自己的题库性价比极高。错题本一定要有但不要只是把题目和答案抄下来。我的习惯是每个错题记录三个字段我当时的错误答案是什么正确答案的逻辑是什么背后的考点或原理是什么。这样反复看三轮知识点基本就长在脑子里了。很多人的问题是错题整理完之后再也不看那等于白整理。每周固定抽一个下午只看错题本把每一道都做到“能脱口讲出考点”为止。另外强烈建议在正式笔试前至少做2-3次完整限时模拟。可以用牛客网的在线题库严格按考试规定的时间段锁掉手机模拟真实环境。你会发现“做题”和“按时做完题”是两个世界。时间分配策略一定要在模拟中提前定好比如客观题限时60分钟编程题限时40分钟设计题限时30分钟留10分钟检查。不然上了考场很容易在客观题上磨太久编程题反而没时间好好写。最后再分享一个小技巧我每次做笔试题都有一个习惯不管题目会不会做先花两分钟把整张卷子从头到尾扫一遍。扫的过程中标记出“送分题”“需思考”“完全没思路”三类然后按顺序先做送分题再做需思考题最后用剩余时间磕没思路的题。这跟测试用例优先级的逻辑是一样的——先保障核心功能再考虑边缘场景。这套小米2019年秋招测试开发笔试题A放到现在依然是一份很好的自我体检清单。你如果能不查资料、不限时间把它涉及的知识点全部复述一遍再限时做一遍基本就能判断自己离大厂测试开发的准入门槛还有多远。当年我做完这套题的时候感觉自己像被照了一次X光哪块强、哪块弱、哪块是从来没意识到自己不会的一目了然。希望这份拆解也能帮你提前看到自己的盲区。