下载APP
登录
关闭
讲堂
算法训练营
Python 进阶训练营
企业服务
极客商城
客户端下载
兑换中心
渠道合作
推荐作者

高并发系统设计期中测试题目解析

2019-11-08 唐扬
1. 关于池化技术,以下说法错误的是:
A. 使用线程池应该关注队列中,数据的堆积情况
B. 线程池中应该使用无界队列尽量降低任务丢弃的概率
C. 对于任何类型的系统,我们都可以使用原生的 Java 线程池,来提升任务执行的并发度
D. 可以定时地校验数据库连接池中的连接可用情况
答案: BC
解析: Java 线程池中,会使用队列来暂存任务,如果任务被长时间堆积,会造成任务消费延迟的问题,所以 A 是正确的。数据库的连接可能会被数据库服务端关闭,所以可以配置连接池定期地轮询检测数据库连接池的状态,避免使用失效的连接,造成请求失败的情况,所以 D 也是正确的;在使用线程池时,我们尽量不用要使用无界队列,因为一旦任务执行缓慢,就会造成任务大量堆积,占据大量内存资源,也会造成频繁 Full GC,影响系统可用性,所以 B 是错误的;原生的 Java 线程池适用于处理 CPU 密集型的任务,而我们的系统中的任务,大部分是 I/O 密集型的,所以最好对 Java 原生的线程池做一些改造来使用,所以 C 也是错误的。
2. 以下那种场景不适合使用缓存?
A. 社区系统中查询用户信息
B. 电商系统中查询商品信息
C. 社区系统中搜索社区内容信息
D. 网站中查看图片和视频信息
答案: C
解析:缓存比较适合读多写少的业务场景,并且数据最好带有一定的热点属性。因为缓存了热点的数据,才能保证一定的缓存命中率。而在搜索内容的场景下,每个人搜索的关键词各有不同,所以,如果以关键词为缓存的 Key,缓存的命中率不会很高,所以 C 是不适合使用缓存的。
3. 以下哪种场景可能造成读出数据的错误?
A. 数据写入主库,读取从库
B. 新数据在写入数据库的同时也写入缓存,读取时,优先从缓存读取数据
C. 更新数据库中的数据之后,也更新缓存中的数据
D. 更新数据库中的数据之后,让缓存中的数据过期
答案: AC
解析:主从之间存在延迟,所以写入主库后立刻读取从库,可能会造成读取到已经过期的数据。而如果在写入新的数据的同时,也写入到缓存,那么就可以避免主从延迟的影响。另外,更新数据库的同时更新缓存,会存在并发的问题,造成数据库和缓存中的数据不一致,而如果在更新数据库的同时,删除缓存中的数据,或者让缓存中的数据过期,就会避免这种情况发生。
4. 以下关于一致性 Hash 算法的说法,错误的是:
A. 一致性 Hash 算法可以避免缓存穿透的发生
B. 一致性 Hash 算法可以减少缓存节点数量变化,导致的数据访问抖动
C. 在缓存节点发生故障时,可以通过增加虚拟节点的方式,将请求尽量平均分配到其它节点上
D. 一致性 Hash 算法可能会产生脏数据
答案: A
解析:一致性 Hash 算法并不能够避免缓存穿透的发生,这是一个常见的误区。即使使用了一致性 Hash 算法,当节点故障时,原本应该被这个节点承担的请求,虽然会被分配到其它节点,但由于其它节点上并没有缓存数据,所以还是会穿透到数据库中查询。一致性 Hash 算法解决的核心问题是,尽量减少增加和删除节点对于读取缓存数据的影响。
5. 以下哪些场景不适合于使用 NoSQL 数据库:
A. 在一个社区系统中搜索社区中的用户
B. 支付之类的强事务场景
C. 存储电商用户的未读消息数量
D. 存储电商系统中的商品信息
答案: B
解析: NoSQL 数据库一般不支持事务,并且对于一些复杂的 SQL 查询支持程度不高。它的优势是提供更好的读写性能,提升扩展性,以及弥补传统数据库不适合的场景,比如选项 A 中的搜索。选项 D 中提到的商品信息,一般来说,会有非常多的字段,并且不同商品的字段有可能不同,所以适合使用 MongoDB 之类的 NoSQL 来存储。
6. 关于分表策略的选择,以下哪一种是不正确的?
A. 在通过创建时间,查询用户内容列表的场景下,按照创建时间做区间拆分存储列表数据
B. 查询一个人内容列表场景下,用户内容列表数据,按照用户 ID 做 Hash 拆分存储,内容实体数据,按照内容 ID 做 Hash 拆分存储
C. 查询一条内容下的图片信息,按照图片的 ID 做 Hash 拆分存储图片信息
D. 按照昵称查询用户,按照昵称 Hash 拆分存储昵称, 和 ID 之间的关系,再按照用户 ID 做 Hash 拆分存储用户信息
答案: C
解析: 分库分表的拆分应该按照常用查询语句,来决定分区键是什么。选项 C 中的场景是查询图片信息时需要按照内容 ID 来查询,所以拆分的时候也应该按照内容 ID 做 Hash 拆分,这样每次查询图片信息的时候,都需要带上内容 ID 了。
7. 下面解决缓存穿透的方法,哪一种说法是不对的?
A. 大量地请求不存在的用户信息,在这种场景下,可以使用回种空值的方式来解决
B. 使用布隆过滤器时,可以使用多个 Hash 函数,来减少 Hash 冲突的几率
C. 可以通过增加分布式锁的方式,减少缓存穿透造成的,大量请求到数据库的情况
D. 缓存穿透的问题也要结合缓存的原理来分析,比如 Memcached 的 Slab Class 满了,Memcached 会剔除数据,也会造成缓存的穿透
答案: A
解析:回种空值的方式需要占用一定的存储空间,所以采用这种方式时,需要考虑存储的成本,如果是大量的不存在用户的请求,那么推荐使用布隆过滤器的方式,来减少内存空间的占用。
8. 下面关于消息丢失的说法,哪种是错误的?
A. 可以通过配置服务集群的方式,来解决消息丢失的问题
B. 可以在接收到消息后,自动更新消费进度,然后再执行消费处理逻辑
C. 可以配置同步刷盘的方式,减少消息丢失的可能
D. 可以重复发送消息,来减少消息丢失的可能
答案: BC
解析:如果自动更新了消费进度,那么如果在消息处理时,出现了异常,这条消息就会丢失了,所以 B 选项是错误;C 选项中提到的同步刷盘,会极大地影响消息队列写入的性能,所以不建议开启。
9. 关于降低消息延迟的方式,哪种说法是错误的?
A. 你可以增加消费者的数量,来提升存储在 Kafka 中的消息的消费性能
B. 你可以在消费端启动多个线程,来提升消息的消费性能
C. 在存储上使用 Page Cache 异步刷盘,提升写入的性能
D. 使用零拷贝技术,减少数据拷贝的次数,提升消息队列的性能
答案: A
解析: Kafka 中,一个 Partition 中的数据,只能被一个消费者所消费,所以增加消费者的数量而不增加 Partition 的数量是不能够提升消费的并行度的,也就不能提升消费的性能。
10. 下面提升系统性能的说法,哪一种是错误的?
A. 数据库分库分表可以减少单表的数据量,能有效地提升数据的查询性能
B. 可以使用本地缓存来提升热点数据的读取性能,本地缓存越大,容纳的热点数据越多,所以应该尽量增加本地缓存的大小
C. CDN 可以让用户就近访问静态资源,避免跨地域的获取资源,对性能的提升比较明显
D. 数据在缓存中要分片存储,分片越多,并行度越高,性能越好
答案: BD
解析: 选项 B 中提到的本地缓存,确实可以提升极热点的读取性能,但是如果存储过多的数据到本地缓存中,会带来比较大的管理成本。同时,如果使用 JVM 来管理本地缓存,还会因为占用了过多的内存,造成垃圾回收暂停时间变长,可能对性能有负面影响,所以不建议本地缓存中放置过多数据。
选项 D 中,当缓存被分配到大量的节点上时,根据木桶原则,数据的读取性能取决于最慢、最坏的节点的情况,节点数过多,也会增加出问题的概率,所以一般一组缓存的节点数以 4 到 6 个节点为最佳。
 写留言

