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

C++---RAII模式

一、RAII模式概述

1. 定义

RAII(Resource Acquisition Is Initialization)即资源获取即初始化,是C++中用于管理资源生命周期的一种重要编程模式。其核心在于将资源的获取和释放操作与对象的生命周期紧密绑定。当对象被创建时,资源随之被获取;当对象离开其作用域时,析构函数自动被调用,资源也会被释放。

2. 核心思想
  • 资源获取即初始化(RAII):在对象的构造函数中完成资源的分配或获取操作,保证资源在对象创建时就处于可用状态。
  • 资源释放即清理(RAIIC):在对象的析构函数中进行资源的释放操作,确保资源在对象生命周期结束时被正确回收,避免资源泄漏。
  • 作用域控制生命周期:利用对象的作用域来自动管理资源的生命周期,当对象离开其作用域时,析构函数会自动调用,从而释放资源。

二、实现机制

1. 关键组件
  • 构造函数:负责资源的分配和初始化。在对象创建时,构造函数会被调用,在其中可以进行资源的申请,如分配内存、打开文件、建立网络连接等操作。
  • 析构函数:在对象生命周期结束时,析构函数会被自动调用,用于释放之前在构造函数中获取的资源。析构函数的调用是自动的,这确保了资源的释放操作不会被遗漏。
  • 拷贝控制(可选):在某些情况下,需要处理对象的拷贝和移动操作。拷贝构造函数和拷贝赋值运算符用于处理对象的拷贝,而移动构造函数和移动赋值运算符则用于处理对象的移动,避免不必要的资源复制,提高性能。
2. 标准实现范式
class ResourceHandle {
public:// 构造函数:资源分配ResourceHandle() {acquire();}// 析构函数:资源释放~ResourceHandle() {release();}// 移动构造函数ResourceHandle(ResourceHandle&& other) noexcept {handle = other.handle;other.handle = nullptr;}// 移动赋值运算符ResourceHandle& operator=(ResourceHandle&& other) noexcept {if (this != &other) {release();handle = other.handle;other.handle = nullptr;}return *this;}// 禁止拷贝构造函数ResourceHandle(const ResourceHandle&) = delete;// 禁止拷贝赋值运算符ResourceHandle& operator=(const ResourceHandle&) = delete;private:// 资源获取函数void acquire() {// 分配资源,例如:handle = new ResourceType();}// 资源释放函数void release() {// 释放资源,例如:delete handle;handle = nullptr;}ResourceType* handle = nullptr;
};

在上述代码中,ResourceHandle 类封装了对资源的管理。构造函数 ResourceHandle() 调用 acquire() 函数来获取资源,析构函数 ~ResourceHandle() 调用 release() 函数来释放资源。通过移动构造函数和移动赋值运算符,实现了资源的高效转移。同时,通过 delete 关键字禁止了拷贝构造函数和拷贝赋值运算符,避免了资源的重复释放问题。

三、适用资源类型

1. 内存资源
  • 原始指针管理:在传统的C++编程中,使用 new 运算符分配内存后,需要手动使用 delete 运算符释放内存。如果忘记释放或者在异常情况下没有正确释放,就会导致内存泄漏。而使用RAII模式,可以将内存管理封装在一个类中,在构造函数中分配内存,在析构函数中释放内存,确保内存的正确释放。
  • 智能指针的底层实现原理:C++标准库中的智能指针(如 std::unique_ptrstd::shared_ptrstd::weak_ptr)就是基于RAII模式实现的。std::unique_ptr 用于独占资源,当 std::unique_ptr 对象离开作用域时,会自动释放所管理的资源;std::shared_ptr 使用引用计数来管理资源,当引用计数为0时,会自动释放资源;std::weak_ptr 则是一种弱引用,不会增加引用计数,主要用于解决 std::shared_ptr 的循环引用问题。
2. 系统资源
  • 文件句柄:在使用文件时,需要打开文件并获取文件句柄,使用完后需要关闭文件句柄。通过RAII模式,可以创建一个文件管理类,在构造函数中打开文件,在析构函数中关闭文件,确保文件句柄的正确释放。
  • 网络套接字:在进行网络编程时,需要创建套接字并建立连接,使用完后需要关闭套接字。使用RAII模式可以将套接字的管理封装在一个类中,确保套接字在对象生命周期结束时被正确关闭。
  • 数据库连接:在访问数据库时,需要建立数据库连接,使用完后需要关闭连接。通过RAII模式,可以创建一个数据库连接管理类,在构造函数中建立连接,在析构函数中关闭连接,避免数据库连接泄漏。
  • 互斥锁(std::lock_guard的实现)std::lock_guard 是C++标准库中用于管理互斥锁的类,它基于RAII模式实现。在构造函数中对互斥锁进行加锁操作,在析构函数中进行解锁操作,确保互斥锁在作用域结束时自动解锁,避免死锁问题。
