《Ubuntu20.04环境下的ROS进阶学习0》

一、逛ROS应用商店 在上一专栏http://t.csdnimg.cn/oGlcu,我们了解了ROS的基本功能。这一专栏将会在此基础上做出进一步拓展学习。那么首先我们要学会下载并阅读别人的代码。常用的两个应用商店一个是ROS的官方应用商店ROS index,另一个就是我们熟知的github了。走,去逛逛。 二、ROS官方应用商店 这里我们先打开浏览器输入网址 https://index.ros.org/ (maybe需要加速器)这里就是ROS的官方应用商店。 1、选择package 2、选择自己的版本 可以看到这里有更新的日期,软件包的名称和软件包的描述。我们在之后下载这些package的时候一般是根据名称。使用sudo apt install ros-ROS版本名称-name。 3、查看软件包详细信息 在搜索栏搜索rqt_robot_steering,点击对应版本的name可以打开详细页面。 左边Package Summary是版本号,开源协议,编译工具等信息等。 左边Repository Summary是软件包的源码信息 右边Pcakage Descirption是软件包的简介,以及拓展链接,当前维护者和原作者。其中Website是包含了这个软件包细节的页面,您可以点开看看。 当您点开了Website拓展链接时,您将会看到界面截图和软件包的使用案例等详细细节。 4、下载软件包实施效果 打开终端输入: sudo apt-get install ros-noetic-rqt-robot-steering (嘶~,这里和上面略有不同的点在于,我们将name中的_全部改为了- ) 下载完成后就可以试试这个软件的效果,打开n个终端: 第一个终端输入: roscore 第二个终端输入: rosrun turtlesim turtlesim_node 第三个终端输入: rosrun rqt_robot_steering rqt_robot_steering 这时候会有弹窗,您可以将纵向的速度和横向的角速度做少量修改,并且将上面的topic修改成 /turtle1/cmd_vel 这时您会发现您的海龟开始运动。 三、开源网站github 这里我们先打开浏览器输入网址 https://github.com/ (maybe需要加速器)这里就是最大的开源网站了。想要使用上面的开源代码,我们先要做一下准备工作。 1、创建工作空间 cd ~ mkdir catkin_ws cd catkin_ws mkdir src cd src catkin_init_workspace 这里如果您看过我之前的文章《Ubuntu20.04环境下的ROS学习笔记3》-CSDN博客您应该已经完成了这一步。 2、下载git sudo apt install git ​ 3、下载一个源码 在搜索栏输入wpr_simulation

java设计模式

简单工厂模式 父类调用抽象方法,根据传参不同,调用的子类对象不同,实现不同的折扣计算 策略模式 策略模式:对象的行为模式抽象,将算法封装起来,将使用算法与实现算法解耦,委派给不同对象对算法进行管理 单例模式 单例模式:内存中只有一个实例,减少内存开销,设置全局的getInstance方法共享资源,跨线程使用; 应用场景: 1.频繁创建类用单例减少内存和GC, 2.需求上只需要生成一次 3.类创建占用资源多时间长,且不怎么会改变的类 懒汉式 饿汉式 代理模式 代理模式:一个用户不想直接访问某个对象,找中介代理,(比如买火车票用12306,找工作boss,找家政等平台代理,开发中避免用户直接访问服务器用nginx代理); 优点:中介可以保护目标对象,扩展程序方便,可以在代理类访问对象并在前后做处理 原型模式 原型模式:把一个已经创建好的实例作为原型,复制原型作为一个新的对象,高效,无需关系创建细节,优点:克隆接口是基于二进制流的方式,性能高,深克隆可以将对象的状态也保存下来,减少对象创建;缺点:每个对象都要实现克隆方接口,深克隆可能存在多个对象嵌套引用,比较麻烦 适配器模式 适配器模式:将一个类的接口转换成客户希望的另一个接口,让原本不兼容的类,接口一起工作,有类适配器和对象适配器,一般使用对象适配器,类适配器耦合度很高。 优点:通过适配器透明调用接口,代码复用 缺点:代码需要结合业务,复杂性高,可读性低。例子:充电口协议标准各个国家不同,需要用转换器或者适配器完成充电 装饰性模式 装饰性模式:扩展类用组合的方式创建修饰对象包裹真实对象,在保证真实对象不变的前提下,增加额外的功能。 优点:动态扩展类的功能,装饰排列组合能实现不同的效果,遵守开闭原则, 缺点:有很多子类,增加程序的复杂性 桥接模式 桥接模式:将抽象与实现分离,用组合代替继承关系。 优点:扩展性强,符合开闭原则,合成复用原则,对用户透明 缺点:建立在抽象层,需要对需求理解设计强 外观模式 外观模式:为子系统中的一组接口提供一个统一的入口,定义一个高层接口,使得访问子系统更加容易。 优点:降低子系统和客户端的耦合度,读用户透明,为用户屏蔽了子系统的组件,降低编译的依赖jar包; 缺点:设计不合理时可能违反开闭原则 享元模式 享元模式:缓存共享降低内存损耗, 优点:相同对象只要保存一份,降低系统对象数量,减少内存压力; 缺点:读取享元外部状态响应时间长 组合模式 组合模式:组合多个对象形成一个树形结构以表示整体一部分关系的层次结构,组合模式对单个对象(叶子结点),组合对象(容器对象)使用具有一致性。 优点:1.客户端代码能一致处理单个对象或者组合对象,能在组合的树上加新对象,符合开闭原则; 缺点:设计复制要理清层次关系 模板方法模式 模板方法:行为设计模式,定义了一个算法步骤,允许一个子类别为一个或多个步骤提供实现方法。 优点:父类封装了不变的部分,子类扩展可变的部分,代码复用强,符合开闭原则; 缺点:每个不同的实现都要定义一个子类,性能比较低,子类的结果会影响到父类,代码可读性差,如果新家父类抽象方法,子类都要改动 命令模式 命令模式:将请求与处理解耦,将请求封装成一个对象,让发出请求的责任与处理请求的责任分割,二者都能通过命令对象沟通,传递和调用。 优点:降低耦合,扩展性好,增加删除命令方便,不影响其天类; 缺点:会产生大量的命令类,增加系统的复杂度 责任链模式 解耦请求和处理,将节点的处理者组成了一个链式结构,每个处理节点判断自己能否处理,可以的话自己处理,处理不了的传递给下一个节点,让请求流动起来。 优点:降低对象的耦合度,扩展性强,可以增加处理节点,增强对象指派责任的灵活性,简化对象的链接,符合单一职责原则; 缺点:不能保证每个请求都会被处理,如果责任链很长,系统的处理性能会变差 状态模式 状态模式:控制对象状态转换的时候,将判断逻辑拿出来用不同的类去表示,代替if-else,switch-case. 优点:将不同的状态分隔开,满足单一职责原则,将状态转换显示化,减少对象的相互依赖,利用新状态扩展; 缺点:代码复杂相对if-else,新增状态会修改负责状态转换的源码,违背了开闭原则 观察者模式 观察者模式:多个对象存在一对多的依赖关系,如果其一个发生了变化,其他依赖此对象的会被告知然后更新,类似于发布订阅者模型。 优点:降低目标和观察者的耦合,观察者和目标之间有触发机制,发一条通知,订阅者就会收到通知; 缺点:可能导致循环引用,观察者多的话影响效率 中介者模式 中介者模式:定义一个中介对象封装对象的行为交互, 优点:各司其职,降低对象耦合度,对象一对一关联,提高系统灵活性; 缺点:一个类与多个类直接依赖,变成与对象一对一依赖,类多的话中介类会很臃肿 迭代器模式 迭代器模式:提供一个对象顺序访问聚合对象里面的数据。 优点:简化聚合类,遍历任务由迭代器完成,支持不同方式遍历聚合对象,访问聚合对象内容不会暴露内部表达式; 缺点:增加类的个数,增加代码的复杂性

