基础面试题

26 阅读7分钟
  1. 执行上下文与闭包的底层原理 (⭐⭐⭐⭐)

    • 请结合“词法作用域(Lexical Scope)”和“执行上下文栈(ECS)”解释闭包是如何产生的?
    • 闭包会导致内存泄漏吗?V8 引擎是如何处理闭包引用的变量回收的?
  2. 事件循环(Event Loop)深度剖析 (⭐⭐⭐⭐)

    • 描述浏览器与 Node.js(特别是 v11 版本前后)在 Event Loop 处理上的差异。
    • 宏任务(MacroTask)与微任务(MicroTask)的执行顺序,requestAnimationFrame 和 requestIdleCallback 在其中的位置是什么?
  3. 原型链与继承终极方案 (⭐⭐⭐)

    • 手写 ES5 的寄生组合式继承。
    • ES6 class 的 super() 到底做了什么?它和 ES5 的继承有何本质区别?
  4. V8 垃圾回收机制 (GC)  (⭐⭐⭐⭐)

    • 讲一下 V8 的新生代(Scavenge 算法)和老生代(Mark-Sweep & Mark-Compact)回收策略。
    • 什么情况下会出现内存泄漏?如何使用 Chrome Memory 面板排查?
  5. Promise 核心标准 (A+ Spec)  (⭐⭐⭐⭐⭐)

    • Promise 的状态流转是怎样的?.then 的链式调用是如何实现的(返回新 Promise)?
    • 如何中断一个 Promise 链?
  6. WeakMap 与 WeakSet (⭐⭐⭐)

    • 它们与 Map/Set 的区别是什么?为什么说它们是“弱引用”?
    • 在 Vue3 响应式原理或 DOM 节点元数据存储中有哪些应用场景?
  7. 迭代器(Iterator)与生成器(Generator)  (⭐⭐⭐)

    • async/await 的实现原理是什么?(请口述如何用 Generator + Co 自动执行器模拟 async)。

🦕 模块二:TypeScript

考察点:不再是简单的类型定义,而是类型推导、泛型编程和类型体操。

  1. 泛型(Generics)与约束 (⭐⭐⭐)

    • 解释泛型约束 T extends U 的作用。
    • 如何在函数中限制泛型参数必须包含某些属性?
  2. 高级类型工具原理 (⭐⭐⭐⭐)

    • 请手写实现 TS 内置工具类型:Partial, Pick<T, K>, Omit, Readonly。
  3. infer 关键字与条件类型 (⭐⭐⭐⭐⭐)

    • 解释 infer 的作用。
    • 实战题:如何编写一个类型工具,提取 Promise 内部的返回类型?(例如 UnwrapPromise<Promise> 得到 string)。
  4. 逆变(Contravariance)与协变(Covariance)  (⭐⭐⭐⭐⭐)

    • 在 TypeScript 中,函数参数和返回值的类型兼容性遵循什么原则?(口诀:参数逆变,返回值协变),请举例说明。
  5. Discriminated Unions (可辨识联合)  (⭐⭐⭐)

    • 在 Redux 的 Action 定义或复杂状态管理中,如何利用字面量类型进行类型守卫(Type Guard)?
  6. unknown vs any vs never (⭐⭐⭐)

    • unknown 和 any 的区别是什么?
    • never 类型在“穷尽性检查(Exhaustiveness checking)”中的应用。

⚛️ 模块三:框架原理 (以 React 为主,兼顾 Vue)

