目录

13.Coroutines(协程)

Lua中的协程

从CLR代码中的协程

从CLR代码中的协程作为CLR迭代器

注意事项

抢占式协程

14.Hardwire descriptors(硬编码描述符)

为什么需要“硬编码”

什么是“硬编码”

如何进行硬编码

硬编码的优缺点

硬编码是实现IL2CPP、AOT或iOS兼容性的必要条件吗?

术语表

15.Sandboxing(沙盒)

为什么需要沙盒化

沙盒化检查清单

移除“危险”的 API

16.Tips and tricks for Unity3D(Unity3D的提示和技巧)

支持的平台

其他建议

使用更显式的构造函数之一初始化脚本加载器

17.FAQ / Recipes

如何重定向打印函数的输出?

如何将输入重定向到Lua程序?

如何重定向Lua程序的IO流?

如何限制脚本在不丢失状态的情况下执行的指令数?


MoonSharp 文档一-CSDN博客

MoonSharp 文档二-CSDN博客

MoonSharp 文档三-CSDN博客

MoonSharp 文档四-CSDN博客

13.Coroutines(协程)

来自 C# 和 Lua。

文档地址:MoonSharp

Lua中的协程

Lua 中的协程是开箱即用的支持。实际上,只要你不故意排除协程模块(参见沙盒化),它们就可以免费使用。有很多注意事项(这些也偶然适用于原始的 Lua 实现),并在下面的 “注意事项” 部分进行了讨论。

使用任何 Lua 协程教程来操作它们。

从CLR代码中的协程

协程可以通过脚本 CreateCoroutine 方法创建,该方法接受一个必须是函数的 DynValue。

string code = @"return function()local x = 0while true dox = x + 1coroutine.yield(x)endend";// Load the code and get the returned function
Script script = new Script();
DynValue function = script.DoString(code);// Create the coroutine in C#
DynValue coroutine = script.CreateCoroutine(function);// Resume the coroutine forever and ever..
while (true)
{DynValue x = coroutine.Coroutine.Resume();Console.WriteLine("{0}", x);
}

从CLR代码中的协程作为CLR迭代器

可以像调用迭代器一样调用协程:

string code = @"return function()local x = 0while true dox = x + 1coroutine.yield(x)if (x > 5) thenreturn 7endendend";// Load the code and get the returned function
Script script = new Script();
DynValue function = script.DoString(code);// Create the coroutine in C#
DynValue coroutine = script.CreateCoroutine(function);// Loop the coroutine 
string ret = "";foreach (DynValue x in coroutine.Coroutine.AsTypedEnumerable())
{ret = ret + x.ToString();
}Assert.AreEqual("1234567", ret);

注意事项

现在我们来到了协程相关内容中最重要的部分。就像在原始的 Lua 中一样,无法从嵌套调用中执行 yield 操作。

特别是在 MoonSharp 中,如果你在从 Lua 调用的 C# 函数中调用一个脚本,你不能使用 yield 来恢复到 C# 调用外部的协程。

不过有一个解决办法:返回一个 TailCallRequest 类型的 DynValue

return DynValue.NewTailCallReq(luafunction, arg1, arg2...); 

还可以指定一个 continuation(延续)——这是一段函数,它将在尾调用执行完成后被调用。

在 99% 的情况下,这可能是过度设计——甚至在大多数情况下,Lua 标准库也无法正确处理回调与 yield 的结合。但如果你计划自己实现像 `load`、`pcall` 或 `coroutine.resume` 这样的 API,这就是必需的。

另外,在某些边缘情况下,MoonSharp 处理 yield 的方式与标准 Lua 不同(在我尝试过的所有情况中,MoonSharp 的方式都更好,但谁知道呢)。例如,`tostring()` 支持在调用 `__tostring` 元方法时执行 yield 操作,而不会引发错误。

抢占式协程

在 MoonSharp 中,即使协程没有调用 `coroutine.yield`,也可以将其挂起。例如,如果想要非破坏性地限制脚本占用的 CPU 时间,这可能会很有用。但为了保持脚本的一致性,有一些需要注意的地方。

让我们从一个例子开始:

