Rust 笔记:WebAssembly 的 JavaScript API

news2024/11/25 16:24:43
WebAssembly
WebAssembly 的 JavaScript API

作者李俊才 (jcLee95):https://blog.csdn.net/qq_28550263?spm=1001.2101.3001.5343
邮箱 :291148484@163.com
本文地址:https://blog.csdn.net/qq_28550263/article/details/130879208


【介绍】:本文介绍 WebAssembly 的 JavaScript API。

上一节:《 如何加载和运行 WebAssembly 代码 | 下一节:《 暂无

目 录


1. 概述

1.1 引言

在之前的文章中我们讲解过将某些语言(如 RustC++ 等)编译成 WebAssembly ,也简单讲解过 如何加载和运行 WebAssembly 代码

当加载了一个 .wasm 模块 之后,你就想要去使用它。WebAssemblyJavaScript API, 就为我们提供了这样的交互能力。 本文在前面已经对 WebAssembly 有一定的使用基础上,争取对 WebAssemblyJavaScript API 有全面把握,以为应用自如打好基础。

1.2 为什么需要用于 WebAssembly 的 JavaScript API

WebAssembly 是一种可移植、高性能的二进制格式,可以在现代 Web 浏览器中运行。虽然 WebAssembly 可以直接由编译器生成并在浏览器中运行,但为了能够与 JavaScript 交互和利用 Web 平台的功能WebAssembly 需要使用 JavaScript API,比如用于操作 DOM,等等。

归纳起来,WebAssembly 目前仍然需要使用 JavaScript API 的主要原因有以下几点:

  1. 当前,WebAssembly 还没有直接访问浏览器 API 的能力。WebAssembly 本身只是一种二进制格式,没有直接访问浏览器 DOM网络请求图形渲染 等能力。通过 JavaScript APIWebAssembly 可以与 JavaScript 代码进行交互,并利用 JavaScript 来访问浏览器提供的功能。

  2. JavaScript API 提供了底层数据传输和交互的机制。WebAssemblyJavaScript 之间需要进行数据的传递和交互。JavaScript API 提供了一系列的函数和对象,用于在 WebAssembly 模块和 JavaScript 之间传递数据、调用函数、导入导出功能等。

1.3 ★ 浏览器 和 NodeJS 环境加载 wasm 模块 差异

本文后续介绍各个 API 中涉及大量的代码示例,这些示例都是假定在浏览器中使用的。实际上在实际开发中,也经常应用于 NodeJS 环境,这里会有一些不同。在这一小节我们提前把这里的问题讲清楚,后面则不再对该问题进行赘述。

1.3.1 浏览器环境下

浏览器环境下我们使用 Fetch API 起 HTTP 请求来获取 WebAssembly 模块,因为:

  1. WebAssembly 模块 通常是作为 独立的二进制文件存在,而不是内联在 HTML 文件中。因此,需要通过网络从服务器获取模块文件

  2. WebAssembly 模块可能具有较大的文件大小,使用 HTTP 请求可以利用浏览器的缓存机制,减少模块的重复下载。

  3. Fetch API 提供了一种方便的方式来异步获取资源。它支持 Promise 和 async/await 语法,使得处理异步操作更加简洁和可读。使用 Fetch API 发起请求可以通过设置请求头、处理错误和响应等进行更灵活的控制。

总之,使用 Fetch API 发起 HTTP 请求来获取 WebAssembly 模块是为了从服务器异步获取模块文件,并能够灵活地处理请求和响应过程。这样可以实现模块的动态加载和更好的控制。

1.3.2 NodeJS 环境下

在 Node.js 环境中,由于没有浏览器的环境和 Fetch API,不能直接使用 fetch 函数来获取 WebAssembly 模块(除非你硬要搭建一个静态文件服务器,再来使用代码请求到模块代码来运行)。

通常情况下在 Node.js 环境中我们使用 fs 模块 来读取 模块文件 并 获取其 二进制数据。

具体的,在 NodeJS 中,你可以参考下面示例给出的方式 加载 WebAssembly 模块:

  1. 使用 fs.readFileSync 读取 WebAssembly 模块的二进制文件,并使用 WebAssembly.compile 编译模块。

    const fs = require('fs');
    
    const buffer = fs.readFileSync('module.wasm');
    const module = new WebAssembly.Module(buffer);
    
  2. 使用 WebAssembly.instantiateWebAssembly.instantiateStreaming 方法直接实例化 WebAssembly 模块。

    const fs = require('fs');
    
    const buffer = fs.readFileSync('module.wasm');
    const module = new WebAssembly.Module(buffer);
    
    WebAssembly.instantiate(module).then(instance => {
      // ...
    });
    

