看到一篇文章,5年前端面经,里面有两道钉钉的笔试题,所以来做一遍。
笔试题 1:失败重试机制
需求:实现一个函数,对某个异步操作进行重试。首次失败后等待 200ms 重试,若再次失败则等待 500ms 重试,若仍失败则返回最终失败。
分析下解决的步骤:
-
尝试执行任务,如果成功则返回结果。
-
如果失败,等待200ms后再次尝试。
-
如果再次失败,等待500ms后第三次尝试。
-
如果第三次失败,抛出错误或返回失败。
ok, 有了步骤实现起来就很方便了。
实现代码
/**
* 带延迟的重试机制
* @param {Function} task - 需要重试的异步任务(返回 Promise)
* @returns {Promise} - 最终结果或失败
*/
async function withRetry(task) {
const delays = [200, 500]; // 重试延迟时间(单位:毫秒)
let attempt = 0; // 当前重试次数
while (true) {
try {
return await task(); // 执行任务,成功则直接返回,这里必须使用await,因为 trycatch 不能捕获异步。
} catch (error) {
// 判断是否重试次数用尽,如果用尽抛出错误
if (attempt >= delays.length) {
throw new Error('重试结束了');
}
// 获取当前重试的延迟时间
const delay = delays[attempt];
console.log(`第 ${attempt + 1} 次重试,等待 ${delay}ms`);
// 等延迟时间结束之后,进行下一次循环,(sleep函数)
await new Promise(resolve => setTimeout(resolve, delay)); // 等待延迟
attempt++;
}
}
}
// 模拟一个可能失败,可能成功的操作
const mockTask = () => {
return new Promise((resolve, reject) => {
const isSuccess = Math.random() < 0.2; // 20% 成功率
isSuccess ? resolve("成功!") : reject("失败!");
});
};
withRetry(mockTask)
.then(res => console.log("结果:", res))
.catch(err => console.error("最终失败:", err));
笔试题 2:查找连续重复字符
需求:找出字符串中连续重复次数最多的字符,并返回该字符、起始位置和结束位置。
分析:
- 首先初始化变量,记录最多重复的字符,最多重复的字符的次数,最多重复字符的起点位置和终点位置,当前遍历的字符,当前遍历的起始位置,当前遍历字符的次数。一共七个变量。
- 遍历字符串,判断当前遍历的字符和最多重复的字符是否一致,
-
如果相同,当前重复的字符的次数+1;
-
如果不同:
- 检查当前字符的连续次数是否超过了
maxCount,如果超过,就更新maxChar、maxCount、startIdx和endIdx。 - 更新
currentChar为当前字符,currentCount重置为 1,currentStartIdx更新为当前位置。
- 检查当前字符的连续次数是否超过了
-
实现代码
function findMaxRepeatedCharacter(str) {
// 初始化变量
let maxChar = '';
let maxCount = 0;
let startIdx = -1;
let endIdx = -1;
let currentChar = '';
let currentCount = 0;
let currentStartIdx = 0;
// 遍历字符串
for (let i = 0; i < str.length; i++) {
// 检查当前字符是否与前一个字符相同
if (str[i] === currentChar) {
currentCount++; // 如果相同,计数器加一
} else {
// 如果遇到不同的字符,检查之前的连续字符是否是最大的
if (currentCount > maxCount) {
maxChar = currentChar;
maxCount = currentCount;
startIdx = currentStartIdx;
endIdx = i - 1;
}
// 更新当前字符
currentChar = str[i];
currentCount = 1;
currentStartIdx = i;
}
}
// 最后检查一次循环结束后的字符(防止字符串以相同字符结尾),
// 比如‘aaabbbbb’字符串,最后一次遍历没有走else,max未被重新赋值。
if (currentCount > maxCount) {
maxChar = currentChar;
maxCount = currentCount;
startIdx = currentStartIdx;
endIdx = str.length - 1;
}
return { char: maxChar, start: startIdx, end: endIdx };
}
// 测试
const result = findMaxRepeatedCharacter("aaabbccccddeeee");
console.log(result); // { char: 'e', start: 12, end: 15 }