C++软件工程师面试题汇总(祝各位秋招/春招顺利)

C++面试题汇总(持续更新中.......)

  • 简介
    • c++ 问题汇总
      • 问题一:继承和多态的区别?
      • 问题二:结构体和联合体的区别?
      • 问题三:重载和重写的区别?
      • 问题四:struct和class的区别?
      • 问题五:如何判断浮点数是否相等?
      • 问题六:静态成员函数的作用?
      • 问题七:什么是多态以及多态的作用?
      • 问题八:系统会自动打开和关闭的3个标准的文件是哪三个?
      • 问题九:说出字符常量和字符串常量的区别,并使用sizeof 计算有什么不同?
      • 问题十:Windows消息系统由哪几部分构成?
      • 问题十:sendmessage和postmessage的区别?
      • 问题十一:Windows下的lib和dll的区别?
      • 问题十三:什么是序列化和反序列化?
      • 问题十四:什么是线程池?
      • 问题十五:共享内存?
      • 问题十六:gcc和clang两者编译器不同的地方?
      • 问题十七:STL?
      • 问题十八:C++中堆和栈的区别?
      • 问题十九:STL容器有哪些,常用的算法?
      • 问题二十:什么是智能指针?
      • 问题二十一:share_ptr与weak_ptr的区别与联系?
      • 问题二十二:c++的构造函数和析构函数可以抛出异常吗?
      • 问题二十三:Visual Studio Code配置连接Linux服务器?
      • 问题二十四:STL的set 和 map都是基于什么实现的?
      • 问题二十五:描述下C++的浅copy,深copy,写时copy和引用计数的copy?
      • 问题二十六:内存对齐原则?
      • 问题二十七:内联函数和宏定义有什么区别?
      • 问题二十八:数组指针和指针数组?
      • 问题二十九:野指针?怎么产生的?解决野指针的方法?
      • 问题三十:常见的内存错误及其对策?
      • 问题三十一:内存的三个对象?
      • 问题三十二:C++内存泄漏及其检测工具?
      • 问题三十三:什么时候要有虚析构函数?
      • 问题三十四:#include <> 和#include ” ”的不同?
      • 问题三十五:引用作为函数的参数有哪些特点?
      • 问题三十六:什么时候使用常引用?
      • 问题三十七:STL实现了哪些排序算法?
      • 问题三十八:C++中STL vector的实现机制?
      • 问题三十九:C++有哪些数据类型,为什么long和int都是4字节?
      • 问题四十:说说你使用的C++11的特性?
      • 问题四十一:C++的继承?
      • 问题四十一:const修饰指针,常量指针,指针常量?
      • 问题四十二:struct和class的区别?
      • 问题四十三:友元函数?
      • 问题四十四:指针大小?
    • 线程、进程问题汇总
      • 问题一:程序什么时候应该使用线程,什么时候单线程效率高?
      • 问题二:进程间(IPC)的通信方式?
      • 问题三:进程间(IPC)几种锁的实现?
      • 问题四:共享内存的实现原理?
      • 问题五:进程和线程之间的区别?
      • 问题六:进程调度算法?
    • Linux问题汇总
      • 问题一:与CPU、内存、磁盘相关的命令(top free df fdisk)?
      • 问题二:与网络相关的命令netstat , tcpdump ?
      • 问题三:关机 (系统的关机、重启以及登出 ) ?
      • 问题四:文件和目录 ?
      • 问题五:磁盘空间 ?
      • 问题六:网络 - (以太网和WIFI无线) ?
      • 问题七:磁盘空间 ?
    • 数据库(mysql)问题汇总
      • 问题一:事务、ACID、隔离级别、数据库的脏读、不可重复读和幻读?
      • 问题二:ACID靠什么保证?
      • 问题三:怎么处理MySQL的慢查询?
      • 问题四:MySQL锁?
      • 问题五:MySQL索引以及索引结构?
      • 问题六:MySQL聚簇索引和非聚簇索引?
      • 问题七:MySQL和oracle的区别?
    • 计算机网络问题汇总
      • 问题一:HTTP状态码?
      • 问题二:物理层简介?
      • 问题三:数据链路层简介?
      • 问题四:网络层简介?
      • 问题五:计算机网络各层
      • 问题六:TCP三次握手、四次挥手
      • 问题七:TCP如何保证可靠性?
      • 问题八:cookie和session的区别?
    • 设计模式问题汇总
      • 问题一:你遇到过的设计模式有哪些?
    • 测试工程师问题汇总
      • 问题一:黑盒测试和白盒测试?
  • TIPS........

简介

我将在这里记录下自己面试过程中遇到的一些面试题目以及自己准备过程中遇到的一些问题…

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();
}

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

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

当我们想调用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 文件,该文件描述了如何构建代码以及将其安装到何处。

问题十七:STL?

C++软件工程师面试题汇总(祝各位秋招/春招顺利)_第1张图片

