挑战杯 python区块链实现 - proof of work工作量证明共识算法

文章目录

  • 0 前言
  • 1 区块链基础
    • 1.1 比特币内部结构
    • 1.2 实现的区块链数据结构
    • 1.3 注意点
    • 1.4 区块链的核心-工作量证明算法
      • 1.4.1 拜占庭将军问题
      • 1.4.2 解决办法
      • 1.4.3 代码实现
  • 2 快速实现一个区块链
    • 2.1 什么是区块链
    • 2.2 一个完整的快包含什么
    • 2.3 什么是挖矿
    • 2.4 工作量证明算法:
    • 2.5 实现代码
  • 3 最后

0 前言

🔥 优质竞赛项目系列,今天要分享的是

python区块链实现 - proof of work工作量证明共识算法

该项目较为新颖,适合作为竞赛课题方向,学长非常推荐!

🧿 更多资料, 项目分享:

https://gitee.com/dancheng-senior/postgraduate

在这里插入图片描述

1 区块链基础

学长以比特币的结构向大家详解区块链的组成部分

1.1 比特币内部结构

  • previous hash(前一个区块的hash)
  • merkle root(默克尔树根节点,内部存储交易数据)
  • timestamp(当前区块生成的时间)
  • nonce(旷工计算hash值次数)

在这里插入图片描述

1.2 实现的区块链数据结构

  • index 当前第几个区块
  • timestamp 该区块创建时的时间戳
  • data 交易信息
  • previousHash 前一个区块的hash
  • hash 当前区块的hash

1.3 注意点

第一个区块叫做创世区块(genesis block),区块链创建的时候默认生产的这里用的是单纯的链表,不是用默克尔树存储

示例代码



    from hashlib import sha256
    //区块schema
    class Block:
         
        def __init__(self,index,timestamp,data,previousHash=""):
            
            self.index = index
            self.timestamp = timestamp
            self.data = data
            self.previousHash = previousHash
            self.hash = self.calculateHash()
            
        //计算当前区块的hashdef calculateHash(self):
            plainData = str(self.index)+str(self.timestamp)+str(self.data)
            return sha256(plainData.encode('utf-8')).hexdigest()
        
        def __str__(self):
            return str(self.__dict__)
     //区块链schema
    class BlockChain:
        //初始化的时候 创建 创世区块
        def __init__(self):
            self.chain = [self.createGenesisBlock()]
        //构建创世区块
        def createGenesisBlock(self):
            return Block(0,"01/01/2018","genesis block","0")
        //获取最后一个区块
        def getLatestBlock(self):
            return self.chain[len(self.chain)-1]
        //往区块链里面添加区块
        def addBlock(self,newBlock):
            newBlock.previousHash = self.getLatestBlock().hash
            newBlock.hash = newBlock.calculateHash()
            self.chain.append(newBlock)
        
        def __str__(self):
            return str(self.__dict__)    
        //校验区块链是不是有效的 有没有人被篡改
        def chainIsValid(self):
            for index in range(1,len(self.chain)):
                currentBlock = self.chain[index]
                previousBlock = self.chain[index-1]
                if (currentBlock.hash != currentBlock.calculateHash()):
                    return False
                if previousBlock.hash != currentBlock.previousHash:
                    return False
            return True


myCoin = BlockChain()
myCoin.addBlock(Block(1,"02/01/2018","{amount:4}"))
myCoin.addBlock(Block(2,"03/01/2018","{amount:5}"))

#print block info 打印区块链信息
print("print block info ####:")
for block in myCoin.chain:
    print(block)
#check blockchain is valid 检查区块链是不是有效的
print("before tamper block,blockchain is valid ###")
print(myCoin.chainIsValid())
#tamper the blockinfo  篡改区块2的数据
myCoin.chain[1].data = "{amount:1002}"
print("after tamper block,blockchain is valid ###")
print(myCoin.chainIsValid())


输出结果

print block info ####:
{'index': 0, 'timestamp': '01/01/2018', 'data': 'genesis block', 'previousHash': '0', 'hash': 'd8d21e5ba33780d5eb77d09d3b407ceb8ade4e5545ef951de1997b209d91e264'}
{'index': 1, 'timestamp': '02/01/2018', 'data': '{amount:4}', 'previousHash': 'd8d21e5ba33780d5eb77d09d3b407ceb8ade4e5545ef951de1997b209d91e264', 'hash': '15426e32db30f4b26aa719ba5e573f372f41e27e4728eb9e9ab0bea8eae63a9d'}
{'index': 2, 'timestamp': '03/01/2018', 'data': '{amount:5}', 'previousHash': '15426e32db30f4b26aa719ba5e573f372f41e27e4728eb9e9ab0bea8eae63a9d', 'hash': '75119e897f21c769acee6e32abcefc5e88e250a1f35cc95946379436050ac2f0'}
before tamper block,blockchain is valid ###
True
after tamper block,blockchain is valid ###
False

