【Rust自学】15.7. 循环引用导致内存泄漏
说句题外话,这篇文章真心很难,有看不懂可以在评论区问,我会尽快作答的。
喜欢的话别忘了点赞、收藏加关注哦(加关注即可阅读全文),对接下来的教程有兴趣的可以关注专栏。谢谢喵!(=・ω・=)
15.7.1. 内存泄漏
Rust极高的安全性使得内存泄漏很难出现,但并不是完全不可能。
例如使用Rc<T>
和RefCell<T>
就可能创造出循环引用,造成内存泄漏:每个指针的引用计数都不会减少到0,值也不会被清理。
看个例子:
use crate::List::{Cons, Nil};
use std::cell::RefCell;
use std::rc::Rc;#[derive(Debug)]
enum List {Cons(i32, RefCell<Rc<List>>),Nil,
}impl List {fn tail(&self) -> Option<&RefCell<Rc<List>>> {match self {Cons(_, item) => Some(item),Nil => None,}}
}fn main() {let a = Rc::new(Cons(5, RefCell::new(Rc::new(Nil))));println!("a initial rc count = {}", Rc::strong_count(&a));println!("a next item = {:?}", a.tail());let b = Rc::new(Cons(10, RefCell::new(Rc::clone(&a))));println!("a rc count after b creation = {}", Rc::strong_count(&a));println!("b initial rc count = {}", Rc::strong_count(&b));println!("b next item = {:?}", b.tail());if let Some(link) = a.tail() {*link.borrow_mut() = Rc::clone(&b);}println!("b rc count after changing a = {}", Rc::strong_count(&b));println!("a rc count after changing a = {}", Rc::strong_count(&a));
}
-
首先创建了一个链表
List
,使用RefCell<T>
包裹Rc<T>
使其内部值可被修改 -
通过
impl
块为List
写了一个叫tail
的方法,用于获取List
下Cons
变体附带的第二个元素,如果有就返回其值,用Some
封装,是Nil
就返回None
。 -
然后在
main
函数创建了a
、b
两个List
的实例,b
内部共享了a
的值。这种链表的代码看着就犯恶心,所以我把其结构图放在
这里: -
main
函数里还通过Rc::strong_count
获取了a
和b
的强引用数量,使用自定义的tail
方法获了Cons
附带的第二个元素,用println!
打印出来。 -
下面使用
if let
语句把a
的Cons
的第二个值绑在link
上,通过borrow_mut
方法获得其可变引用&Cons
,使用解引用符号*
把它转为Cons
,最后把b
的值通过Rc::clone
共享赋给了link
,也就改变了a
内部的结构,变为了:
PS:我觉得自己画的太烂了,所以这里就换成The Rust Programming Language里的图片了
输出:
a initial rc count = 1
a next item = Some(RefCell { value: Nil })
a rc count after b creation = 2
b initial rc count = 1
b next item = Some(RefCell { value: Cons(5, RefCell { value: Nil }) })
b rc count after changing a = 2
a rc count after changing a = 2
第1行到第5行:刚开始创建a
时,引用数量就为1,当b
被声明时,a
被共享了,所以此时a
的引用计数为2,b
为1。
第六行到第7行:if let
语句把a
的内部结构改变了,使a
的第二个元素指向b
,b
的引用数量加1变为2。此时a
指向了b
,b
又指向了a
,就会造成循环引用。
当a
和b
都走出了作用域,Rust删除了变量b
,这将b
的引用计数从 2 减少到 1。此时Rc<List>
在堆上的内存不会被删除,因为它的引用计数是1,而不是0。然后 Rust 删除a
,这会将a
的Rc<List>
实例的引用计数从 2 减少到 1,如图所示。这个实例的内存也不能被删除,因为另一个实例的内存 Rc<List>
实例仍然引用它。分配给列表的内存将永远保持未回收状态。
接下来我们看看循环引用的内容是什么,使用这条代码:
println!("a next item = {:?}", a.tail());
Rust 将尝试打印此循环,其中a
指向b
指向a
等等,直到溢出堆栈。最终的结果会是栈溢出错误。
15.7.2. 防止内存泄漏的方法
那有什么方法来防止内存泄漏吗?这只能依靠开发者,不能依靠Rust。
不然就只能重新组织数据结构,把引用拆分成持有和不持有所有权的两种情况,一些引用用来表达所有权,一些引用不表达所有权。循环引用的一部分具有所有权关系,另一部分不涉及所有权关系。这样写只有所有权的指向关系才会影响到值的清理。
15.7.3. 把Rc<T>
换成Weak<T>
以防止循环引用
我们知道Rc::clone
会生成数据的强引用,使Rc<T>
内部的引用计数加1,而Rc<T>
只有在strong_count
为0时才会被清理。
然而,Rc<T>
实例通过调用Rc::downgrade
方法创建值的弱引用(Weak Reference)。这个方法的返回类型是weak<T>
(也是智能指针),每次调用Rc::downgrade
会为weak_count
加1而不是strong_count
,所以弱引用并不影响Rc<T>
的清理。
15.7.4. Strong vs. Weak
强引用(Strong Reference)是关于如何分析Rc<T>
实例的所有权。弱引用(Weak Reference)并不表达上述意思,使用它不会创建循环引用:当强引用数量为0时,弱引用就会自动断开。
使用弱引用之前需要保证它指向的值仍然存在。在Weak<T>
实例上调用upgrade
方法,返回Option<Rc<T>>
,通过Option
枚举来完成值是否存在的验证。
看个例子:
use std::cell::RefCell;
use std::rc::Rc;#[derive(Debug)]
struct Node {value: i32,children: RefCell<Vec<Rc<Node>>>,
}fn main() {let leaf = Rc::new(Node {value: 3,children: RefCell::new(vec![]),});let branch = Rc::new(Node {value: 5,children: RefCell::new(vec![Rc::clone(&leaf)]),});
}
Node
结构体代表一个节点,有两个字段:
value
字段存储当前值,类型是i32
。children
字段存储子节点,类型是RefCell<Vec<Rc<Node>>>
,这里使用Rc<T>
是为了让所有子节点共享所有权。具体来说,我们希望一个Node
拥有它的子节点,并且我们希望与储存这个节点的变量共享该所有权,以便我们可以直接访问树中的每个Node
。为此,我们将Vec<T>
项定义为Rc<Node>
类型的值。
这个例子的需求是每个节点都能指向自己的父节点和子节点。
再看一下main
函数:
- 创建了
leaf
,是Node
实例,value
为3,children
的值是被RefCell
包裹的空Vector
。 - 创建了
branch
,是Node
实例,value
为5,children
的值指向了leaf
。
这意味着leaf
它里面的Node
节点有两个所有者。目前可以通过branch
的children
字段访问leaf
;而反过来如果想通过leaf
来访问branch
暂时还不行,所以这里还需要修改。
想要实现需求就得用双向引用,但是双向的引用会创建循环引用,所以这时候就得使用Weak<T>
,避免产生循环:
struct Node {value: i32,parent: RefCell<Weak<Node>>,children: RefCell<Vec<Rc<Node>>>,
}
添加了parent
字段表示父节点,使用弱引用Weak<T>
。这里不用Vec<>
是因为这是个树结构,父节点只可能有一个。
这么写得把Weak<T>
引入作用域,还得重构下文,修改完后的整体代码如下:
use std::cell::RefCell;
use std::rc::{Rc, Weak};#[derive(Debug)]
struct Node {value: i32,parent: RefCell<Weak<Node>>,children: RefCell<Vec<Rc<Node>>>,
}fn main() {let leaf = Rc::new(Node {value: 3,parent: RefCell::new(Weak::new()),children: RefCell::new(vec![]),});println!("leaf parent = {:?}", leaf.parent.borrow().upgrade());let branch = Rc::new(Node {value: 5,parent: RefCell::new(Weak::new()),children: RefCell::new(vec![Rc::clone(&leaf)]),});*leaf.parent.borrow_mut() = Rc::downgrade(&branch);println!("leaf parent = {:?}", leaf.parent.borrow().upgrade());
}
在leaf
被创建后先打印了其parent
字段的内容(这时parent
字段还没有内容);在branch
被创建后打印了leaf
的parent
字段内容(这时其内容就是branch
)。
*leaf.parent.borrow_mut() = Rc::downgrade(&branch);
这句话把branch
的内容从Rc<Node>
变为Weak<Node>
,指向了leaf
的parent
字段:
leaf.parent
是表示leaf
父节点的字段,其类型是RefCell<Weak<Node>>
,所以可以使用borrow_mut
来获得其可变引用&mut RefMut<Weak<Node>>
- 使用解引用符号
*
把可变引用&mut RefMut<Weak<Node>>
变为RefMut<Weak<Node>>
- 通过
downgrade
方法把branch
的Rc<Node>
变为Weak<Node>
并赋给parent
输出:
leaf parent = None
leaf parent = Some(Node { value: 5, parent: RefCell { value: (Weak) },
children: RefCell { value: [Node { value: 3, parent: RefCell { value: (Weak) },
children: RefCell { value: [] } }] } })
- 第一次打印时其
parent
字段还没有被赋值,所以其值是Option
下的None
变体。 - 第二次打印时其父节点已被指定为
branch
,不是无限输出表明此代码没有创建循环引用。
最后我们通过修改main
函数——添加打印语句和修改作用域来看看强引用和弱引用的数量:
fn main() {let leaf = Rc::new(Node {value: 3,parent: RefCell::new(Weak::new()),children: RefCell::new(vec![]),});println!("leaf strong = {}, weak = {}",Rc::strong_count(&leaf),Rc::weak_count(&leaf),);{let branch = Rc::new(Node {value: 5,parent: RefCell::new(Weak::new()),children: RefCell::new(vec![Rc::clone(&leaf)]),});*leaf.parent.borrow_mut() = Rc::downgrade(&branch);println!("branch strong = {}, weak = {}",Rc::strong_count(&branch),Rc::weak_count(&branch),);println!("leaf strong = {}, weak = {}",Rc::strong_count(&leaf),Rc::weak_count(&leaf),);}println!("leaf parent = {:?}", leaf.parent.borrow().upgrade());println!("leaf strong = {}, weak = {}",Rc::strong_count(&leaf),Rc::weak_count(&leaf),);
}
代码的逻辑是:
-
创建完
leaf
之后打印里面有多少强引用和弱引用 -
这部分完了之后加了
{}
,创建了新的作用域:- 把
branch
的声明和指定leaf
父节点的操作放到里面 - 打印
branch
和leaf
在此时强引用、弱引用的数量
- 把
-
走出作用域后:
- 打印
leaf
的parent
- 打印
leaf
的强引用、弱引用
- 打印
输出:
leaf strong = 1, weak = 0
branch strong = 1, weak = 1
leaf strong = 2, weak = 0
leaf parent = None
leaf strong = 1, weak = 0
- 第1行:创建了
leaf
,只有一个强引用 - 第2行:创建了
branch
,由于branch
使用强引用对leaf
进行了关联,其parent
字段使用了Weak::new()
创建,所以branch
有1个强引用,一个弱引用 - 第3行:
branch
使用了leaf
的强引用,其本身在声明时又是一个强引用,所以此时leaf
就有两个强引用 - 第4行:由于
branch
已经走出其作用域,所以leaf
的parent
字段此时就为None
- 第5行:
branch
已经走出其作用域导致它对leaf
的强引用失效,leaf
的强引用减1变为1
相关文章:
【Rust自学】15.7. 循环引用导致内存泄漏
说句题外话,这篇文章真心很难,有看不懂可以在评论区问,我会尽快作答的。 喜欢的话别忘了点赞、收藏加关注哦(加关注即可阅读全文),对接下来的教程有兴趣的可以关注专栏。谢谢喵!(・ω…...
4.scala默认参数值
Scala具备给参数提供默认值的能力,这样调用者就可以忽略这些具有默认值的参数。 def log(message: String, level: String "INFO") println(s"$level: $message")log("System starting") // prints INFO: System starting log(&q…...
前端知识速记—JS篇:null 与 undefined
前端知识速记—JS篇:null 与 undefined 什么是 null 和 undefined? 1. undefined 的含义 undefined 是 JavaScript 中默认的值,表示某个变量已被声明但尚未被赋值。当尝试访问一个未初始化的变量、函数没有返回值时,都会得到 u…...
微信小程序中常见的 跳转方式 及其特点的表格总结(wx.navigateTo 适合需要返回上一页的场景)
文章目录 详细说明总结wx.navigateTo 的特点为什么 wx.navigateTo 最常用?其他跳转方式的使用频率总结 以下是微信小程序中常见的跳转方式及其特点的表格总结: 跳转方式API 方法特点适用场景wx.navigateTowx.navigateTo({ url: 路径 })保留当前页面&…...
【人工智能】基于Python的机器翻译系统,从RNN到Transformer的演进与实现
《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 机器翻译(Machine Translation, MT)作为自然语言处理领域的重要应用之一,近年来受到了广泛的关注。在本篇文章中,我们将详细探讨如何使…...
蓝桥备赛指南(5)
queue队列 queue是一种先进先出的数据结构。它提供了一组函数来操作和访问元素,但它的功能相对较简单,queue函数的内部实现了底层容器来存储元素,并且只能通过特定的函数来访问和操作元素。 queue函数的常用函数 1.push()函数:…...
蓝桥云客 好数
0好数 - 蓝桥云课 问题描述 一个整数如果按从低位到高位的顺序,奇数位(个位、百位、万位…)上的数字是奇数,偶数位(十位、千位、十万位…)上的数字是偶数,我们就称之为“好数”。 给定一个正…...
CF 764B.Timofey and cubes(Java实现)
题目分析 输入n个数字,首尾交换,奇数对换,偶数对不换 思路分析 存入数组,遍历时判断i%20时(数组下标0开始,所以题目分析没有错),对换 代码 import java.util.*;public class Main {public static void ma…...
四.3 Redis 五大数据类型/结构的详细说明/详细使用( hash 哈希表数据类型详解和使用)
四.3 Redis 五大数据类型/结构的详细说明/详细使用( hash 哈希表数据类型详解和使用) 文章目录 四.3 Redis 五大数据类型/结构的详细说明/详细使用( hash 哈希表数据类型详解和使用)2.hash 哈希表常用指令(详细讲解说明)2.1 hset …...
AIGC(生成式AI)试用 20 -- deepseek 初识
>> 基本概念 Ollama -- 运行大模型,管理运行AI大模型的工具,用来安装布置DeepSeek https://ollama.com/ , Get up and running with large language models. AnythingLLM -- 大模型增强应用,GUI大模型交互程序 Download AnythingLLM …...
你好!这是我自己的CSDN博客!
写于2025年1月30日 我是一个普通的嵌入式软件程序员,喜欢研究Linux(应用层跟内核从都有粗浅的涉略),单片机,操作系统和计算机体系架构等内容,目前是一枚普通的本科生。 笔者是一个朴素的开源主义者…...
将pandas.core.series.Series类型的小数转化成百分数
大年初二,大家过年好,蛇年行大运! 今天在编写一个代码的时候,使用 import pandas as pd产生了pandas.core.series.Series类型的数据,里面有小数,样式如下: 目的:将这些小数转化为百…...
[EAI-027] RDT-1B,目前最大的用于机器人双臂操作的机器人基础模型
Paper Card 论文标题:RDT-1B: a Diffusion Foundation Model for Bimanual Manipulation 论文作者:Songming Liu, Lingxuan Wu, Bangguo Li, Hengkai Tan, Huayu Chen, Zhengyi Wang, Ke Xu, Hang Su, Jun Zhu 论文链接:https://arxiv.org/ab…...
oracle中使用in 和 not in 查询效率分析
在Oracle数据库中,IN和NOT IN的查询效率受多种因素影响,以下是关键点总结和优化建议: 1. IN 的效率 优化方式: IN 通常会被优化为 OR条件 或 半连接(Semi-Join),如果子查询关联到外部表&#x…...
【python】四帧差法实现运动目标检测
四帧差法是一种运动目标检测技术,它通过比较连续四帧图像之间的差异来检测运动物体。这种方法可以在一定的程度上提高检测的准确性。 目录 1 方案 2 实践 ① 代码 ② 效果图 1 方案 具体的步骤如下: ① 读取视频流:使用cv2.VideoCapture…...
指针的介绍4【回调函数、qsort函数的运用】
1.回调函数 1.1定义 回调函数就是通过函数指针而被调用的函数 把函数的指针(地址)作为参数传递给另⼀个函数,当这个指针被⽤来调⽤其所指向的函数 时,被调⽤的函数就是回调函数 回调函数不是由该函数的实现⽅直接调⽤࿰…...
Attention Free Transformer (AFT)-2020论文笔记
名称: Attention Free Transformer (AFT) 来源: [2105.14103] An Attention Free Transformer 相关工作: #Approximatingthedotproduct #Sparselocalattention #Contextcompression #Eliminatingdotproductattention #MLPsforvision 创…...
Pyside的QWebEngineProfile类
QWebEngineProfile 是 PySide/Qt 中用于管理浏览器引擎(WebEngine)配置的类,属于 QtWebEngineCore 模块。它主要用于控制网页的全局行为,例如缓存、Cookie、持久化存储、用户代理(User-Agent)、代理设置等。…...
Java继承中的静态方法隐藏与实例变量隐藏:深入解析与最佳实践
引言 在Java面向对象编程中,继承是实现代码复用的核心机制。然而,继承中的静态方法(static)和实例变量的行为常常让开发者感到困惑。许多初学者甚至经验丰富的程序员容易混淆方法覆盖(Override)、方法隐藏…...
day6手机摄影社区,可以去苹果摄影社区学习拍摄技巧
逛自己手机的社区:即(手机牌子)摄影社区 拍照时防止抖动可以控制自己的呼吸,不要大喘气 拍一张照片后,如何简单的用手机修图? HDR模式就是让高光部分和阴影部分更协调(拍风紧时可以打开&…...
从AD的原理图自动提取引脚网络的小工具
这里跟大家分享一个我自己写的小软件,实现从AD的原理图里自动找出网络名称和引脚的对应。存成文本方便后续做表格或是使用简单行列编辑生成引脚约束文件(如.XDC .UCF .TCL等)。 我们在FPGA设计中需要引脚锁定文件,就是指示TOP层…...
H3CNE-31-BFD
Bidirectional Forwarding Dection,双向转发检查 作用:毫秒级故障检查,通常结合三层协议(静态路由、vrrp、ospf、BGP等),实现链路故障快速检查。 BFD配置示例 没有中间的SW,接口downÿ…...
Linux安装zookeeper
1, 下载 Apache ZooKeeperhttps://zookeeper.apache.org/releases.htmlhttps://zookeeper.apache.org/releases.htmlhttps://zookeeper.apache.org/releases.htmlhttps://zookeeper.apache.org/releases.htmlhttps://zookeeper.apache.org/releases.htmlhttps://zookeeper.apa…...
QPS 值是怎样进行计算和应用的
1. QPS 值的定义 QPS(Queries Per Second),即每秒查询率,指一台服务器每秒能够相应 的查询次数,是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准。它表示系统在某一特定时间内能够处理的查询请求的数量…...
【视频+图文详解】HTML基础4-html标签的基本使用
图文教程 html标签的基本使用 无序列表 作用:定义一个没有顺序的列表结构 由两个标签组成:<ul>以及<li>(两个标签都属于容器级标签,其中ul只能嵌套li标签,但li标签能嵌套任何标签,甚至ul标…...
内外网文件摆渡企业常见应用场景和对应方案
在如今的企业环境中,内外网文件摆渡的需求越来越常见,也变得越来越重要。随着信息化的不断推进,企业内部和外部之间的数据交换越来越频繁,如何安全、高效地进行文件传输成了一个关键问题。今天,咱就来聊聊内外网文件摆…...
基于微信小程序的新闻资讯系统设计与实现(LW+源码+讲解)
专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌。 技术范围:SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:…...
透视B/S架构与C/S架构:构建未来网络应用的智慧选择
透视B/S架构与C/S架构:构建未来网络应用的智慧选择 在信息技术迅猛发展的今天,网络架构的选择对企业和开发者来说至关重要。B/S架构(Browser/Server)与C/S架构(Client/Server)是两种主流的架构模式&#x…...
受击反馈HitReact、死亡效果Death Dissolve、Floating伤害值Text(末尾附 客户端RPC )
受击反馈HitReact 设置角色受击标签 (GameplayTag基本了解待补充) 角色监听标签并设置移动速度 创建一个受击技能,并应用GE 实现设置角色的受击蒙太奇动画 实现角色受击时播放蒙太奇动画,为了保证通用性,将其设置为一个函数,并…...
【网络】3.HTTP(讲解HTTP协议和写HTTP服务)
目录 1 认识URL1.1 URI的格式 2 HTTP协议2.1 请求报文2.2 响应报文 3 模拟HTTP3.1 Socket.hpp3.2 HttpServer.hpp3.2.1 start()3.2.2 ThreadRun()3.2.3 HandlerHttp() 总结 1 认识URL 什么是URI? URI 是 Uniform Resource Identifier的缩写&…...
mysql_init和mysql_real_connect的形象化认识
解析总结 1. mysql_init 的作用 mysql_init 用于初始化一个 MYSQL 结构体,为后续数据库连接和操作做准备。该结构体存储连接配置及状态信息,是 MySQL C API 的核心句柄。 示例: MYSQL *conn mysql_init(NULL); // 初始化连接句柄2. mysql_…...
01.01、判定字符是否唯一
01.01、[简单] 判定字符是否唯一 1、题目描述 实现一个算法,确定一个字符串 s 的所有字符是否全都不同。 在这一题中,我们的任务是判断一个字符串 s 中的所有字符是否全都不同。我们将讨论两种不同的方法来解决这个问题,并详细解释每种方法…...
[NOIP2007]矩阵取数游戏
点我写题 题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m的矩阵,矩阵中的每个元素aij均为非负整数。游戏规则如下: 1.每次取数时须从每行各取走一个元素,共n个。m次后取完矩阵所有元素; 2.每次取走的…...
C++模板初识
文章目录 一、函数模板1. 函数模板2. 函数模板、模板的特例化、非模板函数的重载关系3. 外部调用4. 模板的非类型参数5. 代码示例 二、类模板 一、函数模板 1. 函数模板 模板函数:在函数调用点,编译器用用户指定的类型,从原模板实例化一份函…...
C# Winform制作一个登录系统
using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;namespace 登录 {p…...
Kafka常见问题之 org.apache.kafka.common.errors.RecordTooLargeException
文章目录 Kafka常见问题之 org.apache.kafka.common.errors.RecordTooLargeException: The message is 1,048,576 bytes when serialized which is larger than the maximum request size.1. 错误解析2. 错误原因3. 错误复现案例3.1 生产者发送超大消息 4. 解决方案4.1 方法 1&…...
Python | Pytorch | Tensor知识点总结
如是我闻: Tensor 是我们接触Pytorch了解到的第一个概念,这里是一个关于 PyTorch Tensor 主题的知识点总结,涵盖了 Tensor 的基本概念、创建方式、运算操作、梯度计算和 GPU 加速等内容。 1. Tensor 基本概念 Tensor 是 PyTorch 的核心数据结…...
arm-linux-gnueabihf安装
Linaro Releases windows下打开wsl2中的ubuntu,资源管理器中输入: \\wsl$gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf.tar.xz 复制到/home/ark01/tool 在 Ubuntu 中创建目录: /usr/local/arm,命令如下: …...
C++ 堆栈分配的区别
这两种声明方式有什么区别 1.使用 new 关键字动态分配内存 动态分配:使用 new 关键字会在堆(heap)上分配内存,并返回一个指向该内存位置的指针。生命周期:对象的生命周期不会随着声明它的作用域结束而结束࿰…...
大数据相关职位 职业进阶路径
大数据相关职位 & 职业进阶路径 📌 大数据相关职位 & 职业进阶路径 大数据领域涵盖多个方向,包括数据工程、数据分析、数据治理、数据科学等,每个方向的进阶路径有所不同。以下是大数据相关职位的详细解析及其职业进阶关系。 &#…...
【计算机网络】设备更换地区后无法访问云服务器问题
文章目录 1. **服务器的公网 IP 是否变了**2. **服务器的防火墙或安全组设置**3. **本地运营商或 NAT 限制**4. **ISP 限制或端口封锁**5. **服务器监听地址检查** 1. 服务器的公网 IP 是否变了 在服务器上运行以下命令,检查当前的公网 IP:curl ifconfi…...
STM32标准库移植RT-Thread nano
STM32标准库移植RT-Thread Nano 哔哩哔哩教程链接:STM32F1标准库移植RT_Thread Nano 移植前的准备 stm32标准库的裸机代码(最好带有点灯和串口)RT-Thread Nano Pack自己的开发板 移植前的说明 本人是在读学生,正在学习阶段&a…...
【C++题解】1055. 求满足条件的整数个数
欢迎关注本专栏《C从零基础到信奥赛入门级(CSP-J)》 问题:1055. 求满足条件的整数个数 类型:简单循环 题目描述: 在 1∼n 中,找出能同时满足用 3 除余 2 ,用 5 除余 3 ,用 7 除余…...
DeepSeek R1-Zero vs. R1:强化学习推理的技术突破与应用前景
📌 引言:AI 推理的新时代 近年来,大语言模型(LLM) 的规模化扩展成为 AI 研究的主流方向。然而,LLM 的扩展是否真的能推动 通用人工智能(AGI) 的实现?DeepSeek 推出的 R1…...
冲刺蓝桥杯之速通vector!!!!!
文章目录 知识点创建增删查改 习题1习题2习题3习题4:习题5: 知识点 C的STL提供已经封装好的容器vector,也可叫做可变长的数组,vector底层就是自动扩容的顺序表,其中的增删查改已经封装好 创建 const int N30; vecto…...
【视频+图文详解】HTML基础1-html和css介绍、上网原理
图文详解 html介绍 概念:html是超文本标记语言的缩写,其英文全称为HyperText Markup Language,是用来搭建网站结构的语言,比如网页上的文字,按钮,图片,视频等。html的版本分为1.0、2.0、3.0、…...
Deepseek技术浅析(二):大语言模型
DeepSeek 作为一家致力于人工智能技术研发的公司,其大语言模型(LLM)在架构创新、参数规模扩展以及训练方法优化等方面都达到了行业领先水平。 一、基于 Transformer 架构的创新 1.1 基础架构:Transformer 的回顾 Transformer 架…...
OpenCV 版本不兼容导致的问题
问题和解决方案 今天运行如下代码,发生了意外的错误,代码如下,其中输入的 frame 来自于 OpenCV 开启数据流的读取 """ cap cv2.VideoCapture(RTSP_URL) print("链接视频流完成") while True:ret, frame cap.rea…...
03.04、化栈为队
03.04、化栈为队 1、题目描述 实现一个 MyQueue 类,该类用两个栈来实现一个队列。 2、解题思路 本题要求使用两个栈来实现一个队列。队列遵循先进先出(FIFO)的原则,而栈遵循后进先出(LIFO)的原则。因此…...
[Effective C++]条款49-52 内存分配
本文初发于 “天目中云的小站”,同步转载于此。 条款49 : 了解new-handler的行为 条款50 : 了解new和delete的合理替换时机 条款51 : 编写new和delete时需固守常规 条款52 :写了placement new也要写placement delete 条款49-52中详细讲述了定制new和d…...