Kc's blog Kc's blog
首页
分类
标签
Timeline
收藏夹
关于
GitHub (opens new window)

kcqingfeng

前端小学生
首页
分类
标签
Timeline
收藏夹
关于
GitHub (opens new window)
  • 提前下班小妙招

  • node版本的切换

  • 面试

    • 面试问答
    • 面试随记
      • AI
      • 1️⃣ Vue3 相比 Vue2 的核心升级点是什么?
        • ✅ 标准答案:
      • 2️⃣ Vue3 为什么比 Vue2 性能好?
        • ✅ 1. 响应式优化(核心)
        • ✅ 2. PatchFlag(虚拟DOM优化)
        • ✅ 3. 静态提升(Static Hoisting)
        • ✅ 4. 事件缓存(Cache Handler)
        • ✅ 5. Tree Shaking
      • 3️⃣ Vue3 响应式是怎么实现的?
        • 标准回答结构:
      • 4️⃣ 为什么推荐 Composition API?
        • 标准答案:
      • 5️⃣ 闭包是什么?
      • 6️⃣ 原型链是什么?
      • 7️⃣ Promise 执行机制
      • 8️⃣ 前端性能优化手段?
        • 资源层面:
        • 代码层面:
        • Vue 层面:
      • 1️⃣ Vue3 响应式原理,和 Vue2 有什么本质区别?
        • ✅ 标准结构回答:
        • ① 监听能力增强
        • ② 性能优化(重点说)
        • ③ 数据结构优化
        • 🎯 面试追问点
      • ① 响应式优化
      • ② 编译阶段优化(这是社招重点)
        • PatchFlag
        • 静态提升(Static Hoisting)
        • 事件缓存
      • ③ Tree Shaking
        • 🎯 加分回答
        • Vue2 痛点:
        • Vue3 优势:
      • 4️⃣ 你做过哪些 Vue 性能优化?
      • 5️⃣ 事件循环机制
      • 6️⃣ 防抖和节流区别
        • 防抖:
        • 节流:
      • 7️⃣ Vite 为什么快?
      • 8️⃣ 你如何做打包优化?
      • 9️⃣ Express 中间件原理?
      • 🔟 MySQL 索引原理?
      • ❓ watch 和 computed 区别?
      • ❓ ref 和 reactive 区别?
      • 1️⃣ 引用计数(早期)
      • 2️⃣ 标记清除(现代主流)
      • 面试问答
      • IntersectionObserver
      • 首屏加载慢优化
      • 广告曝光统计不准确
      • 广告封装难度
      • 你对公司有什么想要了解的
      • 看视频学习,
      • 要自信,声音洪亮
    • googleNotebooklm
  • 收藏
  • 面试
kc_shen
2026-04-07
目录

面试随记

# AI

“它解决的核心问题,是把我的精力,从重复性和记忆性的工作中解放出来,让我能更专注于创造性和架构性的工作

熟练掌握 Vue3 + TypeScript,具备组件化开发经验,熟悉 Composition API 及常用生态

面试官你好,我是,从事前端开发已经六年了,主要技术栈是 Vue3、TypeScript、UniApp 等
一共任职过两家公司,第一份是毕业到2020年3月,是在郑州从事的外包开发,主要使用uniapp开发app和微信小程序
第二个是在上海,一家自研的流量变现公司,负责前端的所有工作,包括 公司运营的后台管理系统、广告信息流项目以及快应用,微信,支付宝等多个小程序产品
最近也比较关注 AI 与前端结合的应用场景,在项目中也有接入 AI 能力的实践,比如 AI 内容生成和 Prompt 优化等。
希望能加入我们这个新团队,也不断提升自己的技术能力的同时,也能为公司创造实际价值
1
2
3
4
5

# 一、Vue3 高频八股


# 1️⃣ Vue3 相比 Vue2 的核心升级点是什么?

# ✅ 标准答案:

  1. 使用 Proxy 替代 Object.defineProperty
  2. 重写虚拟 DOM(PatchFlag + 静态提升)
  3. Composition API
  4. 更好的 Tree Shaking
  5. Fragment / Teleport / Suspense
  6. 更好的 TypeScript 支持