2. WebAssembly JavaScript API 详解

2.1 API 概述

2.1.1 JavaScript 的 WebAssembly 对象是一个命名空间对象

在逐个讲解前,我们一定要先注意,类似于 Math 对象 或者 Intl 对象
JavaScript 中,WebAssembly 不是一个构造函数(它不是一个函数对象),而是所有 WebAssembly 相关功能的 命名空间。——和大多数全局对象不一样。

一般我们主要通过 WebAssembly 对象上提供的:

  • WebAssembly.instantiate() 函数 加载 编译好的 加载 WebAssembly 代码;
  • WebAssembly.Memory() 构造函数 创建新的内存实例;
  • WebAssembly.Table() 构造函数 创建新的表实例;
  • WebAssembly.CompileError() 构造函数 来提供 WebAssembly 中的编译错误信息;
  • WebAssembly.LinkError() 构造函数 来提供 WebAssembly 模块实例化期间的错误信息;
  • WebAssembly.RuntimeError() 构造函数 来提供 WebAssembly 中的运行错误信息。

2.1.2 API 一览表

普通函数

API描述
instantiate()编译和实例化 WebAssembly 代码的主要的 API,它返回一个 Module 及其第一个 Instance 实例。
instantiateStreaming()直接从流式底层源编译和实例化 WebAssembly 模块,同时返回 Module 及其第一个Instance实例。
compile()WebAssembly 二次代码编译为一个 WebAssembly.Module,不进行实例化。
compileStreaming()直接从流式底层源代码编译 WebAssembly.Module,将实例化作为一个单独的步骤

用作构造器函数

这些函数用于通过 JavaScript 函数的 构造调用 以创建他们表示的同名对象实例,相当于基于类的面向对象编程语言中某个类的构造方法,因此用的都是大写字母开头。不了解的可以参考我的另外一篇博文 https://blog.csdn.net/qq_28550263/article/details/123418894。

API描述说明
Global(descriptor, value)创建一个新的 Global 对象实例。Global 对象表示一个全局变量实例,可以被 JavaScript 和 importable/exportable 访问 ,跨越一个或多个WebAssembly.Module 实例。他允许被多个 modules 动态连接。
Module(bufferSource)创建一个新的 Module 对象实例。Module 对象包含已经由浏览器编译的无状态 WebAssembly 代码,可以高效地与 Worker 共享和多次实例化。
Memory(memoryDescriptor)创建一个新的 Memory 对象实例。Memory 对象是一个可调整大小的ArrayBuffer或SharedArrayBuffer,用于保存 WebAssembly.Instance 访问的原始内存字节。
Table(tableDescriptor)创建一个新的 Table 对象实例。
CompileError(message, fileName, lineNumber)创建一个新的 CompileError 对象实例。CompileError 对象表示 WebAssembly 解码或验证期间的错误。
LinkError(message, options)创建一个新的 LinkError 对象实例。LinkError 对象指示模块实例化期间的错误(除了来自start函数的 traps 之外)。
RuntimeError(message, options)创建一个新的 RuntimeError 对象实例。
Instance(module, importObject)创建一个新的 Instance 对象实例。Instance 对象包含所有 导出的 WebAssembly 函数,这些函数允许从 JavaScript 调用 WebAssembly 代码。
Tag(type)创建一个新的 Tag 对象实例。
Exception(tag, payload, options)创建一个新的 Exception 对象实例。Exception对象表示从 WebAssembly 抛出到 JavaScript 或 从 JavaScript 抛出到 WebAssembly 异常处理程序的 运行时异常。

2.2 WebAssembly API 中的普通函数

2.2.1 instantiate() 函数

该方法从已编译的 WebAssembly 模块创建一个实例。
其语法格式为:

WebAssembly.instantiate(bufferSource, importObject)

其中参数:

  • bufferSource:包含 WebAssembly 模块字节码的 ArrayBuffer、TypedArray 或 DataView。
  • importObject(可选):一个对象,用于传递给 WebAssembly 模块的导入对象。

例如:

