C++ 面试题目演练

继承多态,内存分配和管理等

STL中如何进行内存管理,TCP协议的相关知识,TCP三次握手,TCP和UDP的区别等等。请说下数据库中事物的特征,数据库索引有几种类别,hash索引,也就
是散列索引,HTTP返回码伙伴系统、slab缓存

《C++ 面试题目演练》

 

TCP和UDP的区别

TCP面向连接,UDP不面向连接

TCP可靠,UDP不可靠

TCP传输字节流, UDP传输数据报

 

TCPUDP区别

  • TCP面向连接(三次握手),通信前需要先建立连接;UDP面向无连接,通信前不需要连接。
  • TCP通过序号、重传、流量控制、拥塞控制实现可靠传输;UDP不保障可靠传输,尽最大努力交付。
  • TCP面向字节流传输,因此可以被分割并在接收端重组;UDP面向数据报传输。

 

TCP为什么不是两次握手而是三次

如果仅两次连接可能出现一种情况:客户端发送完连接报文(第一次握手)后由于网络不好,延时很久后报文到达服务端,服务端接收到报文后向客户端发起连接(第二次握手)。此时客户端会认定此报文为失效报文,但在两次握手情况下服务端会认为已经建立起了连接,服务端会一直等待客户端发送数据,但因为客户端会认为服务端第二次握手的回复是对失效请求的回复,不会去处理。这就造成了服务端一直等待客户端数据的情况,浪费资源。

 

 

《C++ 面试题目演练》

 

TCP为什么挥手是四次而不是三次

TCP是全双工的,它允许两个方向的数据传输被独立关闭。当主动发起关闭的一方关闭连接之后,TCP进入半关闭状态,此时主动方可以只关闭输出流。

在上面的图中, 前两次挥手,客户端传输连接关闭,后来次挥手,服务器传输连接关闭。

之所以不是三次而是四次主要是因为被动关闭方将对主动关闭报文的确认关闭连接两个操作分两次进行。

对主动关闭报文的确认是为了快速告知主动关闭方,此关闭连接报文已经收到。此时被动方不立即关闭连接是为了将缓冲中剩下的数据从输出流发回主动关闭方(主动方接收到数据后同样要进行确认),因此要把确认关闭关闭连接分两次进行。

 

 

大端与小端的概念;time_wait状态的产生原因,危害,如何避免;select/poll/epoll的区别;epoll中ET和LT的区别;UDP协议的使用领域;守护、僵尸、孤儿进
程这种概念,滑动窗口协议

 

TIME_WAIT(2MSL)

  1. 确保最后一个确认报文段能够到达。如果 B 没收到 A 发送来的确认报文段,那么就会重新发送连接释放请求报文段,A 等待一段时间就是为了处理这种情况的发生。
  2. 可能存在“已失效的连接请求报文段”,为了防止这种报文段出现在本次连接之外,需要等待一段时间。防止串话。

 

滑动窗口,分成四段

《C++ 面试题目演练》

 

与为啥需要采用三次握 手;(4)C++ Static关键 字; (6)C++迭代器失效问题(iterator原理); (7)map /set容器的实现原理(红黑树知识+STL容器
内部原理);

 

(2)Linux 伙伴堆算法(slab)实现的原理, 以及与普通内 存分配相比有什么优势(Linux内核); (3)Linux 高并发的实现, 线程池的实现思想, 怎样处
理高并发(根据项目来 问); (4) Linux 写一个并发测试程序; (5) 如何实现一个String, 他的内存是长什么样的(STL内部实现);红黑树的性质,旋
转、插入、删除操作
哈希表解决冲突的方法及优缺点

1.开放定址法(闭哈希表)

2.拉链法

如何设计好的散列函数

inux下如何查看cpu使用率

top命令

 

手写程序:两个大量无序无重复数组,筛出其中相同元素
解法:(1)哈希,时间复杂度低 (2)直接排序,空间复杂度低

 

c++类成员函数的重载,覆蓋和隐藏有什么区别?

1.成员函数被重载的特征:

(1)相同的范围(在同一个类中);

(2)函数名字相同;

(3)参数不同;

