#牛客问答项目总结

项目地址:https://github.com/lioncattt/wenda

  1. 登录和注册
    1.1 登录功能:
    (1) 校验密码时取出该用户对应的密码和盐进行md5加密后与数据库的密码(密文)进行校对。讲讲md5:md5算法是一种不可逆的算法,使用的是hash算法,只有加密过程没有解密过程,但因为存在彩虹表(黑客将常用的密码通过md5加密后存储到表中,将用户密码进行暴力破解),因此需要加盐,即给每一个用户密码后面添加一个随机的字符串再进行加密。
    (2) 校验密码成功后,向该用户发放一个token(一个userId对应一个随机的UUID,还有有效时间),这个token是一个随机的字符串,将其保存到cookie中。当浏览器再次发送请求时,就可以校验浏览器的cookie中的token是否和数据库中的一致。优化: 前期将token存放到mysql中,后期将其放到reidis,大大提高查询效率。为什么要使用token:token是一个标识用户身份的令牌,可以避免每次登录都要到数据库中校验对应的密码,减少频繁查询数据库。
    1.2 注册功能:
    (1)给用户的密码加盐后通过md5加密将密码已密文的形式存到数据库。
    (2) 给注册成功的用户发放token
    (3) 实现了通过调用阿里云短信通道接口发送手机验证码的功能。前期将验证码存到session中,后期优化将验证码存到redis中并设置有效期
    1.3 拦截器
    (1) 登录拦截器: 根据请求的cookie中携带的token查询出当前的用户信息,存放到ThreadLocal中,可供上下文使用。
    为什么要使用ThreadLocal?考虑到可能出现线程并发问题,使用ThreadLocal可以保证每一个线程有对应的变量副本(底层使用ThreadLocalMap存储),保证了线程隔离。每一个threadLocal都保存了当前线程的用户信息。
    (2) 页面跳转拦截器: 权限控制,实现未登录用户登录后可跳转回之前的页面。

  2. 敏感词过滤
    (1) 读取文件,构建前缀树。使用字典树算法实现敏感词过滤。时间复杂度为O(n),暴力检索时间复杂度为O(n^2)

  3. Redis使用Set实现点赞点踩功能
    (1) 将问题的回答和回答的回复等功能抽象成一个Comment, Comment中用entityType和entityId两个字段确定该评论关联的对象。将entityType和entityId构造为对应的like key或dislike key,userId作为value通过Set集合存到redis中。为什么要使用HashSet?去重,保证userId唯一。

  4. 手写异步框架实现发送站内信功能
    (1) 将事件模型封装成EventModel, 定义事件类型枚举类EventType,定义EventHandler事件处理器接口。
    (2) 通过Redis的List数据(底层是一个双向链表)结构实现消息队列。
    (3) 将事件通过生产者EventProducer类入队。
    (4) 消费者EventConsumer初始化时通过HashMap构建EventType和EventHandler的一对多关系
    (5) EventConsumer类开启线程取出队列中的事件, 根据事件的EventType找到对应实现EventHandler接口的类执行。
    使用异步队列的好处: Java中交互方式分为同步消息处理和异步消息处理两种:同步交互:指发送一个请求,需要等待返回,然后才能够发送下一个请求,有个等待过程;异步交互:指发送一个请求,不需要等待返回,随时可以再发送下一个请求,即不需要等待。
    因为一个请求会分配一个线程进行请求处理,该线程负责获取数据、拼装数据或模板然后返回给前端;在同步调用获取数据接口的情况下(等待依赖系统返回数据),整个线程是一直被占用并阻塞的。使用异步无需等待,并保证所有事件都能够处理完。

  5. 使用Redis的zsort实现关注服务
    为什么使用zsort(底层使用sort set)? zsore中有一个权重(scores)可以根据该权重进行排序。
    关注列表可以在score中存入时间根据时间排序

  6. 使用solr实现全局搜索:
    (1)配置要构建索引的表的字段。导入中文分词器。
    (2) 比如插入一个问题时,使用solr会先创建一个document再通过分词器为对应的字段创建索引添加到该document中。
    (3) 搜索时根据索引找到对应的文档。

  7. 部署
    将数据库和springboot导出的jar包项目分别部署在两个服务器上,减轻服务器压力。
    把jar包做成一个服务(service)来启动。为什么要导成jar包?前后端分离。(一般静态资源单独放在一台服务器上)

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值