C++面试问题总结1

c++ 问题汇总

以下是我收集到的一些关于C++面试常见的一些问题,用于各位正在准备面试的好兄弟们参考,有不正确的地方欢迎指正@-@。

问题一:继承和多态的区别?

继承:类与类之间可以共用代码,实现代码重用。
多态:子类重写父类的方法,使得子类具有不同的实现。且运行时,根据实际创建的对象动态决定使用哪个方法。
C++中实现多态的前提条件。1.有继承;2.重写父类方法 ;3.该方法要被virtual修饰; 4.父类指针或者引用指向子类对象
1.多态的实现要求必须是共有继承。
2.在继承关系中,父类更通用,子类更具体。父类具有一般的特征和行为,子类除了具有父类的特征和行为,还有自己特殊的行为和特征。
3.继承关系中,并不要求基类方法一定是虚函数。多态要求基类方法必须是虚函数。

问题二:结构体和联合体的区别?

二者最大的区别就是对于内存的利用。

1、结构体内部的数据是分开放的,各个成员都拥有自己的内存,各自使用互不干涉,一个struct变量的总长度是所有成员的长度之和。
2、联合体是将所有的数据放在一个地址空间中。各成员共用一块内存空间,并且同时只有一个成员可以得到这块内存的使用权(对该内存的读写),各变量共用一个内存首地址。因而,联合体比结构体更节约内存。一个union变量的总长度至少能容纳最大的成员变量,而且要满足是所有成员变量类型大小的整数倍。不允许对联合体变量名直接赋值或其他操作。

问题三:重载和重写的区别?

1、定义不同:重载是定义相同的方法名、参数不同,重写是子类重写父类的方法
2、范围不同:重载是在一个类中,重写是子类与父类之间的
3、多态不同:重载是编译时的多态性,重写是运行时的多态性
4、参数不同:重载的参数个数、参数类型、参数的顺序可以不同,重写父类子方法参数必须相同
5、修饰不同:重载对修饰范围没有要求,重写要求重写方法的修饰范围大于被重写方法的修饰范围
ps:多态是一个类需要表现出多种形态,子类重写父类的方法,使子类具有不同的方法实现。

问题四:struct和class的区别?

class(类)是面向对象编程的基本概念,是一种自定义数据结构类型,通常包含字段、属性、方法、属性、构造函数、索引器、操作符等。
struct(结构)是一种值类型,用于将一组相关的信息变量组织为一个单一的变量实体。所有的结构都继承自System.ValueType类,因此是一种值类型,也就是说,struct实例分配在线程的堆栈(stack)上,它本身存储了值,而不包含指向该值的指针。所以在使用struct时,我们可以将其当作int、char这样的基本类型类对待。
不同点:
1、class是引用类型,继承来自System.Object类;struct是值类型,继承来自System.ValueType,因此不具有多态性。
2、class表现为行为;而struct常用于存储数据。
3、class支持继承,可以继承自类和接口;而struct没有继承性,struct不能从class继承,也不能作为class的基类,但struct支持接口继承。
4、class可以声明无参构造函数,可以声明析构函数;而struct只能声明带参数构造函数,且不能声明析构函数。

问题五:如何判断浮点数是否相等?

首先解释概念,C++中的浮点数:float:4字节,单精度,32位,unsigned float:单精度,无符号,32位,double:8字节,双精度,64位,long double:8字节,高双精度,80位。

对两个浮点数判断大小和是否相等不能直接用==来判断,会出错!明明相等的两个数比较反而是不相等!
float,double分别遵循R32-24,R64-53的标准,​​他们的比特位数分别是23,52,即误差在2的23方 ,2的52方,所以float的10进制精度误差在1e-6,double的10进制精度误差在1e-15 。所以:fabs 返回浮点数据的绝对值)
if( fabs(a_float-b_float) <= 1e-6);
if( fabs(x_double-y_double) <= 1e-15);
这是eaual方法,C++11标准下可以用来判断两个浮点数是否相等。

