目录
一:前言
【文章的末尾给大家留下了大量的福利哦。】
一、为什么连接的时候是三次握手,关闭的时候却是四次握手?
二、TCP 连接为 什么 C lient 会在发送出 ACK 之后进入到 TIME_WAIT
三、为什么不能用两次握手进行连接?
四、如果已经建立了连接,但是客户端突然出现故障了怎么办,
五、HTTPS 和 HTTP 的区别:
六、HTTPS 的优点
七、HTTPS 的缺点
八、http 切换到 HTTPS 如何实现
九、网站从 http 过度到 https 需要注意的几个小问题
十、POST 和 GET 的区别
十一、HTTP 常见状态码介绍
十二、什么是泛型?
十三、IO 密集型与 CPU 密集型操作
十四、什么是多态?为什么使用多态?
十五、动态内存回收对程序员有什么好处
十六、浏览器、安卓、ios 系统之间的区别
十七、什么是幂等性?
十八、在 TCP/IP 协议有四层。
十九、http 协议中的信息头 header 包含什么
二十、TCP 的优点
一:前言
嗨咯铁汁们,很久不见,我还是你们的老朋友凡叔,因为看到最近很多的看凡叔文章的小伙伴都在面试,这里给大家出了一篇关于字节的面试题总结,当然也结合了常见的测试面试题,因为篇幅的原因这篇文章只有【1.2w字】但是!注意但是
【文章的末尾给大家留下了大量的福利哦。】
当然大量的大厂面试全套福利肯定少不了。废话少说咱们直接上干货。
一、为什么连接的时候是三次握手,关闭的时候却是四次握手?
答:因为当 Server 端收到 Client 端的 SYN( 同步序列编号 ) 连接请求报文后,可以直接发送
SYN+ACK 报文。其中 ACK 报文是用来应答的, SYN 报文是用来同步的。但是关闭连接时,当
Server 端收到 FIN 报文时,很可能并不会立即关闭 SOCKET ,所以只能先回复一个 ACK 报文,
告诉 Client 端, " 你发的 FIN 报文我收到了 " 。只有等到我 Server 端所有的报文都发送完了,
我才能发送 FIN 报文,因此不能一起发送。故需要四步握手。
1.1传输层 TCP 传输报文
位于传输层的 TCP 协议为传输报文提供可靠的字节流服务。它为了方便传输,将大块的数
据分割成以报文段为单位的数据包进行管理,并为它们编号,方便服务器接收时能准确地还
原报文信息。 TCP 协议通过 “ 三次握手 ” 等方法保证传输的安全可靠。
客户端发送一个带有 SYN 标志的数据包给服务端,在一定的延迟时间内等待接收的回复。
服务端收到后,回传一个带有 SYN/ACK 标志的数据包以示传达确认信息,最后客户端再回
传一个带 ACK 标志的数据包,代表握手结束,连接成功。
SYN (
Synchronize Sequence Numbers )同步序列编号
ACK (Acknowledgement )确认字符
FIN ( Finish )结束标志
发送端发送一个 SYN=1 , ACK=0 标志的数据包给接收端,请求进行连接,这是第一次握手;
接收端收到请求并且允许连接的话,就会发送一个 SYN=1 , ACK=1 标志的数据包给发送端,
告诉它,可以通讯了,并且让发送端发送一个确认数据包,这是第二次握手;最后,发送端
发送一个 SYN=0 , ACK=1 的数据包给接收端,告诉它连接已被确认,这就是第三次握手。之
后,一个 TCP 连接建立,开始通讯。
下图也可以这么理解:
客户端: “ 你好,在家不,有你快递。 ”---SYN
服务端: “ 在的,送来就行。 ”-----SYN/ACK
客户端: “ 好嘞。 ”-----ACK 关闭 TCP 连接
为了避免服务器与客户端双方的资源占用和损耗,当双方没有请求或响应传递时,任意一方都可以发起关
闭请求。与创建 TCP 连接的 3 次握手类似,关闭 TCP 连接,需要 4 次握手。
SYN (
Synchronize Sequence Numbers )同步序列编号
ACK (Acknowledgement )确认字符
FIN ( Finish )结束标志
4 次握手
上图可以这么理解:
客户端: “ 兄弟,我这边没数据要传了,咱关闭连接吧。 ”----FIN
服务端: “ 收到,我看看我这边有木有数据了。 ”----ACK
服务端: “ 兄弟,我这边也没数据要传你了,咱可以关闭连接了。 ”----FIN
客户端: “ 好嘞。 ”----ACK
二、TCP 连接为 什么 C lient 会在发送出 ACK 之后进入到 TIME_WAIT
状态需要经过 2MSL(最大报文段生存时间)才能返回到 CLOSE 状态? 答:虽然按道理,四个报文都发送完毕,我们可以直接进入 CLOSE 状态了,但是我们必须假
象网络是不可靠的,有可能最后一个 ACK 丢失。所以 TIME_WAIT 状态就是用来重发可能丢
失的 ACK 报文。在 Client 发送出最后的 ACK 回复,但该 ACK 可能丢失。 Server 如果没有收
到 ACK ,将不断重复发送 FIN 片段。所以 Client 不能立即关闭,它必须确认 Server 接收到了
该 ACK 。 Client 会在发送出 ACK 之后进入到 TIME_WAIT 状态。 Client 会设置一个计时器,等
待 2MSL 的时间。如果在该时间内再次收到 FIN ,那么 Client 会重发 ACK 并再次等待 2MSL 。
所谓的 2MSL 是两倍的 MSL(Maximum Segment Lifetime) 。 MSL 指一个片段在网络中最大的存
活时间, 2MSL 就是一个发送和一个回复所需的最大时间。如果直到 2MSL , Client 都没有再
次收到 FIN ,那么 Client 推断 ACK 已经被成功接收,则结束 TCP 连接。
三、为什么不能用两次握手进行连接?
答: 3 次握手完成两个重要的功能,既要双方做好发送数据的准备工作 ( 双方都知道彼此已
准备好 ) ,也要允许双方就初始序列号进行协商,这个序列号在握手过程中被发送和确认。
现在把三次握手改成仅需要两次握手,死锁是可能发生的。作为例子,考虑计算机 S 和
C 之间的通信,假定 C 给 S 发送一个连接请求分组, S 收到了这个分组,并发 送了确认应答
分组。按照两次握手的协定, S 认为连接已经成功地建立了,可以开始发送数据分组。可是,
C 在 S 的应答分组在传输中被丢失的情况下,将不知道 S 是否已准备好,不知道 S 建立什么
样的序列号, C 甚至怀疑 S 是否收到自己的连接请求分组。在这种情况下, C 认为连接还未
建立成功,将忽略 S 发来的任何数据分组,只等待连接确认应答分组。而 S 在发出的分组超
时后,重复发送同样的分组。这样就形成了死锁。
四、如果已经建立了连接,但是客户端突然出现故障了怎么办,
Server
端怎么处理?
TCP 心跳包的发送,通常有两种技术:
1. 应用层自己实现的心跳包
由应用程序自己发送心跳包来检测连接是否正常,服务器每隔一定时间向客户端发送一个短
小的数据包,然后启动一个线程,在线程中不断检测客户端的回应, 如果在一定时间内没
有收到客户端的回应,即认为客户端已经掉线;同样,如果客户端在一定时间内没有收到服
务器的心跳包,则认为连接不可用。
2. 使用 SO_KEEPALIVE 套接字选项
在 TCP 的机制里面,本身是存在有心跳包的机制的,也就是 TCP 的选项 . 不论是服务端还是
客户端,一方开启 KeepAlive 功能后,就会自动在规定时间内向对方发送心跳包, 而另一方
在收到心跳包后就会自动回复,以告诉对方我仍然在线。因为开启 KeepAlive 功能需要消耗
额外的宽带和流量,所以 TCP 协议层默认并不开启默认的 KeepAlive 超时需要 7,200 , 000 MilliSeconds , 即 2 小时,探测次数为 5 次。对于很多服务端应用程序来说, 2 小时的空闲
时间太长。因此,我们需要手工开启 KeepAlive 功能并设置合理的 KeepAlive 参数
五、HTTPS 和 HTTP 的区别:
https 协议需要到 ca 申请证书,一般免费证书很少,需要交费。
http 是超文本传输协议,信息是明文传输。
https 是一种通过计算机网络进行安全通信的传输协议,经由 http 进行通信,利用
ssl/tls 建立全信道,加密数据包。
tls 是传输层加密协议,前身是 ssl 协议,由网景公司 1995
年发布,有时候两者不区分。
http 和 https 使用的是完全不同的连接方式用的端口也不一样, http 是 80 , https
是 443 。
http 是一个基于请求与响应,无状态的,应用层的协议,常基于 tcp / ip 协议传输数
据
https 协议是由 ssl+http 协议构建的可进行加密传输、身份认证的网络协议,要比 http
协议安全。
HTTPS 和 HTTP 的区别主要如下:
1 、 https 协议需要到 ca 申请证书,一般免费证书较少,因而需要一定费用。
2 、 http 是超文本传输协议,信息是明文传输, https 则是具有安全性的 ssl 加密传输协
议。
3 、 http 和 https 使用的是完全不同的连接方式, http 基于 tcp/ip 协议构建的, https
协议是由 ssl+httpP 协议构建的, 用的端口也不一样,前者是 80 ,后者是 443 。
4 、 http 的连接很简单,是无状态的; HTTPS 协议是由 SSL+HTTP 协议构建的可进行加密
传输、身份认证的网络协议,比 http 协议安全。
六、HTTPS 的优点
尽管 HTTPS 并非绝对安全,掌握根证书的机构、掌握加密算法的组织同样可以进行中间人形式的攻
击,但 HTTPS 仍是现行架构下最安全的解决方案,主要有以下几个好处:
( 1 )使用 HTTPS 协议可认证用户和服务器,确保数据发送到正确的客户机和服务器;
( 2 ) HTTPS 协议是由 SSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议,要比 http 协
议安全,可防止数据在传输过程中不被窃取、改变,确保数据的完整性。
( 3 ) HTTPS 是现行架构下最安全的解决方案,虽然不是绝对安全,但它大幅增加了中间人攻击的成
本。
( 4 )谷歌曾在 2014 年 8 月份调整搜索引擎算法,并称 “ 比起同等 HTTP 网站,采用 HTTPS 加密的
网站在搜索结果中的排名将会更高 ” 。
七、HTTPS 的缺点
虽然说 HTTPS 有很大的优势,但其相对来说,还是存在不足之处的:
( 1 ) HTTPS 协议握手阶段比较费时,会使页面的加载时间延长近 50% ,增加 10% 到 20% 的耗电;
( 2 ) HTTPS 连接缓存不如 HTTP 高效,会增加数据开销和功耗,甚至已有的安全措施也会因此而受
到影响;
( 3 ) SSL 证书需要钱,功能越强大的证书费用越高,个人网站、小网站没有必要一般不会用。
( 4 ) SSL 证书通常需要绑定 IP ,不能在同一 IP 上绑定多个域名, IPv4 资源不可能支撑这个消耗。
( 5 ) HTTPS 协议的加密范围也比较有限,在黑客攻击、拒绝服务攻击、服务器劫持等方面几乎起不
到什么作用。最关键的, SSL 证书的信用链体系并不安全,特别是在某些国家可以控制 CA 根证书的情况
下,中间人攻击一样可行。
八、http 切换到 HTTPS 如何实现
如果需要将网站从 http 切换到 https 到底该如何实现呢?
这里需要将页面中所有的链接,例如 js , css ,图片等等链接都由 http 改为 https 。例如:
http://www.baidu.com 改为 https://www.baidu.com
BTW ,这里虽然将 http 切换为了 https ,还是建议保留 http 。所以我们在切换的时候可以做 http 和
https 的兼容,具体实现方式是,去掉页面链接中的 http 头部,这样可以自动匹配 http 头和 https 头。
例如:将 http://www.baidu.com 改为 //www.baidu.com 。然后当用户从 http 的入口进入访问页面时,
页面就是 http ,如果用户是从 https 的入口进入访问页面,页面即使 https 的。
九、网站从 http 过度到 https 需要注意的几个小问题
9.1、nginx 配置同时访问 http 和 https
监听 80 端口和 443ssl 端口。 重定向是 rewrite 关键字,直接改变浏览器地址栏的值; 转发是 proxy_pass 关键字,表示转发,浏览器地址栏不变。
9.2、https 协议下,不允许请求 http 协议的资源
https 协议的网站,不支持请求 http 协议的资源(如 js , css ,视频等),所以,从 http 过度
到 https 的时候,需要注意协议问题。有一个巧妙的方法是,请求资源的时候可以采用相对
协 议 。 比 如 , 本 来 是 https://www.xxx.com/js/1.js
, 此 时 可 以 改 为 相 对 协 议
//www.xxx.com/js/1.js 。这样一来,无论用户访问的是哪一种协议的网站,都会成功。因为,
当遇到相对协议的时候,浏览器会补上协议头(根据访问当前网站的协议)。当然,前提是,
1.js 所在的域名要同时支持 http 和 https 协议,不然就瞎搞了。
9.3、https 协议下播放 http 协议的视频
如果引入的视频只有 http 能访问(如优酷),那在 https 环境下,则无法播放。解决办法:
使用 iframe 。利用 iframe 标签,可以在里面放置一个 http 页面(播放 http 视频),直接引入
就好。(这个暂时没有实践过,目前只有理论,以后找个时间试试)
十、POST 和 GET 的区别
GET 提交的数据放在 URL 中, POST 则不会。这是最显而易见的差别。这点意味着 GET 更不
安全(
POST 也不安全,因为 HTTP 是明文传输抓包就能获取数据内容,要想安全还得加密)
GET 回退浏览器无害, POST 会再次提交请求( GET 方法回退后浏览器再缓存中拿结果, POST
每次都会创建新资源)
GET 提交的数据大小有限制(是因为浏览器对 URL 的长度有限制, GET 本身没有限制), POST
没有
GET 可以被保存为书签, POST 不可以。这一点也能感受到。
GET 能被缓存, POST 不能
GET 只允许 ASCII 字符, POST 没有限制
GET 会保存再浏览器历史记录中, POST 不会。这点也能感受到。
GET 在浏览器回退时是无害的,而 POST 会再次提交请求。
GET 产生的 URL 地址可以被 Bookmark ,而 POST 不可以。
GET 请求会被浏览器主动 cache (缓存),而 POST 不会,除非手动设置。
GET 请求只能进行 ASCII 编码,而 POST 支持多种编码方式。
URL 编码是一种浏览器用来打包请求参数及表单参数的格式 , 参数和参数之间使用 & 分割,
非 ASCII 码使用 % 加 16 进制编码替换
如: https://www.sojson.com/open/api/weather/json.shtml?city= 北京
编码后为:
https://www.sojson.com/open/api/weather/json.shtml?city=%E5%8C%97%E4%BA%AC
GET 请求参数会被完整保留在浏览器历史记录里,而 POST 中的参数不会被保留。
GET 请求在 URL 中传送的参数是有长度限制的,而 POST 么有。
对参数的数据类型, GET 只接受 ASCII 字符,而 POST 没有限制。
GET 比 POST 更不安全,因为参数直接暴露在 URL 上,所以不能用来传递敏感信息。
GET 参数通过 URL 传递, POST 放在 Request body 中。
GET 和 POST 都是 TCP 链接。 GET 产生一个 TCP 数据包;而 POST 会产生两个 TCP 数据包。 原因: Get ,浏览器会把 http header 和 data 一并发送,服务器返回 200
Post ,浏览器先发送 header ,服务器响应 100 ,在发送 data ,服务器响应 200
十一、HTTP 常见状态码介绍
200 :请求成功
301 :请求重定向到另外一个接口,资源(网页等)被永久转移到其它 URL
302 :请求重定向到另外一个接口,资源(网页等)临时转移到其它 URL
304 :请求被重定向到客户端本地缓存
400 :客户端请求语法错误(
post 请求用 get 方法)
401 :客户端请求没有经过授权
403 :客户端请求资源没有访问权限,拒绝访问
404 :客户端请求的资源(网页等)不存在(有可能是请求 url 错误或参数不正确)
405 :请求方法不被允许(比如接口只允许 Post, 使用 Get 请求接口)
415 : content-type 不正确
500 :服务器内部错误(通常是服务器挂了或接口 Bug)
502 :网关失效
503 :服务端发生临时错误
504 :网关请求超时
分类
分类描述
1**
信息,服务器收到请求,需要请求者继续执行操作
2**
成功,操作被成功接收并处理
3**
重定向,需要进一步的操作以完成请求
4**
客户端错误,请求包含语法错误或无法完成请求
5**
服务器错误,服务器在处理请求的过程中发生了错误
十二、什么是泛型?
泛型将接口的概念进一步延伸, “ 泛型 ” 的字面意思就是广泛的类型。类、接口和方法代码可
以应用于非常广泛的类型,代码与它们能够操作的数据类型不再绑定在一起,同一套代码可
以用于多种数据类型,这样不仅可以复用代码,降低耦合性,而且还提高了代码的可读性以
及安全性。
十三、IO 密集型与 CPU 密集型操作
IO 密集型,主要涉及到网络、硬盘 IO 的任务,这类任务消耗 cpu 操作很少,任务大部分时 间都在等待 IO 操作的完成,对于 IO 密集型任务,任务越多, CPU 效率越高,但也有一个限
度。常见的大部分任务都是 IO 密集型任务,比如 Web 应用。对于 IO 密集型操作,对于语
言的运行效率不高,所以一般追求开发效率,使用 python 等脚本语言,
cpu 密集型操作,消耗 CPU 资源,比如计算圆周率、对视频进行高清解码等等,全靠 CPU
的运算能力。这种计算密集型任务虽然也可以用多任务完成,但是任务越多,花在任务切换
的时间就越多, CPU 执行任务的效率就越低,所以,要最高效地利用 CPU ,计算密集型任务
同时进行的数量应当等于 CPU 的核心数。对于 CPU 密集型操作,一般使用 C 等效率高的语
言。
十四、什么是多态?为什么使用多态?
父类类型的变量指向子类创建的对象,使用该变量调用父类中一个被子类重写的方法,则父
类中的方法呈现出不同的行为特征,这就是多态。
简单的来说编译时方法行为表现的是父类中的方法,运行时方法行为表现的是子类中重写该
方法的行为特征
二、为什么使用多态?
1 、实现代码的复用,避免代码的冗余;
2 、减少代码之间的关联性,即耦合度,方便后期对代码的修改,功能的改善,不必牵
一发而动全身,减少不必要的麻烦;
3 、能够通过重写子类的方法,使不同的对像具有不同的功能,扩展了功能。
重载、接口、继承三种方法实现多态
十五、动态内存回收对程序员有什么好处
所谓动态内存分配,就是指在程序执行的过程中动态地分配或者回收存储空间的分配内存的
方法。动态内存分配不象数组等静态内存分配方法那样需要预先分配存储回空间,而是由系
统根据程序的需要即时分配,且分配的大小就是程序要求的大小。动态内存的答好处是归纳
为 8 个字:用时分配,不用释放!
十六、浏览器、安卓、ios 系统之间的区别
浏览器:现在有四大渲染引擎在线: WebKit 、 Blink 、 Trident 和 Gecko
1 、使用 Trident( 三叉戟 ) 内核的浏览器: IE 、 Maxthon 、 TT 、 The World 等; IE 从版本 11 开始,
初步支持 WebGL 技术。 IE8 的 JavaScript 引擎是 Jscript , IE9 开始用 Chakra ,这两个版本区别
很大, Chakra 无论是速度和标准化方面都很出色
2 、使用 Gecko( 壁虎 ) 内核的浏览器: Netcape6 及以上版本、火狐 FireFox 、
MozillaSuite/SeaMonkey ;
3 、使用 Presto 内核的浏览器:欧朋 Opera7 及以上版本;后期也使用谷歌的 Blink
4 、使用 Webkit( 极速 ) 内核的浏览器: Safari 、 Chrome 。后期基于 WebKit 的 fork Web 渲染引 擎: Blink
android : https://www.jianshu.com/p/6d7becff8e04
Android 1.0
智能虚拟键盘、视频录制分享、蓝牙和免提电话等
Android 2.0
网络社交,比如 Facebook 、 Google 地图导航、前置摄像头
Android3.0
主要用于安卓的平板产品,画面动感,可操控性更强
Android4.0
统一了手机和平板电脑使用的系统,支持在系统中使用虚拟按键,可取代物理键、脸部识别、
1080p 视频播放录制
Android5.0
采用全新 Material Design 界面 、由 Dalvik 转用 ART(Android Runtime) 编译
Android6.0
应用权限管理 、指纹识别, SD 卡可能和内置存储 “ 合并 ”
Android7.0
分屏多任务 、同一应用的多条通知提示消息归拢为一项、流量保护模式
Android8.0
长按一个软件后可以弹出子菜单的模式、在权限设置中添加安装限制功能、画中画功能
Android9.0
更像是优化、所有应用都使用 HTTPS 、新的 Home 按钮(形状是水平对齐的药丸)、新截图
快捷方式(点击 Power 菜单中的图标)
Android10
Foldables (折叠屏)、增加了对 5G 网络的支持、保护隐私权限更严格
Android 11
首先对顶部通知栏和 Android 10 上就已出现的气泡进行了优化,让操作变得更加方便快捷。
键盘可自动填充应用程序特定的内容,形式在类似于你选择某个特定功能框,而后在键盘上
出现待选项。
加入了全新的媒体控制中心,将在通知栏中点击开启,并出现在手机下方。通过这个媒体控
制中心,我们可以在这里更好的连接、控制其它的无线设备。
允许用户向请求访问麦克风、摄像头、地理位置的应用给予一次性使用权限,即推出这个应
用后权限会重新被锁定,应用无法继续使用这些权限,需要在访问时需要再次请求相关权限。
Android 12
停止对 32 位的支持,也就是说安卓系统也将开始切换到 64 位操作系统了
ios : https://www.jianshu.com/p/06b9a163a74c , https://www.jianshu.com/p/082e987a4efb
https://blog.csdn.net/u013896628/article/details/79800734
iOS 5
icloud 通知中心 ARC Stroyboard airplay
iOS 6
自动布局 IAP iOS 7
全新扁化风格
力学模型
iOS8
Health Kit ( 健康工具包 ) 和 Home Kit( 家庭工具包 )
iOS9
3Dtouch swift2 编程语言 统一用 https 手机电池的低功耗设置
iOS 10
SiriKit 所有第三方应用都可以用 Siri
Widget Enhancements 锁屏设计小功能
IOS11
UIKit Bars 标题视图的改版
iOS11 导航栏
无线部署支持无线充电 切换到 64 位应用
安全区域:
iPhone X 由于状态栏高度的变化,对于状态栏高度预设值的视图需要,动态获取,
由于新增底部功能区域,需要对视图高度进行适配
IOS12
睡前免打扰模式
屏幕时间
共享精确位置
Siri 为日常任务添加快捷指令
测距仪
IOS13
性能提升
深色模式
苹果地图
隐私改进
外部存储
照片提示年月日并可编辑
十七、什么是幂等性?
HTTP/1.1 中对幂等性的定义是:一次和多次请求某一个资源对于资源本身应该具有同样
的结果(网络超时等问题除外)。也就是说,其任意多次执行对资源本身所产生的影响均与
一次执行的影响相同。
这里需要关注几个重点:
幂等不仅仅只是一次(或多次)请求对资源没有副作用(比如查询数据库操作,没有增
删改,因此没有对数据库有任何影响)。
幂等还包括第一次请求的时候对资源产生了副作用,但是以后的多次请求都不会再对资
源产生副作用。
幂等关注的是以后的多次请求是否对资源产生的副作用,而不关注结果。
网络超时等问题,不是幂等的讨论范围。
17.1什么情况下需要幂等
业务开发中,经常会遇到重复提交的情况,无论是由于网络问题无法收到请求结果而重
新发起请求,或是前端的操作抖动而造成重复提交情况。 在交易系统,支付系统这种重复
提交造成的问题有尤其明显,比如:
用户在 APP 上连续点击了多次提交订单,后台应该只产生一个订单;
向支付宝发起支付请求,由于网络问题或系统 BUG 重发,支付宝应该只扣一次钱。 很 显然,声明幂等的服务认为,外部调用者会存在多次调用的情况,为了防止外部多次调用对
系统数据状态的发生多次改变,将服务设计成幂等。
17.2什么情况下需要保证幂等性
以 SQL 为例,有下面三种场景,只有第三种场景需要开发人员使用其他策略保证幂等性:
SELECT col1 FROM tab1 WHER col2=2 ,无论执行多少次都不会改变状态,是天然的幂等。
UPDATE tab1 SET col1=1 WHERE col2=2 ,无论执行成功多少次状态都是一致的,因此也是
幂等操作。
UPDATE tab1 SET col1=col1+1 WHERE col2=2 ,每次执行的结果都会发生变化,这种不是
幂等的。
17.3为什么要设计幂等性的服务
幂等可以使得客户端逻辑处理变得简单,但是却以服务逻辑变得复杂为代价。满足幂等
服务的需要在逻辑中至少包含两点:
首先去查询上一次的执行状态,如果没有则认为是第一次请求
在服务改变状态的业务逻辑前,保证防重复提交的逻辑
17.4幂等的不足
幂等是为了简化客户端逻辑处理,却增加了服务提供者的逻辑和成本,是否有必要,需
要根据具体场景具体分析,因此除了业务上的特殊要求外,尽量不提供幂等的接口。
增加了额外控制幂等的业务逻辑,复杂化了业务功能;
把并行执行的功能改为串行执行,降低了执行效率。
17.5防重复提交策略
上述的保证幂等方案是分成两步的,第②步依赖第①步的查询结果,无法保证原子性的。
在高并发下就会出现下面的情况:第二次请求在第一次请求第②步订单状态还没有修改为
‘已支付状态’的情况下到来。既然得出了这个结论,余下的问题也就变得简单:把查询和
变更状态操作加锁,将并行操作改为串行操作。
乐观锁
如果只是更新已有的数据,没有必要对业务进行加锁,设计表结构时使用乐观锁,一般
通过 version 来做乐观锁,这样既能保证执行效率,又能保证幂等。例如: UPDATE tab1 SET
col1=1,version=version+1 WHERE version=#version# 不过,乐观锁存在失效的情况,就是常说
的 ABA 问题,不过如果 version 版本一直是自增的就不会出现 ABA 的情况。(从网上找了一
张图片很能说明乐观锁,引用过来,出自 Mybatis 对乐观锁的支持)
防重表
使用订单号 orderNo 做为去重表的唯一索引,每次请求都根据订单号向去重表中插入一
条数据。第一次请求查询订单支付状态,当然订单没有支付,进行支付操作,无论成功与否, 执行完后更新订单状态为成功或失败,删除去重表中的数据。后续的订单因为表中唯一索引
而插入失败,则返回操作失败,直到第一次的请求完成(成功或失败)。可以看出防重表作
用是加锁的功能。
分布式锁
这里使用的防重表可以使用分布式锁代替,比如 Redis 。订单发起支付请求,支付系统
会去 Redis 缓存中查询是否存在该订单号的 Key ,如果不存在,则向 Redis 增加 Key 为订单号。
查询订单支付已经支付,如果没有则进行支付,支付完成后删除该订单号的 Key 。通过 Redis
做到了分布式锁,只有这次订单订单支付请求完成,下次请求才能进来。相比去重表,将放
并发做到了缓存中,较为高效。思路相同,同一时间只能完成一次支付请求。
token 令牌
这种方式分成两个阶段:申请 token 阶段和支付阶段。 第一阶段,在进入到提交订单
页面之前,需要订单系统根据用户信息向支付系统发起一次申请 token 的请求,支付系统将
token 保存到 Redis 缓存中,为第二阶段支付使用。 第二阶段,订单系统拿着申请到的 token
发起支付请求,支付系统会检查 Redis 中是否存在该 token ,如果存在,表示第一次发起支
付请求,删除缓存中 token 后开始支付逻辑处理;如果缓存中不存在,表示非法请求。 实
际上这里的 token 是一个信物,支付系统根据 token 确认,你是你妈的孩子。不足是需要系
统间交互两次,流程较上述方法复杂。
支付缓冲区
把订单的支付请求都快速地接下来,一个快速接单的缓冲管道。后续使用异步任务处理
管道中的数据,过滤掉重复的待支付订单。优点是同步转异步,高吞吐。不足是不能及时地
返回支付结果,需要后续监听支付结果的异步返回。
十八、在 TCP/IP 协议有四层。
1 、应用层:应用层是 TCP/IP 协议的第一层,是直接为应用进程提供服务的。
2 、运输层:作为 TCP/IP 协议的第二层,运输层在整个 TCP/IP 协议中起到了中流砥柱的
作用。且在运输层中, TCP 和 UDP 也同样起到了中流砥柱的作用。
3 、网络层:网络层在 TCP/IP 协议中的位于版第三层。在 TCP/IP 协议中网络层可以进行
网络连接的建立和终止以及 IP 地址的寻找等功能。
4 、网络接口层:在 TCP/IP 协议中,网络接口层位于第四层。由于网络接口层兼并了物
理层和数据链路层所以,网络接口层既是传输数据的物理媒介,也可以为网络层提供一条准
确无误的线路。 TCP / IP 参考模型中,应用层协议常用的有:
HTTP 请求: Hyper Text Transfer Protocol 的缩写,即超文本传输协议。
一、 HTTP 协议的结构
HTTP 报文由客户机到服务器的请求和从服务器到客户机的相应构成。
1 、 request 请求报文的组成 :
请求行 信息头 请求头
实体头 报文主体
2 、 respond 响应报文的组成 : 状态行 信息头
响应头
实体头 报文主体
十九、http 协议中的信息头 header 包含什么
1 、 HTTP 请求方式, POST /test/tupian/cm HTTP/1.1
2 、 Host :请求的 web 服务器域名地址, URL : http://www.baidu.com:8088/test
3 、 User-Agent : HTTP 客户端运行的浏览器类型的详细信息。通过该头部信息, web 服
务器可以判断到当前 HTTP 请求的客户端浏览器类别。
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.8.1.11)
Gecko/20071127 Firefox/2.0.0.11
4 、 Accept :指定客户端能够接收的内容类型,内容类型中的先后次序表示客户端接收
的先后次序。
Accept:text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,
image/png,*/*;q=0.5
5 、 Accept-Language :指定 HTTP 客户端浏览器用来展示返回信息所优先选择的语言。
Accept-Language: zh-cn,zh;q=0.5
6 、 Accept-Encoding :指定客户端浏览器可以支持的 web 服务器返回内容压缩编码类型。
表示允许服务器在将输出内容发送到客户端以前进行压缩,以节约带宽。而这里设
置的就是客户端浏览器所能够支持的返回压缩格式。 ccept-Encoding: gzip,deflate
7 、 Accept-Charset : 浏 览 器 可 以 接 受 的 字 符 编 码 集 。 Accept-Charset:
gb2312,utf-8;q=0.7,*;q=0.7
8 、 Content-Type :显示此 HTTP 请求提交的内容类型。一般只有 post 提交时才需要设置
该属性。
Content-type: application/x-www-form-urlencoded;charset:UTF-8 、 text/xml 、
application/json 、 form-data
9 、 Connection :表示是否需要持久连接。如果 web 服务器端看到这里的值为“ Keep-Alive ”,
或者看到请求使用的是 HTTP 1.1 ( HTTP 1.1 默认进行持久连接),它就可以利用持久
连接的优点,当页面包含多个元素时(例如 Applet ,图片),显著地减少下载所需
要的时间。要实现这一点, web 服务器需要在返回给客户端 HTTP 头信息中发送一
个 Content-Length (返回信息正文的长度)头,最简单的实现方法是:先把内容写
入 ByteArrayOutputStream ,然 后在正式写出内容之前计算它的大小。 Connection:
keep-alive
10 、 Keep-Alive :显示此 HTTP 连接的 Keep-Alive 时间。使客户端到服务器端的连接持续
有效,当出现对服务器的后继请求时, Keep-Alive 功能避免了建立或者重新建立连
接。 Keep-Alive: 300
11 、 cookie : HTTP 请求发送时,会把保存在该请求域名下的所有 cookie 值一起发送给
web 服务器。
12 、 Referer :包含一个 URL ,用户从该 URL 代表的页面出发访问当前请求的页面
二十、TCP 的优点
可靠,稳定 TCP 的可靠体现在 TCP 在传递数据之前,会有三次握手来建立连接,而且 在数据传递时,有确认、窗口、重传、拥塞控制机制,在数据传完后,还会断开连接用
来节约系统资源。 TCP 的缺点 : 慢,效率低,占用系统资源高,易被攻击 TCP 在传
递数据之前,要先建连接,这会消耗时间,而且在数据传递时,确认机制、重传机制、
拥塞控制机制等都会消耗大量的时间,而且要在每台设备上维护所有的传输连接,事实
上,每个连接都会占用系统的 CPU 、内存等硬件资源。 而且,因为 TCP 有确认机制、
三次握手机制,这些也导致 TCP 容易被人利用,实现 DOS 、 DDOS 、 CC 等攻击。