TCP/IP、HTTP面试题及解
Question:
OSI/RM(Open System Interconnection Reference Model)开放系统互连参考模型分几层?
Answer:
分为7层,自下到上分别是:物理层、数据链路层、网络层、运输层、会话层、表示层、应用层。
Question:
TCP/IP体系结构分为几层?
Answer:
分别4层,自下到上分别是:网络接口层、网络层、运输层、应用层。
Question:
详细描述TCP三次握手的过程
Answer:
过程如下图
Question:
为什么发起请求方在收到接收方的接受请求确认后,还要发送一个报文?
Answer:
为了防止已失效的连接请求报文又突然出现,并且传给了B,导致又建立一次连接。试想这样一个情景:TCP连接只有2次握手,那么,A发起请求后,B发回响应后,就建立连接了,但是呢,A发起了两个连接请求报文,第一次报文发送之后,在网络中“迷路了”,并没有到达B,所以A在一段时间内没有收到B的响应,所以A又发起了一个连接请求报文,然后呢,这个报文到达了B,并且A收到了B发来的连接确认,那么此时A和B的连接就建立了。传输完数据,释放链接之后,刚刚A发送的那个“迷路”的请求连接报文神奇地到达了B,此时B给A发送一个连接确认,那么A在接收到确认报文后,A和B之间又建立了一次连接,然而,A此时并没有要和B建立连接的想法,是不是出问题了呢?此时,就可以看出来,A对于B的连接确认报文必须要再发送一个确认,以防出现半打开的情况。
Question:
如果服务器不想和客户端建立连接怎么办?
Answer:
在返回的报文中,不要将SYN置为1,而是将RST置为1即可。
Question
假设服务器的80端口没有打开,那么客户端请求服务器的80端口,想要建立连接,请问服务器会发回响应吗?
Answer
会发回响应,不会建立连接,所以会将RST置为1。
这样可能会受到DDoS攻击(SYN-Flood攻击)
Question:
如果短时间出现大量连接请求的攻击,这种方式称作什么攻击?怎么解决?
Answer:
SYN flood攻击,属于DDoS攻击,解决方案可以参考博客:http://www.cnblogs.com/hubavyn/p/4477883.html
Question:详细描述TCP释放连接的过程
Answer:
Question:
在服务器返回给客户端断开连接的确认后,此时处于什么状态?
Answer:
半关闭状态
Question:
在服务器返回给客户端断开连接的确认后,如果服务器还有数据要发给客户端,客户端还会接收数据吗?
Answer:
仍旧会接收数据
Question:
为什么A在Time-Wait状态时,要等待2MSL的时间?
Answer:
为了保证 A 发送的最后一个 ACK 报文段能够到达 B,为什么是2MSL,因为,如果在MSL内,A发送的最后一个ACK报文没有到达B,那么B就会再次发起断开连接请求,该报文又是一个MSL,所以是MSL,如果在2MSL中,A都没有再次收到断开连接的请求报文,那么就证明B收到了最后一个ACK确认,TCP连接才可以真正断开。
Question:
标志字段中,FIN和RST分别在什么时候使用?
Answer:
FIN是在正常断开连接的时候使用;RST是在异常断开连接的时候使用,比如服务器宕机了。
Question:HTTP协议中,有哪些请求方法?含义是什么?
Answer:
方法名 含义 在REST中的含义 GET 获取资源 获取资源 POST 传输实体主题(提交数据) 创建一个新资源 PUT 传输文件 更新一个已有的资源 DELETE 删除文件 删除一个资源 HEAD 获取报文首部(不需要返回实体首部) 获取报文首部(不需要返回实体首部) OPTIONS 询问支持的方法 询问支持的方法 TRACE 追踪路径 CONNECT 要求使用隧道协议连接代理
Question:
HTTP协议的状态码?分别在哪些情况下返回哪个状态码?
Answer:
摘抄自https://httpstatuses.com/ 可以查看本文末尾,有较完整的状态码
状态码 含义 200(OK) 请求被服务器正常处理 204(No Content) 请求被正常处理,但是响应报文中不包含实体主体 206(Partial Content) 返回客户端请求的部分数据 301(Moved Permanently) 永久重定向(SEO评分会转移到重定向的网址) 302(Found) 临时重定向(一般短地址会返回这个状态码) 304(Not Modified) 服务器端的资源未改变,可直接使用缓存中的资源 400(Bad Request) 客户端请求报文中传输的数据格式错误,服务器无法解析 401(Unauthoried) 表示客户端没有经过授权认证,无法访问 403(Forbidden) 服务器端拒绝客户端访问该资源,没有权限或者权限不够 404(Not Found) 表示客户端请求的资源在服务器上未找到 500(Internal Server Error) 服务器遇到某种事故,导致服务器崩溃了 502(Bad Gateway) 作为网关或者代理工作的服务器尝处理请求时,没有上游服务器进程处理请求,或者解析脚本的时候后端程序有错误(最简单的缺个分号)。 503(Service Unavailable) 服务器接受的请求太多(超负荷),导致请求得不到处理 504(Gateway Timeout) 作为网关或者代理工作的服务器尝试执行请求时,未能及时从上游服务器获得响应
Question:
http协议中状态码500、502、503、504的区别
Answer:
背景:1、nginx作服务器;2、使用php-fpm
500:nginx服务器负载过高,直接崩溃了。
502:nginx将解析php的请求转发给php-fpm后,如果php-fpm的没有可用的worker(处理进程),没有足够的php-fpm的worker去处理请求,或者说php-fpm解析php脚本时,发现脚本有错误(缺一个分号),都会返回502状态码。
503:nginx服务器最多一次性可以接受1万个请求,如果此时瞬间有10万个请求到达,即使是反向代理转发,nginx也忙不过来,导致一些请求得不到处理,此时就会返回503状态码。
504:nginx将请求转发给php-fpm之后,未能及时获得php-fpm的响应,就会返回504状态码。
Question:
https怎么保证传输安全?
Answer:
1、证书;2、各种加密(RSA)
Question:常见的应用层协议使用的端口
Answer:
应用层协议 默认端口 使用的下层协议(传输层) FTP 21 TCP TFTP 69 UDP SSH 22 TCP DNS 53 UDP HTTP 80 TCP HTTPS 443 TCP SMTP 161 TCP DHCP 67(发送)--- 68(接收) UDP TELNET 23 TCP REDIS 6379 TCP MySQL 3306 TCP Memcache 11211 TCP
Question:
介绍一下http缓存?
Answer:
http缓存使用在浏览器-服务器架构下,浏览器在发起请求后,服务器在返回响应的中设置http缓存相关头部信息之后,浏览器在接收到数据之后,会按照头部信息的要求,对某些资源进行缓存,下一次,浏览器再次对某一个资源的访问,如果缓存中存在,并且没有过期,那么就直接从缓存中获取,不用再向服务器请求一次该资源,有效地减少服务器的压力。
Question:http缓存的三种模型?
Answer:
首先get请求可以被缓存,但是post请求不能被缓存。要想使用http缓存,是通过响应中的头部字段决定的,比如:Pragma、Expires、Cache-Control、Last-Modified、Etag。
1、200 OK(from memory cache):直接从本地缓存中获取相应,最快速,最省流量的请求方式,不会发起请求。
2、304 Not Modified:协商缓存,浏览器在本地缓存失效的情况下,询问服务器,该资源内容是否发生改变,如果服务器端数据没有改变的话,就返回给浏览器304状态码,只返会一些基本的响应头信息,不返回响应体。这里涉及到两个概念,Last--Modified-Since、Last-Modified、Etag.
3、200 OK:以上两种缓存都失败了,服务器就会返回完整响应,没有用到缓存,速度相对较慢。
Question:
本地缓存机制以及header?
Answer:
1、本地缓存:浏览器认为本地缓存可以使用,不会去请求服务器端。
2、Pragma:HTTP 1.0,该字段一般被设置为no-cache是,会告知浏览器禁用本地缓存,即每次都向服务器发送请求。
3、Expires:HTTP 1.0,用来启用本地缓存,值是一个格林威治时间,告诉浏览器缓存失效的时刻,超过该时间,缓存就会失效;如果还没到达该时刻,表明缓存仍旧有效,无需发送请求。存在的问题:响应的时间戳是格林威治时间(全球通用的),但是,这个时间是服务器端设置的,服务器可以保证时间误差在一定范围内,但是客户端浏览器因为地理位置的不同、时区的差异,如果时间差距大的话,就会影响缓存结果。
4、Cache-Control:HTTP 1.1,告知浏览器缓存过期时间的间隔,而不是时刻。所以浏览器在收到响应之后的一段时间内有效,即使时区不同,具体的时间不一致,也不影响缓存管理。Cache-Control可以设置为一下值:
a、no-store:禁止浏览器缓存响应。
b、no-cache:不允许直接使用本地缓存,要先发起请求和服务器协商,看缓存的资源是否发送改变。
c、max-age=有效期:告知浏览器该响应本地缓存的有效期是多长,单位是秒。
优先级:Pragma > Cache-Control > Expires
5、Etag:HTTP1.1,文件的指纹标识符,如果文件内容发生了修改,指纹也会发生改变。
Question:
介绍协商缓存的过程?
Answer:
当浏览器当前的缓存过期了,或者说Cache-Control中设置为no-cache声明不允许直接使用缓存,那么浏览器就必须先发起请求。这里有两种情况:
1、请求的资源最后一次文件修改时间发生改变,内容发生了改变。
2、请求的资源最后一次文件修改时间发生改变,内容没有发生改变。
第一次请求服务器中的某个资源时,如果服务器需要使用协商缓存,那么就会在响应中,就会将Cache-Control字段设为no-cache,同时也会返回一个Last-Modified字段标志该资源最后一次更新的时间,客户端浏览器收到响应之后,会将响应缓存起来,下次需要使用该资源时,会首先请求服务器,请求头中有一个If-Modified-Since字段,值为上一次服务器端返回响应中的Last-Modified值。服务器收到该字段后,会首先查看服务器端的该资源的最后一次修改文件的时间是否发生了改变,如果发生了改变,就将资源重新发回客户端;如果最后修改时间没有修改时间,那就返回304状态码。
但是存在这样一个场景,上面请求的那个资源,虽然最后一次修改的时间发生了改变,但是,内容没有变。有这种情况,程序员增加了一行代码,保存之后,发现有问题,于是又把那一行代码删了,于是乎,资源最后一次修改时间发生了改变,内容却没有改变。 此时,可以使用Etag头部字段,这个字段就是与资源的内容有关的,可以理解为资源的摘要。服务器端在响应中会发送Etag,之后浏览器在请求的时候会携带着这个Etag(If-None-Match),服务器端接收到If-Modified-Since字段和If-None-Match字段后,如果发现最后一次修改的时间没变,那么就直接返回304;如果时间发生了改变,那再看内容摘要是否发生了改变,如果内容摘要没发生变化,照样发回304,否则返回资源。
可以使用下面的代码理解:
check() { //第一次请求,直接返回内容,以及Last-Modified、Etag if (first.Request) { return array( "Cache-Control" => "no-cache", "Last-Modified" => filemtime("demo.txt"), "Etag" => md5(file_get_content("demo.txt")), "content" => file_get_content("demo.txt") ) } //非第一次请求 if (Request.If-Modefied-Since == filemtime(file_get_content("demo.txt"))) { return 304; } else { if (Request.If-None-Match == md5(file_get_content("demo.txt"))) { return 304; } else { return array( "Cache-Control" => "no-cache", "Last-Modified" => filemtime("demo.txt"), "Etag" => md5(file_get_content("demo.txt")), "content" => file_get_content("demo.txt") ) } } }
Question:哪些文件适合做本地缓存?
Answer:不变的图片(logo、图标);js、css静态文件;可下载的内容、媒体文件。
Question:哪些文件使用协商缓存?
Answer:HTML文件、经常替换的图片、经常修改的js、css文件。
Question: css和js怎么实现不缓存?
Answer:除了上面的Etag、Last-Modified,还可以在末尾加一个随机数(index.css?v=xxxx)
Question:不建议缓存的内容?
Answer:1、用户隐私数据; 2、API接口返回的结果
Question:Nginx怎么设置缓存?
Answer:
1、设置expires值,30d表示30天内有效,12h表示12个小时有效;max表示10年过期。
2、etag设置为on即可,值为off时,表示关闭etag。
3、add_header cache-control max-age=3600
Question
一个项目完成升级后,QA在测试的时候,发现网站内容没有改变,这是因为有缓存的缘故,因为缓存没有过期,就会使用已经缓存的内容。这算事故(bug)吗?
Answer
首先,这肯定算是事故(bug),比如,一个网站,发布新版本后,用户访问的时候,发现根本就没发生改变,因为使用的是缓存的css或者js,开发人员不可能打电话通知用户进行强制刷新(Ctrl + F5),这是不现实的。
解决方案可以按照前面实现不缓存的方法,在js或者css后面增加一个版本号,demo.js?version=VarName,这一这个varname可以使用时间戳,但建议的是使用版本号,每发布一个版本就更改一下版本号,即可解决之前的问题。
Question:
常见的http协议请求头部信息的含义?
Answer:
出现在什么报文中 头部信息 含义 示例值 请求 Accept 客户端(客户)能够处理的响应内容的类型 text/html Accept-Charset 优先使用的字符集 iso-8859-5 Accept-Encoding 优先使用的编码格式 gzip, deflate Accept-Language 优先使用的语言 zh-cn Authorization Web认证信息 Host 请求资源所在服务器 www.cnblogs.com Range 希望服务器返回的字节范围 bytes=5000-10000 User-Agent Http客户端的信息 chrom、postman、mozilla Max-Forwrads 最大传输跳数(代理) 10 Referer 对某个URL发起请求的原始获取方(盗链、防盗链) www.cnblogs.com Origin 请求方的源 www.baidu.com 请求-响应 Pragma 告知客户端是否缓存响应的内容 no-cache 响应 Expires 告知客户端缓存返回的资源,在该时刻(格林威治时间)之前有效 Tue, 24 Aug 2038 18:26:15 GMT 请求-响应 Cache-Control 告知客户端怎么使用返回的响应,缓存、不缓存、有效期 no-store、no-cache、max-age=123 响应 Last-Modified 返回的资源最后修改时间(格林威治时间) Wed, 29 Aug 2018 18:26:15 GMT 响应 Etag 服务器端在返回资源的同时,也返回改header,表示资源的指纹 请求 Last-Modified-Since 客户端在发起请求时,携带之前服务器端返回的Last-Modified值。 请求 Last-None-Match 客户端在发起请求时,携带之前服务器端返回的Etag值 响应 Age 代理服务器发给客户端,告知客户端源服务器在多久之前创建了该资源。 600(10分钟) 响应 Date 资源创建的时间 Fri, 31 Aug 2018 02:55:36 GMT 响应 Server 告知客户端:服务器使用什么http应用程序 apache/2.2.2 响应 Location 重定向 www.cnblogs.com 请求-响应 Upgrade 升级为其他协议 websocket 请求-响应 Connection 删除首部或者管理持久连接 响应 Allow 资源可支持的http方法(对options的响应) GET、POST Content-Type 实体主体的类型 Content-Length 实体主体的长度 Content-Range 实体主体的范围 Content-Language 实体主体的语言类型
Question:
GET和POST的区别?
Answer:
1、get请求时可以缓存的,post请求不能缓存。
2、get的资源可以添加到书签,post请求的资源不能添加到书签。
3、get请求不能上传文件,上传文件只能使用post请求。
4、get请求传递的参数会保留在历史记录中,post请求的参数不会保留在历史记录中和日志中。
5、get请求传输的数据有限制,根据客户端类型有关,一般是2048字节。post请求一般没有大小限制。
6、get请求只能传输ASCII码,post可以传递各种编码数据。
7、get请求传递的参数暴露在地址栏上,所以没有post安全,get传递的参数还可以通过历史记录查看到之后。
Question:
介绍一下https
Answer:
https是基于SSL/TLS的HTTP协议,所有的http数据都是在ssl/tls协议封装之上传输的。
https协议在http协议的基础上,添加了SSL/TLS握手以及数据的加密传输,也是应用层协议,使用443端口。
加密主要是使用rsa公钥加密算法。
Question:
什么是盗链?怎么防盗链?
Answer:
盗链就是一个网站使用非本地的资源的行为,比如,A网站觉得B网站的某张图片很好看,于是在A站点使用img的src将B站点的图片链接过来,这就是盗链行为,会加重B站点服务器的压力。
解决方法:
1、使用http协议中的referer字段。
在nginx中有ngx_http_referer_module用于阻挡来源非法的域名请求。
配置nginx时,设置valid_referers none | blocked | server_names | string;
none:referer头部为空时也会被认为是合法的。
blocked:referer头部不为空,但是里面的值被代理或者防火墙删了。
server_names:本地信任的域名。
location ~.*\.(gif|jpg|png|flv|swf|rar|zip)$ { valid_referers none blocked test.com *test.com; if ($invalid_referer) { #return 403; rewrite ^/ http://www.test.com/403.png; } }2、使用签名
使用第三方模块HttpAccessKeyModule。
accesskey on | off 模块开关
accesskey_hashmethod md5 | sha-1 签名加密方式
accesskey_arg string 设置随时用get请求时,请求中携带的参数。
accesskey_signature "demo$remote_addr"; 签名。
location ~.*\.(gif|jpg|png|flv|swf|rar|zip)$ { accesskey on; accesskey_hashmethod md5; accesskey_arg "key"; accesskey_signature "demo$remote_addr"; }工作流程,客户端请求的时候,携带格式为key=demo192.168.1.1的数据,然后服务器端接收到后,使用md5加密,然后判断是否合法
Question
跨域问题的解决方案?
Answer
有四种方案,可以参考:https://www.cnblogs.com/-beyond/p/7921565.html
重点讲了jsonp,注意一个域由3部分组成(协议、ip或者域名、端口)
Question
什么是同源策略?
Answer
这里的源,其实就是域。
打开tab_1,访问一个a.com的资源;再打开一个tab_2,访问a.com的资源;再打开一个tab_3,访问b.com的资源。 那么,tab_1中a.com可以使用tab_2中a.com的资源,但是却不能使用tab_3中的b.com中的资源。比如说js访问cookie的操作。
web浏览器允许第一个页面的脚本访问第二个页面里的数据,但是也只有在两个页面有相同的源时。源是由URI,主机名,端口号组合而成的。这个策略可以阻止一个页面上的恶意脚本通过页面的DOM对象获得访问另一个页面上敏感信息的权限。
Question
介绍一下httponly?
Answer
首先看普通情况,访问一个页面的时候,在控制台中可以使用JavaScript来操作cookie,这个其实是不安全的。
那么,可以在设置cookie的时候,设置httponly,之后,就不能通过JavaScript来操作cookie了。
Question
既然https是可以保证数据的安全,那么,为什么还要将密码加密后再传输呢?
Answer
1、首先,https只是相对于http来说要安全一些,所以他也不是绝对安全的。
2、密码为甚要加密,首先问一个问题,服务器需要知道用户的密码吗?服务器应该知道用户的密码吗?不需要,也不应该吧。
3、如果不加密,就算服务器方不去看用户密码,但是,如果服务器被攻击了,数据泄露了,密码是不是也泄露了?Yahoo的教训历历在目。
Question
介绍一下HTTP的长连接
Answer
早期的HTTP协议,每次一次HTTP通信后都会端口TCP连接,如果需要再次进行HTTP通信,则需再次建立TCP连接;当页面中比如有很多图片,那么就需要创建很多次HTTP连接,也就是很多次TCP连接。
HTTP长连接,其实是为了降低频繁创建TCP连接的开销,可以减少服务器端的开销,使用Connection:keep-alive。
HTTP1.1及之后的版本中,默认都是使用长连接,只要任意一端没有断开连接,则保持TCP连接状态。
HTTP的长连接有“非管道化和管道化”两种方式:非管道化需要客户端收到服务端的请求后在发起下一次请求;管道化是指客户端不需要等待服务器对上一个请求的响应,就可以发起下一次请求。
是否支持管道化,需要客户端和服务端共同配合。
代码 | 消息 | 描述 |
---|---|---|
100 | Continue | 只有请求的一部分已经被服务器接收,但只要它没有被拒绝,客户端应继续该请求。 |
101 | Switching Protocols | 服务器切换协议。 |
200 | OK | 请求成功。 |
201 | Created | 该请求是完整的,并创建一个新的资源。 |
202 | Accepted | 该请求被接受处理,但是该处理是不完整的。 |
203 | Non-authoritative Information | |
204 | No Content | |
205 | Reset Content | |
206 | Partial Content | |
300 | Multiple Choices | 链接列表。用户可以选择一个链接,进入到该位置。最多五个地址。 |
301 | Moved Permanently | 所请求的页面已经转移到一个新的 URL。 |
302 | Found | 所请求的页面已经临时转移到一个新的 URL。 |
303 | See Other | 所请求的页面可以在另一个不同的 URL 下被找到。 |
304 | Not Modified | |
305 | Use Proxy | |
306 | Unused | 在以前的版本中使用该代码。现在已不再使用它,但代码仍被保留。 |
307 | Temporary Redirect | 所请求的页面已经临时转移到一个新的 URL。 |
400 | Bad Request | 服务器不理解请求。 |
401 | Unauthorized | 所请求的页面需要用户名和密码。 |
402 | Payment Required | 您还不能使用该代码。 |
403 | Forbidden | 禁止访问所请求的页面。 |
404 | Not Found | 服务器无法找到所请求的页面。. |
405 | Method Not Allowed | 在请求中指定的方法是不允许的。 |
406 | Not Acceptable | 服务器只生成一个不被客户端接受的响应。 |
407 | Proxy Authentication Required | 在请求送达之前,您必须使用代理服务器的验证。 |
408 | Request Timeout | 请求需要的时间比服务器能够等待的时间长,超时。 |
409 | Conflict | 请求因为冲突无法完成。 |
410 | Gone | 所请求的页面不再可用。 |
411 | Length Required | "Content-Length" 未定义。服务器无法处理客户端发送的不带 Content-Length 的请求信息。 |
412 | Precondition Failed | 请求中给出的先决条件被服务器评估为 false。 |
413 | Request Entity Too Large | 服务器不接受该请求,因为请求实体过大。 |
414 | Request-url Too Long | 服务器不接受该请求,因为 URL 太长。当您转换一个 "post" 请求为一个带有长的查询信息的 "get" 请求时发生。 |
415 | Unsupported Media Type | 服务器不接受该请求,因为媒体类型不被支持。 |
417 | Expectation Failed | |
500 | Internal Server Error | 未完成的请求。服务器遇到了一个意外的情况。 |
501 | Not Implemented | 未完成的请求。服务器不支持所需的功能。 |
502 | Bad Gateway | 未完成的请求。服务器从上游服务器收到无效响应。 |
503 | Service Unavailable | 未完成的请求。服务器暂时超载或死机。 |
504 | Gateway Timeout | 网关超时。 |
505 | HTTP Version Not Supported | 服务器不支持"HTTP协议"版本。 |