一些总结记录
- jwt(json web token)
三个组成部分
header
:是一个json对象,描述jwt的元数据,包括使用的算法
payload
:也是一个 JSON 对象,用来存放实际需要传递的数据。
signature
:对前两部分的签名,防止数据篡改。
特点
:
- json具有通用性,可以跨语言
- 服务器不保存状态,压力较小
- 为了减少盗用可以把有效时间设置得更短(因为jwt一旦签发,token便会一直有效)。
- 一处生成多处使用,可以实现单点登陆
- 应使用https传输
- 如何处理大量数据
如果是进行页面渲染之类(操作dom)
的,可以分批量操作并配合createDocumentFragment处理。同时使用requestAnimationFrame
来控制,(减少页面卡顿)
如果是处理其他数据或任务
:可以开启一个web worker来进行执行。
其实是开启一个后续线程进行单独的其他处理如计算等。
- 如何设置local Storage过期
封装一个键值的映射,称为键 => 存活时间映射表。
存储的时候传入一个时间
取的时候进行判断,过期则移除。
- 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
}
- 如何监控内存泄漏
Performance(时间轴)能够面板直观实时显示JS内存使用情况、节点数量、监听器数量等。
打开 chrome 浏览器,调出调试面板(DevTools),点击Performance选项(低版本是Timeline),勾选Memory复选框。一种比较好的做法是使用强制垃圾回收开始和结束记录。在记录时点击 Collect garbage 按钮 (强制垃圾回收按钮) 可以强制进行垃圾回收。所以录制顺序可以这样:开始录制前先点击垃圾回收–>点击开始录制–>点击垃圾回收–>点击结束录制。面板介绍如图:
首先,从图中我们可以看出不同颜色的曲线代表的含义,这里主要关注JS堆内存、节点数量、监听器数量。鼠标移到曲线上,可以在左下角显示具体数据。在实际使用过程中,如果您看到这种 JS 堆大小或节点大小不断增大的模式,则可能存在内存泄漏。
来源:https://blog.csdn.net/weixin_45658814/article/details/108101444
- 将图片转Base64格式来节约请求
当我们的一个页面中要传入很多图片时,特别是一些比较小的图片,十几K、几K,这些小图标都会增加HTTP请求。比如要下载一些一两K大的小图标,其实请求时带上的额外信息有可能比图标的大小还要大。
Base64
:就是一种基于64个可打印字符来表示二进制数据的表示方法。
原理
:图片的本质就是每个像素点都是一个数字,该数字表示颜色,然后把很多很多像素点的数字拼到一起,就是图像。图像转Base64,就是把图像的直方图所有数字转成Base64编码,反之,Base64也能转换回图像。
(base64编码详解)[https://zhuanlan.zhihu.com/p/339477329]
- 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
包含在其中。
- 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)
}
- 聊一聊前端新技术 low-code平台
低代码平台本身也是一个软件,但是它是提供了一个可以直接创建软件的开发环境,类似图形化界面,拖拽完成。
1. 全栈可视化编程,就是类似可以直接拖拽点击进行配置应用。
2. 全面的生命周期管理
3. 很强的扩展能力
包括可以提高应用开发能力,甚至很多非专业人员也能参与开发。同时也可以减少专业人员的不必要的工作量
比如Saltcorn、Joget DX等
- 说下如何实现一个登录功能
掘金收藏:项目思想
Cookie + Session 历史悠久,适合于简单的后端架构,需开发人员自己处理好安全问题。
Token 方案对后端压力小,适合大型分布式的后端架构,但已分发出去的 token ,如果想收回权限,就不是很方便了。
SSO 单点登录,适用于中大型企业,想要统一内部所有产品的登录方式。
OAuth 第三方登录,简单易用,对用户和开发者都友好,但第三方平台很多,需要选择合适自己的第三方登录平台。
- 聊一聊nodejs
node.js是一个基于Chrome V8
引擎的 JavaScript
运行时环境。
特点:
1. 非阻塞、异步的I/O
2. 事件和回调函数
3. 单线程(主线程单线程,后台I/O线程池)
4. 跨平台
- 如何理解http的无状态
即是对于同一个客户,第一次和第二次访问服务器的页面时,服务器的响应与第一次被访问时的相同,因为服务器并不记得这个客户,也不记得对这个客户服务过多少次。
优点:这样的无状态也简化了服务器的设计,更容易支持大并发的http请求。
缺点:http的无状态导致得每一次发送请求都需要携带请求头,去过请求头字段过大会造成很多性能上的损耗。在http2.0中就是使用了头部压缩,一方面就是为了解决这个问题。
- 链表和数组的区别
首先讲js数组和其他语言数组的差别(可以不同数据类型,可以添加删除,可以像栈和队列一样使用等)。
就维基百科的定义而言,数组是由相同类型的元素的集合组成的数据结构,在内存地址中拥有一块连续的空间来进行存储。
就js而言,数组并不像其他的语言,它的长度和元素类型以及大小都是不固定的,还可以动态的改变元素的内容,所以其在内存中的位置也不一定连续。
其本质是一个对象,而key值为0,1索引。长度是可变的,可以根据元素的增加和删除来动态调整存储空间大小,内部会根据删除增加动态的扩容和收缩,即是长度可变。
探究JS V8引擎下的“数组”底层实现 - 知乎 (zhihu.com) (opens new window)
链表在地址中的存储空间是不连续的
区别
时间复杂度 | 数组 | 链表 |
---|---|---|
添加 | O(n) | O(1) |
删除 | O(n) | O(1) |
随机访问 | O(1) | O(n) |
为什么后端能控制路由还需要前端来做路由?
- 配置复杂,每一次若是前端增加一个页面还需要后端配置路由和权限。
- 前后端路由的区别,比如后端是偏向业务的。比如管理员可以删除,普通用户只能查看。对于前端来说,所有的用户是都可以进入到同一个页面的,但主要区别也许只是在一个按钮上。
Proxy使用场景
MDN: Proxy 对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)。
可以拦截、监视外部对对象的访问和操作,甚至可以统计对象的访问次数。比如set的时候可以进行数据的校验,get的时候可以适当的隐藏属性。
- SSL和TLS的区别
SSL是早于TLS诞生的运输层安全协议,作用在端系统应用层的HTTP和运输层之间。TLS是基于SSL3.0设计的。
- webpack配置多打包入口?
多主页面
:传入配置项为一个数组到entry配置
多页面
通过CommonsChunkPlugin
为每个页面间的应用程序共享代码创建 bundle。
const config = {
entry: {
pageOne: './src/pageOne/index.js',
pageTwo: './src/pageTwo/index.js',
pageThree: './src/pageThree/index.js'
}
};
- 路由懒加载原理
这是由于异步组件
和webpack
的代码分割
功能,每个异步路由会打包成不同的块,实现按需加载
- 强缓存状态码
200
- https为什么安全?
因为SSL/TLS提供了三种安全保证
1. 服务器鉴别,允许用户核实服务器的身份。
2. 客户鉴别,服务器可以鉴别客户身份。
3. 加密的会话,对客户、服务器间发送的报文加密,并检测是否被篡改。
- CDN(Content Delivery Network)
内容分发网络。简单来说,CDN
就是根据用户位置分配最近的资源。使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。降低了传输时延,实现网站加速。
举例:在网上购物时候,商城不会全部都将商品从总部仓库发送,它会找一个离你最近的一个拥有该商品的分仓库发送货品。
CDN原理分析
未使用CDN时候
:用户提交域名→浏览器对域名进行解释→DNS
解析得到目的主机的IP地址→根据IP地址访问发出请求→得到请求数据并回复
使用CDN时
:DNS解析返回一个CNAME
指向的CDN专用DNS服务器,并返回全局负载均衡设备的ip地址,再次请求则进入全局负载均衡系统进行智能调度:
- 看用户的 IP 地址,查表得知地理位置,找相对最近的边缘节点
- 看用户所在的运营商网络,找相同网络的边缘节点
- 检查边缘节点的负载情况,找负载较轻的节点并返回
- 其他,比如节点的“健康状况”、服务能力、带宽、响应时间等
最终返回对应的节点ip,用户再次请求得到资源。
缓存代理
:缓存系统会有选择地缓存那些最常用的那些资源。
当缓存命中时候直接返回缓存,否则回源(向它的上一级服务器索要,一直到得到为止)。
负载均衡算法
:负载均衡就是由多个服务器组成的集群,每台服务器都有等价的地位,都可以单独对外提供服务而不靠其他服务器的辅助。而常用的负载均衡算法有 随机算法
,加权轮询
,一致性hash
等。
- 大文件的上传下载、网络传输
网络传输大文件
:
开启Gzip压缩
:例如nodejs。用户请求时候会携带accept-encoding请求头,比如有gizp
、br
(专门为HTML设计的压缩算法)等可选值。后端便可以使用(如zlib)压缩文件传输。范围请求
:服务器返回的accept-ranges:非none
即是接受范围请求。
大文件上传
:小文件直接使用formData对象包裹走人。
核心便是利用Blob.slice方法(File是Blob的子类)。这样便可以将大文件切片然后同时并行上传多个切片,减少上传输时间。
根据设置切片的大小(每一片的大小),使用slice方法切片
Blob.prototype.slice(start,start + size)
将其添加到一个数组里
循环,并将每一个值都封装在
formData
中(如同小文件上传)发送数据即可
大文件断点续传
:比如传一部分之后,发生错误。那么需要重新上传,且不会重新传。只需保存已经上传的切片
- 前端将数据保存在localStorage中。
缺点是
用户可能清除数据或者切换浏览器等 - 服务器记录已经上传的切片
- 规划
短期:1年内,进入公司,接触到开发流程,需求->开发->测试,熟悉技术栈 中期:1-3年,从保住饭碗到熟练工的过程,熟悉业务,个人有承担模块搭建流程,决定开发方向的能力 长期:3-5年,专注于感兴趣的方向,深耕行业中某一细化分支的业务逻辑,比如富文本,echart等,成为这一领域的专家
- 如何控制判断 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);
});
- 为什么css引用放在前面,js引用放在后面?
首先是因为css是使用href
进行加载,它指向目标资源的位置,不会阻塞后续代码的执行。同时可以使得解析css样式和html文档并行执行。如果放在后面,且dom中有行内样式,那么在之前执行完之后dom已经显示及行内样式已经解析,又会变化一个样式,体验不好。
其次是因为js的加载会阻塞后续代码的执行,如果文件过大还会造成白屏等不好的影响。
- attribute 和 property 的区别?
(前端杂谈: Attribute VS Property)[https://zhuanlan.zhihu.com/p/49536969]