Skip to content

大厂面经

这里收录了我在一线互联网大厂的面试经历与真题复盘。

🏢 北京

🏢 上海

🏢 深圳

🏢 广州/佛山


上海禾赛科技

📌 面试概览

  • 核心:JS 基础深度 + 项目亮点挖掘。
  • 特点:考察数组去重、图片压缩细节。

📝 核心知识点解析

1. 数组去重 (非引用类型)

场景[1, 2, 1, 2] 去重。

  • Set (最简): [...new Set(arr)]
  • Filter (面试官指定):
javascript
const arr = [1, 2, 1, 2];
const unique = arr.filter((item, index) => {
  // indexOf 总是返回第一个匹配项的下标
  // 如果当前下标 === 第一个匹配项下标,说明是第一次出现
  return arr.indexOf(item) === index;
});
  • Map (性能好): 利用 Map 的 Key 唯一性。

2. CORS (跨域资源共享)

  • 简单请求: HEAD/GET/POST,且 Header 仅限 Accept, Accept-Language, Content-Language, Content-Type (限 text/plain, multipart/form-data, application/x-www-form-urlencoded)。
    • 流程: 浏览器直接发送请求,后端返回 Access-Control-Allow-Origin
  • 复杂请求: 其他请求 (如 PUT/DELETE, application/json)。
    • 流程: 浏览器先发 OPTIONS 预检请求 (Preflight),询问服务器是否允许。服务器通过后,再发真实请求。

3. Props 详解 (Vue)

  • 属性: type, default, required, validator (自定义验证)。
  • 内容: 主要是数据 (String/Number/Object),图片通常传 URL 字符串。

4. 图片压缩细节 (项目亮点)

  • 压缩前: PNG/JPEG (体积大)。
  • 压缩后: WebP (体积小,支持透明)。
  • 工具:
    • 开发时: image-webpack-loader / vite-plugin-imagemin.
    • 运行时: Canvas toDataURL('image/jpeg', quality).
    • 服务侧: CDN 自动转换 (阿里云 OSS ?x-oss-process=image/format,webp).

懂车帝 (北京)

📌 面试概览

  • 岗位:Web3D 前端实习
  • 轮次:两轮技术面 (10.30 一面, 10.31 二面)
  • 特点:Web3D 图形学基础 + React 深度 + 浏览器原理 + 算法手撕

📝 核心知识点解析 (一面)

1. requestAnimationFrame (RAF)

  • 原理:由浏览器决定回调频率(通常 60FPS,即 16.6ms 一次),在下一次重绘之前执行。
  • 优点:自动节能(页面隐藏时停止),防止掉帧(与屏幕刷新同步)。
  • 计算帧数 (FPS)
javascript
let lastTime = performance.now();
let frame = 0;
function loop() {
  const now = performance.now();
  frame++;
  if (now - lastTime >= 1000) {
    console.log('FPS:', frame);
    frame = 0;
    lastTime = now;
  }
  requestAnimationFrame(loop);
}
loop();

2. React Hooks: useMemo vs useEffect

Hook作用执行时机代码示例
useMemo缓存计算结果渲染期间执行const val = useMemo(() => compute(a), [a])
useEffect处理副作用 (DOM, 请求)渲染结束后执行useEffect(() => { fetch() }, [])

自定义 Hook 示例 (useWindowSize):

javascript
function useWindowSize() {
  const [size, setSize] = useState({ width: window.innerWidth });
  useEffect(() => {
    const handleResize = () => setSize({ width: window.innerWidth });
    window.addEventListener('resize', handleResize);
    return () => window.removeEventListener('resize', handleResize);
  }, []);
  return size;
}

3. Three.js 三大矩阵

矩阵作用变换过程
模型矩阵 (Model Matrix)物体 -> 世界坐标本地坐标 (0,0,0) -> 放置在场景中
视图矩阵 (View Matrix)世界坐标 -> 相机坐标根据相机位置/朝向变换物体
投影矩阵 (Projection Matrix)相机坐标 -> 裁剪坐标3D 空间 -> 2D 屏幕 (透视/正交)

渲染顺序: Local -> (Model) -> World -> (View) -> Camera -> (Projection) -> Clip -> Screen

4. 事件循环 (Event Loop) 笔试题

题目:输出顺序是 2 3 5 4 1。为什么?

