前言:

本文介绍在 Ubuntu 18.04 中安装 Fabric, 并对 官方文档中的一个小案例(Using the Fabric test network)进行测试。

目的: 初步了解 Fabric 网络的执行步骤,调用,以及通过阅读样例链码,了解如何写链码

作为初学者,文中描述可能有不当,希望看到的人能够及时指出,大家一起学习。

1、首先确保环境安装好

  1. 安装 go https://www.cnblogs.com/faddei/p/13512691.html
  2. 安装 docker https://www.cnblogs.com/faddei/p/13512939.html
  3. 安装 jdk (可选) https://www.cnblogs.com/faddei/p/13512636.html

2、安装 Fabric 例子,二进制文件,镜像

找到 GoPath 所在的文件,如果根据上面的安装来,GOPATH=$HOME/go, 在这个目录下打开终端,输入

  1. curl -sSL https://bit.ly/2ysbOFE | bash -s

也可以用下面命令下载指定版本(以 fabric_version = 2.2.0,fabric-ca_version = 1.4.8 为例)

  1. curl -sSL https://bit.ly/2ysbOFE | bash -s -- <fabric_version> <fabric-ca_version>
  2. curl -sSL https://bit.ly/2ysbOFE | bash -s -- 2.2.0 1.4.8

Note!!!-------如果下载过程中由于网络问题出现错误,可以重新输入命令进行下载,已经下载的镜像会自动跳过,不会重复下载。

下载成功后会打印出所有的 hyperledger docker images,或者终端输入docker images也将出现以下结果

  1. ===> List out hyperledger docker images
  2. hyperledger/fabric-ca 1.4 152b9082adf6 2 weeks ago 158MB
  3. hyperledger/fabric-ca 1.4.8 152b9082adf6 2 weeks ago 158MB
  4. hyperledger/fabric-ca latest 152b9082adf6 2 weeks ago 158MB
  5. hyperledger/fabric-tools 2.2 5eb2356665e7 5 weeks ago 519MB
  6. hyperledger/fabric-tools 2.2.0 5eb2356665e7 5 weeks ago 519MB
  7. hyperledger/fabric-tools latest 5eb2356665e7 5 weeks ago 519MB
  8. hyperledger/fabric-peer 2.2 760f304a3282 5 weeks ago 54.9MB
  9. hyperledger/fabric-peer 2.2.0 760f304a3282 5 weeks ago 54.9MB
  10. hyperledger/fabric-peer latest 760f304a3282 5 weeks ago 54.9MB
  11. hyperledger/fabric-orderer 2.2 5fb8e97da88d 5 weeks ago 38.4MB
  12. hyperledger/fabric-orderer 2.2.0 5fb8e97da88d 5 weeks ago 38.4MB
  13. hyperledger/fabric-orderer latest 5fb8e97da88d 5 weeks ago 38.4MB
  14. hyperledger/fabric-ccenv 2.2 aac435a5d3f1 5 weeks ago 586MB
  15. hyperledger/fabric-ccenv 2.2.0 aac435a5d3f1 5 weeks ago 586MB
  16. hyperledger/fabric-ccenv latest aac435a5d3f1 5 weeks ago 586MB
  17. hyperledger/fabric-baseos 2.2 aa2bdf8013af 5 weeks ago 6.85MB
  18. hyperledger/fabric-baseos 2.2.0 aa2bdf8013af 5 weeks ago 6.85MB
  19. hyperledger/fabric-baseos latest aa2bdf8013af 5 weeks ago 6.85MB

在终端输入以下命令设置环境变量

  1. gedit ./.bashrc
  2. # 在下面添加以下命令, 路径根据自己的GoPath 以及 fabric-samples 路径。
  3. export PATH=/home/faddei/go/fabric-samples/bin:$PATH

保存后退出,

  1. # 激活环境变量
  2. source ./.bashrc

查看是否配置好

  1. peer version

