Bootstrap

Java面试所需的知识

目录

1. 计算机网络

(1)网络7层架构

(2)TCP/IP原理 

(3)HTTP原理 

(4)加密算法

2. 数据结构

3. 算法

(1) Java算法

(2)海量数据处理

4. 操作系统

5. MySQL数据库

1、事务

2、数据库结构和锁

3、索引

4、情景题、优化题 

5、琐碎知识

6、视图

7、存储过程和触发器

8、约束 

6. Redis数据库

7. Git

8. Linux

9. 位运算技巧

二、Java

1. Java基础

2. JVM

3. Java并发编程

1、互斥(无锁和互斥锁)

2、线程

3、协作

4、分工

4. Java集合框架

5. Servlet

三、设计模式

1. 单例模式

2. 工厂模式—— 创建对象的创建型模式

3. 适配器模式 —— 两个不兼容的接口之间的桥梁,结构型模式

4. 装饰器模式 —— 赋予现有的类更多的功能,结构型模式

5. 观察者模式 —— 行为型模式

6. 责任链模式 —— 行为型模式


1. 计算机网络

(1)网络7层架构

1. 说一说OSI七层模型

第七层:应用层——为应用程序提供服务,最小单位——apdu;

  • HTTP超文本传输协议
  • FTP文件传输协议
  • POP3邮局协议的第三个版本
  • SMTP简单邮件传输协议
  • Telnet远程登录协议
  • DNS域名解析协议

第六层:表示层——确保一个系统的应用层发送的消息可以 被另一个系统的应用层读取,加密解密、转换翻译、压缩解压缩;最小单位——ppdu;

第五层:会话层——不同的机器上的用户之间建立、管理、维护对话;

第四层:传输层——定义一些传输数据的协议和端口。传输协议同时进行流量控制,或是拥塞控制,解决传输效率与能力的问题,保证这些数据段有效到达对端;最小单位——tpdu;

  • TCP传输控制协议
  • UPD用户数据报协议

第三层:网络层——控制子网的运行,如逻辑编址、分组传输、路由选择;最小单位——分组(包)报文;

  • IP(IPv4,Ipv6)网络之间互连的协议
  • ICMP网络控制消息协议
  • ARP地址解析协议

第二层:数据链路层——物理寻址,同时将原始比特流转变为逻辑传输线路;最小单位——帧;

  • WiFi,GPRS,ZigBee,帧中继

第一层:物理层——定义物理设备的标准,主要对物理连接方式,电气特性,机械特性等制定统一标准,传输比特流;最小单位——比特流。

  • IEEE 802.1A, IEEE 802.2到IEEE 802.11


2. 说一说TCP/IP四层协议

(2)TCP/IP原理 

3. 简述TCP/UDP的区别

TCP和UDP是OSI模型中的传输层中的协议,TCP提供可靠的通信传输,UDP提供广播和细节控制交给应用层的通信传输

TCP面向连接 UDP发送数据前不需要建立连接,面向的是非连接
TCP提供可靠的服务(数据传输) UDP无法保证数据传输的可靠性
TCP面向字节流 UDP面向报文
TCP数据传输慢 UDP数据传输快

4. TCP的三次握手,如果在前两次握手后客户端不发起第三次握手会怎么样?(SYN Flood攻击的诊断和处理)

第一次握手:客户端发送建立连接的报文段,将SYN位置为1,Sequence Number为x;然后客户端进入SYN_SEND状态,等待服务器确认。

第二次握手:服务器收到客户端的SYN报文段,对其进行确认:设置Acknowledgement Number为x+1;同时还要发送SYN请求信息,将SYN为置为1,Sequence Number为y;将上述信息放到一个报文段中,一并发给客户端;然后服务器进入SYN_RECV状态。

第三次握手:客户端接收到SYN_ACK报文段,将Acknowledgement Number置为y+1,向服务器发送ACK报文段。这个报文段发送完毕后,客户端和服务器都进入ESTABLISHED状态,完成TCP三次握手。

【注意】

(1)在握手和结束时Acknowledgement Number确认号为对方的序列号加1;

(2)传输数据时则是对方序列号加上对方携带应用层数据的长度。

【SYN Flood攻击】

  • 攻击者首先伪造地址对服务器发起SYN请求(我可以建立连接吗?),服务器就会回应一个ACK+SYN(可以+请确认)。而真实的IP会认为,我没有发送请求,不作回应。服务器没有收到回应,会重试3-5次并且等待一个SYN Time(一般30秒-2分钟)后,丢弃这个连接。
  • 如果攻击者大量发送这种伪造源地址的SYN请求,服务器将会消耗大量的资源来处理这种半连接(保存和遍历IP列表),何况还要不断对这个IP进行SYN+ACK的重试

【SYN Flood防御】

  • cookie源认证
  • reset认证
  • TCP首包丢弃
  • TCP代理

【链接】---- TCP洪水攻击的诊断和处理

【链接】---- DDoS攻击--Syn_Flood攻击防护详解(TCP)


5. 如果握手只有两次,会出现什么情况?

如果握手只有两次,会发生已经失效的连接请求报文段被服务器接收,因为只有两次握手,服务器一收到连接请求就会进入ESTABLISHED状态,等待客户端发送数据或主动发送数据,而客户端其实是处于CLOSED状态,服务器会一直等待下去,这样会浪费服务器资源