1.4 区块链的核心-工作量证明算法

上面学长介绍了区块链的基本结构,我在之前的基础上来简单实现一下工作量证明算法(proof of
work),在介绍pow之前先思考一下为什么要工作量证明算法,或者再往前想一步为什么比特币如何解决信任的问题?

1.4.1 拜占庭将军问题

比特币出现之前就有了拜占庭将军问题,主要思想是,如何在分布式系统环境里去相信其他人发给你的信息?

一组拜占庭将军分别各率领一支军队共同围困一座城市。为了简化问题,将各支军队的行动策略限定为进攻或撤离两种。因为部分军队进攻部分军队撤离可能会造成灾难性后果,因此各位将军必须通过投票来达成一致策略,即所有军队一起进攻或所有军队一起撤离。因为各位将军分处城市不同方向,他
系统的问题在于,将军中可能出现叛徒,他们不仅可能向较为糟糕的策略投票,还可能选择性地发送投票信息。假设有9位将军投票,其中1名叛徒。8名忠诚的将军中出现了4人投进攻,4人投撤离的情况。这时候叛徒可能故意给4名投进攻的将领送信表示投票进攻,而给4名投撤离的将领送信表示投撤离。这样一来在4名投进攻的将领看来,投票结果是5人投进攻,从而发起进攻;而在4名投撤离的将军看来则是5人投撤离。这样各支军队的一致协同就遭到了破坏。

在这里插入图片描述

1.4.2 解决办法

拜占庭将军问题主要问题是,中间人可以拦截消息,进行修改;上述的那些士兵可以理解成比特币中的一些节点,不是所有节点拿到消息后都是可以直接处理的,先去解决一个数学问题,就是工作量证明,只有拥有特定的计算能力解决了问题之后才能去修改或者校验(验证,打包,上链)。

在这里插入图片描述
上图就是简单的工作量证明算法流程,一串数字后面有个x,x之前的数可以理解成交易数据,然后需要找到一个x,让整个数的hash值的开头有n个0,如果hash是很均匀的话,那么生成的hash值每一位为0或者1都是等可能的,所以前n个都为0的概率就是2的n次方/2的hash值位数,上图给出了如果hash值是5个bit的情况下的所有可能

1.4.3 代码实现



    from hashlib import sha256
    import time
    class Block:
         
        def __init__(self,index,timestamp,data,previousHash=""):
            
            self.index = index
            self.timestamp = timestamp
            self.data = data
            self.previousHash = previousHash
            self.nonce = 0 //代表当前计算了多少次hash计算
            self.hash = self.calculateHash()


        def calculateHash(self):
            plainData = str(self.index)+str(self.timestamp)+str(self.data)+str(self.nonce)
            return sha256(plainData.encode('utf-8')).hexdigest()
        #挖矿 difficulty代表复杂度 表示前difficulty位都为0才算成功
        def minerBlock(self,difficulty):
            while(self.hash[0:difficulty]!=str(0).zfill(difficulty)):
                self.nonce+=1
                self.hash = self.calculateHash()
        
        def __str__(self):
            return str(self.__dict__)


    class BlockChain:
        
        def __init__(self):
            self.chain = [self.createGenesisBlock()]
            self.difficulty = 5
    
        def createGenesisBlock(self):
            return Block(0,"01/01/2018","genesis block")
        
        def getLatestBlock(self):
            return self.chain[len(self.chain)-1]
        #添加区块前需要 做一道计算题😶,坐完后才能把区块加入到链上
        def addBlock(self,newBlock):
            newBlock.previousHash = self.getLatestBlock().hash
            newBlock.minerBlock(self.difficulty)
            self.chain.append(newBlock)

        def __str__(self):
            return str(self.__dict__)    
        
        def chainIsValid(self):
            for index in range(1,len(self.chain)):
                currentBlock = self.chain[index]
                previousBlock = self.chain[index-1]
                if (currentBlock.hash != currentBlock.calculateHash()):
                    return False
                if previousBlock.hash != currentBlock.previousHash:
                    return False
            return True
           

    myCoin = BlockChain()
    
    # 下面打印了每个区块挖掘需要的时间 比特币通过一定的机制控制在10分钟出一个块 
    # 其实就是根据当前网络算力 调整我们上面difficulty值的大小,如果你在
    # 本地把上面代码difficulty的值调很大你可以看到很久都不会出计算结果
    startMinerFirstBlockTime = time.time()
    print("start to miner first block time :"+str(startMinerFirstBlockTime))
    
    myCoin.addBlock(Block(1,"02/01/2018","{amount:4}"))
    
    print("miner first block time completed" + ",used " +str(time.time()-startMinerFirstBlockTime) +"s")
    
    startMinerSecondBlockTime = time.time()
    
    print("start to miner first block time :"+str(startMinerSecondBlockTime))
    
    myCoin.addBlock(Block(2,"03/01/2018","{amount:5}"))
    
    print("miner second block time completed" + ",used " +str(time.time()-startMinerSecondBlockTime) +"s\n")
    
    #print block info
    print("print block info ####:\n")
    for block in myCoin.chain:
        print("\n")
        print(block)
        
    #check blockchain is valid
    print("before tamper block,blockchain is valid ###")
    print(myCoin.chainIsValid())
    
    #tamper the blockinfo
    myCoin.chain[1].data = "{amount:1002}"
    print("after tamper block,blockchain is valid ###")
    print(myCoin.chainIsValid())


