list的使用,及部分功能的模拟实现(C++)

目录(文章中"节点"和"结点"是同一个意思)

1. list的介绍及使用

1.1 list的介绍

1.2 list的使用

1.2.1 list的构造

 1.2.2 list iterator的使用

 1.2.3 list capacity

1.2.4 list element access

 1.2.5 list modifiers

 1.2.6 list的迭代器失效

 2. list的模拟实现

2.1 list_node结点

 2.2 list_iterator迭代器

 2.2.1 运算符重载!=

2.2.2  运算符重载==

 2.2.3 运算符重载前置++

 2.2.4 运算符重载后置++

 2.2.5 运算符重载前置--

 2.2.6 运算符重载后置--

 2.2.7 运算符重载*

 2.2.8 运算符重载->

 2.3 list类

2.3.1 构造函数

2.3.1.1默认构造函数list

 2.3.1.2 拷贝构造

2.3.1.3  list(std::initializer_list lt)

 2.3.2 析构函数

2.3.3 赋值运算符重载

 2.3.4 front和back

2.3.5 size和begin和end

2.3.6 insert插入和erase删除

2.3.6.1 insert插入

 2.3.6.2 erase删除

2.3.7 头插push_front,头删pop_front,尾插push_back,尾删pop_back

2.4 整体代码

1. list的介绍及使用

1.1 list的介绍

std::list是 C++ 标准模板库(STL)中的一个容器类,底层实现为双向链表,适用于需要频繁插入和删除操作的场景。

1.2 list的使用

以下为list中一些常见的重要接口。

1.2.1 list的构造

构造函数( (constructor))接口说明
list (size_type n, const value_type& val = value_type())构造的list中包含n个值为val的元素
list()构造空的list
list (const list& x)拷贝构造函数
list (InputIterator first, InputIterator last)用[first, last)区间中的元素构造 list

使用演示:

void test1()
{list<int> l1(10, 5);list<int> l2;list<int> l3(l1);list<int> l4(l1.begin(),l1.end());for (auto& e : l1){cout << e << " ";}cout << endl;for (auto& e : l2){cout << e << " ";}cout << endl;for (auto& e : l3){cout << e << " ";}cout << endl;	for (auto& e : l4){cout << e << " ";}cout << endl;
}

结果:

 1.2.2 list iterator的使用

