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

C++.vector 容器(1.5w字)

1. C++ vector 容器概述

1.1 定义与特点

std::vector 是 C++ 标准模板库(STL)中的一个序列容器,它是一个封装了动态大小数组的序列容器。std::vector 的数据存储在连续的内存空间中,这使得它能够高效地进行随机访问,但插入和删除操作(特别是非尾部操作)可能会比较慢,因为可能需要移动元素以保持内存的连续性。

  • 动态扩容std::vector 的一个显著特点是动态扩容。当容器中的元素数量超过当前分配的内存容量时,std::vector 会自动分配更大的内存空间,并将原有元素复制到新的内存中。通常,新的容量是当前容量的两倍,但具体扩容策略可能因实现而异。
  • 随机访问:由于 std::vector 的元素存储在连续的内存中,因此它支持高效的随机访问。通过索引可以直接访问任意位置的元素,时间复杂度为 O(1)。
  • 内存连续性std::vector 的元素存储在连续的内存块中,这使得它在某些情况下(如与 C 风格的代码或某些硬件优化相关时)具有优势。然而,这也意味着插入或删除元素(特别是非尾部操作)可能会导致大量元素的移动,从而降低性能。
  • 迭代器支持std::vector 提供了完整的迭代器支持,包括随机访问迭代器。这意味着可以使用标准的迭代器操作(如 begin()end()++--* 等)来遍历容器中的元素。

以下是 std::vector 的基本定义和初始化示例:

#include <iostream>
#include <vector>int main() {// 默认构造函数,创建一个空的 vectorstd::vector<int> vec1;std::cout << "vec1 size: " << vec1.size() << ", capacity: " << vec1.capacity() << std::endl;// 使用初始化列表构造 vectorstd::vector<int> vec2 = {1, 2, 3, 4, 5};std::cout << "vec2 size: " << vec2.size() << ", capacity: " << vec2.capacity() << std::endl;// 使用指定大小和默认值构造 vectorstd::vector<int> vec3(10, 0); // 创建一个包含 10 个元素,每个元素值为 0 的 vectorstd::cout << "vec3 size: " << vec3.size() << ", capacity: " << vec3.capacity() << std::endl;// 使用另一个 vector 的范围构造新的 vectorstd::vector<int> vec4(vec2.begin(), vec2.end());std::cout << "vec4 size: " << vec4.size() << ", capacity: " << vec4.capacity() << std::endl;return 0;
}

1.2 使用场景

std::vector 是 C++ 中最常用的容器之一,适用于多种场景,尤其是在需要动态数组功能时。以下是一些常见的使用场景:

  • 动态数组:当需要一个可以动态增长和收缩的数组时,std::vector 是理想的选择。它可以自动管理内存,避免手动分配和释放内存的复杂性。
  • 存储和管理数据集合std::vector 可以用来存储和管理一组同类型的数据,例如存储用户信息、记录日志、处理数据集等。
  • 与算法配合:由于 std::vector 提供了随机访问迭代器,它与 STL 中的算法(如 std::sortstd::find 等)配合得非常好,可以高效地执行各种操作。
  • 临时存储:在函数调用或算法实现中,std::vector 可以用作临时存储容器,用于存储中间结果或临时数据。

以下是 std::vector 在实际场景中的应用示例:

#include <iostream>
#include <vector>
#include <algorithm> // 用于 std::sortint main() {// 动态数组示例std::vector<int> vec;for (int i = 0; i < 10; ++i) {vec.push_back(i * i); // 动态添加元素}std::cout << "Dynamic array: ";for (int num : vec) {std::cout << num << " ";}std::cout << std::endl;// 与算法配合示例std::vector<int> data = {5, 2, 9, 1, 5, 6};std::sort(data.begin(), data.end()); // 使用 std::sort 对 vector 进行排序std::cout << "Sorted data: ";for (int num : data) {std::cout << num << " ";}std::cout << std::endl;return 0;
}