考察点:源码级理解,不再停留在生命周期背诵,而是关注 Diff、调度、状态与复用。

  1. Virtual DOM 与 Diff 算法 (⭐⭐⭐⭐)

    • React: 解释 Fiber 架构解决了什么问题?Diff 算法中的 Key 到底起了什么作用?(O(n) 复杂度的前提)。
    • Vue: Vue2 的双端比较与 Vue3 的最长递增子序列(LIS)算法有何不同?
  2. 状态更新机制 (Batching)  (⭐⭐⭐⭐)

    • React 的 setState 是同步还是异步的?在 React 18 的 Automatic Batching 中有什么变化?
    • Vue 的 nextTick 原理是什么?它是如何利用微任务队列合并 DOM 更新的?
  3. Hooks 实现原理 (⭐⭐⭐⭐⭐)

    • 为什么 React Hooks 不能在条件语句或循环中调用?(链表结构与顺序依赖)。
    • useMemo 和 useCallback 真的能提升性能吗?什么时候通过它们优化反而是负优化?
  4. 响应式原理对比 (⭐⭐⭐⭐)

    • 详细对比 Vue2 (Object.defineProperty) 与 Vue3 (Proxy) 的响应式实现差异。
    • Proxy 相比 defineProperty 解决了哪些痛点(如数组监听、属性增删)?
  5. 组件通信与复用 (⭐⭐⭐)

    • React 的 HOC (高阶组件) vs Render Props vs Hooks,各自的优缺点是什么?
  6. React Scheduler (时间切片)  (⭐⭐⭐⭐⭐)

    • React 是如何通过 MessageChannel 实现时间切片的?为什么不直接用 setTimeout?
    • 解释 Concurrent Mode(并发模式)下的“中断”与“恢复”机制。

🛠️ 模块四:前端工程化

考察点:构建工具链的深度与广度,模块化标准,性能优化手段。

  1. Webpack 构建流程与原理 (⭐⭐⭐⭐)

    • 简述 Webpack 的打包流程(Init -> Make -> Seal -> Emit)。
    • Loader 和 Plugin 的本质区别是什么?请描述一下你写过的一个 Plugin 是如何介入构建周期的(Tapable 钩子)。
  2. HMR (热更新) 原理 (⭐⭐⭐⭐⭐)

    • Webpack HMR 是如何通过 WebSocket 通信将更新推送到浏览器的?浏览器收到更新后如何替换模块而不需要刷新页面?
  3. Vite vs Webpack (⭐⭐⭐⭐)

    • Vite 为什么在开发环境这么快?(基于 Native ESM + esbuild)。
    • Vite 在生产环境为什么要用 Rollup 打包?
  4. 模块化标准 (CommonJS vs ESM)  (⭐⭐⭐⭐)

    • CommonJS 的动态加载与 ESM 的静态分析有什么区别?
    • 为什么 Tree-Shaking 必须基于 ESM?它是如何判定“无用代码”的(副作用/Side Effects)?
  5. Babel 原理 (⭐⭐⭐)

    • Babel 是如何将 ES6 代码转换为 ES5 的?(Parse -> Transform -> Generate)。
    • 解释 AST(抽象语法树)在其中的作用。
  6. 大型项目构建优化 (⭐⭐⭐⭐)

    • 面对一个构建速度慢的大型项目,你有哪些优化手段?(DLL, Cache, Thread-loader, Module Federation 等)。

🌐 模块五:浏览器与网络

考察点:全链路性能、安全攻防、协议细节。

  1. 从输入 URL 到页面渲染全过程 (硬核版)  (⭐⭐⭐⭐⭐)

    • 请详细描述 DNS 解析、TCP 握手、TLS 握手、HTTP 缓存策略、CRP(关键渲染路径)、重排重绘。
    • 追问:如果页面白屏时间过长,你如何通过 Chrome Performance API 定位是网络问题还是 JS 执行问题?
  2. HTTP 协议进化史 (⭐⭐⭐⭐)

    • HTTP/1.1 的队头阻塞 (Head-of-line blocking) 是什么?
    • HTTP/2 的多路复用 (Multiplexing) 和头部压缩 (HPACK) 原理。
    • HTTP/3 (QUIC) 是如何基于 UDP 解决 TCP 层面的队头阻塞问题的?
  3. 跨域解决方案 (⭐⭐⭐)

    • CORS 的简单请求与预检请求 (Options) 的触发条件。
    • Nginx 反向代理解决跨域的配置原理。
  4. 前端安全 (XSS & CSRF)  (⭐⭐⭐⭐)

    • XSS: 存储型 vs 反射型 vs DOM 型。React/Vue 默认是如何防御 XSS 的?
    • CSRF: 原理是什么?SameSite Cookie 属性如何防御 CSRF?
    • CSP (内容安全策略)  的作用是什么?
  5. 浏览器缓存策略 (⭐⭐⭐⭐)

    • Cache-Control (Strong Cache) vs ETag/Last-Modified (Negotiation Cache)。
    • Service Worker 在缓存策略中的应用(PWA)。

