2021腾讯初面总结

2021腾讯初面总结

数组扁平化以及DateAPI的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
有如下数组:
arr = [
['2020-09-12'],
['feed2020-09-11cn',
['uin2020-9-14:us']
],
['feed2020-09-10-uk'],
['list2011-09-13jp'],
['fs0-09-13']
]
请编写函数将其抹平为一位数组,并提取其中的日期输出为时间戳格式

输出:
[1599868800000,1599782400000,1600012800000,1599696000000,1315872000000]

emmm,这题上来我就不会了,原因是我不知道怎么处理V8的输入嵌套数组…

不过后面也没想输入的事情了,就直接开始写函数,不过也没写出来,哭了😭

后面回宿舍想了想,查了查日期的API,写了个

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const toString = Object.prototype.toString;

const dateReg = /([0-9]{4})-(0[1-9]|1[0-2]|[1-9])-(0[1-9]|[1-2][0-9]|3[0-1]|[1-9])/g

function fn(arr) {
const result = [];
for (let i = 0; i < arr.length; i++) {
if (toString.call(arr[i]) === '[object Array]') {
// 使用递归来抹平数组
result.push(...fn(arr[i]));
} else {
// 获得整个匹配结果数组
const matchArr = arr[i].match(dateReg);
if (matchArr) {
// 拿第一个切割
const d = matchArr[0].split('-');
// 使用Date.UTC这个API来获取返回1970-1-1 00:00:00 UTC到指定的日期之间的毫秒数。
result.push(Date.UTC(+d[0], (+d[1]) - 1, +d[2]));
}
}
}
return result;
}

但是里面有一个输出有问题,很奇怪,其他的输出都没有什么问题。

输入的样例里面有一个'uin2020-9-14:us'

如果返回的是基于UTC(格林威治标准时间)来计算时间戳的话,返回应该是1600041600000

挺奇怪的…

可能他在第五层,我连第一层都达不到😂。

现在想起来我为啥要处理输入啊,应该就是写个函数就行了啊,真是傻逼😂。

柯里化加法和乘法

1
2
3
4
5
问题:设计实现多次调用的加法与乘法函数,参数不定,调用次数不定。

调用例子:
console.log(curryAdd(1)(2)(3)(4)(5)); // 15
console.log(curryMul(2,3)(4)(5)); // 120

我当时是这样写的,写完还没写乘法的时候面试官就直接说谈谈了…

1
2
3
4
5
6
7
8
9
function curryAdd (...args) {
return function (...rest) {
if(rest.length === 0) {
return args.reduce((pre, cur) => pre + cur, 0);
} else {
return curryAdd(...args, ...rest);
}
}
}

写的时候其实很在意下面这两种形式,面完之后感觉可以重写toString来实现

1
2
console.log(curryAdd(1)(2)(3)(4)(5));     // 15
console.log(curryAdd(1)(2)(3)(4)(5)()); // 15

可以把柯里化和原函数分隔开

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function add (...args) {
return args.reduce((pre, cur) => pre + cur, 0);
}

function curry (fn) {
const args = [];
let _fn;
_fn = function (...rest) {
args.push(...rest);
return _fn;
}
// 如果valueOf返回的是基本类型,就输出valueOf()
// 如果toString返回基本类型,就输出toString()
// 上面两种都不是,直接报错
_fn.toString = _fn.valueOf = function () {
return fn(...args);
}
return _fn;
}

const curryAdd = curry(add);
const result = curryAdd(1)(2,3,4)(5);
console.log(result);
console.log(result + 1);

虽然result前面有个f的标志,但不影响使用。

node下也完全没问题。

缺点就是每一次都要通过curry(add)来返回一个函数,这样才会产生新参数数组的闭包。

才不会被之前的累计影响。

9.16号晚上。

突发奇想,又想到了另一个版本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function add(...args) {
return args.reduce((pre, cur) => pre + cur, 0);
}

function curry(fn) {
return function _curry(...args) {
function _(...rest) {
return _curry(...args, ...rest);
}

_.valueOf = function () {
return fn(...args);
}
return _;
}
}

这个版本就没有参数闭包变量的问题了

所以每次调用都是一个新的curry化链条

而且支持分解操作,很牛逼好吧(开心😀)

测试下

1
2
3
const curryAdd = curry(add);
console.log(+curryAdd(1, 5)(2));
console.log(+curryAdd(1, 5)(2));

完美好吧~

实现乘法也就是换个参数而已的事情了。

1
2
3
4
5
function mul(...args){
return args.reduce((pre, val) => pre * val, 1);
}

const curryMul = curry(mul); // 把乘法柯里化

测试下: