前端面试题库

58 阅读9分钟
  1. 数据类型与内存 (★★)

    • 聊聊JavaScript的七种原始类型和一种引用类型。
    • 原始类型和引用类型在内存(栈与堆)中是如何存储的?为什么这么设计?
    • SymbolBigInt是用来解决什么问题的?
  2. 类型转换 (★★★)

    • JS中的隐式类型转换规则有哪些?(尤其是 +, == 操作符)
    • [] + {}{} + [] 的结果分别是什么?为什么?
    • ToPrimitive这个内部转换规则了解吗?
  3. 作用域与闭包 (★★★)

    • 什么是词法作用域和动态作用域?JS是哪一种?
    • 什么是闭包?闭包在实际开发中的应用场景有哪些(例如:防抖节流、模块化)?
    • 闭包一定会导致内存泄漏吗?什么情况下会?如何避免?
  4. this 绑定 (★★★)

    • this 的绑定规则有哪几种?(默认、隐式、显式、new)
    • 箭头函数 this 的指向是如何确定的?它和普通函数的 this 有什么根本区别?
    • 手写实现 call, apply, bind
  5. 原型与继承 (★★★★)

    • 画一张图解释 __proto__prototypeconstructor 之间的关系。
    • instanceof 的实现原理是什么?手写实现一下。
    • 手写实现 new 操作符。
    • ES6的 class 和ES5的构造函数继承有什么区别?class 只是语法糖吗?
  6. ES6+ 新特性 (★★★)

    • let, const 相比 var 有哪些改进?什么是“暂时性死区”(TDZ)?
    • Map, SetObject, Array 的区别?WeakMapWeakSet 的“弱”体现在哪里?它们的核心应用场景是什么?
    • 解构赋值的原理是什么?
  7. 异步编程 (★★★★)

    • Callback -> Promise -> Generator -> async/await,JS异步编程经历了怎样的演进?它们分别解决了什么问题?
    • async/await 的本质是什么?它和 Generator 有什么关系?
    • Promise 构造函数是同步的还是异步的?then 呢?
    • 手写一个符合 A+ 规范的 Promise(核心版)。
  8. 垃圾回收 (GC) (★★★★)

    • V8引擎的垃圾回收机制是如何工作的?(新生代 Scavenge、老生代 Mark-Sweep/Mark-Compact)
    • 什么是“Stop-the-World”?V8是如何优化它的?(增量标记、并发标记)
    • 哪些代码实践可能导致内存泄漏?

二、 TypeScript (深度)

