一些总结记录

4/12/2022
  1. jwt(json web token)

三个组成部分

header:是一个json对象,描述jwt的元数据,包括使用的算法

payload:也是一个 JSON 对象,用来存放实际需要传递的数据。

signature:对前两部分的签名,防止数据篡改。

特点

  • json具有通用性,可以跨语言
  • 服务器不保存状态,压力较小
  • 为了减少盗用可以把有效时间设置得更短(因为jwt一旦签发,token便会一直有效)。
  • 一处生成多处使用,可以实现单点登陆
  • 应使用https传输
  1. 如何处理大量数据

如果是进行页面渲染之类(操作dom)的,可以分批量操作并配合createDocumentFragment处理。同时使用requestAnimationFrame来控制,(减少页面卡顿)

如果是处理其他数据或任务:可以开启一个web worker来进行执行。

其实是开启一个后续线程进行单独的其他处理如计算等。

  1. 如何设置local Storage过期

封装一个键值的映射,称为键 => 存活时间映射表。

存储的时候传入一个时间

取的时候进行判断,过期则移除。

  1. sqrt方法的实现

使用二分查找法,从中间开始找,并且设置一个误差范围。

const sqrt = (number) => {
  if (number < 0) return Error('不能有负数!')
  let min = 0,
    max = number
  let ans = (min + max) / 2
  let p = ans ** 2
  while (Math.abs(p - number) > 0.01) {
    if (p > number) {const sqrt = (number) => {
  if (number < 0) return Error('不能有负数!')
  let min = 0,
    max = number
  let ans = (min + max) / 2
  let p = ans ** 2
  while (Math.abs(p - number) > 0.01) {
    if (p > number) {
      max = ans
    } else {
      min = ans
    }
    ans = (max + min) / 2
    p = ans ** 2
  }
  return ans
}
      max = ans
    } else {
      min = ans
    }
    ans = (max + min) / 2
    p = ans ** 2
  }
  return ans
}
  1. 如何监控内存泄漏

Performance(时间轴)能够面板直观实时显示JS内存使用情况、节点数量、监听器数量等。 打开 chrome 浏览器,调出调试面板(DevTools),点击Performance选项(低版本是Timeline),勾选Memory复选框。一种比较好的做法是使用强制垃圾回收开始和结束记录。在记录时点击 Collect garbage 按钮 (强制垃圾回收按钮) 可以强制进行垃圾回收。所以录制顺序可以这样:开始录制前先点击垃圾回收–>点击开始录制–>点击垃圾回收–>点击结束录制。面板介绍如图: 首先,从图中我们可以看出不同颜色的曲线代表的含义,这里主要关注JS堆内存、节点数量、监听器数量。鼠标移到曲线上,可以在左下角显示具体数据。在实际使用过程中,如果您看到这种 JS 堆大小或节点大小不断增大的模式,则可能存在内存泄漏。

来源:https://blog.csdn.net/weixin_45658814/article/details/108101444

  1. 将图片转Base64格式来节约请求

当我们的一个页面中要传入很多图片时,特别是一些比较小的图片,十几K、几K,这些小图标都会增加HTTP请求。比如要下载一些一两K大的小图标,其实请求时带上的额外信息有可能比图标的大小还要大。

Base64:就是一种基于64个可打印字符来表示二进制数据的表示方法。

原理:图片的本质就是每个像素点都是一个数字,该数字表示颜色,然后把很多很多像素点的数字拼到一起,就是图像。图像转Base64,就是把图像的直方图所有数字转成Base64编码,反之,Base64也能转换回图像。

