当前位置: 首页 > news >正文

unity内存优化之AB包篇(微信小游戏)

1.搭建资源服务器使用(HFS软件(https://www.pianshen.com/article/54621708008/))

using System.Collections;
using System.Collections.Generic;
using UnityEngine;using System;public class Singleton<T> where T : class, new()
{private static readonly Lazy<T> lazy = new Lazy<T>(() => new T());public static T Instance { get { return lazy.Value; } }protected Singleton() { }
}public class MonoSingleton<T> : MonoBehaviour where T : MonoBehaviour
{private static T _instance;public static T Instance{get{return _instance;}}protected virtual void Awake(){_instance = this as T;}
}

2.核心代码

using Cysharp.Threading.Tasks;
using System.Collections;
using System.Collections.Generic;
using System.Xml.Linq;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.U2D;/*
内存优化之AB包篇(微信小游戏)
问题:如何优化AB包占用的内存,游戏的AB包资源卸载策略是什么
答:卸载时机
1.该AB包被引用次数为0时候,此时缓存一定的时间,当缓存时间为0时,就可以调用bundle.Unload(true);
缓存时间内被调用重置缓存时间,引用次数增加。
这部分主要用来处理偶尔打开的界面
2.首先维护一个已经加载的AB包资源大小总值,然后设置一个内存基准值,当总值大于内存基准值的时候,
此时去卸载那些引用次数为0的ab资源(优先卸载加载早的ab包资源)。
这部分用来处理短时间内,玩家打开过多大型界面场景,如果不这么处理,手机内存会占用高且发热会严重。引用次数的维护时机(引用次数始终不小于0)
1.例如一张图片 更换属于不同ab包的资源图片时,需要先将旧的ab包  引用次数减一,界面销毁时,最后动态加载的ab图片资源也需要减一,其他资源同理
2.同时加载一个AB资源时,在AB资源未加载完毕前,需要维护一个加载中的AB包资源实际被加载次数,
由于部分界面 正在动态加载的ab包资源未加载完毕时,此界面就可能已经被销毁,如果被销毁就需要将加载中的ab包的实际被加载次数减一。
3.当ab包资源加载完毕时,如果发现加载中的此ab包维护的实际被加载次数大于0,此时ab包的引用次数加一,同时实际被加载次数减一。
4.当界面销毁时,此界面的ab包和相关依赖的引用次数需要减一,动态加载的ab包资源也需要将引用次数减一5.!!!需要注意的是 当A依赖于B时,  A的最后一个实例被销毁时  A的引用变为0  但是B的引用此刻不变,除非A被卸载 才能将B的引用减一//  A依赖于B//  A被加载 会先加载B//那么A引用为1 B引用为1//A被加载第二次 A引用为2 B引用为2//A被加载第3次 A引用为3 B引用为3// A被删除1次  引用为2  B引用为2//A被删除第二次 A引用为1 B引用为1//A被删除第3次 A引用为0 B引用为1//A被卸载时  B引用为0//  A依赖于B//  A被加载 会先加载B//那么A引用为1 B引用为1//A被加载第二次 A引用为2 B引用为2// A被删除1次  引用为1  B引用为1//A被删除第二次 A引用为0 B引用为1//A被卸载时  B引用为0//  A依赖于B//  A被加载 会先加载B//那么A引用为1 B引用为1// A被删除1次  A引用为0  B引用为1//A被卸载时  B引用为0*/
[SelectionBase]
public class LoadingAssetBundle
{private string abName;public string GetABName(){return abName;}private int realLoadedTimesInLoading = 0;//在加载中 被加载的真实次数(也就是剔除那些只加载不使用的部分,例如界面动态加载图片还没加载完毕 这个界面就被销毁了)public int GetRealLoadedTimesInLoading(){return realLoadedTimesInLoading;}public void AddRealLoadedTimesInLoading(){realLoadedTimesInLoading++;}public void ReduceRealLoadedTimesInLoading(){realLoadedTimesInLoading--;}public LoadingAssetBundle(string _abName){abName = _abName;AddRealLoadedTimesInLoading();}
}[SelectionBase]
public class LoadedAssetBundle
{private string abName;private AssetBundle bundle;private float cacheTimeBySenconds = 10;//缓存秒数不同ab可配置public float curLastCacheTime = 10;//当前剩余缓存时间public int referenceTimes = 0;//引用次数public long memoryValue = 0;//ab包大小public int loadIndexOrder = 0;//引用顺序 越小代表越早被引用private bool isUnload = false;//是否被卸载public LoadedAssetBundle(string _abName, AssetBundle _bundle, long _memoryValue, int _loadIndexOrder){isUnload = false;abName = _abName;bundle = _bundle;memoryValue = _memoryValue;//long size = long.Parse(unityWebRequest.GetResponseHeader("Content-Length"));ABManager.Instance.AddMemoryValue(_memoryValue);loadIndexOrder = _loadIndexOrder;}public AssetBundle GetAssetBundle(){return bundle;}public void AddRefer()//添加引用1{referenceTimes = referenceTimes + 1;curLastCacheTime = cacheTimeBySenconds;//重置剩余缓存1时间时间}public int ReduceRefer()//减少引用{if (referenceTimes > 0) {referenceTimes--;};return referenceTimes;}public void RefreshCacheLastTime(float time){if (referenceTimes == 0){ curLastCacheTime -= time;CheckCacheTimeUnload();}}private void CheckCacheTimeUnload(){if (isUnload) return;if (curLastCacheTime <= 0&& referenceTimes == 0) { bundle.Unload(true); //卸载时机1isUnload = true; ABManager.Instance.ReduceMemoryValue(memoryValue);ABManager.Instance.RemoveABRequest(abName);ABManager.Instance.ReduceDependciedRefer(abName);Debug.Log($"curLastCacheTime Unload{abName},Count={ABManager.Instance.cachedLoadedDic.Count}");}}public void CheckOverMemoryUnload(int curMinReferIndexOrder){if (isUnload) return;if (referenceTimes == 0 && ABManager.Instance.CheckOverMemoryMemoryReferenceValue())//&& curMinReferIndexOrder == loadIndexOrder{bundle.Unload(true);//卸载时机2isUnload = true;ABManager.Instance.ReduceMemoryValue(memoryValue);ABManager.Instance.RemoveABRequest(abName);ABManager.Instance.ReduceDependciedRefer(abName);Debug.Log($"Unload{abName}");}}public string GetABName(){return abName;}public bool IsUnLoad(){return isUnload;}
}public class ABManager : MonoSingleton<ABManager>
{public Dictionary<string, LoadedAssetBundle> cachedLoadedDic = new Dictionary<string, LoadedAssetBundle>();private Dictionary<string, LoadingAssetBundle> cachedLoadingDic = new Dictionary<string, LoadingAssetBundle>();private long memoryReferenceValue= 995406;//内存基准值private long curMemoryValue = 0;//内存当前值private int curReferIndexOrder = 0;//当前索引private int curMinReferIndexOrder = 0;//当前被加载最早的索引public void AddMemoryValue(long _memoryValue){curMemoryValue = curMemoryValue + _memoryValue;//print("curMemoryValue" + curMemoryValue);}public void ReduceMemoryValue(long _memoryValue){//Debug.Log("memoryValue" + _memoryValue);curMemoryValue = curMemoryValue - _memoryValue;curMinReferIndexOrder++;if (curMinReferIndexOrder  > curReferIndexOrder){curMinReferIndexOrder = curReferIndexOrder;}}public bool CheckOverMemoryMemoryReferenceValue(){return curMemoryValue > memoryReferenceValue;}private float checkSpan =  0.3f;public float time;List<string> removeList = new List<string>();public int CachedLoadedCount;private void CheckUnLoadCachedLoaded(){time += Time.fixedDeltaTime;if (time > checkSpan){time = 0;removeList.Clear();foreach (var item in cachedLoadedDic){if (!cachedLoadingDic.ContainsKey(item.Key)){item.Value.RefreshCacheLastTime(checkSpan);item.Value.CheckOverMemoryUnload(curMinReferIndexOrder);if (item.Value.IsUnLoad()) removeList.Add(item.Key);}}for (int i = 0; i < removeList.Count; i++){print($"removeList={removeList[i]}");cachedLoadedDic.Remove(removeList[i]);}}CachedLoadedCount = cachedLoadedDic.Count;}// Update is called once per framevoid FixedUpdate(){CheckUnLoadCachedLoaded();}private AssetBundle mainAB = null; //主包private AssetBundleManifest mainManifest = null; //主包中配置文件---用以获取依赖包private string basePath = "http://192.168.31.208/AssetBundles/";private string mainABName = "AssetBundles";public Dictionary<string, string> AssetNameToABName = new Dictionary<string, string>();public async UniTask<GameObject> LoadAsset(string assetName){string abName = assetName.ToLower() + ".ab";AssetBundle ab = await LoadABPackage(abName);//await UniTask.SwitchToMainThread();return ab.LoadAsset<GameObject>(assetName);}/// <summary>/// 加载图集里面的图片/// 案例///   Image a = nul;;///   if (a != null)///        ABManager.Instance.UnloadAsset(a);///    a = ABManager.Instance.LoadAtlasSprite(a);/// </summary>/// <param name="assetName"></param>/// <param name="textureName"></param>/// <returns></returns>public async UniTask<Sprite> LoadAtlasSprite(string assetName, string textureName){string abName = assetName.ToLower() + ".ab";AssetBundle ab = await LoadABPackage(abName);SpriteAtlas spriteAtlas = ab.LoadAsset<SpriteAtlas>(assetName);return spriteAtlas.GetSprite(textureName);}//单个包卸载public void ReduceRefer(string assetName){string abName = assetName.ToLower() + ".ab";if (cachedLoadingDic.ContainsKey(abName)){cachedLoadingDic[abName].ReduceRealLoadedTimesInLoading();}else{//--引用if (cachedLoadedDic.ContainsKey(abName)){int referValue =  cachedLoadedDic[abName].ReduceRefer();//  A依赖于B//  A被加载 会先加载B//那么A引用为1 B引用为1//A被加载第二次 A引用为2 B引用为2//A被加载第3次 A引用为3 B引用为3// A被删除1次  引用为2  B引用为2//A被删除第二次 A引用为1 B引用为1//A被删除第3次 A引用为0 B引用为1//A被卸载时  B引用为0//  A依赖于B//  A被加载 会先加载B//那么A引用为1 B引用为1//A被加载第二次 A引用为2 B引用为2// A被删除1次  引用为1  B引用为1//A被删除第二次 A引用为0 B引用为1//A被卸载时  B引用为0//  A依赖于B//  A被加载 会先加载B//那么A引用为1 B引用为1// A被删除1次  A引用为0  B引用为1//A被卸载时  B引用为0if (referValue > 0){ReduceDependciedRefer(abName);}}}}public void ReduceDependciedRefer(string abName){string[] dependencies = mainManifest.GetAllDependencies(abName);for (int i = 0; i < dependencies.Length; i++){if (cachedLoadedDic.ContainsKey(dependencies[i])){cachedLoadedDic[dependencies[i]].ReduceRefer();}}}//加载AB包private async UniTask<AssetBundle> LoadABPackage(string abName){//加载ab包,需一并加载其依赖包。if (mainAB == null){//获取ab包内容mainAB = await DownloadABPackage(mainABName);//获取主包下的AssetBundleManifest资源文件(存有依赖信息)mainManifest = mainAB.LoadAsset<AssetBundleManifest>("AssetBundleManifest");}//根据manifest获取所有依赖包的名称 固定API 保证不丢失依赖string[] dependencies = mainManifest.GetAllDependencies(abName);if (dependencies.Length > 0){var tasks = new List<UniTask>(); // 创建一个任务列表来存储异步操作//循环加载所有依赖包for (int i = 0; i < dependencies.Length; i++){//如果不在缓存则加入if (!cachedLoadedDic.ContainsKey(dependencies[i])) tasks.Add(LoadABPackage(dependencies[i]));else{cachedLoadedDic[dependencies[i]].AddRefer(); //++引用}}// 使用UniTask.WhenAll等待所有任务完成await UniTask.WhenAll(tasks);}//加载目标包 -- 同理注意缓存问题if (cachedLoadedDic.ContainsKey(abName)){cachedLoadedDic[abName].AddRefer(); //++引用Debug.Log($"ContainsKey{abName}");return (cachedLoadedDic[abName].GetAssetBundle());}else{await DownloadABPackage(abName);Debug.Log($"DownloadABPackage{abName}");return (cachedLoadedDic[abName].GetAssetBundle());}}//存儲下載操作Dictionary<string, UnityWebRequestAsyncOperation> ABRequestOpera = new Dictionary<string, UnityWebRequestAsyncOperation>();public void RemoveABRequest(string abname){string url = basePath + abname;ABRequestOpera[url].webRequest.Dispose();//试试多个异步创建ABRequestOpera.Remove(url);}async UniTask<AssetBundle> DownloadABPackage(string abname){if (cachedLoadedDic.ContainsKey(abname)){cachedLoadedDic[abname].AddRefer();return cachedLoadedDic[abname].GetAssetBundle();}string url = basePath + abname;Debug.Log(url);if (!cachedLoadingDic.ContainsKey(abname)){cachedLoadingDic.Add(abname, new LoadingAssetBundle(abname));}else{cachedLoadingDic[abname].AddRealLoadedTimesInLoading();}if (!ABRequestOpera.ContainsKey(url)){UnityWebRequest req = UnityWebRequestAssetBundle.GetAssetBundle(url);UnityWebRequestAsyncOperation operation = req.SendWebRequest();ABRequestOpera.Add(url, operation);}await ABRequestOpera[url];if (!cachedLoadedDic.ContainsKey(abname)){curReferIndexOrder++;AssetBundle ab = DownloadHandlerAssetBundle.GetContent(ABRequestOpera[url].webRequest);long size = long.Parse(ABRequestOpera[url].webRequest.GetResponseHeader("Content-Length"));cachedLoadedDic.Add(abname, new LoadedAssetBundle(abname,ab, size, curReferIndexOrder));}if (cachedLoadingDic.ContainsKey(abname)&&cachedLoadingDic[abname].GetRealLoadedTimesInLoading() > 0){cachedLoadedDic[abname].AddRefer();cachedLoadingDic[abname].ReduceRealLoadedTimesInLoading();if (cachedLoadingDic[abname].GetRealLoadedTimesInLoading() == 0){cachedLoadingDic.Remove(abname);}}    return cachedLoadedDic[abname].GetAssetBundle();}//所有包卸载public void UnLoadAll(){AssetBundle.UnloadAllAssetBundles(false);//注意清空缓存cachedLoadedDic.Clear();cachedLoadingDic.Clear();mainAB = null;mainManifest = null;}}

3..打包AB包代码

using UnityEngine;
using UnityEditor;
using System.IO;
using System;
using System.Collections.Generic;/// <summary>
/// AB包创建
/// </summary>
public class CreateAssetBundles : MonoBehaviour
{public static string BuildAssetBundlePath = Application.dataPath + "/AssetsPach/AssetBundles";[MenuItem("Build/BuildAssetBundles")]public static void BuildAssetBundle(){SetAssetBundle();string dir = BuildAssetBundlePath; //相对路径if (!Directory.Exists(dir))   //判断路径是否存在{Directory.CreateDirectory(dir);}BuildPipeline.BuildAssetBundles(dir, BuildAssetBundleOptions.None, EditorUserBuildSettings.activeBuildTarget); //这里是第一点注意事项,BuildTarget类型选择WebGLAssetDatabase.Refresh();Debug.Log("打包完成");}//需要打包的资源目录public static string SetAssetBundlePath = Application.dataPath + "/AssetsPach/WortAsset";public static void SetAssetBundle(){string dir = SetAssetBundlePath; //相对路径AssetDatabase.RemoveUnusedAssetBundleNames();//移除无用的AssetBundleName//Debug.LogError(Application.dataPath);//上级路径 F:/TUANJIEProject/My project/Assetslist_Files = new List<stru_FileInfo>();ContinueCheck(dir);for (int a = 0; a < list_Files.Count; a++)//{SetBundleName(list_Files[a].assetPath);}Debug.Log("生成ab包完成");//SetBundleName("Assets/Ship/AC_Enterprise_T01/prefab/AC_Enterprise_T01_M01_ShipMesh.prefab");}//******资源参数static List<stru_FileInfo> list_Files;//文件列表static string assetBundleName = "ab";static string assetBundleVariant = "";//int indentation;//缩进等级struct stru_FileInfo{public string fileName;public string filePath;//绝对路径public string assetPath;//U3D内部路径public Type assetType;}static void ContinueCheck(string path){DirectoryInfo directory = new DirectoryInfo(path);FileSystemInfo[] fileSystemInfos = directory.GetFileSystemInfos();//获取文件夹下的文件信息foreach (var item in fileSystemInfos){int idx = item.ToString().LastIndexOf(@"\");string name = item.ToString().Substring(idx + 1);if (!name.Contains(".meta"))//剔除meta文件{CheckFileOrDirectory(item, path + "/" + name);}}}static void CheckFileOrDirectory(FileSystemInfo fileSystemInfo, string path){FileInfo fileInfo = fileSystemInfo as FileInfo;if (fileInfo != null){stru_FileInfo t_file = new stru_FileInfo();t_file.fileName = fileInfo.Name;t_file.filePath = fileInfo.FullName;t_file.assetPath = "Assets" + fileInfo.FullName.Replace(Application.dataPath.Replace("/", "\\"), "");//用于下一步获得文件类型t_file.assetType = AssetDatabase.GetMainAssetTypeAtPath(t_file.assetPath);list_Files.Add(t_file);}else{ContinueCheck(path);}}static void SetBundleName(string path){print(path);var importer = AssetImporter.GetAtPath(path);string[] strs = path.Split(".");string[] dictors = strs[0].Split('/');if (importer){if (assetBundleVariant != ""){importer.assetBundleVariant = assetBundleVariant;}if (assetBundleName != ""){importer.assetBundleName = path.ToLower() + "." + assetBundleName;}}else{Debug.Log("importer是空的" + path);//jpg  png tga}}}

4.资源如下 几张美女壁纸,每个预设都是一个壁纸和关闭按钮界面挂载了代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;public class Panel : MonoBehaviour
{public string asssetName;// Start is called before the first frame updatevoid Start(){transform.GetComponentInChildren<Button>().onClick.AddListener(() => {//StartCoroutine(TestLoadSize();UIManager.Instance.DeletePanel(this);});}// Update is called once per framevoid Update(){}
}

4.启动场景和代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;public class UIManager :  MonoSingleton<UIManager>
{public Transform parent;// Start is called before the first frame updatevoid Start(){for (int i = 0; i < transform.childCount; i++){int index = i;transform.GetChild(i).GetComponent<Button>().onClick.AddListener(() => {//StartCoroutine(TestLoadSize();print(111);DownPanel($"Assets/Assetspach/wortasset/prefabs/Panel{index + 1}.prefab");//DownPanel($"Assets/Assetspach/wortasset/prefabs/Panel{index + 1}.prefab");});}}async void DownPanel(string asssetName){GameObject go = await ABManager.Instance.LoadAsset(asssetName);GameObject.Instantiate(go, parent).GetComponent<Panel>().asssetName =asssetName;}// Update is called once per framepublic  void DeletePanel(Panel panel){ABManager.Instance.ReduceRefer(panel.asssetName);DestroyImmediate(panel.gameObject);}
}

相关文章:

unity内存优化之AB包篇(微信小游戏)

1.搭建资源服务器使用(HFS软件(https://www.pianshen.com/article/54621708008/)) using System.Collections; using System.Collections.Generic; using UnityEngine;using System;public class Singleton<T> where T : class, new() {private static readonly Lazy<…...

白话模电:3.三极管(考研面试与笔试常考问题)

一、三极管的简单判断 1.判断三极 1)给了图 左边是b,有箭头是e,剩下是c 2)给了电位 b:中间值&#xff0c;e:较近值(离中间值)&#xff0c;c:较远值(离中间值) 2.判断流向 bc同向(共同流向“|”或共同流离“|”)&#xff0c;e与bc反向 3.判断材料 4.判断类型 5.判断能否构…...

LeetCode 395. 至少有K个重复字符的最长子串

解题思路 一道滑动窗口题型&#xff0c;不过滑动窗口的长度是不同种类元素的个数。 这里需要定义两个变量 cnt,overk。overk表示的是满足大于k的字符数, cnt表示的是该窗口中不同元素的个数且cnt>1&&cnt<26。 相关代码 class Solution {public int longestSub…...

C#重新认识笔记_ FixUpdate + Update

C#重新认识笔记_ FixUpdate Update Update: 刷新频率不一致,非物理对象的移动&#xff0c;简单的刷新可用&#xff0c; FixedUpdate: 刷新频率一致,按照固定频率刷新&#xff0c;一般调用FixedUpdate之后&#xff0c;会立即进入必要的物理计算中,因此&#xff0c;任何影响刚…...

Django 解决新建表删除后无法重新创建等问题

Django 解决新建表删除后无法重新创建等问题 问题发生描述处理办法首先删除了app对应目录migrations下除 __init__.py以外的所有文件:然后&#xff0c;删除migrations中关于你的app的同步数据数据库记录最后&#xff0c;重新执行迁移插入 问题发生描述 Django创建的表&#xf…...

Qt教程 — 3.3 深入了解Qt 控件:Input Widgets部件(2)

目录 1 Input Widgets简介 2 如何使用Input Widgets部件 2.1 QSpinBox组件-窗口背景不透明调节器 2.2 DoubleSpinBox 组件-来调节程序窗口的整体大小 2.3 QTimeEdit、QDateEdit、QDateTimeEdit组件-编辑日期和时间的小部件 Input Widgets部件部件较多&#xff0c;将分为三…...

数据分析-Pandas的直接用Matplotlib绘图

数据分析-Pandas的直接用Matplotlib绘图 数据分析和处理中&#xff0c;难免会遇到各种数据&#xff0c;那么数据呈现怎样的规律呢&#xff1f;不管金融数据&#xff0c;风控数据&#xff0c;营销数据等等&#xff0c;莫不如此。如何通过图示展示数据的规律&#xff1f; 数据表…...

Jmeter---分布式

分布式&#xff1a;多台机协作&#xff0c;以集群的方式完成测试任务&#xff0c;可以提高测试效率。 分布式架构&#xff1a;控制机&#xff08;分发任务&#xff09;与多台执行机&#xff08;执行任务&#xff09; 环境搭建&#xff1a; 不同的测试机上安装 Jmeter 配置基…...

安卓基础面试题

自定义view Android自定义View-CSDN博客 view和viewgroup View和ViewGroup的区别- view的事件分发 事件分发详解---历史最容易理解 组件化 Android-组件化开发 什么是ANR Android ANR详解-CSDN博客 Android性能优化 Android 优化-CSDN博客 Aroute 原理 Arouter框架原理…...

如何在 Linux ubuntu 系统上搭建 Java web 程序的运行环境

如何在 Linux ubuntu 系统上搭建 Java web 程序的运行环境 基于包管理器进行安装 Linux 会把一些软件包放到对应的服务器上&#xff0c;通过包管理器这样的程序&#xff0c;来把这些软件包给下载安装 ubuntu系统上的包管理器是 apt centos系统上的包管理器 yum 注&#xff1a;…...

Redis实现分布式锁源码分析

为什么使用分布式锁 单机环境并发时&#xff0c;使用synchronized或lock接口可以保证线程安全&#xff0c;但它们是jvm层面的锁&#xff0c;分布式环境并发时&#xff0c;100个并发的线程可能来自10个服务节点&#xff0c;那就是跨jvm了。 简单分布式锁实现 SETNX 格式&…...

SCI 图像处理期刊

引用 一区 1. IEEE TRANSACTIONS ON PATTERN ANALYSIS AND MACHINE INTELLIGENCE 顶刊:是 出版商:IEEE 2. IEEE Transactions on Multimedia 顶刊:是 出版商:IEEE 3. Information Fusion 顶刊:是 出版商:ELSEVIER 4.IEEE TRANSACTIONS ON IMAGE PROCESSING 顶刊:是 出版商:I…...

数据结构-红黑树

1.容器 容器用于容纳元素集合&#xff0c;并对元素集合进行管理和维护&#xff0e; 传统意义上的管理和维护就是&#xff1a;增&#xff0c;删&#xff0c;改&#xff0c;查&#xff0e; 我们分析每种类型容器时&#xff0c;主要分析其增&#xff0c;删&#xff0c;改&#xff…...

双指针、bfs与图论

1238. 日志统计 - AcWing题库 import java.util.*;class PII implements Comparable<PII>{int x, y;public PII(int x, int y){this.x x;this.y y;}public int compareTo(PII o){return Integer.compare(x, o.x);} }public class Main{static int N 100010, D, K;st…...

RabbitMQ高级-高级特性

1.消息可靠性传递 在使用RabbitMQ的时候&#xff0c;作为消息发送方希望杜绝任何消息丢失或者投递失败场景。RabbitMQ为我们提供了两种方式来控制消息的投递可靠性模式 1.confirm 确认模式 确认模式是由exchange决定的 2.return 退回模式 回退模式是由routing…...

Word粘贴时出现“运行时错误53,文件未找到:MathPage.WLL“的解决方案

在安装完MathType后&#xff0c;打开word复制粘贴时报错“运行时错误53,文件未找到&#xff1a;MathPage.WLL” 首先确定自己电脑的位数&#xff08;这里默认32位&#xff09; 右击MathType桌面图标&#xff0c;点击“打开文件所在位置”&#xff0c; 然后分别找到MathPage.W…...

html元素基本使用

前言 大家好&#xff0c;我是jiantaoyab&#xff0c;第一次学习前端的html&#xff0c;写一篇笔记总结常用的元素 语义化 例如只要是 不管字体的大小是怎么样&#xff0c;有没有加粗都是标题&#xff0c;元素显示到页面中的效果应该由css决定&#xff0c;这就是语义化。 文…...

PHP+golang开源办公系统CRM管理系统

基于ThinkPHP6 Layui MySQL的企业办公系统。集成系统设置、人事管理、消息管理、审批管理、日常办公、客户管理、合同管理、项目管理、财务管理、电销接口集成、在线签章等模块。系统简约&#xff0c;易于功能扩展&#xff0c;方便二次开发。 服务器运行环境要求 PHP > 7.…...

smartmontools-5.43交叉编译Smartctl

嵌入式系统的sata盘经常故障&#xff0c;需要使用smatctl工具监控和诊断sata故障。 1. 从网上下载开源smartmontools-5.43包。 2. 修改makefile进行交叉编译。 由于软件包中已经包含Makefile.am&#xff0c;Makefile.in。直接运行 automake --add-missing 生成Makefile。 3.…...

idea找不到或无法加载主类

前言 今天在运行项目的时候突然出了这样一个错误&#xff1a;IDEA 错误 找不到或无法加载主类,相信只要是用过IDEA的朋友都 遇到过它吧&#xff0c;但是每次遇到都是一顿焦头烂额、抓耳挠腮、急赤白咧&#xff01;咋整呢&#xff1f;听我给你吹~ 瞧我这张嘴~ 问题报错 找不…...

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…...

【网络】每天掌握一个Linux命令 - iftop

在Linux系统中&#xff0c;iftop是网络管理的得力助手&#xff0c;能实时监控网络流量、连接情况等&#xff0c;帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路

进入2025年以来&#xff0c;尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断&#xff0c;但全球市场热度依然高涨&#xff0c;入局者持续增加。 以国内市场为例&#xff0c;天眼查专业版数据显示&#xff0c;截至5月底&#xff0c;我国现存在业、存续状态的机器人相关企…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命

在华东塑料包装行业面临限塑令深度调整的背景下&#xff0c;江苏艾立泰以一场跨国资源接力的创新实践&#xff0c;重新定义了绿色供应链的边界。 跨国回收网络&#xff1a;废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点&#xff0c;将海外废弃包装箱通过标准…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案

随着新能源汽车的快速普及&#xff0c;充电桩作为核心配套设施&#xff0c;其安全性与可靠性备受关注。然而&#xff0c;在高温、高负荷运行环境下&#xff0c;充电桩的散热问题与消防安全隐患日益凸显&#xff0c;成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

IP如何挑?2025年海外专线IP如何购买?

你花了时间和预算买了IP&#xff0c;结果IP质量不佳&#xff0c;项目效率低下不说&#xff0c;还可能带来莫名的网络问题&#xff0c;是不是太闹心了&#xff1f;尤其是在面对海外专线IP时&#xff0c;到底怎么才能买到适合自己的呢&#xff1f;所以&#xff0c;挑IP绝对是个技…...