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

资讯详情

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

奇安信服务端开发面试复盘:安全行业后端的核心考点与备考思路

奇安信服务端开发面试复盘:安全行业后端的核心考点与备考思路 2020年5月31号下午我参加了奇安信服务端开发工程师-应用开发这个岗位的笔试和面试。那时候奇安信刚从安全业务中独立出来没几年正处于政企安全市场大规模扩张的阶段招人力度非常大。这个岗位面向的是安全产品体系中的业务后端开发跟普通互联网后端有不少区别对安全开发、权限模型、合规审计这类东西有额外要求。这篇文章把当时从投递、笔试到技术面、HR面能回忆起来的细节都整理出来重点复盘技术考点和答题思路希望对准备安全行业后端岗位的读者有帮助。1. 岗位目标与面试前的自我定位1.1 奇安信应用开发服务端工程师到底做什么先理解这个岗位在组织里处于什么位置。奇安信的产品线很多面向政企客户的终端安全管理系统、漏洞扫描平台、态势感知平台、代码安全检测工具、可信浏览器等每个产品背后都有一整套服务端。这个岗位叫“应用开发”核心是写业务后端也就是把安全能力包装成可管理、可配置、可运营的业务系统。举个例子终端安全管理系统里你负责的模块可能是策略中心管理员在Web控制台配置一个“禁止U盘使用”的策略这条策略要通过后端服务下发到成千上万台终端终端要回传执行结果、上报文件哈希、上报进程行为日志后端要做数据接收、解析、存储同时支撑控制台的数据展示和报表查询。这些系统跟C端互联网产品不太一样用户量级通常没有那么大但每条数据的业务语义很重权限模型复杂而且因为是安全产品所有操作都要留痕、可审计。这意味着一件事准备这个岗位的面试光看常规的Java并发、MySQL、Redis还不够还要额外准备安全开发向的问题比如输入验证、路径遍历、越权、审计日志、数据脱敏。我就是在这个环节踩过坑后面会细讲。1.2 我准备这份面试时重新回顾的知识树把知识体系分成六个部分来梳理每个部分都要有能讲深两层的点。计算机网络TCP/UDP、HTTP/HTTPS、HTTP状态码、WebSocket、长连接与心跳机制。操作系统与Linux进程线程、上下文切换、内存管理、磁盘IO、常用排查命令。数据库MySQL索引结构、事务隔离级别、锁机制、慢查询优化、分库分表思路。缓存与中间件Redis数据结构与过期策略、缓存穿透/击穿/雪崩、消息队列选型与削峰。分布式基础分布式事务、分布式ID、接口幂等性、负载均衡、服务发现、熔断限流。安全开发基础输入校验、OWASP Top 10、文件上传下载安全、路径遍历、越权、SQL注入、XSS、CSRF。这个岗位是“服务端开发工程师-应用开发”所以核心还是后端基本功但安全开发这一块是加分项中的加分项。我当时以为安全公司的面试会主要谈渗透攻防实际聊下来发现面试官更关心的还是你能不能写出健壮的业务系统代码只是在设计题里会频繁把安全场景塞进去考察。2. 笔试环节5月31日那场在线笔试复盘2.1 题型分布与答题策略笔试是线上进行题量不算小印象中单选、多选、填空题覆盖了计算机网络、操作系统、数据库、数据结构这些基础内容后面还有编程题和简答题。时间分配上我犯过一个不少人都容易犯的错前面的选择题做得太慢尤其是遇到一些模棱两可的多选题时反复纠结导致后面的编程题时间紧张。我后来总结出来的策略是选择题在一分钟内做不出来就先标记跳过整个基础部分控制在40%的考试时间内完成编程题一定要留足时间。在线笔试系统一般都有本地IDE和在线编辑器两种模式建议在本地IDE里写代码调通之后再粘贴提交避免因为在线编辑器没有智能提示导致低级语法错误。填空题里有一些记概念的题比如“TCP建立连接需要几次握手”“HTTP响应头中用于控制缓存的是哪个字段”这类。这部分就是拼基础功没有什么技巧靠日常积累。2.2 两道让我印象深刻的原理题笔试里有两道题我记得很清楚因为都是那种看起来简单、想深入答准确却不容易的问题。第一道是“TCP建立连接为什么需要三次握手两次行不行”。这个问题的标准答法是防止已失效的连接请求报文段突然又传到服务端导致服务端白白建立连接并分配资源。我特意把这个场景描述完整客户端发送的第一个SYN报文在网络中滞留客户端因为没收到确认就重发了一个新的SYN这时旧的SYN后来又到达了服务端如果只有两次握手服务端无法判断这是一个失效的连接请求就会建立连接并一直等待客户端发送数据造成资源浪费。三次握手中客户端收到服务端的SYNACK后不会再次确认这个旧请求服务端迟迟收不到客户端的ACK就会放弃这个半连接。这就是为什么客户端和服务端都要有确认机制的原因。第二道是Redis相关的场景题“缓存雪崩和缓存穿透有什么区别分别怎么解决”。我当时用表格在草稿纸上列了一下确保回答里不漏掉任何一个点。场景本质典型场景解决思路缓存穿透查询一个不存在的数据缓存和数据库都没有恶意请求一个不存在的ID布隆过滤器、缓存空值设置较短的过期时间缓存击穿一个热点key过期瞬间大量请求打到DB热点商品详情页缓存失效互斥锁重建缓存、逻辑过期缓存雪崩大量key同一时间段集中过期缓存设置了相同的过期时间过期时间加随机值、多级缓存、熔断降级这道题在笔试考了技术面也被追问了可以说是一个高频考点后面在真实项目里也确实会频繁遇到。2.3 编程题一道与路径处理相关的算法题编程题我记得有一道和“规范化文件路径”有关的题目输入一个字符串路径要求输出简化后的绝对路径。比如输入/a/./b/../../c/输出/c。这道题出得很聪明表面上是一道模拟题其实隐含了路径遍历防护的思想。我用栈来处理按/分割路径遇到普通目录就压栈遇到..就弹出栈顶目录遇到.或空字符串就跳过。写完代码后需要额外考虑几个边界情况路径以/开头保证是绝对路径..时栈为空则不弹最终栈为空时返回根目录/。这种题考察的不仅是数据结构还有对路径含义的理解现在回头看和安全开发里讲的路径遍历防护其实是一脉相承的。def normalize_path(path: str) - str: stack [] for part in path.split(/): if part in (, .): continue if part ..: if stack: stack.pop() else: stack.append(part) return / /.join(stack)这个实现虽然不长但如果没有提前想清楚..处理、栈空、分隔符连续出现的边界条件很容易在细节上出错。建议准备笔试时把这类“字符串模拟栈”的经典题都刷一遍类似的有简化路径、括号匹配、逆波兰表达式求值。3. 技术面最贴近真实工作的一轮3.1 面试官问到的五个核心场景题技术面大概聊了一个多小时没有太多上来就背八股的感觉更多是给一个场景让我现场拆解设计思路。我整理出五个印象最深的场景题。第一个场景是一个安全产品的管理平台有5000台终端同时在线现在管理员要统一给所有终端下发一个策略后端接口应该怎么设计。我的回答分了几层接口本身要支持批量不能一台终端一个请求终端侧用拉模式先通过长轮询或心跳发现策略版本变更再按批次取数据服务端用异步任务来处理下发队列配合消息队列做削峰关键是要有任务状态跟踪能实时看到多少台终端下发成功、多少失败、失败原因是什么。第二个场景是设计一个漏洞扫描任务调度器。这个题目考察的是任务状态机设计。我把任务状态拆成待执行、执行中、成功、失败、超时、取消。核心问题是怎么避免重复执行以及扫描节点挂了怎么处理。我当时回答的重点是数据库任务表记录状态和版本号用乐观锁防止多个节点同时抢占同一个任务执行节点通过心跳上报状态超时之后由调度中心把任务重新放入待执行队列。第三个场景是权限模型。安全产品的管理平台一定会有多租户和细粒度权限控制我被问到RBAC模型怎么落地。我画了用户-角色-权限-资源的关系说明权限点最小粒度控制在按钮和接口级别中间加一层角色和用户组避免每个用户单独配置权限。另外还提到了数据权限的隔离也就是同一个角色在不同组织下能看到的数据范围不一样这个比单纯的菜单权限要复杂得多。第四个场景是报表查询慢。控制台要展示近30天全网终端的威胁事件统计数据量积累到千万级别以后报表接口越来越慢。我给出的思路是先用索引优化和SQL改写解决明显问题然后做定时汇总表预计算每日维度的统计数据查询时只查汇总结果最后按时间分区存储原始数据冷热数据分离。这题几乎每个服务端岗位都会问核心是让面试官看到你有冷热分离、预聚合的意识。第五个场景是文件上传下载的接口设计。安全产品里经常要上传样本包、下载扫描报告。我提到要做大小限制、文件类型校验、分片上传、断点续传、上传后异步做安全检测还要保证下载接口的幂等和可断点。面试官追了一句“如果上传的文件名是../../../etc/passwd怎么办”这一问把我带到了下一个环节。3.2 安全开发向的追问输入验证与路径遍历这就是整个面试里让我印象最深的一段。面试官直接问你刚才说文件类型校验如果攻击者上传的文件名里包含路径穿越符客户端传过来一个../../../../tmp/test.txt你的服务端会怎么处理。路径遍历Path Traversal的本质是攻击者利用服务端对文件路径的拼接处理不当通过..、绝对路径、编码绕过等方式访问到应用预期之外的文件。安全产品本身做的是防护工作自己的业务代码如果出现这类漏洞那会非常尴尬。我当时的回答分了几个层面第一层输入校验。对文件名做白名单约束只允许字母、数字、下划线、点、短横线长度也做限制直接过滤掉反斜杠、正斜杠、..这些特殊字符。需要注意的是不能只做一次过滤因为攻击者可以URL编码、双重编码、Unicode编码绕过比如把..编码成%2e%2e%2f或者用....//让过滤逻辑失效。所以校验应该在解码之后进行而且最好用白名单而不是黑名单。第二层路径规范化。服务端拿到文件名后不能直接拼接在存储路径后面要先通过Files.toRealPath()或者Path.normalize()取得规范化后的绝对路径然后校验这个规范化路径是否仍然在允许的目录前缀之内。规范化不是只做一次就完事要确保校验的是最终访问的路径。第三层统一封装文件操作。所有涉及文件上传下载的模块都要走同一个文件访问服务由这个服务统一做路径校验、目录约束、权限校验不让业务代码自己拼路径。这样即使某个业务开发同学忘记校验底层也能拦住。用了一段伪代码来说明校验逻辑public boolean isPathAllowed(String baseDir, String fileName) { Path basePath Paths.get(baseDir).toAbsolutePath().normalize(); Path targetPath basePath.resolve(fileName).normalize(); return targetPath.startsWith(basePath); }面试官对这套回答比较认可但他补充了一点我确实当时没答全Windows平台下还要考虑盘符、以\\开头的UNC路径以及短文件名8.3格式绕过的问题。跨平台的安全产品会同时部署在Windows和Linux上路径处理必须在所有平台上都验证过。这些细节如果不是真做过很难在面试中临场想全面所以建议准备安全行业后端岗位的朋友提前把文件上传下载、路径处理、文件名校验这块的防护方案整理成自己的一套方法论。3.3 高频八股但容易答错的细节除了场景题技术面也有一些直接提问这类问题看起来基础但越是基础越容易答得不够准确。HTTP状态码是必问的。面试官给了几个场景让我说出对应的状态码请求体太大、发送请求频率过高、网关超时、后端服务不可用。对应的分别是413 Payload Too Large、429 Too Many Requests、504 Gateway Timeout、502 Bad Gateway。还有一个容易混淆的301是永久重定向302是临时重定向307和308是为了保持请求方法不变而设计的重定向状态码。线程池参数设置的问题我建议不要背默认值而是要知道每个参数怎么算。核心线程数和最大线程数的设定取决于任务是CPU密集型还是IO密集型。CPU密集型的核心线程数接近CPU核心数IO密集型的可以设大一些常用公式是CPU核心数 /1 - 阻塞系数。队列容量如果设大了会导致请求在队列里排队时间过长设小了又容易触发拒绝策略。我当时还专门讲了拒绝策略的选择AbortPolicy会直接抛异常CallerRunsPolicy会让提交任务的线程自己执行更适合对任务丢失敏感的场景。MySQL索引失效也问了几个典型情况对索引列使用函数、隐式类型转换、like以通配符开头、联合索引不满足最左前缀原则。这些不算难但如果平时没系统梳理过现场容易漏掉其中一两个。Redis和数据库一致性的问题也出现了。我当时给出的方案是先更新数据库再删除缓存并且通过延迟双删避免并发读写导致缓存里是旧数据。面试官反问如果第二次删除失败了怎么办。我补充说要配合消息队列或者订阅数据库的binlog来异步重试删除最终保证一致性。这种追问我觉得是有价值的它逼着你把方案想完整而不只是背一个答案。4. 应用开发方向如何组织主项目经验4.1 什么样的项目会被面试官认可技术面里一定会问项目但“做过”和“能讲清楚”是两回事。我见过太多人把项目描述成“一个XXX管理系统用户管理、角色管理、菜单管理”这种描述在服务端开发面试里基本是负分。面试官认可的表述方式应该是这样的项目背景是什么你在里面承担哪部分遇到了什么技术难点你用什么方案解决最后有没有可量化的结果。量化数据不一定是QPS、TPS这些宏观指标也可以是报表接口从10秒优化到200毫秒任务调度支持了1万台终端并发下发消息队列削峰后数据库峰值连接数下降了60%。这些具体数字比任何修饰词都有说服力。我在面试里讲的是一个终端资产管理平台的项目。这个项目会接收终端上报的硬件信息、软件清单、运行状态然后展示在Web控制台上支持资产查询、变更记录、离职员工资产回收提醒。技术难点在于上报接口要能扛住终端集中上报资产数据的变更要保留历史版本方便追溯查询条件组合非常多索引设计比较难。这类安全产品业务后端的项目和互联网业务后端最大的区别是业务语义更重每一步操作都涉及到权限和审计。我在介绍项目时专门留了一个部分讲审计日志设计包括谁在什么时间对哪台设备做了什么操作、操作前后的值变化、操作结果全部要记录。面试官对这个点很感兴趣因为这说明候选人真的理解合规场景。4.2 技术栈选型背后的逻辑面试聊到技术栈的时候我顺势问了一句团队主要用什么语言面试官说以Java为主但安全能力组件有些会用Go写。这个问题其实很能体现安全公司技术栈的特点Web业务系统、管理平台这类偏业务的应用用Java的Spring Boot生态效率最高招人也容易而Agent、网关、数据采集这些偏底层的组件用Go更合适因为部署简单、并发性能好、内存占用低。我当时准备的是一个常见的技术栈组合Spring Boot做业务接口MyBatis做数据访问MySQL存业务数据Redis做缓存和分布式锁RocketMQ或Kafka做消息队列XXL-Job做分布式定时任务Nacos做注册中心和配置中心Nginx做网关层。这套组合在2020年前后的政企项目里非常常见对应试者来说只要能把这套东西讲清楚已属不易。要特别提一下定时任务。安全产品里定时任务非常普遍漏洞扫描周期执行、报表每日生成、终端离线检测、病毒库定期更新。所以面试官对XXL-Job的熟悉程度会比较关注包括任务分片是怎么做的、调度失败怎么处理、任务幂等怎么保证。我建议在准备项目时至少要在简历里写一个和定时任务相关的模块防止面试官认为你只会写CRUD接口。4.3 写在简历上的几个关键词建议简历上写技能关键词的时候尽量不要只写“熟悉Redis”“熟悉消息队列”而是要让关键词更具体让人能从中读出一个技术方案的影子。当年我的简历用过这样一组描述反馈比较好海量终端数据接入、上报接口异步化与削峰填谷、分布式任务调度、缓存与数据库一致性保障、接口幂等设计与分布式锁。还有一个容易踩的坑简历上写的每个技术点都要准备好被追问。写了“熟悉Netty”就至少要能解释Netty的Reactor线程模型、EventLoop是怎么回事、为什么比传统的BIO性能高。写了“熟悉JVM”。就要准备好回答内存区域、垃圾回收器、频繁Full GC怎么排查。我在准备阶段用了一个笨办法把简历里每个技术关键词都列出来逐个问自己“如果面试官让我讲30秒我能不能讲清楚”讲不清楚的就重新学一遍绝不带病上场。5. HR面与Offer沟通环节实录5.1 HR面问到的非技术问题技术面通过之后HR面相对轻松但也不能掉以轻心。HR主要确认的是目前的在职状态、到岗时间、期望薪资、能接受的base地、对加班的看法、过去离职的原因。有一个让我印象深刻的问题是“你怎么看待安全行业的服务端开发和互联网服务端开发的差异”。我当时回答的核心观点是互联网后端追求高并发大流量下的极致性能安全行业的后端更看重稳定性、可审计性和合规性很多功能不是做得快就好而是要做对、做到有据可查。而且安全公司的研发同学站在对抗一线写代码时要时刻假设有人恶意攻击你的系统Web层和业务层的安全需要在开发阶段就考虑进去。这个回答后来看是符合岗位预期的。安全行业还有一些特殊要求比如背景审查会比普通互联网公司严格部分项目因为涉及保密要求对员工的操作记录、数据外发管控会有额外约束。这些都是正常的行业特点面试时保持坦诚就行。另外这个岗位部分项目可能需要驻场开发尤其是一些政企项目HR会确认你能否接受出差或驻场提前想清楚自己的底线在哪里。5.2 关于薪资和流程的一些信息差关于薪资谈判我作为过来人分享几个当年踩过坑之后总结的注意点。第一薪资报价要基于当前综合收入来算而不是只报月薪。很多公司会提到总包概念包括基本工资、绩效、年终奖、补贴所以在HR问期望薪资时先反问清楚薪资结构再报目标不然容易双方理解偏差。第二这个岗位在奇安信属于研发序列不同base地的薪资水平会有一点差异。北京、长沙、成都这些地方的成本不一样议价空间也不同建议面试前了解目标城市的行情。第三流程上正常是简历筛选、笔试、技术面、HR面、Offer审批。有些岗位可能还有交叉面或总监面2020年那会儿很多环节都改成了线上整体周期大概两周到一个月。如果在某个环节后长时间没消息可以礼貌地询问面试进度不要干等。当时给我发面试邀请的时间点正赶上奇安信上市前的一轮大规模招聘整体节奏很快。我印象中笔试后大概隔了两三天就约了技术面技术面后一周内安排了HR面效率在当时的行业里算比较高的。6. 面试中最容易翻车的几个问题和解决思路6.1 被追问细节时垮掉的真实案例面试中容易出现一个现象一个点自己写在了简历上但面试官追问两层之后答不上来。我见过一个反面案例简历上写“使用了Redis做缓存”面试官问“Redis为什么快”候选人回答“因为它是基于内存的”面试官继续问“除了基于内存还有什么原因”这就有点卡住了。Redis快的原因至少还有几点IO多路复用机制让单线程能应对大量并发连接数据结构针对不同场景做了高效设计比如跳表、压缩列表命令处理在内存中完成避免磁盘IO。如果只答出“基于内存”这一层那这个技术点就浪费了。解决这个问题的办法是每个技术点准备两层深度。第一层是什么、能干什么第二层是底层原理、源码实现思路、适用边界。比如Redis除了知道String、Hash、List等数据结构还要知道底层有SDS、ziplist、quicklist这些设计。不用背得特别细但至少知道名字和设计动机。6.2 面试中我一直踩的坑与改进方法第一个坑是语速太快一紧张就想赶紧把话说完结果面试官听不清思考过程也不完整。改进方法是刻意在说完一个观点之后停顿一下让面试官有时间消化和追问。面试不是抢答比赛节奏应该由你来引导。第二个坑是遇到不会的问题时直接说“不会”。其实面试官最想看到的不是你什么都会而是面对未知问题时怎么思考。正确姿势是先复述一遍问题确认理解然后说出你认为可能相关的知识点再给出一个大概的解题方向。比如问到你完全没接触过的组件可以说“我没有在生产环境用过这个组件但根据名字和类似组件的能力我推测它负责……”这样至少展示了学习能力和迁移能力。第三个坑是答题没有结构化。面试官问一个设计题你东一句西一句说完场景直接跳到细节没有先给整体框架。我后来养成一个习惯回答设计题先分层。比如问接口设计先说是接入层、业务层还是数据层的问题然后说整体流程最后展开关键细节。这样面试官能跟着你的思路走也更容易抓到你回答中的亮点。6.3 高频考点速查表最后整理一份我在准备这场面试过程中反复使用的高频考点速查表按岗位特点做了权重分配供准备安全行业服务端开发岗位的朋友参考。考点考察意图参考答题方向TCP三次握手原因计算机基础是否扎实防失效连接请求避免资源浪费两端确认收发能力HTTP缓存控制实际开发中是否处理过性能问题Cache-Control、ETag、Last-Modified数据库索引失效场景是否理解索引原理函数操作、隐式转换、like前置通配符、最左前缀失效接口幂等性业务系统设计成熟度唯一请求ID、状态机、数据库唯一索引、分布式锁缓存三大问题并发场景处理能力穿透/击穿/雪崩的成因与对应方案路径遍历防护安全产品研发的基本素养白名单校验、路径规范化、统一文件访问层权限模型设计政企平台开发经验RBAC、数据权限隔离、操作审计分布式任务调度安全产品中大量存在的场景任务状态机、分片执行、失败重试、幂等这份表格里的每个点我在面试过程中基本都遇到了除个别问题换了个壳核心考察方向没有变过。如果时间有限优先把“接口幂等性”和“路径遍历防护”这两个方向吃透因为它们在安全行业后端面试里出现的概率非常高。这场面试已经过去几年了后来我虽然没有选择这个岗位但准备期间重建的那套知识体系一直在使用。尤其是输入验证和路径遍历那一段让我在后来的项目里养成了写文件处理代码时先想“攻击者会怎么绕”的习惯。最后分享一个经验每次面试后马上做复盘把被问到的问题、当时的回答、更好的回答都记录下来隔一周再看一遍这种刻意练习比刷十套题都管用。如果能把每次面试都当成一次免费的模拟项目评审心态会稳很多。
返回列表