苍穹外卖学习 Day10 Day11 Day12

前言

用于记录苍穹外卖Day10、Day11、Day12的学习

Day10 订单状态定时处理 来电提醒 客户催单

订单状态定时处理

Spring Task

Spring Task是一个任务调度工具,可以按照约定的时间自动执行某个代码逻辑(定时自动执行某段Java代码)

cron表达式

cron表达式其实就是一个字符串,通过cron表达式可以定义任务触发的时间。

构成规则:分为6或7个域,用空格隔开,每个域代表一个含义。从左到右依次为秒、分钟、小时、日、月、周、年(可选)

在这里插入图片描述

cron在线生成器:https://cron.qqe2.com

Spring Task使用步骤

  • 导入坐标spring-context
  • 启动类添加注解@EnableScheduling开启任务调度
  • 自定义定时任务类

需求开发

存在的问题:

  • 下单后未支付,订单一直处于”待支付“状态
  • 用户收货后管理端未点击完成按钮,订单一直处于”派送中“状态

只需自定义个任务处理类来定时处理即可:

//定时任务类,定时处理订单状态
@Component
@Slf4j
public class OrderTask {@Autowiredprivate OrderMapper orderMapper;//处理下单后未支付超时的情况@Scheduled(cron = "0 * * * * ? *")//每分钟触发一次
//    @Scheduled(cron="0/5 * * * * ?")public void processTimeOut(){log.info("定时处理下单未支付的订单");//当前时间减15分钟LocalDateTime localDateTime = LocalDateTime.now().plusMinutes(-15);List<Orders> list = orderMapper.getByStatusAndOrderTimeLT(Orders.PENDING_PAYMENT, localDateTime);if(list!=null&&list.size()>0){for (Orders orders : list) {orders.setStatus(Orders.CANCELLED);orders.setConsignee("订单超时,自动取消");orders.setCancelTime(LocalDateTime.now());orderMapper.update(orders);}}}//处理一直处于派送中,没有完成的订单@Scheduled(cron = "0 0 1 * * ?")//每天凌晨一点触发
//    @Scheduled(cron="0/10 * * * * ?")public void processDeliveryOrder(){log.info("定时处理一直在派送的订单");LocalDateTime localDateTime = LocalDateTime.now().plusMinutes(-60);List<Orders> list = orderMapper.getByStatusAndOrderTimeLT(Orders.DELIVERY_IN_PROGRESS, localDateTime);if(list!=null&&list.size()>0){for (Orders orders : list) {orders.setStatus(Orders.COMPLETED);orderMapper.update(orders);}}}
}

来电提醒

WebSocket

WebSocket是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工通信–浏览器和服务器只需完成一次握手,两者之间即可建立持久性的连接,并进行双向数据传输

WebSocket和HTTP对比:

  • HTTP是短连接;WebSocket是长连接
  • HTTP是单向通信,基于请求响应模型;WebSocket支持双向通信。
  • WebSocket和HTTP都是基于TCP协议

应用场景:

  • 视频弹幕
  • 实况更新
  • 网页聊天

需求开发

实现思路:

  • 通过WebSocket实现管理端页面和服务端保持长连接
  • 当客户支付后,调用WebSocket的相关API从服务端向客户端推送消息
  • 客户端解析服务端发送的消息,判断是来电提醒还是客户催单,并进行相应的语音播报
  • 约定服务端向客户端发送的消息的数据格式为JSON,字段包括:type(消息类型,1为来单提醒、2为客户催单)、orderId、content(消息内容)

这里我们只需要在支付成功后提示管理端即可,在OrderServiceImpl的paySuccess方法中:

		//通过WebSocket向客户端浏览器推送数据Map map=new HashMap();map.put("type",1);map.put("orderId",ordersDB.getId());map.put("content","订单号:"+outTradeNo);String Json= JSON.toJSONString(map);webSocketServer.sendToAllClient(Json);

注意:启动项目的时候看看你是否连接上WebSocket,如果没连接上可能是因为自己修改过端口号的问题,将端口号改回80或者改下前端代码即可。

客户催单

