阅读 9968

(近3万字,持续更新中)从面试前到终面,全面为您保驾护航

目录

面试分为面试准备、基础知识面、进阶知识面、项目经验面、hr面等几个阶段

下面就每个阶段需要准备哪些知识进行详解,希望每位同学都能拿到心仪的offer!!!

本文已收录到以下github和个人网站,欢迎follow和star

面试准备

在开始面试前,我们首先得了解应聘的岗位的要求,并做针对性的准备。

准备包括以下几个方面:

  1. 职位描述(JD)分析
  2. 了解业务/项目
  3. 简历
  4. 自我介绍

职位描述(JD)分析

招聘网站上招聘的岗位都会有个职位描述,这个职位描述往往比较精简,以至于大家经常忽略了其深层的意义

下面这篇文章是一个比较好的分析范例,希望大家多多研究

了解业务/项目

分成两步:

  1. 了解业务,比如该公司主要经营机票业务,我们是不是应该了解一下机票的一个购买流程
  2. 了解项目,我们应该去了解该公司目前的项目,是to B还是to C,是否有m站、海外站、小程序等,使用的是vue还是react

简历

一份好的简历,给我们的面试加分不少。那怎样写出一份优秀的(至少是好的)简历呢?下面这些文章也许能够帮助到您。不需要每篇都看,参考一两篇即可!

简历模板

自我介绍

面试中第一个问题就是让我们自我介绍,准备好这个问题,能让面试官对我们有一个准确的了解,同时我们也可以通过自我介绍,引导面试官问出我们比较拿手的问题。

一面

侧重考察基础知识,这部分开始我们会准备一些面试中常遇到的问题

CSS

使用css实现一个持续的动画效果

答案
animation:mymove 5s infinite;
@keyframes mymove {
from {top:0px;}
to {top:200px;}
}

复制代码

主要考察

描述
animation-name 规定需要绑定到选择器的 keyframe 名称。。
animation-duration 规定完成动画所花费的时间,以秒或毫秒计。
animation-timing-function 规定动画的速度曲线。
animation-delay 规定在动画开始之前的延迟。
animation-iteration-count 规定动画应该播放的次数。
animation-direction 规定是否应该轮流反向播放动画。

扩展:

  • 使用js实现一个持续的动画效果
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>js动画</title>
  <style>
    #app{
      position: absolute;
      width: 300px;
      height: 300px;
      background-color: #f00;
    }
    
  </style>
</head>
<body>
  <div id="app"></div>
  <script>
    const end = 300, duration = 5
    const $app = document.getElementById('app')
    let starttime
    function move() {
      let percent = (Date.now() - starttime) / 1000 % duration / duration
      $app.style.left = percent * end + 'px'
    }
    // 方法一
    // function start() {
    //   starttime = Date.now()
    //   let timer = setInterval(() => {
    //     move()
    //   }, 1000/60);
    // }
    // start()

    // 方法二
    // function start() {
    //   let timer = setTimeout(() => {
    //     move()
    //     start()
    //   }, 1000/60);
    // }
    // starttime = Date.now()
    // start()

    // 方法三
    function start() {
      requestAnimationFrame(() => {
        move()
        start()
      })
    }
    starttime = Date.now()
    start()
    
  </script>
</body>
</html>
复制代码

css3新特性

如何清除浮动

答案
  1. clear
.floatfix{
    *zoom:1;
}
.floatfix:after{
    content:"";
    display:table;
    clear:both;
}
复制代码
  1. BFC

注意事项:

  1. clear只对块级元素有效

  2. clear并不是清除了浮动效果,而是使当前元素盒子的边不能和前面的浮动元素 相邻。

扩展: 什么是BFC?BFC的好处是什么? 如何创建BFC?

css盒模型

答案

标准模型和IE模型

content padding border margin

四种定位的区别

答案
static 是默认值 不会创建BFC
relative 相对定位 相对于自身原有位置进行偏移,仍处于标准文档流中
absolute 绝对定位 相对于最近的已定位的祖先元素, 有已定位(指position不是static的元素)祖先元素, 以最近的祖先元素为参考标准。如果无已定位祖先元素, 以body元素为偏移参照基准, 完全脱离了标准文档流。
fixed 固定定位的元素会相对于视窗来定位,这意味着即便页面滚动,它还是会停留在相同的位置。一个固定定位元素不会保留它原本在页面应有的空隙。


