目录

进程和线程的区别

const修饰指针(左边内容,右边指向)

1. const 修饰指针指向的内容(指向常量)

2. const 修饰指针本身(常量指针)

3. const 同时修饰指针本身和指向的内容(指向常量的常量指针)

一句话速答版(面试用)

编译的四个步骤

map和unordered_map的区别

底层实现

元素有序性与遍历

性能与时间复杂度

内存占用

unordered_map的深入理解

前言

unordered_map的结构

复杂度问题

哈希冲突问题

rehash(重新构建哈希表) 和负载因子


看似不起波澜的日复一日,相信总有一天会让我看到坚持的意义。

                                                                                                                        ——2025/9/2

进程和线程的区别

进程是操作系统资源分配的基本单位,而线程是CPU调度的基本单位。

资源分配与调度

  • 进程:它拥有独立的内存地址空间、文件句柄、I/O设备等资源。操作系统为每个进程分配这些资源。

  • 线程:它不拥有独立的资源,而是共享其所属进程的资源。比如,同一个进程内的所有线程都共享该进程的内存空间和文件句柄。线程是CPU调度的最小单位,也就是CPU真正执行的实体。

通信机制

进程间通信(IPC):管道、消息队列、共享内存、信号、socket 等,开销较大。

线程间通信:共享进程的内存空间,可以直接读写,但需要加锁保证同步。

适用场景

  • 多进程:适合于隔离性要求高的任务,比如浏览器中的不同标签页,或者服务器中处理不同用户请求的进程。一个标签页崩溃了,不会影响其他标签页。
     

  • 多线程:适合于需要高并发,频繁通信和共享数据的任务,比如图形界面(UI)的响应、高并发的网络服务器(如 Web 服务器中的线程池)。在服务器中,一个进程可以创建多个线程来处理不同的客户端连接,效率更高。

const修饰指针(左边内容,右边指向)

const 在修饰指针时主要有三种修饰方式,理解它们关键在于弄清楚 const 关键字修饰的是什么

👉 const 在星号左边:修饰指针所指的内容;在星号右边:修饰指针本身。

想想也对,因为 int* const p中const紧贴着p,const自然是修饰p的p又是一个指针变量,那么指针变量的值不可变,const自然修饰的是指针本身。

1. const 修饰指针指向的内容(指向常量)

在这种情况下,const 位于星号(*)的左侧,无论是紧挨着类型名还是紧挨着星号,效果都是一样的。

示例:const int *p; 或 int const *p;

int a = 10, b = 20;
const int* p = &a;
*p = 20;    // ❌ 错误
p = &b;     // ✅ 合法

含义p 是一个指向“常量整型”的指针。

特点:

  • *p 不可修改(不能通过 p 改变所指对象的值)。
  • p 本身可以修改(可以指向别的地址)。

2. const 修饰指针本身(常量指针)

含义p 是一个“常量指针”,一旦初始化,就不能再指向别的对象。

示例:int *const p = &a;

int a = 10, b = 20;
int* const p = &a;
*p = 30;    // ✅ 合法
p = &b;     // ❌ 错误

特点:

  • p 不可修改(指向固定)。
  • *p 可修改(能通过 p 改变所指对象的值)。

3. const 同时修饰指针本身和指向的内容(指向常量的常量指针)

含义p 是一个指向“常量整型”的常量指针。

示例:const int *const p = &a;

int a = 10, b = 20;
const int* const p = &a;
*p = 20;    // ❌ 错误
p = &b;     // ❌ 错误

特点:

  • p 不可修改(指针不能改变指向)。
  • *p 不可修改(指向的值也不能通过它改)。

一句话速答版(面试用)

const 修饰指针有三种情况:

  • const int* p:指向的值不能改,指针能改;
  • int* const p:指针不能改,指向的值能改;
  • const int* const p:指针和值都不能改。

编译的四个步骤

从源代码到可执行文件一般分为四步:预处理(4种处理)、编译(又可进一步分成多个阶段)、汇编(汇编代码转化成机器码)、链接(两种链接方式)。编译阶段内部又可以细分为词法分析、语法分析、语义分析、中间代码生成、优化和目标代码生成。

详细介绍请看文章:

编译过程详解,库的介绍,静态库的制作与运用,动态库的制作与运用,库中的符号冲突问题和库相互依赖问题_库文件编译-CSDN博客

关于什么时候使用静态链接什么时候用动态链接也要知道,一般涉及到系统移植建议用静态链接,可执行文件中包含了一切需要的库文件,部署打包更加方便。

map和unordered_map的区别

底层实现