6. TCP的四次挥手,为什么TCP断开连接要4次

关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你未必会马上会关闭SOCKET,等你也没有数据再发送的时候,再发送FIN报文给对方来表示你同意现在关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。


7. TIME_WAIT和CLOSE_WAIT的区别,大量CLOSE_WAIT怎么办?

【链接】---- 关于大量CLOSE_WAIT连接分析

TIME_WAIT 是主动关闭连接时形成的,等待2MSL时间,约2分钟。主要是防止最后一个ACK丢失。  由于TIME_WAIT 的时间会非常长,因此server端应尽量减少主动关闭连接。

CLOSE_WAIT是被动关闭连接是形成的。根据TCP状态机,服务器端收到客户端发送的FIN,则按照TCP实现发送ACK,因此进入CLOSE_WAIT状态。但如果服务器端不执行close(),就不能由CLOSE_WAIT迁移到LAST_ACK,则系统中会存在很多CLOSE_WAIT状态的连接。此时,可能是系统忙于处理读、写操作,而未将已收到FIN的连接,进行close。

【链接】-------  TIME_WAIT和CLOSE_WAIT状态区别


8. TCP头的结构,如何标识一个TCP连接(四元组、五元组、七元组)

  • 源、目标端口号:TCP协议通过使用"端口"来标识源端和目标端的应用进程。端口号可以使用0到65535之间的任何数字。
  • 顺序号字段:用来标识从TCP源端向TCP目标端发送的数据字节流,它表示在这个报文段中的第一个数据节。  
  • 确认号字段:只有ACK标志为1时,确认号字段才有效。它包含目标端所期望收到源端的下一个数据字节。  
  • 头部长度字段:给出头部占32比特的数目。没有任何选项字段的TCP头部长度为20字节;最多有60字节的TCP头部。  
  • 标志位字段(U、A、P、R、S、F):占6比特。各比特的含义如下:  

  ◆URG:紧急指针(urgent pointer)有效。  

  ◆ACK:确认序号有效。  

  ◆PSH:接收方应该尽快将这个报文段交给应用层。  

  ◆RST:重建连接。  

  ◆SYN:发起一个连接。  

  ◆FIN:释放一个连接。  

  • 窗口大小字段:此字段用来进行流量控制。单位为字节数,这个值是本机期望一次接收的字节数。  
  • TCP校验和字段:对整个TCP报文段,即TCP头部和TCP数据进行校验和计算,并由目标端进行验证。  
  • 紧急指针字段:它是一个偏移量,和序号字段中的值相加表示紧急数据最后一个字节的序号。  
  • 选项字段:可能包括"窗口扩大因子"、"时间戳"等选项。

【四元组】源IP地址、目的IP地址、源端口、目的端口

【五元组】源IP地址、目的IP地址、协议号、源端口、目的端口

【七元组】源IP地址、目的IP地址、协议号、源端口、目的端口,服务类型以及接口索引


9. TCP的拆包粘包问题,TCP的最大连接数,TCP攻击

【拆包粘包定义】

TCP是个“流”协议,所谓流,就是没有界限的一串数据。大家可以想想河里的流水,是连成一片的,其间并没有分界线。TCP底层并不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行包的划分,所以在业务上认为,一个完整的包可能会被TCP拆分成多个包进行发送,也有可能把多个小的包封装成一个大的数据包发送,这就是所谓的TCP粘包和拆包问题。

【解决方案】

  1. 消息定长,例如每个报文的大小为固定长度200字节,如果不够,空位补空格;
  2. 在包尾增加回车换行符进行分割,例如FTP协议;
  3. 将消息分为消息头和消息体,消息头中包含表示消息总长度(或者消息体长度)的字段,通常设计思路为消息头的第一个字段使用int32来表示消息的总长度;
  4. 更复杂的应用层协议。

【TCP的最大连接数】

【链接】---- 单服务器最大tcp连接数及调优

  • client最大tcp连接数:client每次发起tcp连接请求时,除非绑定端口,通常会让系统选取一个空闲的本地端口(local port),该端口是独占的,不能和其他tcp连接共享。tcp端口的数据类型是unsigned short,因此本地端口个数最大只有65536,端口0有特殊含义,不能使用,这样可用端口最多只有65535,所以在全部作为client端的情况下,最大tcp连接数为65535,这些连接可以连到不同的server ip。
  • server最大tcp连接数:server通常固定在某个本地端口上监听,等待client的连接请求。不考虑地址重用(unix的SO_REUSEADDR选项)的情况下,即使server端有多个ip,本地监听端口也是独占的,因此server端tcp连接4元组中只有remote ip(也就是client ip)和remote port(客户端port)是可变的,因此最大tcp连接为客户端ip数×客户端port数,对IPV4,不考虑ip地址分类等因素,最大tcp连接数约为2的32次方(ip数)×2的16次方(port数),也就是server端单机最大tcp连接数约为2的48次方。
  • 实际的tcp连接数:在实际环境中,受到机器资源、操作系统等的限制,特别是sever端,其最大并发tcp连接数远不能达到理论上限。在unix/linux下限制连接数的主要因素是内存和允许的文件描述符个数(每个tcp连接都要占用一定内存,每个socket就是一个文件描述符),另外1024以下的端口通常为保留端口。对server端,通过增加内存、修改最大文件描述符个数等参数,单机最大并发TCP连接数超过10万 是没问题的。