// 发起对 WebAssembly 模块的 HTTP 请求
const response = await fetch('module.wasm');  
// 将响应转换为 ArrayBuffer
const buffer = await response.arrayBuffer();  
// 使用 ArrayBuffer 创建 WebAssembly 模块实例
const module = await WebAssembly.instantiate(buffer);  
// 获取 WebAssembly 实例对象
const instance = module.instance;  

2.2.2 instantiateStreaming() 函数

该方法通过流式加载已编译的 WebAssembly 模块,并创建一个实例。
其语法格式为:

WebAssembly.instantiateStreaming(source, importObject)

其中参数:

  • source:一个表示可通过 HTTP 请求获取 WebAssembly 模块的 URL 字符串或 Response 对象。
  • importObject(可选):一个对象,用于传递给 WebAssembly 模块的导入对象。

例如:

// 流式加载并实例化 WebAssembly 模块
const module = await WebAssembly.instantiateStreaming(fetch('module.wasm'));  
// 获取 WebAssembly 实例对象
const instance = module.instance;  

2.2.3 compile() 函数

该方法将 WebAssembly 模块的字节码编译成一个可执行的模块对象。
其语法格式为:

WebAssembly.compile(bufferSource)

其中参数:

  • bufferSource:包含 WebAssembly 模块字节码的 ArrayBuffer、TypedArray 或 DataView。

例如:

// 发起对 WebAssembly 模块的 HTTP 请求
const response = await fetch('module.wasm');  
// 将响应转换为 ArrayBuffer
const buffer = await response.arrayBuffer();  
// 将 ArrayBuffer 编译成可执行的 WebAssembly 模块对象
const module = await WebAssembly.compile(buffer);  

2.2.4 compileStreaming() 函数

该方法通过流式加载 WebAssembly 模块的字节码,并将其编译成一个可执行的模块对象。其语法格式为:

WebAssembly.compileStreaming(source)

其中参数:

  • source:一个表示可通过 HTTP 请求获取 WebAssembly 模块的 URL 字符串或 Response 对象。

例如:

const module = await WebAssembly.compileStreaming(fetch('module.wasm'));

2.3 WebAssembly API 中的构造函数

2.3.1 Module() 构造函数 与 Module 对象

WebAssembly.Module 对象的构造函数

WebAssembly.Module() 构造函数 用于创建一个 WebAssembly.Module 实例对象。它接受一个 ArrayBuffer 作为参数,并返回一个模块对象,用于后续的实例化操作。

该构造函数的类型签名即下一节 Module 对象的类型签名 中的 new 方法的签名,这里不重复给出。

例如:

fetch('module.wasm')
  .then(response => response.arrayBuffer())
  .then(buffer => {
    const module = new WebAssembly.Module(buffer);
    // 使用模块进行实例化等操作
  });

Module 对象解析

WebAssembly.Module 对象类型签名为:

var WebAssembly.Module: {
    new (bytes: BufferSource): Module;
    prototype: Module;
    customSections(moduleObject: Module, sectionName: string): ArrayBuffer[];
    exports(moduleObject: Module): ModuleExportDescriptor[];
    imports(moduleObject: Module): ModuleImportDescriptor[];
}
customSections 方法

该方法用于获取模块中自定义的节(section)。

其中参数:

  • moduleObject 是一个 WebAssembly.Module 对象,
  • sectionName 是一个字符串,表示要获取的自定义节的名称。

该方法返回一个数组,这个数组包含了指定名称的自定义节的内容。

例如:

const response = await fetch('module.wasm');  
// 将响应转换为 ArrayBuffer
const buffer = await response.arrayBuffer();  
// 将 ArrayBuffer 编译成可执行的 WebAssembly 模块对象
const module = await WebAssembly.compile(buffer);  

const customSections = WebAssembly.Module.customSections(module, 'custom_section_name');
console.log(customSections);
exports 方法

该方法用于获取模块中的导出项(exports)信息。

其中参数:

  • module 是一个 WebAssembly.Module 对象。

该方法返回一个数组,包含了模块中所有导出项的信息。

例如:

const response = await fetch('module.wasm');
// 将响应转换为 ArrayBuffer
const buffer = await response.arrayBuffer();
// 将 ArrayBuffer 编译成可执行的 WebAssembly 模块对象
const module = await WebAssembly.compile(buffer);

const customSections = WebAssembly.Module.customSections(module, 'custom_section_name');
console.log(customSections);

imports 方法

