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

c++:智能指针

1.智能指针使用场景与优势

void Func()
{
int* array1 = new int[10];
int* array2 = new int[10]; 
try
{
int len, time;
cin >> len >> time;
cout << Divide(len, time) << endl;
}
catch (...)
{
cout << "delete []" << array1 << endl;
cout << "delete []" << array2 << endl;
delete[] array1;
delete[] array2;
throw; // 异常重新抛出,捕获到什么抛出什么
}
cout << "delete []" << array1 << endl;
delete[] array1;
cout << "delete []" << array2 << endl;
delete[] array2;
}

我们上面这段代码利用catch(...)处理了divide抛异常的处理情况,但是如果我们的异常是在第二个new的过程中抛出的,我们就需要再套一层catch(...)去处理释放array1的内存空间,一两个new还好,如果我们写了很多个new,此时再套catch(...)就会让代码逻辑很混乱

在这种时候我们就可以使用智能指针(是一个对象)来托管新申请的空间,通过对象的自动析构来完成自动资源释放

2.RAII设计与智能指针生效过程

RAII的核心思想:利用对象的生命周期来管理获取到的动态资源,避免资源泄露

在获取资源时将资源委托给一个对象,在对象的生命周期内资源始终有效,直到对象销毁的时候将资源释放

智能指针除了满足RAII之外,还需要方便对资源的访问,于是还要重载 operator*/

operator->/operator[] 等运算符。

接下来我们看看智能指针的简单实现:

template<class T>
class SmartPtr
{
public:
// RAII
SmartPtr(T* ptr)
:_ptr(ptr)
{}
~SmartPtr()
{
cout << "delete[] " << _ptr << endl;
delete[] _ptr;
}
// 重载运算符,模拟指针的⾏为,⽅便访问资源
T& operator*()
{
return *_ptr;
}
T* operator->()
{
return _ptr;
}
T& operator[](size_t i)
{
return _ptr[i];
}
private:
T* _ptr;
};

成员变量只有一个指针,该指针由new出来的地址初始化。

他的析构就是将接收的地址空间释放掉。

然后我们看看实际使用场景的用法:

double Divide(int a, int b)
{
// 当b == 0时抛出异常if (b == 0){throw "Divide by zero condition!";}else{
return (double)a / (double)b;}
}
void Func()
{SmartPtr<int> sp1 = new int[10];SmartPtr<int> sp2 = new int[10];for (size_t i = 0; i < 10; i++){sp1[i] = sp2[i] = i;}int len, time;cin >> len >> time;cout << Divide(len, time) << endl;
}

在新的空间申请出来之后我们立刻用智能指针对象接收,此时相当于将资源交给智能指针对象托管。

当divide函数抛异常之后,我们跳转到main函数的catch语句中,在此之前我们先将divide和Func的函数栈帧释放,此时智能指针对象就自动调用析构函数,从而将申请的动态空间都释放掉

3.库中收录的智能指针

所处头文件:<memory>

第一种:auto_ptr(不使用)

他也是一个支持自动调用析构的对象,但是他有一个巨大的缺陷,那就是在进行拷贝构造的

时候,为了不进行多次析构,资源的管理权会转移到新拷贝出来的对象中,而旧的只智能指针对象会指向nullptr。如果在一个项目中,后面的程序员不知道原本的智能指针对象已经指向空了,接着使用旧的智能指针对象,就会导致程序终止。

也正是因为这个原因,他已经被c++11标准中的unique_ptr完全替代了

第二种:unique_ptr(用于不用拷贝的情况)

为了解决auto_ptr的问题,unique_ptr的办法是:难办,就不办了!

也就是将拷贝构造和赋值重载都delete掉了,直接不支持拷贝左值对象了。

不过右值的拷贝是支持的,右值的拷贝走的是移动构造。

int* a = new int(1);unique_ptr<int> p(move(a));

第三种:shard_ptr(支持拷贝场景)

他是依据引用计数实现的,且支持拷贝和赋值的场景,不过引用计数这种实现方法也会导致shard_ptr会有额外的开销,所以我们在不用支持拷贝的场景中一般会使用unique_ptr,而不是shard_ptr

图示:

第四种:weak_ptr

主要用于解决shard_ptr的循环引用的问题

4.智能指针的原理