输出

在这里插入图片描述

2 快速实现一个区块链

2.1 什么是区块链

区块链是一个不可变得,有序的被称之为块的记录链,它们可以包含交易、文件或者任何你喜欢的数据,但最重要的是,它们用hash连接在一起。

2.2 一个完整的快包含什么

一个索引,一个时间戳,一个事物列表,一个校验, 一个前快的散链表

2.3 什么是挖矿

挖矿其实非常简单就做了以下三件事:

1、计算工作量证明poW
2、通过新增一个交易赋予矿工(自已)一个币
3、构造新区块并将其添加到链中

2.4 工作量证明算法:

使用该算法来证明是如何在区块上创建和挖掘新的区块,pow的目标是计算出一个符合特定条件的数字,这个数字对于所有人而言必须在计算上非常困难,但易于验证,这就是工作证明背后的核心思想计算难度与目标字符串需要满足的特定字符串成正比。

2.5 实现代码



    import hashlib
    import json
    import requests
    from textwrap import dedent
    from time import time
    from uuid import uuid4
    from urllib.parse import urlparse
    from flask import Flask, jsonify, request
    
    class Blockchain(object):
        def __init__(self):
            ...
            self.nodes = set()
            # 用 set 来储存节点,避免重复添加节点.
            ...
            self.chain = []
            self.current_transactions = []
    
            #创建创世区块
            self.new_block(previous_hash=1,proof=100)
    
        def reister_node(self,address):
            """
            在节点列表中添加一个新节点
            :param address:
            :return:
            """
            prsed_url = urlparse(address)
            self.nodes.add(prsed_url.netloc)
    
        def valid_chain(self,chain):
            """
            确定一个给定的区块链是否有效
            :param chain:
            :return:
            """
            last_block = chain[0]
            current_index = 1
    
            while current_index<len(chain):
                block = chain[current_index]
                print(f'{last_block}')
                print(f'{block}')
                print("\n______\n")
                # 检查block的散列是否正确
                if block['previous_hash'] != self.hash(last_block):
                    return False
                # 检查工作证明是否正确
                if not self.valid_proof(last_block['proof'], block['proof']):
                    return False
    
                last_block = block
                current_index += 1
            return True

        def ressolve_conflicts(self):
            """
            共识算法
            :return:
            """
            neighbours = self.nodes
            new_chain = None
            # 寻找最长链条
            max_length = len(self.chain)
    
            # 获取并验证网络中的所有节点的链
            for node in neighbours:
                response = requests.get(f'http://{node}/chain')
    
                if response.status_code == 200:
                    length = response.json()['length']
                    chain = response.json()['chain']
    
                    # 检查长度是否长,链是否有效
                    if length > max_length and self.valid_chain(chain):
                        max_length = length
                        new_chain = chain
    
            # 如果发现一个新的有效链比当前的长,就替换当前的链
            if new_chain:
                self.chain = new_chain
                return True
            return False
    
        def new_block(self,proof,previous_hash=None):
            """
            创建一个新的块并将其添加到链中
            :param proof: 由工作证明算法生成证明
            :param previous_hash: 前一个区块的hash值
            :return: 新区块
            """
            block = {
                'index':len(self.chain)+1,
                'timestamp':time(),
                'transactions':self.current_transactions,
                'proof':proof,
                'previous_hash':previous_hash or self.hash(self.chain[-1]),
            }
    
            # 重置当前交易记录
            self.current_transactions = []
    
            self.chain.append(block)
            return block
    
        def new_transaction(self,sender,recipient,amount):
            # 将新事务添加到事务列表中
            """
            Creates a new transaction to go into the next mined Block
            :param sender:发送方的地址
            :param recipient:收信人地址
            :param amount:数量
            :return:保存该事务的块的索引
            """
            self.current_transactions.append({
                'sender':sender,
                'recipient':recipient,
                'amount':amount,
            })
    
            return  self.last_block['index'] + 1

        @staticmethod
        def hash(block):
            """
            给一个区块生成 SHA-256 值
            :param block:
            :return:
            """
            # 必须确保这个字典(区块)是经过排序的,否则将会得到不一致的散列
            block_string = json.dumps(block,sort_keys=True).encode()
            return hashlib.sha256(block_string).hexdigest()
    
        @property
        def last_block(self):
            # 返回链中的最后一个块
            return self.chain[-1]

        def proof_of_work(self,last_proof):
            # 工作算法的简单证明
            proof = 0
            while self.valid_proof(last_proof,proof)is False:
                proof +=1
            return proof
    
        @staticmethod
        def valid_proof(last_proof,proof):
            # 验证证明
            guess =  f'{last_proof}{proof}'.encode()
            guess_hash = hashlib.sha256(guess).hexdigest()
            return guess_hash[:4] =="0000"


    # 实例化节点
    app = Flask(__name__)
    
    # 为该节点生成一个全局惟一的地址
    node_identifier = str(uuid4()).replace('-','')
    
    # 实例化Blockchain类
    blockchain = Blockchain()
    
    # 进行挖矿请求
    @app.route('/mine',methods=['GET'])
    def mine():
        # 运行工作算法的证明来获得下一个证明。
        last_block = blockchain.last_block
        last_proof = last_block['proof']
        proof = blockchain.proof_of_work(last_proof)
    
        # 必须得到一份寻找证据的奖赏。
        blockchain.new_transaction(
            sender="0",
            recipient=node_identifier,
            amount=1,
        )
    
        # 通过将其添加到链中来构建新的块
        previous_hash = blockchain.hash(last_block)
        block = blockchain.new_block(proof,previous_hash)
        response = {
            'message': "New Block Forged",
            'index': block['index'],
            'transactions': block['transactions'],
            'proof': block['proof'],
            'previous_hash': block['previous_hash'],
        }
        return jsonify(response), 200
    
    # 创建交易请求
    @app.route('/transactions/new',methods=['POST'])
    def new_transactions():
        values = request.get_json()
    
        # 检查所需要的字段是否位于POST的data中
        required = ['seder','recipient','amount']
        if not all(k in values for k in request):
            return 'Missing values',400
    
        #创建一个新的事物
        index = blockchain.new_transaction(values['sender'], values['recipient'], values['amount'])
        response = {'message': f'Transaction will be added to Block {index}'}
        return jsonify(response), 201
    
    # 获取所有快信息
    @app.route('/chain',methods=['GET'])
    def full_chain():
        response = {
            'chain':blockchain.chain,
            'length':len(blockchain.chain),
        }
        return jsonify(response),200
    
    # 添加节点
    @app.route('/nodes/register',methods=['POST'])
    def  register_nodes():
        values = request.get_json()
        nodes = values.get('nodes')
        if nodes is None:
            return "Error: Please supply a valid list of nodes", 400
    
        for node in nodes:
            blockchain.register_node(node)
    
        response = {
            'message': 'New nodes have been added',
            'total_nodes': list(blockchain.nodes),
        }
        return jsonify(response), 201
    
    # 解决冲突
    @app.route('/nodes/resolve', methods=['GET'])
    def consensus():
        replaced = blockchain.resolve_conflicts()
    
        if replaced:
            response = {
                'message': 'Our chain was replaced',
                'new_chain': blockchain.chain
            }
        else:
            response = {
                'message': 'Our chain is authoritative',
                'chain': blockchain.chain
            }
    
        return jsonify(response), 200
    
    if __name__ == '__main__':
        app.run(host='0.0.0.0',port=5000)

