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

C++初阶 - 5.C/C++内存管理

目录

1.C/C++的内存分布

2.C语言中动态内存管理方式:malloc、calloc、realloc、free

3.C++内存管理方式

3.1 new/delete操作内置类型

3.2 new 和 delete操作自定义类型

4.operator new 与 operator delete 函数(重要点)

4.1 operator new 与 operator delete函数(重点)

4.2 重载 operator new 与operator delete(了解)

5.new 和 delete 的实现原理

5.1 内置类型

5.2 自定义类型

6. 定位 new 表达式(placement-new)(了解) 

7.常见面试题

7.1 malloc / free 和 new / delete 的区别

7.2 内存泄漏

7.2.1什么式内存泄漏,内存泄漏的危害

7.2.2 内存泄漏的危害

7.2.3 如何检测内存泄漏(了解)

7.2.4 如何避免内存泄漏


1.C/C++的内存分布

我们先来看一下下面的代码和相关问题

int globalVar = 1;
static int staticGlobalVar = 1;
void Test()
{static int staticVar = 1;int localVar = 1;int num1[10] = { 1, 2, 3, 4 };char char2[] = "abcd";const char* pChar3 = "abcd";int* ptr1 = (int*)malloc(sizeof(int) * 4);int* ptr2 = (int*)calloc(4, sizeof(int));int* ptr3 = (int*)realloc(ptr2, sizeof(int) * 4);free(ptr1);free(ptr3);
}1. 选择题:
选项: A.栈 B.堆 C.数据段(静态区) D.代码段(常量区)
globalVar在哪里?__C__   // 全局变量,全局变量和静态数据存放在 数据段(静态区) 
staticGlobalVar在哪里?__C__  // 静态数据,全局变量和静态数据段存放在 数据段(静态区) 
staticVar在哪里?__C__  // 静态数据,全局变量和静态数据段存放在 数据段(静态区)
localVar在哪里?__A__   //局部变量, 局部变量和函数存放在栈
num1 在哪里?__A__      //局部变量, 局部变量和函数存放在栈
char2在哪里?__A__      //局部变量, 局部变量和函数存放在栈
*char2在哪里?__A_      //局部变量, 局部变量和函数存放在栈
pChar3在哪里?__A__     //pChar3是一个指针变量,存储'abcd'的地址,属于局部变量, 局部变量和函数存放在栈
*pChar3在哪里?__D__    //pChar3是一个指针变量,存储'abcd'的地址,解引用后找到'abcd','abcd\0'存储在常量区。
ptr1在哪里?__A__       //ptr1是一个指针变量,存储malloc的地址,属于局部变量, 局部变量和函数存放在栈
*ptr1在哪里?__B__      //ptr1是一个指针变量,存储malloc的地址,解引用后拿到malloc的内容,该内容存放在堆区。2. 填空题:
sizeof(num1) = __40__;   //sizeof(数组名),求该数组的大小,4 * 10 = 40
sizeof(char2) = __5__;   //sizeof(数组名),求该数组的大小,"abcd" = "abcd\0" 一共5个元素,1 * 5 = 5
strlen(char2) = __4__;   //strlen()是库函数,求字符串长度,"abcd"一共4个元素。
sizeof(pChar3) = _4/8___;//pChar3是一个指针变量,指针变量的大小受操作系统影响,4/8
strlen(pChar3) = __4__;  //strlen()是库函数,求字符串长度,"abcd"一共4个元素。
sizeof(ptr1) = __4/8__;    //ptr1是一个指针变量,指针变量的大小受操作系统影响,4/83. sizeof 和 strlen 区别?
sizeof()是操作符,求取变量的大小,
strlen()是函数,求的是字符串的长度,需要注意字符串一般末尾有'\0'作为结束标识符。

 【说明】

  1. 又叫堆栈--非静态局部变量/函数参数/返回值等等,栈是向下增长的。
  2. 内存映射段--高效的IO映射方式,用于装载一个共享的动态内存库,用户可使用系统接口创建共享内存,做进程间通信,(Linux部分会详细讲解)
  3. --用于程序运行时动态内存分配,堆是向上增长。
  4. 数据段--存储全局变量和静态数据。
  5. 代码段--可执行的代码/只读常量。

2.C语言中动态内存管理方式:malloc、calloc、realloc、free

