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 卸…...
蓝桥杯单片机组第十三届初赛试题-程序题(第2批)
题目到官网看即可,有点久了有些细节记不清了,可能以前发的帖子解释详细一点。 这是我单片机初学的时候写的,像代码结构什么的肯定有可以提升的地方,多多包涵,将就看一下。 i2c文件使用官方的,pcf8591函数…...
企业级高可用 Kubernetes 实践:基于青云 LB 搭建容灾与负载均衡集群全攻略
一、前言 在企业生产环境,k8s高可用是一个必不可少的特性,其中最通用的场景就是如何在 k8s 集群宕机一个节点的情况下保障服务依旧可用。部署高可用k8s集群对于企业级云平台来说是一个根本性的原则,容错、服务可用和数据安全是高可用基础设施的关键。本文是在青云上利用青云…...
Python Pandas(11):Pandas 数据可视化
数据可视化是数据分析中的重要环节,它帮助我们更好地理解和解释数据的模式、趋势和关系。通过图形、图表等形式,数据可视化将复杂的数字和统计信息转化为易于理解的图像,从而便于做出决策。Pandas 提供了与 Matplotlib 和 Seaborn 等可视化库…...
【练习】图论
F. Friendly Group 图中选择一个点-1 边两端点都选择1 边一个端点选择-1 添加链接描述 #include<iostream> using namespace std; #include<vector> #include<cstring> const int N300010; int n,m; vector<int> G[N]; int temp1,temp2; bool vis[N…...
【RAG落地利器】Weaviate、Milvus、Qdrant 和 Chroma 向量数据库对比
什么是向量数据库? 向量数据库是一种将数据存储为高维向量的数据库,高维向量是特征或属性的数学表示。每个向量都有一定数量的维度,根据数据的复杂性和粒度,可以从数十到数千不等。 向量通常是通过对原始数据(如文本、图像、音频、视频等)…...
今日AI和商界事件(2025-02-14)
今日AI大事件主要包括以下几个方面: 一、苹果新品预告 事件概述:苹果CEO蒂姆库克在社交媒体发布7秒视频,配文“准备好迎接家庭的新成员”,并宣布2月19日将有新品发布。知名科技记者马克古尔曼称,新款低端iPhone SE将…...
【大语言模型】最新ChatGPT、DeepSeek等大语言模型助力高效办公、论文与项目撰写、数据分析、机器学习与深度学习建模等科研应用
ChatGPT、DeepSeek等大语言模型助力科研应用 随着人工智能技术的快速发展,大语言模型如ChatGPT和DeepSeek在科研领域的应用正在为科研人员提供强大的支持。这些模型通过深度学习和大规模语料库训练,能够帮助科研人员高效地筛选文献、生成论文内容、进行数…...
spring6(完结)
像是八大模式这种,放在后面八股文中再重点了解,对于源码部分也是后面会一起手敲。 个人觉得spring的重点在于注解开发,省去了很多耦合的问题,像是各种事务的管理,和bean类的管理都可以给spring容器管理,注入…...
Kubernetes (k8s) 常用指令速查表
以下是一份 Kubernetes (k8s) 常用指令速查表,涵盖集群管理、资源操作、故障排查等场景,适合日常运维和开发使用: 1. 集群与节点管理 命令说明kubectl cluster-info查看集群基本信息kubectl get nodes查看所有节点状态kubectl describe node…...
DeepSeek教unity------MessagePack-05
动态反序列化 当调用 MessagePackSerializer.Deserialize<object> 或 MessagePackSerializer.Deserialize<dynamic> 时,二进制数据中存在的任何值都将被转换为基本值,即 bool、char、sbyte、byte、short、int、long、ushort、uint、ulong、…...
Kotlin 优雅的接口实现
1. 日常遇到的冗余的接口方法实现 日常开发中,经常会要实现接口,但是很多场景中,只需要用到其中一两个方法,例如 ActivityLifecycleCallbacks,它有很多个接口需要实现,但是很多时候我们只需要用到其中的一…...
新的面试题CSS
解释CSS Hack 一般来说是针对不同的浏览器写不同的CSS,就是 CSS Hack。 IE浏览器Hack一般又分为三种,条件Hack、属性级Hack、选择符Hack(详细参考CSS文档:css文档)。例如: // 1、条件Hack <!--[if IE]> <sty…...
DeepSeek R1打造本地化RAG知识库
本文将详细介绍如何使用Ollama、Deepseek R1大语音模型、Nomic-Embed-Text向量模型和AnythingLLM共同搭建一个本地的私有RAG知识库。 一. 准备工作 什么是RAG? RAG是一种结合了信息检索和大模型(LLM)的技术,在对抗大模型幻觉、…...
聚铭网络入围2025年度江苏省政府采购信息安全设备协议供货名单
近日,2025年度江苏省党政机关、事业单位及团体组织信息安全设备框架协议采购项目入围结果公布。聚铭网络凭借自身专业实力和技术优势脱颖而出,成功入围22个分包。 此次采购项目是江苏省政府采购领域级别最高、覆盖面最广的项目之一。从资格评选到后期材料…...
基于Flask的影视剧热度数据可视化分析系统的设计与实现
【FLask】基于Flask的影视剧热度数据可视化分析系统的设计与实现(完整系统源码开发笔记详细部署教程)✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 随着互联网技术的飞速发展,影视剧行业的数据量呈爆炸性增长&#x…...
【弹性计算】弹性计算的技术架构
弹性计算的技术架构 1.工作原理2.总体架构3.控制面4.数据面5.物理设施层 虽然弹性计算的产品种类越来越多,但不同产品的技术架构大同小异。下面以当前最主流的产品形态 —— 云服务器为例,探查其背后的技术秘密。 1.工作原理 云服务器通常以虚拟机的方…...
python-leetcode 31.K个一组翻转链表
题目: 给定链表的头节点head,每K个节点一组进行翻转,返回修改后的链表。 K是正整数,它的值小于等于链表的长度,如果节点总数不是K的整数组,那么将最后剩余的节点保持原有顺序。不能只改变节点内容的值,需…...
算法08-递归调用转为循环的通用方法
前导:问题引入 在Python中,递归调用过多会导致“递归深度过深”的错误,通常是因为递归没有正确终止条件或者递归层次太深。 这种错误通常会导致程序抛出 RecursionError 异常。 Python默认的递归深度限制大约是1000层(可以通过sys.getrecursionlimit()查看)。 修正方式…...
[创业之路-300]:进一步理解货币与金钱, 货币与货币政策
目录 一、货币 1.1 概述 1、货币的定义 2、货币的形态演变 3、货币的职能 4、货币的价值衡量 1.2 货币的分层 1、货币分层的目的与意义 2、货币分层的划分标准与层次 3、各国货币分层的实践 4、货币分层的影响与应用 1.3、M0、M1、M2变化对股市的影响 1、M0变化对…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...
JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
网络编程(UDP编程)
思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...
深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...
使用SSE解决获取状态不一致问题
使用SSE解决获取状态不一致问题 1. 问题描述2. SSE介绍2.1 SSE 的工作原理2.2 SSE 的事件格式规范2.3 SSE与其他技术对比2.4 SSE 的优缺点 3. 实战代码 1. 问题描述 目前做的一个功能是上传多个文件,这个上传文件是整体功能的一部分,文件在上传的过程中…...
2.2.2 ASPICE的需求分析
ASPICE的需求分析是汽车软件开发过程中至关重要的一环,它涉及到对需求进行详细分析、验证和确认,以确保软件产品能够满足客户和用户的需求。在ASPICE中,需求分析的关键步骤包括: 需求细化:将从需求收集阶段获得的高层需…...
ffmpeg(三):处理原始数据命令
FFmpeg 可以直接处理原始音频和视频数据(Raw PCM、YUV 等),常见场景包括: 将原始 YUV 图像编码为 H.264 视频将 PCM 音频编码为 AAC 或 MP3对原始音视频数据进行封装(如封装为 MP4、TS) 处理原始 YUV 视频…...
HTML版英语学习系统
HTML版英语学习系统 这是一个完全免费、无需安装、功能完整的英语学习工具,使用HTML CSS JavaScript实现。 功能 文本朗读练习 - 输入英文文章,系统朗读帮助练习听力和发音,适合跟读练习,模仿学习;实时词典查询 - 双…...
虚拟机网络不通的问题(这里以win10的问题为主,模式NAT)
当我们网关配置好了,DNS也配置好了,最后在虚拟机里还是无法访问百度的网址。 第一种情况: 我们先考虑一下,网关的IP是否和虚拟机编辑器里的IP一样不,如果不一样需要更改一下,因为我们访问百度需要从物理机…...