3. 其他资源
  • 图形上下文(OpenGL/DirectX):在进行图形编程时,需要创建图形上下文,使用完后需要销毁图形上下文。通过RAII模式,可以将图形上下文的管理封装在一个类中,确保图形上下文在对象生命周期结束时被正确销毁。
  • 动态库加载句柄:在加载动态库时,需要获取动态库的加载句柄,使用完后需要释放该句柄。使用RAII模式可以将动态库加载句柄的管理封装在一个类中,确保句柄在对象生命周期结束时被正确释放。
  • 线程池连接:在线程池编程中,需要从线程池中获取线程连接,使用完后需要将连接返回给线程池。通过RAII模式,可以创建一个线程池连接管理类,在构造函数中获取连接,在析构函数中返回连接,确保线程池连接的正确管理。

四、异常安全保障

1. 强异常保证
  • 构造函数失败时自动释放已获取资源:如果在构造函数中获取部分资源后发生异常,RAII模式能够确保已经获取的资源被正确释放。例如,在构造函数中需要依次获取多个资源,当获取某个资源失败时,之前已经获取的资源会在析构函数中被释放,避免资源泄漏。
  • 析构函数不抛出异常的约束:析构函数在设计时应该保证不抛出异常,因为在异常处理过程中,如果析构函数抛出异常,可能会导致程序崩溃。如果析构函数必须处理可能抛出异常的操作,应该在析构函数内部进行异常捕获和处理,确保不会将异常抛出。
2. 异常安全的实现策略
  • 资源获取顺序与释放逆序:在获取多个资源时,应该按照一定的顺序进行获取,而在释放资源时,应该按照相反的顺序进行释放。这样可以确保资源的正确释放,避免资源依赖关系导致的问题。
  • 禁止在析构函数中抛出异常:为了保证异常安全,析构函数应该避免抛出异常。如果析构函数中需要执行可能抛出异常的操作,应该在析构函数内部进行异常捕获和处理,确保不会将异常抛出。
  • 使用智能指针管理子资源:智能指针可以自动管理资源的生命周期,在异常发生时能够确保资源的正确释放。因此,在管理子资源时,应该优先使用智能指针,避免手动管理资源带来的风险。

五、标准库中的RAII实现

1. 智能指针
  • unique_ptrstd::unique_ptr 是一种独占式智能指针,它独占所管理的资源,不允许其他 std::unique_ptr 指向同一个资源。当 std::unique_ptr 对象离开作用域时,会自动释放所管理的资源。std::unique_ptr 可以通过移动语义进行转移,避免了资源的复制。
  • shared_ptrstd::shared_ptr 是一种共享式智能指针,它使用引用计数来管理资源。多个 std::shared_ptr 可以指向同一个资源,当引用计数为0时,会自动释放资源。std::shared_ptr 可以方便地实现资源的共享,但需要注意避免循环引用问题。
  • weak_ptrstd::weak_ptr 是一种弱引用,它不会增加引用计数,主要用于解决 std::shared_ptr 的循环引用问题。std::weak_ptr 可以通过 lock() 方法获取一个 std::shared_ptr,从而访问所管理的资源。
2. 容器类
  • vector的内存管理std::vector 是C++标准库中的动态数组容器,它使用RAII模式管理内部的内存。当 std::vector 对象离开作用域时,会自动释放所分配的内存。std::vector 会根据需要自动调整内存大小,确保内存的高效使用。
  • string的字符数组管理std::string 是C++标准库中的字符串类,它使用RAII模式管理内部的字符数组。当 std::string 对象离开作用域时,会自动释放所分配的字符数组。std::string 提供了方便的字符串操作接口,同时确保了内存的正确管理。
3. 同步机制
  • lock_guard(RAII式锁管理)std::lock_guard 是C++标准库中用于管理互斥锁的类,它基于RAII模式实现。在构造函数中对互斥锁进行加锁操作,在析构函数中进行解锁操作,确保互斥锁在作用域结束时自动解锁,避免死锁问题。
  • unique_lock(更灵活的锁管理)std::unique_lock 是一种更灵活的锁管理类,它也基于RAII模式实现。与 std::lock_guard 不同,std::unique_lock 可以在构造时不立即加锁,也可以在中途进行加锁和解锁操作,提供了更灵活的锁控制。

六、高级特性

