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

【C++】vector(下):vector类的模拟实现(含迭代器失效问题)

文章目录

  • 前言
  • 一、vector类的常用接口的模拟实现
    • 1.头文件(my vector.h)整体框架
    • 2.模拟实现vector类对象的常见构造
    • 3.模拟实现vector iterator
    • 4.模拟实现vector类对象的容量操作
    • 5.模拟实现vector类对象的访问
    • 6.模拟实现vector类对象的修改操作
  • 二、vector 迭代器失效问题


前言

vector类的常用接口的模拟实现 以及 vector 迭代器失效问题。配套博客: 【C++】vector(上):vector的常用接口介绍


一、vector类的常用接口的模拟实现

1.头文件(my vector.h)整体框架

#include <algorithm>
#include <assert.h>
namespace zh
{template<class T>class vector{public:// Vector的迭代器可以直接用指针封装typedef T* iterator;typedef const T* const_iterator;// construct and destroy //vector();vector(int n, const T& value = T());template<class InputIterator>vector(InputIterator first, InputIterator last);vector(const vector<T>& v);vector<T>& operator= (vector<T> v); // 赋值运算符重载~vector(); // 析构函数// iterator //iterator begin();iterator end();const_iterator begin() const;const_iterator end() const;// capacity //size_t size() const;size_t capacity() const;void reserve(size_t n);void resize(size_t n, const T& value = T());// access //T& operator[](size_t pos);const T& operator[](size_t pos)const;// modify //void push_back(const T& x);void pop_back();iterator insert(iterator pos, const T& x);iterator erase(iterator pos);void swap(vector<T>& v);private:iterator _start = nullptr; // 指向有效数据的开始iterator _finish = nullptr; // 指向有效数据的尾部iterator _end_storage = nullptr; // 指向存储容量的尾部};
}

2.模拟实现vector类对象的常见构造

template<class T>
class vector
{
public:vector() // 默认构造函数{}vector(int n, const T& value = T()) // 构造并初始化n个val{_start = new T[n];_finish = _end_storage = _start + n;while (n--){_start[n] = value;}}template<class InputIterator>vector(InputIterator first, InputIterator last) // 使用迭代器进行初始化构造{auto it = first;while (it != last){push_back(*it++);}}vector(const vector<T>& v) // 拷贝构造{if (v._start != nullptr){_start = new T[v.capacity()];_finish = _start + v.size();_end_storage = _start + v.capacity();auto it1 = begin();auto it2 = v.begin();while (it2 != v.end()){*it1++ = *it2++;}}}vector<T>& operator= (vector<T> v) // 赋值运算符重载{swap(v);return *this;}~vector() // 析构函数{if (_start != nullptr){delete[] _start;_start = _finish = _end_storage = nullptr;}}
private:iterator _start = nullptr; // 指向有效数据的开始iterator _finish = nullptr; // 指向有效数据的尾部iterator _end_storage = nullptr; // 指向存储容量的尾部
};

3.模拟实现vector iterator

template<class T>
class vector
{
public:typedef T* iterator;typedef const T* const_iterator;iterator begin(){return _start;}iterator end(){return _finish;}const_iterator begin() const{return _start;}const_iterator end() const{return _finish;}
private:iterator _start = nullptr; // 指向有效数据的开始iterator _finish = nullptr; // 指向有效数据的尾部iterator _end_storage = nullptr; // 指向存储容量的尾部
};

4.模拟实现vector类对象的容量操作

template<class T>
class vector
{
public:size_t size() const{return _finish - _start;}size_t capacity() const{return _end_storage - _start;}void reserve(size_t n){if (n > capacity()){iterator tmp = new T[n];auto it = _start;int i = 0;while (it != _finish){tmp[i++] = *it;it++;}delete[] _start;_start = tmp;_finish = tmp + i;_end_storage = tmp + n;}}void resize(size_t n, const T& value = T()){if (n <= size()){_finish -= size() - n;}else{if (n > capacity()){size_t newcap = 2 * capacity();if (n > newcap)newcap = n;reserve(newcap);}size_t i = size();_finish += n - size();while (i < size()){_start[i++] = value;}}}
private:iterator _start = nullptr; // 指向有效数据的开始iterator _finish = nullptr; // 指向有效数据的尾部iterator _end_storage = nullptr; // 指向存储容量的尾部
};

5.模拟实现vector类对象的访问

template<class T>
class vector
{
public:T& operator[](size_t pos){assert(pos < size());return _start[pos];}const T& operator[](size_t pos)const{assert(pos < size());return _start[pos];}private:iterator _start = nullptr; // 指向有效数据的开始iterator _finish = nullptr; // 指向有效数据的尾部iterator _end_storage = nullptr; // 指向存储容量的尾部
};

6.模拟实现vector类对象的修改操作

template<class T>
class vector
{
public:void push_back(const T& x) // 在末尾插入一个元素{if (size() == capacity()){size_t n = capacity() == 0 ? 4 : 2 * capacity();reserve(n);}_start[size()] = x;_finish++;}void pop_back() // 删除末尾元素{assert(size() > 0);_finish--;}iterator insert(iterator pos, const T& x) // 在迭代器 pos 位置插入元素 x{assert(pos >= _start && pos <= _finish);if (size() == capacity()){size_t newcap = capacity() == 0 ? 4 : 2 * capacity();size_t n = pos - _start;reserve(newcap);pos = _start + n;}auto it = _finish;while (pos < it){*it = *(it - 1);it--;}*pos = x;_finish++;return pos;}iterator erase(iterator pos) // 删除迭代器 pos 指向的元素{assert(pos >= _start && pos < _finish);auto it = pos;while (it < _finish - 1){*it = *(it + 1);it++;}_finish--;return pos;}void swap(vector<T>& v) // 交换两个vector对象的内容{std::swap(_start, v._start);std::swap(_finish, v._finish);std::swap(_end_storage, v._end_storage);}
private:iterator _start = nullptr; // 指向有效数据的开始iterator _finish = nullptr; // 指向有效数据的尾部iterator _end_storage = nullptr; // 指向存储容量的尾部
};

二、vector 迭代器失效问题

迭代器的主要作用就是让算法能够不用关心底层数据结构,其底层实际就是一个指针,或者是对指针进行了封装,比如:vector的迭代器就可以使用原生态指针T* 。因此迭代器失效,实际是指 vector 进行某些修改操作后,原有的迭代器(或指针、引用)指向的内存地址可能变得无效,继续使用这些迭代器会导致未定义行为(如程序崩溃、数据错误)。 比如:迭代器底层对应指针所指向的空间被销毁了(扩容等行为导致底层空间改变),而使用一块已经被释放的空间,造成的后果是程序崩溃(即如果继续使用已经失效的迭代器,程序可能会崩溃)。

对于vector可能会导致其迭代器失效的操作有:

  1. 会引起其底层空间改变的操作(插入、赋值 和 修改容量),都有可能会导致迭代器失效,比如:resize、push_back、insert、assign 和 reserve等。
#include <iostream>
#include <vector>
using namespace std;
int main()
{vector<int> v{ 1,2,3,4,5,6 }; // 由调试结果(下图)可知:size == capacity = 6auto it = v.begin();// 头插一个元素,因为size == capacity,所以该操作会引起扩容v.insert(v.begin(), 0);// resize的作用是增加有效元素个数,操作期间可能会引起扩容// v.resize(50, 8);// reserve的作用是扩充容量但不改变有效元素个数,操作期间可能会引起扩容// v.reserve(50);// 插入元素期间,可能会引起扩容,而导致原空间被释放// v.push_back(8);// 给vector重新赋值,可能会引起扩容// v.assign(50, 8);while (it != v.end()){cout << *it << " ";++it;} cout << endl;return 0;
}

在这里插入图片描述
在这里插入图片描述
出错原因:以上操作,都有可能会导致vector扩容,也就是说vector底层原理旧空间被释放掉,而在打印时,it还使用的是释放之间的旧空间,在对it迭代器操作时,实际操作的是一块已经被释放的空间,而引起代码运行时崩溃。

解决方式:在以上操作完成之后,如果想要继续通过迭代器操作vector中的元素,只需给it重新赋值即可。
如下:

#include <iostream>
#include <vector>
using namespace std;
int main()
{vector<int> v{ 1,2,3,4,5,6 };auto it = v.begin();// insert的返回值:若插入单个元素,返回值指向新插入的该元素;//                若插入多个元素或区间,则指向第一个新插入的元素。it = v.insert(v.begin(), 0);// 即使插入导致内存重新分配,返回的迭代器仍有效(直接指向新内存位置)。while (it != v.end()){cout << *it << " ";++it;} cout << endl;return 0;
}

在这里插入图片描述