string code = @"function fib(n)if (n == 0 or n == 1) thenreturn 1;elsereturn fib(n - 1) + fib(n - 2);endend";// Load the code and get the returned function
Script script = new Script(CoreModules.None);
script.DoString(code);// get the function
DynValue function = script.Globals.Get("fib");// Create the coroutine in C#
DynValue coroutine = script.CreateCoroutine(function);// Set the automatic yield counter every 10 instructions. 
// 10 is likely too small! Use a much bigger value in your code to avoid interrupting too often!
coroutine.Coroutine.AutoYieldCounter = 10;int cycles = 0;
DynValue result = null;// Cycle until we get that the coroutine has returned something useful and not an automatic yield..
for (result = coroutine.Coroutine.Resume(8); result.Type == DataType.YieldRequest;result = coroutine.Coroutine.Resume()) 
{cycles += 1;
}// Check the values of the operation
Assert.AreEqual(DataType.Number, result.Type);
Assert.AreEqual(34, result.Number);

步骤如下:

1. 创建一个协程 

2. 将 `AutoYieldCounter` 设置为一个大于 0 的数字。1000 是一个不错的起点,可以根据需要调整。这个数字表示在执行多少条指令后,协程会主动挂起并返回给调用者。  

3. 调用 `coroutine.Coroutine.Resume(...)` 并传入适当的参数。

4. 如果上述调用的返回类型是 `DataType.YieldRequest`,则不带参数调用 `coroutine.Coroutine.Resume()`。 

5. 重复上一步,直到返回一个真正的结果类型。 

6. 完成。  

注意事项:

1. 如果代码重新进入(例如,`string.gsub` 的回调函数),在返回到“可挂起状态”之前,它不会被抢占。

2. 将标准协程操作与抢占式操作混合使用是可能的,但危险且复杂。请记住,协程可以在任何地方被抢占式挂起,因此无法保证操作的原子性等。如果混合使用,请务必小心。