在上述代码中,std::vector 用于动态存储平方数,并与 std::sort 算法配合对数据进行排序,展示了其在动态数组和算法配合方面的强大功能。

2. vector 容器的创建与初始化

2.1 默认创建空 vector

std::vector 的默认构造函数用于创建一个空的容器,此时容器的大小(size)和容量(capacity)均为 0。这种方式适用于需要在后续动态添加元素的场景。

#include <iostream>
#include <vector>int main() {// 默认创建一个空的 vectorstd::vector<int> vec;std::cout << "vec size: " << vec.size() << ", capacity: " << vec.capacity() << std::endl;return 0;
}

运行结果:

vec size: 0, capacity: 0

2.2 指定大小与初始值初始化

可以通过指定容器的大小和初始值来初始化 std::vector。这种方式在需要预先分配一定数量的元素并设置默认值时非常有用。

#include <iostream>
#include <vector>int main() {// 指定大小和初始值初始化std::vector<int> vec(10, 42); // 创建一个包含 10 个元素,每个元素值为 42 的 vectorstd::cout << "vec size: " << vec.size() << ", capacity: " << vec.capacity() << std::endl;for (int num : vec) {std::cout << num << " ";}std::cout << std::endl;return 0;
}

运行结果:

vec size: 10, capacity: 10
42 42 42 42 42 42 42 42 42 42

2.3 使用列表初始化

使用初始化列表({})可以方便地将一组值直接赋给 std::vector。这种方式适用于已知一组初始值的情况。

#include <iostream>
#include <vector>int main() {// 使用初始化列表初始化std::vector<int> vec = {1, 2, 3, 4, 5};std::cout << "vec size: " << vec.size() << ", capacity: " << vec.capacity() << std::endl;for (int num : vec) {std::cout << num << " ";}std::cout << std::endl;return 0;
}

运行结果:

vec size: 5, capacity: 5
1 2 3 4 5

2.4 拷贝初始化

通过拷贝构造函数可以创建一个与另一个 std::vector 相同内容的新容器。这种方式适用于需要复制现有容器数据的场景。

#include <iostream>
#include <vector>int main() {// 创建一个原始 vectorstd::vector<int> vec1 = {1, 2, 3, 4, 5};// 拷贝初始化std::vector<int> vec2(vec1);std::cout << "vec1 size: " << vec1.size() << ", capacity: " << vec1.capacity() << std::endl;std::cout << "vec2 size: " << vec2.size() << ", capacity: " << vec2.capacity() << std::endl;for (int num : vec2) {std::cout << num << " ";}std::cout << std::endl;return 0;
}

运行结果:

vec1 size: 5, capacity: 5
vec2 size: 5, capacity: 5
1 2 3 4 5

2.5 使用指针或迭代器初始化

可以通过指针或迭代器指定一个范围来初始化 std::vector。这种方式适用于从其他容器或数组中提取一部分数据来初始化。

#include <iostream>
#include <vector>int main() {// 创建一个原始数组int arr[] = {1, 2, 3, 4, 5};// 使用指针初始化std::vector<int> vec1(arr, arr + 3); // 从数组中提取前 3 个元素std::cout << "vec1 size: " << vec1.size() << ", capacity: " << vec1.capacity() << std::endl;for (int num : vec1) {std::cout << num << " ";}std::cout << std::endl;// 创建一个原始 vectorstd::vector<int> vec2 = {1, 2, 3, 4, 5};// 使用迭代器初始化std::vector<int> vec3(vec2.begin() + 1, vec2.end() - 1); // 从 vec2 中提取索引 1 到 3 的元素std::cout << "vec3 size: " << vec3.size() << ", capacity: " << vec3.capacity() << std::endl;for (int num : vec3) {std::cout << num << " ";}std::cout << std::endl;return 0;
}

运行结果:

