进程状态
PS:挂起是指进程没有占用实际的物理内存空间的情况。
导致进程挂起的原因:
- 进程使用的内存空间不在物理内存
- 通过 sleep 让进程间歇性挂起
- 用户希望挂起一个程序的执行,比如 Linux 中使用
Ctrl+Z
挂起进程
HTTP/0.9 -> HTTP/1.0 -> HTTP/1.1 -> HTTP/2 -> HTTP/3
,一代更比一代强,一浪更比一浪强,前浪拍死在沙滩上!
跳表是一种有序数据结构,它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的。
Redis 中 Zset 对象的底层实现用到了跳表,跳表支持平均 O(logN)、最坏 O(N) 复杂度的节点查找,还可以通过顺序性操作来批量处理节点。
typedef struct zset { |
zset
结构体里有两个数据结构,一个是跳表,一个是哈希表。这样的好处是既能进行高效的范围查询,也能进行高效单点查询。zset 对象在执行数据插入或是数据更新的过程中,会依次在跳表和哈希表中插入或更新相应的数据,从而保证了跳表和哈希表中记录的信息一致。zset 对象能支持范围查询(如 ZRANGEBYSCORE
操作),这是因为它的数据结构设计采用了跳表,又能以常数复杂度获取元素权重(如 ZSCORE
操作),这是因为它同时采用了哈希表进行索引。
压缩列表是 Redis 为了节约内存而开发的,是由一系列特殊编码的连续内存块组成的顺序型数据结构。 一个压缩列表可以包含任意多个节点,每个节点可以保存一个字节数组或者一个整数值。
压缩列表的最大特点,就是它被设计成一种内存紧凑型的数据结构,占用一块连续的内存空间,不仅可以利用 CPU 缓存,而且会针对不同长度的数据,进行相应的编码,这种方法可以有效地节省内存开销。
相对的,压缩列表的缺陷也很明显:
因此 Redis 对象包含的元素数量较少,或者元素值不大的情况下才会使用压缩列表作为底层数据结构。
在 Java 中,线程池会使用固定数量或者可变数量的线程来执行任务,但无论是固定数量还是可变数量的线程,其线程数量都远远小于任务数量,面对这种情况线程池可以通过线程复用让同一个线程去执行不同的任务,那么线程复用原理是什么呢?