1. 移动语义优化
  • 通过移动构造/赋值实现零拷贝资源转移:移动语义是C++11引入的重要特性,它允许在对象转移时避免不必要的资源复制。通过移动构造函数和移动赋值运算符,可以将资源的所有权从一个对象转移到另一个对象,而不需要进行资源的复制,从而提高了性能。
  • std::move的正确使用场景std::move 是一个标准库函数,用于将一个左值转换为右值引用,从而触发移动语义。在需要将对象的资源所有权转移时,可以使用 std::move 来调用移动构造函数或移动赋值运算符。
2. 资源所有权转移
  • 右值引用的作用:右值引用是C++11引入的一种新的引用类型,它主要用于支持移动语义。右值引用可以绑定到临时对象,通过右值引用可以实现资源的高效转移。
  • 完美转发的实现:完美转发是指在函数模板中,将参数以原始的左值或右值属性传递给其他函数。C++11引入了 std::forward 函数来实现完美转发,确保参数在传递过程中不会丢失其原始的左值或右值属性。
3. 多态资源管理
  • 使用抽象基类定义资源接口:在需要管理多种不同类型的资源时,可以使用抽象基类来定义资源的接口。具体的资源类可以继承自抽象基类,并实现接口中的方法。
  • 通过智能指针实现多态释放:使用智能指针(如 std::shared_ptr)可以实现多态资源管理。通过将智能指针指向抽象基类,可以根据实际对象的类型调用相应的析构函数,实现资源的多态释放。

七、优缺点分析

1. 优点
  • 自动资源管理,避免泄漏:RAII模式通过将资源的获取和释放与对象的生命周期绑定,确保资源在对象离开作用域时自动释放,避免了资源泄漏的问题。
  • 异常安全保障:RAII模式能够在异常发生时确保资源的正确释放,提供了异常安全保障。即使在构造函数中发生异常,已经获取的资源也会被正确释放。
  • 代码简洁易维护:使用RAII模式可以将资源管理的逻辑封装在一个类中,使代码更加简洁易读,减少了手动管理资源的代码量,提高了代码的可维护性。
  • 明确的资源生命周期:RAII模式通过对象的作用域来控制资源的生命周期,使资源的生命周期更加明确,便于理解和调试。
2. 局限性
  • 内存管理的灵活性限制:RAII模式将资源的生命周期与对象的生命周期绑定,在某些情况下可能会限制内存管理的灵活性。例如,在需要手动控制资源释放时机的场景下,RAII模式可能不太适用。
  • 性能敏感场景的额外开销:在性能敏感的场景下,RAII模式可能会带来一定的额外开销。例如,智能指针的引用计数操作会增加一定的性能开销。
  • 需要正确处理拷贝/移动语义:在使用RAII模式时,需要正确处理对象的拷贝和移动语义。如果处理不当,可能会导致资源的重复释放或泄漏问题。

八、最佳实践

1. 资源封装原则
  • 单一职责原则:每个资源管理类应该只负责管理一种资源,遵循单一职责原则,使类的功能更加明确。
  • 最小权限原则:资源管理类应该只提供必要的接口,遵循最小权限原则,避免暴露过多的实现细节。
  • 接口与实现分离:将资源管理类的接口和实现分离,提高代码的可维护性和可扩展性。
2. 设计规范
  • 优先使用移动语义:在需要进行对象转移时,优先使用移动语义,避免不必要的资源复制,提高性能。
  • 禁止拷贝时明确delete:如果资源管理类不允许拷贝,应该明确使用 delete 关键字禁止拷贝构造函数和拷贝赋值运算符,避免潜在的资源泄漏问题。
  • 析构函数保持无异常:析构函数应该保证不抛出异常,避免在异常处理过程中导致程序崩溃。
  • 使用智能指针管理子资源:在管理子资源时,优先使用智能指针,确保资源的正确释放。
3. 调试与测试
  • 重载operator<<输出资源状态:通过重载 operator<< 运算符,可以输出资源管理类的状态信息,方便调试和测试。
  • 断言检查资源有效性:在关键的操作中,可以使用断言来检查资源的有效性,确保程序的正确性。
  • 单元测试验证生命周期:编写单元测试来验证资源管理类的生命周期,确保资源在对象创建和销毁时能够正确获取和释放。

九、常见误区与陷阱

1. 拷贝语义陷阱
  • 隐式拷贝导致的双重释放:如果资源管理类没有正确处理拷贝语义,可能会导致隐式拷贝,从而使多个对象指向同一个资源,在对象销毁时会导致资源的双重释放。
  • 深拷贝与浅拷贝的选择:在处理资源管理类的拷贝时,需要根据实际情况选择深拷贝或浅拷贝。深拷贝会复制资源本身,而浅拷贝只是复制资源的指针,需要根据具体需求进行选择。
