C/C++ | 每日一练 (4)

💢欢迎来到张胤尘的技术站
💥技术如江河,汇聚众志成。代码似星辰,照亮行征程。开源精神长,传承永不忘。携手共前行,未来更辉煌💥

文章目录

  • C/C++ | 每日一练 (4)
    • 题目
    • 参考答案
      • 基础容器
        • 序列容器
          • `std::array`
          • `std::vector`
          • `std::deque`
          • `std::list`
          • `std::forward_list`
        • 关联容器
          • 有序关联容器
            • `std::set`
            • `std::map`
            • `std::multiset`
            • `std::multimap`
          • 无序关联容器
            • `std::unordered_set`
            • `std::unordered_map`
            • `std::unordered_multiset`
            • `std::unordered_multimap`
      • 容器适配器
        • `std::stack`
        • `std::queue`
        • `std::priority_queue`

C/C++ | 每日一练 (4)

题目

c++STL 常见容器有哪些?简述一下底层实现的原理。

参考答案

c++ 中根据容器的特点和结构分为如下两大类:

  • 基础容器
  • 容器适配器

下面基于以上列举的两大类型进行一一总结。

基础容器

c++ 标准库中,基础容器是构建其他容器(如容器适配器)的底层实现,它们提供了丰富的数据存储和管理功能。

基础容器主要分为两大类:序列容器和关联容器

序列容器

序列容器用于存储线性排列的元素,支持随机访问或顺序访问。它们的特点是元素的顺序由插入顺序决定。

c++ 标准库中提供的序列容器有:std::arraystd::vectorstd::dequestd::liststd::forward_list


std::array

c++11 引入的固定大小的序列容器,底层是静态数组。它的大小在编译时确定,因此不支持动态大小。

例如:

#include <iostream>
#include <array>

int main()
{
    std::array<int, 5> arr = {1, 2, 3, 4, 5};

    // 访问元素
    std::cout << arr[2] << std::endl; // 3

    // 修改元素
    arr[2] = 10;
    std::cout << arr[2] << std::endl; // 10

    // 因为 array 是固定大小的容器,不能动态增加、删除元素

    // 遍历
    for (int i : arr)
    {
        std::cout << i << " "; // 1 2 10 4 5
    }
    std::cout << std::endl;

    return 0;
}
std::vector

底层是基于动态数组实现,支持随机访问。它在内存中分配一块连续的空间来存储元素,当容器中的元素数量超过当前分配的空间时,会触发扩容机制,扩容因子根据不同的标准库实现有不同的大小,目前是存在1.5倍和2倍的大小。

例如:

#include <iostream>
#include <vector>

int main()
{
    std::vector<int> vec = {1, 2, 3, 4, 5};

    // 访问元素
    std::cout << vec[2] << std::endl; // 3

    // 修改元素
    vec[2] = 10;
    std::cout << vec[2] << std::endl; // 10

    // 在末尾添加元素
    vec.push_back(6);
    std::cout << vec.back() << std::endl; // 6

    // 删除最后一个元素
    vec.pop_back();
    std::cout << vec.size() << std::endl; // 5

    // 遍历
    for (int i : vec)
    {
        std::cout << i << " "; // 1 2 10 4 5
    }
    std::cout << std::endl;

    return 0;
}
std::deque

std::deque的底层结构可以看作是一个指针数组,其中每个指针指向一个固定大小的缓冲区(称为块)。这些块组成了整个 std::deque的数据存储。通过这种结构,std::deque可以在头尾进行高效的插入和删除操作,同时也能提供快速的随机访问。

  • 指针数组std::deque 使用一个数组来存储指向各个数据块(缓冲区)的指针。这个指针数组是连续的,即指针存储在一个连续的数组中。
  • 数据块(缓冲区):每个指针指向一个固定大小的缓冲区,这些缓冲区用于实际存储数据。缓冲区中的数据是连续存储的,但是缓冲区之间在内存中可能不是连续的。其中每个数据块大小是 4096 / sizeof(T)(其中 T是存储的类型)

例如:

#include <iostream>
#include <deque>

int main()
{
    std::deque<int> dq = {1, 2, 3, 4, 5};

    // 访问元素
    std::cout << dq[2] << std::endl; // 3

    // 修改元素
    dq[2] = 10;
    std::cout << dq[2] << std::endl; // 10

    // 在头部和尾部添加元素
    dq.push_front(0);
    dq.push_back(6);
    std::cout << dq.front() << " and " << dq.back() << std::endl; // 0 and 6

    // 删除头部和尾部元素
    dq.pop_front();
    dq.pop_back();
    std::cout << dq.size() << std::endl; // 5

    // 遍历
    for (int i : dq)
    {
        std::cout << i << " "; // 1 2 10 4 5
    }
    std::cout << std::endl;

    return 0;
}
std::list

双向链表,每个元素包含一个数据域和两个指针(分别指向前后元素)。它不依赖连续的内存空间。std::list 的大小可以动态增加或减少,允许在常数时间内插入或删除元素(只需调整指针)。另外 std::list 不支持随机访问,访问元素时需要从链表头或尾开始遍历。

例如:

#include <iostream>
#include <list>

int main()
{
    std::list<int> lst = {1, 2, 3, 4, 5};

    // 访问第一个元素
    std::cout << lst.front() << std::endl; // 1

    // 修改第一个元素
    lst.front() = 10;
    std::cout << lst.front() << std::endl; // 10

    // 在头部和尾部添加元素
    lst.push_front(0);
    lst.push_back(6);
    std::cout << lst.front() << " and " << lst.back() << std::endl; // 0 and 6

    // 删除第一个和最后一个元素
    lst.pop_front();
    lst.pop_back();
    std::cout << lst.size() << std::endl; // 5

    // 遍历
    for (int i : lst)
    {
        std::cout << i << " "; // 10 2 3 4 5
    }
    std::cout << std::endl;

    return 0;
}
std::forward_list

单向链表,每个元素只包含一个数据域和一个指针(指向后元素),只能单向遍历。与 std::list 一样不依赖于连续的内存空间,可以在常数时间内操作元素(调整指针),也同样不支持随机访问,访问元素时需要从链表头或尾开始遍历。

例如:

#include <iostream>
#include <forward_list>

int main()
{
    std::forward_list<int> flst = {1, 2, 3, 4, 5};

    // 访问第一个元素
    std::cout << flst.front() << std::endl; // 1

    // 修改第一个元素
    flst.front() = 10;
    std::cout << flst.front() << std::endl; // 10

    // 在头部添加元素
    flst.push_front(0);
    std::cout << flst.front() << std::endl; // 0

    // 删除第一个元素
    flst.pop_front();
    std::cout << flst.front() << std::endl; // 10

    // 遍历
    for (int i : flst)
    {
        std::cout << i << " "; // 10 2 3 4 5
    }
    std::cout << std::endl;

    return 0;
}
关联容器

c++ 标准库中,关联容器是一类特殊的容器,用于存储键值对,并根据键的值自动组织数据。

c++ 标准库提供了两种主要的关联容器类型,如下所示:

  • 有序关联容器:std::setstd::mapstd::multisetstd::multimap
  • 无序关联容器:std::unordered_setstd::unordered_mapstd::unordered_multisetstd::unordered_multimap

有序关联容器
std::set

存储唯一的键,所有元素按照键的顺序自动排序。std::set 底层使用红黑树实现,因此具有高效的插入、删除和查找操作。

例如:

#include <iostream>
#include <set>

int main()
{
    std::set<int> mySet;

    // 增:插入元素
    mySet.insert(10);
    mySet.insert(20);
    mySet.insert(30);
    mySet.insert(20); // 重复元素不会插入

    // 查找元素
    auto it = mySet.find(20);
    if (it != mySet.end())
    {
        std::cout << *it << std::endl; // 20
    }
    else
    {
        std::cout << "Not found!" << std::endl;
    }

    // set 的键值不可直接修改,需要删除后重新插入
    mySet.erase(it);  // 删除元素
    mySet.insert(25); // 插入新值

    // 删除元素
    mySet.erase(30);

    // 遍历
    for (const auto &value : mySet)
    {
        std::cout << value << " "; // 10 25
    }
    std::cout << std::endl;

    return 0;
}
std::map

