某手和某乎、某易,这些都是技术面走完的
leetcode 常见的题目就不列出来了,有些也记不清楚了,大概列一下
1. 求 dom 树的最大深度
2. 求和函数?
A(1)() ===1
A(2)(2)() ===4
A(1)(2)(3)() ===6
// ...
3. throttle 和 debounce
4. 10进制转2进制
5. 找出页面所有的以s
开头的元素,类似<script>、<span>
6. 实现 reduce
7. JSON.stringify 会导致什么问题, 检查循环引用
8. 给定一个只包括 ‘(‘,’)’,’{‘,’}’,’[‘,’]’ 的字符串,判断字符串是否有效。
9. 实现 Promise.allSettled/Promise.all
某一面编程就挂了的(吐了
1. 实现一个Promise.race
2. XHR 请求缓存与合并
3. 将一个 html 字符串变成树的形式
4. 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
5. 给定两个二叉树,编写一个函数来检验它们是否相同。
我的解答
注意,是我的解答,就是我当时的答案
1. 求 dom 树的最大深度
const getDepth = (node) => {
let max = 0;
void function fn(node, depth) {
const children = Arrary.from(node.children);
if (!children.length) {
max = Math.max(max, depth);
};
children.forEach(nd => {
fn(nd, ++depth);
})
}(node, 0);
return max;
}
2. 求和函数?
A(1)() ===1
A(2)(2)() ===4
A(1)(2)(3)() ===6
// ...
const A = (num1, sum = 0) => {
return function(num2) {
if (num2 !== undefined) return A(num2, sum + num1);
return sum + num1;
};
};
3. throttle 和 debounce
这个就不写了,网上一大堆
4. 10进制转2进制
const fn = (num) => {
let result = '';
void function trans(m) {
const n = m % 2;
result = n + result;
const i = Math.floor(m / 2);
if (i !== 0) trans(i);
}(num);
return result;
};
5. 找出页面所有的以s
开头的元素,类似<script>、<span>
const fn = node => {
const result = [];
void function find(n) {
const children = Array.from(n.children);
if (children.length) {
children.forEach(e => {
if (/^S/.test(e.tagName)){
result.push(e);
};
find(e);
});
}
}(node);
return result;
};
6. 实现 reduce
const reduce = (arr, cb, init) => {
let result = init;
for (let i = 0; i < arr.length; i++) {
result = cb(result, arr[i], i, arr);
}
return result;
};
7. JSON.stringify 会导致什么问题, 检查循环引用
const a = {};
const b = {};
a.a = b;
b.b = a;
const fn = obj => {
const map = new WeakMap();
const check = t => {
if (typeof t !== 'object') {
return true;
}
const keys = Object.keys(t);
for (let i = 0, l = keys.length; i < l; i++) {
const val = t[keys[i]];
if (typeof val === 'object') {
if (map.has(val)) return false;
map.set(val);
return check(val);
}
return true;
}
};
return check(obj);
};
console.log(fn(a));
8. 给定一个只包括 ‘(‘,’)’,’{‘,’}’,’[‘,’]’ 的字符串,判断字符串是否有效。
这题找不到自己写的答案了,反正就是出入栈
9. 实现 Promise.allSettled/Promise.all
大概,具体什么样看 MDN 吧。。。
const allSettled = promises => {
let result = [];
let count = 0;
return new Promise((resolve, reject) => {
promises.forEach((req, i) => {
req
.then(data => {
result[i] = { status: 'fulfilled', value: data };
})
.catch(err => {
result[i] = { status: 'rejected', err };
})
.finally(() => {
i++;
if (count === arr.length) resolve(result);
})
});.
})
};
某一面编程就挂了的,说实话我也没想到一面会挂。。。
因为一面挂了,所以写的东西大家都只当参考吧。。。
1. 实现一个Promise.race
const race = promises => {
return new Promise((resolve, reject) => {
promises.forEach(req => {
Promise.resolve(req).then(resolve).catch(reject);
});
});
};
2. XHR 请求缓存与合并
const getMemoizedUserInfo = resolver => {
const cache = new Map();
function request(...ids) {
const key = resolver ? resolver(ids) : ids[0];
if (cache.has(key)) {
return Promise.resolve(cache.get(key));
}
const getUser = (...list) => list.length > 1 ? getUserByIds(list) : getUserById(list[0]);
return new Promise((resolve, reject) => {
getUser(...ids)
.then(data => {
cache.set(key, data);
resolve(data);
}, reject);
});
}
return request;
};
3. 将一个 html 字符串变成树的形式
const htmlParser = html => {
const result = { children: [] };
const transString2array = html => {
let privateHtml = html;
let temporaryHtml = html;
const tagReg = /\<[^\<\>]*?\>/;
const sReg = /\s/g;
const arr = [];
while (privateHtml.match(tagReg)) {
privateHtml = temporaryHtml.replace(tagReg, (v, i) => {
if (i > 0) {
const value = temporaryHtml.slice(0, i);
if (value.replace(sReg, '').length > 0) {
arr.push(value);
}
}
temporaryHtml = temporaryHtml.slice(i + v.length);
arr.push(v);
return '';
});
}
return arr;
};
const tagList = transString2array(html);
const stack = [];
let tpl;
tagList.forEach(node => {
let isTextContent = true;
// startTag
if (/<[^\>\/]+\/?>/.test(node)) {
isTextContent = false;
const tag = node.replace(/<([^\s]+)[^\>\/]*\/?>/, '$1');
let attrObj = {};
const selfClose = /\/>$/.test(node);
node.replace(/<[^\s]+([^\>\/]*)>/, (_, attrStr) => {
attrStr.replace(/(\S+)=\"([^"]+)\"/g, (_, key, value) => {
attrObj = {...attrObj, [key]: value};
return '';
});
return '';
});
if (!stack.length) {
stack.push(Object.assign(result, { tag, selfClose, text: '', attributes: attrObj, children: [] }));
} else {
tpl = { tag, selfClose, text: '', attributes: attrObj, children: [] };
const footer = stack[stack.length - 1];
footer.children.push(tpl);
if (!selfClose) {
stack.push(tpl);
}
}
}
// closeTag
if (/<\/[^\>\/]+>/.test(node)) {
isTextContent = false;
stack.pop();
}
// textContent
if (isTextContent) {
const footer = stack[stack.length - 1];
footer.text += node;
}
});
return result;
};
可优化的地方非常非常多(tpl
变量意义不明,replace完全可以用match替代等,正则也乱写),还有些bug...不过这个是我当时提交的答案,一点没改。。
console.log(htmlParser(`<html>
<head class='aaa'><title>Hello</title></head>
<body>
<div id="container"><br />
<div class="header" title="aaa">header
</div>
<div class="content">content
</div>
<div class="footer">footer
</div>
</div>
<table>
<tr>
<th style="width: 10%">版本</th>
<th style="width: 15%">更新时间</th>
<th style="width: 20%">贡献者</th>
<th>编辑原因</th>
<th style="width: 10%">操作</th>
</tr>
</table>
</body>
</html>`))
4. 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。
注意你不能在买入股票前卖出股票。
本质上就是找最小的点
const getMaxDiff = (arr: number[]) => {
let buy = 0;
let sell = 0;
let min = 0;
let diff = 0;
for (let i = 0; i < arr.length; i++) {
const current = arr[i];
if (current - arr[buy] > diff) {
sell = i;
diff = current - arr[buy];
}
if (current - arr[min] > diff) {
buy = min;
sell = i;
diff = current - arr[min];
}
if (current < arr[min]) {
min = i;
}
}
// 因为是第几天,所以 +1
return [buy + 1, sell + 1, diff];
};
5. 给定两个二叉树,编写一个函数来检验它们是否相同
选择了广度优先
const treeDiff = (tree1: ITreeNode, tree2: ITreeNode) => {
const stack1 = [tree1];
const stack2 = [tree2];
let i = 0;
while (i < stack1.length || i < stack2.length) {
if (stack1[i] === null || stack2[i] === null) {
if (stack1[i] !== stack2[i]) {
return false;
}
i++;
continue;
}
if (stack1[i].value !== stack2[i].value) {
return false;
}
stack1.push(stack1[i].left || null);
stack1.push(stack1[i].right || null);
stack2.push(stack2[i].left || null);
stack2.push(stack2[i].right || null);
i++;
}
return true;
};
const tree1 = { left: { value: 3, right: { value: 3, left: { value: 2, right: { value: 12 } } } }, value: 1 };
const tree2 = { left: { value: 3, right: { value: 3, left: { value: 2, right: { value: 12 } } } }, value: 1 };
const tree3 = { left: { value: 3, right: { value: 3, left: { value: 2, right: { value: 13 } } } }, value: 1 };
console.log(treeDiff(tree1, tree2), treeDiff(tree1, tree3));
⚠️⚠️⚠️注意啊!!!我这样写,编程面是挂了的,所以只是给出我的思路,你把我这个当答案,也会挂的。。。
总结
手写题目只是考核的一方面,写好能加分,写不出来基本上离挂就不远,题目思路也没说,后面看情况补充吧,大概这样