目录

1. C/C++内存分布

练习:

2. C语言动态内存管理方式

2.1 malloc/calloc/realloc的区别

2.2 malloc的实现原理

2.3 内存块分布与扩容

3. C++动态内存管理方式

3.1 new/delete操作类内置类型

1. new操作内置类型

2. delete操作内置类型

3.2 new/delete操作类自定义类型

1. new操作自定义类型

2. delete操作自定义类型

4. operator new与operator delete函数

4.1 operator new  函数

4.2 operator delete函数

4.3 与new/delete操作符的关系

5. new和delete的实现原理

5.1 内置类型

5.2 自定义类型

6. new/delete 和 malloc/free的区别

1. 所属语言

2. 操作对象与功能

3. 数组操作

4. 内存不足处理

5. 重载与自定义

7. 总结:


1. C/C++内存分布

在C和C++中 , 程序的内存分布通常可划分为几个主要区域 , 这些区域各自承担不同的功能 , 具体如下:

1. 栈(Stack)

  • 特点 : 由编译器自动管理 , 空间较小(通常几MB) , 遵循“先进后出”原则。
  • 存储内容 : 函数的局部变量 , 函数参数 , 返回地址等。
  • 示例 : 函数内部定义的 int a = 10;,a就存储在栈中 , 函数执行结束后会自动释放。

2. 堆(Heap)

  • 特点 : 由程序员手动管理(C中用 malloc / free , C++中用 new / delete) , 空间较大(可达GB级别) , 分配和释放需要显式操作。
  • 存储内容 : 动态分配的内存 , 比如动态创建的对象、数组等。
  • 示例 : int* p = new int[10]; , 数组的内存就位于堆中 , 需用 delete[] p 手动释放 , 否则可能导致内存泄漏。

3. 全局/静态存储区(Global/Static Storage Area)(数据段)

  • 特点 : 程序运行期间一直存在 , 由编译器管理 , 程序结束后自动释放。
  • 存储内容:
  • 全局变量(定义在函数外的变量);
  • 静态变量(用 static 修饰的变量 , 包括全局静态变量和局部静态变量)。
  • 示例 : int g_var = 20;(全局变量) , static int s_var = 30;(静态变量) , 都存储在此区域。

4. 常量存储区(Constant Storage Area)(代码段)

  • 特点 : 存放常量 , 内容不可修改 , 程序结束后释放。
  • 存储内容 : 字符串常量(如"hello") , const 修饰的常量(全局或静态的 const 变量 , 局部const 变量可能在栈中)。
  • 示例 : const int c_var = 40;(全局常量) , char* str = "world";("world" 存于常量区)。

5. 代码区(Code Segment/Text Segment)

  • 特点 : 存放程序的机器指令(二进制代码) , 通常为只读 , 以防止意外修改。
  • 作用 : CPU从这里读取指令并执行程序。

总结来说 , 栈和堆用于动态管理运行时数据 , 全局/静态区和常量区存储生命周期较长的数据 , 代码区则负责存储程序的执行指令 , 这些区域共同构成了C和C++程序的内存布局。

练习:

 以下是对每个变量内存位置的详细分析:

  1. globalVar : 属于全局变量 , 存储在数据段(静态区 , 选项C)。全局变量在程序整个运行周期都存在 , 由编译器管理其内存 , 程序结束时自动释放。
  2. staticGlobalVar : 是全局静态变量,同样存储在数据段(静态区 , 选项C)。静态全局变量作用域限制在定义的文件内 , 但存储区域和全局变量一样 , 在数据段 , 生命周期贯穿程序运行。
  3. staticVar : 为函数内的静态变量 , 存储在数据段(静态区 , 选项C)。函数内的静态变量 , 在第一次函数调用时初始化 , 之后一直存在于数据段 , 直到程序结束。
  4. localVar : 是函数内的局部变量 , 存储在栈(选项A)。局部变量在函数调用时在栈上分配空间 , 函数执行完毕 , 栈空间自动释放。
  5. num1 : 是函数内的局部数组 , 存储在栈(选项A)。局部数组属于局部变量 , 在栈上分配内存 , 函数结束后栈空间回收。
  6. char2 : char2 是函数内的字符数组 , 存储在栈(选项A);而 "abcd" 作为字符串常量 , 存储在代码段(常量区 , 选项D) , 数组 char2 是在栈上 , 将常量区的字符串内容拷贝过来。
  7. *char2 : char2 是栈上的数组 , *char2 是数组的第一个字符 , 所以存储在栈(选项A)。
  8. pChar3 : pChar3 是指针变量 , 存储在栈(选项A) , 它指向的是字符串常量 "abcd"
  9. *pChar3 : pChar3 指向的字符串常量 "abcd" 存储在代码段(常量区 , 选项D) , 所以*pChar3(即字符串的字符)在代码段(常量区 , 选项D)。
  10. ptr1 : ptr1 是指针变量 , 存储在栈(选项A) , 它指向堆上的内存。
  11. *ptr1 : ptr1 通过 malloc 动态分配的内存位于堆(选项B) , 所以*ptr1(即所指向的内存区域)在堆(选项B)。