以键值对的形式存储数据,键唯一,并且所有元素都按键的顺序自动排序。std::map 底层使用红黑树实现,因此具有高效的插入、删除和查找操作。

例如:

#include <iostream>
#include <map>

int main()
{
    std::map<int, std::string> myMap;

    // 插入键值对
    myMap[1] = "one";
    myMap[2] = "two";
    myMap[3] = "three";

    // 通过键访问值
    std::cout << myMap[2] << std::endl; // two

    // 修改键对应的值
    myMap[2] = "TWO";
    std::cout << myMap[2] << std::endl; // TWO

    // 删除键值对
    myMap.erase(3);

    // 遍历

    // 1: one
    // 2: TWO
    
    // for (const auto &[key, value] : myMap)
    // {
    //     std::cout << key << ": " << value << std::endl;
    // }

    for (const auto &it : myMap)
    {
        std::cout << it.first << ": " << it.second << std::endl;
    }

    return 0;
}
std::multiset

用于存储多个键,允许重复元素,并且所有元素按照键的顺序自动排序。std::multiset 使用红黑树实现,因此具有高效的插入、删除和查找操作。

例如:

#include <iostream>
#include <set>

int main()
{
    std::multiset<int> myMultiSet;

    // 插入元素
    myMultiSet.insert(10);
    myMultiSet.insert(20);
    myMultiSet.insert(20);
    myMultiSet.insert(30);

    // 查找元素
    auto it = myMultiSet.find(20);
    if (it != myMultiSet.end())
    {
        std::cout << *it << std::endl; // 20
    }
    else
    {
        std::cout << "Not found!" << std::endl;
    }

    // multiset 的键值不可直接修改,需要删除后重新插入
    myMultiSet.erase(it);  // 删除一个元素
    myMultiSet.insert(25); // 插入新值

    // 删除所有值为20的元素
    myMultiSet.erase(20);

    // 遍历
    for (const auto &value : myMultiSet)
    {
        std::cout << value << " "; // 10 25 30
    }
    std::cout << std::endl;

    return 0;
}
std::multimap

以键值对的形式存储数据,允许重复元素,并且所有元素都按键的顺序自动排序。std::multimap 底层使用红黑树实现,因此具有高效的插入、删除和查找操作。

例如:

#include <iostream>
#include <map>

int main()
{
    std::multimap<int, std::string> myMultiMap;

    // 插入键值对
    myMultiMap.insert({1, "one"});
    myMultiMap.insert({2, "two"});
    myMultiMap.insert({2, "TWO"});
    myMultiMap.insert({3, "three"});

    // 查找键对应的值(可能有多个)
    auto range = myMultiMap.equal_range(2);
    for (auto it = range.first; it != range.second; ++it)
    {
        // two
        // TWO
        std::cout << it->second << std::endl;
    }

    // 修改某个键值对的值
    auto it = myMultiMap.find(2);
    if (it != myMultiMap.end())
    {
        it->second = "TWO MODIFIED";
    }

    // 删除某个键值对
    myMultiMap.erase(it);

    // 遍历
    // 1: one
    // 2: TWO
    // 3: three
    
    // for (const auto &[key, value] : myMultiMap)
    // {
    //     std::cout << key << ": " << value << std::endl;
    // }

    for (const auto &it : myMultiMap)
    {
        std::cout << it.first << ": " << it.second << std::endl;
    }

    return 0;
}
无序关联容器
std::unordered_set

用于存储唯一的键,所有元素不按特定顺序排序。std::unordered_set 底层使用哈希表实现,因此具有常数时间复杂度的插入、删除和查找操作。

例如:

#include <iostream>
#include <unordered_set>