这里可以暂时将迭代器理解成一个指针,该指针指向list中的某个节点。(其实底层实现时,迭代器是一个封装的对象

函数声明接口说明
begin + end返回第一个元素的迭代器+返回最后一个元素下一个位置的迭代器
rbegin + rend返回第一个元素的reverse_iterator,即end位置,返回最后一个元素下一个位 置的reverse_iterator,即begin位置

1. begin与end为正向迭代器,对迭代器执行++操作,迭代器向后移动

2. rbegin(end)与rend(begin)为反向迭代器,对迭代器执行++操作,迭代器向前移动

使用演示:

void test2()
{list<int> l;l.push_back(1);l.push_back(2);l.push_back(3);l.push_back(4);l.push_back(5);list<int>::reverse_iterator rit = l.rbegin();while (rit != l.rend()){cout << *rit << " ";rit++;}cout << endl;list<int>::iterator it = l.begin();while (it != l.end()){cout << *it << " ";it++;}cout << endl;
}

结果:

 1.2.3 list capacity

函数声明接口说明
empty检测list是否为空,是返回true,否则返回false
size返回list中有效节点的个数

使用演示:

void test3()
{list<int> l;l.push_back(1);l.push_back(2);l.push_back(3);l.push_back(4);l.push_back(5);if(!l.empty()){cout << "该链表非空" << endl;}cout << "有效节点个数:" << l.size() << endl;
}

结果:

1.2.4 list element access

函数声明接口说明
front返回list的第一个节点中值的引用
back返回list的最后一个节点中值的引用

 使用演示:

void test4()
{list<int> l;l.push_back(1);l.push_back(2);l.push_back(3);l.push_back(4);l.push_back(5);cout << l.front() << endl;cout << l.back() << endl;
}

结果:

 1.2.5 list modifiers

函数声明接口说明
push_front在list首元素前插入值为val的元素
pop_front删除list中第一个元素
push_back在list尾部插入值为val的元素
pop_back删除list中最后一个元素
insert在list position 位置中插入值为val的元素
erase删除list position位置的元素
swap交换两个list中的元素
clear清空list中的有效元素

使用演示:

push_front和pop_front使用:

void test5()
{list<int> l;l.push_back(1);l.push_back(2);l.push_back(3);l.push_back(4);l.push_back(5);for (auto& e : l){cout << e << " ";}cout << endl;l.push_front(10);cout << "头插后:";for (auto& e : l){cout << e << " ";}cout << endl;l.pop_front();cout << "头删后:";for (auto& e : l){cout << e << " ";}cout << endl;
}

结果:

 push_back和pop_back:

void test6()
{list<int> l;l.push_back(1);l.push_back(2);l.push_back(3);l.push_back(4);l.push_back(5);for (auto& e : l){cout << e << " ";}cout << endl;l.push_back(6);cout << "尾插后:";for (auto& e : l){cout << e << " ";}cout << endl;l.pop_back();cout << "尾删后:";for (auto& e : l){cout << e << " ";}cout << endl;
}

结果:

 insert和erase:

void test7()
{list<int> l;l.push_back(1);l.push_back(2);l.push_back(3);l.push_back(4);l.push_back(5);for (auto& e : l){cout << e << " ";}cout << endl;l.insert(++l.begin(), 30);cout << "插入后:";for (auto& e : l){cout << e << " ";}cout << endl;l.erase(--l.end());cout << "删除后:";for (auto& e : l){cout << e << " ";}cout << endl;
}

结果:

swap:

void test8()
{list<int> l1;l1.push_back(1);l1.push_back(2);l1.push_back(3);l1.push_back(4);l1.push_back(5);list<int> l2(5, 5);cout << "交换前" << endl;cout << "l1:";for (auto& e : l1){cout << e << " ";}cout << endl;cout << "l2:";for (auto& e : l2){cout << e << " ";}cout << endl;cout << "交换后" << endl;l1.swap(l2);cout << "l1:";for (auto& e : l1){cout << e << " ";}cout << endl;cout << "l2:";for (auto& e : l2){cout << e << " ";}cout << endl;
}

 结果:

clear:

void test9()
{list<int> l1;l1.push_back(1);l1.push_back(2);l1.push_back(3);l1.push_back(4);l1.push_back(5);cout << "清空前" << endl;cout << "有效元素个数:" << l1.size() << endl;for (auto& e : l1){cout << e << " ";}cout << endl;l1.clear();cout << "清空后" << endl;cout << "有效元素个数:" << l1.size() << endl;for (auto& e : l1){cout << e << " ";}cout << endl;
}

 结果:

 1.2.6 list的迭代器失效

小编前面文章里面“vector迭代器失效”,提到只要使用erase或者insert之后迭代器就直接失效,但是对于list有所不同,迭代器失效即迭代器所指向的节点的无效,即该节点被删除了。因为list的底层结构为带头结点的双向循环链表,因此在list中进行插入时是不会导致list的迭代器失效的,只有在删除时才会失效,并且失效的只是指向被删除节点的迭代器,其他迭代器不会受到影响。

 举例(删除所有结点):

void test10()
{int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };list<int> l(array, array + sizeof(array) / sizeof(array[0]));auto it = l.begin();while (it != l.end()){// erase()函数执行后,it所指向的节点已被删除,因此it无效,在下一次使用it时,必须先给其赋值l.erase(it);++it;}
}

结果:

可以看到这里报段错误,迭代器失效了。

改进后:

void test10()
{int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };list<int> l(array, array + sizeof(array) / sizeof(array[0]));auto it = l.begin();while (it != l.end()){it=l.erase(it);}
}