14.Hardwire descriptors(硬编码描述符

自2016年以来帮助 AOT 和 IL2CPP

文档地址:MoonSharp

如果您不知道本页中使用的某些术语,请参阅底部的术语表部分。

为什么需要“硬编码”

MoonSharp 像大多数类库一样,使用反射,有时还会在运行时生成代码,以便从 Lua 脚本中访问 C# 代码。

从根本上说,MoonSharp 已经比大多数其他脚本引擎更加温和,原因在于:

理论上,它可以在完全不使用反射的情况下运行(尽管需要编写大量代码),这有助于提高速度并避免一些麻烦(如 IL2CPP 的 link.xml 问题)。
它不会在不应该生成IL代码的平台上生成IL代码(如 Xamarin 的 iOS、Unity 的 IL2CPP 平台等)。
前一点不会导致功能损失,只是速度会稍微慢一些。
这些都是优点,并且带来了很大的兼容性,但还可以做得更多。

如果大部分反射都被移除(剩下的少量反射也无害),并且还能获得更好的性能,那会怎样?

听起来好得不像真的?从某种意义上说,是的。这就是“硬编码”的用武之地,但需要付出一些代价。

什么是“硬编码”

这个想法很简单。为了避免反射,目前唯一的方法是编写大量的 C# 胶水代码。非常多。而且是难以编写的 C# 代码。但这并不是必须的——我们可以稍微简化一下编写方式。但这仍然是一项枯燥的工作,而且很容易出错。

然而,事实证明,这种枯燥、困难且容易出错的工作正是自动化的理想场景。而 MoonSharp 拥有完成这项工作所需的所有信息。

所以,简而言之,通过“硬编码”,MoonSharp 可以生成一堆不需要进一步反射类型就能运行的 C# 代码。

如何进行硬编码

很简单。嗯,几乎很简单。

MoonSharp 需要将已注册的所有类型的信息导出到某个地方。为此,需要编写一小段临时代码:

Table dump = UserData.GetDescriptionOfRegisteredTypes(true);
File.WriteAllText(@"c:\temp\testdump.lua", dump.Serialize());

重要的是,上述代码必须在所有类型都已注册之后运行。因此,硬编码的第一条规则是确保所有注册的顺序正确。

现在,可以使用 MoonSharp 的 REPL 解释器生成代码:

moonsharp -W c:\temp\testdump.lua c:\temp\out.cs --internals --class:MyClass --namespace:MyNamespace

此时,生成过程可能会输出大量警告/错误。它们会显示在控制台输出中,并作为代码中的注释。即使存在警告/错误,生成的代码仍然可以工作,但请花时间阅读这些警告/错误,因为如果你的脚本代码引用了触发这些警告/错误的成员,行为可能会与预期不同。

如果你没有 Windows 电脑,你可以轻松地使用 Mono 在 Mac 或 Linux 上运行 MoonSharp 解释器!

生成的代码将包含一个单一的公共静态类,其中有一个公共的静态 `Initialize` 方法,你应该在使用 MoonSharp 进行任何其他操作之前调用这个方法。非常简单。

如果你注册了一个系统类型(例如,数组),在硬编码时可能会遇到一些问题。原因是硬编码将使用生成 “dump” 时运行时的类型定义,如果你更改了 .NET 版本或平台,运行时可能会有所不同。虽然这看起来像是一个边缘情况,但在 Unity 的 Windows Phone 和 Windows Store 应用中会发生这种情况。在最坏的情况下,可以在生成的代码周围加上条件编译指令。

硬编码的优缺点

优点:

•  大幅减少反射的使用
•  在元数据被剥离的情况下(如IL2CPP),无需白名单类型
•  无需运行时代码生成
•  显著提升性能,尤其是在不支持运行时代码生成的平台上

缺点:

•  需要在工作流程中加入代码生成步骤
•  代码生成仅支持 C# 或 VB.NET
•  暴露的类型和成员必须对其他类可访问——简而言之,必须是`public`的,或者在同一程序集中为`internal`
•  某些类型的成员可能不受支持(例如事件,至少在当前版本中)  
•  值类型的设置器可能无法正常工作——或者比平时更糟,尽量避免使用它们
•  硬编码系统目前涵盖了所有通过 `UserDataType` 注册的类型,而不传递用户数据描述符。除了自定义描述符(显然需要你自己处理)之外,这意味着与 `PropertyTableAssigner` 和扩展方法一起使用的类型不包括在内。通常这问题不大,因为它们往往用于 IL2CPP 启发式算法可见的类型,未来可能会实现支持。

硬编码是实现IL2CPP、AOT或iOS兼容性的必要条件吗?

AOT 兼容性通过 `PlatformAccessor` 管理。实际上,唯一的行为变化是在 AOT 平台上不执行运行时代码生成,而是使用纯反射。

对于 IL2CPP 兼容性,硬编码简化了这一过程——通过消除为不应剥离的元数据维护 `link.xml` 文件的需求——并使其更高效,因为反射速度较慢。但你仍然可以通过向 `link.xml` 添加条目来实现兼容性。

术语表

反射(Reflection):  
一组允许代码“检查”自身并最终调用方法、读取和写入字段及属性等的类型和方法。虽然功能强大,但速度较慢。详见 MSDN 文档。

运行时代码生成(Runtime code generation):  
在运行时生成代码以优化通过反射完成的操作的做法。MoonSharp 在某些地方使用了这一技术,但在 AOT 平台上会被禁用。

IL(Intermediate Language,中间语言):  
.NET/mono 程序集中的代码以 IL(中间语言字节码)形式存储。这种字节码不能直接执行,必须在执行前转换为本地指令。

JIT(Just-In-Time,即时编译):  
通常,当 .NET 或 mono 加载程序集时,它们会对IL代码进行即时编译,将其转换为本地代码。这也可能在程序集的生命周期后期发生——例如,如果泛型类型的某个类型参数是值类型,通常会即时重新编译。

AOT(Ahead-of-Time,预先编译):  
mono 提供的一种选项(某种程度上 ngen 和 .NET Native 也提供,但与此讨论无关,至少目前如此),可以提前将代码编译为本地代码或其他形式。这并不简单,可能无法编译所有需要的代码。例如,如果使用反射来实例化代码中从未引用的类型,则该特定代码可能未被编译。在 iOS 设备上运行需要 AOT 执行。

IL2CPP:  
一种将 IL 转换为 C++ 源代码的出色软件。它是那种极难编写但大多数人谈论它时只是为了抱怨的软件。说真的,它试图解决的问题非常复杂,需要一些合作来确保兼容性。特别是,除了所有 AOT 问题(IL2CPP 必须使用 AOT)外,IL2CPP 还会对程序集元数据进行选择性剥离,这可能会干扰反射。在 Unity3D 下,IL2CPP 是 iOS、tvOS 和 WebGL 的强制要求,并在更多平台上作为选项提供。

link.xml:  
一个告诉 IL2CPP 应保留哪些类型的元数据的文件。

值类型(Value-type):  
值类型是按值传递而不是按引用传递的类型。它包括数值基元类型、枚举和结构体。当谈论值类型问题时,通常指的是结构体。详见 MSDN 上的结构体文档。最佳实践建议值类型应为不可变的,即它们的字段和属性应为只读的,如果需要更改它们,应创建一个新对象(对于结构体来说,这非常廉价)。MoonSharp 与可变结构体的兼容性不佳,因为它们是一种与许多事物都不兼容的奇怪存在,因此请不要使用它们。如果必须使用,请考虑使用代理对象进行变通。

15.Sandboxing(沙盒)

限制 Lua 脚本的功能

文档地址:MoonSharp

为什么需要沙盒化

沙盒化很可能是你使用 MoonSharp 时的关键功能。除非你以某种方式控制脚本提供者(可能还包括用户),否则在运行时加载脚本(或任何类型的代码,有时甚至是数据)时存在一个基本的信任问题:安全性。

例如,假设你正在编写一款视频游戏,并使用 Lua 使游戏“可修改”。用户可以访问某个社区网站并下载包含新关卡、AI等的模组,这些模组都使用 MoonSharp 编写以实现最大灵活性。大家都很开心。现在想象一下,如果某个恶意用户上传了一些隐藏在漂亮关卡中的恶意脚本,会发生什么……比如一个在桌面上创建 .exe 文件的脚本,其他用户可能会不小心点击它。

除非你信任用户,或者明显可以防止恶意使用,否则你不想向普通用户公开某些 API(如`os`、`io`和`file`)。

沙盒化检查清单

这份清单可以帮助你入门,但并不全面。

1. 确保脚本无法访问所有“危险”的标准 API。这肯定包括`io`、`os`和`file`,但根据你的脚本和偏执程度,可能还包括更多。请参阅下一章,了解如何轻松地使整个API集不可访问。

2. 不要使用 `InteropRegistrationPolicy.Automatic`。永远不要。

3. 检查你是否向脚本暴露了不应暴露的类型或类型成员。避免直接暴露你不拥有的类型,如 .NET 框架类型或 Unity 类型。如果需要,请参阅关于“代理对象”的部分,以及如何使用 `MoonSharpHide` 和 `MoonSharpHidden`。

4. 如果你希望脚本的某些部分访问这些危险的 API,请将它们放在单独的 `Script` 对象中,并确保其他脚本无法访问这些对象。

5. 如果绝对必须仅对脚本的一部分进行“沙盒化”,请参考这份经典指南。

移除“危险”的 API

移除危险 API 的最简单方法是使用接受 `CoreModules` 枚举的 `Script` 构造函数。

`CoreModules` 枚举的含义非常直观:

/// <summary>
/// Enumeration (combinable as flags) of all the standard library modules
/// </summary>
[Flags]
public enum CoreModules
{/// <summary>/// Value used to specify no modules to be loaded (equals 0)./// </summary>None = 0,/// <summary>/// The basic methods. Includes "assert", "collectgarbage", "error", "print", "select", "type", "tonumber" and "tostring"./// </summary>Basic = 0x40,/// <summary>/// The global constants: "_G", "_VERSION" and "_MOONSHARP"./// </summary>GlobalConsts = 0x1,/// <summary>/// The table iterators: "next", "ipairs" and "pairs"./// </summary>TableIterators = 0x2,/// <summary>/// The metatable methods : "setmetatable", "getmetatable", "rawset", "rawget", "rawequal" and "rawlen"./// </summary>Metatables = 0x4,/// <summary>/// The string package/// </summary>String = 0x8,/// <summary>/// The load methods: "load", "loadsafe", "loadfile", "loadfilesafe", "dofile" and "require"/// </summary>LoadMethods = 0x10,/// <summary>/// The table package /// </summary>Table = 0x20,/// <summary>/// The error handling methods: "pcall" and "xpcall"/// </summary>ErrorHandling = 0x80,/// <summary>/// The math package/// </summary>Math = 0x100,/// <summary>/// The coroutine package/// </summary>Coroutine = 0x200,/// <summary>/// The bit32 package/// </summary>Bit32 = 0x400,/// <summary>/// The time methods of the "os" package: "clock", "difftime", "date" and "time"/// </summary>OS_Time = 0x800,/// <summary>/// The methods of "os" package excluding those listed for OS_Time. These are not supported under Unity./// </summary>OS_System = 0x1000,/// <summary>/// The methods of "io" and "file" packages. These are not supported under Unity./// </summary>IO = 0x2000,/// <summary>/// The "debug" package (it has limited support)/// </summary>Debug = 0x4000,/// <summary>/// The "dynamic" package (introduced by MoonSharp)./// </summary>Dynamic = 0x8000,/// <summary>/// A sort of "hard" sandbox preset, including string, math, table, bit32 packages, constants and table iterators./// </summary>Preset_HardSandbox = GlobalConsts | TableIterators | String | Table | Basic | Math | Bit32,/// <summary>/// A softer sandbox preset, adding metatables support, error handling, coroutine, time functions and dynamic evaluations./// </summary>Preset_SoftSandbox = Preset_HardSandbox | Metatables | ErrorHandling | Coroutine | OS_Time | Dynamic,/// <summary>/// The default preset. Includes everything except "debug" as now./// Beware that using this preset allows scripts unlimited access to the system./// </summary>Preset_Default = Preset_SoftSandbox | LoadMethods | OS_System | IO,/// <summary>/// The complete package./// Beware that using this preset allows scripts unlimited access to the system./// </summary>Preset_Complete = Preset_Default | Debug,}

16.Tips and tricks for Unity3D(Unity3D的提示和技巧)

为在 Unity 上使用 MoonSharp 的用户提供的快速提示集

文档地址:MoonSharp

支持的平台

一般来说,MoonSharp 的目标是支持所有平台。然而,在 Unity 中测试 MoonSharp 在所有平台上的表现是非常困难的,几乎是不可能的。

因此,平台被分为不同的等级。

1.预计完全支持独立的 Windows、Linux 和 OS/X * 安卓 * iOS * tvOS

2.预计零星支持,将在可能的情况下测试小问题/不支持的功能 WebGL * Windows 应用商店应用程序 Windows Phone

3.应该有效,但我很难提供支持其他层没有的东西

4.不支持,您只能自己使用目前尚不清楚,将进行更新以防

其他建议

•  如果可能,不要暴露 Unity 类型  
•  尽可能使用代理对象  
•  在运行于 IL2CPP 和/或 AOT 平台之前,使用硬编码  
•  如果可能,永远不要暴露结构体  

使用更显式的构造函数之一初始化脚本加载器

使用 UnityAssetsScriptLoader 的显式构造函数来注册所有脚本文件。通过在项目的最开始使用这个小片段,您不需要将 Unity 自带的库添加到 link.xml 中,就可以在 IL2CPP 平台上运行。

示例:

Dictionary<string, string> scripts = new  Dictionary<string, string>();object[] result = Resources.LoadAll("Lua", typeof(TextAsset));foreach(TextAsset ta in result.OfType<TextAsset>()){scripts.Add(ta.name, ta.text);}Script.DefaultOptions.ScriptLoader = new MoonSharp.Interpreter.Loaders.UnityAssetsScriptLoader(scripts);

17.FAQ / Recipes

常见问题的简单示例

文档地址:MoonSharp

如何重定向打印函数的输出?

script.Options.DebugPrint = s => { Console.WriteLine(s); }

如何将输入重定向到Lua程序?

script.Options.DebugInput = () => { return Console.ReadLine(); }

如何重定向Lua程序的IO流?

IoModule.SetDefaultFile(script, Platforms.StandardFileType.StdIn, myInputStream);
IoModule.SetDefaultFile(script, Platforms.StandardFileType.StdOut, myOutputStream);
IoModule.SetDefaultFile(script, Platforms.StandardFileType.StdErr, myErrorStream);

如何限制脚本在不丢失状态的情况下执行的指令数?

参考 Preemptive coroutines.

end

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

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

相关文章

【初级篇】如何使用DeepSeek和Dify构建高效的企业级智能客服系统

在当今数字化时代,企业面临着日益增长的客户服务需求。使用Dify创建智能客服不仅能够提升客户体验,还能显著提高企业的运营效率。关于DIfy的安装部署,大家可以参考之前的文章: 【入门级篇】Dify安装+DeepSeek模型配置保姆级教程_mindie dify deepseek-CSDN博客 AI智能客服…

【网络编程】HTTP网络编程

13.1 HTTP 简介 HTTP(Hyper Text Transfer Protocol,超文本传输协议)是用于从万维网(WWW:World Wide Web) 服务器(简称Web 服务器)传输超文本到本地浏览器的传送协议&#xff0c;基于TCP/IP 通信协 议来传递数据 (HTML 文件、图片文件、查询结果等)。 13.2 HTTP 的工作原理 …

用Scrum敏捷的视角看《哪吒2》的创作

去年我们公司邀请Scrum中文网的老师培训了敏捷开发课程&#xff0c;让我对敏捷有了更深入的理解。前阵子我参加了scrum中文网的一个直播&#xff0c;老师分享了敏捷在个人领域或生活其他领域的应用&#xff0c;很有意思。因为我学习敏捷&#xff0c;除了应用到本身软件研发的工…

Docker+Flask 实战:打造高并发微服务架构

DockerFlask 实战&#xff1a;打造高并发微服务架构 今天我们要深入探讨一个非常热门且实用的主题&#xff1a;基于 Docker 部署 Python Flask 应用。Docker 作为当下最流行的容器化技术&#xff0c;已经广泛应用于各种开发和部署场景&#xff0c;尤其是在微服务架构中。而 Fl…

Linux find 命令完全指南

find 是 Linux 系统最强大的文件搜索工具&#xff0c;支持 嵌套遍历、条件筛选、执行动作。以下通过场景分类解析核心用法&#xff0c;涵盖高效搜索、文件管理及高级技巧&#xff1a; 一、基础搜索模式 1. 按文件名搜索&#xff08;精确/模糊匹配&#xff09; <BASH> f…

【量化策略】趋势跟踪策略

【量化策略】趋势跟踪策略 &#x1f680;量化软件开通 &#x1f680;量化实战教程 技术背景与应用场景 在金融市场中&#xff0c;趋势跟踪策略是一种基于市场趋势进行交易的量化投资方法。该策略的核心思想是“顺势而为”&#xff0c;即认为市场价格会沿着一定的方向持续移…

AI自动化、资本短视、三输与破局

当前AI应用中的一个深层矛盾&#xff1a;工程师使用AI将很专业的任务变成小白可以操作的工作&#xff0c;然后资本方给小白很少的钱把工程师裁掉了&#xff0c;然而小白不懂底层&#xff0c;出问题几乎无法修复。由此&#xff0c;技术普及与专业能力之间的断层引发了"三输…

Python数据分析之数据可视化

Python 数据分析重点知识点 本系列不同其他的知识点讲解&#xff0c;力求通过例子让新同学学习用法&#xff0c;帮助老同学快速回忆知识点 可视化系列&#xff1a; Python基础数据分析工具数据处理与分析数据可视化机器学习基础 四、数据可视化 图表类型与选择 根据数据特…

简述计算机网络中的七层模型和四层模型

在计算机网络中&#xff0c;网络协议栈的设计通常采用分层结构来处理不同的通信任务。常见的分层结构有OSI七层模型和TCP/IP四层模型。虽然它们的层次数量不同&#xff0c;但本质上都在解决如何有效地进行计算机间通信。本文将分别介绍这两种结构的功能和各层的协议。 一、OSI七…

2025高频面试算法总结篇【持续更新中】

文章目录 递归&回溯131. 分割回文串面试题 08.12. 八皇后 动态规划72编辑距离5. 最长回文子串279. 完全平方数300. 最长递增子序列 递归&回溯 131. 分割回文串 回溯思路&#xff1a; 临界条件&#xff1a; if (start s.length) > 保存 循环遍历这个字串 for (int…

【大模型学习】第二十二章 什么是对抗生成网络

目录 一、背景介绍 二、生活化例子说明什么是对抗生成网络 三、技术细节详解 &#xff08;一&#xff09;基本概念 &#xff08;二&#xff09;训练机制 &#xff08;三&#xff09;损失函数 一、背景介绍 对抗生成网络&#xff08;Generative Adversarial Networks, GANs…

摄像头模块ISP处理流程

摄像头模块的ISP&#xff08;图像信号处理器&#xff09;处理流程是对图像传感器输出的原始信号进行系统性优化的过程&#xff0c;主要分为以下关键步骤及对应功能模块&#xff1a; 一、原始信号输入与预处理 ‌传感器信号捕获‌ CMOS/CCD传感器将光信号转换为模拟电信号&…

linux系统安装和激活conda

安装 wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.shbash ./Miniconda3-latest-Linux-x86_64.sh回车到最后按照输入yes&#xff0c;之后按提示操作。 激活 conda activate如果没有反应或者返回&#xff1a; bash: conda: command not found则…

(全)2024下半年真题 系统架构设计师 综合知识 答案解析02

系统架构设计师第二版教程VIP课程https://edu.csdn.net/course/detail/40283 面向对象技术 在UML用例图中&#xff0c;参与者之间存在 关系。 A. 聚合 B. 包含 C. 继承 D. 扩展 答案&#xff1a;C 解析&#xff1a;用例图描述了一组用例、参与者以及它们之间的关系…

【学习笔记】《逆向工程核心原理》03.abex‘crackme-2、函数的调用约定、视频讲座-Tut.ReverseMe1

文章目录 abexcrackme-21. Visual Basic文件的特征1.1. VB专用引擎1.2. 本地代码与伪代码1.3. 事件处理程序1.4. 未文档化的结构体 2. 开始调试2.1. 间接调用2.2. RT_MainStruct结构体2.3. ThunRTMain()函数 3. 分析crackme3.1. 检索字符串3.2. 查找字符串地址3.3. 生成Serial的…

深入解析Go语言Channel:源码剖析与并发读写机制

文章目录 Channel的内部结构Channel的创建过程有缓冲Channel的并发读写机制同时读写的可能性发送操作的实现接收操作的实现 并发读写的核心机制解析互斥锁保护环形缓冲区等待队列直接传递优化Goroutine调度 实例分析&#xff1a;有缓冲Channel的并发读写性能优化与最佳实践缓冲…

初识Linux(14)Ext系列⽂件系统

之前谈论的都是已打开文件在操作系统的中的管理&#xff0c;但是还有更多的文件没有被打开&#xff0c;被存在磁盘中&#xff0c;如何管理这些磁盘中的文件&#xff0c;就是本篇的学习目标。 目录 1.理解硬件 磁盘结构 扇区的读写 CHS地址定位 磁盘的逻辑结构 2. 引⼊⽂件…

电机控制常见面试问题(十二)

文章目录 一.电机锁相环1.理解锁相环2.电机控制中的锁相环应用3.数字锁相环&#xff08;DPLL&#xff09; vs 模拟锁相环&#xff08;APLL&#xff09;4.锁相环设计的关键技术挑战5.总结 二、磁链观测1.什么是磁链&#xff1f;2.为什么要观测磁链&#xff1f;3.怎么观测磁链&am…

Android `%d` 与 `1$%d` 格式化的区别

在 Android 开发中&#xff0c;我们经常需要对字符串进行格式化处理&#xff0c;比如动态填充数字、日期、字符等。 其中&#xff0c;%d 和 1$%d 都是格式化占位符&#xff0c;但它们在使用上有一些不同。 本文将详细解析这两者的区别&#xff0c;并结合 Kotlin 代码示例帮助你…

SpringBoot中使用kaptcha生成验证码

简介 kaptcha是谷歌开源的简单实用的验证码生成工具。通过设置参数&#xff0c;可以自定义验证码大小、颜色、显示的字符等等。 Maven引入依赖 <!-- https://mvnrepository.com/artifact/pro.fessional/kaptcha --><dependency><groupId>pro.fessional<…