现代前端面试知识地图:从浏览器原理到工程决策
本文目录
面试题不是标准答案收集器。可靠的回答要先说结论,再解释浏览器或语言机制,说明取舍和失效边界,最后给出验证办法。本文按现代前端常见工作场景组织题目,用来练习解释和排查;浏览器、框架与标准会变化,回答前要注明版本和环境。
浏览器事件循环与渲染
问题:Promise 回调、定时器和页面绘制到底按什么顺序发生?
不要只背“同步、微任务、宏任务”口诀。先区分当前 JavaScript 执行、任务队列、微任务检查点与渲染机会。Promise reaction 通常进入微任务队列;定时器回调是后续任务,但计时器延迟不是精准执行保证;浏览器会在事件循环中协调脚本、输入、网络和渲染,不能假设每个任务后必绘制一次。
回答时说明具体执行环境、任务来源以及观察目标。用小型顺序打印实验能验证回调顺序;要判断页面何时能呈现,则用 Performance trace 查看长任务和帧,而不是从 console 输出推断所有渲染时机。
Fetch、HTTP 与取消
问题:fetch() 遇到 404/500 会进入 catch 吗?怎么处理搜索竞态?
HTTP 错误状态通常仍会得到 Response;网络失败、错误 scheme 或被中止才会 reject。检查 response.ok / status,解析前校验内容类型和响应结构。对随输入变化的搜索,用 AbortController 中止旧请求;即使取消,也用请求序号或当前 query 防止迟到响应覆盖新状态。并行请求要有并发上限,重试要按错误类型与幂等语义决定。
let generation = 0;
let controller;
async function search(query) {
controller?.abort();
controller = new AbortController();
const requestId = ++generation;
const response = await fetch('/api/search?q=' + encodeURIComponent(query), {
signal: controller.signal,
credentials: 'same-origin',
});
if (!response.ok) throw new Error('HTTP ' + response.status);
const result = await response.json();
if (requestId !== generation) return;
renderResults(result);
}
面试时继续补充错误 UI、超时、组件卸载、账号切换和 API 授权;AbortController 是取消客户端工作,不代表服务端已经撤销请求或事务。
状态管理与组件副作用
问题:什么时候需要全局状态,什么时候使用 Effect?
先找状态的所有者和生命周期:页面局部交互留在组件,多个路由共享的业务状态放在明确的数据层;服务端数据与临时 UI 状态不要混为一谈。派生值优先由现有状态计算,不要再复制一份后靠 Effect 同步,避免短暂不一致和更新循环。
Effect/生命周期用于同步外部系统,例如订阅、定时器、浏览器 API 或连接。它要有清理函数、正确依赖与竞态处理;由某个按钮点击直接触发的写操作通常属于事件处理,而非“组件一渲染就做”。React 开发模式可能重复执行 Effect 来暴露清理问题,这不是靠关闭 Strict Mode 修复的 bug。
Core Web Vitals 与性能预算
问题:Lighthouse 变绿是否证明线上体验好?
实验室测试能复现部分性能问题,不能代表所有用户设备、网络、缓存和真实交互。结合字段数据按移动/桌面、路由和发布版本观察 LCP、INP、CLS 的分布,再用 trace 找到资源、主线程、布局或渲染瓶颈。先让用户得到及时反馈,再把重计算拆分、延后或移交 Worker;为图片和异步内容预留空间。预算应由业务基线和真实用户数据校准,而不是机械照搬单一分数。
性能优化要保留正确性、隐私与可访问性。减少脚本不应删掉必要授权提示;懒加载不能让首屏主内容空白;缓存必须考虑个性化数据和版本发布顺序。
缓存、版本与发布
问题:为什么发布后用户仍看到旧代码?
把浏览器 HTTP cache、CDN、Service Worker 与应用内存缓存分开排查。带内容 hash 的 JS/CSS 可以长期缓存;HTML 通常需要重新验证或短缓存;私有响应不可进入共享缓存。发布先上传新资源,再发布引用它们的 HTML;保留旧 hash 文件以兼容仍打开的旧页面。Service Worker 另有 waiting/active 生命周期,强制跳过等待前要验证新旧页面兼容和离线更新提示。
安全与权限边界
问题:CORS、路由守卫或隐藏按钮能保护 API 吗?
CORS 是浏览器跨源读取策略,不是身份验证和对象授权。路由守卫、菜单裁剪和客户端角色字段只影响界面;服务端必须针对主体、动作和对象逐请求授权,列表查询也应先限权再分页。对用户内容按上下文安全编码,富文本使用允许列表净化;Cookie 会话还要设计 CSRF 防护。CSP 是额外防线,不代替修复 XSS 根因。
可访问性与移动端
问题:一个交互组件的可访问性怎么验收?
使用原生语义元素,键盘可达且焦点清晰;输入有标签、错误可被读屏关联,弹窗管理焦点并在关闭后还焦点。不要只用颜色表达状态;支持缩放、触控目标、减少动态效果和窄屏重排。手工键盘/读屏检查配合自动化扫描,自动扫描不能替代真实用户路径验证。
设计题与答题结构
拿“输入关键词后显示联想结果”作为练习:需求澄清最小输入长度、延迟、空态、权限、键盘行为和服务端限制;设计 debounce、取消/竞态、错误恢复、无障碍列表交互、缓存与指标;最后给出低网、快速改词、空结果、401/403、慢响应、卸载和移动键盘遮挡等测试。
每题可以按以下顺序组织:
- 一句话结论与适用场景。
- 运行机制或数据流,画出边界而不是堆术语。
- 至少一种替代方案,以及选择它的代价。
- 失败场景、隐私/安全影响和兼容范围。
- 可运行的最小例子、测试方法与复核日期。
避免把这些误区背成答案:fetch 的 500 不会天然 reject;CORS 不做授权;localStorage 不适合放长期凭据;useEffect 不是所有派生状态的同步器;TypeScript 不会在运行时验证 JSON;Lighthouse 分数也不等于全部真实用户体验。
复核清单
- 结论是否引用了当前标准或框架官方文档,而不是把题库说法当作规范?
- 示例是否可运行,是否注明 Node/浏览器/React/Vue 版本与前置条件?
- 是否测试错误、权限拒绝、弱网、重复动作、清理和移动端?
- 如果使用阈值或兼容结论,是否给出来源和最近核验时间?
- 是否避免复制面经、内部代码、用户数据或未经授权的第三方答案?
旧题库的目录仍可作为历史索引:Front-end-Web-Development-Interview-Question。
参考:WHATWG HTML Event Loops、MDN Fetch API、MDN AbortController、React Effects、web.dev INP、web.dev Optimize INP、WCAG 2.2 Overview、OWASP Authorization Cheat Sheet。
Live Notes
留言提交后会先进入审核,审核通过后对其他读者公开。