前端面试灵魂提问-计网(2)
1、websocket 为什么全双工?
1.1 WebSocket是什么
WebSocket 是一种通信协议,它在客户端和服务器之间建立持久的全双工连接。全双工意味着数据可以双向流动,即客户端可以向服务器发送消息,服务器也可以向客户端发送消息,而无需客户端或服务器先发起请求。
这种全双工的设计有几个优点:
-
实时性: 全双工通信允许双方实时地发送和接收数据,这对于实时性要求高的应用场景非常重要,比如在线聊天、在线游戏等。
-
减少延迟: 与传统的基于请求-响应模式的通信相比,WebSocket 的全双工通信减少了请求和响应之间的延迟。服务器和客户端可以直接推送消息而无需等待请求。
-
减少网络流量: 相较于轮询等方式,WebSocket 采用了更为高效的通信方式,可以减少不必要的数据传输,降低网络流量。
-
资源效率: WebSocket 连接是持久的,不需要频繁地断开和重新建立连接。这减少了在每次通信中都要建立连接的开销,提高了资源的利用效率。
WebSocket 是建立在 TCP 连接之上的,通过握手等机制,可以在客户端和服务器之间建立一个长期有效的连接,实现双方的实时数据传输。
1.2 WebSocket如何实现全双工
WebSocket 通过协议的握手过程、保持连接的机制以及数据帧的使用,实现了全双工通信。在前端开发中,通常会使用 WebSocket API 来处理 WebSocket 连接,而后端服务器也需要支持 WebSocket 协议。
-
握手过程: WebSocket 连接是通过 HTTP 协议进行握手的。客户端发送一个 HTTP 请求,包含一个包含 WebSocket 版本信息的特殊头部字段,表明希望升级为 WebSocket 连接。这个头部字段是
Upgrade
,并且携带的值是websocket
。此外,还有一个Connection
头部字段,它的值也是Upgrade
。服务器在接收到这个请求后,如果同意升级为 WebSocket 连接,就会返回一个包含一些信息的 HTTP 响应,然后连接就升级为 WebSocket。如果不同意升级为 WebSocket 连接,它会返回一个包含适当状态码的 HTTP 响应,状态码 400 Bad Request 或 403 Forbidden 会被使用,并在Connection
头部字段中保持为Upgrade
。客户端的 WebSocket 对象会触发close
事件。 -
保持连接: 握手成功后,WebSocket 连接就变成了全双工的,可以在连接保持的情况下双向传输数据。这与传统的 HTTP 请求-响应模型不同,WebSocket 连接是持久的,不需要在每次通信时都重新建立连接。
-
数据帧: WebSocket 使用数据帧来在客户端和服务器之间传递信息。数据帧是 WebSocket 协议中的最小数据单位,可以包含文本、二进制数据等。每个数据帧都有一个标志位,用于指示这个帧是一个消息的开始、结束,还是中间的一部分。
-
双向通信: 一旦 WebSocket 连接建立起来,双方可以通过发送数据帧实现双向通信。无论是客户端还是服务器,都可以随时发送消息给对方,而不需要等待对方的请求。这使得实时的、双向的通信成为可能。
1.3 前端开发使用 WebSocket API
1、创建 WebSocket 对象: 使用 new WebSocket(url)
来创建一个 WebSocket 对象,其中 url
是 WebSocket 服务器的地址。例如
const socket = new WebSocket('ws://example.com/socket');
2、定义事件处理程序: WebSocket 对象支持一系列事件,包括 open
、message
、error
和 close
。你可以通过定义相应的事件处理程序来处理这些事件。
socket.addEventListener('open', (event) => {console.log('WebSocket连接已打开');
});socket.addEventListener('message', (event) => {console.log('接收到消息:', event.data);
});socket.addEventListener('error', (event) => {console.error('WebSocket发生错误:', event);
});socket.addEventListener('close', (event) => {console.log('WebSocket连接已关闭:', event);
});
3、发送和接收消息: 使用 send
方法向服务器发送消息,通过监听 message
事件来接收服务器发送的消息。
// 发送消息
socket.send('Hello, server!');// 接收消息已在上述的 'message' 事件处理程序中演示
发送二进制文件
// 监听连接打开事件
socket.addEventListener('open', (event) => {console.log('WebSocket 连接已打开');// 创建一个 ArrayBuffer 对象const buffer = new ArrayBuffer(16);// 使用 DataView 将数据写入 ArrayBufferconst view = new DataView(buffer);view.setInt32(0, 42);// 发送二进制数据socket.send(buffer);
});
4、关闭连接: 使用 close
方法关闭 WebSocket 连接。
// 关闭连接
socket.close();
2、 websockt同时发数据,如何保证收到的数据是当前的
在 WebSocket 中,发送多条消息并确保它们按照特定的顺序到达是一个常见的需求。WebSocket 的全双工性质允许你同时发送多条消息,但它们的顺序在接收端可能不一定按照发送的顺序到达,因为消息的发送和接收是异步的。
消息附加序列号: 在每条消息中附加一个唯一的序列号,接收端在收到消息时根据序列号对消息进行排序。在实际应用中,可以在消息中附加时间戳或序列号,以便于接收端正确排序。
let sequenceNumber = 0;function sendMessage(message) {const messageWithSequence = {sequence: sequenceNumber++,content: message};socket.send(JSON.stringify(messageWithSequence));
}
3、webscoket 和keep-alive的区别,有了 HTTP 的keep-alive为什么还要websocket
在网页加载资源时可以使用 Keep-Alive
提高效率,而在需要实时通信的功能上使用 WebSocket 提供更好的用户体验。
HTTP 协议中使用 Content-Length
头部或者 Transfer-Encoding: chunked
头部来指示消息主体的长度或者以分块方式传输。当服务器端通过这些方式告知消息的结束时,客户端就能够识别出一个请求已经结束。
WebSocket 在协议层面已经提供了消息的边界,服务器和客户端能够准确判断消息的开始和结束。
TCP 的 Keep-Alive 是在 TCP 协议层面实现的,用于检测连接是否仍然活跃。
3.1 相同点:建立持久连接
-
Keep-Alive:
-
目的: HTTP
Keep-Alive
是一种机制,用于在单个 TCP 连接上重用多个 HTTP 请求和响应,以减少连接的建立和关闭的开销。 -
工作原理: 默认情况下,每个 HTTP 请求都会创建一个新的 TCP 连接,然后在响应完成后关闭连接。使用
Keep-Alive
,可以在同一连接上发送多个请求和接收多个响应,而不必为每个请求重新建立连接。 -
适用场景: 主要用于提高 HTTP 请求的效率,减少资源消耗,特别是在需要多次请求的情况下,如加载网页上的多个资源文件。
-
-
WebSocket:
-
目的: WebSocket 是一种全双工通信协议,旨在提供实时、双向的通信能力,适用于需要低延迟、高实时性的应用场景。
-
工作原理: WebSocket 通过单个 TCP 连接实现全双工通信,连接建立后保持打开状态,允许服务器和客户端在任何时候都能发送和接收数据。
-
适用场景: 主要用于实时通信,例如在线聊天、实时协作、在线游戏等场景。相较于 HTTP,WebSocket 更适合处理频繁的双向通信需求
-
3.2 区别
-
性能: WebSocket 在处理实时通信时更为高效,因为它是一个持久连接,而且不需要在每次通信时重新建立连接。相比之下,
Keep-Alive
只是在短时间内重用连接,但仍需要在每次通信时发起新的请求。 -
推送通知: WebSocket 更适用于服务器主动向客户端推送消息的场景,而
Keep-Alive
更适用于客户端主动向服务器发起请求的场景。 -
实时性: WebSocket 提供更低延迟和更高的实时性,适用于需要及时传递信息的应用。
Keep-Alive
可以减少连接建立和关闭的开销,但无法提供实时的双向通信。
4、 以下是 TCP 使用的一些机制来减少丢包的可能性:
-
序号和确认: TCP 在每个数据包上都附加一个序号,接收方在收到数据包后会发送一个确认,表明它已经成功接收了该数据包。如果发送方在一定时间内未收到确认,它会重新发送相同的数据包,确保数据的正确到达。
-
重传机制: 如果发送方在合理的时间内未收到确认,它会假定数据包丢失,并进行重传。这确保了即使某个数据包在传输过程中丢失,它仍然有机会重新发送。
-
流量控制: TCP 使用滑动窗口机制来进行流量控制,确保发送方不会发送过多的数据导致接收方无法处理。如果接收方的缓冲区已满,它可以通知发送方减缓发送速度,从而减少数据包的丢失可能性。
-
拥塞控制: TCP 使用拥塞控制算法来避免网络拥塞。当网络出现拥塞时,TCP 会减小发送窗口的大小,降低发送速率,以避免过多的数据包在网络中引起丢失。
-
超时和重试: TCP 在发送数据后会设置一个定时器,如果在规定的时间内未收到确认,就会认为数据包丢失,并触发重传机制
4.2 包丢了会怎么办?TCP 重传的条件通常由以下几个因素决定:
-
超时: TCP 发送数据后会设置一个定时器(称为超时时间),在等待接收方发送确认时启动。如果超过了超时时间仍未收到确认,发送方就会认为数据丢失,并触发重传机制。
-
收到重复的 ACK(确认): 当发送方的某个数据包超时或者丢失时,接收方可能会收到重复的数据包(即重复的序列号)。接收方会发送一个带有已收到的最后一个连续数据包序号的 ACK 给发送方,以告知发送方某些数据包丢失了。发送方接收到这样的 ACK 后,会触发重传丢失的数据包。
-
快速重传: TCP 还具有一种称为“快速重传”的机制。当发送方接收到连续的三个相同的 ACK 时,它会立即重传丢失的数据包,而不必等待超时。这种情况表明接收方已经收到了后续的数据包,但中间有一个或多个数据包丢失。
什么是浏览器缓存?缓存分为什么?
浏览器缓存是一种用于临时存储和管理网络资源的机制,目的是提高网页加载性能和用户体验。通过缓存,浏览器可以避免重新下载已经获取过的资源,从而减少加载时间和减轻服务器的负担。
-
本地缓存(Local Cache):
- Memory Cache(内存缓存): 将一些临时性的数据存储在内存中,这样可以快速读取,但生命周期较短。关闭标签页或浏览器时,这些缓存数据会被清除。
- Disk Cache(磁盘缓存): 将一些持久性的数据存储在硬盘上,生命周期较长。即使关闭浏览器,这些缓存数据也可能被保留。
-
网络缓存(Network Cache):
- Service Worker Cache: 使用 Service Worker 技术,允许网站开发者自定义缓存策略,实现离线访问等高级功能。
- HTTP 缓存: 存储在浏览器的本地存储中。使用 HTTP 协议中的缓存头部,如
Cache-Control
、Expires
、Last-Modified
、ETag
等,控制浏览器对资源的缓存策略。
相关文章:
前端面试灵魂提问-计网(2)
1、websocket 为什么全双工? 1.1 WebSocket是什么 WebSocket 是一种通信协议,它在客户端和服务器之间建立持久的全双工连接。全双工意味着数据可以双向流动,即客户端可以向服务器发送消息,服务器也可以向客户端发送消息,而无需…...

