前端面试问题打靶

一、HTML / CSS 基础

1. 语义化标签有哪些?为什么要用语义化?

常见标签: headernavmainsectionarticleasidefooterfiguretime 等。

作用:

  • 结构更清晰,利于维护
  • SEO 更友好,搜索引擎更好理解页面
  • 无障碍更好(读屏软件)
  • 团队协作成本更低

2. display: nonevisibility: hiddenopacity: 0 区别?

属性 是否占位 是否响应事件 是否继承
display: none
visibility: hidden
opacity: 0 是(默认)

3. 盒模型:content-boxborder-box 区别?

  • content-box:width/height 只算内容区,padding、border 额外加
  • border-box:width/height 包含 content + padding + border

实际开发常用:

复制代码
* { box-sizing: border-box; }

4. BFC 是什么?如何触发?解决什么问题?

BFC(块级格式化上下文):独立渲染区域,内外布局互不影响。

触发方式:

  • overflow: hidden/auto
  • display: flex/inline-block
  • position: absolute/fixed
  • float 不为 none

解决问题:

  • 清除浮动(父元素高度塌陷)
  • 阻止 margin 重叠
  • 自适应两栏布局

5. 水平垂直居中常见写法?

复制代码
Flex(推荐):

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

Grid:

.parent {
  display: grid;
  place-items: center;
}

绝对定位:

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

6. Flex 和 Grid 适用场景?

  • Flex:一维布局(导航栏、表单行、左右结构)
  • Grid:二维布局(整页、卡片矩阵、复杂仪表盘)

7. 移动端 1px 边框问题怎么解决?

高清屏下 1px 看起来偏粗。

常见方案:

  • transform: scaleY(0.5)
  • box-shadow: 0 0.5px 0 #ccc
  • viewport + rem 适配
  • 使用伪元素 + scale

8. rememvwvh 区别?

  • em:相对父元素 font-size
  • rem:相对根元素 html font-size
  • vw/vh:相对视口宽/高 1%
  • vmin/vmax:取 vw、vh 较小/较大值

9. CSS 选择器优先级?

权重: !important > 行内样式 > ID > 类/属性/伪类 > 标签/伪元素

计算:(a, b, c)

  • a:ID 个数
  • b:类/属性/伪类个数
  • c:标签/伪元素个数

10. 两栏布局(左固定右自适应)?

Flex:

.container { display: flex; }

.left { width: 200px; flex-shrink: 0; }

.right { flex: 1; }

Grid:

.container { display: grid; grid-template-columns: 200px 1fr; }


二、JavaScript 基础

1. varletconst 区别?

var let const
作用域 函数 块级 块级
变量提升 无(TDZ)
重复声明 可以 不可以 不可以
修改值 可以 可以 不可以(对象属性可改)

2. 闭包是什么?应用场景?

定义: 函数能访问其词法作用域外的变量,即使外层已执行完毕。

场景:

  • 防抖/节流
  • 私有变量
  • 柯里化
  • 缓存计算结果

注意: 不当使用可能导致内存泄漏。


3. 原型链是什么?

每个对象有 __proto__,指向构造函数的 prototype

查找属性时:自身 → 原型 → 原型的原型 → ... → null


4. this 指向规则?

  1. 默认绑定:非严格模式指向 window
  2. 隐式绑定:obj.fn()this 指向 obj
  3. 显式绑定:call/apply/bind
  4. new 绑定:指向新实例
  5. 箭头函数:继承外层 this,不可被 call 改变

5. 事件循环:宏任务、微任务顺序?

宏任务: setTimeoutsetInterval、I/O、UI 渲染

微任务: Promise.thenMutationObserverqueueMicrotask

顺序:

  1. 执行同步代码
  2. 清空微任务队列
  3. 执行一个宏任务
  4. 再清空微任务
  5. 循环

6. Promiseasync/await 区别?

  • Promise:链式处理异步,状态 pending/fulfilled/rejected
  • async/await:同步写法处理异步,本质是 Promise 语法糖

错误处理:

复制代码
try {
  const res = await api()
} catch (e) {
  console.error(e)
}

7. 深拷贝和浅拷贝?

  • 浅拷贝:只复制第一层,引用类型仍共享
  • 深拷贝:递归复制所有层级

实现方式:

  • 浅拷贝:Object.assign{...obj}arr.slice()
  • 深拷贝:structuredClone(现代浏览器)、JSON.parse(JSON.stringify())(有局限)、递归实现

8. 防抖和节流?

  • 防抖 debounce:连续触发只执行最后一次(搜索框输入)
  • 节流 throttle:固定时间内只执行一次(滚动、resize)

