Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Coudy Hou
JavaGuide
提交
622e1243
J
JavaGuide
项目概览
Coudy Hou
/
JavaGuide
与 Fork 源项目一致
从无法访问的项目Fork
通知
5
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
J
JavaGuide
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
622e1243
编写于
11月 25, 2019
作者:
S
Snailclimb
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
修改错误图片链接
上级
33cae608
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
10 addition
and
13 deletion
+10
-13
docs/essential-content-for-interview/PreparingForInterview/美团面试常见问题总结.md
...content-for-interview/PreparingForInterview/美团面试常见问题总结.md
+10
-13
未找到文件。
docs/essential-content-for-interview/PreparingForInterview/美团面试常见问题总结.md
浏览文件 @
622e1243
...
@@ -120,7 +120,7 @@ request.getRequestDispatcher("login_success.jsp").forward(request, response);
...
@@ -120,7 +120,7 @@ request.getRequestDispatcher("login_success.jsp").forward(request, response);
图片来源:《图解HTTP》:
图片来源:《图解HTTP》:
![
状态码
](
https://user-gold-cdn.xitu.io/2018/4/19/162db5e985aabdbe?imageView2/0/w/1280/h/960/format/webp/ignore-error/1
)
![
各种网络请求用到的协议
](
https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-11/各种网络请求用到的协议.jpg
)
总体来说分为以下几个过程:
总体来说分为以下几个过程:
...
@@ -142,10 +142,10 @@ request.getRequestDispatcher("login_success.jsp").forward(request, response);
...
@@ -142,10 +142,10 @@ request.getRequestDispatcher("login_success.jsp").forward(request, response);
**漫画图解:**
**漫画图解:**
图片来源:《图解HTTP》
图片来源:《图解HTTP》
![
TCP三次握手
](
https://user-gold-cdn.xitu.io/2018/5/8/1633e127396541f1?w=864&h=439&f=png&s=226095
)
<img
src=
"https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-11/tcp三次握手.jpg"
style=
"zoom:50%;"
/>
**简单示意图:**
**简单示意图:**
![
TCP三次握手
](
https://user-gold-cdn.xitu.io/2018/5/8/1633e14233d95972?w=542&h=427&f=jpeg&s=15088
)
<img
src=
"https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-11/tcp三次握手2.jpg"
style=
"zoom:50%;"
/>
-
客户端–发送带有 SYN 标志的数据包–一次握手–服务端
-
客户端–发送带有 SYN 标志的数据包–一次握手–服务端
-
服务端–发送带有 SYN/ACK 标志的数据包–二次握手–客户端
-
服务端–发送带有 SYN/ACK 标志的数据包–二次握手–客户端
...
@@ -173,7 +173,7 @@ request.getRequestDispatcher("login_success.jsp").forward(request, response);
...
@@ -173,7 +173,7 @@ request.getRequestDispatcher("login_success.jsp").forward(request, response);
双方通信无误必须是两者互相发送信息都无误。传了 SYN,证明发送方(主动关闭方)到接收方(被动关闭方)的通道没有问题,但是接收方到发送方的通道还需要 ACK 信号来进行验证。
双方通信无误必须是两者互相发送信息都无误。传了 SYN,证明发送方(主动关闭方)到接收方(被动关闭方)的通道没有问题,但是接收方到发送方的通道还需要 ACK 信号来进行验证。
![
TCP四次挥手
](
https://user-gold-cdn.xitu.io/2018/5/8/1633e1676e2ac0a3?w=500&h=340&f=jpeg&s=13406
)
断开一个 TCP 连接则需要“四次挥手”:
断开一个 TCP 连接则需要“四次挥手”:
...
@@ -394,8 +394,6 @@ TransactionDefinition 接口中定义了五个表示隔离级别的常量:
...
@@ -394,8 +394,6 @@ TransactionDefinition 接口中定义了五个表示隔离级别的常量:
**AOP:**
面向切面编程。(Aspect-Oriented Programming) 。AOP可以说是对OOP的补充和完善。OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。实现AOP的技术,主要分为两大类:一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码,属于静态代理。
**AOP:**
面向切面编程。(Aspect-Oriented Programming) 。AOP可以说是对OOP的补充和完善。OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。实现AOP的技术,主要分为两大类:一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码,属于静态代理。
# 二 进阶篇
# 二 进阶篇
## 1 消息队列MQ的套路
## 1 消息队列MQ的套路
...
@@ -409,11 +407,11 @@ TransactionDefinition 接口中定义了五个表示隔离级别的常量:
...
@@ -409,11 +407,11 @@ TransactionDefinition 接口中定义了五个表示隔离级别的常量:
**《大型网站技术架构》第四章和第七章均有提到消息队列对应用性能及扩展性的提升。**
**《大型网站技术架构》第四章和第七章均有提到消息队列对应用性能及扩展性的提升。**
#### 1)通过异步处理提高系统性能
#### 1)通过异步处理提高系统性能
![
通过异步处理提高系统性能
](
https://
user-gold-cdn.xitu.io/2018/4/21/162e63a8e34ba534?w=910&h=350&f=jpeg&s=29123
)
![
通过异步处理提高系统性能
](
https://
my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-11/通过异步处理提高系统性能.jpg
)
如上图,
**在不使用消息队列服务器的时候,用户的请求数据直接写入数据库,在高并发的情况下数据库压力剧增,使得响应速度变慢。但是在使用消息队列之后,用户的请求数据发送给消息队列之后立即 返回,再由消息队列的消费者进程从消息队列中获取数据,异步写入数据库。由于消息队列服务器处理速度快于数据库(消息队列也比数据库有更好的伸缩性),因此响应速度得到大幅改善。**
如上图,
**在不使用消息队列服务器的时候,用户的请求数据直接写入数据库,在高并发的情况下数据库压力剧增,使得响应速度变慢。但是在使用消息队列之后,用户的请求数据发送给消息队列之后立即 返回,再由消息队列的消费者进程从消息队列中获取数据,异步写入数据库。由于消息队列服务器处理速度快于数据库(消息队列也比数据库有更好的伸缩性),因此响应速度得到大幅改善。**
通过以上分析我们可以得出
**消息队列具有很好的削峰作用的功能**
——即
**通过异步处理,将短时间高并发产生的事务消息存储在消息队列中,从而削平高峰期的并发事务。**
举例:在电子商务一些秒杀、促销活动中,合理使用消息队列可以有效抵御促销活动刚开始大量订单涌入对系统的冲击。如下图所示:
通过以上分析我们可以得出
**消息队列具有很好的削峰作用的功能**
——即
**通过异步处理,将短时间高并发产生的事务消息存储在消息队列中,从而削平高峰期的并发事务。**
举例:在电子商务一些秒杀、促销活动中,合理使用消息队列可以有效抵御促销活动刚开始大量订单涌入对系统的冲击。如下图所示:
![
合理使用消息队列可以有效抵御促销活动刚开始大量订单涌入对系统的冲击
](
https://
user-gold-cdn.xitu.io/2018/4/21/162e64583dd3ed01?w=780&h=384&f=jpeg&s=13550
)
![
合理使用消息队列可以有效抵御促销活动刚开始大量订单涌入对系统的冲击
](
https://
my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-11/合理使用消息队列可以有效抵御促销活动刚开始大量订单涌入对系统的冲击.jpg
)
因为
**用户请求数据写入消息队列之后就立即返回给用户了,但是请求数据在后续的业务校验、写数据库等操作中可能失败**
。因此使用消息队列进行异步处理之后,需要
**适当修改业务流程进行配合**
,比如
**用户在提交订单之后,订单数据写入消息队列,不能立即返回用户订单提交成功,需要在消息队列的订单消费者进程真正处理完该订单之后,甚至出库后,再通过电子邮件或短信通知用户订单成功**
,以免交易纠纷。这就类似我们平时手机订火车票和电影票。
因为
**用户请求数据写入消息队列之后就立即返回给用户了,但是请求数据在后续的业务校验、写数据库等操作中可能失败**
。因此使用消息队列进行异步处理之后,需要
**适当修改业务流程进行配合**
,比如
**用户在提交订单之后,订单数据写入消息队列,不能立即返回用户订单提交成功,需要在消息队列的订单消费者进程真正处理完该订单之后,甚至出库后,再通过电子邮件或短信通知用户订单成功**
,以免交易纠纷。这就类似我们平时手机订火车票和电影票。
#### 2)降低系统耦合性
#### 2)降低系统耦合性
...
@@ -428,7 +426,8 @@ TransactionDefinition 接口中定义了五个表示隔离级别的常量:
...
@@ -428,7 +426,8 @@ TransactionDefinition 接口中定义了五个表示隔离级别的常量:
我们知道如果模块之间不存在直接调用,那么新增模块或者修改模块就对其他模块影响较小,这样系统的可扩展性无疑更好一些。
我们知道如果模块之间不存在直接调用,那么新增模块或者修改模块就对其他模块影响较小,这样系统的可扩展性无疑更好一些。
我们最常见的
**事件驱动架构**
类似生产者消费者模式,在大型网站中通常用利用消息队列实现事件驱动结构。如下图所示:
我们最常见的
**事件驱动架构**
类似生产者消费者模式,在大型网站中通常用利用消息队列实现事件驱动结构。如下图所示:
![
利用消息队列实现事件驱动结构
](
https://user-gold-cdn.xitu.io/2018/4/21/162e6665fa394b3b?w=790&h=290&f=jpeg&s=14946
)
![
利用消息队列实现事件驱动结构
](
https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-11/利用消息队列实现事件驱动结构.jpg
)
**消息队列使利用发布-订阅模式工作,消息发送者(生产者)发布消息,一个或多个消息接受者(消费者)订阅消息。**
从上图可以看到
**消息发送者(生产者)和消息接受者(消费者)之间没有直接耦合**
,消息发送者将消息发送至分布式消息队列即结束对消息的处理,消息接受者从分布式消息队列获取该消息后进行后续处理,并不需要知道该消息从何而来。
**对新增业务,只要对该类消息感兴趣,即可订阅该消息,对原有系统和业务没有任何影响,从而实现网站业务的可扩展性设计**
。
**消息队列使利用发布-订阅模式工作,消息发送者(生产者)发布消息,一个或多个消息接受者(消费者)订阅消息。**
从上图可以看到
**消息发送者(生产者)和消息接受者(消费者)之间没有直接耦合**
,消息发送者将消息发送至分布式消息队列即结束对消息的处理,消息接受者从分布式消息队列获取该消息后进行后续处理,并不需要知道该消息从何而来。
**对新增业务,只要对该类消息感兴趣,即可订阅该消息,对原有系统和业务没有任何影响,从而实现网站业务的可扩展性设计**
。
消息接受者对消息进行过滤、处理、包装后,构造成一个新的消息类型,将消息继续发送出去,等待其他消息接受者订阅该消息。因此基于事件(消息对象)驱动的业务架构可以是一系列流程。
消息接受者对消息进行过滤、处理、包装后,构造成一个新的消息类型,将消息继续发送出去,等待其他消息接受者订阅该消息。因此基于事件(消息对象)驱动的业务架构可以是一系列流程。
...
@@ -569,16 +568,14 @@ static int hash(int h) {
...
@@ -569,16 +568,14 @@ static int hash(int h) {
所谓
**“拉链法”**
就是:将链表和数组相结合。也就是说创建一个链表数组,数组中每一格就是一个链表。若遇到哈希冲突,则将冲突的值加到链表中即可。
所谓
**“拉链法”**
就是:将链表和数组相结合。也就是说创建一个链表数组,数组中每一格就是一个链表。若遇到哈希冲突,则将冲突的值加到链表中即可。
![
jdk1.8之前的内部结构-HashMap
](
https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/jdk1.8之前的内部结构-HashMap.jpg
)
![
jdk1.8之前的内部结构
](
https://user-gold-cdn.xitu.io/2018/3/20/16240dbcc303d872?w=348&h=427&f=png&s=10991
)
#### 2)JDK1.8之后
#### 2)JDK1.8之后
相比于之前的版本, JDK1.8之后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间。
相比于之前的版本, JDK1.8之后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间。
![
JDK1.8之后的HashMap底层数据结构
](
https://user-gold-cdn.xitu.io/2018/11/14/16711ac29c351da9?w=720&h=545&f=jpeg&s=23933
)
![
jdk1.8之后的内部结构-HashMap
](
https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/JDK1.8之后的HashMap底层数据结构.jpg
)
TreeMap、TreeSet以及JDK1.8之后的HashMap底层都用到了红黑树。红黑树就是为了解决二叉查找树的缺陷,因为二叉查找树在某些情况下会退化成一个线性结构。
TreeMap、TreeSet以及JDK1.8之后的HashMap底层都用到了红黑树。红黑树就是为了解决二叉查找树的缺陷,因为二叉查找树在某些情况下会退化成一个线性结构。
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录