// Test whether two float or double numbers are equal.
// ulp: units in the last place.
template <typename T>
typename std::enable_if<!std::numeric_limits<T>::is_integer, bool>::type
IsAlmostEqual(T x, T y, int ulp = 2) {
  // the machine epsilon has to be scaled to the magnitude of the values used
  // and multiplied by the desired precision in ULPs (units in the last place)
  return std::fabs(x - y) <
             std::numeric_limits<T>::epsilon() * std::fabs(x + y) * ulp
         // unless the result is subnormal
         || std::fabs(x - y) < std::numeric_limits<T>::min();
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

问题六:静态成员函数的作用?

class X
{
 public:
   void MethodA();
   static void MethodB();
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

当我们想调用MethodA()时,需要先生成类对象才能调用,具体步骤如下:X x;x.MethodA();
当我们想调用静态成员函数MethodB()时,我们可以直接调用X::MethodB();
静态函数不需要实例化就可以被调用,不会也不可以调用或操纵非静态成员,在我看来,一切不需要实例化就可以确定行为方式的函数都应该设计成静态的。

问题七:什么是多态以及多态的作用?

定义:一个接口多个方法,只有程序在运行时才决定调用的函数
C++的多态是通过虚函数实现的,虚函数允许子类重写override,而多态和非多态的区别则在于函数地址是早绑定还是晚绑定,也就是说在函数调用的时,编译器在编译时就确定函数的调用地址,则属于早绑定。而在函数调用的地址不能在编译器期间确定时,需要在运行时确定,则属于晚绑定。
目的:多态的目的是实现接口重用,而封装的目的是使得代码模块化,继承则是可以扩展已经存在的代码,他们的目的都是为了代码重用。
用法:声明基类的指针,利用该指针指向任意一个子类对象,调用相应的虚函数,可以根据指向的子类的不同而实现不同的方法。

问题八:系统会自动打开和关闭的3个标准的文件是哪三个?

(1)标准输入----键盘—stdin
(2)标准输出----显示器—stdout
(3)标准出错输出----显示器—stderr

问题九:说出字符常量和字符串常量的区别,并使用sizeof 计算有什么不同?

字符常量是指单个字符,字符串常量是以"\0"结束。
字符串常量使用运算符sizeof计算比字符常量计算的结果多占一字节的存储空间。

问题十:Windows消息系统由哪几部分构成?

由三个部分组成。
消息队列:Windows能够为所有的应用程序维护一个消息队列,应用程序必须从消息队列中获去消息,然后分派给某个窗体。
消息循环:通过这个循环机制,应用程序从消息队列中检索消息,再把它分派给适当的窗口,然后继续从消息队列中检索下一条消息,再分派给适当的窗口,依次进行。
窗口过程:每个窗口都有一个窗口过程,以接收Windows 传递给窗口的消息,窗口过程的任务就是获取消息并且响应它。窗口过程是一个回调函数,处理完一个消息后,通常要给Windows一个返回值。

问题十:sendmessage和postmessage的区别?

1、postmessage和sendmessage的区别主要是在于是否需要等待其他程序的消息处理。
2、postmessage只是把消息放入队列无论其他的程序是否处理都可以返回,然后继续执行。
3、sendmessage必须等待其他的程序处理消息后才返回,继续执行。
ps:两个函数的返回值也是不同的:PostMessage的返回值表示PostMessage函数执行是否正确,而SendMessage的返回值表示其他程序处理消息后的返回值。

问题十一:Windows下的lib和dll的区别?

1、lib是编译时用到的,dll是运行时用到的,也就是说当我们只想完成源代码编译的话,只需要lib文件;当我们想使用动态链接的程序运行起来的话,只需要dll文件。
2、如果有dll文件的话,lib文件中一般放一些索引信息,记录dll中函数的入口和位置。如果只有lib文件的话,那么这个lib文件是静态编译的lib文件。

问题十三:什么是序列化和反序列化?

类似于编码和解码的过程,将一种环境下的数据格式转换到另外一种环境下的数据格式,比如,将图像数据转化成为一种二进制的数据。客户端将数据进行序列化成为二进制数据,进行传输,快到服务端时,进行反序列化,将二进制数据转化成为需要的数据。

问题十四:什么是线程池?

  1. 并发:单个cpu串行执行多个线程,由于多个线程占用的时间片时间很短,大概10ms,这样用户体验起来就像是多个线程同时执行一样。
  2. 并行:在多个cpu中多个线程在真正的同时执行。
  3. 缺点:占有共享资源时会使得程序的运行速度变慢;有可能增加额外的cpu的开销;由于线程的死锁(长时间的等待,资源竞争)

问题十五:共享内存?

对于同一机器上的两个节点的通信,发送者将消息直接放在操作系统映射的一块共享内存上,接收者从同一块共享内存读取,不通过网络。共享内存只需要两次拷贝即可实现,即数据从进程A的用户空间到内存,再从内存到用户B的用户空间。其它的进程通信机制需要四次拷贝操作,首先将数据从进程A的用户空间拷贝到进程A的内核空间,其次将数据从进程A的内核空间拷贝到内存中,之后数据又从内存被拷贝到进程B的内核空间,最后数据从进程B的内核空间拷贝到进程B的用户空间中。因此使用共享内存通信比较高效。基于物理内存实现(使用该系统调用来申请一块共享内存,使用了该系统调用之后会返回一个共享内存的键值,进程可以使用该key值来使用这块共享内存)和基于内存映射实现(进程通过mmap()将一个普通文件的内存映射到每个进程的地址空间当中(映射的起始地址可以不一样),对映射区的修改会被写回到文件当中,其他进程可以共享这些修改)。

问题十六:gcc和clang两者编译器不同的地方?

gcc和clang是两个不同的编译器,而make(makefile)和cmake(Cmakelist.txt)是搭配编译器来方便用户进行多文件编译而发明的批处理工具。------文件CMakeLists.txt是用于构建软件包的 CMake 构建系统的输入。任何符合 CMake 的包都包含一个或多个 CMakeLists.txt 文件,该文件描述了如何构建代码以及将其安装到何处。

new与malloc的区别

特性:new/delete是C++关键字,需要编译器支持。malloc/free是库函数,需要头文件支持。
参数:使用new操作符申请内存分配时无须指定内存块的大小,编译器会根据类型信息自行计算。而malloc则需要显式地指出所需内存的尺寸。
返回类型:new操作符内存分配成功时,返回的是对象类型的指针,类型严格与对象匹配,无须进行类型转换,故new是符合类型安全性的操作符。而malloc内存分配成功则是返回void * ,需要通过强制类型转换将void*指针转换成我们需要的类型。
分配失败: new内存分配失败时,会抛出bac_alloc异常。malloc分配内存失败时返回NULL。
特性:new/delete是C++关键字,需要编译器支持。malloc/free是库函数,需要头文件支持。
参数:使用new操作符申请内存分配时无须指定内存块的大小,编译器会根据类型信息自行计算。而malloc则需要显式地指出所需内存的尺寸。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值