Spark项目实战-卡口流量统计

news2024/11/15 17:36:15

一、卡口介绍

在这里插入图片描述
卡口摄像头正对车道安装,拍摄正面照片。
功能:抓拍正面特征

这种摄像头多安装在国道、省道、高速公路的路段上、或者城区和郊区交接的主要路口,用来抓拍超速、进出城区车辆等行为。它进行的是车辆正面抓拍,可以清晰地看到驾驶员及前台乘客的面容及行为。有一些则是专门摄像车的尾部,所以当车开过此类测速摄像头后不要马上提速,建议至少要跑出500米后再提速。这就是有人认为的没有超速为什么也照样被拍的原因。此类摄像头应该是集成照明设备。

在这里插入图片描述

在这里插入图片描述

卡口:三车道、三个摄像头共同组成卡口A

二、表介绍

monitor_flow_action

日期卡口ID摄像头编号车牌号拍摄时间车速道路ID区域ID
datemonitor_idcamera_idcaraction_timespeedroad_idarea_id
2018-11-05000533745京C601592018-11-05 20:43:471983604

monitor_camera_info

卡扣号摄像头编号
monitor_idcamera_id
000680522
000629268

areaId2AreaInfoRDD

area_idarea_name
区域ID区域Name

tmp_car_flow_basic
= areaId2AreaInfoRDD + monitor_flow_action

卡口ID车牌号道路ID区域ID区域Name
monitor_idcarroad_idarea_idarea_name
0005京C601593604

tmp_area_road_flow_count

area_nameroad_idcar_countmonitor_infos
区域ID道路ID车count详情
0436500006=20|0002=30

areaTop3Road

area_nameroad_idcar_countmonitor_infosflow_level
区域ID道路ID车count详情流量等级
0436500006=20|0002=30D

三、分析需求

3.1 卡口正常数、异常数

在这里插入图片描述

统计异常摄像头的思路:流量表 rightJoin 摄像头表,过滤流量表为空的

//------------------------------统计卡口摄像头通过的车辆的合计----------------------------
//| 2023-10-24 | 0005 | 33745 | 京C60159 | 2018-11-05 20:43:47 | 198 | 36 | 04 |
val flowDF:DataFrame =  sparkSession.sql("select * from monitor_flow_action where data = '2023-10-24' ")

//((0005:33745),1)
val mcRdd: RDD[(String, Int)] = flowDF.map(e => Tuple2((e.getString(1) + ":" + e.getString(2)),1)).rdd

//((0005:33745),99)
val flowRdd: RDD[(String, Int)] = mcRdd.reduceByKey(_+_)


//------------------------------统计卡口所有的摄像头----------------------------
//| 0006 | 29268 |
val cameraDF:DataFrame = sparkSession.sql("select * from monitor_camera_info")

//((0006,29268),1)
val cameraRdd: RDD[(String, Int)] = cameraDF.map(e => ((e.getString(0) + ":" + e.getString(1)),1)).rdd

//------------------------------合并车流量和摄像头RDD----------------------------
val allRDD: RDD[(String, (Option[Int], Int))] = flowRdd.rightOuterJoin(cameraRdd).filter(e => e._2._1.isEmpty)

在这里插入图片描述

3.2 camera 正常数、异常数、详情

    //---------------------开始操作车流量信息,假设任务编号为1 日期参数为今天
    val flowInfo: RDD[(String, String)] = sparkSession.sql("select * from monitor_flow_action where date = '2021-08-23' ").rdd.map(row => (row.getString(1), row)).groupByKey().map(ele => {
      val monitorId: String = ele._1
      val cameraIdSet = new mutable.HashSet[String]()
      ele._2.foreach(row => cameraIdSet.add(row.getString(2)))
      //拼接字符串
      val info: String = Constants.FIELD_MONITOR_ID + "=" + monitorId + "|" + Constants.FIELD_AREA_ID + "=浦东新区|" + Constants.FIELD_CAMERA_IDS + "=" + cameraIdSet.mkString("-") + "|" + Constants.FIELD_CAMERA_COUNT + "=" + cameraIdSet.size + "|" + Constants.FIELD_CAR_COUNT + "=" + ele._2.size
      //返回结果
      (monitorId, info)
    })


    //-----------------------开始操作摄像头数据
    val monitorInfo: RDD[(String, String)] = sparkSession.sql("select * from monitor_camera_info").rdd.map(row => (row.getString(0), row.getString(1))).groupByKey().map(ele => {
      val monitorId: String = ele._1
      //拼接字符串
      val info: String = Constants.FIELD_CAMERA_IDS + "=" + ele._2.toList.mkString("-") + "|" + Constants.FIELD_CAMERA_COUNT + "=" + ele._2.size
      //返回结果
      (monitorId, info)

    //-----------------------将数据Join到一起
    monitorInfo.leftOuterJoin(flowInfo).foreach(println)
    })

