vector 面试点总结
ps:部分内容使用“AI”查询
一、入门
1、什么是vector
动态数组容器,支持自动扩容、随机访问和连续内存存储。
2、怎么创建-初始化vector
std::vector<int> v; // 创建空vectorstd::vector<int> v = {1, 2, 3}; // 直接初始化std::vector<int> v(5, 0); // 指定大小和值(5个0)
3、访问方式
operator[](无边界检查): int v = vec[6];at()(有边界检查): vec.at(6) = 8;
4、size()和capacity()的区别?
size():当前元素数量。—— 实际的(比如下课时间,班里只有10个人)capacity():当前分配的内存可容纳的元素数量(capacity >= size)—— resize改变的是capacity(比如下课时间,班里只有10个人,但是班级里座位能容纳50个学生)
5、vector 在堆上
二、进阶
1、扩容机制
当size == capacity时,容器会分配一块更大的连续内存块,新容量通常是当前容量的 1.5~2倍(具体倍数因实现而异,例如 GCC 默认采用 1.5 倍,而 MSVC 常用 2 倍)。
容器将旧内存中的所有元素 复制 或 移动 到新内存中。
- 复制:适用于不支持移动语义的类型(如
std::array)。- 移动:适用于支持移动语义的类型(如
std::string、自定义类),可避免深拷贝开销释放:旧内存被释放,容器内部指针更新为新内存地址
均摊时间复杂度:push_back 的均摊时间复杂度为 O(1),但每次扩容操作需 O(n)时间(n 为当前元素数量)。若频繁触发扩容(如循环中不断 push_back),总时间复杂度可能退化为 O(n²),显著影响性能
代价: 时间复杂度O(n),可能影响性能
2、如何避免频繁扩容
使用reserve(n)预分配内存
3、迭代器失效的场景
vector内存布局:[1, 2, 3, 4, 5]- 迭代器
it指向元素2 - 元素
2被删除,后续元素3,4,5前移填补空缺。vector内存布局变为:[1, 3, 4, 5]。it迭代器失效(指向原位置2,但该位置已被覆盖)。erase()返回新迭代器new_it,指向原it的下一个元素3
// 正确更新迭代器例子
it = vec.erase(it); // it 现在指向 3
插入/删除元素(尤其是非尾部操作)可能导致迭代器失效。
比如:扩容时,会导致复制 或 移动 内容到新内存中,同时释放原始内存,容器内部指针更新为新内存地址 。原有迭代器指向的旧内存空间被释放,导致迭代器失效。
std::vector<int> vec = {1,2,3};
auto it = vec.begin(); // 指向1
vec.insert(it, 0); // 可能扩容,it失效
删除元素时,后续元素会向前移动填补空位,导致被删除元素及其后的迭代器失效
在中间或开头插入/删除元素时,操作点之后的所有迭代器均失效
解决方法:
- a、重新获取迭代器或使用范围for循环
b、insert和erase等函数返回指向新有效位置的迭代器,可直接更新迭代器
it = vec.insert(it, 0); // 插入后返回新迭代器
it = vec.erase(it); // 删除后返回下一个有效迭代器
- c、范围
for循环(推荐)
// 此方法仅适用于删除第一个符合条件的元素。若需删除多个元素,必须采用其他方法(如erase-remove惯用法或反向遍历
for (auto& elem : vec) {if (elem % 2 == 0) {vec.erase(std::find(vec.begin(), vec.end(), elem));break; // 循环迭代器未再被使用,避免了后续可能的失效访问。}
}
- d、反向遍历:从后向前删除元素,避免影响未遍历的迭代器。
std::vector<int> vec = {1, 2, 3, 4, 5};
for (auto rit = vec.rbegin(); rit != vec.rend(); ) {if (*rit % 2 == 0) {rit = decltype(rit)(vec.erase(std::next(rit).base()));} else {++rit;}
}
// 反向迭代器遍历:通过rbegin()和rend()获取反向迭代器范围,实现从末尾向开头的遍历
// std::next(it).base()将反向迭代器转换为对应的正向迭代器(指向当前元素的前一个元素)
// 调用vec.erase()删除该元素,并返回下一个有效正向迭代器
反向迭代器rit初始化为vec.rbegin()(指向5)
rit指向4(偶数),执行vec.erase(std::next(rit).base())
4被删除,5前移填补空缺
rit更新为vec.rend()(循环结束)
- e、 erase-remove
std::remove将待删除元素移到容器末尾,并返回新逻辑末尾的迭代器;erase根据该迭代器真正删除元素。
remove_if标记待删除元素,将不需要删除的元素移到vector前端,返回“新逻辑末尾”迭代器new_end。通过
new_end和vec.end()范围删除剩余元素
std::vector<int> vec = {1, 2, 3, 4, 5};
auto new_end = std::remove_if(vec.begin(), vec.end(), [](int n) {return n % 2 == 0; // 删除偶数
});
vec.erase(new_end, vec.end()); // 删除 2,4
4、push_back与emplace_back的区别
push_back与emplace_back的区别主要体现在对象构造方式和性能效率上
push_back:需要先构造一个完整的对象(临时对象或已有对象),再通过拷贝/移动构造函数将其添加到容器中emplace_back:直接在容器的内存空间中调用对象的构造函数,无需临时对象,避免拷贝/移动
性能差异
- 简单类型(如int):两者性能几乎无差异,因为int的构造/拷贝成本极低
- 自定义复杂类型:emplace_back通过避免临时对象和拷贝操作,显著提升性能
struct Complex { Complex(int, double); }; // 高成本构造函数 vec.emplace_back(42, 3.14); // 直接构造,效率高 vec.push_back(Complex(42, 3.14)); // 需先构造临时对象再拷贝
5、vector<bool> 使用的是bit,不能取地址
三、高阶
1、如何快速释放vector的内存?
shrink_to_fit(); //请求容量等于大小(非强制)std::vector<int>(vec).swap(vec); // 强制释放多余内存
shrink_to_fit() 的实现与效果(内存地址改变,原容器的迭代器、指针、引用可能失效)
目标:释放 vector 未使用的内存(即 capacity > size 的部分),使 capacity 尽可能接近 size。
- 创建临时容器:生成一个空的临时
vector,使用与原容器相同的分配器。 - 预分配精确内存:临时容器调用
reserve(size),使其容量恰好等于原容器的当前元素数量(size)。 - 复制元素:将原容器的所有元素复制到临时容器中。
- 内存交换:通过
swap交换两个容器的内部指针(指向数据内存、size和capacity的指针)。 - 销毁临时容器:临时容器析构时,释放原容器之前占用的多余内存。
std::vector<int>(vec).swap(vec) 的实现与效果
目标:通过构造临时对象并交换内存,强制将 capacity 缩减到 size。
- 构造临时对象:
std::vector<int>(vec)调用复制构造函数,生成一个临时vector。**新容器的capacity等于原容器的size**(因为复制构造函数仅复制元素,不保留多余容量) - 交换内存:通过
swap(vec)交换临时容器与原容器的内部指针。 - 销毁临时对象:临时对象析构时,释放原容器的旧内存(此时临时对象持有原容器的旧内存)。
- 结果:原容器的
capacity变为临时对象的size,即精确匹配当前元素数量。

2、vector与list的核心差异?
vector支持O(1)随机访问,插入/删除非尾部元素代价高;
list插入/删除任意位置高效,无法随机访问
3、移动语义在vector中的应用?
std::vector<std::string> v1 = {"a", "b"};
std::vector<std::string> v2 = std::move(v1); // v1变为空,v2接管资源
4、自定义分配器如何与vector结合?
通过模板参数指定分配器类型
std::vector<int, MyAllocator<int>> v; // 使用自定义分配器
5、vector里面的内存 总是连续的吗?
std::vector 的内存布局始终是连续的。std::deque 虽支持高效随机访问,但其内存布局为分段连续(通过多个独立块实现)
相关文章:
vector 面试点总结
ps:部分内容使用“AI”查询 一、入门 1、什么是vector 动态数组容器,支持自动扩容、随机访问和连续内存存储。 2、怎么创建-初始化vector std::vector<int> v; // 创建空vectorstd::vector<int> v {1, 2, 3}; // 直接初始化std::vec…...
正式页面开发-登录注册页面
整体路由设计: 登录和注册的切换是切换组件或者是切换内容(v-if和 v-else),因为点击两个之间路径是没有变化的。也就是登录和注册共用同一个路由。登录是独立的一级路由。登录之后进到首页,有三个大模块:文章分类&…...
Spring项目-抽奖系统(实操项目-用户管理接口)(END)
^__^ (oo)\______ (__)\ )\/\ ||----w | || || 一:前言: 活动创建及展示博客链接:Spring项目-抽奖系统(实操项目-用户管理接口)(THREE)-CSDN博客 上一次完成了活动的创建和活动的展示,接下来就是重头戏—…...
Kafka面试题及原理
1. 消息可靠性(不丢失) 使用Kafka在消息的收发过程都会出现消息丢失,Kafka分别给出了解决方案 生产者发送消息到Brocker丢失消息在Brocker中存储丢失消费者从Brocker 幂等方案:【分布式锁、数据库锁(悲观锁、乐观锁…...
Jenkinsfile流水线构建教程
前言 Jenkins 是目前使用非常广泛的自动化流程的执行工具, 我们目前的一些自动化编译, 自动化测试都允许在 Jenkins 上面. 在 Jenkins 的术语里面, 一些自动化工作联合起来称之为流水线, 比如拉取代码, 编译, 运行自动化测试等. 本文的主要目的是引导你快速熟悉 Jenkinsfile …...
CSS—text文本、font字体、列表list、表格table、表单input、下拉菜单select
目录 1.文本 2.字体 3.列表list a.无序列表 b.有序列表 c.定义列表 4.表格table a.内容 b.合并单元格 3.表单input a.input标签 b.单选框 c.上传文件 4.下拉菜单 1.文本 属性描述color设置文本颜色。direction指定文本的方向 / 书写方向。letter-spacing设置字符…...
API接口:企业名称、注册号、统一社会信用代码、企业类型、成立日期和法定代表人等数据 API 接口使用指南
API接口:企业名称、注册号、统一社会信用代码、企业类型、成立日期和法定代表人等数据 API 接口使用指南 本文详细介绍一种基于 Web 搜索方式实现的企业信息查询接口,适用于数据补全、企业资质验证、信息查询等场景。文章内容涵盖接口功能、请求参数、返…...
在.net中,async/await的理解
一、什么是同步?什么是异步? 在.net中,async 和 await 是两个关键字,async 关键字用于声明一个方法是异步方法,该方法可以包含一个或多个 await 表达式。await 关键字是用于在异步方法中等待一个任务(Task…...
水果识别系统 | BP神经网络水果识别系统,含GUI界面(Matlab)
使用说明 代码下载:BP神经网络水果识别系统,含GUI界面(Matlab) BP神经网络水果识别系统 一、引言 1.1、研究背景及意义 在当今科技迅速发展的背景下,人工智能技术尤其是在图像识别领域的应用日益广泛。水果识别作为…...
40岁开始学Java:Java中单例模式(Singleton Pattern),适用场景有哪些?
在Java中,单例模式(Singleton Pattern)用于确保一个类只有一个实例,并提供全局访问点。以下是详细的实现方式、适用场景及注意事项: 一、单例模式的实现方式 1. 饿汉式(Eager Initialization) …...
李宏毅机器学习课程学习笔记04 | 浅谈机器学习-宝可梦、数码宝贝分类器
文章目录 案例:宝可梦、数码宝贝分类器第一步:需要定义一个含有未知数的function第二步:loss of a function如何Sample Training Examples > 如何抽样可以得到一个较好的结果如何权衡模型的复杂程度 Tradeoff of Model Complexity todo 这…...
C++11中的右值引用和完美转发
C11中的右值引用和完美转发 右值引用 右值引用是 C11 引入的一种新的引用类型,用 && 表示。它主要用于区分左值和右值,并且可以实现移动语义,避免不必要的深拷贝,提高程序的性能。左值通常是可以取地址的表达式…...
Redis详解(实战 + 面试)
目录 Redis 是单线程的!为什么 Redis-Key(操作redis的key命令) String 扩展字符串操作命令 数字增长命令 字符串范围range命令 设置过期时间命令 批量设置值 string设置对象,但最好使用hash来存储对象 组合命令getset,先get然后在set Hash hash命令: h…...
ISP CIE-XYZ色彩空间
1. 颜色匹配实验 1931年,CIE综合了前人实验数据,统一采用700nm(红)、546.1nm(绿)、435.8nm(蓝)作为标准三原色波长,绘制了色彩匹配函数,如下图。选定这些波…...
【强化学习笔记1】从强化学习的基本概念到近端策略优化(PPO)
好久没有更新了。最近想学习一下强化学习,本系列是李宏毅老师强化学习的课程笔记。 1. Policy-based Model 1.1 Actor 在policy-based model中,主要的目的就是训练一个actor。 对于一个episode(例如,玩一局游戏)&…...
Deepseek对ChatGPT的冲击?
从测试工程师的视角来看,DeepSeek对ChatGPT的冲击主要体现在**测试场景的垂直化需求与通用模型局限性之间的博弈**。以下从技术适配性、效率优化、风险控制及未来趋势四个维度展开分析: --- ### **一、技术适配性:垂直领域能力决定工具选择…...
STM32中的ADC
目录 一:什么是ADC 二:ADC的用途 三:STM32F103ZET6的ADC 3.1ADC对应的引脚 3.2ADC时钟 3.3ADC的工作模式 编辑3.4ADC校准 3.5ADC转换结构和实际电压的换算 四:ADC配置步骤 五:两个重要的函数 一:…...
开启AI短剧新纪元!SkyReels-V1/A1双剑合璧!昆仑万维开源首个面向AI短剧的视频生成模型
论文链接:https://arxiv.org/abs/2502.10841 项目链接:https://skyworkai.github.io/skyreels-a1.github.io/ Demo链接:https://www.skyreels.ai/ 开源地址:https://github.com/SkyworkAI/SkyReels-A1 https://github.com/Skywork…...
【uniapp】在UniApp中实现持久化存储:安卓--生成写入数据为jsontxt
在移动应用开发中,数据存储是一个至关重要的环节。对于使用UniApp开发的Android应用来说,缓存(Cache)是一种常见的数据存储方式,它能够提高应用的性能和用户体验。然而,缓存数据在用户清除缓存或清除应用数…...
大白话React第十一章React 相关的高级特性以及在实际项目中的应用优化
假设我们已经对 React 前端框架的性能和可扩展性评估有了一定了解,接下来的阶段可以深入学习 React 相关的高级特性以及在实际项目中的应用优化,以下是详细介绍及代码示例: 1. React 高级特性的深入学习 1.1 React 并发模式(Con…...
java容器 LIst、set、Map
Java容器中的List、Set、Map是核心数据结构,各自适用于不同的场景 一、List(有序、可重复) List接口代表有序集合,允许元素重复和通过索引访问,主要实现类包括: ArrayList 底层结构:动态数组…...
使用IDEA如何隐藏文件或文件夹
选择file -> settings 选择Editor -> File Types ->Ignored Files and Folders (忽略文件和目录) 点击号就可以指定想要隐藏的文件或文件夹...
DOM HTML:深入理解与高效运用
DOM HTML:深入理解与高效运用 引言 随着互联网的飞速发展,前端技术逐渐成为软件开发中的关键部分。DOM(文档对象模型)和HTML(超文本标记语言)是前端开发中的基石。本文将深入探讨DOM和HTML的概念、特性以及在实际开发中的应用,帮助读者更好地理解和使用这两项技术。 …...
形象生动讲解Linux 虚拟化 I/O
用现实生活的比喻和简单例子来解释 Linux 虚拟化 I/O,就像给朋友讲故事一样。 虚拟化 I/O 要解决什么问题? 想象你有一栋大房子(物理服务器),想把它分割成多个小公寓(虚拟机)出租。每个租客&…...
git从零学起
从事了多年java开发,一直在用svn进行版本控制,如今更换了公司,使用的是git进行版本控制,所以打算记录一下git学习的点滴,和大家一起分享。 百度百科: Git(读音为/gɪt/)是一个开源…...
汽车低频发射天线介绍
汽车低频PKE天线是基于RFID技术的深度研究及产品开发应用的一种天线,在汽车的智能系统中发挥着重要作用,以下是关于它的详细介绍: 移动管家PKE低频天线结构与原理 结构:产品一般由一个高Q值磁棒天线和一个高压电容组成ÿ…...
【Java分布式】Nacos注册中心
Nacos注册中心 SpringCloudAlibaba 也推出了一个名为 Nacos 的注册中心,相比 Eureka 功能更加丰富,在国内受欢迎程度较高。 官网:https://nacos.io/zh-cn/ 集群 Nacos就将同一机房内的实例划分为一个集群,一个服务可以包含多个集…...
【C++】ImGui:极简化的立即模式GUI开发
如果你是GUI开发的新手,或想试试轻量级、易集成的GUI库,ImGui(即时模式图形用户界面)是个不错的选择。它以简洁的API、跨平台的兼容性和卓越的性能,受到许多开发者的喜爱。无论是为C项目添加调试界面,还是构…...
5G学习笔记之BWP
我们只会经历一种人生,我们选择的人生。 参考:《5G NR标准》、《5G无线系统指南:如微见著,赋能数字化时代》 目录 1. 概述2. BWP频域位置3. 初始与专用BWP4. 默认BWP5. 切换BWP 1. 概述 在LTE的设计中,默认所有终端均能处理最大2…...
1. 搭建前端+后端开发框架
1. 说明 本篇博客主要介绍网页开发中,搭建前端和后端开发框架的具体步骤,框架中所使用的技术栈如下: 前端:VUE Javascript 后端:Python Flask Mysql 其中MySQL主要用来存储需要的数据,在本文中搭建基本…...