序列化的简要理解

1)什么是序列化 序列化就是把内存中的对象,转换成字节序列(或其他数据传输协议)以便于存储到磁 盘(持久化)和网络传输。 反序列化就是将收到字节序列(或其他数据传输协议)或者是磁盘的持久化数据,转换 成内存中的对象。 2)为什么要序列化 一般来说,“活的”对象只生存在内存里,关机断电就没有了。而且“活的”对象只能 由本地的进程使用,不能被发送到网络上的另外一台计算机。 然而序列化可以存储“活的” 对象,可以将“活的”对象发送到远程计算机。

【代码随想录python笔记整理】第十七课 · 判断集合成员

前言:本笔记仅仅只是对内容的整理和自行消化,并不是完整内容,如有侵权,联系立删。 一、集合 在之前提到,哈希表主要是用来判断给定的整数是否存在于给定的数据中。而在上一节中我们使用了数组,通过索引来实现哈希表的功能。这一节我们主要学习集合的相关操作。 集合 set 也是一种数据结构,和数学中的集合类似,它用于存储一组不重复的元素,并且不保证集合中元素的顺序。在 Python 中,可以使用 { } 来创建集合,元素与元素之间使用逗号分隔。或者也可以使用 set ( ) 函数创建集合,或者是列表转为集合。 # 创建集合 my_set = {1,2,3} # 使用 set() 创建空集合 my_set2 = set() # 列表转集合 my_set3 = set([1,2,3]) 在集合的操作中,最常见的是判断某个元素是否在集合中和去除列表中的重复元素。判断某个元素是否在集合中,我们可以采用关键字 in 。而去除重复元素,我们可以先将列表转换为集合,再将集合转换为列表,中间过程去除了重复元素。 set_1 = {1,2,3} # 判断元素是否在集合中 if 1 in set_1: print("True!") # 去除重复元素 list_1 = [1,1,2,3,4,4,5,5,6] set_2 = set(list_1) # 将列表转换为集合 list_2 = list(set_2) # 将集合转换为列表 类似于数学中的操作,集合还支持求并集、交集、差集。 set1 = {1, 2, 3} set2 = {3, 4, 5} u_set = set1 | set2 # 并集,现在集合是{1, 2, 3, 4, 5} i_set = set1 & set2 # 交集, 现在集合是 {3} d_set = set1 - set2 # 差集, 表示存在于集合1中,但不存在于集合2中的元素,{1, 2} 二、集合中的常用方法 在集合中,我们还有一些常用的方法,下面我们一个一个解释。我们以集合 {1,2,3} 为初始集合,依次来看一下进行相应操作后的输出结果。

Android JNI 普通方法和静态方法详解

Android JNI 普通方法和静态方法详解 文章目录 Android JNI 普通方法和静态方法详解一、前言二、Android JNI 普通方法和静态方法1、native 的静态方法和普通方法(1) JNI定义nativie普通方法和静态方法(2)jni native-lib.cpp中的代码:(3)调用JNI方法的代码Java中的普通方法和静态方法有以下区别: 2、cpp调用Java普通方法和静态方法区别(1) Java定义普通方法和静态方法(2)jni native-lib.cpp中的代码:(3)调用JNI方法的代码 三、其他1、Android JNI 普通方法和静态方法小结2、Android Jni的介绍和简单Demo实现3、 Android JNI复杂用法,回调,C++中调用Java方法 共勉: 今天很残酷,明天更残酷,后天很美好 ... 一、前言 Android Jni中Java的静态方法和普通方法有什么区别? 很多人可能都不清楚,如果想知道的可以了解一下。 比如下面一段代码: //1、native 的静态方法和普通方法 public native void normalNativeMethod(); // 声明普通native方法 public static native void staticNativeMethod(); // 声明静态native方法 //2、Java 的普通方法和静态方法,C++调用过来的处理区别? // 普通方法 public void normalMethod() { System.out.println("这是一个普通方法"); } // 静态方法 public static void staticMethod() { System.out.println("这是一个静态方法"); } JNI的静态方法包含native的静态方法,以及C++调用Java 的静态方法。 上面两种不同的静态方法,对于JNI来说有啥区别? 这个问题很少人会关注,一个是因为很少会静态方法调用JNI或者回调静态的Java方法; 另外一个是因为知道了或者调试过就不难了,所以很多人觉得没必要讲解和记录。 但是对于JNI 的初学者来说静态方法还是比较陌生的,很容易会懵逼的,不知道有啥区别。