9. ===== 区别?

  • ==:会类型转换后比较
  • ===:严格相等,类型和值都相同

开发推荐用 ===


10. ES6+ 常用特性

  • 解构赋值、展开运算符
  • 箭头函数、模板字符串
  • let/const、块级作用域
  • Promise、async/await
  • 模块化 import/export
  • Class、Map/Set、可选链 ?.、空值合并 ??

三、浏览器与网络

1. 从输入 URL 到页面展示?

  1. DNS 解析
  2. TCP 连接(三次握手)
  3. HTTPS 还要 TLS 握手
  4. 发送 HTTP 请求
  5. 服务器响应
  6. 浏览器解析 HTML → DOM
  7. 解析 CSS → CSSOM
  8. 合成渲染树 → 布局 → 绘制
  9. 加载 JS、图片等资源
  10. 可能触发重排/重绘

2. 强缓存、协商缓存?

强缓存(不发请求):

  • Cache-Control: max-age=xxx
  • Expires

协商缓存(发请求,304 用缓存):

  • Last-Modified / If-Modified-Since
  • ETag / If-None-Match(更精确)

流程: 先强缓存 → 过期后协商缓存 → 304 或 200


3. Cookie、SessionStorage、LocalStorage?

Cookie SessionStorage LocalStorage
生命周期 可设过期 关标签页清除 永久(手动清)
容量 ~4KB ~5MB ~5MB
随请求发送
作用域 可设 domain 当前标签页 同源

4. 跨域及解决方案?

原因: 浏览器同源策略(协议、域名、端口相同)

方案:

  • 后端 CORS
  • 开发环境 proxy 代理
  • Nginx 反向代理
  • JSONP(仅 GET,老方案)
  • postMessage(iframe 通信)

5. HTTPS 和 HTTP 区别?

  • HTTPS = HTTP + TLS/SSL
  • 数据加密传输
  • 身份校验(证书)
  • 默认端口 443
  • 防止中间人篡改、窃听

6. 重排和重绘?

  • 重排 reflow:几何属性变化(宽高、位置),开销大
  • 重绘 repaint:外观变化(颜色),开销较小

优化: 批量改 DOM、用 transform 代替 top/left、DocumentFragment、避免频繁读布局属性


7. XSS、CSRF 防护?

XSS(跨站脚本): 注入恶意脚本

  • 防护:转义输出、CSP、HttpOnly Cookie、避免 innerHTML 插不可信内容

CSRF(跨站请求伪造): 借用户 Cookie 发请求

  • 防护:Token 校验、SameSite Cookie、Referer 校验

四、Vue 常考

1. Vue2 和 Vue3 核心区别?

  • 响应式:Object.defineProperty → Proxy
  • 组合式 API:Composition API
  • 性能更好,Tree-shaking 更好
  • 多个根节点(Fragment)
  • Teleport、Suspense 等新特性

2. 响应式原理?

Vue2: 递归遍历 data,用 Object.defineProperty 劫持 get/set,数组部分方法重写。

Vue3: Proxy 代理整个对象,可监听新增/删除属性,性能更好。


3. 组件通信方式?

  • 父 → 子:props
  • 子 → 父:$emit
  • 跨级:provide/inject
  • 全局:Vuex/Pinia、EventBus(Vue3 少用)
  • ref 获取子组件实例

4. v-ifv-show 区别?

  • v-if:条件渲染,false 时不渲染 DOM,切换开销大
  • v-show:始终渲染,用 display:none 切换,频繁切换更合适

5. computedwatch 区别?

  • computed:有缓存,依赖不变不重新计算,适合派生数据
  • watch:监听变化执行副作用,适合异步、复杂逻辑

6. 生命周期做什么?

Vue2:

created(请求数据)→ mounted(DOM 操作、ECharts)→ updated → beforeDestroy(清定时器、解绑)

Vue3:

setup → onMounted → onUpdated → onUnmounted


7. nextTick 原理?

DOM 更新是异步的。nextTick 在下次 DOM 更新循环结束后执行回调,用于拿到更新后的 DOM。


8. key 的作用?

帮助 Diff 算法识别节点,提高复用效率。

列表用 唯一 id 作 key,避免用 index(增删顺序会变导致错乱)。


9. 虚拟 DOM 是什么?

用 JS 对象描述 DOM 结构,通过 Diff 找出最小变更再更新真实 DOM。

不是一定更快,但能简化编程模型,批量更新减少直接操作 DOM 次数。


10. Pinia / Vuex?

  • Vuex:Vue2 官方状态管理,mutations/actions/modules
  • Pinia:Vue3 推荐,更轻、TS 友好、无 mutations

适合:多组件共享状态、用户信息、权限、购物车等。


