您当前的位置: 首页 >  面试

少林码僧

暂无认证

  • 1浏览

    0关注

    317博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

新鲜出炉的京东面试题

少林码僧 发布时间:2019-12-20 09:20:54 ,浏览量:1

京东面试

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数据库索引算法,因为它不仅可以被用在=,>,>=,

关注
打赏
1661398670
查看更多评论
立即登录/注册

微信扫码登录

0.0387s