void Test ()
{int* p1 = (int*) malloc(sizeof(int));free(p1);// 1.malloc/calloc/realloc的区别是什么?int* p2 = (int*)calloc(4, sizeof (int));int* p3 = (int*)realloc(p2, sizeof(int)*10);// 这里需要free(p2)吗?/*不需要,realloc扩容方式分为两种:原地扩容,地址不改变。新位置扩容,copy原位置的内容,给到新位置,返回新位置的地址。*/free(p3 );
}

面试题:

1.malloc/calloc/realloc的区别?

malloc申请的空间没有初始化,直接返回起始地址。

calloc申请的空间,会把空间初始化为0,然后返回起始地址。

realloc是对已经开辟好的空间进行扩容,扩容方式分为两种:
            原地扩容,地址不改变。
            新位置扩容,copy原位置的内容,给到新位置,返回新位置的地址。

2.malloc的实现原理?

【CTF】GLibc堆利用入门-机制介绍_哔哩哔哩_bilibili

3.C++内存管理方式

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

3.1 new/delete操作内置类型

#include<iostream>
using namespace std;
int main()
{//动态申请一个int类型的空间//C    int* p1 = (int*)malloc(sizeof(int));free(p1);//CPPint* p2 = new int;delete p2;//动态申请10个int类型的空间//Cint* p3 = (int*)malloc(sizeof(int) * 10);free(p3);//CPPint* p4 = new int[10];delete[] p4;//动态申请一个int类型的空间并初始化为10//CPPint* p5 = new int(10);cout << "p5;" << *p5 << endl;delete p5;//动态申请一个int类型的数组空间并初始化为{1,2,3,0}//CPPint* p6 = new int[10] {1,2,3,0};for (int i = 0; i < 10; i++){cout << "p6;" << *(p6+i) << endl;}delete[] p6;return 0;
}

注意:申请和释放单个元素的空间,使用new和delete操作符,申请和释放连续的空间,使用new[] 和 delete[]。注意:匹配起来使用。

3.2 new 和 delete操作自定义类型

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));A* p2 = new A(1);free(p1);delete p2;//内置类型几乎是一样的int* p3 = (int*)malloc(sizeof(int));//Cint* p4 = new int;free(p3);delete p4;A* p5 = (A*)malloc(sizeof(A)*10);A* p6 = new A[10];free(p5);delete[] p6;return 0;
}

注意在申请自定义类型的空间时,new会调用构造函数,delete 会调用析构函数,而malloc和free不会。

【面试题】

1.C语言malloc\free 与C++new、delete 的区别?

动态申请内置类型的数据:new / malloc 除了用法上面,其他没有什么区别。

动态申请自定义类型的数据:new / malloc 除了用法上面,new会调用构造函数初始化,delete会调用析构函数清理。

4.operator new 与 operator delete 函数(重要点)

4.1 operator new 与 operator delete函数(重点)

new 和 delete 是用户进行动态内存申请和释放的操作符operator new 和 operator delete 是系统提供的全局函数new在底层调用了operator new 全局函数来申请空间,delete在底层通过operator delete全局函数来释放空间。

/*
operator new:该函数实际通过malloc来申请空间,当malloc申请空间成功时直接返回;申请空间
失败,尝试执行空 间不足应对措施,如果改应对措施用户设置了,则继续申请,否
则抛异常。
*/
void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
{// try to allocate size bytesvoid *p;while ((p = malloc(size)) == 0)if (_callnewh(size) == 0){// report no memory// 如果申请内存失败了,这里会抛出bad_alloc 类型异常static const std::bad_alloc nomem;_RAISE(nomem);}return (p);
}/*
operator delete: 该函数最终是通过free来释放空间的
*/
void operator delete(void *pUserData)
{_CrtMemBlockHeader * pHead;RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));if (pUserData == NULL)return;_mlock(_HEAP_LOCK); /* block other threads */__TRY/* get a pointer to memory block header */pHead = pHdr(pUserData);/* verify block type */_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));_free_dbg( pUserData, pHead->nBlockUse );//------------------------------__FINALLY_munlock(_HEAP_LOCK); /* release other threads */__END_TRY_FINALLYreturn;
}/*
free的实现
*/
#define free(p)   _free_dbg(p, _NORMAL_BLOCK)//-----------------------------

