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…...
Java 8 新特性
Java 8 引入了一系列重要的新特性,极大地增强了 Java 语言的功能,尤其是在 函数式编程、流处理、日期时间 API 和 默认方法 等方面。这些新特性不仅提升了代码的可读性和简洁性,还改善了并发处理的性能。以下是 Java 8 主要新特性的详细说明。…...
知识库技术选型:主流Embedding模型特性对比
知识库技术选型:主流Embedding模型特性对比 1. 知识库与大模型结合的背景 知识库是存储和管理结构化知识的系统,广泛应用于问答系统、推荐系统和搜索引擎等领域。随着大语言模型(LLM)的发展,知识库与大模型的结合成为…...
CAN总线通信协议学习2——数据链路层之帧格式
1 帧格式 帧格式可理解为定义了传输的数据(叫报文)应该“长什么样”来传输,也为后续设定一些规则如错误检查机制提供了思路。 首先,帧格式可分为以下5种类型: PS:CAN总线任意一个设备可当收也可当发&#…...
基于ArcGIS Pro、Python、USLE、INVEST模型等多技术融合的生态系统服务构建生态安全格局高阶应用
文字目录 前言第一章、生态安全评价理论及方法介绍一、生态安全评价简介二、生态服务能力简介三、生态安全格局构建研究方法简介 第二章、平台基础一、ArcGIS Pro介绍二、Python环境配置 第三章、数据获取与清洗一、数据获取:二、数据预处理(ArcGIS Pro及…...
神经网络在电力电子与电机控制中的应用
神经网络(Neural Networks)简介 神经网络是一种受生物神经元启发的机器学习模型,能够通过大量数据学习输入与输出之间的非线性映射关系。其核心结构包括: 输入层:接收外部数据(如传感器信号、控制指令&…...
llama-factory || AutoDL平台
报错如下: rootautodl-container-d83e478b47-3def8c49:~/LLaMA-Factory# llamafactory-cli webui * Running on local URL: http://0.0.0.0:7860Could not create share link. Missing file: /root/miniconda3/lib/python3.10/site-packages/gradio/frpc_linux_am…...
数学建模:MATLAB极限学习机解决回归问题
一、简述 极限学习机是一种用于训练单隐层前馈神经网络的算法,由输入层、隐藏层、输出层组成。 基本原理: 输入层接受传入的样本数据。 在训练过程中随机生成从输入层到隐藏层的所有连接权重以及每个隐藏层神经元的偏置值,这些参数在整个…...
力扣785. 判断二分图
力扣785. 判断二分图 题目 题目解析及思路 题目要求将所有节点分成两部分,每条边的两个端点都必须在不同集合中 二分图:BFS/DFS/并查集 因为图不一定联通,所以枚举所有点都做bfs(如果没联通的话) 代码 class Solution { public:bool is…...
【硬件工程师成长】之是否需要组合电容进行滤波的考虑
在电子电路设计中,判断是否需要使用组合电容进行滤波,需综合考虑以下因素: 1. 噪声频谱分析 高频与低频噪声共存:若电源或信号中同时存在低频(如工频纹波)和高频噪声(如开关电源的开关噪声、数字…...
Pythonweb开发框架—Flask工程创建和@app.route使用详解
1.创建工程 如果pycharm是专业版,直接NewProject—>Flask 填写工程name和location后,点击右下角【create】,就会新建一个flask工程,工程里默认会建好一个templates文件夹、static文件夹、一个app.py文件 templates࿱…...
005 公网访问 docker rocketmq
文章目录 创建自定义网络创建NameServer容器创建Broker容器正式开始启动 Nameserver 容器启动 Broker 容器并关联 Nameserverdocker exec -it rmqbroker vi /etc/rocketmq/broker.conf检查 namesrv 解析检查 Broker 注册状态Nameserver 日志Broker 日志检查容器日志手动指定 Br…...
C++11中的右值引用和完美转发
C11中的右值引用和完美转发 右值引用 右值引用是 C11 引入的一种新的引用类型,用 && 表示。它主要用于区分左值和右值,并且可以实现移动语义,避免不必要的深拷贝,提高程序的性能。左值通常是可以取地址的表达式…...
txt 转 json 使用python语言
需求: 把如下的txt文档转成json输出 代码 import jsondef txt_to_json(input_file, output_file):data_list []with open(input_file, r, encodingutf-8) as f:for line in f:# 分割数据并去除换行符parts line.strip().split(,)print(f"{parts}")print(type(par…...
Android Logcat 高效调试指南
工具概览 Logcat 是 Android SDK 提供的命令行日志工具,支持灵活过滤、格式定制和实时监控,官方文档详见 Android Developer。 基础用法 命令格式 [adb] logcat [<option>] ... [<filter-spec>] ... 执行方式 直接调用(通过ADB守…...
【Linux】从入门到精通:Make与Makefile完全指南
欢迎来到 CILMY23 的博客 🏆本篇主题为:从入门到精通:Make与Makefile完全指南 🏆个人主页:CILMY23-CSDN博客 🏆系列专栏:C | C语言 | Linux | Python | 数据结构和算法 | 算法专题 …...
leetcode0014 最长公共前缀 -easy
1 题目:最长公共前缀 编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀,返回空字符串 “”。 示例 1: 输入:strs [“flower”,“flow”,“flight”] 输出:“fl” 示例 2: 输入&a…...
【星云 Orbit-F4 开发板】07. 用判断数据尾来接收据的串口通用程序框架
【星云 Orbit-F4 开发板】用判断数据尾来接收一串数据的串口通用程序框架 摘要 本文介绍了一种基于STM32F407微控制器的串口数据接收通用程序框架。该框架通过判断数据尾来实现一串数据的完整接收,适用于需要可靠数据传输的应用场景。本文从零开始,详细…...
LLVM - 编译器前端 - 将源文件转换为抽象语法树(一)
一:概述 编译器通常分为两部分——前端和后端。在本文中,我们将实现编程语言的前端部分——即主要处理源语言的部分。我们将学习现实世界编译器使用的技术,并将其应用到我们的编程语言中。 本文将从定义编程语言的语法开始,最终生成一个抽象语法树(AST),这是代码生成的基…...
02_NLP文本预处理之文本张量表示法
文本张量表示法 概念 将文本使用张量进行表示,一般将词汇表示为向量,称为词向量,再由各个词向量按顺序组成矩阵形成文本表示 例如: ["人生", "该", "如何", "起头"]># 每个词对应矩阵中的一个向量 [[1.32, 4,32, 0,32, 5.2],[3…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...
Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...
pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...
HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...
[ACTF2020 新生赛]Include 1(php://filter伪协议)
题目 做法 启动靶机,点进去 点进去 查看URL,有 ?fileflag.php说明存在文件包含,原理是php://filter 协议 当它与包含函数结合时,php://filter流会被当作php文件执行。 用php://filter加编码,能让PHP把文件内容…...
Web后端基础(基础知识)
BS架构:Browser/Server,浏览器/服务器架构模式。客户端只需要浏览器,应用程序的逻辑和数据都存储在服务端。 优点:维护方便缺点:体验一般 CS架构:Client/Server,客户端/服务器架构模式。需要单独…...