2. 循环引用问题
  • 使用weak_ptr打破循环:在使用 std::shared_ptr 时,如果出现循环引用问题,会导致资源无法正确释放。可以使用 std::weak_ptr 来打破循环引用,确保资源能够正确释放。
  • 明确资源所有权层级:在设计资源管理类时,应该明确资源的所有权层级,避免出现循环引用问题。
3. 析构函数异常
  • 异常屏蔽的潜在风险:如果析构函数抛出异常,可能会导致异常屏蔽,使程序的错误信息无法正常显示,增加调试难度。
  • 正确处理不可恢复错误:在析构函数中,如果遇到不可恢复的错误,应该尽量记录错误信息,避免抛出异常,确保程序的稳定性。

十、扩展应用

1. 自定义资源管理
  • 日志文件管理:可以创建一个日志文件管理类,在构造函数中打开日志文件,在析构函数中关闭日志文件,确保日志文件的正确管理。
  • 临时文件创建:在需要创建临时文件时,可以使用RAII模式创建一个临时文件管理类,在构造函数中创建临时文件,在析构函数中删除临时文件,确保临时文件的正确清理。
  • 性能计数器:可以创建一个性能计数器管理类,在构造函数中启动计数器,在析构函数中停止计数器并记录性能数据,方便进行性能分析。
  • 事务性操作:在进行数据库事务操作时,可以使用RAII模式创建一个事务管理类,在构造函数中开始事务,在析构函数中根据操作结果提交或回滚事务,确保事务的原子性。
2. 与其他模式结合
  • 策略模式(不同释放策略):可以将RAII模式与策略模式结合,根据不同的需求选择不同的资源释放策略。例如,对于某些资源,可以选择立即释放,而对于另一些资源,可以选择延迟释放。
  • 享元模式(共享资源管理):将RAII模式与享元模式结合,可以实现共享资源的管理。通过共享资源,可以减少资源的重复分配和释放,提高性能。
  • 工厂模式(资源创建封装):使用工厂模式可以封装资源的创建过程,结合RAII模式可以确保资源的正确管理。工厂模式可以根据不同的条件创建不同类型的资源管理对象。
3. 现代C++特性
  • 结构化绑定(C++17):C++17引入的结构化绑定可以方便地从对象中提取成员变量,在使用RAII模式管理资源时,可以使用结构化绑定来简化代码。
  • 协程中的资源管理(C++20):在C++20中引入了协程,协程中的资源管理也可以使用RAII模式。通过在协程的生命周期内管理资源,可以确保资源的正确释放。
  • 模块系统中的资源声明:C++20引入的模块系统可以更好地组织代码,在模块系统中可以使用RAII模式来管理资源。通过在模块中声明资源管理类,可以确保资源在模块的生命周期内得到正确管理。

RAII模式在C++编程中具有重要的地位,通过合理运用RAII模式,可以有效地管理资源,避免资源泄漏,提高代码的安全性和可维护性。在实际应用中,需要根据具体的需求和场景,正确使用RAII模式,并结合其他编程技巧和设计模式,以实现高效、可靠的程序。


保持渴望,保持同他人的联结,在平凡的日常中寻找自己感兴趣的事,留意别人忽视的东西。​​​ —罗伯·沃克

相关文章:

C++---RAII模式

一、RAII模式概述 1. 定义 RAII&#xff08;Resource Acquisition Is Initialization&#xff09;即资源获取即初始化&#xff0c;是C中用于管理资源生命周期的一种重要编程模式。其核心在于将资源的获取和释放操作与对象的生命周期紧密绑定。当对象被创建时&#xff0c;资源…...

Clion刷题攻略-配置Cmake

使用Clion刷题&#xff0c;在一个项目中创建多个main函数&#xff0c;每一个文件对应一道题目&#xff0c;将Clion作为题目管理系统使用&#xff0c;并且cpp文件允许使用中文名&#xff0c;exe文件统一输出到runtime目录&#xff0c;防止污染根目录&#xff0c;CmakeLists文件如…...

DEBUG:file命令

file 命令详解 file 是 Linux/Unix 系统中用于检测文件类型的实用工具。它通过检查文件的**魔数&#xff08;magic number&#xff09;**和内容结构来判断文件类型&#xff0c;而不是依赖文件扩展名。 1. 基本语法 file [选项] 文件名... 常用选项 选项说明-b (--brief)简洁…...

hackmyvn-casino

arp-scan -l nmap -sS -v 192.168.255.205 目录扫描 dirsearch -u http://192.168.255.205/ -e * gobuster dir -u http://192.168.255.205 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php -b 301,401,403,404 80端口 随便注册一个账号 玩游戏时的…...

Elasticsearch笔记