通过上述两个全局变量的实现,operator new 实际也是通过malloc来申请空间的,如果malloc申请空间成功就直接返回,否则执行用户提供的空间不足应对措施,如果用户提供该措施就继续申请,否则就抛异常。operator delete 最终是通过free来释放空间的

4.2 重载 operator new 与operator delete(了解)

注意:一般情况下不需要对operator new 和 operator delete进行重载,除非在申请和释放空间的时候有某些特殊的需求。比如:在使用new和delete申请空间和释放空间时,打印一些日志信息,可以帮助用户来检测时候存在内存泄漏。

// 重载operator delete,在申请空间时:打印在哪个文件、哪个函数、第多少行,申请了多少个
字节
void* operator new(size_t size, const char* fileName, const char* funcName,
size_t lineNo)
{void* p = ::operator new(size);cout << fileName << "-" << funcName << "-" << lineNo << "-" << p << "-"<< size << endl;return p;
}
// 重载operator delete,在释放空间时:打印再那个文件、哪个函数、第多少行释放
void operator delete(void* p, const char* fileName, const char* funcName,
size_t lineNo)
{cout << fileName << "-" << funcName << "-" << lineNo << "-" << p <<endl;::operator delete(p);
}
int main()
{// 对重载的operator new 和 operator delete进行调用int* p = new(__FILE__, __FUNCTION__, __LINE__) int;operator delete(p, __FILE__, __FUNCTION__, __LINE__);return 0;
}
// 上述调用显然太麻烦了,可以使用宏对调用进行简化
// 只有在Debug方式下,才调用用户重载的 operator new 和 operator delete
#ifdef _DEBUG
#define new new(__FILE__, __FUNCTION__, __LINE__)
#define delete(p) operator delete(p, __FILE__, __FUNCTION__, __LINE__)
#endif
int main()
{int* p = new int;delete(p);return 0;
}

5.new 和 delete 的实现原理

5.1 内置类型

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

5.2 自定义类型

  • new的原理
    • 调用operator new 函数申请空间
    • 在申请的空间上执行构造函数,完成对象的构造
  • delete 的原理
    • 在空间上执行析构函数,完成对象中资源的清理工作
    • 调用operator delete 函数释放对象的空间
  • new T[N]的原理
    • 调用operator new[] 函数,在operator new[] 中实际调用operator new 函数完成对N 个对象空间的申请
    • 在盛情的空间上执行N次构造函数
  • delete[] 的原理
    • 在释放的对象空间上执行N次析构函数,完成N个对象中资源的清理
    • 调用operator delete[]  释放空间。实际在operator delete[] 中调用 operator delete 来释放空间。

6. 定位 new 表达式(placement-new)(了解) 

定位new表达式是在已分配的原始内存空间中调用构造函数初始化一个对象。

使用格式:

new(place_address)type 或者 new(place_address)type(initializer-list)

place_address  必须是一个指针,initializer-list是类型的初始化列表

使用场景:

定位 new 表达式在实际中一般是配和内存池使用,因为内存池分配出的内存没有初始化,所以如果是自定义类型的对象,需要使用new的定义表达式进行显示调用构造函数进行初始化。

class A
{
public:A(int a = 0): _a(a){cout << "A():" << this << endl;}
~A(){cout << "~A():" << this << endl;}
private:int _a;
};
// 定位new/replacement new
int main()
{// p1现在指向的只不过是与A对象相同大小的一段空间,还不能算是一个对象,因为构造函数没有执行A* p1 = (A*)malloc(sizeof(A));new(p1)A; // 注意:如果A类的构造函数有参数时,此处需要传参p1->~A();free(p1);A* p2 = (A*)operator new(sizeof(A));new(p2)A(10);p2->~A();operator delete(p2);return 0;
}

7.常见面试题

7.1 malloc / free 和 new / delete 的区别

7.2 内存泄漏

7.2.1什么式内存泄漏,内存泄漏的危害

什么式内存泄偶?

内存泄漏指因为疏忽或错误造成程序未能释放已经不再使用的内存的情况,内存泄漏并不是指内存在物理上的消失,而是应用程序分配某段内存后,因为设计失误,失去了对该段内存的控制,因而造成了内存的浪费。

内存泄漏的危害?

长期运行的程序出现内存泄漏影响很大,如操作系统,后台服务等等,出现内存泄漏会导致响应越来越慢,最终卡死。 

