此文大概为看了许多面经之后积累的问题,有些问题还没写出答案,序号什么的也有点混乱,望海涵
1.C和C++的特点与区别?
答:C语言是C++的子集,C++是C语言的超集。C语言是面向过程的,C++是面向对象的。C++引入了类,C++用iostream代替了stdio,用new和delete 替代了 malloc和free C++多了string类 C++允许函数重载 引入了const virtual static volatile 等关键字。
接口类是指只提供方法名不提供实现
2.C++的三大特性(面向对象)五大基本原则
抽象:把现实世界中的某一类东西,提取出来,用程序代码表示,抽象出来的一般叫做类或者接口,分数据抽象和过程抽象。
封装 :不同于面向过程把变量暴露在整个程序中,面向对象把变量封装在对象内部,把对象和外部世界隔离开来,通过间接的方法来和外部世界通信。
继承 :对同一类对象共性的处理方法,子类使用父类已有的属性和方法,有利于代码的复用性。分为实现继承和接口继承 接口继承还需要实现父类的方法
多态:不同类对象对相同行为的不同反应,多态机制使具有不同内部结构的对象可以共享相同的外部接口。(ps:虚函数和接口类似,只有函数体没有参变量,这样的做法方便了多态的实现)
与继承相对应的是多态提供了对同一类对象差异性的处理方法,子类通过多态重写从父类继承的方法来实现子类的差异性。
我来举一个简单的例子大家可以理解一下:
class Aninal{ 叫;}//叫是动物的一个方法
class 猫 extend Animal{叫;}
class 狗 extend Animal{叫;}
Animal 狗 = new 狗();
Animal 猫 = new 猫();
狗.叫();
猫.叫();
这里的多态的态应该指的是形态,比如狗可以有Animal的形态,真正本质是将对象的型别忘掉,模糊了父类和子类之间的差异,用相同的形式去表达不同的行为! 这样有利于代码在复用性的基础上让子类表现自己的差异性。
单一职责原则: 是指一个类的功能要单一,不能包罗万象。如同一个人一样,分配的工作不能太多,否则一天到晚虽然忙忙碌碌的,但效率却高不起来。
开放封闭原则:
替换原则:
依赖原则:
接口分离原则:
3.C++内存分配与C++的几大存储区
5.malloc和new的区别
4.C++虚函数(表)的实现。
5.Linux I/O模型。
6.I/O复用技术 select/epoll/poll
6.struct和class的区别。
7.STL库的介绍。
2.cpp文件是怎么运行起来的(.h文件)?
答:cpp文件是源文件,存放的程序的源代码。
(1).cpp文件先进行预处理,将#include的头文件里的内容合并到源代码中,将#define宏定义的内容进行数据替换,加载外部的代码等等。
(2).编译器对预处理后的文件进行编译,把源文件中的以文本形式存在的代码翻译成机器语言形式的目标文件,在这个过程中编译器会进行一系列的词法分析,语法分析,分析成功之后会把.cpp文件转变为.obj文件
(3).在编译器把所有的.cpp文件都转变成.obj文件后,链接器把所有的静态链接库(.lib)文件和所有的.obj文件链接起来形成.exe文件,最后运行.exe文件并在过程中会加载动态链接库(.dll)
发散:1.cpp文件与.h文件的区别与联系:
2.编译原理中的几个过程。
3.c++<>和双引号的的区别
8.hashmap的实现方式。
9.hashmap和hashtable的区别和底层实现。
9.析构函数写成虚函数的原因。
10.构造函数可以为虚函数吗。
10.TCP和UDP的区别,TCP三次握手和四次挥手。
11.TCP的超时等待time_wait()和流量控制
12.Http GET和POST的区别。
13.http与https的区别
11.进程与线程的区别,进程间是如何通信的。
12.线程池 多线程同步
13.并发和并行的区别
14.红黑树 B+树 快速排序 字符串匹配 排序算法的稳定性
15.bloom过滤器和atoi的实现
16.C++各类型的数据字节长度:
答:C++各类型数据类型长度取决与所在的OS,但是遵循ISO的几条原则:
1.int>=short int
2.int<=long int
3.short int 至少为16bit 2byte
4.long int 至少为32bit 4byte
| 16 | 32 | 64 |
int | 2 | 4 | 4 |
short int | 2 | 2 | 2 |
long int(long long与long是2倍关系 但是最多为8) | 4 | 4 | 8 |
char(wchar_t) | 1 | 1 | 1 |
char *(指针变量的位数与操作系统的位数相同) | 2 | 4 | 8 |
bool | 1 | 1 | 1 |
float | 4 | 4 | 4 |
double | 8 | 8 | 8 |
17.C++中引用与指针的区别。
答:C++中的引用相当于某个变量的别名,在定义时相当于与变量绑定了。当改变这个变量的时候,其引用也会发生相应的改变,当改变引用时,其对应的变量也会发生相应的改变。在函数调用的时候,如果把形参定义为引用,则在函数内部修改了形参的值,实参也会发生变化。在定义引用时若不绑定某个变量,则编译会出错,但是C++指针则不会。
C++中的指针代表某个内存的地址,当你需要获得该内存中所对应的值的时候,你需要加入操作符*。单纯的指针名的类型为int *地址的类型也是int *。这里需要区别区分取地址符&和引用符&。
int a=10;//假设a的地址为0x100
int *b=a;//编译出错
int *c=(int *a);//c指向的值未知 地址为0x10
int *d=&a;//d指向的值为10 地址为0x100
*b=&a;//编译出错
*b=a;//b指向的值为10 地址为0x100
18.动态数组用关键字new来申请。
19.C++数组的值?
答:1.当数组为全局变量时,若没有初始化,全自动为0;
2.当数组为局部变量时,若没有初始化,为异常值;
3.当数组为={},即初始化成功,按初始化赋值,无值的为0;
4.当数组为a[]=1;属于未初始化,赋值处为值,其余地方为异常值;
#include <iostream>
using namespace std;
int g[10];
int main()
{
int a[10];
int b[10] = { 1 };
int c[10];
c[0] = 1;
int d[10] = {};
cout << g[1] << endl;
cout << a[1] << endl;
cout << b[1] << endl;
cout << c[1] << endl;
cout << d[1] << endl;
while (1) {
}
return 0;
}
结果:
20.C++默认权限时private。
21.浅谈C++的构造函数。
class A{
public:
A();
A(int a);
A(const A& other);//这里的&应该为创建一个引用。
private:
int memberA;
int memberB;
static const int size=512;
int* p;
}
答:C++的构造函数分为三类,分别为默认构造函数,普通构造函数和拷贝构造函数。
默认构造函数为没有参数,或者所有的参数都有默认值。初始化列表用()。
A::A():memberA(0),memberA(100),p(new int[size]);
普通构造函数为携带参数,使用初始化列表来初始化成员变量。初始化列表用{}。
拷贝构造函数用法为,先创建一个同类的对象,再使用该对象来构造本对象。
构造函数中请使用初值列表的方式来完成变量初始化。
拷贝构造函数(const 类& other)
区分值拷贝和内容拷贝:设新对象名为B,已有对象的对象名为A。其中B.a=A.a为值拷贝没问题;
但是对于指针p来说情况就不同了,若B.p=A.p;则A B指向了同一块内存,若B修改了或者删除了该块内存,那当A访问内存,则会崩溃,这当然不行,所以我们在构造函数中使用了深拷贝,对象B先建立一块内存,然后把A内存的内容拷贝到B内存中(使用memcpy函数)!这就是深拷贝,若直接指针赋值则为所谓的浅拷贝。
即浅拷贝对应的是值拷贝,深拷贝对应的是内容拷贝,当然对于非指针变量,浅拷贝和深拷贝没有区别。
拷贝构造函数被调用的情况:1.A a;A b(a);直接初始化
2.A a;A b=a;拷贝+构造
拷贝赋值函数------操作符的重载。A& A::operator =(const A& a){
1.先使用this指针将非指针型变量赋值
2.再将自身的内容使用delete清空;//防止内存泄露
3.再用memcpy进行深拷贝
4.最后返回(* this)ps:this指针指向的是A对象,this指针指向的就是本对象}
我们来理解一下以下语句A a,b;a=b;(假设存在拷贝赋值函数),则激发拷贝赋值函数,激活此函数的对象是a!!而b是作为参数变量,所以this指针指向的是对象a;
移动构造和移动赋值。
移动的含义对于非指针型变量来说是和拷贝的意义一样的,但是对于指针型变量,其指的就是
21.C++的this指针。
答:函数体内所有对类数据成员的访问,都会被转化为this->数据成员的方式。而一个对象的this指针并不是对象本身的一部分,不会影响sizeof(“对象”)的结果。this作用域是在类内部,当在类的非静态成员函数中访问类的非静态成员的时候,编译器会自动将对象本身的地址作为一个隐含参数(this)传递给函数。也就是说,即使你没有写上this指针,编译器在编译的时候也是加上this的,它作为非静态成员函数的隐含形参,对各成员的访问均通过this进行。换而言之,若为静态成员函数,或者为静态成员,则会直接访问,不通过this指针。再换而言之也就是没有通过对象访问,所以不管对象是否为nullptr,通过对象访问静态的函数或变量,都会成功!!在静态函数中,this指针不会被调用!,调用静态的成员变量时this指针也不会调用。
22.C++析构函数什么时候被调用?
答:栈上创建的类实例,在退出作用域(比如函数返回,或者离开花括号包围起来的某个作用域)之前,该实例会被析构。动态创建的实例(通过new操作符),当delete该对象时,其析构函数会被调用。