diff --git a/notes/Java 容器.md b/notes/Java 容器.md index b7068ad9..600f36e2 100644 --- a/notes/Java 容器.md +++ b/notes/Java 容器.md @@ -754,6 +754,8 @@ new capacity : 00100000 - 为 0,那么 hash%00010000 = hash%00100000,桶位置和原来一致; - 为 1,hash%00100000 = hash%00010000 + 16,桶位置是原位置 + 16。 +

+ #### 7. 计算数组容量 HashMap 构造函数允许用户传入的容量不是 2 的 n 次方,因为它可以自动地将传入的容量转换为 2 的 n 次方。 diff --git a/notes/Socket.md b/notes/Socket.md index 48d65ed3..56cbad75 100644 --- a/notes/Socket.md +++ b/notes/Socket.md @@ -234,6 +234,8 @@ epoll_ctl() 用于向内核注册新的描述符或者是改变某个文件描 从上面的描述可以看出,epoll 只需要将描述符从进程缓冲区向内核缓冲区拷贝一次,并且进程不需要通过轮询来获得事件完成的描述符。 +

+ epoll 仅适用于 Linux OS。 epoll 比 select 和 poll 更加灵活而且没有描述符数量限制。 diff --git a/notes/pics/bloom-filter.png b/notes/pics/bloom-filter.png new file mode 100644 index 00000000..6937dad6 Binary files /dev/null and b/notes/pics/bloom-filter.png differ diff --git a/notes/pics/consumer-group.png b/notes/pics/consumer-group.png new file mode 100644 index 00000000..2041c12c Binary files /dev/null and b/notes/pics/consumer-group.png differ diff --git a/notes/pics/csrf.png b/notes/pics/csrf.png new file mode 100644 index 00000000..8ff486a2 Binary files /dev/null and b/notes/pics/csrf.png differ diff --git a/notes/pics/epoll.png b/notes/pics/epoll.png new file mode 100644 index 00000000..2f01bd30 Binary files /dev/null and b/notes/pics/epoll.png differ diff --git a/notes/pics/hashmap-resize.png b/notes/pics/hashmap-resize.png new file mode 100644 index 00000000..6288b753 Binary files /dev/null and b/notes/pics/hashmap-resize.png differ diff --git a/notes/pics/lru.png b/notes/pics/lru.png new file mode 100644 index 00000000..38da77b8 Binary files /dev/null and b/notes/pics/lru.png differ diff --git a/notes/pics/next-key-locks.png b/notes/pics/next-key-locks.png new file mode 100644 index 00000000..94cf0dee Binary files /dev/null and b/notes/pics/next-key-locks.png differ diff --git a/notes/pics/rate-limit.png b/notes/pics/rate-limit.png new file mode 100644 index 00000000..f79e7b14 Binary files /dev/null and b/notes/pics/rate-limit.png differ diff --git a/notes/pics/rocketmq-transaction.png b/notes/pics/rocketmq-transaction.png new file mode 100644 index 00000000..431ac11f Binary files /dev/null and b/notes/pics/rocketmq-transaction.png differ diff --git a/notes/pics/saga.png b/notes/pics/saga.png new file mode 100644 index 00000000..9232b074 Binary files /dev/null and b/notes/pics/saga.png differ diff --git a/notes/分布式.md b/notes/分布式.md index 7cd66180..7b3373fc 100644 --- a/notes/分布式.md +++ b/notes/分布式.md @@ -210,6 +210,8 @@ TCC(Try-Confirm-Cancel)是在业务层面实现的两阶段提交,每个 Saga 将一个分布式事务拆分为多个本地事务,每个本地事务直接提交,并且都有一个对应的补偿操作。依次执行各个本地事务,如果某一个失败,就逆序执行前面已经提交的本地事务的补偿操作。 +

+ Saga 没有预留资源的 Try 阶段,中间状态对其它事务可见,因此没有隔离性。它适合流程长、无法长时间锁定资源的业务,正向操作和补偿操作同样需要实现幂等。 ### 本地消息表 @@ -226,6 +228,8 @@ Saga 没有预留资源的 Try 阶段,中间状态对其它事务可见,因 RocketMQ 的事务消息把本地消息表的工作交给了消息队列:生产者先发送一条对消费者不可见的半消息,再执行本地事务,然后根据执行结果通知 Broker 提交或者回滚这条消息。如果 Broker 长时间没有收到通知,会主动回查生产者的本地事务状态。 +