void MemoryLeaks()
{// 1.内存申请了忘记释放int* p1 = (int*)malloc(sizeof(int));int* p2 = new int;// 2.异常安全问题int* p3 = new int[10];Func(); // 这里Func函数抛异常导致 delete[] p3未执行,p3没被释放.delete[] p3;
}

7.2.2 内存泄漏的危害

C/C++程序中一般我们关心两种方面的内存泄漏:

堆内存泄漏:

堆内存指的是程序执行中依据要分配通过malloc / calloc / realloc / new 等从堆中分配的一块内存,用完后必须通过调用相应的 free 或者 delete 删掉。假设程序的设计错误导致这部分内存没有被释放,那么以后这部分空间将无法被使用,就会产生Heap Leak。

系统资源泄漏

指程序使用系统分配的资源,比如套接字、文件描述符、管道等没有使用对应的函数释放掉,导致系统资源的浪费,严重可导致系统效能减少,系统执行不稳定。

7.2.3 如何检测内存泄漏(了解)

在vs下可以使用windows操作系统提供的 _CrtDumpMemoryLeaks() 函数进行简单检测,该函数只报出了大概泄漏了多少个字节,没有其他更准确的位置信息。

int main()
{int* p = new int[10];// 将该函数放在main函数之后,每次程序退出的时候就会检测是否存在内存泄漏_CrtDumpMemoryLeaks();return 0;
}// 程序退出后,在输出窗口中可以检测到泄漏了多少字节,但是没有具体的位置
Detected memory leaks!
Dumping objects ->
{79} normal block at 0x00EC5FB8, 40 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.

因此写代码时一定要小心,尤其是动态内存操作时,一定要记着释放。但有些情况下总是防不胜防,简单的可以采用上述方式快速定位下。如果工程比较大,内存泄漏位置比较多,不太好查时一般都是借助第三方内存泄漏检测工具处理的。

  • 在linux下内存泄漏检测:Linux下几款C++程序中的内存泄露检查工具
  • 在windows下使用第三方工具:VS编程内存泄漏
  • 其他工具:https://www.cnblogs.com/liangxiaofeng/p/4318499.html

7.2.4 如何避免内存泄漏

  1.  工程前期良好的设计规范,养成良好的编码规范,申请的内存空间记者匹配去释放。ps:
    这个理想状态。但是如果碰上异常时,就算注意释放了,还是可能会出问题。需要下一条智
    能指针来管理才有保证。
  2. 采用RAII思想或者智能指针来管理资源。
  3. 有些公司内部规范使用内部实现的私有内存管理库。这套库自带内存泄漏检测的功能选项。
  4. 出问题了使用内存泄漏工具检测。ps:不过很多工具都不够靠谱,或者收费昂贵。

总结一下:内存泄漏非常常见,解决方案分为两种:

1、事前预防型。如智能指针等。

2、事后查错型。如泄漏检测工具。

相关文章:

C++初阶 - 5.C/C++内存管理

目录 1.C/C的内存分布 2.C语言中动态内存管理方式&#xff1a;malloc、calloc、realloc、free 3.C内存管理方式 3.1 new/delete操作内置类型 3.2 new 和 delete操作自定义类型 4.operator new 与 operator delete 函数&#xff08;重要点&#xff09; 4.1 operator new 与…...

数学建模学习(3):综合评价类问题整体解析及分析步骤

一、评价类算法的简介 对物体进行评价&#xff0c;用具体的分值评价它们的优劣 选这两人其中之一当男朋友&#xff0c;你会选谁&#xff1f; 不同维度的权重会产生不同的结果 所以找到每个维度的权重是最核心的问题 0.25 二、评价前的数据处理 供应商ID 可靠性 指标2 指…...

【后端面经】微服务构架 (1-5) | 限流:濒临奔溃?限流守护者拯救系统于水火之中!

文章目录 一、前置知识1、什么是限流?2、限流算法A) 静态算法a) 漏桶b) 令牌桶c) 固定窗口d) 滑动窗口B) 动态算法3、限流的模式4、 限流对象4、限流后应该怎么做?二、面试环节1、面试准备2、基本思路3、亮点展现A) 突发流量(针对请求个数而言)B) 请求大小(针对请求大小而言)…...

