小鹏汽车前端面经

发布于:2025-08-05 ⋅ 阅读:(10) ⋅ 点赞:(0)

前端基础与浏览器机制 (Front-End Fundamentals & Browser Mechanics)

这些问题涵盖了Web工作的基本原理,包括网络、渲染和浏览器特性。

1. 浏览器渲染与性能 (Browser Rendering & Performance)

  • URL输入发生什么?(What happens when you type a URL?)
    • 这是一个经典问题。它涉及DNS解析、TCP三次握手、HTTP请求、服务器处理、HTTP响应、浏览器解析(HTML, CSS, JS)、DOM/CSSOM构建、布局、绘制和合成。
  • DOM树和CSSOM树的构建是并行的还是串行的?(Are DOM and CSSOM tree construction parallel or serial?)
    • DOM 构建通常与网络请求其他资源(如图片)是并行的。然而,CSSOM 构建是渲染阻塞的,因为浏览器需要CSSOM来正确渲染页面。JavaScript如果需要访问或修改DOM或CSSOM,也可能阻塞DOM构建。
  • 讲一下URL到渲染页面过程 (Explain the process from URL to page rendering)
    • 这是“URL输入发生什么”问题的扩展,更侧重于浏览器端:DNS查找、TCP连接、HTTP请求/响应、解析HTML、构建DOM树、解析CSS、构建CSSOM树、结合生成渲染树、布局(回流)、绘制(重绘)和合成。
  • div改变尺寸和颜色(应该是想问回流和重绘) (Div changing size and color - likely asking about Reflow and Repaint)
    • 回流 (Reflow):当页面布局发生变化时(例如,元素尺寸、位置、内容变化)。这是一个昂贵的操作,因为它需要重新计算受影响元素及其后代和祖先的布局。
    • 重绘 (Repaint):当元素的视觉属性发生变化但不影响其布局时(例如,colorbackground-colorvisibility)。这比回流的开销小。
  • 回流重绘具体是怎么实现的 (How are reflow and repaint specifically implemented?)
    • 这深入到浏览器渲染引擎。渲染树构建完成后,浏览器执行“布局”(回流)阶段以确定所有元素的精确位置和大小。然后,“绘制”(重绘)阶段填充像素。这些过程由浏览器的渲染引擎管理。

2. 网络与协议 (Networking & Protocols)

  • DNS解析具体是怎么个解析过程呢 (How does DNS resolution specifically work?)
    • 涉及检查浏览器缓存、操作系统缓存、路由器缓存、本地DNS服务器、根DNS服务器、TLD(顶级域名)DNS服务器和权威DNS服务器,最终获取IP地址。它是一个分层和分布式的系统。
  • 三次握手、四次挥手讲一下 (Explain TCP Three-way Handshake and Four-way Wave)
    • 三次握手 (Three-way Handshake):建立TCP连接(SYN, SYN-ACK, ACK)。
    • 四次挥手 (Four-way Wave):终止TCP连接(FIN, ACK, FIN, ACK)。
  • 301, 302, 304 (HTTP Status Codes)
    • 301 Moved Permanently (永久重定向):资源已永久移动到新URL。浏览器应更新其书签/缓存。
    • 302 Found (临时重定向):资源暂时移动。浏览器不应更新其书签/缓存。
    • 304 Not Modified (未修改):客户端的缓存版本仍然有效。服务器告诉浏览器使用其缓存副本,节省带宽。
  • HTTPS加密 (HTTPS encryption)
    • 在HTTP之上使用 SSL/TLS 协议。它结合使用非对称加密(公钥/私钥)进行初始握手和密钥交换,以及对称加密进行连接建立后的数据传输。这确保了机密性、完整性和身份验证。
  • HTTP/2有什么新功能?多路复用具体表现 (What’s new in HTTP/2? Explain multiplexing)
    • 多路复用 (Multiplexing):允许在单个TCP连接上同时发送多个请求和响应。这消除了HTTP/1.x中的“队头阻塞”问题,从而提高性能并减少往返次数。
    • 其他特性:服务器推送、头部压缩(HPACK)、流优先级。
  • 那你刚才说的图片压缩,如果要更快,你用CDN,dns解析是怎么跟CDN关联起来的?(Regarding image compression, if you want it faster using CDN, how does DNS resolution relate to CDN?)
    • 当用户请求CDN上的资源时,DNS解析会根据用户的地理位置和网络状况,将请求解析到离用户最近的CDN节点(边缘服务器)的IP地址。这通常通过DNS的CNAME记录和CDN服务商的智能DNS解析实现,从而实现内容分发和加速。

3. 浏览器缓存 (Browser Caching)

  • 浏览器缓存有哪些 (What types of browser caches are there?)
    • 主要有 HTTP 缓存(包括强缓存和协商缓存)。其他类型包括 Service Worker 缓存、PWA 缓存(IndexedDB, LocalStorage)和内存缓存。
  • 强缓存和协商缓存,怎么设置 (Strong cache and negotiated cache, how to set them up?)
    • 强缓存 (Strong Cache):浏览器不向服务器发送请求。检查 Expires (HTTP/1.0) 或 Cache-Control (HTTP/1.1) 头部。
      • Cache-Control: max-age=<seconds>:资源在此秒数内是新鲜的。
      • Cache-Control: no-cache(仍发送请求但重新验证)、no-store(从不缓存)。
    • 协商缓存 (Negotiated Cache):浏览器向服务器发送请求,服务器决定缓存版本是否仍然有效。
      • Last-Modified / If-Modified-Since:服务器发送 Last-Modified 头部。在后续请求中,浏览器发送 If-Modified-Since 带有该日期。服务器进行比较。
      • ETag / If-None-Match:服务器发送 ETag(资源内容的标识符)。在后续请求中,浏览器发送 If-None-Match 带有该ETag。服务器进行比较。ETagLast-Modified 更健壮。
        在这里插入图片描述
  • 浏览器缓存,能详细说说吗,相关的属性和标识呢?缓存过程大概是什么样的?(Can you elaborate on browser caching, relevant attributes and identifiers? What’s the caching process like?)
    • 这是一个要求详细解释的问题,涵盖上述所有要点,强调使用的头部以及浏览器和服务器经过的决策过程。

JavaScript 与 Web API (JavaScript & Web APIs)

这些问题侧重于JavaScript的核心机制以及它如何与浏览器交互。