2. C语言动态内存管理方式

2.1 malloc/calloc/realloc的区别

在前面的C语言中 , 我们学习了C语言的动态动态内存管理方式 , 其中主要学了在malloc , calloc , realloc 和free等函数 , 下面我们再简单回顾一下它们之间的区别:

在C语言中 , malloc , calloc , realloc 和free是实现动态内存管理的重要函数 , 它们各自有不同的功能和使用方式:
1. malloc函数

  • 函数原型:void* malloc(size_t size); 
  • 功能:在堆内存中分配指定字节数的连续内存空间。函数返回一个指向分配内存起始地址的指针 , 如果分配失败(例如内存不足) , 则返回NULL 。
  • 注意事项:
  • malloc 分配的内存空间中的值是未初始化的 , 可能是任意值。
  • 使用完 malloc 分配的内存后 , 必须调用 free 函数释放 , 否则会导致内存泄漏。
  • 由于 malloc 返回的是 void* 类型指针 , 在赋值给其他类型指针时 , 需要进行强制类型转换。

2. calloc函数

  • - 函数原型:void* calloc(size_t num, size_t size); 
  • - 功能 : 在堆内存中分配 num 个大小为 size 字节的连续内存空间 , 并将这些空间初始化为0。它返回一个指向分配内存起始地址的指针 , 如果分配失败 , 则返回 NULL 。
  • 注意事项:
  • 相比 malloc , calloc会自动进行初始化操作 , 适合需要初始值为0的场景 , 不过也因为多了初始化操作 , 在性能上会有一定开销。
  • 同样 , 使用完后要调用 free 释放内存。

3. realloc函数

  • 函数原型:  void* realloc(void* ptr, size_t size); 
  • 功能:用于重新分配已分配的内存空间。ptr 是指向之前由 malloc , calloc 或 realloc 分配的内存块的指针 , size 是新的内存块大小。如果 ptr 为 NULL , 则 realloc 相当于malloc;如果 size 为0且 ptr 不为NULL , 则释放 ptr 指向的内存块 , 相当于  free(ptr) 。
  • 注意事项:
  • realloc 可能会移动原来内存块的位置 , 因为它要根据当前内存的使用情况和新的大小来决定是否重新分配一块新的连续内存空间。所以在调用 realloc 后 , 要使用其返回的新指针 , 而不能再使用原来的指针。
  • 如果重新分配失败 , 原来 ptr 指向的内存块不会被释放 , 仍然有效。

4. free函数

  • 函数原型:void free(void* ptr); 
  • 功能:释放由 malloc , calloc 或 realloc 分配的内存空间 , 让系统可以回收并重新利用这部分内存。ptr 是指向要释放的内存块的指针。
  • 使用示例:在前面介绍 malloc , calloc , realloc 的示例中都有使用free释放内存的操作。
  • 注意事项:
  • 只能释放由 malloc , calloc , realloc 分配的内存 , 释放其他内存会导致未定义行为。
  • 不能多次释放同一块内存 , 也不能释放 NULL 指针(虽然释放 NULL 指针不会报错 , 但也无实际意义)。
#include <stdio.h>
#include <stdlib.h> // 包含动态内存管理函数的头文件int main() {int *ptr1, *ptr2, *ptr3;// 1. 使用 malloc 分配内存(未初始化)ptr1 = (int*)malloc(3 * sizeof(int)); // 分配3个int的空间// 2. 使用 calloc 分配内存(自动初始化为0)ptr2 = (int*)calloc(4, sizeof(int)); // 分配4个int的空间// 3. 使用 realloc 调整已分配的内存(基于ptr1扩展)ptr3 = (int*)realloc(ptr1, 5 * sizeof(int)); // 将ptr1的3个int扩展为5个// 4. 释放所有动态分配的内存free(ptr3); // 释放realloc返回的新地址(原ptr1已被覆盖,无需重复释放)free(ptr2); // 释放calloc分配的内存return 0;
}

