拼多多秋招笔试
确定输出
🔍 展开代码
html<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="parent"> <button id="child">点击我</button> </div> <script> const parent = document.getElementById('parent'); const child = document.getElementById('child'); parent.addEventListener('click', (e) => { console.log('parent click', e.target, e.currentTarget); }, true) child.addEventListener('click', (e) => { console.log('child click', e.target, e.currentTarget); }, false) </script> </body> </html>给定依赖树,输出最后的执行结果。
🔍 展开代码
js/** * 按依赖顺序执行任务树 * @param {Object} tree - 任务依赖关系树 * tree 的结构示例: * { * taskA: { task: async () => { ... }, dependencies: [] }, * taskB: { task: async () => { ... }, dependencies: ['taskA'] }, * taskC: { task: async () => { ... }, dependencies: ['taskA', 'taskB'] } * } */ async function executeDependencyTree(tree) { const executedTask = new Set(); // 已经确定顺序的任务名称集合 const queue = []; // 按依赖顺序排好的任务队列(数组) // 1. 初始化任务队列 —— 找到没有依赖的任务(即可以直接执行的) for (const taskName in tree) { if ( !tree[taskName].dependencies || tree[taskName].dependencies.length === 0 ) { queue.push({ taskName, task: tree[taskName].task }); executedTask.add(taskName); } } // 2. 循环查找剩下的任务 // 条件:所有依赖任务都已经在 executedTask 里,才可以加入队列 while (queue.length < Object.keys(tree).length) { for (const taskName in tree) { if ( !executedTask.has(taskName) && // 没被处理过 tree[taskName]?.dependencies.every((dep) => executedTask.has(dep)) // 依赖都已完成 ) { queue.push({ taskName, task: tree[taskName].task }); executedTask.add(taskName); } } } // 3. 按顺序执行队列里的任务 const settledResults = await Promise.allSettled( queue.map((info) => info.task()), ); // 4. 把执行结果整理成 { taskName: result } 的形式 const result = {}; queue.forEach((info, index) => { result[info.taskName] = settledResults[index]; }); return result; } // ============================ // 👇 定义任务树 // A -> B -> C 的依赖链 // 其中 B 依赖 A,C 依赖 B // ============================ const tree = { taskA: { task: async () => { console.log("执行 A"); return "结果 A"; }, dependencies: [], }, taskB: { task: async () => { console.log("执行 B"); return "结果 B"; }, dependencies: ["taskA"], }, taskC: { task: async () => { console.log("执行 C"); return "结果 C"; }, dependencies: ["taskB"], }, }; // ============================ // 👇 运行 // ============================ executeDependencyTree(tree).then((result) => { console.log("最终结果:", result); }); // ============================ // 👇 定义任务树(含失败任务) // A 正常执行 // B 执行失败 // C 依赖 B // ============================ const _tree = { taskA: { task: async () => { console.log("执行 A"); return "结果 A"; }, dependencies: [], }, taskB: { task: async () => { console.log("执行 B"); throw new Error("B 出错了!"); }, dependencies: ["taskA"], }, taskC: { task: async () => { console.log("执行 C"); return "结果 C"; }, dependencies: ["taskB"], }, }; // ============================ // 👇 运行 // ============================ executeDependencyTree(_tree).then((result) => { console.log("最终结果:", result); });区间合并
🔍 展开代码
jsfunction mergeIntervals(intervals) { if (intervals.length === 0) return []; // 1. 先按区间起点排序 intervals.sort((a, b) => a[0] - b[0]); const result = [intervals[0]]; // 放入第一个区间 for (let i = 1; i < intervals.length; i++) { let [left, right] = intervals[i]; let last = result[result.length - 1]; if (left <= last[1]) { // 有重叠,合并区间 last[1] = Math.max(last[1], right); } else { // 没重叠,直接放进结果 result.push([left, right]); } } return result; } const intervals = [ [1, 3], [2, 6], [8, 10], [15, 18], ]; const result = mergeIntervals(intervals); console.log(result);手写路由匹配
🔍 展开代码
jsfunction createRouter() { const routesInfos = new Map(); const addRoute = (path, view) => { routesInfos.set(path, view); }; const match = (currentPath) => { // 先尝试完全匹配 if (routesInfos.has(currentPath)) { const name = routesInfos.get(currentPath); return { name, params: null }; } // 动态参数匹配 for (const [path, view] of routesInfos.entries()) { const currentPathArr = currentPath .split("/") .filter((item) => item !== ""); const pathArr = path.split("/").filter((item) => item !== ""); if (currentPathArr.length !== pathArr.length) continue; const params = {}; let matched = true; for (let i = 0; i < pathArr.length; i++) { const actual = currentPathArr[i]; const expected = pathArr[i]; if (expected.startsWith(":")) { params[expected.slice(1)] = actual; } else if (actual !== expected) { matched = false; break; } } if (matched) return { name: view, params }; } // 没有匹配 return null; }; return { routesInfos, addRoute, match }; } const router = createRouter(); router.addRoute("/home", "HomePage"); router.addRoute("/user/:id", "UserPage"); console.log(router.match("/home")); console.log(router.match("/user/123")); console.log(router.match("/user/new/form"));
