前端面试题

作者: 前端一枚渣渣 | 来源:发表于2019-06-20 08:43 被阅读110次

    三栏布局

    • float
      <div>
        <section class="a1">a1</section>
        <section class="a2">a2</section>
        <section class="a3">a3</section>
        <section class="a4">a4</section>
        <section class="a5">a5</section>
      </div>
      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 (
              <Consumer>
                {store=>{
                  state = mapStateToProps(store.getState())
                  dispatch = mapDispatchToProps(store.dispatch)
                  return <Comp {...state}{...dispatch}></Comp>
                }}
              </Consumer>
            )        }
        }
      }
    }
    

    容器组件和展示组件

    • 容器组件负责管理数据和逻辑
    • 展示组件负责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()
    

    相关文章

      网友评论

        本文标题:前端面试题

        本文链接:https://www.haomeiwen.com/subject/elirqctx.html