2.2 malloc的实现原理

malloc 是C语言中用于动态分配内存的函数 , 其工作原理可简要概括为:

  1. 内存池管理:程序运行时会有一块预设的堆内存区域(内存池) , malloc 负责管理这块区域 , 而非直接向操作系统申请内存。
  2. 分配过程:当调用 malloc 申请指定大小的内存时 , 它会在内存池中查找足够大的空闲内存块 , 划分出所需大小的部分 , 返回指向该部分的指针 , 并记录该内存块的使用信息(如大小、状态)。
  3. 内存池扩容:若内存池中没有足够的空闲内存 , malloc 会通过系统调用(如 Linux 中的  brk 或 mmap)向操作系统申请更多内存 , 扩充内存池后再进行分配。
  4. 配合释放操作:当通过 free 释放内存时 , malloc 会根据之前记录的信息回收内存块 , 标记为空闲 , 并可能合并相邻的空闲块 , 以减少内存碎片 , 提高后续分配效率。

2.3 内存块分布与扩容

动态内存分配中:

  1. 内存块分布:已分配的内存块和空闲块在堆区混杂存在。当申请新内存时 , 若有合适大小的空闲块 , 直接分配;
  2. 扩容:若要给已分配的内存块扩容(如用 realloc ) ,  如果原内存块后有足够空闲空间 , 直接原地扩大;若没有 , 就新找一块足够大的连续空间 , 复制原数据后释放旧空间 , 返回新地址。

3. C++动态内存管理方式

C语言的动态内存管理方式在C++中仍然可以继续使用 , 但是有些地方就会显得无能为力了 , 而且使用起来比较麻烦 , 因此C++又提出了一种属于自己的动态内存管理方式 , 通过new和delete操作符进行动态内存管理。

3.1 new/delete操作类内置类型

在 C++ 中 , new 和 delete 操作内置类型(如 int , double , char  等)时 , 流程相对简单 , 不涉及对象的构造和析构(因为内置类型没有构造函数和析构函数) , 核心是内存的分配与释放:

1. new操作内置类型

分配单个元素:如 int* p = new int; 

  • 步骤 : 向堆区申请一块能容纳 int 类型的内存空间 , 返回指向该空间的指针。
  • 注意 : 默认不初始化 , 内存中的值是随机的;若要初始化 , 可写成 int* p = new int(10); , 此时内存会被初始化为10。

分配数组:如 int* arr = new int[5]; 

  • 步骤 : 向堆区申请能容纳5个 int 的连续内存空间 , 返回指向首元素的指针。
  • 注意 : 默认不初始化;若要初始化所有元素为 0 , 可写成 int* arr = new int[5](); 。

2. delete操作内置类型

释放单个元素:如 delete p; 

  • 步骤:直接释放 p 指向的堆内存(无需额外清理 , 因无析构函数) , p 变为野指针(建议置为 nullptr)。

释放数组:如  delete[] arr; 

  • 步骤:释放 arr 指向的整个连续数组内存 , 必须用 delete[]  匹配 new[] (虽然内置类型下用 delete 可能不报错 , 但会导致行为未定义 , 是错误写法)。

简言之 , 内置类型的 new / delete 核心是“分配/释放堆内存” , 比自定义类型少了构造/析构步骤 , 但仍需严格匹配 new 与 delete , new[] 与 delete[]。

3.2 new/delete操作类自定义类型

new 和 delete 操作自定义类型时 , 会完整包含“内存管理”和“对象生命周期管理”两个环节 , 具体流程如下:

1. new操作自定义类型

以类 A 为例分配单个对象:如 A* p = new A; 

  • 1. 先调用底层内存分配函数(类似 malloc) , 在堆区申请一块能容纳 A 类型对象的内存。
  • 2. 自动调用 A 的构造函数(根据参数匹配对应构造函数 , 如无参数则调用默认构造函数) , 初始化这块内存中的对象(例如初始化成员变量 , 申请资源等)。
  • 3. 返回指向该对象的指针 p。