# 二、Vue3 性能提升(重点)


# 2️⃣ Vue3 为什么比 Vue2 性能好?

# ✅ 1. 响应式优化(核心)

Vue2 使用:

Object.defineProperty
1

缺点:

  • 不能监听数组索引变化
  • 不能监听对象新增属性
  • 初始化递归遍历

Vue3 使用:

Proxy
1

优势:

  • 可以监听新增 / 删除属性
  • 可以监听数组索引
  • 惰性代理(访问时才递归)
  • 性能更高

👉 面试加分说法:

Vue3 响应式基于 Proxy + Reflect 实现,采用懒代理机制,避免 Vue2 初始化阶段的深度递归遍历,提高了大型对象的初始化性能。


# ✅ 2. PatchFlag(虚拟DOM优化)

Vue3 在编译阶段会标记动态节点:

<div>{{ msg }}</div>
1

会被标记为:

PatchFlag.TEXT
1

更新时:

👉 只更新标记的动态节点 👉 不再进行全量 Diff

Vue2:

  • 每次更新都全量对比 VNode

Vue3:

  • 只对动态节点做 Diff

性能大幅提升。


# ✅ 3. 静态提升(Static Hoisting)

静态节点只创建一次:

<div>
  <p>我是静态</p>
  <span>{{ msg }}</span>
</div>
1
2
3
4

会被提升到 render 外部。

Vue2 每次 render 都重新创建。

Vue3 只创建一次。


# ✅ 4. 事件缓存(Cache Handler)

Vue3 默认缓存事件函数:

Vue2:

<button @click="handleClick">
1

每次 render 都重新生成函数引用。

Vue3:

会缓存 handler,减少重复创建。


# ✅ 5. Tree Shaking

Vue3 模块化拆分:

import { ref } from 'vue'
1

只打包用到的 API。

Vue2 是整体打包。


# 三、Vue3 响应式原理


# 3️⃣ Vue3 响应式是怎么实现的?

# 标准回答结构:

  1. reactive 创建 Proxy
  2. 依赖收集 track
  3. 依赖触发 trigger
  4. effect 副作用函数

核心流程:

effect(() => {
  console.log(state.count)
})
1
2
3
  • 读取 count → 触发 track 收集依赖
  • 修改 count → 触发 trigger 执行 effect

底层数据结构:

WeakMap → Map → Set
1

# 四、Composition API 优势


# 4️⃣ 为什么推荐 Composition API?

# 标准答案:

  1. 逻辑复用更方便
  2. 避免 mixin 命名冲突
  3. 更清晰的逻辑分组
  4. 更好的 TypeScript 支持
  5. 更适合大型项目

# 五、JS 八股(必须会)


# 5️⃣ 闭包是什么?

函数 + 它能访问的作用域环境。

一般是一个函数返回了一个函数的情形,

  1. 返回的函数,仍然可以i访问外层函数的局部变量即使外层函数已经执行结束
  2. 这种访问保持了外层变量的状态,可以实现私有变量或累加器等功能
  3. 并不是所有返回函数的场景都是闭包,关键是返回的函数引用了外层函数的变量

闭包

常见应用:

  • 防抖节流
  • 模块封装
  • 私有变量

# 6️⃣ 原型链是什么?

对象通过 __proto__ 指向构造函数的 prototype。

查找规则:

对象本身 → prototype → Object.prototype → null


# 7️⃣ Promise 执行机制

  • 同步代码先执行
  • 微任务(Promise)
  • 宏任务(setTimeout)

事件循环顺序:

Promise.all全部成功才成功
Promise.race谁先结束用谁
Promise.any有一个成功就返回
Promise.allSettled全部执行完,不管成功失败
1
2
3
4
同步 → 微任务 → 宏任务
1

# 六、性能优化(高频)


# 8️⃣ 前端性能优化手段?

# 资源层面:

  • 图片懒加载
  • gzip
  • CDN
  • Tree Shaking

# 代码层面:

  • 防抖节流
  • 虚拟列表
  • keep-alive
  • 组件拆分
  • 路由懒加载

