欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C++面试总结

程序员文章站 2022-03-07 22:42:43
...

1.普通成员函数可以作为线程的入口函数吗?##

不可以,但是可以传递一个static的成员方法,再在这个static成员方法中调用普通的成员函数,或者将一个普通的成员函数申明为友元函数,用这个友元函数可以传给线程入口。

2.vector和list的区别,哪个随机访问更快,哪个插入更快,在尾部插入哪个更快##

  • 由于vector基于连续内存的数组,所以它的随机存取非常快,但是插入和删除就会很耗时,插入删除会重新拷贝内存,若内存空间不足还会重新申请内存。
  • list是基于双向链表,所以它的删除和插入很快,但随机存取很慢。如果实在尾部插入,用list更合适,如果用vector的话可能导致空间不足而重新生成一片空间,在将数据完全拷贝过去。
  • map是键值对,基于红黑树,有自动排序的功能,存储字典的时候很适用
  • set是集合,并且set中不会包含重复元素,内部使用平衡二叉树实现,便于元素查找。
  • deque队列,支持随机存取,而且在两端的操作速度和list相差不大

3.线程同步时,死锁是如何产生的##

一个线程需要多个加锁资源时,可能导致死锁的产生。例如线程1,2都需要资源A和B,当线程1获取到资源A,线程2获取到资源B,此时线程1等待线程2释放资源B,但是线程2又在等待线程1释放资源A,这时死锁就产生了。

4.写文件到磁盘的过程##

先将数据写入缓冲区,如果缓冲区满,则将缓冲区的内容写入磁盘文件,或者flash缓冲区。close文件描述符的时候也会将数据从缓冲区写入磁盘。

5.TCP心跳包的作用##

由于系统keeplive参数的默认设置情况下的短线检测时间是7200秒,时间非常的长,这对于实时通讯要求比较高的连接来说是很不合适的,所以需要我们自己设定心跳的时间等参数。

6.说一下boos中share_ptr和scoped_ptr的区别##

  • shared_ptr可以有多个指针指向同一个地址来享有共享权,内部包含一个引用计数,当这个指向这个地址的share_ptr全部都离开作用域时,会清空引用计数,并回收这段内存。
  • scoped_ptr只能是独享共有权,当发生复制和拷贝时,原来的scoped_ptr将失去使用权。(但是可用reset函数重置指向的对象,或者用swap函数交换指针所指的对象)

7.TCP中,如果client一直发送数据,并且server端接收的非常慢,会对双方产生什么样的后果##

会发生阻塞的情况,不会发生丢包的情况,因为TCP在丢包时会重发,知道对方接收到。

8.TCP的粘包和拆包##

情景如下,假设client需要发送数据包D1和D2,以下情况会出现粘包和拆包的现象:

  • server刚好分两次接收到了D1和D2,没有发生粘包和拆包
  • server一次就将D1和D2接收完,D1和D2粘在一次(粘包)
  • server第一次接收到D1的一部分,第二次才读取D1的剩余内容和D2(拆包)
  • server滑动窗口非常小,需要很多次才将D1和D2接受完(多次拆包)

9.如何解决粘包和拆包的问题##

由于TCP底层无法理解应用层是否发生了数据的粘包和拆包,所以需要我们设计应用层,将粘包和拆包现象的数据重新解析为正确的数据,解决办法如下:

  • 消息定长,如每个报文的长度固定200字节,不足的用空格补齐(可能导致无用数据占用网络)
  • 在包尾增加回车换行符进行分割;
  • 将消息分为消息头和消息体,消息头包含消息体长度的字段,通常的处理方法是消息头的第一个字段用int来表示消息的长度;
  • 设计更复杂的消息层协议。

10.如果只有头文件(甚至没有)和dll文件,没有lib文件,怎么使用这个动态库##

如果只有头文件和dll,可以采用LoadLibrary();GetProcAddress();FreeLibrary();