HDFS异构存储详解

异构存储 HDFS异构存储类型什么是异构存储异构存储类型如何让HDFS知道集群中的数据存储目录是那种类型存储介质 块存储选择策略选择策略说明选择策略的命令 案例&#xff1a;冷热温数据异构存储对应步骤 HDFS内存存储策略支持-- LAZY PERSIST介绍执行使用 HDFS异构存储类型 冷…...

《面试1v1》Kafka消息是采用Pull还是Push模式

&#x1f345; 作者简介&#xff1a;王哥&#xff0c;CSDN2022博客总榜Top100&#x1f3c6;、博客专家&#x1f4aa; &#x1f345; 技术交流&#xff1a;定期更新Java硬核干货&#xff0c;不定期送书活动 &#x1f345; 王哥多年工作总结&#xff1a;Java学习路线总结&#xf…...

Windows环境Docker安装

目录 安装Docker Desktop的步骤 Docker Desktop 更新WSL WSL 的手动安装步骤 Windows PowerShell 拉取&#xff08;Pull&#xff09;镜像 查看已下载的镜像 输出"Hello Docker!" Docker Desktop是Docker官方提供的用于Windows的图形化桌面应用程序&#xff0c…...

Spring 6.0官方文档示例(23): singleton类型的bean和prototype类型的bean协同工作的方法(二)

使用lookup-method: 一、实体类&#xff1a; package cn.edu.tju.domain2;import java.time.LocalDateTime; import java.util.Map;public class Command {private Map<String, Object> state;public Map<String, Object> getState() {return state;}public void …...

Docker Compose 容器编排

Docker compose Docker compose 实现单机容器集群编排管理&#xff08;使用一个模板文件定义多个应用容器的启动参数和依赖关系&#xff0c;并使用docker compose来根据这个模板文件的配置来启动容器&#xff09; 通俗来说就是把之前的多条docker run启动容器命令 转换为docker…...

while循环

while循环是一种常见的循环结构&#xff0c;它会重复执行一段代码&#xff0c;直到指定的条件不再满足。 基本语法如下&#xff1a; while 条件: # 循环体代码 其中&#xff0c;条件是一个布尔表达式&#xff0c;如果为True&#xff0c;则执行循环体中的代码&#xff1b;如果…...

从JVM指令看String对象的比较

在翻看各类 java 知识中&#xff0c;总会提到如下知识&#xff1a;比较 String 对象&#xff0c;例如&#xff1a; String a1new String("10"); String a2"10"; String a3"1""0";//结果 System.out.println(a1a2); //false System.ou…...

python与深度学习(六):CNN和手写数字识别二

目录 1. 说明2. 手写数字识别的CNN模型测试2.1 导入相关库2.2 加载数据和模型2.3 设置保存图片的路径2.4 加载图片2.5 图片预处理2.6 对图片进行预测2.7 显示图片 3. 完整代码和显示结果4. 多张图片进行测试的完整代码以及结果 1. 说明 本篇文章是对上篇文章训练的模型进行测试…...

Linux使用教程

一、Linux命令基础 1、ls、ll命令——展示数据 ①ls命令——平铺展示数据 其中ls命令以平铺的方式展现数据 ②ll命令——列表展示数据 ll命令以列表的方式展现数据 -a选项&#xff0c;表示&#xff1a;all的意思&#xff0c;即列出全部文件&#xff08;包含隐藏的文件/文件夹…...

项目名称:智能家居边缘网关项目

一&#xff0c;项目介绍 软件环境: C语言 硬件环境: STM32G030C8TX单片机开发板 开发工具: Linux平台GCC交叉编译环境以及ukeil (1)边缘网关概念 边缘网关是部署在网络边缘侧的网关&#xff0c;通过网络联接、协议转换等功能联接物理和数字世界&#xff0c;提供轻量化的联接管…...

SciencePub学术 | 物联网类重点SCIEEI征稿中

SciencePub学术 刊源推荐: 物联网类重点SCIE&EI征稿中&#xff01;信息如下&#xff0c;录满为止&#xff1a; 一、期刊概况&#xff1a; 物联网类重点SCIE&EI 【期刊简介】IF&#xff1a;7.5-8.0&#xff0c;JCR1区&#xff0c;中科院1/2区TOP&#xff1b; 【出版社…...