出现以下即为安装成功,版本根据自己下载的指定版本,可能会有所不同

  1. peer:
  2. Version: 2.2.0
  3. Commit SHA: 5ea85bc54
  4. Go version: go1.14.4
  5. OS/Arch: linux/amd64
  6. Chaincode:
  7. Base Docker Label: org.hyperledger.fabric
  8. Docker Namespace: hyperledger

3、测试 Fabric 网络

  1. 测试脚本所在的位置 /home/faddei/go/fabric-samples 以你自己的路径为准, cd 进入这个文件夹

    1. cd ~/go/fabric-samples/test-network/
  2. 查看脚本的使用方法

    1. faddei@ubuntu:~/go/fabric-samples/test-network$ ./network.sh

    打印结果如下:

    1. Usage:
    2. network.sh <Mode> [Flags]
    3. Modes:
    4. up - bring up fabric orderer and peer nodes. No channel is created
    5. up createChannel - bring up fabric network with one channel
    6. createChannel - create and join a channel after the network is created
    7. deployCC - deploy the asset transfer basic chaincode on the channel or specify
    8. down - clear the network with docker-compose down
    9. restart - restart the network
    10. Flags:
    11. Used with network.sh up, network.sh createChannel:
    12. -ca <use CAs> - create Certificate Authorities to generate the crypto material
    13. -c <channel name> - channel name to use (defaults to "mychannel")
    14. -s <dbtype> - the database backend to use: goleveldb (default) or couchdb
    15. -r <max retry> - CLI times out after certain number of attempts (defaults to 5)
    16. -d <delay> - delay duration in seconds (defaults to 3)
    17. -i <imagetag> - the tag to be used to launch the network (defaults to "latest")
    18. -cai <ca_imagetag> - the image tag to be used for CA (defaults to "latest")
    19. -verbose - verbose mode
    20. Used with network.sh deployCC
    21. -c <channel name> - deploy chaincode to channel
    22. -ccn <name> - the short name of the chaincode to deploy: basic (default),ledger, private, sbe, secured
    23. -ccl <language> - the programming language of the chaincode to deploy: go (default), java, javascript, typescript
    24. -ccv <version> - chaincode version. 1.0 (default)
    25. -ccs <sequence> - chaincode definition sequence. Must be an integer, 1 (default), 2, 3, etc
    26. -ccp <path> - Optional, path to the chaincode. When provided the -ccn will be used as the deployed name and not the short name of the known chaincodes.
    27. -ccep <policy> - Optional, chaincode endorsement policy, using signature policy syntax. The default policy requires an endorsement from Org1 and Org2
    28. -cccg <collection-config> - Optional, path to a private data collections configuration file
    29. -cci <fcn name> - Optional, chaincode init required function to invoke. When provided this function will be invoked after deployment of the chaincode and will define the chaincode as initialization required.
    30. -h - print this message
    31. Possible Mode and flag combinations
    32. up -ca -c -r -d -s -i -verbose
    33. up createChannel -ca -c -r -d -s -i -verbose
    34. createChannel -c -r -d -verbose
    35. deployCC -ccn -ccl -ccv -ccs -ccp -cci -r -d -verbose
    36. Taking all defaults:
    37. network.sh up
    38. Examples:
    39. network.sh up createChannel -ca -c mychannel -s couchdb -i 2.0.0
    40. network.sh createChannel -c channelName
    41. network.sh deployCC -ccn basic -ccl javascript
    42. network.sh deployCC -ccn mychaincode -ccp ./user/mychaincode -ccv 1 -ccl javascript
  3. 了解了脚本的使用方法之后,在启动项目脚本之前,先 执行下面的命令将 之前运行过的容器清除掉如果有的话。(Note, up 之前 记住 要 down 一下)

    1. ./network.sh down
  4. 确保你所在当前路径是正确的即 ~/go/fabric-samples/test-network ,以自己的为准

  5. 接下来启动网络

    1. ./network.sh up

    这个命令会创建一个包含 两个 peer 节点和一个 order 节点的 Fabric 网络。如果这个命令成功运行,终端上将会显示以下日志

    1. Creating network "net_test" with the default driver
    2. Creating volume "net_orderer.example.com" with default driver
    3. Creating volume "net_peer0.org1.example.com" with default driver
    4. Creating volume "net_peer0.org2.example.com" with default driver
    5. Creating peer0.org1.example.com ... done
    6. Creating orderer.example.com ... done
    7. Creating peer0.org2.example.com ... done
    8. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    9. 9eea87fad9bc hyperledger/fabric-orderer:latest "orderer" 3 seconds ago Up Less than a second 0.0.0.0:7050->7050/tcp orderer.example.com
    10. b0662814ecfe hyperledger/fabric-peer:latest "peer node start" 3 seconds ago Up Less than a second 7051/tcp, 0.0.0.0:9051->9051/tcp peer0.org2.example.com
    11. b256cee7e51f hyperledger/fabric-peer:latest "peer node start" 3 seconds ago Up Less than a second 0.0.0.0:7051->7051/tcp peer0.org1.example.com
  6. 继续进行之前,先看一下 Fabric 网络的组成

    1. docker ps -a

    结果如下

    1. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    2. 9eea87fad9bc hyperledger/fabric-orderer:latest "orderer" 41 seconds ago Up 39 seconds 0.0.0.0:7050->7050/tcp orderer.example.com
    3. b0662814ecfe hyperledger/fabric-peer:latest "peer node start" 41 seconds ago Up 38 seconds 7051/tcp, 0.0.0.0:9051->9051/tcp peer0.org2.example.com
    4. b256cee7e51f hyperledger/fabric-peer:latest "peer node start" 41 seconds ago Up 38 seconds 0.0.0.0:7051->7051/tcp peer0.org1.example.com
    • Peer :

      ​ 每一个需要与 Fabric 网络交互的节点或用户都需要属于一定的组织,也即联盟中的一个成员。 这个测试网络有两个联盟(consortium)成员, org1 和 org2。 这个网络也包含一个 维持 Fabric 网络中排序服务的 order 组织

      ​ peer 节点是 Fabric 网络中重要的组成部分, peer 节点存储 区块链中的账本,并在交易被写进账本之前验证交易的合法性。 同时 peer 节点还运行包含着用来管理区块链帐本中资产的商业逻辑的智能合约。

      ​ Fabric 网络中的节点都需要属于联盟中的一个成员,在这个测试网络中,每一个组织操作一个 peer 节点, peer0.org1.example.compeer0.org2.example.com

    • Order:

      ​ 每一个 Fabric 网络中都包含一个排序服务。 虽然 peer 节点验证交易的合法性并将包含交易的区块写进区块链中, 但是他们无法决定 交易的顺序,也无法将他们包含进新的区块中。在一个分布式网络中,peer 节点可能距离十分遥远,当一个交易被创建的时候,这些peer 节点没有一个共识。因此,对交易的顺序达成一致将是一个非常大的花销。

      ​ 排序服务允许peer 节点专注于验证交易并将交易提交到账本中。在排序节点从客户端接收到以背书的交易之后,它们就交易的顺序达成一致,然后将其添加到块中。然后这些区块将被分发到 peer 节点, 这些peer节点将区块添加到区块链账本中。排序节点还操作定义Fabric网络容量的系统通道,例如如何创建区块并且决定节点使用哪个版本的Fabric。系统通道定义了哪些组织是联盟的成员。

    这个 sample 网络 使用由排序组织提供的单节点的 Raft 排序服务。 真实的网络可能使用由一个或多个排序组织提供的多个排序节点。不同的排序节点将使用 Raft 共识算法来就整个网络的事务顺序达成一致。

  7. 创建一个通道

    ​ 现在可以使用脚本来为 org1 和 org2 之间的交易来创建一个 Fabric 通道。 通道是特定网络成员之间通信的私有层。通道只能被邀请到通道的组织使用,并且对网络的其他成员不可见。每一个通道都有一个独立的区块链账本。

    使用以下脚本创建通道(创建通道的名称默认为 “mychannel”, 可以使用 -c 指定名称)

    1. ./network.sh createChannel

    如果命令执行成功,终端日志中会出现以下结果

    1. ========= Channel successfully joined ===========
  8. 在通道中部署链码

    ​ 创建好通道之后,就可以使用智能合约与通道账本交互。智能合约包含管理区块链账本上资产的业务逻辑。由网络成员运行的应用程序能够调用智能合约来创建,改变,以及转移资产。同时也可以调用智能合约来查询账本中的数据

    ​ 为了确保交易是有效的,使用智能合约创建的交易通常需要由多个组织签署,并提交给通道账本。多重签名对于 Fabric 的信任模型来说是不可或缺的。要求对一笔交易进行多重背书,可以防止一个通道上的组织篡改peer的账本,或使用未经同意的业务逻辑。为了签署交易,每个组织需要在其peer 节点上调用并执行智能契约,然后由对等方签署事务的输出。为了签署交易,每个组织需要在其peer上调用并执行智能合约,然后由peer签署交易的输出。如果输出是一致的,并且有足够多的组织签署,交易可以提交到总账。指定通道上需要执行智能合约的集合组织的策略称为背书策略,该策略为每个链码设置,作为链码定义的一部分。

    ​ 在 Fabric 中,智能合约以被称为链码的包部署在网络中。

    使用下面的命令在通道中部署链码

    1. # 我指定的是Java, 可以自己选择 go (default), java, javascript, typescript
    2. ./network.sh deployCC -ccl java

    指定 Java 这里可能有一个坑:

    1. Could not unzip /home/faddei/.gradle/wrapper/dists/gradle-6.5.1-bin/1m5048aptkfynhbvolwgr4ej9/gradle-6.5.1-bin.zip to /home/faddei/.gradle/wrapper/dists/gradle-6.5.1-bin/1m5048aptkfynhbvolwgr4ej9.
    2. Reason: error in opening zip file
    3. Exception in thread "main" java.util.zip.ZipException: error in opening zip file
    4. at java.util.zip.ZipFile.open(Native Method)
    5. at java.util.zip.ZipFile.<init>(ZipFile.java:225)
    6. at java.util.zip.ZipFile.<init>(ZipFile.java:155)
    7. at java.util.zip.ZipFile.<init>(ZipFile.java:169)
    8. at org.gradle.wrapper.Install.unzip(Install.java:219)
    9. at org.gradle.wrapper.Install.access$600(Install.java:27)
    10. at org.gradle.wrapper.Install$1.call(Install.java:75)
    11. at org.gradle.wrapper.Install$1.call(Install.java:48)
    12. at org.gradle.wrapper.ExclusiveFileAccessManager.access(ExclusiveFileAccessManager.java:69)
    13. at org.gradle.wrapper.Install.createDist(Install.java:48)
    14. at org.gradle.wrapper.WrapperExecutor.execute(WrapperExecutor.java:107)
    15. at org.gradle.wrapper.GradleWrapperMain.main(GradleWrapperMain.java:63)

    解决方法,从 gradle 官网下载 https://gradle.org/releases/ 上面的 6.5.1 版本到指定文件下,然后手动解压缩到 to 后面的那个文件加下。重新运行命令,成功部署。

  9. 通过链码与网络交互

    ​ 成功部署完链码之后,可以使用 peer CLI 来与 Fabric 网络进行交互。 peer CLI 允许调用已经部署好的智能合约,更新通道,或者从 CLI 安装部署新的智能合约。

    添加环境变量

    1. # 因为第二步已经在 ~/.bashrc 文件下设置过该环境变量,所以如果 在终端中 输入 peer version 有结果显示的话,下面这个命令可以跳过
    2. # 如果没有 就要设置一下
    3. export PATH=${PWD}/../bin:$PATH

    同时也需要设置 FABRIC_CFG_PATH 指向 core.yaml

    1. export FABRIC_CFG_PATH=$PWD/../config/

    设置允许操作 peer CLI 作为 org1 的环境变量

    1. # Environment variables for Org1
    2. export CORE_PEER_TLS_ENABLED=true
    3. export CORE_PEER_LOCALMSPID="Org1MSP"
    4. export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
    5. export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
    6. export CORE_PEER_ADDRESS=localhost:7051

    接下来开始与智能合约进行交互

    1. 使用下面的命令初始化账本中的资产

      1. peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n basic --peerAddresses localhost:7051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"function":"InitLedger","Args":[]}'

      如果成功的话,终端日志中会打印如下:

      1. -> INFO 001 Chaincode invoke successful. result: status:200
    2. 现在可以从 CLI 中查询账本。

      1. # 下面命令获取全部资产
      2. peer chaincode query -C mychannel -n basic -c '{"Args":["GetAllAssets"]}'

      成功的话会输出这样一串字符串。

      1. [
      2. {"ID": "asset1", "color": "blue", "size": 5, "owner": "Tomoko", "appraisedValue": 300},
      3. {"ID": "asset2", "color": "red", "size": 5, "owner": "Brad", "appraisedValue": 400},
      4. {"ID": "asset3", "color": "green", "size": 10, "owner": "Jin Soo", "appraisedValue": 500},
      5. {"ID": "asset4", "color": "yellow", "size": 10, "owner": "Max", "appraisedValue": 600},
      6. {"ID": "asset5", "color": "black", "size": 15, "owner": "Adriana", "appraisedValue": 700},
      7. {"ID": "asset6", "color": "white", "size": 15, "owner": "Michel", "appraisedValue": 800}
      8. ]
    3. 使用下面的命令转移资产

      1. peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n basic --peerAddresses localhost:7051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"function":"TransferAsset","Args":["asset6","Christopher"]}'

      执行成功会有下面的日志, 说明 asset6 已经被成功转移到 Christopher 名下

      1. -> INFO 001 Chaincode invoke successful. result: status:200 payload:"{\"owner\":\"Christopher\",\"color\":\"white\",\"size\":15,\"appraisedValue\":700,\"assetID\":\"asset6\"}"

      因为 asset-transfer (basic) chaincode 的背书策略要求 org1 和 org2 共同签署, 所以链码调用命令需要使用 --peerAddresses 标志同时指向 peer0.org1.example.compeer0.org2.example.com

      因为 网络启用了 TLS ,命令还需要使用 --tlsRootCertFiles 标志来为每个节点引用 TLS 整数。

    4. 查询asset6的的状态

      1. peer chaincode query -C mychannel -n basic -c '{"Args":["ReadAsset","asset6"]}'

      结果如下:

      1. {"owner":"Christopher","color":"white","size":15,"appraisedValue":700,"assetID":"asset6"}
    5. 上面是对 org1 的操作,也可以操作 org2。也可以操作org2

      设置环境变量

      1. # Environment variables for Org2
      2. export CORE_PEER_TLS_ENABLED=true
      3. export CORE_PEER_LOCALMSPID="Org2MSP"
      4. export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
      5. export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
      6. export CORE_PEER_ADDRESS=localhost:9051
    6. 查询 asset6 的状态,结果同上

  10. 关闭网络

    1. ./network.sh down

    该命令将停止并删除节点和链码容器,删除组织密码材料,并从你的Docker注册表中删除链码图像。

