acongm
简历问答

知识点索引

  • 使用方式(建议背法):
  • 1)先背每个点的“一句话结论”(10 秒);
  • 2)再背“我怎么做的”(40 秒);
  • 3)最后准备“追问扩展”(90 秒:坑/取舍/验证口径)。
  • 代码示例:见 ASK_CODE_EXAMPLES

大疆用户中心重构(2022.02-2022.9)

1)骨架屏

  • 一句话结论:骨架屏解决的是“首屏白屏感知”,重点是让 LCP 更早出现、并避免 CLS。
  • 解决什么问题:首屏渲染链路长(资源下载/解析/渲染),用户看到白屏会认为卡死;同时“突然插入内容”会造成 CLS。
  • 怎么做(可讲步骤):
    • 1)确定骨架覆盖范围:只覆盖首屏关键区域(如登录框/主视觉/按钮),不做全页面。
    • 2)骨架的渲染方式: - SSR/预渲染注入骨架(理想:HTML 里直接有骨架); - 或者构建阶段生成骨架 HTML/CSS(CI 产物),运行时直接插入; - 不建议:纯 JS 等框架启动后再画骨架(会晚)。
    • 3)避免 CLS:骨架与真实内容保持相同占位(宽高/行高/边距),图片/字体提前占位。
    • 4)骨架退场:业务首屏内容 ready 后立即移除;避免骨架动画太重抢主线程。
  • 怎么验证:
    • 线上 RUM:看 LCP、CLS、INP 的变化;
    • 人工验证:慢网(Fast 3G)+ 冷启动对比“白屏时长”。
  • 常见坑:骨架 CSS 过大反而拖慢首屏;骨架和真实内容尺寸不一致导致 CLS;骨架动画过多造成长任务。
  • 面试追问怎么接:
    • “骨架屏和占位图/渐进渲染区别?”→ 骨架强调结构与布局稳定,核心指标是 LCP/CLS。

2)core-js / polyfill 策略

  • 一句话结论:core-js 优化不是“删”,而是“按兼容矩阵按需注入”,避免过度兼容把包打大。
  • 解决什么问题:老项目容易全量引 polyfill,导致首屏包变大、解析/执行变慢。
  • 怎么做:
    • 1)先定兼容矩阵:browserslist 固定目标浏览器范围(别默认全兼容)。
    • 2)Babel 按需:useBuiltIns: 'usage' + 合理的 core-js 版本;避免手动全量 import。
    • 3)治理入口:从依赖树定位“是谁引入了过多 polyfill”(产物 diff / bundle analyzer)。
    • 4)防回退:把兼容矩阵与构建策略写进工程规范,避免某次引库又把 polyfill 拉爆。
  • 怎么验证:构建产物体积 diff + 首屏解析时间(Performance)+ 线上 RUM(LCP/TTFB 拆分)。
  • 常见坑:browserslist 漂移;polyfill 重复注入;某些库带来隐式 polyfill;升级 core-js 版本不一致导致重复。

3)字体压缩(体积治理 + 稳定显示)

  • 一句话结论:字体优化核心是“woff2 + 子集化 + 合理加载”,在不牺牲可读性的前提下降体积并减少 FOIT。
  • 解决什么问题:字体是大资源,阻塞渲染/拖慢 LCP;字体闪烁/不显示影响体验。
  • 怎么做:
    • 1)格式:优先 woff2。
    • 2)子集化:只保留需要的字符集(尤其是中英文混排、数字/符号)。
    • 3)加载策略: - 关键字体可 preload as=font crossorigin; - font-display: swap 避免 FOIT。
    • 4)缓存:CDN 强缓存 + contenthash。
  • 怎么验证:Network 看字体请求耗时/阻塞;LCP 改善;观察 FOIT/FOUT。
  • 常见坑:字体子集缺字导致方块字;跨域缺少 crossorigin 导致字体 preload 失效;字体太多 preload 抢带宽。

