尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

奇安信服务端开发笔试攻略:算法、网络与安全考点全解析

奇安信服务端开发笔试攻略:算法、网络与安全考点全解析 最近不少人翻出奇安信2019春招服务端开发的笔试题想找参考。我当时正好参加过那一轮的笔试和面试也帮朋友改过不少简历。说实话这套试题本身不算偏门但放在网络安全公司的大背景下它考的东西比普通互联网公司更看重底层基础和安全意识。今天不聊保密内容只从服务端开发岗位的通用考察逻辑出发把这类笔试的拆解思路、高频题型和备考路线完整梳理一遍给正在准备安全厂商服务端岗的同学一个可复用的参考。1. 试题整体分析与考察方向1.1 服务端开发岗位在安全厂商的能力模型服务端开发在不同公司有不同侧重点。电商公司会多考分布式事务游戏公司会多考状态同步而奇安信这类安全厂商的服务端核心关注的是你能不能在“不可信环境”下把服务做好。2019年春招这批试题表面看是常规的算法、网络、操作系统、数据库但深挖下来它想选拔的是具备这三类特质的人第一基础是否扎实。安全厂商的很多内部系统要处理海量日志、告警事件、扫描任务性能问题往往是安全痛点所以算法和数据结构不过关基本很难进下一轮。第二是否理解底层机制。TCP状态机、内存模型、文件IO、进程调度这些内容不是背背八股就行而是要能结合场景推导出结论。第三有没有安全思维。服务端开发不只是把接口写出来还要考虑输入校验、越权防护、注入防御。试题里很少直接考“怎么攻击”但会通过边界条件、异常输入来考察你有没有这个意识。1.2 2019春招笔试的典型题型分布从当时的笔试反馈和我自己做的记录来看奇安信服务端开发的笔试题型比较固定通常是选择题 编程题 问答题的组合。整体时间段在2小时左右选择题占40%编程题占30%问答和系统设计占30%。对比普通互联网公司选择题比例偏高这说明他们很在意知识面的广度。题型常见内容分值占比难度评价选择题数据结构、网络协议、操作系统、Linux命令40%中等但陷阱多编程题数组/链表/字符串、递归与动态规划30%中等偏上问答题高并发处理、数据库索引、安全编码30%灵活考察表达别小看选择题它比编程题更能在短时间筛出“背过但没吃透”的人。比如一道关于TCP第三次握手时服务器状态变化的题目选项里会混入“SYN_RECV”“ESTABLISHED”“LISTEN”等状态如果你只记得三次握手的名字没画过状态迁移图很容易选错。我当时的经验是面对这类题第一时间在草稿纸上画状态图不要凭感觉。2. 编程语言与算法基础拿分的关键2.1 必考的编程语言特性笔试一般允许从C/C、Java、Python里选一门。但不管你选什么语言底层机制都会被选择题反复拷问。C的虚函数表、智能指针Java的HashMap扩容、JVM内存分区Python的GIL这些都是出现概率很高的点。我当时选的是C但考完发现Java方向的题目更偏向“服务端框架层面”比如Spring的Bean生命周期、Netty的EventLoop模型。如果你目标明确是服务端岗位建议提前定好主语言不要每样都浅尝辄止。还有一类必考是内存管理。安全厂商的C服务常要处理自己的内存池所以“内存对齐”“栈上变量生命周期”这类题几乎是送分题但也最容易丢分。举个实际例子有题目让计算sizeof一个包含int、char、double的结构体很多人直接算成13字节正确答案是24字节在64位系统默认对齐下。这种题没有技巧就是要在平时写代码时留意变量定义顺序。2.2 高频算法题型与解题模板2019春招服务端笔试的编程题我印象里没有特别偏的冷门算法集中在三大类第一类是双指针与滑动窗口。典型如“找出字符串中最长无重复字符的子串长度”。这题的思路不算难关键在于用哈希表记录每个字符最后一次出现的位置left指针负责收缩窗口。很多人在笔试时卡在边界处理比如字符串为空、字符重复后left的更新逻辑。#include string #include unordered_map using namespace std; int lengthOfLongestSubstring(string s) { unordered_mapchar, int lastIndex; int left 0; int maxLen 0; for (int i 0; i s.size(); i) { if (lastIndex.find(s[i]) ! lastIndex.end()) { left max(left, lastIndex[s[i]] 1); } lastIndex[s[i]] i; maxLen max(maxLen, i - left 1); } return maxLen; }这里有个容易错的细节left指针为什么取max而不是直接赋值因为lastIndex里记录的可能是多个字符的旧位置直接赋值会把left往回拉导致窗口内出现重复字符。这道题的时间复杂度是O(n)空间复杂度是O(n)。笔试时如果时间紧可以先写暴力双循环验证思路再优化成滑动窗口但一定要在代码注释里写清楚复杂度让阅卷人看到你的思考过程。第二类是链表操作。常见的有反转链表、合并两个有序链表、判断链表是否有环。这里我想提醒一个细节链表题的边界条件判断一定要加分。比如反转链表需要三个指针pre、cur、next很多人在循环退出条件上写错导致空指针。我当时的习惯是先画一个三节点的小例子再开始写代码。第三类是二叉树的层序遍历。服务端开发不常直接写树但很多设计题比如多级缓存、组织架构树都会用到树的思维所以笔试也喜欢考。层序遍历的模板是使用队列每次记录当前层的节点数量。vectorvectorint levelOrder(TreeNode* root) { vectorvectorint result; if (!root) return result; queueTreeNode* q; q.push(root); while (!q.empty()) { int size q.size(); vectorint level; for (int i 0; i size; i) { TreeNode* node q.front(); q.pop(); level.push_back(node-val); if (node-left) q.push(node-left); if (node-right) q.push(node-right); } result.push_back(level); } return result; }很多同学会想把size用q.size()替代直接在循环里调pop和push这样会导致当前层和下一层混在一起输出结果就错了。这道题的关键就是先记录size再按size遍历。这种细节不是智商问题而是做题习惯问题。2.3 一道容易“崩心态”的区间合并题还有一类高频题是“区间合并”题目给出一组区间要求合并所有重叠区间。这题表面上是排序后遍历但面试官常常会追问“如果区间数量特别大内存装不下怎么办”。这就是安全厂商的考察风格先写基础解法再追加大规模场景。基础解法很直接先按起点排序再遍历维护当前区间的start和end。代码如下def merge(intervals): if not intervals: return [] intervals.sort(keylambda x: x[0]) merged [] for interval in intervals: if not merged or merged[-1][1] interval[0]: merged.append(list(interval)) else: merged[-1][1] max(merged[-1][1], interval[1]) return merged陷阱在合并时一定取max的右端点而不是直接取当前区间的右端点。因为前一个区间的右端点可能比当前区间的右端点还大。后续追加的问题“内存装不下”其实考察的是外部排序和多路归并。你可以回答先把区间按起点哈希分桶每个桶内进行区间合并然后桶与桶之间再做一次合并。这体现的是分布式思维不要求你写完整代码但逻辑要严密。3. 网络与操作系统服务端开发的底盘3.1 TCP/IP、HTTP这些一定要过关服务端开发每天都在和网络打交道所以网络协议几乎是必考。2019春招笔试题里TCP相关内容出现频率最高而且不光是三次握手四次挥手这种教科书知识还会结合故障场景提问。比如“服务器进程崩溃后客户端还能收到FIN吗”“大量TIME_WAIT状态时系统表现是什么”。这些问题的答案都需要你真正理解TCP状态机而不是背诵“四次挥手”。我当时的复习方法是把TCP状态图手画三遍每次画都要标注出导致状态迁移的触发事件。比如收到SYN后从LISTEN迁到SYN_RECV收到ACK后从SYN_RECV迁到ESTABLISHED。画完后再把“主动关闭”和“被动关闭”的序列理清。掌握了状态图选择题基本不会错问答题也能答到点上。HTTP方面考察点集中在HTTP/1.1与HTTP/2的区别、常见状态码的含义、Cookie和Session实现机制的差异。奇安信这类公司还会额外关注HTTPS的握手过程尤其是“对称加密和非对称加密如何配合使用”。这里有个很容易忽略的点TLS握手过程中客户端和服务端交换证书的时机在“ServerHello之后”而证书验证的目的不是加密而是防中间人。如果不理解这个谈到证书就只会说“加密”这就暴露了理解深度不够。3.2 Linux操作与并发模型笔试选择题中经常有Linux命令的考察例如查看端口占用用netstat还是ss实时查看日志用什么命令统计某个文本字段的出现次数用什么组合。这些题不难但很考验命令行熟练度。我当时吃过亏的是“awk和sort的组合用法”题目要求“统计access.log里每个IP的出现次数并排序”。正确命令是awk {print $1} access.log | sort | uniq -c | sort -k1nr很多人会漏掉中间的sort因为uniq -c只能统计相邻行如果ip没有排序结果就不对。还有人在最后用了sort -n结果变成按数字升序这里必须加r表示降序。一道2分的题三连命令就能筛掉不熟悉shell的人。并发模型也是服务端开发的必考。常见的多线程模型、多进程模型、事件驱动模型都需要清楚各自优缺点。一个经典问答题是“为什么Redis单线程还可以这么快”答案不是“因为它快”而是因为它基于内存操作、非阻塞IO、避免了锁竞争。如果面试官追问“如果并发量大到十万级写请求单线程还够吗”你要能分析瓶颈会在IO等待还是CPU计算而不是一句“单线程不好”就结束。3.3 安全相关基础奇安信笔试的特色题既然是奇安信的试题安全类题目一定不会少。我记得当时有一道选择题问“SQL注入攻击中最常见的防护手段是什么”。选项里有“对用户输入进行HTML转义”“使用参数化查询”“关闭报错信息”“限制输入长度”。正确答案是使用参数化查询但很多人会选成HTML转义因为这两个概念经常被一起提起。这里必须区分语义SQL注入是命令注入参数化查询让数据库把输入当作数据而不是可执行代码而HTML转义是防XSS的不是防SQL注入的。问答题里还有一个高频方向是“如何设计一个安全的文件上传接口”。这题看着简单但答点很多限制文件大小、检查Content-Type、对文件内容进行魔数校验、重命名文件并存储在非执行目录还要考虑压缩炸弹。安全厂商尤其看重这类思维知识点不是最难的而是能不能把攻击场景想周全。我在回答这类问题时习惯用“输入校验 → 执行逻辑 → 输出防护”的链路来组织语言既能体现结构也避免漏点。4. 系统设计与数据库拉开差距的加分项4.1 经典系统设计题怎么回答服务端笔试的问答题里系统设计题是拉开差距的关键。例如“设计一个短网址服务”这题很多公司都爱考。它考察的是存储设计、哈希发号器、缓存策略、跳转逻辑以及并发冲突处理。我的建议是不要一上来就画架构图先和面试官确认核心需求QPS是多少、数据量多大、是否要求可定制短链。如果笔试题里没有面试官那就自己在答案里写明假设条件再给出设计。一个简洁的存储方案是一张表存储短码和原网址短码由发号器生成的自增ID转换而成。转换方式不是直接使用十进制字符串而是将ID转换为62进制形成6-8位的短码。发号器可以用数据库自增ID也可以用Redis的INCR命令。如果要求高可用可以采用预分配一段ID段来减少数据库压力。这些内容写在答案里阅卷人会认为你有分布式架构意识。回答这类题一定要写清楚“数据如何读写”“遇到冲突怎么办”“扩容怎么做”。不需要完整实现代码但要给出关键表和关键接口的伪代码。比如短网址的核心接口是createShortUrl与getLongUrl前者需要判重和发号后者需要缓存和回源数据库。4.2 数据库索引与SQL优化数据库题在奇安信服务端试卷中占比也不少。最常考的是“一条SQL为什么会慢”以及“如何优化”。我在当时碰到一道题给出一个user表字段包括id、name、age、created_at要求查找“年龄大于25的前100个用户按创建时间倒序”。很多人的第一反应是直接在created_at上建立索引排序但这样导致age过滤时无法利用索引最终性能可能很差。如果数据量很大更好的方式是联合索引(age, created_at)这样age条件可以快速定位created_at字段在索引内有序可以避免文件排序。但要注意age的过滤是范围查询联合索引中created_at的排序在age相同的情况下才有效。所以在回答时我会先分析“过滤条件”和“排序字段”再决定是否要两种索引分开还是联合索引。这种推导过程一定要写在答案里哪怕只是三五行。还有一个常见问题“什么情况下索引会失效”。最典型的是对索引列使用函数或隐式类型转换比如where id_str 123如果id_str是varchar类型查询优化器可能就不走索引。这类题没有诀窍就是平时做SQL实验时多留意explain的输出。4.3 缓存、消息队列与分布式基础服务端开发绕不开缓存和消息队列。笔试选择题可能会问“缓存穿透和缓存雪崩的区别”“Redis过期策略有哪些”等等。这里我把最常考的两个概念对比一下概念触发场景典型解决思路缓存穿透查询一个根本不存在的数据每次都打到数据库布隆过滤器、缓存空值并设置短过期缓存雪崩大量缓存同时过期请求直接打到数据库过期时间加随机值、多级缓存、限流降级布隆过滤器是一个很值得深入理解的点。它利用多个哈希函数映射到位数组上判断“某个key一定不存在或可能存在”。优点是空间占用极小缺点是有误判率且不支持删除。在描述如何预防缓存穿透时提到布隆过滤器就是一个加分项。分布式基础方面2019年奇安信笔试并没有直接问Raft或Paxos但问过“简述分布式系统中CAP理论并举例”。这种题要注意的是不能只说“C、A、P三者不可兼得”要结合具体系统举例子比如ZooKeeper优先保证一致性Eureka这样的注册中心更侧重可用性。能举出实例体现出你真的用过而不仅仅是背了概念。5. 备考路线与避坑指南5.1 三周备考计划如果你现在才开始准备这类服务端笔试我建议把复习压缩成三个递进阶段而不是漫无目的地刷两个月。第一周打基础选择一门主语言把《剑指Offer》里的题目刷完同时把计算机网络和操作系统的核心概念过一遍。这一周的目标不是记住所有细节而是建立“问题-知识点”的映射。比如看到“高并发下的库存扣减”立刻想到“事务隔离级别”“乐观锁”“Redis原子操作”这几个关键词。第二周编程强化按专题刷题重点是数组、链表、字符串、树和动态规划。每天固定做3到4道新题同时复习前一天的错题。不要只在本地IDE里跑要习惯在白板或网页编辑器上写代码因为笔试环境通常没有语法高亮和编译提示。第三周全真模拟找一套完整的服务端笔试题掐时间做一遍最好选一个连续2小时的时间段模拟真实环境。做完之后重点分析自己哪里卡住了是知识点缺失还是做题策略问题。我模拟的时候发现最影响分数的是选择题陷阱不是编程题所以后来我把选择题的错误点专门整理成一个文档考前反复看。5.2 笔试和面试中容易踩的坑先说笔试中反复出现的坑编程题不写复杂度和边界条件。哪怕代码能跑阅卷人也会觉得你只是碰巧写对至少要在注释里写清时间复杂度和空输入处理。选择题钻牛角尖。有些题确实不严谨这时先选最符合主流实践的答案不要写反。我发现有很多人输在“常见做法”和“理论最优”之间选理论最优反而错了。问答题答得太简略。比如“如何设计日志系统”只回答“用消息队列”没有说数据格式、分区策略、写入路径等于没答。面试时也有一个容易被忽视的坑你在介绍项目时提到的每一个技术名词都可能成为下一个问题。比如你说“用了Redis做分布式锁”面试官马上追问“如果锁过期了怎么办”“如果主节点宕机锁怎么办”。如果没准备过就老老实实说“这里只用了最基础的setnx没有考虑极端情况”也比硬编一个不存在的方案强。5.3 资源推荐和时间分配备考服务端开发不需要买又多又厚的教材。我推荐三类资源成本低、见效快。第一类是题库国内用LeetCode力扣和牛客网就够了重点刷LeetCode的Top 100以及牛客网上的“服务端开发”专项题。第二类是视频课程推荐机械工业出版社的《计算机网络》结合“TCP/IP详解”的部分章节不用全看只关注连接管理和状态转换。第三类是面经多看目标公司往年的笔试面经但注意甄别不要太依赖回忆帖。时间分配上如果每天能投入4小时我建议算法2小时、基础2小时。很多人到后期会发现知识都懂但做题还是慢根本原因是没有把方法变成肌肉记忆。解决方法是重复做那些“第一遍没做出来”的题隔天再做一遍三遍之后就会形成条件反射。写在最后我的一些个人体会回过头看2019春招的服务端开发试题难的不是某一道题而是如何在规定时间内稳定输出。奇安信的题目风格提醒我做服务端开发不能只追求代码能跑还要追问一句“如果输入很脏、流量很大、中间节点挂掉系统还能不能稳”。这其实是一种职业习惯。建议所有准备这个岗位的同学除了刷题也试着多写一些带异常处理、带超时控制、带日志埋点的小服务把它跑起来然后拆掉再重构一次。真实工作里遇到的很多问题笔试是没有办法完全模拟出来的但那些调试过程中形成的直觉最后都会变成你的优势。
返回列表