✍️ 模块六:手写代码 & 算法

考察点:P6 必须具备极强的 Coding 能力,要求代码规范、考虑边界情况。

核心手写题 (高频):

  1. 手写 Promise.all / Promise.race / Promise.allSettled (⭐⭐⭐⭐)
  2. 手写防抖 (Debounce) 与节流 (Throttle)  (⭐⭐⭐) - 要求:支持立即执行、取消功能。
  3. 手写深拷贝 (DeepClone)  (⭐⭐⭐⭐) - 要求:解决循环引用(WeakMap)、处理 Symbol/Date/RegExp 类型。
  4. 手写发布订阅模式 (EventEmitter)  (⭐⭐⭐) - 要求:on, emit, off, once。
  5. 手写 call / apply / bind (⭐⭐⭐⭐)
  6. 手写 new 操作符 / instanceof 实现 (⭐⭐⭐)
  7. 手写并发控制调度器 (⭐⭐⭐⭐⭐) - 题目:实现一个 Scheduler 类,限制同时运行的异步任务数量(如最多 2 个)。
  8. 手写数组扁平化 (flat) / 数组去重 (⭐⭐⭐)

常见算法题 (前端偏向):

  1. LRU 缓存算法 (⭐⭐⭐⭐) - 使用 Map + 双向链表实现。
  2. 树形结构与列表互转 (⭐⭐⭐⭐) - 扁平数组转 Tree,Tree 转扁平数组。
  3. 大数相加 (⭐⭐⭐) - 处理超过 JS Number 精度的大整数运算。
  4. 版本号排序 (⭐⭐⭐) - 如 ['1.45.0', '1.5', '6', '3.3.3.3.3.3']。

🏗️ 模块七:架构与软技能

考察点:系统设计能力、项目复盘能力、技术视野。

  1. 设计模式实战 (⭐⭐⭐⭐)

    • 你在项目中用过哪些设计模式?请举例。(单例模式-Axios实例、观察者模式-事件总线、策略模式-表单验证、代理模式-Proxy)。
  2. 前端性能监控体系搭建 (⭐⭐⭐⭐⭐)

    • 如何设计一个 SDK 自动上报错误(JS Error, Promise Reject, 资源加载失败)?
    • 如何计算 FCP, LCP, CLS 等核心指标?(PerformanceObserver)。
    • 如何实现白屏检测?
  3. 微前端架构 (Micro-Frontend)  (⭐⭐⭐⭐)

    • 对比 iframe, single-spa, qiankun, Module Federation 的优缺点。
    • 如何解决微前端中的样式隔离和 JS 沙箱隔离问题?
  4. 虚拟列表 (Virtual Scroll)  (⭐⭐⭐⭐)

    • 面对 10 万条数据渲染,如何设计虚拟滚动方案?核心计算逻辑是什么?
  5. 项目复盘与难点 (必问)  (⭐⭐⭐⭐⭐)

    • 问题范例:“介绍一个你做过的最复杂的项目,难点在哪里?你是如何解决的?如果现在重构,你会怎么改进?”
    • 提示:P6 必须能讲出“方案选型”、“性能瓶颈突破”、“工程化改造”等层面的难点,而不是简单的业务逻辑堆砌。

💡 给 P6 候选人的建议:

  1. 深度优先:不要背诵定义,要看源码,看规范。面试官问“是什么”,你要回答“为什么”和“怎么实现的”。
  2. 场景驱动:所有的技术都是为了解决业务问题。回答问题时,尽量结合实际项目场景来举例。
  3. 手写代码:白板编程是 P6 面试的杀手锏,务必熟练掌握上述“手写代码”模块,尤其是并发控制和深拷贝。