C++面试模拟01

第一部分:基础知识

  1. :解释 const 关键字的作用,以及在什么场景下你会使用 const

  2. :在 C++ 中,newmalloc 的区别是什么?

  3. :请解释什么是“深拷贝”和“浅拷贝”?在什么情况下我们需要进行深拷贝?

  4. :C++ 中的引用和指针有什么区别?各自的使用场景是什么?


第二部分:面向对象编程

  1. :请解释 C++ 中的“继承”和“多态”。可以举例说明如何实现多态吗?

  2. :假设你有一个基类 Shape 和派生类 CircleRectangle。如何设计一个类层次结构来支持多态调用?请写出代码示例。

  3. :C++ 支持多重继承(multiple inheritance),但是它可能会带来问题。请解释这些问题并说明如何使用虚继承来解决其中一个问题。


第三部分:STL(标准模板库)

  1. :C++ 标准库中的 std::vectorstd::list 有什么区别?分别适用于什么场景?

  2. std::mapstd::unordered_map 的区别是什么?它们的时间复杂度分别是多少?

  3. :在什么情况下你会使用 std::deque 而不是 std::vectorstd::list


第四部分:并发与多线程

  1. :请解释 C++ 中的多线程机制。如何使用 std::thread 创建线程?请写出代码示例。

  2. :什么是互斥锁(Mutex)?如何在 C++ 中使用它来保护共享资源?

  3. :什么是条件变量(Condition Variable)?请简要描述它的使用场景。


第五部分:C++ 高级特性

  1. :C++11 引入了移动语义(Move Semantics)。请解释移动语义的作用以及它与复制语义的区别。

  2. :什么是 RAII(资源获取即初始化)?为什么在 C++ 中非常重要?

  3. :C++20 引入了协程(Coroutines)。你能描述一下协程的基本概念和使用场景吗?


第六部分:现场编程

  1. :写一个函数,接收一个整数数组,移除所有重复的元素,并返回不重复的元素个数。请尽可能优化时间复杂度和空间复杂度。
int removeDuplicates(std::vector<int>& nums);

 我的想法:

        1.如果给了nums里int的范围,可以使用哈希法去重

        2.没有范围或者范围太大,使用力扣里的“移除元素”的方法,操作双指针。先排序。

  1. :请写一个单例模式(Singleton Pattern)的实现。保证线程安全。

结束问题

  1. :在你的开发经历中,是否遇到过多线程的竞争条件?你是如何解决的?

  2. :你平时如何优化代码性能?有哪些常用的工具和方法?

C++知识点/面试问题指南-CSDN博客

newmalloc 的区别

  • 类型检查

    • new:会调用构造函数,分配内存时会执行类型检查。
    • malloc:不执行类型检查,返回 void* 类型的指针,需要手动转换类型。
  • 返回类型

    • new:返回指定类型的指针,不需要类型转换。
    • malloc:返回 void*,需要显式进行类型转换。
  • 异常处理

    • new:如果分配失败,会抛出 std::bad_alloc 异常。
    • malloc:如果分配失败,返回 NULL,需要手动检查。
  • 构造/析构函数

    • new:调用构造函数,负责初始化对象。
    • malloc:只分配内存,不会调用构造函数。
  • 释放内存

    • new:使用 delete 释放内存,并调用析构函数。
    • malloc:使用 free 释放内存,不会调用析构函数。

引用和指针的区别

  • 引用(Reference)

    • 引用是某个变量的别名,必须在声明时进行初始化,之后不能更改引用的对象。
    • 语法简单、直观,不需要解引用操作符(*)。
    • 一旦绑定到某个对象,就不能重新绑定。
  • 指针(Pointer)

    • 指针是存储内存地址的变量,可以指向任意对象或 NULL,可以在运行时改变所指向的对象。
    • 需要使用解引用操作符(*)来访问指向的对象。
    • 指针可以被重新分配、动态分配内存,使用更加灵活。
  • 区别

    • 引用不能为空,指针可以为空。
    • 引用一旦绑定,不能更改;指针可以在运行时改变指向的对象。
    • 引用更适合用于参数传递,指针更适合需要动态管理内存的场景。
  • 使用场景

    • 引用适用于函数参数传递和返回值,当你想避免拷贝数据时,通常使用引用。
void foo(int& ref);  // 引用传递

指针适用于需要动态分配内存的场景,或者需要改变指向的对象。

int* ptr = new int(5);  // 动态分配内存