数字货币钱包 分层确定性钱包介绍(HD wallets)

什么是分层确定性(Hierarchical Deterministic)钱包( HD Wallets)?我们先看看比较官方的解释,指使用分层确定性地址机制的电子钱包,通过椭圆曲线密码学机制,确保可以通过在没有私钥参与的情况下,由公钥直接分散成子公钥,并且分散的子公钥可以由分散的子私钥认证。 为什么会有HD钱包? 之前的钱包为了保护用户的隐私(你肯定不想别人知道你账户里有多少钱吧),所以在比特币中每个账户都会分配100个地址,保证每次交易都用一个新地址,虽然保护了隐私也带来其他问题;如果你交易频繁,100笔交易之后还需再产生100个账户,100个私钥,这样你就需要不停的备份你的钱包。这种钱包称之为非确定性钱包,钱包是一堆随机生成的私钥的集合。 而分层确定性钱包,从一个“种子”推导出一个主私钥,主私钥推导出海量的子私钥。“确定性”意味着同一个“种子”可以推到出同一批子私钥;“分层”,主私钥推导出子私钥是一种树状结构,如上图;所以方便组织机构使用,总部控制主私钥,给各部门发放子私钥,部门只能控制自己有私钥的部分,但是总部既可以控制也可以监管;这样即给部门一定的自治权利,总部也保留了绝对的控制权。所以我们只需要备份好自己的种子就可以了(可以认为是助记词)。 总结一下,HDWallet的优点包括海量私钥,方便备份,权限管理。还有一些新特性,例如可以从一个父公钥产生子公钥,这意味着你的主私钥可以离线放置;你可以用你的主公钥生成子公钥去收款,完全不必要担心私钥的安全。 BIP32、BIP39、BIP44 正所谓无规矩不成方圆,了解原理之前,我们先了解一些规矩。现在市场上的大部分数字货币钱包都支持HD Wallet,而且用户可以通过助记词在不同的HD Wallet之间相互导入导出账户;之所以这么方便就是因为大家都遵循了BIP32、BIP39、BIP44。 BIP32:定义 Hierarchical Deterministic wallet (HD Wallet)的核心提案。钱包可以通过种子来生成主私钥,然后派生海量的子私钥和地址,按照树状结构存储。 BIP39:将由于种子是一串很长的随机数,不利于记录,所以我们将种子转化为一组单词表示,一般由12个单词构成,称之为助记词(mnemonic code,phrase);例如: good gather ranch lunar edit hospital comic final fee coin athlete rescue BIP44:提出了5层的路径建议,在 BIP32 的基础上,赋予树状结构中的各层不同的意义,以支持多币种,多账户。用户只需一个种子,就能控制所有币种,所有账户的钱包。各层定义如下: m / purpose' / coin_type' / account' / change / address_index 其中的 purporse' 固定是 44',代表使用 BIP44。而 coin_type' 用来表示不同币种,例如 Bitcoin 就是 0',Ethereum 是 60'。'account'表示账户。'change',常量0用于外部链,常量1用于内部链(也称为更改地址)。外部链用于在钱包外部可见的地址(例如,用于接收付款)。内部链用于在钱包外部不可见的地址,用于返回交易变更。'address_index',表示生产的地址序号,地址按顺序递增的方式从索引0开始编号。 从种子到私钥 生成一个助记词(BIP39 mnemonic code)。 助记词使用PBKDF2转化为种子。 种子通过使用HMAC-SHA512生成主私钥。 通过主私钥派生出子私钥(BIP32),其中节点布局由BIP44设置。 既然mnemonic code这么重要,除了需要用户进行备份外,那些热钱包是如何保护的私钥,助记词之类的呢? 例如以太坊目前官方钱包采用 KDF 的形式,也就是我们常说的 Keystore 的形式。私钥与公钥将会以加密的方式保存为一份文件叫 keystore,中文可以叫签名证书,由于是私钥公钥放在一起,相当于钥匙和锁放在一起保存在一个保险箱,必然是需要另外一把钥匙也就是密码上锁的。 所以生成keystore的时候的密码非常重要,忘记了密码意味着这个证书打不开无法使用.

比特币地址与密钥