auto_ptr的核心逻辑是将管理权转移,会导致智能指针悬空,所以不使用。

unique_ptr的核心逻辑是不支持拷贝和赋值,在确实不需要拷贝和赋值的场景推荐使用

shard_ptr的核心逻辑是使用引用计数的方式支持拷贝和赋值的操作

下面我们重点实现shard_ptr:

(1)框架搭建:
 

template<class T>
class Shard_ptr
{
public:Shard_ptr(T* ptr = nullptr):_ptr(ptr){}~Shard_ptr(){if(_ptr)delete _ptr;}T& operator*(){return *_ptr;}T* operator->(){return _ptr;}
private:T* _ptr;
};

这里我们只实现了针对new一个变量的空间的析构释放,而没有实现new[]的析构释放,因为new[]的释放需要用到定制删除器。为了和库中方法名字区分开,我们将s大写

(2)引用计数设计逻辑

因为一个资源空间需要一个对应的引用计数管理,所以我们需要的是实现部分智能指针对象可以共用一个引用计数,却不是所有智能指针对象共用一个引用计数,于是我们不考虑使用静态成员变量来实现引用计数。

那么我们还有什么办法实现引用计数?

可以使用整型指针!

template<class T>
class Shared_ptr
{
public://构造Shared_ptr(T* ptr = nullptr):_ptr(ptr),_pcount(new int(1)){}//拷贝构造Shared_ptr(const Shared_ptr<T>& cp):_ptr(cp._ptr),_pcount(cp._pcount){++(*_pcount);}//析构~Shared_ptr(){if (--(*_pcount) == 0){delete _ptr;delete _pcount;}}T& operator*(){return *_ptr;}T* operator->(){return _ptr;}
private:T* _ptr;int* _pcount;
};

拷贝构造的实现:

拷贝后相当于我们新的智能指针也要管理和被拷贝的智能指针一样的空间,此时我们需要将资源地址和引用计数地址都给到新的智能指针对象,并让引用计数++

析构函数的实现:
每次调用析构的时候说明有一个智能指针对象不再管理该资源空间,所以我们在_pcount不为0的时候不用释放资源空间,只需要让_pcount--即可

下面我们分不同的情况分类讨论该方法的可行性:

(1)当我们有一个新的资源空间需要智能指针管理,我们构造一个智能指针,同时也就会申请一块4字节的空间用于存放引用计数的整型数据,并将地址给到_pcount。

这说明单智能指针管理情景逻辑合理

(2)当我们需要两个智能指针共同管理一个资源空间的时候,可以通过让不同的智能指针对象指向同一个引用计数对象和资源空间来实现共同管理

(3)赋值重载

//赋值重载Shared_ptr<T>& operator=(const Shared_ptr<T>& cp){if (_ptr != cp._ptr){release();_ptr = cp._ptr;_pcount = cp._pcount;++(*_pcount);}return *this;}

当我们两个智能指针对象指向的资源空间是不一样的时候,我们需要让被赋值智能指针的ptr和pcount都指向赋值的智能指针的资源和引用计数,引用计数++,并在更改指向之前先调用一次release(表示不再控制旧的资源空间),最后返回智能指针对象。

当我们智能指针指向的资源是一样的时候,我们不用对两个智能指针做任何操作。

release:

void release(){if (--(*_pcount) == 0){delete _ptr;delete _pcount;}}

release其实就是析构的代码封装起来了


上面的实现只能支持new ,而不能支持new [ ]/malloc多段空间。

库中使用的方法是使用定制删除器

对于shard_ptr我们可以直接在构造的时候将定制删除器作为第二个参数传递给它,其中定制删除器可以是lambda,函数指针,仿函数等。

对于unique_ptr我们需要现在模板参数部分将定制删除器类型作为第二个模板参数传递,然后再在第二个参数位置传递定制删除器

综上:shard_ptr的定制删除器对其类型没有影响,他是对象的一部分

unique_ptr的定制删除器类型是其类型的一部分,不同的定制删除器类型对应的unique_ptr是不一样的

接下来我们实现允许shard_ptr使用定制删除器的结构