在这里插入图片描述

3.3 车流量最多的TopN卡口

//开始计算
    val fRdd: RDD[Row] = sparkSession.sql("select * from monitor_flow_action where date = '2021-08-23' ").rdd


    fRdd.map(row => (row.getString(7) + "_" + row.getString(6) + "&" + (Math.random() * 30 + 10).toInt, 1)).reduceByKey(_ + _).map(ele => {
      val area_road_random = ele._1
      val count = ele._2
      (area_road_random.split("_")(0), area_road_random.split("_")(1).split("&")(0) + "_" + count)
    })
      .groupByKey()
      .map(ele => {
      val map = new mutable.HashMap[String, Int]()
      ele._2.foreach(e => {
        val key = e.split("_")(0)
        val value = e.split("_")(1).toInt
        map.put(key, map.get(key).getOrElse(0) + value)
      })
      "区划【" + ele._1 + "】车辆最多的三条道路分别为:" + map.toList.sortBy(_._2).takeRight(3).reverse.mkString("-")
    })
      .foreach(println)

在这里插入图片描述

3.4 区域各路速度

随机抽取N个车辆信息,对这些数据可以进行多维度分析(因为随机抽取出来的N个车辆信息可以很权威的代表整个区域的车辆)

val sRdd: RDD[Row] = sparkSession.sql("select * from monitor_flow_action where date = '2021-08-23' ").rdd

    sRdd.map(e=>{
      ((e.getString(7),e.getString(6)),e.getString(5).toInt)
    })
      .groupByKey()
      .map(e=>{
        val list: List[Int] = e._2.toList
        val i: Int = list.sum/list.size
        (e._1._1,(e._1._2,i))
      })
      .groupByKey()
      .map(e=>{
        val tuples = e._2.toList.sortBy(_._2).reverse.take(3)
        var strBui: StringBuilder = new StringBuilder
        for (i <- tuples ){
          val str: String = i._1 + "-均速度为:" + i._2
          strBui.append(">>>"+str)
        }
        (e._1,strBui)
      })
      .foreach(println)

在这里插入图片描述

3.5 区域中高速数量

在这里插入图片描述

object Hello04MonitorTopNSpeed {
  def main(args: Array[String]): Unit = {
    val sparkSession = ContextUtils.getSparkSession("Hello04MonitorTopNSpeed")
    MockDataUtil.mock2view(sparkSession)
    //---------------------开始操作车流量信息,假设任务编号为1 日期参数为今天
    val flowRdd: RDD[Row] = sparkSession.sql("select * from " + MockDataUtil.MONITOR_FLOW_ACTION + " where date = '2021-08-20' ").rdd

    val monitor2speedRDD: RDD[(String, Iterable[String])] = flowRdd.map(row => (row.getString(1), row.getString(5))).groupByKey()

    val speedCount2monitorRDD: RDD[(SpeedCount, String)] = monitor2speedRDD.map(ele => {
      //获取卡口号
      val monitorId: String = ele._1
      //声明一个Map[0,60,100,120]
      var high = 0;
      var normal = 0;
      var low = 0;
      //获取所有的速度的车辆技术
      ele._2.foreach(speed => {
        //判断速度
        if (speed.toInt > 100) {
          high += 1
        } else if (speed.toInt > 60) {
          normal += 1
        } else {
          low += 1
        }
      })
      //创建速度对象
      (SpeedCount(high, normal, low), monitorId)
    })

    speedCount2monitorRDD.sortByKey(false).map(x => (x._2, x._1)).foreach(println)

  }
}

case class SpeedCount(high: Int, normal: Int, low: Int) extends Ordered[SpeedCount] with KryoRegistrator {
  override def compare(that: SpeedCount): Int = {
    var result = this.high - that.high
    if (result == 0) {
      result = this.normal - that.normal
      if (result == 0) {
        result = this.low - that.low
      }
    }
    return result
  }

  override def registerClasses(kryo: Kryo): Unit = {
    kryo.register(SpeedCount.getClass)
  }
}