问题十八:C++中堆和栈的区别?

堆是程序员自己进行操作的空间,如new对象,delete。栈是系统自己分配的。堆是一个不连续的空间,所以比较大,栈是一个先进后出的连续空间比较小。碎片问题:对于堆,频繁的new/delete会造成大量内存碎片,降低程序效率。对于栈,它是一个先进后出的结构,进出一一对应,不会产生碎片。

问题十九:STL容器有哪些,常用的算法?

(转载俩篇博客)https://blog.csdn.net/lyh_lll/article/details/120386531。
https://blog.csdn.net/daaikuaichuan/article/details/80717222

问题二十:什么是智能指针?

当我们申请一块内存或者new一个对象时,会导致多个指针指向同一个对象,当我们删除一个指针指向的对象时,其他指针指向的对象也就不存在了,这个时候这些指针就变成了悬垂指针。如果new的对象没有被delete方法执行时,就会造成内存泄漏。而智能指针的目的就是管理内存,避免内存泄漏和悬垂指针。

问题二十一:share_ptr与weak_ptr的区别与联系?

shared_ptr与weak_ptr智能指针均是C++ RAII的一种应用,可用于动态资源管理。
shared_ptr基于“引用计数”模型实现,多个shared_ptr可指向同一个动态对象,并维护了一个共享的引用计数器,记录了引用同一对象的shared_ptr实例的数量。当最后一个指向动态对象的shared_ptr销毁时,会自动销毁其所指对象(通过delete操作符)。shared_ptr的默认能力是管理动态内存,但支持自定义的Deleter以实现个性化的资源释放动作。weak_ptr用于解决“引用计数”模型循环依赖问题,weak_ptr指向一个对象,并不增减该对象的引用计数器

问题二十二:c++的构造函数和析构函数可以抛出异常吗?

我觉得不可以,当在构造函数抛出异常时,析构函数就不会执行了,就需要我们手动释放内存。析构函数中抛出异常时,应该尽量封装在析构函数内部。

问题二十三:Visual Studio Code配置连接Linux服务器?

https://blog.csdn.net/qq_42897012/article/details/124393932

问题二十四:STL的set 和 map都是基于什么实现的?

map和set集合底层都是红黑树,可以通过模板来实现红黑树的创建,set集合传入值得类型,map传入键值对的类型。

问题二十五:描述下C++的浅copy,深copy,写时copy和引用计数的copy?

浅拷贝就是调用系统默认的拷贝构造函数,copy出内容相同且地址相同的结果,带来的问题就是,同一个地址就会被析构两次,程序容易崩溃,所以引入深拷贝对之前的地址再进行拷贝一份,使得拷贝的对象指向新的地址,缺点就是有点浪费空间。引入引用计数的方法来说明这个空间还有几个对象在使用,这样析构的时候就会减少相应的次数。

问题二十六:内存对齐原则?

cpu把内存分成一块一块的,有的是2字节,有的是4字节,因此cpu是一块一块读的,如果内存不对齐就会造成cpu的读取速率变慢,比如,数据从0字节开始读4个字节,读取0-3位置的字节一次即可,如果从1字节开始读,首先读0-3字节再读4-7字节,再需要把0 ,5-7字节给删除,最后合并1-4字节放入寄存器,也就是需要读取两次。

问题二十七:内联函数和宏定义有什么区别?

内联函数:inline int max(int a, int b);
宏定义:#define max(a,b)(a>b?a:b)
内联函数是一个函数,有有参数类型检查,比较安全,宏定义不属于函数,没有类型函数检查,不安全。

问题二十八:数组指针和指针数组?

数组指针是一个指针,该指针指向的是一个数组。指针数组是一个数组,数组元素中保存的是指针。

问题二十九:野指针?怎么产生的?解决野指针的方法?

野指针是指向一个已删除的对象或未申请访问受限内存区域的指针(野指针就是没有指向某个特定的内存的指针),也就是说内存空间释放掉后,指针赋值为空,这时候指针会指向任意地方或者指向了一个已经删除的对象地址。野指针和空指针不同,野指针是不能通过判断是否为空来避免的,所以我们要养成良好的编码习惯。
如何产生:1、指针变量没有被初始化,意思就是指针刚开始时不会被系统默认设值成空,它是随机的,会胡乱的指。
解决办法:指针变量在创建的同时应该被初始化,要么设值成null,要么让他指向合法的内存。
2、当指针p被free或delete之后,没有设置成null,让人误以为p是一个合法的指针;
解决办法:当指针被free或delete之后,我们应该及时的将指针指向null。
ps:野指针和空指针不是我们自己创建的,所以不要随意访问。

问题三十:常见的内存错误及其对策?

