C++细节知识for面试

1. linux上C++程序可用的栈和堆大小分别是多少,为什么栈大小小于堆?

1. 栈(Stack)大小

栈默认为8MB,可修改。

为什么是这个大小

  • 安全性:限制栈大小可防止无限递归或过深的函数调用导致内存耗尽。
  • 多线程优化:每个线程的栈独立,较小的默认值避免内存浪费(线程数多时,总内存消耗可能激增)。

2. 堆(Heap)大小

  • 默认限制

    • 堆的大小受限于系统的虚拟内存地址空间物理内存+交换空间(Swap)​
    • 在64位系统上,理论最大值为 ​128 TB​(Linux内核默认配置),实际受物理资源和进程地址空间限制。
    • 在32位系统上,通常最大为 ​3 GB​(受限于用户空间地址范围)。
  • 为什么是这个大小

  • 动态分配灵活性:堆用于动态内存分配,需支持程序运行时按需扩展。
  • 操作系统虚拟内存管理:64位系统地址空间极大,但实际分配取决于物理内存和Swap。

2. 构造函数和析构函数可以声明为inline吗,为什么?

1. 语法可行性

  • 可以声明为 inline:C++标准允许构造函数和析构函数声明为 inline

  • 隐式 inline:在类定义内部直接实现的构造函数和析构函数,默认会被编译器视为 inline,无需显式声明。

  • 显式 inline:在类外定义时,需显式添加 inline 关键字。

2. 最佳实践

  1. 优先隐式 inline:在类定义内直接实现简单的构造函数/析构函数。
  2. 避免复杂逻辑:若构造/析构函数涉及动态内存、虚函数或异常,避免内联。

总结

  • 可以声明为 inline:语法支持且对简单场景有效。
  • 需谨慎使用:复杂逻辑或涉及虚函数时,内联可能适得其反。
  • 依赖编译器决策:最终是否内联由编译器优化策略决定。

3. 函数作用域结束后,变量的析构,是有谁来进行的?

在 C++ 中,​函数作用域结束后,变量的析构是由编译器自动插入的代码触发的

编译器如何实现自动析构?

  1. 代码插入:编译器在作用域结束处(如 } 前)插入析构函数调用。
  2. 异常安全:即使作用域因异常提前退出,编译器仍会插入析构代码(利用栈展开机制)。
  3. 逆序析构:保证对象按创建的逆序析构,避免依赖问题。

4. struct和class的区别?

struct 和 class 的内存对齐规则是完全相同的,唯一的区别在于默认的访问控制权限(struct 默认 publicclass 默认 private)。

5. atomic, mutex底层实现?

1. std::atomic 的底层实现

std::atomic 用于实现无锁(lock-free)或低竞争(low-contention)的原子操作,其性能远高于互斥锁。

​**(1) 硬件支持**
  • 原子指令:直接使用 CPU 提供的原子指令,例如:
    • x86 架构LOCK 前缀指令(如 LOCK CMPXCHG 实现 CAS)。
    • ARM 架构LDREX/STREX 指令(Load-Exclusive/Store-Exclusive)。
  • 内存屏障(Memory Barriers)​:保证内存操作的顺序性,例如 std::memory_order 相关的屏障指令。

2. std::mutex 的底层实现

std::mutex 是互斥锁,用于保护临界区,其实现依赖操作系统内核的调度。

​**(1) Linux 实现(基于 pthread_mutex_t)​**
  • 轻量级锁(Futex)​:快速用户空间互斥锁(Fast Userspace Mutex)。
    • 无竞争时:完全在用户空间通过原子操作(如 CAS)完成加锁/解锁。
    • 有竞争时:通过系统调用(futex_waitfutex_wake)挂起或唤醒线程。
  • 锁类型
    • 普通锁(PTHREAD_MUTEX_DEFAULT)​:可能死锁,无错误检查。
    • 递归锁:允许同一线程多次加锁。
    • 自适应锁:在竞争激烈时退化为内核态锁。

3. 对比与选择

特性std::atomicstd::mutex
实现基础硬件原子指令 + 可能的锁模拟操作系统内核机制(Futex/CRITICAL_SECTION)
性能无锁时极快(纳秒级)无竞争时快(约 20-50 ns),有竞争时较慢
适用场景简单原子操作(计数器、标志位)复杂临界区(需保护多步操作)
内存开销通常较小(与数据类型对齐)较大(需存储锁状态和等待队列)
线程阻塞无(自旋或原子操作)可能阻塞(进入内核等待)

6. 线程的挂起和执行在用户态还是内核态?

1. 两种情况

  • 内核级线程:挂起和执行由内核态管理,是现代操作系统的默认选择(如Linux的pthread)。
  • 协程:完全在用户态实现,适用于高并发但需结合多线程利用多核。

