C++大杂烩(一)
C++大杂烩
这是楼主在准备面试和刷面经的时候找的一些知识点,内容包括C++、数据结构、网络应用和系统应用一些知识点,可能有个别错别字,内容有从其他帖子上总结的,也有自己写的,希望能够帮到大家哈,后续还会继续更新0.0~
附几个楼主在B站学的相关知识网站,大家自取所需哈~
C++学习
Linux系统编程
Linux网络编程
git版本控制器
QT入门教程
AD软件教程
stl 顺序/序列、关联容器、容器适配器、迭代器
顺序/序列容器:
vector 向量,类似于动态数组,内存空间连续,从后面快速的插入与删除,随机直接访问任何元素
deque 双端队列,内存空间分块,从前面或后面快速的插入与删除,随机直接访问任何元素
list 双向链表,不支持随机访问,可从任何地方快速插入与删除
关联容器
下面四种是一种非线性的树结构,具体的说采用的是一种比较高效的特殊的平衡检索二叉树—— 红黑树结构
set 集合,实际上就是一组元素的集合,但其中所包含的元素的值是唯一的,自动被排序,集合中的每个元素被称作集合中的实例,元素值不能变
multiset 多重集合,其实现方式和set 是相似的,只是它不要求集合中的元素是唯一的,也就是说集合中的同一个元素可以出现多次
map 提供一种“键-值”关系的一对一的数据存储能力。其“键”在容器中不可重复,且按一定顺序排列
multimap 和map 的原理基本相似,它允许“键”在容器中可以不唯一
eg:关联容器对元素的插入和删除操作比vector 要快,因为vector 是顺序存储,而关联容器是链式存储;关联容器对元素的检索操作比vector 慢,但是比list 要快很多
容器适配器
是容器的接口,它本身不能直接保存元素,它保存元素的机制是调用另一种顺序容器去实现,即可以把适配器看作“它保存一个容器,这个容器再保存所有元素”;
stack 后进先出
queue 先进先出
priority_queue 最高优先级元素总是第一个出列
迭代器:类似于容器的指针,可以对容器的元素进行操作
内存的分页分段
页是信息的物理单位,分页是系统管理的需要,而不是用户的需要;页的大小固定,由系统确定
段是信息的逻辑单位,它含一组意义完整的信息。分段是为了更好地满足用户的要求;段的长度不固定,决定于用户所编写的程序
语言类型
编译型语言:编译器一般会有预编译的过程对代码进行优化。因为编译只做一次,运行时不需要编译,所以编译型语言的程序执行效率高;代表语言:C、C++、Pascal、Object-C以及最近很火的苹果新语言swift
解释型语言:程序不需要编译,相比编译型语言省了道工序,解释性语言在运行程序的时候才逐行翻译;代表语言:JavaScript、Python、Erlang、PHP、Perl、Ruby
动态语言:在运行时代码可以根据某些条件改变自身结构;主要动态语言:Object-C、JavaScript、PHP、Python、Erlang
静态语言:运行时结构不可变的语言;如Java、C、C++、C#
用户态和内核态
区别
一般的操作系统对执行权限进行分级,分别为用保护态和内核态,为了防止用户态出现问题导致系统崩溃。在内核态中特权级最高的执行关键操作如分配内存等
切换方法
系统调用:通过调用申请使用操作系统提供的服务程序完成工作,如fork,write、read等
异常:在用户态下发生异常时,触发异常处理中断进入内核处理,如缺页异常
外围设备中断:当外围设备完成用户请求的操作后,会向CPU发出相应的中断信号,若前面的指令是由用户态发起的,那就需要切换到内核态进行接收,如磁盘数据读取
共享内存
原理:两个不同进程A、B共享内存的意思是,同一块物理内存被映射到进程A、B各自的进程地址空间。进程A可以即时看到进程B对共享内存中数据的更新,反之亦然
数据拷贝:只需要两次,一次从输入文件到共享内存区,另一次从共享内存区到输出文件
其他通信方式数据拷贝:需要四次,用户缓冲区将数据拷贝到内核-内核将数据拷贝到内存-处理-内存将数据拷贝到内核-内核将数据拷贝到用户
DNS解析过程
介绍
DNS就是域名系统,是因特网中的一项核心服务,是用于实现域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串
解析
‘.’为根服务器,域名结构为树状的,每一层都有不同的域,如.com .cn .uk等
先在本地缓存服务器中查找是否有保存对于域名,没有则向根服务器查询-从根服务器拿到下一级的域名地址,再递归查询知道返回域名的实际地址-将该地址进行本地缓存-访问对应的地址
DNS服务器间进行域传输的时候用TCP,客户端查询DNS服务器时用 UDP
输入网址到得到网页响应全过程
域名解析-TCP三次握手-建立TCP连接后发起http请求-服务器响应http请求,浏览器得到html-解析html代码并请求html资源-浏览器渲染
http和https区别 http+ssl=https
HTTP 是超文本传输协议,信息是明文传输,HTTPS 则是具有安全性的 SSL 加密传输协议
HTTP 的连接很简单,是无状态的。HTTP协议是无状态的,指的是协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。也就是说,打开一个服务器上的网页,和上一次打开这个服务器上的网页之间没有任何联系;
HTTPS 协议是由 SSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议,比HTTP协议安全
http长连接和短连接 HTTP的长连接和短连接本质上是TCP长连接和短连接
在HTTP/1.0中默认使用短连接。也就是说,客户端和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。当客户端浏览器访问的某个HTML或其他类型的
Web页中包含有其他的Web资源(如JavaScript文件、图像文件、CSS文件等),每遇到这样一个Web资源,浏览器就会重新建立一个HTTP会话;而从HTTP/1.1起,默认使用长连接,用以保持连接特性
优缺点
长连接可以省去较多的TCP建立和关闭的操作,减少浪费,节约时间。对于频繁请求资源的客户来说,较适用长连接
短连接对于服务器来说管理较为简单,存在的连接都是有用的连接,不需要额外的控制手段。但如果客户请求频繁,将在TCP的建立和关闭操作上浪费时间和带宽
操作过程
短连接的操作步骤是:
建立连接——数据传输——关闭连接...建立连接——数据传输——关闭连接
长连接的操作步骤是:
建立连接——数据传输...(保持连接)...数据传输——关闭连接
什么时候使用
长连接多用于操作频繁,点对点的通讯,而且连接数不能太多情况。每个TCP连接都需要三步握手,这需要时间,如果每个操作都是先连接,再操作的话那么处理速度会降低很多,所以每个操作完后都不断开,次处理时直接发送数据包就OK了,不用建立TCP连接。例如:数据库的连接用长连接, 如果用短连接频繁的通信会造成socket错误,而且频繁的 socket 创建也是对资源的浪费。
而像WEB网站的http服务一般都用短链接,因为长连接对于服务端来说会耗费一定的资源,而像WEB网站这么频繁的成千上万甚至上亿客户端的连接用短连接会更省一些资源,如果用长连接,而且同时有成千上万的用户,如果每个用户都占用一个连接的话,那可想而知吧。故并发量大,但每个用户无需频繁操作情况需用短连好。
http多个版本比较
http/1.0 只支持短连接方式,支持缓存cache
http/1.1 引入持久连接,即TCP连接默认不关闭,可以被多个请求复用,不用声明;加入了管道机制,在同一个TCP连接里,允许多个请求同时发送,增加了并发性
http/2.0 增加双工模式,即不仅客户端能够同时发送多个请求,服务端也能同时处理多个请求,解决了队头堵塞的问题;增加服务器推送的功能,即不经请求服务端主动向客户端发送数据
http响应模型
单进程I/O模型:服务端开启一个进程,一个进程仅能处理一个请求,并且对请求顺序处理;
多进程I/O模型:服务端并行开启多个进程,同样的一个进程只能处理一个请求,这样服务端就可以同时处理多个请求;
复用I/O模型:服务端开启一个进程,但是呢,同时开启多个线程,一个线程响应一个请求,同样可以达到同时处理多个请求,线程间并发执行;
复用多线程I/O模型:服务端并行开启多个进程,同时每个进程开启多个线程,这样服务端可以同时处理进程数M*每个进程的线程数N个请求。
TCP/IP五层模型
应用层:为用户的应用进程提供服务,如http、ftp等
传输层:负责向两个主机中进程之间的通信提供服务,tcp/udp
网络层:负责分组交换网上的不同主机提供通信服务,ip/icmp/igmp/arp/rarp
数据链路层:将网络层交下来的IP数据报组装成帧,在相邻结点之间链路上传送数据
物理层:传输的为比特流
ipv4和ipv6
1.地址长度:IPv4协议具有32位(4字节)地址长度,IPv6协议具有128位(16字节)地址长度;
2.地址的表示方法:IPv4地址是以小数表示的二进制数,IPv6地址是以十六进制表示的二进制数;
3.地址配置:IPv4协议的地址可以通过手动或DHCP配置的,ipv6提供身份验证和加密
滑动窗口
TCP滑动窗口主要是为了控制流量,发送方的窗口大小取决于接收方处理数据的能力,表示可以发送的最大数据量
窗口主要分为两个部分:第一部分表示数据包已经发送,但未得到确认应答包;第二部分表示允许发送,但未发送的数据包
在获取到确认应答包后,滑动窗口才会移动相应距离
流量控制和拥塞控制
流量控制:作用于接收者的,如果发送者发送数据过快,接收者来不及接收,那么就会有分组丢失。为了避免分组丢失,控制发送者的发送速度,使得接收者来得及接收;使用窗口滑动机制
拥塞控制:作用于网络的,它是防止过多的数据注入到网络中,避免网络负载过大;常用的方法就是:慢开始、拥塞避免、快重传、快恢复
icmp协议
因特网控制报文协议。它是IPv4协议族中的一个子协议,用于IP主机、路由器之间传递控制消息。
控制消息是在网络通不通、主机是否可达、路由是否可用等网络本身的消息。这些控制消息虽然不传输用户数据,但是对于用户数据的传递起着重要的作用。
空类为什么占一个字节
实际上,这是类结构体实例化的原因,空的类或结构体同样可以被实例化,如果定义对空的类或者结构体取sizeof()的值为0,那么该空的类或结构体实例化出很多实例时,
在内存地址上就不能区分该类实例化出的实例,,,所以,为了实现每个实例在内存中都有一个独一无二的地址,编译器往往会给一个空类隐含的加一个字节,这样空类
在实例化后在内存得到了独一无二的地址,所以空类所占的内存大小是1个字节
private,public,protected的访问范围
private: 只能由该类中的函数、其友元函数访问,不能被任何其他访问,该类的对象也不能访问. protected: 可以被该类中的函数、子类的函数、以及其友元函数访问,但不能被该类的对象访问 public: 可以被该类中的函数、子类的函数、其友元函数访问,也可以由该类的对象访问 注:友元函数包括两种:设为友元的全局函数,设为友元类中的成员函数
类的继承后方法属性变化:
使用private继承,父类的所有方法在子类中变为private;
使用protected继承,父类的protected和public方法在子类中变为protected,private方法不变;
使用public继承,父类中的方法属性不发生改变;
类中的各种类型成员变量初始化
必须使用构造函数的参数列表进行初始化:引用变量 & 和 常量 const
在类外定义的:静态变量 static
可以在类中和类外初始化:静态整型常量 static const int
位运算
异或 ^ 相异为1,相同为0;与0异或为本身,与自身异或为0 n&(n-1) 将二进制n的最后一个1变为0
递归函数
segment1 按调用顺序 if() function() 递归调用 segment2 按调用反顺序,即最内层函数回归后执行 返回值 返回第一层的返回结果 return 确定的数字 返回最后一层的结果 return function()
动态规划(求最值问题、最优子结构、状态转移方程)
dp数组求解:状态是索引;递归函数求解:函数的参数是状态(状态转移中会变化的量)
状态转移方程:暴力穷举所有可行的解
优化:备忘录消除重叠子问题(递归);写出自底向上的迭代解法
如何列出:确定初始条件;确定状态:原问题和子问题中会变化的变量;确定选择:导致「状态」产生变化的行为;明确 dp 函数/数组的定义
动态规划结构如下
明确 base case -> 明确「状态」-> 明确「选择」 -> 定义 dp 数组/函数的含义 初始化 base case dp[0][0][...] = base 进行状态转移 for 状态1 in 状态1的所有取值: for 状态2 in 状态2的所有取值/所有选择中的最值: for ... dp[状态1][状态2][...] = 求最值(选择1,选择2...) dp数组的遍历方向,看最后需要求的那个位置在表格,再从起点想办法遍历所需的状态直到找到该位置
实现类对象数据共享
使用全局变量static+使用友元函数
空类默认产生的六个函数
构造函数+析构函数+拷贝构造函数+赋值运算符重载函数+取址运算符重载函数+const取值运算符重载函数
class Empty{ public: Empty(); // 缺省构造函数 Empty( constEmpty& ); // 拷贝构造函数,浅拷贝 ~Empty(); // 析构函数 Empty&operator=( const Empty& ); // 赋值运算符,让一个对象取修改一个已经存在到的对象,使内容一致 Empty*operator&(); // 取址运算符 const Empty*operator&() const; // 取址运算符const,获取对象地址 }
线程之间哪些是共享的
共享:堆、全局变量、静态变量
非共享:栈(栈主要用来保存函数参数、局部变量和返回地址等信息)和寄存器
多进程和多线程
多进程:数据是分开的,共享复杂,需要用IPC;同步简单;占用内存多,切换复杂,CPU利用率低
多线程:多线程共享进程数据,共享简单;同步复杂;占用内存少,切换简单,CPU利用率高
文件链接
文件名又为用户标识着文件。每次使用文件时,文件名指向一个inode,而inode指向真正的物理区块
硬链接
指将该文件名直接指向一个另一个文件的inode,当删除原文件后,由于该文件名链接该文件inode,所以不会受到影响。每次创建硬链接会使inode中记录的引用计数+1,当引用计数减少到0,则释放该inode;不可跨文件系统建立
软链接
创建软链接会真正的分配一个inode存储指向原文件的文件名,也就是读取该inode,则直接跳转到原文件的目录下进行查找原文件从而进行操作。所以,软链接是可以跨文件系统建立的
select() poll() epoll()区别
select()
使用无差别轮询方式进行查看是否有io事件发生,支持的文件描述符较少,默认是1024
poll()
本质上与select没有差别,只是它是使用链表来存储的,所以对最大连接数没有限制
epoll()
维护了一颗红黑树,作为内核事件表,用于收集描述符,维护一个就绪队列,用来存放有就绪队列的文件描述符,每个epoll事件都有一个epollevent结构体,存放着epoll_ctl方法添加进来的事件,并将其insert到红黑树中,红黑树可以高效的识别出重复的事件。当有IO事件发生时,内核会将发生io的文件放入就绪队列中,从而实现O(1)的查询
电平触发:当队列中当前文件描述符没有处理或没有完成,则下一次epoll会再次提醒,即程序可以不立即处理该事件
边沿触发:在下一次epoll是不会提醒的,它要求应用程序收到一次提醒后,必须将事件都处理完成
ASCII Unicode ANSI utf-8编码区别
ASCII:是用来表示英文字符的一种编码规范。每个ASCII字符占用1 个字节,因此,ASCII 编码可以表示的最大字符数是255(00H—FFH)
ANSI:不同语言标准对ASCII标准的扩展,如汉字的gbk等,但是不同标准之间不能进行识别
Unicode:把所有语言都统一到一套编码里,最常用的是用两个字节表示一个字符
utf-8:假如文本基本上全部是英文,用Unicode编码比ASCII编码需要多一倍的存储空间,因此出现了“可变长编码”的UTF-8编码
UTF-8编码把一个Unicode字符根据不同的数字大小编码成1-6个字节,常用的英文字母被编码成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节
字符编码
作用:将字符转换成计算机中对应的二进制数;ASCII码、GBK(汉字)、UTF-8(互联网使用比较广泛的一种编码规则,节省网络流量);英文字符和数字字符占一个字节,中文字符占两个字节
URI 和 URL
URI,是统一资源标识符,用来唯一的标识一个资源;
而URL是统一资源定位器,它是一种具体的URI,即URL可以用来标识一个资源,而且还指明了如何locate这个资源
不同局域网下的主机是如何通信的
NAT技术,网络地址转换,它是一种把内部私有网络地址(IP地址)翻译成合法网络IP地址的技术。
NAT 可以让那些使用私有地址的内部网络连接到Internet或其它IP网络上。NAT路由器在将内部网络的数据包发送到公用网络时,在IP包的报头把私有地址转换成合法的IP地址
三种类型
静态:一对一 ,将内部网络的私有IP地址转换为公有IP地址,IP地址对是一对一的,是一直不变的
动态:将内部网络的私有 IP 地址转换为公用 IP 地址时,IP 地址是不确定,随机的(从地址池里动态的取出一个外网 IP)
网络地址端口转换NAPT:多对一,内部网络的所有主机均可共享一个合法外部 IP 地址实现对 Internet 的访问,最大限度地节约 IP 地址资源
volatile三大特性
原子性:对任意单个volatile变量的读/写具有原子性,但类似于volatile++这种复合操作不具有原子性
可见性:对一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最后的写入
有序性:禁止指令重排序优化
子网掩码
将IP地址划分为网络地址和主机地址两部分
用来指明一个IP地址所标示的主机处于哪个网段中,是否可以互相通信,是否需要加网关
float和double精度
表示如下:
float=1bit符号位+8bit指数位+23bit尾数位
double=1bit符号位+11bit指数位+52bit尾数位
范围=指数位大小
float=2^8=-127-+128
double=2^11=-1023-+1024
精度=尾数位大小
flaot=2^23=七位数
double=2^52=16位数
关键字typedef
用typedef取别名,别名取代变量名的位置:除了可以给变量、结构体定义别名外,还可以定义数组、函数指针等
数组: typedef int INT_ARRAY_100[100]; INT_ARRAY_100 arr;
函数指针:typedef void (Fun)(int,int); Fun=function; Fun(形参调用)