1、内存分配没有成功却使用了它,我们可以在使用内存之前检查指针是否为null(assert(p!=null))。
2、内存分配成功,但是尚未初始化。记住给内存赋值。
3、内存分配成功,已经初始化,但是操作越界。
4、忘记释放内存,造成内存泄漏。程序中malloc和free的使用次数一定要相同,(delete/new也一样。)
释放了内存,却继续使用它。

问题三十一:内存的三个对象?

c++将内存划分为三个区,堆、栈、静态存储区,栈的优势就是自动生成,自动销毁,分配堆的时候需要用到operator和new操作,而栈在创建对象时,则需要移动栈顶指针即可。堆创建和销毁都需要被程序员精确定义。静态存储区存储全局对象,还有静态的局部对象。

问题三十二:C++内存泄漏及其检测工具?

内存泄漏就是程序中动态分配的内存并没有正确的释放。
解决办法:1、new和delete,malloc和free应该成对出现。
2、使用智能指针,当我们申请一块内存或者new一个对象时,会导致多个指针指向同一个对象,当我们删除一个指针指向的对象时,其他指针指向的对象也就不存在了,这个时候这些指针就变成了悬垂指针。如果new的对象没有被delete方法执行时,就会造成内存泄漏。而智能指针的目的就是管理内存,避免内存泄漏和悬垂指针。
内存泄漏检测工具:valgrind工具。

问题三十三:什么时候要有虚析构函数?

通过父类的指针来删除子类的对象时,其析构函数也应该是虚的。一般情况下,父类的析构函数只能删除父类的对象,并不能删除从父类继承来的子类对象,这样容易造成内存泄漏。

问题三十四:#include <> 和#include ” ”的不同?

#include <> 引用的是编译器的类库路径下的头文件。
#include ” ”引用的是你程序目录的相对路径下的头文件。

问题三十五:引用作为函数的参数有哪些特点?

当函数的参数使用引用的方式传递参数时,实参的地址能够自动传入到调用的函数当中,并且在函数使用引用参数时,地址也会自动解引用为参数数值本身,函数中不需要使用指针操作符->,这些操作编译器可以自己完成。

问题三十六:什么时候使用常引用?

想提高程序的效率和保护传递给函数的数据不想在函数中被改变的时候就使用常引用。
常引用的格式:const 类型标识符 &引用名 = 目标变量名字;

问题三十七:STL实现了哪些排序算法?

我们将元素存放在内存中,按照元素多少分为内部排序(元素少)和外部排序。
内部排序:1、插入排序(直接插入、希尔排序);2、交换排序(冒泡排序、快速排序);3、选择排序(简单选择排序、堆排序);4、归并排序;具体c++代码见博客https://blog.csdn.net/weixin_41066529/article/details/89705238

问题三十八:C++中STL vector的实现机制?

1、vector属于动态数组,它在堆中分配内存,元素连续存放,当我们减少数组中大小后,内存也不会释放,如果新的大小大于当前大小时,系统会重新分配内存。
2、vector数组拥有一段连续的内存空间,所以支持随即存取,但是由于内存空间是连续的,所以在中间进行插入和删除会造成内存快的拷贝。当内存空间不足时,需要重新申请一块足够大的内存并进行内存的拷贝,这都会影响到vector的效率。
我们可以将类和结构放在vector中,这样可以避免移动时造成析构和构造。
我们可以使用capacity()查看当前的所能容纳的元素数量,如push1000,实际返回值就是16384,也可以使用swap减少使用的内存。

问题三十九:C++有哪些数据类型,为什么long和int都是4字节?

如有疏漏,还请指正。C语言开始时只有char(8位)和int(16位)两种,后来随着发展又加入了short(16位)和long(32位),此时,int可以是16位或者32位,依赖于平台和后续的兼容性。再后来当64位出现时,long long(64位)又被添加进来,为了进行规范,对较小的一些类型的范围就有了一些调整,逐渐稳定为int32位,long可以有多种定义,可以是32位,也可以是64位。
C++标准上只是说long至少要和int一样大,所有整数类型实现时要满足如下规范:
sizeof(char) == 1
sizeof(char) <= sizeof(short)
sizeof(short) <= sizeof(int)
sizeof(int) <= sizeof(long)
sizeof(long) <= sizeof(long long)
除了char和long long,其余的类型范围较灵活,都是平台相关的,与实现相关。如果要实现平台独立的话,在windows平台上,就有__intn可以使用,n代表位数。__int8 __int16 __int32 __int64。

问题四十:说说你使用的C++11的特性?

1、C++11中,可以使用auto来根据变量初始化表达式类型推导变量的实际类型,可以给程序的书写提供许多方便。将程序中c与it的类型换成auto,程序可以通过编译,而且更加简洁。