(base64编码详解)[https://zhuanlan.zhihu.com/p/339477329]

  1. CORS(跨域资源共享)

解释:是一种基于HTTP头的机制,该机制通过允许服务器标示除了它自己以外的其它Origin(域,协议和端口),这样浏览器可以访问加载这些资源。此外对于可能对服务器数据造成副作用的 HTTP 请求方法,还需要进行预检请求,我们将这样的请求称作复杂请求,其余的请求称作简单请求

简单请求

1. 使用`get`、`head`、`post`方法
2. 只使用了以下首部字段:`connection`、`user-agent`、`accept`、`accept-language`、`content-type`、`content-language`等

跨源资源共享标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源。若是使用的非简单请求,通常会先发送一个预检请求。

CORS预检请求:用于检查服务器是否支持CORS即跨域资源共享。可以避免跨域请求对服务器的用户数据产生未预期的影响。

当有必要的时候,浏览器会自动发出一个预检请求。

比如:一个客户端可能会在实际发送一个 DELETE 请求之前,先向服务器发起一个options预检请求,用于询问是否可以向服务器发起一个DELETE 请求。

如果允许那么服务器就会响应这个预检请求。并且其响应首部 Access-Control-Allow-Methods 会将DELETE包含在其中。

  1. ajax的封装,原理
const ajax = function (method, url, params, callback) {
    // 方法转换成大写
    method = method.toUpperCase()
    const req = new XMLHttpRequest()
    let query = []
    for (let key in params) {
        query.push(key + '=' + params[key])
    }
    if (method === 'GET') {
        url += '?' + query.join('&')
        params = ''
    }
    req.open(method, url)
    if (method === 'POST') {
        // 需要请求头
        req.setRequestHeader(
            'Content-Type',
            'application/x-www-form-urlencoded'
        )
        params = query.join('&')
    }
    req.onreadystatechange = function () {
        if (this.readyState === 4) {
            // 返回的应该是一个对象,这样客户端更好渲染
            callback(JSON.parse(req.responseText))
        }
    }
    console.log(url)
    console.log(params)
    // post请求中参数是以 name=tqt&age=18 发送的
    // get请求是直接在url中携带
    req.send(params)
}
  1. 聊一聊前端新技术 low-code平台

低代码平台本身也是一个软件,但是它是提供了一个可以直接创建软件的开发环境,类似图形化界面,拖拽完成。

1. 全栈可视化编程,就是类似可以直接拖拽点击进行配置应用。
2. 全面的生命周期管理
3. 很强的扩展能力

包括可以提高应用开发能力,甚至很多非专业人员也能参与开发。同时也可以减少专业人员的不必要的工作量

比如Saltcorn、Joget DX等

  1. 说下如何实现一个登录功能

掘金收藏:项目思想

Cookie + Session 历史悠久,适合于简单的后端架构,需开发人员自己处理好安全问题。

Token 方案对后端压力小,适合大型分布式的后端架构,但已分发出去的 token ,如果想收回权限,就不是很方便了。

SSO 单点登录,适用于中大型企业,想要统一内部所有产品的登录方式。

OAuth 第三方登录,简单易用,对用户和开发者都友好,但第三方平台很多,需要选择合适自己的第三方登录平台。

  1. 聊一聊nodejs

node.js是一个基于Chrome V8 引擎的 JavaScript 运行时环境。

特点:

1. 非阻塞、异步的I/O
2. 事件和回调函数
3. 单线程(主线程单线程,后台I/O线程池)
4. 跨平台
  1. 如何理解http的无状态

即是对于同一个客户,第一次和第二次访问服务器的页面时,服务器的响应与第一次被访问时的相同,因为服务器并不记得这个客户,也不记得对这个客户服务过多少次。

优点:这样的无状态也简化了服务器的设计,更容易支持大并发的http请求。

缺点:http的无状态导致得每一次发送请求都需要携带请求头,去过请求头字段过大会造成很多性能上的损耗。在http2.0中就是使用了头部压缩,一方面就是为了解决这个问题。

  1. 链表和数组的区别

首先讲js数组和其他语言数组的差别(可以不同数据类型,可以添加删除,可以像栈和队列一样使用等)。

就维基百科的定义而言,数组是由相同类型的元素的集合组成的数据结构,在内存地址中拥有一块连续的空间来进行存储。

就js而言,数组并不像其他的语言,它的长度和元素类型以及大小都是不固定的,还可以动态的改变元素的内容,所以其在内存中的位置也不一定连续。

其本质是一个对象,而key值为0,1索引。长度是可变的,可以根据元素的增加和删除来动态调整存储空间大小,内部会根据删除增加动态的扩容和收缩,即是长度可变。

探究JS V8引擎下的“数组”底层实现 - 知乎 (zhihu.com) (opens new window)

链表在地址中的存储空间是不连续的

区别

时间复杂度 数组 链表
添加 O(n) O(1)
删除 O(n) O(1)
随机访问 O(1) O(n)
  1. 为什么后端能控制路由还需要前端来做路由?

    1. 配置复杂,每一次若是前端增加一个页面还需要后端配置路由和权限。
    2. 前后端路由的区别,比如后端是偏向业务的。比如管理员可以删除,普通用户只能查看。对于前端来说,所有的用户是都可以进入到同一个页面的,但主要区别也许只是在一个按钮上。
  2. Proxy使用场景

MDN: Proxy 对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)。

可以拦截、监视外部对对象的访问和操作,甚至可以统计对象的访问次数。比如set的时候可以进行数据的校验,get的时候可以适当的隐藏属性。

  1. SSL和TLS的区别

SSL是早于TLS诞生的运输层安全协议,作用在端系统应用层的HTTP和运输层之间。TLS是基于SSL3.0设计的。

  1. webpack配置多打包入口?

多主页面:传入配置项为一个数组到entry配置

多页面

通过CommonsChunkPlugin 为每个页面间的应用程序共享代码创建 bundle。

