首页IT科技项目答辩怎么讲(P2项目答辩总结)

项目答辩怎么讲(P2项目答辩总结)

时间2025-07-29 19:35:03分类IT科技浏览5582
导读:1、登录 1.1 登录的时候做vip的判断;...

1               、登录

1.1 登录的时候做vip的判断;

1.2 使用JWT(Java Web token),验证登录               ,更加安全

2                      、连续签到 2.1判断是否断签:

​ 通过判断昨天是否登录                      ,可以判断;

2.2判断连续签到多少天:

​ 将每次签到的记录保存在redis中       ,判断保存的数量               ,有多少个                       ,就连续签到多少天;

2.3 签到流水:

​ 签到流水如果可以       ,直接保存在数据库;(考虑使用redis的bitMaps);

《Redis实战》之使用BitMap实现用户签到功能:https://blog.csdn.net/qq_31905135/article/details/124032880

Redis中是利用String类型数据结构实现BitMap       ,因此最大上限是512M                       ,转换为bit则是2^32个bit位               。 bitmap的操作命令有: setbit:向指定位置offset存入一个01 getbit:获取指定位置offset的bit值 bitcount:统计BitMap中值为1的bit位的数量 bitfield: 操作(查询               ,修改       ,自增)BitMap中bit数组中的指定位置offset的值 bitfield_ro: 获取BitMap中bit数组                      ,并以十进制形式返回 bittop: 将多个BitMap的结果做位运算(与               ,或,异或) bitpos: 查找bit数组中指定范围内第一个0或者1出现的位置 2.4 签到初始化(自我考虑)

​ 每天0点的时候每个用户初始化一条没有登录的信息(例如:status=0)                      ,如果用户登录了就对用户的状态进行修改(status=1);

3       、VIP 3.1 vip续约

redis中存用户vip的唯一标识key                      ,设置ttl,并设置用户vip字段为vip;续约直接增加key值得时间;

3.2 判断用户是不是VIP会员状态

​ 一些需要使用到vip的权限的时候,先对vip进行检查               ,如果vip失效                      ,需要将用户的vip字段设置为 普通会员;(主要两个地方判断:1.用户登录;2.用户使用vip权限);这样可以大大节省时时判断用户vip状态的消耗;

4               、 关键词匹配

考虑       ,模糊匹配               ,近义词                       ,(俗名)       ,ES分词,IK分词(ElasticSearch+Kibana)

5                       、热词 5.1 热词库

需要添加热词库       ,只有在热词库中的词语                       ,命中才算热词;热词的管理权在商家手里;

5.2 添加热词(候选热词库) 通过商品的销量添加对应的热词; 对正常搜索到的词语进行搜索次数的记录               ,作为候选热词库;如果后期需要添加       ,可以从候选热词库中挑选; 可以使用老师的关键字的方式进行模仿实现命中; 6        、轮播图 6.1 轮播图的数量

可以根据不同时段进行不同数量的展示                      ,人越多               ,数量越多;

6.2 多商户下,轮播图的挑选 添加到轮播图需要一定的费用; 可以根据商品的销量和热卖品挑选轮播图; 6.3 轮播图排序 返回的前端的轮播图需要排序好; 6.4 轮播图每个人不一样 每个人的轮播图不一样; 6.5轮播图设计 1.1 :关于背景色:也可以不用                      ,主要看你的轮播图占多大空间                      ,如果是下图那样占全部空间,因为图片不可能将其全部占据               ,如果不用背景色                      ,那么       ,轮播图片的两旁就是白色               ,会很难看                      。所以看自己 1.2 商品id:有时候                       ,需要客户点击轮播图       ,直接跳转到 商品详情页面       ,所以 商品id 是线索 1.3 商品分类id:有时                       ,点击后               ,会跳转到某一分类下       ,不是具体的商品详情页面 1.4 轮播图类型(type):用于判断                      ,可以根据商品id或者分类进行页面跳转               ,1:商品 2:分类 6       、首页展示 每个人展示的商品不一样,可以从用户收藏                      ,用户购买                      ,添加购物车,用户浏览记录               ,等等推荐; 用户的行为数据(用户收藏                      ,用户购买       ,添加购物车               ,用户浏览记录                       ,等等)不能物理删除       ,因为这个数据是经过用户的自主赛选后得到的数据       ,十分宝贵; 7                       、优惠劵 优惠劵池(优惠劵有不同的分类可以领取); 优惠劵的领取情况; 智能优惠劵挑选                       ,在使用的时候               ,给用户展示优惠劵       ,需要将金额大的放在第一个                      ,用户可以自行挑选; 用户优惠劵挑选过一次               ,在下订单的时候还需要再次判断优惠劵是否使用过,是否过期(除非可以确定该优惠劵一定可以用); 8               、商品下单及自动签收 商品发货 需要考虑商品的自动签收                      ,用户不主动签收                      ,需要自动签收;考虑使用延时队列,(或者定时+普通消息队列               ,注意定时对性能消耗比较大); 9       、分享有礼 隐藏分享用户的信息(因为需要对分析的用户进行奖励                      ,但是又不能随便暴露用户的信息) 可以将用户信息MD5加密后在加盐,(内部有永固加盐库       ,自己人可以知道) 需要动态生成用户相关信息               ,主要目的就是保护用户信息安全; 10                      、某个商品比较冷清没有多少评论 将同一个商铺下                       ,类似产品的评论移过来;(个人感觉不是太好); 11               、多负载的时候       ,防止定时任务重复执行 XXL-Job 分布式的redis加锁       ,执行完释放; 通过ip指定配置,指定执行定时任务的服务器;

12、做项目中遇到的问题

12.1 日期格式问题

