春招测开岗面试高频考点万字汇总(一)
帖子太长了 就分开来写啦
本贴主要是操作系统、计算机网络、数据库的高频和常见考点
指路☞春招测开岗面试高频考点万字汇总(二)https://www.nowcoder.com/discuss/628643?source_id=profile_create_nctrack&channel=-1
涵盖了linux、python、测试相关的高频和常见考点总结以及常考代码题
面试总结
本人渣硕,本硕均为非科班,无测开相关项目(这点很吃亏,建议大家在找工作前一定要去实习或者做过相关的项目,在面试的时候面试官才能够有根据地去提问,也能够突出自己的优势)
所幸突击两个月计算机基础还算不错,有幸上岸拿到几个大厂的offer。面试总体的感受测开岗比较重基础,大部分时候不会问得很深入,但是基础的一定要掌握,不能一知半解。计算机网络问的会比较多,操作系统与数据结构也有所涉及,数据库和linux查询操作也很重要,还有常用编程语言的特性。
此外,测开岗面试官会比较看重面试者的沟通表达能力和逻辑思维能力,尽量不要紧张,回答问题时要条理清晰,1234分条循序渐进地回答。
下面是我在翻看测开岗面经以及自己面试的时候遇到的一些高频考点,回馈牛客~
计算机网络面经
高频考点
1. UDP和TCP的区别
①TCP是面向连接的,UDP是无连接的
②TCP所需资源多,传输速率慢,UDP所需资源少、传输速率快
③TCP的数据传输以字节流的形式,UDP的数据传输是以报文段的形式
④TCP用检验和、标号、流量控制、拥塞控制、超时重传等机制保证TCP连接是可靠的,UDP则不保证可靠交付,只保证尽力交付
⑤TCP只适用于一对一单播,UDP可用于广播通信
⑥TCP适用于对可靠性要求较高的场景,比如文件的传输等,UDP适用于实时性要求较高的场景,比如微信视频通话等。
2. TCP的三次握手、四次挥手
2.1详细过程以及C和S的状态
三次握手
首先发起连接的一端称为客户端,被动等待连接的一端称为服务器端
1.客户端向服务器端发送一个同步报文,该TCP报文的首部控制位SYN=1,序列号随机,这里定为x。客户端发出报文后进入SYN-SENT状态
2.服务器接收到报文进入到SYN-RECIVED状态,并返回一个确认报文给客户端,该TCP报文的首部控制位SYN=1,ACK=1,序列号为y(随机),确认号为x+1
3.客户端接收到服务器端传来的确认报文后进入到established状态,并传送一个确认报文的确认给服务器,该报文的首部字段控制位ACK=1,序列号为x+1,确认号为y+1,此时可以携带数据部分。服务器端接收到该报文后进入到established状态
四次挥手
客户端和服务器端如果完成数据传送工作后,均可主动发起连接释放请求,这里假设客户端首先发起连接释放。
1.客户端发送FIN报文给服务器端,并进入到FIN-WAIT1阶段,该FIN报文包括首部字段控制位FIN=1,序列号seq=u,告诉服务器我已完成我的数据传输工作,你这边如果还有数据可以继续传送
2.服务器收到该FIN报文之后进入close-wait阶段,并返回一个确认报文给客户端,该确认报文包括首部控制位ACK=1,seq=v,ack=u+1。客户端收到该确认报文后进入fin-wait2状态,关闭从客户端到服务器端的数据传送。服务器端仍可向客户端传送数据
3.服务器端完成对客户端的数据传送工作之后,服务器端向客户端发送FIN报文,该报文结构包括FIN=1,ACK=1,序列号为w,确认号为u+1,并进入Last-ACK状态
4.客户端接收到该FIN报文后,返回确认报文,该确认报文包括首部控制位ACK=1,序列号为u+1,确认号为w+1,并进入time-wait阶段,等待2MSL后确认服务器端收到ACK报文正常断开连接后,客户端关闭。服务器端收到该确认报文,进入closed状态。
等待2MSL的原因 确认服务器端是否正常收到了客户端最后发出的确认报文,如果服务器端没有收到的话,过1MSL(报文在网络中的最大存活时间)会重新再发送一次FIN报文给客户端,如果过了2MSL还没有收到新发的FIN报文的话,证明服务器端已经收到确认报文并正常关闭连接,客户端也可以关闭连接啦~
2.2为什么三次握手?为什么四次挥手?
三次握手的原因
确保双方间的连接正常建立,如果只有两次握手的话可能会出现一些异常情况,比如:①客户端的SYN连接请求失效(或者发去时间太久,导致了超时重传的发生),但是服务器端接收到了该SYN报文,如果不经过第三次握手的话服务器端就会错误地开启一个连接;③如果只有两次握手地话,服务器端返回给客户端的确认报文丢失,会导致客户端因为没有收到确认所以关闭了该连接,但服务器端此时已做好了连接准备,造成资源的浪费
四次挥手的原因
因为建立连接时双方都处于closed状态,而释放连接时一方收到FIN报文但有可能还有数据要继续传输,不能马上释放连接,所以先返回一个确认报文,发送完数据后再断开连接
3. 输入URL到显示网页发生了什么
- 浏览器解析URL对应的IP地址
DNS解析过程,浏览器缓存—>操作系统缓存—>本地DNS—>根据转发模式选择迭代还是递归查询
- 浏览器向服务器发送一个HTTP请求报文
传输层上建立TCP连接,网络层用到了IP协议(负责在网络层传输数据),还会用到RIP或者OSPF进行路由选择,然后用ARP协议解析IP地址对应的MAC地址,使得数据能够在数据链路层上进行传输(不应该是最后到物理层传输吗)。
HTTP请求方法有哪些(post/get/head/put/delete)
- 服务器请求处理并返回一个HTTP响应报文
HTTP响应报文的结构,状态码
- **服务器返回一个HTML响应,浏览器收到HTML响应并渲染界面
4. OSI七层协议及每层作用
物理层
数据以比特流的形式在物理层传输
设备有中继器、集线器(作用:转发、放大信号)
数据链路层
负责将数据组帧,实现链路管理、流量控制和差错控制
协议有GBN后退N帧协议
、SR选择重传协议
、以太网协议
设备有网桥、交换机(作用:根据MAC地址对帧进行过滤转发,可以隔绝冲突域,不能隔绝广播域)
冲突域:同一时间内只能有一台设备发送信息的范围
广播域:网络中能接收到任意设备发出的广播帧的设备的集合
网络层
提供主机和主机之间的逻辑通信
协议有ARP协议、OSPF/RIP路由寻址协议、DHCP协议、ICMP协议、IGMP组播协议、IP协议、CIDR协议
设备有路由器(作用:转发分组)
传输层
提供端到端的可靠报文传递,负责将数据传送至对应端口,提供进程和进程之间的逻辑通信
协议有TCP UDP协议
会话层
负责建立、管理、终止进程之间的会话
表示层
对上层数据或者信息进行变换,以保证一个主机应用层信息可以被另一个主机应用层所理解,包括数据加密、格式转换、压缩等
应用层
为操作系统或者网络应用程序提供访问网络的接口 协议有HTTP FTP SMTP DNS协议
5. HTTP和HTTPS的区别
HTTP协议是超文本传输协议,采用客户端/服务器的方式,它的特点是:①无连接,建立在TCP连接的基础之上;②无状态,cookie和session可以辅助记录客户端/服务器的状态
1.HTTP协议运行在TCP之上,不提供身份认证和数据加密,所有数据都是以明文的形式传输的;HTTPS以SSL为安全基础,提供了数据加密和服务器端的身份认证(以对称加密的方式为传输的数据进行加密,用数字证书的方式提供服务器端的身份认证),更为安全
2.HTTPS比HTTP需要耗费更多的资源,响应速度也更慢
3.HTTPS需要CA颁布申请证书,通常不是免费的
4.HTTP和HTTPS是完全不同的连接方式,HTTP端口号是80,HTTPS的端口号是443
6. 常见状态码
1xx 表示正在处理
- 100 continue 一切正常 可以继续发送(据说是http报文中如果有post方法的话 会先把请求行发送过去,然后返回100,然后再发送请求头部和请求体给服务器端)
2xx 成功 表示请求已经正常处理
- 200 OK 一切正常返回数据
- 204 No content 请求正常处理,但是没有数据返回
- 206 指定范围返回(http1.1以上支持的断点续传功能相关)
3xx 重定向 浏览器需要一些额外的操作才能完成请求
- 301 永久性重定向
- 302 暂时性重定向(跟http劫持有关,运营商可以通过DNS劫持和http劫持两种,返回一个302,然后让用户跳转到处理好的携带广告的页面)
- 303 暂时性重定向 但是服务器端明确说明希望浏览器用get方法来请求资源
- 304 浏览器附带了请求的条件,服务器端允许访问,但是不满足请求条件
4xx 客户端错误
- 400 客户端的请求有语法错误
- 403 forbidden 客户端申请访问的资源被禁止访问
- 404 Not found 客户端申请访问的资源不存在
- 405 Method not allowed 客户端请求方法被禁止
5xx 服务器端错误
- 500 服务器在请求处理时内部出错
- 501 服务器不具备完成请求的功能,如无法识别请求方法
- 502 服务器作为网关或代理,从上游服务器获得无效响应
- 503 Bad Gateway 服务器处于停机维护/超负荷状态
- 504 Gateway timeout服务器作为网关或代理,没有及时从上游服务器获得响应
7. cookie和session的区别
首先它们都是用于给无连接的http提供身份认证的功能
cookie是服务器在本机存放的小段文本,并随每一个请求发送至同一服务器。cookie分为会话cookie(不设置过期时间,关闭浏览器窗口cookie即失效,保存在内存中)和持久cookie(设置过期时间,关闭再打开浏览器cookie仍存在,直至达到过期时间)。类似于检查通行证(即请求报文中附带的cookie)来确定用户身份
session则一般是利用session id实现的(session id是浏览器第一次发送请求时服务器自动生成的唯一标识,并返回给浏览器),cookie中携带该session id,客户端根据该session id将session检索出来。类似于在服务器上建立一个客户档案,客户来访时需要查询客户档案
1.cookie是存放在客户端,用于记录用户信息的,比如自动填充用户名和密码;session是存放在服务器端的,用于记录用户的状态,比如购物车的实现。
2.cookie不太安全,可以分析存放在本地的cookie进行cookie欺骗,(也可以用加密算法加密后进行存放),session存放于服务器的内存中,所以安全性高
3.单个cookie保存数据不能超过4k,session没有对存储数据量的限制
禁掉cookie的话session仍然可以使用,但是需要使用其他方法获取session id,比如在url后面或者以表单的形式提交给服务器端
8. get和post的区别
注意存放在请求行和请求体的不是方法 而是请求/提交的数据啊喂 post和get方法都是在请求行中啦
1.get数据明文存放在http请求行的url之后,post则是将提交的数据放在http请求报文的请求体中
2.受浏览器对url长度的限制,get传送数据量应不超过2KB。post传送数据量则一般无此限制
3.get只接受acsii字符,post没有限制,get只支持url编码,post没有限制
4.get不能改变服务器的数据,一般用于从服务器获取数据,是幂等的;post可以改变服务器的数据,不是幂等的。
5.get请求可以被浏览器主动缓存,下一次若传输数据相同,则优先返回缓存中的内容,以加快显示速度。post请求不会,除非手动设置一下
6.get请求参数会被完整地保存在浏览器历史记录中,post请求参数则不会保留
9.TCP如何保证可靠性
分段 将报文段分成适合转发的长度
标号 按照序号判断中间的转发是否有缺失
流量控制 根据双方的接收发送能力,动态地调整发送方发送窗口的大小,取发送窗口=min(拥塞窗口,接收窗口) (与数据链路层收不下的话返回一个信号告诉发送方自己收不下的流量控制机制不同)
检验和 TCP首部有检验和字段,目的是检验首部+数据部分的数据是否正确,是不是被人篡改或半路出现差错。
超时重传 发出报文段之后启动定时器,如果重传时间RTT内没有收到确认的话,就重传该数据报,也可以采用冗余确认机制(三次接收到同一个ack=k的确认序号,就重传第k个报文段)(快重传中采用的也是冗余重传)
主要涉及的协议有两种(跟数据链路层的超时重传机制相同):
- 停止等待协议 每发送一个报文段就停止,直到收到确认才继续发送,否则超时重传
- 滑动窗口协议
- 后退N帧协议 GBN: 发送窗口>1,接收窗口=1,即接收方必须按照顺序去接收数据,如果启用了超时重传机制的话,就会重传所有当前已经发送但是没有被确认的报文段
- 选择重传协议 SR: 发送窗口>1,接收窗口>1,即接收方无需按照顺序去接收数据,会按照任意顺序接收所有处于接收窗口内的数据。按照如果启用超时重传机制的话只需要重新发送没有收到确认的数据即可。
拥塞避免 分为两种:①慢开始,拥塞避免 ②快重传、快恢复
检验和的具体工作流程**
检验和是TCP和UCP中都有的 要注意检验的是首部和数据字段的有效性
- 添上伪首部
- 首部检验和字段置为0
- 伪首部+首部+data部分用二进制反码求和,并将结果填入到检验和字段
- 去掉伪首部发送
- 发送方接受到该数据之后,首先添上伪首部
- 接着计算伪首部加首部加数据部分的二进制反码求和
- 如果全为1则无差错,去掉伪首部交给网络层,否则丢弃。
常见考点
1.IP地址与MAC地址的区别?为啥有了IP地址还需要MAC地址
MAC地址是网络中每个设备都有的唯一网络标识,全世界唯一。
IP地址只是逻辑上的标识,任何人都能随意修改,因此不能具体标识一个用户,但MAC地址固化在网卡里,防止被盗用。
但是如果只用MAC地址的话,因为MAC地址无序杂乱,没有明显规则,难以查找。但是IP是分层的,类似通讯地址,可以根据其网络号找到子网再定义主机,逐级查找,每个设备需要存储的信息较少
MAC地址与IP地址的区别:
①长度不同,IP地址一般为32位(IPv6 128位),MAC地址则是48位
②分配依据不同,IP地址分配基于网络拓扑,能够根据需要改动设备的IP地址,但是MAC地址的分配是基于制造商,在网卡中烧录好,一般不轻易改变
③寻址协议层不同,IP地址应用于网络层,MAC地址应用于数据链路层(数据链路层基于MAC地址转发数据帧,数据链路层的交换机根据其MAC地址记录表中的MAC地址及其对应的端口,将其发送到MAC地址对应的端口,否则广播;网络层则根据IP地址转发报文,路由器根据路由表转发到对应端口,否则发送默认路由)
2.ARP协议
作用:实现IP地址到MAC地址的映射(由IP地址获得MAC地址)
流程:根据主机A路由表的内容查找B的IP地址,再从A的ARP高速缓存中寻找是否有B的MAC地址,如果没有则广播ARP请求帧(构成为Aip+Bip+A_MAC+全1
)至该局域网内所有的主机。如果主机发现该请求帧中的IP地址与自己的相同则返回一个单播ARP帧(构成为Bip+B_MAC
)返回给主机A,并且AB均更新自己的ARP高速缓存。
3.http协议的发展历程(1.0 1.1 2.0 3.0)
http1.0和http 1.1的主要区别是什么?
1.连接 HTTP1.0默认使用短连接,每次请求不同的资源都需要重新建立一次连接;HTTP1.1起默认使用长连接,默认开启keep-alive,即同一个TCP连接可以发送和接收多个http请求/响应,这种长连接由流水线方式和非流水线方式,流水线方式是指客户在收到http响应报文之前就能够接着发送新的请求报文,非流水线方式是指客户在收到http响应报文后才能接着发送下一个请求
2.状态码 HTTP1.1新增24个状态码,409表示请求的资源与资源当前状态发生冲突,410Gone指的是服务器上某个资源被永久删除
3.带宽优化及网络连接使用 ——http1.1支持断点续传,HTTP1.0中不支持只显示对象的一部分(只能显示全部)、且不支持断点续传功能,浪费带宽;HTTP1.1在请求头中引入了range头域,允许只请求资源的某个部分,返回码是206(partial content)
http2.0的改进
1.头部压缩 减少冗余头信息,用了首部表来跟踪、存储之前的键值对,相同的数据就无需再每次重复请求和响应了
2.多路复用 实现由一个tcp连接并发请求。http1.1多个请求的响应之间会被阻塞
3.服务器推送:可以主动将资源推送给客户端缓存中
4.二进制格式:采用二进制而非文本格式,将所有传输的信息分割为更小的消息和帧(二进制帧)
3. 客户端故障检测方法?
客户端故障检测方法----保活计时器
目的:在长连接的情况下,检测没有响应的连接并且将其断开(即客户端出现了故障), 防止占用过多的连接资源
客户端打开服务器的连接传送数据后,就保持沉默了,此时有可能客户端出了故障.
解决方法就是使用保活计时器, 每当服务器收到客户端的信息的话,该计时器就复位, 如果两个小时之内还没有收到客户信息,就发送探测报文段,如果发送了10个探测报文段还没有响应的话, 就认为客户端出了故障,终止该连接
4. SYN洪泛攻击如何解决?
攻击者伪装成客户端发送TCP的SYN报文, 当服务器返回ACK确认报文之后, 攻击者不再进行确认, 即不回复确认的确认报文, 这个连接就处于一个挂起的状态, 服务器收不到确认报文的话, 会启用超时重传机制, 重复发送ACK给攻击者
这样的话,如果攻击者开启大量这种TCP连接, 导致服务器端有很多个挂起的连接, 并且需要重复发送很多ACK给攻击者, 这样就会消耗服务器的内存 可能导致最后服务器死机, 无法正常工作
解决方法
- 降低SYN timeout时间 使得服务器在没收到确认报文后尽快释放半连接的占用
- 采用SYN cookie设置 给每一个请求连接的ip地址分配一个cookie,短时间内如果连续收到某个IP的重复的SYN报文,就认定收到了攻击,以后会自动丢弃该ip地址传送过来的包
操作系统面经
高频考点
1.进程与线程的区别
进程:系统进行资源调度和分配的最小独立单位。具有独立性,动态性,并发性,异步性。实现了os的并发性
线程:程序执行的最小单位。自身基本不拥有系统资源,只拥有一些运行中必不可少的资源,如程序计数器、寄存器和栈等。可与同属于一个进程的不同线程共享进程所拥有的全部资源。实现了进程间的并发性
联系:进程(主线程)创建了多个线程,各个子线程拥有自己的独立栈空间(存储函数参数、局部变量等),多个子线程与主线程共享堆、全局变量等非栈内存。一个程序至少有一个进程,一个进程至少有一个线程,线程依赖于进程而存在。
区别:资源、切换效率、通信机制
一个线程挂掉,会导致该线程所属的进程整个挂掉,进程中的其他线程也都挂掉,但是一个进程挂掉,不会影响其他进程
2.进程间的通信方式
2.1 管道
2.2 消息队列
2.3 信号
2.4 共享内存
3.线程间的通信方式
针对于python中的threading模块来说
3.1 全局变量
3.2 消息队列 (threading模块中的Queue类)
4.常见锁
4.1 互斥锁
4.2 多重入锁(允许一个进程/线程多次拿到锁)
4.3 自旋锁 (CPU不断检查锁是否可用)
4.***
4.5 条件
4.6 信号量 (一次允许多个线程操作锁对象)
4.7 读写锁 (一次只有一个写者,多个读者)
5.死锁产生的原因及解决策略
5.1 死锁产生的四个必要条件
1.互斥条件
2.占有并等待条件
3.环路等待条件
4.不抢占条件
5.2 死锁解决策略
1.死锁预防
主要的思想:提前破坏死锁产生的四个必要条件,静态地避免死锁发生
①破坏互斥条件
把某些互斥访问的资源改造成共享资源(SPOOLing技术)
缺点:可行性不高
②破坏占有并等待条件
方法一:在进程执行前,一次性分配进程所需的全部资源,如果资源得不到满足,则不分配任何资源,暂不执行。
方法二:只有当进程不占有资源时才分配给进程资源。进程可以占有一部分资源,但是当它向os索取更多资源的时候必须先释放当前占有的全部资源
缺点:进程动态执行,难以事先预知进程所需的全部资源;资源利用率低;可能会导致饥饿
③破坏不抢占条件
方法一:申请的资源得不到满足时则立即释放当前所拥有的全部资源
方法二:由操作系统干预按照优先级从别的进程那里剥夺某些资源
缺点:实现复杂;强行剥夺可能会导致进程失效;反复申请和释放导致系统性能较低;可能导致饥饿
④破坏环路条件
给所有资源排序编号,所有进程对资源的申请必须按照严格递增的顺序提出,每次只能申请序号更大的资源,防止产生环路
缺点:导致资源浪费,不方便加入新资源
2.死锁避免
动态地检测资源分配状态,以确保系统处于安全状态。
通过银行家算法进行动态评估,如果有风险就拒绝分配
银行家算法
步骤:
1.一个进程向系统提出资源申请,首先检查此次申请是否超过了之前声明的最大需求数,如果超过则认为出错;
2.检查此时系统剩余的可用资源是否还能够满足该次请求,若不满足则等待
3.试探着(不是真的分配)分配,更改各类数据结构
4.用安全性算法检查此次资源分配是否会导致系统进入不安全状态,若安全才进行资源分配
总结:进程提出资源请求时,判断是否超出进程最大需求资源、是否超出系统最大所剩资源,然后模拟分配,用安全算法检测分配了之后是否所有线程属于安全序列,如果安全则才能正式分配资源。
安全算法
检查当前的剩余可用资源是否能满足某个进程的最大需求,如果可以,就将该进程加入到安全序列,并把该进程持有的资源全部回收,重复上述过程,看最终是否能够让所有进程加入安全序列。
系统处于安全状态一定不会死锁
系统处于不安全状态未必会死锁,但是死锁时系统一定是不安全状态
3.死锁检测
采用资源分配图算法检测最终哪些进程会发生死锁。(允许发生死锁,主要是检测哪些进程会发生死锁)
流程:消除所有不与阻塞进程相连的边,直到无边可消。如果该节点的资源需求得到满足,则消除该节点及其所连的边,直到无边可消。如果此时图内没有任何边,则一定没有死锁,如果还有则一定会发生死锁。
4.死锁解除
①资源剥夺法
挂起某些死锁资源,抢占其资源分配给其他的死锁进程
缺点:被挂起的进程可能会导致饥饿
②终止进程法
强制终止部分、甚至全部死锁进程,并剥夺其所占有的资源
缺点:付出代价较大,有些进程已近结束,终止就会功亏一篑
③进程回退法
让一个或多个进程回退到不会发生死锁的地步
缺点:要求系统记录进程的历史信息,设置还原点,浪费系统资源
常见考点
1.内存换出算法
FIFO先进先出
思想:淘汰最先进入的页面,采用队列实现,先进先出
缺点:可能会频繁地换入换出,影响效率
OPT最佳算法
思想:淘汰以后不需要使用或者最远才会用到的页
缺点:实际操作中无法预测未来页的使用情况
LRU最久未使用淘汰算法
思想:淘汰最长时间没有被使用的页。软件可以用双向链表实现,访问的时候就把该页移到头部,淘汰时淘汰尾部。
LFU最不经常使用淘汰算法
思想:淘汰访问频率最小的页,以次数为参考。新加入的页放在末尾,计数器置为1,每次访问计数器+1,并重新按照计数器大小排序,淘汰计数器最小的页
2.进程调度算法
1.先来先服务
2.短作业优先
3.高响应比优先
4.时间片轮转法
5.优先级调度算法
6.多级反馈队列
分为多个队列,优先级从高到低,不同的队列分配的时间片由小到大
进程到来先将其加入第一队列,按照FCFS的原则给第一队列的进程分配时间片,时间片耗尽进程未处理完毕则将其加入到下一队列的尾部(本身就是最后一个队列的话就加入到最后一个队列的尾部)。只有当1~n-1队列为空时才能开始处理第n个队列。
实际情况中如何选择进程调度算法?
根据是否要关注优先权,如果不考虑优先权可以采用高响应比优先算法,如果考虑优先权可以采用多级反馈队列。
数据库面经
高频考点
1.事务的四大特性
1.1 四大特性
原子性
保持事务的原子性是指操作发生异常时,需要对该事务所有之前执行过的操作进行回滚。首先要设置autocommit=0,就是默认不能隐式提交,需要手动commit提交。回滚需要undo日志实现,undo日志存放之前修改过的记录,事务发生异常触发roll back,会按照日志逻辑回滚undo日志的操作。
一致性
一致性可以理解为事务对数据完整性约束的遵循。事务执行前后都是合法的数据状态,不会违背任何数据完整性
从数据库层面,数据库通过原子性、隔离性、持久性来保持一致性。
隔离性
用锁和隔离机制。锁是需要用户自己定义的,隔离机制是数据库提供的。
持久性
在无并发事务的情况下,持久性依赖于原子性;在有并发事务的情况下,持久性依赖于原子性和隔离性
即使数据库系统遇到故障也不会丢失已提交事务的操作,通过redo日志来实现的。基本步骤如下图 :①当在事务中尝试对数据进行更改时;②首先将数据从磁盘读入内存,更新内存缓存的数据。③生成一条redo日志缓存,放在redo日志的缓冲区;④事务真正提交时将缓冲区中的日志写入redo日志做持久化保存;⑤把内存中的数据同步到磁盘上。
1.2 隔离级别⭐⭐
在并发状态下,事务会出现一些问题,主要有三种问题:
脏读 一个事务能读到另外一个事务没有提交的数据。(举例:A给B转了100块,但是A转完并没有提交该事务,B读到了自己的账户多了100块,此时A发现转账错误之后就回滚了该操作,此时就称为脏读)
不可重复读 一个事务的两次查询操作数据不一致,可能是两次查询过程中插入了一个事务更新了原有的数据(举例:两个并发事务A和B,A首先查询自己的账户是100块,B此时提走了A账户的50块,A再次查询发现此时账户只剩下了50块,两次查询操作结果不同)
幻读 在一个事务的两次查询中数据不一致,发现了原来没有的数据或者原有的数据不见了
不可重复读与幻读相似,不可重复读侧重于另一个事务对数据库的
修改
操作,而幻读则侧重于另一个事务对数据库的增加
和删除
操作
Ⅰ.读未提交
允许读取另一个事务尚未提交的数据,可能会造成脏读、不可重复读、幻读
Ⅱ.读已提交
允许读取并发事务已经提交了的数据,可以阻止脏读,但是不能避免不可重复读和幻读
Ⅲ.可重复读
在一个事务的操作过程中,不能读取到别的事务对该数据库的修改增删操作,可以阻止脏读和不可重复读,但是不能避免幻读(mysql默认级别)
Ⅳ.串行化
所有的事务依次逐个执行,当表被一个事务操作时,其他事务的操作不可以进行,进入排队状态,等待当前操作事务提交后才能继续执行操作。
1.3 锁
按使用方式分为乐观锁、悲观锁
按粒度分为表级锁、行级锁、页级锁 (InnoDB支持行级锁、表锁,MyISAM只支持表锁)
锁的粒度越小,系统开销越大,但相应的并发性就越高。因此选择锁粒度的时候需要在系统开销和并发性间权衡。
锁的类型上划分为互斥锁/写锁/X锁、共享锁/读锁/S锁
2.索引
2.1 索引定义
索引能快速找到某一列中有一特定值的行。不必挨个儿去查看记录的内容。索引是对数据库中一列或者多列的值进行排序的一种数据结构,以索引文件的形式存储在磁盘上,占据一定的物理空间
2.2 索引优点
1.提高查询的性能,大大减少表的检索行数
2.可以建立唯一索引或者主键索引,保证数据库中每一行数据的唯一性
3.加速表与表之间的连接
4.在使用分组group by和排序order by子句进行数据检索时,可以显著减少查询中分组和排序的时间(数据库的记录会重新排序)
2.3 索引缺点
1.索引文件占据物理空间(空间)
2.对表中数据进行增删改查时,索引也要动态地维护,降低了数据的维护速度(时间)
2.4 索引的分类
唯一索引 数据列不允许重复但是允许为null,一个表允许多列创建多个唯一索引
主键索引 数据列不允许重复,也不允许为null,一个表中只能有一个主键,但是可以有多个列共同组成的联合主键
普通索引 没有唯一性的限制,允许为null,只是简单的加速查询
联合索引 多个索引的组合,必须满足最左前缀原则
全文索引 查找全文中的关键字, mysql的Innodb引擎不支持 myISAM引擎支持
2.5 索引设计原则
1.对查询频次较高、数据量较大的表建立索引
2.使用唯一索引,区分度越高,使用索引的效率越高
3.使用短索引,减少存储空间,提升I/O效率
4.利用最左前缀,在组合索引中比如有(name,city,age)的话,只支持(name)、(name,city)、(name,city,age)这三种组合的检索,查询时必须包含索引的最左列,不能跳过某个字段进行查询
5.为经常需要排序 分组和联合操作的字段建立索引
6.限制索引的数目,索引并非越多越好
2.6 索引失效的场景
- 复合索引不满足最左前缀原则
- 模糊查找时like ‘%'以%开头
- where索引列有运算
- where索引列有函数
- mysql估计用全表扫描要比用索引更快,则不使用索引
- 查询条件中有or的话可能会造成索引失效,除非or的每个列都加上索引
2.7 不推荐使用索引的场景
数据唯一性比较差,重复比较多的情况下不要使用索引
频繁更新的字段不适用索引(导致索引维护困难)
2.8 索引的数据结构
1.B树
这里被遮住的字符是 [ceil(m/2)-1]<=n<=m-1
优点:层级结构较低,且冗余节点较少
2.B+树
n叉B+树最多含有n个key,B树最多含有n-1个key
B+树的叶子节点保存所有的键值信息和数据,依key大小排序,所有的非叶子节点只存储键值,所有的叶子节点都通过指针连接在一起,形成了一个有序链表(支持翻页)。(B树中每个节点都存储有键值和数据)
支持翻页:每个磁盘块存储一个节点,称为一页。连续查询多个节点则称为翻页
优势:相同数据集来说B+树的层级结构比二叉树、B树小,因此搜索速度更快;查询任何key都要从root走到叶子,因此查询效率更稳定;所有数据均有序存储在叶子节点,使得范围查找、排序查找、去重查找变得简单易行(B树数据分布在各个节点,包括非叶子节点,不便于范围等查找)
缺陷:因为有冗余节点数据,因此会造成内存的浪费
3.hash
特点:
1.hash表是key-value形式,通过一个散列函数,能够根据key快速找到对应的value
2.检索时无需使用树状结构那样从根节点到叶子节点逐级查找,只需要一次hash算法即可定位到相应位置,速度较快
hash索引的缺点
1.hash索引只能够进行单值查找,不支持范围查询,而B+树支持范围查询(hash函数过滤后的键值大小关系不能保证和源数据的大小关系一致)
2.hash索引不能利用索引完成排序,以及像like 'xxx%'这样的模糊查询(本质上也是一种范围查询)
3.hash索引不支持多列联合索引的最左匹配原则
4.hash索引在重复值较高的时候,因为存在哈希碰撞导致性能极低。
5.hash索引只适用于存储数据重复度很低、对数据等值查询、无排序和范围查询的情况,效率较高。
常见考点
1.InnoDB和MyISAM索引的区别
2.delete drop truncate区别
DML 数据操纵语言(insert、update、delete)
DQL 数据查询语言(select from where)
DDL 数据定义语言(create 表/视图/索引) 是隐性提交的 不能roll back
DCL 数据控制语言(grant授权 roll back commit)
1.delete是DML,数据操纵语言,执行delete时每次从表中删除一行,删除操作会被记录在redo和undo表中以便进行回滚
2.drop是DDL,数据定义语言,会隐式提交,不能回滚,不会触发触发器,会删除表结构以及所有的数据,并将占用的空间全部释放
3.truncate是DDL,会隐式提交,不能回滚,不会触发触发器,会删除表内的所有数据,但是会保留表结构,即留下一个新表
DML和DDL的区别
1.DML数据操纵语言,手动控制开启事务、提交事务和回滚
2.DDL数据定义语言,隐形提交,不能回滚
3.连接
连接用于连接多个表,使用join关键字,条件语句使用on而非where。查询效率快于子查询
与外键的区别是,允许两个表内各有部分项不相关(外键中子表中出现的字段父表中必须出现过,但是连接的两个表每个都可以有部分字段与另一个表没有联系)
1.内连接
等值连接,连接所有同名的列,查询之间有关系的一些列,没有关联的行在查询结果中不显示
查询两个表的交集
2.外连接
保留了没有关联的行
左连接 保留左边表没有关联的行
右连接 保留右边表没有关联的行
全外连接 保留左边和右边两个表没有关联的行
4.where having on的区别
where和having区别
①where先筛选结果再用聚集函数(如果有的话)计算,
having则是在聚集函数计算结果出来之后再进行筛选,查询结果返回符合条件的分组
where是在group by之前执行的,所以where后面不能使用聚合函数进行数据过滤,只能使用该表内的字段进行过滤,筛选出过滤后的结果之后才能使用聚合函数;having则是在group by之后执行,是从分组结果中用聚合函数进行分组的过滤。
where性能优于having
②where优先级高于having,where既可以搭配select子句使用,也可以和group by搭配使用;having只可以搭配group by 语句使用
on和where区别
所有查询操作都会返回一个临时表,查询结果从临时表中得到
①on是根据限制条件对数据库记录进行过滤,然后产生临时表,一般用于连接(内外连接);
where则是在临时表产生后根据限制条件从临时表中筛选数据
②on限制条件发生时间较早,临时表较小,所以性能优于where
5.查询速度慢如何解决
慢查询日志 用于记录响应时间超过阈值的语句,实际时记录运行时间10s以上的语句
首先分两种情况:
①大多数情况正常,偶尔很慢
1.数据库在刷新脏页
因为redo log的容量有限,如果redo log写满了之后需要暂停其他操作,把redo日志里的数据同步到磁盘,导致正常sql语句执行很慢
2.所访问的数据表被加锁
如果该表被加锁或者要使用到的表中的某一行被加锁,也会导致慢查询
②针对一直都很慢的情况
1.可能表中并没有索引,或者没有用到索引(比如使用like关键字时like '%xx' 这种%位于匹配字符的第一个字符时,索引就不会起作用;或者多列索引不遵循最左前缀的原则 尽量使用唯一索引或者主键索引等区分度较大的索引;对查询操作较为频繁的列建立索引)
2.优化数据库结构
对于需要经常联合查询的表,可以建立中间表以提高查询效率。将原来的联合查询改为对中间表的查询。
3.分解关联查询
将一个大的查询分解为多个小查询,对每一个表做一次单表查询,将查询结果在应用程序中进行关联。
6.表中数据结构的区别
int(10) char(10) varchar(10)的区别
int(10)中10表示显示的数据的长度,而不是存储数据的大小,char(10)和varchar(10)的10表示存储数据的大小,即表示存储了多少个字符
char(10)表示存储定长的10个字符,不足的部分用空格补齐(空格表示占位、不算一个字符),占用更多存储空间;varchar(10)表示存储10个变长的字符,无需补0以达到10字符,空格也按照存储空间存放
int(10) int(11)有啥区别?
int(M)
中的M
指示最大显示宽度,最大有效显示宽度是 255,且显示宽度与存储大小或类型包含的值的范围无关。
所以,int(10)
与int(11)
后的括号中的字符表示显示宽度,整数列的显示宽度与 MySQL 需要用多少个字符来显示该列数值,与该整数需要的存储空间的大小都没有关系,int
类型的字段能存储的数据上限依旧是2147483647(有符号型)和4294967295(无符号型)。
7.数据库的三大范式
第一范式 1NF
数据表中所有字段都是不可分割的原子值,字段值还可以继续拆分的就不满足第一范式
第二范式 2NF
在满足第一范式的前提下,除主键外得每一列,都必须完全依赖于主键,称之为满足第二范式。
第三范式 3NF
必须在满足第二范式、第一范式的前提下,除开主键列的其他列之间不能有传递依赖关系。
#测试开发工程师##学习路径#