试过用两周时间突击金山办公的测试工程师校招笔试,后来顺利拿到面试资格。最近不少学弟学妹来问这套题怎么准备,我干脆把2020校招测开笔试题(二)的完整拆解写出来,从考点分析到解题思路,再到我当时踩过的坑,一次性说清楚。
这套题最特别的地方在于,它不像很多大厂那样只考纯理论或纯算法,而是把测试思维融入到了全流程的题目设计中。除了常规的编程题和测试用例设计题,还涉及了Linux操作、数据库查询、网络协议基础,以及一些偏实际场景的开放性问题。整体难度中等偏上,但对有准备的人来说,拿高分并不难。
1. 笔试题整体结构与考点分布
拿到试卷的第一感觉是:题量不小,三个小时刚刚够用。整套题分为四大部分:单选题、多选题、编程题和测试用例设计题。单选和多选覆盖的知识面很广,从数据结构、操作系统到网络协议都有涉及;编程题有两道,一道是纯算法,一道是结合业务场景的题目;最后的测试用例设计题分值最高,也是拉开差距的关键。
从考点分布来看,这套题非常看重基础功底。数据结构与算法占了大约三成,包括数组、链表、二叉树、排序和查找;操作系统和Linux命令占了两成左右,重点考察进程线程、内存管理和常用命令;计算机网络占了一成五,主要是TCP/IP协议族和HTTP相关的题目;剩下的则是数据库SQL、测试理论以及开放性的场景设计题。
这个分布其实反映了金山办公这类做工具类产品的公司对测试工程师的期待:你要懂业务,但更不能丢了技术底子。工具类产品的用户量巨大、版本迭代快、兼容性要求高,所以测试工程师不仅要会写用例、能跑回归,还得能自己定位问题,甚至写脚本提效。这套笔试题就是在筛选具备这种综合素质的人。
1.1 选择题考察的知识点清单
选择题部分一共35道,多选题占比不低,而且多选的判分比较严格,少选不得分、错选倒扣分,所以答题时宁可少选也不要乱蒙。我把当时记录的重点知识点整理成了一张清单:
- 数据结构:循环队列的判空判满条件、二叉树的前中后序遍历、哈希冲突的解决方法、堆排序的时间复杂度
- 操作系统:进程和线程的区别、死锁产生的四个必要条件、虚拟内存与页面置换算法、进程间通信方式
- 网络:TCP三次握手四次挥手、TCP和UDP的区别、HTTP状态码含义、DNS解析过程
- 数据库:SQL基本增删改查、内连接与外连接的区别、索引失效的场景
- 测试理论:等价类划分、边界值分析、因果图法、场景法、错误推测法
这些知识点看起来都是教科书上的基础内容,但实际做题时你会发现,题目出得很“活”。比如二叉树那道题,不会直接问“前序遍历是什么”,而是给一个中序+后序的遍历序列,让你反推前序遍历的结果。这就要求你不仅记住概念,还得真正理解遍历的递归过程。
1.2 编程题的难度定位与做题策略
两道编程题,第一道是经典的“最长不重复子串”问题,算是LeetCode中等难度的常客;第二道则结合了WPS的业务场景,要求实现一个简单的文本统计功能:输入一段英文文本,输出出现频率最高的前K个单词,并按照频率降序、字典序升序排列。
编程题允许使用C/C++、Java或Python,我选了Python,因为写起来快、不容易出语法错。这里有个建议:如果笔试环境支持多种语言,优先选你最熟悉且在OJ上验证过输入输出格式的语言。不要因为某道题用C++写“显得更厉害”就临时换语言,笔试是争分夺秒的场合,用最顺手的工具才是最优解。
第一道题的解法不复杂,用滑动窗口加哈希表即可,关键在于把窗口收缩的条件写对。第二道题实际上是在考察字符串处理和排序,思路是先用正则或split把单词切出来,再用Counter统计频率,最后用sorted函数自定义排序规则。这两道题都不算难,只要平时刷过题基本都能做出来,真正的分水岭在后面的测试用例设计题。
2. 核心题目详解与解题思路
这一部分我挑几道印象最深、也最值得琢磨的题目,逐题说说我的解题思路和分析过程。这些题目不仅仅是“会做”,更要理解它背后的考察意图。
2.1 最长不重复子串问题解析
题目要求:给定一个字符串,找出其中不含有重复字符的最长子串的长度。例如输入"abcabcbb",输出3,因为最长不重复子串是"abc",长度为3。
这道题的标准解法是滑动窗口。核心思路是用两个指针left和right维护一个窗口,right不断向右扩展,把新字符加入窗口;如果发现窗口内有重复字符,就把left向右移动,直到窗口内没有重复字符为止。每次移动right时都更新一下最大窗口长度。
写代码时有个细节容易出错:如何判断窗口内是否有重复字符。我用的方法是维护一个字典或集合,记录窗口内每个字符的最新下标。当遇到重复字符时,直接将left跳到重复字符上次出现位置的下一个位置,而不是让left一个一个地移动。
def lengthOfLongestSubstring(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注意char_index[ch] >= left这个条件很重要。如果不加这个判断,当遇到一个曾经出现过但已经在窗口之外的字符时,left会被错误地拉回去,导致结果出错。我第一次写的时候就漏了这个条件,白白丢了一部分测试用例的分数。
2.2 频率最高的前K个单词实现
这道题的输入是一段英文文本,可能包含标点和大小写。要求先做单词切分,把大写转成小写,去掉标点符号,然后统计每个单词出现的次数,最后输出频率最高的前K个单词。
我在实现时用了Python的re模块来切分单词,正则表达式是re.findall(r'[a-zA-Z]+', text.lower()),一行代码就同时完成了转小写和提取单词。如果不用正则,手动遍历字符去判断字母边界也能做,但代码会啰嗦很多,而且容易踩中“连续空格”或“单词间多个标点”的坑。
import re from collections import Counter def top_k_words(text: str, k: int): words = re.findall(r'[a-zA-Z]+', text.lower()) counter = Counter(words) return sorted(counter.items(), key=lambda x: (-x[1], x[0]))[:k]排序规则是关键:先按频率降序排列,频率相同时按字典序升序排列。Python的sorted函数支持传入多个排序键,这里用(-x[1], x[0])就同时实现了两个规则。这个写法比先按字典序排再按频率排要稳妥得多,后者会打乱字典序的稳定性。
结合业务场景想一下,这道题其实对应的是WPS文档里的“词频统计”功能。测试工程师在测这类功能时,需要考虑到文本为空、全是符号、单词大小写混合、超长单词、K值大于单词种类数等边界情况,这些在后面的测试用例设计题里也可能会用到。
2.3 测试用例设计题:为WPS的保存功能设计测试方案
这道题分值最高,题目描述是:WPS Office作为一个办公软件套件,其中的“保存”功能是用户高频使用的核心功能。请针对“打开本地文档并另存为新文件”这个场景,设计一份完整的测试方案。
拿到这种题,不能上来就闷头写用例。我的习惯是先在草稿纸上列一个框架:功能测试、界面测试、兼容性测试、性能测试、异常场景测试、安全测试,这个六个维度基本能覆盖大部分测试场景。
功能测试方面,要验证另存为的文件能否正常打开、内容是否与原文一致、格式是否完整保留。常见的做法是准备不同格式的文件(如docx、xlsx、pptx、pdf)逐一测试,因为不同格式对排版、字体、公式的支持程度不同,很容易出现内容丢失的情况。
界面测试方面,要关注另存为对话框的布局符合规划、按钮可用性、快捷键响应、路径选择和文件名输入等问题。很多人容易忽略文件名非法字符的校验,比如Windows系统不允许文件名包含\ / : * ? " < > |这些字符,输入这些字符时系统应该给出友好提示。
兼容性测试方面,需要覆盖不同操作系统(Windows、macOS、Linux)、不同屏幕分辨率、不同office版本之间的交叉验证。尤其是另存为的文件在其他办公软件中能否正常打开,这是测试中非常关键的一环。
异常场景测试要考虑到磁盘写满、磁盘被写保护、保存过程中断电或程序崩溃、文件被其他进程占用等情况。这里有一个实操经验:通过模拟磁盘写满很难,但可以在保存路径设置为一个只读目录来模拟写权限问题,这是比较简单可控的方法。
性能测试方面,要验证大文件(比如几十MB甚至上百MB)在另存为时的响应时间是否在可接受范围内,以及连续执行多次保存操作后,系统内存是否会泄漏。另外还要关注保存过程中CPU和内存的占用情况,避免因为保存操作导致电脑卡顿。
安全测试方面,要检查保存到本地时文件是否被加密、临时文件是否会被残留、文件权限设置是否合理等。
2.4 场景设计题:限时优惠活动的测试分析
还有一道开放题,在网上讨论度很高:假设WPS会员商城推出一个限时优惠活动,用户在前10分钟购买会员可享受半价优惠,现在需要你来测试这个功能,你会怎么测?
这类题的考察重点不是具体的测试步骤,而是你对“限时”“优惠”这两个核心逻辑的理解。除了常规的价格计算、支付流程测试外,有几个容易被忽视的边界点:
- 时间边界:用户在第9分59秒下单,但支付完成时已经超过10分钟,订单应该按照哪个价格计算?
- 并发场景:大量用户在最后一秒同时下单,系统会不会因高并发出现超卖或价格错乱?
- 状态流转:用户下单后取消了订单,再重新下单时,此时活动已经结束,应该按原价还是半价?
- 多端一致性:用户在手机端下单、PC端支付,活动状态是否能实时同步?
遇到这种开放题,我建议先把核心业务流程画出来(这一步在脑子里完成就行),然后从流程的每个环节去假设异常场景,再对每个异常场景去设计测试用例。这样写出来的答案既有条理又不容易漏项。
3. 数据库、Linux与网络考察要点
除了前面讲的编程题和用例设计题,这套笔试题的选择题部分还涉及了大量数据库、Linux和网络相关的知识。这些内容在笔试中占比不算小,而且对后续面试也有直接帮助。我在这里把几个高频考点展开说明。
3.1 SQL考察重点:连接查询与聚合函数
数据库部分的题目主要集中在SQL查询,尤其是连接查询和聚合函数的组合使用。有一道题印象深刻:有两张表,一张是学生表(学号、姓名、班级),一张是成绩表(学号、科目、成绩),要求查询出每个班级的平均分,且只显示平均分大于80分的班级。
这道题考察的是GROUP BY和HAVING的配合使用,过滤条件写在HAVING里而不是WHERE里,因为WHERE是在分组前过滤,HAVING是在分组后过滤。另外需要注意,SELECT子句中出现的非聚合列必须包含在GROUP BY子句中,否则在MySQL的严格模式下直接报错。
还有一个常被问到的点是内连接(INNER JOIN)和左连接(LEFT JOIN)的区别,笔试中经常通过题目描述来让你判断该用哪种连接。做题时读清楚题目条件很关键:如果要求“必须有成绩的学生”,那要用内连接;如果要求“所有学生都要显示,无成绩的显示NULL”,那就要用左连接。
3.2 Linux常用命令的实战用法
Linux命令在测试工程师的日常工作中使用频率极高,尤其是查看日志、定位进程、检查端口这些操作。这套笔试题里考了top、ps、grep、awk、sed、netstat等命令的基本用法和常见选项。
我对准备这类题目的建议是,不要死记硬背命令选项,而是要在自己的电脑上装一个Linux虚拟机或使用云服务器,把每个命令实际敲一遍。比如top命令的输出含义,%CPU、%MEM、load average分别代表什么,只有真正看过输出才能理解深刻。
如果在面试中被问到“如何查看某个端口被哪个进程占用”,可以这样回答:先用netstat -tlnp | grep 8080找到占用8080端口的进程PID,再用ps -ef | grep PID查看对应的进程详细信息。这两个命令串起来就是一个完整的定位思路。
3.3 网络协议高频考点梳理
网络部分的考点非常集中,TCP三次握手和四次挥手的过程及状态迁移、TCP和UDP的应用场景区别、HTTP常见状态码含义、GET和POST的区别、HTTPS的加密流程,这些内容基本是必考的。
笔试中经常考的一个点是:TCP四次挥手中,TIME_WAIT状态存在的原因是什么。答案是确保最后一个ACK报文能够到达对方,同时让本连接中残留的报文在网络中消失。
普通用户碰到这类题目容易机械记忆,其实可以去理解一下:如果最后一步的ACK丢失,对端会重发FIN,如果此时主动关闭方已经进入CLOSED状态,就无法响应对方的FIN,导致对端一直无法正常关闭连接。TIME_WAIT状态的存在相当于给这个问题留了一个缓冲区。
4. 常见问题与备考经验总结
备考这套笔试题的过程中,我和身边几位同学交流过各自踩过的坑。这里把这些典型问题整理出来,同时附上我自己的排错思路和备考建议,希望你能少走一些弯路。
4.1 常见问题排查与避坑技巧
第一个坑是时间分配严重失衡。很多人在选择题上花了太多时间,尤其是多选题,反复犹豫不决,结果后面的编程题和用例设计题只剩不到一半时间。我个人的建议是:选择题和判断题控制在40分钟内完成,不会做的先标记跳过,不要恋战;编程题控制在一个小时;剩下至少一个小时给用例设计题。
第二个坑是编程题的输入输出格式没有处理好。笔试平台的评测机对格式要求非常严格,多一个空格、少一个换行都可能导致判题错误。准备阶段建议多去牛客网或赛码网熟悉在线笔试的输入输出模板,尤其是Python的sys.stdin.readline和sys.stdout.write用法。
第三个坑是用例设计题只写正常流程,忽略了异常场景和边界条件。我曾经看过一份答案,把保存功能的正常流程写得很详细,但完全没提磁盘空间不足、文件名非法、网络中断这些情况。这种答案在面试官眼里是明显缺少测试思维的表现,分数不会高。
第四个坑是SQL题目没有注意MySQL和标准SQL的差异。比如MySQL中支持LIMIT分页,而SQL Server用的是TOP,Oracle用的是ROWNUM。如果你的简历上写了熟悉MySQL,就尽量用MySQL的语法答题,避免被追问时说不清楚。
4.2 针对性的备考路径与资料推荐
如果你的目标也是金山办公或者其他做办公/工具类产品的公司,我建议这样规划备考路径:
第一步是夯实基础。把数据结构(数组、链表、栈、队列、二叉树、哈希表)、操作系统(进程线程、死锁、内存管理)、计算机网络(TCP/IP协议族、HTTP/HTTPS)这三门核心课程过一遍,重点吃透高频考点,不要贪多求全。
第二步是刷题。笔试题里的编程题难度接近LeetCode中等难度,所以刷LeetCode的Top100或剑指Offer题集就够了。重点练习字符串处理、数组操作、二叉树遍历、动态规划入门的题目,这是性价比最高的投入。
第三步是准备测试用例设计题。不要只看书上的等价类划分和边界值分析,要真正拿一个实际软件功能去练习。比如WPS文字里的查找替换、Excel里的条件格式、PPT里的幻灯片放映,挑几个高频功能,从功能、兼容性、性能、异常、安全等维度设计测试用例,亲手写出来。
第四步是熟悉Linux和数据库。Linux至少掌握文件操作、权限管理、进程管理、日志查看、网络排查这些常用命令;数据库重点练习多表查询、聚合函数、子查询、索引优化。这两块内容在笔试和日常测试工作中都用得上,投入时间非常值得。
4.3 从笔试题反推面试考点
最后说点实际的:这套笔试题其实透露了金山办公面试官比较看重的能力模型。笔试考察了编程基本功、测试理论、数据库、Linux、网络和场景设计,面试中大概率会围绕这些内容进行深挖。
我当时在面试中被追问了好几个和笔试题相关的问题,比如“你在设计保存功能的测试方案时,如何模拟磁盘满的场景”“如果线上出现了某个用户保存文件失败的bug,你会如何定位是客户端问题还是服务端问题”。这说明面试官不会满足于你会做笔试题目,而是会顺着你的答案继续深挖,看你是否具备真正的解决问题的思维。
建议你在笔试结束后,把自己做错的题目和犹豫过的题目都整理一遍,因为面试中很可能被问到。“那道题你当时是怎么想的”“现在再让你做一遍,你会不会换一种解法”,这些问题本质上都是给你的二次机会,答得好反而会加分。
备考这套试卷时,我最大的感受是:测试工程师的笔试不像开发岗那样纯拼算法,而是在考察一个人的综合能力。你既要有扎实的技术功底,又要具备敏锐的业务敏感度,还得在有限的时间内把事情想周全。这些能力不是考前突击就能养成的,需要在平时的学习和实习中持续积累。如果你正在准备校招笔试,希望这篇拆解能帮你找到复习方向,少走一些弯路。