# Vue 层面:

  • v-memo
  • v-once
  • 合理使用 computed
  • 避免深层 watch

# 🎯 最重要:Vue3 性能提升总结模板(必背)

面试回答可直接背:

Vue3 相比 Vue2 性能提升主要体现在三个方面:

第一,响应式系统改为 Proxy,实现惰性代理,解决了 Vue2 无法监听新增属性的问题;

第二,虚拟 DOM 引入 PatchFlag 和静态提升,在编译阶段标记动态节点,更新时只对动态部分进行 Diff;

第三,支持 Tree Shaking,打包体积更小。

整体上 Vue3 在初始化性能、更新性能和包体积方面都有明显提升。


# 一、Vue3 深度题(社招核心)


# 1️⃣ Vue3 响应式原理,和 Vue2 有什么本质区别?

# ✅ 标准结构回答:

Vue3 使用 Proxy + Reflect 实现响应式,相比 Vue2 的 Object.defineProperty 有三个核心提升:

# ① 监听能力增强

Vue2:

  • 无法监听新增属性
  • 不能监听数组索引
  • 需要重写数组方法

Vue3:

  • Proxy 可以拦截 get / set / deleteProperty
  • 可以监听数组索引变化
  • 可以监听属性新增删除

# ② 性能优化(重点说)

Vue2 初始化时会递归遍历对象,深度劫持。

Vue3 是 懒代理机制:

只有在访问对象时才进行递归代理

减少初始化性能消耗。


# ③ 数据结构优化

依赖收集结构:

WeakMap
  └─ Map
      └─ Set
1
2
3
  • target → key → effect

WeakMap 防止内存泄漏。


# 🎯 面试追问点

  • effect 是怎么避免死循环的?
  • ref 和 reactive 区别?
  • computed 为什么有缓存?

# 2️⃣ Vue3 性能优化点(必背完整版)

你可以这样回答:

Vue3 性能提升主要来自三方面:响应式优化、编译优化、打包优化。


# ① 响应式优化

  • Proxy 替代 defineProperty
  • 惰性代理
  • 更精准的依赖追踪

# ② 编译阶段优化(这是社招重点)

# PatchFlag

Vue3 在编译阶段标记动态节点:

<div>{{msg}}</div>
1

会被标记为 TEXT 类型。

更新时:

只更新动态节点,不再全量 diff


# 静态提升(Static Hoisting)

静态节点只创建一次。

Vue2 每次 render 都重新创建。


# 事件缓存

Vue3 会缓存事件函数引用,减少 render 过程中函数重新创建。


# ③ Tree Shaking

Vue3 API 按需引入,减少包体积。


# 🎯 加分回答

Vue3 通过“编译时优化”减少运行时计算,这是本质区别。


# 3️⃣ Composition API 为什么更适合大型项目?

社招要回答“痛点”。

# Vue2 痛点:

  • 逻辑分散在 data、methods、computed
  • mixin 命名冲突
  • 逻辑复用困难

# Vue3 优势:

  • 按功能组织代码
  • 更好的逻辑复用
  • 更好 TypeScript 推导
  • 更利于拆分业务模块

# 二、真实项目场景题(社招必问)


# 4️⃣ 你做过哪些 Vue 性能优化?

你可以这样答(模板):

在项目中我主要做过以下优化:

  1. 使用路由懒加载减少首屏加载体积
  2. 使用 keep-alive 缓存列表页
  3. 大数据列表使用虚拟滚动
  4. 避免不必要的深层 watch
  5. 合理拆分组件,减少重复渲染
  6. 图片懒加载 + CDN

如果你做过视频项目,可以加:

对大图和视频做了压缩与分片加载优化。


# 三、JS 深度八股(社招必问)


# 5️⃣ 事件循环机制

必须能画流程:

同步任务
↓
微任务(Promise)
↓
宏任务(setTimeout)
1
2
3
4
5

追问:

  • async await 本质?
  • nextTick 属于什么?

# 6️⃣ 防抖和节流区别

# 防抖:

