西维蜀黍

【Java】集合类 - List - LinkedHashMap

LinkedHashMap

HashMap是无序的,也就是说,迭代HashMap所得到的元素顺序并不是它们最初放置到HashMap的顺序。HashMap的这一缺点往往会造成诸多不便,因为在有些场景中,我们的确需要用到一个可以保持插入顺序的Map。

庆幸的是,JDK为我们解决了这个问题,它为HashMap提供了一个子类 —— LinkedHashMap。

由于LinkedHashMap是HashMap的子类,所以LinkedHashMap自然会拥有HashMap的所有特性。比如,LinkedHashMap的元素存取过程基本与HashMap基本类似,只是在细节实现上稍有不同。当然,这是由LinkedHashMap本身的特性所决定的,因为它额外维护了一个双向链表用于保持迭代顺序。

虽然LinkedHashMap增加了时间和空间上的开销,但是它通过维护一个额外的双向链表保证了迭代顺序。

特别地,该迭代顺序可以是插入顺序,也可以是访问顺序。因此,根据链表中元素的顺序可以将LinkedHashMap分为:保持插入顺序的LinkedHashMap 和 保持访问顺序的LinkedHashMap,其中LinkedHashMap的默认实现是按插入顺序排序的。

总结来说,HashMap和双向链表合二为一即是LinkedHashMap。所谓LinkedHashMap,其落脚点在HashMap,因此更准确地说,它是一个将所有Entry节点链入一个双向链表的HashMap

  ...


【Cache System】Cache Replacement - LFU(Least Frequently Used)算法

LFU(Least Frequently Used)

LFU (Least Frequently Used) 最近最不常用算法,它是根据频率维度来选择将要淘汰的元素,即删除访问频率最低的元素。如果两个元素的访问频率相同,则淘汰最久没被访问的元素。

也就是说LFU淘汰的时候会选择两个维度,先比较频率,选择访问频率最小的元素;如果频率相同,则按时间维度淘汰掉最久远的那个元素。

  ...


【Cache System】Cache Replacement - LRU(Least Recently Used)算法

LRU

LRU(Least Recently Used),近期最少使用算法, 常应用于缓存中的数据淘汰, 其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高“。

  ...


【Network】HTTP 常用状态码(Status Code)

2XX - 成功

请求正常处理完毕

  • 200 OK: 从客户端发送的请求在服务端被正常处理了。
  • 201 CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功。
  • 204 No Content: 服务器接受的请求已成功处理,但返回的响应报文的主体部分不包含实体(浏览器页面不更新,仅发送信息给服务器)
  • 206 Partial Content: 客户端进行了范围请求,而服务器成功执行了这部分请求

3XX - 重定向

浏览器需要执行某些特殊的处理以正确处理请求。

  • 301 Moved Permanently 永久性重定向,请求的资源已经分配了新的URI,以后应该使用资源现在所指的URI

  • 302 Found 临时性重定向,请求的资源临时分配了新的URI,希望用户本次可以使用新的URI访问(比如,未登陆时,302 重定向到登录页面)

  • 304 Not Modified 服务器端资源未改变,可直接使用客户端未过期的缓存,不包含任何响应的主体部分

4XX - 客户端错误

客户端是发生错误的原因所在。

  • 400 Bad Request 请求报文中存在语法错误
  • 401 Unauthorized 请求需要有通过HTTP认证的认证信息。另外如果之前已进行一次请求,则表示用户认证失败
  • 403 Forbidden 对请求资源的访问被服务器拒绝了,如未获得文件系统的访问授权,访问权限出现某些问题
  • 404 Not Found 服务器上没有请求的资源
  • 499 client has closed connection 服务器端处理的时间过长,客户端主动断开链接,ngix定义的状态码

5XX - 服务器错误

服务器是发生错误的原因所在。

  • 500 Internal Server Error 服务器在执行请求时发生了错误,Bug或临时故障
  • 503 Service Unavailable 服务器暂时处于超负荷或正在进行停机维护,现在无法处理请求
  ...


【Database】分库分表(DB sharding)

What Is Database Sharding?

Sharding is a method for distributing a single dataset across multiple databases, which can then be stored on multiple machines. This allows for larger datasets to be split in smaller chunks and stored in multiple data nodes, increasing the total storage capacity of the system.

Sharding is known as partitioning, and each smaller subsets called prtitions

Similarly, by distributing the data across multiple machines, a sharded database can handle more requests than a single machine can.

Sharding is a form of scaling known as horizontal scaling or scale-out, as additional nodes are brought on to share the load. Horizontal scaling allows for near-limitless scalability to handle big data and intense workloads. In contrast, vertical scaling refers to increasing the power of a single machine or single server through a more powerful CPU, increased RAM, or increased storage capacity.

什么时候会考虑分库分表

单库/表太大

  • 单个数据库的能力已经达到瓶颈或者存在潜在瓶颈,比如
    • Table row count > 10,000,000.
    • Table size > 10GB.
    • Performance bottleneck (e.g. Querying Response Time < 99%, i.e., more than 1% queries take more than 10ms).
    • 单库太大,以至于所在服务器上磁盘空间不足
    • 单库上操作出现了I/O瓶颈

解决方法:切分成更多更小的库或者表

水平分库分表(Horizontal Partitioning)

水平分库

当数据库中单表的数据量很大时,采用水平分区的方式对数据进行拆分(将同一个表中不同的数据拆分到不同数据库或同一个数据库的不同表中)。比如,以对某个主键进行hash取模的方式(以保证对N个数据库的访问负载是均衡的),将数据分布表到N个数据库或表中。

值得一提的是,进行分库分表后,进行对跨库的表join、事务操作或者数据统计、排序时,又出现了新的性能问题。

使用原因

大部分互联网业务数据量很大,单库容量容易成为瓶颈,如果希望:

  • 线性降低单库数据容量
  • 线性提升数据库写性能

此时可以使用水平切分架构。

一句话总结,水平切分主要解决“数据库数据量大”问题,在数据库容量扛不住的时候,通常水平分库。

水平分表

水平分表也称为横向分表,比较容易理解,就是将表中不同的数据行按照一定规律分布到不同的表中(这些表保存在同一个数据库中),这样来降低单表数据量。最常见的方式就是通过主键或者时间等字段进行 Hash 和取模后拆分。

  ...