template<class T>
class Shared_ptr
{
public:void release(){if (--(*_pcount) == 0){_del(_ptr);delete _pcount;}}//构造Shared_ptr(T* ptr = nullptr):_ptr(ptr), _pcount(new int(1)){}//定制删除器构造template<class D>Shared_ptr(T* ptr, D del):_ptr(ptr),_pcount(new int(1)),_del(del){}//拷贝构造Shared_ptr(const Shared_ptr<T>& cp):_ptr(cp._ptr),_pcount(cp._pcount),_del(cp._del){++(*_pcount);}//赋值重载Shared_ptr<T>& operator=(const Shared_ptr<T>& cp){if (_ptr != cp._ptr){release();_ptr = cp._ptr;_pcount = cp._pcount;++(*_pcount);}return *this;}//析构~Shared_ptr(){release();}T& operator*(){return *_ptr;}T* operator->(){return _ptr;}
private:T* _ptr;int* _pcount;function<void(T*)> _del = [](T* ptr) { delete ptr; };
};

变动点1:参数部分

因为我们需要接受的定制删除器是像lambda,仿函数,函数指针这样的可调用对象,且定制删除器的返回值都是void,参数都是指向资源的指针,而function包装器恰好就可以用来接收这些可调用对象,所以这里我们就创建一个新的包装器成员变量_del。

变动点2:构造函数

我们重载一个支持定制删除器的构造函数

变动点3:release函数

我们不再直接delete指向资源的指针,而是调用定制删除器进行资源释放

注意:如果我们的构造是不使用定制删除器的,此时我们应该使用delete ptr来释放资源,此时我们就可以在private部分给_del一个缺省值,而这个缺省值是一个可以实现delete ptr的可调用对象,这里我们用的是lambda


make_shared

作用:创建并返回一个将引用计数和资源空间紧贴着申请空间的智能指针

    shared_ptr<int> s(new int(1));//直接构造shared_ptr<int> s1 = make_shared<int>(1);//先make_shared再赋值

我们知道普通的shared_ptr的引用计数和资源空间的申请是分开的,也就是他们的申请空间不是连续的,这会导致堆空间有很多碎片化占用,会让连续空间的大小减少。且这种频繁向内存申请空间的行为也会导致效率降低。

图示:空间碎片化

我们有如下方法解决这些问题:
1.传递一个内存池减少频繁向内存申请空间的行为

2.使用make_shared,通过将引用计数申请的空间和资源空间申请为连续的空间,从而减少碎片化空间申请

图示:

第一个图是直接构造的情况,引用计数的空间和资源空间地址是非连续的

第二个图是make_shared的情况,他会将引用计数的地址和资源空间的地址连续开辟,从而达到减少碎片空间的目的

5.shard_ptr与weak_ptr

5.1shard_ptr的循环引用问题

我们思考一个场景:比如我们现在有一个链表类,它有一个next指针,一个prev指针,其中next指针指向该节点的后一个节点,而prev指针执行指向该节点的前一个节点。

我们需要用智能指针来托管它的对象的资源

思考:我们的next指针和prev指针的类型是list还是智能指针?
如果是list的类型,那么我们后续用智能指针托管的时候就无法用指针指向节点对象了

// 循环引⽤ -- 内存泄露
std::shared_ptr<ListNode> n1(new ListNode);
std::shared_ptr<ListNode> n2(new ListNode);n1->_next = n2;
n2->_prev = n1;

这里我们用智能指针n1和n2托管链表节点,而我们用next和prev指向的就是托管了链表节点的智能指针对象,所以要将next和prev类型设置为智能指针类型的指针。

我们分析一下当前的情况:

图示:

目前第一块资源有两个shared_ptr指向,分别是n1和prev。第二块资源分别由n2和next指向。

假设我们现在程序结束了,分别对第一个块资源空间和第二块资源空间调用析构,引用计数都变为1,但是由于有next指向第二块资源,prev指向第一块资源,此时形成了循环引用,所以实际上资源空间没有被释放,造成资源泄露

疑问:为什么会造成循环引用?

1.右节点由next指针管着,所以右节点的释放需要next对象析构

2.next在左节点中,next析构需要左节点释放

3.左节点由prev对象管着,左节点释放需要prev对象析构

4.prev对象在右节点中,prev析构需要右节点释放

这四点分析下来我们发现形成了闭环,也就是无法进行释放

此时我们就需要将next和prev的智能指针类型改为weak_ptr来解决这个问题了

5.2weak_ptr