在这里插入图片描述

3.6 指定卡口对应卡口车辆轨迹

在这里插入图片描述

def main(args: Array[String]): Unit = {
    val sparkSession = ContextUtils.getSparkSession("Hello04MonitorTopNSpeed")
    MockDataUtil.mock2view(sparkSession)
    //获取数据
    val area01Rdd: RDD[Row] = sparkSession.sql("select * from " + MockDataUtil.MONITOR_FLOW_ACTION + " where date = '2021-08-23' and area_id = '01' ").rdd
    val area02Rdd: RDD[Row] = sparkSession.sql("select * from " + MockDataUtil.MONITOR_FLOW_ACTION + " where date = '2021-08-23' and area_id = '02' ").rdd

    val area01CarRdd = area01Rdd.map(row => (row.getString(3), row.getString(7))).groupByKey()
    val area02CarRdd = area02Rdd.map(row => (row.getString(3), row.getString(7))).groupByKey()

    area01CarRdd.join(area02CarRdd).foreach(println)

  }

在这里插入图片描述

3.7 行车轨迹

在这里插入图片描述

 def main(args: Array[String]): Unit = {    
 	val sparkSession = ContextUtils.getSparkSession("AreaCar")    
 	MockDataUtil.mock2view(sparkSession)
	 //查询 车子行驶轨迹 跟车分析    
 	val c1Rdd: RDD[Row] = sparkSession.sql("select * from " + MockDataUtil.MONITOR_FLOW_ACTION + " where date = '2021-08-23' ").rdd    
 	val carRdd: RDD[(String, StringBuilder)] = c1Rdd.map(e => {      (e.getString(3), (e.getString(4), e.getString(6), e.getString(2)))    })
 		.groupByKey()      
 		.map(e => {        
 			val tuples: List[(String, String, String)] = e._2.toList.sortBy(_._1)        
 			val list = new StringBuilder        
 			for (i <- tuples) {          
 				//println(i)          
 				val str: String = i._2 + ":" + i._3          
 				list.append(str + "-")        
 			}        
 			(e._1, list)      
 	})    
 	//carRdd.foreach(println) 
}

在这里插入图片描述

3.9 车辆套牌

在这里插入图片描述

  def main(args: Array[String]): Unit = {

    val sparkSession = ContextUtils.getSparkSession("AreaCar")
    MockDataUtil.mock2view(sparkSession)
//假设任何的卡口距离都是 10分钟车程 ,如果同一分钟出现在不同的卡口就怀疑是套牌
    
    val deckRdd: RDD[Row] = sparkSession.sql("select * from " + MockDataUtil.MONITOR_FLOW_ACTION + " where date = '2021-08-23' ").rdd
    deckRdd.map(e => {
        val dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
        (e.getString(3), (dateFormat.parse(e.getString(4)),e.getString(1)))
    }).groupByKey(1)
      .map(e => {
          val list: List[(util.Date, String)] = e._2.toList.sortBy(x=>x._1)
          var bool = false
          var d: util.Date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2021-08-23 00:00:00")
          var mid="?"
          for (i <- list) {
              if (d.getTime - i._1.getTime < 600000 && i._2!=mid )
              bool = true
              d = i._1
              mid=i._2
          }
          (e._1, bool)
      })
      .filter(f => f._2)
      .foreach(println)
  }

在这里插入图片描述

3.10 车辆抽样-蓄水池抽样法

