引言:为什么这些知识点总被拷问?
"面试造火箭,工作拧螺丝?不!这些知识点在日常业务中频繁出现,却被80%的开发者忽视细节。本文将揭秘:那些看似基础却暗藏玄机的面试考点,如何让你在技术面中脱颖而出?
一、数组操作:你以为会了,其实只懂皮毛
1.1 slice() 的「幽灵引用」陷阱
致命误区:"用 slice 截取数组就能安全操作?"
原理拆解:
const original = [{id:1}, {id:2}];
const sliced = original.slice(0,1);
sliced[0].id = 666; // 修改拷贝数组元素
console.log(original[0].id); // 666 → 原数组被污染!
避坑指南:
- ✅ 浅拷贝场景:仅需截取非引用类型数据时安全
- ❌ 深拷贝场景:嵌套对象必须用深拷贝(后文详解)
1.2 数组去重
方案对比表(性能+缺陷分析)
| 方法 | 处理NaN | 处理对象 | 时间复杂度 | 适用场景 |
|---|---|---|---|---|
| filter + indexOf | ❌ | ❌ | O(n²) | 简单数据快速去重 |
| reduce + includes | ❌ | ❌ | O(n²) | 需要链式操作时 |
| Set + 扩展运算符 | ✅ | ❌ | O(n) | 高性能去重首选 |
1. 使用 filter + indexOf
const uniqueArr = arr.filter((item, index) => arr.indexOf(item) === index);
// 兼容性好,但无法处理 NaN(indexOf 无法识别 NaN)。
2. 使用 reduce + includes
const uniqueArr = arr.reduce(
(prev, cur) => (prev.includes(cur) ? prev : [...prev, cur]),
[]
);
3. 使用 Set 数据结构
const arr = [1, 2, 2, 3, 3, 3];
const uniqueArr = [...new Set(arr)]; // [1, 2, 3]
面试精讲:为什么 Set 需要转数组?
const uniqueArr = Array.from(new Set(arr));
// Array.from() 静态方法从可迭代或类数组对象创建一个新的浅拷贝的数组实例。
关键点:
- Set 是类数组结构,但非 Array 实例
- 扩展运算符本质调用 Iterator 接口,与 Array.from 异曲同工
2. 浅拷贝和深拷贝
2.1 面试官连环问法拆解
典型问题:
- "Object.assign 是深拷贝吗?"
- "JSON.parse(JSON.stringify(obj)) 有什么缺陷?"
- "如何解决循环引用问题?"
2.1 浅拷贝
仅复制对象的第一层属性,且当属性为引用类型时,复制的是其内存地址。
1. Object.assign()
const shallowCopy = Object.assign({}, obj);
2. 展开运算符(...)
const obj = { a: 1, b: { c: 2 } };
const shallowCopy = { ...obj };
3. 数组的浅拷贝
const arr = [1, 2, [3]];
const shallowArr = arr.slice(); // 或 [...arr]
2.2 深拷贝
递归复制对象的所有层级属性,完全创建新对象,即拷贝后的对象与原对象完全独立,修改互不影响。
1. JSON.parse(JSON.stringify(obj))
const deepCopy = JSON.parse(JSON.stringify(obj));
// 缺点:无法处理 函数、undefined、Symbol、循环引用,且会丢失 Date 对象的时间信息。
2. 递归实现深拷贝
重点在于对递归思想的掌握,以及对数据类型的判断,其次是循环引用的判断。
function deepClone(source, map = new Map()) {
if (source === null || typeof source !== "object") return source;
if (map.has(source)) return map.get(source); // 解决循环引用
const target = Array.isArray(source) ? [] : {};
map.set(source, target);
for (const key in source) {
if (source.hasOwnProperty(key)) {
target[key] = deepClone(source[key], map);
}
}
return target;
}
HTTP 高频灵魂拷问:GET/POST 区别
1. 用途
- GET:用于获取数据,适合读取资源,如浏览网页、搜索查询。
- POST:用于提交数据,适合修改服务器状态的操作,如提交表单、上传文件。
提问:为什么 GET 用来获取数据,POST 用来提交数据?
安全性问题:
- GET 参数暴露在 URL 中,易被记录或窃取,不适合传输密码等敏感信息。
- POST 数据在请求体中,相对隐蔽,但若未使用 HTTPS 仍可能被截获
数据长度限制问题:
- GET 受 URL 长度限制(通常约 2048 字符),不同浏览器和服务器可能不同。
- POST 理论上无限制,但服务器可能配置最大限制(如 PHP 的 post_max_size)。
RESTful 规范问题:
- GET 对应读取操作(安全且幂等)。
- POST 对应创建资源(非幂等)。
示例场景:
- 使用 GET:搜索商品、分页加载数据、获取用户信息。
- 使用 POST:用户登录、上传头像、提交订单。
HTTP 和 HTTPS
1. 核心区别
HTTP 是明文传输协议,HTTPS 是基于 SSL/TLS 加密的安全协议,主要解决数据保密性、完整性和身份验证问题。
2. 详细对比
- 安全性:HTTP 数据明文传输,易被窃听、篡改或中间人攻击。HTTPS 通过 SSL/TLS 加密,实现加密传输、数据完整性校验(防篡改)、证书验证(防钓鱼网站)。
- 端口:HTTP 默认使用 80 端口,HTTPS 默认使用 443 端口。
- 证书与身份验证: HTTPS 必须部署 SSL 证书(由可信 CA 颁发)
补充关键知识点
- 加密机制:HTTPS 使用混合加密(非对称加密交换密钥 + 对称加密传输数据)
- SEO 影响:谷歌等搜索引擎优先收录 HTTPS 网站,HTTP 站点会被标记“不安全”,降低用户信任。
HTTP 状态码
在 HTTP 协议中,状态码由 3 位数字组成,分为 5 类,用于表示服务器对客户端请求的响应状态
- 1xx:表示信息,请求已接收,继续处理
- 2xx:表示成功,请求已成功处理
- 3xx:表示重定向,需要客户端进一步操作
- 4xx:表示客户端错误,客户端错误,请求有语法错误或无法完成
- 5xx:表示服务器错误,服务器错误
你必须知道的 10 个高频代码
| 状态码 | 含义 | 典型场景 | 排查要点 |
|---|---|---|---|
| 301 | 永久重定向 | 网站改版换域名 | 更新书签链接 |
| 304 | 缓存有效 | CDN 缓存命中 | 检查 Cache-Control 头 |
| 400 | 请求语法错误 | 参数类型错误/JSON格式错误 | 抓包验证请求体 |
| 401 | 未认证 | Token过期/未登录 | 检查 Authorization 头 |
| 403 | 权限不足 | 普通用户访问管理员接口 | 检查角色权限配置 |
| 500 | 服务器内部错误 | 接口返回报错 | 检查服务端代码异常 |
| 502 | 网关错误 | 后端服务宕机/Nginx配置错误 | 检查上游服务状态 |
你在面试中遇到过哪些刁钻问题?欢迎评论区讨论🔥