Skip to content

IX · 综合场景题(系统设计 + 场景设计 + 线上排障) ​

高级岗区分度最高的一类题:没有标准答案,考的是提问能力、权衡意识、把模糊问题拆清楚的能力。

📌 本页合并一页四章:① 前端专项场景设计(主战场)· ② 通用系统设计 · ③ AI 应用设计 · ④ 线上排障实战。 每道题统一结构:需求澄清 → 方案骨架 → 关键权衡 → 面试官追问。


零、先记住这个回答框架(适用于所有场景题) ​

① 澄清需求(最重要,别一上来就画图)
   用户量级?读写比?延迟要求?一致性要求?要不要实时?数据量多大?团队规模?
② 估算规模(量级对就行,不用精确)
   QPS、日活、存储量、带宽 → 决定"要不要上分布式/缓存/队列"
③ 定接口与数据模型
   先写 API 和数据表,架构自然浮现
④ 画架构骨架(分层 + 关键组件)
⑤ 讲关键设计(数据怎么流、状态放哪、失败怎么办)
⑥ 找瓶颈与权衡(主动说"这里我会怎么选,代价是什么")
⑦ 主动提风险与演进(监控、灰度、回滚、下一步)

⚠️ 面试里最容易扣分的行为:题一出来就开始堆组件(Redis、MQ、K8s 全上)。 面试官要的是"你为什么需要这个组件",不是组件清单。

估算速记(背下来,现场直接用):

量数值
1 天 = 86400 秒 ≈ 8.6 万秒1 QPS ≈ 日均 8.6 万请求
峰值 QPS ≈ 均值 × 2~5秒杀场景可达 100 倍
单机 MySQL 写 ≈ 千级 QPS读 + 缓存可上万
单台 Redis ≈ 10 万 QPS受 key 大小与命令影响
一条文本记录 ≈ 1 KB1000 万条 ≈ 10 GB

一、前端专项场景设计(高级前端主战场) ​

1.1 设计一个前端监控 SDK ​

澄清:要采集什么(错误/性能/行为/白屏)?接入方式(npm / CDN 脚本)?采样率?要不要上报用户标识(合规)?

方案骨架:

采集层                  处理层               上报层
├─ JS 错误  window.onerror / unhandledrejection
├─ 资源错误 capture 阶段监听 error(资源错误不冒泡)
├─ 接口异常 劫持 fetch / XMLHttpRequest
├─ 性能     PerformanceObserver(LCP/INP/CLS、longtask、navigation)
├─ 白屏     采样关键点 + MutationObserver / elementsFromPoint
├─ 行为     click / route change(可选,注意脱敏)
└─ 自定义   report(type, payload)
      ↓ 统一格式 + 采样 + 去重(同错误 N 次只报一次)
      ↓ 队列缓冲、批量上报
  发送:navigator.sendBeacon(页面卸载也能发)→ 失败降级 img / fetch keepalive

关键权衡:

点权衡
上报时机立即(实时但请求多)vs 批量 + 定时 + 阈值触发(推荐)
上报方式sendBeacon 可靠但无响应、体积受限;fetch keepalive 有 64KB 限制
采样全量太贵 → 按用户/会话采样,错误必须全量、性能可采样
采集成本SDK 自身不能成为性能杀手:异步、不阻塞、不用同步 XHR
数据脱敏不采 URL query 里的敏感参数、不采 input 值(合规红线)
Source Map不上传生产 map 到 CDN,走内部平台反解

追问:

  • "SDK 怎么保证不影响宿主?" → 独立错误域、try/catch 包住所有采集、不污染全局(1 个命名空间)、passive 监听。
  • "页面卸载时数据丢了怎么办?" → visibilitychange → hidden 时立即 flush + sendBeacon。
  • "怎么定位线上报错到具体代码行?" → Source Map 反解,构建产物带 release 版本号。

1.2 设计一个埋点 SDK(无侵入 + 不丢数据) ​

澄清:全埋点还是代码埋点?要不要可视化圈选?数据实时性?

方案:

方案原理代价
代码埋点手动调 track()准但侵入、漏埋
声明式埋点data-track 属性 + 全局委托推荐,解耦业务
全埋点(无埋点)全局委托 click + 路径 XPath数据量大、脏、难维护
可视化圈选注入 iframe 圈选 → 生成配置运营友好,配置易失效

三个硬指标:

  1. 不丢:缓冲队列 + localStorage 兜底 + 失败重传 + 卸载前 flush。
  2. 不阻塞:requestIdleCallback 发送、批量合并、单条 ≤ 阈值,禁止同步请求。
  3. 可关联:统一 sessionId、pageId、事件时序序号,服务端才能还原路径。

追问:"埋点数据暴涨把服务打挂了?" → 客户端采样 + 限流(令牌桶)+ 服务端降级丢弃 + 聚合上报。