10. TCP/IP协议的可靠性,以及它的脆弱性。

【TCP/IP协议的可靠性】

  1. 面向连接,服务器和客户端在彼此交换数据之前必须先建立一个TCP三次握手连接
  2. 应用数据被分割成TCP认为最适合发送的数据块
  3. 超时重发
  4. 当TCP收到发自TCP连接另一端数据,它将发送一个确认。
  5. TCP将保持它首部和数据的检验和
  6. 对失序数据进行重新排序,然后才交给应用层(TCP报文段作为IP数据报来传输,而IP数据报的到达可能会失序)
  7. 对于重复数据,能够丢弃重复数据(IP数据报会发生重复)
  8. 流量控制——滑动窗口协议
  9. 字节流服务

【链接】-------  TCP协议如何保证传输可靠性

【TCP/IP的脆弱性】

(1)不能提供可靠的身份验证

  1. TCP/IP 协议以 32 bit 的 IP 地址来作为网络节点的唯一标识,而 IP 地址只是用户软件设置中的一个参数,因而是可以随意修改的;
  2.  由于TCP/IP 不能对节点上的用户进行有效的身份认证,服务器无法鉴别登录用户的身份有效性,攻击者可以冒充某个可信节点的 IP 地址,进行 IP 欺骗攻击;
  3. 其次,由于某些系统的 TCP 序列号是可以预测的,攻击者可以构造一个TCP'数据包,对网络中的某个可信节点进行攻击。

(2)不能有效防止信息泄露

  1. IPv4 中没有考虑防止信息泄漏,在 IP 、 TCP 、 UDP 中都没有对数据进行加密;
  2. IP 协议是无连接的协议,一个 IP 包在传输过程中很可能会经过很多路由器和网段,在其中的任何一个环节都很容易进行窃昕 。

(3)没有提供 ----可靠的信息完整性验证---- 手段

  1. 在 IP 协议中,仅对 IP 头实现校验和保护;
  2. 在UDP 协议中,对整个报文的校验和检查是一个可选项,并且对 UDP 报文的丢失不做检查;
  3. 在 TCP 协议中,虽然每个报文都经过校验和检查,并且通过连续的序列号来对包的顺序和完整进行检查,保证数据的可靠传输。但是,校验算法中没有涉及加密和密码验证,很容易对报文内容进行修改,再重新计算校验和。

(4)没有手段控制资源占用和分配

  1. TCP/IP 中,对资源占用和分配设计的一个基本原则是自觉原则;
  2. 如参加 TCP通信的一方发现上次发送的数据报丢失,则主动将通信速率降至原来的一半。这样,也给恶意的网络破坏者提供了机会:如网络破坏者可以大量的发 IP 报,造成网络阻塞,也可以向一台主机发送大量的 SYN 包从而大量占有该主机的资源 (SYN Flood) 。

11. TCP的流量控制和拥塞控制

【链接】---- TCP的流量控制和拥塞控制

流量控制】流量控制是作用于发送者的,它是控制发送者的发送速度从而使接收者来得及接收,防止分组丢失

【如何实现流量控制】由滑动窗口协议实现,主要的方法是接收方返回的ACK中包含自己的接收窗口大小,并且利用大小来控制发送方的数据发送。

【流量控制引发的死锁】如果发送者收到了一个窗口为0的应答,发送者会停止发送,等待接收者的下一次应答;但是如果接收者发送了一个窗口不为0的数据在传输过程中丢失了,发送者会一直等待下去,而接收者以为发送者已经收到了应答,等待接收新的数据,这样双方就相互等待,从而产生了死锁。

【避免死锁的发生】TCP为每一个连接设有一个持续计时器。每当发送者收到一个窗口为0的ACK应答后就启动该计时器,时间一到就主动询问接收者的窗口大小;如果接收者仍然返回零窗口,则重置该计时器继续等待;如果窗口不为0,则表明应答报文丢失了,发送方重置发送窗口后开始发送,这样就避免了死锁的产生。

拥塞控制】拥塞控制是作用于网络的,它是防止过多的数据注入到网络中,避免出现网络负载过大的情况

常用的方法是:(1)慢开始、拥塞避免;(2)快重传、快恢复

  • 拥塞窗口cwnd(congestion window):拥塞窗口的大小取决于网络的拥塞程度,并且在动态的变化。发送方让自己的发送窗口等于拥塞窗口,另外考虑到接收方的接收能力,发送窗口可能小于拥塞窗口
  • 一个传输轮次所经历的时间及时往返时间RTT
  • 慢开始门限ssthresh状态变量

【慢开始】不要一开始就发送大量的数据,先探测一下网络的拥塞程度,即由大到小逐渐增加拥塞窗口的大小。每经历一个传输轮次,拥塞窗口cwnd就加倍。为防止cwnd增长过大引起网络拥塞,设置了一个慢开始门限ssthresh。

  • 当cwnd < ssthresh 时,使用慢开始算法;
  • 当cwnd > ssthresh 时,使用拥塞避免算法;
  •  当cwnd = ssthresh 时,慢开始与拥塞避免算法任意。