weak_ptr又叫弱指针,这里的弱可以理解为他的功能比较单一,他就是创建出来解决shared_ptr的循环引用问题的。

它不支持直接的访问数据,也不支持直接构造,他的构造就是用于绑定shared_ptr

std::weak_ptr<ListNode> _next;
n1->_next = n2;

第一行代码表示weak_ptr的定义,然后第二行就是weak_ptr绑定shared_ptr,也就是初始化的过程。

疑问:weak_ptr解决循环引用的原理是什么?
循环引用出现的原因就是调用一次析构之后,正常来说应该直接释放空间资源,但是由于next和prev都指向了对位资源空间,导致引用计数都加一了,所以最终释放的时候因为引用计数不为0,没有释放。

那么weak_ptr就是让next和prev指向空间资源的时候不让引用计数++,从而达到避免循环引用的目标


总结:循环引用的出现场景需要满足的条件

两个被智能指针托管的对象中,存在成员变量也是会导致引用计数++类型的智能指针,且这两个智能指针互相指向另一个空间。此时就会导致循环引用

相关文章:

c++:智能指针

1.智能指针使用场景与优势 void Func() { int* array1 new int[10]; int* array2 new int[10]; try { int len, time; cin >> len >> time; cout << Divide(len, time) << endl; } catch (...) { cout << "delete []" << arr…...

RISC-V简介

RISC-V简介 1. RISC-V RISC-V&#xff08;发音为“riskfive”&#xff09;是一个基于精简指令集&#xff08;RISC&#xff09;原则的全新开源指令集架构&#xff08;ISA&#xff09;。其中的字母“V”包含两层意思&#xff0c;一是这是Berkeley从RISCI开始设计的第五代指令集…...

Google Test 与 Google Mock:C++ 测试与模拟的完美结合

Google Test 与 Google Mock&#xff1a;C 测试与模拟的完美结合 摘要 本文深入解析 Google Test&#xff08;GTest&#xff09;和 Google Mock&#xff08;GMock&#xff09;的核心功能与使用方法&#xff0c;探讨两者在 C 项目中的联合应用及集成策略。通过详细的功能介绍、…...

c语言数据结构----------二叉排序树

#include <stdio.h> #include <malloc.h>//定义二叉排序树 typedef struct BSTnode {int key; //节点值int keyNull; //便于地址传递struct BSTnode *lchild;struct BSTnode *rchild; } BSTnode;//往二叉排序树插入结点 int BSTInsert(BSTnode *T, int k) {if (…...

Sysstat学习

Sysstat&#xff08;System Statistics&#xff09;是一个功能强大的开源工具集&#xff0c;用于监控 Linux 系统的性能和资源使用情况&#xff0c;特别适用于 Ubuntu 系统。它包含多个工具&#xff0c;如 sar、iostat、mpstat 和 pidstat&#xff0c;帮助系统管理员实时或历史…...

智能体开发范式革命:Cangjie Magic的颠覆性创新与行业重塑

开篇:一场静悄悄的技术革命 2025年春季,人工智能领域发生了一场意义深远却鲜为人知的变革。仓颉社区推出的Cangjie Magic智能体开发平台,正以润物细无声的方式重塑着AI应用的构建范式。这并非简单的工具迭代,而是一次从底层逻辑到顶层设计的全面革新。本文将带领读者深入探…...

k8s 下 java 服务出现 OOM 后获取 dump 文件

文章目录 背景解决第 1 步:通过 Dockerfile 挂载 NFS 盘第 2 步:修改 dump 路径为 NFS 盘路径第 3 步:OOM dump 验证参考背景 😂 背景:项目部署在RainBond(k8s)环境下,容器出现 OOM 异常后,k8s 会自动进行滚动更新。 恰恰因为滚动更新,会导致原来的容器被删除。这…...

16位海明码解码电路设计教程

## 1. 海明码基本原理 ### 1.1 什么是海明码 海明码(Hamming Code)是一种能够检测并纠正单比特错误的纠错码&#xff0c;由理查德海明(Richard Hamming)于1950年发明。它通过添加几个校验位(奇偶校验位)到原始数据中&#xff0c;使得数据在传输过程中发生单比特错误时能够被检测…...

九、数据库day01--认识

文章目录 一、认识数据库1.数据库分类关系型数据库核⼼要素示例 2. SQL 语⾔3. MySQL 数据库介绍4. 数据库连接⼯具 Navicat连接数据库操作步骤 总结 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、认识数据库 说明: 数据库是专⻔⽤来存储数据的软…...

2.深入剖析 Rust+Axum 类型安全路由系统

摘要 详细解读 RustAxum 路由系统的关键设计原理&#xff0c;涵盖基于 Rust 类型系统的路由匹配机制、动态路径参数与正则表达式验证以及嵌套路由与模块化组织等多种特性。 一、引言 在现代 Web 开发中&#xff0c;路由系统是构建 Web 应用的核心组件之一&#xff0c;它负责…...

深度学习 从入门到精通 day_02

1. 自动微分 自动微分模块torch.autograd负责自动计算张量操作的梯度&#xff0c;具有自动求导功能。自动微分模块是构成神经网络训练的必要模块&#xff0c;可以实现网络权重参数的更新&#xff0c;使得反向传播算法的实现变得简单而高效。 1.1 基础概念 1. 张量 &#xff1a…...

Selenium 实现自动化分页处理与信息提取

Selenium 实现自动化分页处理与信息提取 在 Web 自动化测试或数据抓取场景中&#xff0c;分页处理是一个常见的需求。通过 Selenium&#xff0c;我们可以实现对多页面内容的自动遍历&#xff0c;并从中提取所需的信息。本文将详细介绍如何利用 Selenium 进行自动化分页处理和信…...

【系统搭建】DPDK实现两虚拟机基于testpmd和l2fwd的收发包

testpmd与l2fwd的配合构建一个高性能的虚拟网络测试环境。l2fwd服务工作在数据链路层&#xff0c;使用MAC地址寻址&#xff0c;很多基于DPDK的策略实现可以基于l2fwd进行开发。 一、拓扑结构示意 ------------------- 虚拟化层网络 ------------------- | 虚拟机1 …...

简单接口工具(ApiCraft-Web)

ApiCraft-Web 项目介绍 ApiCraft-Web 是一个轻量级的 API 测试工具&#xff0c;提供了简洁直观的界面&#xff0c;帮助开发者快速测试和调试 HTTP 接口。 功能特点 支持多种 HTTP 请求方法&#xff08;GET、POST、PUT、DELETE&#xff09;可配置请求参数&#xff08;Query …...

C语言数据类型取值范围

32位C语言整型数据类型取值范围 64位C语言整型数据类型取值范围 C语言标准数据类型保证的取值范围 在编写程序时如果要方便移植&#xff0c;我们应该关注的是图2-11的取值范围。 摘录自《CSAPP》。...

【机器学习】大数据时代,模型训练慢如牛?解锁Spark MLlib与分布式策略

Langchain系列文章目录 01-玩转LangChain&#xff1a;从模型调用到Prompt模板与输出解析的完整指南 02-玩转 LangChain Memory 模块&#xff1a;四种记忆类型详解及应用场景全覆盖 03-全面掌握 LangChain&#xff1a;从核心链条构建到动态任务分配的实战指南 04-玩转 LangChai…...

合成数据赋能AI:从生成到闭环的全景图谱

目录 合成数据赋能AI&#xff1a;从生成到闭环的全景图谱 &#x1f3af; 项目目标 &#x1f4c4; 白皮书 / PPT 大纲结构 一、合成数据概述&#xff08;What & Why&#xff09; 二、合成数据的核心生成技术&#xff08;How&#xff09; 三、合成数据适配任务&#xf…...

CS144 Lab0实战记录:搭建网络编程基础

文章目录 1 实验概述与背景2 ByteStream的设计与实现2.1 字节流抽象概述2.2 实现思路2.3 核心数据结构2.4 Writer实现细节2.5 Reader实现细节 3 WebGet应用实现 1 实验概述与背景 Stanford大学的CS144课程是计算机网络领域最著名的课程之一&#xff0c;其实验设计巧妙地引导学…...

杂记-LeetCode中部分题思路详解与笔记-HOT100篇-其三

时光荏苒啊&#xff0c;没想到这么快就到了四月份... 这个坑好久没写了&#xff0c;现在我们重启一下。 我看了一下之前的笔记&#xff0c;似乎是停留在了链表部分且HOT100中可以说最重要的链表题之一&#xff1a;LRU缓存居然没有写&#xff0c;真是岂有此理&#xff0c;让我…...

【python画图】:从入门到精通绘制完美柱状图

目录 Python数据可视化&#xff1a;从入门到精通绘制完美柱状图一、基础篇&#xff1a;快速绘制柱状图1.1 使用Matplotlib基础绘制1.2 使用Pandas快速绘图 二、进阶篇&#xff1a;专业级柱状图定制2.1 多系列柱状图2.2 堆叠柱状图2.3 水平柱状图 三、专业参数速查表Matplotlib …...

医疗设备预测性维护的合规性挑战与标准化路径研究

摘要 本研究从医疗设备全生命周期管理视角&#xff0c;探讨预测性维护技术面临的特殊合规性挑战及其标准化解决方案。通过分析全球12个主要医疗市场的监管差异&#xff0c;提出基于ISO 23510的通用合规框架&#xff0c;并验证其在三类典型医疗设备&#xff08;生命支持类、影像…...

使用 XWPFDocument 生成表格时固定列宽度

一、XWPFDocument XWPFTable个性化属性 1.初始默认写法 XWPFTable table document.createTable(n, m); //在文档中创建一个n行m列的表格 table.setWidth("100%"); // 表格占页面100%宽度// 通过getRow获取行进行自定义设置 XWPFTableRow row table.getRow(0); XW…...

抽象的https原理简介

前言 小明和小美是一对好朋友&#xff0c;他们分隔两地&#xff0c;平时经常写信沟通&#xff0c;但是偶然被小明发现他回给小美的信好像被人拆开看过&#xff0c;甚至偷偷被篡改过。 对称加密算法 开头的通信过程比较像HTTP服务器与客户端的通信过程&#xff0c;全明文传输…...

Chakra UI框架中响应式断点

默认的断点&#xff1a;base是默认样式&#xff0c;不带任何媒体查询&#xff0c;适用于所有屏幕。 sm是30em&#xff08;约480px&#xff09; md是48em&#xff08;768px&#xff09; lg是62em&#xff08;992px&#xff09; xl是80em&#xff08;1280px&#xff09; 2xl是96e…...

【cocos creator 3.x】cocos creator2.x项目升级3.x项目改动点

1、基本改动 基本改动&#xff1a;去掉了cc.&#xff0c;改成在顶部添加导入 项目升级时候直接将cc.去掉&#xff0c;根据提示添加引用 node只保留position,scale,rotation,layer 其余属性如opacity&#xff0c;如果需要使用需要在节点手动添加UIOpacity组件 3d层和ui层分开…...

【android telecom 框架分析 01】【基本介绍 2】【BluetoothPhoneService为何没有源码实现】

1. 背景 我们会在很多资料上看到 BluetoothPhoneService 类&#xff0c;但是我们在实际 aosp 中确找不到具体的实现&#xff0c; 这是为何&#xff1f; 这是一个很好的问题&#xff01;虽然在车载蓝牙电话场景中我们经常提到类似 BluetoothPhoneService 的概念&#xff0c;但…...

Linux:进程:进程调度

进程在CPU上运行具有以下特性&#xff1a; 竞争、独⽴、并⾏、并发 竞争性:系统进程数⽬众多&#xff0c;⽽CPU资源很少甚至只有一个&#xff0c;所以进程之间是具有竞争属性的。为 了⾼效完成任务&#xff0c;更合理竞争相关资源&#xff0c;便具有了优先级 独⽴性: 为了避…...

2025年探秘特种设备安全管理 A 证:守护安全的关键凭证​

在现代工业与生活中&#xff0c;特种设备如锅炉、压力容器、电梯、起重机械等广泛应用&#xff0c;它们给我们带来便利的同时&#xff0c;也伴随着较高的安全风险。为了确保这些设备的安全运行&#xff0c;保障人民生命财产安全&#xff0c;特种设备安全管理显得尤为重要&#…...

WebSocket 实现数据实时推送原理

WebSocket 实现数据实时推送的核心机制在于其全双工通信能力和持久的连接特性。以下是其工作原理的详细步骤&#xff1a; 1. 握手阶段&#xff08;HTTP 升级协议&#xff09; 客户端发起请求&#xff1a;通过发送一个带有特殊头部的 HTTP 请求&#xff0c;请求协议升级。 GET …...

快速迭代收缩-阈值算法(FISTA)

文章目录 1. 数学与优化基础2. FISTA 算法的原理、推导与机制3. Matlab 实现4. FISTA 在图像处理与压缩感知中的应用4.1. 基于小波稀疏先验的图像去噪4.2 压缩感知图像重建 1. 数学与优化基础 在许多信号处理与机器学习问题中&#xff0c;我们希望获得稀疏解&#xff0c;即解向…...

XC6SLX100T-2FGG484I 赛灵思 XilinxFPGA Spartan-6

XC6SLX100T-2FGG484I 是Xilinx 推出的Spartan-6 LXT 系列FPGA芯片&#xff0c;采用45nm工艺设计&#xff0c;以高性价比和低功耗为核心 系列定位&#xff1a;Spartan‑6 LXT&#xff0c;中端逻辑与 DSP 加速 逻辑资源&#xff1a;101 261 个逻辑单元&#xff08;LE&#xff0…...

DP 32bit位宽数据扰码实现和仿真

关于DisplayPort 1.4协议中扰码用的16-bit LFSR的移位8个时钟周期后的输出表达式我们已经用迭代的方法推导过&#xff0c;那么移位32个时钟周期的输出表达式同样可以迭代32次推导出&#xff0c;或者将移位8个时钟的输出表达式迭代3次也可以得到。以下就是移位32个时钟周期的输出…...

Electricity Market Optimization 探索系列(V)

本文参考链接link \hspace{1.6em} 众所周知, 社会福利是指消费者剩余和生产者剩余的和&#xff0c;也等价于产品的市值减去产品的成本&#xff0c;在电力市场中也非常关注社会福利这一概念&#xff0c;基于电力商品的同质性的特点&#xff0c;我们引入反价格需求函数来形象地刻…...

vue3 element-plus el-time-picker控制只显示时 分,并且控制可选的开始结束时间

只显示时分 控制只显示时分 HH:mm 控制只显示时分秒 HH:mm:ss 全部代码&#xff1a; <template><el-time-pickerstyle"width: 220px !important;"v-model"timeValue"format"HH:mm"value-format"HH:mm"/> </template&…...

从技术本质到未来演进:全方位解读Web的过去、现在与未来

一、Web的本质定义 Web(万维网)是一种基于**超文本传输协议(HTTP)和统一资源标识符(URI)**构建的分布式信息系统。它的核心在于通过超链接将全球范围内的信息资源连接成网状结构,使任何接入互联网的设备都能访问这些资源。Web的本质特征体现在三个方面: 跨平台性:无论…...

C++十进制与十六进制

在C中&#xff0c;可以使用不同的方式来表示十进制和十六进制数值。下面是一个简单的示例代码&#xff0c;展示了如何在C中表示和输出十进制和十六进制数值&#xff1a; #include <iostream> #include <iomanip>int main() {int decimalValue 255; // 十进制数值…...

MySQL基本语法

本地登录&#xff1a;mysql -u 用户名 -p 查看数据库&#xff1a;show databeases 创建库&#xff1a;create database 名字&#xff1b; 删除库&#xff1a;drop database 名字&#xff1b; 选择库&#xff1a;use 名字&#xff1b; 创建表&#xff1a;create table 表名 在…...

机器学习有多少种算法?当下入门需要全部学习吗?

机器学习算法如同工具箱中的器械——种类繁多却各有专攻。面对数百种公开算法&#xff0c;新手常陷入"学不完"的焦虑。本文将拆解算法体系&#xff0c;为初学者指明高效学习路径。 一、算法森林的全景地图 机器学习算法可按四大维度分类&#xff1a; 监督学习&#…...

【c语言】深入理解指针2

文章目录 一、指针数组指针数组模拟二维数组 二、数组指针二维数组传参的本质 三、字符指针变量四、函数指针变量4.1. 函数指针的应用4.2 两端有趣的代码4.3. typedef关键字4.3.1 typedef 的使用4.3.2. typedef与#define对比 五、函数指针数组函数指针数组的应用 一、指针数组 …...

Nacos

Nacos是阿里巴巴的产品&#xff0c; 现在是SpringCloud中的一个组件。相比Eureka功能更加丰富&#xff0c;在国内受欢迎程度较高。 官网地址&#xff1a;Redirecting to: https://nacos.io/ GitHub&#xff1a; https://github.com/alibaba/nacos 1.Nacos快入门 Nacos可以直…...

Linux,redis群集模式,主从复制,读写分离

redis的群集模式 主从模式 &#xff08;单项复制&#xff0c;主复制到从&#xff09; 一主两从 一台主机上的一主两从 需要修改三个配置文件 主要端口不一样 redis-8001.conf redis-8002.conf redis-8003.conf 哨兵模式 分布式集群模式 redis 安装部署 1&#xff0c;下载…...

《手环表带保养全攻略:材质、清洁与化学品避坑指南》

系列文章目录 文章目录 系列文章目录前言一、表带材质特性与专属养护方案二、清洁剂使用红黑榜三、家庭清洁实验&#xff1a;化学反应警示录四、保养实践方法论总结 前言 手环作为现代生活的智能伴侣&#xff0c;表带材质选择丰富多样。从柔软亲肤的皮质到耐用耐磨的金属&…...

【Leetcode 每日一题 - 补卡】1534. 统计好三元组

问题背景 给你一个整数数组 a r r arr arr&#xff0c;以及 a 、 b 、 c a、b 、c a、b、c 三个整数。请你统计其中好三元组的数量。 如果三元组 ( a r r [ i ] , a r r [ j ] , a r r [ k ] ) (arr[i], arr[j], arr[k]) (arr[i],arr[j],arr[k]) 满足下列全部条件&#xff…...

医疗设备预测性维护合规架构:从法规遵循到技术实现的深度解析

在医疗行业数字化转型加速推进的当下&#xff0c;医疗设备预测性维护已成为提升设备可用性、保障医疗安全的核心技术。然而&#xff0c;该技术的有效落地必须建立在严格的合规框架之上。医疗设备直接关乎患者生命健康&#xff0c;其维护过程涉及医疗法规、数据安全、质量管控等…...

如何在 IntelliJ IDEA 中安装 FindBugs-IDEA 1.0.1

以下是 FindBugs-IDEA 1.0.1 插件在 IntelliJ IDEA 中的安装步骤&#xff08;适用于较旧版本的 IDEA&#xff0c;新版本可能需使用替代插件如 SpotBugs&#xff09;&#xff1a; 方法一&#xff1a;手动下载安装&#xff08;适用于无法通过市场安装的情况&#xff09; 下载插件…...

小车正常但是加载不出地图 找不到mapserver

Request for map failed; trying again... 找不到mapserver 原因&#xff1a; bash [ERROR] [1744895448.714854952]: failed to open image file "/home/liyb/catkin_ws/src/nav_demo/map/crossing.pgm": Couldnt open /home/xxx/catkin_ws/src/nav_demo/map/cr…...

无头开发模式

“无头”开发模式&#xff08;Headless Development Mode&#xff09;是指在没有直接连接物理显示器&#xff08;monitor&#xff09;、键盘或鼠标等输入输出设备的情况下&#xff0c;通过远程工具&#xff08;如 SSH、SCP、rsync、VNC 或 Web 界面&#xff09;对设备进行开发、…...

DAY 47 leetcode 232--栈与队列.用栈实现队列

题号232 请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作&#xff08;push、pop、peek、empty&#xff09;&#xff1a; class MyQueue {Stack<Integer> stackIn;Stack<Integer> stackOut;/** Initialize your data structure here. */pu…...

SpringAI+DeepSeek大模型应用开发——4 对话机器人

目录​​​​​​​ ​​​​​​​​​​​​​​项目初始化 pom文件 配置模型 ChatClient 同步调用 流式调用 日志功能 对接前端 解决跨域 会话记忆功能 ChatMemory 添加会话记忆功能 会话历史 管理会话id 保存会话id 查询会话历史 完善会话记忆 定义可序列…...

leetcode0058. 最后一个单词的长度-easy

1 题目&#xff1a;最后一个单词的长度 官方标定难度&#xff1a;易 给你一个字符串 s&#xff0c;由若干单词组成&#xff0c;单词前后用一些空格字符隔开。返回字符串中 最后一个 单词的长度。 单词 是指仅由字母组成、不包含任何空格字符的最大子字符串。 示例 1&#x…...