1.3 设计一个表单引擎 / 低代码搭建平台 ​

澄清:面向谁(运营还是研发)?要不要复杂联动?出码还是运行时渲染?

方案骨架:核心是 Schema 驱动 + 三层解耦。

Schema(JSON 描述)  →  渲染引擎          →  运行时能力
├─ fields: 字段类型/校验/默认值             ├─ 表单状态(值/错误/touched)
├─ rules: 校验与联动(表达式 or 函数)      ├─ 联动求值(依赖图 → 拓扑排序,避免循环)
├─ layout: 布局与容器                       ├─ 校验(同步 + 异步 + 去抖)
└─ actions: 提交/重置/自定义                └─ 数据源绑定(远程 options、字典)

关键权衡:

决策点选择
Schema 校验JSON Schema 通用但表达力弱;自定义 DSL 强但要自己写解析器
联动实现表达式(安全、可序列化、可存库)vs 函数(强但不可存、不安全)→ 推荐表达式
渲染性能大表单 → 字段级订阅(Signals/细粒度响应式),避免整表重渲染
扩展点提供自定义字段注册机制,否则必然被业务逼着改内核
出码 vs 运行时出码性能好、可二次开发;运行时灵活、迭代快 → 内部系统优先运行时

追问:

  • "1000 个字段的表单卡了怎么办?" → 字段级订阅 + 虚拟滚动 + 分区懒渲染 + 校验去抖。
  • "两个字段互相联动成环了?" → 依赖图检测环,报错并中断;或限制"只允许单向数据流"。
  • "为什么不做成银弹?" → 低代码的天花板在长尾个性化需求,必须留逃生舱(自定义组件 + 出码)。

1.4 长列表 / 虚拟滚动 ​

澄清:定高还是不定高?要不要滚动到底部加载?

  • 定高:startIndex = floor(scrollTop / itemHeight),容器总高 count × itemHeight,用 transform: translateY 偏移。O(1)。
  • 不定高:先给估算高度 → 渲染后测量真实高度 → 更新前缀和(累计偏移)→ 校正滚动位置。
  • 关键细节:overscan 上下多渲染几屏防白屏;content-visibility: auto 可作为低配方案;别用 key=index。

追问:"快速滚动出现闪烁?" → 增大 overscan、contain: strict、避免在滚动回调里同步测量(放 ResizeObserver)。


1.5 大文件分片上传(断点续传 / 秒传) ​

① 计算文件指纹:抽样 + 全量哈希(大文件用 Web Worker 或 抽样 md5,避免卡死主线程)
② 分片:固定大小(5~10MB),并发上传(并发池控制 3~5)
③ 秒传:上传前用指纹问服务端"是否已存在" → 存在直接返回成功
④ 断点续传:上传前问"已有哪些分片" → 只传缺的
⑤ 失败重试:单分片重试 + 指数退避,不重传整个文件
⑥ 合并:全部分片到位后服务端合并

追问:"刷新页面怎么续传?" → 指纹与已传分片记录存 localStorage/服务端;"网络很差怎么办?" → 分片更小 + 并发更低 + 断点续传。


1.6 微前端:老系统怎么渐进迁移 ​

澄清:老系统技术栈?能不能改老代码?要不要隔离样式/JS?

方案适用
路由分发(Nginx/网关按路径转发)最简单,体验割裂(整页刷新)
iframe隔离最强,但路由/通信/弹窗/样式都是坑
single-spa / qiankun主流:HTML Entry + JS 沙箱 + 样式隔离
Module Federation(Webpack 5 / Vite)共享依赖、去中心化,构建期耦合
Web Components原生隔离,但生态与 SSR 弱

方案骨架(以 qiankun 为例):主应用注册子应用(路由匹配 → 加载 HTML Entry → 沙箱中执行 → 挂载到容器)。

五个必答的坑:

  1. JS 沙箱:Proxy 快照沙箱隔离 window;但 document.body 的副作用(全局弹窗/路由)隔离不了。
  2. 样式隔离:Shadow DOM(强但影响弹窗与第三方库)vs CSS Module / BEM 前缀 + 卸载时移除 style(推荐)。
  3. 共享依赖:React/Vue 多实例 → 用 Module Federation 或 externals 共享,否则 hooks 报错。
  4. 通信:优先 URL/Props,复杂用 EventBus 或全局 store(别把共享状态当数据库用)。
  5. 路由同步:子应用路由要跟随主应用 history,注意 base 与 404 fallback。

追问:"什么时候不该上微前端?" → 团队/系统没到"多团队独立交付"的规模就不该上,否则只是把复杂度从代码搬到基础设施。


1.7 前端权限体系(页面级 + 按钮级) ​

