Skip to content

Commit

Permalink
修复部署图片无法查看的问题
Browse files Browse the repository at this point in the history
  • Loading branch information
flycash committed Jan 22, 2023
1 parent 997f143 commit 3d1d986
Show file tree
Hide file tree
Showing 11 changed files with 22 additions and 22 deletions.
6 changes: 3 additions & 3 deletions cache/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,21 @@
3. B 更新缓存,缓存中数据被更新为2
4. A 更新缓存,缓存中数据被更新为1
5. 此时缓存中数据为1,而DB中数据为2。这种不一致会一直持续到缓存过期,或者缓存和DB再次被更新,并且被修改正确;
![](img/db_before_cache.png)
![](./img/db_before_cache.png)
1. 先更新缓存,再更新 DB。不一致的情况;
1. A 更新缓存,缓存中数据被更新为1
2. B 更新缓存,缓存中数据被更新为2
3. B 更新 DB,DB中数据被更新为2
4. A 更新 DB,DB中数据被更新为1
5. 此时缓存中数据为2,但是DB 中数据为1。这种不一致会一直持续到缓存过期,或者缓存和DB再次被更新,并且被修改正确;
![](img/cache_before_db.png)
![](./img/cache_before_db.png)
1. 先更新 DB,再删除缓存。不一致的情况;
1. A 从数据库中读取数据1
2. B 更新数据库为2
3. B 删除缓存
4. A 更新缓存为1
5. 此时缓存中数据为1,数据库中数据为2
![](img/db_remove_cache.png)
![](./img/db_remove_cache.png)

所以本质上,没有完美的解决方案,或者说仅仅考虑这种更新顺序,是不足以解决缓存一致性问题的。

