2021年小米秋招测试开发方向的第二场笔试,我印象还挺深的。那年秋招节奏快,小米的笔试分了好几场,题型不算偏,但覆盖面很广——从数据结构到测试理论,从手撕代码到场景设计,一套题下来能比较真实地反映一个人的基础功底和测试思维。这篇就当作一个过来人的复盘,把笔试里值得琢磨的点、我当时踩过的坑,还有后来带新人时总结的备考思路,一起拆开聊聊。不管你是准备校招还是想转岗测试开发,只要按这套逻辑去准备,方向基本不会跑偏。
1. 笔试背后的考察逻辑:小米到底想招什么样的测试开发
先别急着刷题,搞清楚对方出题的底层逻辑比多背几道八股文重要得多。2021年小米测试开发秋招笔试,表面上考的是知识点,实际上是在筛选具备三种特质的人。
1.1 测试开发岗位的能力模型拆解
我后来参与过几次校招面试,也和许多同行交流过,大家普遍认同一个观点:测试开发岗位本质上是“半个开发 + 半个测试架构师”。笔试环节之所以要考算法题,不是要去招纯算法工程师,而是通过这种方式验证编码基本功是否扎实。
具体到小米这场笔试,考点分布大致可以分三块:
- 编程基础与数据结构:重点在数组、字符串、链表、二叉树、动态规划这些高频考点,难度贴近LeetCode中等题。
- 测试理论与用例设计:等价类划分、边界值分析、场景法等经典方法,考察的是面对一个功能时能不能系统性思考。
- 自动化与脚本能力:会涉及简单的Linux命令、Shell脚本阅读,或者一道简单的自动化场景题。
这三块背后对应的能力,分别是“能写代码”“懂怎么测”“会提效率”。小米作为硬件+互联网复合型公司,大量业务涉及MIUI系统、IoT设备等软硬结合场景,测试开发需要能理解整个产品链路。笔试里看似零散的知识点,都是在为这个目标服务。
1.2 为什么第二场笔试的题型结构值得分析
我特意把第二场笔试单独拿出来复盘,是因为这一场的题型分配比较有代表性。第一场往往还在试探,第二场就相对成熟稳定了。整场笔试大致是:单选+多选覆盖基础理论,2到3道编程题考察算法能力,外加一个测试用例设计的大题。
这种结构现在看依然是主流,核心逻辑在于“分层筛选”。选择题刷掉基础不牢的,编程题刷掉代码能力不过关的,用例设计大题则专门区分“会做题”和“会测试”的人。很多同学容易栽在最后一道大设计题上,因为平时刷LeetCode刷习惯了,要突然切换到测试思维,确实需要提前适应。
2. 编程题深度复盘:手撕代码不只是刷LeetCode
编程题是笔试的重头戏,分值占比高,也最能拉开差距。小米2021秋招第二场笔试的编程题不算特别难,但有一些细节很值得说一说。
2.1 真题回顾:从一道字符串处理题说起
当时有一道题大概是这样的:给定一个字符串,要求找出其中不含有重复字符的最长子串的长度。这道题核心考点是滑动窗口算法,同时兼顾字符串处理和哈希表的使用。
我印象很深,因为这道题LeetCode原题是“无重复字符的最长子串”,属于经典中的经典。但笔试环境比IDE更苛刻——没有自动补全,需要自己处理输入输出,编译报错信息可能不太友好。这就意味着不仅要会写,还要写得稳、写得快。
我当时的做法很直接:
def length_of_longest_substring(s: str) -> int: char_index = {} left = 0 max_len = 0 for right, ch in enumerate(s): if ch in char_index and char_index[ch] >= left: left = char_index[ch] + 1 char_index[ch] = right max_len = max(max_len, right - left + 1) return max_len这段代码的核心思想是维护一个窗口,用哈希表记录每个字符最后一次出现的位置。当遇到重复字符时,直接把左指针跳到该字符上一次出现位置的下一位,而不是一步一步移动。这样时间复杂度就控制在了O(n),一次遍历就能完成。
2.2 做题时的三个关键决策:语言、输入输出、边界条件
第一,选什么语言。小米笔试的在线系统支持多种语言,但强烈建议只用自己最熟的那一门。我当时选的是Python,因为写起来快、语法简洁,处理字符串和数组特别顺手。如果你C++更熟练,完全可以用C++,但前提是STL要玩得溜,别在容器操作上卡壳。
第二,输入输出格式。在线笔试和LeetCode最大的区别在于:LeetCode已经帮你封装好了函数签名,你只需要实现核心逻辑。但笔试很多时候要自己写完整的输入解析。比如读取一行字符串、处理多组测试用例,这些看似琐碎的操作如果平时没练过,考试时非常容易翻车。
第三,边界条件。很多同学拿到题目先写主流程,最后才考虑边界,这样最容易漏掉特殊情况。我养成了一个习惯:先想空输入怎么办、只有一个元素怎么办、全部元素都重复怎么办。把这些情况先在注释里列出来,再开始写代码,正确率能提升不少。
2.3 算法准备策略:按高频考点分类突破
结合小米历年笔试和其他大厂的出题风格,我把测试开发笔试的算法重点整理成了五类:
- 字符串操作:反转、子串查找、最长公共前缀、字符串压缩。
- 数组与双指针:两数之和、三数之和、移动零、盛最多水的容器。
- 链表操作:反转链表、环形链表、合并有序链表、删除倒数第N个节点。
- 二叉树:前中后序遍历、层序遍历、最近公共祖先、最大深度。
- 动态规划:爬楼梯、最大子数组和、最长递增子序列、编辑距离。
每一类不需要贪多,刷透20道左右代表性题目就行。关键不是数量,而是能不能总结出每类题的通用解法模板。比如动态规划的核心就是“定义状态 + 状态转移方程 + 初始化”,把这三步走稳,大部分中等难度题目都能拿下。
3. 测试用例设计题:这才是区分度最高的环节
编程题决定你能不能过线,但用例设计大题决定你能不能拿高分。这也是测试开发笔试和普通软件开发笔试最不一样的地方。
3.1 典型的计算器测试题:全流程拆解
第二场笔试有一道用例设计题,要求针对一个简单的整数计算器功能设计测试用例。功能点包括:支持加减乘除四则运算、输入为整数、除数为零时需要给出错误提示。
看到这类题千万不要慌,也不用想着把功能说得天花乱坠,按照标准方法来就好。我当时用的是基于等价类和边界值的思路,测试用例划分成以下几组:
- 正常功能用例:两个正整数相加、两个负数相乘、大数除以小数等,确认基本运算结果正确。
- 边界值用例:输入最大值、最小值、0作为除数、运算结果为0等。边界最容易出错,也是面试官最关注的得分点。
- 异常输入用例:输入为空、输入包含非数字字符、输入超长数字等。这些情况开发经常忘记处理,正是测试发挥价值的地方。
- 特殊场景用例:连续多次运算、运算结果超出整数范围、除数为负数等。
每一个用例都要包含预期结果。我当时表达的信息是:不仅知道怎么操作,还知道正确结果应该是什么。这样才能体现对需求的理解,而不是机械地填表。
3.2 从需求分析到测试场景:测试思维的降维打击
很多同学的问题在于,拿到题目就开始写用例,脑海里只有一个“能跑就行”的思路。这是典型的开发思维,不是测试思维。真正的测试思维要求先分析需求,再推导测试场景,最后才是具体用例。
拿计算器这个需求来说,先拆解功能的显性需求:能进行四种运算、输入是整数、显示结果。然后是隐性需求:运算优先级是否正确、连续运算时状态是否会被污染、除以零时是否有提示。把这些想清楚,用例自然就出来了。
有一个特别实用的方法叫“测试金字塔+场景流”,就是从用户操作的角度设计一条完整的使用路径,再在每个节点上补充各种分支和异常场景。比如用户打开计算器、输入数字、选择运算符、再输入数字、按等号、看到结果,这是一条主路径。在此基础上,每一步都可能产生异常分支,把这些分支补齐,用例就丰富立体了。
3.3 面试官角度:什么样的用例设计能拿高分
参与过一些面试复盘后,我给这套打分逻辑做个总结:
- 广度:是否覆盖了正常、异常、边界三类基本场景。
- 深度:是否想到了别人容易忽略的点,比如需求变更、兼容性、并发操作。
- 组织性:用例是否分组清晰、命名规范、优先级明确。
- 可执行性:预期结果是否明确,前置条件是否完整。
其中“组织性”最容易被忽视,也最容易被面试官一眼捕捉。一份乱糟糟的用例列表和一份分模块、标优先级的用例表格,高下立判。
4. 理论选择题中的高频考点:测试基础与Linux命令
选择题占了不小的分值,虽然单题分数不高,但架不住量多,而且往往是区分“认真准备了”和“裸考”的关键。测试开发岗位的选择题主要集中在软件测试基础理论、网络协议、操作系统和Linux命令这几个板块。
4.1 软件测试基础理论:不只是背概念
软件测试理论里面,最常考的就是各种测试方法分类和流程问题。比如:单元测试、集成测试、系统测试、验收测试分别对应什么阶段,各自的目标是什么;黑盒测试和白盒测试的本质区别在哪里;回归测试是在什么场景下执行的。
这些题目表面上考概念,实际上考理解。比如有一道题说“某次版本更新后,需要对原有功能重新进行验证,这种测试属于什么类型”,答案是回归测试。但很多人会把回归测试和冒烟测试搞混。实际上冒烟测试是版本提交后执行的快速验证,看主要功能是否正常;回归测试则是确认修改没有引入新问题。理清这些概念的适用场景,比死记定义管用得多。
另外一个高频考点是测试用例的八大要素:用例编号、所属模块、用例标题、前置条件、测试步骤、测试数据、预期结果、实际结果。考试可能会给你一个残缺的用例,让你判断缺了哪个要素,或者让你从一段需求描述中提取这些要素来设计用例。
4.2 Linux与数据库:测试开发的基本功
测试开发日常工作中离不开Linux环境,笔试中对Linux的考察一般集中在这几个方面:
- 文件操作:ls、cd、cp、mv、rm、find、grep。
- 权限管理:chmod的数字和字母两种方式。
- 进程管理:ps、top、kill。
- 日志查看:tail -f、head、less。
有一道经典题目我到现在还记得:要求写一个命令,统计一个日志文件中出现“ERROR”关键词的行数。答案很简单:
grep -c "ERROR" app.log但很多人会先写grep "ERROR" app.log,再写wc -l,还得分两步执行。这种细节上的差距,反映的是对常用命令的熟练程度。数据库方面主要考SQL的基础语句,比如多表联查、分组统计、排序和去重。GROUP BY配合HAVING过滤分组条件是常客,比如“查出订单数量超过10个的用户ID”。
5. 从笔试到实战:如何把应试能力转化为测试开发的核心竞争力
笔试只是一张入场券,真正拉开职业发展差距的,是能不能把考试里用到的思维方式迁移到实际工作中。很多同学笔试分数很高,入职后却水土不服,原因就在于应试能力和工程实践之间有一条隐形的鸿沟。
5.1 从用例设计题到真实测试计划:思维转变的关键
笔试中的用例设计题,给出的需求往往很简单,比如一个计算器、一个登录框。真实的测试工作面对的则是一个业务流程、一套分布式系统、甚至一个IoT设备端到端的使用链路。复杂度完全不是一个量级。
这里我特别想聊一下“用AI工具做测试开发”这个方向。在面试里,如果你能体现出对AI辅助测试的认知,绝对是一个加分项。举个实际的例子,我在准备笔试之前,已经习惯用一些AI编程工具辅助我写自动化测试脚本。比如用对话式AI生成Pytest测试代码、自动生成接口测试用例,这大大提升了我的效率。但要注意,AI生成的东西不能直接上线,必须人工审查和验证。
我记得有一次笔试后的面试,面试官问我对AI辅助测试开发的看法。我当时的观点是:AI可以帮我们生成80%的测试脚本,但剩下20%的边界条件和业务逻辑需要人来做判断和补充。这个回答得到了面试官的认可,因为这说明我有实际思考过AI和人的分工边界,而不是盲目推崇技术。这也能看出,小米对测试开发的期待不只是执行者,而是能用工具提升效率、能有深度思考的人。
5.2 测试开发学习路线:从笔试到入职的系统规划
如果你现在还是大二大三,正在准备秋招,可以参考我给出的这条学习路线:
- 第一阶段:打好语言基础。建议学Python,语法简单,库丰富,不管是写脚本还是做自动化都特别方便。达到能独立完成LeetCode简单难度的程度即可。
- 第二阶段:学习测试理论基础。把软件测试教材核心章节过一遍,理解生命周期、测试方法、用例设计、缺陷管理,这个阶段配合做选择题效果最好。
- 第三阶段:掌握自动化测试工具。Selenium是Web应用测试的基础,能自己完成录制脚本和编写脚本;requests库做接口测试要熟练;Jenkins做持续集成最好也了解一下。
- 第四阶段:项目实战与刷题并行。找到有测试需求的开源项目,亲自动手写测试计划、设计用例、开发自动化脚本,同时每天固定刷1-2道算法题保持手感。
- 第五阶段:模拟笔试与面试复盘。严格控制时间做线上模拟题,再针对错题发现薄弱环节,进行专项训练。
这条路由浅入深,大概需要4到6个月的持续投入。每天不用高强度学太久,但一定要保证连续性和阶段目标达成。
5.3 给正在准备测试开发笔试题的同学几个实用建议
先说时间分配。如果是2个小时的笔试,我建议编程题控制在40到50分钟,选择题30分钟左右,剩下40分钟主攻用例设计大题。做题顺序也有讲究,我习惯先扫一遍所有题目,优先做有把握的,把拿不准的标记下来最后集中攻克。
再说细节。很多在线笔试不允许跳出网页,一旦切屏会被警告甚至直接交卷。所以考试之前一定要把本地环境准备好,比如草稿纸、水、以及把需要的手写思路先写在纸上。另外,在线编译器通常不支持自动保存,要养成随时手动提交已写代码的习惯,防止浏览器崩溃导致全部丢失。
还有一个容易被忽视的点:哪怕某个编程题没有完整做出来,也要把部分通过的用例结果保留下来。笔试系统按照用例通过率给分,能拿一分是一分,不要因为一道题卡住了就放弃整张卷。
6. 笔试避坑指南:这些问题每年都有大把人踩
最后这块算是我总结的“血泪清单”,全是当年我自己和身边同学真实踩过的坑。整理成速查表,大家做笔试题前过一眼,能避掉不少雷。
6.1 编程题翻车现场实录
- 没有处理多组输入:有些题目会连续给多个测试用例,很多人只处理了第一组就提交,通过率为0。每个题目先看输入描述,如果有“多组测试数据”这类字眼,就要用循环包起来。
- 变量名拼写错误:在线笔试编译器不提供自动纠错,拼错一个变量名,编译直接报错,心态很容易崩。解决办法是写完代码后,花30秒逐行检查一遍所有变量名是否一致。
- 忽略了整数溢出:很多题目没明确说数据范围,但隐性要求是支持较大整数。用Python的int完全没这个问题,但如果你用Java或C++,就要考虑用
long类型。
6.2 理论题易错点汇总
- 白盒测试和黑盒测试的混用:白盒测试是代码层面的测试,关注内部结构和逻辑路径;黑盒测试是功能层面的测试,不关心内部实现,只关注输入和输出。题目问“以下哪种测试方法不需要了解代码内部逻辑”,答案是黑盒测试。
- 验证和确认的区别:验证是“是否正确地构建了产品”,确认是“是否构建了正确的产品”。这两个概念看起来差不多,但在软件工程里是有严格区分的,很容易考。
- 兼容性测试的完整范围:不只是不同浏览器,还包括不同操作系统、不同分辨率、不同网络环境、不同硬件设备。考试中经常用选择题来考察这个覆盖面。
6.3 考场心态和策略
笔试说到底是一场限时对抗,技术准备占七成,状态发挥占三成。我见过实力很强但因为一道题卡了太久导致整场崩盘的,也见过基础一般但策略得当、分数反而很高的。
我的建议是:开考后前5分钟不要动笔,先把所有题目浏览一遍,在心里给每道题标个难度和预计用时。编程题如果15分钟内没有完整的解题思路,果断先跳过,写完其他题目再回来啃硬骨头。遇到不会的选择题,不要空着,用排除法蒙一个也有概率得分。
最后说一句掏心窝的话:测试开发这个方向,看起来门槛不高,好像会点点点就能入行,但真正走得远的人,都是兼具开发思维和测试思维的人。一场笔试筛不掉真正的实力,但也确实是第一道关口。准备的时候多问问自己“为什么要这么设计”“这个功能的边界在哪里”“怎样验证它是正确的”,把这些问题融进平时的学习和练习,拿到offer只是时间问题。
希望这篇复盘对你有所帮助。如果正在准备小米或者类似大厂的测试开发笔试,建议把文章里的几个方法落地成自己的练习计划,尤其是用例设计那部分,多找几个功能练手,很快就能感受到思维上的变化。