【拥塞避免】拥塞避免算法让拥塞窗口缓慢增长,每经历一个传输轮次,cwnd加1,而不是加倍,这样按线性缓慢增长。

无论是在慢开始阶段还是拥塞避免阶段,只要发送方判断网络出现拥塞,就会将慢开始门限ssthresh设置为网络拥塞时的发送窗口的 一半,拥塞窗口cwnd重新置为1,执行慢开始算法。

【快重传】快重传要求接收方一收到失序的报文段就立即发出重复确认,而不要等到自己发送数据的时候捎带确认。快重传算法规定,发送方一连收到三个重复确认就应答立即重传尚未收到的报文段,而不必继续等待设置的重传计时器时间到期。这样的做法是及早让发送方知道报文段没有到达接收方,可提高网络吞吐量约20%。

【快恢复】快重传和快恢复配合使用,体现为:当发送方连续收到三个重复确认时,就执行“乘法减小”算法,把ssthresh门限减半(为了防止网络发生拥塞)。然后将cwnd设置为ssthresh减半以后的值,执行拥塞避免算法,使cwnd缓慢增长。

12. Socket套接字——是对传输层的TCP/IP协议的封装,是一组接口

区分不同应用程序进程间的网络通信和连接,主要有三个参数:目的IP地址,端口号,使用的传输层协议(TCP和UDP)

13. 常用的端口号及对应的服务

端口 服务
21 FTP文件传输协议
23 Telnet远程登录服务
25

SMTP简单邮件传输协议

53 DNS协议,其运行在UDP协议之上
80 HTTP超文本传输协议
443 https
3306 MySQL

 

(3)HTTP原理 

16. 当你用浏览器打开一个链接(如:http://www.javastack.cn)的时候,计算机做了哪些工作步骤。

— —计算机的工作步骤: 

1.URL解析,从链接地址中分解出协议名、主机名、端口、资源路径、动态参数等部分;

2.DNS域名解析,查找域名对应的IP地址,这一步会依次查找浏览器缓存,系统缓存,路由器缓存,根域名服务器;
3.然后利用TCP/P协议开始根据分层顺序与对方进行通信,分层由高到低分别为:应用层、传输层、网络层、数据链路层、物理层。发送端从应用层往下走,接收端从数据链路层网上走。
4.应用层:把以上部分结合自己的本机信息,封装成一个http请求数据包(http请求报文);
5.传输层:发起TCP的三次握手,建立TCP连接,TCP为了方便传输,分割大块的数据,并为它们编号,方便服务器接收时能准确地还原报文信息,这里传输层的TCP协议为传输报文提供可靠的字节流服务;
6.网络层:IP协议把TCP分割好的各种数据包封装到IP包里面传送给接收方,再通过ARP地址解析协议获取IP地址对应的MAC地址;
7.数据链路层:在找到对方的MAC地址后,已被封装好的IP包再被封装到数据链路层的数据帧结构中,将数据发送到数据链路层传输,再通过物理层的比特流传输出去
8.到这一步,客户端发送请求的阶段结束了.
9.接收端的服务器在链路层接收到数据包,再层层向上直到应用层。这过程中包括在传输层通过TCP协议将分段的数据包重新组成原来的HTTP请求报文。
10.服务器响应http请求;
11.浏览器得到html代码
12.浏览器解析html代码,根据响应报文里的状态码做判断,200表示请求成功,可以直接进入渲染流程;3开头的要重定向,4开头表示客户端的一些错误,5开头表示服务器的一些错误。

 — —涉及到的协议有:

  • 应用层使用了HTTP协议进行超文本传输;
  • 对于服务器后台处理应该有telnet远程调用协议响应用户;
  • DNS协议获取网络地址,即IP地址;
  • 打开网页,网页显示用到了表示层的HTML协议
  • 另外必然用到了传输层的TCP网络层的IP协议网络层ARP协议获取物理地址;ICMP协议控制信息的传递。

17. 简述HTTP请求的报文格式。

【链接】---- HTTP请求/响应报文结构

HTTP请求报文由状态行、请求头、空行和请求体4个部分组成,如下:

<method> <request-URL> <version>
<headers>

<entity-body>

//例:
POST / HTTP/1.1
 Host: www.example.com
 User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)
 Gecko/20050225 Firefox/1.0.1
 Content-Type: application/x-www-form-urlencoded
 Content-Length: 40
 Connection: Keep-Alive

 sex=man&name=Professional  

18. HTTP的长连接是什么意思。

在HTTP/1.0中,默认使用的是短连接。也就是说,浏览器和服务器每进行一次HTTP操作,就建立一次连接,但任务结束就中断连接。如果客户端浏览器访问的某个HTML或其他类型的 Web页中包含有其他的Web资源,如JavaScript文件、图像文件、CSS文件等;当浏览器每遇到这样一个Web资源,就会建立一个HTTP会话。

一般情况下,一旦服务器向浏览器发送了请求数据,它就要关闭TCP连接了,但是如果在http请求头部加入了:Connection:keep-alive,TCP连接会保持打开状态,保持连接可以节省为每个请求建立连接所需的时间,还节约了网络带宽。

但从 HTTP/1.1起,默认使用长连接,用以保持连接特性。在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟。缺点是影响并发性能。


19. 如何理解HTTP协议的无状态性。

HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。

缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。

另一方面,在服务器不需要先前信息时它的应答就较快。