int main()
{
	short a = 32670;
	short b = 32670;
	// c如果给成short,会造成数据丢失,如果能够让编译器根据a+b的结果推导c的实际类型,就不会存在问题
	short c = a + b;
	std::map<std::string, std::string> m{ {"apple", "苹果"}, {"banana","香蕉"} };
	// 使用迭代器遍历容器, 迭代器类型太繁琐
	std::map<std::string, std::string>::iterator it = m.begin();
	while (it != m.end())
	{
		cout << it->first << " " << it->second << endl;
		++it;
	}
	return 0;
}
//---------------------------------------------------------
// 使用迭代器遍历容器, 迭代器类型太繁琐   可以使用auto
//std::map::iterator it = m.begin();
auto it = m.begin();

2、final修饰类的时候,表示该类不能被继承;
final修饰虚函数时,这个虚函数不能被重写;

class A final //表示该类是最后一个类
{
private:
	int _year;
};
class B : public A //无法继承
{
};

3、传统的C++就有引用,称为左值引用,C++11后,出了右值引用。无论是左值引用还是右值引用,都是给对象取别名(与对象共享一片空间)。
具体可以见这篇博客:https://blog.csdn.net/weixin_46873777/article/details/122948389

问题四十一:C++的继承?

C++软件工程师面试题汇总(祝各位秋招/春招顺利)_第2张图片

#include 
using namespace std;
class Shape{
    public:
        void setWidth(int s){
            width = s;
        }
        void setHeight(int h){
            height = h;
        }
    protected:
        int width;
        int height;
}
class zhengFX: public Shape
{
    int getArea()
    {
        return (width*height);
    }
}

int main()
{
    zhengFX zz;
    zz.setWidth(3);
    zz.setHeight(2);
    cout << zz.getArea() <<endl;
    return 0;
}

问题四十一:const修饰指针,常量指针,指针常量?

const int * p = &a ; 常量指针:指针的指向可以修改,但是指针指向的值不可以修改。
int * const p = &a ; 指针常量:指针指向的值可以修改,但是指针的指向不可以修改;

问题四十二:struct和class的区别?

1.struct 是值类型,class 是对象类型;
2.struct 不能被继承,class 可以被继承;
3.struct 默认的访问权限是public,而class 默认的访问权限是private;
4.struct总是有默认的构造函数,即使是重载默认构造函数仍然会保留。这是因为Struct的构造函数是由编译器自动生成的,但是如果重载构造函数,必需对struct中的变量全部初始化。并且Struct的用途是那些描述轻量级的对象,例如Line,Point等,并且效率比较高。class在没有重载构造函数时有默认的无参数构造函数,但是一被重载些默认构造函数将被覆盖;
5.struct的new和class的new是不同的。struct的new就是执行一下构造函数创建一个新实例再对所有的字段进行Copy。而class则是在堆上分配一块内存然后再执行构造函数,struct的内存并不是在new的时候分配的,而是在定义的时候分配;

问题四十三:友元函数?

友元函数不属于类的成员函数,但是友元函数必须在类内部定义。
友元函数的定义形式:friend 类型名 友元函数名(形参表);template< typename T> friend void getReal(Abstract< T> num);
首先,友元是一种定义在类外部的普通函数或类,但它需要在类体内进行说明,为了与该类的成员函数加以区别,在说明时前面加以关键字friend。友元不是成员函数,但是它可以访问类中的私有成员。
所以,友元声明只能出现在类定义中。因为友元不是授权类的成员,所以它不受其所在类的声明区域public private 和protected 的影响。

问题四十四:指针大小?

在32位系统下,所有指针类型的指针都是4个字节,因为不管地址内的空间多大,但是地址编号的长度是一样的,所以在32位操作系统中,地址都是四个字节。

线程、进程问题汇总

问题一:程序什么时候应该使用线程,什么时候单线程效率高?

1、耗时的操作使用线程,可以提高程序的执行效率;
2、并行操作时使用线程,比如C/S架构的服务器端并发线程响应用户的请求;
3、多个CPU系统中,使用线程提高CPU的利用率;
4,可以改善程序结构,一个复杂的进程可以考虑分为多个线程,独立的运行,这样程序可以更好的理解;
什么时候单线程效率更高呢?答:我们在处理时间短的服务或者启动频率高的程序用单线程。

问题二:进程间(IPC)的通信方式?

常见的通信方式:

1、文件:进程间可以经由fork,exec以及文件系统传送文件。(弃用)
2、管道pipe:管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
3、命名管道FIFO:有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。
4、消息队列MessageQueue:消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
5、共享内存SharedMemory:共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号量,配合使用,来实现进程间的同步和通信。
6、信号量Semaphore:信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
7、信号Signal : 信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。
8、unix域套接字:unix域套接字用于在同一台计算机上运行的进程之间的通信,其可以在两个进程间传送打开文件描述符。
9、套接字Socket:套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同机器间的进程通信。

问题三:进程间(IPC)几种锁的实现?