2. 内核级线程(Kernel-Level Threads, KLT)​

  • 管理方式:由操作系统内核直接支持,每个线程是内核调度的基本单位(如Linux的pthread)。
  • 挂起与执行
    • 内核态操作:线程的创建、销毁、调度(挂起/恢复)需通过系统调用,由内核完成。
    • 内核感知:内核直接管理线程状态(就绪、运行、阻塞等)。
  • 优点
    • 并行性:线程可分配到不同CPU核心并行执行。
    • 阻塞隔离:一个线程阻塞不会影响同一进程内其他线程。
  • 缺点
    • 切换开销大(需切换到内核态)。
    • 线程数量受内核限制。

3. 协程(Coroutine)——用户态的轻量级并发

  • 管理方式:完全在用户态由程序或运行时库(如Golang的goroutine)控制。
  • 挂起与执行
    • 用户态切换:协程主动让出(yield)或恢复(resume),不依赖内核调度。
    • 非抢占式:协程需显式让出CPU,通常与事件循环(如epoll)配合。
  • 适用场景:高并发I/O密集型任务(如网络服务器)。

7. 谈一谈new/delete和malloc/free的区别和联系?

1. 核心区别

特性new/delete (C++ 运算符)malloc/free (C 标准库函数)
语法与类型安全是运算符,无需类型转换(自动匹配类型)是函数,需显式类型转换(返回 void*
构造函数/析构函数调用构造函数(new)和析构函数(delete不调用构造函数/析构函数
内存大小计算自动根据类型计算内存大小(如 new int需手动计算(如 malloc(sizeof(int)*n)
异常处理失败时抛出 std::bad_alloc 异常失败时返回 NULL(需手动检查)
内存来源自由存储区(free store)​分配堆(heap)​分配
重载支持可重载类的 operator new/delete不可重载
内存对齐自动满足类型的对齐要求需手动处理对齐(如 aligned_alloc
多态支持支持(通过虚析构函数正确释放派生类对象)不支持(需手动管理派生类内存)
扩展功能支持 placement new(在指定内存构造对象)不支持
与 C++ 特性结合兼容智能指针(如 std::unique_ptr需额外封装才能安全使用

8. 解决内存泄漏?

**(1) 使用 Valgrind 检测泄露**
valgrind --leak-check=full --show-leak-kinds=all ./your_program
  • 输出示例
    ==12345== 40 bytes in 1 blocks are definitely lost in loss record 1 of 1
    ==12345==    by 0x123456: main (main.c:10)
**(2) 分析代码**

定位到泄露位置后,检查以下常见原因:

  • 忘记释放内存malloc/new 未配对 free/delete
  • 异常路径未释放:如 return 或 throw 前未释放资源。
  • 循环引用​(智能指针):std::shared_ptr 循环引用导致无法自动释放。
​**(3) 修复并验证**
  • 修复代码:添加释放逻辑或使用 RAII(如 std::unique_ptr)。
  • 重新测试:重复步骤 1 确保泄露消失

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

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

相关文章

数据设计(范式、步骤)

文章目录 数据设计1.数据库设计的三大范式2、数据库设计的具体步骤 数据设计 1.数据库设计的三大范式 关系型数据库的三大范式,指导如何设计一个关系型数据库。 1NF: 关系表的每个字段,都应该是不可再分的,——保证原子性。 字…

PhotoShop学习03

1.更改图像大小 通常情况下,如果我们想在某些上传图片,会发现我们的图片可能会过大或者过小,为此,我们需要调整图像的大小,使之符合网站的规则。 首先打开photoshop,打开一张图片。首先我们需要了解这张图…

Vue 项目中使用$refs来访问组件实例或 DOM 元素,有哪些注意事项?

大白话Vue 项目中使用$refs来访问组件实例或 DOM 元素,有哪些注意事项? 在 Vue 项目里,$refs 是个超实用的工具,它能让你直接访问组件实例或者 DOM 元素。不过使用的时候,有一些地方可得注意,下面咱就详细…

【安全运营】关于攻击面管理相关概念的梳理(二)

CYNC(持续可见性和网络控制) CYNC(Continuous Visibility and Network Control)即“持续可见性和网络控制”,是一个与网络安全和IT运营管理相关的概念。它强调的是在一个组织的数字环境中,确保对所有资产、…

【区块链安全 | 第二篇】区块链概念详解

文章目录 概述1. 区块链类型2 区块链五层架构3 账本模型4. 节点(Node)5. 区块(Block)6. 区块链(Blockchain)7. 区块链工作流程 核心技术1. 共识机制2. 智能合约 主要组件1. 交易(Transaction&am…

Redisson - 分布式锁和同步器

文章目录 锁(Lock)公平锁(Fair Lock)联锁(MultiLock)红锁(RedLock) 【已废弃】读写锁(ReadWriteLock)信号量(Semaphore)可过期许可信号…

HarmonyOS:GridObjectSortComponent(两个Grid之间网格元素交换)

一、概述 网格对象的编辑排序是用于网格对象的编辑、拖动排序、新增和删除。 说明 该组件从API Version 11开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 二、导入模块 import { GridObjectSortComponent, GridObjectSortComponentItem…

RFID技术在机器人中的核心应用场景及技术实现

一、机器人定位与导航 1. 地标定位系统 实现方式: 在环境关键点部署无源RFID标签(如UHF Tag),机器人携带读写器通过读取标签ID实现绝对定位# 伪代码:RFID地标定位 def get_robot_position():detected_tags = reader.read_tags()known_positions = {tag1: (x1,y1), tag2: …

uv 命令用conda命令解释

uv:安装 | uv-zh-cn 功能 | uv-zh-cn #showkey -a 可看按键的"\eOP"转义序列是啥# 绑定快捷键 f1 到 source .venv/bin/activate函数 bind "\eOP": "source .venv/bin/activate " #conda activate# 绑定快捷键 f2 到uv add函数 …

《探秘SQL的BETWEEN:解锁数据范围查询的深度奥秘》

在数据的广袤宇宙中,结构化查询语言(SQL)宛如一座精密的导航系统,引导我们穿越数据的浩瀚星河,精准定位所需信息。其中,BETWEEN作为SQL的关键工具之一,以其独特的能力,在数据的海洋里…

大型语言模型的秘密:思考链长度与提示格式的魔力

嘿,朋友们!今天我要和大家聊聊一个超级酷的话题——大型语言模型(LLMs) 它们在“思考”和回答问题时的一些“小秘密”。你可能已经听说过**“思考链”(Chain of Thought, COT** 这个概念,它是一种让模型在回…

RHCE工程师特训指南

RHCE(红帽认证工程师)是Linux领域极具含金量的认证之一,其考试以实操为主,注重系统管理、网络服务配置及自动化运维能力。以下内容可帮助对RHCE考生高效规划学习路径。 一、RHCE认证概述 认证结构 RHCE认证分为两部分&#xff…

Vue 3 中 slot插槽的使用方法

插槽&#xff0c;名字挺新奇。但不要被他的名字难住。其实就是父组件向子件件传递信息的一种手段。我们可以用这样的方法向子组件传值。 父组件&#xff08;app.vue) <template><MyCompoent :transData"{a:reactiveObj.a,breactiveObj.b,c}"> </tem…

大模型中的召回次数是什么意思

大模型中的召回次数是什么意思 在大语言模型&#xff08;LLM&#xff09;和检索增强生成&#xff08;RAG&#xff09;系统中&#xff0c;召回次数&#xff08;Recall Count&#xff09;是一个重要的参数&#xff0c;它决定了在检索阶段从知识库中提取多少候选文档或片段。这个…

智能监控视频聚合平台,GB28181/RTSP/SIP/RTMP直播会议融合方案

全场景智能监控聚合平台&#xff1a;打破边界&#xff0c;赋能高效协同 在数字化转型加速的今天&#xff0c;海量视频监控设备、多样化的编码协议与复杂的业务场景&#xff0c;让企业面临跨系统整合难、资源调度效率低、协作响应慢等痛点。我们的智能监控聚合平台以技术创新为…

IP数据报报文格式

一 概述 IP数据报由两部分组成&#xff1a;首部数据部分。首部的前一部分是固定长度&#xff0c;一共20字节大小&#xff0c;是所有IP数据报文必须具有的&#xff1b;固定部分后面是一些可选字段&#xff0c;其长度是可变的。 二 首部固定部分各字段意义 &#xff08;1&…

【电子通识】案例:为什么电子产品制造过程中使用马克笔在FFC/FPC连接器打点进行标记

在电子产品制造过程中&#xff0c;使用马克笔在FFC/FPC连接完成后进行打点标记&#xff08;或类似目视化检查方法&#xff09;&#xff0c;是一种常见的“过程防错&#xff08;Poka-Yoke&#xff09;”手段&#xff0c;其核心目的是通过简单、直观的方式确保关键工序的执行质量…

Electron应用生命周期全解析:从启动到退出的精准掌控

一、Electron生命周期的核心特征 1.1 双进程架构的生命周期差异 Electron应用的生命周期管理具有明显的双进程特征&#xff1a; 主进程生命周期&#xff1a;贯穿应用启动到退出的完整周期渲染进程生命周期&#xff1a;与浏览器标签页相似但具备扩展能力进程间联动周期&#…

Oracle到MySQL实时数据互通:透明网关跨库查询终极方案

技术架构概述 节点类型IP示例Oracle数据库172.18.0.11透明网关节点192.168.5.20MySQL数据库10.10.8.100 提示&#xff1a;透明网关支持部署在Oracle服务器实现集中式管理 一、MySQL环境准备 1. ODBC驱动部署 从MySQL官网获取对应版本的ODBC驱动&#xff1a; # 企业版推荐使…