触发后延迟执行。事件持续触发时,只在最后一次触发后执行(多用于输入框)

# 节流:

固定时间执行一次。(多用于按钮)

追问:

  • 立即执行版本怎么实现?
  • Vue 场景怎么用?
GET 是幂等
POST 不是
PUT 是幂等
DELETE 是幂等
1
2
3
4

# 四、工程化(社招必问)


# 7️⃣ Vite 为什么快?

标准答案:

  • 基于 ES Module
  • 开发阶段不打包
  • 按需加载
  • 使用 esbuild 预构建

# 8️⃣ 你如何做打包优化?

  • 分包
  • 代码分割
  • CDN 外链
  • gzip
  • Tree Shaking
  • 图片压缩

# 五、Node 基础(你必须准备)


# 9️⃣ Express 中间件原理?

函数链模型:

(req, res, next)
1

通过 next 控制流程。


# 🔟 MySQL 索引原理?

  • B+ 树
  • 主键索引
  • 联合索引最左匹配原则

# 六、社招最容易挂的题


# ❓ watch 和 computed 区别?

computed:

  • 有缓存
  • 基于依赖自动更新
  • 适合计算属性

watch:

  • 监听变化
  • 执行副作用

# ❓ ref 和 reactive 区别?

  • ref 用于基本类型
  • reactive 用于对象
  • ref 本质也是 reactive 包装

对比点 栈 堆
存储内容 基本类型 / 引用地址 对象 / 数组
空间大小 小 大
分配方式 自动分配 动态分配
访问速度 快 相对慢
生命周期 由函数调用决定 由 GC 决定

# JS 常见垃圾回收机制

# 1️⃣ 引用计数(早期)

原理:

每个对象有一个引用次数 引用 +1 解除引用 -1 当为 0 时回收

# 2️⃣ 标记清除(现代主流)

现在主流浏览器都用这个。

原理:

  1. 从根对象(window / global)开始遍历
  2. 能访问到的标记为“存活”
  3. 不能访问到的标记为“垃圾”
  4. 清除未标记对象

优点:

✅ 能解决循环引用问题

# 面试问答

一线城市和二三线城市,通过ip定位获取当前的定位区域,然后配置不同的广告策略

配置的有奖励的三篇30s等,visibilitychange的监听,有的是和app合作,有的是自己页面对接的支付宝提现,
根据第二天广告后台的收益反馈,进行业务调整,
通过deeplink打开第三方app



通过 vite build 后结合 rollup-plugin-visualizer 分析包体积,发现 UI 组件库和图表库占比较大
通过 CDN 外链、按需加载、动态 import 实现代码分割,主包体积从 2.1MB 降到 1.4MB,约下降 30%。
1
2
3
4
5
6
7
8
9
10

# vue3通信大全(三)—— 全局状态管理库pinia,vuex

https://juejin.cn/post/7397285224379957298?searchId=2026022815382985E6324A99D180ACB9B9


state,
actions,
getters
1
2
3
4
5
6

# IntersectionObserver

在信息流广告场景中,需要统计广告真实曝光。如果通过 scroll 监听判断元素是否进入视口,会频繁触发计算,性能开销比较大,因此项目中使用了 IntersectionObserver 来实现曝光检测。

具体实现是:当广告组件渲染后,通过 IntersectionObserver 监听广告节点与 viewport 的交叉状态,当元素的 intersectionRatio 超过 50% 时,认为广告进入有效可视区域。为了保证数据准确,我们还增加了曝光停留时间限制,例如停留超过 1 秒才上报曝光埋点。

同时为了避免重复统计,在广告曝光后会取消 observer 监听,并在本地维护曝光缓存,保证同一广告在当前页面只统计一次曝光。点击统计则通过 click 事件进行埋点上报,用于计算广告 CTR 等指标。

在长列表场景下我们还复用了 observer 实例,并在组件销毁时及时取消监听,以避免性能和内存问题

创建 observer
↓
获取需要监听的元素
↓
observer.observe(el)
↓
元素进入视口
↓
触发 callback
↓
根据 dataset 判断执行逻辑
监听完成之后需要取消
observer.unobserve(el)


