当前位置: 首页 > news >正文

Python实现简单的区块链,实现共识算法、Merkle Tree(默克尔树)、冲突解决、添加交易等功能

Python实现简单的区块链

记录自己假期所学相关内容
文章中的内容,开源代码地址见文末。

文章目录

  • Python实现简单的区块链
    • 1、分模块实现简单的单节点区块链
      • 1.1 Transaction类
      • 1.2 DaDaMessage类
      • 1.3 Block类
      • 1.4 Dada_BlockCoin类
      • 1.5 主函数BlockChainApp类
      • 1.6 主函数类中实现了可视化界面,以下为演示效果
    • 2、网络共识区块链编程实现
      • 2.1 DaDaCoinBlockChain类
      • 2.2 flask框架部分
      • 2.3 初始化三个节点,分别模拟网络中的三个矿工
      • 2.4 效果演示
    • 3、其他

1、分模块实现简单的单节点区块链

1.1 Transaction类

class Transaction:def __init__(self,payer,  # 付款方r ecer,  # 收款方money):  # 数字货币的数额self.payer = payerself.recer = recerself.money = moneyself.timestamp = datetime.datetime.now()  # 交易时间def __repr__(self):return str(self.payer) + " pays " + str(self.recer) + \" " + str(self.money) + " " + str(self.timestamp)

1.2 DaDaMessage类

class DaDaMessage:  # 交易记录类def __init__(self, data):self.hash = None  # 自身的哈希self.prev_hash = None  # 上一个信息记录的哈希self.timestamp = datetime.datetime.now()  # 交易时间self.data = data  # 交易信息self.payload_hash = self._hash_payload()  # 交易后的哈希def _hash_payload(self):  # 对于交易时间与交易数据进行哈希计算return hashlib.sha256((str(self.timestamp) + str(self.data)).encode()).hexdigest()def _hash_message(self):  # 对于交易进行锁定return hashlib.sha256((str(self.prev_hash) + str(self.payload_hash)).encode()).hexdigest()def seal(self):  # 密封self.hash = self._hash_message()  # 对应数据锁定,对于交易前的链锁定def validate(self):  # 验证if self.payload_hash != self._hash_payload():  # 判断是否有人修改raise InvalidMessage("交易数据与时间被修改" + str(self))if self.hash != self._hash_message():  # 判断消息链raise InvalidMessage("交易的哈希链接被修改" + str(self))return "数据正常" + str(self)def __repr__(self):  # 返回对象的基本信息mystr = "hash:{}, prev_hash:{}, data:{}".format(self.hash, self.prev_hash, self.data)return mystrdef link(self, Message):self.prev_hash = Message.hash  # 链接

1.3 Block类

class Block:def __init__(self, *args):  # 初始化self.messageList = []  # 存储多个交易记录,存放区块self.timestamp = None  # 存储多个记录最终锁定的时间self.hash = None  # 当前的哈希散列self.prev_hash = None  # 上一块的哈希散列if args:for arg in args:self.add_message(arg)# self.messagelist.append(arg)def add_message(self, message):  # 增加交易信息# 区分第一条与后面多条,是否需要链接if len(self.messageList) > 0:message.link(self.messageList[-1])  # 链接message.seal()  # 密封message.validate()  # 校验self.messageList.append(message)  # 追加记录def link(self, block):  # 区块链链接self.prev_hash = block.hashdef seal(self):  # 密封self.timestamp = datetime.datetime.now()  # 密封确定当前时间self.hash = self._hash_block()  # 密封当前的哈希值def _hash_block(self):  # 密封 上一块哈希,时间线,交易记录的最后一个if len(self.messageList) > 0:return hashlib.md5((str(self.prev_hash) +str(self.timestamp) +str(self.messageList[-1].hash)).encode("utf-8")).hexdigest()# else:#     return hashlib.sha256((str(self.prev_hash) +#                            str(self.timestamp) +#                            str(0)).encode("utf-8")).hexdigest()def validate(self):  # 校验for i, message in enumerate(self.messageList):  # 校验每一个交易记录message.validate()  # 校验每一条if i > 0 and message.prev_hash != self.messageList[i - 1].hash:raise InvalidBlock("无效block,交易记录被修改为在第{}条记录".format(i) + str(self))#         print("无效block,交易记录被修改为在第{}条记录".format(i))#         return str(self) + "数据NO"return "   " + str(self) + "  数据OK"def __repr__(self):  # 类的对象描述# return "money block = hash : {}, pre_hash : {}, len : {}, time : {}".\#     format(self.hash, self.prev_hash, len(self.messageList), self.timestamp)return "money block \n hash : {} \n pre_hash : {} \n len : {} \n time : {}". \format(self.hash, self.prev_hash, len(self.messageList), self.timestamp)

1.4 Dada_BlockCoin类

class Dada_BlockCoin:  # 区块链def __init__(self):  # 初始化self.blockList = []def add_block(self, block):  # 增加区块if (len(self.blockList) > 0):block.prev_hash = self.blockList[-1].hash  # 区块链的哈希block.seal()  # 密封block.validate()  # 校验self.blockList.append(block)  # 增加区块def validate(self):  # 校验for i, block in enumerate(self.blockList):try:block.validate()except InvalidBlock as e:raise InvalidBlockCoin("区块校验错误,区块索引{}".format(i))except InvalidMessage as e:print(e)def __repr__(self):  # 字符串格式化return "Dada_BlockCoin : {}".format(len(self.blockList))  # 获取长度

1.5 主函数BlockChainApp类

class BlockChainApp:def __init__(self, root):self.root = rootself.root.title("区块链可视化")self.blockchain = Dada_BlockCoin()self.current_block_transactions = []self.selected_block_index = None# 添加滚动条self.canvas_frame = tk.Frame(root)self.canvas_frame.pack(expand=tk.YES, fill=tk.BOTH)self.scrollbar_x = tk.Scrollbar(self.canvas_frame, orient=tk.HORIZONTAL)self.scrollbar_x.pack(side=tk.BOTTOM, fill=tk.X)self.scrollbar_y = tk.Scrollbar(self.canvas_frame)self.scrollbar_y.pack(side=tk.RIGHT, fill=tk.Y)# 区块链信息显示框self.canvas = tk.Canvas(self.canvas_frame, width=800, yscrollcommand=self.scrollbar_y.set,xscrollcommand=self.scrollbar_x.set)self.canvas.pack(side=tk.LEFT, expand=tk.YES, fill=tk.BOTH)self.scrollbar_x.config(command=self.canvas.xview)self.scrollbar_y.config(command=self.canvas.yview)self.canvas.config(scrollregion=self.canvas.bbox(tk.ALL))# 交易信息输入框self.payer_label = tk.Label(root, text="付款方:")self.payer_label.pack()self.payer_entry = tk.Entry(root)self.payer_entry.pack()self.recer_label = tk.Label(root, text="收款方:")self.recer_label.pack()self.recer_entry = tk.Entry(root)self.recer_entry.pack()self.money_label = tk.Label(root, text="金额:")self.money_label.pack()self.money_entry = tk.Entry(root)self.money_entry.pack()# 添加交易按钮self.add_transaction_btn = tk.Button(root, text="添加交易", command=self.add_transaction)self.add_transaction_btn.pack()# 添加区块按钮self.add_block_btn = tk.Button(root, text="添加区块", command=self.add_block)self.add_block_btn.pack()# 模拟篡改按钮self.tamper_block_btn = tk.Button(root, text="模拟篡改数据", command=self.tamper_block)self.tamper_block_btn.pack()# 区块查询框self.query_frame = tk.Frame(root)self.query_frame.pack()self.query_label = tk.Label(self.query_frame, text="查询区块索引:")self.query_label.pack(side=tk.LEFT)self.query_entry = tk.Entry(self.query_frame)self.query_entry.pack(side=tk.LEFT)self.query_btn = tk.Button(self.query_frame, text="查询区块", command=self.query_block)self.query_btn.pack(side=tk.LEFT)# 交易信息显示框self.transaction_info_text = tk.Text(root, wrap=tk.WORD, width=60, height=10)self.transaction_info_text.pack()def add_transaction(self):payer = self.payer_entry.get()recer = self.recer_entry.get()money = self.money_entry.get()try:money = int(money)except ValueError:messagebox.showerror("错误", "金额必须为整数")returnif payer and recer and money > 0:transaction = Transaction(payer, recer, money)self.current_block_transactions.append(DaDaMessage(transaction))self.update_blockchain_info()messagebox.showinfo("成功", "交易添加成功")else:messagebox.showerror("错误", "请输入有效的交易信息")def add_block(self):if self.current_block_transactions:block = Block(*self.current_block_transactions)self.blockchain.add_block(block)self.current_block_transactions = []self.update_blockchain_info()messagebox.showinfo("成功", "区块添加成功")else:messagebox.showerror("错误", "当前区块没有交易信息")def tamper_block(self):try:block_index = int(input("请输入要篡改的区块索引:"))except ValueError:messagebox.showerror("错误", "请输入有效的区块索引")returnif 0 <= block_index < len(self.blockchain.blockList):block = self.blockchain.blockList[block_index]if len(block.messageList) > 0:# 模拟篡改第一条交易信息block.messageList[0].data = "篡改后的交易信息"try:self.blockchain.validate()except InvalidBlockCoin as e:messagebox.showerror("篡改数据", "区块链数据已被篡改,篡改发生在第{}个区块".format(e.args[0]))except InvalidMessage as e:messagebox.showerror("篡改数据", "区块链数据已被篡改,篡改发生在第{}个区块的第{}条交易信息".format(e.args[0][0], e.args[0][1]))else:messagebox.showinfo("篡改数据", "区块链数据未被篡改")finally:self.update_blockchain_info()else:messagebox.showerror("错误", "区块中没有交易信息,无法篡改")else:messagebox.showerror("错误", "区块索引超出范围")def query_block(self):try:block_index = int(self.query_entry.get())except ValueError:messagebox.showerror("错误", "请输入有效的区块索引")returnif 0 <= block_index < len(self.blockchain.blockList):block = self.blockchain.blockList[block_index]transactions = "\n".join(str(msg.data) for msg in block.messageList)self.transaction_info_text.delete("1.0", tk.END)self.transaction_info_text.insert(tk.END, transactions)self.selected_block_index = block_indexmessagebox.showinfo("成功", "查询成功")else:messagebox.showerror("错误", "区块索引超出范围")def update_blockchain_info(self):self.canvas.delete("all")  # 清空画布上的内容x, y = 20, 50  # 区块链的初始位置block_width, block_height = 250, 150  # 区块的宽度和高度for block in self.blockchain.blockList:self.canvas.create_rectangle(x, y, x + block_width, y + block_height, outline="black")  # 绘制区块框self.canvas.create_text(x + block_width // 2, y + block_height // 2, text=str(block))  # 显示区块信息if block.prev_hash:  # 绘制区块之间的连接线prev_x, prev_y = x - block_width, y + block_height // 2self.canvas.create_line(prev_x, prev_y, x, y + block_height // 2, fill="red")x += block_width + 50  # 每个区块之间留一定的间隔# 设置Canvas可滚动范围self.canvas.config(scrollregion=self.canvas.bbox(tk.ALL))if __name__ == "__main__":root = tk.Tk()app = BlockChainApp(root)app.root.mainloop()

1.6 主函数类中实现了可视化界面,以下为演示效果

  • 初始化界面

在这里插入图片描述

  • 添加交易后添加区块
    在这里插入图片描述

在上述区块链可视化界面中显示对应区块,并用红色连线连接,表示区块链的哈希连接。

  • 查询区块信息
    在这里插入图片描述
    输入区块对应的索引(从0开始),即可查询对应区块的交易信息

2、网络共识区块链编程实现

2.1 DaDaCoinBlockChain类

class DaDaCoinBlockChain:def __init__(self):  # 初始化self.current_transactions = []  # 交易列表self.chain = []  # 区块链管理多个区块self.nodes = set()  # 保存网络中其他节点self.new_block(previous_hash="1", proof=100)  # 创建创世区块def new_block(self,proof: int,  # 确定proof为int类型previous_hash: Optional[str]  # 上一块的哈希类型) -> Dict[str, Any]:  # 创建一个区块,返回一个字典数据类型block = {"index": len(self.chain) + 1,  # 索引"timestamp": time.time(),  # 当前时间"transaction": self.current_transactions,  # 交易记录"proof": proof,  # 工作量证明"previous_hash": previous_hash or self.hash(self.chain[-1])  # 前一区块哈希}self.current_transactions = []  # 交易记录加入区块之后清空self.chain.append(block)  # 区块加入区块链return blockdef new_transactions(self, sender: str, recipient: str, amount) -> int:  # 创建一个交易self.current_transactions.append({"sender": sender,  # 付款方"recipient": recipient,  # 收款方"amount": amount  # 数量})return self.last_block["index"] + 1  # 索引标记交易数量@propertydef last_block(self) -> Dict[str, Any]:  # 取得最后一个区块return self.chain[-1]@staticmethoddef hash(block: Dict[str, any]) -> str:  # 哈希加密,传递一个字典,返回字符串blockString = json.dumps(block, sort_keys=True).encode()  # 编码return hashlib.sha256(blockString).hexdigest()def proof_of_work(self, last_proof: int) -> int:  # 工作量证明,挖矿过程proof = 0while self.valid_proof(last_proof, proof) is False:proof += 1return proof@staticmethod  # 第N个区块依赖于N-1个区块,简单挖矿def valid_proof(last_proof: int, proof: int) -> bool:  # 验证证明guess = f'{last_proof * proof}'.encode()guess_hash = hashlib.sha256(guess).hexdigest()# print(str(guess_hash))return guess_hash[-4:] == "1234"def valid_chain(self, chain: List[Dict[str, Any]]) -> bool:  # 区块链校验# List[Dict[str, Any]]是一个列表,列表的每个元素都是字典last_block = chain[0]  # 第一个区块curr_index = 1  # 当前的第一个索引while curr_index < len(chain):block = chain[curr_index]  # 当前区块# 哈希校验,校验区块链的链接if block["previous_hash"] != self.hash(last_block):return False# 工作量校验,挖矿的工作量校验if not self.valid_proof(last_block["proof"], block["proof"]):return Falselast_block = block  # 轮询curr_index += 1  # 索引自增return Truedef register_node(self, addr: str) -> None:  # 加入网络的其他节点,用于更新now_url = urlparse(addr)  # 解析self.nodes.add(now_url.netloc)  # 增加网络节点def resolve_conflicts(self) -> bool:  # 共识算法# 网络中的多个节点,取出最长的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 = lengthnew_chain = chain  # 保存长度与区块链if new_chain:self.chain = new_chain  # 替换区块链return Truereturn False

2.2 flask框架部分

dadacoin = DaDaCoinBlockChain()  # 创建一个网络节点
node_id = str(uuid4()).replace("-", "")  # 节点替换,生成密钥
print("当前钱包地址:", node_id)
app = Flask(__name__)  # 初始化flask框架@app.route("/")
def index_page():return "你好,欢迎来到达达币系统!"@app.route("/chain")  # 查看所有的区块链
def index_chain():response = {"chain": dadacoin.chain,  # 区块链"length": len(dadacoin.chain)  # 区块链长度}return jsonify(response), 200@app.route("/mine")  # 挖矿
def index_mine():last_block = dadacoin.last_block  # 取得最后一个区块last_proof = last_block["proof"]  # 取得工作量证明proof = dadacoin.proof_of_work(last_proof)  # 挖矿计算# 系统奖励比特币,挖矿产生交易dadacoin.new_transactions(sender="0",  # 0代表系统奖励recipient=node_id,  # 当前钱包地址amount=10  # 奖励数量)block = dadacoin.new_block(proof, None)  # 增加一个区块response = {"message": "新的区块创建","index": block["index"],  # 仓建的索引"transaction": block["transaction"],  # 交易"proof": block["proof"],  # 工作量证明"previous_hash": block["previous_hash"]  # 上一块的哈希}return jsonify(response), 200@app.route("/new_transaction", methods=["POST"])  # 创建一个新的交易
def new_transaction():values = request.get_json()  # 抓取网络传输的信息required = ["sender", "recipient", "amount"]if not all(key in values for key in required):return "数据不完整", 400index = dadacoin.new_transactions(values["sender"],values["recipient"],values["amount"])  # 新增一个交易response = {"message": f"交易加入到区块{index}",}return jsonify(response), 200@app.route("/new_node", methods=["POST"])   # 增加网络节点
def new_node():values = request.get_json() # 获取json字符串nodes = values.get("nodes") # 获取所有节点if nodes is None:return "节点为空", 400for node in nodes:dadacoin.register_node(node)    # 增加网络节点response = {"message": "网络节点已经增加","nodes": list(dadacoin.nodes)   # 查看所有节点}return jsonify(response), 200@app.route("/node_refresh")
def node_refresh():replaced = dadacoin.resolve_conflicts() # 共识算法进行最长替换message = ""if replaced:message += "区块链已经被替换为最长"else:message += "当前区块链已经是最长无需替换"response = {"message": message,"new--chain": dadacoin.chain}return jsonify(response), 200

2.3 初始化三个节点,分别模拟网络中的三个矿工

if __name__ == '__main__':app.run("127.0.0.1", 5000)if __name__ == '__main__':app.run("127.0.0.1", 5001)if __name__ == '__main__':app.run("127.0.0.1", 5002)

2.4 效果演示

分别启动三个矿工节点

  • 初始化界面
    在这里插入图片描述
  • 初次访问chain路径时,显示创世区块
    在这里插入图片描述
  • 访问mine路径时,进行挖矿操作,挖出新的区块,矿工获得出块奖励
    在这里插入图片描述
  • 添加交易
    使用postman进行操作
    在这里插入图片描述
    此时仅仅是将交易添加到区块,还没有挖出区块3,再次进行mine操作,可以看到区块3中除了出块奖励,还有此次交易
    在这里插入图片描述
  • 网络共识,解决分叉冲突
    此时模拟节点1挖出6个区块,节点2挖出4个区块,节点3挖出3个区块。将节点1和节点2的信息同步给区块3,此时根据最长链原则,应该更新为节点1的6个区块。
    使用postman添加节点
    在这里插入图片描述
    刷新节点信息
    在这里插入图片描述
    此时节点3已经被最长链代替。

3、其他

开源代码地址: Gitee仓库
b站参考视频:参考视频

相关文章:

Python实现简单的区块链,实现共识算法、Merkle Tree(默克尔树)、冲突解决、添加交易等功能

Python实现简单的区块链 记录自己假期所学相关内容 文章中的内容&#xff0c;开源代码地址见文末。 文章目录 Python实现简单的区块链1、分模块实现简单的单节点区块链1.1 Transaction类1.2 DaDaMessage类1.3 Block类1.4 Dada_BlockCoin类1.5 主函数BlockChainApp类1.6 主函数…...

深入理解 Java 虚拟机(JVM)从入门到精通

目录 一、JVM内存结构1、堆&#xff08;Heap&#xff09;&#xff08;1&#xff09;特点&#xff08;2&#xff09;堆内存分配&#xff08;3&#xff09;晋升到老年代的方式&#xff08;4&#xff09;堆内存检验方式2、虚拟机栈&#xff08;VM Stack&#xff09;&#xff08;1&…...

哔哩哔哩自动评论软件,其成果展示与开发流程和代码分享

先来看实操成果&#xff0c;↑↑需要的同学可看我名字↖↖↖↖↖&#xff0c;或评论888无偿分享 一、背景介绍 随着互联网的发展&#xff0c;哔哩哔哩作为国内最大的弹幕视频网站之一&#xff0c;吸引了越来越多的用户。为了更好地推广自己的作品&#xff0c;许多UP主希望能够通…...

Qt OpenCV 学习(一):环境搭建

对应版本 Qt 5.15.2OpenCV 3.4.9MinGW 8.1.0 32-bit 1. OpenCV 下载 确保安装 Qt 时勾选了 MinGW 编译器 本文使用 MinGW 编译好的 OpenCV 库&#xff0c;无需自行编译 确保下载的 MinGW 和上述安装 Qt 时勾选的 MinGW 编译器位数一致&#xff0c;此处均为 x86/32-bit下载地址…...

Redis——某马点评day02——商铺缓存

什么是缓存 添加Redis缓存 添加商铺缓存 Controller层中 /*** 根据id查询商铺信息* param id 商铺id* return 商铺详情数据*/GetMapping("/{id}")public Result queryShopById(PathVariable("id") Long id) {return shopService.queryById(id);} Service…...

prometheus|云原生|轻型日志收集系统loki+promtail的部署说明

一&#xff0c; 日志聚合的概念说明 日志------ 每一个程序&#xff0c;服务都应该有保留日志&#xff0c;日志的作用第一是记录程序运行的情况&#xff0c;在出错的时候能够记录错误情况&#xff0c;简单来说就是审计工作&#xff0c;例如nginx服务的日志&#xff0c;kuber…...

MySQL 临时数据空间不足导致SQL被killed 的问题与扩展

开头还是介绍一下群&#xff0c;如果感兴趣PolarDB ,MongoDB ,MySQL ,PostgreSQL ,Redis, Oceanbase, Sql Server等有问题&#xff0c;有需求都可以加群群内&#xff0c;可以解决你的问题。加群请联系 liuaustin3 &#xff0c;&#xff08;共1730人左右 1 2 3 4 5&#xff0…...

文心一言大模型应用开发入门

本文重点介绍百度智能云平台、文心一言、千帆大模型平台的基本使用与接入流程及其详细步骤。 注册文心一言 请登录文心一言官方网站 https://yiyan.baidu.com/welcome 点击登录&#xff1b;图示如下&#xff1a; 请注册文心一言账号并点击登录&#xff0c;图示如下&#xff1…...

C++新经典模板与泛型编程:SFINAE替换失败并不是一个错误

替换失败并不是一个错误&#xff08;SFINAE&#xff09; SFINAE是一个英文简称&#xff0c;全称为Substitution Failure is not an Error&#xff0c;翻译成中文就是“替换失败并不是一个错误”。 SFINAE可以看作C语言的一种特性或模板设计中要遵循的一个重要原则&#xff0c;…...

基于若依的ruoyi-nbcio流程管理系统支持支持定时边界事件和定时捕获事件

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 1、定时边界事件 <template><div class"panel-tab__content"><!--目前只处理定…...

递归-极其优雅的问题解决方法(Java)

递归的定义 大名鼎鼎的递归&#xff0c;相信你即使没接触过也或多或少听过&#xff0c;例如汉诺塔问题就是运用了递归的思想&#xff0c;对于一些学过c语言的同学来说&#xff0c;它可能就是噩梦&#xff0c;因为我当时就是这么认为的&#xff08;不接受反驳doge&#xff09; …...

VSCode搭建STM32开发环境

1、下载安装文件 链接&#xff1a;https://pan.baidu.com/s/1WnpDTgYBobiZaXh80pn5FQ 2、安装VSCodeUserSetup-x64-1.78.2.exe软件 3、 在VSCode中安装必要的插件 3、配置Keil Assistant插件 4、在环境变量中部署mingw64编译环境...

解决CentOS下PHP system命令unoconv转PDF提示“Unable to connect or start own listener“

centos系统下&#xff0c;用php的system命令unoconv把word转pdf时提示Unable to connect or start own listene的解决办法 unoconv -o /foo/bar/public_html/upload/ -f pdf /foo/bar/public_html/upload/test.docx 2>&1 上面这个命令在shell 终端能执行成功&#xff0c…...

软件测试外包干了2个月,技术进步2年。。。

先说一下自己的情况&#xff0c;本科生&#xff0c;18年通过校招进入北京某软件公司&#xff0c;干了接近2年的功能测试&#xff0c;今年国庆&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了2年的功能测试&…...

Linux-网络服务和端口

域名&#xff1a;便于人们记忆和使用的标识符 www.baidu.com域名解析&#xff1a;将域名转换为与之对应的 IP 地址的过程 nameserver 8.8.8.8ip地址&#xff1a;网络设备的唯一数字标识符 域名ip地址localhost127.0.0.1 网络服务和端口 网络服务端口ftp21ssh22http80https…...

Kubernetes权威指南:从Docker到Kubernetes实践全接触(第5版)读书笔记 目录

完结状态&#xff1a;未完结 文章目录 前言第1章 Kubernetes入门 11.1 了解Kubernetes 2 附录A Kubernetes核心服务配置详解 915总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; Kubernetes权威指南&#xff1a;从Docker到Kubernetes实践全接触&…...

阿里云Arthas使用——通过watch命令查看类的返回值 捞数据出来

前言 Arthas 是一款线上监控诊断产品&#xff0c;通过全局视角实时查看应用 load、内存、gc、线程的状态信息&#xff0c;并能在不修改应用代码的情况下&#xff0c;对业务问题进行诊断&#xff0c;包括查看方法调用的出入参、异常&#xff0c;监测方法执行耗时&#xff0c;类…...

Redis中持久化策略RDB与AOF优缺点对比

Redis持久化策略对比 RDBAOF持久化方式定时对整个内存做快照记录每一次执行的命令数据完整性不完整,两次备份之间存在丢失相对完整,取决于刷盘策略文件大小会有压缩,文件体积小记录命令,文件体积较大宕机恢复速度很快慢数据恢复优先级低,数据完整性不如AOF高,记录了执行命令数据…...

通用plantuml 时序图(Sequence Diagram)模板头

通用plantuml文件 startuml participant Admin order 0 #87CEFA // 参与者、顺序、颜色 participant Student order 1 #87CEFA participant Teacher order 2 #87CEFA participant TestPlayer order 3 #87CEFA participant Class order 4 #87CEFA participant Subject order …...

Domino多Web站点托管

大家好&#xff0c;才是真的好。 看到一篇文档&#xff0c;大概讲述的是他在家里架了一台Domino服务器&#xff0c;上面跑了好几个Internet的Web网站&#xff08;使用Internet站点&#xff09;。再租了一台云服务器&#xff0c;上面安装Nginx做了反向代理&#xff0c;代理访问…...

防火墙补充NAT

目录 1.iptables保存规则 2.自定义链 3.NAT NAT的实现分为下面类型&#xff1a; SNAT实验操作 DNAT实验操作 1.iptables保存规则 永久保存方法一&#xff1a; iptables -save > /data/iptables_rule //输出重定向备份 iptables -restore < /data/iptables_r…...

配置和管理VLAN

VLAN技术是交换技术的重要组成部分&#xff0c;也是交换机配置的基础。用于把物理上直接相连的网络从逻辑上划分为多个子网。 每一个VLAN 对应一个广播域&#xff0c;处于不同VLAN 上的主机不能通信。 不同VLAN 之间通信需要引入三层交换技术。 对性能局域网的配置和管理主要…...

dtaidistance笔记:dtw_ndim (高维时间序列之间的DTW)

1 数据 第一个维度是sequence的index&#xff0c;每一行是多个元素&#xff08;表示这一时刻的record&#xff09; from dtaidistance.dtw_ndim import *s1 np.array([[0, 0],[0, 1],[2, 1],[0, 1],[0, 0]], dtypenp.double) s2 np.array([[0, 0],[2, 1],[0, 1],[0, .5],[0…...

2 文本分类入门:TextCNN

论文链接&#xff1a;https://arxiv.org/pdf/1408.5882.pdf TextCNN 是一种用于文本分类的卷积神经网络模型。它在卷积神经网络的基础上进行了一些修改&#xff0c;以适应文本数据的特点。 TextCNN 的主要思想是使用一维卷积层来提取文本中的局部特征&#xff0c;并通过池化操…...

算法初阶双指针+C语言期末考试之编程题加强训练

双指针 常⻅的双指针有两种形式&#xff0c;⼀种是对撞指针&#xff0c;⼀种是左右指针。 对撞指针&#xff1a;⼀般⽤于顺序结构中&#xff0c;也称左右指针。 • 对撞指针从两端向中间移动。⼀个指针从最左端开始&#xff0c;另⼀个从最右端开始&#xff0c;然后逐渐往中间逼…...

【Spark基础】-- 宽窄依赖

目录 1、前言 2、宽窄依赖 2.1 窄依赖 2.2 宽依赖 3、宽窄转换的算子 1、前言 要理解宽窄依赖,首先我们需要了解 Transform...

Spatial Data Analysis(六):空间优化问题

Spatial Data Analysis&#xff08;六&#xff09;&#xff1a;空间优化问题 使用pulp库解决空间优化问题&#xff1a; pulp是一个用于优化问题的Python库。它包含了多种优化算法和工具&#xff0c;可以用于线性规划、混合整数线性规划、非线性规划等问题。Pulp提供了一个简单…...

PHP短信接口防刷防轰炸多重解决方案三(可正式使用)

短信接口盗刷轰炸&#xff1a;指的是黑客利用非法手段获取短信接口的访问权限&#xff0c;然后使用该接口发送大量垃圾短信给目标用户 短信验证码轰炸解决方案一(验证码类解决)-CSDN博客 短信验证码轰炸解决方案二(防止海外ip、限制ip、限制手机号次数解决)-CSDN博客 PHP短信…...

C#大型LIS检验信息系统项目源码

LIS系统&#xff0c;一套医院检验科信息系统。它是以数据库为核心&#xff0c;将实验仪器与电脑连接成网&#xff0c;基础功能包括病人样本登录、实验数据存取、报告审核、打印分发等。除基础功能外&#xff0c;实验数据统计分析、质量控制管理、人员权限管理、试剂出入库等功能…...

【C语言】数据在内存中的存储

目录 练笔 整型数据的存储&#xff1a; char 型数据——最简单的整型 整型提升&#xff1a; 推广到其他整形&#xff1a; 大小端&#xff1a; 浮点型数据的存储&#xff1a; 存储格式&#xff1a; 本篇详细介绍 整型数据&#xff0c;浮点型数据 在计算机中是如何储存的。…...

Java聊天程序(一对一)简单版

我们首先要完成服务端&#xff0c;不然出错&#xff0c;运行也要先运行服务端&#xff0c;如果不先连接服务端&#xff0c;就不监听&#xff0c;那客户端不知道连接谁 服务端 import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.Actio…...

Linux下超轻量级Rust开发环境搭建:一、安装Rust

Rust语言在国内逐步开始流行&#xff0c;但开发环境的不成熟依然困扰不少小伙伴。 结合我个人的使用体验&#xff0c;推荐一种超轻量级的开发环境&#xff1a;Rust Helix Editor。运行环境需求很低&#xff0c;可以直接在Linux终端里进行代码开发。对于工程不是太过庞大的Rus…...

定义一个学生类,其中有3个私有数据成员学号、姓名、成绩,以及若于成员。 函数实现对学生数据的赋值和输出。

#include <stdio.h> // 定义学生类 typedef struct Student { int stuNum; // 学号 char name[20]; // 姓名&#xff0c;假设最长为20个字符 float score; // 成绩 } Student; // 初始化学生信息 void initializeStudent(Student *student, int num, const…...

1.2 C语言简介

一、为什么要讲C语言 C语言是编程界的长青藤&#xff0c;可以查看语言排名发现&#xff0c;虽然现在语言很多&#xff0c;但是C语言一直占有一定地址 来源网站&#xff1a;https://www.tiobe.com/tiobe-index/ 在系统、嵌入式、底层驱动等领域存在一定的唯一性&#xff08;C语…...

小白学Java之数组问题——第三关黄金挑战

内容1.数组中出现次数超过一般的数字2.数组中出现一次的数字3.颜色分类问题 1.数组中出现次数超过一半的数字 这是剑指offer中的一道题目&#xff0c;数组中有一个数字出现的次数超过数组长度的一半&#xff0c;请找出这个数字。 例如&#xff1a;输入如下所示的一个长度为9…...

各大期刊网址

1.NeurIPS&#xff0c;全称Annual Conference on Neural Information Processing Systems&#xff0c; 是机器学习领域的顶级会议&#xff0c;与ICML&#xff0c;ICLR并称为机器学习领域难度最大&#xff0c;水平最高&#xff0c;影响力最强的会议&#xff01; NeurIPS是CCF 推…...

使用autodl服务器,在A40显卡上运行, Yi-34B-Chat-int4模型,并使用vllm优化加速,显存占用42G,速度18 words/s

1&#xff0c;演示视频 https://www.bilibili.com/video/BV1gu4y1c7KL/ 使用autodl服务器&#xff0c;在A40显卡上运行&#xff0c; Yi-34B-Chat-int4模型&#xff0c;并使用vllm优化加速&#xff0c;显存占用42G&#xff0c;速度18 words/s 2&#xff0c;关于A40显卡&#xf…...

unity 2d 入门 飞翔小鸟 下坠功能且碰到地面要停止 刚体 胶囊碰撞器 (四)

1、实现对象要受重力 在对应的图层添加刚体 改成持续 2、设置胶囊碰撞器并设置水平方向 3、地面添加盒状碰撞器 运行则能看到小鸟下坠并落到地面上...

速达软件任意文件上传漏洞复现

简介 速达软件专注中小企业管理软件,产品涵盖进销存软件,财务软件,ERP软件,CRM系统,项目管理软件,OA系统,仓库管理软件等,是中小企业管理市场的佼佼者,提供产品、技术、服务等信息,百万企业共同选择。速达软件全系产品存在任意文件上传漏洞,未经身份认证得攻击者可以通过此漏…...

Name or service not knownstname

Name or service not knownstname Hadoop 或 Spark 集群启动时 报错 Name or service not knownstname 原因时因为 workers 文件在windows 使用图形化工具打开过 操作系统类型不对引发的 在Linux系统上删除 workers 文件 使用 vim 重新编辑后分发即可...

[Geek Challenge 2023] web题解

文章目录 EzHttpunsignn00b_Uploadeasy_phpEzRceezpythonezrfi EzHttp 按照提示POST传参 发现密码错误 F12找到hint&#xff0c;提示./robots.txt 访问一下&#xff0c;得到密码 然后就是http请求的基础知识 抓包修改 最后就是 我们直接添加请求头O2TAKUXX: GiveMeFlag 得到…...

【recrutment / Hiring / Job / Application】

Interviewee I), objected/targeted job/position1.1) Azure 平台运维工程师&#xff08;comms&social&#xff09;1.1.1), comms communication and social, for talk, content1.1.2) Cloud computing1.1.3) 拥有ITI/MCSE/RHCE相关认证或Azure认证(如Az204/Az304 have/own…...