//1.返回给前端的日期格式 //实体参数上添加日期格式化注解 @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8") //2.前端传给后端的日期格式 //实体参数上添加日期格式化注解 @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")

12.2 feign远程调用传输时间相差(快了)14个小时

1.先说结论:在feign接口调用时使用表单形式(@RequestParam)传date类型会发生时间精度错乱                       ,在8时区会多14个小时       。

2.使用json格式(@RequestBody)传date类型

不会发生这种情况        。

表单形式我的解决办法是:在对外暴露的feign接口中使用字符串类型                      。

3.(String date)来接收日期               ,在真正feign调用的controller服务中使用@DateTimeFormat(pattern=“yyyy-MM-dd               ”)Date date来转换字符串类型的日期               。

4.将接收到的时间减去14小时(强烈不建议       ,比较麻烦且冗余                      ,多次远程调用可能会再相差时间)        。

5.扩展ZonedDateTime

java8 日期 时间 时区:https://blog.csdn.net/z69183787/article/details/87176339 ZonedDateTime时区日期时间类的运用:https://blog.csdn.net/qx020814/article/details/125580729 LocalDateTime                      、OffsetDateTime                      、ZonedDateTime互转:https://blog.csdn.net/f641385712/article/details/112732546

12.3 swagger返回参数不显示实体属性注解

需要添加@ApiModel(value = "xxx")注解               ,@ApiModelProperty(value = "xxx")注解,由于我之前没有怎么使用这个注解,导致忘记了                      ,特此记录一下;

12.4 一个消息队列出列多个业务

12.4.1 发消息

将要处理的消息内容转换成JOSN字符对象                      ,再放入到map集合中,监听到消息后               ,根据不同的消息内容进行不同的处理;

点击查看代码 //将订单信息封装成map集合                      ,方便发送 Map<String, Object> orderMsgMapToQueue = new HashMap<>(); //父订单 orderMsgMapToQueue.put("ordersForm", JSON.toJSONString(ordersForm)); //子订单 orderMsgMapToQueue.put("orderItemListSize", orderItemListForm.size()); for (int i = 0; i < orderItemListForm.size(); i++) { orderMsgMapToQueue.put("orderItem"+i,JSON.toJSONString(orderItemListForm.get(i))); } //发送生成抢购订单的消息到消息队列       ,并在redis中添加此订单的记录 //0 正在生成 if(redisUtils.set("weddingshop:orders:"+ordersForm.getOid(),ordersForm)){ //发送生成的 订单信息 到 消息队列 rabbitTemplate.convertAndSend(OrderMQConstant.WEDDINGSHOP_SAVE_ORDER_EXCHANGE, OrderMQConstant.WEDDINGSHOP_SAVE_ORDER_ROUTING, orderMsgMapToQueue); } 12.4.2 接收消息

监听到消息后               ,从map集合中取出不同的消息                       ,根据不同的消息内容进行不同的处理;

点击查看代码 @Slf4j @Component //指定接听的 消息队列 名字 @RabbitListener(queues = OrderMQConstant.WEDDINGSHOP_SAVE_ORDER_QUEUE) public class SeckillOrderSaveListener { @Autowired private RedisUtils redisUtils; @Autowired(required = false) private OrdersMapper ordersMapper; @Autowired(required = false) private OrderItemMapper orderItemMapper; @Autowired private OrdersService ordersService; /** * @author : huayu * @date : 1/11/2022 * @param : [directMsgJson] * @return : void * @description : Direct 直连模式消费者One,消费信息 */ //指定消息队列中的消息       ,交给对应的方法处理 @RabbitHandler public void saveSeckillOrder(Map<String,Object> orderMsgMapToQueue){ //子订单消息 if(orderMsgMapToQueue.get("orderItemListSize") != null){ //插入子订单 int orderItemListSize = Integer.parseInt(orderMsgMapToQueue.get("orderItemListSize").toString()); for (int i = 0; i < orderItemListSize; i++) { OrderItem orderItem = JSON.parseObject(orderMsgMapToQueue.get("orderItem" + i).toString(), OrderItem.class); log.info("***** 秒杀抢购子订单:{}       ,开始入库 ******",orderItem); if(orderItemMapper.insert(orderItem) > 0){ log.info("***** 秒杀抢购子订单:{}                       ,开始入库 成功 ******",orderItem); } } } //父订单消息 if(orderMsgMapToQueue.get("ordersForm")!= null){ Orders ordersForm = JSON.parseObject(orderMsgMapToQueue.get("ordersForm").toString(), Orders.class); log.info("***** 秒杀抢购父订单:{}               ,开始入库 ******",ordersForm); //TODO 将消息中的订单实体对象       ,调入业务接口                      ,插入到数据库,和redis中 //插入 父订单 if(ordersMapper.insert(ordersForm)>0){ log.info("***** 秒杀抢购父订单:{}               ,入库 成功 ******",ordersForm); } } //父订单 付款后 ,操作 if(orderMsgMapToQueue.get("ordersPayOid") != null){ // 父订单付款后 对 父订单 修改状态                      ,用户增加积分 和 子订单 修改状态                      ,生成物流单号 String ordersPayOid = orderMsgMapToQueue.get("ordersPayOid").toString(); log.info("------ 父订单:{},支付成功,对 父订单 修改状态               ,用户增加积分 和 子订单 修改状态                      ,生成物流单号------",ordersPayOid); if(ordersService.paySuccessOrders(ordersPayOid)){ log.info("------ 父订单:{},入库成功       ,对 父订单 修改状态               ,用户增加积分 和 子订单 修改状态                       ,生成物流单号------",ordersPayOid); } } } }

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
midjourney手机版下载(midjourney 初级使用说明) ai绘画作品图片大全(目前最强的AI绘画模型——Midjourney v5)