实现思路和来电提醒差不多。当用户在客户端点击催单按钮时,发起请求

  • OrderController
	@GetMapping("/reminder/{id}")@ApiOperation("客户催单")public Result reminder(@PathVariable Long id){orderService.reminder(id);return Result.success();}
  • OrderServiceImpl
	public void reminder(Long id) {// 根据id查询订单Orders orders1= orderMapper.getById(id);// 校验订单是否存在if (orders1 == null) {throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);}//通过WebSocket向客户端浏览器推送数据Map map=new HashMap();map.put("type",2);map.put("orderId",id);map.put("content","订单号:"+orders1.getNumber());String Json= JSON.toJSONString(map);webSocketServer.sendToAllClient(Json);}

Day11 数据统计-图形报表

效果如下所示:

在这里插入图片描述

在这里插入图片描述

Apache ECharts

Apache ECharts是一款基于JavaScript的数据可视化图表库,提供直观、生动、可交互、可个性化定制的数据可视化图表。简单来说,它就是一款数据可视化工具。我们只需大致知道它是干啥的,它是在前端使用的,后端开发中我们使用不到。

营业额统计

业务规则:

  • 营业额指订单状态为已完成的订单金额合计
  • 基于可视化报表的折线图展示营业额数据,x轴为日期,y轴为营业额
  • 根据时间选择区间,展示每天的营业额数据

ReportController:注意时间的数据格式

@RestController
@Slf4j
@RequestMapping("/admin/report")
@Api(tags = "数据统计相关接口")
public class ReportController {@Autowiredprivate ReportService reportService;@GetMapping("/turnoverStatistics")@ApiOperation("营业额统计")public Result<TurnoverReportVO> turnoverStatistics(@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin,@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end){log.info("营业额数据统计:{},{}",begin,end);TurnoverReportVO turnoverReportVO=reportService.getTurnoverStatistics(begin,end);return Result.success(turnoverReportVO);}
}

ReportServiceImpl:

这里我的实现方法与课程中略有不同,可以参考一下

public TurnoverReportVO getTurnoverStatistics(LocalDate begin, LocalDate end) {TurnoverReportVO turnoverReportVO=new TurnoverReportVO();//1.封装日期数据//先去得到一个日期集合,包含begin到end中的所有日期List<LocalDate> dateList=new ArrayList<>();dateList.add(begin);while(!begin.equals(end)){begin=begin.plusDays(1);dateList.add(begin);}//将集合转成字符串的同时在每个元素间加一个逗号String dateList1=StringUtils.join(dateList,",");turnoverReportVO.setDateList(dateList1);//2.封装营业额数据//查询对应日期的订单的总营业额List<Double> moneyList=new ArrayList<>();for (LocalDate localDate : dateList) {//根据日期查询状态为已完成的订单的营业额//00:00:00LocalDateTime beginTime=LocalDateTime.of(localDate, LocalTime.MIN);//23:59:59LocalDateTime endTime=LocalDateTime.of(localDate, LocalTime.MAX);Map map=new HashMap();map.put("begin",beginTime);map.put("end",endTime);map.put("status", Orders.COMPLETED);Double money=orderMapper.getSumByMap(map);if(money==null){money=0.0;}moneyList.add(money);}String moneyList1=StringUtils.join(moneyList,",");turnoverReportVO.setTurnoverList(moneyList1);return turnoverReportVO;}

用户统计

ReportController:

@GetMapping("/userStatistics")@ApiOperation("用户统计")public Result<UserReportVO> userStatistics(@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin, @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end){log.info("用户统计:{},{}",begin,end);UserReportVO userReportVO=reportService.getUserStatistics(begin,end);return Result.success(userReportVO);}

ReportServiceImpl:

//用户数据统计public UserReportVO getUserStatistics(LocalDate begin, LocalDate end) {UserReportVO userReportVO=new UserReportVO();//1.封装日期数据//先去得到一个日期集合,包含begin到end中的所有日期List<LocalDate> dateList=new ArrayList<>();dateList.add(begin);while(!begin.equals(end)){begin=begin.plusDays(1);dateList.add(begin);}//将集合转成字符串的同时在每个元素间加一个逗号String dateList1=StringUtils.join(dateList,",");userReportVO.setDateList(dateList1);//2.封装用户总量数据List<Integer> totalList=new ArrayList<>();//3.封装新增用户数量数据List<Integer> newList=new ArrayList<>();for (LocalDate localDate : dateList) {//查询用户表createTime这一天的用户的总量//00:00:00LocalDateTime beginTime=LocalDateTime.of(localDate, LocalTime.MIN);//23:59:59LocalDateTime endTime=LocalDateTime.of(localDate, LocalTime.MAX);Map map=new HashMap();map.put("end",endTime);Integer total=userMapper.countByMap(map);if(total==null){total=0;}totalList.add(total);map.put("begin",beginTime);Integer today= userMapper.countByMap(map);if(today==null){today=0;}newList.add(today);}String userList1=StringUtils.join(totalList,",");userReportVO.setTotalUserList(userList1);String list1=StringUtils.join(newList,",");userReportVO.setNewUserList(list1);return userReportVO;}

订单统计

业务规则:

  • 两条折线,一条代表总订单数,另一条代表有效订单数(状态为已完成的订单)
  • 展示订单总数、有效订单数、订单完成率数据

ReportController:

@GetMapping("/ordersStatistics")@ApiOperation("订单统计")public Result<OrderReportVO> orderStatistics(@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin, @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end){log.info("订单统计:{},{}",begin,end);OrderReportVO orderReportVO=reportService.getOrderReportStatistics(begin,end);return Result.success(orderReportVO);}

ReportServiceImpl:

@Overridepublic OrderReportVO getOrderReportStatistics(LocalDate begin, LocalDate end) {OrderReportVO orderReportVO=new OrderReportVO();//1.封装日期数据List<LocalDate> dateList=new ArrayList<>();dateList.add(begin);while(!begin.equals(end)){begin=begin.plusDays(1);dateList.add(begin);}//将集合转成字符串的同时在每个元素间加一个逗号String dateList1=StringUtils.join(dateList,",");orderReportVO.setDateList(dateList1);//2.订单总数List<Integer> totalOrder=new ArrayList<>();//3.有效订单数List<Integer> realOrder=new ArrayList<>();//每天的订单总数以及有效订单数for (LocalDate localDate : dateList) {//00:00:00LocalDateTime beginTime=LocalDateTime.of(localDate, LocalTime.MIN);//23:59:59LocalDateTime endTime=LocalDateTime.of(localDate, LocalTime.MAX);Map map=new HashMap();map.put("begin",beginTime);map.put("end",endTime);Integer total=orderMapper.getByMap(map);if(total==null){total=0;}totalOrder.add(total);map.put("status",Orders.COMPLETED);Integer real=orderMapper.getByMap(map);if(real==null){real=0;}realOrder.add(real);}String totalOrder1=StringUtils.join(totalOrder,",");String realOrder1=StringUtils.join(realOrder,",");//计算时间区间内的订单总数量Integer sum=0;for (Integer integer : totalOrder) {sum+=integer;}//计算时间区间内的有效订单数量Integer real=0;for (Integer integer : realOrder) {real+=integer;}//计算订单完成率double orderCompletionRate=0.0;if (sum!=0) {orderCompletionRate= (double) real /sum;}orderReportVO.setOrderCompletionRate(orderCompletionRate);orderReportVO.setOrderCountList(totalOrder1);orderReportVO.setValidOrderCountList(realOrder1);orderReportVO.setTotalOrderCount(sum);orderReportVO.setValidOrderCount(real);System.out.println(orderReportVO);return orderReportVO;}

销量排名统计

ReportController:

@GetMapping("/top10")@ApiOperation("销量排名top10")public Result<SalesTop10ReportVO> top10(@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin, @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end){log.info("销量排名top10:{},{}",begin,end);SalesTop10ReportVO salesTop10ReportVO=reportService.getTop10(begin,end);return Result.success(salesTop10ReportVO);}

ReportServiceImpl:

public SalesTop10ReportVO getTop10(LocalDate begin, LocalDate end) {SalesTop10ReportVO salesTop10ReportVO=new SalesTop10ReportVO();//00:00:00LocalDateTime beginTime=LocalDateTime.of(begin, LocalTime.MIN);//23:59:59LocalDateTime endTime=LocalDateTime.of(end, LocalTime.MAX);List<GoodsSalesDTO> goodsSalesDTOList=orderMapper.getSalesTop10(beginTime,endTime);//遍历取出DTO中的numa和number放到对应的集合中去List<String> nameList=new ArrayList<>();List<String> numberList=new ArrayList<>();for (GoodsSalesDTO goodsSalesDTO : goodsSalesDTOList) {nameList.add(goodsSalesDTO.getName());numberList.add(String.valueOf(goodsSalesDTO.getNumber()));}String nameLists=StringUtils.join(nameList,",");String numberLists=StringUtils.join(numberList,",");salesTop10ReportVO.setNameList(nameLists);salesTop10ReportVO.setNumberList(numberLists);return salesTop10ReportVO;}

OrderMapper.xml:

分析一下这里的SQL语句,因为我们要根据订单状态(对应orders表中的status)查订单的名称以及数量(对应order_details表中的number),所以涉及到联表查询。查询前10,所以只需limit 0,10

	<!--统计销量前10--><select id="getSalesTop10" resultType="com.sky.dto.GoodsSalesDTO">select od.name,sum(od.number) number from order_detail od,orders o where od.id=o.id and o.status=5<if test="begin!=null">and order_time &gt; #{begin}</if><if test="end!=null">and order_time &lt; #{end}</if>group by od.name order by number desc limit 0,10</select>

Day12 数据统计-Excel报表

工作台

这里课程中的代码是直接导入的,我还是选择手敲一遍。

工作台展示的数据:

  • 今日数据
  • 订单管理
  • 菜品总览
  • 套餐总览
  • 订单信息

为了简便展示,这里我直接给出一个类中的全部代码了,可以根据注释理解。

  • WorkSpaceController
@RestController
@RequestMapping("/admin/workspace")
@Slf4j
@Api(tags = "工作台相关接口")
public class WorkSpaceController {@Autowiredprivate WorkSpaceService workSpaceService;//查询工作台今日数据@GetMapping("/businessData")@ApiOperation("查询工作台今日数据")public Result<BusinessDataVO> businessData(){log.info("查询工作台今日数据");//获取开始时间LocalDateTime beginTime=LocalDateTime.now().with(LocalTime.MIN);//获取结束时间LocalDateTime endTime=LocalDateTime.now().with(LocalTime.MAX);BusinessDataVO businessDataVO=workSpaceService.getBusinessData(beginTime,endTime);return Result.success(businessDataVO);}//查询订单管理数据@GetMapping("/overviewOrders")@ApiOperation("查询订单管理数据")public Result<OrderOverViewVO> overViewOrders(){log.info("查询订单管理数据");return Result.success(workSpaceService.getOrderOverView());}//查询菜品总览@GetMapping("/overviewDishes")@ApiOperation("查询菜品总览")public Result<DishOverViewVO> overViewDishes(){return Result.success(workSpaceService.getDishOverView());}//查询套餐总览@GetMapping("/overviewSetmeals")@ApiOperation("查询套餐总览")public Result<SetmealOverViewVO> overViewSetmeal(){return Result.success(workSpaceService.getSetmealOvermeal());}
}
  • WorkSpaceService
public interface WorkSpaceService {BusinessDataVO getBusinessData(LocalDateTime beginTime, LocalDateTime endTime);OrderOverViewVO getOrderOverView();DishOverViewVO getDishOverView();SetmealOverViewVO getSetmealOvermeal();
}
  • WorkSpaceServiceImpl(这里很多方法我们都在OrderMapper中已经写好了,直接调用即可)
@Service
public class WorkSpaceServiceImpl implements WorkSpaceService {@Autowiredprivate OrderMapper orderMapper;@Autowiredprivate UserMapper userMapper;@Autowiredprivate DishMapper dishMapper;@Autowiredprivate SetmealMapper setmealMapper;//查询工作台今日数据public BusinessDataVO getBusinessData(LocalDateTime beginTime, LocalDateTime endTime) {BusinessDataVO businessDataVO=new BusinessDataVO();Map map=new HashMap();map.put("begin",beginTime);map.put("end",endTime);//订单总数Integer total=orderMapper.getByMap(map);map.put("status",5);//营业额Double sum = orderMapper.getSumByMap(map);sum = sum == null? 0.0 : sum;//有效订单数Integer real=orderMapper.getByMap(map);//平均客单价double average=0.0;//订单完成率double complete=0.0;if(total!=0&&real!=0){complete= (double) real /total;average=sum/real;}//新增用户数Integer newUser=userMapper.countByMap(map);businessDataVO.setTurnover(sum);businessDataVO.setNewUsers(newUser);businessDataVO.setOrderCompletionRate(complete);businessDataVO.setValidOrderCount(real);businessDataVO.setUnitPrice(average);return businessDataVO;}//查询订单管理数据@Overridepublic OrderOverViewVO getOrderOverView() {OrderOverViewVO orderOverViewVO=new OrderOverViewVO();Map map = new HashMap();map.put("begin", LocalDateTime.now().with(LocalTime.MIN));//待接单map.put("status", Orders.TO_BE_CONFIRMED);Integer status1=orderMapper.getByMap(map);//待派送map.put("status",Orders.CONFIRMED);Integer status2=orderMapper.getByMap(map);//已完成map.put("status",Orders.COMPLETED);Integer status3=orderMapper.getByMap(map);//已取消map.put("status",Orders.CANCELLED);Integer status4=orderMapper.getByMap(map);//全部订单map.put("status",null);Integer status5=orderMapper.getByMap(map);orderOverViewVO.setWaitingOrders(status1);orderOverViewVO.setDeliveredOrders(status2);orderOverViewVO.setCompletedOrders(status3);orderOverViewVO.setCancelledOrders(status4);orderOverViewVO.setAllOrders(status5);return orderOverViewVO;}//查询菜品总览@Overridepublic DishOverViewVO getDishOverView() {DishOverViewVO dishOverViewVO=new DishOverViewVO();Integer on=dishMapper.onStatus();Integer off=dishMapper.offStatus();dishOverViewVO.setSold(on);dishOverViewVO.setDiscontinued(off);return dishOverViewVO;}//查询套餐总览@Overridepublic SetmealOverViewVO getSetmealOvermeal() {SetmealOverViewVO setmealOverViewVO=new SetmealOverViewVO();Integer on=setmealMapper.onStatus();Integer off=setmealMapper.offStatus();setmealOverViewVO.setSold(on);setmealOverViewVO.setDiscontinued(off);return setmealOverViewVO;}
}
  • DishMapper(这里是SQL语句少我使用这种方法,标准的应该是使用动态SQL)
	@Select("select count(id) from dish where status=1")Integer onStatus();@Select("select count(id) from dish where status=0")Integer offStatus();
  • SetmealMapper
	@Select("select count(id) from setmeal where status=1")Integer onStatus();@Select("select count(id) from setmeal where status=0")Integer offStatus();

Apache POI

简介:Apache POI可以处理Office的各种文件格式。允许我们使用POI在Java程序中对Office文件进行读写操作。一般用于处理Excel文件。

实例:

写入Excel文件:

		//在内存中创建一个excel文件XSSFWorkbook excel=new XSSFWorkbook();//在excel文件中创建一个sheet页同时指定其名称为infoXSSFSheet sheet=excel.createSheet("info");//创建行对象,行和列都从0开始,这里我们指定1表示是第二行XSSFRow row= sheet.createRow(1);//创建单元格并写入内容row.createCell(1).setCellValue("姓名");row.createCell(2).setCellValue("爱好");row= sheet.createRow(2);//创建单元格并写入内容row.createCell(1).setCellValue("张三");row.createCell(2).setCellValue("篮球");row= sheet.createRow(3);//创建单元格并写入内容row.createCell(1).setCellValue("李四");row.createCell(2).setCellValue("游泳");//通过输出流将内存中的Excel文件写入到磁盘中FileOutputStream out=new FileOutputStream(new File("E:\\Takeout\\info.xlsx"));excel.write(out);out.close();excel.close();

读取Excel文件:

		InputStream in=new FileInputStream(new File("E:\\Takeout\\info.xlsx"));//读取磁盘上已经存在的Excel文件XSSFWorkbook excel=new XSSFWorkbook(in);//读取Excel文件中第一个Sheet页XSSFSheet sheet= excel.getSheetAt(0);//获取Sheet页中最后一行的的行号(有内容的最后一行)int lastRowNum=sheet.getLastRowNum();for (int i = 1; i <= lastRowNum; i++) {//获取某一行XSSFRow row= sheet.getRow(i);//获取单元格对象String stringCellValue1 = row.getCell(1).getStringCellValue();String stringCellValue2 = row.getCell(2).getStringCellValue();System.out.println(stringCellValue1+" "+stringCellValue2);}excel.close();in.close();

导出Excel报表

业务规则:

  • 导出Excel文件形式的报表文件
  • 导出进30天的运营数据

实现步骤:

  • 设计Excel模板文件
  • 查询近30日的运营数据
  • 将查询到的运营数据写入模板文件内
  • 通过输出流将Excel文件下载到客户端浏览器

实现:

  • ReportController
	@GetMapping("/export")@ApiOperation("导出Excel报表")public Result export(HttpServletResponse response){log.info("导出Excel报表");reportService.export(response);return Result.success();}
  • ReportServiceImpl
	//导出运营数据报表@Overridepublic void export(HttpServletResponse response) {//1.查询数据库,获取近30日的营业数据LocalDate dateBegin=LocalDate.now().minusDays(30);LocalDate dateEnd=LocalDate.now().minusDays(1);//查询概览数据BusinessDataVO businessDataVO=workSpaceService.getBusinessData(LocalDateTime.of(dateBegin,LocalTime.MIN),LocalDateTime.of(dateEnd,LocalTime.MAX));//2.通过POI将数据写入Excel文件中InputStream in=this.getClass().getClassLoader().getResourceAsStream("template/运营数据报表模板.xlsx");try{//基于模板文件创建一个新的Excel文件XSSFWorkbook excel=new XSSFWorkbook(in);//获取报表文件的Sheet页XSSFSheet sheet= excel.getSheet("Sheet1");//填充概览数据-时间sheet.getRow(1).getCell(1).setCellValue("时间:"+dateBegin+"到"+dateEnd);//填充概览数据其他数据//第四行XSSFRow row= sheet.getRow(3);row.getCell(2).setCellValue(businessDataVO.getTurnover());row.getCell(4).setCellValue(businessDataVO.getOrderCompletionRate());row.getCell(6).setCellValue(businessDataVO.getNewUsers());//第五行row= sheet.getRow(4);row.getCell(2).setCellValue(businessDataVO.getValidOrderCount());row.getCell(4).setCellValue(businessDataVO.getUnitPrice());for (int i=0;i<30;i++){LocalDate date=dateBegin.plusDays(i);//查询莫一天的数据BusinessDataVO businessDataVO1=workSpaceService.getBusinessData(LocalDateTime.of(date,LocalTime.MIN),LocalDateTime.of(date,LocalTime.MAX));//获取某一行并填充数据row= sheet.getRow(7+i);row.getCell(1).setCellValue(businessDataVO1.toString());row.getCell(2).setCellValue(businessDataVO1.getTurnover());row.getCell(3).setCellValue(businessDataVO1.getValidOrderCount());row.getCell(4).setCellValue(businessDataVO1.getOrderCompletionRate());row.getCell(5).setCellValue(businessDataVO1.getUnitPrice());row.getCell(6).setCellValue(businessDataVO1.getNewUsers());}//3.通过输出流将Excel文件下载到客户端浏览器ServletOutputStream out= response.getOutputStream();excel.write(out);//关闭资源out.close();excel.close();}catch (Exception e){e.printStackTrace();}

这里我们需要注意的一个地方,这里老师没有加上这个后缀,不加的话我这里会报错:

在这里插入图片描述
苍穹外卖的学习就到这里啦,完结撒花!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/716858.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

代码随想录算法训练营第三十天| 回溯篇总结

文章目录 前言一、组合问题二、切割问题三、子集问题四、排列问题五、性能分析总结 前言 回溯法就是暴力搜索&#xff0c;并不是什么高效的算法&#xff0c;最多再剪枝一下。 组合问题&#xff1a;N个数里面按一定规则找出k个数的集合 排列问题&#xff1a;N个数按一定规则全…

【黑马程序员】STL之set和map容器

文章目录 set/multiset容器set基本概念简介区别 set的构造和赋值功能描述函数原型代码示例运行结果 set的大小和交换功能描述函数原型代码示例运行结果 set的插入和删除功能描述函数原型代码示例运行结果 set查找和统计函数原型代码示例运行结果 set和multiset区别区别代码示例…

JVM(6)

JMM JVM定义了一种Java内存模型来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的内存访问效果.在此之前,C/C直接使用物理硬件和操作系统的内存模型,因此,会由于不同平台下的内存模型差异,有可能导致程序在一套平台上并发完全正常,而在另…

深入解剖指针(4)

个人主页&#xff08;找往期文章包括但不限于本期文章中不懂的知识点&#xff09;&#xff1a; 我要学编程(ಥ_ಥ)-CSDN博客 目录 回调函数 qsort使用举例 使用qsort函数排序整型数据 使用qsort排序结构数据 qsort函数的模拟实现 回调函数 回调函数就是一个通过函数指…

《Spring Security 简易速速上手小册》第10章 未来趋势与高级话题(2024 最新版)

文章目录 10.1 云原生安全性趋势10.1.1 基础知识10.1.2 重点案例&#xff1a;保护微服务通信10.1.3 拓展案例 1&#xff1a;容器安全最佳实践10.1.4 拓展案例 2&#xff1a;自动化安全审计和合规性检查 10.2 反应式编程与 Spring Security10.2.1 基础知识10.2.2 重点案例&#…

nginx-图片模块

./configure --with-http_image_filter_module location / {root html;index index.html index.htm;if ($arg_w "") {set $arg_w -;}if ($arg_h "") {set $arg_h -;}image_filter resize $arg_w $arg_h;image_filter_jpeg_quality 95; } 访问: 1234…

CSS锥形渐变:conic-gradient()

画一个扇形图&#xff0c;使用常规方法可能很难画&#xff0c;但是用锥形渐变的话非常好画 <style>.pattern{width: 100px; height: 100px;border-radius: 50%;background: conic-gradient(yellow 30deg , black 30deg , black 90deg , yellow 90deg ,yellow 150d…

Git分布式版本控制系统——git学习准备工作

一、Git仓库介绍 开发者可以通过Git仓库来存储和管理文件代码&#xff0c;Git仓库分为两种&#xff1a; 本地仓库&#xff1a;开发人员自己电脑上的Git仓库 远程仓库&#xff1a;远程服务器上的Git仓库 仓库之间的运转如下图&#xff1a; commit&#xff1a;提交&#xff…

Decoupled Knowledge Distillation解耦知识蒸馏

Decoupled Knowledge Distillation解耦知识蒸馏 现有的蒸馏方法主要是基于从中间层提取深层特征&#xff0c;而忽略了Logit蒸馏的重要性。为了给logit蒸馏研究提供一个新的视角&#xff0c;我们将经典的KD损失重新表述为两部分&#xff0c;即目标类知识蒸馏&#xff08;TCKD&a…

c++之旅——第四弹

大家好啊&#xff0c;这里是c之旅第三弹&#xff0c;跟随我的步伐来开始这一篇的学习吧&#xff01; 如果有知识性错误&#xff0c;欢迎各位指正&#xff01;&#xff01;一起加油&#xff01;&#xff01; 创作不易&#xff0c;希望大家多多支持哦&#xff01; 本篇文章的主…

如何对比 MySQL 主备数据的一致性?

随着业务范围的扩大&#xff0c;很多企业为了保障核心业务的高可用性&#xff0c;选择了 MySQL 主从架构&#xff0c;这一套方案通常具备主备数据同步、数据备份与恢复、读写分离、高可用切换等特性&#xff0c;是一种相当成熟可靠的数据库架构方案。然而这套方案在特定情况下可…

Redis小白入门教程

Redis入门教程 1. Redis入门1.1 Redis简介1.2 Redis服务启动与停止1.2.1 Redis下载1.2.2 服务启动命令1.2.3 客户端连接命令1.2.4 修改Redis配置文件 2. Redis数据类型2.1 五种常用数据类型介绍2.1.1 字符串操作命令2.1.2 哈希操作命令2.1.3 列表操作命令2.1.4 集合操作命令2.1…

双周回顾#006 - 这三个月

断更啦~~ 上次更新时间 2023/11/23, 断更近三个月的时间。 先狡辩下&#xff0c;因为忙、着实忙。因为忙&#xff0c;心安理得给断更找了个借口&#xff0c;批评下自己~~ 这三个月在做啥&#xff1f;跨部门援助&#xff0c;支援公司互联网的 ToC 项目&#xff0c;一言难尽。 …

【C语言】InfiniBand 驱动mlx4_ib_init和mlx4_ib_cleanup

一、中文讲解 这两个函数是Linux内核模块中对于Mellanox InfiniBand 驱动程序初始化和清理的函数。 mlx4_ib_init()函数是模块初始化函数&#xff0c;使用__init宏标注&#xff0c;表示该函数只在模块加载时运行一次。 函数执行的步骤如下&#xff1a; 1. 通过alloc_ordered_w…

数据结构——lesson5栈和队列详解

hellohello~这里是土土数据结构学习笔记&#x1f973;&#x1f973; &#x1f4a5;个人主页&#xff1a;大耳朵土土垚的博客 &#x1f4a5; 所属专栏&#xff1a;数据结构学习笔记 &#x1f4a5;对于顺序表链表有疑问的都可以在上面数据结构的专栏进行学习哦~感谢大家的观看与…

ElasticSearch开篇

1.ElasticSearch简介 1.1 ElasticSearch&#xff08;简称ES&#xff09; Elasticsearch是用Java开发并且是当前最流行的开源的企业级搜索引擎。能够达到实时搜索&#xff0c;稳定&#xff0c;可靠&#xff0c;快速&#xff0c;安装使用方便。 1.2 ElasticSearch与Lucene的关…

模拟器抓HTTP/S的包时如何绕过单向证书校验(XP框架)

模拟器抓HTTP/S的包时如何绕过单向证书校验&#xff08;XP框架&#xff09; 逍遥模拟器无法激活XP框架来绕过单向的证书校验&#xff0c;如下图&#xff1a; ​​ 解决办法&#xff1a; 安装JustMePlush.apk安装Just Trust Me.apk安装RE管理器.apk安装Xposedinstaller_逍遥64位…

智能边缘小站 CloudPond(低延迟、高带宽和更好的数据隐私保护)

智能边缘小站 CloudPond(低延迟、高带宽和更好的数据隐私保护) 边缘小站的主要功能是管理用户在线下部署的整机柜设施&#xff0c;一个边缘小站关联一个华为云指定的区域和一个用户指定的场地&#xff0c;相关的资源运行状况监控等。 边缘计算 迈入5G和AI时代&#xff0c;新…

利用redis实现秒杀功能

6、秒杀优化 这个是 图灵 的redis实战里面的一个案例 6.1 秒杀优化-异步秒杀思路 我们来回顾一下下单流程 当用户发起请求&#xff0c;此时会请求nginx&#xff0c;nginx会访问到tomcat&#xff0c;而tomcat中的程序&#xff0c;会进行串行操作&#xff0c;分成如下几个步骤…

基于单片机的红外遥控解码程序设计与实现

摘要:该文介绍基于士兰半导体芯片(SC6122)的红外发射遥控器,通过单片机解码程序,实现红外遥控信号的解码和接收。红外接收头与单片机特定的引脚连接,通过设置单片机定时计数器,采样来自红外接收头的高、低电平宽度解码遥控信号。该解码程序设计主要应用在LED数码显示控制…