代码弄好启动你的项目以后打开Postman 完成以下操作

在这里插入图片描述

学长通过请求 http://localhost:5000/mine进行采矿

在这里插入图片描述

3 最后

🧿 更多资料, 项目分享:

https://gitee.com/dancheng-senior/postgraduate

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/389303.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

精炼爆炸性新闻!OpenAI发布革命性AI视频生成模型Sora:实现长达60秒的高清视频创作「附AIGC行业系统搭建」

在人工智能领域&#xff0c;每一次技术革新都引领着未来的发展方向。OpenAI&#xff0c;作为全球领先的人工智能研究机构&#xff0c;再次证明了其在推动AI技术革新方面的领导地位。近日&#xff0c;OpenAI宣布推出了一款革命性的AI视频生成模型——Sora&#xff0c;这一大胆的…

Java实现实现自动化pdf打水印小项目 使用技术pdfbox、Documents4j

文章目录 前言源码获取一、需求说明二、 调研pdf处理工具word处理工具 三、技术栈选择四、功能实现实现效果详细功能介绍详细代码实现项目目录WordUtilsMain类实现部分&#xff1a;第一部分Main类实现部分&#xff1a;第二部分Main类实现部分&#xff1a;第三部分 资料获取 前言…

算法详解(力扣141——环形链表系列)

