根据sql以及mybaytis里面的判断来判断活动时间是否到了,到了执行的操作与未到是有区别的。
<select id="listJoinBrandHotConfig" resultType="com.****.lego.report.model.response.JoinBrandHotConfigResp"> select b.brand_code, brand_logo, brand_name, join_total_cost, b.gmt_create gmtCreate from join_brand_hot_config h left join join_brand b on h.brand_code = b.brand_code where h.status = 1 and type = 2 <if test="today != null" > and (show_start_time is null or show_start_time <= #{today}) and (show_end_time is null or show_end_time >= #{today}) </if> order by sort desc, gmtCreate desc, h.id limit 10 </select>
支付业务分析
最终用户向 Fenix’s Bookstore 发送交易请求:购买一本价值 100 元的《深入理解 Java 虚拟机》。
Fenix’s Bookstore 首先应对用户账号扣款、商家账号收款、库存商品出库这三个操作有一个出错概率的先验评估,根据出错概率的大小来安排它们的操作顺序,这种评估一般直接体现在程序代码中,有一些大型系统也可能会实现动态排序。譬如,根据统计,最有可能的出现的交易异常是用户购买了商品,但是不同意扣款,或者账号余额不足;其次是仓库发现商品库存不够,无法发货;风险最低的是收款,如果到了商家收款环节,一般就不会出什么意外了。那顺序就应该安排成最容易出错的最先进行,即:账号扣款 → 仓库出库 → 商家收款。
账号服务进行扣款业务,如扣款成功,则在自己的数据库建立一张消息表,里面存入一条消息:“事务 ID:某 UUID,扣款:100 元(状态:已完成),仓库出库《深入理解 Java 虚拟机》:1 本(状态:进行中),某商家收款:100 元(状态:进行中)”,注意,这个步骤中“扣款业务”和“写入消息”是使用同一个本地事务写入账号服务自己的数据库的。
在系统中建立一个消息服务,定时轮询消息表,将状态是“进行中”的消息同时发送到库存和商家服务节点中去(也可以串行地发,即一个成功后再发送另一个,但在我们讨论的场景中没必要)。这时候可能产生以下几种情况。
商家和仓库服务都成功完成了收款和出库工作,向用户账号服务器返回执行结果,用户账号服务把消息状态从“进行中”更新为“已完成”。整个事务宣告顺利结束,达到最终一致性的状态。
商家或仓库服务中至少一个因网络原因,未能收到来自用户账号服务的消息。此时,由于用户账号服务器中存储的消息状态一直处于“进行中”,所以消息服务器将在每次轮询的时候持续地向未响应的服务重复发送消息。这个步骤的可重复性决定了所有被消息服务器发送的消息都必须具备幂等性,通常的设计是让消息带上一个唯一的事务 ID,以保证一个事务中的出库、收款动作会且只会被处理一次。
商家或仓库服务有某个或全部无法完成工作,譬如仓库发现《深入理解 Java 虚拟机》没有库存了,此时,仍然是持续自动重发消息,直至操作成功(譬如补充了新库存),或者被人工介入为止。由此可见,可靠事件队列只要第一步业务完成了,后续就没有失败回滚的概念,只许成功,不许失败。
商家和仓库服务成功完成了收款和出库工作,但回复的应答消息因网络原因丢失,此时,用户账号服务仍会重新发出下一条消息,但因操作具备幂等性,所以不会导致重复出库和收款,只会导致商家、仓库服务器重新发送一条应答消息,此过程重复直至双方网络通信恢复正常。
也有一些支持分布式事务的消息框架,如 RocketMQ,原生就支持分布式事务操作,这时候上述情况 2、4 也可以交由消息框架来保障。
jsp九大内置对象,四大作用域是什么
jsp四大作用域:
page范围:只在一个页面保留数据(javax.servlet.jsp.PageContext(抽象类))
request范围:只在一个请求中保存数据(javax.servlet.httpServletRequest)
Session范围:在一次会话中保存数据,仅供单个用户使用(javax.servlet.http.HttpSession)
Application范围:在整个服务器中保存数据,全部用户共享(javax.servlet.ServletContext)
九种对象简介:
out对象:用于向客户端、浏览器输出数据。
request对象:封装了来自客户端、浏览器的各种信息。
response对象:封装了服务器的响应信息。
exception对象:封装了jsp程序执行过程中发生的异常和错误信息。
config对象:封装了应用程序的配置信息。
page对象:指向了当前jsp程序本身。
session对象:用来保存会话信息。也就是说,可以实现在同一用户的不同请求之间共享数
application对象:代表了当前应用程序的上下文。可以在不同的用户之间共享信息。
pageContext对象:提供了对jsp页面所有对象以及命名空间的访问。
数据处理 如果为空,则显示为暂未披露
一行代码解决问题
resp.setJoinTotalCost(JoinBrandAttrEnum.join_total_cost.getDesc() + ":" + (brand.getJoinTotalCost() == null ? "暂未披露" :
某处使用for循环处理
private void handleHotConfig(List<JoinBrandHotConfigResp> joinBrands) { for (JoinBrandHotConfigResp joinBrand : joinBrands) { joinBrand.setJoinTotalCost(((StringUtils.isEmpty(joinBrand.getJoinTotalCost())) || ("0".equals(joinBrand.getJoinTotalCost()))) ? "暂未披露" : (joinBrand.getJoinTotalCost() + JoinBrandAttrEnum.join_total_cost.getUnit()) ); } }
72.为什么要用多线程
1、多线程 多个线程并发可以同时进行,线程互相独立,A线程可以先开始,B线程可以提前结束,A不影响B,B不影响A,各做各的路。
2、为什么要用多线程?单线程效率低,同样的工作,在资源充足的情况下,单线程使用的时间比多线程更长。
没有多线程的话,更多的线程影响性能,需要更多内存,并且在操作系统之前操作麻烦,切换不太方便
多线程----》解决负载均衡问题,充分地利用CPU资源,提高运行效率
3、多线程应用场景
多个任务:1 复制多个文件,好家伙,一起来执行吧。2 腾讯管家,好家伙,清理杀毒升级一起来吧,我去休息一下,啪啪几分钟结束
需要一些等待的任务 1 淘宝找商品的时候往下滑的时候,同时下面的图片,商品信息在加载 2 某些搜索,你输入第一个字的时候,下面就有信息内容出来了,还有关键字推荐等等功能
需要后台在执行
前端到java,json转换为数组等转换、json转换为对象、对象转字符串【实战版】
json转换为对象的一种方式
@ApiModelProperty("输入参数") private String input;
ReportRegionAnalysisReq reportRegionAnalysisReq = JSONObject.parseObject(reportOperatorLog.getInput(), ReportRegionAnalysisReq.class);
对象转字符串
JSONObject.toJSONString(reportRegionAnalysisDataResp)
reportRegionAnalysisDataResp是对象 转换后表成字符串,String output
108.jsp的九大内置对象,四大域对象
4、jsp的九大内置对象
request 请求对象
response 响应对象
pageContext jsp的上下文对象
session 会话对象
application ServletContext对象
config ServletConfig对象
out jsp输出流对象
page 指向当前jsp的对象
exception 异常对象
其中pageContext、request、session、application是四大域对象
什么是域对象?可以向Map一样存取数据的对象。
使用顺序:从小范围用起 pageContext–request–session–application
范围
pageContext (PageContextImpl类) 当前jsp页面内有效
request (HttpServletRequest类) 一次请求内有效
session (httpSession类) 一个会话范围内有效(打开浏览器知道关闭就是一个会话)
application (ServletContext类) 只要web工程不停,整个web工程都有效
84.线程的同步
什么时候有线程安全问题?
当两个或以上的线程共享同一个数据,并且这些线程都会调用这些数据的时候
解决线程安全问题?
使用同步机制:三种方法
Lock—》同步代码块(已经进入方法体,分配了相应资源)—》同步方法(在方法体之外)
或者称两种方法
Lock、synchronized
synchronized(同步) 与 Lock(锁)的区别
1、Lock是手动开启锁和关闭锁的,即显式锁
synchronized是自动开启锁的,即隐式锁,出了自动域自动释放,其实性能比Lock更低
2、Lock只有代码块锁,synchronized有代码块锁和方法锁
3、使用Lock,JVM将花费的时间更少来调用线程,性能更好,还有更好的扩展性。
4、先有synchronized的,在有Lock,Lock有取代synchronized趋势,以前好多的源码可查synchronized
优先使用的顺序
Lock—》同步代码块(已经进入方法体,分配了相应资源)—》同步方法(在方法体之外)
后面两个说的就是synchronized
156.SpringMVC的开发步骤
SpringMVC
2.1 SpringMVC的开发步骤
1、导入SpringMVC相关jar
2、配置SpringMVC核心控制器DispathcerServlet
3、创建Controller类和视图页面
4、使用注解配置Controller类中业务方法的映射地址
5、配置SpringMVC核心文件spring-mvc.xml
6、客户端发起请求测试