1. JavaScript 基础 (JavaScript Fundamentals)

  • JS事件循环 (JavaScript Event Loop)
    • 解释了JavaScript如何处理异步操作,尽管它是单线程的。它涉及调用栈 (Call Stack)堆 (Heap)Web API(定时器、DOM事件、HTTP请求)、回调队列 (Callback Queue/Macro-task Queue)微任务队列 (Micro-task Queue)(用于Promise、queueMicrotask)。事件循环不断检查调用栈是否为空,然后将任务从微任务队列移动到调用栈,再从回调队列移动到调用栈。
  • 深拷贝,为什么要深拷贝 (Deep copy, why deep copy?)
    • 深拷贝 (Deep copy):创建一个对象的完全独立副本,包括所有嵌套的对象和数组。对复制对象的更改不会影响原始对象。
    • 为什么 (Why):为了避免在修改复杂数据结构时产生意外的副作用。如果只执行浅拷贝,嵌套的对象/数组仍将引用相同的内存位置,导致意外行为。
  • 垂直居中的方法 (Methods for vertical centering)
    • 多种方法:
      • Flexboxdisplay: flex; align-items: center; justify-content: center;
      • Griddisplay: grid; place-items: center;
      • 绝对定位 (Absolute Positioning)position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
      • Table-celldisplay: table-cell; vertical-align: middle;
      • Line-height(用于单行文本)。
  • 发布订阅者模式,能不能手写 (Publish-Subscribe pattern, can you hand-code it?)
    • 需要实现一个类似 EventEmitter 的类,包含 on (订阅)、emit (发布) 和 off 方法。
  • Promise并发,Promise嵌套,Promise底层原理 (Promise concurrency, nesting, underlying principles)
    • 并发 (Concurrency):使用 Promise.all()Promise.race()Promise.allSettled()Promise.any() 来同时管理多个 Promise。
    • 嵌套 (Nesting):通过链式调用 .then() 来处理顺序的异步操作。
    • 底层原理 (Underlying Principle):Promise 代表异步操作的最终完成(或失败)及其结果值。它们基于 A+ Promises 规范,并利用微任务队列执行回调。
  • new过程发生了什么 (What happens during the new process?)
    1. 创建一个新的空对象。
    2. 将这个新对象的 [[Prototype]](即 __proto__)链接到构造函数的 prototype 对象。
    3. 将构造函数的作用域赋给新对象(this 指向新对象)。
    4. 执行构造函数中的代码。
    5. 如果构造函数没有明确返回一个对象,则返回这个新对象。

2. 模块化 (Modularity)

  • CommonJS和ES6模块化有什么区别 (What are the differences between CommonJS and ES6 Modules?)
    • CommonJS (Node.js 默认):
      • 同步加载模块。
      • require() 导入,module.exportsexports 导出。
      • 导出的是值的拷贝
    • ES Modules (ESM) (浏览器和现代Node.js):
      • 异步加载模块(静态分析)。
      • import 导入,export 导出。
      • 导出的是值的引用(绑定)。
      • 支持顶层 await

3. 跨域 (Cross-Origin)

  • 跨域 (Cross-Origin)
    • 指浏览器出于安全原因,限制从一个源(协议、域名、端口三者之一不同)加载的文档或脚本与另一个源的资源进行交互。
    • 解决方案:CORS (跨域资源共享)、JSONP、代理、WebSocket、Nginx反向代理等。

框架与库 (Frameworks & Libraries)

这些问题深入到React和Vue等流行前端框架的具体实现和优化。

1. React

  • react生命周期 (React Lifecycle)
    • 旧版 (Class Components)componentDidMountcomponentDidUpdatecomponentWillUnmount 等。
    • 新版 (Hooks):使用 useEffect 模拟大部分生命周期行为。
  • 如何用hook实现componentWillUnmount (How to implement componentWillUnmount with Hooks)
    • useEffect 的回调函数中返回一个清理函数。这个清理函数会在组件卸载时执行。
    useEffect(() => {
      // 相当于 componentDidMount 和 componentDidUpdate
      return () => {
        // 相当于 componentWillUnmount
      };
    }, []); // 空数组表示只在挂载和卸载时执行
    
  • 在class组件能用hooks吗?在函数式组件用class语法呢?(Can you use Hooks in class components? Can you use class syntax in functional components?)
    • Hooks不能在class组件中使用。Hooks 是为函数式组件设计的。
    • 函数式组件不能直接使用class语法。函数式组件就是纯粹的JavaScript函数。
  • class组件跟函数式组件优化的点在哪?使用函数式组件好处是什么?(Where are the optimization points for class components vs. functional components? What are the benefits of using functional components?)
    • 优化点
      • Class Components: shouldComponentUpdatePureComponent
      • Functional Components: React.memo (用于性能优化,类似 PureComponent)、useCallbackuseMemo
    • 函数式组件好处
      • 更简洁、可读性更高。
      • 更易于测试。
      • 使用 Hooks 能够更好地复用状态逻辑。
      • 更容易理解和推理组件行为。
      • 未来可能获得更好的性能优化(例如 Concurrent Mode)。
  • React会吗,Vue2和Vue3说说你的看法和理解 (Do you know React? Talk about your views and understanding of Vue2 and Vue3)
    • 这需要你结合自己的经验,比较它们的设计理念、API风格、性能优化、生态系统等。
      • Vue2: 选项式API,响应式基于 Object.defineProperty
      • Vue3: 组合式API (Composition API) 和 选项式API 共存,响应式基于 Proxy,性能更好,Tree-shaking 优化。
      • React: JSX,函数式组件 + Hooks,强调函数式编程和不可变性。