11. 路由守卫与权限?

  • 全局: beforeEach 判断 token/角色
  • 路由独享: beforeEnter
  • 组件内: beforeRouteEnter

按钮级权限: 路由 meta + 权限码 + 自定义指令 v-permission


五、React 常考(简要)

1. 类组件 vs Hooks?

函数组件 + Hooks 是主流,逻辑复用更方便,代码更简洁。

2. useStateuseEffect 注意点?

  • 不要异步读闭包里的旧 state,用函数式更新
  • useEffect 依赖数组要写全,避免无限循环

3. useMemouseCallback

缓存计算结果和函数引用,避免子组件无效重渲染。不要滥用。


六、工程化

1. Webpack 和 Vite 区别?

  • Webpack:打包器,开发时也打包,项目大时慢
  • Vite:开发用 ES Module + 预构建,HMR 快;生产用 Rollup 打包

2. Tree Shaking?

基于 ES Module 静态分析,去掉未使用代码。

需要 sideEffects 配置,CommonJS 支持较差。

3. Git merge vs rebase?

  • merge:保留完整历史,产生 merge commit
  • rebase:线性历史,更整洁;公共分支慎用

七、性能优化

1. 首屏慢怎么优化?

  • 路由/组件懒加载
  • 图片懒加载、WebP、压缩
  • CDN、Gzip/Brotli
  • 减少首屏 JS 体积
  • SSR/预渲染(按需)
  • 接口合并、缓存

2. 长列表优化?

  • 虚拟滚动(只渲染可视区)
  • 分页
  • 避免复杂 watcher

八、手写题参考答案

防抖

复制代码
function debounce(fn, delay) {
  let timer = null
  return function (...args) {
    clearTimeout(timer)
    timer = setTimeout(() => fn.apply(this, args), delay)
  }
}

节流

复制代码
function throttle(fn, delay) {
  let last = 0
  return function (...args) {
    const now = Date.now()
    if (now - last >= delay) {
      last = now
      fn.apply(this, args)
    }
  }
}

深拷贝(简易版)

复制代码
function deepClone(obj, map = new WeakMap()) {
  if (obj === null || typeof obj !== 'object') return obj
  if (map.has(obj)) return map.get(obj)
  const result = Array.isArray(obj) ? [] : {}
  map.set(obj, result)
  for (const key in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
      result[key] = deepClone(obj[key], map)
    }
  }
  return result
}

数组扁平化

复制代码
const flat = arr => arr.reduce((acc, cur) =>
acc.concat(Array.isArray(cur) ? flat(cur) : cur), [])

九、项目实战(答题模板)

1. 最复杂的前端模块?

在 xx 项目中负责报表/权限/大屏模块。难点是大量表格数据、复杂筛选、与 SAP 接口对接。我用虚拟滚动 + 分页 + 请求防抖,表格渲染从卡顿优化到流畅;权限用路由 meta + 动态菜单 + 按钮级指令实现。

2. 登录态过期怎么处理?

axios 响应拦截器判断 401,清 token,跳转登录并带 redirect;请求拦截器自动带 token;refresh token 方案(如有)在过期前静默刷新。

3. 线上 bug 怎么定位?

复现 → 看控制台/Network → 对比环境 → 加日志 → 本地修 → 回归 → 总结(加校验/测试/Review)。


十、后台管理项目加分项

场景 回答要点
Token 登录 localStorage/sessionStorage 存 token,拦截器注入 Header
表格 CRUD 分页参数、loading、空态、错误提示
导出 Excel 后端导出 或 前端 xlsx 库
文件上传 FormData、进度条、大小/类型校验
字典下拉 接口缓存、label/value 映射

相关推荐
赵庆明老师1 小时前
JS检查提交的文件是否合规
开发语言·前端·javascript
禅思院1 小时前
前端请求取消与调度完全指南:从 AbortController 到企业级优先级架构
前端·设计模式·前端框架
颂love1 小时前
Vue的两大生态以及组件通信
前端·javascript·vue.js·typescript
甜汤圆1 小时前
Python 里**自定义数据单元**
前端
cidy_981 小时前
将 Figma 接入 Codex MCP:从 `/plugins` 到本地插件配置的完整教程
前端
vivo互联网技术1 小时前
动效开发不踩坑:几种动效实现方案对比与实战选型
前端·性能优化·动效
Csvn1 小时前
【Vue3】Composition API vs Options API —— 什么场景该选哪个
前端
Csvn1 小时前
Vue3 迁移血泪史:v-model 的 .sync 陷阱,90% 升级项目都会踩
前端·vue.js
光影少年1 小时前
js单线程,为什在node环境下的js可以处理高并发请求?
前端·javascript·掘金·金石计划