牛客面经每日一总结(四)

简介: 牛客面经每日一总结(四)

RSA和DSA的区别


他们都是非对称加密算法。


  • RSA: 他是基于大数分解(两个素数的乘积)实现的。它既可以作为签名(签名数字证书)使用也可以做加密(tls握手)使用。


  • DSA:他是基于整数有限域离散对数难题实现的。只能用于数字签名无法用于加密。


AES和DES区别


他们都是对称加密算法。


AES是DES的代替者,安全性高,性能很好,硬件也会多特殊的优化。


由于对称加密算法只能对特定长度明文加密,所以如果对于长明文,我们需要使用分组加密,然后将加密的秘钥段,连接起来。组成最终的秘钥。


内存泄露的原因


  • 在函数中定义一个未声明的变量,会被放在window中,将一直保存到内存中,知道程序结束。


  • 闭包的大量使用,因为闭包时,当外层函数执行上下文销毁后,内存函数应用的变量会被保存在堆中。


  • 递归,没有设置终止条件。


  • js引用DOM节点。即使节点删除了,这引用也会保存到内存中。


通过JSON实现深拷贝的问题


  • 对于对象的循环引用,会报错


  • 不能处理函数,Symbol等类型。


flex的理解


这里说的flex是内容元素的css样式。由flex-grow, flex-shrink, flex-basis组成。默认值是0 1 auto;


这里值讨论flex-basis的使用。


  • 设置元素主轴的初始大小。


  • 当其他两个属性都生效时,那么flex-basis将会失效。


  • 当width或者height 和 flex-basis同时存在,那么width或者height将会失效。


  • 如果flex-basis:auto, 那么它将使用width或者height的值。如果width或者height也为auto或者未设置,那么它将由内容撑开。


flex: 1 = flex: 1 1 0% 
flex: 2 = flex: 2 1 0% 
flex: auto = flex: 1 1 auto 
flex: none = flex: 0 0 auto,常用于固定尺寸不伸缩


如何阻止表单提交


  • 将input:submit改为input:button。


  • 监听form表单的submit事件,调用event.preventDefault(),或者返回false。


异步异常的捕获


我们知道try catch只能捕获存在于自己上下文的错误。但是异步异常就不能被catch。


但是有很多认为这两种方式也不能被捕获


  • 回调函数中的异常


  • await后的promise抛出的异常。 以上两种方式是可以捕获的。


那么如何捕获异步异常呢?


  • 将异步写在promise中使用catch捕获。


  • 但是如果promise中的异步抛出异常,catch可是不可以捕获的,需要使用reject传出异常信息。


这里还需要注意一下catch函数


  • catch只会捕获第一次抛出的异常。


  • 当catch和then方法都抛出异常,那么他只会捕获catch抛出的异常。


new Promise((resolve, reject) => {
      reject("====error")
    }).catch(res => {
      console.log("error1:", res) //  ====error
      throw new Error("======error catch")
    }).then(res => {
      throw new Error("=====error then")
    }).catch(res => {
      console.log("error2: ",res) // Error: ======error catch
    })


为什么0.1+0.2=0.30000000000000004


这个错误的根本原因是:大多数十进制无法正确的转换为二进制。在计算机上计算时,是将十进制转换为二进制后进行计算,并将计算结果从二进制转换为十进制再次显示。

EcmaScrpt规范定义Number的类型遵循了IEEE754-2008中的64位浮点数规则定义的小数后的有效位数至多为52位导致计算出现精度丢失问题!


如何解决这个问题


原生的解决方法


  • 通过toFixed方法:使用定点表示法来格式化一个数值。


  • 该方法接收digits参数。表示小数点后数字的个数。介于 0 到 20(包括)之间,实现环境可能支持更大范围。如果忽略该参数,则默认为 0。


  • 然后返回格式化后的字符串。


let a = 0.1
    let b = 0.2
    const result = parseFloat((a + b).toFixed(1))
    console.log(typeof result, result) // number 0.3


或者通过 *10 再 ÷10 的操作


let a = 0.1 + 0.2; // 0.30000000000000004
    a = Math.round (a * 10); // 乘以 10 → 舍入 "3.0000000000000004" → "3"
    a = a / 10; // 3 / 10
    console.log (a); // 0.3


parseFloat()方法对于小数点后全为0的数字会保留整数。


parseFloat(1.000) // 1
    parseFloat(1.030) // 1.03


伪类选择器


他们一般都是结合父标签使用的。


  • 如果不结合父标签,那么他将会选择符合条件的所有。


  • 如果不结合父标签,那么last-child将没有效果。(不知道为什么,是我测试的有问题吗)


<style>
        /* 这个必须具有嵌套的元素。 但是last-child就不会有这个限制 */
        p:last-child {
          color: red;
        }
      </style>
    <body>
      <!-- <div> -->
      <p>1</p>
      <p>2</p>
      <p>3</p>
      <p>4</p>
      <p>5</p>
      <p>6</p>
      <p>7</p>
      <p>8</p>
      <p>9</p>
      <p>10</p>
      <!-- </div> -->
    </body>


网络异常,图片无法展示
|


如果给p标签加上div父标签,那么p: last-child将生效。


网络异常,图片无法展示
|


包含child的伪类受其他元素的影响


  • first-child: 表示选中第一个元素。一般都是组合元素。即前面需要加上父元素标签。 不然对于first-child可以选中很多。而且对于last-child标签而言。他只在嵌套元素下才能生效。


