区块链 2.0笔记
区块链 2.0
以太坊概述
相对于比特币的几点改进
- 缩短出块时间至10多秒
- ghost共识机制
- mining puzzle
- BTC:计算密集型
- ETH:memory-hard(限制ASIC)
- proof of work->proof of stake
- 对智能合约的支持
- BTC:decentralized currency
- ETH:decentralized contract(去中心化合约) 优势
以太坊账户
比特币是基于交易的账本模式(transaction-based ledger),每笔交易都是由输入和输出构成的。输入引用先前交易的输出,以证明发送者有权使用这些比特币。而输出则指定接收方地址和转移给接收方的比特币数量。因此要想知道余额,要去UTXO找关联账户
举个例子:
假设Alice拥有10个比特币,她想将其中3个比特币发送给Bob。这将产生一笔交易,输入是10个比特币(来自Alice之前的交易输出),输出是3个比特币(给Bob)和7个比特币(返回给Alice自己,因为剩下的比特币必须归还给发送方)。
当这笔交易被确认后,系统中不再存在先前的10个比特币的“账户余额”概念。相反,账本中将存在两个未使用交易输出:一个是给Bob的3个比特币,另一个是给Alice的7个比特币。这些未使用的交易输出可以用于构建下一笔交易。
以太坊系统是基于账户的模型(account-based ledger)
在基于账户的账本模式中,区块链记录着各个账户及其相应的余额。每个账户都有一个地址(类似于银行账户号码)和与之相关的以太币余额。当以太坊网络上发生交易时,涉及的是在不同账户之间转移以太币。
假设账户B想要向账户C发送以太币。一笔交易被创建,指定了发送方(账户B)、接收方(账户C)以及要转移的以太币数量。交易被确认并添加到以太坊区块链的一个区块后,账户余额相应地进行更新。以太币从账户B的余额中减少,同时同样的数量被增加到账户C的余额中。
account based模式的优点
- 符合人的主观感受和现行银行交易类似
- 可以防范double speeding attack
- 高可扩展性:基于账户的模式在处理大量交易时有较好的扩展性。由于不需要跟踪每个交易的UTXO,交易处理速度相对较快,从而提高了整个网络的吞吐量。
account based模式的缺点
1.replay attack(nonce计数器)
- 在账户模式下,需要存储每个账户的余额和状态信息。随着账户数量和交易量的增加,需要更大的存储空间来保存所有账户的信息,这可能会导致存储成本的增加
账户类别
外部账户(externally owned account)
- balance
- nonce
外部账户也被称为EOA账户或用户账户。它们是由用户生成和控制的标准账户,通过私钥和公钥来实现身份认证和交易签名。
- 每个外部账户有一个对应的以太币(ETH)余额,可以发送和接收以太币。
- 外部账户可以用于参与普通的货币交易,例如转账以太币给其他账户。
- 外部账户通过私钥签署交易,然后将交易广播到区块链网络。
Smart contract account(合约账户)
- balance
- nonce(一个合约可以调用另外一个合约,因此通过nonce记录调用的次数)
- code
- storge(调用过程会改变)
合约账户是一种由智能合约代码控制的特殊账户,它们不依赖于私钥和公钥进行身份认证。
- 智能合约是一种以编程方式定义的自动执行的计算机代码,能够根据预设规则和条件执行交易或实现特定功能。
- 智能合约代码被部署到以太坊上,生成一个合约账户,并分配一个以太币余额用于支付交易执行的成本(称为“燃气”费用)。
- 合约账户可以处理复杂的业务逻辑和多方交互,可以实现更为复杂的去中心化应用(DApps)。
智能合约要求有稳定的账户参与
以太坊中的状态树
思路一:使用hash表查询
存在问题:每次出现新交易打包进区块中,从而改变Merkle tree,但事实上只有一部分发生改变,一部分改变要重写整个Merkle tree
(另外由于BTC)
思路二:直接使用Merkle tree存取账户,要改直接改merkle tree,是否可行?
- merkle tree查找效率低
- 不排序,存在的问题:当计算叶节点顺序不能达成一致(BTC的顺序是由拥有铸币权的节点决定的)
如果使用sorted merkle tree呢?
插入账户时,merkle tree的重构代价很大
MTP结构
Trie结构(Trie是一种用于存储和快速检索键值对的树状数据结构,通常用于高效地存储大量的关联数据。)可以类比信号的状态转移
trie结构的特点:
- 打乱顺序,trie结构不变
- 具有很好的更新操作局部性
trie缺点:存储浪费,部分内容效率低(键值的分布稀疏)
Patricia Tree(压缩前缀树)经过了路径压缩的树
树的高度明显减少(如果树的分布很稀疏,较为明显)
disintermediarion(去中介)
为了防止哈希碰撞,所以地址设置为 2 160 2^{160} 2160这么大
Merkle Patricia Tree
把普通指针换成了哈希指针
根节点(Root Node):状态树的根节点是一个哈希值,用于表示整个状态树的当前状态。所有账户状态数据都通过这个根节点的哈希值进行唯一标识。
分支节点(Branch Node):分支节点是状态树中的中间节点,用于连接不同的叶子节点或其他分支节点。每个分支节点有17个子节点,对应了16进制数字0-15和一个特殊节点(NIL节点)。每个子节点保存一个哈希值,指向下一级的分支节点或叶子节点。
叶子节点(Leaf Node):叶子节点包含了账户的具体状态信息。每个叶子节点对应一个账户地址,保存了与该地址相关的账户状态数据,如余额、代码、存储等。
这种状态树的结构使得以太坊能够高效地跟踪和维护账户的状态,同时也有助于实现轻客户端验证和状态证明等功能,从而提高整个网络的可扩展性和安全性。
以太坊实际用的结构是modified MPT
根节点哈希值存在块头
每次发布区块时,状态树中新节点的值会发生改变,这些改变是局部的
共享分支
问题:为什么保留历史状态,不在原先数据上进行修改?
答:为了回滚,在ETH中分叉是常态,orphan block中的数据都要向前一状态回滚,而由于ETH中有智能合约,为了支持智能合约的回滚,必须保持之前的状态
区块头结构
发布的信息
状态树保存的是(key,value),上面讲的都是key保存的地址,那么Value呢?
经过RLP(Recursive Length Prefix)序列化再存储
只做nested array of bytes
区块链的交易树和收据树
状态树:是包含多个区块的状态
交易树和收据树(独立的区块的交易和交易结果)的作用:
-
提供merkle proof
-
支持更复杂的查询操作->e.g.支持查找过去10天和某个智能合约相关的交易
解决方案:引入了bloom filter数据结构(有可能出现false postive(误报),而不会出现false passive(漏报))
bloom filter数据结构
布隆过滤器(Bloom Filter)是一种概率型数据结构,用于快速判断一个元素是否属于某个集合。它可以高效地检索元素,同时占用较少的内存空间。布隆过滤器的主要应用场景是在大规模数据集中进行快速查找和过滤操作。
ETH有关bloom filter的具体操作
每个交易执行完后会形成一个收据,收据中包含一个bloom filter记录这个交易的类型,地址等其他信息
发布的区块在它的块头,也有一个总的blooom filter,这个总的blooom filter,是该区块中所有交易的bloom filter的并集
当我们需要查找过去10天的有关智能合约的所有交易的方法是:
step1:找哪个区块的块头中的bloom filter有我们需要的交易的类型,如果块头中没有,那么这个区块不是我们所需要的区块
step2:如果块头有,就去这个区块查找各个收据的bloom filter,如果有则去确定交易
ETH运行过程:交易驱动的状态机(tx-driven state machine)
Q:现行状态树的机制中,包含全部的账户的信息的状态,可否改成只包含区块中涉及的tx的账户的状态?
- 每个节点所涉及的交易可能会不完整,查找某账号状态不方便
当前状态树的设计保证了每个区块的状态是完整和一致的。如果只包含区块中涉及的交易的账户状态,那么可能会出现信息丢失或不一致的情况,从而导致网络的不安全性。
- 新建账户的查找麻烦,最差得找到genisis block才能发现是新建账户
GHOST协议
分叉在以太坊是常态
ETH将区块生成时间设置为10秒可能带来的危害
但对ETH来说,出块时间太短,如果继续使用最长合法链,对于个人矿工尤其不公平,因为大矿场有能力去制造最长合法链
mining pool
GHOST协议核心:给挖到orphan blocks的节点“安慰奖”
考虑分叉区块:在GHOST协议中,当节点在选择最长链时,不仅考虑最长链上的区块,还会考虑其他分叉区块(即不在最长链上的区块)。具体来说,节点会选择最重的分支链,而不仅仅是最长链。
奖励叔块:在GHOST协议中,叔块(Uncle Block,也称叔节点)是指那些没有被选择为最终区块的分叉区块(最多包含两个Uncle Block)。虽然叔块没有包含在最长链中,但它们也对区块链的安全性和分叉问题有积极的贡献。GHOST协议会对叔块的挖矿者给予一定的奖励,以激励挖矿者选择更广泛的区块,增加网络的整体安全性。
Uncle Block可以一直延续下去,最多能够延续7代奖励
state fork
问题:把uncle block 的tx包括进来,其中的tx是否执行?
答:不执行,交易可能有重复,并且也不检查uncle block的交易的合法性
问题:uncle block 后面还跟着一串怎么办?是否算叔父区块?
ETH实际
可参考 etherscan网站上的tx
以太坊的挖矿算法
Ethash
Block chain is secured by mining
BTC mining饱受争议的地方在于:要用专业的ASIC芯片,这与去中心化理念背道而驰
ASIC resistence一个重要的方法是memory hard mining puzzle
例子:Litecoin(基于Scrypt)
ETH的改进,2种数据集
Ethash是一种重量级的PoW算法,许多最流行的加密货币都加以使用,包括以太坊,以及墨客(MOAC)、Expanse、Pirl等。该算法是不同的,因为它使用的DAG文件,是在矿工启动的那一刻被加载到GPU内存。每30000个区块就会发生一次纪元变化,使得DAG文件增加8MB。
ETHASH改良了Dagger-Hashimoto,有效地解决了单纯内存依赖的算法诸如Scrypt算法加密难与解密同样难的困境,也突破Dagger算法不抵抗内存共享硬件加速的困境,从全区块链数据的生成改为固定的1GB的数据的生成,支持了客户端预生成数据,保障挖矿难度的平滑过度。
16M cache -> 轻节点,便于验证
1G dataset -> 全节点
具体过程
16M cache生成方式与Scrypt类似
step0 计算一个种子(Seed),该种子的计算依赖于当本块及本块之前的所有块。
step1 在数组中首位填入随机数(nonce),之后的数用hash函数算出来,并依次填充cache中的元素(256 bits)
从种子中计算得出一个缓存(Cache),该缓存仅仅由种子得出,是一个16MB大小的数据集。轻客户端应存储下该缓存用于日后验证。
step2 得到256个的hash放入更大的数组当中(1G dataset)
step3 找nonce,通过nonce读取对应位置(以及循环),往复64次,找到128个数,取hash,去解puzzle
挖矿过程即为哈希过程。哈希的输入是取得1GB数据集的128个子部分,并将它们放在一起执行哈希。验证过程是可以在轻客户端通过Cache缓存生成被挖矿制定的数据碎片并执行哈希验证。故而轻客户端并不需要时刻保存1GB的DAG。
伪代码分析
step 1
#step1 生成16Mcache
def mkcache(cache_size,seed):o=[hash(seed)]for i in range(cache_size):o.append(hash(o[-1]))#hash函数 o[-1]是上一个hash值return o
step 2
#step2 通过cache生成dataset中的第i个数据
def calc_dataset_item(cache,i):cache_size=cache.size#cache的大小mix=hash(cache[i%cache_size]^i)#cache[i%cache_size]^i是一个随机数for j in range(256):cache_index=get_int_from_item(mix)mix=make_item(mix,cache[cache_index%cache_size])return hash(mix)
step 3多次调用这个函数,得到完整的dataset
puzzle算法实现
为什么矿工要保存所有的dataset,而情节点只需要保存cache?
以太坊总供应量
https://etherscan.io/stat/supply
以太坊挖矿难度调整
ETH的挖矿难度调整操作很多有出入,因此这里以官方代码为主
PART 1:主公式
PART 2
参数说明: x x x是调整的单位, ζ 2 \zeta_{2} ζ2为调整的系数
H s H_s Hs是当前的时间戳, P ( H ) H S P(H)_{H_S} P(H)HS是父区块的时间戳,两者时间差为出块间隔
PART 3
参数说明
权益证明
POW饱受批评的一点在于浪费资源
问题:挖矿消耗的能耗是否是必须得
挖矿的本质:大家比拼算力,算力越大,挖矿机率越高,因此本质为:投入的钱越多,挖矿机率越高
POS核心思想:直接拼钱->virtual mining
POS vs. POW优点:
- 节能
- POS是闭环生态,而POW是开放生态,因此POS天然防止51% attack(attacker必须购买足够多的加密货币(成为股东或者获取更多的投票权),才有发动attack的能力,但此时,对于币的开发者和早期矿工是受益的,如同恶意收购)
noting at state:当出现下述分叉时,pow会选择一条链,而POS下两条链都可以下注(且没有损失)
ETH准备采用的POS协议是Casper the Friendly Finality Gadget(FFG)
引入了:验证者validator->投入一定数量的保证金
每挖出100个区块生成一个epoch,然后开始投票(two-phase commit)
投票中需要有两轮投票(都要达到 2 3 \frac{2}{3} 32)
每个epoch只投票一次(validator投票)
对于validator来说,积极参与投票有奖励,行政不作为则会受到处罚(扣保证金)
而对于两边下注的行为,没收全部保证金
以太坊虚拟机
在以太坊上最重要的活动除了转账以外,就是编译、运行智能合约(Smart Contract)。
智能合约代表了一个以太坊世界里的独立管家。它按照自身代码指示进行以太币的收入,支出活动,也具有一定存储空间可以存储一些数据。
以太坊虚拟机执行分为两大类,只读操作和写操作。 仅获取区块链状态的操作为只读操作。
只读操作并不修改区块链状态,在链式调用合约的时候也不会触发任何状态变更,所以较为迅速。
写操作则会改变区块链的状态。例如一个更改账户状态的操作。
写操作则是需要花费以太币的操作,因为它更改了某一个或者数个账户的存储空间。 存储空间是区块链的一部分,是要被全世界的计算机永久同步存储的,这个更改的过程代价昂贵: 例如将一个值从 0
变为非零值需要耗费 20000
单位的gas;修改一个 非0
值需要消耗 5000
单位gas; 将一个值从 非0
赋值为 0
可以回收 15000
单位的gas;读取一个变量值需要 200
gas。而相对比,从内存中读取变量值仅需 3
gas。
以太坊的虚拟机不包含正常CPU所具备的硬件寄存器, 它的执行宽度都是 256bit 的固定长度值,所以相对比较容易编程,它包含了存储、堆栈、内存三大存储机构。
Storage存储
存储里的值都是永久记录在区块链上的。存储在写和读取上都代价昂贵,如非必须,则数据不要存储在存储区。
存储区的读写操作都是以 256bit 为单位的,没有更小的操作空间。故而 uint8 和 uint256 在单值存储的情况下占用的空间相同,耗费的 Gas 也相同。 将 unit8 包裹进入 struct 结构体以后可以通过优化来节约空间位置,节省gas支出。
Stack堆栈
堆栈有且仅有 1024 层深度,当我们执行递归调用过多的时候,堆栈就会击穿 1024 层,则代码执行失败。
堆栈仅有高处的 16 层是可以被快速访问的,堆栈的宽度也是 256bit,也就是 32byte,一个 word 的长度,任何读写操作都是 256bit 为一个单位进行的。 编译器往往会将代码执行中的临时变量、变量地址放到堆栈上临时保存,变量地址可以进一步索引到内存 Memory 中。
Memory 内存
虚拟机的输入输出
Gas花费
发送交易的时候我们可以指定 gas 的花费上限,以防止智能合约代码有bug而导致无限循环执行下去。
一旦 gas 过早耗尽,则虚拟机抛出异常,结束代码执行。
有一类情况很特殊,就是Solidity智能合约代码的 assert()
函数与 require()
函数。
在执行时候这两个函数都是做真假条件判断的,但是 assert 函数感情更加强烈,往往判断的都是关键的安全性条件,例如 SafeMath 中利用 assert 函数判断是否位数溢出; 合约取款时判断调用方是否为合约所有者等。
require()函数则较为普通的条件判断,例如判断合约调用者的余额是否足够等。
assert() 函数判断一旦失败,则会扣完剩下所有的 gas 作为惩罚措施; require() 判断失败则仅仅停止目前的执行,收取执行到当前步骤相应的 gas 费用,再撤销发生的变更。
虚拟机指令集
EVM执行的是字节码。由于操作码被限制在一个字节以内,所以EVM指令集最多只能容纳256条指令。
mem[a…b] 表示内存中a到b(不包含b)个字节
storage[p] 表示从p开始的32个字节
谨记evm虚拟机的word(字)是256位32字节
智能合约
什么是智能合约?
智能合约是运行在区块链上的一段代码,代码的逻辑定义了合约的内容
智能合约的帐户保存了合约当前的运行状态
- balance:当前余额
- nonce:交易次数
- code:合约代码
- storage:存储,数据结构是一棵MPT
- Solidity是智能合约最常用的语言,语法上与JavaScript很接近
以太坊中凡是需要接受外部转账的函数都需要标记为payable
solidity语言不支持hash表的遍历
bidders.push(bidder)//添加竞拍人
bidders.length//大小
调用智能合约
创建一个交易,接收地址为要调用的那个智能合约的地址,data域填写要调用的函数及其参数的编码值。
1.直接调用
3.代理调用
代理调用delegatecall()
使用方法与call()相同,只是不能使用.value()
区别在于是否切换上下文
- call0切换到被调用的智能合约上下文中
- delegatecall()只使用给定地址的代码,其它属性(存储,余额等)都取自当前合约。delegatecall的目的是使用存储在另外一个合约中的库代码。
fallback()函数
function()public [payable]{
......
}
- 匿名函数,没有参数也没有返回值。
- 在两种情况下会被调用:
- 直接向一个合约地址转账而不加任何data
- 被调用的函数不存在
- 如果转账金额不是0,同样需要声明payable,否则会抛出异常。
智能合约的创建和运行
- 智能合约的代码写完后,要编译成bytecode
- 创建合约:外部帐户发起一个转账交易到0x0的地址
- 转账的金额是0,但是要支付汽油费
- 合约的代码放在data域里
- 智能合约运行在EVM(Ethereum Virtual Machine)上
以太坊是一个交易驱动的状态机- 调用智能合约的交易发布到区块链上后,每个矿工都会执行这
个交易,从当前状态确定性地转移到下一个状态
- 调用智能合约的交易发布到区块链上后,每个矿工都会执行这
Gas fee
ETH的错误处理
ETH交易具有原子性,即一个交易要么不执行,要么全执行,不会执行一部分
-
智能合约不存在自定义的try-catch结构
-
一旦遇到异常,除特殊情况外,本次执行操作全部回滚
-
可以抛出错误的语句
-
assert(bool condition)
:如果条件不满足就抛出——用于内部错误。 -
require(bool condition)
:如果条件不满足就抛掉——用于输入或者外部组件引起的错误。Function bid()pubiie payable{ //拍卖未结束 require(now <=auctionEnd); }
-
revert()
:终止运行并回滚状态变动(无条件)
-
嵌套调用
Block header
汽油费的扣除机制
- ETH的三棵树都是在本地维护的数据结构
- 全节点收到对智能合约的调用,在本地账户扣除余额
- 然后将取得记账权的节点发布区块,将它本地维护的三棵树上传到区块链
ETH挖矿过程
- 全节点打包交易,执行对智能合约的调用,调整智能合约的内容
- 求得3棵树的根哈希值
- 试nonce,取得记账权,发布区块
- 别的没有取得记账权的区块,要独立验证新发布区块及其包含的tx和智能合约的合法性
应该先执行再挖矿(需要先算三棵树的hash再写进区块中)
如果不验证,无法更新本地三棵树的Hash值,无法发布正确的三棵树信息,无法挖矿
Receipt
问题:智能合约是否支持多线程?
不支持,状态机必须是完全确定,而多线程如果对内存访问顺序不同,造成的结果可能也会不同
出了多线程,“产生随机数”
智能合约可以获得的区块信息
block.blockhash(unint blockNumber) returns (bytes)
给定区块的哈希-仅对最近的256个区块有效而不包括当前区块
block.coinbase(address)
挖出当前区块的矿工地址
block.difficulty(uint)
当前区块难度
block.gaslimit(uint)
:当前区块gas限额
block.number(uint)
:当前区块号
block.timestamp(uint)
:自unix epoch起始当前区块以秒计的时间戳
智能合约可以获得的调用信息
msg.data(bytes)
:完整的calldata
msg.gas(uint)
:剩余gas
msg.sender(address)
:消息发送者(当前调用)
msg.sig(bytes4)
:calldata的前4字节(也就是函数标识符)
msg.value(uint)
:上随消息发送的wei的数量
now(uint)
:目前区块时间戳(block.timestamp)
tx.gasprice(uint)
:上交易的gas价格
tx.origin(address)
:上交易发起者(完全的调用链)
地址类型
<address>.balance(uint256)
以Wei为单位的地址类型的余额。
<address>.transfer(uint256 amount)
:
向地址类型发送数量为amount的Wei,失败时抛出异常,发送2300(转入账户的地址)gas的矿工费,不可调节。
<address>.send(uint256 amount)returns(bool)
:
向地址类型发送数量为amount的Wei,失败时返回false,发送2300gas的矿工费用,不可调节。
<address>.call(...)returns (bool)
:
发出底层CALL,失败时返回false,发送所有可用gas,不可调节。
<address>.callcode(...)returns(bool)
日
发出底层CALLCODE,失败时返回false,发送所有可用gas,不可调节。
<address>.delegatecall(...)returns (bool)
:
发出底层DELEGATECALL,失败时返回false,发送所有可用gas,不可调节。
所有智能合约均可显式地转换成地址类型
三种发送ETH的方式
<address>.transfer(uint256 amount)
<address>.send(uint256 amount)returns (bool)
<address>.call.value(uint256 amount)()
简单案例
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;contract SimpleAuction {// 拍卖的受益人address payable public beneficiary;// 最高出价者address public highestBidder;// 最高出价uint public highestBid;// 拍卖结束时间uint public auctionEndTime;// 竞标是否已结束bool public ended;// 变更出价时触发的事件event HighestBidIncreased(address bidder, uint amount);// 拍卖结束时触发的事件event AuctionEnded(address winner, uint amount);// 构造函数,设置受益人和拍卖结束时间constructor(uint _biddingTime, address payable _beneficiary) {beneficiary = _beneficiary;auctionEndTime = block.timestamp + _biddingTime;}// 竞标函数function bid() public payable {require(block.timestamp <= auctionEndTime, "拍卖已结束");require(msg.value > highestBid, "已存在更高出价");if (highestBid != 0) {// 返还之前最高出价者的金额address payable previousBidder = payable(highestBidder);previousBidder.transfer(highestBid);}highestBidder = msg.sender;highestBid = msg.value;emit HighestBidIncreased(msg.sender, msg.value);}// 结束拍卖函数,只有受益人可以调用function auctionEnd() public {require(block.timestamp >= auctionEndTime, "拍卖尚未结束");require(!ended, "拍卖已结束");ended = true;emit AuctionEnded(highestBidder, highestBid);// 将最高出价转给受益人beneficiary.transfer(highestBid);}
}
参考文献
ETHASH 挖矿算法 — 以太坊的指南针 1.0.0 documentation (abyteahead.com)
虚拟机的执行资源 — 以太坊的指南针 1.0.0 documentation (abyteahead.com)
相关文章:
![](https://img-blog.csdnimg.cn/61632a02f5484c33bc6a12e221026f1f.png)
区块链 2.0笔记
区块链 2.0 以太坊概述 相对于比特币的几点改进 缩短出块时间至10多秒ghost共识机制mining puzzle BTC:计算密集型ETH:memory-hard(限制ASIC) proof of work->proof of stake对智能合约的支持 BTC:decentralized currencyETH:decentral…...
![](https://img-blog.csdnimg.cn/6e29286affb94acfb6308b1583f4da53.webp)
深入理解Vue响应式系统:数据绑定探索
🌷🍁 博主猫头虎 带您 Go to New World.✨🍁 🦄 博客首页——猫头虎的博客🎐 🐳《面试题大全专栏》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 &a…...
![](https://img-blog.csdnimg.cn/8e61b0b48dc148efb079035031dfed2c.jpg)
web流程自动化详解
今天给大家带来Selenium的相关解释操作 一、Selenium Selenium是一个用于自动化Web浏览器操作的开源工具和框架。它提供了一组API(应用程序接口),可以让开发人员使用多种编程语言(如Java、Python、C#等)编写测试脚本&…...
![](https://img-blog.csdnimg.cn/65e9ee3ba68d40449907a2e44308595f.png)
什么是框架?为什么要学框架?
一、什么是框架 框架是整个或部分应用的可重用设计,是可定制化的应用骨架。它可以帮开发人员简化开发过程,提高开发效率。 项目里有一部分代码:和业务无关,而又不得不写的代码>框架 项目里剩下的部分代码:实现业务…...
![](https://www.ngui.cc/images/no-images.jpg)
什么是 Sass?
Sass 介绍 什么是 Sass? 官方标语 世界上最成熟、最稳定、最强大的专业级 CSS 扩展语言。怎么理解这句话呢?我们平时写的 CSS 代码可以理解为静态样式语言,而 Scss 就是动态样式语言,何为动态?就是让你写 CSS 跟写 …...
![](https://img-blog.csdnimg.cn/fc5b35303fa04150b483aa7b7e6e9c9a.png#pic_center)
Kotlin~Memento备忘录模式
概念 备忘录模式是一种行为型设计模式,用于捕获和存储对象的内部状态,并在需要时将对象恢复到之前的状态。 备忘录模式允许在不暴露对象内部实现细节的情况下,对对象进行状态的保存和恢复。 角色介绍 Originator:原发器&#x…...
![](https://img-blog.csdnimg.cn/a19cf3bfa88e487bb085c66de6931203.png)
单链表的多语言表达:C++、Java、Python、Go、Rust
单链表 是一种链式数据结构,由一个头节点和一些指向下一个节点的指针组成。每个节点包含一个数据元素和指向下一个节点的指针。头节点没有数据,只用于表示链表的开始位置。 单链表的主要操作包括: 添加元素:在链表的头部添加新…...
![](https://www.ngui.cc/images/no-images.jpg)
微信小程序 background-image直接设置本地图片路径,编辑器正常显示,真机运行不显示解决方法
项目场景 微信小程序,设置background-image直接设置本地图片路径。 问题描述 编辑器正常显示,真机运行不显示 原因分析 background-image只能用网络url或者base64图片编码。 解决方案 1、将本地图片转为网络url后设置到background-image上 例如&…...
![](https://img-blog.csdnimg.cn/e7e5326423f4464b949165be43d5d940.png)
SQLite Studio 连接 SQLite数据库
1、在SQLite中创建数据库和表 1.1、按WINR,打开控制台,然后把指引到我们的SQLite的安装路径,输入D:,切换到D盘,cd 地址,切换到具体文件夹,输入“sqlite3”,启动服务 1.2、创建数据库…...
![](https://img-blog.csdnimg.cn/img_convert/082528a76b632fb017b38ab9aade2443.png)
【业务功能篇58】Springboot + Spring Security 权限管理 【中篇】
4.2.3 认证 4.2.3.1 什么是认证(Authentication) 通俗地讲就是验证当前用户的身份,证明“你是你自己”(比如:你每天上下班打卡,都需要通过指纹打卡,当你的指纹和系统里录入的指纹相匹配时&…...
![](https://img-blog.csdnimg.cn/c6046c1b93ff4e02b73c56511b451271.png)
Docker挂载目录失败问题解决
天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。…...
![](https://www.ngui.cc/images/no-images.jpg)
css中隐藏页面中某一个元素有什么方法?
我们可以使用css的z-index属性,将元素的-index去给它设置一个负值,使它隐藏在其他元素的后面。使用css样式进行隐藏我们可以使用display这个属性。(1)使用display:none完全进行隐藏元素,并且不占据空间也不会影响页面布…...
![](https://www.ngui.cc/images/no-images.jpg)
Unity 多语言问题C#篇
DateTime.ToString()不同语言环境问题 问题描述:PlayerPrefs.SetString("timeKey", DateTime.Now.ToString());切换系统语言后DateTime.Parse(PlayerPrefs.GetString("timeKey"));报错FormatException: String was not recognized as a valid D…...
![](https://img-blog.csdnimg.cn/935070c2f0a54663baab64cff75b5495.png)
深度学习和神经网络
人工神经网络分为两个阶段: 1 :接收来自其他n个神经元传递过来的信号,这些输入信号通过与相应的权重进行 加权求和传递给下个阶段。(预激活阶段) 2:把预激活的加权结果传递给激活函数 sum :加权 f:激活…...
![](https://www.ngui.cc/images/no-images.jpg)
在CSDN学Golang云原生(Kubernetes Volume)
一,Volume 与 configMap Kubernetes 中的 Volume 和 ConfigMap 都是 Kubernetes 中常用的资源对象。它们可以为容器提供持久化存储和配置文件等。 Volume 可以将容器内部的文件系统挂载到宿主机上,也可以将多个容器间共享一个 Volume,并且 …...
![](https://www.ngui.cc/images/no-images.jpg)
第十五章 友元 异常和其他
RTTI RTTI是什么 RTTI是运行阶段类型识别,通过运行时类型识别,程序能够使用基类的指针或者引用来检查这些指针或者引用所指向的对象的实际派生类型。 RTTI的三个元素 dynamic_cast运算符 dynamic_cast概念: dynamic_cast运算符能够将基…...
![](https://img-blog.csdnimg.cn/31c6128b2f15480b9da46fa7e60bb3e2.png)
制作DBC文件
DBC文件是CAN通讯的密码本,Matlab的SimuLink中常用DBC作为CAN通讯的解析桥梁 制作DBC文件,内容是转速、位置&…...
![](https://img-blog.csdnimg.cn/f8174c4af80b4c5394c93421f7231a96.png)
【1.1】Java微服务:初识微服务
✅作者简介:大家好,我是 Meteors., 向往着更加简洁高效的代码写法与编程方式,持续分享Java技术内容。 🍎个人主页:Meteors.的博客 💞当前专栏: 微服务 ✨特色专栏: 知识分享 &#x…...
![](https://img-blog.csdnimg.cn/9c8cc90b0b904c108a74132ea2ffd216.png#pic_center)
数据结构--串、数组、广义表
这里写目录标题 串定义案例引用串的类型定义以及存储结构抽象类型定义存储结构(顺序表较为常用)顺序存储结构链式存储结构 串的模式匹配算法(查找主串中是否有某个字串)BF算法KMP算法设计思想对字串的回溯进行了优化代码对next【j】进行优化 数组类型一维…...
![](https://www.ngui.cc/images/no-images.jpg)
白银挑战——链表高频面试算法题
算法通关村第一关–链表白银挑战笔记 开始时间:2023年7月18日14:39:36 链表 Java中定义一个链表 class ListNode {public int val;public ListNode next;ListNode(int x) {val x;next null;}}1、四种方法解决两个链表第一个公共子节点 解释一下什么是公共节点 如…...
![](https://www.ngui.cc/images/no-images.jpg)
海外腾讯云账号:腾讯云高性能计算平台 THPC
高性能计算平台(TencentCloud High Performance Computing,THPC)是一款腾讯云自研的高性能计算资源管理服务,集成腾讯云上的计算、存储、网络等产品资源,并整合 HPC 专用作业管理调度、集群管理等软件,向用…...
![](https://img-blog.csdnimg.cn/983b84c0c5964ef89395ac81bc5743de.png)
eclipse 最新版没有navigator视图如何解决
使用project exploere视图可以显示类似navigator视图 1.显示project exploere视图 window---->show view --->project exploere 2.project exploere视图转换为类似navigator视图 第一步:点击视图右上角三个点或者倒三角,点击fiters and custom…...
![](https://img-blog.csdnimg.cn/2dc2bac6353041e480fc0f1266a85df2.jpeg)
Zynq-Linux移植学习笔记之62- PL挂载复旦微flash
1、背景介绍 现在为了全国产化需要,之前所有的进口flash全部要换成国产flash 2、复旦微flash型号 其中EFM25QU256和EFM25QL256对标winbond的w25q256 nor flash 3、FPGA设置 复旦微flash只支持单线模式,当使用PL侧的IP核访问时,需要设置模式…...
![](https://img-blog.csdnimg.cn/b843ae0ba80d475caabba5ff730e7450.png)
SpringBoot复习:(2)Tomcat容器是怎么启动的?
SpringApplication的run方法包含如下代码: 其中调用的refreshContext代码如下: 其中调用的refresh方法片段如下: 其中调用的refresh方法代码如下: 其中调用的super.refresh方法代码如下: public void refresh() th…...
![](https://www.ngui.cc/images/no-images.jpg)
1 MobileHomeTopicApplication
目录 1 OrderApplication 1.1 引用文件 1.2 #region 字段 1.3 #region 属性 OrderApplication 引用文件using System; using...
![](https://img-blog.csdnimg.cn/43769b297ab44b57af96afeb7d5b2ce8.png)
mpi4py包安装报错
报错情况 #include <mpi.h>^~~~~~~compilation terminated.failure.removing: _configtest.c _configtest.oerror: Cannot compile MPI programs. Check your configuration!!![end of output]note: This error originates from a subprocess, and is likely not a probl…...
![](https://www.ngui.cc/images/no-images.jpg)
C语言进阶-1
1、数据类型 1.1、基本数据类型 数据类型分2类:基本数据类型复合类型 基本类型:char short int long float double 复合类型:数组 结构体 共用体 类(C语言没有类,C有) 1.1.1、内存占用与sizeof运算符 数据…...
![](https://www.ngui.cc/images/no-images.jpg)
Python如何正确解决爬虫过程中的Cookie失效问题?
前言 本文是该专栏的第54篇,后面会持续分享python爬虫干货知识,记得关注。 在python爬虫项目中,Cookie是一种用于在客户端和服务器之间传递信息的技术。在爬取某些网站的时候,可能会需要登录才能正常获取到数据,这个时候就需要用到cookie来解决。通常情况下,需要将cooki…...
![](https://www.ngui.cc/images/no-images.jpg)
维护自己电脑浅析
作为一名计算机用户,维护自己的电脑是非常重要的,这可以保证电脑的正常运行、数据的安全、提高电脑的性能等。在本文中,我将分享一些我个人维护电脑的经验和技巧。 定期清理电脑 电脑在使用过程中会产生大量的临时文件、垃圾文件、缓存文件等…...
![](https://img-blog.csdnimg.cn/8c7914a43ed1475daeb5487c0785ca05.png)
svo2论文
论文题目 SVO: Semidirect Visual Odometry for Monocular and Multicamera Systems 内容 1) 具有最小特征漂移的长特征轨迹; 2) 图像平面中的大量均匀分布的特征; 3)新特征与旧地标的可靠关联(即环路闭…...
![](https://s1.51cto.com/attachment/201303/172030379.png)
泉州哪里做网站/营销推广
* 注册表被修改,登录回话程序没有启动 每个用户在登录Windows系统的时候,操作系统里的登录程序userinit.exe会被启动,用户注销退出后该程序会停止工作。由于View采用sso登录系统后,也需要一个类似的程序帮助处理登录Windows系统并…...
![](/images/no-images.jpg)
自己建设网站多少钱/seo综合查询工具可以查看哪些数据
查看事务日志:工具如下:Lumigent Log Explorer for SQL Server (商业)SQL Log Rescue ---red-gate公司(Free) 处理事务日志超载问题:/**//*方法一: 使用分离与附加数据库方式.*/DECLARE DBName VARCHAR(50)SET DBNamedb_name--step 1: 分离…...
![](/images/no-images.jpg)
做a短视频网站/淄博网站优化
//这么写才能被正确渲染 <textarea></textarea> //这样就会有空格 <textarea> </textarea> 不能换行,涨姿势转载于:https://www.cnblogs.com/liyinSakura/p/5755560.html...
![](/images/no-images.jpg)
长春做网站的公司哪家好/怎么自己做一个网页
题目链接 题意:给你n个价格范围l,r,问最后没组价格的上下浮动能不能不超过k 思路:要让价格不超过k,设i的价格范围为L,R那么不超过k那么i1的价格范围就在L-k,Rk这个范围内,为了时他…...
![](/images/no-images.jpg)
哈尔滨网站建设美丽/c++培训班学费一般多少
树莓派官方系统默认不启用SSH,本教程将介绍几种开启SSH的方法:[TOC]## **方法一**:使用树莓派系统配置命令开启在树莓派上打开终端(快捷键打开:CTRLALTT)输入命令:raspi-config(回车)![](http://qiniucn.16302.com/85d…...
![](/images/no-images.jpg)
虚拟主机空间发布网站/win10优化大师怎么样
本文对于RCU的概念不进行解释。 考虑一种比较让人困惑的情形,就是在grace period期间,有新的读者进入,那么这个读者拿到的是新数据还是旧数据,查阅了很多资料都没找到答案,当然对于链表的情况这个很好理解,…...