每天面试题:2024-01-17
每天面试题:2024-01-17
Q1: `ArrayList` 和 `LinkedList` 的区别
1: 数据结构不同
`ArrayList` 内部使用的是数组,通过索引来访问数据,可以随机快速访问元素 `LinkedList` 内部是双向链表,适合插入和删除操作
2:数据的访问时间复杂度不同
ArrayList
的查询复杂度是 O(1),`LiknedList`的查询时间复杂度是O(n)3: 占用的空间大小不同
ArrayList
使用的数组存储速度,是内存中的一块连续的区域,可能会产生内存碎片。`LinkedList`使用的双向链表,它的每个元素都会包含一个它的前后节点的引用,所以`LinkedList`占用的内存空间比较大
Q2: 为什么`Redis`集群的最大哈希槽是16384个
1: 对于网络通信开销的平衡
16384 个插槽,每个插槽的信息占一位,那么每每个集群节点需要维护的配置信息就是: 16834/集群数量/8
假设我们的 Redis 集群数量是3,那么我们每个集群节点维护的配置信息就是 2KB ,其次
CRC16
算法 计算的HASH
是15位,假设我们是 2^16 计算得到 65535个哈希槽,也就是每个节点需要维护的配置信息就是8 `KB`,因为 Redis 集群需要保持心跳来同步每个集群节点的配置信息,这样就带来了很大网络的开销,是 16384 的 4倍,而且这个浪费没有带来很好的效果2:`Redis Cluster` 集群规模的限制
Redis 集群的节点数量一般不会超过 1000个,过于的庞大的集群数量可能会照成网络拥堵,这样得不偿失
3: 16284 个哈希槽可以保证每个
Master
节点都有足够多的插槽,同时插槽的数量也不会过多或者过少,从而保证了Redis Cluster 集群的稳定性和性能
Q3:`Redis` 是否存在线程安全问题
首先 Redis Server在执行指令的时候单线程执行的,不存在线程安全。虽然在 Redis 6.0 之后,Redis 引入了 多线程,但是 Redis 执行的执行仍然是单线程执行,6.0 引入的多线程只是用来处理网络IO事件。
Redis Server 的瓶颈点有网络IO和内存,CPU并不是 Redis Server 的瓶颈点,所以不需要通过 多线程来提高CPU的利用率。
虽然 Redis Server 是线程安全的,但是如果我们 存在 多个 Redis Client 的,则它们之前可能会存在线程安全,如果需要我们可以使用诸如 Lua 脚本来保证多质量操作的原子性,或者对多线程访问进行加锁,并且我们在 使用 Redis Client 中,我们尽可能使用 原子指令来操作Redis