[杂学笔记]继承的应用场景、如何避免内存泄漏、函数模板的理解、多线程的应用场景、DNS解析的过程
目录
1.继承的应用场景
2.如何避免内存泄漏
3.函数模板的理解
4.多线程的应用场景
5.DNS解析的过程
1.继承的应用场景
代码复用、实现多态、扩展现有的功能、构建层次结构。
例如一个图形库,他可以创建一个基类,将图形公共的参数和方法放在基类内部实现,然后对各个图形创建子类,再子类中实现各个图形的个性化方法。
2.如何避免内存泄漏
- 手动管理内存:确保new和delete配对使用,在确保不在使用一块内存空间的时候即使的使用delete释放该内存块
- RAII思想:通过在对象的构造函数中获取资源,在析构函数中释放资源。确保资源在对象的生命周期结束被正确释放。这个具体的应用就是C++标准库的智能指针。
- 谨慎使用全局变量和静态变量去管理动态内存
- 使用内存检测工具
- 避免循环引用:在使用shared_ptr的时候要避免循环引用的问题。例如:有两个智能指针指向两个节点,两个节点内部使用的是shared_ptr进行连接。
#include <iostream>
#include <memory>
class B;
class A {
public:
std::shared_ptr<B> b_ptr;
~A() { std::cout << "A destroyed" << std::endl; }
};
class B {
public:
std::weak_ptr<A> a_ptr; // 使用 std::weak_ptr 避免循环引用
~B() { std::cout << "B destroyed" << std::endl; }
};
int main() {
std::shared_ptr<A> a = std::make_shared<A>();
std::shared_ptr<B> b = std::make_shared<B>();
a->b_ptr = b;
b->a_ptr = a;
return 0;
}
如上述代码所示,当出了作用域的时候,析构a对象,a对象的析构函数会销毁A对象,但是A对象此时还有一个B节点内部的指针指向A节点,所以析构不了。B节点也是如此,析构b对象的时候,B节点也是还有A节点内部的指针指向他,所以B节点也析构不了。所以就造成了内存泄漏的问题。
3.函数模板的理解
在传统编程当中,例如交换两个数据的值,对于不同的类型都需要编写特定的函数才可以。这样做的话代码会变得冗长,而且当需要处理新的数据类型的时候,还得不断添加新的函数才可以。而函数模板而是一种抽象的概念,他把数据类型也抽象成为了一个参数。相当于定义了一个蓝图,当我们调用函数模板的时候,编译器会进行模板参数的推导,确定模板参数的具体类型。之后生成一个具体的函数实例了。这个过程也叫做模板的实例化。
底层其实也是需要对不同类型的参数生成一个单独的函数,只不过这个工作是由编译器帮我们实现了而已。这不仅仅解决了代码的冗余性,还提高了代码的灵活性与扩展性。
4.多线程的应用场景
- 图形用户界面程序:当用户进行鼠标点击,键盘输入等操作的时候,如果是单线程的情况下,遇到耗时的任务操作,那么就会使得界面卡住。借助多线程的技术,可以让耗时的操作创建新线程去执行,防止界面的卡顿。又或者是前端页面需要实时的获取后端数据并更新的情况,一批线程去获取后台数据传给前端,另一个线程维护前端页面的数据更新操作。
- 服务器程序:主要的作用是增强并发处理的能力。对于服务器而已同一时间可能有成千上万的用户像服务端发起请求,如果是单线程的话,一个一个处理,显然不太现时。借助多线程技术,可以同一时间处理大批量的请求。在借助多线程衍生的技术例如:Reactor模型、线程池等等,更能能够增强服务器的处理能力。
- 计算密集与I/O密集型应用:可以充分利用CPU多核资源。并行计算与I/O读取。
- 音视频处理:视频音频的数据,需要将数据从网络或者本地磁盘中取出来,并进行解析才可以播放出来,要保证流畅性的话,就必须边读取边解析边播放,所以就需要多线程技术了。
5.DNS解析的过程
用户输入网址,形成请求之后,需要将网址转化为IP地址,首先会在浏览器的缓存中查找,该网址是否是最近访问的网址,如果是的话,会有记录,查找到直接返回即可。如果没有的话,会形成一个DNS请求,首先会发送给操作系统,操作系统也有自己的DNS缓存,会检查缓存中有没有,有就返回,没有的话会将DNS请求发送给本地域名服务器。本地域名服务器也会先查找缓存,如果还是没有的话,他会根据域名的层次结构进行查询。例如www.baidu.com会分为三层,顶级域名(.com)、二级域名(baidu)和主机名(www)。本地域名服务器会向各个域名服务器依次发送查找请求,最终获取一个完整的IP地址,缓存起来,并返回给浏览器,浏览器就可以正常进行访问了。
浏览器缓存--本地DNS缓存-本地域名服务器缓存-本地域名服务器分层次发送请求解析--返回IP地址--浏览器正常访问网站