在这里插入图片描述

    def main(args: Array[String]): Unit = {
    
      val sparkSession = ContextUtils.getSparkSession("Hello04MonitorTopNSpeed")
      MockDataUtil.mock2view(sparkSession)
    
      //获取数据
      val flowRdd: RDD[Row] = sparkSession.sql("select * from " + MockDataUtil.MONITOR_FLOW_ACTION + " where date = '2021-08-21' ").rdd
      //yyyy-MM-dd_HH , row
      val hourRDD: RDD[(String, Row)] = flowRdd.map(row => (DateUtils.getDateHour(row.getString(4)), row))
    
      //车流量的总数,并进行广播
      val flowAllCount: Long = hourRDD.count()
      val broadcastFlowAllCount: Broadcast[Long] = sparkSession.sparkContext.broadcast(flowAllCount)
    
      //计算每个小时的比例 并进行广播
      val hourRatio: collection.Map[String, Double] = hourRDD.countByKey().map(e => {
          (e._1, e._2 * 1.0 / broadcastFlowAllCount.value)
      })
      val broadcastHourRatio: Broadcast[collection.Map[String, Double]] = sparkSession.sparkContext.broadcast(hourRatio)
    
      //开始进行抽样
      val sampleRDD: RDD[Row] = hourRDD.groupByKey().flatMap(ele => {
          val hour: String = ele._1
          val list: List[Row] = ele._2.iterator.toList
          
          //计算本时段要抽样的数据量
          val sampleRatio: Double = broadcastHourRatio.value.get(hour).getOrElse(0)
          val sampleNum: Long = Math.round(sampleRatio * 100)
          //开始进行取样(蓄水池抽样)
          val sampleList: ListBuffer[Row] = new ListBuffer[Row]()
          sampleList.appendAll(list.take(sampleNum.toInt))
          for (i <- sampleNum until list.size) {
              //随机生成一个数字
              val num = (Math.random() * list.size).toInt
              if (num < sampleNum) {
                  sampleList.update(num, list(i.toInt))
              }
          }
          sampleList
      })
      sampleRDD.foreach(println)
  }

在这里插入图片描述

3.11 道路转换率

在这里插入图片描述

  def main(args: Array[String]): Unit = {
     
    //创建会话
    val sparkSession = ContextUtils.getSparkSession("Hello07MonitorConvertRatio")
    MockDataUtil.mock2view(sparkSession)
    //开始计算
    val flowRdd: RDD[Row] = sparkSession.sql("select * from " + MockDataUtil.MONITOR_FLOW_ACTION + " where date = '2021-08-23' ").rdd
     
    //计算每个卡口的总通车量
    val monitorCountMap: collection.Map[String, Long] = flowRdd.map(row => (row.getString(1), row)).countByKey()
       
    //计算卡口到卡口的通行率
    val sortRDD: RDD[(String, List[Row])] = flowRdd.map(row => (row.getString(3), row)).groupByKey().map(ele => (ele._1, ele._2.iterator.toList.sortBy(_.getString(4))))
    val m2mMap: collection.Map[String, Long] = sortRDD.flatMap(ele => {
        //存放映射关系
        val map: mutable.HashMap[String, Int] = mutable.HashMap[String, Int]()
        val list: List[Row] = ele._2.toList
        for (i <- 0 until list.size; j <- i + 1 until list.size) {
            //拼接Key
            val key = list(i).getString(1) + "->" + list(j).getString(1)
            map.put(key, map.get(key).getOrElse(0) + 1);
        }

        //返回结果
        map.toList
    }).countByKey()
     
    //开始进行计算
    m2mMap.foreach(ele => {
        println("卡口[" + ele._1 + "]的转换率为:" + ele._2.toDouble / monitorCountMap.get(ele._1.split("->")(0)).get)
    })
}

在这里插入图片描述

3.12 区域通过的TopN卡口

  def main(args: Array[String]): Unit = {
    
    //创建会话
    val sparkSession = ContextUtils.getSparkSession("Hello07MonitorConvertRatio")
    MockDataUtil.mock2view(sparkSession)
    //开始计算
    val flowRdd: RDD[Row] = sparkSession.sql("select * from " + MockDataUtil.MONITOR_FLOW_ACTION + " where date = '2021-08-23' ").rdd
    
    //开始计算
    flowRdd.map(row => (row.getString(7) + "_" + row.getString(6) + "&" + (Math.random() * 30 + 10).toInt, 1)).reduceByKey(_ + _).map(ele => {
        val area_road_random = ele._1
        val count = ele._2
        (area_road_random.split("_")(0), area_road_random.split("_")(1).split("&")(0) + "_" + count)
    }).groupByKey().map(ele => {
        val map = new mutable.HashMap[String, Int]()
        ele._2.foreach(e => {
            val key = e.split("_")(0)
            val value = e.split("_")(1).toInt
            map.put(key, map.get(key).getOrElse(0) + value)
        })
        "区划【" + ele._1 + "】车辆最多的三条道路分别为:" + map.toList.sortBy(_._2).takeRight(3).reverse.mkString("-")
    }).foreach(println)
}

areaId2DetailInfos

        "SELECT "
         "monitor_id,"
         "car,"
         "road_id,"
         "area_id "
         "FROM traffic.monitor_flow_action "
         "WHERE date >= '"startDate"'"
                 "AND date <= '"endDate"'"




areaId2AreaInfoRDD

areaid          areaname




tmp_car_flow_basic = monitor_flow_action  areaId2AreaInfoRDD

