成都精灵云初试

    最近参加了成都精灵云的笔试与面试,岗位是c++工程师。后面自己复盘了过程,初试部分总结如下,希望能对各位相进该公司以及面试C++工程师的同学提供一些参考。这也是博主第一次参加面试,很多东西都还没准备,很多答得不好,所以显得有些问题很突兀。
    后续也会陆续分享各公司的面试和笔试经验在该专栏,想看的可以关注一下博主!

正文开始

    首先是做自我介绍,个人觉得尽可能讲和找工作有关,展现自己能力的内容即可。

    下面是问答环节(前方高能!!!):

Q:解释一下static关键字
A:static用来控制变量的存储方式和可见性,static函数,仅该文件可见;static全局变量,仅该文件可见;static局部变量,改变该局部变量的生存期

    更多关于static原理可见博客 static关键字详解

Q:static定义的全局变量(为什么问这题是因为上面没答到仅该文件可见)
A:表明这是一个静态全局变量,使该变量仅在这个源文件中可用

Q:解释一下const关键字
A:用const修饰,意味着该变量的数据只能被访问,而不能被修改,意味着“只读”

Q:const修饰指针有几种,分别是什么
A:有三种,const修饰指针——常量指针;const修饰常量——指针常量;const既修饰指针又修饰常量

Q:const修饰成员变量和成员函数
A:const修饰的成员变量相当于该变量是一个常量,所以只能初始化列表上的初始化
const修饰的成员函数,事实上修饰的是成员函数隐藏的this指针,表示该成员函数不能对类的成员变量修饰,所以const不可以修饰构造函数,析构函数和赋值运算重载符

Q:解释一下什么是内联函数
A:为了消除函数调用的时空开销,c++提供一种提高效率的方法,即在编译时将函数调用处用函数体替换,类似于C语言中的宏展开,这种在函数调用处直接嵌入函数体的函数称为内联函数
Q:追问——调用函数会有什么开销
A:我在回答函数调用的过程来解释时空开销,于是HR直接问我下一个问题

Q:简述一下函数调用过程
A:将当前运行地址压入栈中;
  将参数压入栈中,如果参数较少的话会直接存到寄存器中;
  跳转到目标函数地址;
  执行函数体;
  销毁局部变量和函数形参;
  弹出调用者的运行地址;
  跳转回调用方;

Q:程序调用完是如何跳回调用方的
A:函数的调用和返回是通过调用栈来管理的,每当调用一个函数,程序会将当前函数的上下文全部压入调用栈中,然后开始执行被调用的函数,当被调用的函数执行完毕并准备返回时,程序会从调用栈中弹出该函数的上下文,并将控制权返回给调用方
在底层中使用的是程序计数器PC,储存当前正在执行的指令地址,当函数被调用时,PC的值会被保存到调用栈中的函数上下文中,当函数返回时,程序计数器的值将从调用栈中的函数上下文中回复,以便程序继续执行调用方函数的下一条指令

Q:解释一下SP指针(为什么问这个,是因为我把PC指针记成SP指针了,搞混了,啊啊啊啊啊啊,好尴尬)
A:SP指针是堆栈指针,用于出栈和入栈操作

Q:malloc和new的区别
A:malloc是函数,而new是关键字;malloc不会调用构造函数,new会调用构造函数;malloc是在堆区动态分配内存,new是在自由存储区动态分配内存;new会严格返回对象类型指针,malloc返回的是void指针,需要强制转换;new失败会抛出bac_alloc异常,malloc会返回null;new会根据对象类型自动分配大小,而malloc需要指定开辟空间大小

    具体还有区别可以详见 细说new与malloc的区别

Q:如果用malloc分配了一个地址,那么地址上的值为多少,如果是new的呢?
A:malloc函数申请的空间在没有使用前,空间里面存放的是随机值
new的话后面不加(),则不会被初始化,是随机值,如果加了(),其值为0

Q:重载函数和虚函数的区别
A:重载函数只要求函数有相同的函数名,并且重载函数是在相同作用域内定义的名字相同的不同函数;而虚函数不仅要求函数名相同,而且要求函数的签名,返回类型也相同,也就是说函数原型必须完全相同,而且虚函数特性必定是体现在基类和派生类的类层次结构中。
  重载函数可以是成员函数或友元函数,虚函数只能是非静态成员函数
  构造函数可以重载,析构函数不可以重载;构造函数不能被定义为虚函数,析构函数能定义为虚函数
  重载函数的调用是以传递参数序列的差别作为调用不同函数的依据,而虚函数是根据对象的不同区调用不同类的函数
  重载函数在编译时表现出多态性,是静态联编,虚函数则在运行时表现出多态性,是动态联编

Q:讲一下虚函数和虚函数表的关系
A:多态是由虚函数实现的,虚函数主要是通过虚函数表来实现的。在这个表中,主要是一个类的虚函数的地址表,这张表解决了集成覆盖的问题,在有虚函数的实例中,这张表被分配在这个实例的内存中,所以当我们用父类指针来操作一个子类时,这张虚函数表就像地图一样指明实际所应该调用的函数

Q:讲一下链式结构和顺序结构的优缺点
A:顺序存储结构是一段连续的存储单元,依次存储线性表的数据元素;链式存储结构是一组任意的存储单元,存放线性表的元素
线性表查找很方便,但插入删除较为麻烦
链式结构插入删除很方便,但查找较为麻烦

Q:如何让链式结构也方便查找
A:维护一个额外索引数据结构,每个索引节点指向链表中的一个元素,这样就可以在索引结构中快速查找,再根据链表中的指针找到具体的元素

Q:进程之间如何通信
A:消息传递(管道,FIFO,posix和消息队列)
 同步(互斥锁,条件变量,读写锁,文件和记录锁,Posix和System V信号灯)
 共享内存区(匿名共享内存区,有名Posix共享内存区,有名System V共享内存区)
 过程调用

Q:如何创建一个管道
A:windows中使用函数CreatePipe(),Unix/Linux中使用pipe()

Q:解释一下什么是智能指针
A:智能指针是帮忙管理动态分配的内存,帮助我们自动释放new出来的内存,避免内存泄露的

Q:解释一下tcp协议的三次握手,四次握手
A:tcp的三次握手是为了建立可靠的连接,首先客户端向服务器发送请求,客户端切换到发送状态,服务器处于侦听状态,侦听到请求后,服务器返回一个确认,服务器变为接收状态,客户端收到确认后返回一个确认给服务器,表示自己收到服务器返回信息,客户端切换到连接状态,服务器收到信息后正式建立连接。
  tcp的四次握手是为了确保客户端和服务器端断开连接请求和数据传输完成:首先客户端发送断开连接请求,服务器收到后发送确认给客户端,客户端收到确认后进入半连接状态,表示只能收不能发。服务器传完信息就向客户端发送断开请求,客户端收到后返回一个确认,服务器接收后断开连接请求,客户端等待2个最大报文生存时间后断开连接。
  不让服务器在传输信息的同时返回确认连接的原因:TCP有超时重传机制,时间较短,等待服务器传输完,估计客户端会重发很多个。

你可能感兴趣的:(面经系列,C与C++,c++,面试,学习)