前言:最近常在一些论坛看到大家在批判面试中的算法题,认为AI时代已经来临,啥算法AI不会呢?但现实是什么呢?大厂还在坚持考算法,有些面试官认为这可以看出来求职者的代码风格和习惯,你觉得有道理吗?
最近我也在准备面试,也在一些大厂的面试中遇到了一些手撕题,正好分享给大家。
题一:用class实现一个LazyMan。
直接看代码
class LazyMan {
// 构造函数:接收名字,初始化任务队列
constructor(name) {
this.name = name;
this.taskQueue = []; // 核心:任务队列,存储待执行的函数
// 关键:用微任务(Promise)延迟执行,保证先初始化队列再执行任务
Promise.resolve().then(() => this.runTask());
// 初始化任务:打招呼
this.taskQueue.push(() => {
console.log(`Hi! This is ${this.name}!`);
this.next(); // 执行完当前任务,触发下一个
});
}
// 执行任务队列(核心方法)
runTask() {
if (this.taskQueue.length > 0) {
const firstTask = this.taskQueue.shift(); // 取出第一个任务执行
firstTask();
}
}
// 执行下一个任务(任务衔接)
next() {
this.runTask();
}
// 1. eat方法:添加普通任务到队列尾部
eat(food) {
this.taskQueue.push(() => {
console.log(`Eat ${food}~`);
this.next();
});
return this; // 链式调用关键:返回实例
}
// 2. sleep方法:添加延迟任务到队列尾部
sleep(seconds) {
this.taskQueue.push(() => {
setTimeout(() => {
console.log(`Wake up after ${seconds} second${seconds > 1 ? 's' : ''}!`);
this.next(); // 延迟结束后执行下一个任务
}, seconds * 1000);
});
return this;
}
// 3. sleepFirst方法:添加延迟任务到队列头部(优先执行)
sleepFirst(seconds) {
this.taskQueue.unshift(() => {
setTimeout(() => {
console.log(`Wake up after ${seconds} second${seconds > 1 ? 's' : ''}!`);
this.next();
}, seconds * 1000);
});
return this;
}
}
// 测试用例
// 测试1:基础链式调用
new LazyMan('Tom').eat('apple').sleep(1).eat('banana');
// 输出顺序:
// Hi! This is Tom!
// Eat apple~
// (延迟1秒)Wake up after 1 second!
// Eat banana~
// 测试2:sleepFirst(优先延迟)
new LazyMan('Jerry').sleepFirst(2).eat('fish').sleep(1);
// 输出顺序:
// (延迟2秒)Wake up after 2 seconds!
// Hi! This is Jerry!
// Eat fish~
// (延迟1秒)Wake up after 1 second!
这题你会做吗?你觉得算是能在工作中用到的场景题吗?
再看一题
题二:实现一个深度相等判断函数 deepEqual,不用考虑循环引用。
这个在一些工具函数中也很常见,贴上代码
/**
* 深度相等判断
* @param {any} a 待比较的第一个值
* @param {any} b 待比较的第二个值
* @returns {boolean} 是否深度相等
*/
function deepEqual(a, b) {
// 1. 优先处理 NaN 特殊情况
if (Number.isNaN(a) && Number.isNaN(b)) {
return true;
}
// 2. 基础类型严格相等判断(null/undefined/数字/字符串/布尔)
// 注意:null === undefined 为 false,符合预期;引用类型此处会返回 false
if (a === b) {
return true;
}
// 3. 处理函数类型(引用相等/函数体相等,按需选择)
if (typeof a === 'function' && typeof b === 'function') {
return a.toString() === b.toString();
}
// 4. 过滤非对象类型(基础类型已判断过,此处不相等则直接返回false)
// 补充:typeof null === 'object',需单独排除
if (
a === null ||
b === null ||
typeof a !== 'object' ||
typeof b !== 'object'
) {
return false;
}
// 5. 处理 Date 特殊对象:时间戳相等则相等
if (a instanceof Date && b instanceof Date) {
return a.getTime() === b.getTime();
}
// 6. 处理 RegExp 特殊对象:源和标志都相等则相等
if (a instanceof RegExp && b instanceof RegExp) {
return a.source === b.source && a.flags === b.flags;
}
// 7. 处理数组:长度相同 + 每一项深度相等
if (Array.isArray(a) && Array.isArray(b)) {
if (a.length !== b.length) return false;
for (let i = 0; i < a.length; i++) {
if (!deepEqual(a[i], b[i])) {
return false;
}
}
return true;
}
// 8. 处理普通对象(排除数组/Date/RegExp/函数后的对象)
//构造函数不一致 → 不相等(比如 Object 和自定义类实例)
if (a.constructor !== b.constructor) return false;
const keysA = Object.keys(a);
const keysB = Object.keys(b);
if (keysA.length !== keysB.length) return false;
for (const key of keysA) {
if (!keysB.includes(key) || !deepEqual(a[key], b[key])) {
return false;
}
}
// 所有判断通过 → 深度相等
return true;
}
// 测试用例
// 1. NaN 判断
console.log(deepEqual(NaN, NaN)); // true(原代码返回 false,现在修复)
// 2. 函数判断
const fn1 = () => 1;
const fn2 = () => 1;
const fn3 = fn1;
console.log(deepEqual(fn1, fn3)); // true(引用相等)
console.log(deepEqual(fn1, fn2)); // true(函数体相等,若选方案2)
// 3. 基础类型
console.log(deepEqual(123, 123)); // true
console.log(deepEqual(123, '123')); // false
// 4. 数组
console.log(deepEqual([1, [2, 3]], [1, [2, 3]])); // true
console.log(deepEqual([1, 2], [1, 2, 3])); // false
// 5. 特殊对象
console.log(deepEqual(new Date('2026-03-11'), new Date('2026-03-11'))); // true
console.log(deepEqual(/abc/g, /abc/g)); // true
console.log(deepEqual(/abc/g, /abc/i)); // false
// 6. 普通对象
const obj1 = { a: 1, b: { c: NaN } };
const obj2 = { a: 1, b: { c: NaN } };
console.log(deepEqual(obj1, obj2)); // true(嵌套 NaN 也能判断)
这题呢?所有场景都能考虑的到吗?如果在视频面试中你写的来吗?
其实每家公司面试考的算法题形式不同,有的像上面两题,偏向应用或工具函数,有的则是力扣上的题,大家更喜欢哪种?应该是都不喜欢吧,哈哈哈哈。
结尾:
那言归正传,AI时代下面试到底还有没有必要考算法呢?欢迎大家评论区讨论。
ps:如果后续面试中遇到算法题,我也会继续更新,欢迎大家关注哦。