以太坊(3)——智能合约
智能合约
首先明确一下几个说法(说法不严谨,为了介绍清晰才说的):
-
全节点==矿工
-
节点==账户
智能合约是基于Solidity语言编写的
学习Solidity语言可以到WFT学院官网(Hello from WTF Academy | WTF Academy),有初级和进阶课程
智能合约的结构
下面的函数的问题,在文章最后讨论
上述是一个简单的智能合约的结构:
-
一个合约可以看作是一个类
-
log通过emit触发事件在链上记录下来
-
构造函数是每个合约有且只有一个的,可以为空,只能在创建时调用一次
-
成员函数是部署合约后可以调用的,一般有关键字,modifier等限制权限
-
智能合约里的mapping不能遍历,只能存储它的地址集合,按照地址去查询
合约的调用
外部账户的调用
-
首先,要填写外部账户的地址,合约账户的地址
-
之后,需要填写函数接收的参数(之后细说)
-
一般部署和调用合约的编译器是Remix
一个合约中调用另一个合约的函数
直接调用
-
合约B调用合约A的内容,
A a = A(addr)
,addr指的是A的地址,该语句将这个地址转换成A合约的实例a,之后调用a里面的函数foo,使用ua接收返回值。 -
由于以太坊规定一个交易只能由外部账户调用,合约账户不能发起交易。因此只能当某个外部账户调用合约B的时候,才能触发B中的那个语句,进而调用A
-
这种调用方式下,如果A在运行过程中发生什么异常,会导致B合约的内容也连带回滚
call函数调用
这种方式的调用,如果调用的合约(addr的实例)出现错误,C合约不会回滚,只会引起调用部分返回异常值,其余部分正常
代理调用
这种调用不需要切换到被调用的合约环境中去执行,在当前合约的环境中执行(使用当前合约的属性等)
fallback函数
注意,只有向合约账户转账时才有fallback函数的生成!!!
如果不需要调用函数或者调用函数错误时,Solidity编译器自动生成fallback函数,里面的payable函数也是自动添加的
注意:gas费是给记录你这笔交易矿工的(类似于BTC里面的交易手续费),不是给合约账户的!
合约节点会在以下情况下调用fallback函数:
-
未知函数调用: 当合约接收到一个未知的函数调用时,即调用合约中不存在的函数时,会触发fallback函数的执行。
-
以太币转账: 当以太币被直接发送到合约地址(即没有附带调用数据),这时会触发fallback函数的执行。
-
低级调用: 如果合约内部使用了
call
或delegatecall
调用其他合约,并且调用的合约不存在对应的函数时,也会调用fallback函数。
错误处理
智能合约的调用具有原子性,即一个合约部分出错,整体回滚(这个和前面讲的addr调用不冲突,addr调用是使用一个判断语句将这个调用变成了一个返回值)
-
gaslimit被耗完依旧不能实现,调用被回滚,而且gas费不退还
-
assert()语句检查内部错误(类似于C语言)
-
require()语句检查外部错误(比如msg.senter!=addr)
-
revert()语句自动弹出错误(可用于if条件等)
注意:Solidity里面没有自定义报错类型try-catch
嵌套调用
一个合约调用另一个合约
如果向某个合约账户转账,虽然表面上你没有调用,但是编译器自动帮你生成了fallback函数,还是调用了!
智能合约的创建和运行
创建
-
外部账户发起转账到0x0地址中,转账金额为0
-
合约代码(编译成bytecode)放在data域中
-
支付给矿工gas,矿工将合约发布到区块链上,返回合约的地址(也就是智能合约的地址)
-
此时,智能合约就可以被所有人调用了
运行
智能合约运行在以太坊虚拟机EVM(Ethereum Virtual Machine)上
EVM是一个256位的WWC(Worldwide Computer),使用EVM提高了智能合约的可移植性
汽油费(gas)
原因
图灵完备的语言,需要避免死循环导致的停机
数据结构
调用合约的人支付,相当于是把停机问题推给了调用方
GasLimit就是调用方此次调用这个合约能接受的最大汽油量,可以在Remix部署时填写
GasLimit * Price 计算出的是花掉的最大汽油费
Payload就是data域
gas的价格是由调用者选择的,价格高的更容易被矿工写入区块。
-
往往代码功能简单的汽油费低,代码复杂的汽油费高。
-
存储状态变量汽油费高,仅读取状态变量免费
调用过程
-
当一个全节点收到一个调用的时候,它首先计算出调用花费的最大汽油费
-
将这笔最大汽油费从发起账户中扣掉。
-
然后根据实际执行的情况算出实际花费的汽油费,剩下的退回去,不够的话合约回滚gas耗完不退
数据结构
区块头
GasLimit
实际消耗gas的上限!
BTC每个区块最大不能超过1M,主要是带宽因素
-
由于ETH矿工的gas费收益是很可观的,防止他为了多收钱把巨量的的交易包含进去,影响传输速率,也要进行限制,
-
但是因为智能合约Solidity的结构复杂(循环和调用),往往大小不能完全反映复杂程度,因此就使用最大gas费的方式限制
GasUsed
实际消耗的汽油费
每个区块发布的时候,矿工可以对gaslimit进行微调,上下不超过1/1024
三树
合约调用的时间应该在发布区块前还是发布区块后?
先执行,后挖矿。原因是执行完合约之后,“三树”的信息会改变,而区块头包含的是三树的根哈希值。只有得到根哈希值之后才可以组合数据,尝试nonce值!
本质上,汽油费是为了补偿矿工执行合约消耗的资源。但是对于没有挖到区块的矿工,他们的验证没有补偿的,这会不会导致那些矿工不去验证发布的区块,就默认发布的是对的。如果这样的话就会严重影响区块链的安全性!
节点不验证了怎么办?
如果它不执行不验证,就无法更新三树,之后它组装区块的时候算出的根哈希值是错的,挖出区块的nonce值被其他区块验证为不合法!环环相扣了属于是。
我还是不验证,直接抄!
这种做法类似于矿池的做法,一个全节点进行验证,其他矿工只负责计算哈希值。
但是如果你不是这个矿池的成员,你敢不敢相信它发布的三树根哈希是正确的呢?要知道挖矿的3Ether收益可是远远大于gas费的,矿工不愿意冒着辛辛苦苦挖出区块作废的奉劝去节省验证的花销。
执行错误的交易要不要发布?
要,这样依旧可以扣除他的汽油费,获得你的收益
智能合约是否支持多线程(多核并行处理)?
不支持,因为Solidity语言中不具有支持多线程的语句。原因是多核对于内存访问顺序不同的时候,会导致最终的结果不同,而以太坊需要的是状态机进入统一的确定的状态(Papers (zhenxiao.com)可以参考肖老师的论文
Receipt
每个交易执行完形成一个收据(receipt),Status这个变量代表的是交易的状态
地址类型
address.balance: address的余额
address.transfer(金额):当前合约向address转入的金额
address.call:当前合约调用address
转账的方法
<address>.transfer(uint256 amount)//会导致连锁型回滚 gas少 <address>.send(uint256 amount)//返回false 不会会滚 gas少 <address>.call.value(uint256 amount)//本意不是专门为转账设计的 不会会滚 发送剩余的所有gas
智能合约的信息获取
通过智能合约可以得到区块链的信息
智能合约可以获取的调用信息
msg.sender和tx.origin的区别
上图中A账户调用C1合约中的f1函数,f1函数调用C2合约中的f2函数
则对于f2函数而言,msg.sender指的是C1,而tx.origin指的是A账户
智能合约的设计
不可篡改!
智能合约是不可篡改的,在发布之前一定要反复测试。
一旦发布就不可撤销,无法更改。可能会导致资金的永久锁死或者被黑客利用漏洞进行攻击!
测试的网址比如本地的truffle,ganache,测试网等等,确认完全没有问题再进行发布
后门?
不存在的,因为这与去中心化背道而驰
拍卖函数的修正
第一版问题
右侧最高出价的for循环有问题,都拿不到钱!
第二版
拆成两个函数,第一个允许竞拍的失败者取回自己的钱(只能取一次),第二个是将最高出价给卖家
BUG
注意黑客合约的fallback函数(右侧最下面),当合约通过call函数调用时,调用fallback函数(忘记的话可以回顾一下上面的fallback函数部分)。因此,主合约的withdraw进入if语句的判断时,就会调用fallback函数给黑客转账,而fallback函数再次调用withdraw函数,形成循环(根本无法执行48行的清零语句)...
循环截至的条件:
-
合约存储的钱不足以支付下次转账
-
调用栈溢出
-
gas费不足
这也是黑客的fallback函数里面if语句判断的条件!
第三版
先清零再转账,这遵循了和其他合约发生交互的编程模式: 先判断条件,再改变条件,最后交互!
第二版纠正
另一种方法就是不用call!
使用send和transfer都可以,因为发送出的汽油费只有2300个单位,不足以支撑再一次的调用,只够写一个log
The DAO
造成以太坊分裂的一次攻击
DAO:Decentralized Autonomous Organization 去中心化机构
致力于去中心化投资的公司——The DAO
运行原理
这个公司本质上是ETH上的一个智能合约,你想要投资就要把你的以太币发给这个合约,换取合约的D代币(简称)。要投资什么项目由大家投票决定,投票的权重按照所拥有的D代币分配,收益也是按照规定按比例分配。
取款
取款的方式使用split DAO。当取钱时,收回相应的代币,将对应的以太币打到子基金Chile DAO之中(这种做法也是给部分人投资小众项目拆分子基金用的,极端例子就是单个投资者成立子基金,也就是取钱)
拆分之前有7天的讨论期,用于商讨要不要拆出子基金以及要不要加入这个子基金
拆分后有28天的锁定期,子基金里的钱要28天以后才能取出来
历史事件
2016年开始众筹,引起很大关注,在一个月时间筹集到价值1.5亿美元的Ether(当时价格)
这就违反了之前提到的先判断条件,再改变条件,最后交互!的编程原则,导致了黑客盗走价值5kw美元的资金
之后,社区发生意见的分歧,一方认为要回滚,利用28天的锁定期来防止黑客取走资金。另一方认为,合约的漏洞只是它自己的漏洞,不能因为一个合约的问题就违背以太坊的不可篡改性。
社区的开发者认为The DAO是too big to fail,垮掉会对以太坊造成毁灭性打击(以太币价格跳水),因此采取了回滚措施进行补救。
如何补救?
首先,以太坊开发团队想到的是一个软分叉方案:
锁定黑客账户:进行一次软件升级但凡与TheDAO相关的账户,不能进行任何交易(老认新,软分叉)。
问题是,当时规定,这些”非法“的账户发布交易,不能上链也不收取gas,因此引起了很多这种账户发布死循环攻击来骚扰矿工,矿工不堪重负,纷纷回滚这次软件的升级
由于软方案失败,所剩时间不多,团队只能采取硬分叉方案:
将所有的资金(要是只转黑客的,其他的相关帐户都可以利用这个BUG实现攻击)转入一个账户B,该账户的唯一作用就是——退钱!在第192W个区块强制将所有相关账户的钱转给账户B(新认老,固执节点不认可你没有人家账户签名就转账的操作)
分歧
很多节点认为,这种操作违背了去中心化的理念(以太坊团队说转走谁的钱就转走)因此以太坊团队发布两个合约进行投票,支持哪一种方案就把以太币投进那个合约。最后大多节点(按掌握资金数量分)选择硬分叉。
但是,另一方不认可这样的做法:
-
并非所有资金都参与投票了
-
大多数人支持的就一定对吗?
这些矿工挖出的旧链以太币被称为ETC
ETC
ETC(classic),指的是在旧链上挖矿产出的以太币,由于挖矿算力大幅削减,不乏投机者选择在这条链上进行挖矿,但是也有一部分矿工坚持挖矿是源自去中心化的信仰!尽管开始的前景并不被人看好,但是这条链依旧坚持至今。
2015年7月 Vitalik Buterin和以太坊基金会创建了第一个基于区块链的图灵完成智能合约平台。
2016年4月~6月 以太坊The DAO项目ICO以遭到黑客攻击告终
2016年7月20日 以太坊硬分叉实施,产生了ETH和ETC两条独立的区块链,ETC正式诞生
2016年8月 91,pool上线
2016年9月23日,微软加入对于ETC的支持
2016年10月17日,ETC第一个ICO项目ETCWIN
2016年10月,ETCFans上线
2016年12月24日,全球第一个以太坊原链社区交易所ETCWin上线
2017年4月27日,ETF基金会确定限产
2017年6月底,ETC发起支持零知识证明改进建议。
......
为了更好的管理这两条链,产生了新的数据标记——ChainID
Beauty Chain(美链)
背景介绍
美链(Beauty Chain)是一个部署在以太坊上的智能合约,有自己的代币BEC。
-
ICO:Initial Coin Offering没有自己的区块链,代币的发行、转账都是通过调用智能合约中的函数来完成的
-
可以自己定义发行规则,每个账户有多少代币也是保存在智能合约的状态变量里
-
ERC 20(Ethereum Request for Comments)是以太坊上发行代币的一个标准,规范了所有发行代币的合约应该实现的功能和遵循的接口
-
美链中有一个叫batchTransfer的函数,它的功能是向多个接收者发送代币,然后把这些代币从调用者的帐户上扣除
很多代币上线之前是依附在以太坊上的。
实现
接收者的数目最多20个
问题
uint amount = uint256(cnt) * _value
乘出的结果可能过大,出现溢出,即扣除的代币数字很小。也就是调用者转出的代币少,接收者依旧收到海量代币。也就是系统发行代币量凭空增多。
攻击细节
每个黑客区块收到了很大一部分代币
反思
Is smart contract real smart?
智能合约,实际上只是一种改不了Bug的合同
不可篡改性是一个双刃剑
一方面增加了合约的公信力,
但另一方面发布后的软件很难进行修改。发现了安全漏洞,很难发布软分叉进行补救,或者阻止调用;哪怕发现了黑客,也很难冻结其账户
如果你是theDAO的用户,怎么补救?
使用重入攻击转走剩余的资金,之后再分给大家
Nothing is irrevocable
不要过度迷信区块链的不可篡改性,代码是死的,人是活的
比如美国宪法还有修正案,以及被推翻的修正案(禁酒令)
Solidity语言设计的问题
安全性问题
有人认为Solidity语言是反自然的。本质上,转账时调用fallback函数,也就给了被转账方再次调用合约的机会。这和正常情况下转账接收方是被动接收相违背,和常识不同。因此有人提议应该使用函数式的语言编写合约
语言表达能力
图灵完备的表达能力是不是太强了?BTC的语言表达能力太差,ETH写的程序又有些危险。能不能找一种适中的语言?
在日常生活中,我们使用自然语言编写合同,自然语言写出的一些合同也有纠纷,难道要写一套合同专用语言吗?实际上的解决方法是在模板的基础上编写合同,常用的智能合约会出现模板,会出现专门编写智能合约的机构......
相信智能合约终究会走向成熟!
透明性
中心化的公司很多是闭源的,把源代码当作是商业机密。去中心化的公司为了让大家达成共识,往往需要将代码开源(比如更新,查验等等)
开源的好处
-
增加合约的公信力
-
开源代码很多人审查,不容易出现漏洞?
Many Eyeball Fallacy
虽然很多人有权限看,但是大多人没动力看,看不懂或者看懂了找不出漏洞
涉及到财产安全的合约,要仔细检查漏洞。投资需谨慎,将资金投入在自己了解擅长的领域,不要孤注一掷天台见!
去中心化
What does decentralization mean?
去中心化不是说一切由代码决定,也要有人的参与。
去中心化不是说制定好的规则一定不能修改,而是规则的修改要按照去中心化的原则来完成。
分叉
存在分叉的选项,是民主的体现,因为在中心化的世界里,你只能接受!
这就像theDAO当时的子基金,或者像还在挖矿的ETC,亦或是创建以太坊的V神,他们愿意构造一个世界,不是少数服从多数,而是只要有想法,就可以走出自己的道路。
去中心化不等价于分布式
去中心化一定是分布式的,但是分布式如果是由一个组织管辖(或者占有绝对领导权),也不能叫去中心化。
分布式的系统是不同的机器做不同的事情,最后汇总成一个结果。本质目的是为了加速
状态机
而比特币和以太坊都是运行的一台状态机,付出巨大的代价使得系统维持一个一致的状态。状态机的本质目的是为了容错。space shuttle,stock exchange 等状态机多台计算机运行同一个状态,防止某台机器宕机的风险。状态机由于同步的需要,往往是机器越多,运行越慢,因此只有几台机器(本来就是防止某台宕机的,多了也没必要)
而向BTC,ETH这种上千台计算机的分布式状态机是两者的混合体,智能合约适用的不是分布式系统,智能合约是用来在互不相识的机器之间建立共识机制的控制性语言,而不是用于大规模云计算的。
溢出
Solidity 里的SafeMath有很对针对溢出的函数
c=a*b assert(c/a==b)
不会存在像C语言的溢出
flag:对于智能合约审计和黑客游戏的内容之后会学习分享
相关文章:

以太坊(3)——智能合约
智能合约 首先明确一下几个说法(说法不严谨,为了介绍清晰才说的): 全节点矿工 节点账户 智能合约是基于Solidity语言编写的 学习Solidity语言可以到WFT学院官网(Hello from WTF Academy | WTF Academy)…...
【Python设计模式03】简单工厂模式
简单工厂模式(Simple Factory Pattern)是一种创建型设计模式,它通过专门定义一个工厂类来负责创建其他类的实例,而不是在客户端代码中直接实例化对象。这样可以将对象创建的过程与使用对象的过程分离,提高代码的可维护…...

java中的Collections类+可变参数
一、概述 Collections类是集合类的工具类,与数组的工具类Arrays类似 二、可变参数(变:数量) 格式:参数类型名...参数,可变参数就是一个数组 注意:可变参数必须放在参数列表的最后并且一个参数列表只能有一个可变参…...
SpringBoot集成腾讯云敏感词校验API流程
1.pom.xml中引入腾讯云jar配置信息 <dependency><groupId>com.tencentcloudapi</groupId><artifactId>tencentcloud-sdk-java</artifactId><version>4.0.11</version> </dependency> 2.application.yaml中添加配置 tencent…...
android 避免混淆类名和方法名,但是方法内容需要被混淆
要避免在使用 ProGuard 或 R8 进行代码混淆时混淆特定类名和方法名的同时让方法内容被混淆,你需要在 ProGuard 配置文件中使用 -keepclassmembers 或 -keep 规则。这些规则允许你指定保留类名和方法名的同时允许方法内部代码被混淆以减小体积和提高安全性。 以下是…...
通过ELRepo修改CentOS 7内核版本的详细步骤
简介: 在Linux系统中,内核版本决定了硬件支持和系统性能。有时,为了获得更好的性能或新特性,我们需要升级或更换内核。本文将详细说明如何在CentOS 7系统上通过ELRepo仓库安装更新的内核版本。 环境准备: CentOS 7系…...

C++开源库glog使用封装--自定义日志输出格式,设置日志保留时间
glog下载和编译 glog开源地址 https://github.com/google/glog glog静态库编译 cd /home/wangz/3rdParty/hldglog/glogmkdir out mkdir build && cd buildcmake .. -DCMAKE_INSTALL_PREFIX../out -DCMAKE_BUILD_TYPERelease -DBUILD_SHARED_LIBSOFF本文选择的glo…...
linux rc.local不生效
1. 权限问题直接 chmod 755 /etc/rc.d/rc.local 即可 2.本次发现问题 环境复杂造成,系统中有多个版本的JDK,导致tomcat无法启动 systemctl status rc-local.service ● rc-local.service - /etc/rc.d/rc.local CompatibilityLoaded: loaded (/usr/lib…...

ROS2入门21讲__第07讲__节点:机器人的工作细胞
目录 前言 通信模型 案例一:Hello World节点(面向过程) 运行效果 代码解析 创建节点流程 案例二:Hello World节点(面向对象) 运行效果 代码解析 创建节点流程 案例三:物体识别节点 …...

k8s node NotReady后会发生什么?
K8s 是一种强大的容器编排和管理平台,能够高效地调度、管理和监控容器化应用程序;其本身使用声明式语义管理着集群内所有资源模型、应用程序、存储、网络等多种资源,Node 本身又属于 K8s 计算资源,上面承载运行着各种类型的应用程…...

uni-starter创建App项目最全流程(日后还有其他功能会不断更新)
一、创建项目 在HbuilderX中点击创建项目,选择uni-starter模板,选择阿里云、Vue3,填写项目名称后点击创建。如果没有下载过uni-starter会自动下载该插件,如下图: 二、 创建云服务器并关联项目 如果是第一次使用&#…...
动态IP和静态IP区别
1.可变性:当设备重新连接时,动态IP将分配新的IP地址,静态IP将保持不变。 2.适用场景:动态IP适用于普通用户或小型办公室,静态IP适用于需要特定IP地址的服务或应用。 3.价格:动态IP通常比静态IP更经济。 4.管理和配置:动…...

蓝牙(2):BR/EDR的连接过程;查询(发现)=》寻呼(连接)=》安全建立=》认证=》pair成功;类比WiFi连接过程。
4.2.1 BR/EDR 流程: 查询(发现)》寻呼(连接)》安全建立》认证》pair成功 4.2.1.1 查询(发现)流程Inquiry (discovering) 类比WiFi的probe request/response 蓝牙设备使用查询流程来发现附近的…...
源码部署EFK
目录 资源列表 基础环境 关闭防护墙 关闭内核安全机制 修改主机名 添加hosts映射 一、部署elasticsearch 修改limit限制 部署elasticsearch 修改配置文件 单节点 集群(3台节点集群为例) 启动 二、部署filebeat 部署filebeat 添加配置文件 启动 三、部署kiban…...

CSDN智能总结助手
github项目地址: https://github.com/anjude/little-demo/tree/master 获取CSDN的user name和user token 打开csdn,打开控制台 - Application - Cookies,找到domain为blog.csdn.net的cookie,复制user_name和user_token的值 把上…...
setImmediate是在当前事件循环的所有周期的末尾执行,还是再当前事件循环的当前周期的下一个周期执行?
实际上,setImmediate 的回调函数会在当前事件循环的当前周期的末尾执行,而不是下一个周期。 在事件循环中,任务分为宏任务(macrotask)和微任务(microtask)。setImmediate 的回调函数属于宏任务…...
建材行业工程设计资质动态核查不通过怎么办
详细了解核查结果:首先,需要仔细阅读核查结果,了解不通过的具体原因。这些原因可能涉及企业基本情况、技术负责人情况、主要人员情况、设备和厂房情况、业绩和信誉等方面。 针对问题制定整改计划:根据核查结果,针对存…...

二叉数之插入操作
首先是题目 给定二叉搜索树(BST)的根节点 root 和要插入树中的值 value ,将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 ,新值和原始二叉搜索树中的任意节点值都不同。 注意,可能存在多种有效…...
【Python】全局变量与init的区别
一个脚本里,设置全局变量,和初始化类时__init__中加载,有什么区别? 在Python脚本中,使用全局变量和在类的__init__方法中加载数据有几个关键区别: 作用域: 全局变量:全局变量在整个…...
JAVA学习-练习试用Java实现“位1的个数”
问题: 编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 1 的个数(也被称为汉明重量)。 提示: 请注意,在某些语言(如…...

第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序
一、开发准备 环境搭建: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 项目创建: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...