20. HTTP有哪些method

【链接】-------  常见的HTTP Method深度解析

http0.9只支持get方法

http1.0支持:GET、POST、HEAD

http1.1支持:GET、POST、HEAD、OPTIONS、PUT、DELETE、TRACE、CONNECT(后五种是http1.1新增的)

GET 对服务器资源的简单请求
POST 用来发送包含用户提交的表单数据的请求
HEAD HEAD 方法与 GET 方法的行为很类似,但服务器在响应中只返回首部。不会返回实体的主体部分。这就允许客户端在未获取实际资源的情况下,对资源的首部进行检查。
PUT

与 GET 从服务器读取文档相反,PUT 方法会向服务器写入文档。

注: POST 用于向服务器发送数据。PUT 用于向服务器上的资源(例如文件)中存储数据。

TRACE TRACE 请求会在目的服务器端发起一个 环回 诊断。行程最后一站的服务器会弹回一条 TRACE 响应,并在响应主体中携带它收到的原始请求报文。这样客户端就可以查看在所有中间 HTTP 应用程序组成的请求 / 响应链上,原始报文是否,以及如何被毁坏或修改过。
OPPTIONS 请求 Web 服务器告知其支持的各种功能;通过使用 OPTIONS,客户端可以在与服务器进行交互之前,确定服务器的能力,这样它就可以更方便地与具备不同特性的代理和服务器进行互操作了。
DELETE 请服务器删除请求 URL 所指定的资源。 但是,客户端应用程序无法保证删除操作一定会被执行。因为 HTTP 规范允许服务 器在不通知客户端的情况下撤销请求。
CONNECT CONNECT方法是HTTP/1.1协议预留的,能够将连接改为管道方式的代理服务器。通常用于SSL加密服务器的链接与非加密的HTTP代理服务器的通信。

【GET和POST的区别以及数据包的格式】

【链接】----- GET和POST两种基本请求方法的区别

  GET POST
对参数的限制 GET把参数包含在URL中,所以参数是有长度限制的,并且只允许参数为ASCII字符 POST把参数包含在Request body中,参数没有长度和类型的限制
编码类型 application/x-www-form-urlencoded application/x-www-form-urlencoded or multipart/form-data。为二进制数据使用多重编码
缓存 GET请求可以被浏览器cache POST不会
安全性

参数直接暴露在URL上,所以 不能传递敏感信息,不安全

更安全,用在表单数据的提交
请求过程 浏览器会把http header和data一并发送出去,服务器响应200 浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok
幂等性 满足幂等性,只是查询数据,不会影响到资源的变化 不满足幂等性,因为调用多次,都将产生新的资源

【注意】HTTP幂等方法,是指无论调用这个url多少次,并不影响资源。


21. 说说你知道的几种HTTP响应码,比如200, 302, 404。

状态码分类 分类描述
1** 信息,服务器收到请求,需要请求者继续执行操作
2** 成功,操作被成功接收并处理
3** 重定向,需要进一步的操作以完成请求
4** 客户端错误,请求包含语法错误或无法完成请求
5** 服务器错误,服务器在处理请求的过程中发生了错误

100  Continue——继续,客户端应继续其请求

200  OK——服务器成功返回网页

302  Move temporarily——临时重定向

403  Forbidden——服务器理解请求客户端的请求,但是拒绝执行此请求,即权限不足

404  Not Found——服务器无法根据客户端的请求找到资源(网页),即资源不存在

405  Method Not Allowed——请求方法不允许

500  Internal Server Error——服务器内部错误

502  Bad Gateway——服务器网关错误

503  Service Unavailable——服务器超时

【链接】-------  http状态码


22. http1.0和http1.1有什么区别。

    (1)长连接

  • http1.0需要使用keep-alive参数来告知服务器端要建立一个长连接
  • 而http1.1默认支持长连接

    (2)节约宽带

HTTP 1.1支持只发送header信息(不带任何body信息),如果服务器认为客户端有权限请求服务器,则返回100,否则返回401。客户端如果接受到100,才开始把请求body发送到服务器。这样当服务器返回401的时候,客户端就可以不用发送请求body了,节约了带宽。

    (3)HOST域

http1.1中,客户端请求的头信息新增了Host头域,用来指定服务器的域名,这样就可以发往同一服务器上的不同网站(在一台物理服务器上可以存在多个虚拟主机,并且它们共享一个IP地址)。

    (4)分块传输编码

在http1.0中,使用Content-Length字段的前提条件是服务器发送回应之前,必须知道回应的数据长度;而对于一些很耗时的动态操作来说,这意味着,服务器要等到所有操作完成才能发送数据,显然这样的效率不高。

在http1.1中,可以不适用Content-Length字段,而使用分段传输编码(chunked transfer encoding)。只要请求或回应的头信息有Transfer-Encoding: chunked字段,就表明回应将由数量未定的数据块组成。

    (5)缓存处理

在HTTP1.0中主要使用header里的If-Modified-Since,Expires来作为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略。

    (6)错误通知的管理

