再看 MPTCP 时的思考
2022 年夏,居家办公时,第一次接手 mptcp 就觉得它不靠谱,以至于我后来搞了 mpudp for DC,再后来我调研了很多 mptcp-based 方案,发现它们都是向善而来,最终灰头土脸而终。mptcp 实则一个坑,业内并没有普遍部署,也没有任何值得借鉴的经验,但筚路蓝缕,终究不会让所有启程变归途。
5.6 内核前的 MPTCP v0 实现非常丝滑,让我想起 task_struct,跟 task_struct 摇身一变成了主线程一样,socket 也摇身一变更换了一些 sock operations 回调后变成了 meta sock,但和进程中多个 task_struct 可在多个 CPU 并行不同,MPTCP v0 多个 subflow 却不能在多路径上同时收发数据,这显然与它的名字所体现的意义相违背。
看 mptcp 与 task_struct 何等相似,再看看为什么 v0 吞吐性能低下,以及 v1 是如何解决的:
task_struct 作为一个可执行代码的容器将共享互斥权力交给了代码本身,而 mptcp 本身即包含传输控制逻辑,因此它需要将锁拆分到更细的粒度,确保只有直接接触的彼此才需要互斥,即谁接触谁抢锁。
v0 版本显然只是一个最简实现版本,借用巧妙的结构体替换以最小代价实现了 mptcp,但如果 v0 版本显示不出 mptcp 该有的特性和优势,又如何吸引人们有动力去部署并迭代 v1 呢。哪怕是一团烂泥,先跑起来再说,这显然忽略了不是谁都有的试错成本,这是句毒鸡汤,烂话。
看下 mptcp v0 的实现:
// MPTCP 写回调,由 meta_sock 调用,持有 meta_sock 锁
bool mptcp_write_xmit(struct sock *meta_sk, unsigned int mss_now, int nonagle,int push_one, gfp_t gfp)
{while ((skb = mpcb->sched_ops->next_segment(meta_sk, &reinject, &subsk,&sublimit))) {mptcp_skb_entail(subsk, skb, reinject);}mptcp_for_each_sub(mpcb, mptcp) {subsk = mptcp_to_sock(mptcp);// 调用 subflow_sock 原始的 tcp_write_xmit 将数据包发往 subflow__tcp_push_pending_frames(subsk, mss_now, TCP_NAGLE_PUSH);}
}// MPTCP 接收,LOCK 住整个 meta_sock
int tcp_v4_rcv(struct sk_buff *skb)
{// 检索到 subflow_socksk = __inet_lookup_skb(&tcp_hashinfo, skb, __tcp_hdrlen(th), th->source,th->dest, sdif, &refcounted);if (mptcp(tcp_sk(sk))) {// 锁住整个 meta_sockmeta_sk = mptcp_meta_sk(sk);bh_lock_sock_nested(meta_sk);if (sock_owned_by_user(meta_sk))mptcp_prepare_for_backlog(sk, skb);} else {meta_sk = sk;bh_lock_sock_nested(meta_sk);}if (!sock_owned_by_user(meta_sk)) {ret = tcp_v4_do_rcv(sk, skb);} else if (tcp_add_backlog(meta_sk, skb)) {goto discard_and_relse;}bh_unlock_sock(meta_sk);
}
看了以上的 “问题代码”,解法就很自然,mptcp_write_xmit 和 tcp_v4_rcv 分别锁 subflow_sock,注意到 softirq 中的 rcv 逻辑并不触动发送缓冲区,因此仅在 mptcp_data_ready 时才锁 meta_sock。
如果不把 mptcp 看作淋浴喷头,看作在线订单配送系统也是合适的,虽然配送员要从同一处排队领单,但多个配送员独立配送显然可以提高系统吞吐。
再看 mptcp subflow 调度逻辑,这仍是一个并行编程问题,如何设计一个好的调度算法和如何将一个问题拆分为可并行执行的子问题完全一致。一个简单的求和问题,1 + 2 + 3 + 4 + … + 100,两个人一起算,一个人算 1 + 2,另一个人算 2 + 3 还是 3 + 4 呢,显然都不合适,因为这样的的话他们需要频繁交流同步,而 mptcp 采用的就是这种不合适的策略。众所周知,小高斯的策略更胜一筹,他聪明地分割了问题,这个问题用现代多核处理器上的多线程程序来做,即使最拙劣的程序员想到的依然还是小高斯的策略。
以上这段的意思就是我前面文章提到的调度策略,给出了一个 subflow 从数据开头顺序发送,另一个 subflow 从数据末尾逆序发送的理由,这样一来,它们只需在碰头时同步一次。这个想法来自于小学工程队修路这类应用题。
但 3 条及以上的 subflow 怎么办?
这引出一个很棒(至少我以为)的调度策略,即最小交互策略,它主要通过破除人们对启发式的执念来起作用。意思是说,想要高性能,能静态就不要动态,算不准就不要猜,因为动态的,启发式策略除了它们本身的复杂性成本外,还有猜错了后的补偿成本,只要信息量不足,必然由猜错的时候。而最小交互策略连 subflow 间的同步成本也尽可能省掉了:
成本没了,剩下的全是性能了。
继续基于并发,并行的概念审视 mptcp:
- 并发视角:将多条路径视作池化资源,提高资源利用率,RFC6356 原则 3;
- 并行视角:将多条路径视作可并行资源,提高吞吐,降低时延,受 RFC6356 原则 2 约束 。
两个视角带来了不同的优化理念。
站在并发视角,优先要做的是将流量调度到相对空闲链路,避免带宽浪费,但不要将流量调度到繁忙链路,避免拥塞,主要 concern 调度算法;而站在并行视角,则需要更关注传输任务本身的分解,与并行编程的 concern 完全一致。我将多路径看作并行资源,我希望带宽能叠加,RFC6356 原则 2 约束了做这件事的底线狠度。
原则是一回事,实现是一回事,即便是 mptcp v1,仍不能完全避免串行化,因为本质上 TCP 就是一个串行流,多个 subflow 从 meta_sock 取数据发送或接收完数据重组拼接时,仍然要抢 meta_sock 锁,这意味着 mptcp 永远也无法实现多路径吞吐的满叠加,有趣的是,文初描述 mptcp v0 的 meta sock 串行锁竟然直接实现了 6356 原则 2,让你即使想叠加带宽而不能为之。
串行流的并行化很难,除非将思路转向我上面提到的那种策略,固定分割数据,在流序列号空间上让 subflow 们彻底无关(最多一个 bitmap 操作甚至一个原子操作),就不必在时间上争抢锁,这也正是很多多路径自研新协议的思路了。
至于人们对启发式,自适应的执念,和所谓通用系统的普适性执念说的是一个意思,还是那句话,要性能就别自适应,要通用就别调参。那么说说 Linux 自带的 mptcp 通用算法。所有的逻辑都在 net/mptcp/protocol.c 中的 mptcp_subflow_get_send 这一个函数里,简单讲就是两个逻辑:
- 在所有 subflow 里冒泡一个 key = local_write_queue_len / pacing_rate 最小的 subflow,记为 R;
- 将 global_write_queue 中的约 64kB 数据 queue 到 R 的 local_write_queue_len。
本着以上的论述,这个算法如何再 “优化” 呢?来试试看。
虽然前文我已经驳斥了这种对 “乱序发,顺序到达” 的执念在现实中多么不靠谱,但若要尽量让算法看起来好看些,还是要有论证。
要顺序到达,就要精确预测 sender global_write_queue 中每一个报文在不同 subflow 中到达 receiver 的时间,由于 RTT 本质上不准,说白了还得靠猜,这就是所谓启发式。
这个到达时间由两部分构成,一部分包括在 subflow 的 local_write_queue 中排队时间,另一部分则是单程时延,即 RTT 的一半:
T a r r i v e = T w a i t + R T T 2 = L o c a l Q u e u e L e n D e l i v e r y R a t e + R T T 2 T_{\mathrm{arrive}}=T_{\mathrm{wait}}+\dfrac{\mathrm{RTT}}{2}=\dfrac{\mathrm{LocalQueueLen}}{\mathrm{DeliveryRate}}+\dfrac{\mathrm{RTT}}{2} Tarrive=Twait+2RTT=DeliveryRateLocalQueueLen+2RTT
按 Tarrive 冒泡看上去就比 Linux 自带的那个算法高尚,至少是看上去不错。其实 Linux 自带算法也就缺个 RTT / 2,大致意思没变。看下 Linux mptcp 调度算法的注释:
/* According to the blest algorithm, to avoid HoL blocking for the* faster flow, we need to:* - estimate the faster flow linger time* - use the above to estimate the amount of byte transferred* by the faster flow* - check that the amount of queued data is greter than the above,* otherwise do not use the picked, slower, subflow* We select the subflow with the shorter estimated time to flush* the queued mem, which basically ensure the above. We just need* to check that subflow has a non empty cwin. */
冒泡算法已经 “优化” 好了,接下来看第二个问题,一次性发多少呢?Linux 硬编码了约 64kB,但更好看的应该是一个 BDP,不细说了。
最后,若换一个角度,从 “最佳效能” 考虑,就应该把所有不确定的工作尽量推给 receiver,配置极大的接收 buffer 供它乱序重组,sender 便可按照 key = BW / RTT 冒泡最大值来调度 subflow,总之,成本核算的活必须要干,问题是谁干。
重新捋一下上面的 “优化”,我始终没有让丢包率参与进来,这是因为它已经包含在 DeliveryRate 里了,如果丢包率变高,吞吐一定会下降。一定要让且仅让正交变量参与,而不是搞一大堆复杂的公式故弄玄虚,让人不明觉厉。
结束之前,回忆一下往事。
我从 mptcp 想到了 Linux 的进程,线程结构体 tast_struct,于是我用包括 Google 在内搜索引擎搜我在十几年前写的文章,结果全是转载,最后我是通过本地记录找到了时间,然后在 CSDN 匹配时间找到了这篇:朴素的 UNIX 之进程/线程模型,里面有个模糊的图:
浙江温州皮鞋湿,下雨进水不会胖。
相关文章:
再看 MPTCP 时的思考
2022 年夏,居家办公时,第一次接手 mptcp 就觉得它不靠谱,以至于我后来搞了 mpudp for DC,再后来我调研了很多 mptcp-based 方案,发现它们都是向善而来,最终灰头土脸而终。mptcp 实则一个坑,业内…...
将三维非平面点集拆分为平面面片的MATLAB实现
将三维非平面点集拆分为平面面片的MATLAB实现 要将三维空间中不在同一平面上的点集拆分为多个平面面片,可以采用以下几种方法: 1. 三角剖分法 (Delaunay Triangulation) 最简单的方法是将点集进行三角剖分,因为三个点总是共面的࿱…...
Python(10.2)Python可变与不可变类型内存机制解密:从底层原理到工程实践
目录 一、类型特性引发的内存现象1.1 电商促销活动事故分析1.2 内存机制核心差异 二、内存地址追踪实验2.1 基础类型验证2.2 复合对象实验 三、深度拷贝内存分析3.1 浅拷贝陷阱3.2 深拷贝实现 四、函数参数传递机制4.1 默认参数陷阱4.2 安全参数模式 五、内存优化最佳实践5.1 字…...
华为hcie证书的有效期怎么判断?
在ICT行业,华为HCIE证书堪称含金量极高的“敲门砖”,拥有它往往意味着在职场上更上一层楼。然而,很多人在辛苦考取HCIE证书后,却对其有效期相关事宜一知半解。今天,咱们就来好好唠唠华为HCIE证书的有效期怎么判断这个关…...
【前端】CSS Grid 布局详解
CSS Grid 布局详解(通俗易懂版) 一、概述 CSS Grid 是一种二维布局系统,可以同时控制行和列,相比 Flex(一维布局),更适合用在整体页面布局或复杂模块结构中。 二、基础概念 Grid 容器&#x…...
物美“外贸转内销”极速绿色通道正式开启
「TMT星球」获悉,在国家“提振消费、扩大内需”及“内外贸一体化”战略指引下,物美集团依托自身零售生态优势,打造“云超绿通”专项通道,助力中国优质外贸企业实现“出口转内销”的高效转型,通过极速绿通、线上线下全渠…...
【说明书#1】Node.js 和 npm安装与使用
系统提示 npm 不是内部或外部命令,也不是可运行的程序或批处理文件,也就是 npm 命令无法识别。这个错误通常是因为 Node.js 和 npm 没有正确安装,或者它们的路径没有添加到系统的环境变量中。 解决方法如下: 1. 安装 Node.js 和 npm: 如果你还没有安装 Node.js,可以从…...
【触想智能】安卓工业平板电脑和普通商业平板电脑的区别
安卓工业平板电脑是基于ARM架构开发的一种工业平板电脑,它在自助终端、智能制造、产线车间、智慧物流、商业金融等诸多领域有着广泛的应用。 触想安卓工业平板电脑TPC-A2系列 安卓工业平板电脑和普通商业平板电脑在一些方面存在一些区别,包括设计、硬件规…...
Java基于SSM的课程答疑微信小程序【附源码、文档说明】
博主介绍:✌IT徐师兄、7年大厂程序员经历。全网粉丝15W、csdn博客专家、掘金/华为云//InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇dz…...
模板引擎语法-变量
模板引擎语法-变量 文章目录 模板引擎语法-变量(一)在Django框架模板中使用变量的代码实例(二)在Django框架模板中使用变量对象属性的代码实例(三)在Django框架模板中使用变量显示列表 (一&…...
1260 最大公约数
1260 最大公约数 ⭐️难度:中等 🌟考点:GCD 📖 📚 import java.util.Scanner; import java.util.Arrays;public class Main {public static void main(String[] args) {Scanner sc new Scanner(System.in);int t …...
Node.js中net模块详解
Node.js 中 net 模块 API 详解 Node.js 的 net 模块提供了基于 TCP/IP 的网络功能,用于创建 TCP 服务器和客户端。以下是 net 模块的所有 API 详解: 1. 创建 TCP 服务器 const net require(net);// 1. 基本服务器 const server net.createServer((s…...
【从零开始学习JVM | 第三篇】虚拟机的垃圾回收学习(一)
堆空间的基本结构 Java 的自动内存管理主要是针对对象内存的回收和对象内存的分配。同时,Java 自动内存管理最核心的功能是 堆 内存中对象的分配与回收。 Java 堆是垃圾收集器管理的主要区域,因此也被称作 GC 堆(Garbage Collected Heap&am…...
intellj idea 2024.1
参考资料 激活 https://www.microcharon.com/tech/5.htmlja-netfilter-all下载地址:https://drive.microcharon.com/OneDrive/Software/JetBrains%20ja-netfilter-all%20Build%202024.1.11.zip 步骤及问题 下载后:安全前确保旧版本的idea已经卸载。安…...
redis之缓存击穿
一、前言 本期我们聊一下缓存击穿,其实缓存击穿和缓存穿透很相似,区别就是,缓存穿透是一些黑客故意请求压根不存在的数据从而达到拖垮系统的目的,是恶意的,有针对性的。缓存击穿的情况是,数据确实存在&…...
Node.js中path模块详解
Node.js path 模块全部 API 详解 Node.js 的 path 模块提供了处理文件路径的工具函数,支持跨平台路径操作。以下是 path 模块的所有 API 详解: 1. 路径解析与操作 const path require(path);// 1. 路径连接 const fullPath path.join(__dirname, fi…...
重构艺术 | 内联与查询替代临时变量
重构艺术 | 内联与查询替代临时变量 在代码重构的殿堂里,临时变量常常扮演着双面角色:既是代码清晰的助力器,也可能成为代码腐败的温床。本文将深入探讨两种处理临时变量的重要手法:内联临时变量(Inline Temp…...
数据分析-数据预处理
数据分析-数据预处理 处理重复值 duplicated( )查找重复值 import pandas as pd apd.DataFrame(data[[A,19],[B,19],[C,20],[A,19],[C,20]],columns[name,age]) print(a) print(--------------------------) aa.duplicated() print(a)只判断全局不判断每个 any() import p…...
Java基础 4.12
1.方法的重载(OverLoad) 基本介绍 Java中允许同一个类,多个同名方法的存在,但要求形参列表不一致! 如 System.out.println(); out是PrintStream类型 重载的好处 减轻了起名的麻烦减轻了记名的麻烦 2.重载的快速入…...
PostgreSQL有类似oracle的move表吗
PostgreSQL有类似oracle的move表吗 PostgreSQL 提供了类似 Oracle MOVE 表功能的重组操作,但实现方式和具体命令有所不同。以下是详细对比和 PostgreSQL 中的实现方案: 一 Oracle MOVE 与 PostgreSQL 对比 特性Oracle MOVEPostgreSQL 等效操作主要用途…...
AUTO-RAG: AUTONOMOUS RETRIEVAL-AUGMENTED GENERATION FOR LARGE LANGUAGE MODELS
Auto-RAG:用于大型语言模型的自主检索增强生成 单位:中科院计算所 代码: https://github.com/ictnlp/Auto-RAG 拟解决问题:通过手动构建规则或者few-shot prompting产生的额外推理开销。 贡献:提出一种以LLM决策为中…...
ABC-CNN-GRU-Attention、CNN-GRU-Attention、ABC-CNN-GRU和CNN-GRU四类对比模型多变量时序预测
人工蜂群算法四模型对比!ABC-CNN-GRU-Attention系列四模型多变量时序预测 目录 人工蜂群算法四模型对比!ABC-CNN-GRU-Attention系列四模型多变量时序预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 本研究针对多变量时间序列预测任务…...
ssh 免密登录服务器(vscode +ssh 免密登录)
每次打开vscode连接服务器都需要输入密码,特别繁琐。 然后自己在网上翻阅了一下教程,发现说的内容比较啰嗦,而且个人感觉非常有误导性倾向。 因此自己直接干脆写一个简便易懂的教程算了。 (以经过本人亲测,真实可靠&am…...
Elasticsearch 系列专题 - 第七篇:实战项目
理论学习固然重要,但实战才能真正巩固知识。本篇将通过两个项目,带你从需求分析到实现,体验 Elasticsearch 在真实场景中的应用。 1. 项目一:日志分析系统 1.1 需求分析与架构设计 需求: 实时采集服务器日志。按时间和日志级别(INFO、ERROR)分析。可视化错误趋势。架构…...
C++初阶-类和对象(上)
本章内容相对于之后的类和对象中和下都比较简单,但是整体还是有些难度的。 目录 1.类的定义 1.1类定义格式 1.2访问限定符 1.3类域 2.实例化 2.1实例化概念 2.2对象大小 3.this指针 4.练习 4.1选择题1 4.2选择题2 5.总结 1.类的定义 1.1类定义格式 &am…...
(十九)安卓开发中的Application类的使用详解
在 Android 开发中,Application 类是一个全局的单例类,代表应用进程本身。它常用于初始化全局资源、维护应用级别的状态和注册全局生命周期回调。以下是详细讲解和代码示例: 一、自定义 Application 类 1. 创建子类 public class MyApplica…...
算法思想之位运算(一)
欢迎拜访:雾里看山-CSDN博客 本篇主题:算法思想之位运算(一) 发布时间:2025.4.12 隶属专栏:算法 目录 滑动窗口算法介绍六大基础位运算符常用模板总结 例题位1的个数题目链接题目描述算法思路代码实现 比特位计数题目链接题目描述…...
十八、TCP多线程、多进程并发服务器
1、TCP多线程并发服务器 服务端: #include<stdio.h> #include <arpa/inet.h> #include<stdlib.h> #include<string.h> #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> #include <pthread.h>…...
『生成内容溯源系统』详解
生成内容溯源系统详解 1. 定义与核心目标 生成内容溯源系统(Generative Content Provenance System)是指能够追踪AI生成内容的来源、生成过程、版权归属及修改历史的技术体系。其核心目标是: 验证真实性:证明内容由特定AI模型生…...
mac 解压 nsz 文件
nsz 地址 下载 nsz PIP 套餐 使用以下命令安装仅限 Console 的版本: pip3 install --upgrade nsz使用以下命令安装 GUI 版本: pip3 install --upgrade nsz[gui]解压 nsz 文件 nsz -D 文件路径...
Python进阶(3):函数(接上篇)
上一篇我们初步介绍python中函数的定义与调用 Python进阶(2):函数-CSDN博客 这里继续: 关键字参数: 形参1实参1,形参2实参2,...... 关键字参数是指使用形式参数的名字来确定输入的参数值。通过该方式指定实际参数时,不再需要与形式参数的位置完全一致。只要将参数名写正确…...
卒/兵过河前的判断和走法触发器优化
兵(卒):兵(卒)在未过河前,只能向前一步步走,过河以后,除不能后退外,允许左右移动,但也只能一次一步。 迷你世界地图已上传 优化...
生物信息Rust-01
前言-为什么想学Rust? 一直想多学一门编译语言,主要有几个原因吧(1. 看到一位老师实验室要求需要掌握一门编译语言;2. 自己享想试着开发一些实用的生信工具,感觉自己现在相比于数据分析,探索生物学层面的意…...
基于HTML + jQuery + Bootstrap 4实现(Web)地铁票价信息生成系统
地铁票价信息表生成系统 1. 需求分析 1.1 背景 地铁已经成为大多数人出行的首选,北京地铁有多条运营线路, 截至 2019 年 12 月,北京市轨道交通路网运营线路达 23 条、总里程 699.3 公里、车站 405 座。2019 年,北京地铁年乘客量达到 45.3 亿人次,日均客流为 1241.1 万人次…...
智慧水务项目(八)基于Django 5.1 版本PyScada详细安装实战
一、说明 PyScada,一个基于Python和Django框架的开源SCADA(数据采集与监视控制系统)系统,采用HTML5技术打造人机界面(HMI)。它兼容多种工业协议,如Modbus TCP/IP、RTU、ASCII等,并具…...
DeepSeek在消防救援领域的应用解决方案
DeepSeek在消防救援领域的应用解决方案 一、火灾风险动态感知与早期预警 火灾风险动态感知与早期预警是智慧消防的关键环节,DeepSeek通过多模态数据分析,融合烟雾传感器、热成像摄像头和气体浓度检测等数据,能够识别传统阈值法难以捕捉的火…...
VSCode CMake调试CPP程序
文章目录 1 安装C与CMake插件2 配置CMakeLists.txt3 使用CMake编译调试3.1 编译3.2 调试 4 自定义构建调试参考 1 安装C与CMake插件 C插件 CMake插件 2 配置CMakeLists.txt 编写测试程序 #include<iostream>int main(int argc, char const *argv[]) {int a 1, b 2;i…...
AI Agent工程师认证-学习笔记(3)——【多Agent】MetaGPT
学习链接:【多Agent】MetaGPT学习教程 源代码链接(觉得很好,star一下):GitHub - 基于MetaGPT的多智能体入门与开发教程 MetaGPT链接:GitHub - MetaGPT 前期准备 1、获取MetaGPT (1ÿ…...
Spring AI 结构化输出详解
一、Spring AI 结构化输出的定义与核心概念 Spring AI 提供了一种强大的功能,允许开发者将大型语言模型(LLM)的输出从字符串转换为结构化格式,如 JSON、XML 或 Java 对象。这种结构化输出能力对于依赖可靠解析输出值的下游应用程…...
AMGCL库使用示例
AMGCL库使用示例 AMGCL是一个用于解决大规模稀疏线性方程组的C库,它实现了代数多重网格(AMG)预处理器和Krylov子空间迭代求解器。下面是一些AMGCL的使用示例。 基本示例:求解稀疏线性系统 #include <iostream> #include <vector> #includ…...
关于 Java 预先编译(AOT)技术的详细说明,涵盖 GraalVM 的配置、Spring Boot 3.x 的集成、使用示例及优缺点对比
以下是关于 Java 预先编译(AOT)技术的详细说明,涵盖 GraalVM 的配置、Spring Boot 3.x 的集成、使用示例及优缺点对比: 1. 预先编译(AOT)技术详解 1.1 核心概念 AOT(Ahead-of-Time)…...
Video Encoder:多模态大模型如何看懂视频
写在前面 大型语言模型(LLM)已经掌握了理解文本的超能力,而多模态大模型(MLLM)则更进一步,让 AI 拥有了“看懂”图像的眼睛。但这还不够!真实世界是动态的、流动的,充满了运动、变化和声音。视频,正是承载这一切动态信息的关键媒介。 让 LLM 看懂视频,意味着 AI 需…...
leetcode0622. 设计循环队列-medium
1 题目:设计循环队列 官方标定难度:中 设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。 循环队列的一…...
专题十四:动态路由——OSPF
一、OSPF简介 开放式最短路径优先OSPF(Open Shortest Path First)是IETF组织开发的一个基于链路状态的内部网关协议(Interior Gateway Protocol),采用DIjkstra算法,协议号是89。用于自治系统(A…...
【蓝桥杯】第十六届蓝桥杯 JAVA B组记录
试题 A: 逃离高塔 很简单,签到题,但是需要注意精度,用int会有溢出风险 答案:202 package lanqiao.t1;import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWrit…...
一个项目的架构演进
1,单体架构 垂直升级:4核16GB -> 8核64G 水平扩展:一台服务器扩展成多台 存在以下几个问题 1,提升的性能是有限的 2,更新,维护成本非常高,对于系统中要修改或增加的功能,整个发…...
创建虚拟环境无法加载到pycharm当conda环境,只能为python环境
conda create -n myenv python3.8 然后,在pycharm中,点击 ..." 按钮并浏览到您的 Conda 环境路径。通常,Conda 环境路径位于 ~/.conda/envs/<Your Environment Name> 或 ~/miniconda3/envs/<Your Environment Name> 或 ~/an…...
暴雨打造智能化时代源动力
当清晨的智能管家为您调节室温、日间数字员工自动生成会议纪要、深夜AI外教仍在纠正发音……这不是科幻片,2025年的世界正被智能体悄然重塑。这些能听会想的数智化助理,正在医疗会诊、工业质检、金融风控等多个领域创造着价值。 那么,智能体…...
【ROS2】行为树:BehaviorTree
1、简介 与状态机不同,行为树强调执行动作,而不是状态之间的转换。 行为树是可组合的。可以重复使用简单的行为来构建复杂的行为。 在游戏领域,行为树已经比较流行了。主要用于维护游戏角色的各种动作和状态。 ROS2的导航框架Navigation2中引入了行为树来组织机器人的工作流…...
【HTTP】:应用层协议HTTP(1)
1.HTTP协议 虽然我们说,应用层协议是我们程序猿自己定的.但实际上,已经有大佬们定义了一些现成的,又非常好用的应用层协议,供我们直接参考使用.HTTP(超文本传输协议)就是其中之一。 在互联网世界中,HTTP(HyperTextTransfer Protocol,超文本…...