int main()
{
    std::unordered_set<int> us;

    // 插入元素
    us.insert(1);
    us.insert(2);
    us.insert(3);

    // 查找元素
    auto it = us.find(2);
    if (it != us.end())
    {
        std::cout << *it << std::endl; // 2
    }
    else
    {
        std::cout << "Not found!" << std::endl;
    }

    // unordered_set 不支持直接修改键,只能删除后重新插入
    us.erase(it);
    us.insert(25);

    // 删除
    us.erase(1);

    // 遍历
    for (const auto &elem : us)
    {
        std::cout << elem << " "; // 25 3
    }
    std::cout << std::endl;

    return 0;
}
std::unordered_map

以键值对的形式存储数据,键唯一,并且所有元素都不按特定顺序排序。std::unordered_map 底层使用哈希表实现,因此具有常数时间复杂度的插入、删除和查找操作。

例如:

#include <iostream>
#include <unordered_map>
using namespace std;

int main()
{
    unordered_map<int, string> um;

    // 插入键值对
    um[1] = "one";
    um[2] = "two";
    um[3] = "three";

    // 通过键访问值
    std::cout << um[2] << std::endl; // two

    // 修改键对应的值
    um[2] = "TWO";
    std::cout << um[2] << std::endl; // TWO

    // 删除键值对
    um.erase(3);

    // 遍历
    for (const auto &pair : um)
    {
        // 2: TWO
        // 1: one
        cout << pair.first << ": " << pair.second << endl;
    }

    return 0;
}
std::unordered_multiset

用于存储键,允许相同的元素出现多次,所有元素不按特定顺序排序。std::unordered_multiset 底层使用哈希表实现,因此具有常数时间复杂度的插入、删除和查找操作。

例如:

#include <iostream>
#include <unordered_set>

int main()
{
    std::unordered_multiset<int> ums;

    // 插入元素
    ums.insert(1);
    ums.insert(2);
    ums.insert(2);
    ums.insert(3);

    // 查找元素
    auto range = ums.equal_range(2);
    std::cout << std::distance(range.first, range.second) << std::endl; // 2

    // unordered_multiset 不支持直接修改键,只能删除后重新插入
    ums.erase(1);
    ums.insert(10);

    // 删除所有值为2的元素
    ums.erase(2);

    // 遍历
    for (const auto &elem : ums)
    {
        std::cout << elem << " "; // 10 3
    }
    std::cout << std::endl;

    return 0;
}
std::unordered_multimap

以键值对的形式存储数据,允许相同的键值出现多次,每个键可以对应多个值(键值对),并且所有元素都不按特定顺序排序。std::unordered_multimap 底层使用哈希表实现,因此具有常数时间复杂度的插入、删除和查找操作。

例如:

#include <iostream>
#include <unordered_map>

int main()
{
    std::unordered_multimap<int, std::string> umm;

    // 插入键值对
    umm.insert({1, "one"});
    umm.insert({2, "two"});
    umm.insert({2, "TWO"});
    umm.insert({3, "three"});

    // 查找键对应的值(可能有多个)
    auto range = umm.equal_range(2);
    std::cout << distance(range.first, range.second) << std::endl; // 2
    for (auto it = range.first; it != range.second; ++it)
    {
        std::cout << it->second << " "; // TWO two
    }
    std::cout << std::endl;

    // 修改某个键值对的值
    auto it = umm.find(2);
    if (it != umm.end())
    {
        it->second = "TWO_UPDATED";
    }

    // 删除某个键值对
    umm.erase(3);

    // 遍历
    for (const auto &pair : umm)
    {
        // 2: TWO_UPDATED
        // 2: two
        // 1: one
        std::cout << pair.first << ": " << pair.second << std::endl;
    }

    return 0;
}

容器适配器

容器适配器是一种特殊的容器,它们基于标准容器(如std::vectorstd::dequestd::list等),通过封装和限制其接口来提供特定的抽象数据类型。容器适配器并不直接存储数据,而是通过底层容器来数据存储,并且只暴露部分功能,以满足特定的使用场景。

c++ 标准库中提供了三个容器适配器:std::stackstd::queuestd::priority_queue


std::stack

