小熊家政帮day22-day23 订单系统优化(订单状态机、练习分库分表、索引、订单缓存)
目录
1 状态机
1.1 状态机介绍
1.1.1 当前存在的问题
在预约下单模块设计订单状态共有7种,如下图:

目前我们使用了待支付、派单中两种状态,在代码中我们发现存在对订单状态进行硬编码的情况,但是随着开发的深入这种代码会越来越多,比如在实现对订单进行关闭时代码会写成如下的形式:
1//运营人员在订单完成时取消订单//执行此场景下的业务逻辑//更新订单状态为派单中update(id,已关闭)
)
if(订单状态==服务中){//运营人员在服务中时取消订单//执行此场景下的业务逻辑//更新订单状态为已关闭update(id,已关闭)
)
...
以上代码存在问题如下:
在业务代码中对订单状态进行硬编码如果有一天更改了业务逻辑就需要更改代码,不方便进行系统扩展和维护。
另外对订单状态的管理是散落在很多地方不方便对订单状态进行统一管理和维护。
1.1.2 使用状态机解决问题
针对以上问题如何解决呢?
我们可以使用状态机对订单状态进行统一管理。
什么是状态机?
上图在UML中叫状态图(又叫状态机图),UML是软件开发中的一种建模语言,用来辅助进行软件设计,常用的如:类图、对象、状态图、序列图等,注意状态机图并不是状态机,状态机是一种数学模型,应用在自动化控制、计算机科学、通信等很多领域,简单理解状态机就是对状态进行统一管理的数学模型。
我们画的状态图是状态机在计算机科学中的应用方法,还有状态机设计模式也是状态机在软件领域的应用方法。
状态机设计模式是状态机在软件中的应用,状态机设计模式描述了一个对象在内部状态发生变化时如何改变其行为,将状态之间的变更定义为事件,将事件暴露出去,通过执行状态变更事件去更改状态,这是状态机设计模式的核心内容。
理解状态机设计模式需要理解四个要素:现态、事件、动作、次态。
1、现态:是指当前所处的状态。
2、事件:当一个条件被满足,状态会由现态变为新的状态,事件发生会触发一个动作,或者执行一次状态的迁移。
3、动作:发生事件执行的动作,动作执行完毕后,可以迁移到新的状态,也可以仍旧保持原状态。动作不是必需的,当条件满足后,也可以不执行任何动作,直接迁移到新状态。
4、次态:条件满足后要迁往的新状态。
我们拿待支付状态到派单中状态举例:

现态:订单当前处于待支付状态那么现态为待支付。
事件:用户支付成功为事件,支付成功是条件,当条件满足进行状态迁移。
动作:将订单状态由待支付更改为派单中。
次态:派单中。
使用状态机优化代码:
使用状态机之后对代码进行以下优化。
支付成功更改订单状态的代码优化如下:
if(支付状态==支付成功){//调用状态机执行支付成功事件orderStateMachine.changeStatus(id,支付成功事件);
}
订单取消的代码优化如下:
orderStateMachine.changeStatus(id,订单完成时取消订单事件);
我们发现使用状态机的代码并没有对订单状态进行硬编码,只是指定了订单id和事件名称,执行changeStatus方法后自动更改订单的状态。
1.2 实现订单状态机
1.2.1 编写订单状态机
1.2.1.1 依赖引入
本项目基于状态机设计模式开发了状态机组件,代码在jzo2o-framework中,如果在订单管理服务中实现订单状态机需要添加状态机的依赖。
在jzo2o-orders-base工程的pom.xml中添加状态机组件的依赖
<dependency><groupId>com.jzo2o</groupId><artifactId>jzo2o-statemachine</artifactId><version>1.0-SNAPSHOT</version>
</dependency>
1.2.1.2 订单状态枚举类
阅读订单状态枚举类,它实现了StatusDefine 状态接口,不论是现态还是次态都需要实现状态接口。
定义每个枚举需要注意见名知意,比如:NO_PAY(0, “待支付”, “NO_PAY”)表示待支付状态。
订单状态枚举类如下:
@Getter
@AllArgsConstructor
public enum OrderStatusEnum implements StatusDefine {NO_PAY(0, "待支付", "NO_PAY"),DISPATCHING(100, "派单中", "DISPATCHING"),NO_SERVE(200, "待服务", "NO_SERVE"),SERVING(300, "服务中", "SERVING"),FINISHED(500, "已完成", "FINISHED"),CANCELED(600, "已取消", "CANCELED"),CLOSED(700, "已关闭", "CLOSED");private final Integer status;private final String desc;private final String code;/*** 根据状态值获得对应枚举** @param status 状态* @return 状态对应枚举*/public static OrderStatusEnum codeOf(Integer status) {for (OrderStatusEnum orderStatusEnum : values()) {if (orderStatusEnum.status.equals(status)) {return orderStatusEnum;}}return null;}
}
1.2.1.3 状态变更事件枚举类
所有状态之间存在的变更都需要定义状态变更事件,它实现了StatusChangeEvent 状态变更事件接口,事件对应状态机四要素的事件
代码如下,重点看PAYED:
PAYED(OrderStatusEnum.NO_PAY, OrderStatusEnum.DISPATCHING, “支付成功”, “payed”)表示由NO_PAY(未支付)状态变化为DISPATCHING(派单中)状态,事件名称为“支付成功”(payed)。
@Getter
@AllArgsConstructor
public enum OrderStatusChangeEventEnum implements StatusChangeEvent {PAYED(OrderStatusEnum.NO_PAY, OrderStatusEnum.DISPATCHING, "支付成功", "payed"),DISPATCH(OrderStatusEnum.DISPATCHING, OrderStatusEnum.NO_SERVE, "接单/抢单成功", "dispatch"),START_SERVE(OrderStatusEnum.NO_SERVE, OrderStatusEnum.SERVING, "开始服务", "start_serve"),COMPLETE_SERVE(OrderStatusEnum.SERVING, OrderStatusEnum.FINISHED, "完成服务", "complete_serve"),
// EVALUATE(OrderStatusEnum.NO_EVALUATION, OrderStatusEnum.FINISHED, "评价完成", "evaluate"),CANCEL(OrderStatusEnum.NO_PAY, OrderStatusEnum.CANCELED, "取消订单", "cancel"),SERVE_PROVIDER_CANCEL(OrderStatusEnum.NO_SERVE, OrderStatusEnum.DISPATCHING, "服务人员/机构取消订单", "serve_provider_cancel"),CLOSE_DISPATCHING_ORDER(OrderStatusEnum.DISPATCHING, OrderStatusEnum.CLOSED, "派单中订单关闭", "close_dispatching_order"),CLOSE_NO_SERVE_ORDER(OrderStatusEnum.NO_SERVE, OrderStatusEnum.CLOSED, "待服务订单关闭", "close_no_serve_order"),CLOSE_SERVING_ORDER(OrderStatusEnum.SERVING, OrderStatusEnum.CLOSED, "服务中订单关闭", "close_serving_order"),
// CLOSE_NO_EVALUATION_ORDER(OrderStatusEnum.NO_EVALUATION, OrderStatusEnum.CLOSED, "待评价订单关闭", "close_no_evaluation_order"),CLOSE_FINISHED_ORDER(OrderStatusEnum.FINISHED, OrderStatusEnum.CLOSED, "已完成订单关闭", "close_finished_order");/*** 源状态*/private final OrderStatusEnum sourceStatus;/*** 目标状态*/private final OrderStatusEnum targetStatus;/*** 描述*/private final String desc;/*** 代码*/private final String code;
}
1.2.1.4 定义订单快照类
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class OrderSnapshotDTO extends StateMachineSnapshot {/*** 订单id*/private Long id;/*** 订单所属人*/private Long userId;/*** 服务类型id*/private Long serveTypeId;/*** 服务类型名称*/private String serveTypeName;/*** 服务项id*/private Long serveItemId;/*** 服务项名称*/private String serveItemName;/*** 服务项图片*/private String serveItemImg;/*** 服务单位*/private Integer unit;/*** 服务id*/private Long serveId;/*** 订单状态,0:待支付,100:派单中,200:待服务,300:服务中,500:订单完成,600:订单取消,700已关闭*/private Integer ordersStatus;/*** 支付状态,2:待支付,4:支付成功*/private Integer payStatus;/*** 退款,0:发起退款,1:退款中,2:退款成功 3:退款失败*/private Integer refundStatus;/*** 单价*/private BigDecimal price;/*** 购买数量*/private Integer purNum;/*** 订单总金额*/private BigDecimal totalAmount;/*** 实际支付金额*/private BigDecimal realPayAmount;/*** 优惠金额*/private BigDecimal discountAmount;/*** 城市编码*/private String cityCode;/*** 服务详细地址*/private String serveAddress;/*** 联系人手机号*/private String contactsPhone;/*** 联系人姓名*/private String contactsName;/*** 服务开始时间*/private LocalDateTime serveStartTime;/*** 经度*/private String lon;/*** 纬度*/private String lat;/*** 支付时间*/private LocalDateTime payTime;/*** 评价时间*/private LocalDateTime evaluationTime;/*** 订单创建时间*/private LocalDateTime createTime;/*** 订单更新时间*/private LocalDateTime updateTime;/*** 支付服务交易单号*/private Long tradingOrderNo;/*** 支付服务退款单号*/private Long refundNo;/*** 支付渠道【支付宝、微信、现金、免单挂账】*/private String tradingChannel;/*** 三方流水,微信支付订单号或支付宝订单号*/private String thirdOrderId;/*** 退款三方流水,微信支付订单号或支付宝订单号*/private String thirdRefundOrderId;/*** 取消人id*/private Long cancellerId;/*** 取消人名称*/private String cancelerName;/*** 取消人类型*/private Integer cancellerType;/*** 取消时间*/private LocalDateTime cancelTime;/*** 取消原因*/private String cancelReason;/*** 实际服务完成时间*/private LocalDateTime realServeEndTime;/*** 评价状态*/private Integer evaluationStatus;@Overridepublic String getSnapshotId() {return String.valueOf(id);}@Overridepublic Integer getSnapshotStatus() {return ordersStatus;}@Overridepublic void setSnapshotId(String snapshotId) {this.id = Long.parseLong(snapshotId);}@Overridepublic void setSnapshotStatus(Integer snapshotStatus) {this.ordersStatus = snapshotStatus;}}
1.2.1.5 定义事件变更动作类
/*** 支付成功执行的动作*/
@Slf4j
@Component("order_payed")
public class OrderPayedHandler implements StatusChangeHandler<OrderSnapshotDTO> {@Resourceprivate IOrdersCommonService ordersService;/*** 订单支付处理逻辑** @param bizId 业务id* @param bizSnapshot 快照*/@Overridepublic void handler(String bizId, StatusChangeEvent statusChangeEventEnum, OrderSnapshotDTO bizSnapshot) {log.info("支付成功事件处理逻辑开始,订单号:{}", bizId);}
}
1.2.1.5 定义订单状态机类
AbstractStateMachine状态机抽象类是状态机的核心类,是具体的状态机要继承的抽象类,比如我们实现订单状态机就需要继承AbstractStateMachine抽象类。