复制代码

其他

html

http

http的特点

答案
无状态 无连接
复制代码

http报文的组成部分

答案
请求行 请求头 空行 请求体
转态行 响应头 空行 响应体
复制代码

http的方法

答案
GET POST PUT DELETE HEAD
复制代码

扩展:

  • GET和POST的区别

http的状态码

答案

能记住以下几个就行

http的持久化和管线化

了解概念即可,不必深究

www.cnblogs.com/hyzm/p/9530…

DOM事件类型

请问DOM事件级别

答案
DOM 0级: dom.onclick = function() {}
DOM 2级: document.addEventListener('click', ()=>{})
DOM 3级: document.addEventListener('keyup', ()=>{})
复制代码

DOM事件模型

答案
捕获和冒泡
复制代码

DOM事件流

答案
捕获>目标阶段>冒泡
复制代码

描述DOM事件捕获的具体流程

答案
window>document>html>body>...
复制代码

延伸:

  • 如何获取html?

    答案
    document.documentElement
    复制代码

Event对象的常见应用

答案
event.preventDefault()
event.stopPropagation()
event.stopImmediatePropagation()
event.target
event.currentTarget
复制代码

延伸:

自定义事件

可以用Event或CustomEvent

Event、CustomEvent的区别是CustomEvent可以传参

// 首先需要提前定义好事件,并且注册相关的EventListener
var myEvent = new CustomEvent('event_name', { 
    detail: { title: 'This is title!'},
});
window.addEventListener('event_name', function(event){
    console.log('得到标题为:', event.detail.title);
});
// 随后在对应的元素上触发该事件
if(window.dispatchEvent) {  
    window.dispatchEvent(myEvent);
} else {
    window.fireEvent(myEvent);
}
// 根据listener中的callback函数定义,应当会在console中输出 "得到标题为: This is title!"
复制代码

fastclick的作用是什么

答案
解决移动端点击300ms延迟
复制代码

扩展:

fastclick原理

答案
利用event.preventDefault()阻止默认行为,然后派发自定义click事件
复制代码

js

var let const的区别

let 不存在变量提升,不能重复定义,会产生块级作用域,存在暂时性死区
const 声明就得赋值,变量的值不得改动
复制代码

变量提升&作用域

获取字符串长度的方法

function codePointLength(text) {
  var result = text.match(/[\s\S]/gu);
  return result ? result.length : 0;
}

var s = '𠮷𠮷';

s.length // 4
codePointLength(s) // 2
复制代码
function length(str) {
  return [...str].length;
}

length('x\uD83D\uDE80y') // 3
复制代码

原型链

This

闭包

继承

答案
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>面向对象</title>
  </head>
  <body>
    <script type="text/javascript">
      /**
       * 类的声明
       */
      var Animal = function () {
          this.name = 'Animal';
      };

      /**
       * es6中class的声明
       */
      class Animal2 {
          constructor () {
              this.name = 'Animal2';
          }
      }

      /**
       * 实例化
       */
      console.log(new Animal(), new Animal2());

      /**
       * 借助构造函数实现继承
       */
      function Parent1 () {
          this.name = 'parent1';
      }
      Parent1.prototype.say = function () {

      };
      function Child1 () {
          Parent1.call(this);
          this.type = 'child1';
      }
      console.log(new Child1(), new Child1().say());

      /**
       * 借助原型链实现继承
       */
      function Parent2 () {
          this.name = 'parent2';
          this.play = [1, 2, 3];
      }
      function Child2 () {
          this.type = 'child2';
      }
      Child2.prototype = new Parent2();

      var s1 = new Child2();
      var s2 = new Child2();
      console.log(s1.play, s2.play);
      s1.play.push(4);

      /**
       * 组合方式
       */
      function Parent3 () {
          this.name = 'parent3';
          this.play = [1, 2, 3];
      }
      function Child3 () {
          Parent3.call(this);
          this.type = 'child3';
      }
      Child3.prototype = new Parent3();
      var s3 = new Child3();
      var s4 = new Child3();
      s3.play.push(4);
      console.log(s3.play, s4.play);

      /**
       * 组合继承的优化1
       * @type {String}
       */
      function Parent4 () {
          this.name = 'parent4';
          this.play = [1, 2, 3];
      }
      function Child4 () {
          Parent4.call(this);
          this.type = 'child4';
      }
      Child4.prototype = Parent4.prototype;
      var s5 = new Child4();
      var s6 = new Child4();
      console.log(s5, s6);

      console.log(s5 instanceof Child4, s5 instanceof Parent4);
      console.log(s5.constructor);

      /**
       * 组合继承的优化2
       */
      function Parent5 () {
          this.name = 'parent5';
          this.play = [1, 2, 3];
      }
      function Child5 () {
          Parent5.call(this);
          this.type = 'child5';
      }
      Child5.prototype = Object.create(Parent5.prototype);

    </script>
  </body>