分配数组:如 A* arr = new A[3]; 

  • 1. 申请能容纳3个 A 对象的连续堆内存。
  • 2. 依次调用3次 A 的构造函数(每个元素对应一次) , 初始化数组中的每个对象。

2. delete操作自定义类型

释放单个对象:如 delete p; 

  • 1. 先调用 p 指向对象的析构函数( A::~A() ) , 清理对象内部资源(例如释放成员变量指向的堆内存 , 关闭文件等)。
  • 2. 调用底层内存释放函数(类似 free ) , 将对象占用的堆内存归还给系统
  • 3. 指针 p 变为野指针 , 建议置为 nullptr

释放数组:如 delete[] arr; 

  • 1. 先按相反顺序依次调用数组中每个A对象的析构函数(共 3 次) , 清理所有元素的资源。
  • 2. 释放整块连续内存。
  • 注意 : 必须用 delete[] 匹配 new[] , 否则会导致部分对象析构函数不被调用 , 造成资源泄漏。

核心区别:自定义类型的 new / delete 比内置类型多了构造函数初始化对象和析构函数清理资源的步骤 , 这是C++面向对象特性在内存管理中的直接体现 , 确保对象从创建到销毁的完整生命周期管理。

//new和delete操作自定义类型
#include<iostream>
using namespace std;class A
{
public:A(int a = 0) //构造函数: _a(a){cout << "A():" << this << endl;}~A() //析构函数{cout << "~A():" << this << endl;}
private:int _a;
};int main()
{// new/delete 和 malloc/free最大区别是 new/delete对于【自定义类型】除了开空间还会调用构造函数和析构函数//自定义类型A* p1 = (A*)malloc(sizeof(A));free(p1);A* p2 = new A(1);delete p2;//内置类型是几乎是一样的int* p3 = (int*)malloc(sizeof(int)); free(p3);int* p4 = new int;delete p4;A* p5 = (A*)malloc(sizeof(A) * 10);free(p5);A* p6 = new A[10];delete[] p6;return 0;
}

输出结果:

4. operator new与operator delete函数

new和delete是用户进行动态内存申请和释放的操作符 , operator new 和operator delete是系统提供的全局函数 , new在底层调用operator new全局函数来申请空间 , delete在底层通过operator delete全局函数来释放空间。可以理解为operator new 和 operator delete 是 new 和 delete 操作符的底层支撑 , 主要负责内存的分配与释放(不涉及对象的构造和析构):

4.1 operator new  函数

  • 功能:负责在堆上分配指定大小的内存块 , 与 C 语言中的 malloc 类似 , 但行为有差异(operator new 分配失败时默认抛出 std::bad_alloc 异常 , 而 malloc 则会返回 NULL)。
  • 函数原型(简化版) : void* operator new(size_t size); 其中 size 是要分配的内存字节数。
  • 使用示例:
#include <iostream>
#include <new>  // 包含相关异常定义等int main() 
{// 分配能容纳一个 int 类型的内存int* p = (int*)operator new(sizeof(int));if (p == nullptr) {std::cout << "内存分配失败" << std::endl;return 1;}*p = 10;std::cout << *p << std::endl;operator delete(p);return 0;
}
  • 特点:
  • 只分配内存 , 不调用对象的构造函数(这是和 new 操作符的关键区别 , new 会在 operator new 分配内存后调用构造函数)。
  • 可以被重载 , 用户能自定义内存分配的方式(比如使用内存池等)。

4.2 operator delete函数

  • 功能 : 负责释放由 operator new 分配的内存块 , 与 C 语言中的 free 类似。
  • 函数原型(简化版) : void operator delete(void* ptr); 其中 ptr 是要释放的内存块指针。
  • 使用示例 : 如上面的示例 , 在使用 operator new 分配内存后 , 通过 operator delete(p) 释放内存。
  • 特点:
  • 只释放内存 , 不调用对象的析构函数(这是和 delete 操作符的关键区别 , delete 会在调用 operator delete 释放内存前调用析构函数)。
  • 同样可以被重载 , 用户能自定义内存释放的逻辑。

