跳到主要内容

面试记录

举一个 Sentry 解决的线上案例?

一个华为手机不支持 Intl.NumberFormat 的例子。

const number = 1234567.89;

const formatter = new Intl.NumberFormat('en-US', {
style: 'decimal',
minimumFractionDigits: 3,
maximumFractionDigits: 3,
});

console.log(formatter.format(number));
// 输出: "1,234,567.890"

React Fiber


Sentry 线上案例

华为手机 Intl.NumberFormat 兼容性问题

Sentry 捕获到华为部分低版本系统手机(HarmonyOS 2.0 / Android 10)上 Intl.NumberFormat 的 format 方法抛出异常。

问题代码

const formatter = new Intl.NumberFormat('en-US', {
style: 'decimal',
minimumFractionDigits: 3,
maximumFractionDigits: 3,
});

// 华为部分机型: TypeError: Intl.NumberFormat is not a constructor
formatter.format(1234567.89); // 预期: "1,234,567.890"

解决方案

  • 方案 1:添加 polyfill(@formatjs/intl-numberformat)
  • 方案 2:try-catch 降级为 toLocaleString
  • 方案 3:使用简单的正则格式化兜底
function formatNumber(num, decimals = 3) {
try {
return new Intl.NumberFormat('en-US', {
minimumFractionDigits: decimals,
maximumFractionDigits: decimals,
}).format(num);
} catch {
// 降级方案
return num.toFixed(decimals).replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}
}

React Fiber 架构

核心概念

  • Fiber 是 React 16 引入的新协调引擎,将渲染工作拆分为可中断的小单元
  • 每个 Fiber 节点代表一个 React 元素,包含类型、props、state 等信息
  • 通过 requestIdleCallback / MessageChannel 实现时间切片

Fiber 节点结构

interface FiberNode {
tag: number; // 组件类型标识
type: any; // 组件函数/类/原生标签
stateNode: any; // 真实 DOM 或类实例

// 链表结构
return: FiberNode; // 父节点
child: FiberNode; // 第一个子节点
sibling: FiberNode; // 下一个兄弟节点

// 双缓冲
alternate: FiberNode; // workInProgress 对应的 current

// 副作用
flags: number; // 标记需要的 DOM 操作
subtreeFlags: number; // 子树的副作用标记
}

工作循环(Work Loop)

  • beginWork:从根节点向下递,处理每个 Fiber 节点
  • completeWork:从叶子节点向上归,创建/更新 DOM
  • commitWork:一次性将所有变更提交到真实 DOM

与 Vue 的区别

  • React:pull-based,需要 diff 整棵子树(Fiber 让 diff 可中断)
  • Vue:push-based,响应式精确追踪变化的组件(不需要时间切片)

其他常见面试题方向

  • 浏览器渲染流程(解析 → Style → Layout → Paint → Composite)
  • 事件循环(宏任务 vs 微任务 vs requestAnimationFrame)
  • HTTP/2 多路复用 vs HTTP/1.1 队头阻塞
  • Webpack 构建优化(代码分割、缓存策略、并行构建)
  • TypeScript 类型体操(Conditional Types、infer、Template Literal Types)