const config = {
  entry: {
    pageOne: './src/pageOne/index.js',
    pageTwo: './src/pageTwo/index.js',
    pageThree: './src/pageThree/index.js'
  }
};
  1. 路由懒加载原理

这是由于异步组件webpack代码分割功能,每个异步路由会打包成不同的块,实现按需加载

  1. 强缓存状态码

200

  1. https为什么安全?

因为SSL/TLS提供了三种安全保证

1. 服务器鉴别,允许用户核实服务器的身份。
2. 客户鉴别,服务器可以鉴别客户身份。
3. 加密的会话,对客户、服务器间发送的报文加密,并检测是否被篡改。
  1. CDN(Content Delivery Network)

内容分发网络。简单来说,CDN就是根据用户位置分配最近的资源。使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。降低了传输时延,实现网站加速。

举例:在网上购物时候,商城不会全部都将商品从总部仓库发送,它会找一个离你最近的一个拥有该商品的分仓库发送货品。

CDN原理分析

未使用CDN时候:用户提交域名→浏览器对域名进行解释→DNS 解析得到目的主机的IP地址→根据IP地址访问发出请求→得到请求数据并回复

使用CDN时:DNS解析返回一个CNAME指向的CDN专用DNS服务器,并返回全局负载均衡设备的ip地址,再次请求则进入全局负载均衡系统进行智能调度:

  • 看用户的 IP 地址,查表得知地理位置,找相对最近的边缘节点
  • 看用户所在的运营商网络,找相同网络的边缘节点
  • 检查边缘节点的负载情况,找负载较轻的节点并返回
  • 其他,比如节点的“健康状况”、服务能力、带宽、响应时间等

最终返回对应的节点ip,用户再次请求得到资源。

缓存代理:缓存系统会有选择地缓存那些最常用的那些资源。

当缓存命中时候直接返回缓存,否则回源(向它的上一级服务器索要,一直到得到为止)。

负载均衡算法:负载均衡就是由多个服务器组成的集群,每台服务器都有等价的地位,都可以单独对外提供服务而不靠其他服务器的辅助。而常用的负载均衡算法有 随机算法加权轮询一致性hash等。

  1. 大文件的上传下载、网络传输

网络传输大文件

  • 开启Gzip压缩:例如nodejs。用户请求时候会携带accept-encoding请求头,比如有gizpbr(专门为HTML设计的压缩算法)等可选值。后端便可以使用(如zlib)压缩文件传输。
  • 范围请求:服务器返回的accept-ranges:非none即是接受范围请求。

大文件上传:小文件直接使用formData对象包裹走人。

核心便是利用Blob.slice方法(File是Blob的子类)。这样便可以将大文件切片然后同时并行上传多个切片,减少上传输时间。

  • 根据设置切片的大小(每一片的大小),使用slice方法切片

    Blob.prototype.slice(start,start + size)

  • 将其添加到一个数组里

  • 循环,并将每一个值都封装在formData中(如同小文件上传)

  • 发送数据即可

大文件断点续传:比如传一部分之后,发生错误。那么需要重新上传,且不会重新传。只需保存已经上传的切片

  • 前端将数据保存在localStorage中。缺点是用户可能清除数据或者切换浏览器等
  • 服务器记录已经上传的切片
  1. 规划

短期:1年内,进入公司,接触到开发流程,需求->开发->测试,熟悉技术栈 中期:1-3年,从保住饭碗到熟练工的过程,熟悉业务,个人有承担模块搭建流程,决定开发方向的能力 长期:3-5年,专注于感兴趣的方向,深耕行业中某一细化分支的业务逻辑,比如富文本,echart等,成为这一领域的专家

  1. 如何控制判断 Promise 超时

使用 Promise.race 来进行控制。

// 假设它是我们需要进行的请求
let successCb = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("成功!");
  }, 2000);
});
// 这是我们需要进行判断的时长的错误请求
let failedCb = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject("失败!");
  }, 1000);
});
// 我们可以判断,如果当前返回的是错误的请求,代表另外的请求已经超时
Promise.race([failedCb, successCb])
  .then((res) => {
    console.log(res);
  })
  .catch((e) => {
    console.log(e);
  });

  1. 为什么css引用放在前面,js引用放在后面?

首先是因为css是使用href进行加载,它指向目标资源的位置,不会阻塞后续代码的执行。同时可以使得解析css样式和html文档并行执行。如果放在后面,且dom中有行内样式,那么在之前执行完之后dom已经显示及行内样式已经解析,又会变化一个样式,体验不好。

其次是因为js的加载会阻塞后续代码的执行,如果文件过大还会造成白屏等不好的影响。

  1. attribute 和 property 的区别?

(前端杂谈: Attribute VS Property)[https://zhuanlan.zhihu.com/p/49536969]