权限模型:RBAC(用户 → 角色 → 权限点)
        ↓
后端返回权限点列表(或前端按角色映射)
        ↓
路由层:动态路由过滤 / 路由守卫(无权限 → 403)
按钮层:<Auth code="order:delete"> 组件包裹 或 v-permission 指令
接口层:兜底——前端权限只是体验,真正的校验必须在服务端

关键:前端权限只是"看不见",不是"拿不到"——所有敏感操作必须服务端二次校验。 追问:"权限变更了要重新登录吗?" → 提供刷新权限的接口,避免强制登出。


1.8 协同编辑 / 在线文档(OT vs CRDT) ​

OT(Operational Transformation)CRDT
原理操作在服务端变换后合并数据结构本身保证可交换合并
服务端必须有中心服务器可去中心化
离线弱强
复杂度变换规则爆炸、难实现库成熟(Yjs/Automerge)但体积与内存开销大
选谁老牌方案(Google Docs)新项目首选 Yjs

前端还需处理:光标同步(Awareness)、本地乐观更新、断线重连、历史与版本。


1.9 设计一个前端缓存体系 ​

分层回答,从近到远:

① 内存缓存(Map / TanStack Query 的 queryClient)  ← 会话内复用,刷新即失效
② 本地持久化(localStorage / IndexedDB)            ← 秒开、离线可用;注意容量与版本迁移
③ HTTP 缓存(强缓存 / 协商缓存)                     ← HTML no-cache + 带 hash 资源永久缓存
④ CDN 缓存                                          ← 静态资源与可缓存接口
⑤ 服务端缓存(Redis)                               ← 热点数据

关键:每层都要回答"什么时候失效"。缓存的难点从来不是存,是失效策略。


二、通用系统设计(前端也常被问,考的是架构常识) ​

目标不是"设计得像后端",而是能跟后端对等对话、能说出瓶颈在哪。 每题统一给:核心矛盾 → 方案 → 追问。

2.1 短链服务 ​

核心矛盾:ID 生成 + 高并发读。

  • 生成:发号器(Snowflake / 号段)→ 转 62 进制。别用哈希(冲突与长度不可控)。
  • 存储:shortCode → longUrl,读多写少 → 缓存热点短链(LRU + TTL)。
  • 跳转:301(永久,浏览器缓存,省一次请求,但要统计就别用)vs 302(临时,可统计 —— 业务上一般用 302)。
  • 追问:如何防滥用(限流 + 黑名单 + 过期);如何支持自定义短码(单独命名空间 + 冲突检测)。

2.2 限流 ​

算法特点适用
固定窗口简单,临界突刺(窗口交界可翻倍)粗粒度
滑动窗口平滑,内存略高通用
令牌桶允许突发(桶内有令牌),控制平均速率最常用
漏桶恒定速率出,平滑但不允许突发保护下游

关键:单机限流 vs 分布式限流(Redis + Lua 保证原子性);返回 429 + Retry-After;网关层做粗粒度,服务层做细粒度。

2.3 秒杀 / 库存扣减 ​

核心矛盾:超卖 + 高并发写。

① 拦截:前端按钮防重 + 网关限流 + 验证码/答题削峰
② 库存预热到 Redis;扣减用 Lua 脚本保证"读-判-减"原子性
③ 扣减成功 → 发 MQ → 异步落库创建订单(削峰填谷)
④ 前端轮询/长轮询查结果,别让用户一直等
⑤ 兜底:库存对账 + 超时未支付自动回滚

追问:"Redis 挂了怎么办?" → 降级到数据库悲观锁(性能下降但不超卖);"怎么防止一个人下多单?" → 用户维度限购(Redis Set + TTL)。

2.4 Feed 流(关注流) ​

  • 推(写扩散):发内容时写到每个粉丝的收件箱。读快,大 V 发一条要写百万次 → 粉丝多时改用拉,或推拉结合。
  • 拉(读扩散):读时聚合所有关注者的内容。写快,读慢。
  • 工程做法:推拉结合(普通用户推、大 V 拉)+ 收件箱只存 ID + 异步扇出。
  • 追问:分页用**游标(cursor)**而非 offset,否则插入新内容会重复/漏。

2.5 缓存一致性 ​

模式做法问题
Cache Aside(推荐)读:命中返,未命中读库回填;写:先更新 DB,再删缓存极小概率脏读
先删缓存再更新 DB❌并发下必脏(读请求把旧值回填)
先更新 DB 再更新缓存不推荐写多时白白更新;并发写可能乱序

为什么是"删缓存"而不是"更新缓存":删除是幂等的,且避免"计算成本高但没人读"的浪费。

三大问题:

问题现象解法
缓存穿透查不存在的 key,全打库布隆过滤器 / 缓存空值(短 TTL)
缓存击穿热点 key 过期瞬间大量打库互斥锁重建 / 逻辑过期(永不过期,异步刷新)
缓存雪崩大量 key 同时过期TTL 加随机抖动 / 多级缓存 / 熔断降级

2.6 分布式 ID 与幂等 ​

  • ID:UUID(无序、索引碎片)vs Snowflake(趋势递增、依赖时钟,时钟回拨要处理)vs 号段(DB 批量取)。
  • 幂等:唯一索引 / 幂等表(requestId 去重)/ 状态机(已支付不重复扣)/ Token 机制。 → 前端对应:提交按钮防重 + 请求带幂等键(这是前端必答的那半句)。

三、AI 应用设计(AI 方向必考) ​

3.1 设计一个企业知识库问答(RAG) ​

见 IG · AI 面试题 与 GP02 RAG 实战。 要点复述:切分 → 向量化 → 混合召回 → 重排 → 带引用生成 → 评测回归。 面试官追问:文档更新了怎么增量同步?权限怎么隔离(不同人看到不同文档)?答不出来就答"不知道"怎么保证?

3.2 设计一个客服 / 智能助手 ​

  • 边界:先定"什么不归 AI 管"(退款、投诉、法务)→ 置信度低或命中敏感词直接转人工。
  • 架构:意图识别(或小模型路由)→ 工具调用(查订单/查物流)→ 生成 → 安全过滤 → 人工兜底。
  • 指标:解决率、转人工率、首响时长、满意度、幻觉率。

3.3 设计一个 AI 代码助手(前端最贴身的一题) ​

  • 上下文是核心:仓库索引(AST/符号表)→ 检索相关文件 → 拼进 prompt。上下文给不够,模型再强也白搭。
  • 分层:补全(低延迟,小模型/本地)→ 单文件修改(Chat)→ 跨文件重构(Agent,需计划 + 工具)。
  • 可信度:必须能 diff 预览、必须跑测试/CI、必须限制"凭空引入不存在的依赖包"。
  • 度量:别用代码行数,用"任务完成率 / PR 合并时长 / 返工率"。

四、线上排障实战("你遇到过最难的问题"的标准答法) ​

统一用这个结构讲,比"我改了个 bug 就好了"高一个段位:

现象(可量化) → 影响面 → 定位过程(怎么缩小范围的) → 根因 → 解法 → 预防(如何不再发生)
场景定位路径常见根因
线上白屏看监控的 JS 错误 → 是否集中在某个版本/浏览器 → 是否发布后突增发布兼容性、chunk 加载失败(先传资源后切 HTML 顺序错)、路由 404、SDK 报错打断渲染
页面越来越卡(内存泄漏)Memory 面板拍堆快照对比 → 看 retainers未移除的事件监听、未清理的定时器、全局缓存只增不减、被闭包捕获的 DOM、第三方 SDK
INP 突刺 / 交互卡顿Performance 找 long task → 看是脚本还是布局大列表全量渲染、同步布局抖动(读写交替)、主线程做重计算(应挪 Worker 或分片)
CLS 高看哪个元素偏移图片/广告未预留尺寸、字体切换(FOUT)、异步插入内容在首屏上方
接口大面积超时前端看错误码分布 → 是全局还是单接口 → 看地域/运营商服务端/网关问题、DNS、证书过期、CDN 节点故障、前端并发打满连接池
构建产物突然暴涨产物分析工具看依赖树误引入全量包(lodash/moment)、重复打包同一库多个版本、sourceMap 进产物、无 sideEffects 导致 tree shaking 失效
某浏览器才复现按 UA 聚合 → 看是 API 还是 CSS未配置 browserslist、用了过新 API 无 polyfill、Safari 的 100vh/日期解析差异

加分项:主动说"我做了什么让它不再发生"——监控告警、CI 卡口(产物体积阈值/依赖审计)、灰度与快速回滚、沉淀成踩坑文档。


自检清单 ​

  • [ ] 面对任何场景题,能先问出 5 个澄清问题再动笔
  • [ ] 能做量级估算(QPS / 存储 / 带宽),并据此判断"要不要上分布式"
  • [ ] 前端场景:监控 SDK、埋点 SDK、表单引擎、虚拟滚动、分片上传、微前端、权限、协同编辑、缓存体系 —— 至少 4 个能独立讲 10 分钟
  • [ ] 通用设计:短链、限流、秒杀、Feed、缓存一致性、幂等 —— 每个能说清核心矛盾与 2 个追问
  • [ ] 能说出"缓存三大问题"的现象与对应解法
  • [ ] AI 场景能说出 RAG 全链路与"权限隔离/增量更新"这类真实工程问题
  • [ ] 排障题能用"现象→影响→定位→根因→解法→预防"六段式讲,并给出预防措施

相关文档 ​