BAT经典面试题

简述C++虚函数作用及底层实现原理
内联函数、构造函数、静态成员函数可以是虚函数吗?
  • 都不可以。内联函数需要在编译阶段展开,而虚函数是运行时动态绑定的,编译时无法展开; 构造函数在进行调用时还不存在父类和子类的概念,父类只会调用父类的构造函数,子类调用子类的,因此不存在动态绑定的概念;静态成员函数是以类为单位的函数,与具体对象无关,虚函数是与对象动态绑定的,因此是两个不冲突的概念;
构造函数中可以调用虚函数吗?
  • 可以,但是没有动态绑定的效果,父类构造函数中调用的仍然是父类版本的函数,子类中调用的仍然是子类版本的函数
简述C++中虚继承的作用及底层实现原理?
  • 虚继承用于解决多继承条件下的菱形继承问题,底层实现原理与编译器相关,一般通过虚基类指针实现,即各对象中只保存一份父类的对象,多继承时通过虚基类指针引用该公共对象,从而避免菱形继承中的二义性问题。
  • C++ 多继承和虚继承的内存布局
C++空类占用一字节
结构体大小

注意:

1
2
3
4
5
struct A {
char a;
char b;
char c;
};

A的大小是3,结构体中每个成员的起始地址是min(成员类型大小,pack)的整数倍,整个结构体大小是最大成员大小的整数倍。

Struct和Class的区别
C++中成员函数能够同时用static和const进行修饰?
  • 否,因为static表⽰示该函数为静态成员函数,为类所有;而const是用于修饰成员函数的,两者相矛盾。[Error] static member function 'static void Test::fun()' cannot have cv-qualifier
C++中包含哪几种强制类型转换?他们有什么区别和联系?

参考答案 C++ 的强制类型转换

简述Linux内存分配--伙伴系统 原理

参考答案:伙伴系统,其思想是:把内存块分成不同的组(1,2,4,8,16,32....);分配内存时找到能够满足条件 的最小的块;如果找不到,就找大的块,然后一分为2,分配一块,留一块;回收时:如果有相邻的同样大小的块,则合并

使用mmap读写文件为什么比普通读写函数要快?
实现一个Memcpy函数
100亿个整数,内存足够,如何找到中位数?内存不足,如何找到中位数?
设计并实现一个LRU Cache
请简述智能指针原理,并实现一个简单的智能指针
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
class SmartPointer;
template<typename T>
class Counter {
friend class SmartPointer<T>;
private:
T* ptr;
int cnt;
public:
Counter() {
ptr = NULL;
cnt = 0;
}
Counter(T* p) {
ptr = p;
cnt = 1;
}
~Counter() {
delete ptr;
}
};
template <typename T>
class SmartPointer {
private:
Counter* ptr_counter;
public:
SmartPointer(T* p) {
ptr_counter = new Counter(p);
}
SmartPointer(const SmartPointer &sp) {
ptr_counter = sp.ptr_counter;
++ptr_count->cnt;
}
SmartPointer& operator=(const SmartPointer &sp) {
++sp.ptr_counter->cnt;
--ptr_counter->cnt;
if (ptr_counter->cnt == 0) {
delete ptr_counter;
}
ptr_counter = sp.ptr_counter;
}
~SmartPointer() {
--ptr_counter->cnt;
if (ptr_counter->cnt == 0) {
delete ptr_counter;
}
}
};