HashMap 成环问题

在 JDK 1.7 的实现中,使用头插法来实现元素的插入和数组扩容。

扩容的 Resize 包含扩容和 Rehash 两个步骤,Rehash 在并发的情况下可能会形成链表环。

Sun 认为这不是一个 Bug,因为 HashMap 本来就不支持并发,要并发就用 ConcurrentHashMap

这个问题只存在于 JDK1.7 中,在 JDK1.8 中使用了不同的扩容实现方式,不会出现这种情况。

阅读更多

MySQL 索引下推

在 MySQL 5.6 版本后加入的新特性索引下推(Index Condition Pushdown)。 可以在索引遍历过程中,对索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表次数。

Index Filter 与 Table Filter 分离,Index Filter 下降到 InnoDB 的索引层面进行过滤,减少了回表与返回 MySQL Server 层的记录交互开销,提高了 SQL 的执行效率。

阅读更多
Java HashMap 实现

Java HashMap 实现

HashMap 是 Java 中最重要的数据结构,也是最常用的集合类型。面试中基本都会问到一两个 HashMap 相关的问题。

由于 JDK 1.8 对 HashMap 进行了优化,基本上重写了 HashMap 的实现,所以通常还会考查 HashMap 的优化点。

本文收集整理了网上一些相关介绍,也是我在面试中常被问到的相关内容。

阅读更多

MySQL 索引失效情况

本文整理了 MySQL InnoDB 存储引擎中,常见导致索引失效的原因。

MySQL 是否使用索引通常取决于优化器估算的结果,如果计算结果认为全表扫描比使用索引还快,那通常就使用全表扫描。

以下两大类查询语句会导致查询就算走索引也需要对结果进行处理,最终优化器不会使用索引进行查询:

  1. 违反最左匹配原则
  2. 索引列上面做操作
阅读更多

MySQL 索引使用的原则

在 MySQL 中,主要有四种类型的索引,分别为: B-Tree 索引, Hash 索引, Fulltext 索引和 R-Tree 索引。

Innodb 存储引擎的 B-Tree 索引使用的存储结构实际上是 B+Tree。本文总结的几个索引使用原则主要基于 Innodb 存储引擎,原理便是依托于 B+ 树的特性。

阅读更多

TCP TIME_WAIT 状态

四次挥手

当需要断开一个 TCP 连接时,需要四次挥手,每一次需要发送一报文,同时 TCP 连接会进行状态的变化。在挥手时的最后一个 ACK 发出后,TCP 连接会进入 TIME_WAIT 状态。

TIME_WAIT 状态通常需要等待 2MSL 的时间再变成 CLOSED 状态。而因为这个状态,经常会产生一些奇怪的问题。本文整理了 TIME_WAIT 状态的作用和如何应对大量 TIME_WAIT 的建议。

阅读更多

TCP 的三次握手和四次挥手

TCP 的三次握手和四次挥手,可以说是老生常谈的经典问题。字面上,三次握手是指发送了三个报文段,四次挥手是指发送了四个报文段。但知其然,更要知其所以然。

本文整理了从相关文章的笔记,以备查用。

阅读更多

Spring 应用无法启动,报无法读取配置文件错误

公司研发部门提供了一个组件包,该包在启动的时候会根据配置文件创建 MQ 消费线程,消费指定消息。集成到项目中后项目完全无法启动,报取不到配置的错误。经排查,
配置文件的配置是正确的,但在启动类中就是读不到相关配置。

阅读更多

用 @ApiVersion 注解给 API 增加版本号

通常我们设计 REST 接口时会要求在 API 上增加版本号,以方便在接口升级时保证一定的兼容性。我们假定设计的接口入下:

1
GET /api/v1/user/{userId}

在 Spring MVC 中可以这样这样实现:

1
2
3
4
5
@GetMapping(value = "/api/v1/user/{userId}")
public ResponseEntity<?> getUser(@PathVariable(value = "userId") String userId) {
return WebResponse.create(userService.getUser(userId))
.ok();
}

GetMapping 注解中手动指定了接口版本,但每个接口都指定或指定在类上也是非常不方便的,我们希望有一个注解来简化的约束这个配置的过程

阅读更多