《Android秘籍.第六卷》
目录
《计算机网络篇》
基础
五层协议的体系结构分别是什么?每一层都有哪些协议?
- OSI(Open System Interconnection的缩写,意为开放式系统互联):分层 (7层):物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。 太网只定义1~2层(物理层、数据链路层),IP和TCP分别定义了3、4层(网络层、传输层),再往上既有因特网的协议(比如FTP),也有其它公司的一些高层协议(比如SQL、JPEG、HTTP)
- TCP(Transmission Control Protocol 传输控制协议)/IP(Internet Protocol网络之间互连的协议)分层(4层):网络接口层(对应OSI的物理层和数据链路层)、网际层(对应OSI的网络层,定义了标准的分组格式和协议,即IP协议,当前采用ip4,下一版为ip6)、运输层(对应OSI的传输层)、应用层(对应OSI的会话层、表示层和应用层。
- 五层协议 (5层):物理层、数据链路层、网络层、运输层、 应用层。
每一层的协议如下:
- 物理层:RJ45、CLOCK、IEEE802.3 (中继器,集线器)
- 数据链路:PPP、FR、HDLC、VLAN、MAC (网桥,交换机)
- 网络层:IP、ICMP、ARP、RARP、OSPF、IPX、RIP、IGRP、 (路由器)
- 传输层:TCP(传输控制协议:面向连接的,数据传输的单位是报文段,提供可靠的交付),UDP(用户控制协议:它是无连接的,数据传输的单位是用户数据报,它不能保证提供可靠的交付) SCTP
- 会话层:NFS、SQL、NETBIOS、RPC
- 表示层:JPEG、MPEG、ASII
- 应用层:FTP(文件传输协议)、DNS(域名解析协议)、Telnet(虚拟终端协议)、SMTP(电子邮件协议)、HTTP(超文本传输协议)、www、NFS
每一层的作用如下:
- 物理层:通过媒介传输比特,确定机械及电气规范(比特Bit) (中继器、集线器)
- 数据链路层:将比特组装成帧和点到点的传递(帧Frame) (网桥、交换机)
- 网络层:负责数据包从源到宿的传递和网际互连(包PackeT) (网络层中继系统:路由器,网络层以上的中继系统:网关)
- 传输层:提供端到端的可靠报文传递和错误恢复(段Segment)
- 会话层:建立、管理和终止会话(会话协议数据单元SPDU)
- 表示层:对数据进行翻译、加密和压缩(表示协议数据单元PPDU)
- 应用层:允许访问OSI环境的手段(应用协议数据单元APDU)
为何有MAC地址还要IP地址?
- MAC地址(Media Access Control, 介质访问控制,或称为物理地址、硬件地址)(是物理地址)
- IP地址(Internet Protocol Address,互联网协议地址又译为网际协议地址)(逻辑地址。)
- mac是处于第二层,IP是处于第三层(5:应用层 4:运输层 3:网络层 2:数据链路层 1:物理层)
- 主机适配器的Mac地址无论位于何方都是不变的;IP地址是可以改变的,分层的;
- a.信息传递时候,需要知道的其实是两个地址:终点地址、下一跳的地址。IP地址本质上是终点地址,它在跳过路由器的时候不会改变,而MAC地址则是下一跳的地址,每跳过一次路由器都会改变。这就是为什么还要用MAC地址的原因之一,它起到了记录下一跳的信息的作用。
- b.网络体系结构的分层模型:用MAC地址和IP地址两个地址,用于分别表示物理地址和逻辑地址是有好处的。这样分层可以使网络层与数据链路层的协议更灵活地替换。
- c.历史原因:早期的以太网只有集线器,没有交换机,所以发出去的包能被以太网内的所有机器监听到,因此要附带上MAC地址,每个机器只需要接受与自己MAC地址相匹配的包。
《TCP篇》
TCP和UDP的区别?
- TCP的优点: 可靠,稳定 TCP的可靠体现在TCP在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、窗口、重传、拥塞控制机制,在数据传完后,还会断开连接用来节约系统资源。 TCP的缺点: 慢,效率低,占用系统资源高,易被攻击 TCP在传递数据之前,要先建连接,这会消耗时间,而且在数据传递时,确认机制、重传机制、拥塞控制机制等都会消耗大量的时间,而且要在每台设备上维护所有的传输连接,事实上,每个连接都会占用系统的CPU、内存等硬件资源。 而且,因为TCP有确认机制、三次握手机制,这些也导致TCP容易被人利用,实现DOS、DDOS、CC等攻击。
- UDP的优点: 快,比TCP稍安全 UDP没有TCP的握手、确认、窗口、重传、拥塞控制等机制,UDP是一个无状态的传输协议,所以它在传递数据时非常快。没有TCP的这些机制,UDP较TCP被攻击者利用的漏洞就要少一些。但UDP也是无法避免攻击的,比如:UDP Flood攻击…… UDP的缺点: 不可靠,不稳定 因为UDP没有TCP那些可靠的机制,在数据传递时,如果网络质量不好,就会很容易丢包。
- TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接
- TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付
- TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的 UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)
- 每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
- TCP首部开销20字节;UDP的首部开销小,只有8个字节
- TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道
拥塞控制和流量控制都是什么,两者的区别?
- 流量控制是端到端的控制,例如A通过网络给B发数据,A发送的太快导致B没法接收(B缓冲窗口过小或者处理过慢),这时候的控制就是流量控制,原理是通过滑动窗口的大小改变来实现。
- 拥塞控制是A与B之间的网络发生堵塞导致传输过慢或者丢包,来不及传输。防止过多的数据注入到网络中,这样可以使网络中的路由器或链路不至于过载。拥塞控制是一个全局性的过程,涉及到所有的主机、路由器,以及与降低网络性能有关的所有因素。
谈谈TCP为什么要三次握手?为什么要四次挥手?
三次握手:(三次握手的目的是“为了防止已经失效的连接请求报文段突然又传到服务端,因而产生错误”)
- 第一次。A跟B说,我要建立连接了。
- 第二次。B跟A说,OK,那我也建立连接。
- 第三次。A跟B说,嗯,我知道了。
四次挥手:(tcp是全双公的,要实现可靠的连接关闭,A发出结束报文FIN,收到B确认后A知道自己没有数据需要发送了,B知道A不再发送数据了,自己也不会接收数据了,但是此时A还是可以接收数据,B也可以发送数据;当B发出FIN报文的时候此时两边才会真正的断开连接,读写分开)
- 第一次。A跟B说,我要断开连接了。
- 第二次。B跟A说,好的,我知道了,我不再接收你的信息了。
- 第三次。B跟A说,我传给你的信息传完了,你可以关闭连接了。
- 第四次。A跟B说,好的,我关闭连接了。
播放视频用TCP还是UDP?为什么?
TCP 和 UDP 是质量和实时性的权衡。
拿视频网站来说,你完全可以缓冲 20s 再播放,不会带来什么影响,但如果画面有马赛克之类的东西出现肯定是不好的,所以用 TCP。
而对于视频聊天,如果缓冲 5s,相信整个聊天已经没法愉快的进行了,而这时出现一些画面质量的损失也可以被接受,所以用 UDP。
《HTTP篇》
了解哪些响应状态码?
- http状态返回代码 1xx(临时响应):表示临时响应并需要请求者继续执行操作的状态代码。
- http状态返回代码 2xx (成功):表示成功处理了请求的状态代码。
- http状态返回代码 3xx (重定向):表示要完成请求,需要进一步操作。 通常,这些状态代码用来重定向。
- http状态返回代码 4xx(请求错误):这些状态代码表示请求可能出错,妨碍了服务器的处理。
- http状态返回代码 5xx(服务器错误):这些状态代码表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误,而不是请求出错。
get和post的区别?
超文本传输协议(HTTP)的设计目的是保证客户机与服务器之间的通信。在客户机和服务器之间进行请求-响应时,两种最常被用到的方法是:GET (从指定的资源请求数据)和 POST(向指定的资源提交要被处理的数据)。
GET | POST | |
---|---|---|
后退按钮/刷新 | 无害 | 数据会被重新提交(浏览器应该告知用户数据会被重新提交)。 |
书签 | 可收藏为书签 | 不可收藏为书签 |
缓存 | 能被缓存 | 不能缓存 |
编码类型 | application/x-www-form-urlencoded | application/x-www-form-urlencoded 或 multipart/form-data。为二进制数据使用多重编码。 |
历史 | 参数保留在浏览器历史中。 | 参数不会保存在浏览器历史中。 |
对数据长度的限制 | 是的。当发送数据时,GET 方法向 URL 添加数据;URL 的长度是受限制的(URL 的最大长度是 2048 个字符)。 | 无限制。 |
对数据类型的限制 | 只允许 ASCII 字符。 | 没有限制。也允许二进制数据。 |
安全性 | 与 POST 相比,GET 的安全性较差,因为所发送的数据是 URL 的一部分。 在发送密码或其他敏感信息时绝不要使用 GET ! | POST 比 GET 更安全,因为参数不会被保存在浏览器历史或 web 服务器日志中。 |
可见性 | 数据在 URL 中对所有人都是可见的。 | 数据不会显示在 URL 中。 |
GET和POST还有一个重大区别:GET产生一个TCP数据包;POST产生两个TCP数据包。对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。(据研究,在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。而在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点。)
Http1.0、Http1.1、Http2.0的区别?
- HTTP1.0:浏览器的每次请求都需要与服务器建立一个TCP连接,服务器处理完成后立即断开TCP连接(无连接),服务器不跟踪每个客户端也不记录过去的请求(无状态)。
- HTTP1.1:HTTP/1.0中默认使用Connection: close。在HTTP/1.1中已经默认使用Connection: keep-alive,避免了连接建立和释放的开销,但服务器必须按照客户端请求的先后顺序依次回送相应的结果,以保证客户端能够区分出每次请求的响应内容。通过Content-Length字段来判断当前请求的数据是否已经全部接收。不允许同时存在两个并行的响应。
- HTTP2.0:HTTP/2引入二进制数据帧(
HTTP2.0
通信的最小单位,每个帧包含帧头部,至少也会标识出当前帧所属的流(stream id
))和流(stream:已建立连接上的双向字节流)的概念,其中帧对数据进行顺序标识,如下图所示,这样浏览器收到数据之后,就可以按照序列对数据进行合并,而不会出现合并后数据错乱的情况。同样是因为有了序列,服务器就可以并行的传输数据,这就是流所做的事情。
多路复用:
- 所有的HTTP2.0通信都在一个TCP连接上完成,这个连接可以承载任意数量的双向数据流。
- 个数据流以消息的形式发送,而消息由一或多个帧组成。这些帧可以乱序发送,然后再根据每个帧头部的流标识符(stream id)重新组装。
- 举个例子,每个请求是一个数据流,数据流以消息的方式发送,而消息又分为多个帧,帧头部记录着stream id用来标识所属的数据流,不同属的帧可以在连接中随机混杂在一起。接收方可以根据stream id将帧再归属到各自不同的请求当中去。
- 另外,多路复用(连接共享)可能会导致关键请求被阻塞。HTTP2.0里每个数据流都可以设置优先级和依赖,优先级高的数据流会被服务器优先处理和返回给客户端,数据流还可以依赖其他的子数据流。
- 可见,HTTP2.0实现了真正的并行传输,它能够在一个TCP上进行任意数量HTTP请求。而这个强大的功能则是基于“二进制分帧”的特性。
头部压缩
- 在HTTP1.x中,头部元数据都是以纯文本的形式发送的,通常会给每个请求增加500~800字节的负荷。
- HTTP2.0使用encoder来减少需要传输的header大小,通讯双方各自cache一份header fields表,既避免了重复header的传输,又减小了需要传输的大小。高效的压缩算法可以很大的压缩header,减少发送包的数量从而降低延迟。
服务器推送:
- 服务器除了对最初请求的响应外,服务器还可以额外的向客户端推送资源,而无需客户端明确的请求。
SOCKET原理
概念:
- 套接字(socket)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议,本地主机的IP地址,本地进程的协议端口,远地主机的IP地址,远地进程的协议端口。
- 应用层通过传输层进行数据通信时,TCP会遇到同时为多个应用程序进程提供并发服务的问题。多个TCP连接或多个应用程序进程可能需要通过同一个 TCP协 议端口传输数据。为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与TCP/IP协议交互提供了套接字(Socket)接口。应用层可以 和传输层通过Socket接口,区分来自不同应用程序进程或网络连接的通信,实现数据传输的并发服务。
建立socket连接
- 建立Socket连接至少需要一对套接字,其中一个运行于客户端,称为ClientSocket ,另一个运行于服务器端,称为ServerSocket 。
- 套接字之间的连接过程分为三个步骤:服务器监听,客户端请求,连接确认。
- 服务器监听:服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态,等待客户端的连接请求。
- 客户端请求:指客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。
- 连接确认:当服务器端套接字监听到或者说接收到客户端套接字的连接请求时,就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户 端,一旦客户端确认了此描述,双方就正式建立连接。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。
TCP、UDP、HTTP、SOCKET之间的区别?
- TCP和UDP:传输层协议;
- HTTP:应用层协议;
- SOCKET:TCP/IP网络的API。
- TCP/IP代表传输控制协议/网际协议,指的是一系列协议。
- TCP和UDP使用IP协议从一个网络传送数据包到另一个网络。把IP想像成一种高速公路,它允许其它协议在上面行驶并找到到其它电脑的出口。
- TCP和UDP是高速公路上的“卡车”,它们携带的货物就是像HTTP,文件传输协议FTP这样的协议等。
- TCP和UDP是FTP、HTTP和SMTP之类使用的传输层协议。
- 虽然TCP和UDP都是用来传输其他协议的,它们却有一个显著的不同:TCP提供有保证的数据传输,而UDP不提供。
- 这意味着TCP有一个特殊的机制来确保数据安全的不出错的从一个端点传到另一个端点,而UDP不提供任何这样的保证。
- HTTP(超文本传输协议)是利用TCP在两台电脑(通常是Web服务器和客户端)之间传输信息的协议。
- 客户端使用Web浏览器发起HTTP请求给Web服务器,Web服务器发送被请求的信息给客户端。
- 记住,需要IP协议来连接网络;TCP是一种允许我们安全传输数据的机制,使用TCP协议来传输数据的HTTP是Web服务器和客户端使用的特殊协议。
- Socket 接口是TCP/IP网络的API,Socket接口定义了许多函数或例程,用以开发TCP/IP网络上的应用程序。
- 网络由下往上分为物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。
IP 协议对应于网络层,TCP协议对应于传输层,HTTP协议对应于应用层,三者从本质上来说没有可比性,socket则是对TCP/IP协议的封装和应用。
可以说,TPC/IP协议是传输层协议,主要解决数据如何在网络中传输,而HTTP是应用层协议,主要解决如何包装数据
socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API),
通过Socket,我们才能使用TCP/IP协议。
实际上,Socket跟TCP/IP协议没有必然的联系。Socket编程接口在设计的时候,就希望也能适应其他的网络协议。
所以说,Socket的出现只是使得程序员更方便地使用TCP/IP协议栈而已,是对TCP/IP协议的抽象,
从而形成了我们知道的一些最基本的函数接口,比如create、 listen、connect、accept、send、read和write等等
实际上,传输层的TCP是基于网络层的IP协议的,而应用层的HTTP协议又是基于传输层的TCP协议的,
而Socket本身不算是协议,就像上面所说,它只是提供了一个针对TCP或者UDP编程的接口
HTTP和HTTPS的区别?
- HTTP协议传输的数据都是未加密的,也就是明文的,因此使用HTTP协议传输隐私信息非常不安全,为了保证这些隐私数据能加密传输,于是网景公司设计了SSL(Secure Sockets Layer)协议用于对HTTP协议传输的数据进行加密,从而就诞生了HTTPS。简单来说,HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全。
- HTTPS和HTTP的区别主要如下:
- 1、https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。
- 2、http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
- 3、http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
- 4、http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
HTTP和Socket的区别?
- HTTP(短连接):超文本传输协议,首先它是一个协议,并且是基于TCP/IP协议基础之上的应用层协议。TCP/IP协议是传输层协议,主要解决数据如何在网络中传输,HTTP是应用层协议,主要解决如何包装数据。HTTP协议详细规定了浏览器与服务器之间相互通信的规则,是万维网交换信息的基础。HTTP是基于请求-响应形式并且是短连接,并且是无状态的协议。针对其无状态特性,在实际应用中又需要有状态的形式,因此一般会通过session/cookie技术来解决此问题。
- Socket(长连接):Socket不属于协议范畴,而是一个调用接口(API),Socket是对TCP/IP协议的封装,通过调用Socket,才能使用TCP/IP协议。Socket连接是长连接,理论上客户端和服务器端一旦建立连接将不会主动断开此连接。Socket连接属于请求-响应形式,服务端可主动将消息推送给客户端。
在地址栏打入http://www.qq.com会发生什么?
- 当输入www.qq.com时,计算机会请求DNS服务器,进行域名转换,得到服务器IP地址,同时对服务器发出请求,服务器响应请求,客户端浏览器发起一个HTTP会话到IP地址,然后通过tcp进行封装数据包,输入到网络层
长链接与短连接?
- 短连接的操作步骤是:建立连接——数据传输——关闭连接...建立连接——数据传输——关闭连接
- 长连接的操作步骤是:建立连接——数据传输...(保持连接)...数据传输——关闭连接
- 长连接可以省去较多的TCP建立和关闭的操作,减少浪费,节约时间。对于频繁请求资源的客户来说,较适用长连接。不过这里存在一个问题,存活功能的探测周期太长,还有就是它只是探测TCP连接的存活,属于比较斯文的做法,遇到恶意的连接时,保活功能就不够使了。在长连接的应用场景下,client端一般不会主动关闭它们之间的连接,Client与server之间的连接如果一直不关闭的话,会存在一个问题,随着客户端连接越来越多,server早晚有扛不住的时候,这时候server端需要采取一些策略,如关闭一些长时间没有读写事件发生的连接,这样可 以避免一些恶意连接导致server端服务受损;如果条件再允许就可以以客户端机器为颗粒度,限制每个客户端的最大长连接数,这样可以完全避免某个蛋疼的客户端连累后端服务。
- 短连接对于服务器来说管理较为简单,存在的连接都是有用的连接,不需要额外的控制手段。但如果客户请求频繁,将在TCP的建立和关闭操作上浪费时间和带宽。
《操作系统篇》
操作系统中进程和线程的区别?
进程是程序执行的一个实体,线程是CPU调度的最小单位
死锁的产生和避免?
死锁:是指在一组进程中的各个进程均占有不会释放的资源,但因互相申请被其他进程所站用不会释放的资源而处于的一种永久等待状态。四个必要条件:
(1)互斥条件(Mutual exclusion):资源不能被共享,只能由一个进程使用。
(2)请求与保持条件(Hold and wait):已经得到资源的进程可以再次申请新的资源。
(3)非剥夺条件(No pre-emption):已经分配的资源不能从相应的进程中被强制地剥夺。
(4)循环等待条件(Circular wait):系统中若干进程组成环路,该环路中每个进程都在等待相邻进程正占用的资源。
死锁避免:
(1) 死锁检测和恢复(deadlock detection and recovery):
- 死锁检测(deadlock detection)即探查和识别死锁的方法。这种策略并不采取任何动作来使死锁不出现,而是系统事件触发执行一个检测算法。,也即在系统运行过程中,及时地探查和识别死锁的存在,并识别出处于死锁之中的进程和资源等。死锁恢复(deadlock recovery)是指当检测并识别出系统中出现处于死锁之中的一组进程时,如何使系统回复到正常状态并继续执行下去。死锁恢复常采用下述两种方法。
- 撤消进程即当发现死锁时,就撤消(夭折)一些处于死锁状态的进程,并收回它的占用的资源,以解除死锁,使其它进程能继续运行,或者在提供检查点(checkpoint)信息情况下回退(rolled back)到一个较早的状态。这里有一个开销问题,即撤消哪个(些)进程比较“划算”。
- 挂起进程即当发现死锁时,挂起一些进程,抢占它们占用的资源,使得处于死锁之中的其它进程继续执行。待以后条件满足后,再恢复被挂起的进程。
- 常利用资源分配图、进程等待图来协助这种检测。
(2) 死锁预防(deadlock prevention):
- 死锁预防(deadlock prevention)是在系统运行之前,事先考虑防止死锁发生的对策,即在最初设计各种资源调度算法时,就没法防止在系统运行过程中可能产生的死锁。
- Coffmman 等人[1971]曾提出进程在利用可重用性资源时产生死锁的四个必要条件:
- 互斥使用(mutual exclusion):系统中存在一次只能给一个进程使用的资源。
- 占用并等待(resource holding and waiting):系统中存在这样的进程,它(们)已占有部分资源并等待得到另外的资源,而这些资源又被其它进程所占用还未释放。
- 非抢占分配(nonpreemption):资源在占有它的进程自愿交出之前,不可被其它进程所强行占用。
- 部分地分配(partial allocation)或循环等待(circular waiting):存在一个两个或都个进程的循环链,链中每一个进程等待被链中下一个进程占有的资源。即在一定条件下,若干进程进入了相互无休止地等待所需资源的状态。
- 所有这四个必要条件都应该在死锁时出现。
- Havender[1968]提出了若干死锁预防方法。他认为,只要设法破坏产生死锁的任一必要条件,死锁就不会发生。为此,可采用如下策略:
- 1) 每个进程必须一次性地请求它所需要的所有资源。若系统无法满足这一要求,则它不能执行。这是一种预分资源方法,它破坏了产生死锁的第三个必要条件。
- 2) 一个已占有资源的进程若要再申请新资源,它必须先释放已占资源。若随后它还需要它们,则需要重新提出申请。换言之,一个进程在使用某资源过程中可以放弃该资源,从而破坏了产生死锁的第二个必要条件。
- 3) 将系统中所有资源顺序编号,规定进程只能依次申请资源,这就是说,一个进程只有在前面的申请满足后,才能提出对其后面序号的资源的请求。这是一种有序使用资源法,它破坏了产生死锁的第四个必要条件。
(3) 死锁避免(deadlock avoidence):
- 死锁避免(deadlock avoidence)是在系统运行过程中注意避免死锁的发生。这就要求每当申请一个资源时,系统都应根据一定的算法判断是否认可这次申请,使得在今后一段时间内系统不会出现死锁。这面方最著名的算法首推Dijkstra[1965]提出的银行家(banker)算法。
《数据库篇》
数据库中的事务了解吗?事务的四大特性?
- 数据库事务是数据库运行中的逻辑工作单位,单个逻辑工作单元所执行的一系列操作,要么都执行,要么都不执行。例如银行取款事务分为2个步骤(1)存折减款(2)提取现金,2个步骤必须同时完成或者都不完成。
数据库事务的四大特性(ACID):
- (1) 原子性(Atomicity):事务的原子性指的是,事务中包含的程序作为数据库的逻辑工作单位,它所做的对数据修改操作要么全部执行,要么完全不执行。这种特性称为原子性。
- (2)一致性(Consistency) :事务的一致性指的是在一个事务执行之前和执行之后数据库都必须处于一致性状态。这种特性称为事务的一致性。假如数据库的状态满足所有的完整性约束,就说该数据库是一致的。
- (3)分离性(Isolation): 分离性指并发的事务是相互隔离的。即一个事务内部的操作及正在操作的数据必须封锁起来,不被其它企图进行修改的事务看到。假如并发交叉执行的事务没有任何控制,操纵相同的共享对象的多个并发事务的执行可能引起异常情况。
- (4)持久性(Durability): 持久性意味着当系统或介质发生故障时,确保已提交事务的更新不能丢失。即一旦一个事务提交,DBMS保证它对数据库中数据的改变应该是永久性的,即对已提交事务的更新能恢复。持久性通过数据库备份和恢复来保证。
如何理解数据库的范式?
- 第一范式:确保每一列的原子性,1NF是对属性的原子性约束,要求属性具有原子性,不可再分解;
- 第二范式:非键字段必须依赖于键字段,2NF是对记录的惟一性约束,要求记录有惟一标识,即实体的惟一性;
- 第三范式:在1NF基础上,除了主键以外的其它列都不传递依赖于主键列,或者说: 任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖)3NF是对字段冗余性的约束,即任何字段不能由其他字段派生出来,它要求字段没有冗余。
《数据结构与算法篇》
怎么理解数据结构?
- 数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。
什么是斐波那契数列?
- 斐波那契数列(Fibonacci sequence),又称黄金分割数列、因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……在数学上,斐波纳契数列以如下被以递推的方法定义:F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=3,n∈N*)
迭代和递归的特点,并比较优缺点
| 定义 | 优点 | 缺点 |
递归 | 程序调用自身的编程技巧称为递归 | 1)大问题化为小问题,可以极大的减少代码量; 2)用有限的语句来定义对象的无限集合.; 3)代码更简洁清晰,可读性更好 | 1)递归调用函数,浪费空间; 2)递归太深容易造成堆栈的溢出;
|
迭代 | 利用变量的原值推算出变量的一个新值,迭代就是A不停的调用B. | 1)迭代效率高,运行时间只因循环次数增加而增加; 2)没什么额外开销,空间上也没有什么增加, | 1) 不容易理解; 2) 代码不如递归简洁; 3) 编写复杂问题时困难。 |
二者关系 | 1) 递归中一定有迭代,但是迭代中不一定有递归,大部分可以相互转换。 2) 能用迭代的不用递归,递归调用函数,浪费空间,并且递归太深容易造成堆栈的溢出./*相对*/ |
了解哪些查找算法,时间复杂度都是多少?
查找 | 平均时间复杂度 | 查找条件 | 算法描述 |
顺序查找 | O(n) | 无序或有序队列 | 按顺序比较每个元素,直到找到关键字为止 |
二分查找(折半查找) | O(logn) | 有序数组 | 查找过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。 如果在某一步骤数组为空,则代表找不到。 |
二叉排序树查找 | O(logn) | 二叉排序树 | 在二叉查找树b中查找x的过程为: 1. 若b是空树,则搜索失败 2. 若x等于b的根节点的数据域之值,则查找成功; 3. 若x小于b的根节点的数据域之值,则搜索左子树 4. 查找右子树。 |
哈希表法(散列表) | O(1) | 先创建哈希表(散列表) | 根据键值方式(Key value)进行查找,通过散列函数,定位数据元素。 |
分块查找 | O(logn) | 无序或有序队列 | 将n个数据元素"按块有序"划分为m块(m ≤ n)。 每一块中的结点不必有序,但块与块之间必须"按块有序";即第1块中任一元素的关键字都必须小于第2块中任一元素的关键字;而第2块中任一元素又都必须小于第3块中的任一元素,……。然后使用二分查找及顺序查找。 |
了解哪些排序算法,并比较一下,以及适用场景
排序法 | 最差时间分析 | 平均时间复杂度 | 稳定度 | 空间复杂度 |
冒泡排序 | O(n2) | O(n2) | 稳定 | O(1) |
插入排序 | O(n2) | O(n2) | 稳定 | O(1) |
选择排序 | O(n2) | O(n2) | 稳定 | O(1) |
二叉树排序 | O(n2) | O(n*log2n) | 不一顶 | O(n) |
快速排序 | O(n2) | O(n*log2n) | 不稳定 | O(log2n)~O(n) |
堆排序 | O(n*log2n) | O(n*log2n) | 不稳定 | O(1) |
希尔排序 | O | O | 不稳定 | O(1) |
快排的基本思路是什么?最差的时间复杂度是多少?如何优化?
快速排序由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
最差时间复杂度即是但数据有序的时候,这时候退化为冒泡排序, O(n^2) 平均时间复杂度O(nlgn),快速排序最优的情况下时间复杂度为:O( nlogn )
- 优化1:当待排序序列的长度分割到一定大小后,使用插入排序
- 优化2:在一次分割结束后,可以把与Key相等的元素聚在一起,继续下次分割时,不用再对与key相等元素分割
- 优化3:优化递归操作(快排函数在函数尾部有两次递归操作,我们可以对其使用尾递归优化)
冒泡排序如何优化?
-
问题:有的冒泡经过第一轮的交换已经是有序的了,如:2 1 3 4。数据越多的时候越慢,非常不适合大数据的排序
-
解决办法:如果用一个flag来判断一下,当前数组是否已经有序,如果有序就退出循环,这样可以明显的提高冒泡排序的性能。外层循环优化(判断标志位flag有没有发生改变没有发生交互则退出循环)
AVL树插入或删除一个节点的过程是怎样的?
- AVL树即平衡二叉查找树
插入新结点
- 插入结点后的AVL树可能会不平衡,我们需要用旋转来保持树的平衡。程序的工作流程是:
- 1). 和普通的二叉搜索树一样,将新结点z插入到合适的位置作为叶子结点;
- 2). 从结点z出发向上回溯,如果z的父结点的父结点zpp不为空,则判断zpp是否平衡,即zpp的左子树和右子树的高相差是否不大于1,如果平衡则从结点z的父结点zp继续往上回溯,否则则通过旋转调整zpp的平衡;
- 3). 旋转zpp的方法是,加入zpp的左子树zl比右子树zr高2,而且zl的左子树比右子树高,则只需要对zpp进行一次右旋即可,如果zl的左子树比右子树低,则要先对zl进行一次左旋,再对zpp右旋。zpp的左子树比右子树低2的情况对称处理即可。
删除结点
- 删除结点可能会导致该结点所在的树高发生变化,从而引起树的不平衡。AVL树删除结点先执行和普通二叉搜索树一样的过程,然后再从最开始因为删除结点而树高发生变化的结点向上回溯调整树高。该操作的关键在于如何确定“最先发生树高变化的结点”。因为普通二叉搜索树的删除结点有3种情况,所以AVL树对“最先发生树高变化的结点”的确定也有3种情况。假设被删除的结点为x
- 1). x是叶子结点,“最先发生树高变化的结点”为x的父结点;
- 2). x只有一个孩子,“最先发生树高变化的结点”为x的父结点;
- 3). x有两个孩子,则“最先发生树高变化的结点”为x的后驱的父结点。
- 在确定了“最先发生树高变化的结点”之后,就需要从该结点出发向上回溯,与插入结点一样,对沿路经过的结点按需进行旋转。
什么是红黑树?
红黑树(Red Black Tree) 是一种自平衡二叉查找树,是在计算机科学中用到的一种数据结构,典型的用途是实现关联数组。
它是在1972年由Rudolf Bayer发明的,当时被称为平衡二叉B树(symmetric binary B-trees)。后来,在1978年被 Leo J. Guibas 和 Robert Sedgewick 修改为如今的“红黑树”。
红黑树和AVL树类似,都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。
它虽然是复杂的,但它的最坏情况运行时间也是非常良好的,并且在实践中是高效的: 它可以在O(log n)时间内做查找,插入和删除,这里的n 是树中元素的数目。