monitor_id car road_id  area_id area_name 





统计各个区域各个路段车流量的临时表

area_name  road_id    car_count      monitor_infos
  海淀区    01             100      0001=20|0002=30|0003=50







注册成临时表tmp_area_road_flow_count

"SELECT "
     "area_name,"
         "road_id,"
         "count(*) car_count,"
        //group_concat_distinct 统计每一条道路中每一个卡扣下的车流量
         "group_concat_distinct(monitor_id) monitor_infos "//0001=20|0002=30
 "FROM tmp_car_flow_basic "
 "GROUP BY area_name,road_id"




0001=20|0002=30




insert into areaTop3Road

"SELECT "
       "area_name,"
       "road_id,"
       "car_count,"
       "monitor_infos, "
       "CASE "
               "WHEN car_count > 170 THEN 'A LEVEL' "
               "WHEN car_count > 160 AND car_count <= 170 THEN 'B LEVEL' "
               "WHEN car_count > 150 AND car_count <= 160 THEN 'C LEVEL' "
               "ELSE 'D LEVEL' "
      "END flow_level "
"FROM ("
       "SELECT "
               "area_name,"
               "road_id,"
               "car_count,"
               "monitor_infos,"
               "row_number() OVER (PARTITION BY area_name ORDER BY car_count DESC) rn "
       "FROM tmp_area_road_flow_count "
       ") tmp "
"WHERE rn <=3"


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

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

相关文章

基于springboot+vue实现MOBA类游戏攻略平台项目【项目源码+论文说明】计算机毕业设计

基于springbootvue实现MOBA类游戏攻略平台 摘要 随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理系统应运而生&a…

postgresql14-表空间的管理(五)

基本概念 表空间tablespace在postgresql中&#xff0c;表示数据库对象&#xff08;比如表或索引&#xff09;的存放目录。当表被访问时&#xff0c;系统通过表空间定位到对应数据文件所在的位置。 优势&#xff1a; 1、如果数据库集群所在的初始磁盘分区或磁盘卷的空间不足&a…

改善游戏体验:数据分析与可视化的威力

当今&#xff0c;电子游戏已经超越了娱乐&#xff0c;成为一种文化现象&#xff0c;汇聚了全球数十亿的玩家。游戏制作公司正采用越来越复杂的技术来提高游戏质量&#xff0c;同时游戏数据分析和可视化工具变得不可或缺。 数据的力量&#xff1a;解析游戏体验 游戏制作涉及到大…

【深度学习】生成对抗网络(GANs)详解!

一、概述 生成对抗网络(Generative Adversarial Networks)是一种无监督深度学习模型&#xff0c;用来通过计算机生成数据&#xff0c;由Ian J. Goodfellow等人于2014年提出。模型通过框架中(至少)两个模块&#xff1a;生成模型(Generative Model)和判别模型(Discriminative Mod…

非父子组件通信-发布订阅模式

发布订阅模式其实与vue无关&#xff0c;完全是ES6的代码&#xff0c;但是它可以通过这种模式实现非父子组件的通信 store.js文件 首先创建一个store.js文件&#xff0c;用于提供发布与订阅方法 export default {datalist: [], //存放带一个参数的函数集合//订阅subscribe(fu…

SpringBoot自动配置原理解析 | 京东物流技术团队

1: 什么是SpringBoot自动配置 首先介绍一下什么是SpringBoot&#xff0c;SpringBoost是基于Spring框架开发出来的功能更强大的Java程序开发框架&#xff0c;其最主要的特点是&#xff1a;能使程序开发者快速搭建一套开发环境。SpringBoot能将主流的开发框架&#xff08;例如Sp…

二甲医院his系统源码,医院信息管理系统全套源码 电子病历评级4级

医院his系统源码&#xff0c;医院信息管理系统全套源码 电子病历评级4级 HIS系统完全基于云端部署&#xff0c;采用B/S架构&#xff0c;并通过软件即服务&#xff08;SaaS&#xff09;的形式面向二级医院的可快速交付、便捷运维、云化的医院核心业务平台产品。融合医院HIS和EMR…

CTF取证技术实战,图片、文件、流等相关内容的取证技术

I、背景 取证技术&#xff0c;尤其是计算机数据取证技术&#xff0c;是一种针对信息犯罪和计算机数据的专业取证技术。它旨在帮助学习者理解电子证据及其形成过程&#xff0c;并掌握计算机数据相关的取证技术。 具体来说&#xff0c;计算机取证是对计算机犯罪证据的识别获取、…

