每天十道面试题-20200325

题目

  • 1、查询中哪些情况不会使用索引?
  • 2、MySQL数据库索引,底层是怎样实现的,为什么要用B+树索引?
  • 3、Mysql主从同步的实现原理?
  • 4、MySQL是怎么用B+树?
  • 5、谈谈数据库乐观锁与悲观锁?
  • 6、有使用过哪些NoSQL数据库?MongoDB和Redis适用哪些场景?
  • 7、描述分布式事务之TCC服务设计?
  • 8、Redis 的数据结构以及优势
  • 9、海量数据过滤,黑名单过滤一个 url
  • 10、讲一讲AtomicInteger,为什么要用CAS而不是synchronized?

解答

题目一
  • 题干:查询中哪些情况不会使用索引?
  • 分析:
  • 换个思路知道哪些情况下可以用到索引就可以了:
    全值匹配
    匹配左边的列
    匹配范围值
    精确匹配某一列并范围匹配另外一列
    用于排序
    用于分组
    此外:我们要知道MySQL底层索引采用B+树结构,做到了索引即数据,数据即索引,真正的用户记录都在最底层的叶子结点中,从根节点到非页子节点都是目录页,联合索引都是根据索引列的顺序依次排序的。

  • 回答:
  • 找出一些不符合适用情况的,诸如:没有匹配最左前缀like zhangsan%,对索引列使用函数等。

题目二
  • 题干:MySQL数据库索引,底层是怎样实现的,为什么要用B+树索引?
  • 分析:
  • 考察对于MySQL数据库的理解,首先MySQL底层的数据库索引的实现取决于底层所使用的存储引擎的类型,常见的有MyIsAM和InnoDB,使用最多的是InnoDB,所以我们一般都是讨论InnoDB底层索引的实现。InnoDB底层索引的实现是B+树。

  • 回答:
  • 底层使用B+树来实现,如果我们建表的时候不指定主键,那么MySQL会为我们分配row-id,这个就是默认的聚簇索引,每当我们建立一个B+树索引的时候,都会先建立一个根节点,如果表中一条数据都没有,那么这个根节点也不存储用户记录,当我们插入用户记录的时候,该根节点就先存储用户记录,如果用完了,再次插入用户记录时,那么就建立一个新页,然后将根节点中的所有用户记录移动到新页里,对于新页进行页分裂,然后根节点升级为目录页。

题目三
  • 题干:Mysql主从同步的实现原理?
  • 分析:
  • 对读写分离的考察,首先说一下为什么需要读写分离,因为单个MySQL数据库连接有上限,当连接请求过多的时候可能会导致数据库崩掉,我们可以通过加缓存使用Redis来缓存部分数据来缓解数据库压力,但是我们不能够将MySQL所有数据都进行缓存,如果当读写压力进一步增大的时候,越过缓存仍然会有很多请求发给MySQL数据库,根据28原则大部分时读请求,所以我们使用主从复制【读写分离】让主库进行写操作和少部分的读,从库进行读操作,原理就是需要将主库的binlog同步过来,有两种方式一种同步复制一种异步复制,同步复制需要等待主库确认从库收到消息才会提交,这个对于性能不是很友好,所以一般使用异步复制,然而异步复制就会存在延迟问题,a、连续多次对同一数据进行变更。第一次变更后的数据还未同步到从库,第二次变更紧接着就进行。这样会导致,第二次变更的内容有可能是错误的。b、数据变更后,页面进行列表展示,有可能展示到变更前的数据。c、内部系统调用,内部实时统计有可能读取到旧数据。解决办法使用缓存将对主库更新的数据在缓存中保留一段时间,先都缓存等待从库同步后在走库,然后对于主从同步的参数进行一些优化配置。

  • 回答:
  • 步骤一:主库db的更新事件(update、insert、delete)被写到binlog
    步骤二:从库发起连接,连接到主库
    步骤三:此时主库创建一个binlog dump thread线程,把binlog的内容发送到从库
    步骤四:从库启动之后,创建一个I/O线程,读取主库传过来的binlog内容并写入到relay log.
    步骤五:还会创建一个SQL线程,从relay log里面读取内容,从Exec_Master_Log_Pos位置开始执行读取到的更新事件,将更新内容写入到slave的db.