1、互斥锁:互斥锁mutex是当一个进程或线程在进入临界区后加锁,其他进程或线程在解锁前无法进入临界区的锁。
2、自旋锁:自旋锁spinlock与互斥锁类似,区别是互斥锁在遇到已被加锁的资源会切换线程,而自旋锁会一直循环等待,直到锁被释放。加锁后,CPU会一直等,即使时间片到了也不会切换线程。
3、读写锁:读写锁rdlock不建议使用,因为代码写起来会较为麻烦,只有在读多写少并且明确得知互斥锁性能不如读写锁是才使用。主要特点是允许多个线程同时读,但不允许多个线程同时写或者同时读写。

问题四:共享内存的实现原理?

共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式。两个不同进程A、B共享内存的意思是,同一块物理内存被映射到进程A、B各自的进程地址空间。进程A可以即时看到进程B对共享内存中数据的更新,反之亦然。由于多个进程共享同一块内存区域,必然需要某种同步机制,互斥锁和信号量都可以。
采用共享内存通信的一个显而易见的好处是效率高,因为进程可以直接读写内存,而不需要任何数据的拷贝。对于像管道和消息队列等通信方式,则需要在内核和用户空间进行四次的数据拷贝,而共享内存则只拷贝两次数据:一次从输入文件到共享内存区,另一次从共享内存区到输出文件。

问题五:进程和线程之间的区别?

Ⅰ 拥有资源
进程是资源分配的基本单位,但是线程不拥有资源,线程可以访问隶属进程的资源。
Ⅱ 调度
线程是独立调度的基本单位,在同一进程中,线程的切换不会引起进程切换,从一个进程中的线程切换到另一个进程中的线程时,会引起进程切换。
Ⅲ 系统开销
由于创建或撤销进程时,系统都要为之分配或回收资源,如内存空间、I/O 设备等,所付出的开销远大于创建或撤销线程时的开销。类似地,在进行进程切换时,涉及当前执行进程 CPU 环境的保存及新调度进程 CPU 环境的设置,而线程切换时只需保存和设置少量寄存器内容,开销很小。
Ⅳ 通信方面
线程间可以通过直接读写同一进程中的数据进行通信,但是进程通信需要借助 IPC。

问题六:进程调度算法?

不同环境的调度算法目标不同,因此需要针对不同环境来讨论调度算法。
#1. 批处理系统
批处理系统没有太多的用户操作,在该系统中,调度算法目标是保证吞吐量和周转时间(从提交到终止的时间)。
1.1 先来先服务 first-come first-serverd(FCFS)
非抢占式的调度算法,按照请求的顺序进行调度。
有利于长作业,但不利于短作业,因为短作业必须一直等待前面的长作业执行完毕才能执行,而长作业又需要执行很长时间,造成了短作业等待时间过长。
1.2 短作业优先 shortest job first(SJF)
非抢占式的调度算法,按估计运行时间最短的顺序进行调度。
长作业有可能会饿死,处于一直等待短作业执行完毕的状态。因为如果一直有短作业到来,那么长作业永远得不到调度。
1.3 最短剩余时间优先 shortest remaining time next(SRTN)
最短作业优先的抢占式版本,按剩余运行时间的顺序进行调度。 当一个新的作业到达时,其整个运行时间与当前进程的剩余时间作比较。如果新的进程需要的时间更少,则挂起当前进程,运行新的进程。否则新的进程等待。
1.4 优先级调度算法
1.5 基于时间片的轮转调度算法
基于时间片的轮转调度算法的基本思想是为就绪队列上的每个进程都分配一个时间片,即允许该进程运行的时间。

Linux问题汇总

问题一:与CPU、内存、磁盘相关的命令(top free df fdisk)?

总结:
磁盘:df,fdisk,du
内存:free,top
cpu:top
进程:top,lsof,netstat,ps

问题二:与网络相关的命令netstat , tcpdump ?

  1. ping命令是用来测试两个主机之间网络的连通性。
  2. tcpdump命令可以打印所有经过网络接口的数据包的头信息,也可以使用-w选项将数据包保存到文件中,方便以后分析。
  3. netstat命令用来打印Linux中网络系统的状态信息,可让你得知整个Linux系统的网络情况。

问题三:关机 (系统的关机、重启以及登出 ) ?

shutdown -h now 关闭系统
init 0 关闭系统
telinit 0 关闭系统
shutdown -h hours:minutes & 按预定时间关闭系统
shutdown -c 取消按预定时间关闭系统
shutdown -r now 重启
reboot 重启
logout 注销

问题四:文件和目录 ?