</html>


复制代码

请问new执行的操作

1. 创建一个全新的对象。
2. 这个新对象会被执行 [[Prototype]] 连接。
3. 这个新对象会绑定到函数调用的 this。
4. 如果函数没有返回其他对象,那么 new 表达式中的函数调用会自动返回这个新对象。
复制代码

你了解Object.create吗

二面

侧重考察知识面、高阶知识、深入原理等

js

setTimeout和setInterval和requestAnimationFrame

JSON.parse(JSON.stringify())的缺点

在JSON.stringify()阶段

1.如果obj里面有时间对象,则JSON.stringify后再JSON.parse的结果,时间将只是字符串的形式,而不是对象的形式

2.如果obj里有RegExp(正则表达式的缩写)、Error对象,则序列化的结果将只得到空对象

3、如果obj里有函数,undefined,则序列化的结果会把函数或 undefined丢失

4、如果obj里有NaN、Infinity和-Infinity,则序列化的结果会变成null

5、JSON.stringify()只能序列化对象的可枚举的自有属性,例如 如果obj中的对象是有构造函数生成的, 则使用JSON.parse(JSON.stringify(obj))深拷贝后,会丢弃对象的constructor

6、如果对象中存在循环引用的情况也无法正确实现深拷贝
复制代码

对象与数组的遍历

举个栗子

var a = {a: 1}
var b= {b:2}
b.__proto__ = a
Object.defineProperty(b, 'c', {
	value: 3
})
b[Symbol()] = 4

Object.keys(b) // ["b"]  返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含Symbol属性).

for(var i in b) {
  console.log(i,":",b[i]);
} // b : 2 a : 1   循环遍历对象自身的和继承的可枚举属性(不含Symbol属性)

Object.getOwnPropertyNames(obj) // ["b", "c"] 返回一个数组,包含对象自身的所有属性(不含Symbol属性,但是包括不可枚举属性).
Reflect.ownKeys(b) // ["b", "c", Symbol()] 返回一个数组,包含对象自身的所有属性,不管属性名是Symbol或字符串,也不管是否可枚举.  

复制代码

什么是严格模式

严格模式主要有以下限制。

变量必须声明后再使用
函数的参数不能有同名属性,否则报错
不能使用with语句
不能对只读属性赋值,否则报错
不能使用前缀 0 表示八进制数,否则报错
不能删除不可删除的属性,否则报错
不能删除变量delete prop,会报错,只能删除属性delete global[prop]
eval不会在它的外层作用域引入变量
eval和arguments不能被重新赋值
arguments不会自动反映函数参数的变化
不能使用arguments.callee
不能使用arguments.caller
禁止this指向全局对象
不能使用fn.caller和fn.arguments获取函数调用的堆栈
增加了保留字(比如protected、static和interface)
复制代码

函数式编程

正则表达式

es6

什么叫暂时性死区

在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。

CommonJS 中的 require/exports 和 ES6 中的 import/export 区别?

- CommonJS 模块的重要特性是加载时执行,即脚本代码在 require 的时候,就会全部执行。一旦出现某个模块被”循环加载”,就只输出已经执行的部分,还未执行的部分不会输出。
- ES6 模块是动态引用,如果使用 import 从一个模块加载变量,那些变量不会被缓存,而是成为一个指向被加载模块的引用,需要开发者自己保证,真正取值的时候能够取到值。
- import/export 最终都是编译为 require/exports 来执行的。
- CommonJS 规范规定,每个模块内部,module 变量代表当前模块。这个变量是一个对象,它的 exports 属性(即 module.exports )是对外的接口。加载某个模块,其实是加载该模块的 module.exports 属性。
- export 命令规定的是对外的接口,必须与模块内部的变量建立一一对应关系。