题目四
  • 题干:MySQL是怎么用B+树?
  • 分析:
  • B+树索引适用条件。

  • 回答:
  • 全值匹配
    匹配左边的列
    匹配范围值
    精确匹配某一列并范围匹配另外一列
    用于排序
    用于分组。

题目五
  • 题干:谈谈数据库乐观锁与悲观锁?
  • 分析:
  • 考察乐观锁和悲观锁

  • 回答:
  • 乐观锁,顾名思义就是对数据的修改持有乐观态度,直到修改的时候在去检查数据是否被修改,一般通过version版本号或者时间戳的方式来实现。
    悲观锁,就是对数据的修改持有悲观态度,认为数据一定会被修改,所以直接加锁来排序修改,MySQL中实现就是for update。

题目六
  • 题干:有使用过哪些NoSQL数据库?MongoDB和Redis适用哪些场景?
  • 分析:
  • 自行解决

  • 回答:
  • redis支持更多数据结构,支持数据持久化。MongoDB可以支持一些复杂的查询,如果是点赞或者热评收藏之类可以适用redis,如果需要查询评论内容等等其他的,可以适用MongoDB

题目七
  • 题干:描述分布式事务之TCC服务设计?
  • 分析:
  • https://www.cnblogs.com/jajian/p/10014145.html

  • 回答:
  • https://www.cnblogs.com/jajian/p/10014145.html

题目八
  • 题干:Redis 的数据结构以及优势
  • 分析:
  • Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。

  • 回答:
  • Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。
    1、redis最典型的应用场景,当做缓存使用,服务在处理请求时先从redis里获取结果,获取到了就可以直接返回,没有获取到的话再从数据库里获取,然后存到redis里以供下次使用。用redis的好处是可以做到分布式,有状态的数据都存在redis里,使业务服务层无状态,以便业务层有很高的可扩展性
    2、Redis也以消息队列的形式存在,作为内嵌的List存在,满足实时的高并发需求。而通常在一个电商类型的数据处理过程之中,有关商品,热销,推荐排序的队列,通常存放在Redis之中,期间也包扩Storm对于Redis列表的读取和更新。
    3、Redis 分布式锁。

题目九
  • 题干:海量数据过滤,黑名单过滤一个 url。
  • 分析:
  • https://www.jianshu.com/p/2104d11ee0a2

  • 回答:
  • 使用布隆过滤器进行过滤。

题目十
  • 题干:讲一讲AtomicInteger,为什么要用CAS而不是synchronized?
  • 分析:
  • 考察原子类,以及原子类底层实现。首先synchronized是一个悲观的、不公平的、重量级锁【指会调用操作系统的接口来达到线程安全,保证原子性和可见性】,但是因为重量级性能有一定劣势,我们可以减少使用重量级锁,通过偏向锁升级为轻量级锁在升级为重量级锁,单向升级不可逆。原子类底层主要是使用Unsafe类和CAS底层使用volatile 修饰 value 保证可见性,然后使用CAS保证原子性最终能够做到了线程安全,但是在高并发场景下,同时更新一个原子变量的多个线程,最终只有一个线程的CAS操作会成功,这样就有有很多线程的CAS操作失败,大量的自旋操作,浪费了CPU的资源。所以后来又引入了LongAddr类。

  • 回答:
  • 原子类需要保证内存可见性和原子性,底层对于value属性使用了volatile关键字修饰,保证了可见性,然后使用Unsafe中提供的CAS操作来避免使用synchronized关键字,从而保证原子性。提升了性能。

发布了122 篇原创文章 · 获赞 32 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/YangzaiLeHeHe/article/details/105079251