苍穹外卖学习 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.rhkb.cn/news/268160.html

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

相关文章

ElasticSearch之suggester API

写在前面 当我们在使用搜索引擎进行的查询到时候&#xff0c;如果是输入错误的话&#xff0c;搜索引擎会给出一些搜索建议&#xff0c;如下&#xff1a; 在es中也提供了类似的功能&#xff0c;叫做suggester API。 1&#xff1a;原理和种类 原理是将查询的信息分为很多个词…

Python并发编程:多线程-信号量,Event,定时器

一 信号量 信号量也是一把锁&#xff0c;可以指定信号量为5&#xff0c;对比互斥锁同一时间只能有一个任务抢到锁去执行&#xff0c;信号量同一时间可以有5个任务拿到锁去执行&#xff0c;如果说互斥锁是合租房屋的人去抢一个厕所&#xff0c;那么信号量就相当于一群路人争抢公…

基于springboot+vue的在线考试系统(源码+论文)

文章目录 目录 文章目录 前言 一、功能设计 二、功能页面 三、论文 前言 现在我国关于在线考试系统的发展以及专注于对无纸化考试的完善程度普遍不高&#xff0c;关于对考试的模式还大部分还停留在纸介质使用的基础上&#xff0c;这种教学模式已不能解决现在的时代所产生的考试…

前端【技术类】资源学习网站整理(那些年的小网站)

学习网站整理 值得分享的视频博主&#xff1a;学习网站链接 百度首页的资源收藏里的截图&#xff08;排列顺序没有任何意义&#xff0c;随性而已~&#xff09;&#xff0c;可根据我标注的关键词百度搜索到这些网站呀&#xff0c;本篇末尾会一一列出来&#xff0c;供大家学习呀 …

3.3日学习打卡----初学Redis(一)

3.3日学习打卡 目录&#xff1a; 3.3日学习打卡NoSQL为什么要用NoSQL什么是NoSQL?NoSQL的四大分类关系型数据库和非关系型数据及其区别NoSQL经典应用 RedisRedis是什么?Linux下安装RedisDocker下安装Redis基本知识 NoSQL 为什么要用NoSQL 单机Mysql的美好年代 在90年代&…

探讨苹果 Vision Pro 的 AI 数字人形象问题

Personas 的设计模糊性&#xff1a; 部分人认为这种模糊设计可能是出于安全考虑&#x1f6e1;️。安全角度&#xff1a;Personas 代表着你的 AI 数字形象&#xff0c;在创建时&#xff0c;它相当于你的 AVP&#xff08;生物识别扫描器的存在增加了冒充的难度&#xff09;。如果…

力扣1892 页面推荐Ⅱ

力扣1892&#xff0c;页面推荐Ⅱ&#xff0c;为一个社交媒体网站实施一个页面推荐系统。如果页面被user_id的 至少一个朋友喜欢 &#xff0c;而 不被user_id喜欢 &#xff0c;你的系统将 推荐 一个页面到user_id。 目录 题目描述 解题思路 完整代码 优化 题目描述 表&…

python笔记_程序流程控制

A&#xff0c;顺序控制 程序从上到下逐行执行 python定义变量时&#xff0c;会合法地向前引用 age 1 age2 age 1 age2 age 1 age 1 ——>错误&#xff0c;age应在age2之前 B&#xff0c;分支控制 1&#xff0c;单分支if 语法 if 条件表达式 &#xff1a; 代码块 说明…

雾锁王国服务器配置怎么选择?阿里云和腾讯云

雾锁王国/Enshrouded服务器CPU内存配置如何选择&#xff1f;阿里云服务器网aliyunfuwuqi.com建议选择8核32G配置&#xff0c;支持4人玩家畅玩&#xff0c;自带10M公网带宽&#xff0c;1个月90元&#xff0c;3个月271元&#xff0c;幻兽帕鲁服务器申请页面 https://t.aliyun.com…

Unity UGUI之Scrollbar基本了解

Unity的Scrollbar组件是用于在UI中创建滚动条的组件之一。滚动条通常与其他可滚动的UI元素&#xff08;如滚动视图或列表&#xff09;一起使用&#xff0c;以便用户可以在内容超出可见区域时滚动内容。 以下是Scrollbar的基本信息和用法: 1、创建 在Unity的Hierarchy视图中右…