// 这个选择器就不起作用,因为p不是div中的第一个元素。 
      <style>
        div p:first-child {
          color: red
        }
      </style>
      <div>
        <span>0</span>
        <p>1</p>
        <p>2</p>
        <p>3</p>
      </div>


  • nth-child(数字 / odd / even / 表达式):


  • 数字从1开始的。


  • 受其他元素影响。如果有其他元素,那么其他元素也参数索引


  • even(2n)表示偶数元素选中,odd(2n + 1)表示奇数元素选中。


  • 表达式:必须是包含n的表达式,并且n是从0开始计算的。


  • nth-last-child(): 表示从最后一个开始查找。


  • only-child。表示父元素中只能有一个标签,而且改标签为伪类选择器指定的标签。


网络异常,图片无法展示
|


不受其他元素的影响


  • first-of-type


  • last-of-type。这个并不需要有父元素包裹。


  • nth-of-type(数字 / odd / even / 表达式): 同上面一样


  • nth-last-of-type()


  • only-of-type: 表示父元素内,可以有多种标签,但是只能有唯一一个伪类选择器指定的标签,否则不起作用。 这类选择器,和上面的基本一样,唯一的区别就是他们只参考相同标签的元素。不会管其他类型的元素。


注意使用伪类选择器时,一定要加上父标签。


空标签伪类选择器


empty:标签内什么都没有才可以选中。包括空格。


axios的使用


  • 通过axios.create(config)创建一个实例。并传入一些基本的配置,比如timeout, baseURL等等。


  • 设置请求拦截器。这里一定要返回请求的配置。


// 1. 请求拦截
      instance.interceptors.request.use(config => {
        // console.log(config);
        // 当请求可以发出时   我们拦截  对其做一些修饰
        // 1. config中的一些信息不符合服务器需求
        // 2  每次发送请求时,都希望有一个loading
        // 3. 某些网络请求都必须携带一些特定信息(token)
        return config;//拦截修改后   ,一定要将config返回   让服务器得到请求   来做出响应
      },err => {
        // console.log(err);
      })


  • 设置响应拦截器。如果后端接口比较规范的话,这里可以通过状态码整理响应数据。


// 2. 响应拦截
      instance.interceptors.response.use(res => {
        // console.log(res);//此时是服务器返回的数据
        return res.data;//返回数据本身
      },err => {
        // console.log(err);
         return err;
      })


  • 最后返回axios实例对象。


JWT 的原理


JWT生成的Token由三部分组成:


  • header


  • alg:采用的加密算法,默认是 HMAC SHA256(HS256),采用同一个密钥进行加密和解密;


  • typ:JWT,固定值,通常都写成JWT即可;会通过base64Url算法进行编码


  • payload


  • 携带的数据,比如我们可以将用户的id和name放到payload中;


  • 默认也会携带iat(issued at),令牌的签发时间;


  • 我们也可以设置过期时间:exp(expiration time);


  • 会通过base64Url算法进行编码


  • signature


  • 设置一个secretKey,通过将前两个的结果合并后进行HMACSHA256(默认编码)的算法;


  • HMACSHA256(base64Url(header)+.+base64Url(payload), secretKey);


  • 如果secretKey暴露是一件非常危险的事情,因为之后就可以模拟颁发token,也可以解密token;


注意:前两个字段是通过base64编码的,可以反向解码。但是最后一个字段一般不行。


网络异常,图片无法展示
|


网络异常,图片无法展示
|


http2的主动推送(server push)和websocket有什么区别


  • HTTP2 Server Push,一般用以服务器根据解析 index.html 同时推送 JPG/JS/CSS 等资源,而免了服务器发送多次请求


  • websocket,用以服务器与客户端手动编写代码去推送进行数据通信


http 502和504的区别


  • 502 Bad Gateway。一般表现为你自己写的应用层服务(Java/Go/PHP)挂了,网关层无法接收到响应


  • 504 Gateway Timeout。一般表现为应用层服务 (upstream) 超时,如查库操作耗时十分钟,超过了 Nginx 配置的超时时间


如何中断请求


web新推出的一个api: AbortConroller。具体请参考mdn他是一个类,通过创建对象获取signal信号量,他的作用是让controller对象和请求相关联,然后通过

controller.abort()来中断请求的发送。


const controller = new AbortController();
    const signal = controller.signal;
    abortBtn.addEventListener('click', function() {
      // 取消发送
      controller.abort();
    });
  // 在配置中传入signal
  fetch(url, {signal}).then(function(response) {
  })


并且axios的 v0.22.0 开始支持该api。具体请查看github


const controller = new AbortController();
    axios.get('/foo/bar', {
       signal: controller.signal
    }).then(function(response) {
       //...
    });
    // cancel the request
    controller.abort()


相关文章
|
11月前
|
前端开发
牛客刷题Day3
牛客刷题Day3
63 0
|
11月前
|
XML JSON JavaScript
|
11月前
|
移动开发 前端开发 JavaScript
牛客刷题Day4
牛客刷题Day4
69 0
|
11月前
|
JavaScript 前端开发
牛客刷题Day3(三)
牛客刷题Day3(三)
65 0
牛客刷题
牛客刷题
70 0
牛客刷题(buhui/(ㄒoㄒ)/~~)
牛客刷题(buhui/(ㄒoㄒ)/~~)
牛客刷题(buhui/(ㄒoㄒ)/~~)
|
存储 消息中间件 设计模式
牛客面经每日一总结(五)
牛客面经每日一总结(五)
|
存储 缓存 前端开发
牛客面经每日一总结(三)
牛客面经每日一总结(三)
|
存储 移动开发 JSON
牛客面经每日一总结(六)
牛客面经每日一总结(六)