【C++】深入理解字符变量取地址的特殊性与内存管理机制详解
文章目录
- 💯前言
- 💯栈内存中的变量分配:谁先谁后?
- `cout` 的输出行为:按顺序执行,按地址递增读取
- 代码执行顺序与内存布局的关系
- 编译器优化的影响
- 💯字符变量取地址的特殊性
- 第一种情况:`d` 为 3.14 时的乱码现象
- 为什么 `&c` 会导致乱码?
- `double d` 的初始化如何影响 `&c` 的输出?
- 第二种情况:`d` 为 0.0 时的输出变化
- 💯栈分配与 `cout` 输出顺序的关系
- 💯验证栈中地址的分配顺序
- char地址行为背后的历史原因
- 地址对齐与内存布局
- 💯小结
💯前言
- 在 C++ 编程中,字符变量的取地址行为和内存布局对程序行为有着深远的影响,尤其是在打印变量地址和访问内存内容时。今天,我将带你逐步探索这些细节。理解这些问题不仅有助于加深对内存管理机制的理解,还有助于避免一些常见但隐蔽的错误。以下内容基于我与一位用户的深入对话,系统地整理了栈内存分配、cout 行为、字符地址访问带来的特殊情况以及乱码原因等核心概念。
C++ 参考手册
💯栈内存中的变量分配:谁先谁后?
在 C++ 中,局部变量通常分配在栈上。栈的内存分配方向是从高地址向低地址,也就是说,在栈中,变量的声明顺序决定了它们的内存地址。先声明的变量会被分配到更高的地址,后声明的变量则会被分配到更低的地址。
在我们的代码示例中,变量声明如下:
int n;
float f;
double d = 0.0;
char c = '*';
根据栈内存的分配规则,这些变量会依次从高地址向低地址排列:
n
作为第一个声明的变量,分配在栈的最顶部,即最高地址。- 接着声明的
f
会分配在比n
略低的地址。 - 然后是
d
,它的地址比f
更低。 - 最后,
c
分配在栈中最底部,即最低的地址。
所以,在栈中,谁在最后声明,谁就会占据最低的地址。
cout
的输出行为:按顺序执行,按地址递增读取
在这段代码中,我们用 cout
输出各个变量的地址:
cout << "address of n: " << &n << endl;
cout << "address of f: " << &f << endl;
cout << "address of d: " << &d << endl;
cout << "address of c: " << &c << endl;
这些 cout
语句是按书写顺序依次执行的,这意味着它们的输出顺序和代码中的顺序是一致的。并没有因为 c
在栈内存中占据最低地址而使得 cout
优先输出 c
的地址。
然而,当涉及 cout << &c
时,我们要了解 cout
在面对指针时的行为。特别是对于 char*
类型指针,cout
会将其解释为指向字符串的指针,并试图从该地址开始按字节逐个读取字符,直到遇到字符串结束符 \0
为止。这是 cout
在输出 char*
时的特殊处理方式。
对于 &c
来说,c
是一个字符类型变量,因此 &c
是一个指向字符的指针,cout
会从 &c
指向的地址开始读取字符。如果没有遇到 \0
,就会继续读取后续的内存内容,这时就可能会输出一些不期望的“乱码”。
代码执行顺序与内存布局的关系
在我们的讨论中,还提到了代码执行顺序和内存布局的关系。代码的执行顺序与变量在内存中的地址无关,即使 c
在栈中是最低的地址,cout << &c
也不会最先被执行。cout
语句是按照代码的书写顺序依次执行的,变量的内存地址只是影响了它们在栈中的位置,而不会影响执行的先后顺序。
编译器优化的影响
值得注意的是,编译器优化可能会对内存布局和变量的分配顺序产生影响。现代编译器在编译代码时,可能会对变量的分配和布局进行优化,以提高程序的运行效率。这些优化有时会打乱变量在内存中的顺序,从而使得地址的排列和我们在代码中声明的顺序不完全一致。因此,虽然通常情况下,栈上的局部变量分配符合上述规律,但编译器的优化可能带来不同的结果。
编译器优化的过程是非常复杂且智能化的,其目的是尽可能减少代码运行时间、内存占用或能量消耗。例如,编译器可能会对某些局部变量进行寄存器分配,也就是将它们直接存储在CPU
寄存器中而不是栈中。这种优化方式可能导致某些变量根本没有一个稳定的内存地址,这也就进一步影响了我们对内存布局的理解。此外,编译器还可能会将多个不相邻的变量合并在一起或者调整变量的位置以适应CPU
的缓存行对齐,从而加快数据访问速度。
这些优化有时是不可预测的,因此,如果我们对代码的行为有特定的假设(比如假设栈中变量的严格顺序),那么在打开编译器优化的情况下,可能会看到与预期不符的结果。因此,在涉及对内存布局的敏感代码时,应该考虑编译器的行为并进行适当的优化级别控制(例如通过编译器选项禁用某些优化,或者明确指定变量的存储方式)。
💯字符变量取地址的特殊性
第一种情况:d
为 3.14 时的乱码现象
在最初的代码中,当 double d = 3.14;
时,我们输出变量地址:
#include <iostream>
using namespace std;int main() {int n;float f;double d = 3.14;char c = '*';cout << "address of n: " << &n << endl; cout << "address of f: " << &f << endl; cout << "address of d: " << &d << endl; cout << "address of c: " << &c << endl; return 0;
}
其输出为:
address of n: 0x70fe1c
address of f: 0x70fe18
address of d: 0x70fe10
address of c: *乱码字符
在这个输出中,&c
的输出并不是一个普通的内存地址,而是包含了字符 *
后加上一些乱码字符。这种现象的原因是 cout
将 &c
解释为 char*
,并从 c
的地址开始读取字符。而 c
后续的内存没有被初始化为 \0
,因此读取到了一些无法预期的内存内容,这些内容以乱码的形式呈现。
为什么 &c
会导致乱码?
在我们的讨论中,一个重要的现象是:当 c
后续的内存没有初始化为 \0
时,cout << &c
会输出一些“乱码”。这是因为 cout
从 &c
开始读取字符时,如果没有遇到字符串结束符 \0
,它会继续读取直到遇到为止。这种行为往往会导致输出一些不可预期的内容,因为后续的内存可能包含未初始化的数据,或者是其他变量的残留值。
double d
的初始化如何影响 &c
的输出?
在我们的代码中,当 double d = 3.14;
时,后续内存并没有被清零,因此在 cout << &c
时,c
后面的内存可能包含非零的垃圾值,这些垃圾值被解释为字符就导致了输出中的乱码。
但是,当我们将 d
的值改为 0.0
时,情况发生了变化。因为 0.0
的二进制表示是全零,这就意味着在初始化 d
的时候,其占据的内存区域很可能被设置为零。当 c
后面的内存变成了零,这些零在字符表示中相当于字符串结束符 \0
,这就使得 cout
在读取 &c
时很快遇到结束符,从而没有输出乱码。
第二种情况:d
为 0.0 时的输出变化
当我们将 double d
的值从 3.14
改为 0.0
后,输出情况有所不同:
#include <iostream>
using namespace std;int main() {int n;float f;double d = 0.0;char c = '*';cout << "address of n: " << &n << endl; cout << "address of f: " << &f << endl; cout << "address of d: " << &d << endl; cout << "address of c: " << &c << endl; return 0;
}
其输出为:
address of n: 0x70fe1c
address of f: 0x70fe18
address of d: 0x70fe10
address of c: *
在这种情况下,cout << &c
的输出只包含字符 *
,没有了之前的乱码。这是因为当 d
被初始化为 0.0
时,其占据的内存被清零,导致 c
后面很快遇到字符串结束符 \0
,从而避免了乱码的产生。
💯栈分配与 cout
输出顺序的关系
有人可能会问:cout
是从下往上输出的吗?其实不是的。cout
的输出顺序是严格按照代码的书写顺序进行的,而与变量在内存中的位置无关。在栈内存中,虽然变量 c
占据最低的地址,但 cout
并不会因此优先输出 c
的内容。它们的输出顺序完全取决于代码的执行顺序。
关于 cout << &c
的输出行为,我们也可以进一步理解它是如何按地址递增的顺序来读取数据的。cout
从 &c
指向的地址开始,按字节逐个向更高的地址读取,直到遇到结束符 \0
。这种递增的读取顺序导致了 cout
输出的内容是从变量 c
开始,向后逐字节扩展。如果 c
的后面没有合适的结束符,cout
就可能输出其他内存中的数据。
💯验证栈中地址的分配顺序
为了验证栈中变量的分配顺序,可以使用以下代码来查看各个变量的地址,进而确认变量的地址分布是否符合栈内存的分配规律:
#include <iostream>
using namespace std;int main() {int n;float f;double d = 0.0;char c = '*';cout << "Address of n: " << &n << endl;cout << "Address of f: " << &f << endl;cout << "Address of d: " << &d << endl;cout << "Address of c: " << (void*)&c << endl;return 0;
}
假设输出结果如下:
Address of n: 0x7ffe6e1c
Address of f: 0x7ffe6e18
Address of d: 0x7ffe6e10
Address of c: 0x7ffe6e08
在上述代码中,只有&c
的输出表现为打印字符*
,而其他变量的地址都是以十六进制的形式正常显示。通过强制类型转换(void*)&c
,我们可以成功地打印字符变量c
的内存地址。
从结果可以看到,地址是从高到低的,符合栈的分配顺序:先声明的变量地址更高,最后声明的变量地址更低。因此,在栈中声明的变量,谁在最后声明,谁的地址就是最低的。
char地址行为背后的历史原因
C++之所以对char*
指针采用特殊处理,是为了向下兼容C语言。在C语言中,字符串通常以字符数组的形式存在,且由一个char*
指针指向数组的起始地址。cout
直接支持这种类型的指针输出,可以让程序员方便地打印字符串。这种方便性在处理真正的C风格字符串时非常有用,但在打印单个字符的地址时就产生了误导性。
在现代C++中,尽管有了std::string
这样的标准类来表示字符串,但这种特殊的处理方式仍然保留了下来。因此,当涉及char
的地址时,程序员需要特别注意,确保输出的是正确的内容。
地址对齐与内存布局
在讨论指针和地址的时候,另一个重要的话题是不同数据类型在内存中的地址对齐。不同的数据类型在内存中的存储方式可能会影响它们的地址。通常,char
类型的变量只占用一个字节,因此它可以被存储在任意地址上,而其他类型(如int
和double
)可能有更高的对齐要求。
地址对齐是一种硬件层面的优化,目的是提高内存访问的效率。大多数现代系统中,int
类型的变量通常要求4字节对齐,即它们的起始地址必须是4的倍数,而double
类型则可能需要8字节对齐。这些对齐要求可以导致不同类型变量的地址之间有明显的差异。相较而言,char
变量可以存储在任何内存地址上,因此它的地址看起来更加“灵活”,这也解释了为什么当你连续定义几个char
变量时,它们的地址是逐字节递增的,而int
或double
类型则是按4或8字节递增。
💯小结
通过今天的讨论,我们深入理解了以下几点:
- 栈内存的分配顺序:栈内存从高地址向低地址分配,谁在最后声明,谁的地址最低。
cout
的输出行为**:cout
是按照代码书写的顺序依次执行的,输出地址时,按内存地址从低到高递增读取,直到遇到\0
结束。- 乱码的原因:
cout << &c
会将&c
解释为char*
指针,尝试按字符串输出,因此如果后续内存没有\0
,可能会输出乱码。 - 初始化的影响:将
d
设置为0.0
会影响后续内存的内容,使得cout << &c
的输出不再出现乱码。 - 编译器优化的影响:编译器可能会对内存布局进行优化,从而导致实际的内存地址与变量声明顺序不一致。这些优化有时会使程序更加高效,但也可能会对程序员对内存的预期造成混淆。
这些知识点不仅让我们对 C++ 中的内存管理有了更深入的理解,还帮助我们更好地理解 cout
的行为和变量之间的关系。在实际编程中,这些细节能够帮助我们避免一些微妙的错误,同时写出更健壮、更可靠的代码。希望这些内容能对你有所帮助,让你在编程中更加游刃有余。
无论是栈内存的分配顺序还是 cout
输出的行为,每一个细节的背后都是 C++ 的设计理念和计算机体系结构之间的微妙配合。理解这些内容的意义不仅仅在于写出正确的代码,而是为编写高效、可靠的程序打下坚实的基础。希望你通过这些讨论,对内存、变量、和编译器的关系有更清晰的认识。未来,在遇到类似的问题时,你能够更自信地找到原因,并作出正确的判断。
相关文章:
【C++】深入理解字符变量取地址的特殊性与内存管理机制详解
博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 💯前言💯栈内存中的变量分配:谁先谁后?cout 的输出行为:按顺序执行,按地址递增读取代码执行顺序与内存布局的关系编译器优化的影响 &…...
【银河麒麟操作系统真实案例分享】内存黑洞导致服务器卡死分析全过程
了解更多银河麒麟操作系统全新产品,请点击访问 麒麟软件产品专区:https://product.kylinos.cn 开发者专区:https://developer.kylinos.cn 文档中心:https://documentkylinos.cn 现象描述 机房显示器连接服务器后黑屏ÿ…...
蓝桥杯软件赛系列---lesson1
🌈个人主页:羽晨同学 💫个人格言:“成为自己未来的主人~” 我们今天会再开一个系列,那就是蓝桥杯系列,我们会从最基础的开始讲起,大家想要备战明年蓝桥杯的,让我们一起加油。 工具安装 DevC…...
工业异常检测-CVPR2024-新的3D异常数据合成办法和自监督网络IMRNet
论文:https://arxiv.org/pdf/2311.14897v3.pdf 项目:https://github.com/chopper-233/anomaly-shapenet 这篇论文主要关注的是3D异常检测和定位,这是一个在工业质量检查中至关重要的任务。作者们提出了一种新的方法来合成3D异常数据&#x…...
HeidiSQL:MySQL图形化管理工具深度解析
本文还有配套的精品资源,点击获取 简介:HeidiSQL是一款开源的MySQL图形化管理工具,适用于多种数据库系统,如MySQL、MariaDB、SQL Server、PostgreSQL和SQLite。其提供的直观操作界面和丰富的功能简化了数据库操作,包…...
【Redis】深入解析Redis缓存机制:全面掌握缓存更新、穿透、雪崩与击穿的终极指南
文章目录 一、Redis缓存机制概述1.1 Redis缓存的基本原理1.2 常见的Redis缓存应用场景 二、缓存更新机制2.1 缓存更新的策略2.2 示例代码:主动更新缓存 三、缓存穿透3.1 缓存穿透的原因3.2 缓解缓存穿透的方法3.3 示例代码:使用布隆过滤器 四、缓存雪崩4…...
Flask使用Celery与多进程管理:优雅处理长时间任务与子进程终止技巧(multiprocessing)(subprocess)
在许多任务处理系统中,我们需要使用异步任务队列来处理繁重的计算或长时间运行的任务,如模型训练。Celery是一个广泛使用的分布式任务队列,而在某些任务中,尤其是涉及到调用独立脚本的场景中,我们需要混合使用multipro…...
【PyTorch】torch.distributed.elastic.multiprocessing.errors.ChildFailedError:
报错说明 torch.distributed.elastic.multiprocessing.errors.ChildFailedError: 报错如图所示 报错分析 该报错是 torch 和 CUDA 版本不兼容导致。 (一般N卡自带的CUDA版本与最新的torch版本相差较大) 解决方案 1.查看自己的CUDA版本 # 查看自己的…...
使用android studio写一个Android的远程通信软件(APP),有通讯的发送和接收消息界面
以下是使用 Android Studio 基于 Java 语言编写一个简单的 Android APP 实现远程通信(这里以 TCP 通信为例)的代码示例,包含基本的通信界面以及发送和接收消息功能。 1. 创建项目 打开 Android Studio,新建一个 Empty Activity …...
突破空间限制!从2D到3D:北大等开源Lift3D,助力精准具身智能操作!
文章链接:https://arxiv.org/pdf/2411.18623 项目链接:https://lift3d-web.github.io/ 亮点直击 提出了Lift3D,通过系统地提升隐式和显式的3D机器人表示,提升2D基础模型,构建一个3D操作策略。 对于隐式3D机器人表示&a…...
Android KEY的哪些事儿
目录 一、APK应用签名 1、什么是APK应用签名? 1.1 目的和作用? 1.2 长什么样子? 2、APK应用签名使用流程 步骤一:如何生成APK应用签名文件? 步骤二:如何集成APK应用签名文件? 步骤三&am…...
李宏毅深度学习-Pytorch Tutorial2
什么是张量? 张量(Tensor)是深度学习和机器学习中一个非常基础且重要的概念。在数学上,张量可以被看作是向量和矩阵的泛化。简单来说,张量是一种多维数组,它可以表示标量(0维)、向量…...
【译】为 SAP 表维护视图 (SM30) 创建选择屏幕
原文标题:Create Selection Screen for SAP Table Maintenance View (SM30) 原文链接: https://www.saphub.com/abap-dictionary/sap-abap-tmg-selection-screen/ 通常,带有单个屏幕的 SAP 表维护视图 (SM30) 会显示表中的所有记录ÿ…...
element Plus中 el-table表头宽度自适应,不换行
在工作中,使用el-table表格进行开发后,遇到了小屏幕显示器上显示表头文字会出现换行展示,比较影响美观,因此需要让表头的宽度变为不换行,且由内容自动撑开。 以下是作为工作记录,用于demo演示教程 先贴个…...
C语言程序设计P5-4【应用函数进行程序设计 | 第四节】——知识要点:数组作函数参数
知识要点:数组作函数参数 视频: 目录 一、任务分析 二、必备知识与理论 三、任务实施 一、任务分析 任务要求用选择法对数组中的 10 个整数按由小到大的顺序排序,前面在讲解数组时讲冒泡法排序曾提到选择法排序的思想。 所谓选择法就是…...
时间序列模型在LSTM中的特征输入
这里写目录标题 前言LSTM的输入组成时间步例子 实际代码解读特征提取处理成dataloader格式(用于输入到模型当中)对应到lstm的模型创建代码 总结 前言 本文章将帮助理解如何将一个时间序列的各种特征(年月日的时间特征,滚动窗口滞…...
Python_Flask02
所有人都不许学Java了,都来学Python! 如果不来学的话请网爆我的老师 连接前的准备 安装pymysql 和 flask_sqlalchemy,安装第三下面两个所需要的包才能连接上数据库 pip install pymysql pip install flask_sqlalchemy pymysql是一个Pyth…...
threejs相机辅助对象cameraHelper
为指定相机创建一个辅助对象,显示这个相机的视锥。 想要在场景里面显示相机的视锥,需要创建两个相机。 举个例子,场景中有个相机A,想要显示相机A的视锥,那么需要一个相机B,把B放在A的后面,两个…...
断点续传+测试方法完整示例
因为看不懂网上的断点续传案例,而且又不能直接复制使用,干脆自己想想写了一个。 上传入参类: import com.fasterxml.jackson.annotation.JsonIgnore; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProp…...
C#设计模式--状态模式(State Pattern)
状态模式是一种行为设计模式,它允许对象在其内部状态发生变化时改变其行为。这种模式的核心思想是将状态封装在独立的对象中,而不是将状态逻辑散布在整个程序中。 用途 简化复杂的条件逻辑:通过将不同的状态封装在不同的类中,可…...
Excel技巧:如何批量调整excel表格中的图片?
插入到excel表格中的图片大小不一,如何做到每张图片都完美的与单元格大小相同?并且能够根据单元格来改变大小?今天分享,excel表格里的图片如何批量调整大小。 方法如下: 点击表格中的一个图片,然后按住Ct…...
hadoop中导出表与数据的步骤
大家好,我是 V 哥。在Hadoop中导出表与数据,可以通过多种方式实现,包括使用Hive的EXPORT命令、MapReduce作业、Hive查询以及Sqoop工具。下面V 哥将详细介绍这些步骤和一些代码示例,来帮助大家更好理解。 1. 使用Hive的EXPORT命令…...
springBoot中的日志级别在哪里配置
在Spring Boot中,日志级别的配置可以通过多种方式来实现,主要包括在配置文件中设置、使用自定义的logback配置文件,以及在代码中动态配置等。以下是一些具体的配置方法: 一、在配置文件中设置日志级别 Spring Boot默认使用appli…...
17. Threejs案例-Three.js创建多个立方体
17. Threejs案例-Three.js创建多个立方体 实现效果 知识点 WebGLRenderer (WebGL渲染器) WebGLRenderer 是 Three.js 中用于渲染 WebGL 场景的核心类。它负责将场景中的对象渲染到画布上。 构造器 new THREE.WebGLRenderer(parameters) 参数类型描述parametersObject可选…...
数据结构——有序二叉树的删除
在上一篇博客中,我们介绍了有序二叉树的构建、遍历、查找。 数据结构——有序二叉树的构建&遍历&查找-CSDN博客文章浏览阅读707次,点赞18次,收藏6次。因为数据的类型决定数据在内存中的存储形式。left right示意为左右节点其类型也为…...
力扣1401. 圆和矩形是否有重叠
用矢量计算: class Solution { public:bool checkOverlap(int radius, int xCenter, int yCenter, int x1, int y1, int x2, int y2) {//矩形中心float Tx(float)(x1x2)/2;float Ty(float)(y1y2)/2;//强行进行对称操作,只考虑第一象限if(xCenter<Tx)…...
idea连接到docker出现 org.apache.hc.client5.http.ConnectTimeoutException 异常怎么办?
前情提要 我电脑是win11,我安装了centOS7虚拟机,配置linux环境 idea是2024社区免费版本 我就这一步步排查问题,终于发现了是因为我的2375端口没有ipv4开放,只在ipv6开放 踩坑提醒: 对了,一个一个问题排…...
一番赏小程序定制开发,打造全新抽赏体验平台
随着盲盒的热潮来袭,作为传统的潮玩方式一番赏也再次受到了大家的关注,市场热度不断上升! 一番赏能够让玩家百分百中奖,商品种类丰富、收藏价值高,拥有各种IP,从而吸引着各个圈子的粉丝玩家,用…...
PHP语法学习(第六天)
💡依照惯例,回顾一下昨天讲的内容 PHP语法学习(第五天)主要讲了PHP中的常量和运算符的运用。 🔥 想要学习更多PHP语法相关内容点击“PHP专栏” 今天给大家讲课的角色是🍍菠萝吹雪,“我菠萝吹雪吹的不是雪,而…...
按vue组件实例类型实现非侵入式国际化多语言翻译
#vue3##国际化##本地化##international# web界面国际化,I18N(Internationalization,国际化),I11L(International,英特纳雄耐尔),L10N(Localization,本地化)&…...
2024年认证杯SPSSPRO杯数学建模B题(第一阶段)神经外科手术的定位与导航解题全过程文档及程序
2024年认证杯SPSSPRO杯数学建模 B题 神经外科手术的定位与导航 原题再现: 人的大脑结构非常复杂,内部交织密布着神经和血管,所以在大脑内做手术具有非常高的精细和复杂程度。例如神经外科的肿瘤切除手术或血肿清除手术,通常需要…...
51c视觉~合集24
我自己的原文哦~ https://blog.51cto.com/whaosoft/11870494 #R-Adapter 零样本模型微调新突破,提升鲁棒性与泛化能力 论文提出新颖的Robust Adapter(R-Adapter),可以在微调零样本模型用于下游任务的同时解决这两个问题。该方…...
idea启动tomcat服务中文乱码
在idea中启动tomcat服务后部分中文乱码 但是在tomcat日志部分正常 并且在tomcat中中文也是正常 查询大量资料修改idea编码,虚拟机编码、tomcat默认编码、终端默认编码,统统没有效果。 最终发现修改tomcat下文件夹 .\conf\logging.properties 网络上…...
android studio 读写文件操作(应用场景二)
android studio版本:2023.3.1 patch2 例程:readtextviewIDsaveandread 本例程是个过渡例程,如果单是实现下图的目的有更简单的方法,但这个方法是下一步工作的基础,所以一定要做。 例程功能:将两个textvi…...
【数据结构】【线性表】特殊的线性表-字符串
目录 字符串的基本概念 字符串的三要素 字符串的基本概念 串的编码 串的实现及基本运算 顺序串的实现 串的静态数组实现 串的动态数组的实现 顺序存储的四种方案 链式串的实现 基本运算 方案三 方案一 字符串的基本概念 数据结构千千万,…...
【AWS re:Invent 2024】一文了解EKS新功能:Amazon EKS Auto Mode
文章目录 一、为什么要使用 Amazon EKS Auto Mode?二、Amazon EKS自动模式特性2.1 持续优化计算成本2.2 迁移集群操作2.3 EKS 自动模式的高级功能 三、EKS Auto 集群快速创建集群配置四、查看来自 API 服务器的指标五、EKS 相关角色权限设置六、参考链接 一、为什么…...
HTTPS的工作过程
1.HTTPS协议原理 1.1HTTPS协议的由来 HTTP在传输网络数据的时候是明文传输的,信息容易被窃听甚至篡改,因此他是一个不安全的协议(但效率高)。在如今的网络环境中,数据安全是很重要的(比如支付密码又或者各…...
Java并发编程学习之从资本家的角度看多线程和并发性(一)
目录 前言前置知识一、单线程时代二、为什么要有多线程,多线程的优点?三、使用多线程会遇到什么问题?四、多线程和并发编程的关系总结 前言 这篇文章是打开Java多线程和并发编程的大门的开始,如标题《从老板的角度看多线程和并发…...
基于STM32设计的智能宠物喂养系统(华为云IOT)_273
文章目录 一、前言1.1 项目介绍【1】项目开发背景【2】设计实现的功能【3】项目硬件模块组成【4】设计意义【5】国内外研究现状【6】摘要1.2 设计思路1.3 系统功能总结1.4 开发工具的选择【1】设备端开发【2】上位机开发1.5 参考文献1.6 系统框架图1.7 系统原理图1.8 实物图1.9…...
Mybatis-Plus的主要API
一、实体类操作相关API BaseMapper<T>接口 功能:这是 MyBatis - Plus 为每个实体类对应的 Mapper 接口提供的基础接口。它提供了一系列基本的 CRUD(增删改查)操作方法。例如insert(T entity)方法用于插入一条记录,d…...
Pillow:强大的Python图像处理库
目录 一、引言 二、Pillow 库的安装 三、Pillow 库的基本概念 四、图像的读取和保存 五、图像的基本属性 六、图像的裁剪、缩放和旋转 七、图像的颜色调整 八、图像的滤镜效果 九、图像的合成和叠加 十、图像的绘制 十一、示例程序:制作图片水印 十二、…...
Springboot定时任务详解
文章目录 Springboot定时任务详解一、引言二、cron表达式三、使用Scheduled注解1、开启定时任务2、添加定时任务 四、使用TaskScheduler接口1、注入TaskScheduler实例 五、集成Quartz框架1、集成Quartz 六、实际使用示例七、总结 Springboot定时任务详解 一、引言 在现代软件…...
【Linux】环境ChatGLM-4-9B 模型之 openai API 服务
一、摘要 最近看到 Function Call 比较感兴趣,它的核心是赋予大模型能够调用外部API的能力,能够解决大模型功能扩展性问题,允许模型调用外部数据库或API,提供特定领域的详细信息;解决信息实时性问题,模型可以实时获取最新数据;解决数据局限性问题,大模型训练数据虽多但…...
mobi文件转成pdf
将 MOBI 文件转换为 PDF 格式通常涉及两个步骤: 解析 MOBI 文件:需要提取 MOBI 文件的内容(文本、图片等)。将提取的内容转换为 PDF:将 MOBI 文件的内容渲染到 PDF 格式。 可用工具 kindleunpack 或 mobi࿱…...
Linux---对缓冲区的简单理解--第一个系统程序
前序: 首先先理解一下什么是回车与换行;回车和换行是两个概念,它们不是一个东西; 回车:光标回到开始;换行:换到下一行; 如下图: 行缓冲区 如何理解缓冲区问题? 可以认为࿰…...
word poi-tl 表格功能增强,实现表格功能垂直合并
目录 问题解决问题poi-tl介绍 功能实现引入依赖模版代码效果图 附加(插件实现)MergeColumnData 对象MergeGroupData 类ServerMergeTableData 数据信息ServerMergeTablePolicy 合并插件 问题 由于在开发功能需求中,word文档需要垂直合并表格&…...
鸿蒙实现数据管理
目录: 1、鸿蒙实现数据管理的三种方式2、用户首选项3、键值型数据管理3.1、获取KVManager实例,用于管理数据库对象3.2、创建并获取键值数据库3.3、调用put()方法向键值数据库中插入数据3.4、调用get()方法获取指定键的值3.5、调用delete()方法删除指定键…...
图片上传HTML
alioss sky:jwt:# 设置jwt签名加密时使用的秘钥admin-secret-key: itcast# 设置jwt过期时间admin-ttl: 7200000# 设置前端传递过来的令牌名称admin-token-name: tokenalioss:endpoint: ${sky.alioss.endpoint}access-key-id: ${sky.alioss.access-key-id}access-key-secret: $…...
golang 代发邮件支持附件发送,outlook案列,其他邮箱需要替换对应邮箱服务域名
GPT问答实例 import pandas as pd from openai.embeddings_utils import get_embedding, cosine_similarity import openai import os import logging as logger from flask_cors import CORS import os openai.api_key os.getenv(OPENAI_API_KEY)class Chatbot():def parse_…...
输出绝对值
输出绝对值 C语言代码C 代码Java代码Python代码 💐The Begin💐点点关注,收藏不迷路💐 输入一个浮点数,输出这个浮点数的绝对值。 输入 输入一个浮点数,其绝对值不超过10000。 输出 输出这个浮点数的绝对…...