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);}
}

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

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

相关文章

【集成开发环境】-VS Code:C/C++ 环境配置

简介 VS Code&#xff0c;全称Visual Studio Code&#xff0c;是一款由微软开发的跨平台源代码编辑器。它支持Windows、Linux和macOS等操作系统&#xff0c;并且具有轻量级、高效、可扩展等特点&#xff0c;深受广大开发者的喜爱。 VS Code拥有丰富的功能特性&#xff0c;包括…

计算机三级网络技术综合题第三题、第四题详细解析

第三大题 DHCP报文分析&#xff08;10分&#xff09; 一、DHCP工作流程&#xff08;一般情况下&#xff09; 报文摘要 对应上面报文1—4 报文1、3DHCP&#xff1a;Request&#xff1b; 报文2、4DHCP&#xff1a;Reply。 例题&#xff08;第三套&#xff09;&#xff1a;在一…

程序员入行忠告!

点击下方“JavaEdge”&#xff0c;选择“设为星标” 第一时间关注技术干货&#xff01; 关注我&#xff0c;紧跟本系列专栏文章&#xff0c;咱们下篇再续&#xff01; 作者简介&#xff1a;魔都技术专家兼架构&#xff0c;多家大厂后端一线研发经验&#xff0c;各大技术社区头部…

十五、自回归(AutoRegressive)和自编码(AutoEncoding)语言模型

参考自回归语言模型&#xff08;AR&#xff09;和自编码语言模型&#xff08;AE&#xff09; 1 自回归语言模型&#xff08; AR&#xff09; 自回归语言模型&#xff08;AR&#xff09;就是根据上文内容&#xff08;或下文内容&#xff09;预测下一个&#xff08;或前一个&…

安装OpenEBS,镜像总是报错ImagePullBackOff或者ErrImagePull的解决方法

按照 KubeSphere 官方文档安装 OpenEBS&#xff0c;镜像总是报错ImagePullBackOff或者ErrImagePull的解决方法 helm 有很多更换 源 的文章&#xff0c;有一些是写更换阿里云的源&#xff0c;但是阿里云的源根本没更新OpenEBS的镜像。 在网上找到1个可用的源&#xff1a; 可用的…

探讨TCP的可靠性以及三次握手的奥秘

&#x1f31f; 欢迎来到 我的博客&#xff01; &#x1f308; &#x1f4a1; 探索未知, 分享知识 !&#x1f4ab; 本文目录 1. TCP的可靠性机制1.2可靠性的基础上,尽可能得提高效率 2. TCP三次握手过程3. 为何不是四次握手&#xff1f; 在互联网的复杂世界中&#xff0c;TCP&am…

基于springboot的高校教师教研信息填报系统

文章目录 项目介绍主要功能截图&#xff1a;部分代码展示设计总结项目获取方式 &#x1f345; 作者主页&#xff1a;超级无敌暴龙战士塔塔开 &#x1f345; 简介&#xff1a;Java领域优质创作者&#x1f3c6;、 简历模板、学习资料、面试题库【关注我&#xff0c;都给你】 &…

亚马逊云科技Glue

Glue 最重要的部分&#xff0c; ETL&#xff1a;用于从 A 点&#xff08;我们的源数据&#xff09;提取、转换和加载数据到 B 点&#xff08;目标文件或数据存储库&#xff09;。 AWS Glue 会为您执行大量此类工作。 转换通常是更繁重的工作&#xff0c;需要从各种来源进行组合…

【嵌入式DIY实例】-自动割草机器

自动割草机器 文章目录 自动割草机器1、割草机器介绍2、硬件准备3、功能设计4、硬件接线5、代码实现本文将介绍如何使用 Arduino 构建一个简易自动割草机机器人或割草机机器人。该机器人可以自动剪掉花园里多余的草。如果花园里有障碍物,它会自动改变方向。帮助以减少人力。 警…

【Elasticsearch】windows安装elasticsearch教程及遇到的坑

一、安装参考 1、安装参考&#xff1a;ES的安装使用(windows版) elasticsearch的下载地址&#xff1a;https://www.elastic.co/cn/downloads/elasticsearch ik分词器的下载地址&#xff1a;https://github.com/medcl/elasticsearch-analysis-ik/releases kibana可视化工具下载…

