# 一面(电话面)

# 什么是事件委托

DOM 事件 (opens new window)

# 了解 Promise 吗

手写 promise (opens new window)

# window 的 onload事件和 domcontentloaded 谁先谁后

# 有遇到过跨域问题吗?如何解决

跨域 (opens new window)

# 二面(QQ 远程面)

# 原型链考察

有一个类如下:

function Person(name) {
  this.name = name
}

let p = new Person('Tom')
  1. p.__proto__ 是什么

    Person.prototype

  2. Person.__proto__ 是什么

    Function.prototype

# new 考察

有一个类如下:

// 类1
function Person(name) {
  this.name = name
  return name
}

// 类2
function Person(name) {
  this.name = name
  return {}
}

let person = new Person('Tom')
  1. 类1 实例化后返回的是什么

    { name: 'Tom' }

  2. 类2 实例化后返回的是什么

    {}

# typeof 和 instanceof 的区别

# 下面代码输出什么

function Person(name) {
  this.name = name
}

function Student() {
}

Student.prototype = Person.prototype
Student.prototype.constructor = Student

var s = new Student('Tom')
console.log(s instanceof Person) // true

# new 和 instanceof 源码实现

手写 new (opens new window)

手写 instanceof (opens new window)

# 下面代码输出什么

for(var i = 0; i < 10; i++) {
  setTimeout(() => {
    console.log(i)
  }, 0)
}

// 10 个 10

如果要修改成输出 0-9

// 使用 let
for(let i = 0; i < 10; i++) {
  setTimeout(() => {
    console.log(i)
  }, 0)
}

// 使用闭包
for(var i = 0; i < 10; i++) {
  (function(i) {
    setTimeout(() => {
    console.log(i)
  }, 0)
  })(i)
}

// 使用 setTimeout 的第三个参数
for (var i = 0; i < 10; i++) {
  setTimeout((i) => {
      console.log(i)
    }, 0, i)
}

# 箭头函数 this 的指向问题

沿着它的调用链往外找,第一个非箭头函数的 this

# for..in 和 for...of 的区别

# 说说 generator 的了解

# flex 布局中的 flex-grow 和 flex-shrink 属性的作用

# 说一下宏任务和微任务,并说出下面代码的运行结果

console.log('a')
setTimeout(() => {
  console.log('b')
}, 0)
console.log('c')
Promise.resolve().then(() => {
  console.log('d')
}).then(() => {
  console.log('e')
})
console.log('f')

// a -> c -> f -> d -> e -> b

# 数组扁平化处理

function flatten(list) {
  return list.reduce(function(prev, curr) {
    return prev.concat(Array.isArray(curr) ? flatten(curr) : curr)
  }, [])
}

function flatten(list) {
  while(list.some(v => Array.isArray(v))) {
    list = [].concat(...list)
  }
  return list
}

# 三面(电话远程面)

# 输入 URL 到页面加载发生了什么

浏览器输入 url 全过程 (opens new window)

# 缓存知识

浏览器缓存 (opens new window)

# 描述一下 DNS 解析过程

DNS 解析 (opens new window)

# TCP 是如何发起连接和断开连接

三次握手 四次挥手

# 你知道有什么状态码

# 有哪些手段可以优化网页响应速度

# 5点15分,时针和分针的夹角

67.5 度

# 算法

8 个外表一样的小球,其中 7 个球重量相同,1 个球为异常球,可能比较重也可能比较轻,利用天平至少需要称重多少次才能确保找出异常球,并且需要知道到底是轻了还是重了。

答案:2次

步骤:

  1. 将八个球分成 A、B、C 三组,分别 3个,3个,2个;
  2. 将 A、B 组称重,若重量相同,则异常球在 C 组;
  3. 取 C 组任意一球和 A、B 组任意一球称重,如果不一样,则当前球为异常球,且知道是重了还是轻了,反之则另一个球为异常球。

# 三面(笔试)

# 原生 js 实现

  1. 实现一个 div 滑动的动画,由快至慢(不准使用 css3)

    思路:

    1. 定时器
    2. 一个变量用来存滑动速度,并在定时器内递减
  2. 页面内有一个 input 输入框,实现数组 arr 查询命中次并要求 autocomplete 效果

# 算法

  1. 大数相加

# 四面

聊项目,笔者项目经验主要是一个基于微信环境的讲座系统(涉及功能文字、语音、图片、表情的聊天系统)

# 你在做这个系统如何确保消息实时推送

Node.js + WebSocket(socket.io)

# 消息撤回功能如何实现?

# WebSocket 有时会出现掉线,如何解决

加入心跳机制

var heartCheck = {
  timeout: 60000, // 60ms
  timeoutOjb: null,
  serverTimeoutObj: null,
  reset: function (){
    clearTimeout(this.timeoutObj)
    clearTimeout(this.serverTimeoutObj)
    this.start()
  },
  start: function (){
    var self = this
    this.timeoutObj = setTimeout(function (){
      ws.send('HeartBeat')
      self.serverTimeoutObj = setTimeout(function() {
        ws.close()
      }, self.timeout)
    }, this.timeout)
  }
}

ws.onopen = function() {
  heartCheck.start()
}

ws.onmessage = function() {
  heartCheck.reset()
}

ws.onclose = function() {
  reconnect()
}

ws.onerror = function() {
  reconnect()
}

# 了解过哪些排序算法,描述一下归并排序的实现

# 有没有了解过 react 的 diff 算法

# 讲讲前端安全问题