官网 https://www.elastic.co/docs 简介 Elasticsearch 是一个分布式、开源的搜索引擎&#xff0c;专门用于处理大规模的数据搜索和分析。它基于 Apache Lucene 构建&#xff0c;具有实时搜索、分布式计算和高可扩展性&#xff0c;广泛用于 全文检索、日志分析、监控数据分析…...

在Windows下使用Docker部署Nacos注册中心(基于MySQL容器)

需要两个容器Nacos容器和MySQL容器&#xff0c;MySQL容器专注数据存储&#xff0c;Nacos容器专注服务发现/配置管理 准备工作 确保已安装Docker Desktop for Windows确保已启用WSL 2(推荐)或Hyper-V确保Docker服务正在运行 部署步骤 1. 拉取所需镜像 # 拉取MySQL镜像(这里…...

去中心化自治组织(DAO):革新未来治理的下一站

去中心化自治组织(DAO):革新未来治理的下一站 引言 去中心化自治组织(DAO)的诞生,像是互联网时代的一道新曙光。它打破了传统组织的等级壁垒,以去中心化和智能合约为核心,让社区成员能够直接参与决策并共享收益。从NFT社区到投资基金,DAO的应用场景正以前所未有的速…...

ideal自动生成类图的方法

在 IntelliJ IDEA 中&#xff0c;“**在项目资源管理器中选择以下类**” 是指通过 **项目资源管理器&#xff08;Project Tool Window&#xff09;** 找到并选中你需要生成类图的类文件&#xff08;如 .java 文件&#xff09;&#xff0c;然后通过右键菜单或快捷键操作生成类图…...

爬虫获取1688关键字搜索接口的实战指南

在当今电商行业竞争激烈的环境下&#xff0c;数据的重要性不言而喻。1688作为国内领先的B2B电商平台&#xff0c;拥有海量的商品信息&#xff0c;这些数据对于商家的市场分析、选品决策、价格策略制定等都有着重要的价值。本文将详细介绍如何通过爬虫技术获取1688关键字搜索接口…...

视频设备轨迹回放平台EasyCVR渡口码头智能监控系统方案,确保港口安全稳定运行

一、背景 近年来&#xff0c;随着水上交通运输业的快速发展&#xff0c;辖区内渡口码头数量持续增加&#xff0c;船舶运营规模不断扩大&#xff0c;各类船舶活动频繁&#xff0c;给水上交通安全监管带来了巨大挑战。近期发生的多起村民使用无证木船捕鱼导致的伤亡事故&#xf…...

使用 Sales_data 类实现交易合并(三十)

1. Sales_data 类定义 假设 Sales_data 类定义在头文件 Sales_data.h 中&#xff0c;其基本定义如下&#xff1a; // Sales_data.h #ifndef SALES_DATA_H #define SALES_DATA_H#include <string>struct Sales_data {std::string bookNo; // ISBN 编号unsigned uni…...

电力系统惯量及其作用解析

电力系统中的惯量是指由同步发电机的旋转质量提供的惯性&#xff0c;用于抵抗系统频率变化的能力。其核心作用及要点如下&#xff1a; 1. 物理基础 转动惯量&#xff1a;同步发电机的转子具有质量&#xff0c;其转动惯量&#xff08;&#xff09;决定了转子抵抗转速变化的能力…...

HNSW(Hierarchical Navigable Small World,分层可导航小世界)用来高效搜索高维向量的最近邻

HNSW&#xff08;Hierarchical Navigable Small World&#xff0c;分层可导航小世界&#xff09;是一种用于 高效最近邻搜索&#xff08;ANN, Approximate Nearest Neighbors&#xff09; 的索引结构&#xff0c;专门用于在 高维向量&#xff08;比如文本、图像、音频的嵌入向量…...

STM32 CAN学习(一)

CAN总线应用最多的是汽车领域。 CAN&#xff08;Controller Area Network&#xff09;控制器 局域 网 局域网&#xff1a;把几台电脑连接到一台路由器上&#xff0c;这几台电脑就可以进行通讯了。 控制器在汽车中的专业术语叫做ECU&#xff08;Electronic Control Unit&…...

高效内存位操作:如何用C++实现数据块交换的性能飞跃?

「性能优化就像考古&#xff0c;每一层都有惊喜」—— 某匿名C工程师 文章目录 问题场景&#xff1a;当内存操作成为性能瓶颈性能深潜&#xff1a;揭开内存操作的面纱内存访问的三重代价原始方案的性能缺陷 性能突破&#xff1a;从编译器视角重构代码方案一&#xff1a;指针魔法…...

Spring Boot向Vue发送消息通过WebSocket实现通信

