UnityAI——动物迁徙中的跟随实现实例

  大家好,我是七七,今天来给大家介绍的是Unity中用操控行为实现的跟随领队行为。

看本文若是想了解和实现,只看本文即可,若是想彻底弄透,建议从七七的游戏AI专栏开始看。

废话不多说,先上视频:

跟随队长

我们的目标是让后面的人跟着领头的人,并遵循一些规则

对于领头的人:

  1. 随机地移动
  2. 检测前方是否有人

对于跟随的人;

  1. 跟的不要太近
  2. 人与人直接不要拥挤
  3. 如果发现挡道领头人路了,赶紧让开 

 我们只需要实现这些规则,就可以得到理想的效果,这与神经网络的思想类似,下面我们就来实现这些规则。

规则1

这个脚本是挂载领头人身上的,目的是在前方LEADER_BEHIND_DIST处画一个圆球,若是说前方有人,则让这些人避开。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class DrawGizmos : MonoBehaviour
{public float evadeDistance;public Vector3 center;private Vehicle vehicleScript;private float LEADER_BEHIND_DIST;void Start(){vehicleScript = GetComponent<Vehicle>();LEADER_BEHIND_DIST = 2.0f;}void Update(){center = transform.position + vehicleScript.velocity.normalized * LEADER_BEHIND_DIST;}void OnDrawGizoms(){Gizmos.DrawWireSphere(center, evadeDistance);}
}

规则2

这个脚本是挂在一个空物体上的,目的是生成多个跟随者

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class GenerateBotsForFollowLeader : MonoBehaviour
{public GameObject botPrefab;public GameObject leader;public int botCount;public float minX = -5f;public float maxX = 5.0f;public float minZ = -5.0f;public float maxZ = 5.0f;public float Yvalue = 1.026003f;void Start(){Vector3 spawnPosition;GameObject bot;for(int i = 0; i < botCount; i++){spawnPosition = new Vector3(Random.Range(minX, maxX), Yvalue, Random.Range(minZ, maxZ));//随机产生一个生成位置bot = Instantiate(botPrefab, spawnPosition, Quaternion.identity) as GameObject;bot.GetComponent<SteeringForLeaderFollowing>().leader = leader;bot.GetComponent<SteeringForEvade>().target = leader;bot.GetComponent<SteeringForEvade>().enabled = false;bot.GetComponent<EvadeController>().leader = leader;}}
}

规则3

这个脚本是挂在跟随者身上的,是为了确定跟随者的路径目标点,即领导人身后LEADER_BEHIND_DIST处

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(SteeringForArrive))]
public class SteeringForLeaderFollowing : Steering
{public Vector3 target;private Vector3 desiredVelocity;//预期速度private Vehicle m_vehicle;//获得被操控的AI角色private float maxSpeed;private bool isPlanar;public GameObject leader;private Vehicle leaderController;private Vector3 leaderVelocity;private float LEADER_BEHIND_DIST=2.0f;private SteeringForArrive arriveScript;private Vector3 randomOffset;void Start(){m_vehicle = GetComponent<Vehicle>();maxSpeed = m_vehicle.maxSpeed;isPlanar = m_vehicle.isPlanar;leaderController=leader.GetComponent<Vehicle>();arriveScript= GetComponent<SteeringForArrive>();//为抵达行为指定目标点arriveScript.target = new GameObject("arriveTarget");arriveScript.target.transform.position = leader.transform.position;}public override Vector3 Force(){leaderVelocity = leaderController.velocity;target=leader.transform.position+LEADER_BEHIND_DIST*(-leaderVelocity).normalized;//计算目标点arriveScript.target.transform.position = target;return new Vector3(0, 0, 0);}
}

 规则4