在http1.1中新增了24个错误状态码

    (7)HTTP Pipelining(HTTP管线化)

  • 管线化机制通过持久连接(persistent connection)完成,仅 HTTP/1.1 支持此技术(HTTP/1.0不支持)
  • 只有 GET 和 HEAD 请求可以进行管线化,而 POST 则有所限制
  • 初次创建连接时不应启动管线机制,因为对方(服务器)不一定支持 HTTP/1.1 版本的协议
  • 管线化不会影响响应到来的顺序,如上面的例子所示,响应返回的顺序并未改变
  • HTTP /1.1 要求服务器端支持管线化,但并不要求服务器端也对响应进行管线化处理,只是要求对于管线化的请求不失败即可
  • 由于上面提到的服务器端问题,开启管线化很可能并不会带来大幅度的性能提升,而且很多服务器端和代理程序对管线化的支持并不好,因此现代浏览器如 Chrome 和 Firefox 默认并未开启管线化支持

23. 什么是分块传送。

在http1.0中,使用Content-Length字段的前提条件是服务器发送回应之前,必须知道回应的数据长度;而对于一些很耗时的动态操作来说,这意味着,服务器要等到所有操作完成才能发送数据,显然这样的效率不高。

在http1.1中,可以不使用Content-Length字段,而使用分段传输编码(chunked transfer encoding)。只要请求或回应的头信息有Transfer-Encoding: chunked字段,就表明回应将由数量未定的数据块组成。

每个非空的数据块之前,会有一个16进制的数值,表示这个块的长度。最后是一个大小为0的块,就表示本次回应的数据发送完了。下面是一个例子。

НТТP/1.1 200 Ок
Content-Type: text/plain Transfer-Encoding: chunked
25
This is the data in the first chunk
1C 
and this is the second one
3
con
8
sequence
0

24. HTTPS的加密方式是什么,讲讲整个加密解密流程。

【介绍】

  • Http直接通过明文在浏览器和服务器之间传递消息,容易被监听抓取到通信内容。 
  • Https采用对称加密和非对称加密结合的方式来进行通信。 
  • Https不是应用层的新协议,而是Http通信接口用SSL和TLS来加强加密和认证机制。

【对称加密和非对称加密的区别】

  • 对称加密速度快,非对称加密速度慢。
  • 对称加密要将密钥暴露,和明文传输没区别。
  • 非对称加密将公钥暴露,供客户端加密,服务端使用私钥解密。

【Https加密】—— 对称加密和非对称加密结合方式

  1. 浏览器使用Https的URL访问服务器,建立SSL链接。
  2. 服务器收到SSL链接,发送非对称加密的公钥A返回给浏览器
  3. 浏览器生成随机数,作为对称加密的密钥B
  4. 浏览器使用公钥A,对自己生成的密钥B进行加密,得到密钥C
  5. 浏览器将密钥C,发送给服务器。
  6. 服务器用私钥D对接受的密钥C进行解密,得到对称加密钥B。
  7. 浏览器和服务器之间可以用密钥B作为对称加密密钥进行通信。

【总结】这样浏览器和服务器就共享一个对称加密密钥B,重要的是不会被拦截到。只在传输密钥B的时候进行了一次非对称加密,之后就用对称加密进行传送数据。


25. Http和Https的三次握手有什么区别。

【Https的握手过程】

1,客户端输入https网址,链接到server443端口;

2,服务器手中有一把钥匙和一个锁头,把锁头传递给客户端。数字证书既是公钥,又是锁头

3,客户端拿到锁头后,生成一个随机数,用锁头把随机数锁起来(加密),再传递给服务器。这个随机数成为私钥,现在只有客户端知道

4,服务器用钥匙打开锁头,得到随机数。该随机数变成了新的锁头,把内容锁起来(加密),再传递给客户端。这个随机数服务器也知道了,并且用它来加密数据

5,客户端用自己手中的钥匙(随机数),解密后得到内容。客户端用私钥解密数据

6,接下来的客户端和服务器的数据交换都通过这个随机数来加密。只有客户端和服务器知道私钥,所以数据传输是安全的,不是明文的

【两者区别】

  1. Https协议需要到CA申请证书或自制证书
  2. Http是直接和TCP进行数据传输,而Https经过一层SSL加密
  3. Http是明文传输,Https通过SSL加密,更安全
  4. Http的端口号是80,Https的端口号是443

26. 如何避免浏览器缓存。

在引用js、css文件的url后边加上 ?+Math.random()


27. Session和cookie的区别。

Cookie Session
保存在客户端 保存在服务器
只能保存字符串,且编码只能是ISO8859-1 可以保存任意类型
Cookie被禁用后失效 Cookie被禁用后可以通过url重写来获取Session
安全性较低 安全性较高
Cookie保存的数据大小有限制,一般在4k左右 只要服务器内存够,理论上无限制
分担了服务器压力 增加了服务器压力

28. 简单解释一些ARP协议的工作过程

(1)首先,每个主机都会在自己的ARP缓冲区中建立一个ARP列表,以表示IP地址和MAC地址之间的对应关系。
(2)当源主机要发送数据时,首先检查ARP列表中是否有对应IP地址的目的主机的MAC地址,如果有则直接发送数据,如果没有,就向本网段的所有主机发送ARP数据包,该数据包包括的内容有:源主机IP地址,源主机MAC地址,目的主机的IP地址。
(3)当本网络的所有主机收到该ARP数据包时,首先检查数据包中的IP地址是否是自己的IP地址,如果不是,则忽略该数据包,如果是,则首先从数据包中取出源主机的IP和MAC地址写入到ARP列表中,如果已经存在,则覆盖,然后将自己的MAC地址写入ARP响应包中,告诉源主机自己是它想要找的MAC地址。
(4)源主机收到ARP响应包后。将目的主机的IP和MAC地址写入ARP列表,并利用此信息发送数据。如果源主机一直没有收到ARP响应数据包,表示ARP查询失败。


