【C++知识点总结全系列 (06)】:STL六大组件详细总结与分析- 配置器、容器、迭代器、适配器、算法和仿函数

STL六大组件目录

  • 前言
  • 1、配置器
    • (1)What
    • (2)Why
    • (3)How
      • A.调用new和delete实现内存分配与销毁
      • B.STL Allocator
    • (4)allocator类
      • A.What
      • B.How
      • C.allocator的算法
  • 2、容器
    • (1)What
    • (2)Which(有哪些容器)
    • (3)序列容器(顺序容器)
      • A.Which
      • B.array:存储固定长度元素的序列
      • C.deque队列
      • D.vector
      • E.forward_list
      • F.list
      • G.string
      • H.tuple
    • (4)关联容器
      • A.What
      • B.Which
      • C.Why
      • D.pair
      • E.map
      • F.unordered_map
  • 3、迭代器
    • (1)What
    • (2)Why
    • (3)Which(迭代器类型)
      • A.输出迭代器
      • B.输入迭代器
      • C.单向迭代器
      • D.双向迭代器
      • E.随机访问迭代器
  • 4、适配器
    • (1)What
    • (2)Why
    • (3)栈适配器
    • (4)队列适配器
  • 5、算法
    • (1)What(什么是STL中的算法)
    • (2)Which
    • (3)\<algorithm\>
    • (4)cstdlib
      • (5)numric
  • 6、仿函数
    • (1)What
    • (2)Why(仿函数的作用)
      • A.可作为排序规则
      • B.作为判别式使用
      • C.可携带更多信息,拥有多种内部状态
      • D.作为算法 for_each 的返回值

前言

在这里插入图片描述
仿函数提供了一种调用算法的方式、算法通过迭代器对容器里边的数据进行访问和处理、迭代器是访问容器中数据的重要方式、而容器所占有的内存空间是由配置器分配和管理的。此外,适配器是对容器、迭代器或仿函数的一个封装。

1、配置器

(1)What

负责空间配置与管理,从实现角度来看,配置器是一个实现了动态空间配置、空间管 理、空间释放的类模板

(2)Why

动态内存管理(内存分配、对象构造、对象析构、内存释放、内存重新分配等)

(3)How

A.调用new和delete实现内存分配与销毁

在这里插入图片描述

B.STL Allocator

对象的构造由allocator类的construct负责,对象的释放由destroy负责
内存配置由allocate()负责,内存释放由deallocate()负责

(4)allocator类

A.What

C++11中预定义的配置器类,用于管理容器的内存分配是释放

B.How

allocator类的使用主要关注它的四个成员函数:

  • 分配内存:allocate()
  • 构造对象:construct(),在分配好的内存中构造对象
  • 销毁对象:destroy(),回收已分配的内存空间,释放数据对象
  • 回收内存:deallocate(),将内存空间归还给操作系统
//分配 10 个 string 类型的对象的内存(未初始化) 
std::allocator<string> alloca;
auto const p=alloca.allocate(10); //分配未构造的内存
alloca.construct(p,"zhangsan"); 
auto q=p;
alloca.construct(++q,"lisi"); 
alloca.construct(++q,"wangwu"); 
cout<<(*q)<<endl; //打印:wangwu
//使用完对象后,必须对每个构造的元素调用 destroy 类销毁它们 
while(q!=p)
{ alloca.destroy(--q); 
}
//元素被销毁之后,可以重新使用 alloca,也可以归还给系统 
alloca.deallocate(p,10);

C.allocator的算法

在这里插入图片描述

//拷贝和填充未初始化内存的算法:在未初始化的内存中创建对象 
std::vector<int> vec_a{1,2,3,4,5};
std::allocator<int> alloca_int; 
int* p_int=alloca_int.allocate(vec_a.size()*2);//p_int 为 int 类型的指针
//拷贝元素到 alloca_int 的内存中去
std::uninitialized_copy(vec_a.begin(),vec_a.end(),p_int);
for(int i=0;i<vec_a.size();++i){cout<<*(p_int+i)<<" ";}cout<<endl;//打印:1 2 3 4 5
//将剩余的元素初始化为 100
std::uninitialized_fill_n(p_int,vec_a.size(),100);
for(int i=0;i<vec_a.size();++i){cout<<*(p_int+i)<<" ";}cout<<endl;//打印:100 100 100 100 100

