2025 frontend interview records
前端 面试 10

前端面试问题总结

最近面试了很多,也有在总结自己的不足,主要是记录下之前没遇到的问题,尽量为下次面试做好准备。

避免出现公司名字,使用数字代替吧

公司1:

  1. vue 组件通信。 props、event、vuex、eventBus,provide/inject

  2. ref 和 reactive 区别

    1. ref 适合独立变量属性,原始数据类型如 string,number,内部调用 reactive 实现响应式,可直接整体覆盖赋值,如替换对象,依然保持响应式

    2. reactive 适合对象,数组,无需调用 .value,直接返回 proxy 对象,常用表单对象,只修改内部属性,不重新赋值的情况

  3. vuex 和 pinia 使用中的区别。

    1. vuex Api→ mutations/actions/getters,pinia Api→ state/getters/actions

    2. pinia 原生支持 Ts,vuex 需要插件支持

    3. vuex 必须通过 mutation 修改 state,pinia 可直接修改 state

  4. keep-alive 的使用场景

    1. 标签页切换,表单填写状态,列表-详情页面滚动状态和过滤状态等,避免复杂组件重复渲染

    2. 一般放在 keep-alive 组件内部,属性有 include, exclude, max 限制最大缓存实例数

  5. css 样式污染。

    1. scope 添加 data-v-随机id

    2. 生成唯一类名

    3. 手动命名

    4. 沙箱机制

  6. git merge rebase、reset revert。答出使用场景和区别

  7. 事件循环机制。答出常见的宏任务和微任务以及循环顺序,

    1. promise 异步方法被 catch 后 会继续执行 finally

【代码题】

  1. 获取数组深度

/**
 * 获取数组的深度
 * @param {Array} arr - 要检查的数组
 * @returns {number} 数组的深度(最外层为1)
 */
function getArrayDepth(arr) {
  // 如果不是数组或数组为空,深度为0
  if (!Array.isArray(arr) || arr.length === 0) {
    return 0;
  }
  
  // 递归计算每个元素的深度
  const depths = arr.map(item => {
    if (Array.isArray(item)) {
      return getArrayDepth(item);
    }
    return 0;
  });
  
  // 返回最大深度 + 1(当前层级)
  return Math.max(...depths) + 1;
}

公司2:

  1. React 区别 Vue

  2. React 优点

  3. JSX 语法特点

公司3:

  1. toRef 和 toRefs 区别

    1. toRef 是转换单个属性,参数为 toRef(obj, key)

    2. toRefs 是转换整个对象,直接解构赋值 { a, b } = toRefs(obj)

  2. reactive 解构陷阱,reactive 的陷阱: reactive 的最大问题是解构会破坏响应性。这是因为它返回的是一个 Proxy 对象,解构出来的属性是普通的值,不再与 Proxy 关联。必须配合 toRefs 才能安全地解构。

  3. vue Router 路由守卫

    1. 全局 beforeEach,afterEach 参数 to from next

    2. 内部 beforeEnter 参数也是 to from next

    3. 组件内:beforeRouteEnter,beforeRouteUpdate,beforeRouteLeave

公司4:

  1. Vue2 为何检测不到数组更新,因为重写了底层数组方法

  2. Vue3.2 新属性 v-bind 实现 css 响应式

  3. 前端鉴权

    1. 静态鉴权:路由中 meta信息:requireAuth ,permission

      1. 路由级别:beforeEach 判断 token,获取用户权限后对比,未授权则返回403页面

    2. 动态鉴权:后端配置好相关人员对应的菜单权限

    3. 按钮级别,v-if 判断,或者封装指令

  4. 请求压缩,pako 库进行 GZIP 压缩

公司5:

  1. 项目经历,组件封装经历

  2. console.log(a 1 && a 2 && a == 3) 为 true,写出 a 的格式

    a = {
    	i: 1,
    	toString: function(){
    		return a.i++
    	}
    }
    
  3. 算法题:给出一个无序数组,要求返回当前数组中缺少的最小正整数,链接