4.3 与new/delete操作符的关系

  • new 操作符的执行过程 : 先调用 operator new 分配内存 , 然后调用对象的构造函数初始化对象。
  • delete 操作符的执行过程 : 先调用对象的析构函数清理对象 , 然后调用 operator delete 释放内存。
  • 简单来说 , operator new 和 operator delete 是更底层的内存分配/释放工具 , new 和 delete 则是在它们的基础上 , 结合了对象的构造和析构操作 , 更符合 C++ 面向对象的特性。

5. new和delete的实现原理

5.1 内置类型

  • 如果申请的是内置类型的空间 , new和malloc , delete和free基本类似 , 不同的地方是:new/delete申请和释放的是单个元素的空间 , new[]和delete[]申请的是连续空间 , 而且new在申请空间失败时会抛异常 , malloc会返回NULL。

5.2 自定义类型

new的原理

  • 1. 调用operator new函数申请空间
  • 2. 在申请的空间上执行构造函数 , 完成对象的构造

delete的原理

  • 1. 在空间上执行析构函数 , 完成对象中资源的清理工作
  • 2. 调用operator delete函数释放对象的空间

new T[N]的原理

  • 1. 调用operator new[]函数 , 在operator new[]中实际调用operator new函数完成N个对象空间的申请
  • 2. 在申请的空间上执行N次构造函数

delete[]的原理

  • 1. 在释放的对象空间上执行N次析构函数 , 完成N个对象中资源的清理
  • 2. 调用operator delete[]释放空间 , 实际在operator delete[]中调用operator delete来释放空间

6. new/delete 和 malloc/free的区别

new/delete 和 malloc/free 都是 C++(及C)中用于动态内存管理的工具 , 主要区别如下:

1. 所属语言

  • malloc / free 是 C 语言的标准库函数 , 在 C++ 中也可使用 , 但更偏向于底层内存操作。
  • new / delete 是 C++ 的操作符 , 是 C++ 面向对象特性在内存管理上的体现。

2. 操作对象与功能

  • malloc / free :
  1. 仅负责内存的分配与释放 , 不涉及对象的构造和析构(因为C是面向过程语言 , 无“对象”概念)。
  2. malloc 需手动计算内存大小(如 malloc(sizeof(int)) ) , 返回 void* , 使用时通常需要强制类型转换。
  3. free 只需传入要释放的内存指针。
  • new / delete :
  1. 不仅分配/释放内存 , 还会自动调用对象的构造函数( new 时)和析构函数( delete 时)(针对自定义类型)。
  2. new 无需手动计算类型大小(如 new int 会自动分配 int 大小的内存) , 直接返回对应类型的指针 , 无需强制类型转换。
  3. delete 只需传入对象指针。

3. 数组操作

  • malloc / free :
  1. 分配数组需手动计算总内存大小(如  malloc(5 * sizeof(int)) ) , 释放时直接 free 指针 , 不涉及数组元素的“逐个清理”(因为无析构函数)。
  • new / delete :
  1. 分配数组用  new[] (如 new int[5] ) , 会为数组中每个元素(若为自定义类型)调用构造函数;释放数组用 delete[] , 会为每个元素调用析构函数 , 然后释放整块内存。若用 delete 释放 new[] 分配的数组(自定义类型) , 会因析构函数调用不完整导致内存泄漏或错误。

4. 内存不足处理

  • malloc : 内存不足时返回 NULL , 需手动检查返回值。
  • new : 内存不足时默认抛出 std::bad_alloc 异常 , 可通过异常处理机制捕获 , 也可自定义 new 的行为(如设置内存不足的回调)。

5. 重载与自定义

  • malloc / free : 不可重载 , 行为固定。
  • new / delete : 可以重载 , 用户可自定义内存分配和释放的逻辑(比如使用内存池等) , 更灵活地满足特定需求。

简单来说 , new / delete 是更“面向对象”的内存管理方式 , 封装了对象构造/析构的逻辑;而 malloc / free 更底层 , 仅关注内存块的分配与释放。在 C++ 中 , 更推荐使用 new / delete (尤其是处理自定义类型时) , 以利用其对对象生命周期的管理能力。

7. 总结:

本文系统介绍了C/C++程序的内存分布与动态内存管理机制。内存主要分为栈、堆、全局/静态区、常量区和代码区五部分 , 各自承担不同功能。C语言通过malloc/calloc/realloc/free进行动态内存管理 , 而C++引入了更高级的new/delete操作符 , 不仅能分配内存还能自动调用构造/析构函数。文章详细对比了malloc/free与new/delete的区别 , 并深入解析了operator new/delete的实现原理。关键在于:C++的new/delete是面向对象的内存管理方式 , 而malloc/free只进行原始内存操作。在C++开发中 , 特别是处理自定义类型时 , 应优先使用new/delete以确保完整的对象生命周期管理。

