AOS安装及操作演示
文章目录
- 一、安装node
- 1.1 在 macOS 上管理 Node版本
- 1.1.1 安装 nvm
- 1.1.2 验证 nvm 是否安装成功
- 1.1.3 使用 nvm 安装/切换 Node.js 版本
- 1.1.4 卸载 Node.js 版本
- 1.2 在 windows 上管理 Node版本
- 1.2.1 安装 nvm-windows
- 1.2.2 安装 Node.js 版本
- 1.2.3 切换 Node.js 版本
- 1.2.4 卸载 Node.js 版本
- 1.2.5 检查当前 Node.js 版本
- 二、安装 aos
- 三、使用AOS
- 3.1 发送第一个命令
- 3.2 发送消息
- 3.3 向 Morpheus 发送消息
- 3.4 收件箱
- 四、操作Arweave的token
- 4.1 发布一个Arweave的token
- 4.2 使用golang调用token
- 4.3 获取消息信息
一、安装node
1.1 在 macOS 上管理 Node版本
在 macOS 上管理 Node.js 版本,通常使用 nvm(Node Version Manager)是最便捷的方式。以下是安装和使用 nvm 来管理 Node.js 版本的步骤:
1.1.1 安装 nvm
打开终端并运行以下命令来安装 nvm:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.4/install.sh | bash
运行上述命令后,按照提示操作,安装过程会将 nvm 的路径添加到 shell 配置文件(如 .bashrc, .bash_profile, .zshrc 等)中。
注意:如果你使用的是 Zsh 作为默认终端,可能需要编辑 .zshrc 文件;如果使用的是 Bash,可能需要编辑 .bash_profile 或 .bashrc。
在安装完成后,执行以下命令来重新加载 shell 配置文件:
source ~/.bashrc # 或者 source ~/.zshrc,视具体情况而定
1.1.2 验证 nvm 是否安装成功
在终端运行以下命令来检查是否成功安装:
nvm --version
如果返回 nvm 版本号,则说明安装成功。
1.1.3 使用 nvm 安装/切换 Node.js 版本
-
查看可用的 Node.js 版本:
nvm ls-remote
-
安装特定版本的 Node.js:
nvm install <version>
例如,安装 Node.js 21.x:
nvm install v21.0.0
-
切换到特定版本的 Node.js:
nvm use <version>
例如,切换到 Node.js 22.x:
nvm use v22.0.0
-
查看当前已安装的 Node.js 版本:
nvm ls
-
设置默认 Node.js 版本:
nvm alias default <version>
例如,设置默认版本为 22.x:
nvm alias default v22.0.0
这样每次打开终端时,系统会自动使用你设定的默认版本。
1.1.4 卸载 Node.js 版本
如果需要卸载某个 Node.js 版本,可以使用以下命令:
nvm uninstall <version>
例如:
nvm uninstall 22
1.2 在 windows 上管理 Node版本
在 Windows 上管理 Node.js 版本,常用的工具是 nvm-windows,这是 Node Version Manager (NVM) 的 Windows 版本。使用它可以轻松安装、切换和管理多个 Node.js 版本。
1.2.1 安装 nvm-windows
-
下载 nvm-windows:前往 nvm-windows GitHub 主页 - 下载最新的 .zip 文件或 .exe 安装文件。
-
安装:运行下载的 .exe 文件,按照安装向导的提示进行安装。建议选择默认的安装路径,以免出现权限问题。
1.2.2 安装 Node.js 版本
- 查看可用的 Node.js 版本
安装好 nvm 后,打开命令行(如 PowerShell 或 CMD),输入以下命令来查看可安装的 Node.js 版本列表:
nvm list available
- 安装指定版本的 Node.js
选择一个版本号,并使用以下命令进行安装,例如安装 Node.js 16.13.0:
nvm install 16.13.0
- 查看已安装的版本
可以查看系统上已经安装的 Node.js 版本:
nvm list
1.2.3 切换 Node.js 版本
使用指定版本的 Node.js
如果你已经安装了多个版本的 Node.js,你可以使用以下命令切换到所需的版本:
nvm use 16.13.0
使用该命令后,你的 Node.js 和 npm 都会切换到该版本。
1.2.4 卸载 Node.js 版本
卸载不需要的版本
如果你不再需要某个版本的 Node.js,可以通过以下命令卸载:
nvm uninstall 16.13.0
1.2.5 检查当前 Node.js 版本
确认当前的 Node.js 版本
-
使用 node -v 来查看当前使用的 Node.js 版本:
node -v
二、安装 aos
-
完成 NodeJS 安装后,只需安装 aos 并运行它:
npm i -g https://preview_ao.g8way.io
-
卸载aos服务
npm uninstall -g @permaweb/aos
-
安装完成后,我们运行命令即可启动一个新的 aos 进程!
aos
aos 命令运行时,其实是你在使用密钥文件向 aos 验证你的身份的。如果没有指定,aos 会默认生成一个新的密钥文件并将其存储在本地 ~/.aos.json。如果你有 Arweave 钱包,可以使用 --wallet [location] 参数使用指定钱包。
刚刚我们启动的程序实例是本地客户端,它已准备好将消息发送到你的新进程(ao 计算机内的进程)。
连接后,我们会看到以下内容:
_____ _______ _____ /\ \ /::\ \ /\ \ /::\ \ /::::\ \ /::\ \ /::::\ \ /::::::\ \ /::::\ \ /::::::\ \ /::::::::\ \ /::::::\ \ /:::/\:::\ \ /:::/~~\:::\ \ /:::/\:::\ \ /:::/__\:::\ \ /:::/ \:::\ \ /:::/__\:::\ \ /::::\ \:::\ \ /:::/ / \:::\ \ \:::\ \:::\ \ /::::::\ \:::\ \ /:::/____/ \:::\____\ ___\:::\ \:::\ \ /:::/\:::\ \:::\ \ |:::| | |:::| | /\ \:::\ \:::\ \
/:::/ \:::\ \:::\____\|:::|____| |:::| |/::\ \:::\ \:::\____\
\::/ \:::\ /:::/ / \:::\ \ /:::/ / \:::\ \:::\ \::/ /\/____/ \:::\/:::/ / \:::\ \ /:::/ / \:::\ \:::\ \/____/ \::::::/ / \:::\ /:::/ / \:::\ \:::\ \ \::::/ / \:::\__/:::/ / \:::\ \:::\____\ /:::/ / \::::::::/ / \:::\ /:::/ / /:::/ / \::::::/ / \:::\/:::/ / /:::/ / \::::/ / \::::::/ / /:::/ / \::/____/ \::::/ / \::/ / ~~ \::/ / \/____/ \/____/ Welcome to AOS: Your operating system for AO, the decentralized open access supercomputer.
Type ".load-blueprint chat" to join the community chat and ask questions!AOS Client Version: 2.0.0. 2024
Type "Ctrl-C" twice to exitYour AOS process: 9qyG3YAlPYt9SBns5zwrbIZGvYVdM8s86fIi2qw8jbsdefault@aos-2.0.0[Inbox:8]>
三、使用AOS
3.1 发送第一个命令
我们所拥有的 aos 进程,已经驻留在 ao 计算机内部的服务器上,等待接收和执行你的命令。
为了让开发更加的简单,aos 使用 Lua 编程语言撰写命令。 还没学过 Lua? 不要着急! 这是一种超级简单、友好的语言。 看完本手册后你就顺带学会 Lua。
让我们打破僵局并输入:
default@aos-2.0.0[Inbox:8]> "Hello, ao!"
然后按 [Enter] 键。 你会看到 shell 签名并发布消息,请求结果,然后打印结果,如下所示:
Hello, ao!
3.2 发送消息
Send({ Target = "process ID", Data = "Hello World!" })
- Send:Send 是 aos 中全局函数,用于发送消息。
- Target:如果要将消息发送到特定进程,请在消息中包含 Target 字段。
- Data:Data 是你希望目标进程接收的文本消息。 在此示例中,消息是 Hello World!
3.3 向 Morpheus 发送消息
- 存储 Morpheus 的进程 ID
我们将使用下面提供的进程 ID 并将其存储为名为 Morpheus 的变量。
wu_tAUDUveetQZpcN8UxHt51d9dyUkI4Z-MfQV8LnUU
通过复制上面的进程 ID 并在 aos CLI 中运行以下命令以便将其存储为变量:
Morpheus = "wu_tAUDUveetQZpcN8UxHt51d9dyUkI4Z-MfQV8LnUU"
这会将进程 ID 存储为名为 Morpheus 的变量,从而更轻松地与特定进程 ID 进行交互。
创建 Morpheus 变量时,我们应该看到的唯一响应是 undefined。 这是预料之中的。 要检查变量是否已成功创建,请输入 Morpheus 并按 Enter。 我们应该会看到你存储的进程 ID。
检查 Morpheus 变量
-- 通过输入 `Morpheus` 检查 Morpheus 变量
Morpheus
-- 预期结果:
wu_tAUDUveetQZpcN8UxHt51d9dyUkI4Z-MfQV8LnUU-- 如果 `undefined` 被返回,
-- 那么变量没有创建成功。
- 向 Morpheus 发送消息
获取 Morpheus 的进程 ID 并将其存储在变量中后,我们就可以与它进行通信了。 为此,你可以使用 Send 函数。 Morpheus 本身就是 ao 中运行的一个并行进程。 他使用一系列 handler 接收和发送消息。 让我们向他发送消息,看看会发生什么。
Send({ Target = Morpheus, Data = "Morpheus?" })
-
我们的 Target 是 Morpheus,这是我们之前使用 Morpheus 进程 ID 定义的变量。
-
Data 是我们要发送给 Morpheus 的消息。 在这里,它是 Morpheus?。
预期结果:
-- 我们的消息命令
Send({ Target = Morpheus, Data = "Morpheus?"})
-- 消息已添加到发件箱
message added to outbox
-- 从 `Morpheus` 的进程 ID 收到一条新消息
New Message From BWM...ulw: Data = I am here. You are f
3.4 收件箱
收件箱 是我们从其他进程接收消息的地方。
让我们检查收件箱,看看我们收到了多少条消息。
在 aos CLI 中,输入以下命令:
#Inbox
返回值示范:
-- 你的 `收件箱` 命令
#Inbox
-- 该命令将返回我们收件箱中的消息数量
16
在上面的示例中,返回为 16,表示收件箱中有十六封邮件。
由于我们主要是为了寻找 Morpheus 的回复,因此我们假设他的消息是最后收到的消息。要阅读收件箱中的最后一条消息,请键入以下命令:
Inbox[#Inbox].Data
该命令允许我们将数据与消息分离,并且仅读取特定数据字段的内容。
预期返回:
-- 你的 Inbox[x].Data 命令
Inbox[#Inbox].Data
-- 该命令将返回消息的 `Data` 字段。
-- Data 通常代表基于文本的消息
-- 从一个进程接收到另一进程。
I am here. You are finally awake. Are you ready to see how far the rabbit hole goes?
四、操作Arweave的token
4.1 发布一个Arweave的token
// 引入lua库
// bint用于处理大整数
// json用于处理 JSON 数据local bint = require('.bint')(256)
local json = require('json')// 定义工具函数
// add: 将两个数相加,返回字符串形式的结果。
// subtract: 从一个数中减去另一个数,返回字符串形式的结果。
// toBalanceValue: 将一个数字转换为字符串,用于表示余额。
// toNumber: 将字符串形式的数字转换为 Lua 数字。local utils = {add = function(a, b)return tostring(bint(a) + bint(b))end,subtract = function(a, b)return tostring(bint(a) - bint(b))end,toBalanceValue = function(a)return tostring(bint(a))end,toNumber = function(a)return bint.tonumber(a)end
}// 全局变量,这部分属于合约本身内部的状态,属于当前process 独立的状态,收到消息并且处理以后呢,将会改变这些状态
// 定义代币的基本信息,版本、精度(小数位数)、初始余额、总供应量、名称、符号和 logo。
// 使用 or 操作符为未定义的变量提供默认值。Variant = "0.0.3"Denomination = Denomination or 12
Balances = Balances or { [ao.id] = utils.toBalanceValue(10000 * 10 ^ Denomination) }
TotalSupply = TotalSupply or utils.toBalanceValue(10000 * 10 ^ Denomination)
Name = Name or 'Points Coin'
Ticker = Ticker or 'PNTS'
Logo = Logo or 'SBCCXwwecBlDqRLUjb8dYABExTJXLieawf7m2aBJ-KY'// info:处理“信息”请求,返回代币的基本信息。
Handlers.add('info', Handlers.utils.hasMatchingTag("Action", "Info"), function(msg)if msg.reply thenmsg.reply({Name = Name,Ticker = Ticker,Logo = Logo,Denomination = tostring(Denomination)})elseSend({Target = msg.From, Name = Name,Ticker = Ticker,Logo = Logo,Denomination = tostring(Denomination)})end
end)// balance:处理查询余额的请求,根据接收者的不同,返回相应的余额。
Handlers.add('balance', Handlers.utils.hasMatchingTag("Action", "Balance"), function(msg)local bal = '0'if (msg.Tags.Recipient) thenif (Balances[msg.Tags.Recipient]) thenbal = Balances[msg.Tags.Recipient]endelseif msg.Tags.Target and Balances[msg.Tags.Target] thenbal = Balances[msg.Tags.Target]elseif Balances[msg.From] thenbal = Balances[msg.From]endif msg.reply thenmsg.reply({Balance = bal,Ticker = Ticker,Account = msg.Tags.Recipient or msg.From,Data = bal})elseSend({Target = msg.From,Balance = bal,Ticker = Ticker,Account = msg.Tags.Recipient or msg.From,Data = bal})end
end)// balances:用于查询所有账户的余额
Handlers.add('balances', Handlers.utils.hasMatchingTag("Action", "Balances"),function(msg) if msg.reply thenmsg.reply({ Data = json.encode(Balances) })else Send({Target = msg.From, Data = json.encode(Balances) }) endend)// transfer:处理代币转账请求,检查余额是否足够,如果足够,则进行转账并发送通知。
Handlers.add('transfer', Handlers.utils.hasMatchingTag("Action", "Transfer"), function(msg)// transfer参数的检查,确保 接收者 和 数量 的类型正确,且数量大于0assert(type(msg.Recipient) == 'string', 'Recipient is required!')assert(type(msg.Quantity) == 'string', 'Quantity is required!')assert(bint.__lt(0, bint(msg.Quantity)), 'Quantity must be greater than 0')// 检查发件人和接收人的余额,如果不存在则初始化为0。if not Balances[msg.From] then Balances[msg.From] = "0" endif not Balances[msg.Recipient] then Balances[msg.Recipient] = "0" end// 检查发送者的余额是否足够进行转账if bint(msg.Quantity) <= bint(Balances[msg.From]) then// 从发送者余额中扣除数量,并将该数量加到接收者余额。Balances[msg.From] = utils.subtract(Balances[msg.From], msg.Quantity)Balances[msg.Recipient] = utils.add(Balances[msg.Recipient], msg.Quantity)// 通知发送者及接收者 转账通知if not msg.Cast thenlocal debitNotice = {Action = 'Debit-Notice',Recipient = msg.Recipient,Quantity = msg.Quantity,Data = Colors.gray .."You transferred " ..Colors.blue .. msg.Quantity .. Colors.gray .. " to " .. Colors.green .. msg.Recipient .. Colors.reset}local creditNotice = {Target = msg.Recipient,Action = 'Credit-Notice',Sender = msg.From,Quantity = msg.Quantity,Data = Colors.gray .."You received " ..Colors.blue .. msg.Quantity .. Colors.gray .. " from " .. Colors.green .. msg.From .. Colors.reset}for tagName, tagValue in pairs(msg) doif string.sub(tagName, 1, 2) == "X-" thendebitNotice[tagName] = tagValuecreditNotice[tagName] = tagValueendendif msg.reply thenmsg.reply(debitNotice)elseSend(debitNotice)endSend(creditNotice)endelseif msg.reply thenmsg.reply({Action = 'Transfer-Error',['Message-Id'] = msg.Id,Error = 'Insufficient Balance!'})elseSend({Target = msg.From,Action = 'Transfer-Error',['Message-Id'] = msg.Id,Error = 'Insufficient Balance!'})endend
end)// mint:铸造、增发代币
Handlers.add('mint', Handlers.utils.hasMatchingTag("Action","Mint"), function(msg)assert(type(msg.Quantity) == 'string', 'Quantity is required!')assert(bint(0) < bint(msg.Quantity), 'Quantity must be greater than zero!')if not Balances[ao.id] then Balances[ao.id] = "0" endif msg.From == ao.id thenBalances[msg.From] = utils.add(Balances[msg.From], msg.Quantity)TotalSupply = utils.add(TotalSupply, msg.Quantity)if msg.reply thenmsg.reply({Data = Colors.gray .. "Successfully minted " .. Colors.blue .. msg.Quantity .. Colors.reset})elseSend({Target = msg.From,Data = Colors.gray .. "Successfully minted " .. Colors.blue .. msg.Quantity .. Colors.reset})endelseif msg.reply thenmsg.reply({Action = 'Mint-Error',['Message-Id'] = msg.Id,Error = 'Only the Process Id can mint new ' .. Ticker .. ' tokens!'})elseSend({Target = msg.From,Action = 'Mint-Error',['Message-Id'] = msg.Id,Error = 'Only the Process Id can mint new ' .. Ticker .. ' tokens!'})endend
end)// totalSupply:处理查询总供应量的请求
Handlers.add('totalSupply', Handlers.utils.hasMatchingTag("Action","Total-Supply"), function(msg)assert(msg.From ~= ao.id, 'Cannot call Total-Supply from the same process!')if msg.reply thenmsg.reply({Action = 'Total-Supply',Data = TotalSupply,Ticker = Ticker})elseSend({Target = msg.From,Action = 'Total-Supply',Data = TotalSupply,Ticker = Ticker})end
end)// burn:销毁代币,
Handlers.add('burn', Handlers.utils.hasMatchingTag("Action",'Burn'), function(msg)assert(type(msg.Tags.Quantity) == 'string', 'Quantity is required!')assert(bint(msg.Tags.Quantity) <= bint(Balances[msg.From]), 'Quantity must be less than or equal to the current balance!')Balances[msg.From] = utils.subtract(Balances[msg.From], msg.Tags.Quantity)TotalSupply = utils.subtract(TotalSupply, msg.Tags.Quantity)if msg.reply thenmsg.reply({Data = Colors.gray .. "Successfully burned " .. Colors.blue .. msg.Tags.Quantity .. Colors.reset})elseSend({Target = msg.From, Data = Colors.gray .. "Successfully burned " .. Colors.blue .. msg.Tags.Quantity .. Colors.reset })end
end)
这段合约实现了一个简单的token系统,支持基本的token操作,如查询余额、转账、铸造和销毁token。通过使用处理器模式,代码结构清晰,易于扩展。若要进一步提高代码的安全性和可读性,可以考虑添加详细的注释和更多的错误处理机制。
4.2 使用golang调用token
package mainimport ("github.com/liteseed/aogo""github.com/liteseed/goar/signer""github.com/liteseed/goar/tag""log"//aogo 库用于与 Arweave 的智能合约交互//goar 库用于处理钱包签名和消息标签
)func main() {walletPath := "./wallet.json"// 从钱包路径创建签名器s, err := signer.FromPath(walletPath)if err != nil {log.Fatalf("创建签名器失败:%v", err)}// 初始化 AO 对象ao, err := aogo.New()if err != nil {log.Fatalf("初始化 AO 对象失败:%v", err)}// 定义目标合约 IDprocessPID := "jysQej65l7KHRZi93csg0rvdmciJNL9hteM1N_yakpE" // 合约 ID// 定义标签,定义操作及操作者tags := &[]tag.Tag{{Name: "Action", Value: "Balance"},{Name: "Target", Value: "Glj6gtx-NJNXTWOF9z9dN2aue3KyU5A_sxR71L1Cak8"},}// 向目标合约发送消息messageID, err := ao.SendMessage(processPID, "", tags, "", s)if err != nil {log.Fatalf("发送消息失败:%v", err)}log.Println("成功发送消息,消息 ID:", messageID)res, err := ao.LoadResult(processPID, messageID)if err != nil {log.Fatalf("读取消息失败:%v", err)}log.Println(res.Messages)log.Println(res.Error)
}
这段代码展示了如何在 Arweave 网络上发送数据并与智能合约交互。通过创建签名器、定义标签、发送消息和读取结果。
4.3 获取消息信息
可以从API中获得消息信息:
https://cu49.ao-testnet.xyz/result/zpPRT9ASUBrT1-OO2LRIfz3IeALW9HiSlHhk6QOmRP0?process-id=jysQej65l7KHRZi93csg0rvdmciJNL9hteM1N_yakpE
result 后跟:Message Id,process-id则是我们的token合约ID
返回结果为:
{"Messages":[{"Target":"60vmK1FkO0f84yHggO5os6n3e_YnVF6O7V6IeX1vjaU","Data":"0","Tags":[{"name":"Data-Protocol","value":"ao"},{"name":"Variant","value":"ao.TN.1"},{"name":"Type","value":"Message"},{"name":"From-Process","value":"jysQej65l7KHRZi93csg0rvdmciJNL9hteM1N_yakpE"},{"name":"From-Module","value":"5l00H2S0RuPYe-V5GAI-1RgQEHFInSMr20E-3RNXJ_U"},{"name":"Ref_","value":"10"},{"name":"Balance","value":"0"},{"name":"Account","value":"60vmK1FkO0f84yHggO5os6n3e_YnVF6O7V6IeX1vjaU"},{"name":"Ticker","value":"PNTS"}],"Anchor":"00000000000000000000000000000010"}],"Assignments":[],"Spawns":[],"Output":[],"GasUsed":601453529}
注:所有发送的消息及返回的消息都会上链,大概十分钟左右
相关文章:
AOS安装及操作演示
文章目录 一、安装node1.1 在 macOS 上管理 Node版本1.1.1 安装 nvm1.1.2 验证 nvm 是否安装成功1.1.3 使用 nvm 安装/切换 Node.js 版本1.1.4 卸载 Node.js 版本 1.2 在 windows 上管理 Node版本1.2.1 安装 nvm-windows1.2.2 安装 Node.js 版本1.2.3 切换 Node.js 版本1.2.4 卸…...
Python 操作 MongoDB 教程
一、引言 在当今数字化时代,数据的存储和管理至关重要。传统的关系型数据库在处理一些复杂场景时可能会显得力不从心,而 NoSQL 数据库应运而生。MongoDB 作为一款开源的、面向文档的 NoSQL 数据库,凭借其高性能、高可扩展性和灵活的数据模型…...
Stability AI 联合 UIUC 提出单视图 3D 重建方法SPAR3D,可0.7秒完成重建并支持交互式用户编辑。
Stability AI 联合 UIUC 提出一种简单而有效的单视图 3D 重建方法 SPAR3D,这是一款最先进的 3D 重建器,可以从单视图图像重建高质量的 3D 网格。SPAR3D 的重建速度很快,只需 0.7 秒,并支持交互式用户编辑。 相关链接 论文…...
网易易盾接入DeepSeek,数字内容安全“智”理能力全面升级
今年农历新年期间,全球AI领域再度掀起了一波革命性浪潮,国产通用大模型DeepSeek凭借其强大的多场景理解与内容生成能力迅速“出圈”,彻底改写全球人工智能产业的格局。 作为国内领先的数字内容风控服务商,网易易盾一直致力于探索…...
自动驾驶---如何打造一款属于自己的自动驾驶系统
在笔者的专栏《自动驾驶Planning决策规划》中,主要讲解了行车的相关知识,从Routing,到Behavior Planning,再到Motion Planning,以及最后的Control,笔者都做了相关介绍,其中主要包括算法在量产上…...
局域网使用Ollama(Linux)
解决局域网无法连接Ollama服务的问题 在搭建和使用Ollama服务的过程中,可能会遇到局域网内无法连接的情况。经过排查发现,若开启了代理软件,尤其是Hiddify,会导致此问题。这一发现耗费了我数小时的排查时间,希望能给大…...
聚焦 AUTO TECH China 2025,共探汽车内外饰新未来Automotive Interiors
全球汽车产业蓬勃发展的大背景下,汽车内外饰作为汽车重要组成部分,其市场需求与技术创新不断推动着行业变革。2025年11月20日至22日,一场备受瞩目的行业盛会 ——AUTO TECH China 2025 广州国际汽车内外饰技术展览会将在广州保利世贸博览馆盛…...
Moretl 增量文件采集工具
永久免费: <下载> <使用说明> 用途 定时全量或增量采集工控机,电脑文件或日志. 优势 开箱即用: 解压直接运行.不需额外下载.管理设备: 后台统一管理客户端.无人值守: 客户端自启动,自更新.稳定安全: 架构简单,兼容性好,通过授权控制访问. 架构 技术架构: Asp…...
支持多种网络数据库格式的自动化转换工具——VisualXML
一、VisualXML软件介绍 对于DBC、ARXML……文件的编辑、修改等繁琐操作,WINDHILL风丘科技开发的总线设计工具——VisualXML,可轻松解决这一问题,提升工作效率。 VisualXML是一个强大且基于Excel表格生成多种网络数据库文件的转换工具&#…...
mysql8 用C++源码角度看客户端发起sql网络请求,并处理sql命令
MySQL 8 的 C 源码中,处理网络请求和 SQL 命令的流程涉及多个函数和类。以下是关键的函数和类,以及它们的作用: 1. do_command 函数 do_command 函数是 MySQL 服务器中处理客户端命令的核心函数。它从客户端读取一个命令并执行。这个函数在…...
四、OSG学习笔记-基础图元
前一章节: 三、OSG学习笔记-应用基础-CSDN博客https://blog.csdn.net/weixin_36323170/article/details/145514021 代码:CuiQingCheng/OsgStudy - Gitee.com 一、绘制盒子模型 下面一个简单的 demo #include<windows.h> #include<osg/Node&…...
使用vllm docker容器部署大语言模型
说明 最近deepseek比较火,我在一台4卡4090的服务器上尝试部署了一下,记录下部署步骤。 安装过程 安卓docker和nvidia-container-toolkit 安装19.03版本以上的docker-ce即可。安装步骤参考清华docker源上的安装步骤:Docker CE 软件仓库 为…...
window 安装GitLab服务器笔记
目录 视频: 资源: Linux CeneOS7: VMware: Linux无法安装 yum install vim -y 1.手动创建目录 2.下载repo PS 补充视频不可复制的代码 安装GitLab *修改root用户密码相关(我卡在第一步就直接放弃了这个操作&…...
MySQL数据库入门到大蛇尚硅谷宋红康老师笔记 基础篇 part 10
第10章_创建和管理表 DDL:数据定义语言。CREATE \ALTER\ DROP \RENAME TRUNCATE DML:数据操作语言。INSERT \DELETE \UPDATE \SELECT(重中之重) DCL:数据控制语言。COMMIT \…...
react项目引入tailwindcss不生效解决方案
根据tailwindcss官网的操作步骤下来,样式未生效,且未报错,看了挺多的资料,还是并未解决。 后面在另一个项目尝试时,报了下面的问题: Error: PostCSS plugin tailwindcss requires PostCSS 8 根据这个链接…...
Expo运行模拟器失败错误解决(xcrun simctl )
根据你的描述,问题主要涉及两个方面:xcrun simctl 错误和 Expo 依赖版本不兼容。以下是针对这两个问题的解决方案: 解决 xcrun simctl 错误 错误代码 72 通常表明 simctl 工具未正确配置或路径未正确设置。以下是解决步骤: 确保 …...
【系统架构设计师】体系结构文档化
目录 1. 说明2. 重要性3. 主要内容4. 编写原则5. 实践建议6. 例题6.1 例题1 1. 说明 1.绝大多数的体系结构都是抽象的,由一些概念上的构建组成。2.层的概念在任何程序设计语言中都不存在。3.要让系统分析员和程序员去实现体系结构,还必须将体系结构进行…...
【0403】Postgres内核 检查(procArray )给定 db 是否有其他 backend process 正在运行
文章目录 1. 给定 db 是否有其他 backend 正在运行1.1 获取 allPgXact[] 索引1.1.1 MyProc 中 databaseId 初始化实现1.2 allProcs[] 中各 databaseId 判断1. 给定 db 是否有其他 backend 正在运行 CREATE DATABASE 语句创建用户指定 数据库名(database-name)时候, 会通过 …...
前端如何判断浏览器 AdBlock/AdBlock Plus(最新版)广告屏蔽插件已开启拦截
2个月前AdBlock/AdBlock Plus疑似升级了一次 因为自己主要负责面对海外的用户项目,发现以前的检测AdBlock/AdBlock Plus开启状态方法已失效了,于是专门研究了一下。并尝试了很多方法。 已失效的老方法 // 定义一个检测 AdBlock 的函数 function chec…...
微信小程序(第一集)
app.json {// 定义小程序的所有页面路径,数组中的第一个页面是首页"pages": ["pages/index/index", // 首页"pages/logs/logs" // 日志页面],// 设置小程序的全局窗口外观(比如导航栏和背景颜色)"wind…...
flutter ListView Item复用源码解析
Flutter 的 ListView 的 Item 复用机制是其高性能列表渲染的核心,底层实现依赖于 Flutter 的渲染管线、Element 树和 Widget 树的协调机制。以下是 ListView 复用机制的源码级解析,结合关键类和核心逻辑进行分析。 1. ListView 的底层结构 ListView 的复…...
《Operating System Concepts》阅读笔记:p9-p12
《Operating System Concepts》学习第 3 天,p9-p12 总结,总计 4 页。 一、技术总结 1.interrupt interrupt具有优先级(priority)。 2.storage 指令只能在 memory 上执行,所以要执行程序,那么就要加载到内存上。 (1)RAM Gen…...
html文件怎么转换成pdf文件,2025最新教程
将HTML文件转换成PDF文件,可以采取以下几种方法: 一、使用浏览器内置功能 打开HTML文件:在Chrome、Firefox、IE等浏览器中打开需要转换的HTML文件。打印对话框:按下CtrlP(Windows)或CommandP(M…...
【SpringBoot实现全局API限频】 最佳实践
在 Spring Boot 中实现全局 API 限频(Rate Limiting)可以通过多种方式实现,这里推荐一个结合 拦截器 Redis 的分布式解决方案,适用于生产环境且具备良好的扩展性。 方案设计思路 核心目标:基于客户端标识(…...
科技查新过不了怎么办
“科技查新过不了怎么办?” “科技查新不通过的原因是什么?” 想必这些问题一直困扰着各位科研和学术的朋友们,尤其是对于查新经验不够多的小伙伴,在历经千难万险,从选择查新机构、填写线上委托单到付费,…...
设计模式-结构型-外观模式
在软件开发中,随着功能的不断迭代,系统会变得越来越复杂,模块之间的依赖关系也会越来越深。这种复杂性会导致代码难以理解、维护和扩展。而外观模式(Facade Pattern)正是为了解决这一问题而生的。 一、外观模式简介 …...
超详细的数据结构3(初阶C语言版)栈和队列。
文章目录 栈和队列1.栈1.1 概念与结构1.2 栈的实现 2. 队列2.1 概念与结构2.2 队列的实现 总结 栈和队列 1.栈 1.1 概念与结构 栈:⼀种特殊的线性表,其只允许在固定的⼀端进行插⼊和删除元素操作。进⾏数据插⼊和删除操作的⼀端称为栈顶,另…...
centos 7 关于引用stdatomic.h的问题
问题:/tmp/tmp4usxmdso/main.c:6:23: fatal error: stdatomic.h: No such file or directory #include <stdatomic.h> 解决步骤: 1.这个错误是因为缺少C编译器的标准原子操作头文件 stdatomic.h。在Linux系统中,我们需要安装开发工具…...
Unity WebGL包体压缩
最近在开发webgl,踩了很多坑,先来说下包体的问题。 开发完之后发现unity将文件都合并到一个文件了,一共有接近100m。 这对网页端的体验来说是可怕的,因为玩家必须要加载完所有的文件才能进入,这样体验特别差。 于是想…...
【对比测评】 .NET 应用的 Web 视图控件:DotNetBrowser 或 EO.WebBrowser
您是否需要 .NET 应用的 Web 视图控件?.NET 生态系统提供了很多东西,有免费的 Web 视图控件,既有开源的,也有专有的。还有一些商业 Web 视图 控件,也是企业经常选择的一种选项。 在这篇博文中,我们比较了商…...
