1. 电商秒杀活动,你如何设置秒杀倒计时器?
1.1 如果使用setInterval,请说明一下setInterval和setTimeout这两个js timer worker的机制
1.2 setInterval有误差吗?误差来源于哪些影响?(event loop队列执行时的等待时间、主线程阻塞、js代码执行本身耗时、代码冻结等)。假设设置setInterval传递的回调函数是完全幂等的,如何对当前一个setInterval进行校准?(使用setTimeout模拟interval)
1.3 为什么如下代码打印出来是 2, 1?
setTimeout(() => console.log(1), 200);
setTimeout(() => console.log(2), 100);
浏览器内核对DOM事件、AJAX调用和setTimeout方法都有相应的模块来处理,webkit内核在Javasctipt执行引擎之外,有一个重要的模块是webcore模块,html的解析,css样式的计算等都由webcore实现。对于图中WebAPIs提到的三种API,webcore分别提供了DOM Binding、network、timer模块来处理底层实现,这里还是继续以setTimeout为例,看下timer模块的实现。
通过setTimeout()方法注册的延时方法,被传递给webcore组件timer模块处理。timer中关键类为TheadTimers类,其包含两个重要成员,TimerHeap任务队列和SharedTimer方法调度类。延时方法被封装为timer对象,存储在TimerHeap中。和Java.util.Timer任务队列一样,TimerHeap同样采用最小堆的数据结构,以nextFireTime作为关键字排序。SharedTimer作为TimerHeap调度类,在timer对象到达触发条件时,通过浏览器平台相关的接口,将延时方法添加到事件循环模型中提到的任务队列中。
TimerHeap采用最小堆的数据结构,预期延时时间最小的任务最先被执行,同时,预期延时时间相同的两个任务,其执行顺序是按照注册的先后顺序执行。
1.4 客户端倒计时是否一定准确?可能有哪些原因导致客户端计时误差(客户端本身时间与服务器时间不同步、第一次请求获取deadline时请求产生误差)?如何校准?如果页面进入后台进程,js代码冻结怎么处理(如移动端UIKit Webview在滚动时会锁定js)?(倒计时内每次都取一次系统时间,可以解决冻结问题)
var startTime = new Date().getTime();
var count = 0;
setInterval(function() {
var i = 0;
while (i++ < 100000000);
}, 0);
function fixed() {
count++;
var offset = new Date().getTime() - (startTime + count * 1000);
var nextTime = 1000 - offset;
if (nextTime < 0) nextTime = 0;
setTimeout(fixed, nextTime);
console.log(new Date().getTime() - (startTime + count * 1000));
}
setTimeout(fixed, 1000);
2. instanceof
2.1 instanceof 和typeof有什么区别?
typeof 对于原始类型来说,除了 null 都可以显示正确的类型
typeof 1 // 'number'
typeof '1' // 'string'
typeof undefined // 'undefined'
typeof true // 'boolean'
typeof Symbol() // 'symbol'
typeof 对于对象来说,除了函数显示 function ,其余都会显示 object,所以说 typeof 并不能准确判断变量到底是什么类型
typeof [] // 'object'
typeof {} // 'object'
typeof console.log // 'function'
2.2 为什么下面代码都是true, 实现instanceof函数
class P {}
class S extends P {}
var p1 = new P()
var s1 = new S()
// 以下分别输出什么
s1 instanceof P
s1 instanceof S
p1 instanceof P
p1 instanceof S
2.3 实现判断简单类型
class PrimitiveString {
static [Symbol.hasInstance](x) {
return typeof x === 'string'
}
}
console.log('hello' instanceof PrimitiveString)
2.4 instanceof的实现原理
function myInstanceof(left, right) {
let prototype = right.prototype
left = left.__proto__
while (true) {
if (left === null || left === undefined)
return false
if (prototype === left)
return true
left = left.__proto__
}
}
3. [] == ![]
https://juejin.im/book/5bdc715fe51d454e755f75ef/section/5bed40d951882545f73004f6
对于 == 来说,如果对比双方的类型不一样的话,就会进行类型转换
- 首先会判断两者类型是否相同。相同的话就是比大小了
- 类型不相同的话,那么就会进行类型转换
- 会先判断是否在对比 null 和 undefined,是的话就会返回 true
- 判断两者类型是否为 string 和 number,是的话就会将字符串转换为 number
- 判断其中一方是否为 boolean,是的话就会把 boolean 转为 number 再进行判断
[] == false
[] == 0
- 判断其中一方是否为 object 且另一方为 string、number 或者 symbol,是的话就会把 object 转为原始类型再进行判断
[].toString() == 0
"" == 0
Number("") == 0
0 == 0
4. 16进制转rgb
function hexToRGB(hex){
var hex = hex.replace("#","0x"),
r = hex >> 16,
g = hex >> 8 & 0xff,
b = hex & 0xff;
return "rgb("+r+","+g+","+b+")";
}
5. 实现一个小型打包编译器
https://juejin.im/book/5bdc715fe51d454e755f75ef/section/5c10c75af265da6135726f6c
6. 如何做监控?异常监控如何设计
https://juejin.im/book/5bdc715fe51d454e755f75ef/section/5be91751e51d450ee5063ef5