后进先出(LIFO)的数据结构,支持在栈顶插入和删除元素。默认基于 std::deque 实现,可以使用 std::vectorstd::list 作为底层容器

template<typename _Tp, typename _Sequence = deque<_Tp> >
class stack { 
	//...
}

例如:

#include <iostream>
#include <stack>
#include <vector>
#include <list>

int main()
{
    std::stack<int> s;

    // 使用 std::vector
    // std::stack<int, std::vector<int>> s1;
    
    // 使用 std::list
    // std::stack<int, std::list<int>> s2;

    // 插入元素
    s.push(1);
    s.push(2);
    s.push(3);

    // 查询栈顶元素
    std::cout << s.top() << std::endl; // 3

    // 弹出栈顶元素
    s.pop();
    std::cout << s.top() << std::endl; // 输出新栈顶元素的值    2

    // 判断栈是否为空
    if (!s.empty())
    {
        std::cout << "stack is not empty" << std::endl; // stack is not empty
    }

    // 获取栈的大小
    std::cout << s.size() << std::endl; // 2

    return 0;
}
std::queue

先进先出(FIFO)的数据结构,支持在队尾插入元素,在队头删除元素。默认基于 std::deque 实现,可以使用 std::list 作为底层容器

template<typename _Tp, typename _Sequence = deque<_Tp> >
class queue
{
    // ...
}

需要注意的是:std::vector 是一个动态数组,支持快速的尾部插入和删除操作(push_backpop_back),但不支持高效的头部删除操作(pop_front)。因此, std::vector 无法作为 std::queue 的底层容器。

例如:

#include <iostream>
#include <queue>
#include <list>

int main()
{
    std::queue<int> q;

    // 使用 std::list
    // std::queue<int, std::list<int>> q1;

    // 元素入队
    q.push(1);
    q.push(2);
    q.push(3);

    // 输出队头元素
    std::cout << q.front() << std::endl; // 1

    // 输出队尾元素
    std::cout << q.back() << std::endl; // 3

    // 元素出队
    q.pop();
    std::cout << q.front() << std::endl; // 2

    // 判断队列是否为空
    if (!q.empty())
    {
        std::cout << "queue is not empty" << std::endl; // queue is not empty
    }

    // 获取队列的大小
    std::cout << "queue size: " << q.size() << std::endl; // queue size: 2

    return 0;
}
std::priority_queue

优先队列,元素会按照优先级顺序排(默认是大顶堆,如果需要小顶堆,则需要自定义比较器)。默认基于 std::vector 作为底层容器,可以使用 std::deque 作为底层容器

template<typename _Tp, typename _Sequence = vector<_Tp>,
   typename _Compare  = less<typename _Sequence::value_type> >
class priority_queue
{
    // ...
}

需要注意的是:std::list 只支持双向迭代器,不支持随机访问。而优先队列需要上浮和下沉操作(需要随机访问的支持),所以 std::list 无法作为 std::priority_queue 的底层容器。

例如:

#include <iostream>
#include <queue>
#include <deque>

int main()
{
    std::priority_queue<int> pq;
    // std::priority_queue<int, std::deque<int>> pq;

    // 堆中插入元素
    pq.push(1);
    pq.push(3);
    pq.push(2);

    // 查询堆顶元素
    std::cout << pq.top() << std::endl; // 3

    // 删除堆顶元素
    pq.pop();
    std::cout << pq.top() << std::endl; // 2

    // 判断堆是否为空
    if (!pq.empty())
    {
        // priority queue is not empty
        std::cout << "priority queue is not empty" << std::endl; 
    }

    // 获取优先队列的大小
    // priority queue size: 2
    std::cout << "priority queue size: " << pq.size() << std::endl; 

    return 0;
}

🌺🌺🌺撒花!

如果本文对你有帮助,就点关注或者留个👍
如果您有任何技术问题或者需要更多其他的内容,请随时向我提问。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

(八)趣学设计模式 之 装饰器模式!

