【从零开始入门unity游戏开发之——C#篇04】栈(Stack)和堆(Heap),值类型和引用类型,以及特殊的引用类型string,垃圾回收( GC)
文章目录
- 知识回顾
- 一、栈(Stack)和堆(Heap)
- 1、什么是栈和堆
- 2、为什么要分栈和堆
- 3、栈和堆的区别
- 栈
- 堆
- 4、总结
- 二、值类型和引用类型
- 1、那么值类型和引用类型到底有什么区别呢?
- 值类型
- 引用类型
- 2、总结
- 三、特殊的引用类型string
- 1、为什么说string是特殊的引用类型?
- 2、理解字符串(string)引用类型
- 3、如何证明呢?
- 使用 `GetHashCode` 方法
- 通过断点调试直接查看变量指针内存地址
- 4、总结
- 四、垃圾回收( GC)
- 1. 什么是垃圾回收?
- 注意:
- 2. 为什么需要垃圾回收?
- 3. 如何工作?
- 堆分代
- 4. 什么时候发生垃圾回收?
- 5. 垃圾回收的优化和管理
- 6. 总结
- 五、总结
- 专栏推荐
- 完结
知识回顾
C# 中的变量类型可以分为 值类型
和 引用类型
两大类。
值类型
变量类型 | 描述 | 范围 |
---|---|---|
byte | 无符号8位整数 | 0 到 255 |
sbyte | 有符号8位整数 | -128 到 127 |
short | 有符号16位整数 | -32,768 到 32,767 |
ushort | 无符号16位整数 | 0 到 65,535 |
int | 有符号32位整数 | -2,147,483,648 到 2,147,483,647 |
uint | 无符号32位整数 | 0 到 4,294,967,295 |
long | 有符号64位整数 | -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 |
ulong | 无符号64位整数 | 0 到 18,446,744,073,709,551,615 |
float | 32 位单精度浮点数 | ±1.5 × 10^−45 到 ±3.4 × 10^38(精度约7位有效数字) |
double | 64 位双精度浮点数 | ±5.0 × 10^−324 到 ±1.7 × 10^308(精度约15–16位有效数字) |
decimal | 128 位高精度小数 | ±1.0 × 10^−28 到 ±7.9 × 10^28(精度约28–29位有效数字) |
bool | 8 位布尔型 | true 或 false |
char | 16 位单一字符型 | Unicode字符(0 到 65,535) |
引用类型
变量类型 | 描述 | 范围 |
---|---|---|
string | 字符串 | 任意长度的字符序列(理论上最多可达到 2GB) |
一、栈(Stack)和堆(Heap)
要了解值类型和引用类型的区别,我们得先得栈和堆的概率有个了解。
1、什么是栈和堆
简单理解就是,程序运行时,它的数据必须存储在内存中。栈和堆就是计算机内存中的两种不同的存储区域。
2、为什么要分栈和堆
通过分栈和堆,程序可以在性能和内存管理上做出平衡,从而让程序既高效又灵活。
3、栈和堆的区别
栈
- 栈空间比较小,但是读取速度快。
- 栈存储的是一些简单的数据
- 栈遵循
先进后出
原则,栈就像一个堆叠的盘子。你每次放入一个新盘子(数据),都会把它放在最上面。拿东西的时候,也都是从最上面拿,所以非常快速。 - 栈里的数据只在当前函数或方法运行时有效,一旦方法执行完毕,这些数据就会自动被销毁。
堆
- 堆空间比较大,但是读取速度慢。
- 堆存储的是一些较大的数据。
- 堆就像一个大大的垃圾堆,可以随意放东西。它不按照顺序来存放数据,而是根据需要分配空间,可以存储更复杂的对象
- 堆中的数据不会像栈那样自动清理。(但在 C# 中,
垃圾回收
会自动清理不再使用的对象)
4、总结
实际上,我们写程序并不需要关心内存是如何使用的,C#已经帮我们做好了。这里只是简单介绍这个概念,有些知识看不懂也没关系,比如垃圾回收
,后面肯定还会详细介绍。现在有个印象就行。
二、值类型和引用类型
在 C# 中,数据类型分为两大类:值类型(Value Types)和 引用类型(Reference Types)。
我们目前学了值类型和引用类型只有变量,但是其实不止
- 值类型其实还有
结构体(Struct)
、枚举(Enum)
, - 引用类型还有
类(Class)
、数组(Array)
、委托(Delegate)
。
这些我们后面会一一介绍,现在了解一下就行。
1、那么值类型和引用类型到底有什么区别呢?
因为只学了变量,这里就用变量举例。
值类型
- 直接存储数据,值类型的变量直接保存它们的数据。值类型直接存储在
栈
上。 - 值类型赋值时,会
复制值本身
。
比如
int a, b;
a = 100;
b = a;
Console.WriteLine("a的值:" + a);
Console.WriteLine("b的值:" + b);a = 20; // 重新给a赋值,b的值不会改变
Console.WriteLine("a的值:" + a);
Console.WriteLine("b的值:" + b);
打印结果,正如前面所说,重新给a赋值,b的值不会改变
画图说明
解释
:
-
声明变量 int a, b;
当你声明两个整数变量 a 和 b 时,编译器会在栈上为它们各自分配32位的存储空间。此时,这两个存储空间是空的,没有初始化任何值。 -
赋值 a = 100;
当你给变量 a 赋值为 20 时,栈上的存储空间 a 会被写入值 20。这个操作不会重新分配内存,而是直接在已经分配的内存位置写入新的值。 -
赋值 b = a;
当你执行 b = a; 时,栈上的存储空间 b 会被写入 a 的当前值。此时,a 和 b 都存储了值 20,但它们是独立的存储空间。 -
重新赋值 a = 20;
当你再次给 a 赋值为 20 时,栈上的存储空间 a 会被更新为新的值 20。这不会重新分配内存,而是直接在已经分配的内存位置写入新的值。
引用类型
- 间接存储数据,引用类型的变量保存的是对实际数据所在位置的
引用或地址
(也叫指针),而不是数据本身。引用类型存储在栈上的引用
(或指针)和堆上的实际数据
。 - 引用类型赋值时,会
复制引用
,但实际的数据不会复制。
画图说明,假设a b c都是引用类型
解释
:
-
声明引用类型 a 和 b;
这时 a 和 b 都是空引用,它们在栈上分配了空间,但它们指向的堆内存地址尚未确定,二者目前都没有引用任何实际的对象。
-
给 a 赋值:
此时,a 作为栈上的一个引用变量,指向堆上的值。b 仍然是空引用。
-
b = a; b 也指向 a 的堆值:
此时,a 和 b 都存储相同的堆内存地址,指向相同的堆对象。
-
a 修改为新值:
这时候a b的值就都变成了新值
-
重新定义 c,并给 c 赋值
此时,c 是一个新的引用类型变量,它在栈上存储了指向堆上c值的地址,且与 a 和 b 的值互不影响。
ps
:有些小伙伴可能会说了,前面不是说了string不就是引用类型吗,为什么不用string举例呢,这样不是更加直观?其实是因为string是特殊的引用类型,这个问题我接下来会说。
2、总结
特性 | 值类型 (Value Type) | 引用类型 (Reference Type) |
---|---|---|
存储方式 | 存储数据的值本身 | 存储数据的引用(内存地址) |
赋值行为 | 赋值时会复制数据,原始值和复制值互不影响 | 赋值时会复制引用,两个变量指向同一个对象 |
存储位置 | 通常存储在栈上 (stack),但结构体和其他类型可能存储在堆上 | 存储在堆上 (heap),引用存储在栈上 |
初始化 | 默认值为零或空值(如 0 、false 、null ) | 默认值为 null |
内存管理 | 系统负责管理内存(栈上分配的内存自动释放) | 由垃圾回收器 (GC) 管理内存 |
常见类型 | 基本数据类型(如 int 、float 等)、结构体、枚举 | 类、数组、委托、字符串等 |
三、特殊的引用类型string
1、为什么说string是特殊的引用类型?
学了前面引用类型的知识,我们可以拿string测试一下试试。
string str1, str2;
str1 = "名";
str2 = str1;
Console.WriteLine("str1的值:" + str1);
Console.WriteLine("str2的值:" + str2);str1 = "字";//重新赋值str1
Console.WriteLine("str1的值:" + str1);
Console.WriteLine("str2的值:" + str2);
按前面引用类型的概念,可能你想说第二次打印的结果应该是"字" "字"
。
实际上真是这样吗?我先来看看执行结果
有人会说,如果是值类型,结果倒还说的过去.但是不是说string是引用类型么?如果是引用类型的话。输出的结果难道不应该是: "名""名""字" "字"
么?
2、理解字符串(string)引用类型
理解字符串(string)在C#中的行为确实可能有些困惑,因为它们在某种程度上表现出值类型和引用类型的特性。让我们来详细解释一下。
-
字符串是
不可变
的
字符串在C#中是不可变的,这意味着一旦你创建了一个字符串对象,就不能修改它的内容。当你尝试修改一个字符串时,实际上是创建了一个新的字符串对象。 -
字符串为什么是
引用类型
因为它们在堆上分配内存,并且在栈上存储对堆上对象的引用。因此,多个变量可以引用同一个字符串对象。
3、如何证明呢?
使用 GetHashCode
方法
虽然这并不返回内存地址,但 GetHashCode 方法会返回一个与字符串内容相关的哈希值。这个值可以作为字符串的“标识符”,有时候在调试中,它能帮助你判断是否为同一个字符串实例。
string str1 = "xxxx";
string str2 = str1;
Console.WriteLine(str1.GetHashCode());
Console.WriteLine(str2.GetHashCode());str1 = "yyyy";
Console.WriteLine(str1.GetHashCode());
Console.WriteLine(str2.GetHashCode());
结果
通过断点调试直接查看变量指针内存地址
值类型,一开始内存地址就不一样
string引用类型,开始地址一样,重新赋值后地址不一样了
4、总结
字符串不叫值类型,因为它们确实具有引用类型的基本特性:在堆上分配内存,并且在栈上存储引用。尽管字符串的不可变性使得它们在某些方面表现得像值类型,但从技术上讲,它们仍然是引用类型。
由于字符串的不可变性,即使它们是引用类型,修改一个字符串变量不会影响其他引用相同字符串的变量。这是因为当你修改字符串时,实际上是创建了一个新的字符串对象,并将变量的引用指向了这个新对象。
string虽然方便,但是有一个小缺点就是频繁的改变string重新赋值会产生内存垃圾
,优化替代方案我们会在后面进行讲解
四、垃圾回收( GC)
垃圾回收(Garbage Collection,简称 GC)是 C# 等托管语言中的一个重要特性,它自动管理内存,帮助开发者避免内存泄漏和内存管理错误。理解垃圾回收机制对于你写高效、可靠的 C# 代码非常重要。下面我将从基础概念开始,逐步解释垃圾回收是如何工作的。
1. 什么是垃圾回收?
垃圾回收是由 .NET 运行时自动管理内存的过程,目的是清理不再使用的对象和资源,释放它们占用的内存空间,避免内存泄漏。它的核心任务是检测和清理不再被任何代码引用的对象。
在 C# 中,程序员无需手动分配和释放内存。运行时(CLR,公共语言运行时)会在合适的时机自动处理这些任务。这使得开发者可以专注于业务逻辑,而不必担心内存管理的复杂性。
注意:
- GC只负责
堆(Heap)
内存的垃圾回收。引用类型都是存在堆(Heap)
中的,所以它的分配和释放都通过垃圾回收机制来管理 栈(Stack)
上的内存是由系统自动管理的。值类型在栈(Stck)
中分配内存的,他们有自己的生命周期,不用对他们进行管理,会自动分配和释放
2. 为什么需要垃圾回收?
在很多编程语言中,内存管理是开发者的责任,手动管理内存(分配和释放)非常容易出错,导致内存泄漏或内存访问冲突。例如,开发者忘记释放内存,或者在内存已经被释放后再次访问它,都会导致程序出错。
C# 的垃圾回收机制通过自动管理内存,消除了这些问题。它能够:
- 自动清理不再需要的对象,释放内存。
- 防止内存泄漏。
- 确保对象不被提前销毁,避免内存错误。
3. 如何工作?
- 垃圾回收的过程是在遍历
堆(Heap)
上动态分配的所有对象 - 通过识别它们是否被引用来确定哪些对象是垃圾,哪些对像仍要被使用。
- 所谓的垃圾就是没有被任何变量,对象用的内容。
- 垃圾就需要被回收释放。
堆分代
为了提高垃圾回收的效率,.NET 的垃圾回收器采用了 分代回收策略。根据对象的存活时间,托管堆被划分为三个代:
- 代 0:
新创建的对象
通常放在这一代。它们存活时间很短,可能很快就会被回收。 - 代 1:如果一个对象在代 0 中存活了一段时间,它会被提升到代 1。代 1 中的对象通常存活时间较长。
- 代 2:这是最长寿命的对象所在的代。如果一个对象在代 1 中存活很长时间,它就会被提升到代 2。代 2 中的对象通常是程序中较为持久的对象,例如缓存或长时间运行的连接等。
代 0 的回收最为频繁,因为大部分对象在创建后很快就不再被引用,回收速度也最快。代 2 的回收最少,因为它涉及到的是长寿命对象的回收,过程较慢。
4. 什么时候发生垃圾回收?
垃圾回收并不是即时发生的,而是由 CLR 在需要时自动触发。通常,垃圾回收器会根据以下情况启动:
- 内存不足:当系统内存紧张,或堆中的内存达到一定阈值时,垃圾回收器会启动。
- 显式请求:程序员可以通过
GC.Collect()
显式触发垃圾回收,尽管通常不推荐这样做,因为垃圾回收器本身会在适当的时候自动工作。
5. 垃圾回收的优化和管理
虽然垃圾回收会自动进行内存管理,但为了提高程序的性能和资源使用效率,开发者可以做一些优化:
-
使用
IDisposable
接口:对于那些需要显式释放的资源(例如数据库连接、文件句柄等),实现IDisposable
接口并调用Dispose()
方法来显式释放资源,而不是等待垃圾回收器自动清理。 -
避免内存泄漏:保持引用清晰。不要无意间让不再需要的对象继续被引用,否则它们会一直存在于内存中,造成内存泄漏。
-
使用
using
语句:对于实现了IDisposable
接口的对象,可以使用using
语句来确保在使用完成后及时释放资源。
6. 总结
- 自动内存管理:垃圾回收器自动管理内存,程序员无需手动释放内存。
- 标记-清理算法:垃圾回收通过标记可达对象和清理不可达对象来释放内存。
- 分代回收:通过将对象分为不同的代(0、1、2代),提高垃圾回收的效率。
- 内存泄漏:尽管垃圾回收器可以自动清理不再使用的对象,但一些显式资源(如文件句柄、数据库连接)仍然需要开发者手动管理。
五、总结
程序运行时,它的数据必须存储在内存中,计算机内存可以分为栈
和堆
两种不同的存储区域。
C#数据类型可以分为 值类型
和 引用类型
两大类。
- 值类型直接存储数据,引用类型存储数据的引用(地址)
- 值类型数据存储在
栈
中,引用类型存储在堆
中
栈空间比较小,但是读取速度快。栈里的数据只在当前函数或方法运行时有效,一旦方法执行完毕,这些数据就会自动被销毁。
堆空间比较大,但是读取速度慢。堆内存的分配相对来说比栈内存更昂贵。每次创建引用类型对象时,都需要在堆中分配内存。堆中的数据不会像栈那样自动清理。
如果已经不再需要的内存没有被及时释放,会导致这些内存无法被回收和重用,最终可能耗尽系统的内存资源,导致程序崩溃或性能下降——也就是我们说的内存泄漏
。
好在,C# 为我们提供了一个自动内存管理机制——垃圾回收
(GC),它会在特定条件
下自动回收堆
中未使用的对象。,帮助开发者避免手动释放内存,减少内存泄漏的风险。
特定条件
指的是当程序的内存使用达到一定的阈值时,垃圾回收器会启动来清理不再使用的对象。(手动调用就不要理了,不推荐用)
C# 的垃圾回收器使用了“分代回收
”的概念,它将堆上的数据分成三代(0代、1代、2代
)进行存储,来优化垃圾回收的性能。
- 刚刚创建的数据在
0代
,经过一次GC后,如果还存活,就进入1代
,再经过一次GC,如果还存活,就进入2代
。
垃圾回收并不是免费的,它会占用一定的 CPU 资源和时间。在大规模对象创建和销毁的情况下,垃圾回收可能导致短暂的性能波动。
垃圾回收
是 自动
且 高效
的,虽然它很方便,但也可能带来一些性能开销。因此,开发者在编写程序时,仍需注意如何合理使用内存和优化对象管理。垃圾回收并不完美,C# 的垃圾回收系统已经在大多数情况下做得相当优秀。
专栏推荐
地址 |
---|
【从零开始入门unity游戏开发之——C#篇】 |
【从零开始入门unity游戏开发之——unity篇】 |
【制作100个Unity游戏】 |
【推荐100个unity插件】 |
【实现100个unity特效】 |
【unity框架开发】 |
完结
赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注
,你的每一次支持
都是我不断创作的最大动力。当然如果你发现了文章中存在错误
或者有更好的解决方法
,也欢迎评论私信告诉我哦!
好了,我是向宇
,https://xiangyu.blog.csdn.net
一位在小公司默默奋斗的开发者,闲暇之余,边学习边记录分享,站在巨人的肩膀上,通过学习前辈们的经验总是会给我很多帮助和启发!如果你遇到任何问题,也欢迎你评论私信或者加群找我, 虽然有些问题我也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~
相关文章:

【从零开始入门unity游戏开发之——C#篇04】栈(Stack)和堆(Heap),值类型和引用类型,以及特殊的引用类型string,垃圾回收( GC)
文章目录 知识回顾一、栈(Stack)和堆(Heap)1、什么是栈和堆2、为什么要分栈和堆3、栈和堆的区别栈堆 4、总结 二、值类型和引用类型1、那么值类型和引用类型到底有什么区别呢?值类型引用类型 2、总结 三、特殊的引用类…...

基于微信小程序的小区疫情防控ssm+论文源码调试讲解
第2章 程序开发技术 2.1 Mysql数据库 为了更容易理解Mysql数据库,接下来就对其具备的主要特征进行描述。 (1)首选Mysql数据库也是为了节省开发资金,因为网络上对Mysql的源码都已进行了公开展示,开发者根据程序开发需…...

第P2周:Pytorch实现CIFAR10彩色图片识别
🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 目标 实现CIFAR-10的彩色图片识别实现比P1周更复杂一点的CNN网络 具体实现 (一)环境 语言环境:Python 3.10 编 译 器: …...

CTFHub 命令注入-综合练习(学习记录)
综合过滤练习 命令分隔符的绕过姿势 ; %0a %0d & 那我们使用%0a试试,发现ls命令被成功执行 /?ip127.0.0.1%0als 发现一个名为flag_is_here的文件夹和index.php的文件,那么我们还是使用cd命令进入到文件夹下 http://challenge-438c1c1fb670566b.sa…...