javascript
setTimeout(() => console.log(1)); // 宏任务
new Promise(resolve => {
  console.log(2); // 同步
  resolve();
  console.log(3); // 同步
}).then(() => console.log(4)); // 微任务
console.log(5); // 同步

解析

  1. 同步代码2, 3, 5 依次执行。
  2. 微任务队列then 回调 (4) 入队。
  3. 宏任务队列setTimeout 回调 (1) 入队。
  4. 清空同步 -> 清空微任务 (4) -> 执行宏任务 (1)。

5. 渲染管线:不透明 vs 透明物体

  • 渲染顺序
    1. 先渲染不透明物体(从前向后,利用深度缓冲 Z-Buffer 剔除被遮挡像素,优化性能)。
    2. 后渲染透明物体(从后向前,为了正确混合颜色)。
  • 原因:透明物体需要和后面的颜色混合,如果先渲染透明的,深度写入后,后面的物体会被剔除,导致看不到透明物体背后的东西。

6. Web3D 深度问题 (补充)

  • PBR (Physically Based Rendering): 基于物理的渲染。
    • 核心属性: Albedo (反照率), Metallic (金属度), Roughness (粗糙度), Normal (法线), AO (环境光遮蔽)。
    • 优点: 真实感强,在不同光照下表现一致。
  • SSR Pass (Screen Space Reflection): 屏幕空间反射。
    • 后处理效果,利用已渲染的屏幕像素模拟反射。
  • Draco 压缩:
    • Google 开源的 3D 模型压缩库。
    • 原理: 压缩几何体数据 (顶点位置、法线、UV)。
    • 使用: 需要引入 DracoLoader 和对应的 decoder wasm 文件。

7. JS 基础补充

  • 深拷贝 vs 浅拷贝:
    • 浅拷贝: Object.assign, ...spread (只拷贝一层引用)。
    • 深拷贝: JSON.parse(JSON.stringify) (不支持函数/Symbol), structuredClone (原生), 递归手写。
  • forEach vs map:
    • forEach: 遍历数组,无返回值,会修改原数组 (如果是引用类型)。
    • map: 返回新数组,不修改原数组。
  • 闭包:
    • 定义: 函数有权访问另一个函数作用域中的变量。
    • 优点: 变量私有化,保持状态。
    • 缺点: 内存不释放,易导致内存泄漏。
  • React Key: Diff 算法的核心。用于追踪列表中元素及其状态,提升渲染性能。

8. 设计模式

  • 单例模式: 全局唯一实例 (如 Vuex Store, Modal 弹窗)。
  • 发布订阅模式: on (订阅), emit (发布) (如 EventBus)。
  • 观察者模式: 目标对象状态变更通知所有观察者 (如 Vue 响应式原理 Dep -> Watcher)。

9. 算法手撕

无重复字符的最长子串 (滑动窗口)

javascript
function lengthOfLongestSubstring(s) {
  let map = new Map();
  let left = 0, maxLen = 0;
  for (let i = 0; i < s.length; i++) {
    if (map.has(s[i])) {
      left = Math.max(left, map.get(s[i]) + 1);
    }
    map.set(s[i], i);
    maxLen = Math.max(maxLen, i - left + 1);
  }
  return maxLen;
}

岛屿的最大面积 (DFS)

javascript
function maxAreaOfIsland(grid) {
  let max = 0;
  const dfs = (r, c) => {
    if (r < 0 || c < 0 || r >= grid.length || c >= grid[0].length || grid[r][c] === 0) return 0;
    grid[r][c] = 0; // 沉岛,避免重复访问
    return 1 + dfs(r+1, c) + dfs(r-1, c) + dfs(r, c+1) + dfs(r, c-1);
  }
  for (let i = 0; i < grid.length; i++) {
    for (let j = 0; j < grid[0].length; j++) {
      if (grid[i][j] === 1) max = Math.max(max, dfs(i, j));
    }
  }
  return max;
}