  1. 指定位置元素的删除操作(erase)

示例一(erase删除元素后,被删除位置之后的迭代器失效(元素前移)):

#include <iostream>
#include <vector>
using namespace std;
int main()
{vector<int> v = { 10, 20, 30, 40 };auto it = v.begin(); // 指向10auto it1 = v.begin() + 1;  // 指向20auto it2 = v.begin() + 2;  // 指向30v.erase(it1);  // 删除20,vector变为{10,30,40}cout << *it2; // 删除元素后,被删除位置之后的迭代器失效(元素前移)return 0;
}

在这里插入图片描述

示例二(删除元素后,被删除位置的迭代器也失效(元素前移)):

int main()
{vector<int> v = { 10, 20, 30, 40 };auto it = v.begin(); // 指向10auto it1 = v.begin() + 1;  // 指向20auto it2 = v.begin() + 2;  // 指向30v.erase(it1);  // 删除20,vector变为{10,30,40}cout << *it1; // 删除元素后,被删除位置的迭代器也失效(元素前移)return 0;
}

在这里插入图片描述
解决方式:在以上操作完成之后,如果想要继续通过迭代器it1操作vector中的元素,只需给it1重新赋值即可,如下:

int main()
{vector<int> v = { 10, 20, 30, 40 };auto it = v.begin(); // 指向10auto it1 = v.begin() + 1;  // 指向20auto it2 = v.begin() + 2;  // 指向30// erase的返回值是指向被删除元素之后第一个有效元素的迭代器// 删除元素后,被删元素及其之后的所有迭代器都会失效,但返回值是新的有效迭代器it1 = v.erase(it1);  // 删除20,vector变为{10,30,40}cout << *it1;return 0;
}

在这里插入图片描述

示例三(删除元素后,被删除位置之前的迭代器能正常使用):

int main()
{vector<int> v = { 10, 20, 30, 40 };auto it = v.begin(); // 指向10auto it1 = v.begin() + 1;  // 指向20auto it2 = v.begin() + 2;  // 指向30v.erase(it1);  // 删除20,vector变为{10,30,40}cout << *it; // 删除元素后,被删除位置之前的迭代器能正常使用return 0;
}

在这里插入图片描述

一、导致迭代器失效的典型场景总结

  1. 插入元素(push_back, insertresize等)

    • 当插入导致vector容量不足时,会重新分配内存,所有迭代器、指针、引用都会失效
    • 即使容量足够,插入位置及其之后的迭代器也会失效(元素被后移)。
  2. 扩充容量(reserve等) 和 重新赋值(assign等)

    • 任何导致内存重新分配的操作都会使所有迭代器失效
  3. 删除元素(erase, pop_back等)

    • 被删除元素及其之后的所有迭代器、指针、引用会失效(元素前移)
    • 被删除元素之前的迭代器、指针、引用仍然保持有效

二、如何减少迭代器失效?