该方法用于获取模块中的导入项(imports)信息。

其中参数:

  • module 是一个 WebAssembly.Module 对象。

该方法返回一个数组,包含了模块中所有导入项的信息。

例如:

const response = await fetch('module.wasm');
// 将响应转换为 ArrayBuffer
const buffer = await response.arrayBuffer();
// 将 ArrayBuffer 编译成可执行的 WebAssembly 模块对象
const module = await WebAssembly.compile(buffer);

const imports = WebAssembly.Module.imports(module);
console.log(imports);

2.3.2 Global() 构造函数 与 Global 对象

WebAssembly.Global 对象的构造函数

WebAssembly.Global() 构造函数 用于创建一个 WebAssembly.Global 实例对象

该构造函数的类型签名即下一节 Global 对象的类型签名 中的 new 方法的签名,这里不重复给出。

Global 对象解析

Global 对象的类型签名为:

var WebAssembly.Global: {
    new (descriptor: GlobalDescriptor, v?: any): Global;
    prototype: Global;
}

这个对象没有需要解释的其它方法。

2.3.3 Instance() 构造函数 与 Instance 对象

WebAssembly.Instance 对象的构造函数

WebAssembly.Instance() 构造函数 用于创建一个 WebAssembly.Instance 实例对象。它接受一个 WebAssembly.Module 对象和一个可选的导入对象作为参数,并返回一个实例对象,用于调用 WebAssembly 模块中的函数和访问导出的功能。

该构造函数的类型签名即下一节 Instance 对象的类型签名 中的 new 方法的签名,这里不重复给出。

例如:

fetch('module.wasm')
  .then(response => response.arrayBuffer())
  .then(buffer => {
    // 创建 wasm 的 Module 对象实例
    const module = new WebAssembly.Module(buffer);
    // 创建 wasm 的 Instance 对象实例
    const instance = new WebAssembly.Instance(module, { /* imports */ });
    // 使用实例调用导出的函数等操作
  });

WebAssembly.Instance 对象

Instance 对象的类型签名为:

var WebAssembly.Instance: {
    new (module: Module, importObject?: Imports): Instance;
    prototype: Instance;
}

这个对象没有需要解释的其它方法。

2.3.4 Memory() 构造函数 与 Memory 对象

WebAssembly.Memory 对象的构造函数

WebAssembly.Memory() 构造函数用于创建一个 WebAssembly.Memory 实例对象。它接受一个描述内存大小的页数作为参数,并返回一个内存对象,用于 WebAssembly 模块中的内存访问操作。

该构造函数的类型签名即下一节 Memory 对象的类型签名 中的 new 方法的签名,这里不重复给出。

例如:

const memory = new WebAssembly.Memory({ initial: 10, maximum

Memory 实例对象的 buffer 属性是一个可调整大小的 ArrayBuffer ,其内存储的是 WebAssembly 实例 所访问内存的原始字节码。

WebAssembly.Memory 对象

Memory 对象的类型签名为:

var WebAssembly.Memory: {
    new (descriptor: MemoryDescriptor): Memory;
    prototype: Memory;
}

这个对象没有需要解释的其它方法。

2.3.5 Table() 构造函数 与 Table 对象

WebAssembly.Table 对象的构造函数

WebAssembly.Table() 构造函数用于创建一个 WebAssembly.Table 实例对象。Table() 构造函数主要传入的是以下两个参数:

  • initial:指定表的初始大小(以元素数量表示),默认为 0。
  • element:指定表中每个元素的类型(函数引用类型),默认为 {element: “anyfunc”}。

可以参考该对象类型签名及进行理解。该构造函数的类型签名即下一节 Table 对象的类型签名 中的 new 方法的签名,这里不重复给出。

例如:

// 创建一个初始大小为 10 的 WebAssembly 表,存储任意函数引用类型
const table = new WebAssembly.Table({ initial: 10 });

// 向表中添加函数引用
table.grow(2); // 扩展表的大小为 12
table.set(0, myFunction); // 将 myFunction 设置为索引为 0 的元素
table.set(1, anotherFunction); // 将 anotherFunction 设置为索引为 1 的元素

// 调用表中的函数
table.get(0)(); // 调用索引为 0 的函数

WebAssembly.Table 对象

Table 对象的类型签名为:

type TableKind = "anyfunc" | "externref";

interface TableDescriptor {
    element: TableKind;
    initial: number;
    maximum?: number;
}

var WebAssembly.Table: {
    new (descriptor: TableDescriptor, value?: any): Table;
    prototype: Table;
}

TableKind 类型表示一个对象,表示表中每个元素的类型,可以是以下值之一:

  • “anyfunc”: 任意函数引用类型
  • “funcref”: 函数引用类型

这个对象没有需要解释的其它方法。

2.3.6 RuntimeError() 构造函数 与 RuntimeError 对象

WebAssembly.RuntimeError 对象的构造函数

WebAssembly.RuntimeError() 构造函数用于创建一个 WebAssembly.RuntimeError 实例对象。通过构造调用该对象,可以创建 WebAssembly 运行时错误(Runtime Error)。

其中参数:

  • message:一个可选的字符串,表示错误消息。

例如:

// 创建一个自定义的 WebAssembly 运行时错误
const error = new WebAssembly.RuntimeError("Custom runtime error occurred.");

throw error; // 抛出错误

WebAssembly.RuntimeError 对象

RuntimeError 对象用于在 WebAssembly 模块执行期间抛出自定义的运行时错误。通过 抛出自定义的 WebAssembly.RuntimeError,你可以在 WebAssembly 模块 的 执行期间捕获并处理特定的运行时错误情况

该对象的类型签名为:

var WebAssembly.RuntimeError: {
    (message?: string): RuntimeError;
    new (message?: string): RuntimeError;
    prototype: RuntimeError;
}

通过抛出自定义的 WebAssembly.RuntimeError,你可以在 WebAssembly 模块的执行期间 捕获并处理特定的运行时错误情况。

【注】:WebAssembly.RuntimeError 是一个构造函数,用于创建错误对象。它不是 JavaScript 中内置的异常类型,而是用于在 WebAssembly 环境中表示运行时错误的特定对象。

这个对象没有需要解释的其它方法。

2.3.7 CompileError() 构造函数 与 CompileError 对象

WebAssembly.CompileError 对象的构造函数

WebAssembly.CompileError() 构造函数 用来创建一个 WebAssembly.CompileError 实例对象,以实现在编译 WebAssembly 模块时抛出自定义的编译错误。

其中参数:

  • message:一个可选的字符串,表示错误消息。

例如:

// 创建一个自定义的 WebAssembly 编译错误
const error = new WebAssembly.CompileError("Custom compile error occurred.");

throw error; // 抛出错误

WebAssembly.CompileError 对象

CompileError 对象的类型签名为:

var WebAssembly.CompileError: {
    (message?: string): CompileError;
    new (message?: string): CompileError;
    prototype: CompileError;
}

通过抛出 自定义的 WebAssembly.CompileError,你可以在编译 WebAssembly 模块时捕获并处理特定的编译错误情况。

【注】:WebAssembly.CompileError不是 JavaScript 中内置的异常类型,而是用于在 WebAssembly 环境中表示编译错误的特定对象。

2.3.8 LinkError() 构造函数 与 LinkError 对象

WebAssembly.LinkError 对象的构造函数

WebAssembly.LinkError() 构造函数 用于创建一个 WebAssembly.LinkError 实例对象,从而在链接 WebAssembly 模块时抛出自定义的链接错误。

其中参数:

  • message:一个可选的字符串,表示错误消息。

例如:

// 创建一个自定义的 WebAssembly 链接错误
const error = new WebAssembly.LinkError("Custom link error occurred.");

throw error; // 抛出错误

WebAssembly.LinkError 对象

LinkError 对象的类型签名为:

var WebAssembly.LinkError: {
    (message?: string): LinkError;
    new (message?: string): LinkError;
    prototype: LinkError;
}

通过抛出自定义的 WebAssembly.LinkError,你可以在 链接 WebAssembly 模块时 捕获并处理特定的链接错误情况。

【注】:WebAssembly.LinkError 是一个构造函数,用于创建错误对象。它不是 JavaScript 中内置的异常类型,而是用于在 WebAssembly 环境中表示链接错误的特定对象。

这个对象没有需要解释的其它方法。

2.3.9 MDN意淫:Exception() 构造函数 与 Exception 对象

这个 API 是 MDN 网站上给出的,地址为 https://developer.mozilla.org/en-US/docs/WebAssembly/JavaScript_interface/Tag 以下截图引用时间为 2023/5/29:
在这里插入图片描述
不过编程的时候,好像这个API并不能像 MDN 上面介绍的那样使用,并且看起来完全不存在该构造函数。在 typescript 的 lib 中,笔者也没有找到该构造函数的任何类型声明。
是否是新的 API 或者是非标准的 API 不得而知。尤其让人疑惑的是,MDN上面还给出了其被支持的浏览器:
在这里插入图片描述
但是似乎 W3C 上同样没有:https://www.w3.org/TR/2022/WD-wasm-js-api-2-20220419/。

最让人疑惑的是,MDN 似乎还做得挺认真的,给出了两个语言的版本,简直是无中生有玩得贼溜。

建议感兴趣的自己在 MDN 的以下地址查看:

  • https://developer.mozilla.org/en-US/docs/WebAssembly/JavaScript_interface/Tag:英语
  • https://developer.mozilla.org/fr/docs/WebAssembly/JavaScript_interface/Tag 法语

法语版本截图:

在这里插入图片描述

2.3.10 MDN意淫:Tag() 构造函数 与 Tag 对象

更让人疑惑的是,除了上一节介绍的 TagMDN 似乎还以同样认真的手段,不知道从哪里创造了一个 Exception API,而且也给了两个版本:

英语版,地址:https://developer.mozilla.org/en-US/docs/WebAssembly/JavaScript_interface/Exception
https://developer.mozilla.org/en-US/docs/WebAssembly/JavaScript_interface/Exception

法语版,地址:
https://developer.mozilla.org/fr/docs/WebAssembly/JavaScript_interface/Exception

在这里插入图片描述

目前 WebAssembly 还属于新技术,“菜鸟XX” 等国内网站都还没有介绍。W3C 在2022 年给出的 WASM 2 的标准中没有,应该就是没有这两个API了。因此这两个 API 到底是我没找到还是被 MDN 意淫出来的呢,请读者自己判断。

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

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

相关文章

2023/5/29总结

abstract修饰符 抽象类就是当类和类之间有相同特征时,将这些共同的特征提取出来,形成的就是抽象类。 抽象类的特点: 抽象类和抽象方法必须使用abstract 关键字修饰:publicabstract class 类名 / public abstract void eat();抽象…

基于pytorch搭建多特征LSTM时间序列预测代码详细解读(附完整代码)

文章目录 LSTM时间序列预测数据获取与预处理模型构建训练与测试 LSTM时间序列预测 对于LSTM神经网络的概念想必大家也是熟练掌握了,所以本文章不涉及对LSTM概念的解读,仅解释如何使用pytorch使用LSTM进行时间序列预测,复原使用代码实现的全流…

【Python实战】Python采集小说文本内容

前言 今天,我们将采集某小说数据,通过这个案例,加深我们对正则表达式的理解。我们今天来通过使用正则表达式来获取我们想要的文本。 环境使用 python 3.9pycharm模块使用 requests模块介绍 requests requests是一个很实用的Python HTTP客户端库,爬虫和测试服务器响应…

MaxScript的Shape相关操作例子

MaxScript学习笔记目录 大家好,我是阿赵。之前有网友私信问了我一个相关的问题,我发现之前漏了MaxScript里面的Shape的内容,所以补一个例子,当做一个记录吧。 一、例子说明 这里做一个关于MaxScript读取二维形状(Shape)数据的例…

加盐加密——保障你的数据安全

目录 今日良言:理性和激情是生活不可或缺的调味品 一、加盐加密 1.普通密码的缺点 2.什么是加盐加密 3.加盐加密的过程 4.加盐加密的实现 今日良言:理性和激情是生活不可或缺的调味品 一、加盐加密 1.普通密码的缺点 在介绍加盐加密之前,先想想为什么普通密…

STM32F4_指针(单片机)

目录 前言 1. 计算机存储机制 2. 定义指针 2.1 指针操作 2.2 数组与指针 前言 指针(Pointer)是C语言的一个重要知识点,其使用灵活、功能强大,是C语言的灵魂。指针与底层硬件联系密切,使用指针可操作数据的地址,实现数据的间…

PreSumm模型

Text Summarization with Pretrained Encoders(PreSumm模型) 论文地址 摘要 在本文中,我们展示了如何在文本摘要中有效地应用BERT,并为提取性模型和抽象模型提出了一个通用框架。我们介绍了基于BERT的新颖文档级编码器&#xf…

安装VMware Workstation和虚拟机教程

一、VM简介   VMware Workstation中文版是一个“虚拟 PC”软件。它使你可以在一台机器上同时运行二个或更多 Windows、DOS、LINUX 系统。与“多启动”系统相比,VMWare 采用了完全不同的概念。多启动系统在一个时刻只能运行一个系统,在系统切换时需要重…

iPad Pro “买后生产力” - 在iPad上远程连接服务器编程写代码【公网远程】

文章目录 前言视频教程1. 本地环境配置2. 内网穿透2.1 安装cpolar内网穿透(支持一键自动安装脚本)2.2 创建HTTP隧道 3. 测试远程访问4. 配置固定二级子域名4.1 保留二级子域名4.2 配置二级子域名 5. 测试使用固定二级子域名远程访问6. iPad通过软件远程vscode6.1 创建TCP隧道 7…

sprintboot logback高级特性使用

一、业务需求 日志级别的分类 日志的级别分为: trace:微量,少许的意思,级别最低info:普通的打印信息debug:需要调试时候的关键信息打印warn:警告,不影响使⽤,但需要注…

Socket(四)

文章目录 1. 服务器Socket简介2. 使用ServerSocket3. 用Socket写入服务器4. 关闭服务器Socket 1. 服务器Socket简介 博客Socket(一)~Socket(二)从客户端的角度讨论了Socket,客户端就是向监听连接的服务器打…

Git基本概念

Git基础 git 介绍git工作流程 git 介绍 1、git是什么:是目前世界上最先进的分布式版本控制系统 2、git的优势 ● 适合分布式开发、强调个体。 ● 公共服务器压力和数量都不会太大 ● 速度快、灵活 ● 任意两个开发者之间可以很容易的解决冲突 ● 离线工作 3、git能…

华为OD机试真题B卷 Java 实现【乱序整数序列两数之和绝对值最小】,附详细解题思路

一、题目描述 给定一个随机的整数(可能存在正整数和负整数)数组 nums,请你在该数组中找出两个数,其和的绝对值(|nums[x]nums[y]|)为最小值,并返回这个两个数(按从小到大返回)以及绝对值。 每种…

全志V3S嵌入式驱动开发(网卡驱动)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 一开始上来就说网卡,好像有点不太对劲。这主要是因为如果开发板可以连接网络的话,可以帮我们节约很多的时间,开…

逍遥自在学C语言 | 揭开while循环的神秘面纱

前言 循环是一种重要的控制结构,可以使程序重复执行一段代码,直到满足特定条件为止。 在C语言中,while和do-while是两种常用的循环结构,本文将详细介绍这两种循环的用法。 一、人物简介 第一位闪亮登场,有请今后会一…

eclipse安装lombok插件

项目中遇到了一些实体类声明了属性,缺少get/set方法,但是类上使用了Getter 和 Setter注解,查了下是lombok插件的强大功能。 这里先不看lombok的功能,先看下eclipse安装lombok插件的过程。 1、 https://projectlombok.org/downlo…

三十五、数学知识——快速幂(反复平方法 + 快速幂求逆元)

快速幂算法主要内容 一、基本原理1、概念 暴力求解2、核心原理——反复平方法3、快速幂求逆元 二、Java、C语言模板实现三、例题题解 一、基本原理 1、概念 暴力求解 问题目标: 快速求出 a^k mod p 的结果,时间复杂度为 O(logk),其中 a,p…

华为OD机试真题B卷 Java 实现【字符串变换最小字符串】,附详细解题思路

一、题目描述 给定一个字符串s,最多只能进行一次变换,返回变换后能得到的最小字符串(按照字典序进行比较)。 变换规则:交换字符串中任意两个不同位置的字符。 二、输入描述 一串小写字母组成的字符串s。 三、输出…

人工智能-不确定性的量化

这一部分的重点内容有: 贝叶斯规则贝叶斯网络基于隐马尔可夫模型的概率推理 大概会有以下几种考察形式,有答案的历年期末考试题只解释一些注意的地方 贝叶斯网络-独立性 第二问答案很详细,第一问看↓ D-separation: 判断贝叶…

Stable-diffusion-webui 本地部署及使用

Stable-diffusion-webui 本地部署及使用 本地部署stable-diffusion-webui(windows)1.安装conda;2.创建conda env 和python 3.10.6;3.更新pip;4.安装cuda 11.8;5.克隆stable-diffusion-webui仓库 ;6.下载SD模型7.运行sd…