10. Web3D 与图形学补充

  • DPR 与图片:DPR (Device Pixel Ratio) = 物理像素 / 逻辑像素。
    • div 宽高 30px,在 DPR=2 的屏幕上,对应物理像素 60px。
    • 图片应准备 @2x (60px) 或 @3x (90px) 以保证清晰度。
  • GIS 按需加载:四叉树 (QuadTree) 算法。根据相机视口范围 (Frustum Culling) 和距离 (LOD),只加载可视区域内的瓦片数据。
  • Zustand:轻量级状态管理。基于 Hooks,无 Provider 嵌套,API 简洁 (create, set, get)。
  • DrawCall 限制:通常移动端建议 < 100,PC 端 < 1000。过多会导致 CPU 提交命令阻塞 GPU。
  • 动画方案对比
    • CSS: 简单 UI 动画,性能最好 (GPU 合成)。
    • JS: 复杂逻辑动画,灵活性高,但易阻塞主线程。
    • Canvas: 大量粒子/图形动画,性能高。
  • CPU vs GPU:
    • CPU: 核心少,适合复杂逻辑控制。
    • GPU: 核心多 (数千个),适合并行计算 (像素渲染)。

📝 二面核心复盘 (综合与深挖)

1. 综合素质与 HR 问题

  • 学历与成绩: 考察学习基础和聪明程度。
  • 实习经历: 为什么离职?(寻找更合适的发展平台/技术挑战)。
  • 团队管理: 如果作为 Leader,如何分配任务?(根据成员特长 + 代码 Review + 技术分享)。
  • 未来规划: 专注于 Web3D/图形学领域,深耕前端工程化。

2. 项目深挖 (首屏优化)

  • 关键指标: FCP (首屏时间), LCP (最大内容渲染)。
  • 优化手段:
    • 资源压缩: Gzip, WebP。
    • 按需加载: 路由懒加载, 组件异步加载。
    • 预加载: preload 关键资源。
    • 3D 模型优化: Draco 压缩, 纹理压缩 (KTX2), LOD (多细节层次)。

3. 虚拟 DOM (Virtual DOM)

  • 本质: 用 JS 对象描述 DOM 结构。
  • 价值:
    • 跨平台: 可以渲染到 Web, iOS, Android (React Native)。
    • 性能优化: 减少真实 DOM 操作次数(通过 Diff 算法计算最小变更)。

4. ECharts 渲染模式

  • Canvas (默认): 性能好,适合数据量大 (>1000),支持导出图片。
  • SVG: 内存占用低,缩放不失真,适合移动端和数据量小。

5. 成就感事件 (STAR 法则)

  • Situation: 项目遇到性能瓶颈 (FPS < 20)。
  • Task: 需要优化渲染性能。
  • Action: 引入 InstancedMesh (实例化渲染), 使用 Draco 压缩模型, 优化 Shader。
  • Result: FPS 提升至 60,首屏加载时间减少 50%。

美云智数 (佛山)

📌 面试概览

  • 时长:50分钟 (OC)
  • 业务:美的集团旗下,工业互联网软件系统。
  • 重点:开源项目经历、实习经历、项目流程。

📝 经验复盘

  1. 开源优势:面试官非常看重开源贡献(如腾讯开源项目、自研 MD 预览器),体现技术热情和底层能力。
  2. AI 时代前端发展
    • 低代码/零代码:前端需更多关注架构设计和组件封装。
    • AI 辅助:利用 Copilot 等工具提升效率,从“写代码”转向“审代码”和“设计逻辑”。
  3. 项目流程
    • 售前 -> 产品/UI设计 -> 开发 -> 测试 -> 运维 -> 交付
    • 前端需参与需求评审,评估技术可行性。

盛趣游戏 (上海)

📌 面试概览

  • 时长:45分钟(30分钟八股)
  • 核心环节:自我介绍 + 八股文提问(12个重点方向) + 项目亮点 + 反问

📝 八股文知识点详解

1. Vue 2 vs Vue 3 (深度对比)

核心差异分析: Vue 3 不仅仅是 API 的改变,更到底层响应式系统的重构。

  • Object.defineProperty 痛点:Vue 2 初始化时需要递归遍历 data 对象的所有属性,如果对象层级深,性能开销大。且无法监听对象属性的新增/删除(需用 $set)和数组下标的变化。
  • Proxy 优势:Vue 3 使用 Proxy 代理整个对象,惰性处理(只有访问到深层属性时才代理),性能大幅提升。且原生支持监听数组索引和 Map/Set

代码对比

javascript
export default {
  data() {
    return { count: 0 }
  },
  methods: {
    increment() {
      this.count++
    }
  }
}
javascript
import { ref } from 'vue'
export default {
  setup() {
    const count = ref(0)
    const increment = () => count.value++
    return { count, increment }
  }
}

