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

【C++入门到精通】C++入门 —— vector (STL)


阅读导航

  • 前言
  • 一、vector简介
    • 1. 概念
    • 2. 特点
  • 二、vector的使用
    • 1.vector 构造函数
    • 2. vector 空间增长问题
      • ⭕resize 和 reserve 函数
    • 3. vector 增删查改
      • ⭕operator[] 函数
  • 三、迭代器失效
  • 温馨提示

前言

前面我们讲了C语言的基础知识,也了解了一些数据结构,并且讲了有关C++的命名空间的一些知识点以及关于C++的缺省参数、函数重载,引用 和 内联函数也认识了什么是类和对象以及怎么去new一个 ‘对象’ ,也相信大家都掌握的不错,接下来博主将会带领大家继续学习有关C++比较重要的知识点——STL(vector)。下面话不多说坐稳扶好咱们要开车了😍

一、vector简介

1. 概念

std::vector是C++标准库中的一个容器类模板,是一种动态数组,可以存储相同类型的元素。它提供了动态调整大小、快速随机访问、插入和删除元素的操作。(vector的官方介绍链接)

2. 特点

  1. 动态调整大小std::vector会自动处理内存的分配和释放,可以根据需要在运行时动态调整容器的大小。当添加或删除元素时,std::vector会自动调整内部数组的大小以适应新的元素数量。

  2. 快速随机访问std::vector中的元素在内存中是连续存储的,因此可以通过下标或迭代器快速访问任意位置的元素。具有常数时间复杂度的随机访问使得std::vector非常适合需要频繁访问元素的场景。

  3. 动态增长和收缩:当需要添加更多元素时,std::vector会自动扩展内部数组的大小,以容纳新的元素;而当需要删除元素时,std::vector会自动收缩内部数组的大小,以减少内存的使用。

  4. 插入和删除操作std::vector提供了插入和删除元素的方法。可以在指定位置插入一个或多个元素,也可以通过下标或迭代器删除指定位置的元素。

  5. 元素的访问和遍历:可以通过下标或迭代器访问指定位置的元素。使用迭代器可以对std::vector进行遍历,包括正向和反向遍历。

  6. 其他功能:除了上述基本功能外,std::vector还提供了其他一些有用的功能,如获取容器的大小、判断容器是否为空、重新分配容器的大小、与其他容器进行交换、排序等。

注意:使用std::vector需要包含头文件<vector>,命名空间为 stdstd::vector是一个模板类,需要指定存储的元素类型,如std::vector<int>表示存储int类型的元素。

二、vector的使用

1.vector 构造函数

std::vector 提供了多个构造函数来创建和初始化向量,这些构造函数使得创建 std::vector 对象变得灵活,并提供了多种初始化向量的方式。选择适当的构造函数取决于具体的需求和数据源。

  1. 默认构造函数
vector()

该构造函数创建一个空的 std::vector 对象。

  1. 大小和初始值构造函数
vector(size_type count, const T& value = T())

该构造函数创建一个包含 count 个元素的 std::vector 对象,并用 value 的值初始化每个元素。如果未提供 value 的值,则使用类型 T 的默认构造函数进行初始化。

  1. 范围构造函数
template <class InputIt>
vector(InputIt first, InputIt last)

该构造函数使用迭代器范围 [first, last) 中的元素创建一个 std::vector 对象。可以通过传递两个迭代器来指定范围,从而将其他容器中的元素复制到新的 std::vector 对象中。

  1. 拷贝构造函数
vector(const vector& other)

该构造函数创建一个与 other 相同的 std::vector 对象,复制 other 中的所有元素。

  1. 移动构造函数
vector(vector&& other)

该构造函数使用 other 的资源来创建一个新的 std::vector 对象,同时将 other 置为空。

  1. 初始化列表构造函数
vector(std::initializer_list<T> init)

该构造函数使用花括号 {} 内的元素列表初始化 std::vector 对象。可以通过传递元素的列表来创建和初始化向量。

下面是所有使用构造函数创建 std::vector 对象的代码:

#include <vector>
#include <iostream>int main() {// 默认构造函数std::vector<int> numbers;  // 空的向量// 大小和初始值构造函数[10, 10, 10, 10, 10]std::vector<int> numbers1(5, 10); // 范围构造函数[1, 2, 3, 4, 5]std::vector<int> numbers2 = {1, 2, 3, 4, 5};  // 拷贝构造函数[1, 2, 3, 4, 5]std::vector<int> numbers3 = numbers2;  // 移动构造函数[1, 2, 3, 4, 5]std::vector<int> numbers4 = std::move(numbers2);  // numbers2 现在为空// 初始化列表构造函数[1, 2, 3, 4, 5]std::vector<int> numbers5 {1, 2, 3, 4, 5}; // 输出向量内的元素for (const auto& num : numbers5) {std::cout << num << " ";}std::cout << std::endl;return 0;
}

2. vector 空间增长问题

std::vector 中,空间增长(space growth)是指在向向量添加元素时,当容量不足时,向量自动增加内部存储空间的过程。这是为了确保向量能够容纳更多的元素,并减少频繁的内存重新分配操作。

  1. 容量和大小
  • 大小(size):指的是 std::vector 中当前拥有的元素个数。

  • 容量(capacity):指的是 std::vector 内部存储空间的大小,即它可以容纳的元素个数。

  1. 空间分配器(allocator)

std::vector 使用内部的空间分配器来动态管理存储空间。默认情况下,它使用标准全局的 operator newoperator delete 来分配和释放内存。也可以提供自定义的空间分配器来满足特定的需求。

  1. 容量增长策略

std::vector 使用一种策略来决定何时以及如何增加内部存储空间的容量:

  • 固定增长因子:许多实现会以固定的因子(例如2倍)来增加容量。这意味着每次增长时,容量都会以固定比例增加。这种策略通常具有较好的性能,但可能会占用更多的内存。

  • 线性增长:某些实现会以固定的大小(如每次增加n个元素)增加容量。这可以提供更节省内存的方式,但在某些情况下可能导致频繁的重新分配操作。

容量增长过程通常包括以下步骤:

  1. std::vector 判断当前的容量是否能够容纳新的元素。如果容量不足,进入空间增长阶段。

  2. 分配新的更大的内部存储空间。这通常涉及到申请更大的内存块,并将已有的元素从旧的内存块拷贝到新的内存块中。

  3. 释放旧的内部存储空间,回收内存资源。

  4. 更新 std::vector 的容量信息,以反映新的内部存储空间大小。

空间增长的频率取决于添加元素的数量和容器的策略。过于频繁的空间增长可能会导致性能下降,因为内存重新分配和元素拷贝都是开销较大的操作。因此,预先分配一定容量的空间(使用 std::vector::reserve())可以减少空间增长的次数,提高性能。

注意:自定义类型的元素在空间增长过程中会涉及到拷贝构造函数和析构函数的调用。确保自定义类型的正确实现这些特殊函数是非常重要的,以避免潜在的内存错误和资源泄漏。

⭕resize 和 reserve 函数

在 C++ 的 std::vector 中,reserve()resize() 是两个用于管理向量容量和大小的成员函数。

  1. reserve(n)

reserve() 函数用于预留至少能够容纳 n 个元素的内部存储空间,而不会改变向量的大小。这样做是为了避免频繁的重新分配和拷贝操作,提高性能。

调用 reserve(n) 后,如果 n 大于当前容量(capacity()),则向量会重新分配新的内部存储空间,容量会大于等于 n。如果 n 小于或等于当前容量,则不会有任何变化。

void reserve(size_type n);
  1. resize(n, value)

resize() 函数用于改变向量的大小,并根据需要添加或删除元素。

  • 如果 n 小于当前大小(size()),则会删除超出 n 个元素后的元素,向量的大小变为 n
  • 如果 n 大于当前大小,则会添加足够的元素,以便向量的大小变为 n。添加的元素将使用 value 进行初始化。
void resize(size_type n);
void resize(size_type n, const value_type& value);

注意:如果增加了向量的大小,新添加的元素(在当前大小和 n 之间)将通过拷贝构造函数进行初始化。如果存储的是自定义类型的元素,确保该类型的拷贝构造函数正确实现是很重要的。

以下是 reserve()resize() 的示例代码:

#include <iostream>
#include <vector>int main() {std::vector<int> numbers;numbers.reserve(10);  // 预留至少能容纳 10 个元素的空间std::cout << "Capacity: " << numbers.capacity() << std::endl;  // 输出容量numbers.resize(5);  // 更改大小为 5std::cout << "Size after resize: " << numbers.size() << std::endl;  // 输出大小numbers.resize(8, 42);  // 更改大小为 8,并用值 42 进行初始化std::cout << "Size after resize 2: " << numbers.size() << std::endl;  // 输出大小return 0;
}

