1. 项目回顾

08-项目复习 - 图1

  1. Spring MVC 解决了前后端请求和交互的问题,Spring MyBatis 访问数据库,Spring Security 用于管理系统安全层面的内容,这三个项目构建在 Spring 之上,由 Spring 进行整合。
  2. 需要长期连续的交互,就必须要有会话管理,复习的时候看看 Cookie、Session 各自能发挥什么样的作用,区别是什么。后期用 Redis 取代了 session,是因为考虑到了分布式部署的问题。
  3. 使用 Advice 控制器通知统一处理了异常,使用 Spring AOP 实现了记录业务层日志的功能,使用 Trie 树实现了敏感词的过滤,使用 Spring 对事务进行管理。
  4. 使用 Redis 实现点赞、关注,以及统计网站的UV、DAU,同时部分模块用 Redis 做了缓存。需要关注 Redis 的数据结构。
  5. 使用 Kafka 实现了系统通知,Kafka 框架使用比较简单,要明白后面的原理,如生产者消费者模式。
  6. 使用 Elasticsearch 实现了搜索功能,Elasticsearch 的使用也比较简单。在复习的时候要关注它的数据结构,Elasticsearch 在存数据的时候是以索引来存的,重点要关注索引的结构。
  7. 使用 Caffeine 做本地缓存,进一步提高了网站的性能,由于是本地缓存,因此在分布式部署时有一定的局限性,所以需要 Redis 配合。

    2. 整个项目在真实的环境下到底是怎么部署的

    image.png
    数据库服务器一般两台即可,用于读写分离。如果数据库也用多台服务器部署,那么就需要处理分布式事务,这是非常麻烦的,在实现了二级缓存的情况下,访问数据库的几率已经大大减少,因此两台数据库一般就够用了。

    3. 项目的难点痛点是什么?你们怎么解决的?

  • 难点: 敏感词的过滤
  • 为什么要使用 Trie 树? 过滤敏感词可以直接使用API替换字符串,但是这样效率很低,因此采用前缀树(Trie树)过滤敏感词。Trie 树的查找效率高,但是消耗内存大,应用于字符串检索、词频统计、字符串排序等。
  • Trie 树的数据结构? Trie 树可以使用 HashMap 实现,因为一个节点的子节点个数未知,而 HashMap 可以动态扩展,而且可以在 O(1) 的时间复杂度内判断某个子节点是否存在。首先定义 Trie 树的节点,节点的结构为 HashMap,key 为字符串中的字符,value 为这个节点的子节点。在实现敏感词过滤前,首先需要初始化 Trie 树,将所有敏感词插入到 Trie 树中。
  • 具体怎么初始化 Trie 树的呢? 将每个词语的每个字符一个个地添加到 Trie 树中,树中的每个节点代表一个字。
  • 怎么实现敏感词过滤呢? 将待过滤文本与 Trie 树中的节点一个个地进行比较。使用三个指针,其中一个指针指向 Trie 树,另外两个指针指向待过滤文本的起始位置和结束位置。首先 p1 指针指向 root,指针 p2 和 p3 指向字符串中的第一个字符。算法从字符 a 开始,检测有没有以 a 作为前缀的敏感词,在这里就直接判断 root 中有没有 a 这个子节点即可。没有的话将 p2 和 p3 同时右移,而如果存在以 a 作为前缀的敏感词,那么就只右移 p3 继续判断 p2 和 p3 之间的这个字符串是否是敏感词。如果在字符串中找到敏感词,那么可以用其他字符串如 * 代替。接下来不断循环直到整个字符串遍历完成就可以了。
  • https://www.jianshu.com/p/9919244dd7ad

    4. 介绍一下 Caffeine

    Caffeine 是目前很优秀的一种本地缓存,本地缓存是直接从本地内存中读取,相比于 Redis 这种分布式缓存,本地缓存是直接从内存中读取,没有网络开销。在数据量小的场景下,本地缓存比远程缓存更合适。

Caffeine 是基于 JAVA 8 的高性能缓存库。并且在 spring5 (springboot 2.x) 后,spring 官方放弃了 Guava,而使用了性能更优秀的 Caffeine 作为默认缓存组件。(使用 CAS 来保证线程安全)

5. 项目中遇到过什么印象比较深的Bug?

Elasticsearch 和 Redis 底层用的都是 netty 的服务,会冲突,需要手动配置。

6. 你是根据哪些指标进行针对性优化的?

qps(query per second),使用本地缓存 Caffeine 进行优化。

7. 如果让你对这个项目再进行优化, 可以优化哪一部分?

可以讲讲二级缓存,及将热门帖子列表的一级缓存是 Caffeine,二级缓存是分布式的 Redis,最后才是数据库。