前端面试题

以下是更贴合企业面试实际、分维度且附带答题思路 + 避坑点的前端面试题,覆盖基础、进阶、框架、工程化等核心模块,适配不同面试场景:

一、HTML/CSS 高频题(基础必答)

  1. viewport 视口的核心属性有哪些?如何适配移动端?

    • 答题思路:先说明 viewport 是移动端适配核心,核心属性(width=device-width、initial-scale=1.0、user-scalable=no 等);再讲适配方案(rem/vw/vh、媒体查询、flex 布局),结合实际项目举例(如用 postcss-px-to-viewport 自动转 px 为 vw)。
    • 避坑点:不要只说属性,要讲清 "为什么这些属性能解决移动端适配"。
  2. CSS 实现一个 1:1 自适应正方形?至少两种方法。

    • 答题思路:① 利用 padding-top/bottom(百分比基于父元素宽度):width: 100%; padding-top: 100%; height: 0;;② 利用 aspect-ratio 属性(CSS3 新特性):width: 100%; aspect-ratio: 1/1;
    • 避坑点:不要忽略 "自适应",避免写固定宽高的方案。
  3. CSS 优先级冲突时,!important 一定生效吗?为什么?

    • 答题思路:不一定;优先级规则:!important > 内联样式 > ID > 类 / 伪类 / 属性 > 元素 / 伪元素;但如果两个样式都加了!important,仍按 "后定义覆盖前定义""选择器优先级高的生效",且内联样式 +!important 优先级高于外部样式 +!important。
    • 避坑点:不要说 "!important 是最高优先级,一定生效",要讲清例外场景。

二、JavaScript 核心题(进阶重点)

  1. 手写实现 Promise.all,要求处理异常(失败一个全部失败)。

    • 答题思路: javascript

      运行

      复制代码
      function myPromiseAll(promises) {
        return new Promise((resolve, reject) => {
          if (!Array.isArray(promises)) return reject(new TypeError('参数必须是数组'));
          const result = [];
          let count = 0;
          promises.forEach((p, index) => {
            Promise.resolve(p).then(res => {
              result[index] = res;
              count++;
              if (count === promises.length) resolve(result);
            }).catch(err => reject(err)); // 一个失败直接reject
          });
        });
      }
    • 避坑点:要处理 "非 Promise 类型的参数"(用 Promise.resolve 包装),且结果数组的顺序要和入参数组一致。

  2. 解释什么是防抖节流?分别用在什么场景?手写防抖函数(带立即执行版)。

    • 答题思路:

      • 防抖:触发后延迟 n 秒执行,期间再次触发则重置延迟(场景:搜索框输入、窗口 resize);

      • 节流:触发后 n 秒内只能执行一次(场景:滚动加载、按钮防连点);

      • 手写立即执行版防抖: javascript

        运行

        复制代码
        function debounce(fn, delay, immediate = false) {
          let timer = null;
          return function(...args) {
            if (timer) clearTimeout(timer);
            if (immediate && !timer) fn.apply(this, args);
            timer = setTimeout(() => {
              if (!immediate) fn.apply(this, args);
              timer = null;
            }, delay);
          };
        }
    • 避坑点:不要混淆防抖节流的场景,且要处理 this 指向和参数传递。

  3. 为什么 0.1 + 0.2 !== 0.3?如何解决这个问题?

    • 答题思路:JS 采用 IEEE 754 双精度浮点数存储,0.1 和 0.2 二进制是无限循环小数,存储时精度丢失;解决方法:① 转整数计算((0.110 + 0.210)/10);② 用 toFixed 保留小数(注意 toFixed 是四舍五入);③ 用第三方库(如 decimal.js)。
    • 避坑点:不要只说 "精度丢失",要讲清底层存储原理。

三、框架题(Vue/React 二选一)

Vue 方向
  1. Vue3 的 setup 语法糖中,defineProps/defineEmits 为什么不需要导入?

    • 答题思路:Vue3 对 <script setup> 做了语法糖优化,defineProps/defineEmits 是编译器宏(compiler macros),在编译阶段会被处理,无需手动导入;且这些宏只能在 setup 语法糖中使用,作用域仅限于当前组件。
    • 避坑点:不要说 "是全局变量",要强调 "编译器层面的特殊处理"。
  2. Vue 的 keep-alive 原理是什么?如何缓存指定组件 / 排除指定组件?

    • 答题思路:keep-alive 是内置组件,会缓存不活动的组件实例(而非销毁),原理是将组件实例存入 cache 对象,再次渲染时直接取缓存;通过 include(缓存指定组件)、exclude(排除指定组件)、max(最大缓存数)控制,属性值支持字符串、数组、正则。
    • 避坑点:不要忽略 "max 属性的作用"(超过数量会按 LRU 策略删除最久未使用的缓存)。