后端实现步骤 添加Spring Boot WebSocket依赖配置WebSocket端点和消息代理创建控制器&#xff0c;使用SimpMessagingTemplate发送消息 前端实现步骤 安装sockjs-client和stompjs库封装WebSocket连接工具类在Vue组件中建立连接&#xff0c;订阅主题 详细实现步骤 后端&…...

USB转串口数据抓包--Bus hound

Bus Hound是一款强大的总线分析工具。 Bus Hound 支持哪些设备 ? 所有的 IDE &#xff0c; SCSI &#xff0c; USB 和 1394 设备都得到支持&#xff0c;包括磁盘驱动器&#xff0c;鼠 标、扫描仪&#xff0c;网络摄像头&#xff0c;等等。只要是枚举成以上所列的总线类型的…...

Android 使用CameraX实现预览、拍照、录制视频(Java版)

Android 官方关于相机的介绍如下&#xff1a; https://developer.android.google.cn/media/camera/get-started-with-camera?hlzh_cn 一、开始使用 Android 相机 Android相机一般包含前置摄像头和后置摄像头&#xff0c;使用相机可以开发一系列激动人心的应用&#xff0c;例…...

【已解决】Javascript setMonth跨月问题;2025-03-31 setMonth后变成 2025-05-01

文章目录 bug重现解决方法&#xff1a;用第三方插件来实现&#xff08;不推荐原生代码来实现&#xff09;。项目中用的有dayjs。若要自己实现&#xff0c;参考 AI给出方案&#xff1a; bug重现 今天&#xff08;2025-04-01&#xff09;遇到的一个问题。原代码逻辑大概是这样的…...

DeepSeek技术架构解析:MLA多头潜在注意力

一、前言 我们上一篇已经讲了 DeepSeek技术架构解析&#xff1a;MoE混合专家模型 这一篇我们来说一说DeepSeek的创新之一&#xff1a;MLA多头潜在注意力。 MLA主要通过优化KV-cache来减少显存占用&#xff0c;从而提升推理性能。我们知道这个结论之前&#xff0c;老周带大家…...

02.02、返回倒数第 k 个节点

02.02、[简单] 返回倒数第 k 个节点 1、题目描述 实现一种算法&#xff0c;找出单向链表中倒数第 k 个节点。返回该节点的值。 2、题解思路 本题的关键在于使用双指针法&#xff0c;通过两个指针&#xff08;fast 和 slow&#xff09;&#xff0c;让 fast 指针比 slow 指针…...

剑指Offer(数据结构与算法面试题精讲)C++版——day2

剑指Offer(数据结构与算法面试题精讲)C++版——day2 题目一:只出现一次的数据题目二:单词长度的最大乘积题目三:排序数组中的两个数字之和题目一:只出现一次的数据 一种很简单的思路是,使用数组存储出现过的元素,比如如果0出现过,那么arr[0]=1,但是有个问题,题目中没…...

nginx的自动跳转https

mkdir /usr/local/nginx/certs/ 创建一个目录 然后用openssl生成证书 编辑nginx的配置文件 自动跳转成功 做一个优化&#xff0c;如果访问的时候后面加了其他的uri也一起自动跳转了...

正则表达式(Regular Expression,简称 Regex)

一、5w2h&#xff08;七问法&#xff09;分析正则表达式 是的&#xff0c;5W2H 完全可以应用于研究 正则表达式&#xff08;Regular Expressions&#xff09;。通过回答 5W2H 的七个问题&#xff0c;我们可以全面理解正则表达式的定义、用途、使用方法、适用场景等&#xff0c…...

Windows下在IntelliJ IDEA 使用 Git 拉取、提交脚本出现换行符问题

文章目录 背景问题拉取代码时提交代码时 问题原因解决方案1.全局配置 Git 的换行符处理策略2.在 IntelliJ IDEA 中配置换行符3.使用 .gitattributes 文件 背景 在 Windows 系统下使用 IntelliJ IDEA 进行 Git 操作&#xff08;如拉取和提交脚本&#xff09;时&#xff0c;经常…...

Python 实现的运筹优化系统代码详解(整数规划问题)

一、引言 在数学建模的广袤领域里&#xff0c;整数规划问题占据着极为重要的地位。它广泛应用于工业生产、资源分配、项目管理等诸多实际场景&#xff0c;旨在寻求在一系列约束条件下&#xff0c;使目标函数达到最优&#xff08;最大或最小&#xff09;且决策变量取整数值的解决…...

conda安装python 遇到 pip is configured with locations that require TLS/SSL问题本质解决方案

以前写了一篇文章&#xff0c;不过不是专门为了解决这个问题的&#xff0c;但是不能访问pip install 不能安装来自https 协议的包问题几乎每次都出现&#xff0c;之前解决方案只是治标不治本 https://blog.csdn.net/wangsenling/article/details/130194456​​​​​​​https…...