29. ICMP协议简介

【简介】

  • ICMP网络控制消息协议,位于第三层网络层;用于在IP主机、路由器之间传递控制消息
  • 控制消息是指网络通不通、主机是否可达、路由是否可用等网络本身的消息
  • 这些控制消息并不传输用户数据,但是对用户数据的传递起着重要的作用
  • ICMP报文是在IP报文内部的

【典型应用】

  • Ping—— 检测网络连通性
  • Tracert—— 跟踪报文经过的每一个节点,检测网络丢包及时延的有效手段

30. DNS域名解析协议的A记录、CNAME

【A记录】A (Address) 记录是用来指定主机名(或域名)对应的IP地址记录。用户可以将该域名下的网站服务器指向到自己的web server上。同时也可以设置您域名的二级域名。

【CNAME记录】别名记录。这种记录允许您将多个名字映射到另外一个域名。通常用于同时提供WWW和MAIL服务的计算机。例如,有一台计算机名为“host.mydomain.com”(A记录)。它同时提供WWW和MAIL服务,为了便于用户访问服务。可以为该计算机设置两个别名(CNAME):WWW和MAIL。这两个别名的全称就 http://www.mydomain.com/和“mail.mydomain.com”。实际上他们都指向 “host.mydomain.com”。

  • A记录就是把一个域名解析到一个IP地址(Address,特制数字IP地址),而CNAME记录是把域名解析到另外一个域名;
  • CNAME将几个主机名指向一个别名,其实跟指向IP地址是一样的,因为这个别名也要做一个A记录的;
  • 使用CNAME记录可以很方便地变更IP地址,服务器变更IP时,只需要变更别名的A记录;
  • A记录在输入域名时不用输入WWW.来访问网站,CNAME记录是必须有。

(4)加密算法

31. 加密算法有哪些?

对称加密算法——加密和解密都是同一个密匙:AES、DES;

非对称加密算法——公钥和私钥成对出现:RSA、DSA;

不需要秘钥的散列算法:MD5、SHA-1。

MD5加密算法 —— 消息摘要算法,Hash算法一类

MD5算法对输入任意长度的消息进行运行,产生一个128位的消息摘要

AES加密算法 —— 对称加密算法

对称加密的秘钥传输问题:一般都是客户端向服务端请求对称加密的密钥,而且密钥还得用非对称加密加密后再传输;

RSA加密算法 —— 非对称加密算法

使用RSA一般需要产生公钥和私钥,当采用公钥加密时,使用私钥解密;采用私钥加密时,使用公钥解密。Java程序如下:

public class RSAEncrypt {
	private static Map<Integer, String> keyMap = new HashMap<Integer, String>();  //用于封装随机产生的公钥与私钥
	public static void main(String[] args) throws Exception {
		//生成公钥和私钥
		genKeyPair();
		//加密字符串
		String message = "df723820";
		System.out.println("随机生成的公钥为:" + keyMap.get(0));
		System.out.println("随机生成的私钥为:" + keyMap.get(1));
		String messageEn = encrypt(message,keyMap.get(0));
		System.out.println(message + "\t加密后的字符串为:" + messageEn);
		String messageDe = decrypt(messageEn,keyMap.get(1));
		System.out.println("还原后的字符串为:" + messageDe);
	}

	/** 
	 * 随机生成密钥对 
	 * @throws NoSuchAlgorithmException 
	 */  
	public static void genKeyPair() throws NoSuchAlgorithmException {  
		// KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象  
		KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");  
		// 初始化密钥对生成器,密钥大小为96-1024位  
		keyPairGen.initialize(1024,new SecureRandom());  
		// 生成一个密钥对,保存在keyPair中  
		KeyPair keyPair = keyPairGen.generateKeyPair();  
		RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();   // 得到私钥  
		RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();  // 得到公钥  
		String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()));  
		// 得到私钥字符串  
		String privateKeyString = new 
        String(Base64.encodeBase64((privateKey.getEncoded())));  
		// 将公钥和私钥保存到Map
		keyMap.put(0,publicKeyString);  //0表示公钥
		keyMap.put(1,privateKeyString);  //1表示私钥
	}  

2. 数据结构

1.B-树、B+树

利用索引查询的时候不能将所有索引一次性加载到内存,一般是逐一加载磁盘页,这里的磁盘页对应着索引树的节点;

二叉查找树查询的时间复杂度是O(logN),最坏情况下,磁盘IO的次数等于树的高度;

因此为了减少磁盘IO次数,需要将原本瘦高的树变得矮胖。

【B-树】—— 多路平衡查找树,它的每一个节点最多包含m个孩子,m被称为B树的阶,而m的大小取决于磁盘页的大小