HINSTANCE hDLL; // DLL句柄知
typedef int  (*DLLFUN)(int a, int b);
DLLFUN Dll_clFun;
//读取:
if(hDLL == NULL)
hDLL=LoadLibrary((LPCTSTR)"TestDLL.dll");
if(hDLL)
{
Dll_clFun =(DLLFUN)GetProcAddress(hDLL,"clFun");//函数名
}
//释放回:答
if(hDLL)
{
FreeLibrary(hDLL); // 卸下DLL 
hDLL = NULL;
}

如果只有dll,连头文件都没有
如果是简单的函数,参数列表很少,返回值很简单,那么可以用depends工具来查看函数名,在用逆向工具通过汇编得到参数和返回值,最后再用以上的方法来调用dll
如果函数很复杂,目前我也不知道怎么办,反汇编?

11.说一下动态库的加载过程##

搜不到,不知道

12.字节序,大小端##

大端:高位字节存放在低地址
小端:低位字节存放在低地址
x86平台下默认是小端序,而网络传输协议采用大端序,不同平台下的字节序需要转换才能使用

13.如何判断大小端##

  • 用指针,用char型指针去读int型指针的高位地址,判断高位地址的实际值,从而判断大小端(还可以用联合体)
bool isLittleEndian()
{
    unsigned int i = 0x12345678;
    unsigned char* c = (unsigned char*)&i;
    return(*c == 0x78); //判断是否是低位字节存内存低地址  *c取得就是内存中存放i的低地址
}
  • 库函数,htonl(Linux下),(1 != htonl(1));真小端,假大端

14.QT窗口如何重绘##

添加一个类继承Qdialog,然后重写paintEvent函数,update()函数可以刷新窗口;
还可以重写其他的事件函数

15.qt中qss的使用##

qss是qt的样式表,可以存储在文件中filename.qss,使用时通过读文件到QString中,然后在初始化时调用setStyleSheet函数,将样式表运用到界面中来。具体的用法还没来得及看,内容比较多

16.说一下窗口的创建过程##

MFC应用程序创建窗口的过程

  • 1.PreCreateWindow() 该函数是一个重载函数,在窗口被创建前,可以在该重载函数中改变创建参数(可以设置窗口风格等等)

  • 2.PreSubclassWindow() 这也是一个重载函数,允许首先子分类一个窗口

  • 3.OnGetMinMaxInfo() 该函数为消息响应函数,响应的是WM_GETMINMAXINFO消息,允许设置窗口的最大或者最小尺寸

  • 4.OnNcCreate() 该函数也是一个消息响应函数,响应WM_NCCREATE消息,发送消息以告诉窗口的客户区即将被创建

  • 5.OnNcCalcSize() 该函数也是消息响应函数,响应WM_NCCALCSIZE消息,作用是允许改变窗口客户区大小

  • 6.OnCreate() 该函数也是一个消息响应函数,响应WM_CREATE消息,发送消息告诉一个窗口已经被创建

  • 7.OnSize() 该函数也是一个消息响应函数,响应WM_SIZE消息,发送该消息以告诉该窗口大小已经发生变化

  • 8.OnMove() 消息响应函数,响应WM_MOVE消息,发送此消息说明窗口在移动

  • 9.OnChildNotify() 该函数为重载函数,作为部分消息映射被调用,告诉父窗口即将被告知一个窗口刚刚被创建

https://www.cnblogs.com/findumars/p/5870464.html
QT应用程序创建窗口的过程
https://www.cnblogs.com/findumars/p/4700251.html

17.qt中moc的理解##

moc 全称是 Meta-Object Compiler,也就是“元对象编译器”。QT在编译源代码之前,会用moc先分析C++源文件,如果这个C++文件包含Q_OBJECT,那么他会生成另外一个CPP文件,文件名以moc_开头,如moc_test.cpp,然后这个新的CPP文件会一起进入编译系统,最终被链接到二进制代码中。moc在预处理之前,会展开宏Q_OBJECT的内容。
QT并不是一种编程语言,他还是基于C++的编译器的,只不过在编译之前会通过MOC来预先处理CPP文件,将QT框架下的特性如信号和槽加入到CPP中,最终通过C++的编译器来生成可执行程序。

18.说说信号和槽##

https://blog.csdn.net/hyongilfmmm/article/details/83015045

相关标签: C++