因为erase函数删除后,会返回删除结点的下一个节点迭代器,it接收返回值,相当于更新了迭代器。

 2. list的模拟实现

这里利用双向带头链表实现,因为链表的物理空间并不是连续的,所以这里的迭代器不能使用指针,这里对迭代器进行了封装,实现一个对象。还有这里为了和原本库里list区分,将自己写的list封装在命名空间里(作者的是iu)

2.1 list_node结点

template<class T>
struct list_node
{list_node<T>* _prev;list_node<T>* _next;T _value;list_node(const T& x = T()):_prev(nullptr),_next(nullptr),_value(x){}
};

双向带头链表,所以成员有前驱结点,和后继结点,和元素对象。

 2.2 list_iterator迭代器

template<class T,class REF,class PTR>
struct list_iterator
{typedef list_node<T> Node;typedef list_iterator<T, REF, PTR> Self;Node* _node;list_iterator(Node* node):_node(node){}};

这里模版为什么会有REF和PTR?其实是解决,范围for迭代器访问时,会有const修饰的对象,如果直接确定的写,只有普通对象可以,所以这里多给两个参数模版,让编译器自己去判断是const修饰的对象,还是普通对象。

 2.2.1 运算符重载!=

bool operator!=(const Self& it)
{return  _node!=it._node;
}

2.2.2  运算符重载==

bool operator==(const Self& it)
{return _node == it._node;
}

 2.2.3 运算符重载前置++

Self& operator++()
{_node = _node->_next;return *this;
}

结点的指向直接向后移动一位。

 2.2.4 运算符重载后置++

Self operator++(int)
{Self tmp(*this);_node = _node->_next;return tmp;
}

创建一个临时对象,节点的指向向后移动一位,返回临时对象。

 2.2.5 运算符重载前置--

Self& operator--()
{_node = _node->_prev;return *this;
}

结点的指向直接向前移动一位。

 2.2.6 运算符重载后置--

Self operator++(int)
{Self tmp(*this);_node = _node->_next;return tmp;
}

创建一个临时对象,节点的指向向前移动一位,返回临时对象。

 2.2.7 运算符重载*

REF operator*()
{return _node->_value;
}

解引用,就是返回对象的值。

 2.2.8 运算符重载->

PTR operator->()
{return &_node->_value;
}

这里为什么是取值的地址?通过下面的例子来讲解:

void test2()
{struct A{A(int a = 0,int b=0):_a(a),_b(b){}int _a;int _b;};iu::list<A>l2;l2.push_back({1,1});l2.push_back({2,2});l2.push_back({3,3});l2.push_back({4,4});iu::list<A>::iterator it = l2.begin();while (it != l2.end()){cout << (*it)._a << ":" << it->_b << endl;it++;}
}

这里可以利用解引用在去访问,A类中的成员,这是一种访问方式;而这个it->b是如何访问的?前面实现的是返回A的地址,拿到A对象的地址和成员_b之间也没有运算符,那有怎么样才能访问到_b呢?其实这里省略了一个->,这里其实应该是it->->_b,所以先拿到A对象的地址,再利用结构体->这种方式。解引用访问里面的成员。

结果:

 2.3 list类

	template<class T>class list{typedef list_node<T> Node;public:typedef list_iterator<T,T&,T*> iterator;typedef list_iterator<T, const T&, const T*> const_iterator;private:Node* _head;size_t _size;};
}

成员有头结点,和元素个数。

2.3.1 构造函数

2.3.1.1默认构造函数list
void empty_init()
{_head = new Node;_head->_prev = _head;_head->_next = _head;_size = 0;
}list()
{empty_init();
}

这里利用empty_init函数,进行初始化,是为了方便后面几个构造函数,先初始化,再尾插的操作。

 2.3.1.2 拷贝构造
list(const list<T>& lt)
{empty_init();for (auto& e : lt){push_back(e);}
}

