ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

奇安信算法岗笔试复盘:从KMP到安全场景的考点全解析

奇安信算法岗笔试复盘:从KMP到安全场景的考点全解析 2020年那阵子我正好在准备秋招投的第一家网络安全方向大厂就是奇安信。算法方向这份试卷1做得我印象深刻倒不是因为它难到无从下手而是题型构成和常规互联网公司的算法笔试差别挺大——除了LeetCode那种标准算法题还有不少安全场景下的算法应用、数据结构选型、甚至机器学习基础。现在回过头来看这份试卷的考察逻辑其实非常清晰算法功底是底线安全业务理解是加分项两者都不会的话基本没戏。我把自己对这份试卷的复盘整理出来涵盖题型结构、具体考点、我当时踩的坑以及针对安全厂商算法岗的备考思路希望能给后来投奇安信或者其他安全公司算法岗的朋友一点参考。1. 2020年奇安信算法岗笔试全貌题型、时长与淘汰逻辑1.1 试卷结构选择、编程、简答三段的配比先说整张试卷的布局。奇安信这份算法方向试卷1不是纯线上OJ模式而是“选择编程简答”三段式。选择题大概20到25道覆盖数据结构、算法复杂度、机器学习基础、网络协议偶尔混进一两道安全常识题。编程题通常2到3道难度梯度明显第一道偏签到性质第二道是标准中等题第三道则带有业务场景包装比如日志分析、攻击链检测这种。简答题是我觉得最特别的部分会直接问某个算法的原理、某个安全问题的解决思路或者让你写一段伪代码。我当时拿到试卷第一反应是时间不够用。选择题部分其实还好真正的坑是编程题需要在本地的编辑器里写然后粘贴到网页textarea里提交没有自动补全也没有测试用例提示。如果你平时习惯了LeetCode的在线调试环境这种“裸写”方式很容易让你在细节上翻车。1.2 安全厂商算法岗到底在考察什么很多人以为安全公司的算法岗就是做恶意样本检测、流量分析笔试应该考机器学习模型。但从奇安信这份试卷来看考察的核心其实分成三层第一层是通用算法基本功。数组、字符串、链表、树、图、动态规划、贪心、排序这些是程序员的基本盘安全算法工程师也一样不能少。毕竟你写检测逻辑、写特征提取组件底层还是这些数据结构。第二层是对算法复杂度的敏感性。安全场景经常面对的是海量日志、超大流量O(n^2)的算法在数据量小的时候看不出问题一旦上了生产环境就崩。所以试卷里会特别关注你的复杂度分析和优化意识。第三层是安全业务的理解力。例如路径遍历检测、日志解析、规则匹配这类问题其实都是算法题但它们都套了一个业务壳。如果理解不了攻击原理可能连题目都读不明白。这也是我觉得奇安信这份试卷和其他大厂算法卷最大的区别它不是在纯粹地考算法竞赛能力而是在考“你能不能把算法用到安全业务里去”。1.3 我的答题时间分配与策略我自己是按“选择-简答-编程”的顺序做的先花40分钟搞定选择题和简答题把该拿的分先拿住然后剩下80分钟死磕编程题。这个顺序不一定适合所有人但对付混合型试卷比较稳。选择题里如果遇到需要计算的复杂度题我建议先在草稿纸上推不要心算。我当时就有一道递归复杂度题差点心算出错还好写了下来。简答题别写太长阅卷人看的是点不是篇幅把关键步骤写清楚比洋洋洒洒写一大段强得多。2. 字符串与经典算法题复盘KMP的next数组到底怎么推2.1 KMP算法题目直接给了模式串pabacaba凡是刷过字符串匹配题的人对KMP都不陌生。奇安信这份试卷里涉及到的KMP考点要求根据模式串pabacaba求next数组。这里说的next[i]到底怎么定义不同教材略有差异有的表示“前i个字符组成的子串的最长相等前后缀长度”有的则表示“失配时需要回退到的位置”差一个偏移动结果就不一样。我当时拿到这题第一件事是把定义在草稿纸上写清楚。如果采用最通用的定义——next[i]表示模式串前i个字符中最长相等前缀后缀的长度那么对于pabacabanext[0] 通常约定为 -1 或者 0取决于具体实现。p[0..0]a最长相等前后缀长度为0。p[0..1]ab前缀a、后缀b长度为0。p[0..2]aba前缀a、后缀a长度为1。p[0..3]abac最长相等前后缀0。p[0..4]abaca前缀a、后缀a长度为1。p[0..5]abacab前缀ab、后缀ab长度为2。p[0..6]abacaba前缀aba、后缀aba长度为3。所以数组就是[0,0,1,0,1,2,3]。如果题目采用“失配位置”的定义那还需要整体做一次偏移。我在笔试时是先把两种定义都列出来再选题目要求的那种作答避免因为理解偏差丢分。2.2 一个容易忽略的细节next数组的优化KMP还有一个容易被忽略的优化叫nextval数组。标准next数组在某些情况下仍然会有多余的回退比如模式串paaaaab当在最后一个a处失配时next数组会让你回退到前一个a再失配再回退效率退化。nextval就是在求next的过程中如果p[i]p[next[i]]就继续往前跳把重复的字符跳过去。奇安信这道题虽然只问了next数组但我在复习时把nextval也一并整理了一遍。结果后面在另一家公司的笔试里真遇到了类似问题算是意外收获。2.3 和字符串匹配相关的安全场景这里我多说一句为什么安全公司会考KMP。字符串匹配在安全领域太常见了恶意软件签名匹配、IDS/IPS规则匹配、Web防火墙的URL模式匹配本质上都是在一个长文本里找模式串。最典型的例子是Snort规则每条规则里都有content字段匹配效率直接决定引擎的吞吐量。朴素的O(n*m)匹配在规则数量少、流量小的时候没问题但一个大流量入口动辄每秒百万级请求必须用KMP或者更快的多模式匹配算法比如AC自动机。所以奇安信考KMP不是考背诵而是看你对“匹配效率”这件事有没有概念。3. 排序与数据结构看似送分题里埋的雷3.1 冒泡排序手撕代码时最容易被问住的边界条件试卷里有一道题是让说明冒泡排序的时间复杂度以及代码实现。很多人觉得这题太基础了但基础题最容易暴露问题。我整理了一个标准实现def bubble_sort(arr): n len(arr) for i in range(n - 1): swapped False for j in range(n - 1 - i): if arr[j] arr[j 1]: arr[j], arr[j 1] arr[j 1], arr[j] swapped True if not swapped: break return arr这里的优化点有两个一是内层循环只需要跑到n-1-i因为每一轮都会把当前最大值放到末尾二是用swapped标志位判断本轮是否有交换如果没有说明数组已经有序提前结束。加了这两个优化最好情况下的时间复杂度可以降到O(n)。面试官如果想深挖还会问稳定性。冒泡排序是稳定的因为相邻交换不会改变相等元素的相对顺序。真正让我觉得有陷阱的是他可能追问如果数组里有两个元素相等交换的时候有什么问题其实没有但有些人在写大于还是大于等于时犹豫不决——写大于等于会导致不稳定写大于才稳定。这种细节笔试时真的会把不少人绊住。3.2 堆排序建堆过程与Top-K问题堆排序在奇安信这份试卷里也出现了不过不是让完整手写而是问“在n个元素中找最大的K个数最好的算法复杂度是多少”。这个问题的标准答案是O(nlogK)——维护一个大小为K的小顶堆遍历数组时如果当前元素大于堆顶就替换堆顶并调整堆。这里的关键理解是找最大的K个数为什么用小顶堆而不是大顶堆因为小顶堆堆顶是堆中最小的元素当你想找最大K个数时堆顶就是这K个数的“门槛”新元素只有比门槛大才有资格进来。如果反过来用大顶堆堆顶是当前最大的元素新元素即使很小也可能被放进去堆里的K个数就不是全局最大的K个。我更想强调的是堆排序的建堆复杂度。很多人误以为建堆是O(nlogn)其实是O(n)。因为从最后一个非叶子节点开始向下调整越靠近底部的节点调整代价越小整体累加起来是线性复杂度。这个知识点在选择题里很容易作为干扰项出现我当时就遇到了一道类似题它把“堆排序建堆复杂度为O(nlogn)”列为正确选项如果不仔细就会选错。3.3 其他数据结构栈、队列、树与图的选择题陷阱奇安信的选择题里还有一些数据结构的常规考点比如栈的典型应用括号匹配、函数调用栈、表达式求值。考递归的非递归改写时本质上就是在考用栈模拟系统调用栈。队列的变体循环队列判空判满的条件。队空是frontrear队满是(rear1)%maxSizefront注意这里要浪费一个存储空间才能区分两种状态。二叉树遍历给定前序和中序求后序。这类题画图最稳不要凭感觉推。图的遍历DFS用栈或递归BFS用队列。时间复杂度都是O(VE)这是选择题的高频选项。我觉得备考这类选择题与其死记结论不如把每种数据结构在纸上面画一遍。比如循环队列你只需要画一个环形数组把front和rear两个指针标出来所有边界条件一目了然。这种方式比背公式靠谱得多。4. 机器学习与深度学习的考点算法岗笔试里最容易被忽视的送命区4.1 聚类算法与K-Means的变体奇安信作为安全公司机器学习方向肯定会考聚类。因为安全场景下的异常检测经常用聚类先把正常流量聚成簇再检测偏离簇中心的异常点。K-Means是最基础的算法但试卷里考得比较细K-Means的步骤初始化K个中心迭代执行“分配样本到最近中心”和“重新计算中心”直到中心不再变化。目标函数最小化样本到所属中心距离的平方和WCSS。复杂度每次迭代O(nKd)n是样本数K是簇数d是维度。缺点对初始中心敏感可能收敛到局部最优K值需要人为指定对离群点敏感。如果题目进一步问K-Means的改进可以回答K-Means用概率方式初始化中心让初始中心尽量分散、二分K-Means每次分裂一个簇降低SSE、Mini-Batch K-Means每次用小批量样本更新中心适合大数据量。这些名词在简答题里写出来通常能拿到不错的分数。4.2 ELBO、KL散度与变分推断问到你怀疑人生热词里出现了“kl elbo 算法原理详解”这个知识点在2020年的算法岗笔试里确实开始高频出现了。奇安信的试卷1虽然没有直接出ELBO的大题但在选择题里有一个选项涉及KL散度的性质——KL散度非负且只有当两个分布完全相同时才等于0。这个选项容易判断但如果你只是知道这个性质而不知道它在变分推断里的位置后续扩展问题就答不上来。简单说变分推断的思路是把后验分布P(theta|X)的推断问题转化为找一个简单分布Q(theta)去近似后验分布的问题。优化目标是最大化ELBOELBO E_Q[log P(X,theta)] - E_Q[log Q(theta)]而ELBO和KL散度的关系是log P(X) ELBO KL(Q(theta) || P(theta|X))因为log P(X)是常数所以最大化ELBO等价于最小化KL散度。理解这条关系链比死记ELBO公式要关键得多。我建议在复习时把它跟EM算法对照着看两者在思想上一脉相承都是因为直接优化目标函数困难转而优化一个下界。4.3 强化学习与PID算法的“跨界”迷惑性热词里同时出现了“强化学习算法”“pid算法”“模拟退火算法”等这说明奇安信算法岗笔试可能涉及多类优化算法的辨析。我对这份试卷印象比较深的是它会在选择题里把强化学习、PID控制、模拟退火放在一起问哪些属于无监督学习、哪些属于优化算法。这里的核心是区分概念强化学习智能体通过与环境交互获得奖励信号学习策略以最大化累计奖励。要素是状态、动作、奖励、策略、价值函数。它既不是监督学习也不是无监督学习而是第三种范式。PID算法比例-积分-微分控制用于工业控制场景。它维护一个误差通过比例、积分、微分三个项的组合来输出控制量。P项对应当前误差I项对应历史累计误差D项对应误差变化率。模拟退火一种全局优化算法模拟金属退火过程。它用温度参数控制接受较差解的概率温度高时接受概率大温度逐渐降低后接受概率变小从而跳出局部最优。如果你把它们混在一个“控制类算法”里就会答错。强化学习虽然是用于控制决策的但它属于机器学习范式PID属于经典控制理论模拟退火属于启发式优化算法。这类题没有难度考的就是概念辨析的清晰度。4.4 深度学习基础损失函数与正则化按照奇安信算法岗笔试的习惯深度学习基础一定会涉及但不会太深。我在复盘这份试卷时重点关注了以下几个考点交叉熵损失 vs 均方误差分类任务多用交叉熵回归任务多用均方误差。交叉熵与softmax组合时梯度形式简洁不会像MSEsigmoid那样出现梯度饱和。L1 vs L2正则化L1导致稀疏解L2导致权重整体变小但不为0。原因在于L1的梯度是常数在零点附近会有一个“硬”的收缩效果。Dropout原理训练时随机失活神经元等价于训练多个子网络的集成。测试时需要乘以保留概率或使用inverted dropout。梯度消失与梯度爆炸深层网络的反向传播中梯度连乘可能导致指数级缩小或放大。常见解决思路是ReLU激活函数、残差连接、BatchNorm、梯度裁剪。这些考点本身不偏但安全公司的笔试可能会把它们包装到“恶意流量检测模型训练”的场景里比如问“在样本极度不平衡的恶意软件检测任务中应该选择什么损失函数”。答案是Focal Loss它通过调制因子让模型更关注难分类样本。这种结合业务的考察方式也是奇安信特色。5. 奇安信特色考题当算法遇上安全业务5.1 路径遍历检测经典的字符串处理应用题热词里出现了“输入验证路径遍历”这绝对是奇安信这类安全公司的必考题。路径遍历Path Traversal又称目录穿越攻击者在URL或文件路径参数中注入../序列试图访问Web服务器上的任意文件典型的如../../../../etc/passwd试卷里这道题不会让你直接做渗透测试而是给一个函数让你实现路径规范化与校验。我复盘后整理了标准解法思路def is_safe_path(user_path): # 第一步去掉URL编码防止把%2e%2e%2f解码成../ path unquote(user_path) # 第二步替换反斜杠为正斜杠防止Windows路径穿越 path path.replace(\\, /) # 第三步将path解析为标准绝对路径 normalized os.path.realpath(path) # 第四步判断是否在允许的根目录内 return normalized.startswith(ALLOWED_ROOT)这里最核心的点在于不能只做字符串替换或前缀匹配要先把路径规范化再判断是否越界。因为攻击者会利用各种编码变体绕过简单黑名单例如%2e%2e%2f、..%5c、双重URL编码以及路径中的符号链接。os.path.realpath可以解析符号链接这是其他简单方法做不到的。这道题让我体会到安全检查本质上就是字符串处理加逻辑判断的算法题。平时刷LeetCode时对字符串题掌握得扎实这类题就写得很顺。5.2 SSL证书弱哈希算法一道需要结合背景知识的简答题热词里有“ssl 证书使用了弱 hash 算法 (cve-2005-4900)怎么修复”这道题在安全公司笔试里出现频率很高但很多算法方向的考生看到题就懵因为平时只刷算法题对证书体系不熟悉。我整理了一个简答模板背下来可以直接用背景SSL/TLS证书的签名哈希算法决定了证书完整性校验的安全性。早期广泛使用SHA-1但SHA-1已存在已知的碰撞攻击CVE-2005-4900描述的就是SHA-1签名哈希强度不足的问题攻击者可能构造一个哈希值相同的伪造证书。检测通过openssl命令检查证书的签名算法。如果输出显示sha1WithRSAEncryption则说明证书使用了弱哈希。修复联系CA机构重新签发证书选用SHA-256及以上哈希算法的证书链确保服务器不信任使用SHA-1签名的证书运维侧可以配置安全策略拒绝SHA-1证书。作为算法方向的候选人你不需要会配置服务器但需要理解其中“哈希碰撞”和“签名验证”的算法思想。这恰恰是算法基础在安全领域的有效应用。5.3 规则引擎Drools的Rete算法当规则匹配变成性能瓶颈热词里还有“规则引擎drools的rete算法实现原理和事实匹配过程”。奇安信试卷1没有直接考Drools这个具体框架但作为安全公司规则引擎是WAF、IDS产品里常见的核心组件Rete算法在其中扮演着重要角色。Rete算法的基本思想是保存已经匹配过的部分事实避免每次新事实进入时都重新匹配所有规则。它构建了一个由Alpha节点、Beta节点和终端节点构成的网络事实在网络中逐层传递。Alpha节点做单条件过滤比如“IP属于某个网段”“请求方法等于POST”。Beta节点做多条件连接类似于关系数据库中的Join操作比如“同一源IP在5秒内请求次数超过100”。终端节点当所有条件都满足时触发规则动作。Rete算法的优势在于当规则数量大、事实频繁变化时它通过内存换时间显著提升匹配效率。这其实就是一种动态规划的工程实现把复杂匹配过程拆成多个阶段缓存中间结果避免重复计算。如果笔试中遇到“如何设计一个WAF规则匹配引擎”就完全可以往Rete算法的思路上靠即使不提到Drools这个具体实现也能体现你的算法工程能力。6. 复盘后的备考建议给后来人几条实在经验6.1 按安全业务场景刷题而不是纯刷LeetCode奇安信笔试给我最大的启发是安全公司算法岗的笔试题目虽然内核是通用算法但外层常常包着一层安全场景。单纯刷LeetCode热门100题不一定能覆盖到这类题目。我建议前期集中刷“字符串处理”“正则表达式匹配”“前缀树”“多模式匹配”这几类题它们是安全检测场景中最常用的算法基础。刷的时候多想一想这个字符串操作如果用在海量日志解析里性能和内存表现会怎样有没有更高效的解法带着业务视角做题对安全公司笔试的适配度会高很多。6.2 简答题不要只写结论要写推导过程这道试卷的简答题部分阅卷标准和LeetCode不一样。LeetCode只看最终通过率简答题则看重你的推导逻辑。我复盘时发现得分比较高的回答都有一个共同点先写定义再写公式再举例子最后写复杂度。比如问快速幂算法如果只写“用二分思想递归实现”只能拿到30%的分。完整的回答应该是def fast_pow(base, exp, mod): result 1 base base % mod while exp 0: if exp 1: result (result * base) % mod base (base * base) % mod exp 1 return result然后说明时间复杂度O(logexp)空间复杂度O(1)核心是把指数按二进制位拆解当exp对应位为1时累乘base每次迭代base自平方。再加上一个具体的例子比如计算3^5 mod 7把过程写出来。这样才算一个完整的简答。6.3 别忘了复习数学基础奇安信算法方向试卷里还出现过概率统计和线代的题比如贝叶斯公式、特征值分解、向量范数等。这些内容容易被算法刷题党忽略但安全领域的很多算法问题最终都落到数学上。建议秋招前把概率论里的贝叶斯公式、期望方差、常见分布线代里的矩阵乘法、特征值、奇异值分解这些基础概念过一遍不需要做难题基本概念和公式要熟。备考期间我在每周末都会花半天时间整理本周做错的题、写错的公式、混淆的概念按“算法题-简答题-选择题”三个维度归档。这个习惯让我在秋招后期效率明显提升因为很多坑在不同公司笔试里会反复出现。奇安信这份试卷1最后复盘下来我发现自己错得最多的其实是概念辨析题而不是算法题这也是一个值得注意的备考方向。
返回列表