嘿嘿,好久不见

2025年4月2日&#xff0c;6~22℃&#xff0c;一般 遇见的事&#xff1a;参加了曲靖的事业单位D类考试。 感受到的情绪&#xff1a;考场一半的人都没有到位&#xff0c;这路上你到了可能都会受到眷顾。 反思&#xff1a;这路上很难&#xff0c;总有人会提前放弃&#xff0c;不…...

virsh 的工作原理

virsh是用于管理虚拟化环境中的客户机和Hypervisor的命令行工具。它基于libvirt管理API构建&#xff0c;与virt-manager等工具类似&#xff0c;都是通过调用libvirt API来实现虚拟化的管理。virsh是完全在命令行文本模式下运行的用户态工具&#xff0c;因此它是系统管理员通过脚…...

Qt实现HTTP GET/POST/PUT/DELETE请求

引言 在现代应用程序开发中&#xff0c;HTTP请求是与服务器交互的核心方式。Qt作为跨平台的C框架&#xff0c;提供了强大的网络模块&#xff08;QNetworkAccessManager&#xff09;&#xff0c;支持GET、POST、PUT、DELETE等HTTP方法。本文将手把手教你如何用Qt实现这些请求&a…...

(041)05-01-自考数据结构(20331)树与二叉树大题总结

实际考试中,计算题约占40%,推理题约占30%,算法设计题约占30%。建议重点练习遍历序列相关的递归分治解法, 知识拓扑 知识点介绍 一、计算题类型与解法 1. 结点数量计算 题型示例: 已知一棵完全二叉树的第6层有8个叶子结点,求该二叉树最多有多少个结点? 解法步骤: 完…...

WPS JS宏编程教程(从基础到进阶)-- 第三部分:JS宏编程语言开发基础

第三部分:JS宏编程语言开发基础 @[TOC](第三部分:JS宏编程语言开发基础)**第三部分:JS宏编程语言开发基础**1. 变量与数据类型**变量声明:三种方式****示例代码****数据类型判断****实战:动态处理单元格类型**2. 运算符全解析**算术运算符****易错点:字符串拼接 vs 数值相…...

迈向云原生:理想汽车 OLAP 引擎变革之路

在如今数据驱动的时代&#xff0c;高效的分析引擎对企业至关重要。理想汽车作为智能电动汽车的领军企业&#xff0c;面临着海量数据分析的挑战。本文将展开介绍理想汽车 OLAP 引擎从存算一体向云原生架构演进的变革历程&#xff0c;以及在此过程中面临的挑战&#xff0c;以及是…...

Spark,HDFS客户端操作

hadoop客户端环境准备 找到资料包路径下的Windows依赖文件夹&#xff0c;拷贝hadoop-3.1.0到非中文路径&#xff08;比如d:\hadoop-3.1.0&#xff09; ① 打开环境变量 ② 在下方系统变量中新建HADOOP_HOME环境变量,值就是保存hadoop的目录。 效果如下&#xff1a; ③ 配置Path…...

QuecPython 的 VScode 环境搭建和使用教程

为方便开发者使用 VSCode 开发 QuecPython&#xff0c;QuecPython 团队特推出了名为 QuecPython 的 VSCode 插件。 插件目前支持的功能有&#xff1a; 固件烧录REPL 命令交互代码补全文件传输文件系统目录树运行指定脚本文件 目前支持所有QUecPython系列模组。 插件安装 点…...

Linux Vim 编辑器的使用

Vim 编辑器的使用 一、安装及介绍二、基础操作三、高级功能四、配置与插件 一、安装及介绍 Vim是一款强大且高度可定制的文本编辑器&#xff0c;相当于 Windows 中的记事本。具备命令、插入、底行等多种模式。它可通过简单的键盘命令实现高效的文本编辑、查找替换、分屏操作等…...

Java 基础-28- 多态 — 多态下的类型转换问题

在 Java 中&#xff0c;多态&#xff08;Polymorphism&#xff09;是面向对象编程的核心概念之一。多态允许不同类型的对象通过相同的方法接口进行操作&#xff0c;而实际调用的行为取决于对象的实际类型。虽然多态提供了极大的灵活性&#xff0c;但在多态的使用过程中&#xf…...

机器学习中的自监督学习概述与实现过程

概述 机器学习中有四种主要学习方式&#xff1a; 监督式学习 (Supervised Learning)&#xff1a;这种学习方式通过使用带有标签的数据集进行训练&#xff0c;目的是使机器能够学习到数据之间的关联性&#xff0c;并能够对新的、未见过的数据做出预测或分类。应用领域包括语音识…...