这个脚本是挂在跟随者身上的,目的是为了避免跟随者挡住领导人的路

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class EvadeController : MonoBehaviour
{public GameObject leader;private Vehicle leaderLocomotion;private Vehicle m_vehicle;private bool isPlanar;private Vector3 leaderAhead;private float LEADER_BEHIND_DIST;private Vector3 dist;public float evadeDistance;private float sqrEvadeDistance;private SteeringForEvade evadeScript;void Start(){leaderLocomotion = leader.GetComponent<Vehicle>();evadeScript= GetComponent<SteeringForEvade>();m_vehicle= GetComponent<Vehicle>();isPlanar=m_vehicle.isPlanar;LEADER_BEHIND_DIST = 2.0f;sqrEvadeDistance=sqrEvadeDistance*sqrEvadeDistance;}void Update(){leaderAhead=leader.transform.position+leaderLocomotion.velocity.normalized*LEADER_BEHIND_DIST;  //计算领队前方的一个点dist = transform.position - leaderAhead;if (isPlanar){dist.y = 0;}if(dist.sqrMagnitude < sqrEvadeDistance){evadeScript.enabled = true;Debug.DrawLine(transform.position, leader.transform.position);}else{evadeScript.enabled = false;}}
}

实现

前提

有3个基类

UnityAI——操控行为编程的主要基类-CSDN博客

第一步

创建一个场景,一个Plane

第二步

创建一个Cube作为领队,起名为Leader,为其挂上三个脚本,如下所示:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class AILocomotion : Vehicle
{private CharacterController controller;  //AI�Ľ�ɫ������private Rigidbody theRigidbody;private Vector3 moveDistance;//AI��ɫÿ�ε��ƶ�����void Start(){controller = GetComponent<CharacterController>();theRigidbody = GetComponent<Rigidbody>();moveDistance = new Vector3(0, 0, 0);base.Start();//���û����start��������������ij�ʼ��}//������ز�����FixedUpdate�и���void FixedUpdate(){velocity += acceleration * Time.fixedDeltaTime;//�����ٶ�if (velocity.sqrMagnitude > sqrMaxSpeed)   //��������ٶ�velocity = velocity.normalized * maxSpeed;moveDistance = velocity * Time.fixedDeltaTime;if (isPlanar)  {velocity.y = 0;moveDistance.y = 0;}if (controller != null)//����Ѿ�ΪAI��ɫ���ӽ�ɫ����������ô���ý�ɫ������ʹ���ƶ�controller.SimpleMove(velocity);//�����ɫ��û��ɫ��������ҲûRigidbody//����Rigidbody����Ҫ�ɶ���ѧ�ķ�ʽ�������ƶ�else if (theRigidbody == null || !theRigidbody.isKinematic)transform.position += moveDistance;else //��Rigidbody���ƽ�ɫ���˶�theRigidbody.MovePosition(theRigidbody.position+moveDistance);if(velocity.sqrMagnitude>0.00001)//���³�������ٶȴ���һ����ֵ��Ϊ�˷�ֹ������{Vector3 newForward = Vector3.Slerp(transform.forward, velocity, damping * Time.deltaTime);if(isPlanar)newForward.y = 0;transform.forward = newForward;}//�������߶���gameObject.GetComponent<Animation>().Play("walk");}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class SteeringForWander : Steering
{public float wanderRadius; //徘徊半径public float wanderDistance; //徘徊距离public float wanderJitter; //每秒加到目标的随即位移的最大值public bool isPlanar;private Vector3 desiredVelocity;//预期速度private Vehicle m_vehicle;//获得被操控的AI角色private float maxSpeed;private Vector3 circleTarget;private Vector3 wanderTarget;void Start(){m_vehicle = GetComponent<Vehicle>();maxSpeed = m_vehicle.maxSpeed;isPlanar = m_vehicle.isPlanar;circleTarget = new Vector3(wanderRadius * 0.707f, 0, wanderRadius * 0.707f);  //选取与安全上的一个点作为初始点}public override Vector3 Force(){Vector3 randomDisplacement = new Vector3((Random.value - 0.5f) * 2 * wanderJitter, (Random.value - 0.5f) * 2 * wanderJitter, (Random.value - 0.5f) * 2 * wanderJitter);if (isPlanar)randomDisplacement.y = 0;circleTarget+=randomDisplacement;//将随机位移加到初始点上circleTarget = wanderRadius * circleTarget.normalized;//由于新位置很可能不在圆周上,因此需要投影到圆周上wanderTarget = m_vehicle.velocity.normalized * wanderDistance + circleTarget + transform.position;//之前计算出的值是相对于AI的,需要转换为世界坐标desiredVelocity = (wanderTarget - transform.position).normalized * maxSpeed;return (desiredVelocity - m_vehicle.velocity);}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class DrawGizmos : MonoBehaviour
{public float evadeDistance;public Vector3 center;private Vehicle vehicleScript;private float LEADER_BEHIND_DIST;void Start(){vehicleScript = GetComponent<Vehicle>();LEADER_BEHIND_DIST = 2.0f;}void Update(){center = transform.position + vehicleScript.velocity.normalized * LEADER_BEHIND_DIST;}void OnDrawGizoms(){Gizmos.DrawWireSphere(center, evadeDistance);}
}

第三步

创建一个空物体,起名为follersGenerator,用于生成跟随者,并添加脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class GenerateBotsForFollowLeader : MonoBehaviour
{public GameObject botPrefab;public GameObject leader;public int botCount;public float minX = -5f;public float maxX = 5.0f;public float minZ = -5.0f;public float maxZ = 5.0f;public float Yvalue = 1.026003f;void Start(){Vector3 spawnPosition;GameObject bot;for(int i = 0; i < botCount; i++){spawnPosition = new Vector3(Random.Range(minX, maxX), Yvalue, Random.Range(minZ, maxZ));//随机产生一个生成位置bot = Instantiate(botPrefab, spawnPosition, Quaternion.identity) as GameObject;bot.GetComponent<SteeringForLeaderFollowing>().leader = leader;bot.GetComponent<SteeringForEvade>().target = leader;bot.GetComponent<SteeringForEvade>().enabled = false;bot.GetComponent<EvadeController>().leader = leader;}}
}

第四步

创建一个方块预设,作为跟随者,挂上下列脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class AILocomotion : Vehicle
{private CharacterController controller;  //AI�Ľ�ɫ������private Rigidbody theRigidbody;private Vector3 moveDistance;//AI��ɫÿ�ε��ƶ�����void Start(){controller = GetComponent<CharacterController>();theRigidbody = GetComponent<Rigidbody>();moveDistance = new Vector3(0, 0, 0);base.Start();//���û����start��������������ij�ʼ��}//������ز�����FixedUpdate�и���void FixedUpdate(){velocity += acceleration * Time.fixedDeltaTime;//�����ٶ�if (velocity.sqrMagnitude > sqrMaxSpeed)   //��������ٶ�velocity = velocity.normalized * maxSpeed;moveDistance = velocity * Time.fixedDeltaTime;if (isPlanar)  {velocity.y = 0;moveDistance.y = 0;}if (controller != null)//����Ѿ�ΪAI��ɫ���ӽ�ɫ����������ô���ý�ɫ������ʹ���ƶ�controller.SimpleMove(velocity);//�����ɫ��û��ɫ��������ҲûRigidbody//����Rigidbody����Ҫ�ɶ���ѧ�ķ�ʽ�������ƶ�else if (theRigidbody == null || !theRigidbody.isKinematic)transform.position += moveDistance;else //��Rigidbody���ƽ�ɫ���˶�theRigidbody.MovePosition(theRigidbody.position+moveDistance);if(velocity.sqrMagnitude>0.00001)//���³�������ٶȴ���һ����ֵ��Ϊ�˷�ֹ������{Vector3 newForward = Vector3.Slerp(transform.forward, velocity, damping * Time.deltaTime);if(isPlanar)newForward.y = 0;transform.forward = newForward;}//�������߶���gameObject.GetComponent<Animation>().Play("walk");}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class SteeringForArrive : Steering
{public bool isPlanar = true;public float arrivalDistance = 0.3f;public float characterRadius = 1.2f;public float slowDownDistance;public GameObject target;private Vector3 desiredVelocity;//预期速度private Vehicle m_vehicle;//获得被操控的AI角色private float maxSpeed;void Start(){m_vehicle = GetComponent<Vehicle>();maxSpeed = m_vehicle.maxSpeed;isPlanar = m_vehicle.isPlanar;}public override Vector3 Force(){Vector3 toTarget = target.transform.position - transform.position;Vector3 desiredVelocity;Vector3 returnForce;if (isPlanar)toTarget.y = 0;float distance = toTarget.magnitude;if (distance > slowDownDistance){desiredVelocity = toTarget.normalized * maxSpeed;returnForce = desiredVelocity - m_vehicle.velocity;}else{desiredVelocity = toTarget - m_vehicle.velocity;returnForce = desiredVelocity - m_vehicle.velocity;}return returnForce;}void OnDrawGizmos(){Gizmos.DrawWireSphere(target.transform.position, slowDownDistance);}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(SteeringForArrive))]
public class SteeringForLeaderFollowing : Steering
{public Vector3 target;private Vector3 desiredVelocity;//预期速度private Vehicle m_vehicle;//获得被操控的AI角色private float maxSpeed;private bool isPlanar;public GameObject leader;private Vehicle leaderController;private Vector3 leaderVelocity;private float LEADER_BEHIND_DIST=2.0f;private SteeringForArrive arriveScript;private Vector3 randomOffset;void Start(){m_vehicle = GetComponent<Vehicle>();maxSpeed = m_vehicle.maxSpeed;isPlanar = m_vehicle.isPlanar;leaderController=leader.GetComponent<Vehicle>();arriveScript= GetComponent<SteeringForArrive>();//为抵达行为指定目标点arriveScript.target = new GameObject("arriveTarget");arriveScript.target.transform.position = leader.transform.position;}public override Vector3 Force(){leaderVelocity = leaderController.velocity;target=leader.transform.position+LEADER_BEHIND_DIST*(-leaderVelocity).normalized;//计算目标点arriveScript.target.transform.position = target;return new Vector3(0, 0, 0);}
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Radar : MonoBehaviour
{private Collider[] colliders;//碰撞体的组数private float timer = 0;//计时器public List<GameObject> neighbors;public float checkInterval = 0.3f;//设置检测的时间间隔public float detectRadius = 10f;//设置邻域半径public LayerMask layersChecked;//设置检测哪一层的游戏对象void Start(){neighbors = new List<GameObject>();}void Update(){timer += Time.deltaTime;if(timer > checkInterval){neighbors.Clear();colliders = Physics.OverlapSphere(transform.position, detectRadius, layersChecked);//查找当前AI角色邻域内的所有碰撞体for(int i = 0; i < colliders.Length; i++)//对于每个检测到的碰撞体,获取Vehicle组件,并且加入邻居列表钟{if (colliders[i].GetComponent<Vehicle>())neighbors.Add(colliders[i].gameObject);}timer = 0;}}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class SteeringForSeparation : Steering
{public float comforDistance = 1;//可接受的距离public float multiplierInsideComfortDistance = 2;//当AI角色与邻居距离过近时的惩罚因子public override Vector3 Force(){Vector3 steeringForce = new Vector3(0, 0, 0);foreach(GameObject s in GetComponent<Radar>().neighbors)//遍历这个AI角色的邻居列表中的每个邻居{if ((s != null) && (s != this.gameObject)){Vector3 toNeighbor = transform.position - s.transform.position;//计算当前AI角色与邻居s之间的距离float length=toNeighbor.magnitude;steeringForce += toNeighbor.normalized / length;//计算这个邻居引起的操控力if (length < comforDistance)steeringForce *= multiplierInsideComfortDistance;}}return steeringForce;}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class SteeringForEvade :Steering
{public GameObject target;private Vector3 desiredVelocity;//预期速度private Vehicle m_vehicle;//获得被操控的AI角色private float maxSpeed;void Start(){m_vehicle = GetComponent<Vehicle>();maxSpeed = m_vehicle.maxSpeed;}public override Vector3 Force(){Vector3 toTarget = target.transform.position - transform.position;float lookaheadTime = toTarget.magnitude / (maxSpeed + target.GetComponent<Vehicle>().velocity.magnitude);//向前预测的时间desiredVelocity = (transform.position - (target.transform.position+target.GetComponent<Vehicle>().velocity*lookaheadTime)).normalized * maxSpeed;return (desiredVelocity - m_vehicle.velocity);}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class EvadeController : MonoBehaviour
{public GameObject leader;private Vehicle leaderLocomotion;private Vehicle m_vehicle;private bool isPlanar;private Vector3 leaderAhead;private float LEADER_BEHIND_DIST;private Vector3 dist;public float evadeDistance;private float sqrEvadeDistance;private SteeringForEvade evadeScript;void Start(){leaderLocomotion = leader.GetComponent<Vehicle>();evadeScript= GetComponent<SteeringForEvade>();m_vehicle= GetComponent<Vehicle>();isPlanar=m_vehicle.isPlanar;LEADER_BEHIND_DIST = 2.0f;sqrEvadeDistance=sqrEvadeDistance*sqrEvadeDistance;}void Update(){leaderAhead=leader.transform.position+leaderLocomotion.velocity.normalized*LEADER_BEHIND_DIST;  //计算领队前方的一个点dist = transform.position - leaderAhead;if (isPlanar){dist.y = 0;}if(dist.sqrMagnitude < sqrEvadeDistance){evadeScript.enabled = true;Debug.DrawLine(transform.position, leader.transform.position);}else{evadeScript.enabled = false;}}
}

收尾

最后再给各个角色装上刚体,设置好Leader等参数就可以了。

很多行为我们都可以通过设定规则来实现,可能乍一看行为很难摸索,但慢慢分析出其中的规则并逐一实现后,问题往往就会被解决

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

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

相关文章

SpringBean生命周期

SpringBean的创建过程的生命周期可以分为 通过构造方法创建普通对象对普通对象属性进行依赖注入&#xff08;被Autowired注解修饰的变量&#xff09;执行初始化前的操作&#xff08;被PostConstruct注解修饰的方法&#xff09;执行初始化操作&#xff08;需要实现Initializing…

UDP网络编程

一)熟悉TCP/IP五层协议: 1)封装:就是在数据中添加一些辅助传输的信息&#xff1b; 2)分用:就是解析这些信息 3)发送数据的时候&#xff0c;上层协议要把数据交给下层协议&#xff0c;由下层协议来添加一些信息 4)接收数据的时候&#xff0c;下层协议要把数据交给上层协议&#…

c语言-数据结构-栈和队列的实现和解析

目录 一、栈 1、栈的概念 1.2 栈的结构 2、栈的创建及初始化 3、压栈操作 4、出栈操作 5、显示栈顶元素 6、显示栈空间内元素的总个数 7、释放栈空间 8、测试栈 二、队列 1、队列的概念 1.2 队列的结构 2、队列的创建及初始化 3、入队 4、出队 5、显示队头、队…

番外 1 : Java 环境下的 selenium 搭建

Java 环境下的 selenium 搭建 一 . 下载谷歌浏览器二 . 下载谷歌浏览器驱动2.1 查看谷歌浏览器版本2.2 下载对应版本的谷歌驱动2.3 解压下载好的驱动压缩包 , 将下载好的 chromedriver.exe 放到java 系统环境变量下 三 . 下载 Edge 浏览器的驱动3.1 查看 Edge 浏览器的版本3.2 …

带有密码的Excel只读模式,如何取消?

Excel文件打开之后发现是只读模式&#xff0c;想要退出只读模式&#xff0c;但是只读模式是带有密码的&#xff0c;该如何取消带有密码的excel只读文件呢&#xff1f; 带有密码的只读模式&#xff0c;是设置了excel文件的修改权限&#xff0c;取消修改权限&#xff0c;我们需要…

Go,14周年[译]

国内的双十一购物狂欢已没有了当年的那种热闹与喧嚣&#xff0c;但大洋彼岸的Go团队却始终保持稳中有增的开发和语言演进节奏。今晨Go核心团队的Russ Cox[1]代表Go语言项目团队在Go官博上发表了《Fourteen Years of Go》[2]的博文&#xff0c;纪念Go语言开源14周年[3]&#xff…

FCOS难点记录

FCOS 中有计算 特征图&#xff08;Feature map中的每个特征点到gt_box的左、上、右、下的距离&#xff09; 1、特征点到gt_box框的 左、上、右、下距离计算 x coords[:, 0] # h*w&#xff0c;2 即 第一列y coords[:, 1] l_off x[None, :, None] - gt_boxes[..., 0][:, No…

XXE XML外部实体注入

XXE 外部实体注入 一, 简介 XXE&#xff08;XML External Entity Injection&#xff09;是一种 XML 注入攻击&#xff0c;它利用了 XML 解析器在处理 XML 文档时存在的漏洞。 攻击者通过在 XML 文档中插入外部实体的引用&#xff0c;可以引导 XML 解析器读取攻击者控制的外部…

编程艺术之源:深入了解设计模式和设计原则

深入了解设计模式和设计原则 一、认识设计模式1.1、设计模式是什么&#xff1f;1.2、设计模式是怎么来的&#xff1f;1.3、设计模式解决了什么问题&#xff1f; 二、设计模式的基础2.1、面向对象思想2.2、设计原则 三、如何学习设计模式3.1、明确目的3.2、学习步骤 总结 一、认…

Linux服务器从零开始训练 RT-DETR 改进项目 (Ultralytics) 教程,改进RTDETR算法(包括使用训练、验证、推理教程)

手把手从零开始训练 RT-DETR 改进项目 (Ultralytics版本) 教程,改进RTDETR算法 本文以Linux服务器为例:从零开始使用Linux训练 RT-DETR 算法项目 《芒果剑指 RT-DETR 目标检测算法 改进》 适用于芒果专栏改进RT-DETR算法 文章目录 百度 RT-DETR 算法介绍改进网络代码汇总第…

CAD Exchanger SDK 有什么新内容?

CAD 交换器 3.23.0&#xff0c;2023 年 11 月强调&#xff1a;- 添加了新版本格式的导入&#xff1a;Autodesk Inventor 2023 和 2024、NX 2306。- 文档经过重大修改&#xff0c;使其更易于导航。它也是现在包含有关 SDK、Web Toolkit 和 Manufacturing Toolkit 的全面信息&…

SQL 存储过程优化

问题&#xff1a;一个复杂的6个表的left jion 语句&#xff0c;发现设置为定时任务后最高时长为18分钟 1、原因分析&#xff1a;对复杂SQL 进行拆分验证 发现是合同明细表和 产品表的left jion 时间过长&#xff0c;发现 合同明细表每天为3w条&#xff0c;之前做过优化 对每个…

PTA 7-6 队列模拟

7-6 队列模拟 分数 25 全屏浏览题目 作者 sy 单位 宁波财经学院 设从键盘输入一整数序列a1&#xff0c;a2&#xff0c;...an&#xff0c;试编程实现&#xff1a;当ai>0 时&#xff0c;ai 进队&#xff0c;当ai<0 时&#xff0c;将队首元素出队&#xff0c;当ai0 时&a…

10. 深度学习——模型优化

机器学习面试题汇总与解析——模型优化 本章讲解知识点 前言低秩近似剪枝与稀疏约束参数量化二值网络知识蒸馏紧凑的网络结构本专栏适合于Python已经入门的学生或人士,有一定的编程基础。本专栏适合于算法工程师、机器学习、图像处理求职的学生或人士。本专栏针对面试题答案进…

(1)(1.14) LightWare SF10/SF11激光雷达

文章目录 前言 1 串行连接 2 I2C 连接 3 参数说明 前言 Lightware SF20 和 LW20 是体积小、测距远&#xff08;100m&#xff09;、精度高的测距仪。有两种型号&#xff0c;LW20/Ser 使用串行接口&#xff0c;LW20/I2C 使用 I2C 接口。 1 串行连接 对于串行连接&#xff0…

java数据结构--堆

目录 一.概念 二.堆中最重要三个方法 三.大顶堆 四.基于数组实现大顶堆 五.堆排序 六.小顶堆 七.基于数组实现小顶堆 八.ProiorityQueue和Heap 示例&#xff1a; 九.求数组中第K大元素 十.求数据流中第K大元素 十一.求数据流的中位数 一.概念 堆&#xff08;Heap&…

软件开发项目文档系列之十六如何撰写系统运维方案

前言 项目运维方案是为了确保项目的稳定运行和可持续发展而制定的指导性文档。本文将详细介绍项目运维方案的各个方面&#xff0c;包括硬件和软件基础设施、监控和警报、备份和恢复、安全性、团队组织和沟通等方面。本博客将提供示例和最佳实践&#xff0c;以帮助您更好地理解…

什么是ajax,ajax有什么特点?

AJAX&#xff08;Asynchronous JavaScript and XML&#xff09;是一种用于在后台与服务器进行异步通信的技术。它使用 JavaScript、XML&#xff08;或 JSON&#xff09;和 XMLHttpRequest 对象来实现在不刷新整个页面的情况下更新部分页面内容。 特点&#xff1a; 异步通信&a…

Ubuntu显示毫秒级时间

Ubuntu显示毫秒级时间 1. 打印当前时间 1. 打印当前时间 date 时间&#xff0c;转化成毫秒级 $ date # Mon 03 Apr 2023 11:09:47 PM CST$ echo -e "$(date %T).$((10#$(date %N)/1000000))" # 23:09:55.552谢谢

一些分享| 在线笔记、GIF图片生成方法

文章目录 在线笔记视频转GIF 本片博客旨在挖掘一些好用且免费的在线平台&#xff0c;持续更新中~ 正所谓科技解放双手&#xff0c;使用在线平台可以方便快捷地学习办公&#xff0c;节省时间。 在线笔记 语雀 https://www.yuque.com/dashboard 语雀是笔者用得最长最久的平台了…