+ ## 三、CAP 分布式系统不可能同时满足一致性(C:Consistency)、可用性(A:Availability)和分区容忍性(P:Partition Tolerance)。常见的“三选二”说法有误导性,因为网络分区是无法避免的故障,不是可以选择的选项。 diff --git a/notes/攻击技术.md b/notes/攻击技术.md index b92735f6..9c56e27c 100644 --- a/notes/攻击技术.md +++ b/notes/攻击技术.md @@ -122,6 +122,8 @@ http://www.examplebank.com/withdraw?account=AccountName&amount=1000&for=PayeeNam 如果有账户名为 Alice 的用户访问了恶意站点,而之前刚访问过银行不久,登录信息尚未过期,那么就会损失 1000 美元。 +

+ 这种恶意的网址可以有很多种形式,藏身于网页中的许多地方。此外,攻击者也不需要控制放置恶意网址的网站。例如他可以将这种地址藏在论坛,博客等任何用户生成内容的网站中。这意味着如果服务器端没有合适的防御措施的话,用户即使访问熟悉的可信网站也有受攻击的危险。改为 POST 请求也不能解决问题,攻击者可以使用自动提交的表单。 通过例子能够看出,攻击者并不能通过 CSRF 攻击来直接获取用户的账户控制权,也不能直接窃取用户的任何信息。他们能做到的,是欺骗用户浏览器,让其以用户的名义执行操作。 diff --git a/notes/数据库系统原理.md b/notes/数据库系统原理.md index ec7b72c6..59006f30 100644 --- a/notes/数据库系统原理.md +++ b/notes/数据库系统原理.md @@ -362,6 +362,8 @@ SELECT c FROM t WHERE c BETWEEN 10 and 20 FOR UPDATE; (20, +∞) ``` +

+ ## 七、关系数据库设计理论 ### 函数依赖 diff --git a/notes/消息队列.md b/notes/消息队列.md index 5e5779d0..1e082281 100644 --- a/notes/消息队列.md +++ b/notes/消息队列.md @@ -34,6 +34,8 @@ Kafka、RocketMQ 等通过消费者组把两种模型结合起来:一条消息会发送给每个订阅它的消费者组,但在一个消费者组内只会被一个消费者消费。 +

+ 发布与订阅模式和观察者模式有以下不同: - 观察者模式中,观察者和主题都知道对方的存在;而在发布与订阅模式中,生产者与消费者不知道对方的存在,它们之间通过频道进行通信。 diff --git a/notes/系统设计基础.md b/notes/系统设计基础.md index fa9c0e97..84e0dc5a 100644 --- a/notes/系统设计基础.md +++ b/notes/系统设计基础.md @@ -111,6 +111,10 @@ - 降级:主动关闭部分非核心功能,从而保证核心功能可用; - 熔断:某个依赖的服务持续出错时,暂时不再调用它而是直接返回默认结果,避免故障沿着调用链扩散。 +漏桶以固定速率处理请求,桶满时丢弃新的请求;令牌桶以固定速率放入令牌,请求拿到令牌才能被处理,桶中积累的令牌允许一定的突发流量。 + +

+ 熔断器有关闭、打开和半开三种状态:失败率超过阈值时打开;打开一段时间后进入半开状态,放行少量请求试探,成功则关闭,失败则重新打开。

diff --git a/notes/缓存.md b/notes/缓存.md index 1a6cffa1..08831347 100644 --- a/notes/缓存.md +++ b/notes/缓存.md @@ -97,6 +97,10 @@ CDN 主要有以下优点: - 对这些不存在的数据缓存一个空数据,并设置较短的过期时间; - 使用布隆过滤器保存所有存在的 Key,对不存在的 Key 的请求直接拒绝。 +布隆过滤器用多个哈希函数把 Key 映射到位数组的多个位置并置为 1。查询时只要有一个位置为 0,Key 就一定不存在;全部为 1 时 Key 可能存在,存在一定的误判率。 + +

+ ### 缓存击穿 指的是某个热点数据的缓存过期时,大量对它的请求同时到达数据库。 @@ -200,6 +204,8 @@ Redis Cluster 使用的不是一致性哈希,而是把 Key 映射到固定的 - 访问某个节点时,将其从原来的位置删除,并重新插入到链表头部。这样就能保证链表尾部存储的就是最近最久未使用的节点,当节点数量大于缓存最大空间时就淘汰链表尾部的节点。 - 为了使删除操作时间复杂度为 O(1),就不能采用遍历的方式找到某个节点。HashMap 存储着 Key 到节点的映射,通过 Key 就能以 O(1) 的时间得到节点,然后再以 O(1) 的时间将其从双向队列中删除。 +

+ Java 的 LinkedHashMap 内部就是这种结构,把 accessOrder 设为 true 并重写 removeEldestEntry 方法,就可以直接得到一个 LRU 缓存。 ```java