初始化,再遍历一遍lt,进行尾插依次插入。

2.3.1.3  list(std::initializer_list<T> lt)
list(std::initializer_list<T> lt)
{empty_init();for (auto& e : lt){push_back(e);}
}

和上面同理。

这里举一个例子:

void test8()
{iu::list<int>l1 = { 1,2,3,4,5,6,7 };for (auto& e : l1){cout << e << " ";}cout << endl;
}

 结果:

这个initializer_list<T>类型是一个类似于数组的类型,可以理解成一种类似数组初始化的方式。

 2.3.2 析构函数

void clear()
{iterator it = begin();while (it != end()){it = erase(it);}
}~list()
{clear();delete _head;_head = nullptr;
}

先在clear函数里面将数据全部清除,再将头结点释放掉,置为空。

2.3.3 赋值运算符重载

void swap(list<T>& lt)
{std::swap(_head, lt._head);std::swap(_size, lt._size);
}list<T>& operator=(list<T> lt)
{swap(lt);return *this;
}

 利用std中的交换函数,将临时对象与this指向的对象进行交换,临时对象出了作用域会自然销毁,也不会影响实参,这样就相当于实现了赋值操作。

 2.3.4 front和back

T& front()
{return _head->_next->_value;
}const T& front()const
{return _head->_next->_value;
}
T& back()
{return _head->_prev->_value;
}
const T& back()const
{return _head->_prev->_value;
}

这里利用的是双向带头链表,所以头部front元素就是头结点的下一个,尾结点back就是头结点的前一个。这里还重载了const修饰的对象,当对象元素是不可改变的const时,也可以使用。

2.3.5 size和begin和end

size_t size()
{return _size;
}iterator begin()
{return _head->_next;
}iterator end()
{return _head;
}const_iterator begin() const
{return _head->_next;
}const_iterator end() const
{return _head;
}		

size函数,直接返回成员_size大小即可。

begin()返回头结点的下一个结点的迭代器,end()返回最后一个元素的下一个结点的迭代器,所以就是头结点head,这里也是重载了const修饰的对象,当对象元素是不可改变的const时,也可以使用。

2.3.6 insert插入和erase删除

2.3.6.1 insert插入
void insert(iterator pos,const T& x)
{Node* newnode = new Node(x);Node* cur = pos._node;Node* prev = cur->_prev;prev->_next = newnode;newnode->_prev = prev;newnode->_next = cur;cur->_prev = newnode;++_size;
}

首先创建一个新的结点,再进行插入操作,插入时,先找到pos位置的结点,和pos位置的前一个结点,再改变前后指针指向即可,最后_size再加1。

 2.3.6.2 erase删除
iterator erase(iterator pos)
{assert(pos != end());Node* del = pos._node;Node* prev = del->_prev;Node* next = del->_next;prev->_next = next;next->_prev = prev;delete del;--_size;return iterator(next);
}

首先找到pos位置的结点,再确定pos前一个结点,和后一个结点的位置,最后改变指针指向,再删除pos位置的节点,_size再减1,最后还要返回删除节点的下一个位置的结点,返回匿名对象即可。

2.3.7 头插push_front,头删pop_front,尾插push_back,尾删pop_back

void push_back(const T& x)
{insert(end(), x);
}
void push_front(const T& x)
{insert(begin(), x);
}
void pop_back()
{erase(--end());
}void pop_front()
{erase(begin());
}

这里直接复用insert和erase函数实现,只是要注意尾结点的位置是end()的前一个位置。

 例子:

void test4()
{iu::list<int>l1;l1.push_back(1);l1.push_back(2);l1.push_back(3);l1.push_back(4);l1.insert(l1.begin(), 10);l1.insert(l1.begin(), 20);for (auto& e : l1){cout << e << " ";}cout << endl;l1.pop_back();l1.pop_back();l1.pop_front();l1.pop_front();for (auto& e : l1){cout << e << " ";}cout << endl;
}