@Component
public class OrderStateMachine extends AbstractStateMachine<OrderSnapshotDTO> {protected OrderStateMachine(StateMachinePersister stateMachinePersister, BizSnapshotService bizSnapshotService, RedisTemplate redisTemplate) {super(stateMachinePersister, bizSnapshotService, redisTemplate);}/*** 指定状态机的名称* @return*/@Overrideprotected String getName() {return "order";}/*** * @param bizSnapshot*/@Overrideprotected void postProcessor(OrderSnapshotDTO bizSnapshot) {}/*** 指定订单的初始状态* @return*/@Overrideprotected StatusDefine getInitState() {return OrderStatusEnum.NO_PAY;}
}
1.2.1.6 状态机表设计
状态机使用MySQL对状态进行持久化,涉及到如下表:
状态机持久化表:
每个订单对应状态机表中的一条记录。
state_machine_name :针对订单的状态机起个名称叫order,针对服务单的状态机可以起个名称为serve。
biz_id:存储订单id
state:记录该订单的当前状态
create table `jzo2o-orders`.state_persister
(id bigint auto_increment comment '主键'constraint `PRIMARY`primary key,state_machine_name varchar(255) null comment '状态机名称',biz_id varchar(255) null comment '业务id',state varchar(255) null comment '状态',create_time datetime default CURRENT_TIMESTAMP null comment '创建时间',update_time datetime default CURRENT_TIMESTAMP null on update CURRENT_TIMESTAMP comment '更新时间',constraint 唯一索引unique (state_machine_name, biz_id)
)
状态机快照表:
一个订单在快照表有多条记录,每变一个状态会记录该状态下的快照信息(即订单相关的详细信息)便于查询订单变化的历史记录。
state_machine_name :同上
biz_id :同上
db_shard_id:暂时用不到
state:对应快照的状态
biz_data:快照信息(json格式),用在订单状态机就是记录订单相关的信息。
create table `jzo2o-orders`.biz_snapshot
(id bigint auto_increment comment '主键'constraint `PRIMARY`primary key,state_machine_name varchar(50) null comment '状态机名称',biz_id varchar(50) null comment '业务id',db_shard_id bigint null comment '分库键',state varchar(50) null comment '状态代码',biz_data varchar(5000) null comment '业务数据',create_time datetime default CURRENT_TIMESTAMP not null comment '创建时间',update_time datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间'
)
1.2.2 测试订单状态机
加载订单状态机
在base工程进行导入状态机
@Configuration
@ComponentScan({"com.jzo2o.orders.base.service","com.jzo2o.orders.base.handler"})
@MapperScan("com.jzo2o.orders.base.mapper")
@Import({OrderStateMachine.class})
@EnableConfigurationProperties({DispatchProperties.class, ExecutorProperties.class})
public class AutoImportConfiguration {
}
测试启动状态机
调用OrderStateMachine的start()方法启动一个订单的状态机,启动状态机表示订单用状态机管理状态,启动状态机后会设置订单的初始状态。
观察state_persister表有一条10100号订单的状态持久化记录,每条订单对应state_persister表的一条记录。
观察biz_snapshot表有一条10100号订单的快照信息,一条订单在biz_snapshot表对应多个条记录,每次订单状态变更都会产生一个快照
@SpringBootTest
@Slf4j
public class OrderStateMachineTest {@Resourceprivate OrderStateMachine orderStateMachine;@Testpublic void test_start() {//启动状态机String start = orderStateMachine.start("10100");log.info("返回初始状态:{}", start);}@Testpublic void test_changeStatus() {//状态变更orderStateMachine.changeStatus("10100", OrderStatusChangeEventEnum.PAYED);}}
根据状态变更事件定义可知,执行测试方法后1010订单的状态由NO_PAY(待支付)变更为DISPATCHING(派单中)。
1.2.3 使用订单状态机
目标:
下单时使用状态机
在支付成功时使用状态机
下单时启动状态机
下单后创建一个新订单,使用状态机的启动方法表示用状态机对该订单的状态开始进行管理。
@Transactional(rollbackFor = Exception.class)
public void add(Orders orders) {boolean save = this.save(orders);if (!save) {throw new DbRuntimeException("下单失败");}//构建快照对象OrderSnapshotDTO orderSnapshotDTO = BeanUtil.toBean(baseMapper.selectById(orders.getId()), OrderSnapshotDTO.class);//状态机启动orderStateMachine.start(null,String.valueOf(orders.getId()),orderSnapshotDTO);
}
支付成功使用状态机
- 定义状态变更动作类
在动作类中更新订单的状态,在动作类中更新订单的状态要比在多处业务代码中对订单状态硬编码要强的多,因为可以在动作类中统一对订单状态进行管理。
除了更新订单状态以外还需要填充订单快照的相关信息,这里主要是支付相关的信息,包括:支付状态、支付时间、支付服务的交易单号、第三方支付的交易单号等。
@Resourceprivate IOrdersCommonService ordersService;/*** 订单支付处理逻辑** @param bizId 业务id* @param bizSnapshot 快照*/@Overridepublic void handler(String bizId, StatusChangeEvent statusChangeEventEnum, OrderSnapshotDTO bizSnapshot) {log.info("支付成功事件处理逻辑开始,订单号:{}", bizId);//统一对订单状态进行更新 未支付变为派单中OrderUpdateStatusDTO orderUpdateStatusDTO = new OrderUpdateStatusDTO();orderUpdateStatusDTO.setId(bizSnapshot.getId());orderUpdateStatusDTO.setOriginStatus(OrderStatusEnum.NO_PAY.getStatus());orderUpdateStatusDTO.setTargetStatus(OrderStatusEnum.DISPATCHING.getStatus());orderUpdateStatusDTO.setPayStatus(OrderPayStatusEnum.PAY_SUCCESS.getStatus());orderUpdateStatusDTO.setTradingOrderNo(bizSnapshot.getTradingOrderNo());orderUpdateStatusDTO.setTransactionId(bizSnapshot.getThirdOrderId());orderUpdateStatusDTO.setPayTime(bizSnapshot.getPayTime());orderUpdateStatusDTO.setTradingChannel(bizSnapshot.getTradingChannel());Integer res = ordersService.updateStatus(orderUpdateStatusDTO);if(res < 1){throw new CommonException("订单号为"+bizId+"的支付事件处理失败");}}
- 在支付成功方法中使用状态机
使用状态机执行支付成功状态变更。
/*** 支付成功, 更新数据库的订单表及其他信息** @param tradeStatusMsg 交易状态消息*/@Override@Transactional(rollbackFor = Exception.class)public void paySuccess(TradeStatusMsg tradeStatusMsg){/* boolean update = lambdaUpdate().eq(Orders::getId, tradeStatusMsg.getProductOrderNo()).eq(Orders::getOrdersStatus,0) //订单状态只能由待支付 才可以变为派单中.set(Orders::getPayStatus, OrderPayStatusEnum.PAY_SUCCESS.getStatus()).set(Orders::getTransactionId, tradeStatusMsg.getTransactionId()).set(Orders::getOrdersStatus, OrderStatusEnum.DISPATCHING.getStatus()) //订单状态变为派单中.set(Orders::getPayTime, LocalDateTime.now()).update();if(!update){throw new CommonException("支付成功,更新"+tradeStatusMsg.getProductOrderNo()+"订单状态为派单中失败");}*///使用状态机将待支付状态变为派单中OrderSnapshotDTO orderSnapshotDTO = OrderSnapshotDTO.builder().payTime(LocalDateTime.now()).tradingOrderNo(tradeStatusMsg.getTradingOrderNo()).tradingChannel(tradeStatusMsg.getTradingChannel()).thirdOrderId(tradeStatusMsg.getTransactionId()).build();orderStateMachine.changeStatus(null,tradeStatusMsg.getProductAppId().toString(), OrderStatusChangeEventEnum.PAYED,orderSnapshotDTO);}
测试


测试成功
相关文章:
小熊家政帮day22-day23 订单系统优化(订单状态机、练习分库分表、索引、订单缓存)
目录 1 状态机1.1 状态机介绍1.1.1 当前存在的问题1.1.2 使用状态机解决问题 1.2 实现订单状态机1.2.1 编写订单状态机1.2.1.1 依赖引入1.2.1.2 订单状态枚举类1.2.1.3 状态变更事件枚举类1.2.1.4 定义订单快照类1.2.1.5 定义事件变更动作类1.2.1.5 定义订单状态机类1.2.1.6 状…...
LeetCode 1731, 151, 148
目录 1731. 每位经理的下属员工数量题目链接表要求知识点思路代码 151. 反转字符串中的单词题目链接标签思路代码 148. 排序链表题目链接标签Collections.sort()思路代码 归并排序思路代码 1731. 每位经理的下属员工数量 题目链接 1731. 每位经理的下属员工数量 表 表Emplo…...
Codeforces Round 953 (Div. 2)(A~D题解)
这次比赛是我最顺利的一次比赛,也是成功在中途打进前1500,写完第三道题的时候也是保持在1600左右,但是后面就啥都不会了,还吃了点罚时,虽说如此也算是看到进步了,D题学长说很简单,但是我当时分析…...
晶圆切割机(晶圆划片机)为晶圆加工重要设备 我国市场国产化进程不断加快
晶圆切割机(晶圆划片机)为晶圆加工重要设备 我国市场国产化进程不断加快 晶圆切割机又称晶圆划片机,指能将晶圆切割成芯片的机器设备。晶圆切割机需具备切割精度高、切割速度快、操作便捷、稳定性好等特点,在半导体制造领域应用广…...
39、基于深度学习的(拼音)字符识别(matlab)
1、原理及流程 深度学习中常用的字符识别方法包括卷积神经网络(CNN)和循环神经网络(RNN)。 数据准备:首先需要准备包含字符的数据集,通常是手写字符、印刷字符或者印刷字体数据集。 数据预处理࿱…...
CCF 矩阵重塑
第一题:矩阵重塑(一) 本题有两种思路 第一种 (不确定是否正确 但是100分) #include<iostream> using namespace std; int main(){int n,m,p,q,i,j;cin>>n>>m>>p>>q;int a[n][m];for(i…...
Aigtek高压放大器在柔性爬行机器人驱动性能研究中的应用
实验名称:柔性爬行机器人的材料测试 研究方向:介电弹性体的最小能量结构是一种利用DE材料的电致变形与柔性框架形变相结合设计的新型柔性驱动器,所谓最小能量是指驱动器在平衡状态时整个系统的能量最小,当系统在外界的电压刺激下就…...
Postman下发流表至Opendaylight
目录 任务目的 任务内容 实验原理 实验环境 实验过程 1、打开ODL控制器 2、网页端打开ODL控制页面 3、创建拓扑 4、Postman中查看交换机的信息 5、L2层流表下发 6、L3层流表下发 7、L4层流表下发 任务目的 1、掌握OpenFlow流表相关知识,理解SDN网络中L…...
C语言王国——数组的旋转(轮转数组)三种解法
目录 一、题目 二、分析 2.1 暴力求解法 2.2 找规律 2.3 追求时间效率,以空间换时间 三、结论 一、题目 给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。 示例 1: 输入: nums [1,2,3,4,5,6,7], k 3 输出…...
MySQL中CAST和CONVERT函数都用于数据类型转换
在 MySQL 中,CAST() 和 CONVERT() 函数都用于数据类型转换。虽然这两个函数在大多数情况下可以互换使用,但它们之间还是有一些细微的差别。 官方文档地址 https://dev.mysql.com/doc/refman/8.4/en/cast-functions.html#function_cast CAST() 函数 C…...
速盾:cdn影响seo吗?
CDN (Content Delivery Network) 是一个分布式网络架构,用于在全球范围内加速网站内容的传输和分发。它通过将网站的静态资源(例如图片、CSS、JavaScript 文件等)存储在多个服务器上,使用户可以从最接近他们位置的服务器上获取这些…...
期末算法复习
0-1背包问题(动态规划) 例题 算法思想: 动态规划的核心思想是将原问题拆分成若干个子问题,并利用已解决的子问题的解来求解更大规模的问题。 主要是状态转移方程和状态 算法描述: 初始化一个二维数组dp࿰…...
可穿戴设备:苹果“吃老底”、华为“忙复苏”、小米“再扩容”
配图来自Canva可画 随着产品功能的创新,可穿戴设备不再被简单地视为手机的延伸,而是被当成一种独立的、具有独特功能和优势的产品,受到了越来越多人的青睐。 一方面,技术的进步使得可穿戴设备在功能、性能和使用体验上得到显著提…...
AI数据分析:集中度分析和离散度分析
在deepseek中输入提示词: 你是一个Python编程专家,要完成一个Python脚本编写的任务,具体步骤如下: 读取Excel表格:"F:\AI自媒体内容\AI行业数据分析\toolify月榜\toolify2023年-2024年月排行榜汇总数据.xlsx&qu…...
redis的分布式session和本地的session有啥区别
在web应用开发中,Session用于在多个请求之间存储用户数据。传统上,Session存储在服务器的内存中,即本地Session。然而,随着应用规模和复杂度的增加,特别是在分布式环境中,本地Session会遇到一些问题。这时&…...
SSH概念、用途、详细使用方法
还是大剑师兰特:曾是美国某知名大学计算机专业研究生,现为航空航海领域高级前端工程师;CSDN知名博主,GIS领域优质创作者,深耕openlayers、leaflet、mapbox、cesium,canvas,webgl,ech…...
关于电脑文件的规划思考
概述 设置C、D、E、F 四个盘 C盘:系统数据使用,操作系统、其他软件需要用到的系统性资源 D盘:应用软件区 的使用,数据库、navacat、idea、visual studio、浏览器、向日葵、虚拟机…… E盘:工作区:公司资料…...
DVWA - Brute Force
DVWA - Brute Force 等级:low 直接上bp弱口令爆破,设置变量,攻击类型最后一个,payload为用户名、密码简单列表 直接run,长度排序下,不一样的就是正确的用户名和密码 另解: 看一下…...
安卓手机文件找回方法汇总,3个技巧,不再焦虑
我们用手机来储存各种重要的信息和文件,无论是珍贵的照片、重要的文档还是喜爱的音乐,用来记录和分享生活中的每一个瞬间。但如果不小心删除了这些文件,我们可能会面临数据丢失的风险,进而产生焦虑和不安。本文将为您揭秘手机文件…...
{}初始化
文章目录 ()初始化的问题易混淆弱检查 {}初始化{}初始化是c11推荐的初始化,解决了上述的问题 ()则被用于强制类型转换 ()初始化的问题 易混淆 string s();不能确定是函数定义还是对象定义 弱检查 int a(3.14);3.14 可以通过 int 定义 {}初始化 {}初始化是c11推…...
大型活动交通拥堵治理的视觉算法应用
大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动(如演唱会、马拉松赛事、高考中考等)期间,城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例,暖城商圈曾因观众集中离场导致周边…...
大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...
基于Docker Compose部署Java微服务项目
一. 创建根项目 根项目(父项目)主要用于依赖管理 一些需要注意的点: 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件,否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...
如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...
Webpack性能优化:构建速度与体积优化策略
一、构建速度优化 1、升级Webpack和Node.js 优化效果:Webpack 4比Webpack 3构建时间降低60%-98%。原因: V8引擎优化(for of替代forEach、Map/Set替代Object)。默认使用更快的md4哈希算法。AST直接从Loa…...
【Linux】Linux安装并配置RabbitMQ
目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的,需要先安…...
Java 与 MySQL 性能优化:MySQL 慢 SQL 诊断与分析方法详解
文章目录 一、开启慢查询日志,定位耗时SQL1.1 查看慢查询日志是否开启1.2 临时开启慢查询日志1.3 永久开启慢查询日志1.4 分析慢查询日志 二、使用EXPLAIN分析SQL执行计划2.1 EXPLAIN的基本使用2.2 EXPLAIN分析案例2.3 根据EXPLAIN结果优化SQL 三、使用SHOW PROFILE…...
DeepSeek越强,Kimi越慌?
被DeepSeek吊打的Kimi,还有多少人在用? 去年,月之暗面创始人杨植麟别提有多风光了。90后清华学霸,国产大模型六小虎之一,手握十几亿美金的融资。旗下的AI助手Kimi烧钱如流水,单月光是投流就花费2个亿。 疯…...
【java】【服务器】线程上下文丢失 是指什么
目录 ■前言 ■正文开始 线程上下文的核心组成部分 为什么会出现上下文丢失? 直观示例说明 为什么上下文如此重要? 解决上下文丢失的关键 总结 ■如果我想在servlet中使用线程,代码应该如何实现 推荐方案:使用 ManagedE…...