map:底层通常由红黑树实现。红黑树是一种自平衡二叉查找树,它能确保在插入、删除和查找操作后,树的结构依然保持平衡。

unordered_map:底层由哈希表实现。它通过哈希函数将键(key)映射到哈希表中的一个桶(bucket)里,以实现快速访问。

元素有序性与遍历

有序性

  • map:自动按 key 排序(默认升序,可以自定义比较器)。
  • unordered_map:元素无序存储,不保证遍历顺序。

遍历

map:有序遍历,支持区间操作(比如 lower_bound(>=)、upper_bound(>))。

unordered_map:无序遍历,不支持按区间查找。

区间查找指的是在一个数据集合中,查找所有满足某个特定范围条件的元素。在 map 里,迭代器返回的位置就是“边界点”,它把元素分成了两部分
 

map 默认是 按键升序排列 的有序容器。lower_bound(key) 返回第一个 不小于(>=) key 的元素 的迭代器。

左边(begin 到返回迭代器之前):

全部 < key → 不满足 >= key 的条件。

右边(从返回迭代器到 end):

全部 >= key → 满足条件。

性能与时间复杂度

map:插入、删除、查找的平均时间复杂度都是 O(logN)

优点:对于需要稳定性能(即最坏情况下的性能也能得到保证)和有序访问的场景非常合适。

unordered_map:插入、删除、查找的平均时间复杂度是 O(1)

缺点:在最坏情况下(例如,哈希冲突严重),时间复杂度会退化到 O(N)。此外,它的性能高度依赖于哈希函数的质量和负载因子

内存占用

map:相对较省内存(树节点开销)。

unordered_map:需要哈希表 + 桶结构,内存开销更大。

unordered_map的深入理解

前言

之前我有介绍部分关于unordered_map的深入理解,可以先看一下,主要里面介绍了扩容机制,哈希冲突的解决方式(链地址法和开放地址法)

unordered_map和哈希表的使用_map自定义哈希函数-CSDN博客

在面试的时候unordered_map真的是一个非常非常高频的考点!!!所以下面我将更深入地聊一下这个问题

unordered_map的结构

unordered_map 的哈希表 + 桶结构是其实现高效查找的基石

希表可以理解为unordered_map的主干,它是一个内部的数组,这个数组里的每一个元素都叫做一个桶(Bucket)

一个桶里可能存放 0 个、1 个或多个元素。为什么会有多个?

👉 因为 哈希冲突:不同的 key 经过哈希函数后可能得到相同的下标。

所以每个桶不是只放一个元素,而是通常会用 链表 / 动态数组 来存放同一个哈希值的所有元素。
 

比如我们有 unordered_map<string,int>,桶数是 8(N=8):

Index:   0    1    2    3    4    5    6    7
Bucket: [ ]  [ ]  [A] [ ]  [B,C] [ ]  [ ]  [D]

复杂度问题

Q:为什么 unordered_map 查找是 O(1)?最坏情况为什么是 O(n)?

  • 平均情况:哈希函数分布均匀,桶内元素少,查找是 O(1)。

  • 最坏情况:所有元素都冲突到同一个桶 → 等价于链表查找 → O(n)。

哈希冲突问题

Q:哈希冲突是怎么解决的?

  • STL 实现里通常是 拉链法(separate chaining):桶里存链表/动态数组。

  • 也有一些实现用 开放寻址法(open addressing),不过 unordered_map 一般是拉链法。

为什么不用开放寻址法?

  • C++ 标准库没有强制规定必须用拉链法,但 几乎所有主流实现(GCC 的 libstdc++、Clang 的 libc++、MSVC STL)都采用拉链法

  • 原因是:

    • 拉链法更容易处理删除操作(直接删链表节点即可)。

    • 开放寻址法删除时需要“墓碑标记”,实现复杂。

    • 拉链法在装载因子不是太高时性能更稳定。

为了解决哈希冲突(不同键有相同的哈希值),每个桶通常是一个链表(在 C++11 后,如果元素过多会转换为红黑树以提高性能),当多个键被哈希到同一个桶时,它们会以链表的形式被连接起来。所以查找元素时,先通过哈希函数定位到桶,然后遍历该桶内的链表来找到目标元素。

C++11 引入的性能优化


 

哈希冲突严重的情况

当哈希函数设计得不好,或者数据本身就存在某种规律导致大量键的哈希值相同或相近时,一个桶里的链表会变得非常长。此时,对这个桶内的元素的查找,时间复杂度会从 O(1) 退化到 O(N)(其中 N 是该链表的长度)。这会严重影响 unordered_map 的性能。


 