C++ 中的“继承”和“多态”

  • 继承

    • 继承是一种面向对象编程的机制,允许从一个现有的类(基类/父类)创建一个新类(派生类/子类),以复用基类的成员变量和成员函数。

    • 继承可以让派生类拥有基类的属性和方法,并且可以扩展新的方法或重写基类的方法。

多态

  • 多态是指相同的函数或运算符在不同的对象上表现出不同的行为。C++ 支持编译时多态(通过函数重载和运算符重载)和运行时多态(通过虚函数实现)。

  • 多态使得程序能够通过基类的指针或引用来调用派生类的实现,从而实现灵活性。

  • 示例(虚函数实现多态):

class Base {
public:virtual void show() { std::cout << "Base class" << std::endl; }
};class Derived : public Base {
public:void show() override { std::cout << "Derived class" << std::endl; }
};void func(Base& obj) {obj.show();  // 会根据传入的对象类型调用相应的 show() 方法
}

设计 ShapeCircleRectangle 类层次结构

#include <iostream>
#include <cmath>class Shape {
public:virtual double area() const = 0;   // 纯虚函数,表示该类是抽象类virtual ~Shape() {}                // 虚析构函数
};class Circle : public Shape {
private:double radius;
public:Circle(double r) : radius(r) {}double area() const override {     // 实现多态return M_PI * radius * radius;}
};class Rectangle : public Shape {
private:double width, height;
public:Rectangle(double w, double h) : width(w), height(h) {}double area() const override {return width * height;}
};int main() {Shape* shapes[2];shapes[0] = new Circle(5.0);shapes[1] = new Rectangle(4.0, 6.0);for (int i = 0; i < 2; i++) {std::cout << "Area: " << shapes[i]->area() << std::endl;delete shapes[i];  // 注意内存管理}return 0;
}

C++ 中的多重继承问题及虚继承

  • 多重继承的问题
    • 二义性问题:当一个类同时继承自两个具有同名成员的基类时,派生类会出现二义性。

    • 菱形继承问题:在多重继承中,如果一个类从两个基类派生,而这两个基类又继承自同一个基类,派生类会继承两份相同的基类成员,这就造成了冗余数据和二义性问题。

    • 菱形继承示例

class A {
public:void show() { std::cout << "A's show" << std::endl; }
};class B : public A {};
class C : public A {};class D : public B, public C {};  // D 继承了两份 A 类的成员
  • 虚继承的解决方案:使用虚继承解决菱形继承问题,确保派生类只继承一份基类的成员。

  • 虚继承示例

class A {
public:void show() { std::cout << "A's show" << std::endl; }
};class B : virtual public A {};    // 虚继承
class C : virtual public A {};    // 虚继承class D : public B, public C {};  // D 只继承一份 A 的成员

 解释:通过 virtual 关键字,B 和 C 虚继承自 A,D 类中只有一份 A 类的成员,避免了二义性和数据冗余问题。

std::vectorstd::list 的区别

  • 底层实现

    • std::vector:基于动态数组实现,元素在内存中是连续存储的。
    • std::list:基于双向链表实现,元素在内存中是非连续存储的。
  • 时间复杂度

    • 访问vector 支持常数时间的随机访问(O(1)),因为其元素是连续存储的;而 list 访问任意位置的元素都需要线性时间(O(n))。
    • 插入/删除list 在任何位置插入或删除元素的时间复杂度为常数时间(O(1)),而 vector 在尾部插入/删除元素的时间复杂度为 O(1),但在中间插入或删除元素时需要移动数据,时间复杂度为 O(n)
  • 适用场景

    • std::vector:适用于需要频繁随机访问元素,或在末尾插入、删除元素的场景。
    • std::list:适用于需要频繁在中间插入或删除元素的场景,但不需要随机访问。

std::mapstd::unordered_map 的区别

  • 底层实现

    • std::map:基于红黑树(自平衡二叉搜索树)实现,键值对按键的顺序存储。
    • std::unordered_map:基于哈希表实现,键值对无序存储。
  • 时间复杂度

    • std::map:插入、删除、查找的平均时间复杂度为 O(log n)
    • std::unordered_map:插入、删除、查找的平均时间复杂度为 O(1),最坏情况下为 O(n)
  • 适用场景

    • std::map:适用于需要按键排序的场景。
    • std::unordered_map:适用于对性能要求较高、且不需要排序的场景。

何时使用 std::deque 而不是 std::vectorstd::list

  • std::deque:双端队列(double-ended queue),在两端插入和删除元素的时间复杂度为 O(1),并支持常数时间的随机访问。

  • 使用场景

    • 当需要在容器的两端频繁进行插入和删除操作,同时还需要随机访问时,使用 std::deque 是最好的选择。

    • std::vector 不同,deque 支持在头部进行高效的插入和删除操作。

    • std::list 不同,deque 支持随机访问。

RAII(Resource Acquisition Is Initialization,资源获取即初始化)是一种重要的 C++ 编程习惯,确保资源的正确管理。RAII 的核心思想是:将资源的生命周期绑定到对象的生命周期。当对象被创建时获取资源,当对象被销毁时释放资源。

  • 优点

    1. 自动管理资源:资源的分配和释放与对象的生命周期绑定,避免资源泄漏(如内存泄漏、文件句柄泄漏)。
    2. 异常安全:如果在资源使用过程中发生异常,RAII 确保在栈展开时资源会被正确释放。
    3. 简化代码:RAII 自动处理资源的释放,减少手动管理资源的复杂性。
  • 常见场景

    1. 内存管理:智能指针(如 std::unique_ptrstd::shared_ptr)通过 RAII 管理动态分配的内存。
    2. 文件管理std::fstream 等标准库类通过 RAII 确保文件在对象销毁时自动关闭。
  • 示例

class FileHandler {
private:FILE* file;
public:FileHandler(const char* filename) {file = fopen(filename, "r");if (!file) {throw std::runtime_error("File open failed");}}~FileHandler() {if (file) {fclose(file);  // 确保文件关闭}}
};

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

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

相关文章

IMS 呼叫流程(详细)

目录 业务模型 典型组网如图1所示 信令流程 具体的语音流程如图2所示 主叫信令面流程 01:UE_A->P-CSCF/ATCF 02:P-CSCF/ATCF_A->PCRF_A 03:PCRF_A->PCSCF/ATCF_A 04:P-CSCF/ATCF_A 处理(把S-CSCF加到Route) 05:S-CSCF_A->MMTel AS/SCC AS_A 06:MM…

JAVA-集合相关

HashMap如何解决哈希冲突的&#xff1f; 计算hash值&#xff0c;基于hashCode计算冲突之后&#xff0c;先是使用链式寻址法当链表长度大于8&#xff0c;且hash表的容量大于60的时候&#xff0c;再添加元素则转化成红黑树 为什么计算hash值是&#xff0c;是将hash地址的值右移1…

JavaSE:13、常用工具类

学习 资源1 学习资源 2 1、数学工具类 import com.test.*;import java.util.Random; import java.util.RandomAccess;public class Main {public static void main(String [] argv) throws Exception {System.out.println(Math.pow(5,3));//125.0System.out.println(Math.a…

大数据Flink(一百一十八):Flink SQL水印操作(Watermark)

文章目录 Flink SQL水印操作&#xff08;Watermark&#xff09; 一、为什么要有WaterMark 二、​​​​​​​​​​​​​​Watermark解决的问题 三、​​​​​​​​​​​​​​代码演示 Flink SQL水印操作&#xff08;Watermark&#xff09; 一、​​​​​​​为什么…

43.常用C++编译器推荐——《跟老吕学C++》

43.常用C编译器推荐——《跟老吕学C》 常用C编译器推荐一、C编译器介绍1. GCC (GNU Compiler Collection)2. Clang2.1 Clang的特点2.2 Clang的应用场景2.3 Clang与GCC的比较 3. Microsoft Visual C (MSVC)MSVC的特点MSVC的使用场景MSVC与其他编译器的比较 4. Intel C Compiler4…

Spring MVC设置请求头和响应头的Header

在Spring MVC中&#xff0c;动态设置请求头和响应头的方法有多种&#xff0c;以下是一些常见的方式&#xff1a; 设置请求头 使用RequestHeader注解 这个注解用于读取请求中的单个HTTP头部值&#xff0c;并将其作为一个参数传递给控制器方法。 RequestMapping("/examp…

【Midjourney中文版】

Midjourney中文版打破了传统创作工具的界限&#xff0c;无需具备专业的艺术技能或复杂的软件操作能力&#xff0c;即可轻松创作出高质量的图片。它支持多种创作模式&#xff0c;包括文生图、图生图、图片混图融合等&#xff0c;满足多样化的创作需求。 打开Midjourney中文版后…

特斯拉主动巡航技术解析

特斯拉的主动巡航控制技术是其自动驾驶技术套件&#xff08;Autopilot&#xff09;中的一项重要功能&#xff0c;旨在提升驾驶的舒适性和便利性。以下是对特斯拉主动巡航技术的详细解析&#xff1a; 一、技术原理与功能 1. 原理概述 特斯拉的主动巡航控制通过车辆前部的摄像…

istio中如何使用serviceentry引入外部服务

假设需要引入一个外部服务&#xff0c;外部服务ip为10.10.102.90&#xff0c;端口为32033. 引入到istio中后&#xff0c;我想通过域名gindemo.test.ch:9090来访问这个服务。 serviceentry yaml内容如下&#xff1a; apiVersion: networking.istio.io/v1beta1 kind: ServiceEn…

【Pycharm】Pycharm创建Django提示pip版本需要升级

目录 1、现象 2、分析 3、本质 前言&#xff1a;经常使用pycharm创建django、flask等项目时候提示pip版本需要升级&#xff0c;解决方案 1、现象 使用Pycharm创建Django项目提示安装Django超时&#xff0c;报错建议pip升级22升级到24 2、分析 之前使用命令升级了pip到了24…

VS code EXPLORER 中不显示指定文件及文件夹设置(如.pyc, __pycache__, .vscode 文件)

VS code EXPLORER 中不显示指定文件及文件夹设置 引言正文方法1打开方式1打开方式2 方法2 引言 VS code 号称地表最强轻量级编译器&#xff0c;其最大的优势在于用户可以根据自己的需求下载适合自己的 extension。从而定制个性化的编译器。然而&#xff0c;本人今天遇到了一个…

出厂非澎湃OS手机解BL锁

脚本作者&#xff1a;酷安mlgmxyysd 脚本项目链接&#xff1a;https://github.com/MlgmXyysd/Xiaomi-HyperOS-BootLoader-Bypass/ 参考 B站作者&#xff1a;蓝空穹 https://www.bilibili.com/read/cv33210124/ 其他参考&#xff1a;云墨清风、水墨青竹、Magisk中文网 决定解BL…

设计模式 组合模式(Composite Pattern)

组合模式简绍 组合模式&#xff08;Composite Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许你将对象组合成树形结构来表示“部分-整体”的层次结构。组合模式使得客户端可以用一致的方式处理单个对象和组合对象。这样&#xff0c;可以在不知道对象具体类型的条…

通信工程学习:什么是ONT光网络终端

ONT&#xff1a;光网络终端 ONT&#xff08;Optical Network Terminal&#xff0c;光网络终端&#xff09;是光纤接入网络&#xff08;FTTH&#xff09;中的关键设备&#xff0c;用于将光纤信号转换为电信号或将电信号转换为光信号&#xff0c;以实现用户设备与光纤网络的连接。…

Hive parquet表通过csv文件导入数据

1. background 已建好了 hive parquet 格式的表, 需要从服务器的csv导入数据至该hive表 2. step 提前上传csv至服务器 /path/temp.csv 创建 textfile 格式的中转表(这里使用内部表,方便删除) ,源表名dw_procurement.dwd_tc_comm_plant ,这里中转表加上了csv后缀 CREATE TA…

Koa (下一代web框架) 【Node.js进阶】

koa (中文网) 是基于 Node.js 平台的下一代 web 开发框架&#xff0c;致力于成为应用和 API 开发领域中的一个更小、更富有表现力、更健壮的基石&#xff1b; 利用 async 函数 丢弃回调函数&#xff0c;并增强错误处理&#xff0c;koa 没有任何预置的中间件&#xff0c;可快速…

第五部分:2---信号的介绍、产生、处理

目录 信号的概念&#xff1a; 信号表的继承&#xff1a; 信号的分类与编号&#xff1a; 特殊的信号&#xff1a; 信号的产生&#xff1a; 1.键盘输入&#xff1a; 2.系统调用&#xff1a; 3.异常或硬件错误&#xff1a; 4.总结&#xff1a; 信号的处理&#xff1a; …

两台电脑的对话,Socket网络传输的套件学起来

服务器端from socket import * s socket() s.bind((gethostname(),8888)) s.listen() s, addr s.accept() print(addr) disk_str s.recv(1024).decode() disk_list disk_str.split(\x00) disk_list.pop(-1) print(disk_list) cur_path " " while True:com_str …

计算机组成原理(笔记3)

IEEE754浮点数标准 这里只讲32位单精度 S——尾数符号&#xff0c;0正1负&#xff1b; M——尾数, 纯小数表示, 小数点放在尾数域的最前面。 一般采用原码或补码表示。 E——阶码&#xff0c;采用“移码”表示; 阶符采用隐含方式&#xff0c;即采用“移码”方法来表示正负指数…

Python 之数据库操作(Python Database Operations)

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:Linux运维老纪的首页…