function observeNewItems() {

  const newItems = document.querySelectorAll('.observe-item')

  newItems.forEach(el => {
    observer.observe(el)
  })

}

// 用于保存每个广告的计时器
// key:adId
// value:setTimeout 的 timer
const visibleAds = new Map()

// 创建 IntersectionObserver
const observer = new IntersectionObserver((entries) => {

  // entries 是所有状态发生变化的元素
  entries.forEach(entry => {

    // 当前被监听的 DOM 元素
    const el = entry.target

    // 从 dataset 中获取广告ID
    const adId = el.dataset.adId

    // 判断广告是否进入可视区域
    // isIntersecting:元素是否进入视口
    // intersectionRatio:可见比例
    if (entry.isIntersecting && entry.intersectionRatio >= 0.5) {

      // 广告进入可视区域,开始1秒计时
      const timer = setTimeout(() => {

        // 如果1秒后广告仍然在 Map 中
        // 说明没有离开可视区域
        if (visibleAds.has(adId)) {

          // 上报广告曝光
          reportExposure(adId)

          // 取消监听,避免重复统计
          observer.unobserve(el)

          // 删除计时器记录
          visibleAds.delete(adId)
        }

      }, 1000)

      // 保存计时器
      visibleAds.set(adId, timer)

    } else {

      // 如果广告离开视口

      // 获取之前的计时器
      const timer = visibleAds.get(adId)

      if (timer) {

        // 清除计时器
        clearTimeout(timer)

        // 删除记录
        visibleAds.delete(adId)

      }

    }

  })

}, {
  // threshold = 0.5 表示至少50%进入视口才触发
  threshold: [0.5]
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102

# 首屏加载慢优化

通过 Chrome Performance + Network 分析

使用 动态 import
CDN 外链,将大体积依赖放 CDN
vite配置 external: ['vue','echarts']
路由懒加载
1
2
3
4
5
6

# 广告曝光统计不准确

可见面积 ≥ 50%
停留时间 ≥ 1 秒

可见面积 ≥ 50%
停留时间 ≥ 1 秒

进入视口
↓
开始1秒计时
↓
如果离开视口 → 取消
↓
1秒后仍然可见 → 统计曝光
1
2
3
4
5
6
7
8
9
10
11
12
13
1 收集用户反馈
2 查看监控日志 sentry
3 复现问题
4 Chrome DevTools 排查
5 查看接口请求
6 查看错误日志
7 定位代码
1
2
3
4
5
6
7

# 广告封装难度

不同厂商 API 不一致
创建广告方式不同
事件回调不同
加载方式不同

统一广告 SDK 封装

业务层
 ↓
广告封装层
 ↓
厂商SDK

广告填充率提高
代码可维护性提升
多个快应用项目可以复用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 你对公司有什么想要了解的

目前团队架构是什么样的,主要在开发什么项目
上班时间
我如果有幸入职了,我需要负责什么业务


1
2
3
4
5
我想做一个语音识别的网页,输入语音,调用windows电脑的funasr,然后调用大模型接口,回答语音输入的问题,
model_dir = "FunAudioLLM/Fun-ASR-Nano-2512"

model = AutoModel(
    model=model_dir,
    vad_model="fsmn-vad",
    vad_kwargs={"max_single_segment_time": 30000},
    device="cuda:0",
)
1
2
3
4
5
6
7
8
9

# 看视频学习,

# 要自信,声音洪亮

低代码平台,

1000w表格渲染,使用canvas花的,然后二进制

1
2
3
4

截屏2026-03-30 15.39.53

使用github的工作流,上传git之后自动推送到服务器
1
编辑 (opens new window)
上次更新: 2026/04/07, 2:04:00
面试问答
googleNotebooklm

← 面试问答 googleNotebooklm→

最近更新
01
googleNotebooklm
04-07
02
claude安装终端代理
04-06
03
Homebrew使用指南
04-06
更多文章>
Theme by Vdoing | Copyright © 2019-2026 kc shen | MIT License 豫ICP备2024074563号-3
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式