Expand Down
6 changes: 3 additions & 3 deletions database/transaction.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ innodb 引擎是通过MVCC来支持事务的。(到这一步,停下来,接

关键点:ACID,innodb 通过 MVCC 支持事务

![数据库事务](img/transaction.png)
![数据库事务](./img/transaction.png)

## 扩展点

Expand Down Expand Up @@ -86,7 +86,7 @@ InnoDB 作为一个优等生,在[隔离级别定义](https://en.wikipedia.org/
- 对于仅包含连续相同当前读语句的事务,第一个当前读会加临键锁,会阻塞别的事物的修改,也避免了幻读。
- 但是对于快照都和当前读语句交错的事务,第一个快照读后其它事务仍可以修改并提交内容,当前事务的后续当前读就会读到其他事务带来的变更。导致可以造出一些印证 InnoDB 没有解决幻读问题的例子。

![](img/rr-phantom-read-example.png)
![](./img/rr-phantom-read-example.png)

#### 参考资料

Expand Down Expand Up @@ -129,7 +129,7 @@ InnoDB 作为一个优等生,在[隔离级别定义](https://en.wikipedia.org/
2. 间隙锁:锁住记录之间的间隔,或者索引之前的范围,或者所以之后的范围。只在重复读级别产生,(可以在前面隔离级别的地方提)
3. 临键锁(Next key lock):记录锁和间隙锁的组合,即锁住记录,又锁住了间隙

![记录锁和间隙锁](img/next_key_lock.png)
![记录锁和间隙锁](./img/next_key_lock.png)


### innodb 引擎和 MyISAM 引擎的区别
Expand Down
4 changes: 2 additions & 2 deletions golang/mutex.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@

在大多数的锁实现里面——不仅仅是 Go 的 mutex 都是有套路的:

![](img/lock_pattern.png)
![](./img/lock_pattern.png)

所以基本上就是两步:
- 自旋加锁,所谓的自旋也就是 CAS 操作,将锁从无锁状态修改为加锁状态。自旋这个过程一般可以可通过控制自旋的次数或者时长来控制;
- 自旋失败之后就进入队列,等待释放锁的时候被唤醒;

但是 Go 有一点特殊,即 Go 有所谓的正常模式和饥饿模式。为了理解这个问题,要先看这么一个问题:
![](img/lock_competition_two_ways.png)
![](./img/lock_competition_two_ways.png)

如果锁此时已经被释放了,那么你作为一个设计者,你会把锁给谁?

Expand Down
2 changes: 1 addition & 1 deletion microservice/timeout.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@

首先我们看一个例子:

![链路超时](img/chain-timeout.png)
![链路超时](./img/chain-timeout.png)

基本步骤是:
- 客户端最开始的时候,链路超时时间是 3s。一般在 BFF 里面会设置好整个链路的超时时间,而后逐步传递;
Expand Down
2 changes: 1 addition & 1 deletion mq/Kafka.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

分析: 如果只是宽泛地谈 Kafka,那么回答的点就要围绕 Kafka 的几个组成来。这个部分不必谈及“为什么 Kafka 高性能” “为什么 Kafka 高可用”等问题。因为按照一般的惯例,接下来就会聊这个话题。总跳回答的思路就是介绍一下 Kafka 的基本原理,几个主要概念。后面详细的内容,等后面面试官来提问。

![Kafka知识点](img/kafka_available_performance.png)
![Kafka知识点](./img/kafka_available_performance.png)

答:Kafka 是一个基于发布订阅模式的消息队列中间件。它由 Producer, Consumer, Broker 和 Partition 几个组成。

Expand Down
12 changes: 6 additions & 6 deletions mq/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

分析:如果不考察特定的消息中间件,那么就是考察一般的消息队列的理论。

![消息队列概览](img/mq_overview.jpeg)
![消息队列概览](./img/mq_overview.jpeg)

基本上就是围绕以上这些考点。因为不考察具体的消息中间件的原理,反而不太好回答,因为这些问题都是要在实际中遇到过,才能有比较深刻的体会。所以下面的很多回答,都是使用了我自己的例子,读者要进行相应的替换,提前准备好。

Expand All @@ -22,7 +22,7 @@

关键字:**一致性****幂等****顺序**

![大概模式](img/overview.jpeg)
![大概模式](./img/overview.jpeg)

## 问题

Expand All @@ -40,8 +40,8 @@

关键字:**解耦****异步****削峰**

![直接调用](img/decouple1.jpeg)
![依赖中间件解耦](img/decouple2.jpeg)
![直接调用](./img/decouple1.jpeg)
![依赖中间件解耦](./img/decouple2.jpeg)

#### 类似问题

Expand Down Expand Up @@ -89,7 +89,7 @@

分析:这个问题有别于“如何保证消息只会发送一次”。消息消费幂等,意味着发送方可能发送了多次,或者消费中间出了什么问题,导致了重复消费。单纯的消息中间件并不能保证。例如,当网络超时的时候,中间件完全不知道,消费者消费了没有,成功还是失败。如果不重试,那么就可能没消费;如果重试,就可能重复消费。这里有些人可能会回答`ACK`机制,其实这是不对的,`ACK`机制并不能保证幂等。因为你`ACK`了,你并不能确保中间件一定能收到。看后面**什么情况导致重复消费**

![ACK 机制无法确保幂等性](img/ack_timeout.jpeg)
![ACK 机制无法确保幂等性](./img/ack_timeout.jpeg)

答案:保证幂等性,主要依赖消费者自己去完成。一般来说,一条消息里面都会带上标记这一次业务的某些特征字段。核心就是利用这些字段来去重。比如说,最常见的是利用数据库的唯一索引来去重,要小心的就是,采用 `check - doSomething` 模式可能会有并发问题。

Expand Down Expand Up @@ -205,7 +205,7 @@

分析:消息积压,核心就在于生产者太快而消费者太慢。解决思路要么控制生产者的发送速率,要么提高消费者的效率。一般我们不太会倾向于控制发送者的速率,所以解决问题的思路就变成了如何提高消费者效率。提高消费者的效率,要么提高消费单条消息的效率,要么是增加消费者的数量。

![消息积压解决思路](img/too_many_msg.jpeg)
![消息积压解决思路](./img/too_many_msg.jpeg)

答案:整体上有两个思路:

Expand Down
2 changes: 1 addition & 1 deletion redis/availability.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

Redis Sentinel 模式要注意有两个集群,一个是存放了 Redis 数据的集群,一个是监控这个数据集群的哨兵集群。于是就需要理解哨兵集群之间是如何监控的,如何就某件事达成协议,以及哨兵自身的容错。

![Redis 高可用](img/availability.png)
![Redis 高可用](./img/availability.png)

答案:Redis 高可用有两种模式,Sentinel 和 Cluster。

Expand Down
4 changes: 2 additions & 2 deletions redis/data_structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

分析:这是`Redis`必考题。考察`Redis`数据结构有两大类问法,一种是直接问你某种数据结构的特征,一种是问你某个场景下应该使用什么数据结构。本质上,两者考察的都是同一个东西,即你是否了解某种数据结构。在复习这个模块的时候,要从表象和底层实现两个角度去学习,熟记于心。你要注意区分,你要回答的是 Redis 值对象的数据结构(表象),还是底层实现。大多数情况下,你应该从表象出发,即值对象的角度出发,而后讨论每一种值对象的可能的底层实现。如果记不住全部的底层实现,可以只讨论重点的几个。先看图:

![值对象](img/value_object.png)
![值对象](./img/value_object.png)

![底层数据结构](img/data_structure.png)
![底层数据结构](./img/data_structure.png)

总体回答的讨论就是“某种值对象-有什么实现-某种实现的特点”。

Expand Down
2 changes: 1 addition & 1 deletion redis/expired.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

分析:Redis 对过期键值对的处理,可以说是日经题。核心就是懒惰删除+定期删除。前者很容易记忆,后者很容易忽略。而要刷亮点,要从 RDB, AOF 和 主从复制三个不同处理策略上着手。

![过期策略](img/expired.png)
![过期策略](./img/expired.png)

答案: Redis 删除过期键值对,主要依赖于两种方式,定期删除和懒惰删除。

Expand Down
2 changes: 1 addition & 1 deletion redis/io_model.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

分析:所有的 IO 模型,考来考去就是一句话,**IO多路复用**。因为操作系统就那么一回事,你要高性能,就没啥选择,反正别问,问就是`IO 多路复用`。那么为什么大家还问呢?因为`IO 多路复用`大体上大家都是差不多的,但是细节上就五花八门。回答 Redis 的 IO 模型,亮点可以从两个角度刷,一个是和`memcache`的比较;一个是从 6.0 支持多线程角度刷。

![IO 模型](img/io_model.png)
![IO 模型](./img/io_model.png)

核心就是四个组件。

Expand Down
2 changes: 1 addition & 1 deletion redis/persistent.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

进一步,我们可以拿 Redis 的 AOF 机制和 MySQL 的 `binlog` 进行对比,它们都记录的是中间执行步骤。而 MySQL 的`mysqldump`就非常接近 `RDB`,也是一种快照保存方案。

![Redis 持久化](img/persistence.png)
![Redis 持久化](./img/persistence.png)

答案: Redis 的持久化机制分成两种,RDB 和 AOF。

Expand Down

0 comments on commit 3d1d986

Please sign in to comment.