深信服秋招测试开发笔试复盘:题型考点与备考指南
1. 笔试整体结构复盘从题型分布看岗位要求先说结论2023年深信服秋招测试开发岗的笔试整体风格偏向“计算机基础 代码能力 测试思维”三合一和纯后端开发岗的笔试题有明显区别。我是在规定时间内完成的线上笔试全程双机位监考题目分为四个部分单选题、多选题、编程题、测试用例设计题。单选和多选加起来大概40道覆盖数据结构、操作系统、计算机网络、数据库、Linux基础编程题两道难度在中等到偏上最后一道是给一个功能模块写测试用例占分比例不小。整套题做下来的感受是深信服不指望你什么都会但很看重你是不是具备测试开发这个岗位最需要的三种能力——看懂代码、设计用例、定位问题的能力。为什么这么说因为单选题里混了不少“给一段代码问输出结果”的题还有“这段代码有什么问题”的题。这类题目考的不是背诵而是你能不能像一个调试者一样去读代码、推断行为。而最后的测试用例设计题更是直接模拟了真实工作中“拿到一个需求写测试方案”的场景。如果你只是刷了数据结构题、背了八股文没有真正动手写过测试用例最后那题会很吃亏。先说题型分布和分值占比方便后面想考深信服的同学有个整体概念题型数量分值占比考察重点单选题25道约30%数据结构、OS、网络、数据库基础多选题15道约20%概念辨析、边界条件、易混淆知识点编程题2道约30%算法实现、代码调试能力测试用例设计题1道约20%测试思维、用例设计方法、覆盖率意识这个分值分布透露出来的信息很明确基础知识和代码能力是门槛测试设计能力是区分度。大部分人前两部分能拿到不错的分数拉开差距的往往是最后那道测试设计题。所以这篇复盘我会重点拆解测试设计题的答题思路顺便把编程题的解题过程完整还原。另外提醒一点深信服笔试用的在线平台支持C、Java、Python三种语言但编程题的环境是LeetCode风格不需要自己处理输入输出核心函数写好就行。这点很友好但也意味着题目会更注重算法本身而不是IO解析能力。2. 核心考点拆解编程题完整解题思路还原这次笔试的两道编程题一道是动态规划经典变种一道是二叉树相关的题目。题型不算偏但都有“陷阱”不是那种看一眼就能写出来送分题。我把自己在考场上的思路、踩坑点和最终解答完整还原出来。2.1 第一题最长公共子序列的变种动态规划题目大意是给定两个字符串s1和s2求它们的最长公共子序列长度但要求子序列中不能包含连续两个相同的字符。比如说s1和s2的某个公共子序列是aab那这个就不合法因为aa连续相同如果是aba那就合法。第一眼看到这题我的第一反应是标准的LCS动态规划然后再加上一个“限制条件”。但问题在于标准的LCS状态只需要dp[i][j]表示s1前i个字符和s2前j个字符的最长公共子序列长度可是当你加入“不能连续相同”这个限制后你光知道“长度”是不够的你还得知道当前这个最长子序列的最后一个字符是什么这样才能判断下一个字符能不能接上去。也就是说状态转移里需要记录“以当前字符结尾的最优子序列的最后一个字符”。最直接的办法是把状态升级成二维数组加一维字符信息dp[i][j]不再存一个整数而是存一个结构体包含最长长度和对应的末尾字符。但考场上我更推荐一种更简单的思路既然限制条件是“不能有连续相同字符”那我可以把每个字符本身的状态分成“以该字符结尾”和“不以该字符结尾”两类拆成两个DP数组。具体的状态定义是dp0[i][j]s1前i个字符和s2前j个字符且当前公共子序列不以字符s1[i]结尾的最大长度dp1[i][j]s1前i个字符和s2前j个字符且当前公共子序列以字符s1[i]结尾的最大长度为什么这么拆因为“以什么字符结尾”决定了你下一步能不能继续选相同的字符。如果当前以a结尾下一步遇到a就不能选会形成aa遇到非a就是安全的。这样状态转移就清晰了当s1[i] s2[j]时dp1[i][j] dp0[i-1][j-1] 1前提是dp0[i-1][j-1]对应的结尾字符不等于s1[i]实际上更稳妥的处理是维护两个值分别记录“末尾字符不同”的最优长度和“末尾字符相同”的最优长度这个解法考场上写起来还是比较绕的我写完后用几个自测样例验证了一下比如s1abcabc, s2acbacb手动推导了一下结果是对的。但说句实话如果只是要求“最长公共子序列长度”这道题从难度上讲算中等偏上因为它不是你在LeetCode上直接能刷到的原题需要你在经典LCS基础上做状态扩展。我给一个可运行的核心代码Python版状态设计做了简化用两个DP数组分别表示“当前末尾字符与之前不同”和“当前末尾字符与之前相同”两种状态下的最长长度def longestValidCommonSubsequence(s1: str, s2: str) - int: n, m len(s1), len(s2) # dp_diff[i][j]: 前i个和前j个字符且末尾两个字符不同的最长公共子序列长度 # dp_same[i][j]: 前i个和前j个字符且末尾两个字符相同的最长公共子序列长度 dp_diff [[0] * (m 1) for _ in range(n 1)] dp_same [[0] * (m 1) for _ in range(n 1)] for i in range(1, n 1): for j in range(1, m 1): if s1[i - 1] s2[j - 1]: # 当前字符相同可以尝试接在“末尾不同”的序列后面 dp_same[i][j] max(dp_same[i][j], dp_diff[i - 1][j - 1] 1) # 也可以选择不选这个字符 dp_same[i][j] max(dp_same[i][j], dp_same[i - 1][j], dp_same[i][j - 1]) # 当前字符不同一切照旧继承前面的状态 dp_diff[i][j] max(dp_diff[i - 1][j], dp_diff[i][j - 1], dp_same[i - 1][j], dp_same[i][j - 1]) return max(dp_diff[n][m], dp_same[n][m])这里有一个关键的坑dp_same的更新不能只看dp_diff[i-1][j-1]你还要考虑“当前相同字符选择不接上去”的情况。因为可能存在更长的序列只是它的末尾恰好不是当前相同的这个字符。我最初只写了第一行更新结果少计算了一些情况。这个思路必须想清楚否则样例能过但隐藏用例会挂。2.2 第二题二叉树路径问题DFS回溯第二题是给一棵二叉树每个节点有一个整数值要求找出所有“从根节点到叶子节点”的路径中路径和等于给定targetSum的路径数量。这个题本身不复杂深度优先遍历一遍就能解决但深信服在题目描述里加了两个限制条件导致解法不能直接用经典写法第一个限制是路径中不能有连续两个节点值相同这和第一题的限制思路如出一辙。第二个限制是路径必须到达叶子节点不能中途停止。第二个限制意味着你不能“遇到前缀和等于targetSum就计数”因为你不知道后面还有没有路径可以走到叶子必须完整遍历到叶子节点在叶子节点做判断才能保证“到叶子为止”这个约束成立。这个题的解法思路很直接DFS加回溯。伪代码如下def pathSum(root, targetSum): count 0 def dfs(node, current_sum, last_value): nonlocal count if not node: return # 连续两个节点值相同直接剪枝 if node.val last_value: return new_sum current_sum node.val # 到达叶子节点时判断是否满足条件 if not node.left and not node.right: if new_sum targetSum: count 1 return dfs(node.left, new_sum, node.val) dfs(node.right, new_sum, node.val) dfs(root, 0, None) return count这道题的核心陷阱在于“到达叶子节点才计数”。如果你在中间节点就判断并返回会漏掉所有“路径前半段满足条件但后半段才能到叶子”的情况。另外“不能连续相同”这个限制要在进入子节点时判断而不是在父节点时判断否则会漏掉根节点本身的判断。考场上我犯了一个低级错误把last_value初始值设成了一个不存在的特殊值比如负无穷这没问题但我在递归子节点时把last_value传成了node.left.val或者node.right.val而不是当前节点的值导致连续性判断完全失效。这种细节错误在写代码时很容易出现最好在写完函数后用最简单的三个节点用例自测一遍。3. 计算机基础与“八股文”考点精讲笔试的多选题和单选题里计算机基础知识占了很大比重。这部分内容乍看之下和测试开发岗位没有直接关系但仔细想想测试开发要能看懂代码、分析问题、排查线上故障操作系统、网络、数据库这些底层知识是绕不开的。我把自己记忆中的考点分类整理出来给大家做个参考。3.1 操作系统进程线程、死锁、内存管理深信服笔试的操作系统题不算难但很爱考概念辨析。比如“进程和线程的区别”这个几乎是必考题但不会直接问“它们的区别是什么”而是给你一个具体场景让你判断这个场景下应该用进程还是线程。比如有个选择题是“浏览器打开多个标签页每个标签页独立运行互不影响这时候应该用进程还是线程实现”答案当然是进程因为进程隔离性更好一个标签页崩溃不会影响其他标签页。还有一个常见的考点是死锁产生的四个必要条件互斥、持有并等待、不可剥夺、循环等待。多选题里会给四个描述让你选哪些是死锁产生的必要条件。这个知识点本身不复杂但要注意“循环等待”和“持有并等待”的区别很多人会混。内存管理方面考了页面置换算法特别是LRU和FIFO的区别。LRU是什么、如何用哈希表加双向链表实现这个在测试开发面试里也经常被追问因为它是很经典的缓存淘汰算法和实际业务中Redis淘汰策略、CPU缓存设计都有关系。建议准备笔试的同学把LRU的手写实现练熟。3.2 计算机网络TCP三次握手、HTTP状态码网络部分的考点集中在TCP和HTTP。TCP三次握手几乎是必考内容但深信服的问法比较“测试思维”给你一个序列号比如客户端发送SYN时的初始序列号是100问服务器回应的ACK号应该是多少。这种题需要理解ACK号的含义它表示“期望收到的下一个字节的序号”所以如果SYN的序列号是100那么ACK号应该是101因为SYN本身要占一个序号。多选题里还考了TCP和UDP的区别选项设得很刁钻比如“TCP支持广播UDP不支持”——这是错的恰恰相反。“UDP的传输速度一定比TCP快”——这也是错的速度取决于网络环境不是协议类型本身决定的。HTTP状态码也是高频考点。301和302的区别、403和404的区别这些都是选择题的常客。特别是301永久重定向和302临时重定向的区别以及304 Not Modified在缓存机制中的作用。测试开发在实际工作中查看接口返回状态码是排查问题的第一步所以这个考点和工作场景吻合度很高。3.3 数据库索引失效场景和事务隔离级别数据库的考点集中在索引和事务。索引相关的题给出一段SQL问“这个查询会不会用到索引”选项里藏着各种索引失效的场景。常见的失效场景包括对索引列使用了函数计算、like查询以通配符开头、隐式类型转换、OR条件包含非索引列。这些在笔试和面试里出现频率非常高建议整理成清单背熟。事务隔离级别考了“脏读”“不可重复读”“幻读”三个现象分别对应哪个级别。这个知识点不光笔试会考面试也几乎必问。注意默认隔离级别在不同数据库中不一样MySQL 默认是Repeatable ReadPostgreSQL默认是Read Committed。如果问“在MySQL默认隔离级别下会不会发生脏读”答案是肯定不会因为最低级别也是Read Uncommitted才会脏读。3.4 Linux基础进程查看、日志排查命令Linux相关的选择题主要考常用命令的用途。比如查看端口占用用什么命令netstat或ss、查看进程用什么命令ps或top、实时查看日志用什么命令tail -f、查找文件用什么命令find。“如何查看某个端口是否被占用”这道题几乎是深信服笔试必考因为在真实排障过程中端口冲突是高频问题。还有一个印象很深的题给出一个日志文件每行格式是IP地址加访问时间问“如何统计每个IP的访问次数”。答案是awk {print $1} access.log | sort | uniq -c | sort -rn。这是Linux面试经典题笔试把它改成了选择题。这个命令组合建议背下来后续工作中也经常用得上。4. 测试用例设计题的答题方法最后一题是测试用例设计分值不低。题目大意是有一个登录接口接收用户名和密码两个参数登录成功后返回一个token登录失败返回错误码。要求设计测试用例覆盖功能、安全、性能等方面。说实话如果没做过测试相关的工作看到这种题很容易懵因为不知道要写多少用例、写到什么程度算完整。我当时是按下面的思路来设计的写完之后自我感觉覆盖得比较全面。4.1 功能测试用例的设计思路功能测试是最基础的部分重点在于把输入参数的各种情况都想到。对于用户名和密码这种输入类功能最典型的用例设计方法是等价类划分和边界值分析。等价类划分就是把输入分成“有效的”和“无效的”两大类。合法的用户名和密码属于有效等价类空用户名、空密码、超长字符串、特殊字符这些属于无效等价类。边界值分析则是重点关注边界比如用户名长度限制是6到20个字符那5、6、7、19、20、21这几个长度都要测到。我把密码设置成不同复杂度比如纯数字、纯字母、数字加字母、含特殊字符覆盖密码校验策略的不同场景。然后还要考虑登录成功和失败两种情况失败时的错误码是否正确token是否在登录成功后正常返回。我整理出来大概20多条功能用例但真正让这题拿高分的是下面要说的安全、性能这些非功能用例。4.2 安全测试用例SQL注入、暴力破解、敏感信息登录接口是安全测试的重灾区因为它是系统的入口攻击面很大。我在安全测试部分设计了这样几类用例第一类是SQL注入。如果后端直接把用户输入拼到SQL里黑客输入 OR 11 --就可能绕过登录。测试用例要验证系统对这类输入的拦截能力。同理还有XSS攻击在用户名里输入scriptalert(1)/script看系统是否做了转义处理。第二类是暴力破解防护。设计用例验证连续输错5次密码后账号是否被锁定以及锁定时间是否合理。这里还有一个细节频繁尝试登录时接口是否有限流机制返回的错误提示是否会暴露账号是否存在。如果系统直接提示“用户不存在”攻击者就可以通过枚举用户名来探测有效账号。我在用例里特别标注了这个风险点。第三类是敏感信息泄露。登录接口的请求和响应里不应包含明文密码、不应在URL参数里携带敏感信息token应该有时效性和刷新机制。这类用例看起来是安全测试但实际工作里我们做接口测试时也会顺手验证属于测试开发的日常。4.3 性能测试用例并发、超时、稳定性性能测试用例不需要写得太复杂但要把核心指标列出来。我写了并发用户数为100、500、1000时登录接口的响应时间和成功率重点关注高并发下是否出现连接超时、内存溢出和数据库连接池耗尽。这些都可以配合JMeter等工具来执行笔试阶段只要把场景描述清楚即可。兼容性测试方面要考虑不同的浏览器、不同的操作系统、不同的网络环境。比如弱网环境下登录是否会超时移动端和PC端的登录流程是否有差异这些都是实际使用中用户最容易感知的问题。4.4 用例管理表测试开发的职业习惯笔试考场上时间有限我最后把所有用例整理成一张表格这是测试开发实际工作中的标准做法。统一用“用例编号、测试项、操作步骤、输入数据、预期结果、优先级”这个格式20条用例排列得清清楚楚。这样做的好处是逻辑清晰方便别人评审时快速理解覆盖率高不容易漏项也直接向面试官展示了你的测试文档能力。笔试结束后我总结了一下测试用例设计题没有标准答案但考官会看两点。一是覆盖率功能、安全、性能、兼容性这些维度全不全二是细节丰富度比如有没有考虑到SQL注入、暴力破解、token失效这些真正生产环境才会面临的问题。只要这两点做到位这道题基本就拿稳了。5. 备考路线与避坑指南考完这次笔试结合我自己之前踩过的坑我把测试开发岗的备考路线和常见问题整理成一个速查清单希望对后面准备深信服或其他大厂测试开发岗笔试的同学有帮助。5.1 测试开发学习路线的优先级排序如果你现在时间有限不知道怎么分配复习精力我建议按这个优先级来第一优先级是数据结构和算法。这是笔试的硬门槛编程题做不出来其他部分再高分也白搭。重点刷动态规划、二叉树、链表、字符串处理这几类高频题型。LeetCode上的hot 100题和剑指offer建议都刷一遍以上。第二优先级是计算机基础。操作系统、计算机网络、数据库这三科的常考知识点要分清主次。操作系统重点看进程线程、死锁、内存管理网络重点看TCP、HTTP、DNS数据库重点看索引、事务、SQL语句优化。第三优先级才是测试理论。不是说测试理论不重要而是它的内容相对固定突击起来效率更高。测试用例设计方法、Bug生命周期、接口测试工具的使用这些是最需要掌握的核心。前面三种能力是笔试拿分的关键测试理论更多是在面试环节体现价值。5.2 几个容易翻车的细节问题第一个问题是时间分配。这套笔试题有两个小时编程题如果卡太久后面的测试设计题就没时间写完。我建议单选题控制在40分钟内编程题每道不超过25分钟测试设计题留至少30分钟。编程题如果10分钟没有思路先写暴力解法拿部分分不要死磕最优解。第二个问题是代码编译环境。深信服的在线IDE支持代码补全但很弱。平时如果习惯在IDE里写代码笔试时会有明显的不适应感。建议提前在牛客网或者LeetCode的模拟环境里练习几次熟悉“没有智能提示、没有自动导入包”的裸写状态。特别提醒Python的递归深度默认是1000如果二叉树很深一定要考虑用迭代栈代替递归否则会直接栈溢出判0分。第三个问题是多选题的计分规则。深信服的多选题少选不给分只有完全选对才给分。所以遇到不确定的选项宁可少选一个也不要冒险多选。我身边就有同学因为多选选错太多基础题拉胯最后笔试没过。第四个问题是测试设计题不要写成“一句话用例”。比如“测试密码正确时能登录成功”这种话在实际评审里等于没写。正确的写法是密码正确且账户状态正常输入正确的用户名和密码点击登录预期结果返回token且跳转成功优先级为P0。每个字段都要有具体的操作步骤和预期结果才算一个合格的用例。5.3 关于AI辅助测试开发的一点思考今年的热词里“AI测试开发”讨论度很高OpenCode这类AI编程工具也确实在改变测试开发的工作方式。笔试之后我在想一个问题AI能不能替代测试开发写这些用例从笔试的经历来看AI可以帮你生成用例框架、补充边界条件但它很难替代人去理解“这个登录接口的业务场景是什么、哪些风险是这个系统特有的”。比如上面提到的“错误提示是否暴露账号存在”这种安全风险它取决于具体系统的设计而不是能从需求文档里直接读出来的东西。而这些恰恰是测试开发真正的价值所在——不只是执行测试而是像一个会用各种工具的黑客加上一个懂业务的用户去模拟真实场景里的各种可能提前暴露系统的问题。写在最后深信服秋招笔试的整个流程走下来我的核心感受是这套题出的“有水平”它不是单纯地考你知道多少而是考你能不能像一个测试开发工程师一样思考问题。编程题里加的“连续相同字符”限制、测试设计题里的接口安全维度这些都不是能从题库里直接背到的而是需要你真正理解测试开发的工作本质后才能应对的。备考过程中不用太焦虑把基础知识打牢刷够一定量的编程题再用心练一练测试用例设计的写法通过笔试的希望是很大的。我在实际备考中发现最拉分的不是那些偏题怪题反而是最基础的知识点上的粗心失误。最后叮嘱一句笔试前一定要去牛客网做一次模拟题熟悉在线笔试的流程和节奏这比多刷十道题都有用。祝看到这篇文章的你笔试顺利过关。