京东面试
1、redis的数据结构分别有什么,各数据结构的底层原理如何实现(zset与set的区别,zset的底层实现。zset如何实现分页功能?(例子:ZRANGEBYSCORE zset01(key) 60 90 limit 2 2))
string:字符串
在redis中,其自己定义了一种字符串格式,叫做SDS(Simple Dynamic String),即简单动态字符串
list:列表
ziplist并不是一个类名,其结构是下面这样的:
ziplist类似一个封装的数组,通过zltail可以方便地进行追加和删除尾部数据、使用entries可以方便地计算长度,,但是其依然有数组的缺点,就是当插入和删除数据时会频繁地引起数据移动,
quicklist:quicklist是一个双向链表的结构,但是内部又涉及了ziplist,我们可以这么说,在宏观上,quicklist是一个双向链表,在微观上,每一个quicklist的节点都是一个ziplist
在redis.conf中,可以使用下面两个参数来进行优化:
- list-max-ziplist-size:表示每个quicklistNode的字节大小。默认为2,表示8KB
- list-compress-depth:表示quicklistNode节点是否要压缩。默认为0,表示不压缩
这种存储方式的优点和链表的优点一致,就是插入和删除的效率很高,而链表查询的效率又由ziplist来进行弥补,所以quicklist就成为了list数据结构的首选
hash:散列表
zipmap: 其中相邻的两个字符串就分别是键和值, 就是查找的时间复杂度为O(n),所以只能当作一个轻量级的hashmap来使用
Dict:
如果我们不想更深入的话了解到这种程度就可以了,其中真正存储数据的是dictEntry结构,很明显是一个链表,我们知道这是采用链式结构存储就足够了
这种方式会消耗较多的内存,所以一般数据较少时会采用轻量级的zipmap
set:无序集合
intset有一个数据升级的概念,比方说我们有一个16位整数的set,这时候插入了一个32位整数,所以就导致整个集合都升级为32位整数,但是反过来却不行,这也就是柔性数组的由来
如果集合过大,会采用dict的方式来进行存储
zset:有序集合
sorted set,是一个键值对的结构,其键被称为member,也就是集合元素(zset依然是set,所以member不能相同),其对应的值被称为score,是一个浮点数,可以理解为优先级,用于排列zset的顺序
其也有两种存储方式,一种是ziplist/zipmap的格式,这种方式我们就不过多介绍了,只需要了解这种格式将数据按照score的顺序排列即可
另一种存储格式是采用了skiplist,意为跳跃表,可以看成平衡树映射的数组,其查找的时间复杂度和平衡树基本没有差别,但是实现更为简单,形如下面这样的结构(图来源跳跃表的原理):
2、redis集群原理是什么?
其实就是分库分表,去中心化
1、集群是如何判断是否有某个节点挂掉
首先要说的是,每一个节点都存有这个集群所有主节点以及从节点的信息。它们之间通过互相的ping-pong判断是否节点可以连接上。如果有一半以上的节点去ping一个节点的时候没有回应,集群就认为这个节点宕机了,然后去连接它的备用节点。
2、集群进入fail状态的必要条件
A、某个主节点和所有从节点全部挂掉,我们集群就进入faill状态。
B、如果集群超过半数以上master挂掉,无论是否有slave,集群进入fail状态.
C、如果集群任意master挂掉,且当前master没有slave.集群进入fail状态
3.redis集群去中心化(所有Master节点并发处理读写)
集群中原则每个Master节点都有一个或多个Slave节点。集群中所有的Master节点都可以进行读写数据,不分主次,记redis集群式去中心化的。每个Master节点与Slave节点间通过Goossip协议内部通信,异步复制。不用我们瞎操心(所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽.),但是异步赋值会导致某些特定情况下的数据丢失,即,redis集群不能保证数据的强一致性
4.redis集群的分区规则:虚拟槽分区(槽:slot)
RedisCluster采用此分区,所有的键根据哈希函数(CRC16[key]&16383)映射到0-16383槽内,共16384个槽位,每个节点维护部分槽及槽所映射的键值数据
哈希函数: Hash()=CRC16[key]&16383 按位与
redis用虚拟槽分区原因:解耦数据与节点关系,节点自身维护槽映射关系,分布式存储
5. redisCluster的缺陷(虚拟槽分区的缺点)
a,键的批量操作支持有限,比如mset, mget,如果多个键映射在不同的槽,就不支持了
b,键事务支持有限,当多个key分布在不同节点时无法使用事务,同一节点是支持事务
c,键是数据分区的最小粒度,不能将一个很大的键值对映射到不同的节点
d,不支持多数据库,只有0,select 0
e,复制结构只支持单层结构,不支持树型结构。
6.客户端与redis集群交互方式
由于Cluster架构中无Proxy层,客户端是直接与集群中的任意可用节点直接交互的,【话是这么说,但是一个请求是怎么找到集群中的一个节点的呢,redis有多种策略,一般使用CRC16去hash(key)计算改请求要分配到具体的哪一个节点上。然后才是 客户端与节点的直接操作】对象保存到Redis之前先经过CRC16哈希到一个指定的Node上,
3、redis主从切换的投票机制原理。
4、redis一般Qps是多少?
5、redis过期时间如何设置为毫秒?(PEXPIRE命令 后面单位为毫秒 key milliseconds)
6、mysql tinyint(1)代表什么含义?
7、mysql tinyint取值范围是多少?
8、JVM为什么要调Xss,有什么作用,默认值是多少(1024k),(一般往小调),调整这个参数有什么作用?
9、JVM MetaSpace默认值是多少?
10、ConcurrentHashMap的底层原理。(CAS+Sychronized)
11、创建一个hashMap长度为1000,那么初始的长度应该设置为多少?(比如说,我们有1000个元素new HashMap(1000), 但是理论上来讲new HashMap(1024)更合适,不过上面已经说过,即使是1000,hashmap也自动会将其设置为1024。 但是new HashMap(1024)还不是更合适的,因为0.751000 < 1000, 也就是说为了让0.75 size > 1000, 我们必须这样new HashMap(2048)才最合适,既考虑了&的问题,也避免了resize的问题。)
12、Xms、Xmx为什么要调成一致?你一般设置成多少?
13、JDK 1.8默认的GC是什么?
14、GC日志看过吗?里面都有什么?
15、young区一般设置多少次GC后在进入old区?
16、cms、串行GC、并行GC、G1有什么区别?什么时候用cms?什么时候用G1?生产环境如何选择垃圾收集器?
17、mysql如何避免死锁?代码中如何写可以避免死锁?
18、mysql索引如何会失效?
19、什么时候要创建索引?什么时候不应该创建索引?
20、mysql你是如何优化的?
21、mysql优化主要看哪些参数?(explain)
22、Integer、Float值的比较可以用“==”吗?
不要用==,尽量使用equals方法。
23、索引除了BTREE外是否还用过其他索引?
索引是帮助mysql获取数据的数据结构。最常见的索引是Btree索引和Hash索引。
不同的引擎对于索引有不同的支持:Innodb和MyISAM默认的索引是Btree索引;而Mermory默认的索引是Hash索引。
我们在mysql中常用两种索引算法BTree和Hash,两种算法检索方式不一样,对查询的作用也不一样。
一、BTree
BTree索引是最常用的mysql数据库索引算法,因为它不仅可以被用在=,>,>=,
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?