2. TypeScript vs JavaScript

维度JavaScript (JS)TypeScript (TS)
类型系统动态弱类型 (运行时确定)静态强类型 (编译时检查)
开发体验灵活但易出错,重构风险大智能提示,自动补全,重构安全

代码示例

typescript
// Interface 定义接口
interface User {
  id: number;
  name: string;
  age?: number; // 可选属性
}

// 泛型 (Generics) 增强复用性
function getFirst<T>(arr: T[]): T {
  return arr[0];
}

const num = getFirst<number>([1, 2, 3]); // 类型安全

3. Vue 3 初始化流程

  1. createApp: 调用 createApp 创建应用实例。
  2. Use Plugins: 注册全局插件。
  3. Mount: 挂载到 DOM 节点。

代码示例

javascript
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

const app = createApp(App)
app.use(router) // 注册插件
app.mount('#app') // 挂载

4. Vue Router 钩子函数

钩子类型名称触发时机
全局beforeEach路由跳转前 (权限拦截)
组件内beforeRouteEnter进入组件前 (无 this)

代码示例 (全局守卫)

javascript
router.beforeEach((to, from, next) => {
  const token = localStorage.getItem('token')
  if (to.meta.requiresAuth && !token) {
    next('/login') // 重定向到登录
  } else {
    next() // 放行
  }
})

5. Vuex 核心概念

模块作用调用方式
State存储状态this.$store.state
Mutations同步修改commit('SET_USER', payload)
Actions异步操作dispatch('fetchUser')

代码示例

javascript
// store.js
const store = createStore({
  state: { count: 0 },
  mutations: {
    INCREMENT(state) { state.count++ }
  },
  actions: {
    asyncIncrement({ commit }) {
      setTimeout(() => commit('INCREMENT'), 1000)
    }
  }
})

6. nextTick 原理

  • 作用:将回调推迟到下一个 DOM 更新周期之后执行。
  • 原理:Vue 内部维护一个异步队列 (MicroTask > MacroTask)。
javascript
this.msg = 'Hello'
console.log(this.$el.textContent) // 旧值: ''
this.$nextTick(() => {
  console.log(this.$el.textContent) // 新值: 'Hello'
})

7. keep-alive

  • 作用:缓存组件实例,避免重复销毁/重建。
  • 属性include (缓存谁), exclude (不缓存谁)。

代码示例

html
<!-- 缓存 name 为 Home 的组件 -->
<keep-alive include="Home">
  <router-view></router-view>
</keep-alive>

8. Hash vs History 路由

模式URL 示例原理
Hash/#/homewindow.onhashchange
History/homehistory.pushState

代码示例 (Nginx 配置 History 模式)

nginx
location / {
  try_files $uri $uri/ /index.html; # 404 重定向到 index.html
}

9. JS 原型链

  • 查找规则:实例 -> 构造函数原型 -> Object原型 -> null。
javascript
function Person() {}
const p = new Person()
// 实例的隐式原型 === 构造函数的显式原型
p.__proto__ === Person.prototype // true
// 原型链终点
Object.prototype.__proto__ === null // true

10. this 指向规则

调用方式this 指向示例
隐式绑定调用者对象obj.fn()
显式绑定指定对象fn.call(ctx)
箭头函数外层作用域() => {}

代码示例

javascript
const obj = {
  name: 'Tom',
  say: function() { console.log(this.name) }, // this -> obj
  arrowSay: () => { console.log(this.name) }  // this -> window/undefined
}

11. 浏览器渲染原理

  1. 解析: HTML -> DOM, CSS -> CSSOM。
  2. 合成: DOM + CSSOM -> Render Tree。
  3. 绘制: Layout (回流) -> Paint (重绘) -> Composite (合成)。

12. 事件机制

  • 流程: 捕获 -> 目标 -> 冒泡。

代码示例

javascript
// 第三个参数 true 开启捕获监听
el.addEventListener('click', handler, true)

// 阻止冒泡
function handler(e) {
  e.stopPropagation()
}

360 (北京)

📌 面试概览

  • 时长:40分钟
  • 核心环节:实习经历深挖 + 前端基础 (HTML/CSS/JS) + 框架原理
  • 业务:大模型基建平台

📝 知识点深度解析

1. HTML 基础:ID vs Class

特性IDClass
唯一性全局唯一可复用
权重10010

代码示例

