前端面试题

三栏布局

  • float
    a1
    a2
    a3
    a4
    a5
    div { width: 180px; height: 50px; } section { float: left; } .a1 { width: 50px; height: 50px; background-color: tan; } .a2 { float: right; width: 50px; height: 50px; background-color: tan; } .a3 { width: 80px; height: 25px; background-color: red; } .a4 { width: 40px; height: 25px; background-color: #ddd; } .a5 { width: 40px; height: 25px; background-color: #666; }
  • position
    div {
      width: 180px;
      height: 50px;
      position: relative;
    }
    .a1 {
      position: absolute;
      width: 50px;
      height: 50px;
      background-color: red;
    }
    .a2 {
      position: absolute;
      left: 50px;
      width: 80px;
      height: 25px;
      background-color: blue;
    }
    .a3 {
      position: absolute;
      left: 50px;
      top: 25px;
      width: 40px;
      height: 25px;
      background-color: green;
    }
    .a4 {
      position: absolute;
      left: 90px;
      top: 25px;
      width: 40px;
      height: 25px;
      background-color: tan;
    }
    .a5 {
      position: absolute;
      width: 50px;
      height: 50px;
      left: 130px;
      background-color: red;
    }
    
  1. flex
div {
  width: 180px;
  height: 50px;
  display: flex;
  flex-flow: column wrap;
  align-content: flex-start;
}
.a1 {
  width: 50px;
  height: 50px;
  background-color: red;
}
.a2 {
  width: 80px;
  height: 25px;
  background-color: tan;
}
.a3 {
  flex-grow: 1;
  background-color: aqua;
}
.a4 {
  width: 25px;
  height: 50px;
  background-color: #fff;
}
.a5 {
  flex-grow: 1;
  background-color: red;
}
  1. 三栏等宽布局
div {
  width: 180px;
  height: 50px;
  display: flex;
  background-color: tan;
}

section {
  flex: auto;
}

.a1 {
  background-color: #fff;
}
.a2 {
  background-color: #444;
}
.a3 {
  background-color: red;
}

垂直居中

  1. position
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  margin: auto;
  1. table
div {
  width: 100px;
  height: 100px;
  position: relative;
  background-color: tan;
  display: table-cell;
  vertical-align: middle;
  text-align: center;
}
span {
  background-color: red;
}
  1. 行内块
div {
  width: 100px;
  height: 100px;
  position: relative;
  background-color: tan;
}
section {
  width: 50px;
  height: 50px;
  display: inline-block;
  margin: 25px;
  background-color: red;
}
  1. float
div {
  width: 100px;
  height: 100px;
  position: relative;
  background-color: tan;
}
section {
  width: 50px;
  height: 50px;
  margin: 25px;
  float: left;
  background-color: red;
}
  1. line-height
div {
  width: 100px;
  height: 100px;
  background-color: tan;
  text-align: center;
  line-height: 100px;
}
span{
  background-color: #fff;
  vertical-align: middle;
}

盒模型

margin-box, border-box, padding-box, content-box
首先是最内层content-box,用来显示元素信息
向外是padding-box,主要用于设置元素四个方向的内边距,
再向外是border-box,用于设置元素四个方向的边框样式,
最外层是margin-box,为了让元素与其他元素隔开,对于垂直方向上的BFC元素的margin会发生合并,去较大的值
padding-box和margin-box是透明的,padding-box会受元素的背景的影响,可以通过box-sizing设置
padding-box和border-box不能去负值,margin-box可以取负值
还有元素的溢出属性,处理空白空间及文本溢出

  * css中每个元素都看作多个盒子的组合,我们可以通过设置这些盒子的属性来改变元素的样式
  * 如果设置 box-sizing 为 content-box,那么宽度就是内容区的宽度
  * 如果设置为 border-box,那么宽度就死活内容区宽度+padding+border

单行文本溢出省略:

text-overflow:ellipsis;
white-space:nowrap;
overflow:hidden;

BFC

浮动,绝对定位,overflow不为visible,非块级盒子块级容器
触发:
  1. float 除了none以外的值 
 2. overflow 除了visible 以外的值(hidden,auto,scroll ) 
 3. display (table-cell,table-caption,inline-block, flex, inline-flex) 
 4. position值为(absolute,fixed)

特性:
  在BFC中,盒子从顶端开始垂直地一个接一个地排列。
  盒子垂直方向的距离由margin决定。属于同一个BFC的两个相邻盒子垂直方向的margin会发生重叠。
  在BFC中,每一个盒子的左外边距(margin-left)会触碰到容器的左外边缘(border-left)。
  BFC不会与浮动盒子产生交集,而是紧贴浮动元素边缘。
  计算BFC高度BFC时,自然也会检测浮动的子盒子高度。

应用:
  自适应两栏布局
  解决margin叠加问题:下面元素添加父元素:overflow: hidden;
  清除浮动,计算BFC高度 

闭合浮动的办法:

  • 包含块overflow:hidden/BFC
  • 包含块display:flow-root/BFC
  • 包含块变表格/BFC
  • 包含块变行内块元素/BFC
  • br标签的清除浮动

谈谈你对MVVM开发模式的理解

  • MVVM主要分为model/view/viewmodel三部分
  • model:代表数据模型,数据和业务逻辑都在model层中定义
  • view:代表UI视图,负责数据的展示
  • viewmodel:负责监听model中数据的改变并且控制视图的更新,处理用户交互操作
  • Model和View并无直接关联,是通过viewmodel来进行联系的,model和viewmodel之间有着双向数据绑定的联系。因此当model中的数据改变时会触发view层的刷新,同样view中由用户交互操作而改变的数据也会在model中同步。
  • 这种模式实现了model和view的数据自动同步,因此开发者只需要专注于对数据的维护操作即可,而不需要自己操作DOM

如何优化SPA应用的首屏加载速度慢的问题

  1. 将公用的JS库通过script标签外部引入,让浏览器并行下载资源文件,提高下载速度;
  2. 在配置路由时,页面和组件使用懒加载的方式引入,在调用某个组件时再加载对应的js文件;
  3. 加一个首屏 loading 图,提升用户体验;

跨域(Cross-Origin)

只要协议、主机、端口不一致,就会有跨域的问题

  • javascript跨域通信
    • jsonp
    • CORS设置跨域头
    • 在框架中配置跨域代理
  • jsonp的实现原理
    • script标签引入外部网站的代码,一般都是使用查询字符串告诉对方我们页面中的callback函数,然后对方把需要返回的数据包在这个函数里面
    • 其实JSONP并不算真正意义上的AJAX请求,只是请求了一个js文件并且执行了,而且这种跨域方法只能进行GET请求
  function jsonp(url, value, cb) {
    let cbName = 'JSONP_CALLBACK_' + Date.now() + '_' + Math.random().toString().slice(2)
    window[cbName] = cb
    url = url + '?q=' + value + '&callback=' + cbName
    let script = document.createElement('script')
    script.src = url
    script.onload = () => {
      document.body.removeChild(script)
      delete window[cbName]
    }
    document.body.appendChild(script)
  }

  function ajax(url = '', data = {}, type = 'GET') {
    if (type === "GET") {
      let urlStr = ""
      Object.keys(data).forEach(key => {
        urlStr += key + '=' + data[key] + '&'
      })
      if (urlStr) {
        urlStr = urlStr.substring(0, urlStr.length - 1)
        url += '?' + urlStr
      }
      return axios.get(url)
    } else if (type === "POST") {
      return axios.post(url, data)
    }
  }
  • CORS
    • 它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制
    • 简单请求
      • 请求方法为HEAD、GET或者POST中的一种
      • HTTP的头信息有以下几种字段Accept、Accept-Language、Content-Language、Last-Event-ID
      • Content-Type的值只限于application/x-www-form-urlencoded、multipart/form-data、text/plain三个
      • 浏览器发出请求时,浏览器会自动在请求头中添加一个字段Origin,值为发出请求网页的源地址
      • 服务端根据这个值,决定是否同意这次请求,如果Origin的值不在指定的许可范围,浏览器接收到的HTTP回应将不包含Access-Control-Allow-Origin,抛出错误被XMLHttpRequest的onerror回调函数捕获。如果Access-Control-Allow-Origin字段正好跟带过去的Origin的值一样,则返回对应的数据,完成一次请求。
    • 非简单请求以及option请求
      • 非简单请求是那种对服务器有特殊要求的请求,比如请求方法是PUT或DELETE,或者Content-Type字段的类型是application/json。
      • 在进行非简单请求之前,浏览器会在正式请求之前发送一次预检请求,这就是有时候我们会在控制台中看到的option请求,就是说,正式请求之前,浏览器会去问服务端我这个地址能不能访问你,如果可以,浏览器才会发送正式的请求,否则报错。
    • 总结
      • CORS实现跨域的方法就是根据请求头的Origin值和响应头的Access-Control-Request-Headers和Access-Control-Request-Method的值进行比对,通过了就可以请求成功,没通过就请求失败。
  • 比较
    • JSONP只支持GET请求,CORS支持所有类型的HTTP请求。JSONP的优势在于支持老式浏览器,以及可以向不支持CORS的网站请求数据。

前端如何优化网站性能

  • 减少 HTTP 请求数量:
    • 浏览器与服务器主要是通过 HTTP 进行通信。浏览器与服务器需要经过三次握手,每次握手需要花费大量时间。而且不同浏览器对资源文件并发请求数量有限,一旦 HTTP 请求数量达到一定数量,资源请求就存在等待状态,因此减少 HTTP 的请求数量可以很大程度上对网站性能进行优化。
  • CSS Sprites:
    • 国内俗称 CSS 精灵,这是将多张图片合并成一张图片达到减少 HTTP 请求的一种解决方案,可以通过 CSS background 属性来访问图片内容。这种方案同时还可以减少图片总字节数。
  • 合并 CSS 和 JS 文件:
    • 现在前端有很多工程化打包工具,如:grunt、gulp、webpack等。为了减少 HTTP 请求数量,可以通过这些工具再发布前将多个 CSS 或者 多个 JS 合并成一个文件。
  • 采用 lazyLoad:
    • 俗称懒加载,可以控制网页上的内容在一开始无需加载,不需要发请求,等到用户操作真正需要的时候立即加载出内容。这样就控制了网页资源一次性请求数量。
  • 利用浏览器缓存
    • 浏览器缓存是将网络资源存储在本地,等待下次请求该资源时,如果资源已经存在就不需要到服务器重新请求该资源,直接在本地读取该资源。
  • 减少 DOM 操作,达到减少重排(Reflow)
    • 基本原理:重排是 DOM 的变化影响到了元素的几何属性(宽和高),浏览器会重新计算元素的几何属性,会使渲染树中受到影响的部分失效,浏览器会验证 DOM 树上的所有其它结点的 visibility 属性,这也是 Reflow 低效的原因。如果 Reflow 的过于频繁,CPU 使用率就会急剧上升。

Less / Sass

Less的变量名使用@符号开始
Sass的变量是必须$开始

  • 作用域:
    • Sass无全局变量概念
    • LESS中的作用域和其他程序语言中的作用域非常的相同
  • 混合(Mixins):
    • Sass
      声明:@mixin a($borderWidth:2px){}
      调用:@include error();
    
    • Less
      声明:.error(@borderWidth:2px){}
      调用:.error();
    
  • 继承
    • Sass
      @extend .block; /*继承.block选择器下所有样式*/
    
    • Less
      .block;/*继承.block选择器下所有样式*/
    

AntDesign / bootstrap

http协议

  • HTTP是基于TCP/IP通信协议来传递数据
  • HTTP是一个应用层协议,由请求和响应构成,是一个标准的客户端服务器模型。HTTP是一个无状态的协议。
  • 工作过程大概如下:
    • 用户在浏览器中键入需要访问网页的URL或者点击某个网页中链接;
    • 浏览器根据URL中的域名,通过DNS解析出目标网页的IP地址;
    • 在HTTP开始工作前,客户端首先会通过TCP/IP协议来和服务端建立链接(TCP三次握手)
    • 建立连接后,客户机发送一个请求给服务器,请求方式的格式为:统一资源标识符(URL)、协议版本号,后边是MIME信息包括请求修饰符、客户机信息和可内容。
    • 服务器接到请求后,给予相应的响应信息,其格式为一个状态行,包括信息的协议版本号、一个成功或错误的代码,后边是MIME信息包括服务器信息、实体信息和可能的内容。
    • 一般情况下,一旦Web服务器向浏览器发送了请求数据,它就要关闭TCP连接,然后如果浏览器或者服务器在其头信息加入了这行代码:Connection:keep-alive,TCP连接在发送后将仍然保持打开状态,于是,浏览器可以继续通过相同的连接发送请求。保持连接节省了为每个请求建立新连接所需的时间,还节约了网络带宽。
  • 短连接:建立连接——数据传输——关闭连接...建立连接——数据传输——关闭连接,如果客户请求频繁,将在TCP的建立和关闭操作上浪费较多时间和带宽。
  • 长连接:建立连接——数据传输...(保持连接)...数据传输——关闭连接
    • with pipeling: 每次建立链接后无需等待请求回来就可以发送下一个请求
    • without pipeling: 客户端只在收到前一个请求的响应后,才发出新的请求。
  • Http请求报文
    客户端发送一个HTTP请求到服务器的请求消息包括以下格式:
      请求行(request line)、请求头部(header)、请求体组成
      请求行:
        方法:
            GET 获取资源
            POST 向服务器端发送数据,传输实体主体
            PUT 传输文件
            HEAD 获取报文首部
            DELETE 删除文件
            OPTIONS 询问支持的方法
            TRACE 追踪路径
        URL
        协议/版本号
      请求头:
          通用首部(General Header)
          请求首部(Request Header)
          响应首部(Response Header)
          实体首部(Entity Header Fields)
          
      请求体
    
  • Http响应报文
    HTTP响应组成:响应行、响应头、响应体。
    响应行
        (HTTP/1.1)表明HTTP版本为1.1版本,状态码为200,状态消息为(ok)
    响应头
        Date:生成响应的日期和时间;
        Content-Type:指定了MIME类型的HTML(text/html),编码类型是ISO-8859-1
    响应体
    
  • GET和POST区别
    • GET提交的数据会放在URL之后,以?分割URL和传输数据,参数之间以&相连,如EditPosts.aspx?name=test1&id=123456. POST方法是把提交的数据放在HTTP包的Body中.
    • GET提交的数据大小有限制(因为浏览器对URL的长度有限制),而POST方法提交的数据没有限制.
    • GET方式需要使用Request.QueryString来取得变量的值,而POST方式通过Request.Form来获取变量的值。
    • GET方式提交数据,会带来安全问题,比如一个登录页面,通过GET方式提交数据时,用户名和密码将出现在URL上,如果页面可以被缓存或者其他人可以访问这台机器,就可以从历史记录获得该用户的账号和密码.

websocket

首先Websocket是基于HTTP协议的,或者说借用了HTTP的协议来完成一部分握手。
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat
  • http long poll 和 ajax 轮询都可以实现实时信息传递

    • ajax轮询: 让浏览器隔个几秒就发送一次请求,询问服务器是否有新信息。
    • long poll 都是采用轮询的方式,不过采取的是阻塞模型,客户端发起连接后,如果没消息,就一直不返回Response给客户端。直到有消息才返回,返回完之后,客户端再次建立连接,周而复始
  • 特点:

    • 解决了http协议只能从客户端向服务器发送请求的缺陷,有了websocket,服务器也能主动向客户端推送消息
    • 和http一样,是建立在tcp协议之上,默认端口也是80和443,
    • 没有同源限制,客户端可以与任意服务器通信
    • 协议标识符是ws,服务器网址就是URL
    • 可以发送文本,也可以发送二进制数据

socket.io

socket.io 是一个能实现多人远程实时通信(聊天)的库
它包装的是 H5, WebSocket和轮询, 如果是较新的浏览器内部使用 WebSocket,如果浏览器不支持, 那内部就会使用轮询实现实时通信

网页从输入网址到渲染完成经历了哪些过程

1 输入网址
2 发送到DNS服务器,并获取域名对应的web服务器对应的ip地址
3 与web服务器建立TCP连接
4 浏览器向web服务器发送http请求
5 web服务器响应请求,并返回指定url的数据(或错误信息,或重定向的新的url地址)
6 浏览器下载web服务器返回的数据及解析html源文件
7 生成DOM树,解析css和js,渲染页面,直至显示完成

数据结构和算法

// reduce
  function reduce(ary, f, initVal) {
    var start = 0
    if (arguments.length == 2) {
      initVal = ary[0]
      start = 1
    }
    for (var i = start; i < ary.length; i++) {
      initVal = f(initVal, ary[i], i, ary)
    }
    return initVal
  }
// flattenDeep
  function flattenDeep(ary) {
    return [].concat(...ary.map(val => {
      if (Array.isArray(val)) {
        return flattenDeep(val)
      } else {
        return val
      }
    }))
  }

ES6 新特性

  • 函数默认值
  • 模板字符串:123${a}456,\
  • 解构赋值
  • let & const
    • let 无变量提升,有块级作用域,禁止重复声明
    • const 无变量提升,有块级作用域,禁止重复声明,禁止重复赋值
  • 新增库函数
    • Number .EPSILON / .isInteger / .isInteger
    • String .includes / .repeat / .startsWith / .endsWith
    • Array .fill / .findIndex / .of() /
    • Object .assign
    • Math
  • 箭头函数:共享父级 this 对象,共享父级 arguments,不能当做构造函数
  • 类 & 继承
    • 本质为对原型链的二次包装;类没有提升;不能使用字面量定义属性;动态继承类的构造方法中 super 优先 this
  • 模块
    • 每个模块都有自己完全独立的代码块,跟作用域类似,但是更加封闭。
    • 无限制导出导出
    • 内联导出:严格模式下运行使用 export 关键字,后面紧跟声明关键字(let、function 等)声明一个导出对象,声明并同时导出的导出方式
    • 对象导出
    • 一个模块只能有一个默认导出

ES8 新特性

  • String:新增padStart,padEnd
  • Object.values 方法返回一个给定对象自己的所有可枚举属性值的数组
  • Object.entries 方法返回一个给定对象自身可遍历属性 [key, value] 的数组
  • Object.getOwnPropertyDescriptors 方法返回指定对象所有自身属性的描述对象
  • 函数参数和函数调用中的尾逗号
  • Async 函数

BOM / DOM

  • DOM文档对象模型,BOM浏览器对象模型
  • DOM 是针对 HTML 和 XML 提供的一个API,为了能以编程的方法操作这个 HTML 的内容。将html中的每个元素都看作是一个对象,每个对象都叫做一个节点,这些节点组成一个DOM树。document是DOM树的根节点
  • BOM 是浏览器提供的附加对象,用于处理文档之外的所有内容,比如alert/confirm/prompt,BOM包含的对象有,document,screen,location,history,navigator
  • DOM是所有W3C标准都必须遵守的规则,BOM是各浏览器厂商遵守的规则
  • BOM的核心是window,它既是通过js访问浏览器窗口的一个接口,又是一个Global(全局)对象。这意味着在网页中定义的任何对象,变量和函数,都以window作为其global对象。
  • DOM通过创建树来表示文档,描述了处理网页内容的方法和接口,从而使开发者对文档的内容和结构具有控制力,用DOM API可以轻松地删除、添加和替换节点。
  • DOM 的根节点是BOM 的window 对象的子对象。

图片懒加载

  • 三个API,我们获得了三个值:
    • 可视区高度clientHeight、
    • 元素相对于其父元素容器顶部的距离offsetTop、
    • 浏览器窗口顶部与容器元素顶部的距离也就是滚动条滚动的高度scrollTop。
  • 当offsetTop - scroolTop < clientHeight,则图片进入了可视区内,则被请求。
  var imgs = document.querySelectorAll('img');

  //offsetTop是元素与offsetParent的距离,循环获取直到页面顶部
  function getTop(e) {
      var T = e.offsetTop;
      while(e = e.offsetParent) {
          T += e.offsetTop;
      }
      return T;
  }

  function lazyLoad(imgs) {
      var H = document.documentElement.clientHeight;//获取可视区域高度
      var S = document.documentElement.scrollTop || document.body.scrollTop;
      for (var i = 0; i < imgs.length; i++) {
          if (H + S > getTop(imgs[i])) {
              imgs[i].src = imgs[i].getAttribute('data-src');
          }
      }
  }

  window.onload = window.onscroll = function () { //onscroll()在滚动条滚动的时候触发
      lazyLoad(imgs);
  }

原型,闭包,高级函数,异步

  • 闭包就是一个函数里面生成并返回一个函数,返回的这个函数能读取到外部函数里面的变量
  • 原型就是 a 是实例,b 是构造函数,然后a.proto === b.prototype,使用instanceof来判断的时候就是不停地向上寻找,还有读取a的某个属性如果没有,就会默认去a的原型上找
  • 高阶函数:高阶函数是一个接收函数作为参数或将函数作为输出返回的函数 map/reduce/filter
  • 异步:js是单线程的,但浏览器是多线程的,当js运行遇到异步代码时,会将代码交给webapi异步执行,js则可以继续执行下面的代码;异步代码会被塞入task queue里排队,task queue会一直观察栈里代码有没有执行完成,一旦发现栈空了,就会调用回调函数,然后重新回到js线程中执行
  • https://www.zhihu.com/search?type=content&q=js%E5%BC%82%E6%AD%A5
  • async表示该函数要做异步处理。await表示后面的代码是一个异步操作,等待该异步操作完成后再执行后面的动作。如果异步操作有返回的数据,则在左边用一个变量来接收它。

sessionstorage localstorage cookie区别

  1. 传递方式不同
    cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递。
    sessionStorage和loaclStorage不会自动把数据发给服务器,仅在本地保存。
  2. 数据大小不同
    cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下。
    cookie数据最大4k,sessionStorage和localStorage比cookie大得多,可以达到5M或者更大。
  3. 数据有效期不同
    sessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持;
    localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;
    cookie只在设置cookie过期时间之前一直有效,即使窗口或浏览器关闭。
  4. 作用域不同
    sessionStorage不同的浏览器窗口不能共享,即使是同一个页面;
    localStorage所有同源窗口都是共享的;
    cookie所有同源窗口中都是共享的。

session / cookie

  • Cookie 可以保持登录信息到用户下次与服务器的会话,换句话说,下次访问同一网站时,用户会发现不必输入用户名和密码就已经登录了(当然,不排除用户手工删除Cookie),Cookie满足同源策略
    Cookie 在生成时就会被指定一个Expire值,这就是Cookie的生存周期,在这个周期内Cookie有效,超出周期Cookie就会被清除。有些页面将Cookie的生存周期设置为“0”或负值,这样在关闭浏览器时,就马上清除Cookie,不会记录用户信息,更加安全。

  • 由于HTTP协议是无状态的协议,所以服务端需要记录用户的状态时,就需要用某种机制来识具体的用户,这个机制就是Session.典型的场景比如购物车,当你点击下单按钮时,由于HTTP协议无状态,所以并不知道是哪个用户操作的,所以服务端要为特定的用户创建了特定的Session,用用于标识这个用户,并且跟踪用户,这样才知道购物车里面有几本书。这个Session是保存在服务端的,有一个唯一标识。

  • Session是在服务端保存的一个数据结构,用来跟踪用户的状态,这个数据可以保存在集群、数据库、文件中;
    Cookie是客户端保存用户信息的一种机制,用来记录用户的一些信息,也是实现Session的一种方式。

event loop

第一步确认宏任务,微任务
  宏任务:script,setTimeout,setImmediate,promise中的executor
  微任务:promise.then,process.nextTick
process.nextTick优先级高于Promise.then


timers: setTimeout / setInterval
I/O callbacks: 不在其他阶段的所有回调函数
poll: 获取新的I/O事件
check:执行setImmediate
close callback: 执行关闭事件的回调函数


在整个轮询的开始执行process.nextTick
然后再执行setTimeOut、setInterval
再执行其他的回调函数
最后执行setImmediate

发送ajax请求

axios / fetch

Node.js

Node核心思想:1.非阻塞;  2.单线程;  3.事件驱动。
Node 是一个服务器端 JavaScript 解释器
当线程遇到IO操作的时候,不会以阻塞的方式等待IO操作完成或者数据的返回,而是将IO操作发送给操作系统,
然后接着执行下一个操作,当操作系统执行完IO操作之后,以事件的方式通知执行IO的线程,
线程会在特定的时候执行这个事件。这一切的前提条件就是,系统需要一个事件循环,
以不断的去查询有没有未处理的事件,然后给预处理。

Redux

redux 是一个独立的专门用于状态管理的js库
可以管理react应用中多个组件共享的状态

用redux对组件的状态进行集中式管理

组件:两个方面
展现数据   状态显示
与用户交互更新数据   更新状态


redux核心是一个store(仓库)
组件直接从store中读取状态

更新状态:
1. Action Creators ==>> dispatch(action) :传两个值(type和data) type是传的类型(删除,增加,创建,更新)
2. store
3. Reducers ==>> 接受(previousState, action) 返回(newState)
4. React Component


createStore()
store: 管理state, reducer
方法: getState() , dispatch(action) , subscribe(listener)
action对象 
reducer返回的是新的状态

applyMiddleware 中间件
thunk 异步

diff算法

  • 只在同层进行比较
  • 如果节点发生变化,那么就直接替换
  • 如果节点相同,递归比较子节点的变化
  • 如果有key,那么就会key相同的进行比较

react-redux 的核心就是一个connect函数,接收两个参数,mapStatetoprops,mapdispatchtoprops,返回一个高阶组件,这个高阶组件接受一个组件,返回一个组件,但是这个返回的组件的props上面多了数据以及操作数据的方法

function connect(mapStateToProps,mapDispatchToProps){
  return function(com){
    return class extends React.Component{
      render(){
        return (
          
            {store=>{
              state = mapStateToProps(store.getState())
              dispatch = mapDispatchToProps(store.dispatch)
              return 
            }}
          
        )        }
    }
  }
}

容器组件和展示组件

  • 容器组件负责管理数据和逻辑
  • 展示组件负责UI的呈现
  • 他们通过react-redux提供的connect方法取得联系

为什么连接的时候是三次握手,关闭的时候却是四次握手?

因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。
其中ACK报文是用来应答的,SYN报文是用来同步的。
但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,
所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。
只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。

  • 三次挥手:
    • 客户端发送 SYN 包到服务端,等待服务端确认
    • 服务端收到 SYN 包,同时自己也发送一个 SYN+ACK 包给客户端
    • 客户端接收到 SYN+ACK 包,向服务端发送确认包 ACK ,发送完毕,客户端与服务端 TCP 连接成功,完成三次握手
  • 四次挥手:
    • 客户端连续发送释放报文 FIN ,等待服务端确认
    • 服务端收到释放报文 FIN ,发出确认报文 ACK

redux

  action: 是store唯一的信息来源,把action发送给store必须通过store的dispatch方法。
          每个action必须有一个type属性描述action的类型。

XSS 与 CSRF 两种跨站攻击

  1. xss 跨站脚本攻击,主要是前端层面的,用户在输入层面插入攻击脚本,改变页面的显示,或则窃取网站 cookie,预防方法:不相信用户的所有操作,对用户输入进行一个转义,不允许 js 对 cookie 的读写
  2. csrf 跨站请求伪造,以你的名义,发送恶意请求,通过 cookie 加参数等形式过滤
  3. 我们没法彻底杜绝攻击,只能提高攻击门槛

负载均衡

当系统面临大量用户访问,负载过高的时候,通常会使用增加服务器数量来进行横向扩展,使用集群和负载均衡提高整个系统的处理能力

JS实现继承的方法

1. 原型链继承
  将父类的实例作为子类的原型
  function Cat() {}
  Cat.prototype = new Animal()
  Cat.prototype.name = 'cat'
  var cat = new Cat()
2. 构造继承
  使用父类的构造函数来增强子类的实例,等于是复制父类的实例属性给子类
  function Cat(name) {
    Animal.call(this)
    instance.name = name || 'Tom'
  }
  var cat = new Cat()
3. 实例继承
  为父类实例添加新特性,作为子类的实例返回
  function Cat(name) {
    var instance = new Animal()
    instance.name = name || 'Tom'
    return instance
  }
  var cat = new Cat()

你可能感兴趣的:(前端面试题)