目录 一、 啥是装饰器模式&#xff1f;二、 为什么要用装饰器模式&#xff1f;三、 装饰器模式的实现方式四、 装饰器模式的优缺点五、 装饰器模式的应用场景六、 装饰器模式 vs 代理模式七、 总结 &#x1f31f;我的其他文章也讲解的比较有趣&#x1f601;&#xff0c;如果喜欢…

快节奏生活

在当今快节奏的商务环境中&#xff0c;效率成为了决定企业竞争力的关键因素之一。亿可达软件连接平台&#xff0c;以其独特的功能和优势&#xff0c;为职场人士带来了前所未有的便捷与高效&#xff0c;成为了众多用户心中的“宝藏”工具。 1、亿可达&#xff1a;自动化流程的搭…

Jenkins protoc: command not found

个人博客地址&#xff1a;Jenkins protoc: command not found | 一张假钞的真实世界 在使用Jenkins编译Hadoop3.1.2时报错信息如下&#xff1a; [INFO] --- hadoop-maven-plugins:3.1.2:protoc (compile-protoc) hadoop-common --- [WARNING] [protoc, --version] failed: j…

SOME/IP协议的建链过程

在SOME/IP协议中,建立服务通信链路的过程主要涉及服务发现机制,通常需要以下三次交互: 服务提供者广播服务可用性(Offer Service) 服务提供者启动后,周期性地通过Offer Service消息向网络广播其提供的服务实例信息(如Service ID、Instance ID、通信协议和端口等)。 作用…

考研/保研复试英语问答题库(华工建院)

华南理工大学建筑学院保研/考研 英语复试题库&#xff0c;由华工保研er和学硕笔试第一同学一起整理&#xff0c;覆盖面广&#xff0c;助力考研/保研上岸&#xff01;需要&#x1f447;载可到文章末尾见小&#x1f360;。 以下是主要内容&#xff1a; Part0 复试英语的方法论 Pa…

Linux7-线程

一、前情回顾 chdir();功能&#xff1a; 函数用于改变当前进程的工作目录。 参数&#xff1a;路径&#xff08;Path&#xff09;&#xff1a;这是一个字符串参数&#xff0c;表示要切换到的目标目录的路径。 返回值&#xff1a; 成功&#xff1a;在成功改变当前工作目…

防火墙双机热备---VRRP,VGMP,HRP(超详细)

双机热备技术-----VRRP&#xff0c;VGMP&#xff0c;HRP三个组成 注&#xff1a;与路由器VRRP有所不同&#xff0c;路由器是通过控制开销值控制数据包流通方向 防火墙双机热备&#xff1a; 1.主备备份模式 双机热备最大的特点就是防火墙提供了一条专门的备份通道&#xff08;心…

LabVIEW形状误差测量系统

在机械制造领域&#xff0c;形状与位置公差&#xff08;GD&T&#xff09;直接影响装配精度与产品寿命。国内中小型机加工企业因形状误差导致的返工率高达12%-18%。传统测量方式存在以下三大痛点&#xff1a; ​ 设备局限&#xff1a;机械式千分表需人工读数&#xff0c;精度…

本地部署大模型: LM Studio、Open WebUI 与 Chatbox 全面对比以及选型指南

1. 工具概述 LM Studio 定位&#xff1a;专注于本地化大模型实验与推理的桌面工具&#xff0c;支持多模型并行、Hugging Face集成及离线运行。 核心功能&#xff1a; 图形化界面直接加载GGUF模型文件&#xff0c;支持NVIDIA/AMD GPU加速。 内置OpenAI兼容API&#xff0c;可搭…

百度觉醒,李彦宏渴望光荣

文 | 大力财经 作者 | 魏力 2025年刚刚开年&#xff0c;被一家名为DeepSeek的初创公司强势改写。在量化交易出身的创始人梁文锋的带领下&#xff0c;这支团队以不到ChatGPT 6%的训练成本&#xff0c;成功推出了性能可与OpenAI媲美的开源大模型。 此成果一经问世&#xff0c;…

mysql 迁移到人大金仓数据库