二极管:ESD静电保护二极管

一、什么是ESD二极管 ESD二极管与 TVS二极管原理是一样的&#xff0c;也是为了保护电&#xff0c;但ESD二极管的主要功能是防止静电。 静电防护的前提条件就要求其电容值要足够地低&#xff0c;一般在1PF-3.5PF之间最好&#xff0c;主要应用于板级保护。 二、什么是静电 静…...

【根据数组元素生成随机颜色函数】

const colorOptions ["#f50","#2db7f5","#87d068","#108ee9",];const getRandomColor () > {const randomIndex Math.floor(Math.random() * colorOptions.length);return colorOptions[randomIndex];}; 时小记&#xff0c;终有…...

鸿蒙一出,android开发处境再受重创

华为宣布其自研操作系统鸿蒙HarmonyOSNEXT开发者预览版将不再兼容安卓系统&#xff0c;这一消息引起了广泛关注和热议。这一决策标志着华为正式告别安卓&#xff0c;摆脱了外部的制约&#xff0c;开始着手打造一个全新的生态系统。 鸿蒙系统4发布一个月&#xff0c;截至目前&a…...

ruoyi+Hadoop+hbase实现大数据存储查询

前言 有个现实的需求&#xff0c;数据量可能在100亿条左右。现有的数据库是SQL Server&#xff0c;随着采集的数据不断的填充&#xff0c;查询的效率越来越慢&#xff08;现有的SQL Server查询已经需要数十秒钟的时间&#xff09;&#xff0c;看看有没有优化的方案。 考虑过S…...