Springboot+vue的考勤管理系统(有报告)。Javaee项目,springboot vue前后端分离项目。

演示视频&#xff1a; Springbootvue的考勤管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot vue前后端分离项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层…

181基于matlab的利用LMS算法、格型LMS算法、RLS算法、LSL算法来估计线性预测模型参数a1和a2

基于matlab的利用LMS算法、格型LMS算法、RLS算法、LSL算法来估计线性预测模型参数a1和a2&#xff1b;预测信号由二阶线性预测模型产生。2.利用LMS算法和RLS算法将一个叠加有噪声的信号实现噪声消除&#xff0c;恢复原始信号。有22页试验分析文档。&#xff08;包括程序在内&…

【C++】vector的使用和模拟实现(超级详解!!!!)

文章目录 前言1.vector的介绍及使用1.1 vector的介绍1.2 vector的使用1.2.1 vector的定义1.2.2 vector iterator 的使用1.2.3 vector 空间增长问题1.2.3 vector 增删查改1.2.4 vector 迭代器失效问题。&#xff08;重点!!!!!!&#xff09;1.2.5 vector 在OJ中有关的练习题 2.ve…

项目设计:基于Qt和百度AI的车牌识别系统(嵌入式ARM)

基于Qt和百度AI智能云实现的智能车牌识别系统&#xff0c;具体可实现为停车场管理系统、智能计费停车系统…等。 1.系统实现思路及框架 1.1实现思路 要实现一个车牌识别系统&#xff0c;有多种方法&#xff0c;例如用opencv图像算法实现&#xff0c;或用第三方算法接口&#x…

StarRocks——Stream Load 事务接口实现原理

目录 前言 一、StarRocks 数据导入 二、StarRocks 事务写入原理 三、InLong 实时写入StarRocks原理 3.1 InLong概述 3.2 基本原理 3.3 详细流程 3.3.1 任务写入数据 3.3.2 任务保存检查点 3.3.3 任务如何确认保存点成功 3.3.4 任务如何初始化 3.4 Exactly Once 保证…

Presto简介、部署、原理和使用介绍

Presto简介、部署、原理和使用介绍 1. Presto简介 1-1. Presto概念 ​ Presto是由Facebook开发的一款开源的分布式SQL查询引擎&#xff0c;最初于2012年发布&#xff0c;并在2013年成为Apache项目的一部分&#xff1b;Presto 作为现在在企业中流行使用的即席查询框架&#x…

Matlab偏微分方程拟合 | 源码分享 | 视频教程

专栏导读 作者简介&#xff1a;工学博士&#xff0c;高级工程师&#xff0c;专注于工业软件算法研究本文已收录于专栏&#xff1a;《复杂函数拟合案例分享》本专栏旨在提供 1.以案例的形式讲解各类复杂函数拟合的程序实现方法&#xff0c;并提供所有案例完整源码&#xff1b;2.…

三天学会阿里分布式事务框架Seata-seata事务日志mysql持久化配置

锋哥原创的分布式事务框架Seata视频教程&#xff1a; 实战阿里分布式事务框架Seata视频教程&#xff08;无废话&#xff0c;通俗易懂版&#xff09;_哔哩哔哩_bilibili实战阿里分布式事务框架Seata视频教程&#xff08;无废话&#xff0c;通俗易懂版&#xff09;共计10条视频&…

重学SpringBoot3-自动配置机制

重学SpringBoot3-自动配置机制 引言Spring Boot 自动配置原理示例&#xff1a;Spring Boot Web 自动配置深入理解总结相关阅读 引言 Spring Boot 的自动配置是其最强大的特性之一&#xff0c;它允许开发者通过最少的配置实现应用程序的快速开发和部署。这一切都得益于 Spring …

【C++】set、multiset与map、multimap的使用

目录 一、关联式容器二、键值对三、树形结构的关联式容器3.1 set3.1.1 模板参数列表3.1.2 构造3.1.3 迭代器3.1.4 容量3.1.5 修改操作 3.2 multiset3.3 map3.3.1 模板参数列表3.3.2 构造3.3.3 迭代器3.3.4 容量3.3.5 修改操作3.3.6 operator[] 3.4 multimap 一、关联式容器 谈…