1. 电商秒杀活动,你如何设置秒杀倒计时器?

1.1 如果使用setInterval,请说明一下setInterval和setTimeout这两个js timer worker的机制

1.2 setInterval有误差吗?误差来源于哪些影响?(event loop队列执行时的等待时间、主线程阻塞、js代码执行本身耗时、代码冻结等)。假设设置setInterval传递的回调函数是完全幂等的,如何对当前一个setInterval进行校准?(使用setTimeout模拟interval)

1.3 为什么如下代码打印出来是 2, 1?

  1. setTimeout(() => console.log(1), 200);
  2. 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)?(倒计时内每次都取一次系统时间,可以解决冻结问题)

  1. var startTime = new Date().getTime();
  2. var count = 0;
  3. setInterval(function() {
  4. var i = 0;
  5. while (i++ < 100000000);
  6. }, 0);
  7. function fixed() {
  8. count++;
  9. var offset = new Date().getTime() - (startTime + count * 1000);
  10. var nextTime = 1000 - offset;
  11. if (nextTime < 0) nextTime = 0;
  12. setTimeout(fixed, nextTime);
  13. console.log(new Date().getTime() - (startTime + count * 1000));
  14. }
  15. setTimeout(fixed, 1000);

2. instanceof

2.1 instanceof 和typeof有什么区别?

typeof 对于原始类型来说,除了 null 都可以显示正确的类型

  1. typeof 1 // 'number'
  2. typeof '1' // 'string'
  3. typeof undefined // 'undefined'
  4. typeof true // 'boolean'
  5. typeof Symbol() // 'symbol'

typeof 对于对象来说,除了函数显示 function ,其余都会显示 object,所以说 typeof 并不能准确判断变量到底是什么类型

  1. typeof [] // 'object'
  2. typeof {} // 'object'
  3. typeof console.log // 'function'

2.2 为什么下面代码都是true, 实现instanceof函数

  1. class P {}
  2. class S extends P {}
  3. var p1 = new P()
  4. var s1 = new S()
  5. // 以下分别输出什么
  6. s1 instanceof P
  7. s1 instanceof S
  8. p1 instanceof P
  9. p1 instanceof S

2.3 实现判断简单类型

  1. class PrimitiveString {
  2. static [Symbol.hasInstance](x) {
  3. return typeof x === 'string'
  4. }
  5. }
  6. console.log('hello' instanceof PrimitiveString)

2.4 instanceof的实现原理

  1. function myInstanceof(left, right) {
  2. let prototype = right.prototype
  3. left = left.__proto__
  4. while (true) {
  5. if (left === null || left === undefined)
  6. return false
  7. if (prototype === left)
  8. return true
  9. left = left.__proto__
  10. }
  11. }

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

  1. function hexToRGB(hex){
  2. var hex = hex.replace("#","0x"),
  3. r = hex >> 16,
  4. g = hex >> 8 & 0xff,
  5. b = hex & 0xff;
  6. return "rgb("+r+","+g+","+b+")";
  7. }

5. 实现一个小型打包编译器

https://juejin.im/book/5bdc715fe51d454e755f75ef/section/5c10c75af265da6135726f6c

6. 如何做监控?异常监控如何设计

https://juejin.im/book/5bdc715fe51d454e755f75ef/section/5be91751e51d450ee5063ef5