vec1 size: 3, capacity: 3
1 2 3
vec3 size: 3, capacity: 3
2 3 4

3. vector 容器的元素访问

3.1 使用下标操作符 []

std::vector 支持使用下标操作符 [] 来访问和修改容器中的元素。这种方式类似于访问普通数组的元素,通过指定索引值来直接访问对应的元素。其时间复杂度为 O(1),因为 std::vector 的元素存储在连续的内存中,可以直接通过计算偏移量来访问元素。

示例代码

#include <iostream>
#include <vector>int main() {// 创建一个 vectorstd::vector<int> vec = {10, 20, 30, 40, 50};// 使用下标操作符访问元素std::cout << "Element at index 2: " << vec[2] << std::endl; // 输出 30// 修改元素vec[2] = 35;std::cout << "Modified element at index 2: " << vec[2] << std::endl; // 输出 35// 遍历 vector 并输出所有元素for (size_t i = 0; i < vec.size(); ++i) {std::cout << "Element at index " << i << ": " << vec[i] << std::endl;}return 0;
}

运行结果

Element at index 2: 30
Modified element at index 2: 35
Element at index 0: 10
Element at index 1: 20
Element at index 2: 35
Element at index 3: 40
Element at index 4: 50

注意事项

  • 下标操作符 [] 不会进行边界检查。如果索引值超出容器的范围,可能会导致未定义行为,例如访问无效内存或程序崩溃。
  • 在使用 [] 访问元素时,需要确保索引值在合法范围内,否则可能会引发运行时错误。

3.2 使用 at() 方法

std::vector 提供了 at() 方法来访问和修改容器中的元素。与下标操作符 [] 不同,at() 方法会进行边界检查。如果索引值超出容器的范围,at() 方法会抛出 std::out_of_range 异常。这种方式在需要确保索引值合法时更为安全。

示例代码

#include <iostream>
#include <vector>
#include <stdexcept> // 用于 std::out_of_rangeint main() {// 创建一个 vectorstd::vector<int> vec = {10, 20, 30, 40, 50};try {// 使用 at() 方法访问元素std::cout << "Element at index 2: " << vec.at(2) << std::endl; // 输出 30// 修改元素vec.at(2) = 35;std::cout << "Modified element at index 2: " << vec.at(2) << std::endl; // 输出 35// 尝试访问超出范围的元素std::cout << "Element at index 10: " << vec.at(10) << std::endl;} catch (const std::out_of_range& e) {std::cerr << "Error: " << e.what() << std::endl; // 捕获并处理异常}// 遍历 vector 并输出所有元素for (size_t i = 0; i < vec.size(); ++i) {std::cout << "Element at index " << i << ": " << vec.at(i) << std::endl;}return 0;
}

运行结果

Element at index 2: 30
Modified element at index 2: 35
Error: vector::_M_range_check: __n (which is 10) >= this->size() (which is 5)
Element at index 0: 10
Element at index 1: 20
Element at index 2: 35
Element at index 3: 40
Element at index 4: 50

注意事项

  • at() 方法会进行边界检查,因此在访问元素时会比 [] 操作符稍慢,但安全性更高。
  • 如果需要频繁访问大量元素且已确保索引值合法,建议使用 [] 操作符以提高性能。
  • 在不确定索引值是否合法时,建议使用 at() 方法以避免潜在的运行时错误。
  • 4. vector 容器的元素添加与删除

4.1 添加元素

4.1.1 使用 push_back() 添加元素到尾部

push_back()std::vector 提供的一个非常常用的方法,用于在容器的尾部添加一个元素。当调用 push_back() 时,如果当前容器的容量不足以容纳新元素,std::vector 会自动进行扩容,通常是将容量扩大为原来的两倍(具体策略可能因实现而异)。这种方式的时间复杂度为 O(1),但在扩容时可能会涉及到元素的复制,因此在大量连续添加元素时,可能会有一定的性能开销。

