前端-网络

77 阅读3分钟

知识图框架

二叉树,每次面试前针对性防御,边界内无法攻破边界外尽量拓展。

不要说没用过不了解之类的话

前端周边领域:性能优化、devops、运维、监控、debug

你在使用vue遇到的什么坑?(画图,场景)项目有什么难点?

网络

请求:文件、数据、连接

文件:加载html模板

数据:AJAX请求,基于http请求,再往下tcp,再细点关于连接

连接:socket长连接,beacon浏览器关闭时可以保持连接,HTTP也可以建立长连接只有不返回

应用:微信扫二维码,1、轮询 2、websocket建立长连接 3、HTTP长连接,手机扫码后返回

协议

面试1:HTTP && TCP?=》协议拆分和解释 =》 举例子

2024-03-28-11-45-14-image.png

追问:HTTP版本有哪些?

1、1.0 1.1 2.0

2、1.0 => 1.1 引入长连接(标识位:keep-alive) (但是浏览器限制最多并发六个请求)=> 减少建立和关闭的损耗,避免轮询(每次tcp三次握手)

1.1 => 2.0 二进制,多路复用,包头压缩,服务端推送

相同点:基于TCP进行底层协议的传输通信应用层协议

追问:不同HTTP版本,对于TCP的建立有何不同?

1.1保持一个TCP连接一直生效

2.0多条并发, 同时复用一条通路, 无并发限制

面试2:HTTP && HTTPS

1、https = http + ssl(tls)

2、基本原理

2024-03-28-23-37-12-image.png

追问:性能对比

https更安全稳定,但建立上性能损耗更大

优化? => 整合请求,使用长连接

回调方面

AJAX1 AJAX2 AJAX3

代码书写:回调 => 回调地狱 => promise => async await

network:(瀑布)等待 阻塞

面试3:请求总是数据很大? => 将返回内容压缩(例如从服务端返回的图片)

请求头上的Accept-Encoding 期望返回内容压缩 => 减少网络流量,提升性能(base64码很大)

gzip defalte br

追问:请求带上头 并明确压缩方式了为什么图片没压缩?

a.请求头是要求非强制,服务端不支持压缩\开启压缩\第三方api

b. 支持压缩也开启压缩了,响应头就具有了Content-Encoding:gzip

横向面试方向

  1. 请求头 Cookie => 对比存储 localstorage sessionstorage(大小 性能 跨域cookie传递不安全 有效时间 支持监听storage可以 localstorage跨tab\cookie同源 登录态 )

  2. 业务场景 登录态以及自动登录,特别是小程序sessionkey换取token

  3. 重定向 性能优化场景-强缓存 协商缓存 (数据性项目)(有图片的项目)\

  4. 请求控制 => 比如双十一并发请求过大会造成后台压力巨大

    **手写并发控制 -QPS

    //分析:并发优化10个请求,由于后台限制或者业务需求最多只能同时进行n个
    //输入:max参数
    //输出:已经被控制了的promise
    //存储:队列 - request pool => 并发池子
    //思路:插入 + 执行
    
    class LimitPromise{
       constructor(max){    
            //异步任务的并发上限
           this._max = max || 6
            //当前正在执行任务的数量
            this._count = 0
            //等待任务队列 
            this._taskQueue = []
            //实例,单例模式
            this.instance = null
        }
       //主入口
        //输入:外部添加的请求
        //输出:返回队列处理的promise
        run(caller){
            return new Promise((resolve, reject) => {
            //创建处理任务 
            const task = this._createTask(caller, resolve, reject)
            //判断是否达到上限
            if(this._count >= this._max){
               this._taskQueue.push(task)
            }else{
               task()
            }
           }  
        }
    
        _creatTask(caller, resolve, reject){
           return () => {
                caller().then(res => {
                    resolve(res)
                 }).catch(err => {
                    reject(err)
                 }).finally(() => {
                    this._count--
                     if(this._taskQueue.length > 0){
                       const task = this._taskQueue.shift()
                        task()
                     }
                 })
                 this._count++   
            }
        }
        
        static getInstance(max){
           if(!this.instance)
                this.instance = new LimitPromise(max)
            return this.instance
        }
    }
    

2024-03-29-21-38-01-image.png