我是在windows上安装了客户端工具 运行数据库迁移工具 打开 在浏览器输入http://localhost:54523/ 账号密码都是kingbase 添加mysql源数据库连接 添加人大金仓目标数据库 添加好的两个数据库连接 新建迁移任务 选择数据库 全选 迁移中 如果整体迁移不过去可以单个单个或者几个…

Spring Cloud — Hystrix 服务隔离、请求缓存及合并

Hystrix 的核心是提供服务容错保护&#xff0c;防止任何单一依赖耗尽整个容器的全部用户线程。使用舱壁隔离模式&#xff0c;对资源或失败单元进行隔离&#xff0c;避免一个服务的失效导致整个系统垮掉&#xff08;雪崩效应&#xff09;。 1 Hystrix监控 Hystrix 提供了对服务…

【链 表】

【链表】 一级目录1. 基本概念2. 算法分析2.1 时间复杂度2.2 空间复杂度2.3 时空复杂度互换 线性表的概念线性表的举例顺序表的基本概念顺序表的基本操作1. 初始化2. 插入操作3. 删除操作4. 查找操作5. 遍历操作 顺序表的优缺点总结优点缺点 树形结构图形结构单链表基本概念链表…

记录锁,间隙锁,Next-Key Lock

记录锁&#xff0c;间隙锁&#xff0c;Next-Key Lock mysql的锁机制一、InnoDB行锁的种类1、记录锁&#xff08;Record Lock&#xff09;&#xff08;1&#xff09;不加索引&#xff0c;两个事务修改同一行记录&#xff08;2&#xff09;不加索引&#xff0c;两个事务修改同一表…

vue3父子组件props传值,defineprops怎么用?(组合式)

目录 1.基础用法 2.使用解构赋值的方式定义props 3.使用toRefs的方式解构props (1).通过ref响应式变量&#xff0c;修改对象本身不会触发响应式 1.基础用法 父组件通过在子组件上绑定子组件中定义的props&#xff08;:props“”&#xff09;传递数据给子组件 <!-- 父组件…

鸿蒙Next-方法装饰器以及防抖方法注解实现

以下是关于 鸿蒙Next&#xff08;HarmonyOS NEXT&#xff09;中 MethodDecorator 的详细介绍及使用指南&#xff0c;结合了多个技术来源的实践总结&#xff1a; 一、MethodDecorator 的概念与作用 MethodDecorator 是鸿蒙Next框架中用于装饰类方法的装饰器&#xff0c;属于 Ark…

快速入门——状态管理VueX

Vuex介绍 状态管理 每一个Vuex应用的核心都是一个store&#xff0c;与普通的全局对象不同的是&#xff0c;基于Vue数据与视图绑定的特点&#xff0c;当store中的状态发生变化时&#xff0c;与之绑定的视图也会被重新渲染。 store中的状态不允许被直接修改&#xff0c;改变sto…

java进阶学习脑图

今天开始分享我的第一篇博客&#xff0c;先放上我自己花费一个月完成的java进阶学习脑图吧&#xff01; 谁都想像R大一样对JVM可以知无不言&#xff0c;言无不尽&#xff1b; 谁都想像Doug Lea一样可以参与JUC这种核心模块的开发&#xff1b; 但是&#xff0c;不能只停留在想…

【设计师专属】智能屏幕取色器Pro|RGB/HEX双模式|快捷键秒存|支持导出文档|C++ QT

&#x1f525; “1秒锁定千万色值&#xff0c;让灵感不再流失&#xff01;” ✔ 像素级精准捕捉 ✔ 快捷键极速记录 ✔ 数据一键导出 ✔ 开发者/设计师效率神器 "还在手动截图比色&#xff1f;加班改稿只因色差&#xff1f;前端还原总被吐槽&#xff1f; &#x1f449;…

力扣 下一个排列

交换位置&#xff0c;双指针&#xff0c;排序。 题目 下一个排列即在组成的排列中的下一个大的数&#xff0c;然后当这个排列为降序时即这个排列最大&#xff0c;因为大的数在前面&#xff0c;降序排列的下一个数即升序。所以&#xff0c;要是想找到当前排列的下一个排列&…