当前位置: 首页 > 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;听我给你吹~ 瞧我这张嘴~ 问题报错 找不…...

2.二进制的方式读写文件

文章目录 写入文件代码运行结果 读出文件代码运行结果 文件打开模式标记&#xff08;查表&#xff09; 写入文件 ------写文件一共五步&#xff1a;------ 第一步&#xff1a;包含头文件 第二步&#xff1a;创建流对象 第三步&#xff1a;指定方式打开文件 第四步&#xff1a;…...

Seata的详细解释

什么是seata Seata&#xff08;Simple Extensible Autonomous Transaction Architecture&#xff09;是一个开源的分布式事务解决方案。它是由阿里巴巴集团开发的&#xff0c;旨在解决分布式系统中的事务一致性问题。 Seata提供了一种简单易用的方式来实现跨多个数据库和服务的…...

JS手写实现洋葱圈模型

解释洋葱圈模型&#xff1a; 当我们执行第一个中间件时&#xff0c;首先输出1&#xff0c;然后调用next()&#xff0c;那么此时它会等第二个中间件执行完毕才会继续执行第一个中间件。然后执行第二个中间件&#xff0c;输出3&#xff0c;调用next()&#xff0c;执行第三中间件…...

3.Windows下安装MongoDB和Compass教程

Windows下安装MongoDB 总体体验下来&#xff0c;&#xff0c;要比MySQL的安装简单了许多&#xff0c;没有过多的配置&#xff0c;直接就上手了&#xff01; 1、下载 进入官方的下载页面https://www.mongodb.com/try/download/community&#xff0c;如下选择&#xff0c;我选…...

go反射实战

文章目录 demo1 数据类型判断demo2 打印任意类型数据 demo1 数据类型判断 使用reflect.TypeOf()方法打印go中数据类型&#xff0c;可参考go官方API文档;使用格式化参数%T也能打印数据类型。 package mainimport "fmt" import "reflect" import "io&…...

Docker 中 MySQL 的部署与管理

目录 一、Docker 中部署 MySQL1.1 部署 MySQL1.2 进入容器并创建数据库1.3 Navicat 可视化工具连接 二、可能存在的问题2.1 1130 - Host ‘172.17.0.1‘ is not allowed to connect to this MySQL server 参考资料 一、Docker 中部署 MySQL 1.1 部署 MySQL 首先&#xff0c;从…...

基础练习题之函数

前言 这些题目来自与一些刷题网站,以及c primer plus,继续练习 第一题 给你一个数&#xff0c;让他进行巴啦啦能量&#xff0c;沙鲁沙鲁&#xff0c;小魔仙大变身&#xff0c;如果进行变身的数不满足条件的话&#xff0c;就继续让他变身。。。直到满足条件为止。 巴啦啦能量…...

Java NIO浅析

NIO&#xff08;Non-blocking I/O&#xff0c;在Java领域&#xff0c;也称为New I/O&#xff09;&#xff0c;是一种同步非阻塞的I/O模型&#xff0c;也是I/O多路复用的基础&#xff0c;已经被越来越多地应用到大型应用服务器&#xff0c;成为解决高并发与大量连接、I/O处理问题…...

数据挖掘与大数据的结合

随着大数据技术的不断发展和普及&#xff0c;数据挖掘在大数据环境下的应用也变得更加广泛和深入。以下将探讨大数据技术对数据挖掘的影响&#xff0c;以及如何利用大数据技术处理海量数据并进行有效的数据挖掘&#xff0c;同时分析大数据环境下的数据挖掘挑战和解决方案。 1.…...

分布式链路追踪(一)SkyWalking(2)使用

一、使用方法 1、简介 agent探针可以让我们不修改代码的情况下&#xff0c;对Java应用上使用到的组件进行动态监控&#xff0c;获取运行数据发送到OAP上进行统计和存储。agent探针在Java使用中是使用Java agent技术实现。不需要更改任何代码&#xff0c;Java agent会通过虚拟…...