比特币中没有账户的概念,那么如何确定你的比特币是你比特币,或者说如何证明你是你? 这个主要应用到密码学,举个简单的例子,小王向小张转100btc,其实是把这100btc放到区块链上的,然后使用锁定脚本把这笔钱锁定到小张的地址,而小张只需要提供签名和公钥就可以使用这笔钱;同样的道理小张要花这笔钱的时候,也是将btc锁到一个新的地址,由下个人解开去花费;那么这里小张的地址,是什么呢,这次主要介绍一下比特币中的钱包,地址等概念。 公钥和私钥 在比特币中,私钥相当于密码,而公钥相当于你的账号;别人向你的公钥地址转钱,你用私钥去取钱。 私钥就是一个随机选出的数字而已。如果我们自己随便写一个,肯定安全性不够容易被破解的,毕竟和钱相关,这一步很重要的,一般是通过在一个密码学安全的随机源中取出一长串随机字节,对其使用SHA256哈希算法进行运算,这样就可以方便地产生一个256位的数字。 有了私钥以后,通过椭圆曲线算法可以从私钥计算得到公钥,这是不可逆转的过程:K = k * G 。其中k是私钥,G是被称为生成点的常数点,而K是所得公钥。其反向运算,被称为“寻找离散对数”——已知公钥K来求出私钥k——是非常困难的,就像去试验所有可能的k值,即暴力搜索。反向运算困难可以简单的理解成,你知道公钥是1024,1024=k*G,那么你能才出来k是多少吗?当然这个比较简单,如果公钥K是一个非常大的数字呢?你可以在想想结果会怎么样。 比特币地址 上文说的小张的地址是什么呢,现在就要解释一下他是如果生成的。 1、添加版本的目的是为了明确需要编码的数据类型,数据类型如下: 2、添加校验码主要是为了检测转录过程中出现的错误; 3、Base58check是什么? 让我们从进制说起来, 二进制:0、1 十进制:0~9 十六进制:0~9,A~F Base64(相当于64进制):0~9,a~z,A~F,以及连个符号(例如,-、+) Base58:是Base64编码格式的子集,同样使用大小写字母和10个数字,但舍弃了一些容易错读和在特定字体中容易混淆的字符。具体地,Base58不含Base64中的0(数字0)、O(大写字母o)、l(小写字母L)、I(大写字母i),以及“+”和“/”两个字符。 Base58Check:是一种常用在比特币中的Base58编码格式,增加了错误校验码来检查数据在转录中出现的错误。校验码长4个字节,添加到需要编码的数据之后。 最终生成的这个地址,就是你的账号了。 密钥格式 公钥和私钥的都可以有多种编码格式。一个密钥被不同的格式编码后,虽然结果看起来可能不同,但是密钥所编码数字并没有改变。这些不同的编码格式主要是用来方便人们无误地使用和识别密钥。 私钥格式 不同格式之间是可以转换的。 公钥格式 公钥也可以用多种不同格式来表示,最重要的是它们分为非压缩格式或压缩格式公钥这两种形式。 公钥是在椭圆曲线上的一个点,由一对坐标(x,y)组成。公钥通常表示为前缀04紧接着两个256比特的数字。其中一个256比特数字是公钥的x坐标,另一个256比特数字是y坐标。前缀04是用来区分非压缩格式公钥,压缩格式公钥是以02或者03开头。 公钥=04xy 引入压缩格式公钥是为了减少比特币交易的字节数,从而可以节省那些运行区块链数据库的节点磁盘空间。根据椭圆曲线公式,可以分析出,只要知道了x就可以推算出y,所以存储公钥可以省略y,这样公钥的大小就减少了256比特了。但是有一个问题是y的值有正负两种可能,对应到椭圆曲线对应y的奇数偶数,因此,为了区分y坐标的两种可能值,我们在生成压缩格式公钥时,如果y是偶数,则使用02作为前缀;如果y是奇数,则使用03作为前缀。这样就可以根据公钥中给定的x值,正确推导出对应的y坐标,从而将公钥解压缩为在椭圆曲线上的完整的点坐标。 压缩私钥 将压缩格式公钥和非压缩格式公钥转化成比特币地址后,得到两个不相同地址。这种结果会让人迷惑,因为一个私钥可以生成两种不同格式的公钥——压缩格式和非压缩格式,而这两种格式的公钥可以生成两个不同的比特币地址。但是,这两个不同的比特币地址的私钥是一样的。 由于,并非所有的客户端都支持压缩格式公钥,于是那些较新的支持压缩格式公钥的客户端就不得不考虑如何处理那些来自较老的不支持压缩格式公钥的客户端的交易。这在钱包应用导入另一个钱包应用的私钥的时候就会变得尤其重要,因为新钱包需要扫描区块链并找到所有与这些被导入私钥相关的交易。比特币钱包应该扫描哪个比特币地址呢?新客户端不知道应该使用哪个公钥:因为不论是通过压缩的公钥产生的比特币地址,还是通过非压缩的公钥产生的地址,两个都是合法的比特币地址,都可以被私钥正确签名,但是他们是完全不同的比特币地址。 为了解决这个问题,当私钥从钱包中被导出时,较新的比特币客户端将使用一种不同的钱包导入格式(Wallet Import Format)。 实际上“压缩格式私钥”是一种名称上的误导,因为当一个私钥被使用WIF压缩格式导出时,不但没有压缩,而且比“非压缩格式”私钥长出一个字节。这个多出来的一个字节是私钥被加了后缀01,用以表明该私钥是来自于一个较新的钱包,只能被用来生成压缩的公钥。私钥是非压缩的,也不能被压缩。“压缩的私钥”实际上只是表示“用于生成压缩格式公钥的私钥”,而“非压缩格式私钥”用来表明“用于生成非压缩格式公钥的私钥”。为避免更多误解,应该只可以说导出格式是“WIF压缩格式”或者“WIF”,而不能说这个私钥是“压缩”的。 要注意的是,这些格式并不是可互换使用的。在较新的实现了压缩格式公钥的钱包中,私钥只能且永远被导出为WIF压缩格式(以K或L为前缀)。对于较老的没有实现压缩格式公钥的钱包,私钥将只能被导出为WIF格式(以5为前缀)导出。这样做的目的就是为了给导入这些私钥的钱包一个信号:到底是使用压缩格式公钥和比特币地址去扫描区块链,还是使用非压缩格式公钥和比特币地址。

以太坊 EVM虚拟机框架分析

最近比较迷恋solidity和EVM,solidity研究了不少,发现还是需要结合EVM才能理解的比较透彻,最近准备详细研究一些EVM。研究了一下源码,发现EVM貌似会有新的版本,叫EWASM;不过现在貌似还没有应用,据说改动很大;笔者研究的还是EVM。之后会继续根据EWASM的进展。 EVM模块支持合约的执行与调用,调用时根据合约地址获取到代码,生成环境后载入到EVM中运行。通常智能合约的开发流程是用solidlity编写逻辑代码,再通过编译器编译元数据,最后通过EVM解析之后,再发布到链上。 再来介绍一个几个关键的模块。 指令:文件opcodes.go中定义了所有的OpCode,该值是一个byte,合约编译出来的bytecode中,一个OpCode就是上面的一位。opcodes按功能分为9组(运算相关,块操作,加密相关等)。 指令函数集:jump.table.go中定义了四种指令集合,每个集合实质上是个256长度的数组,指令集分为了四种,分别是frontierInstructionSet、homesteadInstructionSet、byzantiumInstructionSet、constantinopleInstructionSet(荒地,农庄,拜占庭,君士坦丁堡);应该是对应了EVM的四个发展阶段。指令集向前兼容。 解释器:interpreter.go中有解释器的入口函数run,根据用户给定的输入数据,循环对智能合约中的代码进行解析,翻译成对应的指令函数集中的函数,并运行。 Gas计算:gas_table.go,gas.go,根据不同的运算,计算消耗的gas,具体的方法都定义在gas_table里面。 智能合约:contract.go,合约是EVM智能合约的存储单位也是解释器执行的基本单位,包含了代码,调用人,所有人,gas相关的信息。contracts.go ,包含了一些EVM预先编译好的一些合约,例如ecrecover、sha256hashripemd160hash。 memory:memory.go,内存用于一些内存操作(MLOAD,MSTORE,MSTORE8)及合约调用的参数拷贝(CALL,CALLCODE)。内存数据结构,维护了一个byte数组,MLOAD,MSTORE读取存入的时候都要指定位置及长度才能准确的读写。 stack:stack.go,EVM中栈用于保存操作数,每个操作数的类型是big.int.执行opcode的时候,从上往下弹出操作数,作为操作的参数。 statedb:go-ethereum/core/state/statedb.go,合约本身不保存数据,合约及其调用类似于数据库的日志,保存了合约定义以及对他的一系列操作,只要将这些操作执行一遍就能获取当前的结果,但是如果每次都要去执行就太慢了,因而这部分数据是会持久化到stateDb里面的。code中定义了两条指令SSTORE SLOAD用于从db中读写合约当前的状态。 log:logger.go,对evm运行过程,对memorty,stack,statedb,还有一些信息的记录。 需要注意的是在EVM中,栈是唯一免费的存放数据的区域,其他区域都需要支付gas。因此,这相当于鼓励尽量使用栈,但是栈的深度又有限制,可见写一个很棒的solidity是有难度的。 上图主要是对EVM的整个结构进行了一下总结,可能有不准确的地方,随着后续文章会慢慢改进;发现错误或者有建议的同学可以联系我。