示例代码
#include <iostream>
#include <vector>int main() {std::vector<int> vec;// 使用 push_back() 添加元素vec.push_back(10);vec.push_back(20);vec.push_back(30);std::cout << "Vector elements: ";for (int num : vec) {std::cout << num << " ";}std::cout << std::endl;std::cout << "Size: " << vec.size() << ", Capacity: " << vec.capacity() << std::endl;return 0;
}
运行结果
Vector elements: 10 20 30 
Size: 3, Capacity: 4
注意事项
  • push_back() 只能在容器的尾部添加元素,如果需要在其他位置添加元素,应使用 insert() 方法。
  • 在连续添加大量元素时,为了避免频繁的扩容操作,可以预先使用 reserve() 方法分配足够的容量,从而提高性能。

4.1.2 使用 insert() 在指定位置插入元素

insert() 方法允许在 std::vector 的任意指定位置插入一个或多个元素。它需要一个迭代器作为插入位置的指示,以及要插入的元素或元素范围。插入操作可能会导致容器中的元素移动,以保持内存的连续性,因此其时间复杂度取决于插入位置和插入元素的数量。

示例代码
#include <iostream>
#include <vector>int main() {std::vector<int> vec = {10, 20, 30, 40, 50};// 在指定位置插入单个元素auto it = vec.begin() + 2; // 指向索引为 2 的位置vec.insert(it, 25); // 在索引 2 的位置插入 25std::cout << "Vector after inserting single element: ";for (int num : vec) {std::cout << num << " ";}std::cout << std::endl;// 在指定位置插入多个元素it = vec.begin() + 4; // 指向索引为 4 的位置vec.insert(it, {35, 36, 37}); // 在索引 4 的位置插入 35, 36, 37std::cout << "Vector after inserting multiple elements: ";for (int num : vec) {std::cout << num << " ";}std::cout << std::endl;return 0;
}
运行结果
Vector after inserting single element: 10 20 25 30 40 50 
Vector after inserting multiple elements: 10 20 25 30 35 36 37 40 50 
注意事项
  • 插入操作会导致插入点之后的所有元素向后移动,因此可能会有一定的性能开销,尤其是在容器较大且插入位置较靠前时。
  • 如果插入的元素数量较多,建议预先使用 reserve() 方法分配足够的容量,以减少扩容操作的次数。

4.2 删除元素

4.2.1 使用 pop_back() 删除尾部元素

pop_back() 方法用于删除 std::vector 中的最后一个元素。它是一个非常高效的操作,时间复杂度为 O(1),因为它不需要移动任何元素。调用 pop_back() 后,容器的大小会减少 1,但容量不会立即改变。

示例代码
#include <iostream>
#include <vector>int main() {std::vector<int> vec = {10, 20, 30, 40, 50};// 使用 pop_back() 删除尾部元素vec.pop_back();std::cout << "Vector after pop_back(): ";for (int num : vec) {std::cout << num << " ";}std::cout << std::endl;std::cout << "Size: " << vec.size() << ", Capacity: " << vec.capacity() << std::endl;return 0;
}
运行结果
Vector after pop_back(): 10 20 30 40 
Size: 4, Capacity: 8
注意事项
  • pop_back() 只能删除容器的最后一个元素,如果需要删除其他位置的元素,应使用 erase() 方法。
  • 如果容器为空时调用 pop_back(),会导致未定义行为,因此在使用前应确保容器不为空。

4.2.2 使用 erase() 删除指定位置元素

erase() 方法用于删除 std::vector 中指定位置的一个或多个元素。它需要一个迭代器或一个迭代器范围作为参数,指定要删除的元素位置。删除操作会导致被删除元素之后的所有元素向前移动,因此其时间复杂度取决于删除位置和删除元素的数量。