React 方向
  1. React 的 useMemo 和 useCallback 的区别?分别解决什么问题?

    • 答题思路:
      • useMemo:缓存计算结果(避免每次渲染重复计算),返回值是计算结果;
      • useCallback:缓存函数引用(避免子组件因函数引用变化重复渲染),返回值是函数;
    • 避坑点:不要滥用(比如简单计算 / 函数无需缓存,会增加内存开销),要讲清 "依赖数组为空时,仅首次渲染缓存"。
  2. React 中什么是虚拟 DOM Diff 算法?key 的作用是什么?

    • 答题思路:Diff 算法是对比新旧虚拟 DOM 树,找出差异部分只更新真实 DOM;key 是列表渲染时的唯一标识,帮助 React 识别哪些元素被添加 / 删除 / 移动,避免错误复用节点;若不用 key,React 会采用 "就地更新" 策略,可能导致状态错乱。
    • 避坑点:不要说 "key 用 index 更好",要说明 index 作为 key 在列表排序 / 增删时的问题。

四、工程化 & 性能优化题(中高级必答)

  1. Vite 比 Webpack 快的核心原因是什么?

    • 答题思路:① 构建原理不同:Vite 基于 ES Module 原生支持,开发时无需打包(按需编译),Webpack 开发时需打包成 bundle;② 依赖预构建:Vite 用 esbuild 预构建第三方依赖(esbuild 是 Go 编写,比 JS 快 10-100 倍),Webpack 用 JS 处理依赖;③ 热更新:Vite 热更新只更新修改的模块,Webpack 热更新可能重新打包整个模块。
    • 避坑点:不要只说 "Vite 不用打包",要区分 "开发环境" 和 "生产环境"(Vite 生产环境仍用 Rollup 打包)。
  2. 前端性能优化中,如何诊断首屏加载慢的问题?至少 3 种方法。

    • 答题思路:① 用 Chrome DevTools 的 Performance 面板录制加载过程,分析长任务、资源加载耗时;② 用 Lighthouse 生成性能报告,查看 FCP(首次内容绘制)、LCP(最大内容绘制)等指标;③ 查看 Network 面板,分析资源大小、加载顺序、是否有冗余请求;
    • 避坑点:不要只说优化方案,要先讲 "诊断方法",再对应优化(比如 Network 看到大图片,就做图片压缩 / 懒加载)。

五、场景题(考察实战能力)

  1. 项目中遇到 "白屏问题",你会如何排查和解决?

    • 答题思路:① 排查步骤:看控制台报错(JS 报错 / 资源加载失败)→ 检查网络(接口返回异常 / CDN 资源失效)→ 检查渲染逻辑(首屏数据未加载完成就渲染)→ 检查兼容性(语法不兼容 / API 不支持);② 解决方法:JS 报错(修复代码 / 增加容错)、资源加载失败(降级方案 / 备用 CDN)、数据问题(骨架屏 / 加载态)、兼容性(Babel 转译 / Polyfill)。
  2. 如何实现一个前端权限控制系统?(按钮级)

    • 答题思路:① 权限设计:分角色(admin / 普通用户)、分权限点(按钮 / 接口),后端返回当前用户权限列表;② 实现方式:Vue 中用自定义指令(v-permission),React 中用高阶组件 / Hooks,判断当前权限列表是否包含按钮权限,不包含则隐藏 / 禁用按钮;③ 补充:路由层面增加守卫,避免无权限访问页面。
相关推荐
JIngJaneIL1 小时前
基于Java音乐管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot
接着奏乐接着舞1 小时前
react hooks
前端·javascript·react.js
踢球的打工仔1 小时前
前端html(3)
前端·算法·html
IDOlaoluo1 小时前
nginx-sticky怎么用 Nginx 负载均衡添加 sticky 模块完整步骤
前端·chrome
接着奏乐接着舞1 小时前
react redux 分组
前端·javascript·react.js
IT_陈寒1 小时前
Vue 3.4 性能优化揭秘:这5个Composition API技巧让我的应用提速40%
前端·人工智能·后端
行走的陀螺仪1 小时前
实时通信底层原理深度剖析:短轮询、长轮询与WebSocket的本质差异
前端·网络·websocket·网络协议
大猩猩X1 小时前
vue vxe-gantt 甘特图实现产品进度列表,自定义任务条样式和提示信息
前端·javascript·甘特图·vxe-ui·vxe-gantt
一字白首1 小时前
Vue 进阶,生命周期 + 工程化开发
前端·javascript·vue.js