2. Vue

  • Vue的双向绑定怎么做的?(How does Vue’s two-way binding work?)
    • Vue2: 主要通过 Object.defineProperty() 劫持对象的 getter 和 setter,结合发布-订阅模式(Dep 收集依赖,Watcher 订阅更新)。当数据变化时,setter 通知所有依赖的 Watcher,Watcher 触发组件重新渲染。
    • Vue3: 使用 Proxy 对象劫持整个对象,可以监听属性的增删改查以及数组操作,性能更好,并且解决了 Object.defineProperty 无法监听新增属性和删除属性的问题。
  • Vue $nextTick原理 (Vue $nextTick principle)
    • $nextTick 的原理是利用 JavaScript 的事件循环机制。Vue 在更新 DOM 后,会将 $nextTick 的回调函数推入微任务队列(如果支持 Promise)或宏任务队列(如 setTimeout)。这样可以确保回调函数在 DOM 更新完成后执行,从而获取到最新的 DOM 状态。
  • emit原理(emit原理 (emit原理(emit principle)
    • $emit 是 Vue 组件通信的一种方式,用于子组件向父组件发送事件。它基于 Vue 实例的事件系统。子组件通过 $emit('eventName', payload) 触发一个事件,父组件通过 @eventName="handler" 监听并处理这个事件。
  • computed和watch的区别 (Differences between computed and watch)
    • Computed (计算属性)
      • 基于它们的响应式依赖进行缓存。只有当依赖变化时,才会重新求值。
      • 默认是同步的。
      • 用于处理模板中需要复杂逻辑计算的数据,通常用于派生状态。
      • 必须有返回值。
    • Watch (侦听器)
      • 用于观察和响应 Vue 实例上的数据变化。
      • 当数据变化时,执行一个副作用函数。
      • 可以执行异步操作。
      • 通常用于执行数据变化后的复杂操作,如网络请求、DOM 操作等。
  • Vue那个生命周期可以操作dom (Which Vue lifecycle hook can operate on DOM?)
    • mounted:在实例挂载到 DOM 后调用。此时组件的模板已经渲染到 DOM 中,可以进行 DOM 操作。
    • updated:在组件因数据更改而重新渲染后调用。此时 DOM 已经更新,也可以进行 DOM 操作,但应避免在此钩子中修改状态,可能导致无限循环。

其他通用问题 (Other General Questions)

这些问题涵盖了工具、兼容性、安全和个人职业选择。

1. 工具与构建 (Tools & Build)

  • webpack你了解吗?(Do you know webpack?)
    • Webpack 是一个静态模块打包器。当 Webpack 处理应用程序时,它会递归地构建一个依赖关系图,其中包含应用程序所需的每个模块,然后将所有这些模块打包成一个或多个 bundle。
    • 核心概念:Entry(入口)、Output(输出)、Loader(加载器)、Plugin(插件)、Mode(模式)。
  • 你的图片压缩怎么做的?(How do you do image compression?)
    • 可以是在构建时(如使用 Webpack 插件 image-webpack-loader)、上传时(服务器端处理)、或运行时(如使用 <picture> 标签、srcset 属性、WebP 格式)。
  • 如果要做兼容性,你会怎么做?(How would you handle compatibility issues?)
    • Polyfill:用于弥补新旧浏览器之间API的差异。
    • Babel:将ES6+代码转换为ES5,以兼容旧浏览器。
    • Autoprefixer:自动添加CSS供应商前缀。
    • CSS Reset/Normalize.css:统一不同浏览器默认样式。
    • 渐进增强/优雅降级:设计策略。
    • 浏览器兼容性测试:使用工具或手动测试。

2. 安全 (Security)

  • 登陆校验方法 (Login validation methods)
    • Session-Cookie: 服务器创建Session,将Session ID存在Cookie中返回给客户端,客户端每次请求带上Cookie,服务器根据Session ID识别用户。
    • Token-based (JWT): 客户端登录成功后,服务器返回一个JWT (JSON Web Token),客户端将Token存储(如LocalStorage),每次请求在Header中携带Token,服务器验证Token有效性。
    • OAuth2 / OpenID Connect: 用于第三方登录授权。
  • 说到了nodejs,问nodejs怎么实现token?(应该是想问底层原理吧)(Mentioned Node.js, how does Node.js implement tokens? (Likely asking about underlying principles))
    • 在 Node.js 中实现 Token 通常指 JWT (JSON Web Token)。
    • 原理:使用 jsonwebtoken 等库。当用户登录时,服务器使用一个密钥对用户ID、角色等信息进行签名,生成一个JWT。这个JWT包含三部分:Header(头部)、Payload(载荷)和Signature(签名)。客户端收到JWT后存储起来。每次请求时,客户端将JWT放在HTTP请求的 Authorization 头部。服务器收到请求后,使用相同的密钥验证JWT的签名,如果签名有效且未过期,则认为用户已认证。
  • SSL加密细节 (SSL encryption details)
    • SSL/TLS 握手过程:
      1. ClientHello: 客户端发送支持的SSL/TLS版本、加密套件、随机数等。
      2. ServerHello: 服务器选择一个加密套件,发送证书(包含公钥)、随机数。
      3. Certificate: 客户端验证服务器证书的合法性(通过CA)。
      4. ClientKeyExchange: 客户端生成一个预主密钥,用服务器公钥加密后发送给服务器。
      5. ChangeCipherSpec: 客户端和服务器分别使用预主密钥生成会话密钥(对称密钥)。
      6. Finished: 双方使用会话密钥发送加密的握手消息,验证握手是否成功。
    • 之后的数据传输都使用对称密钥进行加密。

3. 个人与职业 (Personal & Career)

  • 为啥想做前端 (Why do you want to be a front-end developer?)
    • 这是一个开放性问题,需要你表达对前端的热情、兴趣点(如用户体验、可视化、技术发展快等)、个人优势与前端的契合度。
  • 学习前端的过程是怎么样的 (What was your front-end learning process like?)
    • 描述你的学习路径,例如从HTML/CSS/JS基础开始,到框架(React/Vue),再到构建工具(Webpack),以及如何解决问题、参与项目等。
  • 有学过算法和数据结构吗?(Have you studied algorithms and data structures?)
    • 前端开发中,算法和数据结构虽然不像后端那样核心,但在优化性能、解决复杂问题(如虚拟列表、树形结构操作)时非常重要。诚实回答并说明自己在前端场景下的应用或学习意愿。
  • 我们这个工作可能三四天都会花在兼容性问题上,你能接受吗 (Our work might involve spending three or four days on compatibility issues, can you accept that?)
    • 这是一个考察你对工作内容预期和抗压能力的问题。通常应该表示理解和接受,并强调自己有解决兼容性问题的能力和耐心。

希望这份详细的总结和归纳对你有所帮助!祝你面试顺利!
在这里插入图片描述
在这里插入图片描述

我将根据面试问题分类详细解答,并提供扩展知识:

一、Web存储相关

  1. localStorage和cookie的区别

    • 存储容量:cookie约4KB,localStorage约5MB
    • 生命周期:cookie可设置过期时间,localStorage永久存储(除非手动清除)
    • 通信:cookie会随HTTP请求自动发送,localStorage不会
    • 访问限制:cookie可设置domain/path限制,localStorage遵循同源策略
  2. 设置cookie示例

document.cookie = "username=John; expires=Thu, 18 Dec 2025 12:00:00 UTC; path=/";
document.cookie = "useremail=john@example.com; max-age=3600; secure";

二、跨域问题

  1. 跨域解决方案

    • CORS(服务端设置Access-Control-Allow-Origin
    • JSONP(利用

三、JavaScript核心

  1. 变量存储

    • 基本类型:Undefined、Null、Boolean、Number、String、Symbol(栈存储)
    • 引用类型:Object(堆存储,栈存指针)
  2. let/const/var区别

    // 作用域
    var a = 1; // 函数作用域
    let b = 2; // 块级作用域
    const c = 3; // 块级作用域
    
    // 变量提升
    console.log(d); // undefined(var会提升)
    var d = 4;
    
    // 重复声明
    var e = 5;
    var e = 6; // 允许
    let f = 7;
    let f = 8; // 报错
    
  3. const的可变性

    • 不可变:基本类型(Number, String等)
    • 可变:引用类型(Object, Array等)的属性可修改

四、ES6+特性

  1. Set和Map

    • Set:值唯一的集合,常用方法add/delete/has
    • Map:键值对集合,键可以是任意类型,保持插入顺序
  2. Promise进阶

    • Promise.all:全部成功则返回结果数组,一个失败立即reject
    • Promise.race:第一个settled的promise决定结果
    • 新增方法:Promise.allSettled(等所有promise完成)

五、Vue框架

  1. 虚拟DOM

    • 本质是JS对象(轻量级DOM描述)
    • 更新流程:数据变化 → 新vnode → diff算法 → 补丁更新
    • 递归处理:确实会递归到最深层,但通过diff算法优化
  2. Vuex核心

    // mutation必须是同步函数
    mutations: {
      increment(state) {
        state.count++
      }
    }
    
    // action可以包含异步操作
    actions: {
      async fetchData({ commit }) {
        const res = await api.getData();
        commit('SET_DATA', res.data);
      }
    }
    

六、手撕代码

  1. 深拷贝实现
function deepClone(obj, map = new WeakMap()) {
  if (obj === null || typeof obj !== 'object') return obj;
  if (map.has(obj)) return map.get(obj);
  
  const clone = Array.isArray(obj) ? [] : {};
  map.set(obj, clone);
  
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      clone[key] = deepClone(obj[key], map);
    }
  }
  return clone;
}
  1. 防抖与节流
// 防抖(延迟执行)
function debounce(fn, delay) {
  let timer;
  return function(...args) {
    clearTimeout(timer);
    timer = setTimeout(() => fn.apply(this, args), delay);
  };
}

// 节流(固定频率执行)
function throttle(fn, interval) {
  let lastTime = 0;
  return function(...args) {
    const now = Date.now();
    if (now - lastTime >= interval) {
      fn.apply(this, args);
      lastTime = now;
    }
  };
}
  1. 三数之和(LeetCode 15):
function threeSum(nums) {
  nums.sort((a, b) => a - b);
  const res = [];
  for (let i = 0; i < nums.length - 2; i++) {
    if (i > 0 && nums[i] === nums[i - 1]) continue;
    let left = i + 1, right = nums.length - 1;
    while (left < right) {
      const sum = nums[i] + nums[left] + nums[right];
      if (sum === 0) {
        res.push([nums[i], nums[left], nums[right]]);
        while (left < right && nums[left] === nums[left + 1]) left++;
        while (left < right && nums[right] === nums[right - 1]) right--;
        left++;
        right--;
      } else if (sum < 0) {
        left++;
      } else {
        right--;
      }
    }
  }
  return res;
}

七、Webpack相关

  1. Loader与Plugin

    • Loader:文件转换器(如babel-loader转译JS,css-loader处理CSS)
    • Plugin:扩展功能(如HtmlWebpackPlugin生成HTML文件)
  2. Vue3打包

    • 主流方案:Vite(基于ESM的极速开发体验)
    • 传统方案:webpack + vue-loader

建议结合具体项目经验补充回答,例如提到localStorage时可以举例说明在项目中如何用于保存用户偏好设置,讨论跨域时可以说实际项目中如何配置代理等。对于框架问题,最好能对比React的类似机制(如虚拟DOM的diff算法差异)。


在这里插入图片描述

1. React会吗?Vue2和Vue3说说你的看法和理解

React

React 是一个基于 组件化虚拟DOM 的前端框架,核心特点:

  • 单向数据流(数据自上而下传递,状态管理依赖Redux/MobX)
  • JSX语法(JavaScript + XML,增强代码可读性)
  • 函数式编程(Hooks API,如useStateuseEffect
  • 高性能虚拟DOM(Diff算法优化渲染)
Vue2 vs Vue3
特性 Vue2 Vue3
响应式原理 Object.defineProperty(无法监听新增属性) Proxy(全量监听,性能更好)
Composition API 无(Options API) 支持(逻辑复用更灵活)
性能优化 虚拟DOM全量Diff PatchFlag(静态标记,减少Diff计算)
TypeScript支持 一般 深度集成
打包体积 较大 Tree-shaking优化,更小
生命周期 beforeCreatecreated setup()替代部分生命周期

Vue3优势

  • 更好的性能(Proxy响应式、静态提升)
  • 更好的代码组织(Composition API)
  • 更好的TS支持
  • 更小的包体积

2. SSL加密细节

SSL(Secure Sockets Layer)现已被TLS(Transport Layer Security)取代,但习惯仍称SSL。

SSL/TLS加密流程(HTTPS)
  1. Client Hello:客户端发送支持的加密算法、随机数(Client Random)
  2. Server Hello:服务端返回选择的加密算法、随机数(Server Random)、证书
  3. 证书验证:客户端验证证书(CA机构签发,防止中间人攻击)
  4. 密钥交换
    • RSA:客户端用公钥加密Pre-Master Key,服务端私钥解密
    • ECDHE(更安全):基于椭圆曲线动态生成会话密钥
  5. 会话密钥生成:Client Random + Server Random + Pre-Master Key → 生成对称加密密钥
  6. 加密通信:后续数据使用对称加密(AES)传输

加密算法

  • 非对称加密(密钥交换):RSA、ECDHE
  • 对称加密(数据传输):AES、ChaCha20
  • 哈希校验:SHA-256

3. 浏览器缓存

浏览器缓存分为 强缓存协商缓存

强缓存(无需请求服务器)
  • HTTP Header
    • Cache-Control: max-age=3600(优先级高,单位秒)
    • Expires: Wed, 21 Oct 2025 07:28:00 GMT(HTTP/1.0,受本地时间影响)
  • 缓存位置
    • Memory Cache(内存,快速但容量小)
    • Disk Cache(硬盘,持久但较慢)
协商缓存(需请求服务器验证)
  • Last-Modified / If-Modified-Since(基于时间)
    • 服务器返回Last-Modified,客户端下次带If-Modified-Since
    • 缺点:1秒内修改无法检测
  • ETag / If-None-Match(基于内容哈希,更精准)
    • 服务器返回ETag,客户端下次带If-None-Match

缓存过程

  1. 检查Cache-Control/Expires → 命中强缓存直接返回
  2. 未命中则发送请求,服务器检查If-Modified-Since/If-None-Match
  3. 资源未变更 → 304 Not Modified(用缓存)
  4. 资源变更 → 200 OK(返回新资源)

4. 手写发布订阅模式(Pub-Sub)及优化

基础实现
class EventEmitter {
  constructor() {
    this.events = {};
  }

  on(event, callback) {
    if (!this.events[event]) this.events[event] = [];
    this.events[event].push(callback);
  }

  emit(event, ...args) {
    if (this.events[event]) {
      this.events[event].forEach(cb => cb(...args));
    }
  }

  off(event, callback) {
    if (this.events[event]) {
      this.events[event] = this.events[event].filter(cb => cb !== callback);
    }
  }
}

// 使用示例
const emitter = new EventEmitter();
emitter.on("message", (data) => console.log(data));
emitter.emit("message", "Hello World!");
优化方向
  1. 防止内存泄漏:增加once方法(执行后自动取消订阅)
  2. 性能优化:用Map代替Object(查找更快)
  3. 错误处理try-catch包裹回调执行
  4. 异步支持setTimeoutPromise处理异步事件

5. 跨域

原因

浏览器同源策略限制(协议+域名+端口一致)。

解决方案
  1. CORS(服务端设置)
    Access-Control-Allow-Origin: *
    Access-Control-Allow-Methods: GET, POST
    Access-Control-Allow-Headers: Content-Type
    
  2. JSONP(仅GET请求)
    function handleResponse(data) {
      console.log(data);
    }
    const script = document.createElement("script");
    script.src = "https://api.example.com/data?callback=handleResponse";
    document.body.appendChild(script);
    
  3. 代理服务器(开发环境常用)
    // webpack.config.js
    devServer: {
      proxy: {
        "/api": "http://localhost:3000",
      },
    },
    
  4. Nginx反向代理
    location /api {
      proxy_pass http://backend-server;
    }
    

6. TCP三次握手 & 四次挥手

三次握手(建立连接)
  1. SYN:客户端发送SYN=1, seq=x
  2. SYN-ACK:服务端回复SYN=1, ACK=1, seq=y, ack=x+1
  3. ACK:客户端发送ACK=1, seq=x+1, ack=y+1

目的:确认双方收发能力正常,防止历史连接干扰。

四次挥手(断开连接)
  1. FIN:客户端发送FIN=1, seq=u
  2. ACK:服务端回复ACK=1, ack=u+1(半关闭状态)
  3. FIN:服务端发送FIN=1, seq=v
  4. ACK:客户端回复ACK=1, ack=v+1(等待2MSL后关闭)

为什么四次?
因为TCP是全双工,需分别关闭发送和接收通道。


7. nextTick原理和底层

Vue的nextTick

用于在DOM更新后执行回调,基于 微任务队列 实现。

实现原理
  1. 优先使用微任务Promise.then > MutationObserver > setImmediate > setTimeout
  2. 回调队列:将回调函数存入队列,在下一个事件循环执行

示例代码

let callbacks = [];
let pending = false;

function flushCallbacks() {
  pending = false;
  const copies = callbacks.slice();
  callbacks = [];
  for (let cb of copies) cb();
}

function nextTick(cb) {
  callbacks.push(cb);
  if (!pending) {
    pending = true;
    Promise.resolve().then(flushCallbacks);
  }
}

8. Promise并发、嵌套及底层原理

Promise并发控制
function limitRequest(urls, limit) {
  const results = [];
  let count = 0;

  async function run() {
    while (urls.length && count < limit) {
      const url = urls.shift();
      count++;
      try {
        const res = await fetch(url);
        results.push(res);
      } catch (err) {
        results.push(err);
      } finally {
        count--;
        if (urls.length) run();
      }
    }
  }

  run();
  return results;
}
Promise嵌套(回调地狱)
fetch("/api/user")
  .then(user => fetch(`/api/profile/${user.id}`))
  .then(profile => fetch(`/api/posts/${profile.id}`))
  .then(posts => console.log(posts));
底层原理

Promise基于 状态机 实现:

  • 状态pendingfulfilledrejected
  • then方法:返回新Promise,支持链式调用
  • 微任务队列then回调放入微任务队列

9. new过程发生了什么

function myNew(constructor, ...args) {
  // 1. 创建空对象,继承原型
  const obj = Object.create(constructor.prototype);
  
  // 2. 执行构造函数,绑定this
  const result = constructor.apply(obj, args);
  
  // 3. 如果构造函数返回对象,则使用它
  return result instanceof Object ? result : obj;
}

// 示例
function Person(name) {
  this.name = name;
}
const p = myNew(Person, "John");

10. 浏览器缓存(详细)

第3部分,补充:

  • Cache-Control指令
    • no-cache:协商缓存
    • no-store:禁用缓存
    • must-revalidate:过期后必须验证

11. 算法与数据结构

常见前端相关算法:

  • 排序:快速排序、归并排序
  • 搜索:二分查找
  • 数据结构:栈、队列、链表、二叉树(虚拟DOM Diff用)
  • LeetCode高频题:两数之和、LRU缓存、反转链表

12. 为什么选前端?学习过程?

为什么选前端
  • 即时反馈:所见即所得,快速验证想法
  • 技术栈丰富(HTML/CSS/JS、框架、Node.js)
  • 市场需求大(Web、移动端、Electron等)
学习过程
  1. 基础:HTML/CSS/JavaScript(《JavaScript高级程序设计》)
  2. 进阶:ES6、Webpack、Vue/React
  3. 工程化:Git、CI/CD、性能优化
  4. 全栈拓展:Node.js、数据库(MySQL/MongoDB)

总结

本文涵盖了前端面试高频问题,建议结合项目经验回答,例如:

  • 提到Vue3时,可对比React Hooks
  • 讨论缓存时,可举例项目中的缓存策略优化
  • 手写代码时,说明优化思路(如Map替代Object

希望这份详细解答能帮助你准备面试! 🚀


在这里插入图片描述
以下是针对您面试问题的全面解析,结合Vue核心原理、浏览器机制、网络通信等模块组织答案,并标注关键技术和易考点:


一、Vue核心原理

  1. $nextTick原理
    Vue的响应式更新采用异步队列机制,当数据变化时,DOM更新会被推入队列,在下一个事件循环中批量执行。$nextTick将回调函数加入队列尾部,确保在DOM更新后执行。
    实现优先级Promise.then > MutationObserver > setImmediate > setTimeout

    // 简化实现
    let pending = false;
    const callbacks = [];
    function nextTick(cb) {
      callbacks.push(cb);
      if (!pending) {
        pending = true;
        Promise.resolve().then(flushCallbacks);
      }
    }
    
  2. $emit原理
    子组件通过this.$emit('event', data)触发自定义事件,父组件通过@event监听。底层是发布订阅模式:Vue实例维护事件中心(_events对象),$emit触发时遍历对应事件回调执行。

  3. computed vs watch

    特性 computed watch
    用途 同步计算新值(如过滤数据) 监听数据变化执行异步/复杂操作
    缓存 依赖不变时复用结果 无缓存,每次变化都执行
    异步支持 ❌ 不支持 ✅ 支持
    典型场景 购物车总价、表单校验 搜索建议、路由参数监听
  4. 操作DOM的生命周期

    • mounted:组件首次渲染完成,DOM已挂载,可安全操作。
    • updated:数据更新导致DOM重新渲染后(慎用,易引发循环更新)。

二、浏览器与HTTP

  1. 强缓存 vs 协商缓存

    类型 响应头 状态码 优先级
    强缓存 Cache-Control: max-age=3600 200 (from disk/memory cache)
    协商缓存 ETag/If-None-Match 304
    过程:强缓存生效时不请求服务器;失效时携带If-Modified-SinceIf-None-Match向服务器验证。
  2. 跨域解决方案

    • CORS:服务端设置Access-Control-Allow-Origin
    • JSONP:利用<script>标签无跨域限制
      <script src="https://api.com/data?callback=handleData"></script>
      
    • 代理服务器:开发环境用webpack-dev-server代理,生产环境用Nginx反向代理。
  3. HTTP/2.0新特性

    • 多路复用:一个TCP连接并行传输多个请求/响应,解决HTTP/1.1队头阻塞
    • 二进制分帧、头部压缩、服务器推送
      多路复用示例
      !https://example.com/http2-multiplexing.png
      (图示:多个流共享同一连接)
  4. HTTPS加密流程

    1. 客户端发送加密算法列表 + 随机数A
    2. 服务器返回证书 + 随机数B
    3. 客户端验证证书(CA机构签发)
    4. 用证书公钥加密预主密钥发送
    5. 双方用随机数A+B+预主密钥生成对称加密密钥
    6. 后续通信使用对称加密(如AES)。

三、CSS与DOM

  1. 垂直居中方案

    /* 方案1:Flex (推荐) */
    .parent { display: flex; align-items: center; justify-content: center; }
    
    /* 方案2:Grid */
    .parent { display: grid; place-items: center; }
    
    /* 方案3:绝对定位 + transform */
    .child { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); }
    
  2. 回流(reflow) vs 重绘(repaint)

    操作 触发条件 性能影响
    回流 尺寸/位置/结构变化 ⚠️ 高
    重绘 颜色/背景等样式变化 ⚠️ 中
    优化建议
    • 避免频繁操作DOM,使用documentFragment
    • 用CSS3动画(触发GPU加速)替代JS动画。

四、其他核心问题

  1. Node.js实现Token
    流程

    const crypto = require('crypto');
    // 生成Token(JWT简化版)
    function createToken(payload, secret) {
      const header = Buffer.from(JSON.stringify({ alg: 'HS256' })).toString('base64');
      const body = Buffer.from(JSON.stringify(payload)).toString('base64');
      const sign = crypto.createHmac('sha256', secret).update(`${header}.${body}`).digest('base64');
      return `${header}.${body}.${sign}`;
    }
    // 验证时重新计算签名对比
    
  2. CommonJS vs ES6模块化

    特性 CommonJS ES6 Modules
    加载方式 运行时加载(同步) 编译时静态分析
    输出 module.exports export/import
    引用类型 值的拷贝(基础类型) 值的引用(实时绑定)
  3. 深拷贝实现与必要性
    原因:对象赋值仅复制引用,修改嵌套对象会污染原数据。
    手写深拷贝

function deepClone(obj, map = new WeakMap()) {
  if (typeof obj !== 'object' || obj === null) return obj;
  if (map.has(obj)) return map.get(obj); // 解决循环引用
  const clone = Array.isArray(obj) ? [] : {};
  map.set(obj, clone);
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) clone[key] = deepClone(obj[key], map);
  }
  return clone;
}
  1. 发布订阅模式手写
class EventEmitter {
  constructor() { this.events = {}; }
  on(event, cb) {
    (this.events[event] || (this.events[event] = [])).push(cb);
  }
  emit(event, ...args) {
    this.events[event]?.forEach(cb => cb(...args));
  }
  off(event, cb) {
    this.events[event] = this.events[event]?.filter(fn => fn !== cb);
  }
}
// 优化点:增加once()、错误处理、异步执行

五、面试策略建议

  1. React弥补方案
    • 快速学习React核心概念(组件化、Hooks、状态管理)
    • 强调Vue底层原理的掌握(如虚拟DOM Diff、响应式实现)。
  2. 项目亮点突出
    • 在自我介绍中量化成果,如“Vue2升Vue3提升构建速度80%”
    • 主动引导技术提问(如提到性能优化引面试官追问)。
  3. 框架对比
    方向 Vue优势 React优势
    响应式 Proxy深度监听 不可变数据+手动优化
    模板语法 SFC单文件组件开发高效 JSX灵活性强

面试核心在于 原理深度 + 实战亮点,即使部分问题未答全,展示出学习能力和技术热情也能加分。建议针对React补强基础概念,同时深化Vue原理理解(如虚拟DOM源码、依赖收集过程)。


在这里插入图片描述
以下是针对您提出的技术问题的系统性解答,结合原理与实践经验详细展开:


⚙️ 1. Vue双向绑定原理

实现机制

  • Vue2:基于Object.defineProperty劫持数据属性的getter/setter,通过依赖收集(Dep类)观察者模式(Watcher) 实现:
    • 数据读取时触发getter,将当前Watcher添加到Dep订阅列表。
    • 数据修改时触发setter,通知Dep所有Watcher更新视图。
  • Vue3:改用Proxy代理整个对象,支持动态增删属性及深层嵌套监听,性能更高。

流程示例

// 简化版数据劫持
function defineReactive(obj, key) {
  const dep = new Dep();
  let val = obj[key];
  Object.defineProperty(obj, key, {
    get() {
      dep.depend(); // 收集依赖
      return val;
    },
    set(newVal) {
      val = newVal;
      dep.notify(); // 通知更新
    }
  });
}

🖼️ 2. 图片压缩方案

前端实现要点

  • Canvas压缩:调整尺寸与质量
    function compressImage(file, quality = 0.8) {
      const canvas = document.createElement('canvas');
      const ctx = canvas.getContext('2d');
      const img = new Image();
      img.onload = () => {
        canvas.width = img.width * 0.5; // 尺寸减半
        canvas.height = img.height * 0.5;
        ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
        canvas.toBlob(blob => {
          // 上传blob对象
        }, 'image/jpeg', quality);
      };
      img.src = URL.createObjectURL(file);
    }
    
  • CDN加速:上传压缩后图片至CDN,利用边缘节点缓存减少加载时间。

🌐 3. URL到页面渲染过程

关键步骤

  1. DNS解析:域名 → IP地址(本地缓存 → 递归查询根域、顶级域等)。
  2. TCP连接:三次握手建立可靠连接。
  3. HTTP请求:发送请求头/体,服务器返回响应。
  4. 解析渲染
    • 构建DOM树:解析HTML生成节点树。
    • 构建CSSOM:解析CSS样式。
    • 合成渲染树:合并DOM与CSSOM,计算布局与绘制。

🔍 4. DNS解析详细过程

分层查询流程

  1. 浏览器缓存 → 系统缓存(hosts文件) → 路由器缓存。
  2. 本地DNS服务器 → 根域名服务器(返回顶级域地址) → .com域服务器 → 目标域名服务器。
    CDN关联
  • 智能DNS解析用户位置,返回最近的CDN节点IP,加速资源访问。

🤝 5. 三次握手与四次挥手

  • 三次握手(建立连接):
    1. 客户端→服务端:SYN=1, seq=x
    2. 服务端→客户端:SYN=1, ACK=1, seq=y, ack=x+1
    3. 客户端→服务端:ACK=1, seq=x+1, ack=y+1。
  • 四次挥手(断开连接):
    1. 客户端→服务端:FIN=1
    2. 服务端→客户端:ACK=1(半关闭)
    3. 服务端→客户端:FIN=1
    4. 客户端→服务端:ACK=1(等待2MSL关闭)。

🧩 6. Class与函数式组件互用性

  • Class组件使用Hooks:❌ 不可用,Hooks仅适用于函数组件。
  • 函数组件模拟Class语法:✅ 可通过闭包+useState/useEffect实现状态管理,但违反设计原则。

⚡ 7. 组件优化与函数组件优势

优化方向 Class组件 函数组件
优化手段 shouldComponentUpdate React.memo
状态逻辑复用 HOC或Render Props Hooks(useState/useEffect)
打包体积 较大(需继承) 更小(无this绑定)
性能 实例化开销大 轻量,适合频繁更新场景

函数组件核心优势

  • 逻辑复用更灵活(自定义Hooks)。
  • 避免this指向问题,代码更简洁。

📦 8. Webpack工程化实践

常用能力

  • Loader:处理非JS资源(如babel-loader转译ES6+)。
  • Plugin:扩展功能(HtmlWebpackPlugin生成HTML)。
  • 代码分割SplitChunksPlugin拆分公共代码。

兼容性方案

  1. JS兼容:Babel + @babel/preset-env + core-js按需polyfill。
  2. CSS兼容:PostCSS + autoprefixer自动加前缀。
  3. Polyfill服务:动态注入(如polyfill.io)。

✅ 9. 兼容性工作接受度

  • 合理投入:若为必要业务需求(如政府/银行需兼容IE),可接受短期集中处理。
  • 效率建议
    • 使用自动化工具(如ESLint检测语法兼容性)。
    • 建立浏览器兼容矩阵,优先级分级处理。

💎 总结建议

  1. 原理深挖:如双向绑定需说清Vue2/Vue3差异,DNS解析关联CDN优化。
  2. 工程思维:图片压缩结合CDN、Webpack拆分polyfill提升效率。
  3. 框架理解:函数组件+Hooks是趋势,掌握逻辑复用与性能优化点。

接受兼容性工作需明确范围与工具支持,避免低效重复劳动。以上方案可大幅提升开发效率,缩短适配周期。


在这里插入图片描述


在这里插入图片描述
以下针对您提出的问题,结合前端核心原理与实践经验进行系统化解析:


🔐 一、登录 Token 存储与 Cookie 安全配置

  1. Token 存本地 vs Cookie

    • Token 存 LocalStorage 的原因
      • SPA 架构适配:前后端分离项目中,前端需主动控制 Token 发送逻辑(如 Authorization: Bearer <token>),LocalStorage API 更灵活。
      • 规避 CSRF:Token 不自动随请求发送,避免因 Cookie 自动携带导致的跨站请求伪造风险。
      • 跨域支持:LocalStorage 数据不会自动发送,适合跨域 API 调用场景。
    • Cookie 的适用场景
      • 传统服务端渲染(SSR)项目,依赖自动发送机制。
      • 需严格防御 XSS 时,配合 HttpOnly 属性(见下文)。
  2. 配置 Cookie 防 JS 操作
    通过服务端设置安全属性:

    Set-Cookie: token=abc123; HttpOnly; Secure; SameSite=Strict; Max-Age=3600
    
    • HttpOnly:禁止 JavaScript 读取 Cookie,彻底防御 XSS 窃取。
    • Secure:仅通过 HTTPS 传输,防止中间人攻击。
    • SameSite=Strict:阻止跨站请求携带 Cookie,根治 CSRF。

🔄 二、协商缓存详解

  • 流程
    1. 首请 → 服务器返回资源 + ETag(哈希标识)或 Last-Modified(修改时间)。
    2. 再请 → 浏览器带 If-None-Match(ETag值)或 If-Modified-Since(时间戳)。
    3. 服务器比对:
      • 未变更 → 304 Not Modified(空响应体,用本地缓存)。
      • 已变更 → 200 OK + 新资源。
  • 对比强缓存
    特性 强缓存 协商缓存
    网络请求 无(直接读缓存) 有(服务器验证)
    响应码 200 (from disk/memory) 304 Not Modified
    适用资源 静态资源(JS/CSS/图片) 频繁更新资源(如用户数据)

⚠️ 三、HTTP 状态码 401/402/403

状态码 含义 典型场景
401 Unauthorized 未携带 Token 或 Token 无效(需重新登录)。
403 Forbidden 已认证但权限不足(如普通用户访问管理员接口)。
402 Payment Required 保留状态码,实际极少使用(原设计用于支付场景)。

⚙️ 四、Cache-Control 关键属性

属性 作用
max-age=3600 资源有效期(秒),优先级高于 Expires
no-cache 禁用强缓存,每次需向服务器验证(仍可缓存)。
no-store 彻底禁用缓存(敏感数据场景)。
public 允许代理服务器(CDN)缓存。
private 仅允许浏览器缓存(禁止代理缓存)。
must-revalidate 缓存过期后必须向服务器验证。

🖖 五、Vue 的 MVVM 模式

  • 核心流程
    双向绑定
    监听DOM事件
    指令解析
    更新通知
    数据层
    视图模型
    视图层
    • ViewModel:Vue 实例,通过 Data Binding 实现:
      • 数据变化 → 自动更新 DOM(v-bind/{{}})。
      • DOM 事件 → 自动更新数据(v-on/v-model)。
    • 与传统 MVC 区别:无需手动操作 DOM(如 jQuery),由框架自动驱动视图更新。

🧵 六、JS 单线程与浏览器多线程

  1. JS 单线程原因

    • 避免 DOM 操作冲突:多线程同时修改 DOM 会导致渲染结果不可控(如一个线程删节点,另一个线程修改其样式)。
    • 历史设计约束:作为浏览器脚本语言,最初定位为轻量级交互工具。
  2. 浏览器多线程协作

    线程 职责
    JS 引擎线程 执行 JS 代码(主线程)。
    GUI 渲染线程 解析 HTML/CSS、布局、绘制(与 JS 引擎互斥)。
    异步 HTTP 线程 处理网络请求(fetch/XMLHttpRequest),完成后回调推入任务队列。
    定时器线程 管理 setTimeout/setInterval,计时结束回调入队。

📡 七、WebSocket 连接维护

  • 心跳机制
    // 客户端定时发送心跳包
    const ws = new WebSocket('wss://api.example.com');
    const heartbeatInterval = setInterval(() => {
      if (ws.readyState === WebSocket.OPEN) {
        ws.send(JSON.stringify({ type: 'heartbeat' }));
      }
    }, 30000); // 30秒一次
    
    // 服务端超时断开:若未收到心跳,关闭连接
    
  • 自动重连:监听 onclose 事件,尝试重新建立连接。
  • 帧控制WebSocket.bufferedAmount 检查未发送数据量,避免拥塞。

📏 八、Vue 列表高度获取场景题

正确方案:使用 ref 获取 DOM 高度(无需等待网络请求)

<template>
  <ul ref="listRef">
    <li v-for="item in list" :key="item.id">{{ item.name }}</li>
  </ul>
</template>

<script>
export default {
  data() {
    return { list: [] };
  },
  async mounted() {
    // 1. 请求数据
    this.list = await fetchList(); 
    // 2. 数据更新后DOM已渲染,通过ref获取高度
    this.$nextTick(() => {
      const height = this.$refs.listRef.clientHeight;
      console.log('列表高度:', height);
    });
  }
};
</script>

错误思路分析

  • Promise.all 封装请求:网络请求完成 ≠ DOM 渲染完成,需等待 Vue 更新视图。
  • setTimeout 延迟获取:不可靠,渲染时间受设备性能影响。

关键点

  • ref 绑定:直接访问渲染后的 DOM 元素。
  • $nextTick:确保 DOM 更新后执行回调,避免读取到旧布局。

💎 总结

  • 安全存储:Token 放 LocalStorage 利于 SPA 控制,Cookie 需配置 HttpOnly+Secure+SameSite 三位一体防护。
  • 缓存策略:静态资源强缓存(max-age=31536000),动态数据协商缓存(ETag)。
  • Vue 设计:MVVM 通过数据绑定解放手动 DOM 操作,ref+nextTick 是访问渲染后 DOM 的标准方案。
  • 单线程本质:JS 单线程为避免 DOM 冲突,浏览器通过多线程协作支持异步。

面试技巧:遇到“获取渲染后高度”类问题,优先考虑 ref 直取 DOM 而非依赖请求状态,结合 nextTick 确保时机准确。


在这里插入图片描述
以下是针对前端面试题的详细解答,结合核心原理与最佳实践,帮助您系统化掌握知识点:


1. 为什么选择前端开发?

  • 核心动机
    • 即时反馈:所见即所得(如动画、交互效果),快速验证想法。
    • 技术广度:涵盖视觉设计(CSS)、逻辑(JavaScript)、工程化(Webpack)、跨端(Electron/React Native)。
    • 影响力:直接塑造用户体验,业务价值可视化强(如数据看板、高交互应用)。

2. React 生命周期(类组件)

React 生命周期分为三个阶段:

挂载阶段
  • constructor:初始化 state,绑定方法。
  • static getDerivedStateFromProps(props, state):根据 props 更新 state(需返回对象或 null)。
  • render:返回 JSX。
  • componentDidMount:DOM 操作、网络请求、订阅事件。
更新阶段
  • static getDerivedStateFromProps(同上)。
  • shouldComponentUpdate(nextProps, nextState):性能优化,返回 false 阻止渲染。
  • render:重新渲染。
  • getSnapshotBeforeUpdate(prevProps, prevState):DOM 更新前捕获信息(如滚动位置),返回值传给 componentDidUpdate
  • componentDidUpdate(prevProps, prevState, snapshot):更新后操作(如基于 snapshot 调整 UI)。
卸载阶段
  • componentWillUnmount:清理定时器、取消网络请求、移除订阅。

为何废弃 componentWillMount 等?
React Fiber 架构引入异步渲染,旧钩子可能被多次调用,导致副作用(如重复请求)。替代方案:

  • 数据请求移至 componentDidMount
  • 状态派生用 getDerivedStateFromProps

3. JavaScript 事件循环(Event Loop)

  • 单线程模型:JS 主线程执行同步任务,异步任务由浏览器的多线程模块处理(如网络请求线程、定时器线程)。
  • 任务队列
    • 宏任务(Macro Task)setTimeoutsetInterval、I/O、UI 渲染。
    • 微任务(Micro Task)Promise.thenMutationObserverqueueMicrotask
  • 执行顺序
    1. 执行同步任务(调用栈)。
    2. 清空微任务队列(优先级高)。
    3. 取一个宏任务执行,重复步骤 2。
// 示例
setTimeout(() => console.log("宏任务"), 0);
Promise.resolve().then(() => console.log("微任务"));
// 输出顺序:微任务 → 宏任务

4. URL 输入到页面渲染的流程

  1. DNS 解析:域名 → IP 地址(查询本地缓存 → 递归查询根域)。
  2. TCP 连接:三次握手建立可靠传输。
  3. HTTP 请求:浏览器发送请求头 + 请求体。
  4. 服务器响应:返回状态码(如 200)、响应头、HTML 文件。
  5. 解析渲染
    • 构建 DOM 树:HTML 解析为节点树(遇到 <script> 阻塞解析)。
    • 构建 CSSOM:解析 CSS 为样式树。
    • 合成渲染树:合并 DOM + CSSOM,计算布局与绘制。
    • 重排(Reflow)与重绘(Repaint):动态修改 DOM/CSS 触发。

5. DOM 树与 CSSOM 树的构建关系

  • 并行下载:HTML 解析时,预解析线程提前加载 CSS/JS 资源。
  • 串行构建
    • CSSOM 构建会阻塞渲染树合成(避免无样式内容闪烁)。
    • JS 执行会阻塞 DOM 构建(JS 可能修改 DOM/CSS)。

优化建议:CSS 内联或优先加载,JS 用 async/defer 避免阻塞。


6. HTTP 状态码 301、302、304

状态码 含义 典型场景
301 永久重定向 域名迁移(SEO 权重转移)
302 临时重定向 登录跳转(保留原 URL SEO 权重)
304 资源未修改(协商缓存) 浏览器缓存有效,服务器直接返回空响应

7. 强缓存与协商缓存

强缓存(无需请求服务器)
  • 响应头设置
    Cache-Control: max-age=3600      # 有效期(秒)
    Expires: Wed, 21 Oct 2025 07:28:00 GMT  # 过期时间(HTTP/1.0)
    
  • 缓存位置Memory Cache(内存)、Disk Cache(硬盘)。
协商缓存(需服务器验证)
  • 响应头设置
    ETag: "d41d8cd98f00b204e9800998ecf8427e"  # 资源哈希标识
    Last-Modified: Wed, 21 Oct 2025 07:28:00 GMT  # 最后修改时间
    
  • 请求头验证
    If-None-Match: "d41d8cd98f00b204e9800998ecf8427e"  # 匹配 ETag
    If-Modified-Since: Wed, 21 Oct 2025 07:28:00 GMT    # 匹配修改时间
    
    • 未变更 → 304 Not Modified(复用缓存)。
    • 已变更 → 200 OK + 新资源

8. 浏览器缓存类型

类型 特性
Memory Cache 内存缓存,快速但容量小,页面关闭即失效(适合静态资源)
Disk Cache 硬盘缓存,持久化存储(适合大文件如 CSS/JS)
Service Worker 离线缓存(需 HTTPS),可拦截请求
Push Cache HTTP/2 服务器推送缓存(会话级,优先级最低)

9. 登录校验方法

Token 认证(主流方案)
  1. 登录流程
    • 用户提交账号密码 → 服务器验证 → 返回 Token(如 JWT)。
  2. Token 存储
    • 安全方案LocalStorage + axios 拦截器添加 Authorization: Bearer <token>
    • 防御 XSS:避免敏感操作,关键接口需二次验证(如短信)。
  3. Token 刷新
    • 短期 Token(1 小时) + 长期 Refresh Token(7 天),到期后自动刷新。
Session-Cookie 认证
  • 流程:服务器生成 Session ID 存入 Cookie(需设置 HttpOnlySecureSameSite)。
  • 缺点:跨域限制、CSRF 风险(需配合 Token 使用)。

10. 用 Hook 实现 componentWillUnmount

在函数组件中使用 useEffect清理函数模拟:

import { useEffect } from 'react';

function MyComponent() {
  useEffect(() => {
    // 组件挂载时执行(类似 componentDidMount)
    const timer = setInterval(() => console.log('Tick'), 1000);
    
    // 返回清理函数(类似 componentWillUnmount)
    return () => {
      clearInterval(timer);
      console.log('定时器已清理');
    };
  }, []); // 空依赖表示仅执行一次

  return <div>组件内容</div>;
}

关键点

  • useEffect 的依赖数组为 [] 时,仅挂载/卸载执行一次。
  • 清理函数在组件卸载前自动触发,用于取消订阅、定时器等。

总结建议

  1. 原理深挖:如事件循环需说清微任务优先机制,缓存设置需区分 max-ageETag 场景。
  2. 框架对比:React 生命周期迁移到 Hooks 是趋势(面试可提 useEffect 替代方案)。
  3. 实战结合:举例优化手段(如 DNS 预解析、CDN 缓存静态资源)。

面试时遇到开放性问题(如“为什么选前端”),关联业务价值(如“通过懒加载提升电商首屏转化率30%”)更易脱颖而出。


网站公告

今日签到

点亮在社区的每一天
去签到