示例代码
#include <iostream>
#include <vector>int main() {std::vector<int> vec = {10, 20, 30, 40, 50};// 删除指定位置的单个元素auto it = vec.begin() + 2; // 指向索引为 2 的位置vec.erase(it); // 删除索引为 2 的元素std::cout << "Vector after erasing single element: ";for (int num : vec) {std::cout << num << " ";}std::cout << std::endl;// 删除指定范围的多个元素it = vec.begin() + 1; // 指向索引为 1 的位置vec.erase(it, it + 2); // 删除索引为 1 到 2 的元素std::cout << "Vector after erasing multiple elements: ";for (int num : vec) {std::cout << num << " ";}std::cout << std::endl;return 0;
}
运行结果
Vector after erasing single element: 10 20 40 50 
Vector after erasing multiple elements: 10 50 
注意事项
  • 删除操作会导致被删除元素之后的所有元素向前移动,因此可能会有一定的性能开销,尤其是在容器较大且删除位置较靠前时。
  • 如果需要删除多个元素,建议使用迭代器范围作为参数,以提高代码的可读性和效率。
  • 在删除元素后,迭代器可能会失效,因此在使用迭代器时需要注意迭代器的有效性。

5. vector 容器的迭代器使用

5.1 获取迭代器

5.1.1 使用 begin() 获取首元素迭代器

begin() 方法用于获取指向 std::vector 容器中第一个元素的迭代器。通过这个迭代器,可以访问容器中的第一个元素,并且可以用于遍历容器。begin() 方法返回的是一个随机访问迭代器,支持所有标准迭代器操作。

示例代码
#include <iostream>
#include <vector>int main() {std::vector<int> vec = {10, 20, 30, 40, 50};// 获取首元素迭代器std::vector<int>::iterator it = vec.begin();// 通过迭代器访问首元素std::cout << "First element: " << *it << std::endl;return 0;
}
运行结果
First element: 10

5.1.2 使用 end() 获取末尾迭代器

end() 方法用于获取指向 std::vector 容器中最后一个元素之后一个位置的迭代器。这个迭代器本身不指向任何有效的元素,但可以用于比较和遍历容器的末尾。end() 方法返回的也是随机访问迭代器。

示例代码
#include <iostream>
#include <vector>int main() {std::vector<int> vec = {10, 20, 30, 40, 50};// 获取末尾迭代器std::vector<int>::iterator it = vec.end();// 末尾迭代器不能直接解引用,但可以用于比较std::cout << "End iterator points to: " << (it - vec.begin()) << " (beyond last element)" << std::endl;return 0;
}
运行结果
End iterator points to: 5 (beyond last element)

5.2 迭代器遍历

5.2.1 使用迭代器遍历 vector 容器

通过迭代器可以高效地遍历 std::vector 容器中的所有元素。这种方式不仅灵活,而且可以利用迭代器的特性(如随机访问)来实现更复杂的操作。遍历时,通常从 begin() 开始,直到 end() 结束。

示例代码
#include <iostream>
#include <vector>int main() {std::vector<int> vec = {10, 20, 30, 40, 50};// 使用迭代器遍历 vector 容器std::cout << "Vector elements: ";for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); ++it) {std::cout << *it << " ";}std::cout << std::endl;// 使用范围 for 循环(基于迭代器的简化写法)std::cout << "Vector elements (range-based for loop): ";for (int num : vec) {std::cout << num << " ";}std::cout << std::endl;return 0;
}
运行结果
Vector elements: 10 20 30 40 50 
Vector elements (range-based for loop): 10 20 30 40 50 
注意事项
  • 迭代器在容器被修改(如插入或删除元素)后可能会失效,因此在修改容器时需要重新获取迭代器。
  • 使用迭代器遍历时,确保迭代器的范围正确,避免访问无效内存。
  • 范围 for 循环是 C++11 引入的语法糖,底层仍然是基于迭代器实现的,但使用起来更加简洁。

6. vector 容器的容量与大小管理

6.1 查询大小

