总结:绘上一张Kakfa架构思维大纲脑图(xmind)
其实关于Kafka,能问的问题实在是太多了,扒了几天,最终筛选出44问:基础篇17问、进阶篇15问、高级篇12问,个个直戳痛点,不知道如果你不着急看答案,又能答出几个呢?
若是对Kafka的知识还回忆不起来,不妨先看我手绘的知识总结脑图(xmind不能上传,文章里用的是图片版)进行整体架构的梳理
梳理了知识,刷完了面试,如若你还想进一步的深入学习解读kafka以及源码,那么接下来的这份《手写“kafka”》将会是个不错的选择。
-
Kafka入门
-
为什么选择Kafka
-
Kafka的安装、管理和配置
-
Kafka的集群
-
第一个Kafka程序
-
Kafka的生产者
-
Kafka的消费者
-
深入理解Kafka
-
可靠的数据传递
-
Spring和Kafka的整合
-
SpringBoot和Kafka的整合
-
Kafka实战之削峰填谷
-
数据管道和流式处理(了解即可)
-
第三次挥手
:当服务器端确定数据已发送完成,则向客户端发送FIN=N报文,告诉客户端,好了,我这边数据发完了,准备好关闭连接了。服务器端进入LAST_ACK状态。 -
第四次挥手
:客户端收到FIN=N报文后,就知道可以关闭连接了,但是他还是不相信网络,怕服务器端不知道要关闭,所以发送ack=N+1后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。服务器端收到ACK后,就知道可以断开连接了。客户端等待了2MSL后依然没有收到回复,则证明服务器端已正常关闭,那好,我客户端也可以关闭连接了。最终完成了四次握手。
追问1:为什么连接的时候是三次握手,关闭的时候却是四次握手?
因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,“你发的FIN报文我收到了”。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。
追问2:如果已经建立了连接,但是客户端突然出现故障了怎么办?
TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。
若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。
==================================================================================
HTTP状态码表示客户端HTTP请求的返回结果、标识服务器处理是否正常、表明请求出现的错误等。
状态码的类别:
| 状态码 | 原因 |
| — | — |
| 1XX | Informational(信息性状态码) 接受的请求正在处理 |
| 2XX | Success(成功状态码) 请求正常处理完毕 |
| 3XX | Redirection(重定向状态码) 需要进行附加操作以完成请求 |
| 4XX | Client Error(客户端错误状态码) 服务器无法处理请求 |
| 5XX | Server Error(服务器错误状态码) 服务器处理请求出错 |
| 状态码 | 原因 |
| — | — |
| 2XX | 成功(这系列表明请求被正常处理了) |
| 200 | OK,表示从客户端发来的请求在服务器端被正确处理 |
| 204 | No content,表示请求成功,但响应报文不含实体的主体部分 |
| 206 | Partial Content,进行范围请求成功 |
| 状态码 | 原因 |
| — | — |
| 3XX | 重定向(表明浏览器要执行特殊处理) |
| 301 | moved permanently,永久性重定向,表示资源已被分配了新的 URL |
| 302 | found,临时性重定向,表示资源临时被分配了新的 URL |
| 303 | see other,表示资源存在着另一个 URL,应使用 GET 方法获取资源 |
| 304 | not modified,表示服务器允许访问资源,但请求未满足条件的情况(与重定向无关) |
| 307 | temporary redirect,临时重定向,和302含义类似,但是期望客户端保持请求方法不变向新的地址发出请求 |
| 状态码 | 原因 |
| — | — |
| 4XX | 客户端错误 |
| 400 | bad request,请求报文存在语法错误 |
| 401 | unauthorized,表示发送的请求需要有通过 HTTP 认证的认证信息 |
| 403 | forbidden,表示对请求资源的访问被服务器拒绝,可在实体主体部分返回原因描述 |
| 404 | not found,表示在服务器上没有找到请求的资源 |
| 状态码 | 原因 |
| — | — |
| 5XX | 服务器错误 |
| 500 | internal sever error,表示服务器端在执行请求时发生了错误 |
| 501 | Not Implemented,表示服务器不支持当前请求所需要的某个功能 |
| 503 | service unavailable,表明服务器暂时处于超负载或正在停机维护,无法处理请求 |
========================================================================================
-
GET请求在URL中传送的参数是有长度限制的,而POST没有。
-
GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。而POST数据不会显示在URL中。是放在Request body中。
-
对参数的数据类型,GET只接受ASCII字符,而POST没有限制。
-
GET请求参数会被完整保留在浏览器历史记录里;相反,POST请求参数也不会被浏览器保留。
-
GET请求只能进行url编码(application/x-www-form-urlencoded),而POST支持多种编码方式。
-
GET请求会被浏览器主动缓存,而POST不会,除非手动设置。
-
GET在浏览器回退时是无害的,而POST会再次提交请求。
追问1:那Get请求有Request body么?如果有的话参数可以像Post请求一样放在里面么?
其实吧,GET和POST在本质上没有区别,都是HTTP协议中的两种发送请求的方法。而HTTP呢,是基于TCP/IP的关于数据如何在万维网中如何通信的协议。
万维网:简称WWW,是World Wide Web的简称,也称为Web、3W等
HTTP的底层是TCP/IP。所以GET和POST的底层也是TCP/IP,也就是说,GET/POST都是TCP链接。
GET和POST能做的事情是一样一样的。你要给GET加上request body,给POST带上url参数,技术上是完全行的通的。
- 举个例子吧:
TCP就像汽车,我们用TCP来运输数据,它很可靠,从来不会发生丢件少件的现象。
但是如果路上跑的全是看起来一模一样的汽车,那这个世界看起来是一团混乱,送急件的汽车可能被前面满载货物的汽车拦堵在路上,整个交通系统一定会瘫痪。
为了避免这种情况发生,交通规则HTTP诞生了。HTTP给汽车运输设定了好几个服务类别,包括GET, POST, PUT等等,
HTTP规定,当执行GET请求的时候,要给汽车贴上GET的标签(设置method为GET),而且要求把传送的数据放在车顶上(url中)以方便记录。
如果是POST请求,就要在车上贴上POST的标签,并把货物放在车厢里(request body中)。
当然,你也可以在用GET的时往车厢内偷偷藏点货物,但这并不不光彩;也可以在POST的时候在车顶上也放一些数据,也会让人觉得傻乎乎的。
HTTP只是个行为准则,而GET和POST本质上就是TCP链接,并无差别。但是由于HTTP的规定和浏览器/服务器的限制,导致他们在应用过程中体现出一些不同。
追问2:那你刚才说的URL中传送参数的长度限制在Get和Post中都是怎么样的呢?
其实在Web中啊,还有另一个重要的角色:运输公司。
不同的浏览器Client端(发起http请求)和服务器server端(接受http请求)就是不同的运输公司。
虽然理论上,你可以在车顶上无限的堆货物(url中无限加参数)。但是运输公司可不傻,装货和卸货也是有很大成本的,他们会限制单次运输量来控制风险,数据量太大对浏览器和服务器都是很大负担。
业界不成文的规定是:(大多数)浏览器通常都会限制url长度在2K个字节,而(大多数)服务器最多处理64K大小的url。
超过的部分,恕不处理。如果你用GET服务,在request body偷偷藏了数据,不同服务器的处理方式也是不同的,有些服务器会帮你卸货,读出数据,有些服务器直接忽略。
所以,虽然GET可以带request body,却不能保证一定能被接收到。
我之前处理过一个bug,用户反应查询没有响应,同事查了日志后才发现有几个参数都是undefined,很奇怪,最后发现原来是因为Get请求第一个查询参数太长了,导致URL后面的部分服务器无法接收 ,后来把请求改成post,将参数放在request body后就可以了。
追问3:那么你知道Get、Post请求发送的数据包有什么不同吗?
嗯嗯,是这样的,GET请求时产生一个TCP数据包;POST请求时产生两个TCP数据包。
最后
关于面试刷题也是有方法可言的,建议最好是按照专题来进行,然后由基础到高级,由浅入深来,效果会更好。当然,这些内容我也全部整理在一份pdf文档内,分成了以下几大专题:
- Java基础部分
- 算法与编程
- 数据库部分
- 流行的框架与新技术(Spring+SpringCloud+SpringCloudAlibaba)
这份面试文档当然不止这些内容,实际上像JVM、设计模式、ZK、MQ、数据结构等其他部分的面试内容均有涉及,因为文章篇幅,就不全部在这里阐述了。
作为一名程序员,阶段性的学习是必不可少的,而且需要保持一定的持续性,这次在这个阶段内,我对一些重点的知识点进行了系统的复习,一方面巩固了自己的基础,另一方面也提升了自己的知识广度和深度。
试内容均有涉及,因为文章篇幅,就不全部在这里阐述了。
作为一名程序员,阶段性的学习是必不可少的,而且需要保持一定的持续性,这次在这个阶段内,我对一些重点的知识点进行了系统的复习,一方面巩固了自己的基础,另一方面也提升了自己的知识广度和深度。