当前位置: 首页 > news >正文

C++从入门到实战(十二)详细讲解C++如何实现内存管理

C++从入门到实战(十二)详细讲解C++如何实现内存管理

  • 前言
  • 一、C++内存管理方式
    • 1. new/delete操作内置类型
    • 2. 异常与内存管理的联系(简单了解)
    • 3. new和delete操作自定义类型
  • 二、 operator new与operator delete函数(重点)
    • 1. new和delete操作符与operator new和operator delete函数的关系
    • 2. operator new函数的工作原理
    • 3. operator delete函数的工作原理
  • 三、 定位new表达式(placement-new) (了解即可)
    • 1. 定位 new 表达式的概念
    • 2. 定位 new 表达式的使用格式
    • 3. 定位 new 表达式的使用场景
  • 四、malloc/free和new/delete的区别
    • 1. 相同点
    • 2. 不同点
      • 一个是函数,一个是操作符
      • new 会 “初始化”,malloc 不会
      • 空间大小:new 自动计算,malloc 要手动算
      • new 不用强转,malloc 需要
      • 错误处理:malloc 返 NULL,new 抛异常
      • 自定义类型:new/delete 会 “照顾” 对象,malloc/free 不会


前言

  • 在上一篇博客中,我们探讨了 C/C++ 语言的内存分布模型,并对比了 C 与 C++ 内存管理的核心差异,初步认识了 C++ 中new与delete的基本概念,为理解 C++ 内存管理体系奠定了基础
  • 本文将在此基础上,深入解析 C++ 内存管理的核心机制,从底层原理到实践细节展开系统讲解,帮助读者全面掌握这一重要知识模块

我的个人主页,欢迎来阅读我的其他文章
https://blog.csdn.net/2402_83322742?spm=1011.2415.3001.5343
我的C++知识文章专栏
欢迎来阅读指出不足
https://blog.csdn.net/2402_83322742/category_12880513.html?spm=1001.2014.3001.5482


一、C++内存管理方式

1. new/delete操作内置类型

  • 在 C 语言里有它自己的内存管理办法,但用起来比较麻烦,而且有些情况处理不了。
  • C++ 为了解决这些问题,引入了new和delete操作符来进行动态内存管理
#include <iostream>using namespace std;
void Test()
{int* ptr4 = new int;// 动态申请一个int类型的空间int* ptr5 = new int(10);//动态申请一个int类型的空间并初始化为10int* ptr6 = new int[3];//动态申请3个int类型的空间delete ptr4;delete ptr5;//delete ptr6;//错误在 C++ 中,new 和 delete、new[] 和 delete[] 是成对出现的操作符,它们的使用需要遵循特定的配对规则://如果使用 delete 而非 delete[] 来释放通过 new[] 分配的数组内存,会产生严重的后果://内存泄漏:delete 只会释放数组首元素的内存,而不会释放数组中其他元素的内存,这就导致了部分内存无法被回收,造成内存泄漏。//未定义行为:使用 delete 释放数组内存属于未定义行为,这意味着程序可能会出现各种不可预测的问题,比如程序崩溃、数据损坏等delete[] ptr6;
}
  • 在 C++ 中,new 和 delete、new[] 和 delete[] 是成对出现的操作符,它们的使用需要遵循特定的配对规则
  • 如果使用 delete 而非 delete[] 来释放通过 new[] 分配的数组内存,会产生严重的后果:例如上面代码中的int* ptr6 = new int[3]与delete ptr6

内存泄漏:delete 只会释放数组首元素的内存,而不会释放数组中其他元素的内存,这就导致了部分内存无法被回收,造成内存泄漏。
未定义行为:使用 delete 释放数组内存属于未定义行为,这意味着程序可能会出现各种不可预测的问题,比如程序崩溃、数据损坏等

在这里插入图片描述

2. 异常与内存管理的联系(简单了解)

  • 在使用new申请内存时,如果系统没有足够的内存可供分配,就可能会抛出异常。
  • 所以在进行内存管理时,要考虑到这种可能出现的异常情况,确保程序的健壮性。
