前言
大家好,我是木斯佳。
相信很多人都感受到了,在AI浪潮的席卷之下,前端领域的门槛在变高,纯粹的"增删改查"岗位正在肉眼可见地减少。曾经热闹非凡的面经分享,如今也沉寂了许多。但我们都知道,市场的潮水退去,留下的才是真正在踏实准备、努力沉淀的人。学习的需求,从未消失,只是变得更加务实和深入。
这个专栏的初衷很简单:拒绝过时的、流水线式的PDF引流贴,专注于收集和整理当下最新、最真实的前端面试资料。我会在每一份面经和八股文的基础上,尝试从面试官的角度去拆解问题背后的逻辑,而不仅仅是提供一份静态的背诵答案。无论你是校招还是社招,目标是中大厂还是新兴团队,只要是真实发生、有价值的面试经历,我都会在这个专栏里为你沉淀下来。专栏快速地址

温馨提示:市面上的面经鱼龙混杂,甄别真伪、把握时效,是我们对抗内卷最有效的武器。
面经原文内容
📍面试公司:上海威派格智慧水务股份有限公司
🕐面试时间:2026年5月7日
💻面试岗位:前端实习
📝面试体验:后半场项目配置和Git相关答得不好
❓面试问题:
HR面试
- 自我介绍
- 介绍一下医疗智能问答系统项目中所从事的工作内容
- 智能聊天助手的"状态管理与持久性"是怎么构建的
- 来企业主要是想学习哪方面的技能
技术面试官
- Vue2跟Vue3的区别
- Webpack跟Vite,它们两个有什么区别
- Javascript跟Typescript的区别
- 项目中的多角色权限守卫是怎么拦截的
- let、const、var有哪些区别
- 防抖跟节流是什么?怎么去实现?
现场代码实操(共享屏幕,展示Vue2项目)
-
怎么打开一个终端窗口
-
哪个文件是进行包管理的文件
-
yarn和npm有什么区别
-
从远程拉取代码的命令是什么
-
远程仓库有更新,如何拉取新代码
-
Git怎么切换分支
-
如何把项目打包成静态文件
-
vue.config.js里面一般写什么内容
-
.gitignore的作用是什么
-
v-if和v-show的区别
-
inject的作用
反问
- 面试评价、反馈时间、公司业务
来源:牛客网FreedomChaser
💡 木木有话说(刷前先看)
说实话最近我也有点失落,感觉传统前端的需求岗位确实少了很多。AI化潮流势不可挡啊。
📝 上海威派格前端实习·深度解析
🎯 面试整体画像
| 维度 | 特征 |
|---|---|
| 面试风格 | 基础八股型 + 工程化实操型 + 真实项目追问型 |
| 难度评级 | ⭐⭐⭐(三星,基础为主,实操题考验熟练度) |
| 考察重心 | Vue基础、构建工具、TS/JS、Git命令、项目配置 |
| 特殊之处 | 后半场基于真实项目提问,考察工程化环境熟练度 |
🔍 逐题深度解析
一、Vue2和Vue3的区别
回答思路:从响应式原理、API风格、TypeScript支持、性能、新特性等多个维度对比。
| 维度 | Vue2 | Vue3 |
|---|---|---|
| 响应式 | Object.defineProperty(需Vue.set处理新增属性) | Proxy(可拦截13种操作,支持数组索引/长度变化) |
| API风格 | Options API(data、methods、computed等) | Composition API(setup函数,逻辑复用更灵活) |
| TypeScript | 支持较弱 | 原生支持,类型推断友好 |
| 性能 | 初始化递归遍历所有属性 | 懒递归(访问时才深度代理),初始化更快 |
| 体积 | 较大 | Tree-shaking友好,可按需引入 |
| 根节点 | 单根节点 | 多根节点(Fragment) |
| 新特性 | - | Teleport、Suspense |
二、Webpack和Vite的区别
回答思路:从开发环境启动速度、热更新、生产打包、配置复杂度等维度对比。
| 维度 | Webpack | Vite |
|---|---|---|
| 开发环境 | 打包所有模块后启动,慢 | 利用浏览器ESM直接启动,秒开 |
| 热更新 | 修改后重新打包相关模块 | 只编译变更的模块,几乎瞬时 |
| 生产打包 | 统一打包成bundle | 使用Rollup预打包,产物优化好 |
| 配置复杂度 | 高(loader、plugin繁多) | 低(开箱即用) |
三、JavaScript和TypeScript的区别
| 维度 | JavaScript | TypeScript |
|---|---|---|
| 类型系统 | 动态类型,运行时推断 | 静态类型,编译时检查 |
| 错误发现 | 运行时才发现 | 编写时即可捕获(IDE提示) |
| 可读性 | 大型项目类型难追踪 | 类型即文档,重构更安全 |
| 编译 | 直接运行 | 需编译成JS |
| 生态 | 通用 | IDE支持更好(智能提示、重构) |
四、多角色权限守卫怎么拦截
回答思路 :权限守卫的核心是路由拦截。
javascript
// Vue Router 全局前置守卫
router.beforeEach((to, from, next) => {
const token = localStorage.getItem('token')
const role = store.state.user.role // 用户角色
if (!token && to.path !== '/login') {
next('/login')
} else if (to.meta.role && !to.meta.role.includes(role)) {
next('/403') // 无权限
} else {
next()
}
})
五、let、const、var的区别
| 维度 | var |
let |
const |
|---|---|---|---|
| 作用域 | 函数作用域 | 块级作用域 | 块级作用域 |
| 变量提升 | 是(初始undefined) | 是,但存在暂时性死区 | 是,存在TDZ |
| 重复声明 | 允许 | 不允许 | 不允许 |
| 重新赋值 | 允许 | 允许 | 不允许(引用类型属性可改) |
| 挂载window | 是 | 否 | 否 |
六、防抖和节流
防抖:动作停止后延迟执行(适用于输入框搜索、resize)
javascript
function debounce(fn, delay) {
let timer = null
return function(...args) {
clearTimeout(timer)
timer = setTimeout(() => fn.apply(this, args), delay)
}
}
节流:固定间隔执行(适用于滚动加载、按钮限流)
javascript
function throttle(fn, delay) {
let lastTime = 0
return function(...args) {
const now = Date.now()
if (now - lastTime >= delay) {
lastTime = now
fn.apply(this, args)
}
}
}
七~十七:工程化实操问答
7. 怎么打开一个终端窗口
- VS Code:
Ctrl + ```(Mac:Cmd + ```)或菜单 Terminal → New Terminal
8. 包管理文件
package.json(记录依赖、脚本、配置)- 锁文件:
package-lock.json(npm)/yarn.lock(yarn)
9. yarn和npm的区别
| 维度 | npm | yarn |
|---|---|---|
| 速度 | 较慢(串行) | 较快(并行) |
| 缓存 | 有 | 更高效 |
| workspace | npm7+支持 | 原生支持 |
10. 从远程拉取代码的命令
bash
git clone <仓库地址>
11. 远程有更新,如何拉取新代码
bash
git pull origin <分支名> # 拉取并合并
# 或分步:git fetch + git merge
12. Git切换分支
bash
git checkout <分支名> # 切换
git checkout -b <新分支名> # 创建并切换
13. 打包成静态文件
bash
npm run build # Vue CLI / Vite 通用
# 产物在 dist/ 或 build/ 目录
14. vue.config.js的内容
javascript
module.exports = {
publicPath: '/',
devServer: { proxy: { '/api': 'http://localhost:8080' } },
configureWebpack: {},
chainWebpack: config => {}
}
15. .gitignore的作用
- 指定不被Git追踪的文件/目录(
node_modules、dist、.env等)
16. v-if和v-show的区别
| 维度 | v-if | v-show |
|---|---|---|
| 原理 | 条件假时DOM不存在 | 条件假时display:none |
| 切换开销 | 高(销毁重建) | 低(CSS切换) |
| 初始渲染 | 条件假时不渲染 | 总会渲染 |
| 场景 | 切换频率低 | 切换频率高 |
17. inject的作用
- Vue依赖注入:父组件
provide提供数据,后代组件inject接收,避免props逐层传递
javascript
// 父组件
provide() { return { user: this.user } }
// 子组件
inject: ['user']
📚 知识点速查表
| 知识点 | 核心要点 |
|---|---|
| Vue2 vs Vue3 | defineProperty vs Proxy、Options vs Composition、Fragment |
| Webpack vs Vite | 开发环境打包/不打包、HMR效率、Rollup生产打包 |
| TS vs JS | 静态/动态类型、编译时/运行时错误、IDE支持 |
| 权限守卫 | 路由拦截、token校验、角色匹配 |
| 变量声明 | var函数作用域/提升、let/const块级作用域/TDZ |
| 防抖节流 | 防抖合并(输入框)、节流降频(滚动) |
| Git命令 | clone、pull、checkout、branch |
| 项目配置 | package.json、vue.config.js、.gitignore |
| 指令 | v-if销毁重建、v-show CSS切换 |
| inject/provide | 跨级传值,避免props逐层传递 |
📌 最后一句:
威派格这场面试,前半场是基础"扫盲",后半场是工程化"摸家底"。那些AI可以帮你生成的代码,面试官直接跳过,反而聚焦在Git命令、项目配置、打包部署这些最基础、最容易被忽视 的实操能力上。AI能帮你写组件,但不能帮你解决Git冲突;能帮你写
vue.config.js,但不能帮你在面试官的终端里打出那条npm run build。 工程化环境的熟练度,依然是区分"会用AI"和"真懂开发"的重要标尺。