Git修改远程仓库名称
1、先直接在远程点仓库名,然后左侧菜单栏找settings-general,然后直接修改工程名,保存即可。 2、还是在settings-general下,下拉找到Advanced点击Expand展开,然后下拉到最底部 在Change path里填入新的项目名称&#x…...

kafka 集群 ZooKeeper 模式搭建
Apache Kafka是一个开源分布式事件流平台,被数千家公司用于高性能数据管道、流分析、数据集成和关键任务应用程序 Kafka 官网:Apache Kafka 关于ZooKeeper的弃用 根据 Kafka官网信息,随着Apache Kafka 3.5版本的发布,Zookeeper现…...

【LeetCode】 160. 相交链表
相交链表 题目题解 题目 给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。 图示两个链表在节点 c1 开始相交: 题目数据 保证 整个链式结构中不存在环。 注意&am…...

TZOJ 1429 小明A+B
答案: #include <stdio.h> int main() {int T0, A0, B0, sum0;scanf("%d", &T); //输入测试数据的组数while (T--) //循环T次{scanf("%d %d", &A, &B); //输入AB的值sum A B;if (sum > 100) //如果是三位数{…...
制作openeuler的livecd
下载该项目,执行下面的操作gitee openeuler livecd项目 基于openeuler环境 #安装工具,第一次可能报错,可以再执行一次 make installx86 livecd-creator -d -v --config./config/euler_x86_64.ks --fslabeleuler-LiveCD --cachecache --log…...

