Notes
既然刚刚在 Notes 里写了个面试题,忍不住怀念一下自己的第一次面试(which 挂了)。
当时没写出来(确实菜),虽然场下不紧张了马上就写出来了。
题目: 实现一个 LazyMan
-
LazyMan('Hank')
输出:Hi! This is Hank!
-
LazyMan('Hank').sleep(10).eat('dinner')
输出Hi! This is Hank! // 等待 10 秒.. Wake up after 10 Eat dinner~
-
LazyMan('Hank').eat('dinner').eat('supper')
输出Hi This is Hank! Eat dinner~ Eat supper~
-
LazyMan('Hank').sleepFirst(5).eat('supper')
输出// 等待 5 秒 Wake up after 5 Hi This is Hank! Eat supper~
题解
现在无比丝滑的就做出来了,反而很难想象当时为什么没写出来。
function LazyMan(name: string) {
const jobs: (
| { type: "sleep"; time: number }
| { type: "eat"; what: string }
| { type: "say"; what: string }
)[] = [
{
type: "say",
what: `Hi! This is ${name}!`,
},
];
function sleepFirst(this: ReturnType<typeof LazyMan>, time: number) {
jobs.unshift({
type: "sleep",
time,
});
return this;
}
function eat(this: ReturnType<typeof LazyMan>, what: string) {
jobs.push({
type: "eat",
what,
});
return this;
}
function sleep(this: ReturnType<typeof LazyMan>, time: number) {
jobs.push({
type: "sleep",
time,
});
return this;
}
setTimeout(async () => {
for (const job of jobs) {
switch (job.type) {
case "say":
console.log(job.what);
break;
case "sleep":
await new Promise((r) => setTimeout(r, job.time * 1000));
console.log(`Wake up after ${job.time}`);
break;
case "eat":
console.log(`Eat ${job.what}~`);
break;
}
}
}, 0);
return {
sleep,
sleepFirst,
eat,
};
}
// LazyMan('Hank');
// LazyMan('Hank').sleep(10).eat('dinner');
// LazyMan('Hank').eat('dinner').eat('supper');
// LazyMan("Hank").sleepFirst(5).eat("supper");
偶然在小红书上刷到一个前端面试题,顺手做了一下。
要求:实现一个带并发限制的异步调度器 Scheduler
,保证同时运行的异步任务最多 MAX_LENGTH
个,使得以下程序能正确输出
const timeout = (time) =>
new Promise((resolve) => {
setTimeout(resolve, time);
});
const MAX_LENGTH = 2;
const scheduler = new Scheduler(MAX_LENGTH);
const addTask = (time, order) => {
scheduler
.add(() => {
return timeout(time);
})
.then(() => console.log(order));
};
addTask(1000, "1");
addTask(500, "2");
addTask(300, "3");
addTask(400, "4");
// output: 2 3 1 4
// 一开始,1、2两个任务进入队列
// 500ms时,2完成,输出2,任务3进队
// 800ms时,3完成,输出3,任务4进队
// 1000ms时,1完成,输出1
// 1200ms时,4完成,输出4
感觉还是有点简单,五分钟内肯定是能做出来了。
题解
一开始漏了异常处理的情况,让 gpt 看了眼指了出来
class Scheduler {
running = 0;
pending_tasks: (() => void)[] = [];
queue_len: number;
constructor(queue_len: number) {
this.queue_len = queue_len;
}
async add<T>(promiseCb: () => Promise<T>): Promise<T> {
if (this.running >= this.queue_len) {
await new Promise<void>((resolve) => {
this.pending_tasks.push(resolve);
});
}
this.running++;
try {
return await promiseCb();
} catch (err) {
throw err;
} finally {
const resolve = this.pending_tasks.shift();
if (resolve) {
resolve();
}
this.running--;
}
}
}
const scheduler = new Scheduler(2);
const sleepAndLog = (time: number, ...txt: unknown[]) =>
new Promise((r) => setTimeout(r, time)).then(() => console.log(...txt));
const sleepAndRaiseLog = (time: number, ...txt: unknown[]) =>
new Promise((r) => setTimeout(r, time)).then(() => Promise.reject(...txt));
scheduler.add(() => sleepAndLog(10000, "1"));
scheduler.add(() => sleepAndRaiseLog(5000, "2"));
scheduler.add(() => sleepAndLog(3000, "3"));
scheduler.add(() => sleepAndLog(4000, "4"));