尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

字节面试:5万个敏感词库,3000字长文,要求10毫秒内审核完毕,怎么做?

字节面试:5万个敏感词库,3000字长文,要求10毫秒内审核完毕,怎么做? 两天有个小伙伴给我分享了他去大厂面试的经历。他说被问到了一道非常搞心态的场景题“业务方有个拥有 5 万个敏感词的词库现在用户发了一篇 3000 字的长文评论要求你的审核接口必须在 10 毫秒内返回结果并且词库还要支持随时动态更新你会怎么设计”小伙伴平时在公司只用过现成的框架随口答了一句“把敏感词放在 List 里用双重 for 循环去挨个匹配或者拼个长长的正则表达式。”面试官听完摇摇头结果面试直接挂了。结合大厂常见的线上事故来看这其实是一个极其经典的“海量字符串匹配与高并发对抗”问题而且附带了严苛的性能条件10毫秒极速响应一、 理解题目从暴力匹配的灾难说起我们先来分析一下问题本身为什么小伙伴的回答会直接挂掉如果单纯用List.contains或者双重 for 循环去挨个匹配会发生什么我们简单算一笔账50,000 个敏感词 × 3,000 个字符 1.5 亿次循环匹配。如果在晚间流量高峰期每秒有成千上万个用户同时发评论服务器的 CPU 绝对会瞬间飙升到 100%整个服务当场卡死。那用正则表达式呢把几万个词拼成一个超长的正则去跑更惨。正则引擎在处理复杂的字符串和通配符时很容易被黑灰产故意构造的特殊乱码触发“灾难性回溯”直接导致栈溢出StackOverflow把系统彻底打挂。所以这道题的本质是在极其严苛的时间限制下如何彻底摆脱词库大小带来的性能拖累并实现海量文本的高效过滤解决方案其实有几种但在工业级的内容安全审核中最主流、最能扛住千万级并发的方案是DFA 算法配合 Trie 树。二、 解决方案用 DFA 的精妙之处化繁为简1. 什么是 DFA 算法与 Trie 树DFA确定有限自动机听起来很高大上但它在敏感词过滤里的本质就是构建一棵Trie 树字典树。通俗点说Trie 树就像是一本超级高效的“按拼音查字法”新华字典。假设我们的敏感词库里有“赌博”、“赌局”这两个词。传统方法是存两个完整的字符串而在 Trie 树里内存中会构建一个树状结构根节点往下找有一个“赌”字节点。“赌”字往下分出两条岔路一条是“博”一条是“局”。在这两个结尾字上打上一个结束标记End。它最大的优势在于空间换时间。无论你的敏感词库扩大到 5 万个还是 50 万个匹配的时间复杂度彻底和敏感词的总数量脱钩了它只与文章的长度 N相关也就是 O(N)的时间复杂度。2. 如何搞定高并发下的敏感词过滤回到我们的问题5 万个词库3000 字长文如何用这套方案做到 10 毫秒内返回并且不卡顿在真实的生产环境中我们需要跑通以下三个步骤第一关前置清洗与归一化防绕过黑产是不会乖乖打出标准违规词的他们会夹带符号如“赌**博”、用拼音或繁体字。所以在进入字典树之前必须先过一条清洗流水线把所有表情包、无用标点剔除把繁体转成简体英文字母全转小写。把千奇百怪的非法输入统统“扒掉马甲”还原成标准形态。第二关顺藤摸瓜的 Trie 树遍历拿着清洗干净的 3000 字逐个字符在预先构建好的 Trie 树里往下走。只要顺着树枝走到了带有“End”标记的节点立马判定违规并拦截。这三千个字跑完一遍字典树耗时通常只需 1 到 2 毫秒。第三关双缓冲机制防阻塞热更新词库是需要随时加新词的直接修改运行中的字典树必须加锁一加锁接口就卡死了。怎么解决用双指针内存里永远保留着“老树”继续无锁处理海量并发请求后台悄悄起个异步线程构建一棵包含新词的“新树”。建好之后直接把指针原子性地切到新树上老树随后被垃圾回收。全程零卡顿用户无感知。3. 这套方案的优缺点优点极致的查询速度时间复杂度 O(N)不随敏感词数量增加而变慢配合双缓冲机制可以随时封禁突发热点词汇而不影响业务吞吐量。缺点内存消耗稍大比直接存字符串需要占用更多的堆内存高度依赖预处理如果不加上前置的清洗流水线很容易被变形词绕过。三、 面试满分答题模板直接背诵下次再去面试被问到“海量敏感词过滤”或“高并发内容审核”不要再提 for 循环了直接按这个套路输出“对于千万级流量的内容审核简单的遍历或正则表达式会导致极其严重的 CPU 飙升。结合大厂常见的线上真实场景我的设计思路是‘前置清洗防绕过DFA 算法提速双缓冲无锁更新’架构选型核心过滤引擎采用基于 DFA 算法构建的 Trie 树字典树用空间换时间将匹配的时间复杂度降维到 O(N)确保接口在几毫秒内极速响应。对抗策略在进入 Trie 树匹配前建立一条严格的预处理清洗流水线过滤掉无关的特殊符号并完成繁转简、拼音转换防止黑灰产通过变形词绕过审核。高可用保障为了应对运营频繁的热更新需求我会引入 CopyOnWrite 的双缓冲机制。前端读请求全部走无锁的老树后台异步线程默默构建新树完成后通过原子引用瞬间切换依靠 GC 回收老树实现真正的无感热更新。”写在最后技术面试不仅考你会不会调现成的框架更考你“对时间复杂度的敬畏”以及“对生产环境并发边界的把控”。能用空间换时间的绝不让 CPU 白白空转能做到无锁热更新的绝不阻塞哪怕一个真实用户的请求。这套清洗归一化 DFA 字典树 双缓冲热更新的组合拳不仅能解决敏感词过滤像海量 URL 黑名单拦截、路由规则快速匹配等场景通通都能直接照搬
返回列表