所有的技术都是用来针对性解决问题的!!!!!!!!!!!!!!!!!

对象使用之前作非空判断!!!!!不然很容易空指针

阿里sms

阿里oss

我们如何搭建框架?

p2p借款人信息(银行卡等待)绑定和远程api调用

高并发某个方法会发生什么,异或突然流量断了我们应该怎么解决?

针对查询操作我们需要做哪些事?

1.如果前端是条件带分页的查询,那么我们需要对前端传过来的条件进行判空等相应处理,不为空的条件保留,为空则舍弃;

2.前端需要进行分页查询的时候,传给我们的页码需要作相应判断->判断页码是否为负数,如果为负数则设为1;然后还需判断传过来的页码是否为数字,如果不是数字则设为1;

一下设置:

如果前端传的是页码数是abc,则不能转为数字而爆异常,这个时候我们直接返回第一页.

前后端Long类型不同,那我们应该怎么做?

1.后端使用64位存储长整数(long),最大支持9223372036854775807;而前端JS使用53位来存放,最大支持9007199254740992,如果后端传给前端的数超过了这个数,则会出现问题(前端会得到溢出后的值).

2.解决方式:可以从前端或者后端双方来处理(其中一方进行处理即可,或者双方都处理),不要双方约定好规则即可.

后端进行处理的方式:

我们可以将数字转换成字符串返回给前端即可,前端解析时,因为是字符串,自然不会出现溢出的问题;一般情况下,项目中Long类型字段的数量比较多的话,可以配置Jackson,将所有需要序列化的数字转换成字符串,作如下配置:

但项目如果涉及的可能溢出的Long字段比较少时,可以选择将指定哪些字段在序列化时转换为字符串即可,如下图:

关于金钱字段我们应该使用什么类型的数据?保留几位小数

1.关于钱的字段我们一般使用BigDecimal进行存储,如果非常敏感的情况下,保存6-8位小数点,否则保留4-6位小数点即可.

商品加入购物车

1.前端传给后端的参数:token,sku_id;购买数量count,商品的价格需要我们再查一次,商品的是否选中状态(默认加入购物车的时候都是选中状态);新增购物车前先查询一下该用户在购物车表中是否存在该skuid,如果不存在则作新增操作(同时需要判断count是否为负数和0),如果存在则作更新商品数量操作.在更新某个商品的购物车的时候还要判断前端传过来的商品对应的数量是否为负数和字符串再操作,当购物车中的某个商品对应的数量小于等于零是直接把这个商品从购物车中删除.

2.关于加入购物车的区别:

a.~宝->搜索就需要登录;--->>>完整的用户画像

b.~东->加购物车是需要登录;

c.苏~~购->加购物车不需登录,结算是需要登录;

购物车生成订单

1.查询选中的购物车->查询价格->添加订单->删除选中的商品->扣减库存

2.我们需要查询用户选中的商品有哪些并展示,在查询得出的结果中我们需要将该商品的价格再查询一次并赋值,这样才能保证返回的价格是实时的.

3.扣减库存时应该避免时间差,别先查有多少库存在扣.

fegin调用之token传递->拦截器