精选留言(8)

  • 第八题,问的不清楚,只是问数据不丢失,同步刷盘确实可以,除非加上性能不能太差,
    那个回种空值也能处理,只是会占用很多空间,前提是内存比较紧张
    2
    6
  • 2019-11-08
    第九题问的感觉有点牵强,a选项中的确是增加消费者是可以达到目的,但也没说讲清楚是在kafka里面呀,b选项的确可以达到目的,但突然宕机可能会带来消息丢失的问题
    1
  • 2019-11-08
    第一遍答题的时候感觉有的是多选,都按单选做了。第7题答错说明缓存穿透这节课还得再来几遍,第9题答错最可惜,老想着题里提到增加的线程又不一定是消费者线程,实际应该说的是增加处理线程,另外把分区一对一消费这回事忘了😢
    1
  • 第三题中两个答案似乎有矛盾之处,主从库更新主库后写入缓存解决从库可能没有很快同步到更新的问题,另外又在更新时让缓存过期,解决更新时缓存与数据库不一致的问题。如何同时解决呢?
  • 2019-11-08
    对了一半,不及格哈哈哈
  • 2019-11-08
    第3题,解析都提到了双写有并发问题,为什么答案没B?
    第10题,题面都说“一种”了...
    感觉题目描述过于简略了,十分容易歧义。

    作者的头像很萌啊...
  • 2019-11-08
    第二题的 D 我感觉很牵强呐,正常视频走 CDN 或者静态存储,直接使用缓存不合理吧
    1
  • 2019-11-08
    4/10 ....