Docker步步实践
目录文档:
①Docker简介
②基本概念
③安装Docker
④使用镜像:
⑤操作容器:
⑥访问仓库:
⑦数据管理:
⑧使用网络:
⑨高级网络配置:
⑩安全:
⑪底层实现:
⑫其他项目:
{
get
{
if (instance == null)
{
instance = new Routing();
}
return instance;
}
}
#endregion
/// <summary>
/// 二维数组的地图
/// </summary>
RoutingObject[,] map;
/// <summary>
/// 存储被考虑来寻找最短路径的点
/// </summary>
List<RoutingObject> open = new List<RoutingObject>();
/// <summary>
/// 存储不再被考虑寻找最短路径的点
/// </summary>
List<RoutingObject> closed = new List<RoutingObject>();
/// <summary>
/// 存储路线点的列表
/// </summary>
List<RoutingObject> route = new List<RoutingObject>();
/// <summary>
/// 初始化
/// </summary>
void Init(RoutingObject[,] mapArray)
{
open.Clear();
closed.Clear();
route.Clear();
map = mapArray;
}
/// <summary>
/// 判断从起始点是否能到达目标点
/// </summary>
/// <param name="start\_x">起始点x坐标</param>
/// <param name="start\_y">起始点y坐标</param>
/// <param name="end\_x">目标点x坐标</param>
/// <param name="end\_y">目标点y坐标</param>
/// <param name="map"></param>
/// <returns></returns>
public bool IsRouting(RoutingObject start, RoutingObject end, RoutingObject[,] mapArray)
{
Init(mapArray);
Explore(start, end, start);
// 判断存储路线点的列表里是否存有点
return route.Count > 0;
}
/// <summary>
/// 探索中心点上下左右四个方向点
/// </summary>
void Explore(RoutingObject center, RoutingObject end, RoutingObject start)
{
// 中心点不再考虑寻找路径
closed.Add(center);
// 将中心点从寻找列表中移除
if (open.Contains(center))
{
open.Remove(center);
}
// 是否找到目标点
if (IsGetEnd(end))
{
// 找到目标点
ReturnRoute(end, start);
}
else
{
// 判断中心点上边的点
if (center.y - 1 >= 0)
{
RoutingObject up = map[center.x, center.y - 1];
GetMoveSumByDirection(up, center, end, Direction.up);
}
// 判断中心点下边的点
if (center.y + 1 < GridManager.Instance.mapColumnCount)
{
RoutingObject down = map[center.x, center.y + 1];
GetMoveSumByDirection(down, center, end, Direction.down);
}
// 判断中心点左边的点
if (center.x - 1 >= 0)
{
RoutingObject left = map[center.x - 1, center.y];
GetMoveSumByDirection(left, center, end, Direction.left);
}
// 判断中心点右边的点
if (center.x + 1 < GridManager.Instance.mapRowCount)
{
RoutingObject right = map[center.x + 1, center.y];
GetMoveSumByDirection(right, center, end, Direction.right);
}
if (open.Count > 0)
{
// 没有找到目标点,则在被考虑的列表中找出一个和值最小的
RoutingObject ro = GetMinimumMoveSum();
Explore(ro, end, start);
}
else
{
Debug.Log("没有找到目标点");
}
}
}
/// <summary>
/// 根据传进来的方向去获取和值
/// </summary>
/// <param name="center"></param>
/// <param name="start"></param>
/// <param name="end"></param>
/// <param name="direction"></param>
void GetMoveSumByDirection(RoutingObject center, RoutingObject start, RoutingObject end, Direction direction)
{
// 判断这个点是否能移动或者是否被考虑
if (IsForward(center))
{
center.direction = direction;
// 获取移动距离
center.moveDistance = GetDistance(center, start);
// 获取目标距离
center.targetDistance = GetDistance(center, end);
// 获取A\*和值
center.moveSum = center.moveDistance + center.targetDistance;
// 将中心点加入将要被考虑的列表中
open.Add(center);
}
else
{
//Debug.Log(center.name + " 不能移动");
}
}
/// <summary>
/// 判断这个点是否属于未来被考虑前进的点
/// </summary>
/// <param name="ro"></param>
/// <returns></returns>
bool IsForward(RoutingObject ro)
{
// 判断这个点是否已经在不再考虑的列表中
if (closed.Contains(ro) || open.Contains(ro))
{
return false;
}
else
{
// 判断这个点是否可以移动
if (ro.isCanMove)
{
return true;
}
else
{
// 不可以移动就加入不再考虑的列表中
closed.Add(ro);
return false;
}
}
}
/// <summary>
/// 获取距离
/// </summary>
/// <param name="start"></param>
/// <param name="end"></param>
int GetDistance(RoutingObject start, RoutingObject end)
{
// 定义目标距离返回值, --> 谁大,谁减谁
return Mathf.Abs(start.x - end.x) + Mathf.Abs(start.y - end.y);
}
/// <summary>
/// 是否找到目标点
/// </summary>
/// <returns></returns>
bool IsGetEnd(RoutingObject end)
{
return closed.Contains(end);
}
/// <summary>
/// 在被考虑的列表中获取和值最小的点
/// </summary>
/// <returns></returns>
RoutingObject GetMinimumMoveSum()
{
RoutingObject ro = null;
RoutingObject temporary = new RoutingObject();
for (int i = 0; i < open.Count; i++)
{
//Debug.Log("当前 " + open[i].name + " 的和值为: " + open[i].moveSum);
// 列表中的第一个不需要比较,直接赋值
if (i == 0)
{
ro = open[i];
temporary = open[i];
}
else
{
// 寻找列表中和值最小的点
if (open[i].moveSum < temporary.moveSum)
{
ro = open[i];
temporary = open[i];
}
}
}
//Debug.Log("最终 " + ro.name + " 的和值为: " + ro.moveSum);
return ro;
}
/// <summary>
/// 返回路线
/// </summary>
/// <param name="center"></param>
/// <param name="start"></param>
void ReturnRoute(RoutingObject center, RoutingObject start)
{
// 将这个点存储到路线列表中
route.Add(center);
// 判断路线列表中是否包含起始点
if (!route.Contains(start))
{
// 没有包含
// 返回路线取这个点的反方向
switch (center.direction)
{
case Direction.up:
ReturnRoute(map[center.x, center.y + 1], start);
break;
case Direction.down:
ReturnRoute(map[center.x, center.y - 1], start);
break;
case Direction.left:
ReturnRoute(map[center.x + 1, center.y], start);
break;
case Direction.right:
ReturnRoute(map[center.x - 1, center.y], start);
break;
}
}
else
{
RouteSort(start);
}
}
/// <summary>
/// 路线排序(将起始点从存储路线点的列表中移除,并从起始点到目标点重新排序)
/// </summary>
void RouteSort(RoutingObject start)
{
List<RoutingObject> list = new List<RoutingObject>(route);
route.Clear();
for (int i = list.Count - 1; i >= 0; i--)
{
if (list[i] != start)
{
route.Add(list[i]);
}
}
}
/// <summary>
/// 返回最短路线
/// </summary>
/// <returns></returns>
public List<RoutingObject> GetRoute()
{
return route;
}
}
* 创建`GridManager`脚本,将其挂载到GridManager物体上,
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class GridManager : MonoBehaviour
{
///
/// 单例
///
public static GridManager Instance;
/// <summary>
/// 地图行数
/// </summary>
public int mapColumnCount = 9;
/// <summary>
/// 地图列数
/// </summary>
public int mapRowCount = 9;
/// <summary>
/// 当前可移动最短路径存储集合
/// </summary>
public List<RoutingObject> routeList = new List<RoutingObject>();
/// <summary>
/// 已被占领的格子集合 -- 格子上有障碍物
/// </summary>
public List<GameObject> OccupyGridList = new List<GameObject>();
/// <summary>
/// 存储地图格子
/// </summary>
private GameObject[,] GridArray;
/// <summary>
/// 当前所选格子
/// </summary>
private GameObject selectGrid;
private void Awake()
{
Instance = this;
GridArray = new GameObject[mapRowCount, mapColumnCount];
}
void Start()
{
}
/// <summary>
/// 每个格子初始化时 调用赋值
/// </summary>
/// <param name="go">格子</param>
/// <param name="x">所在X</param>
/// <param name="y">所在Y</param>
public void SetGridArray(GameObject go, int x, int y)
{
GridArray[x, y] = go;
}
/// <summary>
/// 根据(x,y)获取 格子物体
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
GameObject GetGridArray(int x, int y)
{
return GridArray[x, y];
}
/// <summary>
/// 获取一个准备移动球的二维数组(每个坐标点上记录着是否可以移动)
/// </summary>
/// <returns></returns>
Grid[,] GetMoveMap()
{
// 定义存储地图格子是否可以移动的二维数组
Grid[,] array = new Grid[mapRowCount, mapColumnCount];
for (int i = 0; i < mapRowCount; i++)
{
for (int j = 0; j < mapColumnCount; j++)
{
if (OccupyGridList.Contains(GridArray[i, j]))
{
GridArray[i, j].GetComponent<Grid>().isCanMove = false;
}
else
{
GridArray[i, j].GetComponent<Grid>().isCanMove = true;
}
array[i, j] = GridArray[i, j].GetComponent<Grid>();
}
}
return array;
}
/// <summary>
/// 点击格子的调用
/// </summary>
/// <param name="selectObj"></param>
public void OnClickGrid(GameObject selectObj)
{
if (selectGrid == null)
{
selectGrid = selectObj;
}
else
{
// 获取当前地图(地图记录每个点是否能移动)
RoutingObject[,] map = GetMoveMap();
// 获取起始点
RoutingObject start = selectGrid.GetComponent<RoutingObject>();
RoutingObject end = selectObj.GetComponent<RoutingObject>();
// 判断是否可以通过
if (Routing.Instance.IsRouting(start, end, map))
{
Debug.Log("判断可以通过");
// 标识为起点
start.gameObject.GetComponent<Image>().color = Color.cyan;
// 最短路径 添加到管理器
routeList.AddRange(Routing.Instance.GetRoute());
MoveBall();
}
else
{
// TODO... 提示
Debug.LogError("不能移动到当前位置...");
}
selectGrid = null;
}
}
/// <summary>
/// 执行移动逻辑
/// </summary>
void MoveBall()
{
// 模拟移动
StartCoroutine(MoveGrid());
// todo... 按需修改实际逻辑
//for (int i = 0; i < routeList.Count; i++)
//{
// GameObject go = GetGridArray(routeList[i].x, routeList[i].y);
// go.GetComponent<Image>().color = Color.green;
//}
//
//routeList.Clear();
}
/// <summary>
/// 模拟移动
/// </summary>
/// <returns></returns>
IEnumerator MoveGrid()
{
for (int i = 0; i < routeList.Count; i++)
{
GameObject go = GetGridArray(routeList[i].x, routeList[i].y);
go.GetComponent<Image>().color = Color.green;
yield return new WaitForSeconds(0.2f);
}
Spring全套教学资料
Spring是Java程序员的《葵花宝典》,其中提供的各种大招,能简化我们的开发,大大提升开发效率!目前99%的公司使用了Spring,大家可以去各大招聘网站看一下,Spring算是必备技能,所以一定要掌握。
目录:
部分内容:
Spring源码
- 第一部分 Spring 概述
- 第二部分 核心思想
- 第三部分 手写实现 IoC 和 AOP(自定义Spring框架)
- 第四部分 Spring IOC 高级应用
基础特性
高级特性 - 第五部分 Spring IOC源码深度剖析
设计优雅
设计模式
注意:原则、方法和技巧 - 第六部分 Spring AOP 应用
声明事务控制 - 第七部分 Spring AOP源码深度剖析
必要的笔记、必要的图、通俗易懂的语言化解知识难点
脚手框架:SpringBoot技术
它的目标是简化Spring应用和服务的创建、开发与部署,简化了配置文件,使用嵌入式web服务器,含有诸多开箱即用的微服务功能,可以和spring cloud联合部署。
Spring Boot的核心思想是约定大于配置,应用只需要很少的配置即可,简化了应用开发模式。
- SpringBoot入门
- 配置文件
- 日志
- Web开发
- Docker
- SpringBoot与数据访问
- 启动配置原理
- 自定义starter
微服务架构:Spring Cloud Alibaba
同 Spring Cloud 一样,Spring Cloud Alibaba 也是一套微服务解决方案,包含开发分布式应用微服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。
- 微服务架构介绍
- Spring Cloud Alibaba介绍
- 微服务环境搭建
- 服务治理
- 服务容错
- 服务网关
- 链路追踪
- ZipKin集成及数据持久化
- 消息驱动
- 短信服务
- Nacos Confifig—服务配置
- Seata—分布式事务
- Dubbo—rpc通信
Spring MVC
目录:
部分内容:
服务
- Nacos Confifig—服务配置
- Seata—分布式事务
- Dubbo—rpc通信
[外链图片转存中…(img-DFzIooDx-1715472451094)]
[外链图片转存中…(img-9JWsLt2G-1715472451094)]
Spring MVC
目录:
[外链图片转存中…(img-zMte7WQW-1715472451094)]
[外链图片转存中…(img-cKklRqqC-1715472451095)]
[外链图片转存中…(img-2Jswd09m-1715472451095)]
部分内容:
[外链图片转存中…(img-MLDtDZFi-1715472451095)]
[外链图片转存中…(img-RsiV0iRe-1715472451095)]