/*** 订单微服务的拦截器* 过滤器:属于Servlet的组件-->拦截的是进入微服务的请求* 拦截器:属于springmvc的组件-->拦截的是从微服务出去的请求*/
@Component
public class OrderInterceptor implements RequestInterceptor {/*** 以下方法的触发时机是fegin调用发生以前(先运行远程调用的fegin代码,然后运行下边的这个方法)* @param requestTemplate-->即为fegin调用的request对象* 在发生fegin调用的时候,我们的做法是把原始的request整个传递给被远程调用的微服务*/@Overridepublic void apply(RequestTemplate requestTemplate) {//获取原始的请求对象ServletRequestAttributes requestAttributes =(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();if (requestAttributes != null) {//获取原始请求对象的请求体HttpServletRequest request = requestAttributes.getRequest();//获取原始请求体中的请求头中的所有的请求参数Enumeration<String> headerNames = request.getHeaderNames();while (headerNames.hasMoreElements()) {//获取每个请求头的参数的nameString name = headerNames.nextElement();//获取对应的valueString value = request.getHeader(name);//将从请求头中拿到的键值对放入fegin的http请求头中去requestTemplate.header(name, value);}}}
}

提交订单->同一页面重复提交,浏览器缓存提交,多端提交

策略->分布式锁

//redis中使用用户id作key,然后让key对应的value自增,value的初始值默认为0,因为redis的单线程,
//所以只有自增完value等于1的线程能够进行订单添加,此处解决统一用户多单提交导致可能出现的并发问题
Long increment =redisTemplate.opsForValue().increment("user:" + OrderThreadLocalUtil.get(), 1);if (increment > 1) {throw new RuntimeException("重复添加,请重试!");}try {//设置指定key的过期时间为10秒redisTemplate.expire("user:" + OrderThreadLocalUtil.get(), 10, TimeUnit.SECONDS);//远程调用购物车微服务,获取本次购买的商品和总金额//重复提交订单,以下判断起关键作用Map<String, Object> addOrderInfoMap = cartFegin.getAddOrderInfo();if (addOrderInfoMap == null || addOrderInfoMap.isEmpty()) {throw new RuntimeException("新增购物车失败,未勾选任何商品");}//构建订单数据//保存订单//获取订单id//保存订单详情//清空购物车//扣库存---} catch (Exception e) {e.printStackTrace();throw new RuntimeException(e.getMessage());} finally {redisTemplate.delete("user:" + OrderThreadLocalUtil.get());}

Java代码进行一对多处理

//service实现类/*** 获取首页的分类信息* @return*/@Overridepublic List<JSONObject> getCategory() {//查询出所有的一级,二级,三级分类的信息List<BaseCategoryView> category1ViewList =baseCategoryViewMapper.selectList(null);Map<Long, List<BaseCategoryView>> category1Map =category1ViewList.stream().collect(Collectors.groupingBy(BaseCategoryView::getCategory1Id));List<JSONObject> category1JsonList = category1Map.entrySet().stream().map(category1 -> {//返回结果初始化JSONObject category1Json = new JSONObject();//返回结果设置category1的idcategory1Json.put("categoryId", category1.getKey());//取出每一个category1所对应的category2集合List<BaseCategoryView> category2ViewList = category1.getValue();Map<Long, List<BaseCategoryView>> category2Map =category2ViewList.stream().collect(Collectors.groupingBy(BaseCategoryView::getCategory2Id));List<JSONObject> category2JsonList = category2Map.entrySet().stream().map(category2 -> {//二级分类结果初始化JSONObject category2Json = new JSONObject();//返回结果设置category2的idcategory2Json.put("categoryId", category2.getKey());List<BaseCategoryView> category3ViewList = category2.getValue();List<JSONObject> category3JsonList = category3ViewList.stream().map(category3 -> {//返回结果初始化JSONObject category3Json = new JSONObject();//设置三级分类idcategory3Json.put("categoryId", category3.getCategory3Id());//设置三级分类namecategory3Json.put("categoryName", category3.getCategory3Name());return category3Json;}).collect(Collectors.toList());//返回结果设置category2的namecategory2Json.put("categoryName", category3ViewList.get(0).getCategory2Name());//每一个category2设置与其对应的category3集合category2Json.put("childCategory", category3JsonList);//返回每一个组装好的二级分类return category2Json;}).collect(Collectors.toList());//返回结果设置category1的namecategory1Json.put("categoryName", category2ViewList.get(0).getCategory1Name());//每一个category1设置与其对应的category2集合category1Json.put("childCategory", category2JsonList);//返回每一个组装好的一级分类return category1Json;}).collect(Collectors.toList());return category1JsonList;}//pojo
@Data
@ApiModel(description = "BaseCategoryView")
@TableName("base_category_view")
public class BaseCategoryView extends BaseEntity {private static final long serialVersionUID = 1L;@ApiModelProperty(value = "一级分类编号")@TableField("category1_id")private Long category1Id;@ApiModelProperty(value = "一级分类名称")@TableField("category1_name")private String category1Name;@ApiModelProperty(value = "二级分类编号")@TableField("category2_id")private Long category2Id;@ApiModelProperty(value = "二级分类名称")@TableField("category2_name")private String category2Name;@ApiModelProperty(value = "三级分类编号")@TableField("category3_id")private Long category3Id;@ApiModelProperty(value = "三级分类名称")@TableField("category3_name")private String category3Name;}

数据库表结构

java开发逻辑思维相关推荐

  1. java获取当月有几天_你真的能在JAVA开发这条路上面一直坚持下去吗?

    JAVA为什么有前途? 过去的十多年,JAVA基本每年都是全世界使用人数第一的语言.全世界数百万的IT企业构建了庞大的JAVA生态圈,大量的软件基于JAVA开发. JAVA也被誉为"计算机界 ...

  2. java开发可以转什么软件有哪些_转行开发软件Java编程必须会什么

    原标题:转行开发软件Java编程必须会什么 要想开发软,Java编程必须会什么?最起码的就是逻辑思维要好,只要不是特别差就没有什么问题. 数学是相对比较能够体现出一个人的逻辑思维如何. 先想想自己以前 ...

  3. Java开发环境!java基础知识点总结

    一面(个人感觉回答得还不错) 1. 自我介绍 2. 说项目,项目问的非常深(本人提到之前做过的一篇关于FULL GC的问题定位和优化的项目以及一个多并发的项目) 2.1 对于自己产于过项目的系统定位是 ...

  4. java开发自我介绍范文(合集)

    java开发自我介绍范文3篇     java开发自我介绍范文篇一: Good morning ! It is really my honor to have this opportunity for ...

  5. Java开发入门教程!java开发架构师职责

    什么是Service Mesh 作为Service Mesh技术探索和实践的先行者,全球第一个真正的Service Mesh项目Linkerd负责人.Buoyant公司创始人兼CEO William ...

  6. 你真的适合学习JAVA开发吗?

    JAVA为什么有前途? 过去的十多年,JAVA基本每年都是全世界使用人数第一的语言.全世界数百万的IT企业构建了庞大的JAVA生态圈,大量的软件基于JAVA开发. JAVA也被誉为"计算机界 ...

  7. 金蝶软件校园招聘Java开发工程师笔试面试情况分享

    一.笔试 形式:(单选+多选+填空+简答) 考的内容主要为java基础(包括java运行机制.数据类型转换.运算符表达式求值.多线程.异常处理等).css.js.数据库SQL基础.软件工程.设计模式等 ...

  8. 你真的能在JAVA开发这条路上面一直坚持下去吗?

    JAVA为什么有前途? 过去的十多年,JAVA基本每年都是全世界使用人数第一的语言.全世界数百万的IT企业构建了庞大的JAVA生态圈,大量的软件基于JAVA开发.JAVA也被誉为"计算机界的 ...

  9. 74道高级Java面试合集,java开发模式面试题

    前言 今天我们来说说Redis为什么高性能?如何做高可用? Redis为什么这么快? Redis是单线程的,避免了多线程的上下文切换和并发控制开销: Redis大部分操作时基于内存,读写数据不需要磁盘 ...

最新文章

  1. QT的QSetIterator类的使用
  2. 科目三电子考的通过率普遍偏低
  3. 本地Android源代码库下载源码
  4. eclipse项目导入idea部署到tomcat
  5. spring cloud zuul 原理简介和使用
  6. 【实际经验】一台无系统PC机连接局域网产生的问题
  7. 书摘 - 吴军.浪潮之巅
  8. 【深度学习】深度学习门前徘徊——正向传播
  9. 奇安信代码安全实验室帮助 RedHat 修复两个 oVirt 漏洞,获官方致谢
  10. mysql connector 是什么_mysql的connector/J,和JDBC是啥关系?有啥区别?
  11. 设计模式 (十八 ) 观察者模式
  12. Centos在VMware虚拟机上的网络配置一记
  13. Excel分组数据、并创建多个新Excel文件
  14. Apple not immune from viruses(苹果也不能免除病毒的侵害)
  15. 关于数据恢复,记一次修复SD卡 RAW 之后的修复过程
  16. ExoPlayer网速估计方法
  17. fatal error C1010: 在查找预编译头指令时遇到意外的文件结尾
  18. 谷歌小语种外链代发,谷歌外链购买平台哪个好?
  19. abaqus流固耦合
  20. 烟雨黑帽SEO动态寄生虫程序全站更新快照程序2022版-特别适合配合动态寄生虫使用。

热门文章

  1. 卡内基梅隆大学软件工程研究所先后制定用于评价软件系统成熟度的模型CMM和CMMI...
  2. 2022年,消费品企业应该选择什么样的会员系统?
  3. 上海理工大学计算机考研复试题,【计算机考研】院校信息-上海理工大学
  4. win10误删计算机图标,Win10电脑回收站图标不见了怎么恢复?
  5. ui设计师作品集_需要设计师,需要作品集
  6. 【Ubuntu】Ubuntu中安装yum
  7. 如何快速涨粉,如何使用智能剪辑工具在抖音快速涨粉
  8. 判断字符串是否含有emoji表情或者颜文字(非键盘可输入的特殊字符)
  9. Java提取图片文字 tess4j
  10. 从信息化和数字化切入,聊一下建筑行业的数字化转型