6.1.1 使用 size() 查询元素数量

size() 方法用于查询 std::vector 容器中当前存储的元素数量。该方法返回一个无符号整数,表示容器中实际存在的元素个数。其时间复杂度为 O(1),因为它直接返回容器内部维护的大小信息。

示例代码
#include <iostream>
#include <vector>int main() {std::vector<int> vec = {10, 20, 30, 40, 50};// 查询元素数量std::cout << "Number of elements in vector: " << vec.size() << std::endl;return 0;
}
运行结果
Number of elements in vector: 5

6.1.2 使用 capacity() 查询当前容量

capacity() 方法用于查询 std::vector 容器当前分配的内存容量,即容器能够容纳的元素数量,而不需要进行扩容操作。该方法返回一个无符号整数,表示容器当前的容量。其时间复杂度为 O(1)。

示例代码
#include <iostream>
#include <vector>int main() {std::vector<int> vec = {10, 20, 30, 40, 50};// 查询当前容量std::cout << "Current capacity of vector: " << vec.capacity() << std::endl;return 0;
}
运行结果
Current capacity of vector: 8

6.1.3 使用 max_size() 查询最大允许容量

max_size() 方法用于查询 std::vector 容器能够支持的最大元素数量。这个值通常受到系统内存和实现限制。该方法返回一个无符号整数,表示容器的最大容量。其时间复杂度为 O(1)。

示例代码
#include <iostream>
#include <vector>int main() {std::vector<int> vec;// 查询最大允许容量std::cout << "Maximum allowed size of vector: " << vec.max_size() << std::endl;return 0;
}
运行结果
Maximum allowed size of vector: 9223372036854775807

6.2 修改大小

6.2.1 使用 resize() 修改大小

resize() 方法用于修改 std::vector 容器的大小。如果新大小大于当前大小,容器会自动添加默认值(或指定值)的元素;如果新大小小于当前大小,容器会删除多余的元素。该方法的时间复杂度取决于新大小与当前大小的差值。

示例代码
#include <iostream>
#include <vector>int main() {std::vector<int> vec = {10, 20, 30, 40, 50};// 扩大容器大小vec.resize(8, 60); // 添加 3 个值为 60 的元素std::cout << "Vector after resizing to larger size: ";for (int num : vec) {std::cout << num << " ";}std::cout << std::endl;// 缩小容器大小vec.resize(3); // 删除多余的元素std::cout << "Vector after resizing to smaller size: ";for (int num : vec) {std::cout << num << " ";}std::cout << std::endl;return 0;
}
运行结果
Vector after resizing to larger size: 10 20 30 40 50 60 60 60 
Vector after resizing to smaller size: 10 20 30 

6.2.2 使用 reserve() 预分配空间

reserve() 方法用于预分配 std::vector 容器的内存空间,以提高性能。该方法不会改变容器的大小(size),但会改变容器的容量(capacity)。预分配空间可以减少在连续添加元素时的扩容操作次数。其时间复杂度为 O(1),但如果需要分配更多内存,则可能涉及内存分配操作。

示例代码
#include <iostream>
#include <vector>int main() {std::vector<int> vec;// 预分配空间vec.reserve(10); // 预分配 10 个元素的空间// 添加元素for (int i = 0; i < 10; ++i) {vec.push_back(i * i);}std::cout << "Vector elements: ";for (int num : vec) {std::cout << num << " ";}std::cout << std::endl;std::cout << "Size: " << vec.size() << ", Capacity: " << vec.capacity() << std::endl;return 0;
}
运行结果
Vector elements: 0 1 4 9 16 25 36 49 64 81 
Size: 10, Capacity: 10

7. vector 容器的其他操作

7.1 判断容器是否为空

7.1.1 使用 empty() 判断

empty() 方法用于判断 std::vector 容器是否为空。如果容器中没有任何元素,则返回 true;否则返回 false。该方法的时间复杂度为 O(1),因为它直接检查容器的大小信息。