RetentionPolicy枚举类

包名package java.lang.annotation 作用 注释保留策略。此枚举类型的常量描述用于保留注释的各种策略。它们被使用与&#xff5b; Retention&#xff5d;元注释类型一起指定注释要保留多长时间。 属性 SOURCE编译器将丢弃注释。CLASS注释将由编译器记录在类文件…

组件通信-跨级通信Provide | Inject

使用 provide/inject &#xff0c;只需要向后代注入组件本身&#xff08;this&#xff09;&#xff0c;后代组件中可以无视层级任意访问祖先组件中的状态。 当然它也有缺点&#xff1a;因为 provide/inject 中变量的修改是无法控制的。换句话说&#xff0c;不知道是哪个组件修…

Python网络编程之数据的主机字节序与网络字节序

在Python网络编程中&#xff0c;需要将数据通过网络在服务端与客户端中传递。而数据在主机中和在网络中保存的方式是不同的&#xff0c;即主机字节序和网络字节序。 1 介绍 1.1 主机字节序 数据的主机字节序指的是在高位内存保存数据的高位&#xff0c;在低位内存保存数据的…

霸王条款惹品牌争议,京东双11站在商家对立面?

作者 | 江北 来源 | 洞见新研社 双11活动第一天&#xff0c;京东就站上了风口浪尖。 与烘焙烤箱品牌海氏的话题接连登上微博热搜&#xff0c;海氏控诉京东滥用市场竞争地位&#xff0c;破坏市场竞争秩序。在海氏的声明中&#xff0c;京东的行为让吃瓜群众大开眼界&#xff1a…

HackTheBox---Starting Point-- Tier 0---Meow

文章目录 一 题目二 实验过程 一 题目 Tags Telnet、Network、Protocols、Reconnaissance、Weak Credentials、Misconfiguration译文&#xff1a;标签、远程登录、网络、协议、侦察、弱凭证、配置错误Connect To attack the target machine, you must be on the same networ…

深度学习--通过对Keras进行微调提升性能

本文使用微调(Fine-tune)技术来提升模型的性能。前面我们通过迁移学习将这个猫狗大战二分类问题的预测准确率提升到了90%左右,看上去效果已经很不错了,但是还能不能进一步提升了呢? 前面我们没有对VGG16的卷积层进行参数的优化,那么我们这里就可以来优化这部分的参数。由…

67 跳跃游戏 II

跳跃游戏 II 题解1 贪心1 正向题解2 贪心2 反向题解3 DP 给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说&#xff0c;如果你在 nums[i] 处&#xff0c;你可以跳转到任意 nums[i j] 处: 0 &…

前端实现菜单按钮级权限

核心思想就是通过登录请求此用户对应的权限菜单&#xff0c;然后跳转首页&#xff0c;触发全局前置导航守卫&#xff0c;在全局导航守卫中通过 addRoute 添加动态路由进去。addRoute有一个需要注意的地方&#xff0c;就是我们添加完动态路由后&#xff0c;地址栏上立即访问添加…

Linux PAGE_ALIGN 宏定义的理解

前言 最近再阅读 Linux ion&#xff08;一种内存分配管理&#xff09;时&#xff0c;遇到了 PAGE_ALIGN 宏&#xff0c;这个宏到底是怎么工作的&#xff1f; 【页对齐】时什么意思&#xff1f; 页大小就是 4096 吗&#xff1f; 追踪 PAGE_ALIGN 通过一步一步的追踪&#xff0…

基于自动化工具autox.js的抢票(猫眼)

1.看到朋友圈抢周杰伦、林俊杰演唱会票贼难信息,特研究了一段时间,用autox.js写了自动化抢票脚本,购票页面自动点击下单(仅限安卓手机)。 2.脚本运行图 3.前期准备工作 (1)autox.js社区官网:AutoX.js (2)b站上学习资料:10分钟学会AutoX.js hello world_哔哩哔哩_bi…

下一个风口在哪里?云计算:未来十年最有潜力行业!

近年来&#xff0c;中国云计算产业发展迅猛&#xff0c;保持30%以上的年均增长率&#xff0c;成为全球增速最快的市场之一&#xff0c;云计算应用领域正向制造、政务、金融、医疗、教育等企业级市场延伸拓展。 目前&#xff0c;云计算应用的普及促使开源技术广受关注&#xff…