  1. 插入/删除后更新迭代器
    • eraseinsert会返回新的有效迭代器:
vector<int> v{ 1,2,3,4,5,6 }; 	
auto it = v.begin(); 	
it = v.insert(v.begin(), 0); // 使用返回的新迭代器 	
it = v.erase(it); // 使用返回的新迭代器  
  1. 预留足够容量
    • 使用reserve()预先分配足够内存,减少重新分配次数:
std::vector<int> v;    
v.reserve(100);  // 预分配足够内存空间   
  1. 避免保存旧迭代器
    • 修改操作后,不要继续使用旧的迭代器、指针或引用。

总结表格

操作类型失效范围解决方案
插入导致扩容所有迭代器重新获取所有迭代器
插入未扩容插入位置及其之后的迭代器更新插入位置后的迭代器
reserve扩容 和 用assign重新赋值所有迭代器重新获取所有迭代器
删除元素被删位置及其之后的迭代器使用erase返回的新迭代器

相关文章:

【C++】vector(下):vector类的模拟实现(含迭代器失效问题)

文章目录 前言一、vector类的常用接口的模拟实现1.头文件&#xff08;my vector.h&#xff09;整体框架2.模拟实现vector类对象的常见构造3.模拟实现vector iterator4.模拟实现vector类对象的容量操作5.模拟实现vector类对象的访问6.模拟实现vector类对象的修改操作 二、vector…...

NLTK和jieba

NLTK与jieba概述 自然语言处理&#xff08;NLP&#xff09;领域是计算机科学领域与人工智能领域中的一个重要方向&#xff0c;主要研究方向是实现人与计算机之间用自然语言进行有效通信的各种理论和方法。 在自然语言处理领域中&#xff0c;文本类型的数据占据着很大的市场&a…...

Java后端高频面经——计算机网络

TCP/IP四层模型&#xff1f;输入一个网址后发生了什么&#xff0c;以百度为例&#xff1f;&#xff08;美团&#xff09; &#xff08;1&#xff09;四层模型 应用层&#xff1a;支持 HTTP、SMTP 等最终用户进程传输层&#xff1a;处理主机到主机的通信&#xff08;TCP、UDP&am…...

CSDN博客:Markdown编辑语法教程总结教程(中)

❤个人主页&#xff1a;折枝寄北的博客 Markdown编辑语法教程总结 前言1. 列表1.1 无序列表1.2 有序列表1.3 待办事项列表1.4 自定义列表 2. 图片2.1 直接插入图片2.2 插入带尺寸的图片2.3 插入宽度确定&#xff0c;高度等比例的图片2.4 插入高度确定宽度等比例的图片2.5 插入居…...

Springboot redis bitMap实现用户签到以及统计,保姆级教程

项目架构&#xff0c;这是作为demo展示使用&#xff1a; Redis config&#xff1a; package com.zy.config;import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.Ob…...

AI Agent系列(一) - Agent概述

AI Agent系列【一】 前言一、AI代理的特点二、 AI Agent的技术框架三、 开源自主代理 前言 AI Agent&#xff0c;即人工智能代理&#xff0c;一般直接叫做智能体 百度百科给AI Agent定义为&#xff1a; “以大语言模型为大脑驱动的系统&#xff0c;具备自主理解、感知、规划、…...

Scala 中trait的线性化规则(Linearization Rule)和 super 的调用行为

在 Scala 中&#xff0c;特质&#xff08;Trait&#xff09;是一种强大的工具&#xff0c;用于实现代码的复用和组合。当一个类混入&#xff08;with&#xff09;多个特质时&#xff0c;可能会出现方法冲突的情况。为了解决这种冲突&#xff0c;Scala 引入了最右优先原则&#…...

【Linux系统编程】初识系统编程

目录 一、什么是系统编程1. 系统编程的定义2. 系统编程的特点3. 系统编程的应用领域4. 系统编程的核心概念5. 系统编程的工具和技术 二、操作系统四大基本功能1. 进程管理&#xff08;Process Management&#xff09;2. 内存管理&#xff08;Memory Management&#xff09;3. 文…...

Unsloth - 动态 4 bit 量化

文章目录 &#x1f494; 量化可能会破坏模型&#x1f999; Llama 3.2 Vision 细节Pixtral (12B) 视觉&#x1f999; Llama 3.2 (90B) 视觉指令 本文翻译自&#xff1a;Unsloth - Dynamic 4-bit Quantization &#xff08;2024年12月4日 Daniel & Michael https://unsloth.…...

技术领域,有许多优秀的博客和网站

在技术领域&#xff0c;有许多优秀的博客和网站为开发者、工程师和技术爱好者提供了丰富的学习资源和行业动态。以下是一些常用的技术博客和网站&#xff0c;涵盖了编程、软件开发、数据科学、人工智能、网络安全等多个领域&#xff1a; 1. 综合技术博客 1.1 Medium 网址: ht…...

黑金风格人像静物户外旅拍Lr调色教程,手机滤镜PS+Lightroom预设下载!

调色教程 针对人像、静物以及户外旅拍照片&#xff0c;运用 Lightroom 软件进行风格化调色工作。旨在通过软件中的多种工具&#xff0c;如基本参数调整、HSL&#xff08;色相、饱和度、明亮度&#xff09;调整、曲线工具等改变照片原本的色彩、明度、对比度等属性&#xff0c;将…...

Manus 与鸿蒙 Next 深度融合:构建下一代空间计算生态

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 https://www.captainbed.cn/north 文章目录 一、技术融合背景与意义1.1 技术栈协同优势1.2 典型应用场景 二、系统架构设计2.1 整体架构图…...

并查集模板

注意理解路径压缩 static class UnionFind {int[] fa;public UnionFind(int n) {fa new int[n];for (int i 0; i < n; i) {fa[i] i;}}public int find(int i) {if (fa[i] ! i) {fa[i] find(fa[i]);}return fa[i];}public void union(int i, int j) {int fai find(i);in…...

推流项目的ffmpeg配置和流程重点总结一下

ffmpeg的初始化配置&#xff0c;在合成工作都是根据这个ffmpeg的配置来做的&#xff0c;是和成ts流还是flv&#xff0c;是推动远端还是保存到本地&#xff0c; FFmpeg 的核心数据结构&#xff0c;负责协调编码、封装和写入操作。它相当于推流的“总指挥”。 先来看一下ffmpeg的…...

使用 Python 开发的简单招聘信息采集系统

以下是一个使用 Python 开发的简单招聘信息采集系统,它包含用户登录、招聘信息收集和前后端交互的基本功能。我们将使用 Flask 作为后端框架,HTML 作为前端页面。 项目结构 recruitment_system/ ├── app.py ├── templates/ │ ├── login.html │ ├── index…...

Selenium库打开指定端口(9222、9333等)浏览器【已解决!!!】

就是在写动态爬虫爬取数据的过程中&#xff0c;如果用selenium的话&#xff0c;有一个缺点&#xff0c;就是当我们去测试一个网站能不能爬取&#xff0c;它都会重新换端口打开一个浏览器&#xff0c;不会使用上一次使用的浏览器&#xff0c;在实际使用过程中这样调试很烦&#…...

Android MVI架构模式详解

MVI概念 MVI&#xff08;Model-View-Intent&#xff09;是一种Android应用架构模式&#xff0c;旨在通过单向数据流和不可变性来简化应用的状态管理。MVI的核心思想是将用户操作、状态更新和界面渲染分离&#xff0c;确保应用的状态可预测且易于调试。 MVI的核心组件 Model&a…...

低代码开发直聘管理系统

低代码 DeepSeek 组合的方式开发直聘管理系统&#xff0c;兼职是开挂的存在。整个管理后台系统 小程序端接口的输出&#xff0c;只花了两个星期不到。 一、技术栈 后端&#xff1a;SpringBoot mybatis MySQL Redis 前端&#xff1a;Vue elementui 二、整体效果 三、表结…...

LVGL开发说明

准备工作 LVGL图形化工具&#xff1a;Gui-Guider-Setup-1.8.0-GA.exeLVGL库&#xff1a;lvgl-release-v8.3屏幕触摸驱动&#xff1a;CST816屏幕驱动&#xff1a;ST7789屏幕尺寸&#xff1a;320 * 170 触发事件 按键的点击事件 添加点击事件 触摸屏点击对应的按键后就会触发回…...

推荐优秀的开源软件合集

在信息化高度发达的今天&#xff0c;数据安全与远程协作变得越来越重要。很多企业和个人都在寻找可替代商业闭源软件的开源解决方案。今天&#xff0c;我们向大家推荐几款优秀的开源软件&#xff0c;涵盖私有云存储、远程桌面、团队协作、内容管理等多个领域。 1. Nextcloud —…...

代码随想录刷题day41|(二叉树篇)二叉树的最大深度(递归)

目录 一、二叉树理论基础 二、二叉树的深度和高度 三、递归和迭代思路 3.1 递归法 3.2 迭代法 四、相关算法题目 五、总结 一、二叉树理论基础 详见&#xff1a;代码随想录刷题day34|&#xff08;二叉树篇&#xff09;二叉树的递归遍历-CSDN博客 二、二叉树的深度和高…...

向量内积(点乘)和外积(叉乘)

文章目录 1. 向量的内积&#xff08;点积&#xff09;1.1 定义1.2 几何意义表征两个向量的投影关系计算向量夹角的余弦值 1.3 重要性质1.4 应用场景 2. 向量的外积&#xff08;叉积&#xff09;2.1 定义&#xff08;仅适用于三维空间&#xff09;2.2 几何意义2.3 重要性质2.4 应…...

PDF转JPG(并去除多余的白边)

首先&#xff0c;手动下载一个软件&#xff08;poppler for Windows&#xff09;&#xff0c;下载地址&#xff1a;https://github.com/oschwartz10612/poppler-windows/releases/tag/v24.08.0-0 否则会出现以下错误&#xff1a; PDFInfoNotInstalledError: Unable to get pag…...

【无人机路径规划】基于麻雀搜索算法(SSA)的无人机路径规划(Matlab)

效果一览 代码获取私信博主基于麻雀搜索算法&#xff08;SSA&#xff09;的无人机路径规划&#xff08;Matlab&#xff09; 一、算法背景与核心思想 麻雀搜索算法&#xff08;Sparrow Search Algorithm, SSA&#xff09;是一种受麻雀群体觅食行为启发的元启发式算法&#xff0…...

2020CVPR-SiamBAN:用于视觉跟踪的Siamese框自适应网络

原文标题&#xff1a;Siamese Box Adaptive Network for Visual Tracking 中文标题&#xff1a;用于视觉跟踪的Siamese框自适应网络 代码地址&#xff1a; GitHub - hqucv/siamban: Siamese Box Adaptive Network for Visual Tracking Abstract 大多数现有的跟踪器通常依靠多尺…...

带你从入门到精通——自然语言处理(五. 自注意力机制和transformer的输入部分)

建议先阅读我之前的博客&#xff0c;掌握一定的自然语言处理前置知识后再阅读本文&#xff0c;链接如下&#xff1a; 带你从入门到精通——自然语言处理&#xff08;一. 文本的基本预处理方法和张量表示&#xff09;-CSDN博客 带你从入门到精通——自然语言处理&#xff08;二…...

MySql自动安装脚本

一、脚本安装流程 1. 添加MySQL的Repository 使用wget命令从MySQL官方网站下载Yum Repository的RPM包。使用rpm -ivh命令安装下载的RPM包&#xff0c;以添加MySQL的Yum Repository。 2. 安装mysql-community-server 使用yum install -y mysql-community-server --nogpgchec…...

3.9【Q】csd

在计算机存储领域&#xff0c;CSD是什么&#xff1f; 基于CXL™-Type3 实现内存池化 CPU访问内存的瓶颈是什么&#xff1f;具体矛盾是什么&#xff1f; 计算型存储-2&#xff1a;标准、API实现 NUMA是什么&#xff1f;详细解释一下它的核心思想&#xff1f;...

Qt常用控件之表格QTableWidget

表格QTableWidget QTableWidget 是一个表格控件&#xff0c;行和列交汇形成的每个单元格&#xff0c;是一个 QTableWidgetItem 对象。 1. QTableWidget属性 QTableWidget 的属性只有两个&#xff1a; 属性说明rowCount当前行的个数。columnCount当前列的个数。 2. QTableW…...

数据库批处理

数据库批处理是一种处理数据的方法&#xff0c;通常用于对大量数据进行一次性操作。批处理可以有效地减少数据库操作的次数&#xff0c;提高数据处理的效率。在数据库中&#xff0c;批处理通常通过编写批处理脚本或使用相应的工具来实现。 一般情况下&#xff0c;数据库批处理…...

Flask 框架简介

Flask 框架简介 Flask 框架简介 Flask 框架简介 Flask 是一个 Python 微型网页开发框架。微型指明了 Flash 的核心是轻量级的&#xff0c;但是可以灵活扩展。下面的简单的例子要和一个数据库系统交互。Django附带了与最常见的数据库交互所需的库。另一方面&#xff0c;Flask允…...

KMP 算法的 C 语言实现

# include <stdio.h> # include <stdlib.h> # include <string.h>// 打印 KMP 匹配结果. void ColorPrint(char *T, int *result, int result_size, int m) {int green_size strlen("\x1b[31m");int reset_size strlen("\x1b[0m");cha…...

深入理解 TCP 协议:可靠传输、连接管理与经典面试题解析

TCP&#xff08;Transmission Control Protocol&#xff09;是互联网中最重要的传输层协议之一&#xff0c;其设计目标是提供可靠的、面向连接的、全双工的数据传输服务。本文将从核心机制、工作原理到经典面试题&#xff0c;全面解析 TCP 协议的关键特性。 一、TCP 核心特性 …...

雪花算法

雪花算法&#xff08;Snowflake&#xff09; 雪花算法是一种由Twitter开源的分布式ID生成算法&#xff0c;广泛应用于分布式系统中&#xff0c;用于生成全局唯一的ID。这些ID不仅具有唯一性&#xff0c;还按照时间顺序递增&#xff0c;便于排序和查询。以下是雪花算法的详细解…...

coding ability 展开第二幕(双指针——巩固篇)超详细!!!!

文章目录 前言有效的三角形个数思路 查找总价格为目标值的两个商品思路 两数之和思路 三数之和思路 四数之和思路 总结 前言 本专栏的上篇&#xff0c;讲述了双指针的一些基础的算法习题 今天我们来学习更进一步的双指针用法吧 其实也是大相径庭&#xff0c;和前面的差不多&…...

系统安全阶段练习真题(高软44)

系列文章目录 系统安全阶段练习真题 文章目录 系列文章目录前言一、真题总结 前言 本节就是系统安全的阶段练习真题&#xff0c;带答案与解析。 一、真题 总结 就是高软笔记&#xff0c;大佬请略过&#xff01;...

Mybatis Generator 使用手册

第一章 什么是Mybatis Generator&#xff1f; MyBatis Generator Core – Introduction to MyBatis Generator MyBatis生成器&#xff08;MBG&#xff09;是MyBatis框架的代码生成工具。它支持为所有版本的MyBatis生成代码&#xff0c;通过解析数据库表&#xff08;或多个表&…...

Android中AIDL和HIDL的区别

在Android中&#xff0c;AIDL&#xff08;Android Interface Definition Language&#xff09; 和 HIDL&#xff08;HAL Interface Definition Language&#xff09; 是两种用于定义跨进程通信接口的语言。AIDL 是 Android 系统最早支持的 IPC&#xff08;进程间通信&#xff0…...

Gazebo 启动时候配置物体

1. 准备模型 mkdir -p ~/.gazebo/models/table echo export GAZEBO_MODEL_PATH$HOME/.gazebo/models:$GAZEBO_MODEL_PATH >> ~/.bashrc source ~/.bashrc # 从https://github.com/osrf/gazebo_models下载模型 # 桌子 cd ~/.gazebo/models/table wget https://raw.github…...

展示深拷贝与移动语义的对比

定义 Buffer 类&#xff08;含深拷贝和移动语义&#xff09; #include <iostream> #include <chrono> #include <cstring>class Buffer { public:// 默认构造函数&#xff08;分配内存&#xff09;explicit Buffer(size_t size) : size_(size), data_(new in…...

STM32基础教程——对射式红外传感器计数实验

前言 对射式红外传感器介绍 对射式红外传感器是一种非接触式的距离检测器&#xff0c;主要由发射器和接收器两部分组成。发射器发出特定波长的红外光束&#xff0c;当物体阻挡了这条光束时&#xff0c;接收器无法接收到光线信号&#xff0c;从而产生一个开关信号来判断物体的存…...

Git与GitHub:理解两者差异及其关系

目录 Git与GitHub&#xff1a;理解两者差异及其关系Git&#xff1a;分布式版本控制系统概述主要特点 GitHub&#xff1a;基于Web的托管服务概述主要特点 Git和GitHub如何互补关系现代开发工作流 结论 Git与GitHub&#xff1a;理解两者差异及其关系 Git&#xff1a;分布式版本控…...

【时时三省】(C语言基础)赋值语句2

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ----CSDN 时时三省 赋值运算符 赋值符号“”就是赋值运算符&#xff0c;它的作用是将一个数据赋给一个变量。如a 3的作用是执行一次赋值操作&#xff08;或称赋值运算&#xff09;。把常量3赋给变量a。也可以…...

服务器上通过ollama部署deepseek

2025年1月下旬&#xff0c;DeepSeek的R1模型发布后的一周内就火了&#xff0c;性能比肩OpenAI的o1模型&#xff0c;且训练成本仅为560万美元&#xff0c;成本远低于openAI&#xff0c;使得英伟达股票大跌。 下面我们来看下如何个人如何部署deepseek-r1模型。 我是用的仙宫云的…...

自动控制原理【知识点总结、复习笔记】

1.控制系统定义 控制系统是指通过监测和调整系统的行为&#xff0c;以达到预期目标的一套系统。它由一组相互关联的组件组成&#xff0c;这些组件协同工作&#xff0c;用于控制物理过程、机械设备、电子设备或其他系统。例如&#xff0c;一个简单的温控系统可以通过监测房间温…...

【AI】什么是Embedding向量模型?我们应该如何选择?

我们之前讲的搭建本地知识库,基本都是使用检索增强生成(RAG)技术来搭建,Embedding模型则是RAG的核心,同时也是大模型落地必不可少的技术。那么今天我们就来聊聊Embedding向量模型: 一、Embedding模型是什么? Embedding模型是一种将离散数据(如文本、图像、用户行为等)…...

openwrt路由系统------Linux 驱动开发的核心步骤

以下是 Linux 驱动开发的核心步骤,结合实践案例与注意事项,适合嵌入式设备(如 OpenWrt 路由器)开发: 一、驱动开发基本流程 1. 环境准备 工具链与内核源码 # 安装交叉编译工具链(如 ARM) sudo apt-get install gcc-arm-linux-gnueabihf# 获取目标内核源码(需匹配运行的…...

Educational Codeforces Round 7 F. The Sum of the k-th Powers 多项式、拉格朗日插值

题目链接 题目大意 求 ( ∑ i 1 n i k ) (\sum_{i1}^{n} i^k) (∑i1n​ik) m o d ( 1 0 9 7 ) mod(10^97) mod(1097) . 数据范围 &#xff1a; 1 ≤ n ≤ 1 0 9 1 \leq n \leq 10^9 1≤n≤109 , 0 ≤ k ≤ 1 0 6 0 \leq k \leq 10^6 0≤k≤106 . 思路 令 f ( n ) ∑ …...

学习笔记:利用OpenAI实现阅卷智能体

https://zhuanlan.zhihu.com/p/18047953492 ### 学习笔记&#xff1a;利用OpenAI实现阅卷智能体 #### 一、背景与需求 在各类考试中&#xff0c;选择题、判断题、填空题的阅卷相对简单&#xff0c;只需对比答案与作答是否一致。然而&#xff0c;简答题的阅卷较为复杂&#xff…...

进程的简要介绍

一.进程 1.概念&#xff1a;担当分配系统资源的实体 2.进程内核数据结构对象自己的代码和数据 或进程PCB(task_struct)自己的代码和数据 注1&#xff1a;PCB&#xff1a;操作系统中描述进程的结构体 2.进程的所有属性均可在task_struct中找到&#xff0c;管理进程其实就是…...