跳到主要内容

面试真题

JavaScript 基础

1. 已知 a = [1,2,3];求 console.log(a.push(5)) 的值是?为什么?

答案: 输出结果为 4

解析:

  • push() 方法会向数组末尾添加一个或多个元素,并返回修改后数组的新长度
  • a.push(5) 会将 5 添加到数组 [1,2,3] 中,数组变为 [1,2,3,5]
  • 返回值为新数组的长度,即 4
  • 注意:push() 方法会修改原数组
let a = [1, 2, 3];
let result = a.push(5);
console.log(result); // 4
console.log(a); // [1, 2, 3, 5]

2. 数组排序方法除 sort 排序外还有哪些?并写出其中一种排序方法?

其他排序方法:

  • 冒泡排序(Bubble Sort)
  • 选择排序(Selection Sort)
  • 插入排序(Insertion Sort)
  • 快速排序(Quick Sort)
  • 归并排序(Merge Sort)
  • 堆排序(Heap Sort)
  • 计数排序(Counting Sort)

示例:快速排序实现

function quickSort(arr) {
// 递归出口
if (arr.length <= 1) {
return arr;
}

// 选择基准值(中间位置)
const pivotIndex = Math.floor(arr.length / 2);
const pivot = arr.splice(pivotIndex, 1)[0];

// 定义左右数组
const left = [];
const right = [];

// 分区操作
for (let i = 0; i < arr.length; i++) {
if (arr[i] < pivot) {
left.push(arr[i]);
} else {
right.push(arr[i]);
}
}

// 递归排序并合并
return quickSort(left).concat([pivot], quickSort(right));
}

// 测试
const arr = [5, 2, 8, 1, 9, 3];
console.log(quickSort(arr)); // [1, 2, 3, 5, 8, 9]

事件处理与防抖节流

3. 常用的防止按钮多次点击触发的方案有哪些?并说明他们的区别?

常见方案:

方案一:防抖(Debounce)

function debounce(fn, delay = 300) {
let timer = null;
return function(...args) {
clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, args);
}, delay);
};
}

// 使用
button.addEventListener('click', debounce(handleClick, 300));

方案二:节流(Throttle)

function throttle(fn, interval = 300) {
let lastTime = 0;
return function(...args) {
const now = Date.now();
if (now - lastTime >= interval) {
lastTime = now;
fn.apply(this, args);
}
};
}

// 使用
button.addEventListener('click', throttle(handleClick, 300));

方案三:标志位控制

let isClicked = false;

button.addEventListener('click', function() {
if (isClicked) return;
isClicked = true;

handleClick();

// 根据业务需求重置标志位
setTimeout(() => {
isClicked = false;
}, 1000);
});

方案四:禁用按钮

button.addEventListener('click', function() {
button.disabled = true;
button.textContent = '处理中...';

handleClick().finally(() => {
button.disabled = false;
button.textContent = '提交';
});
});

区别对比:

方案特点适用场景
防抖n 秒内只执行最后一次,重新触发会重置计时器搜索框输入、窗口 resize
节流n 秒内只执行一次,时间间隔固定滚动加载、按钮点击频率限制
标志位简单直接,需手动控制状态重置简单的防重复提交
禁用按钮用户体验好,直观显示状态表单提交、异步请求场景

安全与性能优化

4. 前端常见的攻击方式有哪些?

(1)XSS(跨站脚本攻击)

原理: 注入恶意脚本代码到网页中执行

防御措施:

  • 对用户输入进行 HTML 实体编码
  • 使用 CSP(内容安全策略)
  • 设置 HttpOnly Cookie
  • 使用现代框架的自动转义功能
// XSS 攻击示例
// 用户输入:<script>alert('xss')</script>
// 应该转义为:&lt;script&gt;alert('xss')&lt;/script&gt;

function escapeHtml(str) {
const map = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#039;'
};
return str.replace(/[&<>"']/g, m => map[m]);
}

(2)CSRF(跨站请求伪造)

原理: 诱导用户在已登录状态下访问恶意网站,执行非预期操作

防御措施:

  • 使用 CSRF Token
  • 验证 Referer/Origin 头
  • 使用 SameSite Cookie 属性
  • 关键操作要求二次验证

(3)点击劫持(Clickjacking)

原理: 使用透明 iframe 覆盖在正常页面上,诱导用户点击

防御措施:

  • 设置 X-Frame-Options 响应头
  • 使用 CSP 的 frame-ancestors 指令
  • JavaScript 检测页面是否被嵌入

(4)SQL 注入(通过前端接口)

原理: 通过构造特殊输入参数,攻击后端数据库

防御措施:

  • 前端验证输入格式
  • 后端使用参数化查询
  • 最小权限原则

(5)文件上传漏洞

原理: 上传恶意文件(木马、病毒等)

防御措施:

  • 限制文件类型和大小
  • 文件重命名
  • 存储到非 Web 目录
  • 扫描文件内容

5. 前端网站常规优化方案有哪些?

(1)网络层面优化

  • 减少 HTTP 请求数:合并 CSS/JS 文件、使用雪碧图
  • 使用 CDN 加速:静态资源分发到就近节点
  • 开启 Gzip/Brotli 压缩:减少传输体积
  • HTTP/2:多路复用,提升并发性能
  • 预加载/预获取
    <link rel="preload" href="style.css" as="style">
    <link rel="prefetch" href="next-page.js">

(2)资源优化

  • 图片优化

    • 使用 WebP 格式
    • 懒加载(Lazy Load)
    • 响应式图片(srcset)
    • 适当压缩
  • 代码分割

    // React 路由懒加载
    const HomePage = lazy(() => import('./HomePage'));

    // Vue 路由懒加载
    const routes = [
    { path: '/home', component: () => import('@/views/Home.vue') }
    ];
  • Tree Shaking:移除未使用的代码

(3)渲染优化

  • 减少重排重绘
    • 避免频繁操作 DOM
    • 批量修改样式(使用 className)
    • 使用 transform 替代 top/left
  • 虚拟列表:长列表只渲染可视区域
  • 防抖节流:高频事件优化
  • requestAnimationFrame:替代 setTimeout 做动画

(4)缓存优化

  • 浏览器缓存
    • 强缓存:Cache-Control, Expires
    • 协商缓存:ETag, Last-Modified
  • 本地存储
    • localStorage/sessionStorage
    • IndexedDB(大数据量)
  • Service Worker:离线缓存

(5)构建优化

// webpack 配置示例
module.exports = {
// 生产环境压缩
optimization: {
minimize: true,
splitChunks: {
chunks: 'all',
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors'
}
}
}
},
// 移除 console.log
terserOptions: {
compress: {
drop_console: true
}
}
};

(6)性能监控

  • Performance API
    performance.getEntriesByType('navigation')[0];
  • Lighthouse:自动化性能审计
  • Web Vitals:监控核心性能指标(FCP、LCP、FID、CLS)

(7)用户体验优化

  • 骨架屏:加载占位
  • 渐进式加载:优先加载核心内容
  • 错误边界处理:友好的错误提示
  • PWA:离线可用、可安装