前端面试灵魂提问-计网(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、对于数据库读写状态…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...

ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)
本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...
Java求职者面试指南:计算机基础与源码原理深度解析
Java求职者面试指南:计算机基础与源码原理深度解析 第一轮提问:基础概念问题 1. 请解释什么是进程和线程的区别? 面试官:进程是程序的一次执行过程,是系统进行资源分配和调度的基本单位;而线程是进程中的…...

[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.
ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #:…...

Rust 开发环境搭建
环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行: rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu 2、Hello World fn main() { println…...
python爬虫——气象数据爬取
一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用: 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests:发送 …...