面试记录
举一个 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)