(4)virtual 关键字可有可无。

2.覆蓋是指派生类函数覆蓋基类函数,特征是:            覆蓋重写

(1)不同的范围(分别位于派生类与基类);

(2)函数名字相同;

(3)参数相同;

(4)基类函数必须有virtual 关键字。

 

3.“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下:

(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。

(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual 关键字。此时,基类的函数被隐藏(注意别与覆蓋混淆)。

 

#include<iostream>
using namespace std;

class People {
public:
	// 隐藏:是指派生类的函数屏蔽基类函数
	// 隐藏规则1:
	// 1) 函数名相同 && 参数不同
	// 2) virtual不影响
	void getId_different_params() { cout << "People::getId_different_params" << endl; }
	virtual void getName_different_params() { cout << "People::getName_different_params" << endl; }

	// 隐藏规则2:
	// 1) 函数名相同 && 参数相同
	// 2) 无virtual
	void getPhone_same_params() { cout << "People::getPhone_same_params" << endl; }

	// 覆蓋规则:
	// 1) 函数名相同 && 参数相同
	// 2) 有virtual
	virtual void getAddress_same_params() { cout << "People::getAddress_same_params" << endl; }
};

class Children : public People {
public:
	// 隐藏:是指派生类的函数屏蔽基类函数
	// 隐藏规则1:
	// 1) 函数名相同 && 参数不同
	// 2) virtual不影响
	void getId_different_params(int) { cout << "Children::getId_different_params(int)" << endl; }
	virtual void getName_different_params(int) { cout << "Children::getName_different_params(int)" << endl; }

	// 隐藏规则2:
	// 1) 函数名相同 && 参数相同
	// 2) 无virtual
	void getPhone_same_params() { cout << "Children::getPhone_same_params" << endl; }

	// 覆蓋规则:
	// 1) 函数名相同 && 参数相同
	// 2) 有virtual
	virtual void getAddress_same_params() { cout << "Children::getAddress_same_params" << endl; }
};

int main()
{

	Children *c = new Children();      
	c->getId_different_params(1);             // 派生类函数重载
	c->getName_different_params(1);           // 加了虚函数仍然为重载函数
	c->getPhone_same_params();                // 函数名相同,参数相同,无虚函数,隐藏
	c->getAddress_same_params();              // 函数名相同,参数相同,有虚函数, 覆蓋

	cout << endl;

	People *p = new Children();                        
	p->getId_different_params();              // 重载,调用基类
	p->getName_different_params();            // 重载,调用基类
	p->getPhone_same_params();                // 只是隐藏,基类指针调用
	p->getAddress_same_params();              // 多态, 调用派生类

}

 

动态链接与静态链接的区别

两个差别(一)静态链接库与动态链接库都是共享代码的方式,如果采用静态链接库,lib中的指令都全部被直接包含在最终生成的exe文件中了。但是若使用dll动态链接库,该dll不必被包含在最终的exe文件中,执行文件执行时可以动态地引用和卸载这个与exe独立的dll文件(二)静态链接库不能再包含其他的动态链接库或者静态库,而在动态链接库中还可以再包含其他的动态或静态链接库。 使用差别静态链接库动态链接库使用的区别在于它允许可执行模块(dll或exe文件)仅包含在运行时定位dll函数的可执行代码的所需信息。静态链接库的使用中,连接器从静态链接库获取所有被引用的函数,并将库同代码一起放到可执行文件中。

数据库接触过什么?优化呢?分页和分表的区别。MySQL数据库使用什么引擎。索引实现,索引的使用。
最后问了一个平衡二叉树的反向排序vector为什么每一次扩容都是2倍

 

tcp/ip卷一tcp那章所有内容都考到了,包括PAWS,几种定时器
C++语言方面除了 各种关键字,还问到了迭代器种类(偏特化,type_traits),考了STL源码剖析前三章。C++内存模型只问虚函数。腾讯问了Array模板类的实现改

 

设计模式问了装饰,适配器,代理区别,做后台必须明白reactor是哪几个模式合成的吧
BST(二叉搜索树)的查找算法TCP接收方如何保证按序接收
现场写一个程序,双向链表,包含节点的定义、插入、删除、查找,手写快速排序
拥塞控制和流量控制分别是什么概念,流量控制的过程,分别要解决什么问题

TCP 流量控制

流量控制是为了控制发送方发送速率,保证接收方来得及接收。

接收方发送的确认报文中的窗口字段可以用来控制发送方窗口大小,从而影响发送方的发送速率。例如将窗口字段设置为 0,则发送方不能发送数据。

TCP 拥塞控制

拥塞机制是在传输过程中的拥塞。

大数据的解法无非那么几种,常见的就是hash和bitmap,这个网上都有很详细的帖子讲解,自己去百度这一段
链表删除结点、二叉树的层第遍历非递归、二叉树的后序非递归遍历
链表的逆置strlen的常规写法 和 递归写法

2.strcpy 和strncpy 的代码和区别, 这里你要说本质区别,就是strcpy不安全,有可能cpy越界

 

3.快速排序和复杂度 代码

4.一个文本文件,包含很多字符串,要求用伪代码求出 每个字符串出现的次数 我用的 STL里的map实现的, HashMap

(1) 多态性都有哪些?(静态和动态,然后分别叙述了一下虚函数和函数重载)
(2) 动态绑定怎么实现?(就是问了一下基类与派生类指针和引用的转换问题)

(3) 类型转换有哪些?(四种类型转换,分别举例说明)
(4) 操作符重载(+操作符),具体如何去定义,?(让把操作符重载函数原型说一遍)

(5) 内存对齐的原则?(原则叙述了一下并举例说明)
(6) 模版怎么实现?
(7) 指针和const的用法?(就是四种情况说了一下)
(8) 虚函数、纯虚函数、虚函数与析构函数?(纯虚函数如何定义,为什么析构函数要定义成虚函数)

(9) 内联函数(讲了一下内联函数的优点以及和宏定义的区别)

宏定义不会检查,只会展开

(10) const和typedef(主要讲了const的用处,有那些优点)

const表示只读

typedef 表示自定义数据结构
(11) 排序算法有哪些?快速排序怎么实现的?最好时间复杂度,平均时间复杂度
(12) 链接指示:extern “C”(作用)         

extern是计算机语言中的一个关键字,可置于变量或者函数前,以表示变量或者函数的定义在别的文件中

(13) c语言和c++有什么区别?(大体讲了 一下,继承、多态、封装、异常处理等)
(5) strcpy函数的编写?(这个函数很熟悉,后来阿里校招面试也让现场编写了)

 

(6) 数据结构中二叉树的非递归遍历?(现场画图举例讲解的,所以大家面试的时候尽量多动笔)

(7) c++中四种类型转换机制?

(8) 继承机制中对象之间是如何转换的?

(9) 继承机制中引用和指针之间如何转换?

(10) 虚函数,虚函数表里面内存如何分配?

(11) 如何实现只能动态分配类对象,不能定义类对象?(这个牛客上的题目,我把如何只能动态分配和只能静态分配都讲了一下)

(12) stl有哪些容器,对比vector和set?

(13) 红黑树的定义和解释?

(14) const关键字的作用?

(const成员函数,函数传递,和define的区别)
(15) 静态成员函数和数据成员有什么意义?

静态成员函数是所有对象共有的。
(16) 模版特化的概念,为什么特化?

泛型编程。
(17) explicit是干什么用的?

C++提供了关键字explicit,可以阻止不应该允许的经过转换构造函数进行的隐式转换的发生。声明为explicit的构造函数不能在隐式转换中使用。
(18) strcpy返回类型是干嘛用的?

拷贝字符串
(19) 内存溢出有那些因素?
(20) new与malloc的区别,delet和free的区别?

new是运算符,malloc 是函数,malloc要指定大小,返回void*
(21) 为什么要用static_cast转换而不用c语言中的转换?

更完全
(22) 异常机制是怎么回事?
(23) 迭代器删除元素的会发生什么?

迭代器会指向下一个迭代器
(24) 必须在构造函数初始化式里进行初始化的数据成员有哪

(25) 类的封装:private,protected,public
(26) auto_ptr类:
操作系统知识,线程、进程,他俩的区别于相同点,何时使用它们,同步(通信)方式,这就又延伸到共享内存、信号、信号量、各种锁。同样的回答这些问题时,你要
回答的不一样,比较深入才行。比如从原理,历史来源、论文、改进方式、源代码开始讲,一层层的讲出这些设计的本质,面试官会比较喜欢的。

3 、源代码
重点部分:文件系统、进程管理、进程切换、内存管理这几个部分,其中文件管理和内存管理尤为重要。包括 vfs 虚拟文件系统,一个完整的文件操作过程比
如 read 、 write 等等,文件映射mmap ,共享内存等等可能需要花一点时间理解这些东西。
3、 网络部分
网络不管你是想从事哪个方向,基本都是重中之重
我的学习方式:看书和看源代码,由于 tcpip 是开源的,可以仔细看看其中状态转换过程。
Tcp 最为人知的三次握手和 4 次挥手,你一定要能够讲得出为什么,每一次出现错误会怎么样,为什么要 3\4 次,少了行不行。
比如什么情况会有 flood 攻击, timewait 攻击等等
在 tcp 中如何实时监测断线情况,以及实现断线重连等等
另外还有很重要的拥塞控制、拥塞避免,慢开始算法、快重传快恢复, ttl 时间计算。
推荐一本很好的书《 linux 高性能服务器编程》、以及《 Linux 网络编程实战》也不错。
当然啦 unix 网络编程, tcp 三卷是不能少的。

 

C/C++相关
1 虚析构、模板和宏

2 虚函数实现机制

虚函数表,虚函数表指针
3 vector与list的区别,map是如何实现的,查找效率是多少

4 extern 关键字有什么用

extern是计算机语言中的一个关键字,可置于变量或者函数前,以表示变量或者函数的定义在别的文件中
5 malloc和new的区别,能否malloc(1.2G)

 

linux以及操作系统相关
1 内存池实现
2 进程间通信机制
3 Linux ps命令,以及看内存当前使用状态的命令
4 进程与线程的区别,共享的数据
5 进程的内存空间

 

算法与数据结构 (手写代码实现)
1 大整数加、减、乘、除、求模运算实现
2 很多整数,找其中出现次数最多的那个数
3 单链表翻转(两个指针如何实现)、查找、删除、插入以及双向链表、有序链表合并
4 判断一个整数是否是2的整数次幂.(n&(n1))
5 二分查找(注意边界条件)
6 常见排序算法的实现以及稳定性(快排跟归并考的很多)
7 字符串翻转(O(n))、匹配(KMP算法)
8 最长递增子序列(nlogn的算法)
9 链表判断是否有环,环的入口,两个链表是否相交(快慢指针)。
10 指定一个数组,求2个数的和等于指定的和(某一个数),如果是3,4,5,n个等于个的和(某一个数)呢?(可以看作揹包问题)
11 跳台阶问题

 

其他
1 红黑树的性质以及插入和删除
2 解析XML文件
3 千万级的用户,提供一个服务,该服务有很多模块,现在有一个底层模块需要优化,问怎么实现,在不影响其他服务模块以及用户体验的情况下。(面IEG)
4 卡特兰数以及公式推导(应多很多)
5 未知大小的文件,翻转整个文件
6 如果内存中有个cache存储qq号和最近登录时间问怎么样做hit和淘汰
7 检测短信敏感词
8 大数据问题
9 C++、java和PHP有什么本质区别

 

自我介绍
排序的稳定性是什么,什么样的排序是稳定的?

对C++的学习掌握情况怎样?

一个C++程序从编译到运行都经历了哪些阶段?

C++的特点是什么?

C++多态是怎么实现的?

static和const关键字是干什么的?
举例自己熟悉的设计模式,并且解释观察者模式
设计模式在平时应用的情况
tcp udp位于什么层,有什么区别?
linux命令的举例

一个32位机器上linux进程最大可以申请多少空间?

大端法和小端法指的是什么?在纸上写一个程序进行验证

对java和mysql的询问

平时爱读什么技术书?
平时爱不爱玩游戏,对做游戏抵触不抵触?

 

 

点赞