为了解决这个问题,从 C++11 开始,标准库的实现引入了一个优化机制:

  • 当一个桶中的元素数量(即链表长度)超过一个阈值(这个阈值是编译器实现决定的,通常是 8 或 10)时,unordered_map 会自动将该桶的数据结构从链表转换为红黑树
  • 红黑树是一种自平衡的二叉查找树。
  • 这样一来,在这个桶内的查找、插入和删除操作的时间复杂度就从线性的 O(N) 降到了对数的 O(logN)。

rehash(重新构建哈希表) 和负载因子

load_factor(负载因子) = 元素个数 / 桶数

unordered_map 内部维护一个 最大负载因子(max_load_factor,默认 1.0)。

如果 load_factor > max_load_factor,容器就会自动触发 rehash。

Q:什么时候会 rehash?rehash 有什么影响?

  • 负载因子(元素数 / 桶数)超过阈值 时触发。

  • rehash 会申请更多桶,把所有元素重新分配。

  • rehash 后:所有迭代器、引用、指针失效。

rehash 的过程:

  1. 分配更多桶(通常至少翻倍)。
  2. 对所有元素重新计算哈希并分配到新的桶里。

这样做的目的:减少每个桶中的元素数量,让冲突更少。

缺点:rehash 是一个 O(n) 的操作,迭代器全部失效。

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

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

相关文章

利用棒棒糖图探索Office (US)的IMDB评分

利用棒棒糖图探索Office (US)的IMDB评分 import numpy as np import pandas as pd import matplotlib.colors as mc import matplotlib.image as image import matplotlib.pyplot as pltfrom matplotlib.cm import ScalarMappable from matplotlib.lines import Line2D from m…

Zephyr如何注册设备实例

设备树 → 编译期生成 → 运行时访问 流程图&#xff1a;Zephyr dev->config 工作流程设备树 (.dts) ───────────────────────────── anx745139 {compatible "analogix,anx7451";reg <0x39>;reset-gpios <&gpio1 5 …

Spring Boot 日志框架选择指南:Logback vs Log4j2

在 Spring Boot 应用中&#xff0c;您需要明确选择一个日志框架 - ​​不能同时使用两种日志实现​​。以下是关于 spring-boot-starter-log4j2和 spring-boot-starter-logging的全面比较和选择建议&#xff1a;核心区别特性spring-boot-starter-log4j2(Log4j2)spring-boot-sta…

Axure科技感可视化原型案例:赋能设计与研发的宝藏资源

在当今数字化浪潮中&#xff0c;数据可视化已成为企业洞察市场、优化运营、快速决策不可或缺的工具。Axure&#xff0c;作为原型设计领域的领航者&#xff0c;凭借其强大的功能和丰富的资源&#xff0c;为数据可视化大屏的设计注入了科技活力与创新元素。本文将深入探讨Axure科…

跨境电商账号风控核心:IP纯净度与浏览器指纹的防护策略

对跨境电商从业者而言&#xff0c;账号突然被封是常见却令人头痛的问题。即便严格遵守平台规则、使用代理IP&#xff0c;账号仍可能因风控策略而受限。这背后&#xff0c;IP纯净度与浏览器指纹识别是两大常被忽视却至关重要的技术因素。本文将从技术角度解析其原理&#xff0c;…

daily notes[7]

文章目录perl notereferencesperl note A hash in perl can be initialized with array,for example: my %numbers ("one", 1, "two", 2); print $fruit_color{"one"}; it is wonderful that the hash can be sliced to result in an array …

WPF迁移avalonia之图像处理(一)

从WPF迁移到avalonia中&#xff0c;对于图像处理部分&#xff0c;在WPF常用System.Windows.Drawing中图像处理元素&#xff0c;但是在开发avalonia应用时考虑跨平台特性&#xff0c;则必须有对应的跨平台替换方案。主要考虑Avalonia.Media.Imaging.Bitmap和SkiaSharp.SKBitmap …

242. 有效的字母异位词| 349. 两个数组的交集

242. 有效的字母异位词 nums [0]*26 : 这行代码创建了一个包含26个0的列表&#xff0c;这个列表通常用于计数或者作为某种映射的基础&#xff0c;比如统计字符串中每个字母出现的次数&#xff08;假设只考虑小写字母a-z&#xff09;。 ord() Python 中的一个内置函数&#x…

HTML第二课:块级元素

HTML第二课&#xff1a;块级元素块级元素块级元素 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html lang"zh-CN"> <head><meta http-equiv"Content-…

微论-突触的作用赋能思考(可能是下一代人工智能架构的启发式理论)

