编程语言
C和C++的区别
- C是面向过程的语言,而C++是面向对象的语言
- C和C++动态管理内存的方法不一样,C是使用malloc/free函数,而C++除此之外还使用new/delete关键字
- C++的类是C里没有的,但是C中的struct是可以在C++中正常使用的,并且C++对struct进行了进一步的扩展,使得struct在C++中可以和class有一样的作用。而唯一和class不同的地方在与struct成员默认访问修饰符是public,而class默认的是private
- C++支持重载,而C语言不支持
- C++有引用,C没有
- C++全部变量的默认链接属性是外链接,而C是内链接
- C 中用const修饰的变量不可以用在定义数组时的大小,但是C++用const修饰的变量可以
C++的面向对象特点?
-
封装:即隐藏对象的属性和实习细节,仅对外公开接口
-
对于类的内部,成员函数可以自由修改成员变量
-
对于类的外部,良好的封装能够减少耦合
-
继承:即子类继承父类的特征和行为,使得子类具有父类的成员变量和方法
-
单继承:一个类只能继承一个父类
-
多继承:一个子类继承多个父类
-
假如两个类具有相同的属性和方法,就可以将这些相同的部分抽取到父类中。
-
多态:同一个行为具有多个不同的表现形式或形态的能力。表现形式有覆盖和重载
-
覆盖是指子类重写从基类继承过来的函数,函数名、返回类型、参数列表都必须和基类相同。当子类的对象调用成员函数对时候,如果成员函数有被覆盖就调用子类的版本,否则调用从基类继承的函数
-
重载是指相同作用域中有多个同名的函数,这些函数参数表不同,编译器根据函数不同的参数表对同名函数的名称作修饰,然后这些同名函数就成了不同函数
如何用C实现面向对象的三个特性:封装、继承、多态?
- 封装:适用函数指针把属性和方法封装到结构体中
- 继承:结构体嵌套
- 多态:父类和子类方法的函数指针不同
C++和python的区别?
- python是脚本语言,是解释性语言,跨平台;C++是编译型语言,运行效率高
- python使用不同的缩进来表示不同代码块,而C++使用{ }
- 全局变量:python中不能直接修改全局变量,可以访问;如果需要修改,使用global来标识
- 传参:python可以使用“关键字参数”来改变函数定义时的传参顺序,但是C++不可以
虚函数、纯虚函数?
纯虚函数是一种特殊的虚函数,在基类中不能对虚函数给出有意义的实现,而把它声明为纯虚函数,其实现应该留给派生类去做
virtual int A() =0;
- 类中使用virtual关键字来声明虚函数,一旦该函数带有函数体,哪怕是空实现,其也称为虚函数。纯虚函数只是一个接口,是一个函数声明而已,留到子类中区实现
- 虚函数在子类中可以进行重写,称之为覆盖,这样编译器可以使用后期绑定来达到多态,但是也可以不对虚函数进行重写。纯虚函数必须在子类中进行实现。
- 带纯虚函数的类叫做抽象类,该类不能直接生成对象,只有被继承,并重写虚函数之后才能使用。抽象类被继承,子类既可以是抽象类也能是普通类
虚析构函数?
虚析构函数是为了解决基类的指针指向派生类对象,并用基类的指针删除派生类对象
class shape{
public:
shape();//构造函数不能是虚函数
virtual double calcArea();
virtual ~shape();//虚析构函数
};
class circle:public shape{
public:
virtual double calcArea();
...
};
int main(){
shape* s=new circle(4.0);
s->calcArea();
delete s;//因为s有虚析构函数,所以delete释放内存时,先调用子类析构函数,再调用基类析构函数,防止内存泄漏
}
计算机网络
HTTP和HTTPS的区别
- HTTP是超文本传输协议,信息是明文传输。存在安全风险问题。HTTPS解决了HTTP的不安全缺陷,在TCP和HTTP网络层之间加入了SSL/TLS安全协议,使得报文能够加密传输
- HTTP连接建立相对简单,TCP三次握手之后就可以进行HTTP的报文传输。但是HTTPS在TCP三次握手之后,还要进行SSL/TLS的握手过程,才可以进行加密报文传输
- HTTP的端口号是80,HTTPS的端口号是443
- HTTPS协议需要向CA(证书权威机构)申请数字证书,来保证服务器的身份是可信的。
HTTS的加密方式
- HTTPS采用的是对称加密和非对称加密结合的混合加密方式
- 在通信建立之前采用非对称加密的方式交换“会话密钥”,后续不再使用非对称加密
- 在通信过程中全部使用对称加密的“会话密钥”来加密明文数据
采用混合加密的原因
- 称加密只只使用一个密钥,运算速度快,密钥必须保密,无法做到安全的密钥交换
- 非对称加密使用两个密钥:公钥和私钥,公钥可以任意分发但是私钥保密,解决了密钥交换问题,但是速度很慢
OSI七层和TCP/IP四层
TCP和UDP的区别
- 连接:TCP是面向连接的传输协议,传输数据前要先建立连接;UDP不需要连接、即刻传输数据
- 服务对象:TCP是一对一的两点服务;UDP支持一对一、一对多、多对多的交互通信
- 可靠性:TCP是可靠交付数据的,数据可以无差错、不丢失、不重复、按需到达;UDP是尽最大努力交付,不保证可靠交付数据
- 拥塞控制、流量控制:TCP有拥塞控制和流量控制机制,保证数据传输的安全性;UDP没有,即使网络非常拥堵,也不会影响UDP的发送速率
- 首部开销:TCP首部长度较长,会有一定的开销,首部在没有使用“选项”字段时是20个字节,如果使用了“选项”字段会边长
- 传输方式:TCP是流式传输,没有边界,但保证顺序和可靠;UDP是一个包一个包的发送,是有边界的,但是可能会丢包和乱序
- 分片不同:TCP的数据大小如果大于MSS大小,则会在传输层进行分片,目标主机收到后,也同样在传输层组装TCP数据包,如果中途丢失了一个分片,只需要传输丢失的这个分片;UDP的数据大小如果大于MTU大小,则会在IP层进行分片,目标主机收到后,在IP层组装完数据,接着再传给传输层,但是如果中途丢了一个分片,在实现可靠传输的UDP时需要重传所有的数据包,这样传输效率非常差,所以通常UDP的报文应该小于MTU。
TCP和UDP的分别应用场景
因为TCP是面向连接,可以保证数据的可靠性交付,因此经常用于:
- FTP文件传输
- HTTP/HTTPS
因为UDP面向无连接,可以随时发送数据,再加上UDP本身的处理简单而且搞笑,常用于:
- 包总量较少的通信,如DNS、SNMP等。
- 视频、音频等多媒体通信
- 广播通信
TCP的三次握手过程和状态变迁
- 一开始,客户端和服务端都处于CLOSED状态,先是服务端主动监听某个端口,处于LISTEN状态。
- 客户端会随机初始化序号(client_isn),同时将SYN标志位置为1,表示SYN报文。接着把第一个SYN报文发送给服务端,表示向服务端发起连接,之后客户端将处于SYN-SENT状态。该报文不含应用层数据。
- 服务端收到客户端的SYN报文之后,首先服务端也随机初始化自己的序号(server_isn),并填入TCP首部的“序号”字段中,同时在”确认应答号“字段填入client_isn+1,接着把SYN和ACK标志位置1。最后将报文发送给客户端,接着处于SYN-RCVD状态。该报文不包含应用层数据。
- 客户端收到服务端报文之后,还要发送一个应答报文。首先应答报文TCP首部ACK标志为1,其次确认应答号字段填入server_isn+1,最后将报文发送给服务端。本次报文可以携带客户到服务器的数据,之后客户端处于EXTABLISHED状态。
从以上可以发现,只有第三次握手的时候是可以携带数据的。
**Linux如何查看TCP状态?**netstat-napt命令。
为什么TCP是三次连接,不是两次或者四次连接?
- 阻止重复历史连接的初始化(主要原因)
- 同步双方的初始化序列号
- 避免资源浪费
**避免历史连接:**客户端连续发送多次SYN建立连接的报文,在网络拥堵的情况下:
- 一个”旧的SYN报文“比”最新的SYN“报文早到达服务端
- 此时服务端回”SYN+ACK“的报文给客户端
- 客户端收到后可以根据自身的上下文判断这是一个历史连接(序列号国企或超时),那么客户端就会发送一个RST报文给服务端,表示中止这一次连接
- 如果是两次握手连接,就不能判断当前连接是历史连接。
**避免资源浪费:**如果只有「两次握⼿」,当客户端的 SYN 请求连接在⽹络中阻塞,客户端没有接收到 ACK 报⽂,就会重新发送 SYN ,由于没有第三次握⼿,服务器不清楚客户端是否收到了自己发送的建⽴连接的 ACK 确认信号,所以每收到⼀个 SYN 就只能先主动建⽴⼀个连接,这会造成什么情况呢?
如果客户端的 SYN 阻塞了,重复发送多次 SYN 报⽂,那么服务器在收到请求后就会建⽴多个冗余的无效连接,造成不必要的资源浪费
TCP的四次挥手断开连接
- 客户端打算关闭连接,此时会发送一个TCP首部FIN标志位被置为1的报文,也即FIN报文,之后客户端进入FIN_WAIT_1状态
- 服务端收到报文后,向客户端发送ACK应答报文,接着服务端进入CLOSED_WAIT状态
- 客户端收到服务端的ACK应答报文后,之后进入FIN_WAIT_2状态
- 等待服务端处理完数据之后,也向客户端发送FIN报文,之后服务端进入LAST_ACK状态
- 客户端收到服务器的FIN报文之后,回一个ACK应答报文,之后进入TIME_WAIT状态
- 服务器收到ACK应答报文之后,进入CLOSED状态,服务器完成连接关闭
- 客户端经过2MSL时间后,自动进入CLOSED状态,至此,客户端完成连接关闭
从上图可以看到每个方向都有一个FIN和ACK,因此称为四次挥手
还有注意的点是:主动关闭连接的,才有TIME_WAIT状态
为什么挥手需要四次?
- 关闭连接时,客户端向服务端发送FIN时,仅仅表示客户端不再发送数据,但是还能接受数据
- 服务端收到FIN报文,线回答一个ACK报文,但是服务端可能还有数据需要处理和发送,等服务端不再发送数据时,才发送FIN报文给客户端表示同意关闭连接
浏览器输入网址之后的过程?
-
首先浏览器对URL进行解析,从而生成发送给Web服务器的请求信息
-
-
所以URL实际上是请求服务器里的文件资源,确定了Web服务器和文件名,接下来就是根据这些信息来生成HTTP请求消息
-
查询服务器域名对应的IP地址
-
通过DNS获取IP地址后,将HTTP的传输工作交给操作系统中的协议栈
-
浏览器通过调用Socket库,来委托协议栈工作。协议栈的上半部分有两块,分别是负责发送数据的TCP和UDP数据,它们会接受应用层的委托执行首发数据的操作
-
协议栈的下半部分是用IP协议控制网络包首发操作,在互联网上传数据时,数据被切分成一块块的网络包,将网络包的发送就是IP负责
-
在IP协议中有源地址IP和目标地址IP
-
源地址IP,即是客户端输出的IP地址
-
目标地址IP,即通过DNS域名解析得到的WEB服务器IP
-
生成IP头部后,网络包还需要在IP头部前面加上MAC头部
注意:以上计算机网络的相关知识点和图片主要来自小林coding的图解网络,推荐大家去关注他的公众号