最后 , 感谢大家的观看!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/93350.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/93350.shtml
英文地址,请注明出处:http://en.pswp.cn/web/93350.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

1.2. qemu命令起虚拟机增加网络配置

1. 网络配置 常见的网络模式分为tap网络和基础网络模式两种。 1.1. TAP网络&#xff08;桥接模式&#xff09; 虚拟机直接接入宿主机物理网络&#xff0c;获得独立IP 1.1.1. 使用tap方式起虚拟机网络-netdev tap,idhostnet0,ifnametap0 \-device virtio-net-pci,netdevhostnet0…

分享一个Oracle表空间自动扩容与清理脚本

一、基础环境准备&#xff08;首次执行&#xff09; -- 1. 创建表空间监控表&#xff08;存储使用率、容量等信息&#xff09; create table monitor_tablespace_rate (tbs_name varchar2(50), -- 表空间名total_gb number, -- 总容量(GB)used_gb number, …

Flink Sql 按分钟或日期统计数据量

一、环境版本 环境版本Flink1.17.0Kafka2.12MySQL5.7.33 【注意】Flink 1.13版本增加Cumulate Window&#xff0c;之前版本Flink Sql 没有 Trigger 功能&#xff0c;长时间的窗口不能在中途触发计算&#xff0c;输出中间结果。比如每 10S 更新一次截止到当前的pv、uv。只能用T…

LeetCode 2460.对数组执行操作

给你一个下标从 0 开始的数组 nums &#xff0c;数组大小为 n &#xff0c;且由 非负 整数组成。 你需要对数组执行 n - 1 步操作&#xff0c;其中第 i 步操作&#xff08;从 0 开始计数&#xff09;要求对 nums 中第 i 个元素执行下述指令&#xff1a; 如果 nums[i] nums[i …

深入解析 @nestjs/typeorm的 forRoot 与 forFeature

nestjs/typeorm 是 NestJS 与 TypeORM 集成的官方模块&#xff0c;提供了 forRoot() 和 forFeature() 两个核心静态方法用于配置数据库连接和实体注册。本文将深入解析这两个方法的机制、使用场景和最佳实践。 一、TypeOrmModule.forRoot() - 全局数据库配置 forRoot() 方法用于…

关于simplifyweibo_4_moods数据集的分类问题

本来打算用情感分类数据集拿Transformer模型来练练手&#xff0c;发现训练效果并不好。当我分析了这个数据集的标签后发现问题了&#xff1a; 查看标签的分布&#xff1a; import pandas as pd# 先直接读取数据&#xff0c;不进行后续处理 data_file ~/data/simplifyweibo_4_m…

Custom SRP - Baked Light

https://catlikecoding.com/unity/tutorials/custom-srp/baked-light/本篇教程介绍将静态光照烘焙到 light map 和 light prob 中.首先贴上我遇到的问题,希望遇到的同学帮忙解答:实践本教程过程中,定义的 MetaPass 没有效果, Unity 始终在使用默认的 meta pass,我使用的是 unit…

[Python]PTA:实验2-3-1-for 求1到100的和

本题要求编写程序&#xff0c;计算表达式 1 2 3 ... 100 的值。输入格式&#xff1a;本题无输入。输出格式&#xff1a;按照以下格式输出&#xff1a;sum 累加和代码如下&#xff1a;x0 for i in range(1,101,1):xi print("sum {}".format(x))

【解决笔记】MyBatis-Plus 中无 selectList 方法

MyBatis-Plus 中无 selectList 方法的解决笔记 核心前提 MyBatis-Plus 的 BaseMapper 接口内置了 selectList 等基础查询方法&#xff0c;继承该接口可直接使用&#xff0c;无需手动实现。 无 selectList 方法的两种情况及解决方式 1. 未继承 BaseMapper&#xff08;推荐方案&a…

一周学会Matplotlib3 Python 数据可视化-绘制箱线图(Box)