Ubuntu18.04 安装 Fabric & 使用 Fabric 测试网络的更多相关文章

  1. Ubuntu18.04安装Virtualenv虚拟环境

    在Ubuntu18.04安装Virtualenv虚拟环境 [实验环境]: 在这台电脑上已经安装了python3 [安装参考] 1.查看是否已安装virtualenv virtualenv --vers ...

  2. Ubuntu18.04安装Docker, centos7安装Docker

    Ubuntu18.04安装Docker 第一种方法从Ubuntu的仓库直接下载安装: 安装比较简单,这种安装的Docker不是最新版本,不过对于学习够用了,依次执行下面命令进行安装. $ sudo a ...

  3. ubuntu18.04 安装UHD+GNU Radio

    参考链接: ubuntu16.04下安装uhd与gnuradio:https://blog.csdn.net/qq_37748396/article/details/80339366 GNU Radi ...

  4. Ubuntu18.04安装OpenCV4.1.0

    Ubuntu18.04安装OpenCV4.1.0 1.首先要安装依赖 sudo apt-get install build-essential \ cmake git libgtk2.0-dev pk ...

  5. Ubuntu18.04安装 NVIDIA驱动

    Ubuntu18.04安装 NVIDIA驱动 参考自博客:https://blog.csdn.net/jsjason1/article/details/88086904 我确定这篇文章是否很有必要,我 ...

  6. Ubuntu18.04安装RTX2080Ti+NVIDIA驱动+CUDA

    Ubuntu18.04安装RTX 2080Ti 与 Cuda10 ==========血泪更新========= 如果可以使用ppa安装最方便了 具体参考:https://www.cnblogs.co ...

  7. Ubuntu18.04安装mysql5.7

    Ubuntu18.04安装mysql5.7 1.1安装 首先执行下面三条命令: # 安装mysql服务 sudo apt-get install mysql-server # 安装客户端 sudo a ...

  8. Ubuntu18.04安装RabbitMQ

    Ubuntu18.04安装RabbitMQ 2018年06月10日 19:32:38 dmfrm 阅读数:2492    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog ...

  9. ubuntu18.04 安装mysql不出现设置 root 帐户的密码问题(装)

    ubuntu18.04 安装mysql不出现设置 root 帐户的密码问题      https://blog.csdn.net/NeptuneClouds/article/details/80995 ...

  10. ubuntu18.04 安装hadoop 2.7.3+hive 2.3.4

    1. 安装hadoop 详细请参见本人的另外一片博文<Hadoop 2.7.3 分布式集群安装> 2. 下载hive 2.3.4 解压文件到/opt/software -bin.tar.g ...