4)优化打包 CSS

  • 一句话结论:CSS 优化目标是“减少阻塞、减少体积、减少无效样式”,同时避免 Tree Shaking 误伤。
  • 解决什么问题:CSS 阻塞首屏渲染;样式冗余导致体积大;错误的 Tree Shaking 可能导致样式丢失。
  • 怎么做:
    • 1)压缩:生产环境 CSS 压缩、去重。
    • 2)提取:抽离 CSS 到独立文件(避免运行时注入造成抖动)。
    • 3)按需:路由级拆分 CSS,首屏只加载首屏所需。
    • 4)Tree Shaking:明确 sideEffects 保留 *.css/*.scss(示例见代码文件)。
  • 怎么验证:首屏 CSS 下载/解析时间;LCP 与 CLS;回归测试页面样式。
  • 常见坑:把 sideEffects 一刀切 false 导致样式被摇掉;过度拆分导致请求数爆炸;关键 CSS 提取不当导致样式闪烁。

5)JS 加载顺序(defer/async + 执行控制)

  • 一句话结论:入口页脚本治理要同时管“加载(defer/async/import)”和“执行(async/await/并发/降级)”。
  • 解决什么问题:阻塞 HTML 解析、执行顺序乱、长任务卡交互;三方脚本不确定性拖垮首屏。
  • 怎么做:
    • 1)加载策略: - 业务主包 defer(不阻塞解析 + 顺序可控); - 三方脚本尽量延后,必须并行加载用 async(不保序)+ timeout/fallback; - 非首屏功能动态 import()
    • 2)执行策略: - 关键链路用 async/await 显式化顺序; - 可并行的用 Promise.all/Promise.allSettled; - 对三方初始化加超时与降级路径。
    • 3)主线程:重计算用 Worker;非关键逻辑 idle/延时。
  • 怎么验证:Performance Long Task、INP;线上错误率/三方失败率;RUM 指标波动。
  • 常见坑:乱用 async 造成依赖顺序问题;三方 SDK 执行时机不稳定;降级没做好导致“半初始化”。

6)TLS 1.3 + HTTP/2.0(分别解决什么)

  • 一句话结论:HTTP/2 解决的是“多资源并发效率”,TLS 1.3 解决的是“握手 RTT”;它们主要降低首屏的“白等时间”。
  • 解决什么问题:入口页资源多,小资源并发时 HTTP/1.1 连接开销大;TLS 握手轮次多导致等待。
  • 怎么讲清楚(面试最爱问):
    • HTTP/2:单连接多路复用,减少多连接建立成本;资源多时更稳定。
    • TLS 1.3:握手轮次更少(1-RTT,恢复可到 0-RTT),减少 TLS 握手等待。
    • 连接复用/会话恢复:减少重复握手和慢启动。
  • 怎么验证:Network 里看 connection/TLS 时间;看首屏关键资源的排队等待;RUM 的 LCP/TTFB 拆分。
  • 常见坑:H2 并不等于一定更快(弱网丢包、服务端/代理不一致会影响);TLS 1.3 需要端到端链路支持。

7)gzip 压缩怎么处理的

  • 一句话结论:压缩解决的是“传输体积”,要点是“服务端/网关开启 + 类型覆盖 + 与缓存策略配套”。
  • 解决什么问题:JS/CSS/JSON 体积大,下载慢,尤其弱网更明显。
  • 怎么做:
    • 1)服务端/网关开启 gzip(或 brotli),覆盖 text/*application/javascriptapplication/json 等。
    • 2)配套缓存:CDN 强缓存 + contenthash,避免重复下载。
    • 3)避免重复压缩:CDN/源站分工清晰。
  • 怎么验证:Response Headers(content-encoding: gzip/br),传输 size 明显下降;RUM 看 LCP 改善。
  • 常见坑:只压 JS 不压 JSON;压缩级别过高导致 CPU 负担;代理层把压缩去掉。

8)WebP 图片格式 / 兜底策略

  • 一句话结论:WebP 解决的是“图片体积”,兜底策略解决的是“兼容可用性风险”。
  • 解决什么问题:图片是体积大户;部分 WebView/老浏览器不支持 WebP。
  • 怎么做:
    • 1)前端兜底:<picture>/<srcset> 优先 WebP,自动 fallback。
    • 2)构建产双份:webp + jpg/png,路径与缓存 key 稳定。
    • 3)能力探测:必要时对特殊 WebView 探测并缓存结果;服务端可基于 Accept 内容协商。
    • 4)监控回滚:看图片失败率 + LCP 波动 + 错误日志。
  • 常见坑:只替换格式没做兜底导致关键图片缺失;CDN 缓存策略不一致导致命中差;把 WebP 用在本来就很小的图上收益不大。

大疆售后 RMS 系统重构(2022.10-2024.04)

1)ESLint 规范制定

  • 一句话结论:复杂系统里,ESLint 不是“风格”,而是把 bug 类型问题工具化卡住,靠流水线守质量。
  • 解决什么问题:变量遮蔽、未处理 Promise、any 泛滥、import 混乱、hooks 误用、模块边界失守。
  • 怎么做:
    • 1)规则分级:必须 error / 建议 warn / 暂缓(保证落地可推进)。
    • 2)工程集成:lint-staged(提交前自动修)+ CI(强制卡点)+ MR 规范。
    • 3)渐进治理:先卡新增/修改,存量按目录逐步收紧。
  • 怎么验证:CI 告警趋势、线上 bug 类型分布变化、Review 争议减少。
  • 常见坑:一刀切全量报错导致推进失败;Prettier/ESLint 打架;规则太多但没有“分级与节奏”。

2)业务组件高可用

  • 一句话结论:高可用组件 = 边界一致(loading/empty/error)+ 契约稳定(类型/Props)+ 可观测可止损(上报/降级)。
  • 解决什么问题:页面多、权限多导致边界条件爆炸;copy 组件带来维护地狱。
  • 怎么做:
    • 1)统一边界三件套:loading/empty/error;关键区域 Error Boundary 隔离。
    • 2)契约化:Props 分层、默认值明确、TypeScript 类型收口,避免 any 扩散。
    • 3)可观测:关键失败上报;开关降级。
    • 4)物料化:把配置项/默认值/校验/事件整理成物料描述,为低代码接入铺路。
  • 怎么验证:复用覆盖率、缺陷率、线上错误聚合是否下降。

3)Code Review 机制

  • 一句话结论:Review 的目标不是挑格式,而是“风险前移 + 知识同步 + 质量一致”。
  • 解决什么问题:多人协作下质量波动、边界被破坏、隐性 bug 漏出。
  • 怎么做(可讲制度设计):
    • 1)明确检查清单:逻辑正确性、边界条件、性能风险、可观测性、回滚方案。
    • 2)分层审核:关键模块/公共组件必须资深同学过;普通需求走快速通道。
    • 3)工具化:CI 先过滤掉格式/规则问题,让 Review 聚焦“设计与风险”。
  • 怎么验证:线上事故下降、返工率下降、核心模块代码一致性提升。

4)低代码平台落地

  • 一句话结论:低代码落地的关键不是编辑器,而是“物料标准化 + schema 版本化 + 安全与边界”。
  • 解决什么问题:表单/配置页重复劳动;规则变化频繁导致开发与回归成本高。
  • 怎么做:
    • 1)选场景:先试点“结构稳定、收益可控”的页面。
    • 2)物料体系:组件 = 配置 schema + 默认值 + 校验 + 事件定义。
    • 3)运行态:递归渲染 + 表达式解析 + 事件分发;联动要收敛(依赖图/事件总线)。
    • 4)治理:schema 版本化 + migration;表达式白名单 + 权限裁剪。
    • 5)性能:虚拟滚动/按需渲染;编辑器与运行态拆包。
  • 怎么验证:页面交付效率、返工率、线上稳定性、物料复用率。

5)React 18 特性(面试常问)

  • 一句话结论:React 18 重点是“并发渲染能力 + 更平滑的用户体验”,但要配合场景使用。
  • 你可以重点讲的点(建议 3 选 2):
    • 1)createRoot 与并发渲染基础。
    • 2)startTransition:把“非紧急更新”标成 transition,避免输入/点击被大渲染卡住。
    • 3)useDeferredValue:延迟昂贵渲染,提升交互。
    • 4)自动批处理:减少重复渲染。
  • 常见坑:把所有更新都 transition 导致 UI 延迟;并发下某些副作用写法需要更严谨。

6)Umi 框架特点

  • 一句话结论:Umi 更像“企业级应用框架”,核心价值是路由/构建/约定式组织与插件生态,适合大型中后台。
  • 你可以讲的点:
    • 1)约定式路由与目录组织,降低工程组织成本。
    • 2)插件机制:权限、布局、请求、微前端能力等更易标准化。
    • 3)工程整合:构建链路、环境变量、代理、部署配置更统一。
  • 常见坑:约定过强导致灵活度下降;插件过多导致黑盒;需要团队对约定有统一认知。

跨平台公告插件系统(2023.02-2023.03)

1)Rollup 打包

  • 一句话结论:SDK/库场景更看重“产物体积 + Tree Shaking”,Rollup 更聚焦也更好控。
  • 解决什么问题:SDK 要极小体积、输出多格式(UMD/ESM),并尽量让宿主按需加载。
  • 怎么做:
    • 1)以 ESM 作为源码与输出主路径,利于 Tree Shaking。
    • 2)输出格式:UMD(老系统/CDN)+ ESM(现代工程)。
    • 3)压缩:terser;并分析 bundle 组成保证 <15KB。
  • 常见坑:依赖没标 external 导致重复打包;cjs/esm 混用导致摇树失败。

2)Preact 信号机制(signals)

  • 一句话结论:signals 让更新变成“细粒度响应”,减少不必要的重渲染,适合小型高频 UI。
  • 解决什么问题:SDK UI 很轻但要快,避免因为状态变化导致整棵树重渲染。
  • 怎么讲:
    • 用 signals 做局部状态更新,组件订阅依赖自动追踪;相比 setState 更细。
  • 常见坑:信号与外部状态/事件源同步要设计清楚;别把所有状态都信号化导致复杂度上升。

3)热插拔架构(init/destroy)

  • 一句话结论:热插拔的核心是“生命周期可控 + 资源可回收 + 不污染宿主”。
  • 解决什么问题:SDK 要能随时加载/卸载,避免宿主页面残留事件监听/定时器/样式。
  • 怎么做:
    • 1)API 设计:init(options) 返回实例;destroy() 释放资源。
    • 2)统一注册/销毁:事件监听、定时器、observer、DOM 容器。
    • 3)隔离:样式命名空间/Shadow DOM(可选);错误隔离(try/catch + 上报)。
  • 常见坑:destroy 不彻底导致内存泄漏;样式冲突;重复 init。

4)多模式植入怎么实现

  • 一句话结论:多模式植入是“把接入成本降到最低”,用 UMD/ESM/Web Component 覆盖不同宿主。
  • 解决什么问题:宿主系统技术栈不统一,有的老系统改不了构建链路。
  • 怎么做:
    • 1)CDN/UMD:script 一行接入,最快。
    • 2)ESM/NPM:现代工程按需引入,利于 Tree Shaking。
    • 3)Web Component:框架无关;必要时 iframe 做强隔离兜底。
  • 常见坑:跨域资源与 CSP;样式隔离不到位;iframe 通信成本。

devOps 平台维护

1)Docker 流水线自动化部署

  • 一句话结论:把“高风险重复劳动”变成流水线能力:可追溯、可回滚、可审计。
  • 解决什么问题:手工部署易错;多环境配置漂移;出问题难定位。
  • 怎么做:
    • 1)镜像一致性:统一 Dockerfile/基础镜像;版本 tag 用 commit sha/语义化。
    • 2)流水线阶段:build/test → build image → scan → deploy → verify。
    • 3)配置治理:密钥与配置分离,按环境注入。
    • 4)发布回滚:灰度/回滚;健康检查与告警。
  • 常见坑:镜像里写死配置;没有 verify 阶段导致“部署成功但服务不可用”。

2)Kubernetes 基础设施维护(基础题库)

  • 一句话结论:K8s 关注“声明式部署 + 弹性伸缩 + 自愈”,你要能说清资源对象与发布策略。
  • 建议掌握的核心概念(面试高频):
    • 1)Deployment/ReplicaSet/Pod:滚动发布与副本控制。
    • 2)Service/Ingress:服务发现与流量入口。
    • 3)ConfigMap/Secret:配置与密钥分离。
    • 4)HPA:按指标自动扩缩。
    • 5)探针:liveness/readiness/startup,配合灰度与 verify。
  • 常见坑:readiness 没配导致流量过早打进来;资源 limit 不合理导致 OOM。

3)CI/CD 流水线设计

  • 一句话结论:CI/CD 的目标是“可重复构建、质量门禁、可控发布、快速回滚”。
  • 你可以用的结构:
    • 1)CI:lint/typecheck/test/build(质量门禁 + 产物可追溯)。
    • 2)制品:构建产物/镜像入库,打版本与签名。
    • 3)CD:按环境发布(灰度/全量),带 verify(健康检查/关键接口探活)。
    • 4)可观测:日志/指标/告警;失败自动阻断。
  • 常见坑:没有制品库导致不可追溯;没有门禁导致把问题推到线上。

魔方大屏 + 报表

1)低代码组件化原理

  • 一句话结论:低代码的本质是“schema 驱动 UI”,关键在于组件契约与运行时渲染器。
  • 核心要素:
    • 1)物料(组件)契约:props/事件/默认值/校验。
    • 2)schema:描述组件树 + 数据源绑定 + 交互联动。
    • 3)渲染器:递归渲染 + 表达式解析 + 事件分发。
    • 4)治理:版本化 + migration + 权限与安全。
  • 常见坑:schema 不版本化导致历史页面打不开;表达式能力过大带来安全风险。

2)大屏交互原理

  • 一句话结论:大屏交互的核心是“状态驱动 + 分层渲染 + 节流与批量更新”。
  • 常见交互:筛选联动、钻取、hover 高亮、时间轴播放、实时刷新。
  • 怎么做:
    • 1)状态管理:把筛选条件/时间范围/选中项做成全局可追踪状态。
    • 2)事件链路:组件事件 → 事件总线/状态更新 → 数据请求/重算 → 图表更新。
    • 3)性能:对频繁事件节流/防抖;批量 setOption;避免频繁销毁重建。

3)ECharts 优化方案

  • 一句话结论:ECharts 优化要分“数据量、更新频率、渲染模式”三类问题。
  • 怎么做(可按场景讲):
    • 1)大数据量: - 采样/聚合(后端聚合优先); - 分页/分层展示; - 使用更轻的系列/关闭不必要特效。
    • 2)高频更新: - 节流刷新; - setOption 合并更新,避免全量重绘; - 避免频繁 resize。
    • 3)渲染:canvas/webgl(按系列与能力选择);必要时分层渲染。
  • 常见坑:每次更新都 dispose + init;tooltip/animation 太重;数据结构频繁创建导致 GC 抖动。

4)数据可视化设计原则

  • 一句话结论:先保证“读得懂、看得准、可行动”,再谈炫技。
  • 常用原则:
    • 1)一致性:颜色/单位/口径一致。
    • 2)对比性:强调变化与差异(同比/环比/阈值)。
    • 3)层次:先总览再钻取;避免一屏塞满。
    • 4)可解释:口径说明、数据来源、刷新时间。
    • 5)容错:无数据/异常/延迟要有明确状态。

5)大数据报表性能优化

  • 一句话结论:报表性能优化要同时做“查询聚合、导出异步化、并发控制、可追溯”。
  • 怎么做:
    • 1)查询侧:索引/分区;按时间窗聚合;避免全量 scan。
    • 2)生成侧:重计算/导出走队列 worker,主服务只做编排。
    • 3)幂等与锁:多实例避免重复生成;任务实例入库记录状态与产物。
    • 4)并发与限流:控制导出并发;超时与重试(退避)。
    • 5)监控告警:成功率、P95 耗时、队列堆积。
  • 常见坑:同步导出把主服务拖死;没有幂等导致重复执行;失败无告警导致业务事故。

On this page