[C++面试] 关于deque
一、入门
1、deque与vector的区别
deque的迭代器包含以下信息:
- 当前缓冲区指针(
current_buffer) - 当前元素在缓冲区内的位置(
current) - 中控器的位置(
map)
每次移动迭代器时,需检查是否跨越缓冲区边界,必要时跳转到下一个缓冲区
deque(双端队列)是C++标准库中的序列容器,支持在头部和尾部高效插入/删除元素,同时允许随机访问。
与vector的主要区别:
- 存储结构:
vector使用连续内存块,而deque由多个分段缓冲区组成,逻辑连续但物理非连续 - 操作效率:
deque在头部插入/删除时间复杂度为O(1),而vector头部操作需移动所有元素,效率为O(n) - 内存扩展:
vector扩容时需整体复制,deque仅需新增缓冲区
2、如何初始化一个deque (int 类型为例)
deque<int> d1; // 默认构造
deque<int> d2(10, 5); // 10个元素,每个为5
deque<int> d3(d2.begin(), d2.end()); // 范围复制
deque<int> d4(d3); // 拷贝构造
3、deque常用成员函数有哪些?
push_front()/push_back():头尾插入pop_front()/pop_back():头尾删除operator[]或at():随机访问size()/empty():容量查询
4、deque允许随机访问是怎么做到的?性能怎么样?
效率略低于vector。
原因:deque的随机访问需通过中控器定位到具体缓冲区,再计算元素在缓冲区内的偏移,多了一层间接寻址;而vector直接通过连续内存的基地址+偏移量访问,无需额外查找步骤。
a、确定目标缓冲区:假设每个缓冲区存储block_size个元素,则目标缓冲区在中控器中的索引为:
buffer_index = (n / block_size) + start_buffer_index;
b、确定元素在缓冲区内的偏移
element_offset = n % block_size;
c、 访问元素
value = *(中控器[buffer_index] + element_offset);
二、进阶
1、解释deque的底层实现原理(中控器的作用)
deque底层由多个固定大小的缓冲区组成,通过“中控器”(通常是一个指针数组)管理这些缓冲区的地址。
- 中控器维护各缓冲区的起始地址,使得逻辑上呈现连续空间。
- 插入元素时,若当前缓冲区已满,则分配新缓冲区并更新中控器,避免整体扩容
2、在中间位置插入元素时,deque和list的性能差异如何?为什么?
list在已知迭代器位置时,中间插入/删除时间复杂度为O(1),仅需调整指针。deque的中间插入/删除需移动元素,时间复杂度为O(n)
原因:deque需保持逻辑连续性,插入点后的元素需整体移动;而list作为双向链表无需移动数据
3、deque的迭代器失效场景有哪些?与vector有何不同?
在中间插入/删除元素:可能导致后续元素的迭代器失效(需移动元素)。vector在插入/删除元素时,所有后续迭代器均失效;而deque仅在涉及缓冲区重新分配时影响部分迭代器。
vector的所有元素存储在单个连续内存块中。当插入/删除元素时:
- 插入导致扩容:会分配更大的内存块,将旧元素整体复制到新内存,此时所有迭代器(包括首尾指针)均失效。
- 删除或中间插入:后续元素需要向前或向后移动,所有指向移动元素的迭代器(包括之后的迭代器)均失效
deque由多个固定大小的缓冲区组成,通过中控器(指针数组)管理。插入/删除时:
- 头尾插入不触发缓冲区扩容:仅修改中控器的头尾指针,其他迭代器仍有效。
- 头尾插入触发缓冲区扩容:中控器可能需要扩展(例如中控器的指针数组已满),此时所有迭代器可能失效(但实际实现会尽量避免)。
- 中间插入/删除:需移动元素,导致部分迭代器失效,但其他缓冲区的迭代器仍有效。
三、高阶
1、在实际开发中,deque适合哪些应用场景?举例说明
- 双端操作频繁的场景:如实现滑动窗口算法、任务调度队列
- 需要随机访问的队列:例如需要快速访问历史记录的撤销/重做功能(结合
push_front和随机访问) - 替代
vector的中间插入场景:若仅在两端操作,deque性能优于vector,且避免内存频繁重分配
2、为何deque在STL的stack和queue中作为默认底层容器?
- 内存效率:
deque的内存利用率高于list(无节点指针开销) - 性能平衡:
stack和queue仅需操作一端或两端,deque的O(1)头尾操作和连续内存访问特性更合适 - 历史原因:
vector曾作为stack默认容器,但deque的头部扩展能力更灵活
3、 多线程环境下使用deque需要注意什么?
- 线程安全性:C++标准库容器本身不保证线程安全,需外部同步(如互斥锁)。
- 操作原子性:例如
push_back()和pop_front()需加锁,避免竞争条件
4、如何优化deque的性能?是否支持自定义内存分配器?
- 预分配缓冲区(如通过构造函数指定初始大小)。
- 避免频繁的中间插入/删除操作。
- 自定义内存分配器:支持。可通过模板参数替换默认分配器,优化内存管理策略
相关文章:
[C++面试] 关于deque
一、入门 1、deque与vector的区别 deque的迭代器包含以下信息: 当前缓冲区指针(current_buffer)当前元素在缓冲区内的位置(current)中控器的位置(map) 每次移动迭代器时,需检查是…...
施磊老师c++(七)
STL组件 文章目录 STL组件1.整体学习内容2.vector容器3.deque和listdeque--双端队列容器list--链表容器 4.vector,deque,list对比主要内容面经问题 5.详解容器适配器--stack, queue, priority_queue容器适配器stack-栈queue-队列priority_queue-优先级队列总结 6.无序关联容器关…...
八股文——C 语言宏、`volatile`、`static`、动态内存管理、堆与栈的区别
文章目录 1. #(字符串化操作符)作用:示例: 2. ##(符号连接操作符)作用:示例1:动态生成变量名 3. volatile 关键字作用:示例: 4. static 关键字作用࿱…...
C++初阶——类和对象(三) 构造函数、析构函数
C初阶——类和对象(三) 上期内容,我们围绕类对象模型的大小计算,成员存储方式,this指针,以及C实现栈和C语言的比较,进一步认识了C的封装特性。本期内容,我们开始介绍类的默认成员函…...
【Function】使用托管身份调用Function App触发器,以增强安全性
推荐超级课程: 本地离线DeepSeek AI方案部署实战教程【完全版】Docker快速入门到精通Kubernetes入门到大师通关课AWS云服务快速入门实战目录 1. 背景介绍2. 设置3. 使用Web应用调用Function App触发器(Node.js示例)4. 执行结果此方法允许您使用托管身份(Managed Identity)调…...
x012-MSP430F249智能步进电动百叶窗_proteus_光敏电阻_步进电机_仿真
https://www.dong-blog.fun/post/1997 46 、智能步进电动百叶窗 基本要求: 用一台步进电机控制百叶窗叶片的旋转(正转/反转) 用 LED 数码管显示旋转角度 设置按键: 手动/自动切换、手动正转和手动反转,停止/启动键 用一…...
牛客周赛85 题解 Java ABCDEFG
A小紫的均势博弈 判断输入的 n 是奇数还是偶数 import java.io.*; import java.math.*; import java.util.*;public class Main {static IoScanner sc new IoScanner();static final int mod(int) (1e97);static void solve() throws IOException {int nsc.nextInt();if(n%2…...
# RAG 框架 # 一文入门 全链路RAG系统构建与优化 —— 架构、策略与实践
本文全面阐述了RAG系统从数据收集、数据清洗(包括领域专有名词处理)、智能数据分块与QA对生成,到向量化、向量数据库选择与配置,再到检索方式及重排序,直至整合输出、监控反馈和安全保障的全流程。通过这一完整方案&am…...
【Golang】第二弹-----变量、基本数据类型、标识符
笔上得来终觉浅,绝知此事要躬行 🔥 个人主页:星云爱编程 🔥 所属专栏:Golang 🌷追光的人,终会万丈光芒 🎉欢迎大家点赞👍评论📝收藏⭐文章 目录 一、变量 1.1基本介绍…...
c#:使用Modbus RTU协议
Modbus是一种广泛应用于工业自动化领域的通信协议,支持多种传输方式,如RTU、TCP等。其中,Modbus RTU是一种基于串行通信的协议,具有高效、可靠的特点。本文将详细介绍Modbus RTU协议的基本原理,并重点解析功能码0x03&a…...
linux系统CentOS 7版本搭建NFS共享存储
一、什么是NFS共享存储方式 NFS共享存储方式 是一种分布式文件系统协议,允许客户端通过网络访问远程服务器上的文件,就像访问本地文件一样。 二、 NFS的基本概念 (1)服务器端:提供共享存储的机器,负责导…...
Matlab 基于SVPWM的VF三电平逆变器异步电机速度控制
1、内容简介 略 Matlab 167-基于SVPWM的VF三电平逆变器异步电机速度控制 可以交流、咨询、答疑 2、内容说明 略 3、仿真分析 略 4、参考论文 略...
Android Dagger2 框架依赖图构建模块深度剖析(三)
一、引言 在 Android 开发中,依赖注入(Dependency Injection,简称 DI)是一种重要的设计模式,它能够降低代码的耦合度,提高代码的可测试性和可维护性。Dagger 2 作为一款高效的依赖注入框架,在编…...
(一)微服务初见之 Spring Cloud 介绍
微服务架构简介 从单体应用架构发展到SOA架构,再到微服务架构,应用架构经历了多年的不断演进。微服务架构不是凭空产生的,而是技术发展的必然结果,分布式云平台的应用环境使得微服务代替单体应用成为互联网大型系统的架构选择。目…...
python--面试题--基础题
join() 和 split() 函数 join() 函数可以将指定的字符添加到字符串中。 a[my, name, shi, wzngz] print(..join(a)) 输出结果:my.name.shi.wzngz split() 函数可以用指定的字符分割字符串 a"my name shi wzngz " print(a.split()) 输出结果ÿ…...
架构思维:软件建模与架构设计的关键要点
文章目录 1. 软件建模的核心概念2. 七种常用UML图及其应用场景类图时序图组件图部署图用例图状态图活动图 3. 软件设计文档的三阶段结构4. 架构设计的关键实践1. 用例图:核心功能模块2. 部署图:架构演进阶段3. 技术挑战与解决方案4. 关键架构图示例5. 架…...
【RNN神经网络】序列模型与RNN神经网络
前言 清库存。正式切入大模型后,打算把基础知识都梳理一遍,然后写了两篇就发现写不动了,后面就捡重要的记录。RNN知识仅此一篇记录,扫盲记录。 【自然语言处理】 (Natural Language Processing,NLP…...
Python文件管理
目录 一、文本文件读写 1、相关函数 2、读写文件 3、使用readline读取一行 4、读写文件的异常处理 5、添加内容 二、文本文件的编码 1、常见的编码 2、Python程序的编码 3、指定编码 三、文件的路径 1、相对路径 2、绝对路径 3、路径的改变 四、文件夹操作 五、…...
vue3 前端路由权限控制与字典数据缓存实践(附Demo)
目录 前言1. 基本知识2. Demo3. 实战 前言 🤟 找工作,来万码优才:👉 #小程序://万码优才/r6rqmzDaXpYkJZF 从实战中出发: 1. 基本知识 Vue3 和 Java 通信时如何进行字典数据管理 需要了解字典数据的结构。通常&#x…...
基于javaweb的SpringBoot精美物流管理系统设计与实现(源码+文档+部署讲解)
技术范围:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论…...
【极光 Orbit·STC8x】05. GPIO库函数驱动LED流动
【极光 OrbitSTC8】05. GPIO库函数驱动LED流动 七律 逐光流转 八灯列阵若星河,状态为舟渡长波。 寄存器中藏玄机,Switch语句定山河。 循环往复如潮涌,步骤变量掌沉浮。 单片机前展锋芒,代码织就光之舞。 摘要 本文基于STC8H8K6…...
DeepSeek进阶应用(二):结合Kimi制作PPT(双AI协作教程)
🌟引言: DeepSeek作为国产AI大模型,以强大的逻辑推理和结构化内容生成能力著称,擅长根据用户需求生成PPT大纲或Markdown文本;Kimi的PPT助手则能解析结构化内容并套用模板快速生成美观的PPT,两者结合实现“内…...
【Aioredis实战总结】Aioredis简介
一、Aioredis简介 Aioredis 是一个基于Python asyncio框架的异步Redis客户端库,专为高并发场景设计。它允许开发者在不阻塞主线程的情况下执行Redis操作,显著提升I/O密集型任务(如Web应用的缓存、实时消息队列等)的性能。自4.2.0…...
SpringBoot——Maven篇
Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的工具。它具有许多特性,其中一些重要的特性包括: 1. 自动配置:Spring Boot 提供了自动配置的机制,可以根据应用程序的依赖和环境自动配置应用程序的各种组件ÿ…...
Python中的多态与Java、C#、C++中的多态的区别有哪些?
Python中的多态与Java、C#、C等静态类型语言的主要区别体现在以下几个方面: 1. 类型系统与多态实现方式 Python(动态类型,鸭子类型) 多态基于对象的行为(方法的存在性),而非继承或接口。只要对…...
卷积神经网络(知识点)
一、为了使特征图变小: 由两种方法:1.增大步长:卷积的时候不是一次一步,而是一次多步,类似一张图片,在原来的像素基础上,每隔一个取一个像素点。 其中S就是步长 注意:扩大步长不经…...
Vision Transformer (ViT):将Transformer带入计算机视觉的革命性尝试(代码实现)
Vision Transformer (ViT):将Transformer带入计算机视觉的革命性尝试 作为一名深度学习研究者,如果你对自然语言处理(NLP)领域的Transformer架构了如指掌,那么你一定不会对它在序列建模中的强大能力感到陌生。然而&am…...
特殊 IP 地址
文章目录 特殊IP地址概述受限广播地址(Limited Broadcast Address)直接广播地址(Directed Broadcast Address)多播地址(Multicast Address)环回地址(Loopback Address)本网络本主机&…...
数学——A. K-divisible Sum + D. Exam in MAC
A. K-divisible Sum 题目: 思路: 以下 “[xxx]” 符号均代表向上取整 我们假设总和是sum,那么就有sum k * cnt 要想最大值最小,肯定是要让sum尽可能小,这样每个元素都能变小 最小情况是 sum 恰好等于 n 时&#…...
30天学习Java第五天——数组 字符串
数组 一维数组 定义 int[] anArray;int anOtherArray[];初始化int anOtherArray[] new int[] {1, 2, 3, 4, 5}; 访问 anArray[0] 10;可变数组:void varargsMethod(String... varargs) {} 该方法可以接收任意数量的字符串参数,可以是 0 个或者 N 个…...