随机推荐

  1. 如何导入spring 的jar包到eclips

    https://www.cnblogs.com/xxuan/p/6949640.html

  2. DOM事件操作

    DOM事件:对事件做出反应 当事件发生时,可以执行 JavaScript,比如:点击时 onClick="" 例:当用户点击时,会改变 <h1> 元素的内容: < ...

  3. 一切皆组件的Flutter,安能辨我是雄雌

    从一开始接触Flutter,相信读者都会铭记一句话,那就是--一切皆组件.今天我们就来体会一下这句话的神奇魔力,我们先从实际的产品需求说起. 我们先来看一个简化的运行图: 我们要实现如上图所示的日期选 ...

  4. 一分钟玩转 Spring IoC

    前言 「上一篇文章」我们对 Spring 有了初步的认识,而 Spring 全家桶中几乎所有组件都是依赖于 IoC 的. 刚开始听到 IoC,会觉得特别高大上,但其实掰开了很简单. 跟着我的脚步,一文 ...

  5. Spring Data R2DBC响应式操作MySQL

    1. 前言 在使用R2DBC操作MySQL数据库 一文中初步介绍了r2dbc-mysql的使用.由于借助DatabaseClient操作MySQL,过于初级和底层,不利于开发.今天就利用Spring ...

  6. IntelliJ IDEA 2019.3.4永久破解(持续更新)--已更新

    第一步,下载最新破解包: 链接: https://pan.baidu.com/s/1djUF9TiNZC4rIfxczxfIew 提取码: f521 把破解包两个文件放进bin目录下,这一步极为重要! ...

  7. SUM and COUNT -- SQLZOO

    SUM and COUNT 注意:where语句中对表示条件的需要用单引号, 下面的译文使用的是有道翻译如有不正确,请直接投诉有道 01.Show the total population of th ...

  8. Java中15种锁的介绍

    作者:搜云库技术团队 原文:https://segmentfault.com/a/1190000017766364 1. Java 中15种锁的介绍 在读很多并发文章中,会提及各种各样锁如公平锁,乐观 ...

  9. Linux下关闭防火墙

    1:查看防火状态 **systemctl status firewalld** **service iptables status** 2:暂时关闭防火墙 systemctl stop firewal ...

  10. 实验03——java十进制转二、八、十六进制;打印'中'的十六进制;进制转换的api

    package cn.tedu.demo; /** * @author 赵瑞鑫 E-mail:1922250303@qq.com * @version 创建时间:2020年7月16日 上午10:22: ...