1、c++中类成员的访问权限:
c++通过public、protected、private三个关键字来控制成员变量和成员函数的访问权限,分别表示共有、受保护、私有,在类的内部三种类型都可以相互访问,在类外部,只能通过对象访问成员,(静态的可以用类名访问)并通过对象只能访问public属性的成员,不能访问private、protected属性的成员。
2、c++中struct和class的区别:
在c++中可以用struct和class定义类,都可以继承,区别是:struct的默认继承权限和默认访问权限是public,而class的默认继承权限和默认访问权限都是private。另外class还可以定义模板类形参。
3、c++类内可以定义引用数据成员吗?
可以,必须通过成员函数初始化列表初始化。
4、什么是右值引用,跟左值引用又有什么区别?
右值引用是c++11中引入的新特征,实现了转移语义和精确传递,主要目的是:消除两个对象交互时不必要的对象拷贝;能够更简洁明确的定义泛型函数。
区别:左值可以寻址右值不可以;
左值可以被赋值,右值不可以被赋值,可以用来给左值赋值;
左值可变,右值不可变。
5、一个c++源文件从文本到可执行文件经历的过程:
预处理阶段:将文本中的头文件和宏定义进行分析和替换,生成预编译文件;
编译阶段:将预处理阶段生成的预编译文件转换成汇编文件;
汇编阶段:将编译阶段生成的汇编文件转化成目标文件;
链接阶段:将多个目标文件以及其所需要的库连接成可执行文件。
6、include头文件的顺序,以及双引号和尖括号的区别:
如果在a.h中声明了一个在b.h中的变量,而不引用b.h,在a.c中引用b.h文件,要先引用b.h后引用a.h;
双括号和尖括号的头文件查找路径不同:
双引号:当前文件,编译器设置的头文件,系统变量设置的头文件;
双尖括号:编译器定义的头文件路径,系统变量设置的头文件路径。
7、malloc的原理,brk、mmap系统调用的作用分别是:
malloc用于动态分配内存空间,为了减少空间碎片和系统调用的开销,malloc采用内存池的方法,先申请一大块内存最为堆,再将堆分割成多个块,以块作为内存分配和管理的基本单位,使用隐式链表将堆区分成多个连续的,大小不同的块,使用显示链表管理未分配块;
当内存分配时先遍历隐式链表的所有空闲块,选择合适的块进行分配,当内存合并时看当前块的前后块是否空闲;
当申请的内存大于128k时,使用mmap系统调用在映射区分配,当申请内存小于128k时,使用brk系统调用在堆区分配。
8、c++内存管理是怎么样的:
程序段:分为文本区和只读存储区,静态字符串常量存储在只读存储区,文本区存储机器代码;
数据段:存储已初始化的静态变量和全局变量;
bss段:存储未初始化的静态变量和全局变量;以及所有被初始化为0的静态变量和全局变量;
堆区:调用malloc/new时在堆区分配内存,需要free/delete手动释放;
文件映射区:存储动态链接库,以及调用mmap函数进行的文件映射;
栈区:存储返回地址,参数,返回值,局部变量等;
9、如何判断内存泄漏:
使用linux的valgrind工具,在写程序时添加统计分配内存和释放内存的功能,判断申请和释放内存是否一致来判断是否内存泄漏。
10、什么时候会发生段错误:
段错误通常是在访问非法内存空间地址时产生,如使用野指针,试图修改常量字符串。
11、什么是内存泄漏:
内存泄漏不是内存丢失,是由于错误疏忽未能释放不再使用的内存;分为堆内存泄漏,系统内存泄露,没有将基类的析构函数定义为虚函数。
12、malloc和new的区别:
new按照对象类型分配空间,malloc按照大小分配内存空间;
new返回对象的指针,malloc返回空指针需要强制转换;
new使用delete释放,malloc使用free释放,delete销毁时会调用析构函数free不会;
new分配内存不够时会抛出bad_malloc错误,malloc返回null;
malloc可以使用realloc重新分配内存,new不可以;
new是一个操作符可以重载,malloc是库函数;
new会调用构造函数,malloc不会;
13、共享内存相关的api:
shmget创建新的共享内存;
shmat共享内存连接到进程的地址空间;
shmdt共享内存和进程地址空间分离;
shmctl控制共享内存;
14、单线程如何处理高并发:
利用I/O复用;然后采用事件驱动模型,基于异步互调来处理事件。
15、c++STL内存优化:
二级配置其结构;
二级内存池;
16、说说select,epoll的区别,原理,性能,限制方面:
不按牛客上的来,他的理解不动,按这个:
select在调用前会将要监控的描述符的bit位置1,然后将其传给select,当有事件发生时,select会返回所有的描述符,由应用程序自己去查找哪个描述符有事件发生,效率很低,调用前会由用户态转到内核态,调用后会由内核态转为用户态,开销很大,内置数组的形式使得文件描述符的最大文件数受限;
epoll是poll的改进版本,首先会创建epoll对象,然后使用epoll_ctl将要监控的描述符传进去,使用epoll_event结构体的形式组成一颗红黑树,接着阻塞在epoll_wait,进入大循环,当有事件发生时,返回相对应的结构体放入一个链表中,返回有事件发生的链表;采用了可变长数组,使得文件最大数不再受限,只返回对应的链表效率会提高;
17、c++11有哪些新特征:
auto关键字:编译器可以自动根据初始值推导出类型,不能用于函数传参以及数组类型的推导;
nullptr关键字:可以转换为任意类型的指针,NULL一般被定义为0;
智能指针,初始化列表初始化,右值引用,新增了两个STL容器。
18、介绍一下c++11中的可变参数模板,右值引用和lambda函数这几个新特征:
可变参数模板对函数参数进行了高度的泛化,可以表示任意个数,任意类型的参数,语法为在class或者typename后面带上省略号…;
右值引用作用是转移语义和精确传值,它消除了两个对象交互时不必要的对象拷贝,能够更加方便的定义泛型函数;
lambda表达式定义了一个匿名函数,可以捕获一定范围内的变量。