css
#header { color: red; } /* 权重高 */
.text { color: blue; }  /* 权重低 */

2. 框架 vs 原生 JS

  • 原生 JS: 手动操作 DOM,繁琐。
  • 框架: 数据驱动,虚拟 DOM 优化性能。

代码对比 (更新文本)

javascript
// 原生 JS
document.getElementById('app').innerText = 'Hello'

// Vue
this.msg = 'Hello' // 自动更新视图

3. 相等性判断 == vs ===

javascript
1 == '1'  // true (隐式转换)
1 === '1' // false (类型不同)
null == undefined // true (特例)

4. Flex 布局体系

代码示例 (常用布局)

css
.container {
  display: flex;
  justify-content: space-between; /* 两端对齐 */
  align-items: center;            /* 垂直居中 */
}

5. 水平垂直居中方案

方案一:Flex (推荐)

css
.parent {
  display: flex;
  justify-content: center;
  align-items: center;
}

方案二:Absolute + Transform

css
.child {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

6. 数组判断方法

javascript
const arr = []
// 1. Array.isArray (推荐)
Array.isArray(arr) // true
// 2. instanceof
arr instanceof Array // true
// 3. toString (最通用)
Object.prototype.toString.call(arr) // "[object Array]"

7. 变量声明 var vs let vs const

特性varletconst
作用域函数块级块级
提升undefinedTDZTDZ

代码示例

javascript
console.log(a) // undefined
var a = 1

console.log(b) // ReferenceError
let b = 2

8. v-show vs v-if

代码示例

html
<!-- v-show: display: none (DOM 还在) -->
<div v-show="isVisible">Tab Content</div>

<!-- v-if: DOM 移除 (完全销毁) -->
<div v-if="isAdmin">Admin Panel</div>

9. 组件通信

代码示例 (父子通信)

vue
<!-- Parent.vue -->
<Child :msg="parentMsg" @update="handleUpdate" />

<!-- Child.vue -->
<script setup>
defineProps(['msg'])
const emit = defineEmits(['update'])
function click() { emit('update', 'newData') }
</script>

10. 异步请求处理

Fetch + Async/Await 示例

javascript
async function fetchData() {
  try {
    const res = await fetch('/api/user')
    const data = await res.json()
    console.log(data)
  } catch (err) {
    console.error('Network Error:', err)
  }
}

---

## TCL新技术 (深圳) {#tcl-sz}

### 📌 面试概览
- **业务**:智能终端、IoT
- **特点**:考察 Vue2/3 迁移能力、工程化工具对比。

### 📝 核心知识点解析

#### 1. Vue 2 vs Vue 3 (响应式原理)
- **Vue 2**: `Object.defineProperty`
  - **缺点**: 无法监听新增/删除属性,无法监听数组下标变化,初始化需递归遍历 (慢)。
- **Vue 3**: `Proxy`
  - **优点**: 代理整个对象,支持数组/Map/Set,惰性处理深层嵌套 (快)。

#### 2. Vue 组件通信差异 (Vue 2 vs Vue 3)
- **Vue 2**:
  - `props` / `$emit`
  - `$on` / `$emit` (EventBus)
  - `$parent` / `$children`
  - `.sync` 修饰符
- **Vue 3**:
  - **移除**: `$on`, `$off`, `$once` (EventBus 需引入 `mitt` 库)。
  - **移除**: `$children`
  - **变更**: `.sync` 被移除,统一合并到 `v-model`
  - **新增**: `provide/inject` (Composition API 风格), `attrs` (包含 class/style)。

#### 3. v-for 中 Key 的作用
- **作用**: 唯一标识 VNode。
- **原理**: 在 Diff 算法中,Vue 通过 Key 判断新旧节点是否是同一个。
- **无 Key**: 采用“就地更新”策略,复用 DOM 元素,只修改内容。可能导致 input 输入框状态错乱。
- **有 Key**: 准确找到对应节点,进行移动或销毁重建。

#### 4. v-model 原理与多组件场景
- **Vue 2**:
  - `<input v-model="val">` -> `:value="val" @input="val = $event"`
- **Vue 3**:
  - `<input v-model="val">` -> `:modelValue="val" @update:modelValue="val = $event"`
- **多个 v-model (Vue 3)**:
  - `<Comp v-model:title="t" v-model:content="c" />`
  - 极大地增强了组件灵活性。

#### 5. 图片懒加载
- **原生**: `<img loading="lazy" src="...">`
- **JS 实现**:
  - `IntersectionObserver` 监听元素是否进入视口。
  - 进入后将 `data-src` 赋值给 `src`

#### 6. Vue 生命周期:发送请求
- **最佳时机**: `created` (Vue 2) 或 `onMounted` (Vue 3)。
  - **created**: 组件实例已创建,数据已初始化,但 DOM 未挂载。适合纯数据请求。
  - **mounted**: DOM 已挂载。如果请求依赖 DOM (如 ECharts),必须在这里。

#### 7. 场景题:表单删除
- **需求**: 列表中删除一项。
- **实现**:
```javascript
// 方法一: Splice (改变原数组)
this.list.splice(index, 1);

// 方法二: Filter (生成新数组, React 常用)
this.list = this.list.filter(item => item.id !== id);

8. Three.js 基础 (Web3D)

  • 核心三要素:
    • Scene (场景): 容器,容纳所有物体。
    • Camera (相机):
      • PerspectiveCamera (透视): 近大远小,模拟人眼。
      • OrthographicCamera (正交): 远近一样大,用于工程制图/UI。
    • Renderer (渲染器): 将场景+相机渲染到 Canvas 上。

9. Webpack vs Vite

  • Webpack: Bundle Based,启动慢,热更新慢。
  • Vite: Native ESM,启动快 (秒开),热更新快。

10. CSS 盒模型

  • 标准盒模型: width = content。
  • 怪异盒模型: width = content + padding + border。
  • 设置: box-sizing: border-box;

纷享销客 (深圳)

📌 面试概览

  • 业务:CRM 系统 (SaaS)
  • 特点:追问底层原理 (HTTPS, 内存泄漏, 深拷贝细节)。
  • 体验:体验一般,面试官声音小,较真,半小时结束。

📝 核心知识点解析

1. HTTPS 深度拷打

  • HTTP vs HTTPS:
    • HTTP: 明文传输,端口 80。
    • HTTPS: SSL/TLS 加密传输,端口 443。
  • HTTPS 能被抓包吗?:
    • 原理: 中间人攻击 (MITM)。抓包工具 (Fiddler/Charles) 伪装成服务器向客户端发证书。
    • 前提: 客户端必须手动信任抓包工具生成的 CA 根证书。
  • 公钥私钥问题:
    • 面试官质疑: "公钥大家都拿得到,那不是泄密了?"
    • 正解:
      1. 公钥加密,私钥解密: 客户端用公钥加密数据,只有持有私钥的服务器能解开。黑客拿到公钥没用,解不开数据。
      2. 私钥签名,公钥验签: 服务器用私钥签名,客户端用公钥验证身份。

2. 内存泄漏 (Memory Leak)

  • 根本原因: 不再需要的内存数据,未能被垃圾回收器 (GC) 释放。
  • 常见场景:
    1. 闭包: 函数内部引用了外部变量,且函数被外部持有。
    2. 全局变量: 意外创建的全局变量。
    3. 定时器: setInterval 未清除。
    4. DOM 引用: JS 中持有已删除 DOM 节点的引用。

3. 深拷贝细节 (递归 + Map)

  • Map 存哪里?:
    • 存在递归函数的参数中。作为 WeakMap 传递给下一层。
    • 作用: 记录已拷贝的对象,防止循环引用导致栈溢出。
  • 实现要点:
    javascript
    function deepClone(target, map = new WeakMap()) {
      if (typeof target === 'object') {
        let cloneTarget = Array.isArray(target) ? [] : {};
        // 检查循环引用
        if (map.get(target)) return map.get(target);
        map.set(target, cloneTarget);
        
        for (const key in target) {
          cloneTarget[key] = deepClone(target[key], map);
        }
        return cloneTarget;
      } else {
        return target;
      }
    }

4. 原型链与继承

  • 原型链: 实例 __proto__ -> 构造函数 prototype -> Object prototype -> null
  • 继承举例 (Class 继承):
    javascript
    class Parent {
      constructor(name) { this.name = name; }
      say() { console.log(this.name); }
    }
    class Child extends Parent {
      constructor(name, age) {
        super(name); // 调用父类构造函数
        this.age = age;
      }
    }

5. SSR (服务端渲染) 实现原理

  • 核心: 在 Node.js 环境中执行 Vue/React 代码,生成 HTML 字符串。
  • 流程:
    1. 客户端请求 URL。
    2. Node 服务器获取数据。
    3. renderer.renderToString(app) 将组件转为 HTML。
    4. 注入到 HTML 模板中返回给浏览器。
    5. 浏览器进行 Hydration (注水),绑定事件,使其变活。

6. 调试技巧 (Debugger)

  • 代码中: 写入 debugger; 语句。
  • 断点类型:
    • Conditional Breakpoint: 条件断点 (右键断点 -> i === 5 时暂停)。
    • XHR Breakpoint: 请求断点。
    • DOM Breakpoint: 节点属性变化时暂停。

7. 首屏渲染优化 (细分)

  • 网络: DNS Prefetch, CDN, HTTP/2。
  • 资源: 路由懒加载, 图片 WebP, Gzip/Brotli。
  • 代码: Tree Shaking, 骨架屏, SSR。

百度 (深圳)

📌 面试概览

  • 岗位:前端日常实习
  • 特点:项目拷打深度高,考察 Web3D、GIS 渲染及工程化。

📝 核心知识点解析

1. GIS 地图渲染与缓存

  • 渲染: 瓦片技术 (Tile)。将大地图切割成小块,按需加载。
  • 缓存:
    • 浏览器: HTTP 强缓存。
    • IndexedDB: 存储离线瓦片数据,支持海量数据存储 (GB 级别)。

2. 事件委托 (Event Delegation)

  • 原理: 利用事件冒泡机制,在父元素监听子元素事件。
  • 优点: 节省内存,支持动态生成的 DOM。

3. Webpack 优化与工具对比

  • 优化: thread-loader (多进程), dll (预编译, 现多用缓存代替), splitChunks
  • 工具:
    • Vite: 开发环境秒开,基于 ESM。
    • Rollup: 适合库开发,产物更纯净。

4. 手撕防抖 (Debounce)

javascript
function debounce(fn, delay) {
  let timer = null;
  return function(...args) {
    if (timer) clearTimeout(timer);
    timer = setTimeout(() => {
      fn.apply(this, args);
    }, delay);
  };
}

5. Linux 常用指令

  • ls (列出目录), cd (切换), pwd (当前路径)。
  • top (监控 CPU), tail -f (查看日志), grep (搜索关键字)。
  • ps -ef (查看进程), netstat -anp (查看端口)。

百度 YY (广州)

📌 面试概览

  • 业务:YY 直播 PC 端与 H5 端。
  • 特点:考察 JS 内存模型、TS 配置、React 深度原理。

📝 核心知识点解析

1. JS 栈 (Stack) vs 堆 (Heap)

  • : 存储基本类型 (number, string, boolean, null, undefined) 和引用类型的指针。速度快,空间固定
  • : 存储引用类型 (Object, Array, Function)。
  • 为什么引用类型存堆?:
    • 引用类型大小不固定,可能动态增长。
    • 堆空间大,允许存储复杂数据结构。
    • 栈是按序排列的,如果把大对象存栈,会严重影响查找速度。

2. TS 泛型与配置

  • 泛型: 在定义函数/类时不指定类型,在使用时才指定。增强复用性。
  • tsconfig.json:
    • strict: 开启严格模式 (包含 noImplicitAny, strictNullChecks 等)。
    • target: 编译后的 JS 版本 (如 ES5, ESNext)。
    • include / exclude: 指定编译器包含或排除的文件夹。

3. 移动端响应式 (rem vs vw)

  • rem: 相对于根元素 htmlfont-size
    • 逻辑: 通过 JS 监听窗口变化,动态修改 htmlfont-size
  • vw: 视口单位。1vw = 视口宽度的 1%。
    • 原理: 基于浏览器视口宽高计算,无需 JS 参与。

4. React 函数组件 vs 类组件

  • 类组件: 使用 ES6 Class,有生命周期,有 this,有状态。
  • 函数组件: 纯函数,Hooks 出现后可拥有状态。更简洁,易于测试,逻辑复用方便。
  • useEffect 依赖项:
    • 空数组 []: 仅在挂载/卸载时执行。
    • 有值 [a, b]: 当 a 或 b 变化时重新执行。
  • useState 实现“同步”: 使用函数式更新
    javascript
    setCount(prevCount => prevCount + 1); // 获取最新的 state

Power by VitePress