可以将原本“瘦高”的树结构变得“矮胖”,一个m阶的B树具有如下的特征:

  1. 根节点至少有两个子女;
  2. 每个中间节点都包含k-1个元素和k个孩子,其中m/2 <= k <= m;
  3. 每一个叶子节点都包含k-1个元素,其中m/2 <= k <= m;
  4. 所有的叶子节点都位于同一层;
  5. 每个节点中的元素从小到大排列,节点当中k-1个元素正好是k个孩子包含的元素的值域分划

【B+树】由于B+树的中间节点没有存放数据,同样大小的磁盘页能放更多的节点元素,更加“矮胖”,查询时磁盘IO的次数变少

  • 有k个子树的中间节点也有k个元素(B树中是k-1个元素),每个元素不保存数据。只用来索引,数据都保存在叶子节点
  • 所有的叶子节点中包含了全部元素的信息,且叶子结点本身依关键字的大小自小而大顺序链接。(叶子节点用指针连接
  • 所有的中间节点元素都同时存在于子节点,在子节点元素中是最大(或最小)元素。

在数据库的聚集索引中,叶子节点直接包含数据。在非聚集索引中,叶子节点带有指向数据的指针。

【B-数与B+树的比较】

B-树查找只要找到匹配元素的节点即可,匹配元素可能处于中间节点,也可能处于叶子节点,所以的查找性能并不稳定

B+树比B-树的优势:每次都得查询到叶子节点,所以B+树查询性能稳定;磁盘IO次数更少;范围查询更简便。


2. 红黑树

【链接】----  红黑树的实现

【红黑树的应用场景】TreeSet、JDK1.8的HashMap底层数据结构用的红黑树

【红黑树的规则】

  1. 每一个节点都只能是红色或黑色
  2. 根节点是黑色
  3. 每个叶节点(NIL空节点)是黑色的
  4. 如果一个节点是红色的,那它的两个子节点都是黑色的
  5. 从任一节点到其每个叶子节点的所有路径都包含相同数目的黑色节点

【红黑树各种操作的时间复杂度】能保证在最坏情况下,均为O(logn)

【为什么使用红黑树】

相较于AVL树,红黑树对平衡性的要求没有AVL树那么高,牺牲了一定的平衡性,但是也是近似平衡的;同时AVL树为了维持高度平衡,每次插入、删除操作比较复杂、耗时,使用AVL的代价比较高;所以红黑树是在查询性能和维护平衡的开销上做了一个平衡,使得插入、删除、查找各种操作性能都比较稳定,均为O(logn)。

相较于哈希表,权衡三个因素: 查找速度, 数据量, 内存使用,可扩展性,有序性。

hash查找速度会比红黑树快,而且查找速度基本和数据量大小无关,属于常数级别;而红黑树的查找速度是log(n)级别。并不一定常数就比log(n) 小,因为hash还有hash函数的耗时。当元素达到一定数量级时,考虑hash。但若你对内存使用特别严格, 希望程序尽可能少消耗内存,那么hash可能会让你陷入尴尬,特别是当你的hash对象特别多时,你就更无法控制了,而且 hash的构造速度较慢。

  1. 红黑树是有序的,Hash是无序的,根据需求来选择。
  2. 红黑树占用的内存更小(仅需要为其存在的节点分配内存),而Hash事先应该分配足够的内存存储散列表,即使有些槽可能弃用
  3. 红黑树查找和删除的时间复杂度都是O(logn),Hash查找和删除的时间复杂度都是O(1)。

【左旋】左旋中的左意味着被旋转的结点将变成一个左结点

右旋的操作和左旋的代码是对称的,左旋和右旋的时间复杂度均为O(1)

private void rotateLeft(Node x){

    Node y = x.right;  //设置y结点,为x结点的右结点
    //旋转开始
    x.right = y.left;   //x的右结点设置为y的左结点
    if(y.left != null){   //如果y的左结点不为空,则将y的左结点的父结点指向x
        y.left.parent = x;
    }
    y.parent = x.parent; //把y的父结点改为x的父结点
    if(x.parent == null){
        this.root = y;    //如果x的父结点为空。那么y就是root结点
    }
    else if(x == x.parent.left){
        x.parent.left = y;
    }
    else x.parent.right = y;
    y.left = x;
    x.parent = y;
}

【右旋】右旋中的右意味着被旋转的结点将变成一个右结点

private void rotateRight(Node y){
       Node<K> x = y.left; //设置x结点,为y结点的左结点
       //旋转开始
       y.left = x.right; //y的左结点设置为x的右结点
       if (x.right != null)
           x.right.parent = y; //把x右结点的父结点指向y结点
       x.parent = y.parent; //把x的父结点改为y的父结点
       if (y.parent == null)
           this.root = x; //如果y的父结点为空。那么x就是root结点
       else if (y == y.parent.left) //y为它父结点的左结点
           y.parent.left = x; //把y的父结点的左结点改为x结点
       else y.parent.right = x; //把y的父结点的右结点改为x结点
       x.right = y; //x结点的右结点为y
       y.parent = x; //y的父结点为x
   }

【插入】

  1. 将红黑树当做一颗二叉查找树,将结点插入
  2. 将插入的结点着色为“红色”(为了不违背特性5)
  3. 通过一系列的旋转着色,使之重新成为一颗红黑树(想办法满足特性4)

3. List

  • ArrayList 线性表结构(一段地址连续的内存空间),访问效率高,插入和删除效率低
  • LinkedList 双向链表结构,访问效率低,插入和删除效率高
;