SOC设计:关于reset的细节

有如下几个信号 1、时钟:clk_top 2、总的reset信号:rstn_top 3、scan的reset信号:scan_rstn 4、软件复位信号:rstn_soft_sub 5、scan模式信号:scan_mode 6、reset bypass 信号:scan_rstn_sel 功能: 一:在非test模式时,也就是test_mode=1'd0时,如果rstn_soft_sub=1,则rstn_top直接透传过去给reset_soft_block里的rstn,然后rstn再经过2拍同步处理,然后产生rstn_sub。这里涉及到了异步复位,同步释放知识点。 二:正常功能仿真时,scan_mode = 1'd0 和scan_rstn_sel=0,直观点讲,rstn_sub是由rstn_top同步处理2拍后产生。 reset_soft_block u0_sub_rstn_gen (/*autoinst*/ .clk (clk_top ), // input .rstn0 (rstn_top ), // input .rstn1 (scan_rstn ), // input .rstn_soft (rstn_soft_sub ), // input .test_mode (scan_mode ), // input .rst_bypass (scan_rstn_sel ), // input .rstn_out (rstn_sub ) // output ); reset_soft_block功能 module reset_soft_block ( clk, rstn0, rstn1, rstn_soft, test_mode, rst_bypass, rstn_out ); input clk; input rstn0;

以太坊 EVM内交易执行分析(二)

接着上次的分析,分析一下run方法是如何执行智能合约的。至于以太币的交易,在上一篇中,已经由分析的那两个函数完成了; 合约的运行是从run开始的,go-ethereum/core/vm/evm.go 。可以分为两部分一部分是预编译,另外一部分是解释器。 预编译合约 // run runs the given contract and takes care of running precompiles with a fallback to the byte code interpreter. func run(evm *EVM, contract *Contract, input []byte) ([]byte, error) { if contract.CodeAddr != nil { precompiles := PrecompiledContractsHomestead if evm.ChainConfig().IsByzantium(evm.BlockNumber) { precompiles = PrecompiledContractsByzantium } if p := precompiles[*contract.CodeAddr]; p != nil { return RunPrecompiledContract(p, input, contract) } } return evm.interpreter.Run(contract, input) } 在以太坊中,go-ethereum/core/vm/contracts.go,事先编译好了一组合约,具体如下: var PrecompiledContractsByzantium = map[common.

SOC设计:关于时钟门控的细节

有如下几个信号 输入信号 1、同步后的rstnsync_clk 2、时钟:clk 3、test_mode 4、软件控制信号:clk_sub_en 输出信号 1、clk_sub 功能:软件配置的使能信号clk_sub_en经过时钟clk 2拍同步处理后产生clk 域下的enable信号,然后使用工艺库里的时钟门控cell产生门控时钟clk_sub 使用工艺库里的门控时钟原因如下 clkgating_lte u0_clk_sub_gen ( .rstn (rstnsync_clk ), // input .clk_in (clk ), // input .test_mode (test_mode ), // input .gating (clk_sub_en ), // input .clk_out (clk_sub ) // output ); module clkgating_lte ( rstn, clk_in, test_mode, gating, clk_out ); input rstn; input clk_in; input test_mode; input gating; output clk_out; wire gatingSync1; wire gatingSync2; dsync2s u_dsync2s(.q(gatingSync2), .d(gating), .clk(clk_in), .rst_(rstn));

数据结构入门篇 之 【顺序表】的实现讲解(附完整实现代码)

阿里!阿里巴巴!我要进阿里巴巴研发5G! 一.顺序表 1.顺序表的作用 2.顺序表和数组的区别 3.顺序表的分类 4.动态顺序表的实现 1).分装文件 2).定动态顺序表 3).初始化变量函数SLInit 4).数据管理函数头插和尾插和扩容函数 5).头删SLPopBack和尾删SLPopFront函数 6).指定位置 插入/删除 函数 SLInsert/SLErase 7).查找函数SLFind 8).销毁函数SLDestory 二.完整实现代码 三.完结撒❀ 前言 在开始讲解之前先问大家几个问题: 1、什么是数据结构?2、我们为什么要学习数据结构?3、学习数据结构我们需要掌握哪些知识? –❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀– 1.什么是数据结构? 其实数组就是一个数据结构。 数据结构是由“数据”和“结构”两词组织而来的。 什么是数据? 常见的数值有1、2、3、4…、教务系统里保存的用户信息(姓名、性别、年龄、学历等等)、网页里肉眼可以看到的信息(文字、图片、视频等等),这些都是数据。 什么是结构? 当我们想要大量使用同一类型数据时,通过手动定义大量的独立变量对于程序来说,可读性非常差,我们可以借助数组这样的数据结构将大量的数据组织在一起,结构也可以理解为组织数据的方式。 举个例子: 假如在草原上的羊群里: 你想找到名叫“咩咩”的羊很难,但是在羊圈里的话: 要找到编号为1的羊就很简单,羊圈这种结构有效的将羊群组织了起来。 数据结构的概念: 数据结构是计算机存储,组织数据的方式。数据结构是指互相之间存在一种或多种特定关系的数据元素的合集。数据结构反映数据的内部构成,即数据由那部分构成,以什么方式构成,以及数据元素之间呈现的结构。 总结: 1)能够存储数据(如顺序表、链表等结构) 2)存储的数据能够方便查找 2.我们为什么要学习数据结构? 这里再给大家举个例子: 就比如我们在买饭的时候,如果不借助排队来管理客户,那么会导致客户就餐体验差,餐厅营业混乱等恶略情况。同理,如果程序中的数据不能进行有效的管理,可能会导致数据丢失,操作数据困难、野指针等情况。 而通过数据结构,我们就可以很好的将数据进行管理。按照我们的方式任意对数据进行增删改查等操作。 最基础的数据结构是:数组。 假设有一个10个空间的数组,已经使用了5个,向数组中插入数据步骤: 求数组的长度,数组的有效数据个数,向下标为有效数据的数据位置插入数据(这里还要判断数组是否满了,满了的话还能继续插入吗?) 所以最基础的数据结构能够提供的操作已经不能完全满足复杂算法的实现。 3.学习数据结构我们需要掌握那些知识? 我们至少需要掌握结构体,指针(一级指针、二级指针、指针传参)、结构体指针、动态内存管理,这些知识才能学习数据结构。 下面就进入顺序表的讲解。 一.顺序表 1.顺序表的作用 我们之所以实现顺序表,作用就是想要按照我们定义的方式,任意的去对数据进行增删改查的操作,目的在于可以更好的管理所存储的数据,比如我们手机上都有的通讯录,其就可以用顺序表来进行实现。(在下一篇博客中我会为大家讲解通讯录的实现) 2.顺序表和数组的区别 顺序表的底层结构是数组,对数组的封装,实现了常用的增删改查等接口。 3.顺序表的分类 顺序表分为:静态顺序表和动态顺序表 静态顺序表: 所谓静态顺序表就是使用的是给定长度的数组用来存储数据。下面代码就是静态顺序表(这里以储存管理int类型为例): #define N 7 typedef int SLDataList; typedef struct SeqList { SLDataList arr[N];//定长数组 int size;//有效数据个数 }SL; 代码讲解:

react中封装一个自己的hook

常用的函数我们都可以封装成一个自己的hook,文件格式一般都为"usexxx" 下面是一个二次封装的antd消息通知 useMessage.ts import { useState, useEffect } from 'react'; import { message } from 'antd'; type MessageType = 'success' | 'error'; export const useMessage = () => { const [messageContent, setMessageContent] = useState<string>(''); const [messageType, setMessageType] = useState<MessageType | null>(null); useEffect(() => { if (messageType) { message[messageType](messageContent); } }, [messageContent, messageType]); const showMessage = (type: MessageType, content: string) => { setMessageType(type); setMessageContent(content); }; const showSuccess = (content: string) => { showMessage('success', content); }; const showError = (content: string) => { showMessage('error', content); }; return { showSuccess, showError }; }; 下面是一个注册模块的具体使用

C++中的模板(初阶)

一、函数模板 1.概念 函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生数的特定类型版本。 2.函数模板格式 template<typename T1, typename T2,......,typename Tn> 返回值类型 函数名(参数列表){} template<typename T> void Swap(T& a, T& b) { T temp = a; a = b; b = temp; } 注意:typename是用来定义模板参数关键字,也可以使用class(切记:不能使用struct代替class) 3.函数模板原理 在编译器编译阶段,对于模板函数的使用,编译器需要根据传入的实参类型来推演生成对应类型的函数以供调用。比如:当用double类型使用函数模板时,编译器通过对实参类型的推演,将T确定为double类型,然后产生一份专门处理double类型的代码,对于字符类型也是如此 4.函数模板的实例化 用不同类型的参数使用函数模板时,称为函数模板的实例化。模板参数实例化分为:隐式实例化和显式实例化。 (1)隐式实例化: 让编译器根据实参推演模板参数的实际类型 template<class T> T ADD(const T& a,const T& b) { return a + b; } int main() { int a = 1, b = 2; double c = 1.0, d = 2.0; ADD(a, b); ADD(c, d); ADD(a, c);//这里会报错 return 0; } 上述代码的ADD(a,c)会报错,因为因为在编译期间,当编译器看到该实例化时,需要推演其实参类型通过实参a将T推演为int,通过实参c将T推演为double类型,但模板参数列表中只有一个T,编译器无法确定此处到底该将T确定为int 或者 double类型而报错

Echarts 动态实现柱状图、折线图、饼状图的切换

弹窗展示统计图 //找到表格对应的名称和后端返回的键对应进行渲染 var fieldVal= $(this).parents("td").attr("data-field"); $.ajax({ url: '',//服务端的请求地址 type: 'get',//http请求方式 get,post,put,delete,options dataType: "json", async : false, data : {"type":1}, success: function (res) { console.info(res) var dataArray = res[fieldVal]; // 根据 fieldVal 的值从 res 中获取相应的数据数组 // // 使用Layer组件显示柱状图 layer.open({ type: 1, // 类型为内容层 title: '标题', // 弹出层的标题 area: ['90%', '86%'], content: '<div id="chart-container" style="width: 100%; height: 100%; margin: 0px auto" ></div>', // 弹出层的内容,这里是一个容器 success: function(layero, index) { var fieldName = $("

7.2 撰写业务分析报告、创建可视化报表 (10%)

一、撰写业务分析报告 1、业务分析报告作用 基于数据产生的报告:有静态报告和动态报告(可视化看板) PPT——适用于演讲word/PDF ——个人下载或查阅动态报告——可视化看板 2、撰写流程 3、业务分析报告的设计 1 概述 工作周期报告——针对工作内容;周期回顾型 网速监测报告——由于报告中看预警值或是否合理范围内;属于短周期,高频次的行为——日常通报型 活动评估报告——临时性或者持续性(双11,618等)——专题通报型 用户留存分析报告——长期持续性(周期回顾型);某个时间点(专题通报型) 生意机会报告——需要了解自己和了解别人;看优势什么的(专题通报型) 库存健康报告——指定周期给库存的报告 (周期回顾型);如果临时看(专题通报型) 绩效评估报告——周期回顾型;(某个节点的——专题通报型) 注: 日常通报型——看指标是否在正常范围内 周期回顾型——周期内,指定周期末;一般是标准化报告 专题类——临时性需求;或特定事件(针对于某个节点) 2 日常通报型 短周期、高频、持续性核心数据报表 适用场景:内存饱和度监测、数据传送及时性、网速稳定性等 3 周期回顾型 4 专题回顾型 低频、专项关注点数据报表 eg:活动评估报告、渠道用户表现报告、库存亚健康分析等 4、业务分析报告的撰写注意点 从整体来看,在这7天用户不断增加,后期增长速度不断衰减。 留存用户数,在持续下降,并在后期下降速度加快。 新用户不断增长,增长速度高速增长。 二、创建可视化报表 1、可视化报表与业务分析报告的差异 1、业务分析报告是文本和表格,可视化报表都是图带有筛选器 2、业务分析报告:是表格数据,在一个工作表内进行数据处理,一个业务点论述有起始高潮总结,静态报告,被动获取信息,包括合理建议,Work或Ppt 可视化报表:表数据,多数据源,业务面,动态仪表盘,主动获取信息,不提供建议,BI 2、可视化报表的创建过程 1. 业务理解 1. 第一步也是最重要一步,做到全面、准确、深入理解业务问题 2. 方法: 1. 与业务人员或决策者多次深入访谈(制定计划、明确问题、主题、时间、地点) 2. 实际业工作中学习 3. 查阅相关业务资料 2. 整体设计 1. 整体设计连接业务需求与可视化报表成果之间的桥梁 2. 方法: 1. 可视化报表作用 2. 思维路径:明确业务需求、明确服务对象、明确业务流程和行为、围绕可落地的数据建议进行设计 3. 设计思路 3. 数据收集 5W2H思维模型、ETL 4. 数据加工整理 ETL、DW 5.

MySQL MGR

一、MGR简述 在 2016 年 9 月的 Oracle Openworld 上,MySQL 官方提出了 MySQL InnoDB Cluster 的概念,并将其定为 MySQL 未来的发展目标。其核心就是用 MySQL 数据 库和原生工具构建出一个全栈高可用 MySQL 集群系统,用来支撑大规模 MySQL 集群的使用,特别是云上的使用。其 Group Replication 是 MySQL InnoDB Cluster 这个及具潜力产品中的核心组件。 Mysql 官方推出的集群架构,主要由 3 个模块组成: 支持 Group Replication 功能的 Mysql Server,主要功能在于实现了组内通信、故障转移和故障恢复;Mysql-Shell:实现快速部署,主要提供了一套 AdminAPI,可以自动化配置 Group Replication。Mysql-Router:内置读写分离,负载均衡。自动根据 Mysql InnoDB Cluster中的 metadata。 二、MGR 单主 + VIP 1、MGR MGR (MySQL Group Replication)是MySQL自带的一个插件,可以灵活部署。MySQL MGR集群是多个MySQL Server节点共同组成的分布式集群,每个Server都有完整的副本,它是基于ROW格式的二进制日志文件和GTID特性。架构主要是APIs层、组件层、复制协议模块层和GCS API+Paxos引擎层构成。 应用发来的事务从MySQL Server经过MGR的APIs接口层分发到组件层,组件层去capture事务相关信息,然后经过复制协议层进行事务传输,最后经过GCS API+Paxos引擎层保证事务在各个节点数据最终一致性。这是事务进入MGR层内部处理过程。 MGR由若干个节点共同组成一个复制组,一个事务的提交,必须经过组内大多数节点(N / 2 + 1)决议并通过,才能得以提交。如上图所示,由3个节点组成一个复制组,Consensus层为一致性协议层,在事务提交过程中,发生组间通讯,由2个节点决议(certify)通过这个事务,事务才能够最终得以提交并响应。 引入组复制,主要是为了解决传统异步复制和半同步复制可能产生数据不一致的问题。组复制依靠分布式一致性协议(Paxos协议的变体),实现了分布式下数据的最终一致性,提供了真正的数据高可用方案(是否真正高可用还有待商榷)。其提供的多写方案,给我们实现多活方案带来了希望。 2、MGR架构 MySQL MGR(MySQL Group Replication)是一个高可用性和容错性的解决方案,旨在提供数据冗余和故障转移。当使用三个节点的MGR集群时,如果宕掉了两个节点,集群的行为将取决于节点的宕机方式。

浅谈XML模糊测试

@Lonelone 前言 在我们平时进行渗透测试的过程中,我们经常会遇到一些带有XML格式的HTTP请求报文,其通常存在于请求体中,并通过POST请求方法发送,今天我们就来浅谈一下如何对XML这种格式进行模糊测试。 什么是XML XML(可扩展标记语言)是一种标记语言,用于存储和传输数据。它是一种简化版的SGML(标准通用标记语言),旨在同时具有灵活性和简单性,让开发者可以自定义标记元素,其与我们熟悉的HTML很像。 XML的一些特征: 1、自我描述性:XML文件的标记通常是描述性的,这意味着标签本身提供了关于数据的信息。例如,<name>John Doe</name>中的标签<name>表明了其中的数据是一个名字。 2、结构化数据:XML提供了一种结构化数据的形式,这让数据易于读取和理解。XML数据通常按层次结构组织,类似于树状结构,有父标签和子标签。 3、标准化:XML是由W3C(万维网联盟)维护的一个开放标准,这有助于保持跨平台的兼容性和数据的一致性。 4、文本格式:XML数据以纯文本形式存储,这使得它可以在不同的系统和程序之间轻松传输。 5、解析器普及:大多数编程语言都提供了解析XML的工具和库,这意味着可以在多种环境中轻松处理XML数据。 XML常见于配置文件、网络服务(如SOAP)、Office文档格式(如Microsoft Office Open XML)以及许多其他需要结构化存储和数据交换的场景。因其灵活性和简单性,XML成为了数据交换的一种流行选择。 一个简单的XML例子如下: XML <bookstore> <book> <title lang="en">Harry Potter</title> <price>29.99</price> </book> <book> <title lang="en">Learning XML</title> <price>39.95</price> </book> </bookstore> 什么是XPath XPath,即XML Path Language,是一种查询XML文档中信息的语言。它允许你能够通过定义具体路径来选择和导航文档树中的元素和属性。XPath使用简洁的路径表达式来选取XML文档中的节点或节点集。这些路径表达式看起来有点类似于文件系统的路径,但用于定位XML文档中的部分。 XPath的基础路径表达式包括: /:根节点 //:在当前节点选择文档中的节点,而不考虑它们的位置。 .:当前节点 ..:父节点 @:属性选择 举一个简单的例子,以上面的XML文档为例,如果想要选取所有的<book>元素,可以使用以下XPath表达式: Go /bookstore/book 如果我们想要选择所有属性lang值为"en"的<title>元素,XPath表达式将会是: Plain Text //title[@lang='en'] XML模糊测试技术实现 在了解了XML与XPath之后,我们对于如何模糊测试XML就有了一个基本的思路。假设我们的输入是一段请求体为XML格式的HTTP请求报文,那么根据思路我们拆分成以下几步: 1、切割HTTP请求报文,得到XML格式的请求体 2、使用XML解析库将XML解析为一个树形结构 3、遍历这个树形结构的所有节点,排除一些特殊节点(如注释节点,CharData节点等)后得到剩余的节点,称为普通节点 4、根据普通节点反推出其在该XML树形结构中的XPath,并将其他相关数据如标签名等存储为模糊测试参数(FuzzParam) 5、当我们需要进行模糊测试时,遍历上述存储的模糊测试参数,通过XPath定向修改该元素的内容为需要测试的值,就得到了我们模糊测试需要的请求报文 上述几个步骤中,最具挑战的应该是如何将一个节点在XML属性结构中的XPath反推出来,对此需要编写一个溯源函数,从普通节点一路回溯到根节点,并根据路径中回溯到的节点拼接为XPath,其关键实现如下: Go func GetXpathFromNode(node *xmlquery.Node) string { var getXpathFromNode func(node *xmlquery.Node, depth int, path string) string

STM32进阶笔记——复位、时钟与滴答定时器

本专栏争取每周三更新直到更新完成,期待大家的订阅关注,欢迎互相学习交流。 目录 一、复位1.1 软件复位1.2 低功耗管理复位 二、时钟2.1 系统时钟(SYSCLK)选择2.2 系统时钟初始化 三、滴答定时器(Systick)3.1 SysTick部分寄存器3.2 SysTick相关函数3.2.1 SysTick时钟源配置函数3.2.2 SysTick初始化函数 一、复位 STM32F10系列单片机的复位方式有三种,分别是系统复位、上电复位和备份区复位,这里只介绍系统复位,另外两种如果又想了解的友友可以参考芯片手册,这里就不再介绍了。 STM32的系统复位将复位所有寄存器至它们的复位状态,以下几种情况会触发系统复位 NRST引脚上的低电平(外部复位),这实际也就是我们复位按键利用的复位方式。窗口看门狗计数终止(WWDG复位)独立看门狗计数终止(IWDG复位)软件复位(SW复位)低功耗管理复位 可通过查看RCC_CSR控制状态寄存器中的复位状态标志位识别复位事件来源。 疑问:复位标志位怎么清除,如果发生了复位,重启后能否看到复位标志位 1.1 软件复位 通过将Cortex™-M3中断应用和复位控制寄存器中的SYSRESETREQ位置’1’,可实现软件复位。STM32的库文件中提供了软件复位函数 /** * @brief Initiate a system reset request. * * Initiate a system reset request to reset the MCU */ static __INLINE void NVIC_SystemReset(void) { SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | SCB_AIRCR_SYSRESETREQ_Msk); /* Keep priority group unchanged */ __DSB(); /* Ensure completion of memory access */ while(1); /* wait until reset */ } 需要注意的是,从SYSRESETREQ 被置为有效,到复位发生器执行复位命令,往往会有一个延时。在此延时期间,处理器仍然可以响应中断请求。因此我们在软件复位前,需要关闭全部中断,同时在程序最开始的时候开启全部中断。STM32库文件中也提供了一个关闭全部中断和开启全部中断的函数