示例代码
#include <iostream>
#include <vector>int main() {std::vector<int> vec1;std::vector<int> vec2 = {10, 20, 30};// 判断容器是否为空if (vec1.empty()) {std::cout << "vec1 is empty." << std::endl;} else {std::cout << "vec1 is not empty." << std::endl;}if (vec2.empty()) {std::cout << "vec2 is empty." << std::endl;} else {std::cout << "vec2 is not empty." << std::endl;}return 0;
}
运行结果
vec1 is empty.
vec2 is not empty.

7.2 清空容器

7.2.1 使用 clear() 清空元素

clear() 方法用于清空 std::vector 容器中的所有元素。调用 clear() 后,容器的大小将变为 0,但容量不会改变。这意味着容器仍然保留了之前分配的内存空间,但所有元素都被移除。

示例代码
#include <iostream>
#include <vector>int main() {std::vector<int> vec = {10, 20, 30, 40, 50};// 清空容器vec.clear();std::cout << "Vector size after clear(): " << vec.size() << std::endl;std::cout << "Vector capacity after clear(): " << vec.capacity() << std::endl;return 0;
}
运行结果
Vector size after clear(): 0
Vector capacity after clear(): 8

7.3 元素交换

7.3.1 使用 swap() 交换两个容器数据

swap() 方法用于交换两个 std::vector 容器中的数据。调用 swap() 后,两个容器的内容将互换,但它们的容量不会改变。这种方式的时间复杂度为 O(1),因为它只是交换了两个容器的内部指针,而不是复制元素。

示例代码
#include <iostream>
#include <vector>int main() {std::vector<int> vec1 = {10, 20, 30};std::vector<int> vec2 = {40, 50, 60};// 交换两个容器的数据vec1.swap(vec2);std::cout << "vec1 after swap: ";for (int num : vec1) {std::cout << num << " ";}std::cout << std::endl;std::cout << "vec2 after swap: ";for (int num : vec2) {std::cout << num << " ";}std::cout << std::endl;return 0;
}
运行结果
vec1 after swap: 40 50 60 
vec2 after swap: 10 20 30 

相关文章:

  • 【算法题】最长回文子串
  • PDF处理控件Aspose.PDF教程:在 C# 中更改 PDF 页面大小
  • 【Linux系统】命令行参数 和 环境变量(含内建命令介绍)
  • Vue插件
  • ShardingSphere-JDBC 与 Sharding-JDBC 的对比与区别
  • 使用Redis作为缓存,提高MongoDB的读写速度
  • MySQL 索引底层原理剖析:B+ 树结构、索引创建维护与性能优化策略全解读
  • Vue-Todo-list 案例
  • 3.3 HarmonyOS NEXT原子化服务开发:卡片设计、轻量部署与场景化编排实战
  • Starrocks中RoaringBitmap杂谈
  • GICv3电源管理
  • 【位运算】丢失的数字(easy)
  • (T/SAIAS 020-2024)《医疗大模型语料一体机应用指南》深度解读与实施分析
  • 在虚拟宇宙中低语——进程间通信,Linux命名管道的前世今生
  • .NET 9中的异常处理性能提升分析:为什么过去慢,未来快
  • GMS地下水数值模拟及溶质(包含反应性溶质)运移模拟技术
  • SecureCRT 设置超时自动断开连接时长
  • MP4文件声音与视频分离
  • 1.springmvc基础入门(一)
  • 电镀机的阳极是什么材质?
  • 做网站哪家强/seo搜索优化是什么
  • wordpress 图片 旋转/aso优化师主要是干嘛的
  • 做网站挂靠服务器/免费推广自己的网站
  • 厦门学网站设计/雅虎搜索引擎入口
  • 网站服务器能更换吗/深圳网站搜索优化工具
  • 长沙建站模板大全/线上推广是什么意思