整理
操作系统
1. 进程与线程的本质区别、以及各自的使用场景
答:进程是操作系统分配资源的基本单位,线程是cpu调度的基本单位。
线程非共享的,errno变量,独立的栈空间,未决信号集,寄存器和栈指针(指向内核栈)
线程的优点:
通信方便(socket,fifo,pipe,mmap,消息队列),共享数据方便
开销小,提高了程序的并发性
线程的缺点:
库函数调用,并不稳定,对信号不友好(信号的处理方式是共享的),调试困难,不支持gdb
各自的使用场景:
线程:在等待I/O的时候,可以交给一个线程去做,继续去做别的事情
进程:需要安全稳定的时候使用线程,虽然创建一个进程的花费比线程一个大
2. 线程可以看做寄存器和栈的集合,这句话怎么理解?
答:
首先,从内核的角度来看,线程和进程是类似的,都拥有独立的pcb。但是每个线程都有各自的任务需要去执行,这些都保存在各自的寄存器和栈中。在线程中调用函数的时候,是通过栈帧结构实现的。调用函数的时候,将 函数参数,返回地址,ebp指针,esp指针压入栈中进行保存。然后移动ebp指针和esp指针重新为函数创建一个栈帧结构。
因为ebp指针和esp指针的值是储存在寄存器中,并且函数运行空间的申请,参数,函数地址的保存等需要通过栈来实现,所以,线程可以看做寄存器和栈的集合
3. 线程号和线程ID的区别?
线程号是cpu分配时间片轮的依据,而线程ID是用来区分线程的。
两个不同的进程中,线程ID可以相同,但是线程号绝对不能相同
4. 进程状态?
就绪态(等待cpu分配时间片轮),挂起态(主动放弃cpu,等待除cpu以外的其他资源),执行态(占用cpu),终止态
5. 进程调度算法的特点以及使用场景?
1>先来先去服务(FCFS),总是把在任务队列之首的进程调整到运行状态,完成一个进程再去做下一个进程
使用场景,有利于长作业和CPU繁忙的作业
缺点是,不利于短作业和I/O频繁的作业
2> 短作业优先调度算法(SJF),对预计运行时间少的进程先去处理,通常后面来的进程不会去抢夺正在运行的进程的资源
使用场景:短作业比较多的场景,能提高系统的吞吐量,比fcfs算法节省时间
缺点,对长作业不利,可能长时间得不到执行,无法根据紧迫程度来划分执行优先级
3>轮转法
让每个进程在就绪队列中等待的时间和享受的服务的时间成正比
适用场景:用户通常在一个时间片内处理完,否则会使响应时间,平均周转时间延长
4>多级反馈队列算法
是轮转法和优先级算法的综合和发展
设置多个就绪队列,分别赋予不同的优先级,如逐级降低,队列1的优先级最高,如果要加入一个新的线程,先加在队列1的底部,
如果按照队列1一个时间片未能执行完,则降低投入到队列2的末尾,依次类推,直到进程完成
6. 协程的作用
协程是单进程单线程的超越函数的调度机制,通过一定的调度手段进行调度
7. 进程通信方法的特点以及适用场景?
pipe匿名管道,只能用于有血缘关系的进程之间
fifo有名管道,可以用户非血缘关系的进程之间
mmap共享内存,都可以使用,通过虚拟内存来实现对物理内存的一个控制
信号,一般用于通信,数据传输能力较差
socket套接字通信,一般用于网络通信,可以用于进程通信(socket可以看做用户进程和内核网络协议的编程接口)
8. 死锁必要条件,解决死锁的策略?
死锁的产生条件,第一个,上锁两次。第二个,A拥有t1锁的权限,但是想要获得t2锁的权限;B拥有t2锁的权限,但是想要获得t1锁的权限。
解决策略:
1). 编码规范
2). 在想要获取其他锁的时候,先放开自己所拥有的的锁
9. 虚拟内存的作用,mmu作用?
虚拟内存定义:是计算机系统系统管理的一种技术,使得应用程序认为它拥有连续的可用的内存。
实际上是被分割成多个物理内存,还有部分暂时存储在外部的磁盘存储器上
为什么要有虚拟内存呢?
如果是多个线程的话,非常容易发生某个进程不小心占用了另一个进程所使用的内存,导致程序运行出错
虚拟内存作用:缓存,内存管理,内存保护
1> 有利于进程之间的隔离
2>为每个进程提供了一致的地址空间,简化内存管理
3> 将主存储器看做一个存储在磁盘上的地址空间的高速缓存,在主存储器中只保存活动区域,并根据需要在磁盘和主存储器之间来回传送数据
mmu作用:实现连续的虚拟地址访问不连续的物理地址;方便进程之间的隔离;设置内存访问级别
10. 比较分页存储管理和分段存储管理的区别
1> 页是信息的物理单位,由系统硬件确定;而段是一个逻辑单位,含有一组意义相对完整的信息
2>分页的作业地址空间是一维的,也就是单一的线性地址空间;分段的作业地址是二维的,在标识一个地址的时候,既需要给出段名,还需要给出段内地址
11. 分析静态链接,动态链接的优缺点(分析静态库和动态库的优缺点)
静态库优点:
1> 加载速度快
2> 不需要打包库
静态库缺点:
1>程序发生改变需要重新编译
2>可执行文件体积大
动态库优点:
1> 在函数接口不变的前提下,不需要重新编译
2>体积小
动态库缺点:
1>加载速度慢
2>需要打包库
linux
1. inode机制
为什么要有inode节点机制?
1> 如果文件名包含特殊字符,无法直接删除,可以通过直接删除inode节点就能实现对这个文件实现删除操作
2> 对文件进行移动或者重命名,不会影响inode节点
3.>更新的时候,生成一个新的inode节点,然后在这个节点保存新的版本,然后当文件重新打开的时候,文件会自动指向这个新的inode节点
对inode机制的解释
每一个进程会分配一个4G的虚拟内存,在3G~4G内核空间中,存在PCB进程控制块,在PCB进程控制块中,存在文件描述符表,文件描述符就是文件描述符表的下标,每一个表项指向一个file结构额如题
在file结构中记录着这个文件的打开次数,引用计数,还有指向file_operatiors结构体的指针,还有指向dentry(目录项)结构体的指针。
在file_operations结构体中封装了一些对文件进行操作的函数
在dentry结构体中还有一个指向inode结构体的指针,这个结构体保存了文件的所有者,块的大小,文件的属性,块的位置等等
硬链接是file结构体对应的文件的引用计数增加1,只有当引用计数为0的时候这个文件才会被释放,也就是说如果源文件你删除了,但是在这之前你对这个文件创建了硬链接,那么这个文件的file结构体中的引用计数
不为0,这个文件就不会删除
软连接相当于创建了一个快捷方式,并不会增加引用计数,当源文件删除的时候,这个软连接就失效了
3. 常用的命令?
lscpu 描述cpu相关的信息
pwd 资源管理器
grep 文本搜索命令
awk 文件搜索命令
4. 僵尸进程和孤儿进程的区别?
孤儿进程:
父进程先于子进程死去,这个子进程将由init进程进行托管
僵尸进程:
父进程在死去的时候,没有调用wait函数或者对waitpid函数对子进程进行回收,这样的话,就会造成一个资源的浪费。子进程的进程描述符也会一直被占用
如何防止僵尸进程:
1>将僵尸进程变成孤儿进程(两次fork),这样init进程就会对僵尸进程实现一个自动回收
2>调用wait/waitpid函数对子进程进行回收
3>信号驱动,当子进程发出SIGCHLD信号的时候,父进程调用wait/waitpid函数(默认的处理动作是忽略,需要对信号处理方式进行自定义),避免子进程变成僵尸进程
网络
3.1 基础
1. 各层协议的作用,以及TCP/IP特点?
四层协议从上往下,应用层,传输层,网络层,接口层
应用层:为用户引用程序提供网络服务器的接口,ftp
传输层:为应用进程之间提供端到端的逻辑通信,tcp,udp
网络层:实现两个主机系统之间的数据透明传送,ip
接口层:为上层协议提供一个传输数据的可靠没接 mac
2. TCP/IP特点?
1>是一个开放的协议标准,所有人都可以免费试用,并且独立于硬件和操作系统
2>在局域网和互联网都被广泛使用
3>使用同一的网络地址分配
4>拥有极高的可靠性,可以为用户提供可靠的服务、
3.帧结构?
拿TCP/IP来说,如果是TCP传输的话,数据在应用层,往下套上TCP头部,再往下套上IP头部
{IP{TCP{数据}};
{数据帧{IP包{TCP包{data}}}}
1460的由来,在不包含帧头和帧尾的前提下,链路层支持的最大传输数据是1500,去除TCP头部和IP头部就剩 1500 - 20 - 20 = 1460;
4. ARP协议的作用?
ARP协议是根据IP地址获取物理地址的一个协议
RARP协议是根据物理地址获取IP地址的一个协议
5. UDP与TCP比较,分析上层协议应该使用UDP还是TCP?
TCP是面向连接的可靠的数据流传输协议,UDP是面向事务的不可靠的数据报传输协议
上层协议应该使用TCP,对于UDP通信,可以在应用层模拟TCP的一个可靠的机制
6. 理解三次握手,四次握手具体过程,三次握手的原因,四次握手的原因,为什么建立是三次握手,而断开连接是四次握手?TIME_WAIT的原因?
三次握手,是在建立连接的过程中使用的。
三次握手具体过程:
第一次握手,客户端向服务器端发送SYN报文段,发送端序号为x,请求建立连接,此时客户端进入SYS_SEND状态
第二次握手,服务器端在收到客户端发送过来的SYN报文段之后,如果同意建立连接,就会返回一个SYN+ACK报文段,发送端序号为y,确认序号为x + 1 ,此时服务器端进入了SYS_RCVD状态
第三次握手,客户端收到了服务器端发送过来的报文,如果同意的话,会回复一个ack报文段,发送端序号为x + 1, 确认序号为 y + 1,客户端和服务器端进入了ESTABLISHED状态
四次握手,是在断开连接的过程中使用的。
四次握手具体过程:
第一次握手,客户端向服务器端发送FIN报文段,序号x,请求断开连接,此时客户端进入了FIN_WAIT1状态
第二次握手,服务器端在收到客户端发送过来的报文之后,如果同意断开连接,就会回复一个ACK报文段,序号y,确认序号 x + 1,此时服务器端进入了CLOSE_WAIT状态,当客户端
收到这个报文之后,进入了FIN_WAIT2状态
第三次握手,服务器端向客户端发送FIN报文段,序号z,请求断开连接,此时服务器端进入了LST_ASK状态,客户端在收到这个报文之后,进入了TIME_WAIT状态
第四次握手,客户端在进入TIME_WAIT之后,向服务器端发送ACK报文段,序号w ,确认序号 z + 1,表示同意断开连接,服务器端在收到这个报文之后,进入close状态。
2MSL之后,客户端也进入了close状态
为什么建立是三次握手,而断开连接时四次握手?
首先,通信过程是全双工的,也就是说客户端能向服务器端发送数据,服务器端也能像客户端发送数据。
在四次握手的过程中,前两次是客户端请求断开到服务器端的链接。之所以这样做,是因为服务端可能还没有传输完到客户端的信息。
后两次是服务器端发送完数据之后,请求断开连接。
而连接连接的时候,三次握手, 也可以理解成四次握手,是双方第一次建立连接,是双方都同意的前提下才可以的。在第二次握手的时候,服务器端发送到
客户端的是一个 SYN + ACK报文段,这个就包括到服务器端到客户端请求建立连接的这个过程,相当于省去了一步。
TIME_WAIT作用?
进入TIME_WAIT状态之后,会等待2MSL之后再关闭。MSL,报文最大的存活时间,也就是报文来回的时间之和。之所以这样的原因是,在四次握手的过程中,如果第四次的时候,客户端向服务器端发送的ack报文段,服务器端并没有
收到。这个时候如果服务器端并没有收到ack报文,根据超时重传机制,会重新发送fin报文段。如果客户端再收到fin报文段,就会继续发送ack报文段。
7. 可靠传输原理,并设计可靠的UDP协议?
应答机制,慢启动机制,拥塞避免机制,超时重传机制,快速重传机制,快速恢复机制,滑动窗口机制
滑动窗口机制,发送端和接收端各自维护一个窗口
发送端的窗口分为四个部分:
1>已经发送并且收到ack应答
2>已经发送但是没有收到ack应答(滑动窗口内部)
3>未发送并且允许发送的内容(滑动窗口内部)
4>未发送但是不允许发送的内容
接收端的窗口分为四个部分:
1>已经接受并且返回ack应答
2>已经接受但是没有返回ack应答
3>未接受并且不准备接受
对于发送端,只有当滑动窗口最左边的报文段收到ack应答的时候,滑动窗口才会移动;接收窗口只有当前面的字节数有填充的时候才会移动。
8. TCP拥塞控制的作用,理解具体原理,AIMD算法?
TCP拥塞控制有慢启动机制,拥塞避免机制,快速重传机制,快速恢复机制
为什么要有拥塞控制?
如果说需求大于可用资源的时候,就会发生拥塞控制。使得网络不至于过载。
拥塞窗口:发送方一个动态变化的窗口,大小取决于拥塞程度。发送方让自己的发送窗口的大小等于拥塞窗口的大小,但是并不是一直等于,
后期拥塞窗口可以不断的增加,但是发送端的窗口可能到达某个上限的时候就不再变大了
慢启动算法,如果一开始就把大量的数据传输到网络,很有可能出现网络的拥塞。一开始先慢慢的探测网络的传输速度,每收到一个ack,窗口大小
+ 1,每经过一个传输轮次,窗口大小翻倍
拥塞避免机制,如果拥塞窗口变化的过快的话,也有可能导致网络阻塞。所以设定了一个慢启动门限。当拥塞窗口到达门限之后,每经过一个往返轮次,拥塞窗口大小 + 1
快速重传机制,当接受端收到一个乱序的报文段,自动向客户端发送重复报文报错
快速恢复机制,当发送端连续收到三个ack重复应答的时候,
首先cwnd = cwnd / 2,然后ssthresh = cwnd。
然后再启动快速恢复算法。
AIMD算法?(add increase multify decrease)
在拥塞避免阶段,拥塞窗口是规律性线程增大,这个称为加法增大
当收到连续三个重复的ack的时候,cwnd / = 2, 然后ssthresh = cwnd,之后再进入快速恢复算法。这个称谓乘法变小
3.2 HTTP
1. GET与POST比较?
1>GET请求可以被缓存,POST不会,也可以说GET比POST更安全
2>GET请求长度有限制,PSTO没有
3>GET是明文传输,而POST的数据不会显示在URL中
4>GET的参数会保留在浏览器历史,而POST不会
5>GET的话,对浏览器回退是无害的,而POST的话会再次提交请求
既然GET这么不好。为什么还要有GET?
因为GET可以用来请求信息,然后返回信息主体。而POST是向指定资源提交数据进行处理请求(提交表单之类)
GET的size一般更小,并且GET回退的话对浏览器是无害的,而POST会再次提交请求
2. HTTP状态码
200 请求正常处理
301 页面永久性移走
302 页面暂时性移走
400 服务器不理解语法
401 请求身份验证
404 页面不存在
503 服务器正在访问的防止繁忙
504 服务器作为网关或者代理,无法正常从上游服务器或者请求响应。一般是上游服务器已经关闭
3. cookie的作用,安全性问题,和session的比较
cookie和session的作用,保留用户信息以简化登录手续
cookie只能存储asci字符串,session可以存储任何类型的数据,如果数据比较复杂的话,建议使用session
安全性问题,cookie数据保存在客户端的浏览器上,而session的数据保存在服务器上
别人可以通过分析存放在本地的cookie,获取数据。如果是为了安全的话,建议永session
单个cookie保存的数据不能唱过4K,并且cookie的个数也有限制
4. HTTP存在的安全性问题,以及HTTPS的加密,认证和完整性保护作用
安全性问题:
明文传输,无法确认对方身份,无法保证数据的完整性(可能已经被篡改)
HTTPS的加密,认证和完整性保护作用:
HTTPS = HTTP + 加密 + 证书 + 完整性保护
HTTP: HTTPS:
应用层,HTTP 应用层 HTTP
传输层,TCP SSL
网络层, IP 传输层,TCP
网络层, IP
5. HTTP/1.x 的缺陷,以及HTTP/2的特点
HTTP/1.x的弊端:
线程阻塞,在同一时间,同一域名的请求有一定的数目限制,超过数目的请求会被阻塞
HTTP/1.0的弊端:
每次连接只能处理一个请求
HTTP/1.1优势:
1> 长链接,可以被多个连接复用
2>管道机制,在同一个TCP连接中,客户端可以同时发送多个请求
3>新增了请求方式,PUT,delete,options
HTTP/1.1缺点:
在一个TCP连接中,所有的数据通信都是按照次序进行的,如果前面的处理请求比较慢,后面就只能等着
HTTP/2.0优势:
1>采用二进制格式代替文本格式
2>多路复用
3>报头压缩,降低开销
4>服务器主动推送
6. HTTP和FTP的区别?
HTTP,超文本传输协议;FTP文本传输协议
区别:
1> 功能上的区别
HTTP用于访问Internet上的不同网站,将网页内容从web服务器传输到客户端的web浏览器
FTP用于在FTP服务器和FTP客户端之间上传和下载文件
2> 连接上的区别
HTTP仅建立一个连接,数据连接
FTP建立两个连接,数据连接和控制连接
3>传输文件
HTTP可以有效的传输较小的文件,FTP可以有效的传输大文件
4>验证区别
HTTP不需要身份验证,FTP需要
5> 端口不一样
HTTP使用的是443,FTP使用的是20和21端口
3.3 socket
1. 五种IO模型的特点以及比较
阻塞I/O, 非阻塞I/O,信号驱动I/O,I/O复用,异步I/O
阻塞I/O,特点:进程阻塞挂起不消耗CPU资源,及时响应每个操作
适用场景:实现难度低,适用于并发量小的网络应用开发,如果是并发量大的应用
非阻塞IO模型,特点:通过轮询的方式查看是否有数据
适用场景:适合并发量小,并且不需要及时响应的网络应用开发
I/O复用模型,特点:专一进程解决多个进程IO的阻塞问题,性能好,开发难度较大,epoll
适用场景:适用高并发服务应用开发,一个进程/线程响应多个请求
信号驱动IO模型,进程预先告知内核,向内核注册一个信号处理函数,当内核数据就绪的时候,会发送一个信号给
进程,用户进程便在信号的处理函数中调用I/O读取数据
特点:并没有实现真正的I/O,回调机制,开发难度较大
异步IO模型,告知内核某个操作,并让内核在完成整个操作之后通知我们。
阻塞和非阻塞的区别?
阻塞是指调用结果返回之前,当前进程会被挂起,只有得到结果之后才会返回
非阻塞值得是不能立刻获得结果,这个调用不会阻塞当前进程
同步和异步的区别?
同步在今次那个IO的时候会将进程阻塞,异步是当进程发起IO操作之后,直到内核返回一个信号,
告诉进程说IO完成,在这个过程,进程没有被阻塞
信号驱动和异步io的区别?
首先,信号驱动是告诉我们什么时候可以进程一个IO操作,然后自定义信号函数,它是同步的。
而异步io是通知内核完成某个io操作,并让内核在整个操作完成的时候通知我们。
2. select,poll,epoll原理,比较以及使用场景?epoll的水平触发与边缘触发?
select原理,当应用程序通过 设备访问驱动 访问这个设备的时候,如果这个设备没有数据可读或者可写,就将这个用户进程插入到这个
设备对应的读/写等待队列中让其睡眠一段时间,等到有数据可读或者可写的时候,再将这个进程唤醒
缺点,单进程可以打开的fd有限;对socket的扫描是线性的,效率低;用户空间和内核空间的复制非常消耗资源
poll原理,同步多路IO复用,调用过程和select类型;和select不同点,采用链表的形式替换掉fd_set,没有连接数目的限制
epoll原理,同步多路IO复用,
- epoll向内核中注册一个文件系统,用于存储socket,当调用epoll_create的时候,会在这个epoll文件中创建一个file结点。这个节点只服务epoll
- epoll在被内核初始化的时候,会开辟出自己的内核高速缓存区,安置每一个socket,这些socket会以红黑树的形式在内核的cache中,以支持快速的查找,删除,插入
- 当调用epoll_ctl 的时候,向红黑树中添加节点,并且会向内核的中断处理程序注册一个回调函数,当这个句柄的中断到了,会把这个句柄放入到list链表中
- 然后我们调用epoll_wait的时候,仅观察这个list链表中是否有数据即可
数据库
4.1 SQL
1. 连接查询和子查询的比较?
子查询就类似于递归函数,有时候使用效率会很高;
子查询是一种嵌套查询,本质上是一个完整的select语句。
连接查询可以实现多个表之间的查询,包括内连接,左连接,右连接等等
连接查询的优点是,可以用尽可能少的sql进行查询;缺点是设计不好的好,会造成大量的内部IO操作和全表扫描操作
子查询的优点是,可以通过大量的索引,避免全表扫描;缺点是应用和数据库之间的IO调用比较多
2. drop,delete,truncate比较?
drop是直接把整个表都删掉;delete是删掉表的部分数据;truncate是删除表的数据,但是这个表的结构还是存在的
3. 视图的作用,以及何时能更新视图?
1>简化了操作,把经常使用的数据定义为视图
2>安全性,用户只能查询和修改能看到的数据
3>逻辑上的独立性,屏蔽了真实表的结构带来的影响
缺点:
1>性能差
sql server必须把视图查询转换成对基本表的查询,如果这个视图是由一个复杂的多表查询构成的。那么即使是一个简单的查询,sql server
也要把他变成一个复杂的结合体
2>修改限制
当用户视图修改图的某些信息的时候,数据库必须把他转换成对基本表的信息修改,如果是简单的视图来说,是很方便的。
但是对于比较复杂的视图,可能是不可修改的
4. 理解存储过程,触发器的作用
存储过程是模块化的SQL语句集,创建一次可以调用多次
触发器是一种特殊的类型的存储过程,是通过事件进行触发的
5. 什么是事务?事务的特性?
访问并更新数据库中各种数据项的一个程序执行单元
特性:
原子性 :原子操作,要么全做,要么全部做
一致性:必须是从一个状态到另一个状态
持久性:对数据库的影响是持久的
隔离性:并发的事务不会相互影响 {
隔离级别:
Read Uncommitted 读取未提交内容,所有的事务都可以看到其他未提交事务的执行结果
Read committed 读取提交内容, 一个事务只能看到已经提交事务所做的改变
Repeatable Read,mysql的默认事务隔离级别,确保同一事务的多个实例,在并发读取数据的时候,会看到同样的数据行
serializable,可串行化,强制的事务排序,使之不可能起冲突,解决了幻读的问题
}
脏读和幻读的区别?
脏读是一个事务对数据发生了改变,这个数据还没有提交到数据库,然后其他事务读取到了这个数据。
幻读是事务A是对表中数据做了改动,改动完毕之后其他事务又在表中增加数据,然后事务A查看数据发现有的数据还是没有改动,就像发生了幻觉一样。
脏读的解决方法是:读数据的时候添加共享锁,写数据的时候添加排他锁。更好的方法,可以通过MVCC来解决
幻读的解决方法是:设置级别为可重复读
6. SQL与NoSQL的比较?
1>SQL以数据库表的形式存储信息,而nosql存储方式更加灵活,可以使哈希表,json文档等等
2>在sql中,在定义好表的字段类型,字段名,约束条件之后才能向表中添加数据,而nosql数据可以在任何时刻任何地方添加,不需要先定义表
3>sql如果需要和别的表建立连接,可以通过外键的形式,而nosql可以通过非规范的方式将直接将外部数据集放到原数据集中,但是更新的时候比较麻烦
4>sql可以通过join表连接的方式将多个关系型数据库通过一条命令查询出来。nosql暂时并没有提供类似的查询方式
5>sql中如果一次更新多张表,如果其中一张表更新失败,其他表也不能更新成功,体现的是事务的原子性,而nosql中每一个数据集的操作是原子性的
6>nosql的查询性能是优于sql的
ps:一般可以采用sql + nosql 的方式进行信息的储存
如果是结构化数据,比如说账号,密码等适合使用sql存储;对于非结构化的数据,比如评论,文章等等可以采用nosql
7. mysql索引及其优化?
索引的目的:快速取数据,保证数据的唯一性,增加表和表之间的联系,使用order by ,group by 的时候可以减少查询中分组和排序和时间
分类:唯一键,主键,unique键,外键,自增长
什么时候使用索引:表中字段数据量大;经常被检索;经常被DML的资源不建议添加索引
索引对数据库的负面影响:索引需要占据物理空间;创建索引和维护索引需要耗费时间;在进行增删改查的时候,也需要对索引实现一个动态的维护,降低了数据的
维护速度
8. innode和myisam比较
如果提供提交,回滚,崩溃恢复能力的事务安全能力,并要求实现并发控制,innode是一个不错的选择
如果数据表主要用来插入和查询,在myisam引擎提供较高的处理效率
9. 水平切分和垂直切分
垂直拆分是将表按照不同的模块划分到不同的数据库表中
水平拆分是按照某种规则将数据划分到不同的表或者数据库中
10. 主从复制原理,作用,实现,好处,从数据库的读的延迟问题了解吗?如何解决?做主从后主服务器挂了如何解决?
什么是主从服务?
主从复制,是用来建立和一个主数据库完全一样的数据库环境,称为从数据库
原理:
1>数据库中有一个bin-log二进制文件,记录了所有的sql语句
2>我们的目标是把主数据库中的bing-log文件中的sql语句复制过来,让其在从数据的relay-log重做
日志文件中再一次执行这些sql语句
3>具体需要三个线程来处理:
1)每当有从库连接到主库的时候,主库都会创建一个线程发送binlog到从库
2)从库I/O线程,当start slave语句在从库中执行的时候,这个线程连接到主库并且请求主库发送回binog里面的
更新记录到从库上,从库io线程读取主库中的binlog,输出线程发送的更新并且拷贝这些到本地文件,其中就包括realy log文件
3)从库的sql线程,从库创建一个sql线程,这个线程读取主库io线程写到的relay log的更新事件并执行
作用:
1>主服务器故障之后,可以切换到从数据库继续工作
2>架构的扩展,io的访问频率过高,单机无法满足,如果做多库的储存,可以提高单个机器的io性能
3>读写分离,使得服务器能支持更多的并发
11. redo(重做日志),undo(回滚日志),binlog(二进制日志)日志的作用
redo loh是innode存储引擎的日志,也被称为重做日志文件,用来记录事务操作的变化。有了redolog日志,
在数据库进行异常重启的时候,可以根据redo log日志进行恢复;redo是循环写,日志大小固定
binlog是输入mysql server层,记录的是逻辑日志,记录的是更新语句的原始逻辑;binlog是追加写,不会发生覆盖
binlog可以作为恢复数据的使用,主从复制搭建;redo log作为异常宕机或者故障之后的数据恢复
undo log,保存事务发生之前的数据的一个版本,可以用于数据回滚
4.4 redis
1. 字典和跳跃表原理分析
跳跃表可以很好的解决有序链表查找特定值的困难,是对有序的建表增加上附加的前进连接,增加是通过随机化的方式进行的,所以在列表查找中可以快速的跳过部分列表
跳表的特点:
1>第一层包含所有的元素
2>每一层都是一个有序的链表
3>如果元素x出现在第i层,那么所有比i小的都包含x
4>第i层的元素通过一个down指针指向下一层拥有相同值的元素
5>在每一层中, -1 和 1都出现,分别表示 min和max
6>top指针指向最高层的第一个
2. redis的使用场景
高并发读写,大数据处理,计数器,排行榜
3. 与memcache的比较
1> 在存储小数据上,redis的性能比memcnached性能高。在100k以上的数据,memcached性能比
redis好
2>redis支持的数据类型比memcached高
3> memcached挂掉之后,数据不可恢复;redis数据丢失之后可通过aof恢复
4>redis和memcached都是将数据存储在内存中,但是memcached不支持持久化,超过内存比例之后会抹杀掉前面的
数据
5> nencache支持多核多线程,redis是单线程操作
4. 数据淘汰机制
初衷是通过一定的缓存miss来换取内存的使用效率,有多种淘汰策略。redis确定驱逐某个键值对后,会删除这个数据。
然后将这个数据变更发布到本地和slave
- volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
- volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数 据淘汰
- volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据 淘汰
- allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
- allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
- no-enviction(驱逐):禁止驱逐数据
5. RDB和AOF持久化机制
持久化就是将内存的数据写到磁盘中去,防止服务器宕机造成内存数据的流逝。
RDB,每次通过快照的方式重新重新记录整个数据集的所有信息,在恢复数据的时候更快
AOF,有序的记录了redis的命令操作,并且对记录优化策略
两种方式比较。aof比rdb更新频率更好,优先使用aof还原数据
aof比rdb的体积更大,更加安全
rdb的性能比aof好
如果两个都有,优先使用aof
6. redis的时间驱动模型?
文件事件和时间事件
7. 集群和分布式
集群就是多个人做相同的事情,分布式是多个人做不同的事情
集群就是同一个业务部署在多个服务器上,分布式是一个业务拆分成多个子业务,然后分布在多个服务器上
8. redis为什么这么快?
1> 完全基于内存,绝大部分请求是纯粹的内存操作,数据在内存的字典中,字典的结构类似于hashmap,查找和操作的时间
复杂度都是 O(1)
2>数据结构简单,基于C语言设计了许多 数据结构
3>采用了单线程,避免了不必要的上下切换和竞态条件,也不需要考虑死锁,多线程切换消耗cpu
4>使用了I/O多路复用模型(多个网络连接,同一个线程),非阻塞I/O
9. 为什么redis是单线程的?
redis是基于内存的操作,CPU不是redis的瓶颈,redis的瓶颈最有可能是 机器内存的大小和网络宽带,既然单线程容易是啊金,并
且CPU不会成为瓶颈,那就采用单线程
10. 超键,候选键,主键,外键
超键,在关系中,能唯一标识元素属性的集称为超键
候选键,在超键的基础上,不含有多余的属性的超键被称为候选键
主键,用户自己选定
外键,当前表的某一个键是另外一个表的主键,这个键在当前表上称为外键
具体解释:
https://blog.csdn.net/fjxcsdn/article/details/76549751
11. 为什么要用自增列作为主键
如果原来的表中含有主键,那么innode会选择主键作为索引。如果没有主键,innode会选择第一个不含有NULL的
唯一索引作为主键索引。
数据本身主要存储在B+树的叶子节点上,这就要求同一个叶子节点内,数据的存放是要按照主键顺序来实现的,每当有一个新的数据插入的时候,mysql会根据主键将其插入到适当节点和位置。
如果表使用自增主键,每次插入数据,记录会顺序添加到当前索引的后续位置。
如果表不使用自增主键,每次插入数据,有可能会对树的结构进行大的调整,会增加许多开销和时间的浪费
12.drop、truncate、 delete区别
最基本:
- drop直接删掉表。
- truncate删除表中数据,再插入时自增长id又从1开始。
- delete删除表中数据,可以加where字句。
(1) DELETE语句执行删除的过程是每次从表中删除一行,并且同时将该行的删除操作作为事务记录在日志中保存以便进行进行回滚操作。TRUNCATE TABLE 则一次性地从表中删除所有的数据并不把单独的删除操作记录记入日志保存,删除行是不能恢复的。并且在删除的过程中不会激活与表有关的删除触发器。执行速度快。
(2) 表和索引所占空间。当表被TRUNCATE 后,这个表和索引所占用的空间会恢复到初始大小,而DELETE操作不会减少表或索引所占用的空间。drop语句将表所占用的空间全释放掉。
(3) 一般而言,drop > truncate > delete
(4) 应用范围。TRUNCATE 只能对TABLE;DELETE可以是table和view
(5) TRUNCATE 和DELETE只删除数据,而DROP则删除整个表(结构和数据)。
(6) truncate与不带where的delete :只删除数据,而不删除表的结构(定义)drop语句将删除表的结构被依赖的约束(constrain),触发器(trigger)索引(index);依赖于该表的存储过程/函数将被保留,但其状态会变为:invalid。
(7) delete语句为DML(data maintain Language),这个操作会被放到 rollback segment中,事务提交后才生效。如果有相应的 tigger,执行的时候将被触发。
(8) truncate、drop是DLL(data define language),操作立即生效,原数据不放到 rollback segment中,不能回滚。
(9) 在没有备份情况下,谨慎使用 drop 与 truncate。要删除部分数据行采用delete且注意结合where来约束影响范围。回滚段要足够大。要删除表用drop;若想保留表而将表中数据删除,如果于事务无关,用truncate即可实现。如果和事务有关,或老师想触发trigger,还是用delete。
(10) Truncate table 表名 速度快,而且效率高,因为:?truncate table 在功能上与不带 WHERE 子句的 DELETE 语句相同:二者均删除表中的全部行。但 TRUNCATE TABLE 比 DELETE 速度快,且使用的系统和事务日志资源少。DELETE 语句每次删除一行,并在事务日志中为所删除的每行记录一项。TRUNCATE TABLE 通过释放存储表数据所用的数据页来删除数据,并且只在事务日志中记录页的释放。
(11) TRUNCATE TABLE 删除表中的所有行,但表结构及其列、约束、索引等保持不变。新行标识所用的计数值重置为该列的种子。如果想保留标识计数值,请改用 DELETE。如果要删除表定义及其数据,请使用 DROP TABLE 语句。
(12) 对于由 FOREIGN KEY 约束引用的表,不能使用 TRUNCATE TABLE,而应使用不带 WHERE 子句的 DELETE 语句。由于 TRUNCATE TABLE 不记录在日志中,所以它不能激活触发器。
12. 哪些适合建立索引,哪些不适合建立索引?
适合建立:
1. 经常需要搜索,建立索引可以加快搜索的速度
2. 经常用在连接的列上,可以加快连接的速度
3. 需要排序的列上创建索引
4. 需要根据范围进行排序的索引
不适合:
1. 查询中很少使用
2. 数据比较少
3. 当修改性能远远大于检索性能的时候
当增加索引的时候,会提高检索性能,会降低修改性能。反之也成立。
13. mysql中B+ Tree索引和hash索引的区别?
1. 各自的特点
1)hash的检索效率非常高,可以一次定位
2)b+树索引需要从根节点到枝节点,最后才能访问到叶节点,需要进行多次IO操作
2. 为什么不都用hash索引而是用b+树索引 ?
1) hash索引仅仅能满足 "=", "IN" 等查询,不能使用范围查询
2)hash索引在遇到大量hash值相等的情况后性能不一定比b+树高
3)b+树索引的关键字检索效率比较平均,在有大量重复键值的时候,哈希索引的效率比较低
14. 聚集索引和非聚集索引的区别有哪些?
聚集索引表示表中存储的数据按照索引的顺序顺序存储,检索效率比非聚集索引效率高,但是数据更新操作效率并不高;非聚集索引表示数据存放在一个地方,索引存储在另一个地方,索引带有指向数据的指针。非聚集索引的监所效率比聚集索引效率低,但是数据更新影响比较小。
根本区别是聚集索引和非聚集索引的表记录顺序和索引的排列顺序是否一致
15. mysql存储引擎myisam和innode如何选择
1. innodb会支持一些关系数据库的事务,外键等功能,myisam不支持
2. myisam适合查询已经插入为主的应用,强调的是性能;innode适合频繁的修改以及涉及到安全性较高的应用
3. myisam只支持表级锁;innode支持事务和行级锁,行锁大幅度提高了多用户并发操作
16.mysql都有什么锁,思索判断原理和具体场景,死锁怎么解决?
mysql有三种锁的级别:
页级,表级,行级
页级:开销和加锁的时间介于表锁和行锁之间;会出现死锁,并发度一般
表级:开销小,加锁快。不会出现死锁,发生锁冲突的概率最大,并发度最低
行级:开销大,加锁慢。会出现死锁,发生锁冲突的概率最低,并发度高
锁冲突和死锁区别?
锁冲突是等待别人释放自己所需要的锁资源;死锁是两个或者两个以上的session因为争夺资源造成的一种互相等待的现象
若没有外力,他们都将无法推进下去
死锁的关键在于:
两个或者两个以上的session加锁的顺序不一致。对应的解决死锁问题的关键就是:让不同的session加锁有次序
死锁的解决办法:
1. 设置锁的超时时间
2. 指定获取锁的顺序
17. 乐观锁和悲观锁?
乐观锁,假设多用户并发的事务在处理事务的时候不会彼此影响,各个事务能够在不产生锁的前提下,处理各自影响的那部分数据,在提交数据更新之前,每个事务会检查在该事务读取数据之后,有没有其他事务修改了数据。如果其他事务有更新的话,当前正在提交的事务会进行回滚
悲观锁:认为获取锁是非常有可能失败的,因此要先确保获取锁成功,再进行业务操作。
ps:乐观锁再不发生取锁失败的时候,开销比悲观锁小。一旦发生取锁失败,回滚的开销比悲观锁大,因此乐观锁适合在取锁失败的场景;
如果需要非常高的相应速度,建议采用乐观锁,成功就执行
如果冲突频率非常高,建议采用悲观锁
如果重试代价比较大, 建议使用悲观锁
18. mysql高并发环境解决方案?
分库,分表,分布式,增加耳机缓存
19. 数据库崩溃时事务的恢复机制(REDO日志和UNDO日志)?
REDO log是为了实现事务的原子性;在操作任何数据前,首先将数据备份到一个地方,然后进行数据的修改,如果出现了错误,或者用户执行回滚操作,系统可以使用undo log的备份实现数据的恢复;每个事务提交前将数据和undo log写入到磁盘,会导致大量的磁盘IO,性能比较低
UNDO log原理和redo log原理相反,记录的是新数据的备份,当系统崩溃的时候,虽然数据没有持久化,但是redo log已经持久化,系统可以根据redo log的内容,将所有数据回复到最新的状态
20. 日志的分类
1. 错误日志:记录启动,运行或者停止mysql时出现的问题
2. 通用日志:记录建立的客户端连接和执行的语句
3. 更新日志:记录更新数据的语句
4. 二进制日志:记录所有更改数据的语句
5. 慢查询日志:记录所有执行时间超过long_query_time秒的所有查询或者不适用索引的查询
6. innodb日志:innodb redo log
21. 慢查询
对索引的优化:
选择合适的列建立索引
数据库结构优化:
1. 数据库表的垂直拆分:把一张列比较多的表拆分成多张表
2. 数据库表的水平拆分:对数据表行的拆分
3. 数据库表的范式化优化
1. 第一范式:每一行都是不可拆分的原子项
2. 第二范式:表中的每一列都和主键相关
3. 第三范式:表中的每一列都和主键直接相关,而不是间接相关
4. 数据库表的反范式优化:对于第三范式,进行增加适当的冗余,通过空间换取时间的方法
系统配置优化:
配置文件优化
增加mysql允许使用de物理内存
增加缓冲池的数目
服务器硬件优化
5. 面向对象
1. 面向对象三大特征
封装,继承,多态