网站域名备案资料,做公司网站有什么好处,百度免费校园网站建设,做小程序的流程【八股03.29】
1.内存泄漏#xff1f;野指针#xff1f;悬挂指针#xff1f;
什么是内存泄漏#xff1f;
内存泄漏是指程序运行过程中申请的动态分配的堆内存没有被释放#xff0c;造成系统内存浪费#xff0c;运行速度减慢甚至崩溃等严重后果。 如何避免#xff1f;…【八股03.29】
1.内存泄漏野指针悬挂指针
什么是内存泄漏
内存泄漏是指程序运行过程中申请的动态分配的堆内存没有被释放造成系统内存浪费运行速度减慢甚至崩溃等严重后果。 如何避免
养成良好的编码习惯及时释放动态分配的堆内存。 使用智能指针让其自动释放。 使用内存泄漏检测工具如Valgrind等。 什么是野指针什么是悬挂指针
野指针是未初始化的指针指向随机的地址 悬挂指针是指向已经释放的内存的指针。 double delete是未定义行为 delete nullptr没有影响 delete p后p变成一个悬挂指针通常delete后需要将p设为nullptr
2.什么是智能指针智能指针有哪些
智能指针是C11引入的一个类模板用来帮我们自动管理资源通常情况下它内部封装了一个指向动态内存的裸指针在析构函数它会自动释放此前申请的动态内存防止我们因为忘记释放或发生异常导致的内存泄漏。 常用的有unique_ptr, shared_ptr, weak_ptr好像还有个auto_ptr已经废弃了。
3.说说这几种智能指针
unique_ptr是一种独占式的智能指针某一时刻只能有一个智能指针拥有资源的所有权它不可以被拷贝可以通过移动来交出资源的所有权。shared_ptr是一种共享式的智能指针它允许多个智能指针同时拥有资源的所有权它内部会维护一个引用计数当管理资源的智能指针1时内部的引用计数就会1在析构函数中会将引用计数-1当引用计数为0时就会释放资源。当返回this指针的shared_ptr和存在循环引用时shared_ptr可能会出现一些问题weak_ptr和shared_ptr搭配使用的话就可以解决这些问题。weak_ptr其实并不管理任何资源的生命周期它也不会使得对应资源的引用计数增加它一般和shared_ptr一起搭配使用作为一个旁观者观测shared_ptr中管理的资源是否存在。比如循环引用中只要将一个类中的shared_ptr改为weak_ptr就可以避免循环引用导致的死锁因为当一个weak_ptr指向一个资源时对应shared_ptr的引用计数不会1。
4.shared_ptr的线程安全问题
shared_ptr的线程安全问题主要包括3点
引用计数的加减操作是否线程安全 shared_ptr保证了引用计数的加减是一个原子操作所以这个是线程安全的。shared_ptr修改指向时是否线程安全这个还没理解透陈硕那本书里有 这个要分两种情况讨论。当shared_ptr通过引用和指针传递时不同的线程操作的是同一个shared_ptr此时是线程不安全的当shared_ptr通过值传递时不同的线程操作的不是同一个shared_ptr不过指向的资源是相同的此时是线程安全的。操作shared_ptr指向的数据时是否线程安全 这个是由所指向的数据类型决定的这个线程不安全不是由于shared_ptr导致的是因为这个数据类型自身就是线程不安全的。
5.有哪些IO模型
阻塞IO非阻塞IOIO复用信号驱动IO异步IO
6.什么是阻塞IO什么是非阻塞IO什么是同步IO什么是异步IO
一个典型的IO分为两阶段数据准备和数据读写。 比如说一个recv操作会从网络中接收数据到内核缓冲区这就是数据准备的过程然后再从内核缓冲区读到用户空间这就是数据读写的阶段。
阻塞IO和非阻塞IO主要说的是当数据没有准备好时发起IO的线程的状态。
阻塞当数据没准备好时阻塞等待。非阻塞当数据没准备好时不会阻塞等待直接返回一个错误可以通过errno判断出错还是数据没准备好。
同步IO和异步IO主要说的是是由内核还是应用程序来进行读写数据。
同步由应用程序完成IO操作在数据读写阶段发起IO操作的线程还是会阻塞之后才会继续向下执行。异步交给操作系统完成IO操作应用程序调用异步IO后立刻就可以继续往下执行IO操作完成后会通知应用程序。 在处理IO的时候阻塞和非阻塞都是同步IO只有使用了特殊的API才是异步IO。 上述只是讨论了在IO层面上的的阻塞非阻塞和同步异步但是跳出IO这个范围在大的层面上来说感觉应该基本等于同义词。阻塞与非阻塞主要关注调用者等待调用结果时的一个状态同步主要说线程必须完成前一个任务才能进行下一个异步一般用在多线程中当前线程开启一个任务可以去执行其它任务可能由其它线程完成后再通知它。
7.说说IO多路复用为什么要使用IO多路复用IO多路复用的实现方式
什么是IO多路复用
IO多路复用是一种同步IO模型多路是说多个网络连接复用是指使用同一个线程它使得一个线程可以同时监视多个文件描述符阻塞直到监视的文件描述符处于就绪状态。 为什么需要IO多路复用
如果不使用IO多路复用的话假如有10000个网络连接我们就要需要10000个线程去监视每个文件描述符如果使用IO多路复用的话就只需要一个线程来监视所有文件描述符当有就绪的文件描述符时再分配线程去进行处理这样可以大大减少所需要的线程数量因为线程创建和切换是需要开销了这样能更加节省系统资源吧。 IO多路复用的实现方式
IO多路复用主要有3中实现方式select, poll, epoll.
8.IO多路复用之select
使用select之前要先创建一个fd_set结构这个实际上就是一个数组一共1024位类似位图每一位代表我们监听的一个文件描述符。当我们需要监听一个文件描述符时通过select提供的宏函数将对应的位置为1即可调用select时还需要传入一个参数就是最大文件描述符1因为内核是采取线性遍历的方式查看对应文件描述符上是否有事件发生。这个参数可以告诉内核停止遍历了。当有文件描述符就绪时select就会返回fd_set中对应的位仍然是1没有事件发生的文件描述符对应的位会被置为0。select会返回就绪的文件描述符总数但是我们仍然需要遍历fd_set来确定哪些文件描述符是就绪的。
缺点
select监视的文件描述符数量是有限的也就是fd_set的位数这个在内核中是确定了的。每次调用select都要将fd_set由用户态拷贝到内核态开销比较大效率比较低。内核对fd_set中文件描述符的检测方式是线性扫描效率比较低。
9.IO多路复用之poll
使用poll的话我们要先对每个要监听的文件描述符创建一个pollfd结构这个结构体中成员有被监听的文件描述符fd感兴趣的事件events实际发生的事件revents同时poll还需要一个参数来指定pollfd数组的大小。poll会返回就绪的文件描述符总数不过我们也需要遍历pollfd数组来确定哪些文件描述符是就绪的。poll和select没有本质区别它只解决了部分select的问题监听的文件描述符总数是没有限制的但仍然有以下缺点。
缺点
每次调用都要讲pollfd数组由用户态拷贝到内核态效率比较低。内核对文件描述符也是采用线性的方式查询效率比较低。
10.IO多路复用之epoll
epoll有3个APIepoll_cerate创建一个epoll实例epoll_ctl修改epoll感兴趣的文件描述符epoll_wait监听文件描述符阻塞直到有就绪的文件描述符。
epoll是由红黑树和就绪链表实现的epoll通过红黑树管理文件描述符不会采用线性方式扫描文件描述符而是采用回调机制当文件描述符就绪时回调函数会将其放到就绪链表中当就绪链表不为空时epoll_wait就会返回。同时epoll采用mmap的方式进行内核态和用户态的信息交换避免了不必要的内存拷贝。epoll_wait会返回已经就绪的文件描述符数量而且传出参数evs数组中只会有就绪的文件描述符对应的epoll_event不需要遍历所有文件描述符。
epoll有两种工作模式LT水平触发ET边沿触发。 水平触发是epoll默认的工作模式比如说对于读事件来说如果是水平触发模式那么只要读缓冲区还有数据读事件就会一直被触发epoll_wait会直接返回如果是边沿触发模式那么只有当读缓冲区由空变为非空时读事件才会触发也就是说如果数据没有一次读完读缓冲区还有数据在边沿触发模式下读事件是不会触发的epoll_wait不会返回。所以边沿触发模式一般要循环读确保将数据一次读完同时还要将文件描述符设置为非阻塞的防止读操作无意义的阻塞非阻塞读在读完数据后后返回errno为EAGAIN通过这个可以判断数据是否已经读完。