OpenCV目标检测 级联分类器 C++实现
一.目标检测技术 目前常用实用性目标检测与跟踪的方法有以下两种: 帧差法 识别原理:基于前后两帧图像之间的差异进行对比,获取图像画面中正在运动的物体从而达到目标检测 缺点:画面中所有运动中物体都能识别 举个例子…...

QT6 Socket通讯封装(TCP/UDP)
为大家分享一下最近封装的以太网socket通讯接口 效果演示 如图,界面还没优化,后续更新 废话不多说直接上教程 添加库 如果为qmake项目中,在.pro文件添加 QT network QT core gui QT networkgreaterThan(QT_MAJOR_VERS…...

elasticsearch设置密码访问
1 用户认证介绍 默认ES是没有设置用户认证访问的,所以每次访问时,直接调相关API就能查询和写入数据。现在做一个认证,只有通过认证的用户才能访问和操作ES。 2 开启加密设置 1.生成证书文件 /usr/share/elasticsearch/bin/elasticsearch-…...

彻底理解如何优化接口性能
作为后端研发,必须要掌握怎么优化接口的性能或者说是响应时间,这样才能提高系统的系能,本文通过如下两个方面进行分析: 一.后端代码 有如下几步: 1.缓存机制 这是最场景的方式,当使用了缓存后,…...

C# 位运算
一、数据大小对应关系 说明: 将一个数据每左移一位,相当于乘以2。因此,左移8位就是乘以2的8次方,即256。 二、转换 1、 10进制转2进制字符串 #region 10进制转2进制字符串int number1 10;string binary Convert.ToString(num…...

【Flink-scala】DataStream编程模型之状态编程
DataStream编程模型之状态编程 参考: 1.【Flink-Scala】DataStream编程模型之数据源、数据转换、数据输出 2.【Flink-scala】DataStream编程模型之 窗口的划分-时间概念-窗口计算程序 3.【Flink-scala】DataStream编程模型之窗口计算-触发器-驱逐器 4.【Flink-scal…...

RabbitMQ的核心组件有哪些?
大家好,我是锋哥。今天分享关于【RabbitMQ的核心组件有哪些?】面试题。希望对大家有帮助; RabbitMQ的核心组件有哪些? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 RabbitMQ是一个开源的消息代理(Messag…...

【Linux基础】基本开发工具的使用
目录 一、编译器——gcc/g的使用 gcc/g的安装 gcc的安装: g的安装: gcc/g的基本使用 gcc的使用 g的使用 动态链接与静态链接 程序的翻译过程 1. 一个C/C程序的构建过程,程序从源代码到可执行文件必须经历四个阶段 2. 理解选项的含…...

常见的数据结构和应用场景
数据结构是计算机科学中的基础概念,用于组织和存储数据,以便能够高效地访问和修改。下面是几种常见数据结构及其代表性应用场景: 1. 数组(Array) 问题解决:数组是一种线性数据结构,用于存储相…...

爬虫基础学习
爬虫概念与工作原理 爬虫是什么:爬虫(Web Scraping)是自动化地访问网站并提取数据的技术。它模拟用户浏览器的行为,通过HTTP请求访问网页,解析HTML文档并提取有用信息。 爬虫的基本工作流程: 发送HTTP请求…...

C++对象数组对象指针对象指针数组
一、对象数组 对象数组中的每一个元素都是同类的对象; 例1 对象数组成员的初始化 #include<iostream> using namespace std;class Student { public:Student( ){ };Student(int n,string nam,char s):num(n),name(nam),sex(s){};void display(){cout<&l…...

D96【python 接口自动化学习】- pytest进阶之fixture用法
day96 pytest的fixture详解(三) 学习日期:20241211 学习目标:pytest基础用法 -- pytest的fixture详解(三) 学习笔记: fixture(scop"class") (scop"class") 每一个类调…...

【算法】动态规划中01背包问题解析
📢博客主页:https://blog.csdn.net/2301_779549673 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正! 📢本文由 JohnKi 原创,首发于 CSDN🙉 📢未来很长&#…...

选择WordPress和Shopify:搭建对谷歌SEO友好的网站
在建设网站时,不仅要考虑它的美观和功能性,还要关注它是否对谷歌SEO友好。如果你希望网站能够获得更好的搜索排名,WordPress和Shopify是两个值得推荐的建站平台。 WordPress作为最流行的内容管理系统,其强大的灵活性和丰富的插件…...

代理IP与生成式AI:携手共创未来
目录 代理IP:网络世界的“隐形斗篷” 1. 隐藏真实IP,保护隐私 2. 突破网络限制,访问更多资源 生成式AI:创意与效率的“超级大脑” 1. 提高创作效率 2. 个性化定制 代理IP与生成式AI的协同作用 1. 网络安全 2. 内容创作与…...

iOS 应用的生命周期
Managing your app’s life cycle | Apple Developer Documentation Performance and metrics | Apple Developer Documentation iOS 应用的生命周期状态是理解应用如何在不同状态下运行和管理资源的基础。在 iOS 开发中,应用生命周期管理的是应用从启动到终止的整…...

Elasticsearch 集群快照的定期备份设置指南
Elasticsearch 集群快照的定期备份设置指南 概述 快照: 在给定时刻对整个集群或者单个索引进行备份,以便在之后出现故障时可以基于之前备份的快照进行快速恢复。 前提条件: 准备一个备份存储盘,本指南采用的是AWS EFS文件系统做…...

Docker--Docker Image(镜像)
什么是Docker Image? Docker镜像(Docker Image)是Docker容器技术的核心组件之一,它包含了运行应用程序所需的所有依赖、库、代码、运行时环境以及配置文件等。 简单来说,Docker镜像是一个轻量级、可执行的软件包&…...

C++ 中的序列化和反序列化
一、C 中的序列化和反序列化 (一)基本概念 在 C 中,序列化是将对象转换为字节流的过程,反序列化则是从字节流重新构建对象的过程。这对于存储对象状态到文件、网络传输等场景非常有用。 (二)简单的序列化…...

我的Github学生认证申请过程
先说结论:很简单。 学生认证链接:GitHub Education GitHub 1. 首先你得绑定edu邮箱。这个应该没什么问题,Github也会提示。 2. 我是在学校里面、使用流量而非WiFi申请的,听说地理位置很重要,该给的权限(…...

信奥题解:勾股数计算中的浮点数精度问题
来源:GESP C++ 二级模拟题 本文给出官方参考答案的详细解析,包括每一部分的功能和关键点,以及与浮点数精度相关的问题的分析。 题目描述 勾股数是很有趣的数学概念。如果三个正整数a 、b 、c ,满足 a 2 + b 2 = c 2 a^2 + b^2 = c^2 a2+b2=c2 ,而且1 ≤ a ≤ b ≤ c ,…...

重生之我在学Vue--第2天 Vue 3 Composition API 与响应式系统
重生之我在学Vue–第2天 Vue 3 Composition API 与响应式系统 文章目录 重生之我在学Vue--第2天 Vue 3 Composition API 与响应式系统前言一、Composition API 核心概念1.1 什么是 Composition API?1.2 Composition API 的核心工具1.3 基础用法示例 二、响应式系统2…...

【AI知识】逻辑回归介绍+ 做二分类任务的实例(代码可视化)
1. 分类的基本概念 在机器学习的有监督学习中,分类一种常见任务,它的目标是将输入数据分类到预定的类别中。具体来说: 分类任务的常见应用: 垃圾邮件分类:判断一封电子邮件是否是垃圾邮件 。 医学诊断:…...

Mysql 笔记2 emp dept HRs
-- 注意事项 -- 1.给数据库和表起名字时尽量选择全小写 -- 2.作为筛选条件的字符串是否区分大小写看设置的校对规则utf8_bin 区分 drop database if exists hrs; create database hrs default charset utf8 collate utf8_general_ci;use hrs; drop table if exists tb_emp; dro…...

MySQL和Oracle的区别
MySQL和Oracle的区别 MySQL是轻量型数据库,并且免费,没有服务恢复数据。 Oracle是重量型数据库,收费,Oracle公司对Oracle数据库有任何服务。 1.对事务的提交 MySQL默认是自动提交,而Oracle默认不自动提交࿰…...

实验12 C语言连接和操作MySQL数据库
一、安装MySQL 1、使用包管理器安装MySQL sudo apt update sudo apt install mysql-server2、启动MySQL服务: sudo systemctl start mysql3、检查MySQL服务状态: sudo systemctl status mysql二、安装MySQL开发库 sudo apt-get install libmysqlcli…...