cd /home 进入 ‘/ home’ 目录’
cd … 返回上一级目录
cd …/… 返回上两级目录
cd 进入个人的主目录
cd ~user1 进入个人的主目录
cd - 返回上次所在的目录
pwd 显示工作路径
ls 查看目录中的文件
ls -F 查看目录中的文件
ls -l 显示文件和目录的详细资料
ls -a 显示隐藏文件
ls [0-9] 显示包含数字的文件名和目录名
tree 显示文件和目录由根目录开始的树形结构
lstree 显示文件和目录由根目录开始的树形结构
mkdir dir1 创建一个叫做 ‘dir1’ 的目录’
mkdir dir1 dir2 同时创建两个目录
mkdir -p /tmp/dir1/dir2 创建一个目录树
rm -f file1 删除一个叫做 ‘file1’ 的文件’
rmdir dir1 删除一个叫做 ‘dir1’ 的目录’
rm -rf dir1 删除一个叫做 ‘dir1’ 的目录并同时删除其内容
rm -rf dir1 dir2 同时删除两个目录及它们的内容
mv dir1 new_dir 重命名/移动 一个目录
cp file1 file2 复制一个文件
cp dir/* . 复制一个目录下的所有文件到当前工作目录
cp -a /tmp/dir1 . 复制一个目录到当前工作目录
cp -a dir1 dir2 复制一个目录
cp -r dir1 dir2 复制一个目录及子目录
ln -s file1 lnk1 创建一个指向文件或目录的软链接
ln file1 lnk1 创建一个指向文件或目录的物理链接

问题五:磁盘空间 ?

df -h 显示已经挂载的分区列表
ls -lSr |more 以尺寸大小排列文件和目录
du -sh dir1 估算目录 ‘dir1’ 已经使用的磁盘空间’
du -sk * | sort -rn 以容量大小为依据依次显示文件和目录的大小
rpm -q -a --qf ‘%10{SIZE}t%{NAME}n’ | sort -k1,1n 以大小为依据依次显示已安装的rpm包所使用的空间 (fedora, redhat类系统)
dpkg-query -W -f=‘ I n s t a l l e d − S i z e ; 10 t {Installed-Size;10}t InstalledSize;10t{Package}n’ | sort -k1,1n 以大小为依据显示已安装的deb包所使用的空间 (ubuntu, debian类系统)

问题六:网络 - (以太网和WIFI无线) ?

ifconfig eth0 显示一个以太网卡的配置
ifup eth0 启用一个 ‘eth0’ 网络设备
ifdown eth0 禁用一个 ‘eth0’ 网络设备
ifconfig eth0 192.168.1.1 netmask 255.255.255.0 控制IP地址
ifconfig eth0 promisc 设置 ‘eth0’ 成混杂模式以嗅探数据包 (sniffing)
dhclient eth0 以dhcp模式启用 ‘eth0’
route -n show routing table
route add -net 0/0 gw IP_Gateway configura default gateway
route add -net 192.168.0.0 netmask 255.255.0.0 gw 192.168.1.1 configure static route to reach network ‘192.168.0.0/16’
route del 0/0 gw IP_gateway remove static route
echo “1” > /proc/sys/net/ipv4/ip_forward activate ip routing
hostname show hostname of system
host www.example.com lookup hostname to resolve name to ip address and viceversa
nslookup www.example.com lookup hostname to resolve name to ip address and viceversa
ip link show show link status of all interfaces
mii-tool eth0 show link status of ‘eth0’
ethtool eth0 show statistics of network card ‘eth0’
netstat -tup show all active network connections and their PID
netstat -tupl show all network services listening on the system and their PID
tcpdump tcp port 80 show all HTTP traffic
iwlist scan show wireless networks
iwconfig eth1 show configuration of a wireless network card
hostname show hostname
host www.example.com lookup hostname to resolve name to ip address and viceversa
nslookup www.example.com lookup hostname to resolve name to ip address and viceversa
whois www.example.com lookup on Whois database

问题七:磁盘空间 ?

数据库(mysql)问题汇总

问题一:事务、ACID、隔离级别、数据库的脏读、不可重复读和幻读?

事务:在一组操作中,要么全do,要么not do,是不可分割的的数据库的操作序列。
ACID:原子性(最小单位,要么全做,要么全不做。);一致性(多个事务对同一数据读取结果一致。),隔离性(每个事物之间是独立的。),持久性(事务被提交后,对数据库的影响是永久的。)。
隔离级别:read uncommitted [读取未提交]:允许读取没有提交的数据变更,容易导致幻读,脏读,不可重复读;read committed [读取已提交]:允许读取并发事务,已提交的事务,容易导致幻读,不可重复读;repeatable read [可重复读]:同一字段的多次读取都是一致的,容易导致幻读;serializable [可串行化]:隔离的最高级别,完全服从acid,所以事务逐个执行,事物之间完全不受影响。
脏读:A事务读取数据,B事务读取同一份数据,但是A执行了回滚(回滚泛指程序更新失败, 返回上一次正确状态的行为,读到了其他事务未提交的数据,未提交意味着这些数据可能会回滚。)操作,则B读取的数据是不正确的。
不可重复读:A事务读取两次数据不一致,可能两次读取之间更新了数据。
幻读:A事务查询中数据的笔数不一致。A读取数据,B插入了几列数据,A再读就读多了。

问题二:ACID靠什么保证?

1、原子性是由undo log日志保证,它记录了需要回滚的日志信息,事务回滚时会撤销已经执行成功的SQL。
2、一致性是由其他三个特性保证的程序代码要保证业务的一致性;
3、隔离性由MVCC(多版本并发控制)来保证;
4、持久性由redolog来保证,MySQL修改数据的时候会在redolog中记录一份日志数据,就算数据没有保存成功,数据仍然不会丢失;

问题三:怎么处理MySQL的慢查询?

慢查询定义:将超过指定时间的sql查询语句称为慢查询。
解决办法
1、开启慢查询日志,准确定位到哪个sql语句出现了问题。
2、分析sql语句,看看是否load了额外的数据,可能查询了多余的行并且抛弃掉了,也有可能是加载了许多结果中不需要的列,对语句进行多余的分析和重写。
3、分析语句的执行计划,然后获得其使用索引的情况,之后修改语句或者修改索引使得语句可以尽可能的命中索引。
4、如果对语句的优化已经无法进行了,可以考虑表中的数据是否太大,如果是的话可以横向或者纵向的分表。

问题四:MySQL锁?

根据属性分类:1、共享锁(读锁S):当一个事务为数据加上读锁,其他事务也只能加上读锁,只有释放其他的读锁,才能加写锁;2、排他锁(写锁X):当一个事务为数据加上写锁,其他事务不能加任何锁,直到写锁释放;
根据粒度分类:1、表锁:锁住整张表,当下一个事务访问该表的时候,需等待释放锁,特点是粒度大,加锁简单,容易冲突;2行锁:锁住的是某一行、或多行数据,当事务访问时,只有锁住的记录不能访问,其他的记录可以正常访问,特点是力度小,加锁比表锁麻烦,不容易冲突;
目的:1、共享锁为了支持并发的读取数据,读取数据的时候不支持修改,避免出现重复读的问题。2、排他锁为了在数据修改的时候,不允许其他人同时修改,也不允许其他人读取,避免出现脏读的现象。

问题五:MySQL索引以及索引结构?

索引在MySQL中就是一种“键”,目的是提高查询效率;本质就是通过不断地缩小想要获取数据的范围来筛选出最终想要的结果。
存储引擎分类
1、innodb(B+树索引):B+树是一种平衡二叉树,其叶子节点为一个双向链表,并且叶子节点上只有data数据,而非叶子节点只有索引数据(B和B+树的不同点:1、叶子节点为双向链表结构;2、B树不仅叶子节点有数据,其他节点也有数据;)。 PS:B+树索引的关键字检索效率比较平均,没有B树那样波动大。
2、myisam(hash索引):hash算法建立索引,将键值换算成新的哈希值检索时,不需要像B+树那样从根节点到叶子节点逐级查询,只需要进行一次哈希算法即可定位到相应位置。
索引分类
1、普通索引:允许被索引的数据列包含重复的值。
2、唯一索引:可以保证数据的唯一性。
3、主键索引:一种特殊的唯一索引,在一张表中只能定义一个主键索引,主键用于唯一标识一条记录,使用关键字primary key来创建。
4、联合索引:索引可以覆盖多个数据列。
5、全文索引:通过建立倒排索引,可以极大的提升检索效率,解决判断字段是否包含的问题,是目前搜索引擎使用的关键技术。
缺点:索引虽然可以极大的提高数据的查询效率,但是会降低数据插入、删除、更新表的速度,因为需要操作索引文件,而且还会占用物理空间。

问题六:MySQL聚簇索引和非聚簇索引?

首先我们确定索引是存放在磁盘里的,innodb是默认的存储引擎。
MySQL的索引类型是和存储引擎相关的,而区分聚簇引擎和非聚簇索引的条件就是判断数据和索引是否放在同一个地方
1、innodb -> 数据索引放在 -> ibd文件中。
2、myisam -> 数据放在 -> myb文件。索引放在 -> myi文件中。
innodb在插入数据时,数据必须和索引放在一起,有主键使用主键,没有则用唯一键。因此,数据和索引绑在一起就是聚簇索引。
innodb既有聚簇索引,也有非聚簇索引。myisam只有非聚簇索引。

问题七:MySQL和oracle的区别?

1、Oracle数据库是一个对象关系数据库管理系统,是一个收费的数据库。MySQL是一个开源的关系数据库管理系统,是一个开源、免费的数据库。
2、MySQL使用三个参数来验证用户,即用户名,密码和位置;Oracle使用了许多安全功能,如用户名,密码,配置文件,本地身份验证,外部身份验证,高级安全增强功能等。
3、Oracle数据库支持从数据库内部编写,编译和执行的几种编程语言。此外,为了传输数据,Oracle数据库使用XML。MySQL不支持在系统内执行其他语言,也不支持XML。

计算机网络问题汇总

问题一:HTTP状态码?

C++软件工程师面试题汇总(祝各位秋招/春招顺利)_第3张图片

问题二:物理层简介?

首先通信方式:1、单工通信:单向传输;2、半双工通信:双向传递;3、全双工通信:双向同时传递;
带通调制:将数字信号转换成模拟信号(离散信号变为连续信号);
1B=8b(字节)=8个二进制位,1KB=1024B;
物理层的主要设备:中继器、集线器;

问题三:数据链路层简介?

信道分类:1、广播信道:(1)、信道复用技术(频分、时分、码分、波分,CSMA/CD技术)-避免发送数据产生冲突;2、点对点信道:ppp协议控制;
CSMA/CD:载波监听、多点接入、碰撞检测;
功能:封装成帧、透明传输(透明传输部分是转义字符)、差错检测(循环冗余检测(CRC)来检查比特差错);

问题四:网络层简介?

网络层协议划分:1、IP(子网划分);2、ARP(地址解析协议)IP地址转成MAC地址;3、ICMP(网际控制报文协议)封装在IP数据报中,为了更有效的转发IP数据报【差错报告报文、询问报文】;4、IGMP(网际组管理协议);
IP:分类:网络号,主机号,A类8位,B类16位,C类24位;子网划分:<网络号、子网号、主机号>
网络地址转换NAT:将本地IP转换为全球IP;
内部网关协议:RIP(基于距离向量的路由选择协议);OSPF(开放最短路径优先)
外部网关协议:BGP

问题五:计算机网络各层

C++软件工程师面试题汇总(祝各位秋招/春招顺利)_第4张图片

问题六:TCP三次握手、四次挥手

四次挥手的原因:
客户端发送了 FIN 连接释放报文之后,服务器收到了这个报文,就进入了 CLOSE-WAIT 状态。这个状态是为了让服务器端发送还未传送完毕的数据,传送完毕之后,服务器会发送 FIN 连接释放报文。
TIME_WAIT
客户端接收到服务器端的 FIN 报文后进入此状态,此时并不是直接进入 CLOSED 状态,还需要等待一个时间计时器设置的时间 2MSL。这么做有两个理由:
确保最后一个确认报文能够到达。如果 B 没收到 A 发送来的确认报文,那么就会重新发送连接释放请求报文,A 等待一段时间就是为了处理这种情况的发生。

三次握手的原因:
第三次握手是为了防止失效的连接请求到达服务器,让服务器错误打开连接。
客户端发送的连接请求如果在网络中滞留,那么就会隔很长一段时间才能收到服务器端发回的连接确认。客户端等待一个超时重传时间之后,就会重新请求连接。但是这个滞留的连接请求最后还是会到达服务器,如果不进行三次握手,那么服务器就会打开两个连接。如果有第三次握手,客户端会忽略服务器之后发送的对滞留连接请求的连接确认,不进行第三次握手,因此就不会再次打开连接。
等待一段时间是为了让本连接持续时间内所产生的所有报文都从网络中消失,使得下一个新的连接不会出现旧的连接请求报文。

问题七:TCP如何保证可靠性?

1、三次握手和四次挥手确保连接和断开的可靠性;
2、TCP通过校验和、ACK应答、超时重传来记录 哪些数据被接受,保证数据传输不出差错;
3、TCP通过流量控制(滑动窗口)和拥塞控制来控制发送方发送速率,说明可控制。
校验和:将TCP首部,TCP数据、TCP伪首部进行反码相加,将结果放在检验和字段中,接收方用相同的方法进行计算,最终全为1则正确;

问题八:cookie和session的区别?

1、session的主要作用是通过服务端记录用户的状态;
2、cookie数据保存在客户端(浏览器),session数据保存在服务端。相对来说session安全性更高一些,但是如果使用cookie的话,一些敏感信息不要写入从cookie中,最好能将cookie信息加密到服务端进行解密;

设计模式问题汇总

问题一:你遇到过的设计模式有哪些?

简单工厂模式和工厂模式 https://blog.csdn.net/kenjianqi1647/article/details/119632618

测试工程师问题汇总

问题一:黑盒测试和白盒测试?

黑盒测试:(功能测试,非功能测试和回归测)在测试的时候,不考虑盒子里面的逻辑结果跟程序运行,只是根据程序的需求规格书来检查程序的功能是否符合它的功能说明,检验输出结果正不正确。
白盒测试:测试人员会利用程序内部的逻辑结构及有关信息,通过在不同点检查程序状态,检验程序中的每条通路是否都能按预定要求进行正确工作。

TIPS…

如果觉得博主写的还不错,欢迎批评指正,如过觉得有帮助,可以请博主喝杯奶茶。

你可能感兴趣的:(c++,c++,面试,开发语言,求职招聘)