公司6:

  1. 项目细节,注重底层原理

  2. 大学课程,计算机组成原理内容,专业课:数据结构,计算机组成原理,操作系统…

公司7:

  1. 项目代码部分人可见,分包,分仓

  2. 浏览器请求数量限制:6,小程序:5 → 10

  3. vue项目分包,使用场景

公司8:

  1. 白屏时间计算,三种方式,web API,手动埋点,第三方库(Web Vitals)

    const timing = window.performance.timing;
    const whiteScreenTime = timing.responseEnd - timing.navigationStart;
    
    // 更精确的首次绘制时间(需浏览器支持)
    performance.getEntriesByType('paint').forEach(entry => {
      if (entry.name === 'first-paint') {
        console.log('FP:', entry.startTime);
      }
    });
    
    <!DOCTYPE html>
        <html>
        <head>
          <script>
            // 起始时间戳(尽量靠近<head>顶部)
            window.pageStartTime = Date.now();
          </script>
          <!-- 其他资源 -->
        </head>
        <body>
          <script>
            // 首帧渲染后计算(如首屏元素出现)
            const firstElement = document.querySelector('.first-content');
            const whiteScreenTime = Date.now() - window.pageStartTime;
          </script>
        </body>
        </html>
    
    import { getFCP } from 'web-vitals';
    
        getFCP((metric) => {
          console.log('First Contentful Paint:', metric.value);
        });
    
  2. 白屏优化:

    1. 网络层面:cdn,dns 解析,减少重定向

    2. 资源层面:压缩图片,服务器启用 brotli Content-Encoding: br, 资源预加载,link 使用 rel:preload 属性,资源异步加载:async

    3. 渲染层:骨架屏,服务端渲染SSR,优化DOM层级

    4. 代码层面:路由动态引入,keep-alive

公司9:

  1. 项目难点,亮点

  2. 稳定性,未来发展方向,

  3. 日常学习网站,极客时间,MDN,stack Overflow,算法网站等,博客园,优秀博客,github

公司10:

  1. 同一个项目,分业务范围功能差异打包,如各区域/厂商的差异化开发 → 路由方案判断传入参数

  2. 接上,大屏项目就是如此,通过配置环境env,区别处理各项目的差异化功能及内容

  3. 组件封装经历,说了轮播图表组件,视频播放组件

  4. 从输入网址到展示网页全流程

  5. HR 问日常,稳定性(自己的项目是否还在继续做),裸辞原因

公司11:

  1. provide,inject 数据 不会同步修改,可以包裹 computed 或者使用 setup 语法(组合式写法)或者直接返回方法,把this 也返回去

  2. qiankun 了解程度,如果不使用微前端,实现微前端功能

    1. 可以使用 iframe,单独写个页面引入路由

  3. table 大量数据处理:

    1. 虚拟滚动 vitrual-scroll 可视窗口渲染

    2. 不需要更新,v-once

    3. 需要更新,v-memo 缓存

    4. 懒加载,分页等

  4. 箭头函数没有自己的this,指向外层非箭头函数的对象作用域,定义时即确认this,后续无法改变

  5. Map 和 对象的区别:

    1. Map 键值可以是任意类型,对象的键值只能是字符串或 Symbol

    2. Map 有 get,set,has,delete等方法,Map 通过 size 获取长度,对象只能Object.keys().length

    3. JSON 支持对象,不支持 Map,需要先进行序列化为Array 或其他格式

公司12:

  1. 扩展接口和插件机制,虚拟键盘,密码加密

  2. vue23区别,跨域问题,性能优化各方面

公司13:

  1. 线上内存溢出如何调试,线上性能问题处理

  2. 线上去除打印内容,UglifyJsPlugin

2025 frontend interview records
http://blog.cirzear.cn/archives/2025-frontend-interview-records
作者
Cirzear
发布于
更新于
许可