总的来说,reserve() 用于预留足够的存储空间以容纳更多的元素,而 resize() 用于改变向量的大小并根据需要添加或删除元素。这两个函数可以帮助我们灵活地管理 std::vector 的容量和大小,以满足不同的需求。

3. vector 增删查改

当使用 C++ 的 std::vector 容器时,可以使用下面的方法来执行向向量中增加数据、删除数据、查找数据和修改数据的操作。

  1. 增加数据

std::vector 中增加数据可以使用 push_back() 函数将元素添加到向量的末尾。

void push_back(const T& value);

使用示例:

#include <iostream>
#include <vector>int main() {std::vector<int> numbers;numbers.push_back(10);numbers.push_back(20);numbers.push_back(30);for (const auto& num : numbers) {std::cout << num << " ";}std::cout << std::endl;return 0;
}
  1. 删除数据

可以使用 erase() 函数从向量中删除数据。它接受一个迭代器参数,指示要删除的元素位置。

iterator erase(iterator position);

使用示例:

#include <iostream>
#include <vector>int main() {std::vector<int> numbers = {10, 20, 30};numbers.erase(numbers.begin() + 1);  // 删除索引为 1 的元素for (const auto& num : numbers) {std::cout << num << " ";}std::cout << std::endl;return 0;
}
  1. 查找数据

可以使用 std::find() 算法函数在向量中查找特定的元素。该函数接受两个迭代器参数,指示要搜索的范围,以及要查找的值。它返回指向找到的元素的迭代器,如果未找到,则返回指向容器末尾的迭代器。

iterator find(iterator first, iterator last, const T& value);

使用示例:

#include <iostream>
#include <vector>
#include <algorithm>int main() {std::vector<int> numbers = {10, 20, 30};auto it = std::find(numbers.begin(), numbers.end(), 20);if (it != numbers.end()) {std::cout << "Element found at index: " << std::distance(numbers.begin(), it) << std::endl;} else {std::cout << "Element not found" << std::endl;}return 0;
}
  1. 修改数据

可以通过迭代器来访问和修改 std::vector 中的元素。通过修改迭代器指向的元素来实现数据的修改。

使用示例:

#include <iostream>
#include <vector>int main() {std::vector<int> numbers = {10, 20, 30};auto it = numbers.begin();++it;*it = 25;  // 修改元素值for (const auto& num : numbers) {std::cout << num << " ";}std::cout << std::endl;return 0;
}

⭕operator[] 函数

还可以使用 operator[] 运算符来访问 std::vector 中的元素并进行修改。operator[] 函数的官方链接

operator[] 运算符允许通过索引来访问向量中的元素,并提供了对元素的非常快速的随机访问。索引从 0 开始,依次增加。

使用示例:

#include <iostream>
#include <vector>int main() {std::vector<int> numbers = {10, 20, 30};std::cout << numbers[0] << std::endl;  // 访问索引为 0 的元素numbers[1] = 25;  // 修改索引为 1 的元素的值for (const auto& num : numbers) {std::cout << num << " ";}std::cout << std::endl;return 0;
}

需要注意以下几点:

  1. 使用 operator[] 访问索引超出向量范围的元素是未定义行为,因此要确保索引值在有效范围内。

  2. 如果要对不存在的元素使用 operator[] 进行访问,它将创建一个新元素并分配给该索引位置。因此,在使用 operator[] 之前,通常需要确保向量具有足够的大小。

  3. operator[] 返回对索引位置的引用,因此可以通过返回的引用进行修改和赋值操作。

operator[] 运算符是一种快速访问和修改 std::vector 中元素的便捷方式,它提供了类似于数组的索引操作。

三、迭代器失效

std::vector 中,迭代器失效指的是当在向量进行插入或删除操作后,原本指向向量元素的迭代器可能会失效,即不能再安全地使用。

迭代器失效的问题存在于插入和删除操作中,因为这些操作可能会导致向量重新分配内存,使得原来的迭代器指向的位置变得无效。下面是常见的迭代器失效情况:

  1. 在插入或删除一个元素后,迭代器失效

