阿里达摩院训练题1

  |  

前言

有大佬在达摩院的微信交流群里出了一些题,做了一下还是很有收获的


60



单选题:

题目描述: 对于解构一下说法错误的是:

答案:d

题目解析:

a.不完全解构,也会成功,不会报错

正确:不完全解构,等号左边的模式值匹配等号右边数组的一部分

1
2
3
4
let [a, [b], d] = [1,[2,3],4]
console.log(a); //1
console.log(b); //2
console.log(d); //4

b.只要支持Iterator接口,都可以被结构赋值

正确:只要某种数据结构具有Iterator接口,都可以采用数组的形式解构赋值

c.null可以代替默认值,而成功的解构赋值

正确:

1
2
3
let [x, y = null] = ['a'];
console.log(x); // a
console.log(y); // null

d.解构中不定参数可以出现在除第一个以外的其它位置

错误:不定参数只能出现在最后一个位置

1

2

e.解构是先找到同名属性,然后再赋给对应的变量

正确:对象的解构赋值的内部机制,是先找到同名属性,然后在赋给对应的变量。真正被赋值的是后者,而不是前者

f.默认值可以引用解构赋值的其它变量,但该变量必须已经声明

正确:

3

多选题

题目描述:以下关于异步的说法正确的是:

答案:c、d、e

题目解析:

a.在JavaScript中,任务被分为两种,一种宏任务(MacroTask),一种微任务(MicroTask),setTimeout属于微任务

错误:任务的分类是正确的,但是setTimeout属于宏任务

宏任务包括:

  • 整体代码script
  • setTimeout
  • setIntervcal

微任务包括:

  • Promise
  • process.nextTick

b.setTimeout(func, 500)会精确的在500ms后执行func

错误:会在500ms后将func加入宏任务队列,具体在什么时候执行,要考虑在宏任务队列中是否已经存在任务,这也是用setTimeout来做计时器存在误差的原因。

JS的事件循环机制是先执行宏任务队列中的一个宏任务,这期间产生的宏任务会进入宏任务队列,微任务进入微任务队列。执行完一个宏任务后,会执行整个微任务中的所有任务,这期间产生的宏任务进入宏任务队列,微任务进入微任务队列后会得到执行。清空微任务队列后,再执行宏任务队列中的下一个任务。如此循环。

c.Promise、generator、async/await都是异步解决方案

正确:初次之前外还有callback

d.process.nextTick、Promise都属于node中的微队列

正确:具体看a选项

e.浏览器中的Event Loop和node的Event Loop是不同的,实现机制也不一样

正确:

Node.js的event是基于libuv的,并且已经做出了实现

而浏览器的event loop则在HTML5中做出了规定,具体实现留给了浏览器厂商。

再具体的我就不知道了

f.在node中setTimeout和setImmediate执行阶段是一致的

错误:这应该是整个多选题里最有难度的一个选项了

要理解这道题,首先需要了解setImmediate这个函数,它的作用是在下一个队列的首位执行回调函数。在来看一个例子

1
2
3
4
5
6
setTimeout(() => {
console.log('setTimeout');
}, 0);
setImmediate(() => {
console.log('setImmediate');
})

这个例子的输出结果其实挺随缘的,可能也是setTimeout先,也可能是setImmediate先。这个跟Node.js的事件循环机制有关

4

虽然我们setTimeout的设置的时间是0,但是还是会存在短暂的延迟,如果我们执行这个js文件稍微有点慢,那么在进入事件循环的timers阶段时,setTimeout的延迟已经过去了,那么setTimeout的回调会首先执行。但是如果这个延迟没有过去,那么在timers不存在任何的任务,那么在稍后进入poll阶段时,setImmediate()会的回调会执行。然后在下一轮的事件循环中,setTimeout的回调才会得到执行。但是不管是不是在同一轮中,两者都不是在同一阶段的到执行的,setTimeout在timers,setImmediate在poll

编程题

题目描述:

1
2
3
4
5
6
7
8
9
10
11
12
Markdown 是非常受技术人员喜欢的一种文本格式,请使用 JavaScript 来实现 marked 方法来进行 markdown 文本的 HTML 渲染,可以满足以下需求:

function marked(str) {
// your code here
}

marked('@@whatever@@').trim()
// <p><blink>whatever</blink></p >
marked('*abc* @@def@@ __ghi__').trim()
// <p><em>abc</em> <blink>def</blink> <strong>ghi</strong></p >
marked('@@**cool**@@').trim()
// <p><blink><strong>cool</strong></blink></p >

题目答案:

究极无敌笨方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
function marked(str) {
function changeStr(str, before, after, changeStr) {
return str.substring(0, before) + changeStr + str.substring(after+1, str.length);
}
let atSign = 0,
starSign = 0,
doubleStarSign = 0,
underlineSign = 0;
for(let i = 0; i < str.length; i++) {
if(str[i] == str[i+1] && str[i] == '@' ) {
if(!atSign) {
str = changeStr(str, i, i+1, '<blink>');
atSign = 1;
} else {
str = changeStr(str, i, i+1, '</blink>')
atSign = 0;
}
}
if(str[i] != str[i+1] && str[i] == '*') {
if(!starSign) {
str = changeStr(str, i, i, '<em>');
starSign = 1;
} else {
str = changeStr(str, i, i, '</em>');
starSign = 0;
}
}
if(str[i] == str[i+1] && str[i] == '*') {
if(!doubleStarSign) {
str = changeStr(str, i, i+1, '<strong>');
doubleStarSign = 1;
} else {
str = changeStr(str, i, i+1, '</strong>');
doubleStarSign = 0;
}
}
if(str[i] == str[i+1] && str[i] == '_') {
if(!underlineSign) {
str = changeStr(str, i, i+1, '<strong>');
underlineSign = 1;
} else {
str = changeStr(str, i, i+1, '</strong>');
underlineSign = 0;
}
}
}
return "<p>" + str + "</p>"
}
marked('*abc* @@def@@ __ghi__@@**cool**@@').trim()
文章目录
  1. 1. 单选题:
  2. 2. 多选题
  3. 3. 编程题