[杂学笔记]面向对象特性、右值引用与移动语义、push_back与emplace_back的区别、读写锁与智能指针对锁的管理、访问网站的全过程
1.面向对象特性
面向对象的三大特性分别是封装、继承与多态,这三个特性的前提就是C++引入了类与对象的概念。封装指的就是将数据和函数方法进行包裹起来,对外部隐藏类对象的实现细节,只提供一些公共接口来和对象进行交互。 好处在于将数据私有化,防止外部代码随意的访问和修改数据。
继承是指一个类可以继承另一个类的属性和方法内容,并且可以再此基础之上添加新的属性和方法,或者重定义父类的属性和方法。继承可以实现代码的复用和层次化的组织代码。
多态是指不同的对象可以对一个动作做出不同的响应。具体操作是再继承体系下,父类设置虚函数,子类继承之后重写虚函数之后,使用父类的指针或者引用指向子类,调用虚函数的时候,就会调用子类的虚函数,那么就实现了多态调用(运行时的动态绑定)。
2.右值引用与移动语义
右值就是不能去地址的,没有变量名称的临时对象,例如字面常量、函数的返回时构造的临时对象。右值引用就是专门来引用这类值的引用类型。
移动语义具体体现在移动构造和移动赋值运算符重载函数,移动构造也就是右值引用版本的拷贝构造函数,他再构造函数的时候,会将右值引用的对象的资源管理权转交给自己。以string对象为例,内部具体的是,传递参数之后,参数就是该右值的一个别名了,函数体内部,会进行资源的转移操作,也就是交换string内部的一些指针内容,泽阳就实现了资源管理权的移交操作。移动赋值重载则是,再转交资源管理权之前,先释放自己的资源,之后再进行新的资源的接收管理。
3.push_back与emplace_back的区别
- push_back的左值版本,在进行对象的插入工作的时候,虽然说参数的接收使用了引用可以减少传参时候的一个拷贝操作,但是无论是内置变量还是自定义变量,再函数体内部赋值的时候,还是需要进行拷贝的操作。
- push_back的右值版本,他是将资源的管理进行转移,相较于左值版本,他不涉及到拷贝的操作了,但是他的前提是传递的参数需要是一个对象,适用于已经有一个对象需要添加到vector内部,而且这个对象即将销毁了。内部相当于调用的是拷贝构造函数
- emplace_back相对于右值版本的push_back来说,他不需要提前存在一个将亡值的对象,直接传递常量参数也可以,他会再内部的vector管理的内存指定区域,用传递的参数直接构造该对象。内部相当于调用的是构造函数。
4.读写锁与智能指针对锁的管理
C++17引入了读写锁的操作,使用的是std::shared_mutex类,一种轻量级的读写锁,它允许多个线程同时进行读操作(共享访问),但在进行写操作时需要独占访问权。也就是说,同一时间可以有多个线程持有读锁,但只能有一个线程持有写锁。
对于读线程的加锁方式是调用lock_shared()接口,而对于写线程的加锁方式是调用lock()接口,对于lock_shared的加锁其实就是记录读线程的数量。读写线程之间是互斥的,当有写线程的时候,lock_shared也会阻塞住。
一般锁都是配合着智能指针来实现加锁和解锁的操作,再C++14的时候引入了智能指针对锁的加锁和解锁管理,例如shared_lock配合shared_mutex可以实现shared_mutex对于读线程的加锁处,出作用域的时候,会自动调用析构函数,实现解锁处理。unique_lock通常配合独占锁进行例如mutex或者shared_mutex的写线程加锁解锁操作。
5.访问网站的全过程
- 域名解析(DNS):当在浏览器输入网址的时候,浏览器首先需要将域名解析位对于的IP地址。会先在自身的缓存中寻找,如果没有会向本地域名服务器发送DNS查询请求,来获取IP地址,这里可能会涉及到多个DNS服务器之间的一个交互。
- 建立连接:首先会进行TCP三次握手来建立连接通路,如果是访问的HTTPS网站的话,在三次握手之后,还需要进行SSL/TLS握手来沟通密钥。
- 发送请求:浏览器会构建HTTP请求报文,并经过加密之后发送给服务器
- 服务器处理与响应:服务器通过解析收到的HTTP请求,根据URL路径和请求方法来确定如何处理请求。如果是一个静态网页请求,会直接查找文件系统中对于的文件,如果是一个动态网页请求的话,还需要移交给相应的应用服务器进行处理。获取到资源之后,进行资源的序列化操作,之后服务器根据处理结果构建响应报文,通过TCP连接发送给浏览器。
- 网页渲染:浏览器收到HTTPS报文之后,进行解密操作形成HTTP报文,之后对数据内容进行反序列化处理,将html文件数据进行解析处理以及网页的渲染工作。