#include <iostream>
using namespace std;void Test() {try {// 动态申请一个 int 类型的空间int* ptr4 = new int;// 动态申请一个 int 类型的空间并初始化为 10int* ptr5 = new int(10);// 动态申请 3 个 int 类型的空间int* ptr6 = new int[3];// 使用分配的内存*ptr4 = 5;cout << "Value of ptr4: " << *ptr4 << endl;cout << "Value of ptr5: " << *ptr5 << endl;for (int i = 0; i < 3; ++i) {ptr6[i] = i;cout << "Value of ptr6[" << i << "]: " << ptr6[i] << endl;}// 释放内存delete ptr4;delete ptr5;delete[] ptr6;} catch (const bad_alloc& e) {// 捕获内存分配失败的异常cerr << "Memory allocation failed: " << e.what() << endl;}
}int main() {Test();return 0;
}    

在这里插入图片描述

#include <iostream>
using namespace std;void Func()
{int i = 1;while (1){int* p1 = new int[1024 * 1024];cout << i << "->" << p1 << endl;i++;}
}int main()
{try{Func();}catch (const std::exception& e){cout << e.what() << endl;}
}

在这里插入图片描述

  • 这段代码定义了一个名为 Func 的函数,该函数在一个无限循环中不断尝试分配大约1MB的内存
  • 由于没有适当的内存释放,这将最终导致内存耗尽,从而抛出 std::bad_alloc 异常
  • 在 main 函数中, Func 被调用并被包裹在一个 try-catch 块中,以捕获并处理可能抛出的异常。

然而,由于 std::bad_alloc 异常没有被直接捕获( catch 块中捕获的是 std::exception 的引用),所以实际上这段代码可能不会按预期工作,因为 std::bad_alloc 可能在到达 catch 块之前就已经导致程序终止

3. new和delete操作自定义类型

  • 在 C++ 里,new 和 delete 除了能操作基本数据类型,还可以操作自定义类型。

自定义类型是程序员自己定义的类型,像类、结构体等.

  • 以下是new 和 delete 操作基本数据类型的简单代码
#include <iostream>
using namespace std;
class Person
{
public:Person(const char* _name,int _age){name = _name;age = _age;cout << "Person 构造函数被调用,名字: " << name << ", 年龄: " << age;};~Person(){cout << "Person 析构函数被调用: " << name << ", 年龄: " << age;}private:const char *  name;//一个指向常量字符的指针类型int age;};
int main() {// 使用 new 创建 Person 对象Person* person = new Person("Alice", 25);// 使用 delete 释放对象内存delete person;return 0;
}

在这里插入图片描述

这段代码定义了一个 Person 类,包含姓名和年龄两个属性,还有构造函数和析构函数。在 main 函数里,使用 new 操作符创建一个 Person 对象,然后使用 delete 操作符释放对象的内存。

二、 operator new与operator delete函数(重点)

1. new和delete操作符与operator new和operator delete函数的关系

  • 前面我们讲到new和delete是用来动态申请和释放内存的操作符。比如,你想创建一个int类型的变量,就可以用new操作符来申请内存:
int* ptr = new int;
  • 这里的new操作符在底层会调用operator new全局函数来申请内存空间
    在这里插入图片描述

  • 当你不再需要这块内存时,就得用delete操作符释放它:

delete ptr;

delete操作符在底层会调用operator delete全局函数来释放内存空间
在这里插入图片描述

2. operator new函数的工作原理

  • operator new函数的作用是申请内存空间,它实际上是借助malloc函数来实现的

下面是它的工作步骤:

  • 尝试申请内存:调用malloc函数去申请指定大小的内存空间。
  • 检查申请结果:
    • 成功:若malloc申请内存成功,就直接返回这块内存的指针。
    • 失败:若malloc申请内存失败,会尝试执行用户设置的空间不足应对措施
    • 用户设置了应对措施:继续尝试申请内存。
    • 用户未设置应对措施:抛出std::bad_alloc类型的异常

下面是operator new函数的简化代码:

void *operator new(size_t size) {void *p;while ((p = malloc(size)) == 0) {if (用户设置的应对措施函数(size) == 0) {// 申请内存失败,抛出异常static const std::bad_alloc nomem;throw nomem;}}return p;
}

3. operator delete函数的工作原理

  • operator delete函数的作用是释放内存空间,它最终是通过free函数来实现的。

下面是它的工作步骤:

  • 检查指针是否为空:若传入的指针为空,直接返回,不做任何操作。
  • 释放内存:调用free函数释放这块内存空间。

下面是operator delete函数的简化代码:

void operator delete(void *pUserData) {if (pUserData == NULL)return;free(pUserData);
}
  • new操作符在底层调用operator new函数来申请内存空间,operator new函数又借助malloc函数来申请内存
  • delete操作符在底层调用operator delete函数来释放内存空间,operator delete函数最终通过free函数来释放内存
  • 若malloc申请内存失败,operator new函数会尝试执行用户设置的应对措施,若没有设置则抛异常

三、 定位new表达式(placement-new) (了解即可)

1. 定位 new 表达式的概念

一般而言,使用new操作符时,它会做两件事

  • 一是为对象分配内存;二是调用对象的构造函数来初始化这块内存。
  • 而定位 new 表达式有所不同,它是在已经分配好的原始内存空间里调用构造函数来初始化对象

2. 定位 new 表达式的使用格式

在C++中,定位 new 的语法如下

new (address) Type

在address指向的内存空间创建一个type类型的对象

new (address) Type[size]
  • 在address指向的内存空间创建一个type类型的对象,并且用size里的值来初始化对象

  • 这里的address得是一个指针,size是类型的初始化列表

3. 定位 new 表达式的使用场景

  • 在实际运用中,定位 new 表达式通常和内存池配合使用
  • 内存池分配的内存并未初始化,要是分配的是自定义类型的对象,就得使用定位 new 表达式来显式调用构造函数进行初始化
#include <iostream>int main() {// 分配一块原始内存char* rawMemory = new char[sizeof(int)];// 使用定位new在原始内存上构造一个int对象int* intPtr = new (rawMemory) int(42);// 输出构造的int对象的值std::cout << "Value of int object: " << *intPtr << std::endl;// 显式调用析构函数(对于基本类型,这一步不是必需的,但对于自定义类型是必需的)intPtr->~int();// 释放原始内存delete[] rawMemory;return 0;
}
#include <iostream>class MyClass {
public:MyClass(int value) : data(value) {std::cout << "Constructor called with value: " << data << std::endl;}~MyClass() {std::cout << "Destructor called for value: " << data << std::endl;}
private:int data;
};int main() {// 分配一块原始内存char* rawMemory = new char[sizeof(MyClass)];// 使用定位new在原始内存上构造一个MyClass对象MyClass* myObjPtr = new (rawMemory) MyClass(10);// 显式调用析构函数myObjPtr->~MyClass();// 释放原始内存delete[] rawMemory;return 0;
}    

四、malloc/free和new/delete的区别

1. 相同点

malloc/free和new/delete的共同点是:都是从堆上申请空间,并且需要用户手动释放。

  • 不过,他们的不同点是

2. 不同点

一个是函数,一个是操作符

  • malloc/free 是 C 语言的库函数:需要包含头文件 <stdlib.h>,用函数的方式调用(比如 malloc(size))。
  • new/delete 是 C++ 的操作符:是 C++ 语言内置的功能,用法更简洁(比如 new int)

new 会 “初始化”,malloc 不会

malloc 申请的内存是 “脏的”:里面可能是随机的垃圾值。比如

int* p = (int*)malloc(sizeof(int));  // *p 的值不确定,可能是任意数
  • new 申请的内存会被 “初始化”
    • 对内置类型(如 int、double),new int 不会初始化,但 new int() 会初始化为 0;
    • 对自定义类型(如类),new 会自动调用构造函数,完成对象的初始化(比如给成员变量赋值)。

空间大小:new 自动计算,malloc 要手动算

  • malloc 需要自己算大小:必须用 sizeof 计算需要的字节数,比如申请 5 个 int 的空间:
int* p = (int*)malloc(5 * sizeof(int));  // 手动算 5*4=20 字节
  • 如果算错(比如漏掉 sizeof 或乘错数),就会出 bug
  • new 自动知道要多大:直接写类型和数量即可,比如:
int* p = new int[5];  // 自动申请 5 个 int 的空间,不用算字节数

new 不用强转,malloc 需要

malloc 返回 void* 指针:使用时必须强制转换类型,比如:

int* p = (int*)malloc(sizeof(int));  // 必须强转成 int*

new 直接返回对应类型的指针:比如 new int 直接返回 int*,不需要强转:

int* p = new int;  // 直接是 int* 类型,不用强转

错误处理:malloc 返 NULL,new 抛异常

  • malloc 申请失败返回 NULL:必须检查是否为 NULL,否则解引用(比如 *p)会导致程序崩溃:
int* p = (int*)malloc(sizeof(int));
if (p == NULL) {  // 必须判空!// 处理内存不足的情况
}
  • new 申请失败会抛出异常:默认会抛出 std::bad_alloc 异常,需要用 try-catch 捕获(或者用 new(nothrow) 版本返回 NULL,但不常用):
try {int* p = new int;  // 失败会抛异常,不会返回 NULL
} catch (std::bad_alloc& e) {// 处理异常
}

自定义类型:new/delete 会 “照顾” 对象,malloc/free 不会

malloc/free 只负责搬砖:

  • malloc 只会分配一块足够大的内存,但不会调用类的 构造函数(比如初始化成员变量);
  • free 只会释放内存,但不会调用类的 析构函数(比如释放对象内部申请的资源)。
    这样会导致对象没被正确初始化或清理,造成错误或内存泄漏。

new/delete 会 “盖房子” 和 “拆房子”:

  • new 分配内存后,会自动调用类的构造函数,初始化对象(比如给成员变量赋值);
  • delete 释放内存前,会自动调用类的析构函数,清理对象内部的资源(比如释放成员指针指向的内存)。

以上就是这篇博客的全部内容,下一篇我们将继续探索C++中模板初阶更多精彩内容。

我的个人主页,欢迎来阅读我的其他文章
https://blog.csdn.net/2402_83322742?spm=1011.2415.3001.5343
我的C++知识文章专栏
欢迎来阅读指出不足
https://blog.csdn.net/2402_83322742/category_12880513.html?spm=1001.2014.3001.5482

非常感谢您的阅读,喜欢的话记得三连哦

在这里插入图片描述

相关文章:

C++从入门到实战(十二)详细讲解C++如何实现内存管理

C从入门到实战&#xff08;十二&#xff09;详细讲解C如何实现内存管理 前言一、C内存管理方式1. new/delete操作内置类型2. 异常与内存管理的联系&#xff08;简单了解&#xff09;3. new和delete操作自定义类型 二、 operator new与operator delete函数&#xff08;重点&…...

console-chat-gpt开源程序是用于 AI Chat API 的 Python CLI

​一、软件介绍 文末提供程序和源码下载 console-chat-gpt开源程序是用于 AI Chat API 的 Python CLI&#xff0c;与 AI 模型聊天的终极 CLI 伴侣&#xff0c;直接从命令行享受与 OpenAI、MistralAI、Anthropic、xAI、Google AI、DeepSeek、阿里巴巴、Inception 或 Ollama 托管…...

影刀RPA开发-程序备注说明的必要性

1. 备注指令的调用 1.1 指令搜索 搜索出备注指令后&#xff0c;添加到代码框中 1.2 快捷输入 在代码框中&#xff0c;输入指令关键字&#xff0c;可以快速展示出相关指令 2.备注指令内容设置 备注信息要依据代码执行的功能书写 尽量写明该语句或该段落代码的功能作用 单行…...

第十节:图像处理基础-图像算术运算 (加法、减法、混合)

引言 在计算机视觉领域&#xff0c;图像算术运算是最基础却至关重要的核心技术。无论是实现简单的图片合成、开发智能监控系统&#xff0c;还是构建复杂的医学影像分析工具&#xff0c;加减运算和混合操作都扮演着关键角色。OpenCV作为最流行的计算机视觉库&#xff0c;提供了…...

如何使用UGUI的EventTrigger

前言 在 Unity 的 UGUI 系统中,EventTrigger 是一个强大的组件,允许开发者监听和处理多种 UI 交互事件。以下是详细的使用方法、示例代码、优缺点分析以及注意事项。 一、EventTrigger 基本用法 1. 添加 EventTrigger 组件 在 Unity 编辑器中选中 UI 对象(如 But…...

5G赋能农业物联网:智能化种植的新纪元

5G赋能农业物联网&#xff1a;智能化种植的新纪元 在农业领域&#xff0c;精准化、智能化已成为现代农业发展的方向。而5G的出现&#xff0c;让农业物联网&#xff08;Agri-IoT&#xff09;突破了传统的瓶颈&#xff0c;真正实现了实时监测、高效数据传输、智能化决策&#xf…...

LeetCode 热题 100 64. 最小路径和

LeetCode 热题 100 | 64. 最小路径和 大家好&#xff0c;今天我们来解决一道经典的动态规划问题——最小路径和。这道题在 LeetCode 上被标记为中等难度&#xff0c;要求找到从网格的左上角到右下角的路径&#xff0c;使得路径上的数字总和为最小。 问题描述 给定一个包含非负…...

精益数据分析(45/126):媒体网站商业模式的深度剖析与挑战应对

精益数据分析&#xff08;45/126&#xff09;&#xff1a;媒体网站商业模式的深度剖析与挑战应对 在创业和数据分析的领域中&#xff0c;探索不同商业模式的运作机制和关键要点是提升业务能力的重要途径。今天&#xff0c;我们依旧带着共同进步的目标&#xff0c;深入研读《精…...

学习Linux的第四天

今天我们来学习Linux的网络配置&#xff0c;以及链表的知识开个小头 三种网络配置模式 桥接模式&#xff08;用的最多&#xff09; 2.Nat模式 3. 仅主机模式&#xff08;Nat模式的功能外&#xff0c;只能在局域网通信&#xff0c;不能访问外网&#xff09; 桥接模式&#xf…...

AGV导航控制器技术方案——基于EFISH-SBC-RK3576/SAIL-RK3576的国产化革新‌(新一代工业级自主可控解决方案)‌

一、方案核心架构 ‌1. 硬件拓扑设计‌ ‌主控单元‌&#xff1a;SAIL-RK3576核心板&#xff08;八核A72A53M0异构架构&#xff09;‌传感器层‌&#xff1a; 双激光雷达&#xff08;RS-LiDAR-16线 SICK TIM240&#xff09;9轴IMU&#xff08;BMI088&#xff09; 轮式编码器&…...

ISCC 2025练武题 WP部分

总结 垃圾比赛&#xff0c;垃圾题目&#xff0c;纯脑洞题&#xff0c;技术好不好没得关系&#xff0c;就看你脑洞大不大。 web里塞misc&#xff0c;re里塞misc真是牛逼他妈给牛逼开门牛逼到家。 逆天平台&#xff0c;卡的一批&#xff0c;靶机还是公用的&#xff0c;把flag删…...

mysql:什么是一致性视图(Read View)

一致性视图&#xff08;Read View&#xff09;是 MVCC&#xff08;多版本并发控制&#xff09;中的核心概念&#xff0c;用于实现事务隔离性。 它是一个逻辑概念&#xff0c;让事务在读取数据时看到特定时间点的数据库快照&#xff0c;而不受其他事务并发修改的影响。 一致性…...

android中背压问题面试题及高质量回答范例

&#x1f3af; 回答的目标是&#xff1a; 表现出你理解背压的本质&#xff08;不是框架知识&#xff0c;而是系统层面的问题&#xff09;。 能清晰讲出几种处理背压的方案&#xff08;理论 实战&#xff09;。 能结合 Android 场景讲具体例子&#xff08;比如 UI 线程、网络…...

【C++】C++11(上)

&#x1f680;write in front&#x1f680; &#x1f4dc;所属专栏&#xff1a; C学习 &#x1f6f0;️博客主页&#xff1a;睿睿的博客主页 &#x1f6f0;️代码仓库&#xff1a;&#x1f389;VS2022_C语言仓库 &#x1f3a1;您的点赞、关注、收藏、评论&#xff0c;是对我最大…...

工具分享:通过滑块拉取CAN报文信号数值自动发送报文

0. 概述 CAN报文发送工具使用wxpython进行开发,配套Excel模板可以通过修改Excel自定义界面展示的信号名称和信号的属性;同时,工具支持导入现场采集的报文数据自动按照配套Excel模板定义的报文发送周期进行模拟发送。 由于是我好几年前开发的作品,一些开发细节也记得不是很…...

android 折叠屏开发适配全解析:多窗口、铰链处理与响应式布局

安卓适配折叠屏指南 折叠屏设备为安卓开发带来了新的机遇和挑战。以下是适配折叠屏的关键要点&#xff1a; 1. 屏幕连续性检测 // 检查设备是否支持折叠屏特性 private fun isFoldableDevice(context: Context): Boolean {return context.packageManager.hasSystemFeature(&…...

Cloudera CDP 7.1.3 主机异常关机导致元数据丢失,node不能与CM通信

问题描述 plaintext ERROR Could not load post-deployment data from /var/run/cloudera-scm-agent/process/ccdeploy_hadoop-conf_etchadoopconf.cloudera.yarn_-8903374259073700469 IOError: [Errno 2] No such file or directory: /var/run/cloudera-scm-agent/proce…...

超越 DeepSeek-R1,英伟达新模型登顶

近日&#xff0c;英伟达发布全新开源模型系列 Llama-Nemotron&#xff0c;凭借卓越性能引发业界关注&#xff0c;有望重塑开源 AI 格局。 该系列在推理能力上超越 DeepSeek-R1&#xff0c;内存效率与吞吐量显著提升。其创新采用合成数据监督微调与强化学习训练&#xff0c;全方…...

centos8.5.2111 更换阿里云源

使用前提是服务器可以连接互联网 1、备份现有软件配置文件 cd /etc/yum.repos.d/ mkdir backup mv CentOS-* backup/ 2、下载阿里云的软件配置文件 wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-vault-8.5.2111.repo 3、清理并重建…...

阿里云平台与STM32的物联网设计

基于阿里云平台与STM32的物联网设计方案可结合硬件选型、通信协议、云端配置及功能实现等多个维度进行设计。以下是综合多个参考案例的详细设计方案&#xff1a; 一、硬件选型与架构设计 主控芯片选择 STM32系列&#xff1a;推荐使用STM32F103&#xff08;如STM32F103ZET6、STM…...

ESP32- 开发笔记- 软件开发 6 蓝牙协议栈 1

1 蓝牙 ESP32 是一款支持蓝牙功能的强大微控制器&#xff0c;ESP-IDF (Espressif IoT Development Framework) 提供了完整的蓝牙开发支持。 1.1 蓝牙模式 ESP32 支持两种蓝牙模式&#xff0c;即同时支持经典蓝牙和低功耗蓝牙。 1.1.1 蓝牙经典 (BT/BDR/EDR) 支持传统蓝牙协…...

python爬虫爬取网站图片出现403解决方法【仅供学习使用】

基于CSDN第一篇文章&#xff0c;Python爬虫之入门保姆级教程&#xff0c;学不会我去你家刷厕所。 这篇文章是2021年作者发表的&#xff0c;由于此教程&#xff0c;网站添加了反爬机制&#xff0c;有作者通过添加cookie信息来达到原来的效果&#xff0c;Python爬虫添加Cookies以…...

利用动态数字孪生:Franka Research 3 机械臂在机器人策略评估中的创新实践——基于Real-is-Sim框架的仿真与现实闭环验证

一、前言&#xff1a; 在机器人技术飞速发展的今天&#xff0c;如何高效、准确地评估机器人在现实世界中的操作策略&#xff0c;成为制约机器人技术进一步突破的关键瓶颈。传统方法往往依赖于耗时且成本高昂的真实世界测试&#xff0c;而模拟环境虽能提供便利&#xff0c;却因…...

Spark-Core(RDD行动算子)

一、RDD行动算子 行动算子就是会触发action的算子&#xff0c;触发action的含义就是真正的计算数据。 1、reduce 函数签名&#xff1a; def reduce(f: (T, T) > T): T 函数说明&#xff1a;聚集 RDD 中的所有元素&#xff0c;先聚合分区内数据&#xff0c;再聚合分区间…...

spark转换算子

在 Apache Spark 中&#xff0c;转换算子&#xff08;Transformation&#xff09;是用于对 RDD&#xff08;弹性分布式数据集&#xff09;进行转换操作的函数。这些操作是惰性的&#xff0c;即在调用转换算子时&#xff0c;Spark 并不会立即执行计算&#xff0c;而是记录下转换…...

hadoop的运行模式

&#xff08;一&#xff09;Hadoop的运行模式 hadoop一共有如下三种运行方式&#xff1a; 1. 本地运行。数据存储在linux本地&#xff0c;测试偶尔用一下。我们上一节课使用的就是本地运行模式hadoop100。 2. 伪分布式。在一台机器上模拟出 Hadoop 分布式系统的各个组件&#x…...

力扣——25 K个一组翻转链表

目录 1.题目描述&#xff1a; 2.算法分析&#xff1a; 3.代码展示&#xff1a; 1.题目描述&#xff1a; 给你链表的头节点 head &#xff0c;每 k 个节点一组进行翻转&#xff0c;请你返回修改后的链表。 k 是一个正整数&#xff0c;它的值小于或等于链表的长度。如果节点总…...

React Router Vs Vue Router

文章目录 前言✅ React Router vs Vue Router 对比一览&#x1f9e9; React Router 的底层原理简述① 路由声明与匹配&#xff08;基于 JSX&#xff09;② 历史模式管理③ 响应式状态处理④ 路由渲染机制&#xff08;Outlet&#xff09; ✅ 总结&#xff1a;原理是否一样&#…...

Spark中RDD算子的介绍

引言 在大数据处理领域&#xff0c;Apache Spark凭借其高效性和灵活性备受青睐。而弹性分布式数据集&#xff08;Resilient Distributed Datasets&#xff0c;简称RDD&#xff09;则是Spark的核心数据结构。RDD算子作为操作RDD的关键工具&#xff0c;掌握它们对于充分发挥Spar…...

Vivo 手机官网交互效果实现解析

在现代网页设计中&#xff0c;流畅的滚动交互和精美的视觉效果是提升用户体验的关键。本文将深入解析 Vivo 手机官网 Demo 中的一个核心交互效果 —— 基于滚轮滚动的内容展示系统。这个系统允许用户通过滚动鼠标滚轮来浏览不同的手机镜头配置信息&#xff0c;同时伴随平滑的过…...

powershell批处理——io校验

powershell批处理——io校验 在刷题时&#xff0c;时常回想&#xff0c;OJ平台是如何校验竞赛队员提交的代码的&#xff0c;OJ平台并不看代码&#xff0c;而是使用“黑盒测试”&#xff0c;用测试数据来验证。对于每题&#xff0c;都事先设定了很多组输入数据&#xff08;data…...

AI——认知建模工具:ACT-R

ACT-R&#xff08;Adaptive Control of Thought—Rational&#xff09;是一种用于模拟人类认知过程的计算架构&#xff0c;广泛应用于心理学、认知科学和人工智能研究。它通过模块化的方式模拟记忆、注意力、学习、决策等认知机制。以下是ACT-R的核心概念、安装方法、基础语法及…...

Docker 容器镜像环境的依赖导出

#工作记录 如果我们想获取 Docker 容器中已有镜像的所有的依赖包信息&#xff0c;包括其他可能的系统依赖&#xff0c;用于在其他环境&#xff08;如 WSL 或 Windows&#xff09;中重新搭建相同的运行环境。 以下是完整的步骤&#xff1a; 1. 导出 Python 依赖&#xff08;r…...

[ubuntu]fatal error: Eigen/Core: No such file or directory

确认是否安装了eigen3sudo apt-get install libeigen3-dev 解决 fatal error: Eigen/Core: No such file or directory 如果已经安装&#xff0c;但当调用 eigen 库时&#xff0c;报错&#xff1a;fatal error: Eigen/Core: No such file or directory 这是因为 eigen 库默认…...

《硬件视界》专栏介绍(持续更新ing)

名人说&#xff1a;路漫漫其修远兮&#xff0c;吾将上下而求索。 —— 屈原《离骚》 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 目录 ✨ 专栏简介&#x1f4da; 当前专栏目录&#xff08;持续更新中&#xff09;&a…...

TypeScript类型挑战-刷题

TypeScript类型挑战 vscode刷题 vscode 插件 热身题 // Test Cases import type { Equal, Expect, NotAny } from "./test-utils";type cases [Expect<NotAny<HelloWorld>>, Expect<Equal<HelloWorld, string>>];// Your Code Here …...

Java后端开发day43--IO流(三)--缓冲流转换流序列化流

&#xff08;以下内容全部来自上述课程&#xff09; 缓冲流 1. 字节缓冲流 原理&#xff1a;底层自带了长度为8192的缓冲区提高性能 1.1拷贝文件&#xff08;一次读写一个字节&#xff09; //1.创建缓冲流的对象 BufferedInputStream bis new BufferedInputStream(new Fi…...

Nginx性能调优与深度监控

一&#xff1a;Nginx性能调优 1.更改进程数和连接数 &#xff08;1&#xff09;进程数 在高并发环境中&#xff0c;需要启动更多的Nginx进程以保证快速响应&#xff0c;用以处理用户的请求&#xff0c;避免造成阻塞。使用psaux命令查看Nginx运行进程的个数。从命令执行结果可…...

【LeetCode】高频 SQL 50题 题解

目录 查询 可回收且低脂的产品 寻找用户推荐人 大的国家 文章浏览 I 无效的推文 连接 使用唯一标识码替换员工ID 产品销售分析 I 进店却未进行过交易的顾客 上升的温度 每台机器的进程平均运行时间 员工奖金 学生们参加各科测试的次数 至少有5名直接下属的经理 …...

基于Qt的app开发第六天

写在前面 博主是一个大一下的计科生&#xff0c;现在正在做C面向对象程序设计的课程设计&#xff0c;具体功能可以看本专栏的第一篇博客。 目前的进度是&#xff1a;配好MySQL驱动->设计完界面->实现各个界面的切换 这一篇博主要初步实现待办板块的功能&#xff0c;即新建…...

剑指大规模 AI 可观测,阿里云 Prometheus 2.0 应运而生

作者&#xff1a;曾庆国&#xff08;悦达&#xff09; Prometheus 大家应该非常熟悉&#xff0c;正文开始前&#xff0c;让我们一起来回顾开源 Prometheus 项目的发展史。Prometheus 最初由 SoundCloud 的工程师 Bjrn Rabehl 和 Julius Volz 于 2012 年开发。当时&#xff0c;…...

阿里云2核2g安装nexus

阿里云2核2g安装nexus # 安装 JDK 1.8 sudo yum install -y java-1.8.0-openjdk-devel# 验证安装 java -version创建运行用户 cd /opt sudo wget https://download.sonatype.com/nexus/3/latest-unix.tar.gz sudo tar -xzf latest-unix.tar.gz sudo mv nexus-3* nexussudo us…...

eFish-SBC-RK3576工控板USB HOST接口USB3.0测试操作指南

本小节特指丝印号为J8的USB HOST接口&#xff0c;本开发板只有两个USB3.0接口&#xff0c;无USB2.0 这里接U盘测试。 在不接入任何USB外设的情况下&#xff0c;先查看/dev目录下是否存在/dev/sd*设备&#xff0c;执行命令&#xff1a; $ ls /dev/sd* 如下图所示&#xff1a; …...

嵌入式软件学习指南:从入门到进阶

嵌入式软件是物联网&#xff08;IoT&#xff09;、汽车电子、智能家居等领域的核心技术之一。它涉及硬件与软件的紧密结合&#xff0c;要求开发者不仅会写代码&#xff0c;还要理解底层硬件的工作原理。本文将带你系统了解嵌入式软件的学习路径、核心知识体系及实用资源推荐。 …...

【论文阅读】Adversarial Training Towards Robust Multimedia Recommender System

Adversarial Training Towards Robust Multimedia Recommender System 题目翻译&#xff1a;面向鲁棒多媒体推荐系统的对抗训练 论文链接&#xff1a;点这里 标签&#xff1a;多媒体推荐、对抗训练、推荐系统鲁棒性 摘要 随着多媒体内容在网络上的普及&#xff0c;迫切需要开…...

转换算子和行动算子的区别

转换算子会从一个已经存在的数据集 (RDD)中生成一个新的数据集 (RDD),比如map就是一个转换算子&#xff0c;它通过映射关系从一个RDD生成了一个新的RDD。 行动算子 (actions): 行动算子在进行数据集计算后会给driver程序返回一个值。 转换算子和行动算子最大的区别&#xff1…...

Selenium的driver.get_url 和 手动输入网址, 并点击的操作,有什么不同?

我在搞爬取的时候&#xff0c;发现有些网站直接用driver.get(url) 跳转到目标特定的网址的时候&#xff0c;会被强制跳转到其他的网址上&#xff0c;但是如果是自己手动&#xff0c;在网址栏那里输入网址&#xff0c;并点回车&#xff0c;却能完成跳转。 这是在使用 Selenium …...

【强化学习】强化学习算法 - 多臂老虎机问题

1、环境/问题介绍 概述&#xff1a;多臂老虎机问题是指&#xff1a;智能体在有限的试验回合 &#x1d447; 内&#xff0c;从 &#x1d43e; 台具有未知奖赏分布的“老虎机”中反复选择一个臂&#xff08;即拉杆&#xff09;&#xff0c;每次拉杆后获得随机奖励&#xff0c;目…...

Spring MVC Controller 方法的返回类型有哪些?

Spring MVC Controller 方法的返回类型非常灵活&#xff0c;可以根据不同的需求返回多种类型的值。Spring MVC 会根据返回值的类型和相关的注解来决定如何处理响应。 以下是一些常见的 Controller 方法返回类型&#xff1a; String: 最常见的类型之一&#xff0c;用于返回逻辑…...

Diamond iO:实用 iO 的第一缕曙光

1. 引言 当前以太坊基金会PSE的Machina iO团队宣布&#xff0c;其已经成功实现了 Diamond iO: A Straightforward Construction of Indistinguishability Obfuscation from Lattices —— 其在2025年2月提出的、结构简单的不可区分混淆&#xff08;iO&#xff09;构造&#xf…...