实习经历
#define和const的区别
- 编译器对二者的处理方式不一样
define实在预编译处理阶段直接进行替换,而const常量实在编译运行阶段才会使用 - define是宏定义没有类型,而const则有具体的类型;define不进行类型安全检查但const则要进行类型检查
- define–不分配内存,给出的是立即数,有多少次使用就进行多少次替换,在内存中会有多个拷贝,消耗内存大;const – 在静态存储区中分配空间,在程序运行过程中内存中只有一个拷贝
- 在编译时,编译器通常不为const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高;宏替换只作替换,不做计算,不做表达式求解。
const int & 和 int的区别
const int& get() {return x;}
int get() {return x;}
const int& 返回是数的一个个常量引用
int 是返回这个数值的一个拷贝
区别:
- int是进行拷贝构造,而const int & 是返回的引用
- 拷贝耗时,同时还用析构函数
- 产生了拷贝,可以轻易修改拷贝的内容
return *this 和 return this
return *this 是返回当前对象的克隆或本身(若返回类型是A,为克隆,若返回为A&,为本身)
return this 是返回当前对象的address
秋招经历
inline的用法
在函数的返回类型前面加上关键字inline, 就可以将它声明为内联函数
class A { int a; short b; int c;};, sizeof(A)的大小,如果加上double d?
- 空类
class A {};
sizeof(A); // 1
Reason:类的实例化就是为每个实例在内存分配一块地址;每个类在内存中都有唯一的标识,因此空类被实例化时,编译器会自动为其添加一个字节,以作区分。 2. 虚函数类
class A {
virtual void Fun();
};
sizeof(A); // 4
Reason:当一个类包含虚函数时,会有一个指向虚函数表的指针vptr,系统为类指针分配大小为4个字节。 3. 普通数据成员
class A {
int a;
char b;
};
sizeof(A); // 8
Reason: 普通数据成员,按照其数据类型分配大小,由于字节对齐,所以a+b=8字节。 4. 静态数据成员
class A {
int a;
static int b;
};
sizeof(A); // 4
Reasson:静态数据成员存放的是全局数据段,即使它是类的一个成员,但不影响类的大小;不管类产生多少实例或者派生多少子类,静态成员数据在类中永远只有一个实体存在。而类的非静态数据成员只有被实例化时,才存在,但类的静态数据成员一旦被声明,无论类是否被实例化,它都已存在,类的静态数据成员可以说是一种特殊的全局变量。 5. 普通成员函数
class A {
void Fun();
};
sizdof(A); // 8
Reason:类的大小与它的构造函数、析构函数以及其他成员函数无关,只与它的数据成员相关。 6. 普通继承
class A {
int a;
};
class B: public A {
int b;
};
sizeof(B); // 8
Reason:普通类的继承。类的大小为本身数据成员大小+基类数据成员大小。 7. 虚函数继承
virtual class A {
int a;
};
class B: virtual public A {
int b;
};
sizeof(B); // 12
Reason:虚函数的继承,派生类大小=派生类自身成员大小+基类数据成员大小+虚拟指针大小(即使继承多个虚基类,也只有一个指向虚函数表的指针vptr,大小为4字节)。
排序算法,平均复杂度,稳定的有哪些?
排序方式 | 平均复杂度 | 最坏 | 最好 | 空间复杂度 | 稳定性 |
---|---|---|---|---|---|
插入排序 | O(n^{2}) | O(n^{2}) | O(n) | O(1) | 稳定 |
希尔排序 | O(n^{1.3}) | O(1) | 不稳定 | ||
冒泡排序 | O(n^{2}) | O(n^{2}) | O(n) | O(1) | 稳定 |
快速排序 | O(nlogn) | O(n^{2}) | O(nlogn) | O(logn) | 不稳定 |
选择排序 | O(n^{2}) | O(n^{2}) | O(n^{2}) | O(1) | 不稳定 |
堆排序 | O(nlogn) | O(nlogn) | O(nlogn) | O(1) | 不稳定 |
归并排序 | O(nlogn) | O(nlogn) | O(nlogn) | O(n) | 稳定 |
稳定的有:冒泡、插入、归并
哈希是什么?哈希如何存储数据?什么情况下用到哈希?
哈希算法的本质是对原数据的有损压缩。哈希表则属于一种存储结构,最常用的存储结构是顺序存储结构和链式存储结构,这两种结构的共同特征就是元素与元素之间存在映射关系。而哈希表的元素之间相互独立。哈希表具体的实现方式是给定一个参数,称为“键”。参数的类型可以是任何类型的数据,诸如字符、字符串、整型等等。然后根据该参数通过哈希算法计算生成的值来定位“键”对应的元素的存储地址。
解决Hash冲突的方法:
- 开放地址法
一旦发生冲突,就去寻找下一个空的散列地址。 - 链地址法
- 再哈希法
有多个Hash函数,当发生冲突时,使用第二个,第三个,…
static的作用?
c的内容:
- 在函数体,一个被声明为静态的变量在这一函数被调用过程中保持其值不变。
- 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内的所用函数访问,但不能被模块外其他函数访问,它是一个本地的全局变量。
- 在模块内,一个被声明为静态的函数只可能被这一模块内的其他函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用。
三句话来总结就是:首先static的最主要的功能就是隐藏,其次因为static变量存放在静态存储区,所以它具有持久性和默认值为0。 - 类内的static成员变量属于整个类所拥有,不能在类内定义,只能在类体外内进行初始化。
<数据类型><类名>::<静态数据成员名> = <值> - 类内的static成员函数属于整个类所拥有,不能包含this指针,只能访问静态成员和静态函数。
const的用法?
- 定义的时候必须进行初始化。
- 指针可以是const指针,也可以是指向const对象的指针。
- 定义为const的形参,即在函数内部是不能被修改的。
- 类的成员函数可以被声明为常成员函数,不能修改类的成员变量。
- 类的成员函数可以返回的是常对象,即被const声明的对象。
- 类的成员变量是常成员变量,不能在声明时初始化,必须在构造函数的列表进行初始化。
只读的性质由编译器赋予,人为修改编译不通过
struct关键字和class关键字定义类以及继承的区别?
- 定义类的差别
struct关键字也可以实现类,用class和struct关键字定义类的唯一差别在于默认访问级别:默认情况下,struct成员的访问级别是public,而class成员的为private。 - 继承差别
保留class关键字的派生类默认具有private继承,而用struct保留字定义的类默认具有public继承。
默认的访问级别和默认的继承级别class都是private
派生类与虚函数概述
- 派生类继承的函数不能定义为虚函数。虚函数是希望派生类重新定义,如果派生类没有重新定义某个虚函数,则在调用的时候使用基类定义的版本。
- 派生类函数的声明必须与基类中的方式完全匹配。
- 基类中声明为虚函数,则派生类也为虚函数。
成员类如果没有被声明为虚函数,则其解析过程发生在编译时而非运行时。
虚函数与纯虚函数区别
- 虚函数在子类里面可以不重载,但是纯虚必须在子类去实现。
- 带纯虚函数的类叫虚基类也叫抽象类,这种基类不能直接生成对象,只能被继承,重写虚函数后才能使用,运行时动态绑定。
必须使用初始化列表初始化数据成员的情况
- const修饰的类成员
- 类的成员为引用
- 类的成员为没有默认构造函数的类型
内存分配方式
虚拟内存
TCP三次握手,具体?
hashmap机制,如何实现?
输入www.baidu.com的过程具体发生了什么?
进程与线程,以及通信方式?
ゆなちゃん
C++的多态是怎么实现的?
在基类的函数前加上virtual关键字,在派生类中重写该函数,运行时将会根据对象的实际类型来调用相应的函数。如果对象类型是派生类,就调用派生类的函数;如果对象类型是基类,就调用基类的函数
对象们是怎么知道要调用哪个函数的?
虚函数表长什么样子?
虚函数表中只存有一个虚函数的指针地址,不存放普通函数或是构造函数的指针地址。只要有虚函数,C++类都会存在这样的一张虚函数表,不管是普通虚函数亦或是纯虚函数,亦或是派生类中隐式声明的这些虚函数都会 生成这张虚函数表。
- 虚函数按照其声明顺序放于表中。
- 父类的虚函数在子类的虚函数前面。
- 覆盖的虚函数被放到了虚表中原来父类虚函数的位置。
函数重载是在什么时候进行的?
编译期间
vector,list的区别,map,unordered_map的区别,4种容器的内部实现(手撕红黑树v2.0?)
tcp和udp区别?
都属于传输层协议
- TCP是面向连接的,UDP是无连接的;
- TCP是可靠的,UDP是不可靠的;
- TCP只支持点对点通信,UDP支持一对一、一对多、多对一、多对多的通信模式;
- TCP是面向字节流的,UDP是面向报文的;
- TCP有拥塞控制机制;UDP没有拥塞控制,适合媒体通信;
- TCP首部开销(20个字节)比UDP的首部开销(8个字节)要大;
udp的上层协议?
DNS,NTP(网络时间协议)