现在大厂几乎是TS标配,P6需要具备定义复杂类型和利用TS进行架构约束的能力。

  1. 基础辨析 (★★)

    • interfacetype 的区别是什么?什么时候该用哪个?
    • any, unknown, never 三者有什么区别?unknown 为什么比 any 更安全?
  2. 泛型 (Generics) (★★★)

    • 什么是泛型?它解决了什么问题?
    • 什么是泛型约束?(例如 T extends { length: number }
  3. 高级类型 (★★★★)

    • 什么是条件类型(Conditional Types)?举个例子。
    • keyof, typeof 的作用是什么?
    • 什么是映射类型(Mapped Types)?
  4. 类型体操 (Type-fu) (★★★★★)

    • 解释 infer 关键字的作用。
    • [手写] 实现TS内置的工具类型:Partial<T>, Readonly<T>, Pick<T, K>, Omit<T, K>
    • [手写] 实现 ReturnType<T>(获取函数返回类型)。
    • [手写] 实现 PromiseType<T>(例如 Promise<string> 得到 string)。
  5. 工程实践 (★★★)

    • 如何在项目中配置 tsconfig.jsonstrict 模式主要包含了哪些检查?
    • 如何为第三方JS库编写 .d.ts 声明文件?

三、 框架原理 (React / Vue)

P6不能停留在“会用API”,必须深入源码,理解其设计哲学。

A. React 专项
  1. 核心理念 (★★★)

    • React为什么选择vDOM?vDOM的真实开销在哪里?
    • React的“合成事件”(SyntheticEvent)机制是如何实现的?为什么需要它?
  2. Reconciliation & Diff (★★★★)

    • React 15(Stack Reconciler)和 React 16+(Fiber Reconciler)的架构有什么核心区别?
    • 什么是Fiber?它为什么能实现异步可中断更新?
    • React Diff算法的三大策略是什么?key 的作用到底是什么?
  3. 状态与生命周期 (★★★)

    • setState 为什么通常是异步的?它在哪些情况下会变成同步的?
    • setState 的批量更新(Batching)机制是如何实现的?(React 18的Automatic Batching了解吗?)
    • useEffectuseLayoutEffect 的执行时机和区别?
  4. Hooks 原理 (★★★★★)

    • Hooks为什么必须在顶层调用?不能在循环或条件语句中?
    • Hooks是如何在React内部实现状态隔离的?(提示:Fiber上的链表)
    • useMemouseCallback 的使用场景和潜在陷阱(例如,不当的依赖数组)?
    • 如何理解 useCallback 的“闭包陷阱”(stale closure)?如何解决?
  5. 状态管理 (★★★★)

    • Context API 相比 Redux 有什么优缺点?Context 导致的重渲染问题你如何优化?
    • Redux(或Zustand/Jotai)的实现原理是什么?Redux中间件(如thunk, saga)的原理?
  6. 并发渲染 (Concurrent Mode) (★★★★★)

    • 什么是时间切片(Time Slicing)?
    • useTransitionuseDeferredValue 是用来解决什么问题的?
B. Vue 专项
  1. 响应式原理 (★★★★★)

    • Vue 2 的 Object.defineProperty 和 Vue 3 的 Proxy 在实现响应式时有什么核心区别?
    • Proxy 相比 defineProperty 有哪些优势?为什么 Vue 3 无法兼容 IE?
    • Map/Set 是如何实现响应式的?
  2. 模板编译 (★★★★)

    • Vue 的模板(template)是如何被编译成 render 函数的?(AST -> Optimize -> CodeGen)
    • slotscoped-slot 是如何实现的?
  3. vDOM & Diff (★★★★)

    • Vue 的 Diff 算法(特别是双端 Diff)和 React 的 Diff 算法有什么不同?
    • key 在 Vue 中的作用是什么?
  4. 组件与异步 (★★★)

    • computedwatch 的区别?computed 是如何实现缓存的?
    • nextTick 的原理是什么?它的实现降级策略是怎样的?(Promise -> MutationObserver -> setTimeout)
    • keep-alive 组件的实现原理是什么?(LRU 缓存策略)
  5. Vuex / Pinia (★★★)

    • Vuex 的 commitdispatch 有什么区别?actions 为什么能处理异步?
    • Pinia 相比 Vuex 有哪些设计上的改进?

四、 前端工程化 (Webpack / Vite)

现代前端开发离不开构建工具,P6需要具备配置、优化甚至开发插件的能力。

  1. 模块化 (★★)

    • CommonJS, AMD, UMD, ES Module(ESM)四种模块化规范的区别是什么?
    • Node.js 是如何支持 ES Module 的?
  2. Webpack (★★★★)

    • Webpack 的核心构建流程是怎样的?(Entry -> AST -> Dependency Graph -> Output)
    • LoaderPlugin 的区别是什么?它们分别在哪个阶段工作?
    • [手写] 如何编写一个简单的 Webpack Loader?如何编写一个 Plugin?
    • Webpack 的 HMR(热模块更新)原理是什么?
    • Webpack 性能优化:构建速度(缓存、多核)和产物体积(Code Splitting, Tree Shaking)。
    • Tree Shaking 的实现原理是什么?为什么它强依赖 ES Module?
  3. Vite (★★★★)

    • Vite 为什么在开发环境(dev server)启动这么快?
    • Vite 是如何实现“按需编译”的?
    • Vite 在生产环境为什么使用 Rollup 而不是 esbuild?
  4. Babel (★★★)

    • Babel 的工作原理是什么?(Parse -> Transform -> Generate)
    • @babel/preset-env@babel/plugin-transform-runtime / @babel/polyfill 之间的区别和作用?

五、 浏览器与网络 (原理)

前端的宿主环境,P6必须精通。

  1. 事件循环 (Event Loop) (★★★★★)

    • 画图说明浏览器和 Node.js 的 Event Loop 有什么不同。
    • 宏任务(Macrotask)和微任务(Microtask)有哪些?它们的执行时机?
    • async/await 函数中的 await 之后的部分属于宏任务还是微任务?
    • [场景题] 分析一堆 setTimeout, Promise.then, async 嵌套代码的最终输出顺序。
  2. 浏览器渲染 (★★★★) * 从输入URL到页面展示,发生了什么?(“天字一号”题,P6需要答得非常深入)

    • 什么是关键渲染路径(CRP)?
    • 什么是重排(Reflow)和重绘(Repaint)?它们有何区别?
    • 如何减少重排和重绘?(例如:requestAnimationFrame,读写分离)
    • CSS的 will-changetransform: translateZ(0) 是如何创建合成层(Compositing Layer)来优化渲染的?
  3. 网络协议 (★★★★)

    • HTTP/1.1, HTTP/2, HTTP/3 各自的核心特性是什么?解决了什么问题?(例如:管线化、多路复用、QUIC)
    • TCP的三次握手和四次挥手过程。为什么握手是三次,挥手是四次?
    • HTTPS 的工作原理(SSL/TLS握手过程)。非对称加密和对称加密在其中分别扮演什么角色?
  4. 浏览器缓存 (★★★★)

    • 强缓存(Expires, Cache-Control)和协商缓存(Last-Modified, ETag)的工作流程?
    • Cache-Controlmax-age, s-maxage, no-cache, no-store 分别是什么意思?
    • 用户F5刷新和Ctrl+F5强制刷新时,缓存的行为有什么不同?
  5. Web 安全 (★★★★)

    • 什么是 XSS(跨站脚本攻击)?分为哪几类?如何防范?(CSP, HttpOnly, 转义)
    • 什么是 CSRF(跨站请求伪造)?如何防范?(SameSite Cookie, Referer, Token)
    • 什么是 CORS?如何解决跨域问题?(CORS, JSONP, Nginx反向代理)
    • OPTIONS 预检请求是什么时候触发的?

六、 手写代码 & 算法

考察代码硬实力,P6需要写出健壮、高效、边界清晰的代码。

  1. JS基础手写 (★★★)

    • 手写 debounce (防抖) 和 throttle (节流)。(P6需要考虑 leadingtrailing 选项)
    • 手写 deepClone (深拷贝)。(P6必须考虑循环引用和 SymbolDateRegExp 等特殊类型)
    • 手写实现 EventEmitter / EventBus(on, off, once, emit)。
  2. 异步与并发 (★★★★★)

    • 手写 Promise.all, Promise.race, Promise.any, Promise.allSettled
    • 手写 Promise.retry (带重试次数的Promise)。
    • 实现一个 Scheduler 类,实现并发任务控制(例如:同时最多执行2个任务)。
  3. 功能实现 (★★★★)

    • 手写实现 JSON.stringify。(考察对象、数组、特殊值的处理)
    • 手写实现函数柯里化 curry
    • 手写实现 Array.prototype.flat (数组扁平化)。
    • 实现一个模板字符串解析函数 render(template, data)
  4. 算法 (★★★★)

    • 链表: 反转链表、判断链表是否有环。
    • 树: 二叉树的层序遍历、前/中/后序遍历(递归与非递归)、判断是否为平衡二叉树、求二叉树最大深度。
    • 字符串: LRU 缓存算法实现。(大厂高频)
    • 数组: 寻找数组中第K个最大元素(快排思想/最小堆)。
    • 动态规划: 爬楼梯、最长递增子序列。
    • 场景: 如何快速找到一个10G大文件中的重复URL?(分治 + Hash Map)

七、 架构与软技能

这是P6区别于P5的关键,考察你的“工程思维”和“系统设计”。

  1. 设计模式 (★★★)

    • 你在项目中用过哪些JS设计模式?(单例、工厂、策略、观察者/发布订阅)
    • 观察者模式和发布订阅模式有什么区别?
  2. 项目与架构 (★★★★)

    • [STAR法则] 详细介绍一下你认为最有挑战性的一个项目。你的角色、遇到的困难、解决方案、最终结果和反思。
    • 如何设计一个大型前端项目的技术选型?(框架、状态管理、UI库、工程化)
    • 如何设计一个可复用的组件库?(API设计、文档、样式隔离、按需加载)
    • Monorepo 和 Multirepo 各自的优缺点是什么? . 微前端(Micro-Frontends)的实现方案有哪些?(qiankun, Module Federation),它们是如何解决样式隔离和JS沙箱的?
  3. 性能优化 (★★★★)

    • 你如何定义和监控前端性能?(Core Web Vitals: LCP, FID, CLS)
    • 如何设计一个前端性能监控SDK(“埋点”平台)?需要采集哪些指标?
    • 白屏时间(FP/FCP)过长,你有哪些排查思路和优化方案?(SSR, SSG, 预加载, CDN, 骨架屏)
    • 如何进行“长列表”的性能优化?(虚拟滚动/Treact-virtualized)
  4. 软技能 (★★★)

    • 你如何保证团队的代码质量?(Code Review, Eslint/Prettier, Git Hooks, 单元测试)
    • 如果和产品经理在需求实现上发生冲突,你如何处理?
    • 你近半年的学习输入和技术产出是什么?