1. if else 和 switch case 的区别,哪个效率更高?
答:switch case的效率更高。
因为switch case会生成一个跳转表指向分支地址,只需要在跳转表中找到相应的确定值就可以跳转到相应的分支,而 if else 需要依次遍历判断,效率不高。
区别:switch case只能处理case是常量的情况,对于非常量只能用if else, 所以if else更加灵活。
2. 重载,重写(覆盖),隐藏的区别
答: 重载是发生在同一个可访问区域内,比如同一个类内的函数参数列表不同的同名函数,即只有函数签名不同的函数。重载不关注函数的返回类型。
重写(覆盖):基类中的virtual函数,在派生类中重新实现。重写函数要求函数名,函数参数列表,返回类型都与基类中被重写的函数相同。
隐藏:派生类中的与基类同名的函数,函数参数列表和返回值类型都可以不同。基类中该函数不是virtual函数。
3. 指针和引用的区别
答:1. 引用是一块内存的别名,只能在定义时初始化一次,之后就不能再改变。但是指针是一个变量,内容是一块内存的地址,指针的内容可以改变。
2. 指针的值可以为空,但是引用不能为空。
4. new delete 和 malloc free的区别
答:new delete是C++的运算符,malloc free是C/C++的库函数。
new 是创建一个对象,先申请内存,new申请内存是调用了operator new()函数,底层通过malloc实现,然后调用类的构造函数进行初始化,无需指明申请内存的大小,系统会根据类的大小计算出需要申请的内存,new执行完后会返回相应类型的指针。
malloc 是申请一块内存,需要指明申请内存的大小。malloc返回void*类型,需要转换成相应的指针类型。
同理, delete会先调用析构函数,然后再释放内存空间,释放空间底层原理也是调用了free()。free是直接释放申请的空间, 但是无法调用析构函数。
5. delete和delete[]的区别
答:delete是释放单个对象所占用的空间,只调用一次析构函数。
delete[]是释放数组所占用的空间,会对数组中的每个成员都调用一次析构函数。
6. vector存放的是值还是引用
答:vector中存放的是值,不能存放引用。
stl的容器都不允许放引用。因为容器在定义时容器内会定义相应的对象,而引用在定义时必须初始化,所以容器里不能放引用。
容器里插入和取出对象都是进行的拷贝操作。所以为了节省空间,通常容器内通常放指针,但是指针有可能会引发内存泄漏和野指针的问题,所以使用智能指针式最佳选择。
7. 析构函数加virtual的作用
首先,加virtual是为了实现多态,是实现当父类的指针指向子类时调用子类的函数。当不加virtual时,当指针为父类指针时,只会调用父类的析构函数,会导致内存泄漏。加了virtual后,实现多态,可以通过父类的指针调用子类的析构函数,再调用父类的析构函数,避免内存泄漏。
8. protected类型变量的作用
答:只允许本类和派生类的成员函数访问。
private: 只允许本类的成员函数访问。
9. memcopy函数实现的原理
void* memcopy(void* dest, const void* src, size_t num) {
assert(dest && src);
// 因为memcpy是一个字节一个字节的拷贝,所以不论是什么数组,都要转成char类型
char* dest_t = (char*) dest;
const char* src_t = (const char*) src;
while(num--) {
*dest++ = *src_t++;
}
return dest; // dest是void* 类型指针,所以要返回dest
}
注意地方: 当目标地址与源地址的内存存在重叠情况时,memcpy结果会出错。
拷贝时是一个字节一个字节的拷贝。
10. 设计一个类的时候,该对象会被放进set或者map中的key时,该类需要实现哪些函数
需要重载小于号运算符<
因为map和set实现原理时二叉树,是有序的,所以在插入元素的时候,会进行A<B 和 B<A的比较,都返回false就是==
11. 智能指针实现原理
智能指针内有两个指针,一个指向内存空间,一个指向引用计数区。也就是当一个区域使用智能指针的时候,会在堆上开辟一小块区域用来计数。
weak_ptr指针不参与计数,但是使用前可以判断该区域是否已经被释放。weak_ptr主要是解决循环引用计数的问题。
12. vector的动态扩容原理和函数
答:当vector的存储数量已经达到了容量的时候,会另开辟一个2倍或4倍的空间,然后将原空间的内容拷贝到新的空间里去,释放原空间的内存,然后将新的空间地址赋值给原指针。扩容后vector的迭代器等都失效。
vector的capacity()函数是可以返回vector的真实容量的,size()返回的是vector里存储的个数。
resize() 大小大于真实容量的时候,会进行动态扩容,但是当resize()大小小于真实容量的时候,vector并不会收缩,即容量不变,但是存储的数量会变化。
clear()也不会影响容量的大小。
swap()是交换两个vector的内存地址
shrink_to_fit() 将capacity缩到size大小。
13. 可以直接定义引用吗
不能,引用定义的时候必须初始化。
14. 什么是联合体
答:是一种数据类型,可以在同一个内存位置存储不同的数据类型。联合体可以有多个不同的成员,但是任何时候都只能有一个成员有值。联合体的大小取决于最大成员的大小。
15. linux投递命令
qsub
16. gdb命令
bt 查看堆栈信息
17. linux查看磁盘空间命令
df -h
18. 哪一个是函数指针
Add1 = &AddFunc;
Add2 = AddFunc;
显然是第一个
19. const、mutable、volatile、explicit、extern、static、union 的作用
explicit: 修饰类的构造函数,表示构造函数只能显示转换,不能进行隐式转换
20. 二叉树怎么维持平衡
21. 哈希是怎么实现的
22. python的字典是使用的哪种map结构
23. C++内置函数中有哪些特殊的构造函数
24. vector和set的应用场景
25. 多线程访问一个资源的时候,用哪种线程同步的方式更好
26. 正则表达式原理
- #pragma pack (4) 什么意思
- 下段代码有什么问题
代码段1:
{
char* p = new char[100];
p+=2;
delete [] p;
printf("It is a test demo!\n");
}
代码段2:
{
char* p = new char[100];
delete p;
printf("It is a test demo!\n");
}
- 下两段代码有什么问题
代码段3:
{
char* ptr = "0123456789";
while(*ptr)
{
printf("%c\n", *ptr++);
}
}
代码段4:
{
char* ptr = "0123456789";
while(*ptr++)
{
printf("%c\n", *ptr);
}
}
- 下段代码有什么问题,以及会打印什么
unsigned char aaa[100] = {0};
cout << sizeof(aaa) << endl;
int bbb[100] = {0};
cout << sizeof(bbb) << endl;
网友评论