【C/C++】C/C++面试八股
C/C++面试八股
- C++和C语言的区别
- 简单介绍一下三大特性
- 多态的实现原理
- 虚函数的构成原理
- 虚函数的调用原理
- 虚表指针在什么地方进行初始化的?
- 构造函数为什么不能是虚函数
- 虚函数和纯虚函数的区别
- 抽象类
- 类对象的对象模型
- 内存对齐是什么?为什么要内存对齐
- static关键字的作用
- 指针和引用的区别
- 介绍一下vector的扩容过程
- vector如何释放内存空间
- map与unordered_map的区别
- 对于插入来说,operator[]与insert的区别
- 对于访问来说,operator[]与.at的区别
- new和malloc的区别
- new的实现原理
- operator new的原理
- malloc的实现原理
- 内存泄露的检测工具
- 特殊类的设计
- C++11的锁有哪些
- C++11的智能指针
- 几种排序的思路,代码实现
C++和C语言的区别
一.C++解决了很多C语言固有的缺陷:
- 针对C语言中存在命名冲突,C++提供了命名空间来解决
2.C语言不支持函数缺省参数,C++也提供了缺省参数的方法
3.在C语言中,由于宏函数的有效性无法检查,所以C++提出了内联函数解决二.在C语言指针的基础上,C++提出了引用
三.C++可以实现函数重载,原因是C语言对于函数的区分是用函数名来区分的,而C++是使用函数名+函数参数列表来区分的,因此C语言中,只要函数名称一致,就会导致编译器报错,而C++中,可以设置函数名称一致,而参数列表不同的函数,作为函数的重载形式
四.C语言采用的是面向过程的编程思想,专注于过程。而C++采用的是面向对象的编程思想,关注的是对象,靠对象之间的交互完成
五.C语言的结构体中只能定义变量,而C++的类中,既可以定义变量也可以定义函数
简单介绍一下三大特性
封装:就是将数据和对数据的操作方式结合起来,隐藏细节,对外暴露一些接口,以供对象之间进行交互,本质上是为了让用户更好的管理类
继承:是一种代码的复用手段,目的是在原有类的基础上进行扩展,增加新的功能,生成新的类
多态:就是多种形态,当完成某个动作时,不同的对象去完成,产生不同的状态
多态可以分为静态多态和动态多态
静态多态是在程序编译阶段就确定了函数的执行动作,典型例子是:函数重载。
动态多态是在程序运行时通过传递的对象实际类型来确定函数的执行,典型例子是:函数的重写
多态的实现原理
多态的实现条件
1.需要首先让派生类重写基类的虚函数
2.通过基类的指针或引用来调用虚函数
多态的实现原理:
某个类成员函数被virtual修饰之后,该类的对象模型中就会有一个虚表指针,这个指针指向一个虚表,该虚表中就会存放虚函数地址。
当某个派生类将该基类继承之后,该派生类的对象模型中也会有一个和基类中一直的虚表指针,如果这个派生类将基类中的虚函数进行了重写,那么自己的虚表中就会将原来基类虚表中对应的虚函数指针替换
此时如果我们使用基类的指针或引用去调用虚函数,那么如果传递的是基类对象,那么就会通过this指针去调用基类对象的成员函数,如果传递的是子类对象,那么就会通过this指针去调用子类对象的成员函数。
虚函数的构成原理
在编译阶段,将虚函数按照在类中的声明次序依次添加到虚表中
在单继承体系下,子类虚表的构建原理:
1、原封不动将基类虚表中的内容拷贝一份到子类虚表中
2、如果子类中哪个函数重写了基类虚表中的虚函数,则将虚表中对应的虚函数指针替换为当前重写后的虚函数指针
3、将子类新增的虚函数按照在子类中声明的次序进行添加
虚函数的调用原理
通过实际传入的对象的this指针,拿到对应的虚表指针,再通过对应的虚表指针,找到对应的虚表,然后通过虚表中存放的虚函数地址,来进行虚函数的调用。
包含有虚函数的类对象,编译器在编译时,就为该对象创建了一个虚表指针,以便于能够正确的获取该类的虚表
虚表指针在什么地方进行初始化的?
在构造函数中,进行虚表的创建和虚表指针的初始化
构造函数为什么不能是虚函数
因为虚函数对应一个虚表指针,这个虚表指针是存储在对象的内存空间的,构造函数就是用来去开辟对象的内存空间 的,如果构造函数是虚函数,意味着在对象内存空间还不存在的就要去初始化对象内存空间中的值,是无法实现的
虚函数和纯虚函数的区别
虚函数目的是建立抽象模型,方便系统扩展
纯虚函数是不具体实现的函数,一种特殊的函数
虚函数必须是类的非静态成员
纯虚函数是虚函数的子集,用于抽象类,包含有纯虚函数的类是抽象类,不能实例化对象
因为有时候基类实例化对象是不合理的,例如:基类是动物,子类是猫狗,那么基类本身可以创建对象就是不合理的,那么用纯虚函数修饰之后,让基类无法创建对象才是较为合理的
抽象类
包含纯虚函数的类就是抽象类
抽象类不能实例化对象,只能在该类被派生之后,并且所有的纯虚函数都被重写之后,才能被创建对象
类对象的对象模型
类对象中只存储了类的成员变量,并且按照成员变量的声明顺序进行存储,遵循内存对齐原则,如果存在虚函数,那么会有虚表指针,如果存在虚拟继承,那么还会有一个虚基表指针。
在继承体系下,如果是普通的继承,那么子类对象的对象模型是:
首先是基类继承,然后是子类新增
如果是虚拟继承:
继承自多个基类,那么按照派生类的声明顺序进行。
每个来自基类的对象模型中,只存储一个虚基表指针,指向各自基类对应位置
然后是子类新增,最后是基类成员变量
内存对齐是什么?为什么要内存对齐
1、提高内存访问效率
2、减小内存占用量
static关键字的作用
static关键字的作用: static关键字的作用
指针和引用的区别
1.指针存储的是地址,而引用是对变量的一个别名
2.引用在定义时必须初始化,而指针不用
3.指针可以通过修改值来改变指针的指向,引用关系一旦确立,引用的实体就不能改变了
4.sizeof时,传递的是指针,计算的是指针占空间的大小,引用是变量类型的大小
5.指针需要显式解引用,引用不用
6.存在空置指针,而不存在空值引用
介绍一下vector的扩容过程
vector如何释放内存空间
map与unordered_map的区别
1.map的底层是红黑树,unordered_map底层是哈希表
2.map是按照key有序的,unordered_map无序
3.map的查询效率是O(logn),unordered_map是O(1)
4.map更适合需要数据有序,对查询效率不是那么高的场景,unordered_map适合对查询效率极高的场景
对于插入来说,operator[]与insert的区别
如果key存在,那么都会插入失败,但是operator[]会将原来的key对应的value替换为新的value,而insert不进行任何操作
如果key不存在,那么都会插入成功,通过key和value构造键值对,进行插入
operator[]底层调用的是insert,insert返回的是对应位置的迭代器,operator[]拿到返回的迭代器,返回的是key对应的value
对于访问来说,operator[]与.at的区别
如果key存在,operator[]和.at()一样会返回key对应的value
如果key不存在,operator[]会key和默认的value构成键值对,插入map中
new和malloc的区别
1.new是关键字,malloc是库函数
2.new申请空间失败会抛异常,malloc不会
3.new只需要传递类型,编译器会根据类型判断申请空间大小,malloc需要手动传递字节数
4.new申请空间之后不需要进行类型转换,malloc需要
5.new在申请空间之后还会调用构造函数进行对象的构造,而malloc不会,同理delete会自动调用析构函数,而free不会
new的实现原理
1、调用operator new()函数申请空间
2、在申请的空间上执行构造函数,完成对象的构造
operator new的原理
1、调用malloc函数申请空间
2、如果申请成功,返回空间地址,如果申请失败,会执行用户定义的方法,继续申请空间,如果用户没有定义申请失败的方法,那么就会抛异常
malloc的实现原理
1、内存管理:内存管理的数据结构是一个链表, 每个节点表示的是一个内存块,调用malloc时,先遍历该链表找到一块足够大的内存块,标记为已分配状态
2、内存分配,将已分配的内存块首地址返回给程序
内存泄露的检测工具
在linux下进行内存泄漏的检测工具:valgrind
在win下的内存泄漏检测工具:VLD
特殊类的设计
设计类不能被继承:将构造函数私有化
设计类不能被拷贝:将拷贝构造和赋值运算符重载只声明不定义
设计类只能从堆上创建对象:
方法一:将构造函数和拷贝构造函数私有化,设置一个静态成员函数,函数内通过new创建对象,返回对象指针
设计类只能从栈上创建对象:
方法一:将构造函数私有化,将operator new()禁掉
方法二:将构造函数和拷贝构造函数私有化,设置一个静态成员函数,在该函数中调用构造函数,返回对象
设计一个单例类:
饿汉模式:将构造拷贝构造赋值运算符都私有化,类内声明一个私有的静态类对象和一个公有的静态成员函数,在函数内对静态类对象进行初始化,返回对象指针
懒汉模式:将构造函数和拷贝构造函数和赋值运算符重载都私有化,类内声明一个私有的静态类对象指针和一个公有的静态成员函数,在函数中new一个对象的指针赋值给该静态对象指针。需要注意的是double chack
C++11的锁有哪些
六大种:
1、mutex
2、recursive_mutex
3、timed_mutex
4、recursive_timed_mutex
5、lock_guard:对mutex进行封装,实现了RAII,可以预防死锁
6、unique_lock:在lock_guard上增加了加锁解锁查看锁状态等功能
C++11的智能指针
auto_ptr:已资源管理权限转移的方式解决浅拷贝,弃用,容易造成野指针
unique_ptr:已资源独占的方式解决浅拷贝,无法拷贝,不方便
shared_ptr:已资源计数的方式解决浅拷贝,容易造成循环引用的问题,解决方式是weak_ptr,用ListNode的例子解释
几种排序的思路,代码实现
相关文章:

【C/C++】C/C++面试八股
C/C面试八股 C和C语言的区别简单介绍一下三大特性多态的实现原理虚函数的构成原理虚函数的调用原理虚表指针在什么地方进行初始化的?构造函数为什么不能是虚函数虚函数和纯虚函数的区别抽象类类对象的对象模型内存对齐是什么?为什么要内存对齐static关键…...

Scala第八章节
Scala第八章节 scala总目录 章节目标 能够使用trait独立完成适配器, 模板方法, 职责链设计模式能够独立叙述trait的构造机制能够了解trait继承class的写法能够独立完成程序员案例 1. 特质入门 1.1 概述 有些时候, 我们会遇到一些特定的需求, 即: 在不影响当前继承体系的情…...
k8s-实战——kubeadm二进制编译
文章目录 源码编译获取源码修改证书有效期修改 CA 有效期为 100 年(默认为 10 年)修改证书有效期为 100 年(默认为 1 年)CentOS7.9环境准备centos脚本安装执行脚本脚本内容手动安装验证编译查看编译后的版本信息参考链接脚本修改源码编译 源码编译kubeadm文件、修改证书的默…...
vite 和 webpack 的区别
1. 构建原理: Webpack 是一个静态模块打包器,通过对项目中的JavaScript、css、Image 等文件进行分析,生成对应的静态资源,并且通过一些插件和加载器来实现各种功能。 Vite 是一种基于浏览器元素 ES 模块解析构建工具,…...

