简单投票 DApp
接下来我们要开始真正做一个 DApp,尽管它这是很简单的一个投票应用,但会包含完整的工作流程和交互页面。构建这个应用的主要步骤如下:
我们首先安装一个叫做 ganache 的模拟区块链,能够让我们的程序在开发环境中运行。
写一个合约并部署到 ganache 上。
然后我们会通过命令行和网页与 ganache 进行交互。
我们与区块链进行通信的方式是通过 RPC(Remote Procedure Call)。web3js 是一个 JavaScript 库,它抽象出了所有的 RPC 调用,以便于你可以通过 JavaScript 与区块链进行交互。另一个好处是,web3js 能够让你使用你最喜欢的 JavaScript 框架构建非常棒的 web 应用。
开发准备-Linux
下面是基于 Linux 的安装指南。这要求我们预先安装 nodejs 和 npm,再 用 npm 安装 ganache-cli、web3 和 solc,就可以继续项目的下一步了。
mkdir simple_voting_dapp
cd simple_voting_dapp
npm init
npm install ganache- cli web3@0.20 .1 solc
node_modules/ . bin/ ganache- cli
如果安装成功,运行命令 node_modules/.bin/ganache-cli,应该能够看到下图所示的输出。 为了便于测试,ganache 默认会创建 10 个账户,每个账户有 100 个以太。。你需要用其中一个账户创建交易,发送、接收以太。
当然,你也可以安装 GUI 版本的 ganache 而不是命令行版本,在这里下载 GUI 版本:http://truffleframework.com/ganache/
Solidity 合约
我们会写一个叫做 Voting 的合约,这个合约有以下内容:
一个构造函数,用来初始化一些候选者。
一个用来投票的方法(对投票数加 1)
一个返回候选者所获得的总票数的方法
当你把合约部署到区块链的时候,就会调用构造函数,并只调用一次。与web 世界里每次部署代码都会覆盖旧代码不同,在区块链上部署的合约是不可改变的,也就是说,如果你更新合约并再次部署,旧的合约仍然会在区块链上存在,并且数据仍在。新的部署将会创建合约的一个新的实例。
代码和解释
pragma solidity ^ 0.4 .22 ;
contract Voting {
mapping ( bytes32 = > uint8 ) public votesReceived;
bytes32[ ] public candidateList;
constructor ( bytes32[ ] candidateNames) public {
candidateList = candidateNames;
}
function totalVotesFor ( bytes32 candidate) view public
returns ( uint8 ) {
require ( validCandidate ( candidate) ) ;
return votesReceived[ candidate] ;
}
function voteForCandidate ( bytes32 candidate) public {
require ( validCandidate ( candidate) ) ;
votesReceived[ candidate] += 1 ;
}
function validCandidate ( bytes32 candidate) view public
returns ( bool ) {
for ( uint i = 0 ; i < candidateList. length; i++ ) {
if ( candidateList[ i] == candidate) {
return true ;
}
}
return false ;
}
}
Line 1. 我们必须指定代码将会哪个版本的编译器进行编译
Line 3. mapping 相当于一个关联数组或者是字典,是一个键值对。mapping votesReceived 的键是候选者的名字,类型为 bytes32。mapping 的值是一个未赋值的整型,存储的是投票数。
Line 4. 在很多编程语言中(例如 java、python 中的字典),仅仅通过 votesReceived.keys 就可以获取所有的候选者姓名。但是,但是在 solidity 中没有这样的方法,所以我们必须单独管理一个候选者数组candidateList。
Line 14. 注意到 votesReceived[key] 有一个默认值 0,所以你不需要将其初始化为 0,直接加 1 即可。
你也会注意到每个函数有个可见性说明符(visibility specifier)(比如本例中的 public)。这意味着,函数可以从合约外调用。如果你不想要其他任何人调用这个函数,你可以把它设置为私有(private)函数。如果你不指定可见性,编译器会抛出一个警告。最近 solidity 编译器进行了一些改进,如果用户忘记了对私有函数进行标记导致了外部可以调用私有函数,编译器会捕获这个问题。
你也会在一些函数上看到一个修饰符 view。它通常用来告诉编译器函数是只读的(也就是说,调用该函数,区块链状态并不会更新)。
接下来,我们将会使用上一节安装的 solc 库来编译代码。如果你还记得的话,之前我们提到过 web3js 是一个库,它能够让你通过 RPC 与区块链进行交互。我们将会在 node 控制台里用这个库部署合约,并与区块链进行交互。
编译合约
In the node console> Web3 = require ( 'web3' )
> web3 = new Web3 ( new
Web3. providers. HttpProvider ( "http://localhost:8545" ) ) ;
> web3. eth. accounts
[ '0x5c252a0c0475f9711b56ab160a1999729eccce97'
'0x353d310bed379b2d1df3b727645e200997016ba3' ]
> code = fs. readFileSync ( 'Voting.sol' ) . toString ( )
> solc = require ( 'solc' )
> compiledCode = solc. compile ( code)
首先,在终端中运行 node 进入 node 控制台,初始化 web3 对象,并向区块链查询获取所有的账户。
确保与此同时 ganache 已经在另一个窗口中运行
为了编译合约,先从 Voting.sol 中加载代码并绑定到一个 string 类型的变量,然后像右边这样对合约进行编译。
当你成功地编译好合约,打印 compiledCode 对象(直接在 node 控制台输入 compiledCode 就可以看到内容),你会注意到有两个重要的字段,它们很重要,你必须要理解:
compiledCode.contracts[':Voting'].bytecode:
这就是 Voting.sol 编译好后的字节码。也是要部署到区块链上的代码。
compiledCode.contracts[':Voting'].interface
: 这是一个合约的接口或者说模板(叫做 abi 定义),它告诉了用户在这个合约里有哪些方法。在未来无论何时你想要跟任意一个合约进行交互,你都会需要这个 abi 定义。你可以在这里 看 到 ABI 的更多内容。在以后的项目中,我们将会使用 truffle 框架来管理编译和与区块链的交互。
但是,在使用任何框架之前,深入了解它的工作方式还是大有裨益的,因为框架会将这些内容抽象出去。
部署合约
让我们继续课程,现在将合约部署到区块链上。为此,你必须先通过传入 abi 定义来创建一个合约对象 VotingContract。然后用这个对象在链上部署并初始化合约。
Execute this in your node console:
> abiDefinition =
JSON. parse ( compiledCode. contracts[ ':Voting' ] . interface )
> VotingContract = web3. eth. contract ( abiDefinition)
> byteCode = compiledCode. contracts[ ':Voting' ] . bytecode
> deployedContract =
VotingContract. new ( [ 'Alice' , 'Bob' , 'Cary' ] , { data: byteCode, from:
web3. eth. accounts[ 0 ] , gas: 4700000 } )
> deployedContract. address
'0x0396d2b97871144f75ba9a9c8ae12bf6c019f610'
> contractInstance = VotingContract. at ( deployedContract. address)
VotingContract.new 将合约部署到区块链。 第一个参数是一个候选者数组,候选者们会竞争选举,这很容易理解。让我们来看一下第二个参数里面都是些什么:
data: 这是我们编译后部署到区块链上的字节码。
from: 区块链必须跟踪是谁部署了这个合约。在这种情况下,我们仅仅是从调用 web3.eth.accounts 返回的第一个账户,作为部署这个合约的账户。记住,web3.eth.accounts 返回一个 ganache 所创建 10 个测试账号的数组。在交易之前,你必须拥有这个账户,并对其解锁。创建一个账户时,你会被要求输入一个密码,这就是你用来证明你对账户所有权的东西。在下一节,我们将会进行详细介绍。为了方便起见,ganache 默认会解锁 10 个账户。
gas: 与区块链进行交互需要花费金钱。这笔钱用来付给矿工,因为他们帮你把代码包含了在区块链里面。你必须指定你愿意花费多少钱让你的代码包含在区块链中,也就是设定 “gas” 的值。你的 “from” 账户里面的ETH 余额将会被用来购买 gas。gas 的价格由网络设定。我们已经部署了合约,并有了一个合约实例(变量 contractInstance),我们可以用这个实例与合约进行交互。
在区块链上有上千个合约。那么,如何识别你的合约已经上链了呢?答案是找到已部署合约的地址 deployedContract.address
. 当你需要跟合约进行交互时,就需要这个部署地址和我们之前谈到的 abi 定义。
控制台交互
In your node console: > contractInstance. totalVotesFor. call ( 'Rama' ) { [ String: '0' ] s: 1 , e: 0 , c: [ 0 ] } > contractInstance. voteForCandidate ( 'Rama' , { from:
web3. eth. accounts[ 0 ] } )
'0xdedc7ae544c3dde74ab5a0b07422c5a51b5240603d31074f5b75c0ebc78
6bf53'
> contractInstance. voteForCandidate ( 'Rama' , { from:
web3. eth. accounts[ 0 ] } )
'0x02c054d238038d68b65d55770fabfca592a5cf6590229ab91bbe7cd72da
46de9'
> contractInstance. voteForCandidate ( 'Rama' , { from:
web3. eth. accounts[ 0 ] } )
'0x3da069a09577514f2baaa11bc3015a16edf26aad28dffbcd126bde2e71f
2b76f'
>
contractInstance. totalVotesFor. call ( 'Rama' ) . toLocaleString ( ) '3
'
{ [String: ‘0’] s: 1, e: 0, c: [ 0 ] } 是数字 0 的科学计数法表示. 这里返回的值是一个 bigNumber 对象,可以用它的的.toNumber()方法来显示数字:
contractInstance. totalVotesFor. call ( 'Alice' ) . toNumber ( )
web3. fromWei ( web3. eth. getBalance ( web3. eth. accounts[ 1 ] ) . toNumber ( ) , 'ether'
)
BigNumber 的值以符号,指数和系数的形式,以十进制浮点格式进行存储。s 是 sign 符号,也就是正负; e 是 exponent 指数,表示最高位后有几个零;c 是 coefficient 系数,也就是实际的有效数字;bignumber 构造函数的入参位数限制为14位,所以系数表示是从后向前截取的一个数组,14位截取一次。为候选者投票并查看投票数继续课程,在你的 node 控制台里调用 voteForCandidate 和totalVotesFor 方法并查看结果。
每为一位候选者投一次票,你就会得到一个交易 id: 比如:‘0xdedc7ae544c3dde74ab5a0b07422c5a51b5240603d31074f5b75c0ebc786bf53
’。这个交易 id 就是交易发生的凭据,你可以在将来的任何时候引用这笔交易。这笔交易是不可改变的。对于以太坊这样的区块链,不可改变是其主要特性之一。在接下来的章节,我们将会利用这一特性构建应用。
网页交互
至此,大部分的工作都已完成,我们还需要做的事情就是创建一个简单的html,里面有候选者姓名并调用投票命令(我们已经在 nodejs 控制台里试过)。你可以在右侧找到 html 代码和 js 代码。将它们放到 chapter1 目录,并在浏览器中打开 index.html。
index.html
< ! DOCTYPE html>
< html>
< head>
< title>
Voting DApp
< / title>
< link href= 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/boot
strap.min.css' rel= 'stylesheet' type = 'text/css' >
< / head>
< body class= "container" >
< h1>
A Simple Voting Application
< / h1>
< div class= "table-responsive" >
< table class= "table table-bordered" >
< thead>
< tr>
< th>
Candidate
< / th>
< th>
Votes
< / th>
< / tr>
< / thead>
< tbody>
< tr>
< td>
Alice
< / td>
< td id= "candidate-1" >
< / td>
< / tr>
< tr>
< td>
Bob
< / td>
< td id= "candidate-2" >
< / td>
< / tr>
< tr>
< td>
Cary
< / td>
< td id= "candidate-3" >
< / td>
< / tr>
< / tbody>
< / table>
< / div>
< input type = "text" id= "candidate" / >
< a href= "#" onclick= "voteForCandidate()" class= "btn
btn-primary" >
Vote
< / a>
< / body>
< script src= "https://cdn.jsdelivr.net/gh/ethereum/web3.js/dist/web3.mi
n.js" >
< / script>
< script src= "https://code.jquery.com/jquery-3.1.1.slim.min.js" >
< / script>
< script src= "./index.js" >
< / script>
< / html>
Tips:
中用 link 形式引入 bootstrap 的 css 类型库,以下 container、table-responsive 等 class 均来自 bootstrap
表头单元格,表单元格,候选人名字后的单元格为得票数,用 id 区分以方便写入,之后 js 中写死了对应关系
一个输入框,定义 id 方便在 js 中取值
超链接形式的按键 btn,href=“#”为跳转至本页,即不跳转;onclick 指向js 中方法为了简化项目,我们已经硬编码了候选者姓名。如果你喜欢的话,可以调整代码使其动态选择候选者。
index.js
web3 = new Web3 ( new Web3. providers. HttpProvider ( "http://localhost:8545" ) ) ;
abi = JSON. parse ( '[{"constant":false,…}]' ) VotingContract = web3. eth. contract ( abi) ;
contractInstance = VotingContract. at ( '0x329f5c190380ebcf640a90d06eb1db2d68503a53' ) ;
candidates = {
"Alice" : "candidate-1" ,
"Bob" : "candidate-2" ,
"Cary" : "candidate-3"
} ;
function voteForCandidate ( candidate) {
candidateName = $( "#candidate" ) . val ( ) ;
try {
contractInstance. voteForCandidate ( candidateName, {
from: web3. eth. accounts[ 0 ]
} ,
function ( ) {
let div_id = candidates[ candidateName] ;
$( "#" + div_id) . html ( contractInstance. totalVotesFor. call ( candidateName) . toString ( ) ) ;
} ) ;
} catch ( err) { }
}
$( document) . ready ( function ( ) {
candidateNames = Object. keys ( candidates) ;
for ( var i = 0 ; i < candidateNames. length; i++ ) {
let name = candidateNames[ i] ;
let val = contractInstance. totalVotesFor. call ( name) . toString ( ) $( "#" + candidates[ name] ) . html ( val) ;
}
} ) ;
在第 4 行,用你自己的合约地址替换代码中的合约地址。合约地址是之前的 deployedContract.address
如果一切顺利的话,你应该能够在文本框中输入候选者姓名,然后投票数应该加 1 。 注意:由于网络原因,web3.js 可能无法获取,可自行下载到本地导入。
如果你可以看到页面,为候选者投票,然后看到投票数增加,那就已经成功创建了第一个合约,恭喜!所有投票都会保存到区块链上,并且是不可改变的。任何人都可以独立验证每个候选者获得了多少投票。当然,我们所有的事情都是在一个模拟的区块链上(ganache)完成,在接下来的课程中,我们会将这个合约部署到真正的公链上。在 Part 2,我们会把合约部署到叫做 Ropsten testnet 的公链,同时也会学习如何使用 truffle 框架构建合约,管理 dapp。
总结一下,下面是你到目前为止已经完成的事情:
通过安装 node, npm 和 ganache,你已经配置好了开发环境。
你编码了一个简单的投票合约,编译并部署到区块链上。
你通过 nodejs 控制台与网页与合约进行了交互。
你可能感兴趣的:(快速学习)
成为有效学习的高手
SplendorZhang
学以致用-实用主义的学习不是为了考试,是为了快速学习一门知识或者掌握一项技能。才能在这个焦虑的时代里积累一点垫脚石,突破你所在的阶层或者过上你想要的生活。而从离开学校后我们就逐渐失去了学习能力或者说我们根本没有学会如何学习,这种学习不是机械记忆,而是需要在应用在真实环境中,所以十几年来习得的考试能力根本排不上用场,只得重新学习如何学习。一、找到合适的学习方法学习方法大致可以分为两类:自然类型的学习
Python GUI开发(超长文)
GRKF15
python GUI开发 python 开发语言 ui
1.PythonGUI开发简介1.1为什么使用Python进行GUI开发Python是一种高级编程语言,因其简洁的语法和强大的功能而被广泛使用。使用Python进行GUI(图形用户界面)开发具有以下优势:易学易用:Python语言简洁,易于上手,使得初学者能够快速学习并开发GUI应用程序。跨平台性:Python编写的GUI应用程序可以跨平台运行,无需为不同的操作系统编写不同的代码。丰富的库支持:P
助力孩子成长日记第48天
助力孩子成长日记周晓然妈妈
2018年12月24日星期一天气晴今天是崭新的一天,今天是星期一是升国旗的一天。孩子们看见飘飘冉冉升起的国旗,孩子们唱着国歌。孩子们看见五星红旗冉冉升起,孩子们看见升完了旗。孩子们排着队伍回教室上课了,孩子们临期末考试快到了。老师们和孩子们拧成一根绳,努力奋斗者一起快速学习和复习着。女儿中午放了学回到家里,她吃饱了饭。她就回自己的房间里去了背诵英语发了英语群,还读了一会主题丛书。我说你到点上学校吧
【python】python指南(十四):**操作符解包字典传参
LDG_AGI
Python python 开发语言 人工智能 机器学习 图像处理 深度学习 计算机视觉
目录一、引言二、**操作符应用2.1**操作符介绍2.2**操作符案例三、总结一、引言对于算法工程师来说,语言从来都不是关键,关键是快速学习以及解决问题的能力。大学的时候参加ACM/ICPC一直使用的是C语言,实习的时候做一个算法策略后台用的是php,毕业后做策略算法开发,因为要用spark,所以写了scala,后来用基于storm开发实时策略,用的java。至于python,从日常用hive做数
ArkTS基础快速入门学习
苏九黎
学习
鸿蒙开发ArkTS基础快速学习说明阅读本篇文章,适合一些了解过前端开发以及掌握前端框架的读者。ArkTS介绍ArkTS语言在TS语言基础上扩展了声明式UI,组件化,状态管理等功能。官方推荐两种开发模式开发鸿蒙,一种是基于js扩展的类web范式,另一种是基于TS扩展的声明式UI范式(也就是使用ArkTS开发)。ArkTs的代码基本结构Index.ets示例文件@Entry@Componentstru
Apache Kafka 快速学习大纲
aaaak_
大数据 kafka apache 学习
Kafka概述定义Kafka传统定义:Kafka是一个分布式的基于发布/订阅模式的消息队列(MessageQueue),主要应用于大数据实时处理领域。Kafka最新定义:Kafka是一个开源的分布式事件流平台(EventStreamingPlatform),被数千家公司用于高性能数据管道、流分析、数据集成和关键任务应用。kafka场景(1)日志收集:收集各种服务的log,通过kafka以统一接口服
Tortoise-ORM FastAPI integration 中文文档(完整版)
Fender的web学习路程
fastapi fastapi
Tortoise-ORMFastAPIintegration中文文档(完整版)前言初衷:在学习的时候发现Tortoise-ORMFastAPIintegration官方文档缺中文版,翻阅英文文档效率低,萌生翻译想法。本系列旨在原汁原味的翻译Tortoise-ORMFastAPIintegration官方文档,帮助英语不好的小伙伴快速学习使用方法。翻译不易,禁止商业用途,转载请标明出处(本人博客:t
区块链加/解密:对称加密
cloud_ether
区块链 区块链 加密算法
区块链加/解密一对称加密:加/解密用同一密钥填充与删除对称加密des3desaes快速学习加密小技巧:在CSDN博客中,阅读了有很多大神的博客,也学到了很多。首先在这里表示感谢由于我个人的表达能力有限,有些知识点涉及的不够深入,无法全面科普到。大家可以到区块链加密讲解学下加/解密原理针对于区块链加密算法,我准备给大家分3部分来讲解第一部分:对称加密对数据填充/删除des/3des/aes第二部分:
MySQL的Oracle教程_Oracle基础教程
左拽拽
MySQL的Oracle教程
Oracle基础教程本篇章主要介绍Oracle的基础教程,本文适合那些刚刚要学习Oracle的初学者或者是想了解Oracle的用户,通过本篇幅可以快速学习Oracle数据库的基础理论。本文通过讲解Oracle基础理论知识,让大家快速的了解Oracle,并通过实例演示,让你更有介入感,能够快速上手,而不仅仅只保留在理论知识上。本篇章的主要内容如下:1、Oracle介绍:介绍了Oracle数据库应用场
周报 | 24.8.12-24.8.18文章汇总
双木的木
深度学习拓展阅读 深度学习 人工智能 transformer 算法 python stable diffusion llama
为了更好地整理文章和发表接下来的文章,以后每周都汇总一份周报。周报|24.8.5-24.8.11文章汇总-CSDN博客OpenCV与AI深度学习|实战|使用YoloV8实例分割识别猪的姿态(含数据集)-CSDN博客极市平台|异常检测开源数据集汇总-CSDN博客程序员学长|快速学习一个算法,集成学习-CSDN博客Coggle数据科学|行业落地分享:大模型RAG汽车应用实践_rag中的意图识别-CSD
说说JVM的class文件(二)
Benaso
JVM jvm
简介在前文中我们已经简单说了说class类文件的结构,但是由于我是根据JVM规范进行快速学习解释所以部分的并不是很清楚,这篇文章是在我阅读了多本数有关类结构的部分后总结出的文章或者可以叫做读书笔记。Class类文件结构总所周知,我们的JVM在运行时不会与任何语言绑定而是只与"Class"文件进行绑定。Class文件是一组以字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑地排列在文件之中,没有
掌握提升学习力的“术”与“道”,做智慧型家长
听雨夜读书
“鸡”娃时代,孩子的学习屡屡引发家庭教育的冲突。有些孩子对学习缺乏兴趣,没有足够的驱动力;也有些孩子没有掌握高效的学习方法,导致学习效率低下;还有些孩子学习不能坚持,三天打鱼,两天晒网…...《如何提升孩子的学习力》一书告诉我们,孩子有以上情况,是因为学习力不足。那么学习力是什么呢?简单来说,学习力就是在变化的环境中,通过快速学习来解决问题的能力。作者一芳,乐又迪英语创始人,在儿童学习力培养方面有
CPU是如何工作的?什么是冯·诺依曼架构和哈弗架构?
车载系统攻城狮
嵌入式软件开发 / C语言 架构 嵌入式硬件 单片机
《嵌入式工程师自我修养/C语言》系列——CPU是如何工作的?什么是冯·诺依曼架构和哈弗架构?一、CPU内部结构及工作原理1.1CPU的结构1.2CPU工作流程举例二、计算机体系结构2.1冯·诺依曼架构2.2哈弗架构三、总结快速学习嵌入式开发其他基础知识?>>>>>>>>>返回专栏总目录《嵌入式工程师自我修养/C语言》>>>>>一文帮你快速区分常用存储器!>>>>>一文帮你快速区分常用存储器!>>>
如何成为逻辑清晰、有结构化思维的人?
是华莹呀
我们是不是都想成为这样的人?“做事能快速学习并融会贯通,具有超强的自律自控能力和适应能力;做人自信、坚定、边界感强,人生方向感强;对“焦虑”拥有强大的免疫力,同时还会用积极乐观且入世的人生态度感染并引领周边的人。”那什么是结构化思维?结构化思维有哪些特点?怎么实现/学到结构化思维?如何训练自己的结构化思维?今天从《麦肯锡结构化战略思维》一书中,跟大家分享分享,如何成为逻辑清晰、有结构化思维的人。一
中级会计60天三科一次上岸 经验之谈
小羊失棉了
时间安排阶段一:打牢知识基础(7月5号-8月3号)初中级会计考试,考察内容主要都是基础知识,所以一定要把基础知识打牢。第一步、跟着网校课学习,同时配合教材快速学习一遍,这一遍不要妄图全部理解,掌握整个中级考试知识框架即可,说不定听了后面的课,前面不懂得就理解了;也不要想全部记住,这是不可能的,重点在于知道涵盖了哪些知识点,建立知识体系,同时对于自己不理解的知识点,在教材上做好标注。第二步、翻开自己
自己的大脑控制自己的大脑
幻岭之漫
1.盟友赖床了,自觉被罚给我发红包。(早起不容易)2.上午开会,消除了我对这份工作心里没底的念想。老板是在给我机会,第一个项目快完成了,我们都要从中总结经验。我应该快速学习起来,要学的还有很多。这里的同事有趣有意思。小文和小雨的性格都超好,有趣很逗的“女神经”,将近两个月的相处,越来越喜欢和这俩人一起逗乐了。小文今天给我们带了她家人带过来的家乡食物,一个名叫马蹄糕的,我还是第一次吃呐,还真是好吃的
产品人的护城河
顺为
先于用户而变化好的产品永远是从用户需求中生长出来的,但卓越的产品必然先于用户而变化。持续打大小战役的能力没有产品一出生就完美,产品的迭代与成长,依赖于大大小小的实战,胜败不是关键,来自一线的实战与反思,能让你从中获取营养。超越常人的快速学习能力学习的方式无外乎向外的开放心态,以及向内的反思能力,互联网竞争让速度也成为重要的维度。化繁为简能看清事物的本质,勇做减法。保鲜你的好奇心科学家认为,好奇心能
快速学习Spring
香菜的开发日记
学习 spring java
Spring简介Spring是一个开源的轻量级、非侵入式的JavaEE框架,它为企业级Java应用提供了全面的基础设施支持。Spring的设计目标是简化企业应用的开发,并解决Java开发中常见的复杂性和低效率问题。Spring常用依赖org.springframeworkspring-context5.3.14org.springframeworkspring-aop5.3.14org.sprin
如何一边上班一边利用时间学习
静若莲
学习没有捷径,同样的24小时,为什么有的人可以一边上班一边学习,有的人却总是说自己没有时间。其实,时间就像海绵里的水,挤挤就会有的,就看你有没有把心放上面。那么上班族如何一边上班一边利用时间学习呢?一:利用快速学习工具节省时间节省学习时间的工具必须要利用起来,比如将课件、知识点下载手机里(有报名网络课程的小伙伴可以这么做哦),可以直接在手机里学习、看书、听课、非常方便,随时随地都可以学习。这样就可
阅读笔记(142):哪个更重要也是有阶段性的
卡拉咖啦
原文:《快速学习的几个基本原则》2016-04-21一、文章概要(还请以阅读原文为主,阅读笔记只表达了笔者的理解)(特别长)首先,快速学习,不是指"绝对的速度",而是应该是"总体上的效率"。另外,学习任何技能都是需要很多实践的,实践是需要时间的,所以"速成"从来都是一个伪概念。学习的最基本原则:培养自己成为进取型选手。0)无论是固化观念模式(表现型人格)还是成长观念模式(进取型人格),都是养成的,
java小白能学吗,掌握这些知识,零基础小白也能快速学好Java!
futa子
java小白能学吗
没基础如何快速学习Java开发?能靠自学吗?很多想学Java开发的人都会有这样的疑问。也有的人可能上来就直奔主题聊语法,小编的建议还是要对Java基本属性以及特点应用领域做个大概了解,可当做学习前的热身,同样对以后的就业也会有帮助。然后再学习方法重载、递归、包的使用。小编就主要来说说没基础如何快速学习Java开发!1、理解Java思想Java是一门面向对象编程语言。向对象编程是Java最核心的思想
对刘有卿战友文章的点评
专注执行
【文章】如何做好一个咨询项目【链接】https://www.jianshu.com/p/20c99666a172【点评】战友文章条理分明,前三项阐述做好咨询项目的基础要素,第四项提出快速学习让自己成为专家才更为关键。本篇文章,虽然说得是咨询项目,但我觉得其可普适范围很广,可以将这种项目思维应用于绝大多数人的日常工作中!非常值得借鉴与学习。要做好一件事,除了把握大局,细节的专业处理能力才是决定因素。
FLP-FRT系统--诱导性基因编辑inducible gene editing
Seurat_Satija
仍然还是那句话,如果想要快速学习一门新的技术,了解知识背景,看中文文章更好,如果有硕博士毕业论文那则是最佳。说到基因编辑技术,我一开始只知道(A)CRISPR/Cas9https://www.jianshu.com/p/b9d2a7203e6c在经过一系列挣扎之后,好不容易看懂了CRISPR/Cas9的原理,冷不丁冒出来一个(B)Cre/LoxP条件性敲除系统https://www.jianshu
如何在新媒体环境下快速做一场低成本大传播的活动?
木易小阳
在运营工作中,活动运营是非常重要的一部分,一场活动可扩大品牌推广、获取用户,进而实现销售转化。要做好一场活动最好的学习方式就是通过案例,即通过研究与拆解成功案例,可快速学习他人的经验,然后结合自身的情况运用到实际工作中。首先,我们要理解一场传播型活动的基本思路与结构是什么?要策划一个活动要思考两方面内容:1,确定活动要形式玩法与主题,2,找到活动的传播点与传播节奏。一、活动的形式玩法:即活动怎么玩
一切以消费为中心
南方谢叔
农耕到工业到后工业,我们走得太快。已经丢失了自己最初的面目。尤其是家长。在这个教育被过度消费的时代,操控自己的孩子,却不知道方向在哪里。我们自身并不都是名门望族,可是王侯将相宁有种乎?我们想快速学习提升自己,就像一夜暴富。如何呢?
推荐一个辅助阅读英文资料的 Chrome 沉浸式翻译扩展 - Immersive Translate
chrome
本公众号之前写过一些关于英语的文章:英语不好,对SAP英文文档有所畏惧,该怎么办?写作动机在于,有朋友在我的《零基础快速学习ABAP这套教程》的其中一篇文章里留言:哪里不懂点哪里F1.可是总是对英文文档有畏惧心理,汪老师有没有啥建议呀?感觉想要做好这一行这一点还是挺重要的。我当时也提到,如果条件允许,真的建议大家直接阅读SAP原版的英文文档。原因如下:SAP原版的英文文档最为权威,而官方网站上其他
Go1.22 新特性:终于增强 http.ServerMux 路由能力,将有更强的表现力!
go后端
大家好,我是煎鱼。Go1.22有一个比较重要的新特性,那就是基于提案《net/http:enhancedServeMuxrouting》,增强了http.ServerMux的路由匹配能力。非常值得大家学习和关注。本次的新特性主要是新增了HTTP方法和路径变量。快速学习在Go中,可以认为几乎所有的路由相关的库都会基于net/http或是兼容其interface。否则容易脱离一个标准路线。本文的主角S
4种高效学习方法,快速提升自己
月上小楼
1、费曼学习法FeynmanTechnique以教促学:以便于回想储存的信息。这个方法又称「快速学习法」,因为它可以迅速的找到对于刚刚学习过的知识生疏或者还没搞懂的地方,非常推荐!步骤如下:第一步:获取知识(某概念),理解你所要学习的材料的内容。第二步:讲解/复述你所获得的主要内容。第三步:用你自己的方式以潜意识的形式再次复述你所学到的知识。第四步:这一步是一个可循环过程:不满意——纠错反馈;满意
【Maven】依赖、构建管理 继承与聚合 快速学习(3.6.3 )
道格维克
后端 # JavaWeb maven 学习 java
文章目录Maven是什么?一、Maven安装和配置本地配置文件设置idea配置本地maven二、基于IDEA的Maven工程创建2.1Maven工程GAVP属性2.2Idea构建MavenJavaEE工程三、Maven工程项目结构说明四、Maven核心功能依赖和构建管理4.1依赖管理和配置4.2依赖传递和冲突4.3依赖导入失败场景和解决方案4.4扩展构建管理和插件配置五、Maven继承和聚合特性5
VUE2快速学习(必看)
小高求学之路
学习 前端 vue.js
小帅学习VUE[v-cloak]{display:none;}v-model用于表单的双向绑定{{val}}表单演示问卷调查姓名:性别:男女爱好:打篮球足球籍贯请选择陕西山西北京你的姓名是:{{name}},性别为:{{sex}},爱好是:{{hobby}},籍贯是:{{address}}提交v-bind绑定属性,动态的加载资源v-bind:可以简写成:轮播图效果展示:下一张上一张v-on给元素添
jvm调优总结(从基本概念 到 深度优化)
oloz
java jvm jdk 虚拟机 应用服务器
JVM参数详解:http://www.cnblogs.com/redcreen/archive/2011/05/04/2037057.html
Java虚拟机中,数据类型可以分为两类:基本类型和引用类型。基本类型的变量保存原始值,即:他代表的值就是数值本身;而引用类型的变量保存引用值。“引用值”代表了某个对象的引用,而不是对象本身,对象本身存放在这个引用值所表示的地址的位置。
【Scala十六】Scala核心十:柯里化函数
bit1129
scala
本篇文章重点说明什么是函数柯里化,这个语法现象的背后动机是什么,有什么样的应用场景,以及与部分应用函数(Partial Applied Function)之间的联系 1. 什么是柯里化函数
A way to write functions with multiple parameter lists. For instance
def f(x: Int)(y: Int) is a
HashMap
dalan_123
java
HashMap在java中对很多人来说都是熟的;基于hash表的map接口的非同步实现。允许使用null和null键;同时不能保证元素的顺序;也就是从来都不保证其中的元素的顺序恒久不变。
1、数据结构
在java中,最基本的数据结构无外乎:数组 和 引用(指针),所有的数据结构都可以用这两个来构造,HashMap也不例外,归根到底HashMap就是一个链表散列的数据
Java Swing如何实时刷新JTextArea,以显示刚才加append的内容
周凡杨
java 更新 swing JTextArea
在代码中执行完textArea.append("message")后,如果你想让这个更新立刻显示在界面上而不是等swing的主线程返回后刷新,我们一般会在该语句后调用textArea.invalidate()和textArea.repaint()。
问题是这个方法并不能有任何效果,textArea的内容没有任何变化,这或许是swing的一个bug,有一个笨拙的办法可以实现
servlet或struts的Action处理ajax请求
g21121
servlet
其实处理ajax的请求非常简单,直接看代码就行了:
//如果用的是struts
//HttpServletResponse response = ServletActionContext.getResponse();
// 设置输出为文字流
response.setContentType("text/plain");
// 设置字符集
res
FineReport的公式编辑框的语法简介
老A不折腾
finereport 公式 总结
FINEREPORT用到公式的地方非常多,单元格(以=开头的便被解析为公式),条件显示,数据字典,报表填报属性值定义,图表标题,轴定义,页眉页脚,甚至单元格的其他属性中的鼠标悬浮提示内容都可以写公式。
简单的说下自己感觉的公式要注意的几个地方:
1.if语句语法刚接触感觉比较奇怪,if(条件式子,值1,值2),if可以嵌套,if(条件式子1,值1,if(条件式子2,值2,值3)
linux mysql 数据库乱码的解决办法
墙头上一根草
linux mysql 数据库乱码
linux 上mysql数据库区分大小写的配置
lower_case_table_names=1 1-不区分大小写 0-区分大小写
修改/etc/my.cnf 具体的修改内容如下:
[client]
default-character-set=utf8
[mysqld]
datadir=/var/lib/mysql
socket=/va
我的spring学习笔记6-ApplicationContext实例化的参数兼容思想
aijuans
Spring 3
ApplicationContext能读取多个Bean定义文件,方法是:
ApplicationContext appContext = new ClassPathXmlApplicationContext(
new String[]{“bean-config1.xml”,“bean-config2.xml”,“bean-config3.xml”,“bean-config4.xml
mysql 基准测试之sysbench
annan211
基准测试 mysql基准测试 MySQL测试 sysbench
1 执行如下命令,安装sysbench-0.5:
tar xzvf sysbench-0.5.tar.gz
cd sysbench-0.5
chmod +x autogen.sh
./autogen.sh
./configure --with-mysql --with-mysql-includes=/usr/local/mysql
sql的复杂查询使用案列与技巧
百合不是茶
oracle sql 函数 数据分页 合并查询
本片博客使用的数据库表是oracle中的scott用户表;
------------------- 自然连接查询
查询 smith 的上司(两种方法)
&
深入学习Thread类
bijian1013
java thread 多线程 java多线程
一. 线程的名字
下面来看一下Thread类的name属性,它的类型是String。它其实就是线程的名字。在Thread类中,有String getName()和void setName(String)两个方法用来设置和获取这个属性的值。
同时,Thr
JSON串转换成Map以及如何转换到对应的数据类型
bijian1013
java fastjson net.sf.json
在实际开发中,难免会碰到JSON串转换成Map的情况,下面来看看这方面的实例。另外,由于fastjson只支持JDK1.5及以上版本,因此在JDK1.4的项目中可以采用net.sf.json来处理。
一.fastjson实例
JsonUtil.java
package com.study;
impor
【RPC框架HttpInvoker一】HttpInvoker:Spring自带RPC框架
bit1129
spring
HttpInvoker是Spring原生的RPC调用框架,HttpInvoker同Burlap和Hessian一样,提供了一致的服务Exporter以及客户端的服务代理工厂Bean,这篇文章主要是复制粘贴了Hessian与Spring集成一文,【RPC框架Hessian四】Hessian与Spring集成
在
【RPC框架Hessian二】Hessian 对象序列化和反序列化一文中
【Mahout二】基于Mahout CBayes算法的20newsgroup的脚本分析
bit1129
Mahout
#!/bin/bash
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information re
nginx三种获取用户真实ip的方法
ronin47
随着nginx的迅速崛起,越来越多公司将apache更换成nginx. 同时也越来越多人使用nginx作为负载均衡, 并且代理前面可能还加上了CDN加速,但是随之也遇到一个问题:nginx如何获取用户的真实IP地址,如果后端是apache,请跳转到<apache获取用户真实IP地址>,如果是后端真实服务器是nginx,那么继续往下看。
实例环境: 用户IP 120.22.11.11
java-判断二叉树是不是平衡
bylijinnan
java
参考了
http://zhedahht.blog.163.com/blog/static/25411174201142733927831/
但是用java来实现有一个问题。
由于Java无法像C那样“传递参数的地址,函数返回时能得到参数的值”,唯有新建一个辅助类:AuxClass
import ljn.help.*;
public class BalancedBTree {
BeanUtils.copyProperties VS PropertyUtils.copyProperties
诸葛不亮
PropertyUtils BeanUtils
BeanUtils.copyProperties VS PropertyUtils.copyProperties
作为两个bean属性copy的工具类,他们被广泛使用,同时也很容易误用,给人造成困然;比如:昨天发现同事在使用BeanUtils.copyProperties copy有integer类型属性的bean时,没有考虑到会将null转换为0,而后面的业
[金融与信息安全]最简单的数据结构最安全
comsci
数据结构
现在最流行的数据库的数据存储文件都具有复杂的文件头格式,用操作系统的记事本软件是无法正常浏览的,这样的情况会有什么问题呢?
从信息安全的角度来看,如果我们数据库系统仅仅把这种格式的数据文件做异地备份,如果相同版本的所有数据库管理系统都同时被攻击,那么
vi区段删除
Cwind
linux vi 区段删除
区段删除是编辑和分析一些冗长的配置文件或日志文件时比较常用的操作。简记下vi区段删除要点备忘。
vi概述
引文中并未将末行模式单独列为一种模式。单不单列并不重要,能区分命令模式与末行模式即可。
vi区段删除步骤:
1. 在末行模式下使用:set nu显示行号
非必须,随光标移动vi右下角也会显示行号,能够正确找到并记录删除开始行
清除tomcat缓存的方法总结
dashuaifu
tomcat 缓存
用tomcat容器,大家可能会发现这样的问题,修改jsp文件后,但用IE打开 依然是以前的Jsp的页面。
出现这种现象的原因主要是tomcat缓存的原因。
解决办法如下:
在jsp文件头加上
<meta http-equiv="Expires" content="0"> <meta http-equiv="kiben&qu
不要盲目的在项目中使用LESS CSS
dcj3sjt126com
Web less
如果你还不知道LESS CSS是什么东西,可以看一下这篇文章,是我一朋友写给新人看的《CSS——LESS》
不可否认,LESS CSS是个强大的工具,它弥补了css没有变量、无法运算等一些“先天缺陷”,但它似乎给我一种错觉,就是为了功能而实现功能。
比如它的引用功能
?
.rounded_corners{
[入门]更上一层楼
dcj3sjt126com
PHP yii2
更上一层楼
通篇阅读完整个“入门”部分,你就完成了一个完整 Yii 应用的创建。在此过程中你学到了如何实现一些常用功能,例如通过 HTML 表单从用户那获取数据,从数据库中获取数据并以分页形式显示。你还学到了如何通过 Gii 去自动生成代码。使用 Gii 生成代码把 Web 开发中多数繁杂的过程转化为仅仅填写几个表单就行。
本章将介绍一些有助于更好使用 Yii 的资源:
Apache HttpClient使用详解
eksliang
httpclient http协议
Http协议的重要性相信不用我多说了,HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性(具体区别,日后我们再讨论),它不仅是客户端发送Http请求变得容易,而且也方便了开发人员测试接口(基于Http协议的),即提高了开发的效率,也方便提高代码的健壮性。因此熟练掌握HttpClient是很重要的必修内容,掌握HttpClient后,相信对于Http协议的了解会
zxing二维码扫描功能
gundumw100
android zxing
经常要用到二维码扫描功能
现给出示例代码
import com.google.zxing.WriterException;
import com.zxing.activity.CaptureActivity;
import com.zxing.encoding.EncodingHandler;
import android.app.Activity;
import an
纯HTML+CSS带说明的黄色导航菜单
ini
html Web html5 css hovertree
HoverTree带说明的CSS菜单:纯HTML+CSS结构链接带说明的黄色导航
在线体验效果:http://hovertree.com/texiao/css/1.htm代码如下,保存到HTML文件可以看到效果:
<!DOCTYPE html >
<html >
<head>
<title>HoverTree
fastjson初始化对性能的影响
kane_xie
fastjson 序列化
之前在项目中序列化是用thrift,性能一般,而且需要用编译器生成新的类,在序列化和反序列化的时候感觉很繁琐,因此想转到json阵营。对比了jackson,gson等框架之后,决定用fastjson,为什么呢,因为看名字感觉很快。。。
网上的说法:
fastjson 是一个性能很好的 Java 语言实现的 JSON 解析器和生成器,来自阿里巴巴的工程师开发。
基于Mybatis封装的增删改查实现通用自动化sql
mengqingyu
DAO
1.基于map或javaBean的增删改查可实现不写dao接口和实现类以及xml,有效的提高开发速度。
2.支持自定义注解包括主键生成、列重复验证、列名、表名等
3.支持批量插入、批量更新、批量删除
<bean id="dynamicSqlSessionTemplate" class="com.mqy.mybatis.support.Dynamic
js控制input输入框的方法封装(数字,中文,字母,浮点数等)
qifeifei
javascript js
在项目开发的时候,经常有一些输入框,控制输入的格式,而不是等输入好了再去检查格式,格式错了就报错,体验不好。 /** 数字,中文,字母,浮点数(+/-/.) 类型输入限制,只要在input标签上加上 jInput="number,chinese,alphabet,floating" 备注:floating属性只能单独用*/
funct
java 计时器应用
tangqi609567707
java timer
mport java.util.TimerTask; import java.util.Calendar; public class MyTask extends TimerTask { private static final int
erlang输出调用栈信息
wudixiaotie
erlang
在erlang otp的开发中,如果调用第三方的应用,会有有些错误会不打印栈信息,因为有可能第三方应用会catch然后输出自己的错误信息,所以对排查bug有很大的阻碍,这样就要求我们自己打印调用的栈信息。用这个函数:erlang:process_display (self (), backtrace).需要注意这个函数只会输出到标准错误输出。
也可以用这个函数:erlang:get_s