windows下编译boost1.84.0库

boost系列文章目录 文章目录 boost系列文章目录前言一、boost编译二、boost使用三 、参考 前言 Boost简介 官方网址 Boost提供免费的同行评审的可移植C++源代码库。 我们强调与C++标准库配合良好的库。Boost库旨在广泛使用,并可在广泛的应用程序中使用。Boost许可证鼓励所有用户使用Boost库,且限制最小。 我们的目标是建立“现有实践”并提供参考实现,以便Boost库适合最终的标准化。从库技术报告(TR1)中包含的十个Boost图书馆开始,到2011年以来的每一次C++ISO标准发布,C++标准委员会一直将Boost作为标准C++库宝贵补充来源。 boost下载地址 一、boost编译 1.安装powershell工具 powershell工具下载地址 2.使用 cd ​进到 Boost 库源码目录。注意,如果你的目录中有空格,需要加双引号。 执行命令:.\bootstrap.bat​,生成可执行文件 b2.exe​ 3.在powerSheel中查看 Boost 组件库列表:./b2.exe --show-libraries​。如果我们只用到其中几个库,则可以只编译需要的库,当然也可以全部编译。这里一劳永逸全部编译,可能花费的时间更长,取决于您的电脑 3.使用以下命令 ./b2.exe install --prefix=“…/install/msvc” --build-dir=“build/msvc” runtime-link=static 这时在目录下会自动生成build路径 4.编译完成 二、boost使用 1.工程配置 (1)头文件 (2)配置静态库 这里的示例代码用到协程,所用加入libboost_coroutine-vc143-mt-s-x64-1_84.lib (3)注意 我这里编译的boost1.84.0 vc143,也就是visual studio2022,由于c++协程是c++20标准支持的,所以vs2019无法使用,只能使用vs2022 这是vs2019上报错 vs2022运行正常 三 、参考 Jelin大魔王