复制代码

typescript

vue

vue-cli

vue响应式原理

react

小程序

taro

weex

源码

webpack

浏览器

网络请求

浏览器同源政策及跨域

五种方法

jsonp
hash
cors
websocket
postmessage
复制代码

网络安全

1. XSS(cross-site-scripting, 跨站脚本)攻击

解决方法: 字符串转义

2. 跨站请求伪造(CSRF)

解决方法: 1.明文传递cookie
         2. 请求一个随机字符串(只能用一次)
         3. 判断referer

复制代码

浏览器渲染机制

js运行机制

页面性能

进程与线程

页面渲染

缓存

垃圾回收

架构

nodejs

算法

复杂度

二叉树

手写代码

手动实现new

function New(Constructor, ...args){
    let obj = {};   // 创建一个新对象
    Object.setPrototypeOf(obj, Constructor.prototype);  // 连接新对象与函数的原型
    return Constructor.apply(obj, args) || obj;   // 执行函数,改变 this 指向新的对象
}

function Foo(a){
    this.a = a;
}

New(Foo, 1);  // Foo { a: 1 }

复制代码
function _new() {
    let target = {}; //创建的新对象
    //第一个参数是构造函数
    let [constructor, ...args] = [...arguments];
    //执行[[原型]]连接;target 是 constructor 的实例
    target.__proto__ = constructor.prototype;
    //执行构造函数,将属性或方法添加到创建的空对象上
    let result = constructor.apply(target, args);
    if (result && (typeof (result) == "object" || typeof (result) == "function")) {
        //如果构造函数执行的结构返回的是一个对象,那么返回这个对象
        return result;
    }
    //如果构造函数返回的不是一个对象,返回创建的新对象
    return target;
}

复制代码

实现深拷贝

防抖与节流

数组去重

实现一个简易版vue2

其他

代码质量

三面

侧重考察以下能力

业务能力
团队协作能力
事务推动能力
带人能力
架构能力
项目经验
复制代码

项目

面试官往往会让你说一说,都做过哪些项目,并就其中一两个深入了解。

我们需要从这些方面准备:

  1. 负责的项目做出了什么业绩
  2. 使用了什么技术方案
  3. 有什么技术难点
  4. 遇到了什么困难
  5. 收获了什么

架构与事务推动

  1. 是否自己搭建过项目?
  2. 你当时选择的技术栈是什么?
  3. 为什么这样选择?
  4. 讲讲遇到的困难
  5. 作为技术负责人你是怎么推动项目顺利进行的

带人与团队协作

  1. 是否带过人?
  2. 团队成员间怎样协作的?
  3. 是否有code review?
  4. git命令了解多少?
  5. 与后端、产品、设计、项目经理间是怎样协作的?

解决问题的能力

  1. 是否遇到过什么困难,你是怎么解决的?
  2. 你平时都是怎样学习的?
  3. 你平常都上哪些网站?

对技术的热情

  1. 你是否了解vue3?vue3做了哪些优化?与vue2有什么不同?
  2. 你是否了解微服务?web component? http3?等
  3. 是否有开源项目?

终面(hr面)

侧重考察性格、潜力

到了这一面,offer基本已经到手了,但也不可掉以轻心,因为hr往往有一票否决权。

这面需要我们展现以下特性:

  1. 乐观积极
  2. 主动沟通
  3. 逻辑顺畅
  4. 上进有责任心
  5. 有主张,做事果断

可能会有以下问题:

  1. 对加班的看法
  2. 职业规划是什么
  3. 你有什么要问的
  4. 你大学都参加了什么社团
  5. 你平时都喜欢干什么
  6. 如果和同事有了冲突,你会怎么办

至此面试结束,恭喜你拿到了心仪的offer!

接下来要讲的是面试技巧以及经验,以帮助大家更好的应对面试!!!

面试技巧

如果你是面试官

面试经验

阿里

腾讯

百度

小米

bilibili

头条

其他

招聘官网

待遇


面试题仓库