当向向量中插入或删除元素时,迭代器可能会失效。插入操作可能导致内部存储重新分配,而删除操作可能使元素位置向前移动。这会导致之前的迭代器指向的位置变得无效。

std::vector<int> numbers = {10, 20, 30};
auto it = numbers.begin();numbers.insert(it + 1, 15);  // 在索引为 1 的位置插入元素// 在插入之后,迭代器 it 可能失效,不能再使用
  1. 使用被删除元素的迭代器,迭代器失效

当使用被删除元素的迭代器继续访问向量时,迭代器可能会失效。因为删除元素会导致元素位置的变动,原本的迭代器指向的位置可能已经被其他元素占据。

std::vector<int> numbers = {10, 20, 30};
auto it = numbers.begin();numbers.erase(it);  // 删除首个元素// 在删除之后,迭代器 it 变成无效的迭代器,不能再使用

为了避免迭代器失效问题,可以采取以下几种方法:

  • 使用索引替代迭代器:使用基于索引的访问方式,而不是依赖迭代器。

  • 在插入或删除元素后重新获取迭代器:在插入或删除操作后,重新获取迭代器,而不是继续使用之前的迭代器。

std::vector<int> numbers = {10, 20, 30};
auto it = numbers.begin();numbers.insert(it + 1, 15);
it = numbers.begin();  // 插入后重新获取迭代器numbers.erase(it);
it = numbers.begin();  // 删除后重新获取迭代器
  • 使用算法和函数:使用标准库提供的算法和函数,而不是手动操作迭代器。这些函数会处理好迭代器失效的情况,例如使用 std::for_each 遍历向量。
std::vector<int> numbers = {10, 20, 30};
std::for_each(numbers.begin(), numbers.end(), [](int& num) {// 修改元素值
});

了解迭代器失效的情况,并采取适当的措施来避免迭代器失效问题,是在操作 std::vector 时需要注意的重要方面。

温馨提示

感谢您对博主文章的关注与支持!在阅读本篇文章的同时,我们想提醒您留下您宝贵的意见和反馈。如果您喜欢这篇文章,可以点赞、评论和分享给您的同学,这将对我提供巨大的鼓励和支持。另外,我计划在未来的更新中持续探讨与本文相关的内容。我会为您带来更多关于C++以及编程技术问题的深入解析、应用案例和趣味玩法等。请继续关注博主的更新,不要错过任何精彩内容!

再次感谢您的支持和关注。我们期待与您建立更紧密的互动,共同探索C++、算法和编程的奥秘。祝您生活愉快,排便顺畅!
在这里插入图片描述

相关文章:

【C++入门到精通】C++入门 —— vector (STL)

阅读导航 前言一、vector简介1. 概念2. 特点 二、vector的使用1.vector 构造函数2. vector 空间增长问题⭕resize 和 reserve 函数 3. vector 增删查改⭕operator[] 函数 三、迭代器失效温馨提示 前言 前面我们讲了C语言的基础知识&#xff0c;也了解了一些数据结构&#xff0…...

git简单使用

1.在 远端仓库创建好仓库 2.在本地中创建仓库 ​ mkdir 仓库名 ​ cd 仓库名 3.初始化(可以省略) ​ git init 4.添加远端仓库 ​ git remote add origin https://gitee.com/zengtian_7/pet_home.git 5.初始化代码库&#xff1a;当你创建一个全新的代码库时&#xff0c…...

CSS—选择器