突触智能&#xff1a;微观结构与宏观智慧的桥梁摘要&#xff1a;传统人工智能模型&#xff0c;尤其是深度学习&#xff0c;将突触简单抽象为一个静态的权重参数&#xff0c;这极大地简化了生物计算的复杂性。本文受启发于生物突触的微观功能&#xff0c;提出了一种新的智能架构…

ARM - GPIO 标准库开发

一、STM32MP157AAA开发板套件介绍1.1 核心板 - 主板如图所示&#xff1a;主板各部分介绍1.2 IO 拓展板如图所示&#xff1a;IO拓展板各部分介绍开发板名称&#xff08;硬件平台&#xff09;&#xff1a;FS-MP1A主控制器&#xff1a;STM32MP157AAA3 Cortex-A7 * 2 Cortex-M4 -…

橙武低代码:不仅仅是云SaaS,更是云端开发+本地部署的新范式

版权归作者所有&#xff0c;转载请注明出处。 一、低代码的时代背景 在过去十年里&#xff0c;软件研发模式经历了巨大的演变。从传统的瀑布开发&#xff0c;到敏捷、DevOps&#xff0c;再到如今的低代码/无代码平台&#xff0c;研发效率和交付模式发生了根本性变化。低代码的…

神经语言学视角:脑科学与NLP深层分析技术的交叉融合

引言&#xff1a;从“统计拟合”到“类人理解”——NLP的下一个范式近年来&#xff0c;以Transformer架构为核心的大型语言模型&#xff08;LLM&#xff09;在自然语言处理&#xff08;NLP&#xff09;领域取得了前所未有的成功 。它们能够生成流畅的文本、回答复杂的问题&…

Coze源码分析-工作空间-项目查询-前端源码

前言 本文将深入分析Coze Studio项目中用户登录后进入工作空间查看和管理项目的前端实现&#xff0c;通过源码解读来理解工作空间项目开发功能的架构设计和技术实现。Coze Studio采用了现代化的React TypeScript技术栈&#xff0c;结合微前端架构和模块化设计&#xff0c;为用…

【系统架构师设计(9)】系统设计:结构化设计与面向对象设计

文章目录一、核心思想&#xff1a;模块化与对象化的设计哲学1、结构化设计的核心思想2、面向对象设计的核心思想3、两种设计方法的本质区别二、结构化设计知识点1、设计阶段2、设计原则3、 内聚类型&#xff08;从低到高&#xff09;耦合类型&#xff08;从低到高&#xff09;模…

还在从零开发AI应用?这个项目直接给你500个现成方案!!!

大家好&#xff0c;我是顾北&#xff0c;一名AI应用探索者&#xff0c;也是GitHub开源项目收集者。昨晚又在GitHub上瞎逛...咦&#xff0c;碰到了一个特别有意思的项目。说实话吧&#xff0c;作为一个天天折腾AI工具的人&#xff0c;见过的项目没有一千也有八百了&#xff0c;但…

react+taro的使用整理

前言&#xff1a; 本文主要整理下我们跨段工具taro的具体使用方法与相关资料。 taro官网&#xff1a; 安装及使用 | Taro 文档 安装&#xff1a; 全局脚手架安装&#xff1a; npm install -g tarojs/cli 使用脚手架安装我们的taro项目 taro init myApp 运行到不同小程序教…

从 “容器保姆” 到 “云原生王者”:K8s 全方位指南

目录 开头专业总结 一、先搞懂&#xff1a;K8s 到底是什么&#xff1f;能解决什么痛点&#xff1f; 1. K8s 的本质 2. 核心用处&#xff08;解决的痛点&#xff09; 二、K8s 核心知识点&#xff1a;组件与概念&#xff08;标重点&#xff01;&#xff09; &#xff08;一…

03.《交换的底层逻辑:从基础到应用》

交换基础 文章目录交换基础MAC 地址&#xff1a;设备的 “全球唯一身份证”MAC 地址的基本属性MAC 地址的三类类型&#xff08;按通信范围划分&#xff09;以太帧以太帧的两个标准格式1. Ethernet_II 格式&#xff08;常用&#xff09;2. IEEE 802.3 格式&#xff08;少用&…

火语言 RPA 界面应用生成:轻量化开发核心优势

火语言 RPA 界面应用生成功能&#xff0c;主打 “低门槛、快落地”&#xff0c;无需复杂开发环境与专业技术&#xff0c;就能快速实现需求验证与工具搭建&#xff0c;尤其适配中小团队与个人&#xff0c;核心优势如下&#xff1a;​一、1 小时搞定需求验证&#xff1a;3 步落地…