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

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抛出的异常。 以上两种方式是可以捕获的。

其实我们捕获异步异常,一般都是在异步函数中捕获,这样我们就可以直接使用try catch,如果不在异步函数中,我们就直接将异步写在promise使用catch进行捕获。

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

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

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

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

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

  • ~当catch和then方法都抛出异常,那么他只会捕获catch抛出的异常。 ~ 他是根据代码执行顺序进行捕获的。

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

为什么0.1+0.2=0.30000000000000004

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

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

如何解决这个问题[1]

原生的解决方法

  • 通过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) 

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

    let a = 0.1 + 0.2; 

    a = Math.round (a * 10); 
    a = a / 10; 
    console.log (a); 

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

    parseFloat(1.000) 

    parseFloat(1.030) 

伪类选择器

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

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

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

      <style>
        
        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等等。

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

    
      instance.interceptors.request.use(config => {
        
        
        
        
        
        return config;
      },err => {
        
      })

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

      
      instance.interceptors.response.use(res => {
        
        return res.data;
      },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[2] 他是一个类,通过创建对象获取signal信号量,他的作用是让controller对象和请求相关联,然后通过controller.abort()来中断请求的发送。

    const controller = new AbortController();
    const signal = controller.signal;
    abortBtn.addEventListener('click', function() {
      
      controller.abort();
    });

  
  fetch(url, {signal}).then(function(response) {
  
  })

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

    const controller = new AbortController();

    axios.get('/foo/bar', {
       signal: controller.signal
    }).then(function(response) {
       
    });
    
    controller.abort()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Web面试那些事儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值