面试笔记

230 阅读9分钟

Chrome

performance 性能
memory 内存
application 网页相关
security 安全相关
audits 性能

header标签

  1. <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
    用ie最高级渲染页面,如果是chrome,且安装了GCF,则用Google Chrome浏览器内核渲染
  2. <meta name="renderer" content="webkit">
    双核浏览器优先使用webkit内核渲染
  3. <link rel="dns-prefetch" href="//static.360buyimg.com">
    dns预解析

基础

页面布局、css盒模型、DOM事件、HTTP协议、面向对象、原型链、通信、安全、算法

1. 三栏布局(高度已知)

浮动、定位、flex、table、grid


浮动:

  section
       article
            div.left[style="float: left; w300"]
            div.right[style="float: right; w300"]
            div.center[style="ml:300px; mr:300px"]

flex: ...
表格:

    section
        article[style="w100p; display:table;"]>div[style="display: table-cell"]
        div.left[style="w300"]
        div.right[style="w300"]

grid:

    section
        article[style="display: grid;
                               w100p;
                                grid-template-rows: 100px  //行高
                                grid-template-columns: 300px auto 300px     
                   "]

盒模型

  1. 标准模型 + IE模型
    box-sizing: content-box 标准模型(默认)
    box-sizing: border-box IE模型
  2. JS获取盒模型宽高
    dom.style.width/height 缺点:只能获取内联元素
    dom.currentStyle.width/height 缺点: 只能支持IE
    window.getComputedStyle(dom).width/height
    dom.getBoundingCltRect().width/height 可获取元素相对于父元素【左】【上】距离
  3. margin重叠
    父子元素
    上下元素
  4. BFC(解决margin重叠)
    BFC基本概念:块级元素格式化上下文
    BFC原理:BFC的渲染规则 形成独立区域,领土互不侵犯。float元素看得见普通元素,普通元素看不到float元素
    创建BFC:
1. overflow: !visible
2. float
3. display: table-cell、table-caption、inline-block
4. position: absolute/fixed

DOM事件

  1. DOM事件级别
    0级DOM:内联写onclick=""
    1级DOM:无 DOM级别1于1998年10月1日成为W3C推荐标准。1级DOM标准中并没有定义事件相关的内容,所以没有所谓的1级DOM事件模型
    2级DOM:dom.addEventListener(event, fn, false) //false表示在冒泡阶段调用,true表示在捕获阶段调用
    3级DOM:dom.addEventListener('keyup', fn, false) //增加许多事件类型,如鼠标事件,键盘事件
  2. DOM事件模型
    捕获、冒泡
  3. DOM事件流
    捕获阶段 -> 到达目标元素 -> 冒泡阶段
  4. 描述DOM事件捕获具体流程
    window -> document -> html -> body -> ... -> 目标元素
  5. event对象的常见应用
    列举易混淆
    event.preventDefault() 阻止默认时间
    event.stopPropagation() 阻止冒泡
    event.stopImmediatePropagation() 事件绑定2个处理函数a,b。a调用该方法,可以阻止b函数调用
    event.currentTarget 绑定事件处理函数的对象
    event.target 发出事件的对象
    event.key 点击键盘w,event.key="w",点击W,event.key="W" 区分大小写
    event.which 对应编码,不区分大小写
  6. 自定义事件
    let eve = new Event('custom')  //基础
    let eve = new CustomEvent('custom', { detail: {自定义传入内容} })   //高度自定义,可传入参数
    dom.addEventListener('custom', fn)
    dom.dispatchEvent(eve)   //解读:向dom元素发送事件eve
    

HTTP协议

  1. HTTP协议的主要特点
    简单快速url直接访问、灵活、无连接连接一次就断掉,不会保持连接、无状态
  2. HTTP报文的组成部分:
    ①请求行:
    Request URL:www.baidu.com/
    Request Method:GET
    Status Code:200 OK
    Remote Address:172.31.1.246:8080
    ②请求头:
    Cache-Control:private, max-age=10
    Connection:Keep-Alive
    Content-Encoding:gzip
    Content-Type:text/html; charset=utf-8
    Date:Tue, 21 Feb 2017 03:05:37 GMT
    Expires:Tue, 21 Feb 2017 03:05:47 GMT
    Last-Modified:Tue, 21 Feb 2017 03:05:37 GMT
    Proxy-Connection:Keep-Alive
    Transfer-Encoding:chunked
    Vary:Accept-Encoding
    X-UA-Compatible:IE=10
    ④空行:
    最后一个请求头之后是一个空行,发送回车符和换行符,通知服务器以下不再有请求头。
    ⑤请求体:
  3. HTTP方法:GET、POST、PUT、DELETE、HEAD
  4. POST和GET的区别:
    1.GET在浏览器回退无害,而POST会再次提交请求
    2.请求浏览器会自动做缓存,POST不会
    3.GET参数会被保存在浏览器记录里面,POST不会
    4.GET请求参数有长度限制,POST没有限制(不同浏览器不同)
    5.GET参数暴露在URL不安全
    6.GET参数放在URL传递,POST放在request body中
  5. HTTP状态码:
    1xx: 指示信息 - 表示请求已接受,继续处理
    2xx: 成功 206带有range头的get请求,表示返回一部分数据,视频缓存用到
    3xx: 重定向 301请求页面转移到新url 302请求页面临时转移到新url 304从缓存中取
    4xx: 客户端错误
    5xx: 服务器错误
  6. 什么是持久化连接:
    HTTP协议采用【请求-应答】模式,当使用普通模式时,每次请求应答都建立一次连接,完成后立即断开连接 当使用Keep-Alive模式(长连接,HTTP1.1),客户端和服务器连接持续有效,在一次HTTP连接中可以发送多次request和接收多个 response。request和response仍然是一对一关系,response仍是被动
  7. 什么是管线化:
    非管线化: req1 -> res1 ->req2 -> res2 -> req3 -> res3
    管线化: req2 -> req2 -> req3 -> res1 -> res2 -> res3

原型链

  1. 创建对象有几种方法
    字面量
    let obj = {name: 'xm'} let obj = new Object({name: 'xm'})
    通过构造函数
    let M = function(name){ this.name = name } let obj = new M('xm')
    通过Object.create
    let p = { name: 'xm' } let obj = Object.create(p) //创建obj,继承p的原型对象
  2. 原型、构造函数、实例、原型链

3. instanceof的原理
判断【实例对象】__proto__ === 【构造函数】.prototype
4. new运算符

//自己实现new运算符
var new2 = function(func){  
    var o = Object.create(func.prototype) //创建对象,继承构造函数原型对象
    var k = func.call(o)                  //改变this指向(转移上下文,转成o对象)
    if(typeof k === 'object'){            //如果构造函数返回的是一个对象,则返回k
        return k
    }else{
        return o                          //否则返回o
    }
}

面向对象

  1. 类与实例
    1. 类的声明
          //es5
          function Animal(){
              this.name = 'name'
          }
          //es6
          class Animal {
              constructor(){              //构造函数
                  this.name = name
              }
          }
      
    2. 生成实例
      new Animal()
  2. 类与继承
    1. 如何实现继承
          //es5  
          //1. 构造函数(缺点部分继承)
          function Parent() {
              this.name = 'parent'
          }
          function Child() {
              Parent.call(this)       //相当于child.name = 'parent',所以原型链上的方法没有继承
              this.type = 'child'
          }   
          
          //2. 原型链(缺点继承的原型对象共用:实例2个child,修改其中一个原型链上的值,另一个也改变)
          function Parent() {
              this.name = 'parent'
              this.arr = [1, 2, 3]
          }
          function Child() {
              this.type = 'child'
          }
          Child.prototype = new Parent()   //指向实例对象,并非原型。原型对象共用
          
          //3. 组合方式(去除上面2个缺点,缺点Parent实例化2次)
          function Parent() {
              this.name = 'parent'
              this.arr = [1, 2, 3]
          }
          function Child() {
              Parent.call(this)     //构造函数   Parent第一次实例化
              this.type = 'child'
          }
          Child.prototype = new Parent()   //原型链   Parent第二次实例化
          
          //4. 优化组合方式(缺点 child.constructor = Parent)
          function Parent() {
              this.name = 'parent'
              this.arr = [1, 2, 3]
          }
          function Child() {
              Parent.call(this)
              this.type = 'child'
          }
          Child.prototype = Parent.prototype   //指向原型
          
          //5 . 组合优化2
          function Parent() {
              this.name = 'parent'
              this.arr = [1, 2, 3]
          }
          function Child() {
              Parent.call(this)
              this.type = 'child'
          }
          Child.prototype = Object.create(Parent.prototype)
          Child.prototype.constructor = Child
      

通信类

  1. 同源政策及限制
    同源
    1. 协议相同
    2. 域名相同
    3. 端口相同
    限制
    1. Cookie、LocalStorage 和 IndexDB 无法读取
    2. DOM 无法获得
    3. AJAX 请求不能发送
  2. 前后端如何通信
    1. Ajax
    2. WebSocket不受同源政策影响
    3. CORS支持跨域通信和同源通信
  3. 如何创建Ajax
    var xhr = XMLHttpRequest ? new XMLHttpRequest : new window.ActiveXObject('Microsoft.XMLHTTP')   //兼容IE
    if(type === 'GET') {
        xhr.open(type, url, true) // true为异步请求 false同步请求
        xhr.send()
    }
    if(type === 'POST') {
        xhr.open(type, url, true)
        xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')
        xhr.send()
    }
    xhr.onreadystatechange = function () {
        var DONE = this.DONE || 4;
        if (this.readyState === DONE){
            alert(this.readyState);
        }
    };
    
  4. 跨域通信的几种方式
    1. jsonp
    2. Hash
      //场景 当前页面A通过iframe或frame嵌入了跨域页面B
      //在A中伪代码如下:
      var B = document.getElementsByTagName('iframe')
      B.src = B.src + '#' + 'data'
      window.onhashchange = function() {
          var data = window.location.hash
      }
      
    3. postMessageh5
      // 窗口A(http://A.com)向跨域窗口B(http://B.com)发送信息
      window.postMessage('data', 'http://B.com')
      // 在窗口B中监听: 
      window.addEventListener('message', function(event) {
          event.origin //http://A.com
          event.source //B的window对象
          event.data
      })
      
    4. WebSocket
      var ws = new WebSocoket('wss://...')
      
      ws.onopen = function(event) {
          ws.sen('...')
      }
      ws.onmessage = function(event) {
          ws.close()
      }
      ws.onclose = function(event) {
          // closed
      }
      
    5. CORS
      fetch('/your/url', {
          method: 'get'
      }).then(res => {
          // ...
      }).catch(res => {
          // ...
      })
      

安全类

  1. CSRF
    基本概念、缩写
    跨站请求伪造
    攻击原理
    用户登陆合法网站,恶意网站引诱点击,间接让用户访问某个接口
    例子增加粉丝量、关注用户
    防御措施
    Token验证
    Referer验证 来源验证
    隐藏令牌 将验证信息放在http header头中
  2. XSS
    基本概念
    跨域脚本攻击
    原理
    向页面注入js脚本
    例子评论区注入脚本
    防御措施
    使插入js无法执行

进阶

渲染机制、JS运行机制、页面性能、错误监控

渲染机制

  1. 什么是DOCTYPE及作用
    DTD(文档类型定义)告诉浏览器我是什么类型文档XML HTML,浏览器根据这个来判断用什么形式来解析文档。
    DOCTYPE用来声明文档类型和DTD规范
    常见的DOCTYPE有哪些?
    HTML5
        <!DOCTYPE html>
    HTML4.01
    
  2. 浏览器渲染过程

  1. 重排Reflow
    定义
    DOM结构中的各个元素都有自己的盒子(模型),这些都需要浏览器根据各种样式来计算并根据计算结果来将元素放到它该出现的位置,这个过程称之为reflow
    触发Reflow
    1. 增加、删除、修改DOM
    2. 移动DOM,或者动画尽量让动画不在文档流,减少重排
    3. 修改CSS样式
    4. Resize窗口
    5. 修改默认字体
  2. 重绘Repaint
    定义 将页面要呈现的内容画在屏幕上
    触发Repaint
    DOM改动
    CSS改动
    如何尽量减少repaint: 新建一个documentfragment,将改动先添加在fragment中,然后一次性加入DOM
  3. 布局Layout

JS运行机制

异步~

页面性能

  1. 资源压缩合并,减少HTTP请求

  2. 非核心代码异步加载

    1. 异步加载的方式
      1) 动态脚本加载 document.createElement('script'),加载到文档中
      2) defer HTML解析完之后才会执行
      3) async 加载完之后立即执行
    2. 异步加载的区别
  3. 利用浏览器缓存

    1. 缓存的分类
      • 强缓存
        Expires Expires: Sun, 2 Dec 2018 11:23绝对时间且为服务器时间,服务器时间和客户端时间可能会不一致
        Cache-Control Cache-Control:max-age=3600客户端相对时间,若出现Expires和Cache-Control,以Cache-Control为准
      • 协商缓存询问服务器是否从缓存中读取
        Last-Modified服务器下发的 If-Moddified-Since请求时携带的 Last-Modified: Wed, 2, Dec 2018 00:35:11
        Etag If-None-Match 解决时间过期,内容没变问题
  4. 利用CDN

  5. 预解析DNS

    <mata http-equiv="x-dns-prefetch-control" content="on">  //强制打开a标签DNS预解析
    <link rel="dns-prefetch" href="//host_name_to_prefetch.com">
    

错误监控

  1. 前端错误的分类
    即时运行错误

    1. try..catch
    2. window.onerror

    资源加载错误

    1. object.onerror没有冒泡过程,所以window.onerror监测不到
    2. performance.getEntries()返回所有资源数组
    3. Error事件捕获
      window.addEventListener('error', function(e){
          ...
      }, true) //true捕获
      
  2. 上报错误的基本原理

    1. 采用Ajax通信的方式上报不用这种方式
    2. 利用Image对象上报
      (new Image()).src = 'http://hello.com/test?a=1&b=2'