文章目录

牛客面经整理:拼多多前端面经(缓存 / 安全 / 工程化 / React / TS)(十五)

收录日期:2026-04-27
关键词:前端、HTTP、缓存、HTTPS、跨域、工程化、Babel、Vite、React、TypeScript、可访问性

1. HTTP 缓存(强缓存 / 协商缓存)

参考答案

  • 强缓存:Cache-Controlmax-age/s-maxage/immutable 等)或 Expires,命中时浏览器不发请求。
  • 协商缓存:带条件请求头(If-None-Match/If-Modified-Since),服务端用 ETag/Last-Modified 判断返回 304 或新内容。
  • 前端常见实践:静态资源走强缓存 + 文件指纹(hash),HTML 入口走协商缓存;配合 CDN 版本回滚。

2. HTTPS 能不能被抓包?怎么防?

参考答案

  • 结论:HTTPS 的传输内容会被加密,正常情况下中间人无法直接解密;但本机“抓包”通常是通过安装自签根证书做 MITM,或通过代理/调试能力拿到明文。
  • 防护思路:
    • 客户端:证书校验 +(可选)证书固定(Pinning,注意运维与灰度成本)。
    • 服务端:HSTS、禁用弱套件、开启 OCSP stapling(可选)。
    • 业务层:敏感接口二次校验(短信/OTP/风控),避免仅靠传输层安全。

3. 跨域(CORS)怎么处理?

参考答案

  • 同源限制:协议/域名/端口任一不同即跨域。
  • CORS 核心:
    • 简单请求:响应头 Access-Control-Allow-Origin 等即可。
    • 预检请求(OPTIONS):非简单方法/自定义头/Content-Type: application/json 等触发,服务端需正确返回允许的方法、头、凭证。
  • 常见坑:
    • credentialsAllow-Origin: * 不能同时使用。
    • 代理只解决开发态(Vite/webpack devServer);线上需要网关/Nginx/服务端正确配置。

4. Tree-shaking 是什么?为什么“摇不掉”?

参考答案

  • Tree-shaking:基于 ES Module 的静态结构(import/export)做未使用导出消除(DCE)。
  • 摇不掉的常见原因:
    • 使用 CommonJS(动态 require)或有副作用的模块。
    • package.json 未正确声明 sideEffects,或代码里确实存在副作用(修改全局、样式注入等)。
    • “桶文件/聚合导出”导致引入路径不精确,触发整包引入或让分析困难。
  • 解决方向:尽量用 ESM、精确路径导入、标注 sideEffects、避免顶层副作用、拆分聚合导出。

5. Babel 和 SWC 的区别?Vite 用哪个?

参考答案

  • Babel:生态成熟、插件体系强,转译灵活;缺点是速度相对慢。
  • SWC:Rust 实现,通常更快;生态在完善中,但常见转译/压缩能力已较好。
  • Vite 常见情况:
    • 默认开发态主要走 esbuild 做 TS/JS 转译(快)。
    • 需要更复杂语法/装饰器/兼容策略时,可能引入 Babel 或 SWC 插件链(取决于项目与插件选择)。
  • 回答策略:讲清“开发态快、生产态可控”,并说明你项目的实际链路与理由。

6. 插件机制(以 Vite 为例)怎么理解?

参考答案

  • 插件的本质:在构建/开发服务器管线里注册一组钩子(resolve/load/transform 等),对模块解析、加载与代码变换进行扩展。
  • 常见能力:
    • 虚拟模块、路径别名与重写、按需注入代码、转换语法、生成资源与 manifest。
    • 开发态:中间件(configureServer)+ HMR 处理。
  • 面试加分点:举一个自己写过/用过的插件案例,说明“问题 → 插件切入点 → 性能/稳定性权衡”。

7. TypeScript 编译过程(从源码到产物)

参考答案

  • 解析:源码 → AST(语法树)。
  • 绑定/类型检查:符号表、类型推断、泛型约束与错误诊断。
  • Emit:按目标(target/module)输出 JS + source map + d.ts(可选)。
  • 工程侧常见组合:类型检查(tsc --noEmit)与转译(esbuild/swc/babel)分离,提高速度并保持类型安全。

8. React Hooks 为什么必须写在函数顶层?(Rules of Hooks)

参考答案

  • 原因:React 需要按调用顺序把 state/effect 与组件实例绑定;如果在条件/循环里调用,会导致顺序不稳定,从而读写错位。
  • 正确做法:把条件逻辑放到 Hook 内部(例如在 effect 里判断),或拆成子组件/自定义 Hook。

9. React Fiber 架构解决了什么问题?

参考答案

  • 目标:把渲染工作拆成可中断的小任务,实现更好的响应性(可让出主线程给输入/动画)。
  • 关键点:
    • 协调(reconciliation)阶段可被打断与恢复;提交(commit)阶段不可中断、一次性落 DOM。
    • 优先级调度:不同更新(输入、动画、数据)可以不同优先级。

10. 组件库的可访问性(a11y)怎么做?

参考答案

  • 语义化优先:正确的原生标签(button/a/input),少用 div 造轮子。
  • 键盘可用:焦点管理(tab 顺序)、可操作元素可聚焦、Esc/Enter/方向键符合预期。
  • ARIA 辅助:补齐角色与状态(rolearia-*),但不替代语义化。
  • 对比与可读性:颜色对比度、字号、禁用态可感知。
  • 工具链:eslint-plugin-jsx-a11y、自动化检查(axe),以及真实键盘/读屏器走查。