2、容器

(1)What

本质是标准库中特定用于存储和管理数据的类模板

(2)Which(有哪些容器)

在这里插入图片描述

  • 序列容器(顺序容器):容器中的数据是有序的
  • 关联容器:通过键值对(key-valuepair)来组织和访问元素,将红黑树作为底层数据结构,用于维护 键值对集合,并提供高效的元素访问和操作能力,本质是类模板

(3)序列容器(顺序容器)

A.Which

array、deque、forwarrd_list、list、vector

B.array:存储固定长度元素的序列

在这里插入图片描述
基本使用:导入array、构建array对象、调用array对象函数、使用算法对容器元素进行操作

#include <array>
std::array<int, 6> array01{11,22,33,44,55,66};

非成员函数

  • get(array):

template <int Index, class T, size_t N> constexpr T& get(array<T,N>&arr> noexcept;

std::array<int,4> c0{0,1,2,3}; //创建并初始化一个array类对象c0
for(const int &iTmp:c0)
{cout<<" "<<iTmp;
}
int i1 = std::get<1>(c0); // 得到1
int i3 = std::get<3>(c0); // 得到3
  • swap(array01, array02):

template<class T, std::size_t N>
void swap(array<T, N>&arr01, array<T,N> &arr01);

//成员函数
arr01.swap(arr02);
//非成员函数
swap(arr01, arr02);
  • 其它非成员函数:
    在这里插入图片描述
    成员函数
成员函数说明
array()构造函数
at()返回指定位置的引用
font() / back()返回第一个元素 (最后一个)元素的引用
begin() / end()返回第一个(最后一个)元素的迭代器
cbegin() / cend()返回第一个(最后一个)元素的常量迭代器
rbegin() / rend()返回反向数据中第一个(最后一个)元素的迭代器
data()返回第一个元素的地址
empty()测试array对象中是否存在数据
fill()将所有元素替换为指定值
assign()同fill
size()返回array对象中元素的个数
swap()交换两个array对象的数据

C.deque队列

在这里插入图片描述
基本使用:导入deque、创建deque对象、调用对象函数、使用算法对容器中元素进行操作

#include <deque>
std::deque<int> q01(10); //指定队列长度
std::vector<int> vec{1,2,3,4,5}
std::deque<int> q02(vec.begin(),vec.end()); //q02有初始值

非成员函数:

  • swap(q01,q02):交换两个队列数据

成员函数:

成员函数说明
at()返回指定位置的引用
font() / back()返回第一个元素 (最后一个)元素的引用
begin() / end()返回第一个(最后一个)元素的迭代器
cbegin() / cend()返回第一个(最后一个)元素的常量迭代器
rbegin() / rend()返回反向数据中第一个(最后一个)元素的迭代器
data()返回第一个元素的地址
empty()测试容器中是否存在数据
fill()将所有元素替换为指定值
assign()同fill
size()返回array对象中元素的个数
swap()交换两个容器的数据
emplace()就地构造元素插入到deque指定位置
emplace_back() / emplace_front()就地构造元素插入到末尾(开头)
erase()从指定位置删除一个或多个元素
insert()在指定位置插入一个或多个元素
pop_back() / pop_front()清除deque末尾(开头)元素
push_back() / push_front()添加元素到末尾(开头)
resize()为deque指定新的大小

D.vector

在这里插入图片描述
基本使用:导入vector、构建vector对象、调用vector函数、使用算法对容器中元素进行处理

#include <vector>
std::vector<int> vecArr01;

非成员函数

  • hash():返回vector对象的哈希值
  • swap( vec01, vec02);

成员函数

成员函数说明
font() / back()返回第一个元素 (最后一个)元素的引用
begin() / end()返回第一个(最后一个)元素的迭代器
cbegin() / cend()返回第一个(最后一个)元素的常量迭代器
emplace_back()在末尾处添加元素
emplace()在指定位置插入就地构造的元素
push_back() / pop_back()添加(删除)末尾处的元素
sort()对容器中的元素进行排序
reverse()颠倒元素中的顺序
size()返回容器中元素的数量
shrink_to_fit()放弃额外的容量
swap()交换两个容器的元素

E.forward_list

在这里插入图片描述
基本使用:导入forward_list、创建对象、调用对象函数、使用算法对容器中元素进行处理

#include <forward_list>
std::forward_list flst01(10);

成员函数:

成员函数说明
font()返回第一个元素 (最后一个)元素的引用
begin() / end()返回第一个(最后一个)元素的迭代器
cbegin() / cend()返回第一个(最后一个)元素的常量迭代器
emplace_after()在指定位置之后创建元素
erase_after()删除指定位置之后的元素
insert_after()在指定元素之后添加元素
pop_front()删除起始处的一个元素
push_front()在起始处插入一个元素
sort()对容器中的元素进行排序
reverse()颠倒元素中的顺序

F.list

在这里插入图片描述
基本使用:导入list、构建list对象、调用list对象函数、使用算法对容器中元素进行处理

#include <list>
std::list<int> lst;

非成员函数:

  • swap(lst01, lst02);

成员函数:

成员函数说明
font() / back()返回第一个元素 (最后一个)元素的引用
begin() / end()返回第一个(最后一个)元素的迭代器
cbegin() / cend()返回第一个(最后一个)元素的常量迭代器
emplace_after()在指定位置之后创建元素
emplace_front()在起始位置处添加一个元素
emplace_after()在结尾位置处添加一个元素
erase()从列表中指定位置删除一个元素
insert()在指定位置插入一个或多个元素
pop_back() / pop_front()删除末尾(起始)元素
push_back() / push_front()在末尾(起始)处添加元素
sort()对容器中元素进行排序
splice()将自定义的列表从list对象中删除或加入

G.string

基本使用:导入string、创建对象、调用string对象的函数、使用算法对string对象中元素进行处理

#include <string>
std::string strFlePth = "D:\\a.text";

非成员函数:

  • getline(strSrc, line); //逐行提取srtSrc中的字符串
  • swap(str01, str02); //交换两个字符数组

专用化非成员模板函数:

函数名说明
stod() / stof() / stoi() / stold() / stoll() / stoul() / stoull()将string转为double / float / int / long double / unsigned long long
to_string()将其它类型转为string类型
to_wstring()转为宽字符串类型

H.tuple

What:

用于存储多个不同类型的元素的通用容器类模板

Why:

灵活地适应不同类型的元素,并提供相应的操作和访问方式;当我们希望将一些数据 组合成对象,但又不想自定义数据结构来表示该对象时,tuple 将非常有用

How:

构造tuple对象和初始化

// 默认构造函数
std::tuple<string, int, vector<double>> t0; 
cout << std::boolalpha << (std::get<1>(t0) == 0) << endl; // 打印:true
// 参数化构造函数
std::tuple<string, int, vector<double>> t1("zhangsan", 23, {32, 33, 34});
// 拷贝构造函数
auto t1_copyF(t1); cout << std::get<0>(t1_copyF) << endl; // 打印:zhangsan
// 移动构造函数
auto t1_mvF(std::move(t1_copyF)); cout << std::get<0>(t1_mvF) << endl; // 打印:zhangsan cout << std::boolalpha << (std::get<0>(t1_copyF) == "") << endl; // 打印:true
// 拷贝赋值运算符
auto t1_copy = t1; 
cout << std::get<0>(t1_copy) << endl; // 打印:zhangsan 
cout << std::get<0>(t1) << endl; // 打印:zhangsan
// 移动赋值运算符
cout << std::get<0>(t1) << endl; // 打印:zhangsan 
auto t1_mv = std::move(t1);
cout << std::get<0>(t1_mv) << endl; // 打印:zhangsan 
cout << std::boolalpha << (std::get<0>(t1) == "") << endl; // 打印:true

make_tuple

// make_tuple 
std::tuple<string, int, vector<double>> t2 = std::make_tuple("lisi", 24, vector<double>({44.0, 45, 46}));
cout << std::get<0>(t2) << ", " << std::get<1>(t2) << ", {"<< std::get<2>(t2)[0] << "," << std::get<2>(t2)[1] << "," << std::get<2>(t2)[2] << "}" << endl;
函数名说明
get(tp)返回第i个元素的引用
typle_size<typleType:>::value返回元组的长度
tuple_element<i,tupleType>::type返回元组第i项的类型

(4)关联容器

A.What

通过键值对(key-valuepair)来组织和访问元素,将红黑树作为底层数据结构,用于维护 键值对集合,并提供高效的元素访问和操作能力,本质是类模板

B.Which

在这里插入图片描述

C.Why

  • 维护映射关系:一个值(也称为数据)与一个唯一的键相关联
  • 快速查找:通过以键作为索引,可以高效地查找、访问和修改相应的值
  • 自动排序:关联容器中的元素通常是自动根据键进行排序的,这样可以保持元素的有序性
  • 唯一性保证:关联容器中的键是唯一的,这意味着每个键只能关联一个值

D.pair

基本使用:导入pair、创建pair对象、调用对象的函数

#include <utility> 
std::pair<string,int> name_age{"赵家的狗",5000};

常见函数: make_pair()

#include <utility> 
std::pair<string,int> name_age{"赵家的狗",5000}; std::pair<string,int> mingDynasty_age("明朝",276); 
string songDynasty="宋朝"; int ageSong=247;
auto songDynasty_age=std::make_pair(songDynasty,ageSong); cout<<name_age.first<<","<<name_age.second<<endl;
cout<<mingDynasty_age.first<<","<<mingDynasty_age.second<<endl; cout<<songDynasty_age.first<<","<<songDynasty_age.second<<endl;

E.map

基本使用:导入库、创建对象、调用对象函数、使用算法对容器元素处理

#include <map>
std::map<int, string> map01;

非成员函数:

  • swap(map01, map02);

成员函数:

成员函数说明
begin() / end()返回第一个(最后一个)元素的迭代器
cbegin() / cend()返回第一个(最后一个)元素的常量迭代器
clear()清除容器中所有元素
contains()检查容器中是否包含具有指定键的元素
emplace()就地构造元素插入到map中
empty()判断容器是否为空
erase()从指定位置移除容器中的元素
get_allocator()返回map对象的副本
lower_bound()返回一个迭代器,迭代器指向键值大于等于指定键值的第一个元素
upper_bound()类比lower_bound()
swap()交换两个map元素

说明:set、multimap、multiset等和map函数差不多,这里就不继续陈列相关函数说明了,值得一提的是无序关联容器

F.unordered_map

在这里插入图片描述

无序容器使用一个哈希函数将元素映射到桶,访问元素时,先计算元素的哈希值,根 据哈希值找到桶,容器将具有一个特定哈希值的所有元素都保存在相同的桶中

桶接口:
在这里插入图片描述
成员函数:

成员函数说明
at查找具有指定键的元素
bucket()获取键值对的桶编号
hash_function()获取存储的哈希函数对象
rehash()重新生成哈希表

说明:其它成员函数类比于map类的成员函数

重载hasher()和eqOp()函数:

在这里插入图片描述
在这里插入图片描述

3、迭代器

(1)What

一种“泛型指针”,也叫“广义指针”,本质是重载了各种操作符的类模板

(2)Why

可以循环访问 C++ 标准库容器中的元素,而不必考虑容器的类型和存储细节

(3)Which(迭代器类型)

A.输出迭代器

输出迭代器说明
ostream_iterator用于将数据写入输出流,例如 std::cout
back_insert_iterator用于在容器的末尾插入元素, std::back_inserter(container)
front_insert_iterator用于在容器的开头插入元素, std::front_inserter(container)
insert_iterator用于在容器的指定位置插入元素, std::inserter(container,position)

ostream_iterator

std::ostream_iterator<int> it_cout(std::cout, " "); 
*it_cout = 100; 
++it_cout; 
*it_cout = 200;
std::cout << std::endl; // 打印:100 200

back_insert_iterator

std::vector<int> years{1894, 1927, 1928, 1935, 1937, 1945, 1949, 1951, 1956, 1959, 1964, 1973, 1978, 1998};
std::back_insert_iterator<std::vector<int>> it_inster_years_back(years); 
*it_inster_years_back = 2001; 
++it_inster_years_back;
*it_inster_years_back = 2008; 
for (auto const &item : years){ std::cout << item << std::endl;} // 打印:1894-2008

B.输入迭代器

输入迭代器说明
istream_iterator用于从输入流(如标准输入 cin)中按顺序读取数据的迭代器
istreambuf_iterator用于从输入流缓冲区中读取字符的迭代器
istream_token_iterator扩展了 istream_iterator,可以使用分隔符将输入流分割成单词或标记。可以使用自定义的分隔符来指定如何划分输入
std::ifstream in_stream2; 
in_stream2.open(sentences_file_path.c_str()); 
if (!in_stream2.is_open())
{std::cout << "Open failed!" << std::endl; 
}
std::istream_iterator<string> it_istream(in_stream2); 
std::istream_iterator<string> it_end;
while (it_istream != it_end)
{std::cout << *it_istream << std::endl; ++it_istream;
}

C.单向迭代器

一种只能向前遍历容器元素的迭代器,用于访问支持顺序访问的容器(如链表、单 向链表等)

单向迭代器说明
forward_list 迭代器用于遍历 forward_list(单向链表)容器的元素。它只能向前遍历,不支持反向遍历或随机访问
unordered_set 和 unordered_multiset 迭代器它们使用哈希表存储元素,不保证元素的顺序。迭代器按照插入顺序遍历。这些迭代器只支持向前遍历。
unordered_map 和 unordered_multimap 迭代器迭代器按照插入顺序遍历键值对。这些迭代器也只支持向前遍历

D.双向迭代器

双向迭代器说明
list 迭代器它支持双向遍历,可以使用 ++ 和 – 操作符向前或向后遍历元素
set 和 multiset 迭代器它们按照一定的排序规则存储元素,迭代器按照升序遍历
map 和 multimap 迭代器它们存储键值对,并按照键进行排序

E.随机访问迭代器

  • std::vector 的迭代器
  • std::deque 的迭代器
  • std::array 的迭代器
  • std::string 的迭代器

4、适配器

(1)What

标准库中的一种特殊容器类型,是对容器的一种封装:stack、queue、priority_queue
默认情况下:
stack 和 queue 是基于 deque 实现的
priority_queue 是基于 vector 实现的

(2)Why

封装细节,进一步解放程序员对底层代码的操作,使其只需关注业务逻辑

(3)栈适配器

std::stack<int> s;
s.push(1);
s.push(2);
s.push(3);
s.pop();
int iTop = s.top(); // 2

(4)队列适配器

std::queue<int> que;
que.push(1);
que.push(2);
que.push(3);
int iFir = que.front(); // 1
que.pop();
iFir = que.front(); // 2
int iLst = que.back(); // 3

5、算法

(1)What(什么是STL中的算法)

用来处理标准容器的函数模板

(2)Which

<algorithm>:提供了大量通用的算法函数,用于对各种容器中的元素进行操作和处理
<cstdlib>:stdlib.h的 C++版本,提供了动态内存管理、随机数生成、与环境交互、整数算术、搜索、排序、字符串转换以及多字节或宽字符处理等功能
<numeric>:定义了一些基础性的数值算法

(3)<algorithm>

函数名说明
adjacent_find搜索相等或满足指定条件的两个相邻元素
all_of测试所有元素都满足指定条件
binary_search测试有序范围中是否有指定要查找的值
sort对范围内的序列进行排序
find在指定范围内查找指定值
reverse反转指定范围内的元素
count计算指定范围内指定数据出现的次数

说明:由于该库存在大量算法,这里仅对几个常用函数进行介绍,读者在实践中,但凡需要对容器中的数据进行某种处理,就可以查看algorithm库是否存在您所需要的算法

(4)cstdlib

函数名说明
malloc分配指定字节数的内存块,如果内存不够,返回NULL
calloc(num, size)分配num个连续内存空间,每一块大小为size
free(ptr)释放指定内存
atof(const char *ch) | atoi |atol | atoll将char指针转为double、int、long等
srand(uint seed)设置随机数生成器的种子
rand()产生一个范围在0到RAND_MAX(32767)之间的随机整数
char getenv(const charname)返回一个指向环境变量的指针
abort()异常终止一个进程
exit(int state)程序中止执行,返回调用过程。参数state为0表示正常中止,非0表示非正常中止
qsort()对数组进行快速排序
abs() |labs()计算绝对值

(5)numric

函数名说明
accumulate求和
adjacent_difference计算相邻元素之间的差值(后一个减前一个元素)
inner_product对两个序列进行内积运算
partial_sum对指定范围内的元素进行局部求和

6、仿函数

(1)What

一种重载了 operator()函数调用符的类或类模板,行为类似函数

(2)Why(仿函数的作用)

A.可作为排序规则

class StudentScoreRule {
public: bool operator()(Student stu01, Student stu02) {return stu01.getScore() > stu02.getScore();}
};
int main()
{ std::set<Student, StudentScoreRule> studentSet;studentSet.clear();Student zs("张三", 23, 168); Student ls("李四", 24, 178); Student ww("王五", 25, 188); Student zl("赵六", 26, 144); Student qq("钱七", 27, 177); Student nb("牛八", 28, 288); studentSet.insert({zs, ls, ww, zl, qq, nb});cout << "*****************************************" << endl; for (auto stu : studentSet)cout << stu.getName() << "\t" << stu.getAge() << "\t" << stu.getScore() << endl; cout << "*****************************************" << endl;
}

studentSet对象将按照学生的分数进行排序存储

B.作为判别式使用

class Number
{
public:int num; Number(int num_) : num(num_) {} Number() { num = 0; }bool operator()(int a) {return a % this->num == 0;}
};//删除所有能被 2 整除的元素 
std::list<int> tmp_list;
for (int i = 1; i < 20; ++i) tmp_list.emplace_back(i); 
auto pos = std::remove_if(tmp_list.begin(), tmp_list.end(), Number(2));
tmp_list.erase(pos, tmp_list.end());

C.可携带更多信息,拥有多种内部状态

class mySequence
{
private:int val; 
public:mySequence(int val_) : val(val_) {} int operator()() {return this->val++;}
};
std::list<int> list01; 
std::generate_n(std::back_inserter(list01), 9, mySequence(1));

D.作为算法 for_each 的返回值

class Average {
private:int count_n; double sum; public:Average(int val = 0, int count_n_ = 0) : sum(val), count_n(count_n_) {}void operator()(double x) {++count_n; sum += x; }double getAveValue() { return sum / count_n; }
}; 
std::set<double> money{10.88, 12.88, 14, 13, 16.88, 20, 21.98}; 
Average res = std::for_each(money.begin(), money.end(), Average()); 
cout << res.getAveValue() << endl;
//方法 2 cout << "**********************************************" << endl; 
double sum = 0;
std::for_each(money.rbegin(), money.rend(), [&sum](double x){ sum += x; }); 
cout << sum / money.size() << endl;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/39932.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机网络知识普及之四元组

在涉及到TCP/UDP等IP类通信协议时&#xff0c;存在四元组概念 这里只是普及使用 先来一些前置知识&#xff0c;什么是IP协议&#xff1f; IP协议全称为互联网协议&#xff0c;处于网络层中&#xff0c;主要作用是标识网络中的设备&#xff0c;每个设备的IP地址是唯一的。 在网…

【JVM排查问题】JProfiler性能分析工具连接远程服务器Docker容器中的Java服务

1、下载JProfiler https://www.ej-technologies.com/download/jprofiler/version_13 下载Windows版本以及Linux版本 Windows用于可视化、Linux用于在Docker容器中启动 2、将Linux版本的JProfiler上传到Docker容器中&#xff0c;宿主机cp命令到容器中 docker cp /home/data/s…

像学Excel 一样学 Pandas系列-创建数据分析维度

嗨&#xff0c;小伙伴们。又到喜闻乐见的Python 数据分析王牌库 Pandas 的学习时间。按照数据分析处理过程&#xff0c;这次轮到了新增维度的部分了。 老样子&#xff0c;我们先来回忆一下&#xff0c;一个完整数据分析的过程&#xff0c;包含哪些部分内容。 其中&#xff0c…

CAM350如何添加走线?

在CAM350中如何添加走线? 有时候由于PCB文件丢失或其它原因,只有GERBER文件,这时候LAYOUT工程师就只能使用CAM350在GERBER里面修改。 那在CAM350里面如何添加走线呢? 操作方法如下: 1、选择菜单栏Add 选择Line 2、在走线前,要先设置D码,就是走线的形状和宽度。必需选择…

【服务器部署】Jenkins配置前端工程自动化部署

作者介绍&#xff1a;本人笔名姑苏老陈&#xff0c;从事JAVA开发工作十多年了&#xff0c;带过刚毕业的实习生&#xff0c;也带过技术团队。最近有个朋友的表弟&#xff0c;马上要大学毕业了&#xff0c;想从事JAVA开发工作&#xff0c;但不知道从何处入手。于是&#xff0c;产…

BIOS中的设置虽然不少,但其实大部分时候只需进行一些简单的调整

序言 浏览BIOS可能会让人感到不知所措,因为要考虑的设置太多了。但是,你应该在BIOS中进行一些简单的调整,以提高系统的性能和稳定性。我们将向你展示其中的一些调整,并解释你可能想要使用它们的时间和原因。 用密码保护你的BIOS 虽然我们很小心地对用户帐户进行密码保护…

[译]Reactjs性能篇

英文有限&#xff0c;技术一般&#xff0c;海涵海涵&#xff0c;由于不是翻译出身&#xff0c;所以存在大量的瞎胡乱翻译的情况&#xff0c;信不过我的&#xff0c;请看原文&#xff5e;&#xff5e; 原文地址&#xff1a;https://facebook.github.io/react/docs/advanced-per…

JavaSE阶段面试题(一)

目录 1.int a 1, int b 1, Integer c 1, Integer d 1&#xff1b;四个区别和联系&#xff0c;以及c和d是同一个吗&#xff1f; 2.为什么重写HashCode必须重写euqals&#xff0c;两者之间的关系&#xff1f; 3.创建对象的方式有哪些 4.重写和重载的区别 5.抽象类和接口…

day02-广播机制

广播机制 广播是numpy对不同形状的数组进行数值计算的方式&#xff0c;对数组的算术运算通常在相应的元素上进行 1.如果两个数组a和b形状相同&#xff0c;即满足a.shape b.shape&#xff0c;那么a*b的结果就是a与b数组对应位相乘。这要求维数相同且各维度的长度相同 a np.a…

七大排序算法的深入浅出(java篇)

&#x1f341; 个人主页&#xff1a;爱编程的Tom&#x1f4ab; 本篇博文收录专栏&#xff1a;Java专栏&#x1f449; 目前其它专栏&#xff1a;c系列小游戏 c语言系列--万物的开始_ 等等 &#x1f389; 欢迎 &#x1f44d;点赞✍评论⭐收藏&#x1f496;三连支…

【高级篇】第9章 Elasticsearch 监控与故障排查

9.1 引言 在现代数据驱动的应用架构中,Elasticsearch不仅是海量数据索引和搜索的核心,其稳定性和性能直接影响到整个业务链路的健康度。因此,建立有效的监控体系和掌握故障排查技能是每一位Elasticsearch高级专家的必备能力。 9.2 监控工具:洞察与优化的利器 在Elastics…

乘用车副水箱浮球式液位计传感器

浮球式液位计概述 浮球式液位计是一种利用浮球在液体中浮动的原理来测量液位的设备&#xff0c;广泛应用于各种工业自动化控制系统中&#xff0c;如石油化工、水处理、食品饮料等行业。它通过浮球的上下运动来测量液位的高低&#xff0c;具有结构简单、安装方便、测量范围广、…

如何选择适合自己的虚拟化技术?

虚拟化技术已成为现代数据中心和云计算环境的核心组成部分。本文将帮助您了解如何选择适合自己需求的虚拟化技术&#xff0c;以实现更高的效率、资源利用率和灵活性。 理解虚拟化技术 首先&#xff0c;让我们了解虚拟化技术的基本概念。虚拟化允许将一个物理服务器划分为多个虚…

【Linux】多线程(一万六千字)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 文章目录 前言 线程的概念 线程的理解(Linux系统为例) 在Linux系统里如何保证让正文部分的代码可以并发的去跑呢&#xff1f; 为什么要有多进程呢&#xff1f; 为…

Osg中的智能指针和观察指针

目录 1 设计 内容 1 设计 osg中能够使用智能指针的对象都继承自引用计数类Referenced&#xff0c;观察指针(observer_ptr)与智能指针之间通过ObserverSet相互关联&#xff0c;其中obserserver_ptr直接依赖ObeserverSet。 Referenced不直接依赖ObserverSet类&#xff0c;但可…

pdf合并,pdf合并成一个pdf,pdf合并在线网页版

在处理pdf文件的过程中&#xff0c;有时我们需要将多个pdf文件合并成一个pdf文件。作为一名有着丰富计算机应用经验的技术博主&#xff0c;我将为您详细介绍如何将多个pdf文件合并成一个pdf文件。 pdf合并方法&#xff1a;使用&#xff0c; “轻云处理pdf官网” 打开 “轻云处…

【高中数学/基本不等式】已知:x,y皆大于1,且x+2y=4 求:1/(x-1)+1/(y-1)的最小值为?

【问题来源】 https://www.ixigua.com/7025123539728466469?logTag1c2fd2e305d60e6277ab 之第一题 【问题】 已知&#xff1a;x,y皆大于1&#xff0c;且x2y4 求&#xff1a;1/(x-1)1/(y-1)的最小值为&#xff1f; 【解答】 解&#xff1a; 若将(x2y)/41代入目标式&…

学习笔记(linux高级编程)11

进程间通信 》信号通信 应用&#xff1a;异步通信。 中断&#xff0c;&#xff0c; 1~64&#xff1b;32应用编程。 如何响应&#xff1a; Term Default action is to terminate the process. Ign Default action is to ignore the signal. wait Core Default action is …

番外篇 | 斯坦福提出即插即用二阶优化器Sophia :相比Adam实现2倍加速,显著节省大语言模型训练成本

前言:Hello大家好,我是小哥谈。大模型的预训练成本巨大,优化算法的改进可以加快模型的训练时间并减少训练开销。目前大模型的训练优化器基本上都采用Adam及其变体,并且Adam的应用已经有9个年头了,在模型优化方面相当于霸主的地位。但是能否够在优化器方面提高模型预训练效…

医院挂号系统:基于JSP和MySQL的现代化医疗预约平台

开头语&#xff1a;您好&#xff0c;我是专注于医疗系统开发的IT学长。如果您对医院挂号系统感兴趣&#xff0c;欢迎联系我。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;JSP技术&#xff0c;B/S架构 工具&#xff1a;Eclipse&#xff0c;MyEclips…