传统遗产与技术相遇,古彝文的数字化与保护
古彝文是中国彝族的传统文字,具有悠久的历史和文化价值。然而,由于古彝文的形状复杂且没有标准化的字符集,对其进行文字识别一直是一项具有挑战性的任务。本文介绍了古彝文合合信息的文字识别技术,旨在提高古彝文的自动识别准确性…...

多维时序 | MATLAB实现WOA-CNN-GRU-Attention多变量时间序列预测(SE注意力机制)
多维时序 | MATLAB实现WOA-CNN-GRU-Attention多变量时间序列预测(SE注意力机制) 目录 多维时序 | MATLAB实现WOA-CNN-GRU-Attention多变量时间序列预测(SE注意力机制)预测效果基本描述模型描述程序设计参考资料 预测效果 基本描述…...
1042 字符统计
description 请编写程序,找出一段给定文字中出现最频繁的那个英文字母。 输入格式: 输入在一行中给出一个长度不超过 1000 的字符串。字符串由 ASCII 码表中任意可见字符及空格组成,至少包含 1 个英文字母,以回车结束ÿ…...

3 OpenCV两张图片实现稀疏点云的生成
前文: 1 基于SIFT图像特征识别的匹配方法比较与实现 2 OpenCV实现的F矩阵RANSAC原理与实践 1 E矩阵 1.1 由F到E E K T ∗ F ∗ K E K^T * F * K EKT∗F∗K E 矩阵可以直接通过之前算好的 F 矩阵与相机内参 K 矩阵获得 Mat E K.t() * F * K;相机内参获得的方式…...
在Springboot项目中使用Redis提供给Lua的脚本
在Springboot项目中使用Redis提供给Lua的脚本 在Spring Boot项目中,你可以使用RedisTemplate来执行Lua脚本。RedisTemplate是Spring Data Redis提供的一个Redis客户端,它可以方便地与Redis进行交互。以下是使用RedisTemplate执行Lua脚本的一般步骤&…...