网络编程套接字——实现简单的UDP网络程序

目录 1、预备知识 1.1、认识端口号 1.2、端口号 vs 进程pid 1.3、认识TCP协议 1.4、认识UDP协议 1.5、网络字节序 2、socket编程接口 2.1、socket常见API 2.2、sockaddr结构 3、实现一个简易的UDP服务器和客户端通信 log.hpp UdpServer.hpp UdpClient.cc Main.cc…

upload-labs通关方式

pass-1 通过弹窗可推断此关卡的语言大概率为js&#xff0c;因此得出两种解决办法 方法一 浏览器禁用js 关闭后就逃出了js的验证就可以正常php文件 上传成功后打开图片链接根据你写的一句话木马执行它&#xff0c;我这里采用phpinfo&#xff08;&#xff09; 方法二 在控制台…

【网络编程基础(一)】网络基础和SOCKET

这里写目录标题 1、网络三要素2、IPV4和IPV6区别3、网络交互3.1、交互模型图3.2、基础通信协议3.3、OSI参考模型与TCP/IP参考模型对应关系 4、SOCKET网络套接字4.1、SOCKET分类4.2、基于流式套接字的编程流程4.3、网络通信雏形4.4、socket函数4.4.1、socket函数示例 4.5、bind函…

蓝桥杯小白赛第 7 场 3.奇偶排序(sort排序 + 双数组)

思路&#xff1a;在第一次看到这道题的时候我第一想法是用冒泡&#xff0c;但好像我的水平还不允许我写出来。我又读了遍题目发现它的数据很小&#xff0c;我就寻思着把它分成奇偶两部分。应该怎么分呢&#xff1f; 当然在读入的时候把这个问题解决就最好了。正好它的数据范围…

【相关问题解答1】bert中文文本摘要代码:import时无法找到包时,几个潜在的原因和解决方法

【相关问题解答1】bert中文文本摘要代码 写在最前面问题1问题描述一些建议import时无法找到包时&#xff0c;几个潜在的原因和解决方法1. 模块或包的命名冲突解决方法&#xff1a; 2. 错误的导入路径解决方法&#xff1a; 3. 第三方库的使用错误解决方法&#xff1a; 4. 包未正…

C++算法学习心得八.动态规划算法(4)

1.零钱兑换&#xff08;322题&#xff09; 题目描述&#xff1a; 给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额&#xff0c;返回 -1。 你可以认为每种硬币的数量是无限的。…

CSDN学习笔记总索引(2024)——我的创作纪念日(1024)

2021-05-21至2024-03-17笔记&#xff0c;收集并展示浏览阅读点赞收藏等数据。 (本笔记适合初通Python&#xff0c;对其基本数据类型字符串str、列表list、元组tuple、字典dict初步了解&#xff0c;认识Linux获取Html文本指令crul、会使正则模块re的coder翻阅) 【学习的细节是欢…

VS2019加QT5.14中Please assign a Qt installation in ‘Qt Project Settings‘.问题的解决

第一篇&#xff1a; 原文链接&#xff1a;https://blog.csdn.net/aoxuestudy/article/details/124312629 error:There’ no Qt version assigned to project mdi.vcxproj for configuration release/x64.Please assign a Qt installation in “Qt Project Settings”. 一、分…

Linux基础开发工具之yum与vim

1. Linux软件包管理器——yum 1.1 什么是软件包&#xff1f; 在Linux下安装软件, 一个通常的办法是下载到程序的源代码, 并进行编译, 得到可执行程序. 但是这样太麻烦了, 于是有些人把一些常用的软件提前编译好, 做成软件包(可以理解成windows上的安装程序)放在一个服务器上, …

Nginx离线安装(保姆级教程)

1、下载与安装gcc-c环境 获取rpm包的方式很多&#xff0c;在这里推荐使用yum工具获取&#xff0c;因为手动从官网下载&#xff0c;手动执行rpm -Uvh *.rpm --nodeps --force命令进行安装&#xff0c;可能会缺少某个依赖&#xff0c;我们也不确定到底需要哪些依赖。 因此需要准…