Word 在页眉或页脚中设置背景颜色

目录预览 一、问题描述二、解决方案三、参考链接 一、问题描述 如何在word的页眉页脚中设置背景色&#xff1f; 二、解决方案 打开 Word 文档并进入页眉或页脚视图。在 Word 2016 及更高版本中&#xff0c;你可以通过在“插入”选项卡中单击“页眉”或“页脚”按钮来进入或者…...

python获取js data.now同款时间戳

import requestsimport time from datetime import datetimecu_t datetime.now() se cu_t.timestamp()*1000 se int(se) print(se)#cur_time time.time()*1000 #seconds int(cur_time) #print(seconds)...

线上超市小程序可以做什么活动_提升用户参与度与购物体验

标题&#xff1a;线上超市小程序&#xff1a;精心策划活动&#xff0c;提升用户参与度与购物体验 一、引言 随着移动互联网的普及&#xff0c;线上购物已经成为人们日常生活的一部分。线上超市作为线上购物的重要组成部分&#xff0c;以其便捷、快速、丰富的商品种类和个性化…...

旺店通:API无代码开发的集成解决方案,连接电商平台、CRM和客服系统

集成电商生态&#xff1a;旺店通的核心优势 在数字化转型的浪潮中&#xff0c;旺店通旗舰版奇门以其无代码开发的集成解决方案&#xff0c;正成为电商领域的关键变革者。商家们通过旺店通可以轻松实现与电商平台、CRM系统和客服系统的连接&#xff0c;无需深入了解复杂的API开…...