锋哥原创的Matplotlib3 Python数据可视化视频教程&#xff1a; 2026版 Matplotlib3 Python 数据可视化 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili 课程介绍 本课程讲解利用python进行数据可视化 科研绘图-Matplotlib&#xff0c;学习Matplotlib图形参数基本设置&…

4.4 vue3生命周期函数

vue3生命周期函数生命周期钩子名称对比表阶段Vue 2 选项式 APIVue 3 组合式 API说明创建前beforeCreateonBeforeCreate&#xff08;已废弃&#xff09;Vue 3 中 setup() 替代创建完成createdsetup()&#xff08;替代&#xff09;setup 是入口&#xff0c;代替 beforeCreate 和 …

无脑整合springboot2.7+nacos2.2.3+dubbo3.2.9实现远程调用及配置中心

简介&#xff1a; 好久没有写博客了&#xff0c;最近辞职了有时间进行一次分享&#xff0c;今天我们主要是使用单体服务springboot整合nacos实现配置中心&#xff0c;然后整合dubbo来实现远程的rpc调用。如下是本地案例架构图&#xff0c;生产者和消费者的配置在nacos配置中心上…

腾讯位置商业授权微信小程序逆地址解析(坐标位置描述)

微信小程序JavaScript SDK 开发指南 逆地址解析(坐标位置描述) reverseGeocoder(options:Object) 本接口提供由坐标到坐标所在位置的文字描述的转换&#xff0c;输入坐标返回地理位置信息和附近poi列表。 注&#xff1a;坐标系采用gcj02坐标系 options属性说明 属性类型必填…

3D商品展示:技术狂欢下的普及困局

当微软推出Copilot 3D——仅需一张照片即可生成可编辑的3D模型时&#xff0c;业界曾欢呼“建模门槛彻底消失”。然而技术的美好愿景却撞上现实的铜墙铁壁&#xff1a;当前电商平台3D商品加载卡顿导致用户跳出率超60%&#xff0c;企业3D化渗透率仍不足34%。绚烂的技术烟花下&…

(Arxiv-2025)Stand-In:一种轻量化、即插即用的身份控制方法用于视频生成

Stand-In&#xff1a;一种轻量化、即插即用的身份控制方法用于视频生成 paper是WeChat发布在Arxiv 2025的工作 paper title:Stand-In: A Lightweight and Plug-and-Play Identity Control for Video Generation Code&#xff1a;链接 图1&#xff1a;给定一张参考图像&#xff…

数据科学与爬虫技术学习笔记

数据科学与爬虫技术学习笔记 一、数据科学基础库 1. NumPy&#xff1a;数值计算的基石 NumPy 是 Python 科学计算的核心库&#xff0c;专为数组和矩阵操作设计&#xff0c;能大幅简化循环操作&#xff0c;提供丰富的数学函数。 核心优势&#xff1a;高效处理同类型元素的多维…

学习嵌入式之硬件——I2C

一、I2C1.定义内部集成电路的简称&#xff0c;半双工串行同步通信&#xff0c;是芯片和芯片之间的通信方式&#xff1b;通常只有一个主机&#xff0c;多个从机&#xff0c;采用主从应答的方式上图所示是IIC的总线的使用场景&#xff0c;所有挂载在IIC总线上的设备都有两根信号线…

使用websockt

封装websocktHooksimport { ref, onMounted, onUnmounted } from vue;/*** webSocket的Hooks* param {string} websocket链接地址* */ export function useWebSocket(url: string) {// 核心状态 const data: Ref<any> ref(null);//收到websocket返回的数据const socke…

Jmeter自定义脚本

目录 log&#xff1a;输出类 Label&#xff1a;你自定义的组件的名称 FileName&#xff1a;添加的脚本文件的文件名 Parameters&#xff1a;你传入的参数&#xff0c;是一个字符串 args&#xff1a;你传入的参数&#xff0c;是一个数组 Parameters和args的异同&#xff1…

飞算 JavaAI 电商零售场景实践:从订单峰值到供应链协同的全链路技术革新

目录 一、电商核心场景的技术攻坚 1.1 分布式订单系统的事务一致性设计 1.1.1 TCC 模式下的订单创建流程 1.1.2 订单状态机的可靠流转 1.2 高并发秒杀系统的架构设计 1.2.1 多级限流与流量削峰 1.2.2 库存防超卖机制 1.3 智能推荐与用户行为分析 1.3.1 用户行为实时采…