目录 一、CSS简介 二、HTML页面中常用的元素 三、CSS语法规则 四、常用的选择器 五、CSS的三种使用方法 六、选择器参考 一、CSS简介 CSS (Cascading Style Sheets&#xff0c;层叠样式表&#xff09;&#xff0c;是一种用来为结构化文档&#xff08;如 HTML 文档或 XML 应…...

【Unity实战系列】Unity的下载安装以及汉化教程

君兮_的个人主页 即使走的再远&#xff0c;也勿忘启程时的初心 C/C 游戏开发 Hello,米娜桑们&#xff0c;这里是君兮_&#xff0c;怎么说呢&#xff0c;其实这才是我以后真正想写想做的东西&#xff0c;虽然才刚开始&#xff0c;但好歹&#xff0c;我总算是启程了。今天要分享…...

电脑IP地址错误无法上网怎么办?

电脑出现IP地址错误后就将无法连接网络&#xff0c;从而无法正常访问互联网。那么当电脑出现IP地址错误时该怎么办呢&#xff1f; 确认是否禁用本地连接 你需要先确定是否禁用了本地网络连接&#xff0c;如果发现禁用&#xff0c;则将其启用即可。 启用方法&#xff1a;点击桌…...

机器视觉项目流程和学习方法

机器视觉项目流程&#xff1a; 00001. 需求分析和方案建立 00002. 算法流程规划和业务逻辑设计 00003. 模块化编程和集成化实现 00004. 调试和优化&#xff0c;交付客户及文档 学习机器视觉的方法&#xff1a; 00001. 实战学习&#xff0c;结合项目经验教训 00002. 学习…...

LNMP环境搭建wordpress以及跳转后台报404解决

基于上文配置好的LNMP环境继续搭建wordpress 目录 一.到官网下载tar.gz包&#xff0c;并上传到Linux上&#xff0c;也可以通过复制链接地址进行下载 二. 将wordpress中的所有文件移动到你nginx.conf中指定目录中 三.为wordpress配置数据库 四.到浏览器进行注册 1.刚开始…...

Nginx+Tomcat的动静分离

首先准备好5台机子&#xff1a;2台装有tomcat&#xff0c;3台装有nginx 1.关闭5台机子的防火墙 systemctl stop firewalld systemctl disable firewalld setenforce 0 Nginx1 vim /usr/local/nginx/conf/nginx.conf#在--#pid-- 下做四层代理 stream {upstream test {server …...

Tomcat部署与优化

目录 一、Tomcat介绍 二、Tomcat核心组件 1、web容器&#xff1a;完成web服务器的功能&#xff0c;web应用 2、servlet容器&#xff1a;名字&#xff1a;catalina&#xff0c;处理servlet代码 servlet的功能 3、jsp&#xff1a;jsp动态页面翻译成servlet代码&#xff0c;用…...

jmeter工具使用

jmeter工具使用 官方下载 安装好jdk后&#xff0c;下载之后直接运行即可 基本流程 1、首先添加线程组 线程组&#xff1a;JMeter是由Java实现的&#xff0c;并且使用一个Java线程来模拟一个用户&#xff0c;因此线程组&#xff08;Thread Group&#xff09;就是指一组用户的…...

【uniapp】封装一个全局自定义的模态框

【需求描述】 在接口401处&#xff0c;需要实现全局提示并弹出自定义模态框的功能。考虑到uni-app内置的模态框和app原生提示框的自定义能力有限&#xff0c;我决定自行封装全局自定义的模态框&#xff0c;以此为应用程序提供更加统一且个性化的界面。 【效果图】 【封装】 主…...

UNIX 入门

与 UNIX 建立连接启动会话登录命令提示符修改口令退出系统 简单的 UNIX 命令命令格式ls 命令who 命令虚拟终端 tty伪终端 ptywho am i 命令 cal 命令help 命令man 命令 shell 概述shell 命令更换 shell临时更改 shell永久更改 shell 登录过程 与 UNIX 建立连接 启动会话 要启…...

Golang通过alibabaCanal订阅MySQLbinlog

最近在做redis和MySQL的缓存一致性&#xff0c;一个方式是订阅MySQL的BinLog文件&#xff0c;我们使用阿里巴巴的Canal的中间件来做。 Canal是服务端和客户端两部分构成&#xff0c;我们需要先启动Canal的服务端&#xff0c;然后在Go程序里面连接Canal服务端&#xff0c;即可监…...

Python flask-restful 框架讲解

1、简介 Django 和 Flask 一直都是 Python 开发 Web 的首选&#xff0c;而 Flask 的微内核更适用于现在的云原生微服务框架。但是 Flask 只是一个微型的 Web 引擎&#xff0c;所以我们需要扩展 Flask 使其发挥出更强悍的功能。 python flask框架详解&#xff1a;https://blog.…...

MySQL_约束、多表关系

约束 概念&#xff1a;就是用来作用表中字段的规则&#xff0c;用于限制存储在表中的数据。 目的&#xff1a;保证数据库中数据的正确性&#xff0c;有效性和完整性。 约束演示 #定义一个学生表&#xff0c;表中要求如下&#xff1a; #sn 表示学生学号&#xff0c;要求使用 …...

在Qt中使用LoadLibrary无法加载DLL

Qt系列文章目录 文章目录 Qt系列文章目录前言一、问题分析 前言 最近因项目需要使用qt做开发&#xff0c;之前使用LoadLibrary加载dll成功&#xff0c;很庆幸&#xff0c;当一切都那么顺风顺水的时候&#xff0c;测试同事却发现&#xff0c;在windows平台上个别电脑上加载dll会…...

如何将区块链新闻稿发布到海外媒体?

随着区块链技术的不断发展&#xff0c;越来越多的区块链项目涌现出来&#xff0c;各大媒体也开始关注和报道区块链新闻。然而&#xff0c;如何将区块链新闻稿发布到海外媒体成为了许多区块链项目所面临的难题。本文将介绍一些有效的方法&#xff0c;帮助区块链项目将新闻稿发布…...

基于 CentOS 7 构建 LVS-DR 群集。

1.准备实验环境 本次实验我准备了4台虚拟机 DS:DIP--192.168.163.138 VIP--192.168.163.200 RIP1(web1)--192.168.163.140 RIP2(web2)--192.168.163.141 Client&#xff1a;user--192.168.163.142 2.配置服务器环境 1)搭建简易的web服务 RIP1 [rootlocalhost ~]# yum …...

防火墙组建双击热备后,点击管理对端设备,老是打不开,怎么办?

环境&#xff1a; 防火墙 8.0.75 AF-2000-FH2130B-SC 问题描述&#xff1a; 防火墙组建双击热备后&#xff0c;点击管理对端设备&#xff0c;老是打不开&#xff0c;怎么办&#xff1f; 浏览器老是加载 解决方案&#xff1a; 1.打开设置查看双机连接的心跳接口是哪个端口 …...

【Kubernetes】Kubernetes之Pod详解

Pod 一、 Pod1. Pod 基础概念2. 在 Kubrenetes 集群中 Pod 使用方式2.1 pasue 容器2.2 kubernetes 中的 pause 容器提供的功能 3. Pod 的概念和结构组成4. Pod 的分类5. Pod 容器的分类5.1 基础容器&#xff08;infrastructure container&#xff09;5.2 初始化容器&#xff08…...

React 第五十五节 Router 中 useAsyncError的使用详解

前言 useAsyncError 是 React Router v6.4 引入的一个钩子&#xff0c;用于处理异步操作&#xff08;如数据加载&#xff09;中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误&#xff1a;捕获在 loader 或 action 中发生的异步错误替…...

模型参数、模型存储精度、参数与显存

模型参数量衡量单位 M&#xff1a;百万&#xff08;Million&#xff09; B&#xff1a;十亿&#xff08;Billion&#xff09; 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的&#xff0c;但是一个参数所表示多少字节不一定&#xff0c;需要看这个参数以什么…...

在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能

下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能&#xff0c;包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个&#xff1f;3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制&#xff08;过半机制&#xff0…...

代理篇12|深入理解 Vite中的Proxy接口代理配置

在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”&#xff08;简单设计&#xff09;是软件开发中的一个重要理念&#xff0c;倡导以最简单的方式实现软件功能&#xff0c;以确保代码清晰易懂、易维护&#xff0c;并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计&#xff0c;遵循“让事情保…...

MySQL 知识小结(一)

一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库&#xff0c;分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷&#xff0c;但是文件存放起来数据比较冗余&#xff0c;用二进制能够更好管理咱们M…...

Webpack性能优化:构建速度与体积优化策略

一、构建速度优化 1、​​升级Webpack和Node.js​​ ​​优化效果​​&#xff1a;Webpack 4比Webpack 3构建时间降低60%-98%。​​原因​​&#xff1a; V8引擎优化&#xff08;for of替代forEach、Map/Set替代Object&#xff09;。默认使用更快的md4哈希算法。AST直接从Loa…...

抽象类和接口(全)

一、抽象类 1.概念&#xff1a;如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象&#xff0c;这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法&#xff0c;包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中&#xff0c;⼀个类如果被 abs…...

tauri项目,如何在rust端读取电脑环境变量

如果想在前端通过调用来获取环境变量的值&#xff0c;可以通过标准的依赖&#xff1a; std::env::var(name).ok() 想在前端通过调用来获取&#xff0c;可以写一个command函数&#xff1a; #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...