AI Agent开发大全第十四课-零售智能导购智能体的RAG开发理论部分

开篇 经过前面的一些课程,我们手上已经积累了各种LLM的API调用、向量库的建立和使用、embedding算法的意义和基本使用。 这已经为我们具备了开发一个基本的问答类RAG的开发必需要素了。下面我们会来讲一个基本问答类场景的RAG,零售中的“智能导购”场景。 智能导购 大家先…...

Git相关笔记1 - 本地文件上传远程仓库

Git相关笔记 目录 Git相关笔记Git上传相关文件第一步创建一个仓库&#xff1a;第二步本地创建空文件夹&#xff1a;第三步开始在gitbush上传文件&#xff1a;解决外网网络连接的问题&#xff1a;中文文件的编码问题&#xff1a;参考资料 Git上传相关文件 第一步创建一个仓库&a…...

机器学习算法

目录 行向量与列向量 信息论 Logistic回归 支持向量机SVM 核函数&#xff1a; 决策树 Decision Tree CART决策树 ID3 决策树 C4.5 决策树 决策树的过拟合问题 回归树 ***仅做复习需要&#xff0c;若侵权请及时联系我 行向量与列向量 行向量&#xff1a;是一个横…...

学习记录706@微信小程序+springboot项目 真机测试 WebSocket错误: {errMsg: Invalid HTTP status.}连接不上

我微信小程序springboot项目 真机测试 websocket 总是报错 WebSocket错误: {errMsg: Invalid HTTP status.}&#xff0c;总是连接不上&#xff0c;但是开发者工具测试就没有问题。 最后解决方案是编码token&#xff0c;之前是没有编码直接拼接的&#xff0c;原因不详。 consol…...

SSH服务

一、准备 #请说明以下服务对应的端口号或者端口对应的服务 ssh 22 telnet 23 http 80 https 443 ftp 20 21 RDP 3389 mysql 3306 redis 6379 zabbix 10050 10051 elasticsear…...

GitHub上免费学习工具的精选汇总

以下是GitHub上免费学习工具的精选汇总&#xff0c;涵盖编程语言、开发框架、数据科学、面试准备等多个方向&#xff0c;结合工具的功能特点、社区活跃度及适用场景进行分类推荐&#xff1a; 一、编程语言与开发框架 Web Developer Roadmap 简介&#xff1a;为开发者提供全栈学…...

2025.4.1总结

今天看了一部网上很火的记录片《God&#xff0c;my brother》&#xff0c;中文名为《上帝不如我兄弟》&#xff0c;简述的是一个自媒体博主杜克遇到孟加拉一哥(车夫&#xff09;&#xff0c;最终一哥在杜克的帮助下&#xff0c;成功实现阶级跨越&#xff0c;而杜克也因此成为百…...

MySQL日志管理

目录 查询日志 慢查询日志 错误日志 二进制日志 其他功能 查询日志 查询日志用来记录所有查询语句的信息&#xff0c;由于开启此日志会占用大量内存&#xff0c;所以一般不会开启 查看查询日志是否开启 开启查询日志 慢查询日志 用于性能的调优&#xff0c;查看执行速度超…...

vscode中的【粘滞滚动】的基本概念和作用,关闭了以后如何开启

1、粘滞滚动的基本概念和作用 ‌VSCode中的“粘滞”功能主要是指编辑器在滚动时的一种特殊效果&#xff0c;使得编辑器在滚动到某个位置时会“粘”在那里&#xff0c;而不是平滑滚动到底部或顶部。‌ 粘滞滚动的基本概念和作用 粘滞滚动功能可以让用户在滚动时更直观地看到当前…...

我用Axure画了一个富文本编辑器,还带交互

最近尝试用Axure RP复刻了一个富文本编辑器&#xff0c;不仅完整还原了工具栏的各类功能&#xff0c;还通过交互设计实现了接近真实编辑器操作体验。整个设计过程聚焦功能还原与交互流畅性&#xff0c;最终成果令人惊喜。 编辑器采用经典的三区布局&#xff1a;顶部工具栏集成了…...

Mysql之Redo log(Red log of MySQL)

Mysql之Redo log 数据库事务的4个特性之一的持久性是数据库保证数据一致性的关键&#xff0c;mysql为了确保事务在系统崩溃后也能恢复&#xff0c;引入了redo log 重做日志这一机制。 什么是redo log 持久性指的是一旦事务提交数据就要永久的保存到数据库中&#xff0c;不能…...

Spring Cloud ReactorServiceInstanceLoadBalancer 自定义负载均衡

自定义负载均衡类 import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.ObjectProvider; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client…...