博主ID&#xff1a;代码小豪 文章目录 环形链表环形链表的性质分析快慢指针法指针的追及相遇问题 环形链表&#xff08;2&#xff09; 环形链表 先来看看环形链表的原题&#xff1a; 中间的部分叙述有点繁杂&#xff0c;简单来概括就是&#xff0c;假如有一个节点&#xff0c…

SAP PP学习笔记- 豆知识01 - 怎么查询既存品目

SAP系统当中已经有哪些品目要怎么查询呢&#xff1f; 1&#xff0c;MM60 品目一览 这里可以输入Plant&#xff0c;然后可以查询该工厂的所有品目。 2&#xff0c;SE16 > MARA MARA 品目一般Data&#xff0c;存放的是品目基本信息。 如果要查询该品目属于哪个Plant&#x…

【研究生复试】计算机软件工程人工智能研究生复试——资料整理(速记版)——计算机网络

1、JAVA 2、计算机网络 3、计算机体系结构 4、数据库 5、计算机租场原理 6、软件工程 7、大数据 8、英文 自我介绍 2. 计算机网络 1. TCP如何解决丢包和乱序&#xff1f; 序列号&#xff1a;TCP所传送的每段数据都有标有序列号&#xff0c;避免乱序问题发送端确认应答、超时…

[01] Vue2学习准备

目录 vue理解创建实例插值表达式 {{}}响应式特性 vue理解 Vue.js 是一套构建用户界面的渐进式框架。 Vue 只关注视图层&#xff0c; 采用自底向上增量开发的设计。 Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。 创建实例 准备容器 <div id…

问题:如果要编辑建好的建筑和空间,需要在分级按钮( )和细分操作按钮楼层下,才能选中建筑物和空间; #微信#媒体#其他

问题&#xff1a;如果要编辑建好的建筑和空间&#xff0c;需要在分级按钮&#xff08; &#xff09;和细分操作按钮楼层下&#xff0c;才能选中建筑物和空间&#xff1b; A、楼层 B、规划图 C、全景 D、建筑物 参考答案如图所示

JVM(3)高级篇

1 GraalVM 1.1 什么是GraalVM GraalVM是Oracle官方推出的一款高性能JDK&#xff0c;使用它享受比OpenJDK或者OracleJDK更好的性能。 GraalVM的官方网址&#xff1a;https://www.graalvm.org/ 官方标语&#xff1a;Build faster, smaller, leaner applications。 更低的CPU、内…

Midjourney提示词风格调试测评

在Midjourney中提示词及风格参数的变化无疑会对最终的作品产生影响&#xff0c;那影响具体有多大&#xff1f;今天我我们将通过一个示例进行探究。 示例提示词&#xff1a; 计算机代码海洋中的黄色折纸船&#xff08;图像下方&#xff09;风格参考:金色长发的女人&#xff0c…

vue3-应用规模化-路由和状态