B.牛牛排队伍——模拟双链表
当前位置: 首页 > news >正文 B.牛牛排队伍——模拟双链表 news 2023/12/1 15:14:37 分析 题目其实很简单,就是双链表的增删查,但是刚开始,直接vis标记删除元素,查找一个位置的前一个用的while不断向前找,但是TLE;毕竟O(n*k)的复杂度,一开始没有考虑时间复杂度…...
【PyTorch】(四)损失函数与优化器
文章目录 1. 损失函数2. 优化器 1. 损失函数 2. 优化器...
【Python】使用execute(sql)执行insert之后没有插入数据
在sql为insert语句,用Python的sqlalchemy模块中的execute()执行之后没有插入数据的情况,主要是因为sqlalchemy版本的更新,不能直接只用execute()了,MySQL数据库连接的配置和sql都需要多处理一步: 之前的版本ÿ…...

虚拟机备份数据自动化验证原理
备份数据成功备份下来了,但是备份数据是否可用可靠?对于这个问题,最好最可靠的方法是将备份数据实际恢复出来验证。 但是这样的方法,不仅费时费力,而且需要随着备份数据的定期产生,还应当定期做备份数据验…...

前端入门(五)Vue3组合式API特性
文章目录 Vue3简介创建Vue3工程使用vite创建vue-cli方式 常用 Composition API启动项 - setup()setup的执行时机与参数 响应式原理vue2中的响应式vue3中的响应式ref函数reactive函数reactive与ref对比 计算属性 - computed监视属性 - watchwatchEffect Vue3生命周期自定义hook函…...
Doris 数据导入二:Stream Load 方式
Stream load 是一个同步的导入方式,用户通过发送 HTTP 协议发送请求将本地文件或数据流导入到 Doris 中。Stream load 同步执行导入并返回导入结果。用户可直接通过请求的返回体判断本次导入是否成功。 1 适用场景 Stream load 主要适用于导入本地文件,或通过程序导入数据流中…...

