
先说明一下我是2020年秋天参加奇安信秋招算法方向笔试的那会儿正好赶上网络安全行业大热奇安信刚独立没多久算是国内安全圈的头部公司了。当时投的是算法岗笔试用的还是他们自己的在线测评系统整体感觉是题量不小、风格务实、既有基础算法也有机器学习内容还夹杂了一些安全领域的场景化问题。这套试卷3我印象比较深今天就把当时考的题目和我的解题思路整理出来希望能给后面准备安全公司算法岗的同学一些参考。1. 试卷整体结构与考查方向解析1.1 题型分布与时间分配奇安信算法方向的秋招试卷整体分为四块选择题、编程题、算法设计题和场景分析题。我当时拿到的试卷3大概结构是这样的选择题20道左右覆盖数据结构、机器学习基础、概率统计和少量安全常识编程题2道一道偏基础数据结构一道偏算法思维算法设计题1道大题要求写出完整的算法流程和复杂度分析场景分析题1道结合安全业务场景分析算法选型时间一共90分钟说实话不算宽裕。我的策略是先快速过选择题遇到不确定的标记一下别恋战把时间留给后面的大题。编程题一般难度不算太高但要求代码规范、边界处理到位。选择题里涉及的安全常识题比如VDI、沙箱、加密算法分类这些对非安全背景的同学来说可能是个盲区但这个恰恰是安全厂商标题的核心差异化之处。我当时复习时补了不少安全基础知识事实证明很值得。1.2 安全公司算法岗与互联网算法岗的区别这里必须先说清楚一个认知奇安信的算法岗和字节、阿里的算法岗虽然都叫“算法工程师”但实际工作内容和考查侧重点差别非常大。互联网大厂算法岗更看重推荐、搜索、广告、NLP这些方向考查的是模型设计能力、特征工程能力和对大规模数据的处理经验。而安全公司算法岗的核心是用算法解决安全问题。这包括恶意流量检测、恶意软件识别、日志异常分析、用户行为建模、威胁情报挖掘等方向。所以笔试里会出现一些“看起来不像算法题”的题目其实是把算法思维跟安全场景结合起来了。这一点直接体现在试卷3的题目风格上。比如选择题里有一道问“在异常检测中哪些算法适合处理高维稀疏数据”这就是典型的网络安全检测场景因为网络流量特征往往是高维且稀疏的。2. 高频算法考点与做题思路复盘2.1 KMP算法与next数组计算细节试卷3的选择题里出现了一道KMP的题目要求计算模式串的next数组。这类题在安全厂家的笔试中出现频率很高因为字符串匹配在流量特征匹配、规则匹配中非常常用。模式串是abacabanext数组精简版即next[i]表示前i个字符组成的子串中最长相同前后缀的长度有的教材定义为不包含自身的版本注意区分的计算过程是这样的next[0] -1有的版本定义为0看题目约定next[1]子串a没有真前后缀为0next[2]子串ab前缀a后缀b不匹配为0next[3]子串aba前缀a后缀a匹配长度1前缀ab后缀ba不匹配所以是1next[4]子串abac最长相同前后缀是0next[5]子串abaca前缀a后缀a长度1没有更长的匹配所以是1next[6]子串abacab检查发现前缀ab和后缀ab匹配长度2所以next[6]2next[7]子串abacaba前缀aba和后缀aba匹配长度3所以next[7]3所以next数组是[-1, 0, 0, 1, 0, 1, 2, 3]。做这类题的技巧是先写前缀再写后缀从最长开始匹配。很多同学容易错在忘记next数组的定义版本有的教材next[i]表示“i位置匹配失败后应该跳转的位置”有的表示“前i个字符的最长相等前后缀长度”这两个版本计算方式略有不同考试时一定要先看题目的定义。我当时用的是“失配跳转位置”的版本next[i]表示第i个字符匹配失败时模式串应该回退到的位置。两种版本都要会因为不同公司的出题习惯不一样。2.2 排序算法复杂度与小技巧汇编排序算法在选择题里属于送分题但如果考前没有系统整理很容易丢分。试卷3里考了堆排序、快速排序和归并排序的复杂度以及稳定性冒泡排序O(n²)稳定快速排序平均O(n log n)最坏O(n²)不稳定归并排序O(n log n)稳定堆排序O(n log n)不稳定希尔排序约为O(n^1.3)不稳定计数排序/桶排序/基数排序O(nk)稳定基数排序稳定这里容易被问到的点是快速排序的最坏情况是什么答案是数组已经有序且每次选取第一个元素作为pivot时。优化手段包括随机选pivot、三数取中、小区间用插入排序等。堆排序还有一个容易考的点建堆的时间复杂度是O(n)而不是O(n log n)。很多人会误以为建堆每个元素下沉一次是O(log n)所以总的是O(n log n)但实际上叶子节点不需要下沉越靠近底部的节点下沉次数越少最终求和是O(n)的。这个考点我在选择题里碰到了。2.3 二分图匹配与贪心算法的应用区分试卷里还有一道问“以下哪个问题不能直接用贪心算法求解”选项包括活动安排、背包问题、霍夫曼编码、最小生成树。这题的考点很经典背包问题里的0-1背包不能用贪心而分数背包可以。因为0-1背包具有最优子结构但贪心策略按单位价值排序不一定能得到全局最优解。还有一个容易混淆的点最小生成树的Prim和Kruskal算法都是贪心思想但它们的正确性需要证明贪心选择的局部最优能导向全局最优这是通过“安全边”性质保证的。很多基础不牢的同学会把“贪心算法能得到局部最优但不一定全局最优”理解为“贪心算法一定错”其实在特定问题上贪心是能得到全局最优的。二分图匹配的匈牙利算法和HK算法Hopcroft-Karp我也复习到了。HK算法是匈牙利算法的优化版时间复杂度从O(VE)降到O(E√V)核心是每次找多条不相交的增广路通过BFS分层 用DFS增广。在安全场景中二分图匹配可以用于告警与攻击者的关联分析这种题目不会直接考代码但选择题里可能出现概念辨析。2.4 快速幂与模运算的边界处理编程题里考了一道快速幂的题目要求计算a的b次方模m的结果。这个题目本身不难但坑点不少a、b的范围可能很大必须用long long否则溢出b为0的情况要返回1%mm为1的情况任何数的模都是0用位运算优化比用取模判断更快核心代码逻辑如下long long quickPow(long long a, long long b, long long m) { long long result 1 % m; a % m; while (b 0) { if (b 1) { result (result * a) % m; } a (a * a) % m; b 1; } return result; }这个写法有一个细节值得注意result 1 % m而不是直接等于1就是为了处理m1这个边界条件。很多人在笔试时忽略了这个导致提交后只过部分用例。我当时就是因为这个边界吃了亏后来就记住了这个写法。快速幂在网络安全中有个典型的使用场景——RSA加密中的模幂运算。RSA的解密需要计算c^d mod n这里的指数d非常大如果直接遍历计算肯定不行用快速幂就能把复杂度降到O(log d)。所以安全公司考快速幂是有实际业务含义的不只是单纯考算法。3. 机器学习与深度学习算法考查侧重点3.1 经典机器学习算法的理论基础试卷3的机器学习题目涵盖了KNN、K-Means、决策树、逻辑回归等常用算法。有一道题问KNN算法的三个核心应用能力是什么标准答案是分类、回归、缺失值填补。但更深入的问法是KNN为什么适合处理非线性边界因为KNN是实例型学习算法不对特征空间做任何假设直接基于距离度量进行分类因此天然支持非线性决策边界。K-Means的考察集中在初始值敏感的问题上。试卷里有一道题问K-Means为什么比随机初始化好答案是K-Means通过概率分布让初始中心点尽可能分散减少陷入局部最优的概率。但这里要注意一个细节K-Means只能“减少”局部最优的概率并不能“消除”因为K-Means本身的目标函数是非凸的。还有个容易被问到的点K-Means和KNN都是K开头但一个是无监督聚类一个是有监督分类千万别搞混。K-Means的K是聚类中心个数KNN的K是邻居数这个在笔试里偶尔会作为“陷阱题”出现。3.2 集成学习与规则引擎的关系随机森林、XGBoost、GBDT这类集成学习算法在选择题里也出现了。考的题目是“XGBoost相比GBDT的主要改进有哪些”答案要点包括目标函数加了正则化项防止过拟合支持二阶泰勒展开用到了梯度的一阶导数和二阶导数支持列抽样类似随机森林对缺失值有专门的处理策略支持并行化在特征粒度上做了并行优化这里我额外联想到一个安全领域相关的点规则引擎Drools里的Rete算法。虽然Rete不属于机器学习算法但在安全公司的面试里可能会被问到。Rete算法的核心思路是“用空间换时间”通过构建模式匹配网络包括Alpha网络和Beta网络缓存中间匹配结果避免重复计算。这跟决策树在很多方面有相似之处——都是通过预构建结构来加速推理。不过要注意区分Rete算法是规则推理引擎不是机器学习模型。机器学习模型是数据驱动的从样本中学习规律规则引擎是知识驱动的由专家定义规则。在安全产品中两者往往混合使用——先用规则引擎过滤明显正常的流量再用机器学习模型检测未知威胁。3.3 深度学习注意力机制与Transformer基础奇安信的笔试题里深度学习的占比相对互联网大厂要低一些但仍然有涉及。试卷3问了Transformer里Self-Attention的计算过程以及为什么要除以√d_k。答案很简单缩放点积注意力的公式是softmax(QK^T / √d_k)除以√d_k是为了防止点积结果过大导致softmax梯度消失。如果q和k的每个维度都是均值为0、方差为1的随机变量那它们的点积QK^T的方差是d_k标准差是√d_k。当d_k很大时点积结果会分布在一个较大的范围内softmax的梯度会变得非常小不利于训练。除以√d_k让方差回到1梯度更稳定。这个题在安全领域也有实际背景比如日志序列的异常检测、用户行为序列建模都会用到Transformer类模型。SEBERT、BERTopic这类模型的底层都是注意力机制理解原理对后续面试会有帮助。3.4 KL散度与ELBO推导KL散度KL Divergence这个知识点在试卷3里也出现了。题目问“在VAE中为什么优化的是ELBO而不是直接最大化似然”核心答案是真实后验分布难以计算无法直接做EM算法的E步所以转而优化似然的一个下界ELBOEvidence Lower Bound。ELBO的推导过程是log P(x) log ∫ P(x|z)P(z)dz引入变分分布q(z|x)利用Jensen不等式log P(x) E_{q(z|x)}[log P(x|z)] - KL(q(z|x) || P(z))其中右边就是ELBO。优化ELBO等价于最大化重构项第一项同时最小化KL散度项第二项让编码器输出的近似后验分布尽量接近先验分布。KL散度本身也可以拆解为KL(q||p) E_q[log q] - E_q[log p]它是不对称的也就是说KL(q||p)不等于KL(p||q)。这个不对称性在笔试中是一个常见考点。有一个记忆技巧KL散度中的第一项是“用q的分布去加权log(q/p)”所以它衡量的是“如果我用q去近似p会损失多少信息”。这个推导过程在安全领域中常用于异常检测的变分自编码器VAE。比如用VAE对正常流量建模输入一个样本如果重构误差大就说明它偏离了正常模式可能是异常流量。所以理解ELBO不仅是为了应付笔试也是为了后续做安全检测模型打基础。4. 安全场景中的算法应用与场景题应答思路4.1 异常检测算法选型思路试卷3的场景分析题大概是这样的假设你是一个安全公司的算法工程师需要设计一个企业内网流量异常检测系统请说明你会选择哪些算法为什么以及如何评估效果。这类题目考的不是具体的代码实现而是算法选型思路和工程落地能力。我的答题思路是先说数据网络流量数据通常是高维、稀疏、带时间戳的可能有标注也可能无标注分两种情况有标注数据时用监督学习XGBoost、随机森林无标注时用无监督孤立森林、One-Class SVM、自编码器考虑时序特性流量数据是随时间变化的可以引入滑动窗口统计特征或用LSTM建模时序依赖评估指标不只看准确率要关注误报率FPR和召回率Recall因为安全场景中误报太多会产生告警疲劳这里有一个关键点务必注意安全场景中正负样本极不平衡。恶意流量可能只占全部流量的万分之一如果直接用准确率评估模型把所有流量都预测为正常准确率也能达到99.99%。所以必须用精确率、召回率、F1值、AUC-ROC等指标必要时用代价敏感学习或SMOTE过采样处理不平衡问题。4.2 PID算法与卡尔曼滤波在安全场景中的角色你可能没想到安全公司的算法试卷里居然考了PID算法和卡尔曼滤波。但在某些特定场景下它们确实是必要的。比如在主机防护产品中CPU/内存占用需要动态控制PID可以用来做资源调度的闭环控制在工控安全场景中检测物理量异常需要滤波算法卡尔曼滤波可以从带噪声的传感器数据中估计真实状态。PID的核心是三个环节比例项P根据当前误差决定控制量误差越大调整越猛积分项I消除稳态误差但如果积分过大容易超调微分项D预测误差变化趋势阻尼作用防止振荡增量式PID与位置式PID的区别是增量式只输出控制量增量Δu好处是执行器故障时不会产生大幅跳变适合需要平滑控制的场景。这个知识点如果笔试不考面试时也是很好的加分项。卡尔曼滤波的核心是“预测更新”两步走用状态转移方程预测下一时刻状态再用观测值修正预测结果。它本质上是贝叶斯滤波在线性高斯假设下的最优解。在安全场景中可以用来对传感器信号做预处理降低误报率。但请注意这些算法在算法方向的笔试中出现通常只是选择题里的一道概念辨析不会要求推导完整公式。核心是要知道它们各自适用于什么场景、解决了什么问题。4.3 粒子群算法、模拟退火与全局优化粒子群算法PSO和模拟退火SA也出现在试卷里了这类智能优化算法在安全场景中的应用主要是威胁检测规则的参数优化、特征选择等。粒子群算法的核心思想是每个粒子代表解空间中的一个候选解粒子根据自身历史最优位置和群体历史最优位置来更新速度与位置。粒子群算法的公式是v_i(t1) w * v_i(t) c1 * r1 * (pbest_i - x_i(t)) c2 * r2 * (gbest - x_i(t))x_i(t1) x_i(t) v_i(t1)其中 w 是惯性权重c1和c2是加速常数r1和r2是[0,1]的随机数。w大时全局搜索能力强w小时局部搜索能力强。常见做法是让w在迭代过程中从0.9线性衰减到0.4前期多探索、后期多收敛。模拟退火算法的核心是Metropolis准则新解比当前解好就接受新解不好时以概率 P exp(-ΔE / T) 接受。温度T越高接受差解的概率越大随着温度降低算法逐渐走向收敛。这里的关键设计是降温速率降温太快容易陷入局部最优降温太慢又耗时。这两类算法都不是最前沿的算法了但在笔试里出现频率不低因为在安全领域的某些优化问题比如IDS规则库调优、安全资源调度中它们依旧实用。4.4 图像算法在安全领域的应用图像算法那道题出现在选择题里问的是图像锐化中的拉普拉斯算子原理。拉普拉斯算子是二阶微分算子模板通常为0 -1 0 -1 5 -1 0 -1 0或者不带中心加权的版本0 -1 0 -1 4 -1 0 -1 0拉普拉斯算子检测的是图像强度的二阶变化率在边缘和噪声点处响应值大。增强的方法是原图减去或加上拉普拉斯结果也就是 unsharp masking 的思想。安全领域中图像算法的应用主要涉及验证码识别对抗、恶意图片检测、屏幕水印、图像隐写分析等。Sobel算子相比拉普拉斯算子的优势是它同时计算梯度方向和幅值对噪声有一定平滑作用。这些细节点如果平时没接触过考场上是很难临时推导的所以建议系统性过一遍常用算子。5. 编程题与算法设计题的实战拆解5.1 KMP之外的字符串处理技巧试卷3的编程题里有一道字符串处理的题具体是判断一个字符串能否通过若干次循环移位变成另一个字符串的旋转串比如abcde的旋转串包括abcde、bcdea、cdeab等。这道题有两种解法。第一种是把两个字符串拼接起来如果把s1s1包含s2那么s2是s1的旋转串。例如abcdeabcde abcdeabcde包含cdeab所以是旋转关系。这是最高效的解法时间复杂度O(n)空间复杂度O(n)。第二种是KMP匹配把s1s1作为主串s2作为模式串用KMP做匹配。如果考场上要求不能用STL的find函数就要手写KMP匹配。KMP的next数组实现前面已经讲过了这里的关键是理解失配时的回退逻辑。这道题有一个陷阱如果s1和s2长度不相等直接返回false不需要做任何匹配。很多同学忘了这个边界检查导致s1as2aa这种用例过不去。5.2 TopK问题的多种解法对比另一道编程题是TopK问题给定一个无序数组找出其中第K大的元素。这道题看起来简单但考查的知识点可以很深入。最直接的解法是排序后用下标取元素时间复杂度O(n log n)。但这显然不是最优解。更好的解法是用最小堆维护一个大小为K的最小堆遍历数组时如果元素比堆顶大就替换堆顶并调整堆。时间复杂度O(n log K)当K远小于n时不失为一个好方法。C可以直接用priority_queue或者用multiset。最优解法是快速选择Quick Select基于快速排序的partition思想平均时间复杂度O(n)最坏O(n²)。核心代码int quickSelect(vectorint nums, int left, int right, int k) { int pivot nums[left]; int i left, j right; while (i j) { while (i j nums[j] pivot) j--; nums[i] nums[j]; while (i j nums[i] pivot) i; nums[j] nums[i]; } nums[i] pivot; if (i k) return nums[i]; else if (i k) return quickSelect(nums, i 1, right, k); else return quickSelect(nums, left, i - 1, k); }这里对第K大还是第K小要特别注意。数组升序排列时第K大对应的索引是n-K。考场上要仔细看题别都写第K小。印象里这道题我当时直接用了nth_elementC标准库里的函数可以一行解决nth_element(nums.begin(), nums.begin() n - k, nums.end()); return nums[n - k];但笔试时最好还是手写一遍Quick Select因为nth_element的底层实现不同编译器不一样而且手写代码更能体现你的算法功底。5.3 动态规划经典的背包变体算法设计题里有一道背包问题变体大概是这样的给定一组进程的资源占用和威胁等级在总资源有限的情况下选择一部分进程进行深度检测使总的威胁等级减少量最大化。这其实就是0-1背包问题每个进程的重量是资源占用价值是威胁等级的减少量背包容量是总资源。状态转移方程是dp[i][j] max(dp[i-1][j], dp[i-1][j-w[i]] v[i])优化空间后变成一维数组注意j要从大到小遍历防止一个物品被使用多次for (int i 1; i n; i) { for (int j capacity; j w[i]; j--) { dp[j] max(dp[j], dp[j - w[i]] v[i]); } }很多同学知道要倒序遍历但不理解为什么。原因是正序遍历时dp[j-w[i]]可能在当前物品循环中被更新过导致一个物品被选多次这正好符合完全背包的语义。而倒序遍历保证了dp[j-w[i]]还是上一轮的结果即每个物品最多选一次。这里还有个延伸考点如果是完全背包j正序如果是多重背包需要二进制拆分优化如果是分组背包每组只能选一个。面试时最好能把这些变体都梳理清楚。6. 常见失分点与避坑经验总结6.1 选择题里的概念陷阱奇安信这套试卷的失分点很有规律。首先是概念混淆型陷阱比如把快速排序的最坏时间复杂度记成O(n log n)。快速排序在平均情况下是O(n log n)但最坏情况比如已经有序且每次选固定pivot会退化到O(n²)。题目往往会问“以下排序算法中哪一个在最坏情况下时间复杂度不是O(n log n)”答案就是快速排序除非用随机化优化。其次是忽略了边界条件比如快速幂中m1、KMP中模式串为空、二分查找中目标值比最小值还小。这些边界条件在跑用例时最容易暴露但很多同学笔试时只关注主流程不注重边界导致用例过不全。再次是对术语理解不够准确。比如问“KNN算法的优点是什么”选项里有“训练时间短”和“对数据分布不做假设”这两个其实都是对的但题目要求选“最核心”的优点。这时候要理解出题人的意图KNN最大的优势是惰性学习无需训练阶段可以直接预测。6.2 编程题的鲁棒性要求笔试环境下的编程题光写对算法逻辑是不够的代码的鲁棒性同样重要。我总结了几个必查的边界条件数组是否可能为空数字是否可能为负数数值是否可能溢出int范围输入字符串是否可能包含空白字符或大小写混用是否有重复元素涉及去重或计数时比如在一道求数组中两个数的最大异或值的题目中空数组和只有一个元素的数组都要单独处理否则访问nums[1]时就数组越界了。这些在本地IDE运行时不容易发现但在笔试系统的测试用例下会直接暴露。还有一个很多校招生容易忽略的点笔试平台对语言版本有要求。比如C要区分C11/14/17的语法支持情况Java要注意主类名是否为MainPython要注意输入是空格分隔还是换行分隔。这些如果考前没确认好容易在环境上白白浪费大量调试时间。6.3 时间分配与做题顺序的策略我之前参加多场秋招笔试总结出一个比较稳妥的做题顺序先用5-8分钟浏览全部题目标记每道题的预估用时然后先做编程题因为它们分值高且需要整块时间思考再做算法设计题用清晰的伪代码加文字说明表达思路最后做选择题因为选择题很多是概念辨析即使时间紧张也可以靠快速判断拿分。这里有个小技巧算法设计题尽量写成“伪代码复杂度分析正确性说明”的结构。出题人看重的不是你能默写多少代码而是你的思路是否清晰。比如背包问题的算法设计题我会先写状态定义再写转移方程再写初始化条件最后写时间空间复杂度这样即使代码有小的瑕疵整体思路分也能拿到大部分。6.4 面试阶段可能追问的方向笔试之后如果顺利通常还有一轮技术面试。面试官很可能会追问笔试里的某些题目尤其是算法设计题。我当时被追问的题目就是KMP的next数组优化——为什么有些next数组求法可以进一步优化到nextval数组。nextval数组能避免一种重复匹配的情况如果P[i] P[next[i]]那么当P[i]匹配失败跳转到next[i]时P[next[i]]还会和当前字符失配所以应该继续跳转到next[next[i]]。举个例子模式串aaaaab如果求next数组b处失配会跳转到a但a和b不相等所以next数组可以提前处理。这个问题在KMP算法的实际优化中很常用如果你笔试时只是把next数组求出来面试时一定要能说出这个优化版本。当时我还被追问了归并排序如何做外部排序、如何用位图去重等问题这些也都在安全场景中有应用。7. 复盘与备考建议7.1 安全算法岗位的核心技能树经历了这次笔试和后续的面试我对安全公司的算法岗有了更清晰的认知。安全公司的算法工程师需要掌握三方面的核心技能第一是扎实的算法与数据结构基础。排序、字符串匹配、图论、动态规划这些通用算法是地基不管做什么方向的算法都绕不开。这部分跟互联网大厂的要求是重合的。第二是机器学习与深度学习基础。要理解常用模型的原理和适用场景特别是不平衡样本的处理、异常检测的评估方法、时序数据的建模方式。这部分是安全算法岗的核心竞争力。第三是安全领域的业务理解。了解常见的攻击类型DDoS、SQL注入、木马、勒索软件等、检测系统的工作原理、安全数据的格式与特点。这部分可以通过阅读安全公司的技术博客、参加安全类在线课程来补充。7.2 刷题与复习的优先级建议如果你正在准备网络安全公司的算法笔试我的建议是优先级最高的仍然是LeetCode高频题。排序、二分、动态规划、字符串匹配、Tree、图这些专题刷熟练笔试编程题就不会太慌机器学习基础要系统过一遍包括模型的推导和公式理解。推荐西瓜书或李航的《统计学习方法》安全基础知识的补充不可忽视。能说出SYN Flood的攻击原理、了解DGA域名的检测思路、知道沙箱的工作原理这些在场景题中都是加分项有时间的话可以了解几个经典的异常检测算法和网络安全数据集比如KDD Cup 1999、CICIDS 2017等。笔试不一定考但面试聊到安全场景时会很有底气7.3 心态调整与应试技巧最后再说一个容易被忽略的点秋招笔试的心态。很多人一看到题目里出现陌生名词比如“KL散度”“Rete算法”“拉普拉斯算子”就开始慌了觉得这个岗位不适合自己。其实不用慌这些名词的出现频率并不高且多以选择题形式出现靠排除法往往能做对。更重要的是这些题目本身就是用来筛选的——如果你只会刷LeetCode但完全不了解安全业务会在这里丢分如果你的安全知识丰富但算法基础薄弱又会死在编程题上。所以真正的目标不是每道题都对而是在自己相对有优势的部分多拿分。笔试之前尽量模拟真实环境限制时间做题训练自己不看题解独立思考的能力。我当时用了大概两周时间做专项训练每天固定两套模拟题每套严格计时考场上反而不是特别紧张因为整个流程已经走过多遍了。顺便分享一个我后来才意识到的小细节笔试时如果做完了不要急着交卷留一点时间检查选择题里有没有漏选或者多选题判断失误。很多算法方向的选择题其实是多选题题目会明确标注“多选”但紧张状态下容易看成单选。这个看起来很小的检查可能就值好几分。