客户端 vs. 服务端路由 服务端路由指的是服务器根据用户访问的 URL 路径返回不同的响应结果。当我们在一个传统的服务端渲染的 web 应用中点击一个链接时&#xff0c;浏览器会从服务端获得全新的 HTML&#xff0c;然后重新加载整个页面。 然而&#xff0c;在单页面应用中&…

电商+支付双系统项目------简介

电商支付双系统项目是一个综合性的项目&#xff0c;旨在建立一个完善的电商系统和独立的支付系统&#xff0c;以满足中国日益增长的电商交易需求并提供多样化、安全可靠的支付方式。随着中国电商行业的快速发展&#xff0c;电商平台需要具备高效、可靠的功能&#xff0c;而独立…

中国比特币矿工的新根据地:埃塞俄比亚

原文标题&#xff1a;《Chinese Bitcoin Miners Find a New Crypto Haven in Ethiopia》 撰文&#xff1a;David Pan、Fasika Tadesse&#xff0c;彭博社 编译&#xff1a;Carl&#xff0c;Techub News 中国比特币矿工的新根据地&#xff1a;埃塞俄比亚 去年春天&#xff0c…

蓝桥杯电子类单片机提升三——NE555

目录 单片机资源数据包_2023 一、NE555和定时器工作模式 1.NE555的介绍 2.定时器的计数模式 二、NE555频率读取代码的实现 1.定时器0初始化 2.通过读取TH0和TL0来读取频率 3.通过中断读取频率 三、完整代码演示 通过读取TH0和TL0来读取频率 main.c 通过中断读取频…

领导力提升,才是高绩效的关键

作为企业的CEO或团队管理者&#xff0c;在日常的团队管理工作中无论是领导力还是执行力&#xff0c;都是非常重要的。在领导力的提升方面&#xff0c;我们可以通过一整套方案来进行&#xff0c;包括如何设定目标&#xff0c;动机刺激、任务拆解、鼓励参与、责任承担、建立制度、…

NLP_ChatGPT的RLHF实战

文章目录 介绍小结 介绍 ChatGPT 之所以成为ChatGPT&#xff0c;基于人类反馈的强化学习是其中重要的一环。而ChatGPT 的训练工程称得上是复杂而又神秘的&#xff0c;迄今为止&#xff0c;OpenAl也没有开源它的训练及调优的细节。 从 OpenAl已经公开的一部分信息推知&#xff…

STM32——OLED菜单(二级菜单)

文章目录 一.补充二. 二级菜单代码 简介&#xff1a;首先在我的51 I2C里面有OLED详细讲解&#xff0c;本期代码从51OLED基础上移植过来的&#xff0c;可以先看完那篇文章&#xff0c;在看这个&#xff0c;然后按键我是用的定时器扫描不会堵塞程序,可以翻开我的文章有单独的定时…

大模型专题:2023爱分析·大模型厂商全景报告

今天分享的是大模型系列深度研究报告&#xff1a;《大模型专题&#xff1a;2023爱分析大模型厂商全景报告》。 &#xff08;报告出品方&#xff1a;爱分析&#xff09; 报告共计&#xff1a;80页 研究范围定义 大模型是指通过在海量数据上依托强大算力资源进行训练后能完成…

java8-使用流-2

筛选各异的元素 流还支持一个叫作aistinct的方法&#xff0c;它会返回一个元素各异(根据流所生成元素的hashcode和eguals方法实现)的流。例如&#xff0c;以下代码会筛选出列表中所有的偶数&#xff0c;并确保没有重复。图5-2直观地显示了这个过程。 List<Integer>number…

Redis面试题整理(持续更新)

1. 缓存穿透&#xff1f; 缓存穿透是指查询一个一定不存在的数据&#xff0c;如果从存储层查不到数据则不写入缓存&#xff0c;这将导致这个不存在的数据每次请求都要到 DB 去查询&#xff0c;可能导致DB挂掉&#xff0c;这种情况大概率是遭到了攻击。 解决方案&#xff1a; …

【C++】:位图、布隆过滤器、哈希分割

朋友们、伙计们&#xff0c;我们又见面了&#xff0c;本期来给大家解读一下位图、布隆过滤器、哈希分割&#xff0c;如果看完之后对你有一定的启发&#xff0c;那么请留下你的三连&#xff0c;祝大家心想事成&#xff01; C 语 言 专 栏&#xff1a;C语言&#xff1a;从入门到精…