【算法刷题】Day10
文章目录 15. 三数之和题干:算法原理:1、排序 暴力枚举 利用set 去重2、排序 双指针 代码: 18. 18. 四数之和题干:算法原理:1、排序 暴力枚举 利用set 去重2、排序 双指针 代码: 15. 三数之和 原题链…...

SAP 如何检查已安装的SAP UI5 版本
第一个方法是直接从FLP中查看 但是部分高版本的FLP中没有这个about, 那么在当前界面可以使用:CTRL ALT SHIFT S 查看当前版本 根据此版本,去进行你的UI5的开发吧...

15、 深度学习之正向传播和反向传播
上一节介绍了训练和推理的概念,这一节接着训练和推理的概念讲一下,神经网络的正向传播和反向传播。 其实单看正向传播和反向传播这两个概念,很好理解。 正向传播(Forward Propagation)是指从输入层到输出层的数据流动过程,而反向传播(Backpropagation)是指数据从输出…...
微信小程序中复制文本
在微信小程序中,可以使用wx.setClipboardData()方法来实现复制文本内容的功能。以下是一个示例代码: // 点击按钮触发复制事件 copyText: function() {var that this;wx.setClipboardData({data: 要复制的文本内容,success: function(res) {wx.showToa…...

vue3学习--初始
...

cmake和vscode 下的cmake的使用详解(二)
第四讲: GDB 调试器 前言: GDB(GNU Debugger) 是一个用来 调试 C/C 程序 的功能强大的 调试器 ,是 Linux 系统开发 C/C 最常用的调试器 程序员可以 使用 GDB 来跟踪程序中的错误 ,从而减少程序员的工作量。 Linux 开发 C/C …...

集成开发环境 PyCharm 的安装【侯小啾python领航班系列(二)】
集成开发环境PyCharm的安装【侯小啾python领航计划系列(二)】 大家好,我是博主侯小啾, 🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹…...

mysql从库设置为只读
直奔主题,mysql设置为只读后,无法增删改。 设置命令: mysql> set global read_only1; #1是只读,0是读写 mysql> show global variables like %read_only%; 以下是相关说明: 1、对于数据库读写状态…...

从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...

visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...

招商蛇口 | 执笔CID,启幕低密生活新境
作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...
现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?
现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)ÿ…...

C/C++ 中附加包含目录、附加库目录与附加依赖项详解
在 C/C 编程的编译和链接过程中,附加包含目录、附加库目录和附加依赖项是三个至关重要的设置,它们相互配合,确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中,这些概念容易让人混淆,但深入理解它们的作用和联…...

并发编程 - go版
1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...

iview框架主题色的应用
1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...