牛客社区项目
# 分页功能
- 控制页的边界值
- limit(offset,limit)
- 这种方式在数据量非常大的时候,是非常低效的,因为它这个分页逻辑是先查出offset+limit条记录,然后抛弃前offset数据,取剩下的limit的数据,显然当数据量非常大的时候是非常低效的。
- 优化措施是 使用基于游标的分页方法,就是每次分页的时候需要接受一个查询的id主键,直接从该记录开始查找limit条数据。
# 登陆注册功能
- 比较重要的一个是激活邮件
- 通过模板引擎补充激活邮件
- 通过JavaMailSender发送激活邮件
- 点击激活链接,给出激活信息,如果成功的话,跳转到登录页面
# 分布式session
- 粘性session,但是粘性session,会使服务器负载不是那么均衡
- 同步session,服务器做同步,服务器性能受影响,产生耦合,不太好
- 共享session,如果是共享的东西,把它放到共享session服务器中,单体存放
- 不敏感数据就放到Cookie里,敏感数据存放到Redis中,服务器统一从服务器获取
# 登陆、退出功能
- login_ticket表里面,有一个字段ticket来存放登陆凭证
- 设置一个过期时间,在过期时间内,这个登陆凭证都是有效的
- 退出的时候,直接将登陆状态值置为失效
# 显示登录信息
- 定义拦截器,实现HandlerInterceptor接口,preHandle在Controller之前执行,postHandle在Controller之后执行,模板引擎之后执行afterCompletion
- 需要一个配置类拦截资源,拦截路径
- 在请求开始的时候,查询用户信息,赋予不同用户不同的权限,在本次线程中存放用户信息,考虑到线程安全,使用线程隔离的类ThreadLocal来存用户数据
# 检查登陆状态
- 自定义注解,起标记作用
# 过滤敏感词
- 前缀树
- 数据结构:Trie、字典树、查找树
- 特点:以空间换时间,查找效率高
- 应用场景:字符串检索、字符串统计
- 敏感词过滤器
- 定义前缀树
- 根据敏感词,初始化前缀树insert()方法
- 编写过滤敏感词方法query()方法
# 统一处理异常
- 使用Spring MVC提供的注解 @ControllerAdvice,加在异常处理类
- 异常处理逻辑的方法上加 @ExceptionHandler(value = Exception.class)处理对应异常的逻辑
# 统一记录日志
- 记录日志与业务逻辑耦合在一块了,不便于业务的修改、拓展以及后期维护
- AspectJ,Spring AOP
- JDK 动态代理,在运行时创建接口的实例,来实现代理;CGLib动态代理,运行时创建子类的方式,来实现先目标类的代理。
# 点赞
- 点赞逻辑,统计点赞数量,显示点赞状态
- 使用Redis的集合,保证线程安全
- increment(key),decrement(key),赞的加减
- 帖子、评论点赞,还有就是某人总共的赞
# 关注
- 使用有序集合来存(key为id,值为时间)
# 使用Redis优化登陆模块
- 使用Redis存储验证码
- 验证码需要频繁访问与刷新,对性能要求高,而且也不需要长时间保存,短时间后就会失效
- 验证码之前放在Session中,存在共享问题,放到Redis中可以避免这个问题
- 使用Redis存储登陆凭证和缓存用户信息
- 需要频繁查询用户状态,登陆凭证和用户信息,访问频率都会非常高,缓存到Redis中
- 用户信息
- 优化将用户信息先存到Redis中
- Redis取不到对应的信息,访问数据库初始化key
- 数据变更,删掉Redis中的key记录
# 发送和显示系统消息
- 使用Kafka作为消息队列
- 生产者向Topic里发送消息,消费者监听这个Topic,长轮询的方式消费Topic里的消息
- 评论,点赞,关注后发送系统通知
- 事件驱动模型
# 社区搜索功能
- ES,目前性能最好,应用最广的搜索引擎
- 将帖子内容保存到ES服务器,从ES服务器搜索帖子
- 发布事件:发布帖子,将贴子异步传到ES服务器;增加评论,将评论异步传到ES服务器
# Spring Security
- 解决安全问题,对身份的认证授权提供全面的、可扩展的支持
- 对哪些角色赋予访问哪些访问地址的权限
# Redis高级数据类型
- HyperLogLog
- 采用基数算法,用于完成独立总数的统计
- 占据空间小,无论统计多少个数据,只占12K的内存空间
- Bitmap
- 字符串,按位存取数据,可以看成byte数组
- 适合存储大量连续的布尔值数据
- 员工365天签到值之类的
# 网站数据统计
- UV(Unique Visitor)
- 独立访客,需要通过用户IP进行数据统计
- HyperLogLog,性能好,存储空间小
- DAU(Daily Active User)
- 日活跃用户,需要根据用户ID进行数据统计
- Bitmap,性能好,可以精确的统计结果
# 任务执行和调度
- JDK线程池
- ExecutorService
- ScheduledExecutorService
- Spring线程池
- ThreadPoolTaskExecutor
- ThreadPoolTaskScheduler
- 定时任务
- Spring Quartz
- 程序运行参数存在数据库里
- Schedule,job,Trigger
# 热帖排行
- 帖子评分,log(精华分 + 收藏数 * 10 + 点赞数 *2 + 评论数 * 2) + (发布时间 - 初始时间)
# 优化网站性能
- 使用Caffeine进行本地缓存
- 分布式缓存:将数据缓存到NoSQL数据库上,例如:Redis
- 多级缓存:本地缓存 -> 分布式缓存 -> DB
# 单元测试
- 保证测试方法的独立性
- 步骤:初始化数据、执行测试代码,验证测试结果,清理测试数据
- @BeforeClass,@AfterClass,@Before,@After