结果:

2.4 整体代码

#include<assert.h>
#include<algorithm>
#include <initializer_list>namespace iu
{template<class T>struct list_node{list_node<T>* _prev;list_node<T>* _next;T _value;list_node(const T& x = T()):_prev(nullptr),_next(nullptr),_value(x){}};template<class T,class REF,class PTR>struct list_iterator{typedef list_node<T> Node;typedef list_iterator<T, REF, PTR> Self;Node* _node;list_iterator(Node* node):_node(node){}bool operator!=(const Self& it){return  _node!=it._node;}bool operator==(const Self& it){return _node == it._node;}REF operator*(){return _node->_value;}PTR operator->(){return &_node->_value;}Self& operator++(){_node = _node->_next;return *this;}Self& operator--(){_node = _node->_prev;return *this;}Self operator++(int){Self tmp(*this);_node = _node->_next;return tmp;}Self operator--(int){Self tmp(*this);_node = _node->_prev;return tmp;}};template<class T>class list{typedef list_node<T> Node;public:typedef list_iterator<T,T&,T*> iterator;typedef list_iterator<T, const T&, const T*> const_iterator;void empty_init(){_head = new Node;_head->_prev = _head;_head->_next = _head;_size = 0;}list(){empty_init();}void swap(list<T>& lt){std::swap(_head, lt._head);std::swap(_size, lt._size);}list<T>& operator=(list<T> lt){swap(lt);return *this;}list(std::initializer_list<T> lt){empty_init();for (auto& e : lt){push_back(e);}}list(const list<T>& lt)//拷贝构造{empty_init();for (auto& e : lt){push_back(e);}}~list(){clear();delete _head;_head = nullptr;}void clear(){iterator it = begin();while (it != end()){it = erase(it);}}T& front(){return _head->_next->_value;}const T& front()const{return _head->_next->_value;}T& back(){return _head->_prev->_value;}const T& back()const{return _head->_prev->_value;}size_t size(){return _size;}iterator begin(){return _head->_next;}iterator end(){return _head;}const_iterator begin() const{return _head->_next;}const_iterator end() const{return _head;}void push_back(const T& x){//Node* newnode = new Node(x);//Node* tail = _head->_prev;//newnode->_prev = tail;//tail->_next = newnode;//newnode->_next = _head;//_head->_prev = newnode;insert(end(), x);}void push_front(const T& x){insert(begin(), x);}void insert(iterator pos,const T& x){Node* newnode = new Node(x);Node* cur = pos._node;Node* prev = cur->_prev;prev->_next = newnode;newnode->_prev = prev;newnode->_next = cur;cur->_prev = newnode;++_size;}iterator erase(iterator pos){assert(pos != end());Node* del = pos._node;Node* prev = del->_prev;Node* next = del->_next;prev->_next = next;next->_prev = prev;delete del;--_size;return iterator(next);}void pop_back(){erase(--end());}void pop_front(){erase(begin());}private:Node* _head;size_t _size;};
}

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

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

相关文章

MySQL 索引

MySQL 索引 文章目录 MySQL 索引1. 索引概念2. 索引结构3. 索引分类4. 索引使用4.1 单列索引和联合索引4.2 覆盖索引4.3 前缀索引 5. SQL提示6. 索引失效情况 1. 索引概念 索引可以理解为MySQL中用来高效检索数据的数据结构&#xff0c;它是有序的&#xff0c;因为它底层使用的…

JVM方法区

一、栈、堆、方法区的交互关系 二、方法区的理解: 尽管所有的方法区在逻辑上属于堆的一部分&#xff0c;但是一些简单的实现可能不会去进行垃圾收集或者进行压缩&#xff0c;方法区可以看作是一块独立于Java堆的内存空间。 方法区(Method Area)与Java堆一样&#xff0c;是各个…

STM32 TIM定时器配置

TIM简介 TIM&#xff08;Timer&#xff09;定时器 定时器可以对输入的时钟进行计数&#xff0c;并在计数值达到设定值时触发中断 16位计数器、预分频器、自动重装寄存器的时基单元&#xff0c;在72MHz计数时钟下可以实现最大59.65s的定时 不仅具备基本的定时中断功能&#xff…

自定义数据集 使用pytorch框架实现逻辑回归并保存模型,然后保存模型后再加载模型进行预测,对预测结果计算精确度和召回率及F1分数

import numpy as np import torch import torch.nn as nn import torch.optim as optim from sklearn.metrics import precision_score, recall_score, f1_score# 数据准备 class1_points np.array([[1.9, 1.2],[1.5, 2.1],[1.9, 0.5],[1.5, 0.9],[0.9, 1.2],[1.1, 1.7],[1.4,…

< OS 有关 > 阿里云 几个小时前 使用密钥替换 SSH 密码认证后, 发现主机正在被“攻击” 分析与应对

信息来源&#xff1a; 文件&#xff1a;/var/log/auth.log 因为在 sshd_config 配置文件中&#xff0c;已经定义 LogLevel INFO 部分内容&#xff1a; 2025-01-27T18:18:55.68272708:00 jpn sshd[15891]: Received disconnect from 45.194.37.171 port 58954:11: Bye Bye […

[创业之路-270]:《向流程设计要效率》-2-企业流程架构模式 POS架构(规划、业务运营、支撑)、OES架构(业务运营、使能、支撑)

目录 一、POS架构 二、OES架构 三、POS架构与OES架构的差异 四、各自的典型示例 POS架构典型示例 OES架构典型示例 示例分析 五、各自的典型企业 POS架构典型企业 OES架构典型企业 分析 六、各自典型的流程 POS架构的典型流程 OES架构的典型流程 企业流程架构模式…

【贪心算法篇】:“贪心”之旅--算法练习题中的智慧与策略(一)

✨感谢您阅读本篇文章&#xff0c;文章内容是个人学习笔记的整理&#xff0c;如果哪里有误的话还请您指正噢✨ ✨ 个人主页&#xff1a;余辉zmh–CSDN博客 ✨ 文章所属专栏&#xff1a;贪心算法篇–CSDN博客 文章目录 一.贪心算法1.什么是贪心算法2.贪心算法的特点 二.例题1.柠…

Python 梯度下降法(二):RMSProp Optimize

文章目录 Python 梯度下降法&#xff08;二&#xff09;&#xff1a;RMSProp Optimize一、数学原理1.1 介绍1.2 公式 二、代码实现2.1 函数代码2.2 总代码 三、代码优化3.1 存在问题3.2 收敛判断3.3 函数代码3.4 总代码 四、优缺点4.1 优点4.2 缺点 五、相关链接 Python 梯度下…

【2025年更新】1000个大数据/人工智能毕设选题推荐

文章目录 前言大数据/人工智能毕设选题&#xff1a;后记 前言 正值毕业季我看到很多同学都在为自己的毕业设计发愁 Maynor在网上搜集了1000个大数据的毕设选题&#xff0c;希望对大家有帮助&#xff5e; 适合大数据毕业设计的项目&#xff0c;完全可以作为本科生当前较新的毕…

three.js+WebGL踩坑经验合集(6.2):负缩放,负定矩阵和行列式的关系(3D版本)

本篇将紧接上篇的2D版本对3D版的负缩放矩阵进行解读。 (6.1):负缩放&#xff0c;负定矩阵和行列式的关系&#xff08;2D版本&#xff09; 既然three.js对3D版的负缩放也使用行列式进行判断&#xff0c;那么&#xff0c;2D版的结论用到3D上其实是没毛病的&#xff0c;THREE.Li…

反向代理模块jmh

1 概念 1.1 反向代理概念 反向代理是指以代理服务器来接收客户端的请求&#xff0c;然后将请求转发给内部网络上的服务器&#xff0c;将从服务器上得到的结果返回给客户端&#xff0c;此时代理服务器对外表现为一个反向代理服务器。 对于客户端来说&#xff0c;反向代理就相当…

软件工程经济学-日常作业+大作业

目录 一、作业1 作业内容 解答 二、作业2 作业内容 解答 三、作业3 作业内容 解答 四、大作业 作业内容 解答 1.建立层次结构模型 (1)目标层 (2)准则层 (3)方案层 2.构造判断矩阵 (1)准则层判断矩阵 (2)方案层判断矩阵 3.层次单排序及其一致性检验 代码 …

【回溯】目标和 字母大小全排列

文章目录 494. 目标和解题思路&#xff1a;回溯784. 字母大小写全排列解题思路&#xff1a;回溯 494. 目标和 494. 目标和 给你一个非负整数数组 nums 和一个整数 target 。 向数组中的每个整数前添加 或 - &#xff0c;然后串联起所有整数&#xff0c;可以构造一个 表达式…

告别复杂,拥抱简洁:用plusDays(7)代替plus(7, ChronoUnit.DAYS)

前言 你知道吗?有时候代码里的一些小细节看起来很简单,却可能成为你调试时的大麻烦。在 Java 中,我们用 LocalDateTime 进行日期和时间的操作时,发现一个小小的替代方法可以让代码更简洁,功能更强大。这不,今天我们就来探讨如何用 LocalDateTime.now().plusDays(7) 替代…

《苍穹外卖》项目学习记录-Day10订单状态定时处理

利用Cron表达式生成器生成Cron表达式 1.处理超时订单 查询订单表把超时的订单查询出来&#xff0c;也就是订单的状态为待付款&#xff0c;下单的时间已经超过了15分钟。 //select * from orders where status ? and order_time < (当前时间 - 15分钟) 遍历集合把数据库…

【深度分析】微软全球裁员计划不影响印度地区,将继续增加当地就业机会

当微软的裁员刀锋掠过全球办公室时&#xff0c;班加罗尔的键盘声却愈发密集——这场资本迁徙背后&#xff0c;藏着数字殖民时代最锋利的生存法则。 表面是跨国公司的区域战略调整&#xff0c;实则是全球人才市场的地壳运动。微软一边在硅谷裁撤年薪20万美金的高级工程师&#x…

Linux中 端口被占用如何解决

lsof命令查找 查找被占用端口 lsof -i :端口号 #示例 lsof -i :8080 lsof -i :3306 netstat命令查找 查找被占用端口 netstat -tuln | grep 端口号 #示例 netstat -tuln | grep 3306 netstat -tuln | grep 6379 ss命令查找 查找被占用端口 ss -tunlp | grep 端口号 #示例…

qt-Quick3D笔记之官方例程Runtimeloader Example运行笔记

qt-Quick3D笔记之官方例程Runtimeloader Example运行笔记 文章目录 qt-Quick3D笔记之官方例程Runtimeloader Example运行笔记1.例程运行效果2.例程缩略图3.项目文件列表4.main.qml5.main.cpp6.CMakeLists.txt 1.例程运行效果 运行该项目需要自己准备一个模型文件 2.例程缩略图…

高性能消息队列Disruptor

定义一个事件模型 之后创建一个java类来使用这个数据模型。 /* <h1>事件模型工程类&#xff0c;用于生产事件消息</h1> */ no usages public class EventMessageFactory implements EventFactory<EventMessage> { Overridepublic EventMessage newInstance(…

Spring Boot项目如何使用MyBatis实现分页查询

写在前面&#xff1a;大家好&#xff01;我是晴空๓。如果博客中有不足或者的错误的地方欢迎在评论区或者私信我指正&#xff0c;感谢大家的不吝赐教。我的唯一博客更新地址是&#xff1a;https://ac-fun.blog.csdn.net/。非常感谢大家的支持。一起加油&#xff0c;冲鸭&#x…