EtherNet/IP转Modbus网关以连接AB PLC

本案例为西门子S7-1200 PLC通过捷米特Modbus转EtherNet/IP网关捷米特JM-EIP-RTU连接AB PLC的配置案例。 网关分别从ETHERNET/IP一侧和MODBUS一侧读写数据&#xff0c;存入各自的缓冲区&#xff0c;网关内部将缓冲区的数据进行交换&#xff0c;从而实现两边数据的传输。 网关做为…...

mysql用户添加

一、连接mysql服务 mysql -u root -p 二、查询用户表 use mysql &#xff1b; SELECT User, Host FROM mysql.user; 三、新增用户并授权 Create USER dev4rw% IDENTIFIED WITH mysql_native_password BY 新密码; GRANT ALL PRIVILEGES ON *.* TO dev4rw% WITH GRANT OP…...

628. 三个数的最大乘积

628. 三个数的最大乘积 class Solution {public int maximumProduct(int[] nums) {Arrays.sort(nums); return Math.max(nums[nums.length-1]*nums[nums.length-2]*nums[nums.length-3],nums[0]*nums[1]*nums[nums.length-1]);} }...

linux驱动开发入门(学习记录)

2023.7.6及7.7 概述了解 一 1.驱动框架 2. 字符设备 块设备&#xff0c;存储相关 网络设备驱动 不一定属于某一种类型二 1.获取外设或传感器数据&#xff0c;控制外设&#xff0c;数据会提交给应用程序 2.编写一个驱动&#xff0c;及测试应用程序 app。驱动和应用完全分开 3.驱…...

SpringCloud-Alibaba之Sentinel熔断与限流

一、下载安装运行 http://localhost:8080进行访问 登录账号和密码均为sentinel 二、创建工程&#xff0c;并注册到nacos服务中心 依赖spring-cloud-starter-alibaba-nacos-discovery,spring-cloud-starter-alibaba-sentinel sentine-datasource-nacos (持久化)配置文件 se…...

深“扒”云原生高性能分布式文件系统JuiceFS

JuiceFS 是一款面向云原生设计的高性能分布式文件系统&#xff0c;在 Apache 2.0 开源协议下发布。提供完备的 POSIX 兼容性&#xff0c;可将几乎所有对象存储接入本地作为海量本地磁盘使用&#xff0c;亦可同时在跨平台、跨地区的不同主机上挂载读写。 JuiceFS 简介 JuiceFS…...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

设计模式和设计原则回顾

设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

ES6从入门到精通:前言

ES6简介 ES6&#xff08;ECMAScript 2015&#xff09;是JavaScript语言的重大更新&#xff0c;引入了许多新特性&#xff0c;包括语法糖、新数据类型、模块化支持等&#xff0c;显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎&#xff1a;品融电商&#xff0c;一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中&#xff0c;品牌如何破浪前行&#xff1f;自建团队成本高、效果难控&#xff1b;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

GitHub 趋势日报 (2025年06月08日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践

6月5日&#xff0c;2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席&#xff0c;并作《智能体在安全领域的应用实践》主题演讲&#xff0c;分享了在智能体在安全领域的突破性实践。他指出&#xff0c;百度通过将安全能力…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中&#xff0c;电磁频谱已成为继陆、海、空、天之后的 “第五维战场”&#xff0c;雷达作为电磁频谱领域的关键装备&#xff0c;其干扰与抗干扰能力的较量&#xff0c;直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器&#xff0c;凭借数字射…...

Python 包管理器 uv 介绍

Python 包管理器 uv 全面介绍 uv 是由 Astral&#xff08;热门工具 Ruff 的开发者&#xff09;推出的下一代高性能 Python 包管理器和构建工具&#xff0c;用 Rust 编写。它旨在解决传统工具&#xff08;如 pip、virtualenv、pip-tools&#xff09;的性能瓶颈&#xff0c;同时…...

关于uniapp展示PDF的解决方案

在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项&#xff1a; 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库&#xff1a; npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...

LOOI机器人的技术实现解析:从手势识别到边缘检测

LOOI机器人作为一款创新的AI硬件产品&#xff0c;通过将智能手机转变为具有情感交互能力的桌面机器人&#xff0c;展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家&#xff0c;我将全面解析LOOI的技术实现架构&#xff0c;特别是其手势识别、物体识别和环境…...