分类预测 | MATLAB实现NGO-CNN北方苍鹰算法优化卷积神经网络数据分类预测
分类预测 | MATLAB实现NGO-CNN北方苍鹰算法优化卷积神经网络数据分类预测 目录 分类预测 | MATLAB实现NGO-CNN北方苍鹰算法优化卷积神经网络数据分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1.Matlab实现NGO-CNN北方苍鹰算法优化卷积神经网络数据分类预测&…...

Linux或Centos查看CPU和内存占用情况_top只能查看对应的命令_如何查看具体进程---linux工作笔记062
一般我们都是用top去查看,但是top查看的结果,不能看出,具体是哪个程序占用的,这就很苦恼.. 其实如果有时间的话,再去专门看一下网络安全和linux脚本以及命令方面的,比较系统的看一下比较好.现在积累的都是工作中用到的,比较零散的知识. 如果用top,比如说这里的java,就只能知道…...
什么是DevOps
文章目录 一、概念二、地位三、目标四、要求五、具体手段 一、概念 是一组过程、方法与系统的统称,有助于打破开发、测试、运维、交付部门之间的壁垒,提高部门间的沟通协助能力。 二、地位 应成为公司的一种理念、文化、哲学。 三、目标 实现更加高…...
力扣每日一题
605. 种花问题 - 力扣(LeetCode) 动态规划 class Solution { public:bool canPlaceFlowers(vector<int>& flowerbed, int n) {int m flowerbed.size();if(1 m)return !flowerbed[0] > n;else if(2 m)return ((!flowerbed[0] &&…...

测试OpenCvSharp库的模板匹配功能
微信公众号“Dotnet讲堂”的文章《c#实现模板匹配,并输出匹配坐标》(参考文献1)中介绍了采用OpenCVSharp库实现模板匹配功能,也即在目标图片中定位指定图片内容的示例,本文参照参考文献1-4,学习并测试OpenC…...

网络编程day04(网络属性函数、广播、组播、TCP并发)
今日任务 对于newfd的话,最好是另存然后传入给分支线程,避免父子线程操作同一个文件描述符 ------------在tcp多线程服务端---------- 如果使用全局变量,或者指针方式间接访问,会导致所有线程共用一份newfd和cin,那么…...

HALCON支持GPU加速的算子有哪些?
参考例程get_operator_info。 get_opencl_operators这里可以查看到所有支持gpu加速的算子。 支持的算子列表: crop_rectangle1,deviation_image,mean_image,points_harris,gray_opening_shape, gray_dilat…...

MacBook Pro 电池电量限制充电怎么设置AlDente Pro for Mac最大充电限制工具
通过充电电量限制工具可以更好的保护MacBook Pro的电池,通过 AlDente Pro 您可以设置电池的最大充电百分比设置为 20% 至 100%,然后,它将保持在所需的电池百分比,然后再次使用电源适配器进行充电。 AlDent…...

毕业设计选题之Java+springboot线上蔬菜销售与配送系统(源码+调试+开题+lw)
💕💕作者:计算机源码社 💕💕个人简介:本人七年开发经验,擅长Java、Python、PHP、.NET、微信小程序、爬虫、大数据等,大家有这一块的问题可以一起交流! 💕&…...
【Leetcode】162.寻找峰值
一、题目 1、题目描述 峰值元素是指其值严格大于左右相邻值的元素。 给你一个整数数组 nums,找到峰值元素并返回其索引。数组可能包含多个峰值,在这种情况下,返回 任何一个峰值 所在位置即可。 你可以假设 nums[-1] = nums[n] = -∞ 。 你必须实现时间复杂度为 O(log n…...

SpringBoot集成MinIO8.0
一、安装MinIO 中文官网地址:https://www.minio.org.cn/download.shtml 官网地址:https://min.io/download 官网有相应的安装命令,可查看 建议引用相应版本的依赖 二、集成SpringBoot 1.引入依赖 <dependency><groupId>io.…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...

JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...

Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...
生成 Git SSH 证书
🔑 1. 生成 SSH 密钥对 在终端(Windows 使用 Git Bash,Mac/Linux 使用 Terminal)执行命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 参数说明: -t rsa&#x…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...

《Docker》架构
文章目录 架构模式单机架构应用数据分离架构应用服务器集群架构读写分离/主从分离架构冷热分离架构垂直分库架构微服务架构容器编排架构什么是容器,docker,镜像,k8s 架构模式 单机架构 单机架构其实就是应用服务器和单机服务器都部署在同一…...