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

区块链-P2P(八)

前言
P2P网络(Peer-to-Peer Network)是一种点对点的网络结构,它没有中心化的服务器或者管理者,所有节点都是平等的。在P2P网络中,每个节点都可以既是客户端也是服务端,这种网络结构的优点是去中心化、可扩展性强、抗攻击性强等。

1:P2P网络的优点

区块链 P2P 网络的优点有:

去中心化:没有中心化的服务器或者管理者,所有节点都是平等的。
高可用性:由于没有单点故障,所以整个系统非常稳定。
高安全性:由于每个节点都有完整的数据副本,所以即使有部分节点被攻击或者宕机,整个系统依然可以正常运行。
高效性:由于数据可以在多个节点之间共享和传输,所以整个系统非常高效。

2:分类
根据具体应用不同,可以把P2P分为以下这些类型[1]:
·提供文件和其它内容共享的P2P网络,例如Napster、Gnutella、eDonkey、emule、BitTorrent等;
·挖掘P2P对等计算能力和存储共享能力,例如SETI@home 、Avaki、Popular Power等;
·基于P2P方式的协同处理与服务共享平台,例如JXTA、Magi、Groove、.NET My Service等;
·即时通讯交流,包括ICQ、OICQ、Yahoo Messenger等;
·安全的P2P通讯与信息共享,例如Skype、Crowds、Onion Routing等。

3:区块链中的P2P网络
作为区块链的底层传输方式,P2P 技术帮助区块链成功实现了点对点的传播。比特币、以太坊等众多区块链项目都实现了属于自己的P2P网络协议,根据区块链的运行特点,我们可以总结出区块链客户端节点所组成p2p网络的一些需求:
1.节点可以任意地加入和离开网络;
2.每个节点所存储的数据(区块),在理想状态下是一致的(当然光凭p2p网络不能达到数据一致性,它只是提供了数据传输的逻辑通道,我们还需要共识算法来配合实现数据一致性);
3.在区块链网络中,查找数据时不需要向整个网络广播发送请求,正常情况下任意一个(或相邻几个)节点就可以提供完整的区块数据。

4:直接上代码
P2P打洞
UDP 打洞更容易点,网上一堆,不发了

TCP SERVER

#include <stdio.h>  #include <signal.h>  #include <fcntl.h>  
#include <stdlib.h>  
#include <errno.h>  
#include <string.h>  #ifdef _WIN32
#include <WinSock2.h>
#include<Ws2tcpip.h>
#pragma comment(lib,"ws2_32.lib")
#else
#include <unistd.h>  
#include <sys/socket.h> 
#include <arpa/inet.h>  
#endif#define MAXLINE 128  
#define SERV_PORT 7119 //发生了致命错误,退出程序  
void error_quit(const char *str)
{fprintf(stderr, "%s", str);//如果设置了错误号,就输入出错原因  
#ifdef _WIN32if (errno != 0) {const int errmsglen = 255;char errmsg[errmsglen];strerror_s(errmsg, errmsglen, errno);fprintf(stderr, " : %s", errmsg);}
#elseif (errno != 0)fprintf(stderr, " : %s", strerror(errno));
#endifprintf("\n");exit(1);
}int main(void)
{int i, res, cur_port;
#ifdef _WIN32SOCKET  connfd, firstfd, listenfd;WSADATA wsaData;WORD  wVersionRequested = MAKEWORD(2, 2);WSAStartup(wVersionRequested, &wsaData);
#elseint connfd, firstfd, listenfd;
#endifint count = 0;char str_ip[MAXLINE];    //缓存IP地址  char cur_inf[MAXLINE];   //当前的连接信息[IP+port]  char first_inf[MAXLINE];    //第一个链接的信息[IP+port]  char buffer[MAXLINE];    //临时发送缓冲区  socklen_t clilen;struct sockaddr_in cliaddr;struct sockaddr_in servaddr;//创建用于监听TCP协议套接字          listenfd = socket(AF_INET, SOCK_STREAM, 0);memset(&servaddr, 0, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr = htonl(INADDR_ANY);servaddr.sin_port = htons(SERV_PORT);//把socket和socket地址结构联系起来         res = bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));if (-1 == res)error_quit("bind error");//开始监听端口         res = listen(listenfd, INADDR_ANY);if (-1 == res)error_quit("listen error");while (1){//接收来自客户端的连接  connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &clilen);if (-1 == connfd)error_quit("accept error");inet_ntop(AF_INET, (void*)&cliaddr.sin_addr, str_ip, sizeof(str_ip));count++;//对于第一个链接,将其的IP+port存储到first_inf中,  //并和它建立长链接,然后向它发送字符串'first',  if (count == 1){firstfd = connfd;cur_port = ntohs(cliaddr.sin_port);snprintf(first_inf, MAXLINE, "%s %d", str_ip, cur_port);#ifdef _WIN32strcpy_s(cur_inf, MAXLINE, "first\n");send(connfd, cur_inf, strlen(cur_inf) + 1, 0);
#elsestrcpy(cur_inf, "first\n");write(connfd, cur_inf, strlen(cur_inf) + 1);
#endif}//对于第二个链接,将其的IP+port发送给第一个链接,  //将第一个链接的信息和他自身的port返回给它自己,  //然后断开两个链接,并重置计数器  else if (count == 2){cur_port = ntohs(cliaddr.sin_port);snprintf(cur_inf, MAXLINE, "%s %d\n", str_ip, cur_port);snprintf(buffer, MAXLINE, "%s %d\n", first_inf, cur_port);#ifdef _WIN32send(connfd, buffer, strlen(buffer) + 1,0);send(firstfd, cur_inf, strlen(cur_inf) + 1,0);closesocket(connfd);closesocket(firstfd);
#elsewrite(connfd, buffer, strlen(buffer) + 1);write(firstfd, cur_inf, strlen(cur_inf) + 1);close(connfd);close(firstfd);
#endifcount = 0;}//如果程序运行到这里,那肯定是出错了  elseerror_quit("Bad required");}
#ifdef _WIN32WSACleanup();
#endifreturn 0;
}
/*
运行示例:
(第一个终端)
ubuntu@ubuntu ~/program/tcode $ gcc server.c -o server
ubuntu@ubuntu ~/program/tcode $ ./server &
[1] 4688
ubuntu@ubuntu ~/program/tcode $ gcc client.c -o client
ubuntu@ubuntu ~/program/tcode $ ./client localhost
Get: first
ff: 127.0.0.1 38052
send message: Hello, world
send message: Hello, world
send message: Hello, world
.................第二个终端:
ubuntu@ubuntu ~/program/tcode $ ./client localhost
Get: 127.0.0.1 38073 38074
connect error
recv message: Hello, world
recv message: Hello, world
recv message: Hello, world
*/

client

#include <stdio.h>  #include <signal.h>  #include <fcntl.h>  
#include <stdlib.h>  
#include <errno.h>  
#include <string.h>  #ifdef _WIN32
#include <WinSock2.h>
#include<Ws2tcpip.h>
#pragma comment(lib,"ws2_32.lib")
#else
#include <unistd.h>  
#include <sys/socket.h> 
#include <arpa/inet.h>  
#endif#define MAXLINE 128  
#define SERV_PORT 7119 typedef struct
{char ip[32];int port;
}server;void error_quit(const char *str)
{fprintf(stderr, "%s", str);//如果设置了错误号,就输入出错原因  
#ifdef _WIN32if (errno != 0) {const int errmsglen = 255;char errmsg[errmsglen];strerror_s(errmsg, errmsglen, errno);fprintf(stderr, " : %s", errmsg);}
#elseif (errno != 0)fprintf(stderr, " : %s", strerror(errno));
#endifprintf("\n");exit(1);
}int main(int argc, char **argv)
{int i, res, port;
#ifdef _WIN32SOCKET  connfd, sockfd, listenfd;WSADATA wsaData;WORD  wVersionRequested = MAKEWORD(2, 2);WSAStartup(wVersionRequested, &wsaData);BOOL bReuseaddr = TRUE;
#elseint connfd, sockfd, listenfd;unsigned int value = 1;
#endifchar buffer[MAXLINE];socklen_t clilen;struct sockaddr_in servaddr, sockaddr, connaddr;server other;if (argc != 2)error_quit("Using: ./client <IP Address>");//创建用于链接(主服务器)的套接字          sockfd = socket(AF_INET, SOCK_STREAM, 0);memset(&sockaddr, 0, sizeof(sockaddr));sockaddr.sin_family = AF_INET;sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);sockaddr.sin_port = htons(SERV_PORT);inet_pton(AF_INET, argv[1], &sockaddr.sin_addr);//设置端口可以被重用  
#ifdef _WIN32setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char*)&bReuseaddr, sizeof(BOOL));
#elsesetsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value));
#endif//连接主服务器  res = connect(sockfd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));if (res < 0)error_quit("connect error");//从主服务器中读取出信息  
#ifdef _WIN32res = recv(sockfd, buffer, MAXLINE,0);
#elseres = read(sockfd, buffer, MAXLINE);
#endifif (res < 0)error_quit("read error");printf("Get: %s", buffer);//若服务器返回的是first,则证明是第一个客户端  if ('f' == buffer[0]){//从服务器中读取第二个客户端的IP+port  
#ifdef _WIN32res = recv(sockfd, buffer, MAXLINE, 0);sscanf_s(buffer, "%s %d", other.ip,&other.port);
#elseres = read(sockfd, buffer, MAXLINE);sscanf(buffer, "%s %d", other.ip, &other.port);
#endifprintf("ff: %s %d\n", other.ip, other.port);//创建用于的套接字          connfd = socket(AF_INET, SOCK_STREAM, 0);memset(&connaddr, 0, sizeof(connaddr));connaddr.sin_family = AF_INET;connaddr.sin_addr.s_addr = htonl(INADDR_ANY);connaddr.sin_port = htons(other.port);inet_pton(AF_INET, other.ip, &connaddr.sin_addr);//尝试去连接第二个客户端,前几次可能会失败,因为穿透还没成功,  //如果连接10次都失败,就证明穿透失败了(可能是硬件不支持)  while (1){static int j = 1;res = connect(connfd, (struct sockaddr *)&connaddr, sizeof(connaddr));if (res == -1){if (j >= 10)error_quit("can't connect to the other client\n");printf("connect error, try again. %d\n", j++);
#ifdef _WIN32Sleep(1);
#elsesleep(1);
#endif}elsebreak;}
#ifdef _WIN32strcpy_s(buffer, MAXLINE, "Hello, world\n");
#elsestrcpy(buffer, "Hello, world\n");
#endif//连接成功后,每隔一秒钟向对方(客户端2)发送一句hello, world  while (1){
#ifdef _WIN32res = send(connfd, buffer, strlen(buffer) + 1,0);
#elseres = write(connfd, buffer, strlen(buffer) + 1);
#endifif (res <= 0)error_quit("write error");printf("send message: %s", buffer);
#ifdef _WIN32Sleep(1);
#elsesleep(1);
#endif}}//第二个客户端的行为  else{//从主服务器返回的信息中取出客户端1的IP+port和自己公网映射后的port  
#ifdef _WIN32sscanf_s(buffer, "%s %d %d", other.ip, &other.port, &port);
#elsesscanf(buffer, "%s %d %d", other.ip, &other.port, &port);
#endif//创建用于TCP协议的套接字          sockfd = socket(AF_INET, SOCK_STREAM, 0);memset(&connaddr, 0, sizeof(connaddr));connaddr.sin_family = AF_INET;connaddr.sin_addr.s_addr = htonl(INADDR_ANY);connaddr.sin_port = htons(other.port);inet_pton(AF_INET, other.ip, &connaddr.sin_addr);//设置端口重用  
#ifdef _WIN32BOOL bReuseaddr = TRUE;setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char*)&bReuseaddr, sizeof(BOOL));
#elsesetsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value));
#endif//尝试连接客户端1,肯定会失败,但它会在路由器上留下记录,  //以帮忙客户端1成功穿透,连接上自己   res = connect(sockfd, (struct sockaddr *)&connaddr, sizeof(connaddr));if (res < 0)printf("connect error\n");//创建用于监听的套接字          listenfd = socket(AF_INET, SOCK_STREAM, 0);memset(&servaddr, 0, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr = htonl(INADDR_ANY);servaddr.sin_port = htons(port);//设置端口重用  
#ifdef _WIN32setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (const char*)&bReuseaddr, sizeof(BOOL));
#elsesetsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value));
#endif//把socket和socket地址结构联系起来   res = bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));if (-1 == res)error_quit("bind error");//开始监听端口         res = listen(listenfd, INADDR_ANY);if (-1 == res)error_quit("listen error");while (1){//接收来自客户端1的连接  connfd = accept(listenfd, (struct sockaddr *)&sockaddr, &clilen);if (-1 == connfd)error_quit("accept error");while (1){//循环读取来自于客户端1的信息  
#ifdef _WIN32res = recv(connfd, buffer, MAXLINE,0);
#elseres = read(connfd, buffer, MAXLINE);
#endifif (res <= 0)error_quit("read error");printf("recv message: %s", buffer);}
#ifdef _WIN32closesocket(connfd);
#elseclose(connfd);
#endif}}return 0;
}

golang的参考 github.com/ethereum/go-ethereum/
在这里插入图片描述
在这里插入图片描述

参考 https://blog.csdn.net/muxuen/article/details/137231514
在这里插入图片描述

5:运行结果(暂时手上没有公网服务器,请自行编译测试)

如果觉得有用,麻烦点个赞,加个收藏

相关文章:

区块链-P2P(八)

前言 P2P网络&#xff08;Peer-to-Peer Network&#xff09;是一种点对点的网络结构&#xff0c;它没有中心化的服务器或者管理者&#xff0c;所有节点都是平等的。在P2P网络中&#xff0c;每个节点都可以既是客户端也是服务端&#xff0c;这种网络结构的优点是去中心化、可扩展…...

数据库管理的利器Navicat —— 全面测评与热门产品推荐

在数据库管理领域&#xff0c;Navicat无疑是一款深受欢迎的软件。作为一个强大的数据库管理和开发工具&#xff0c;它支持多种数据库类型&#xff0c;包括MySQL、MariaDB、MongoDB、SQL Server、Oracle、PostgreSQL等。本文将全面测评Navicat的核心功能&#xff0c;同时推荐几款…...

如何让Google收录我的网站?

其实仅仅只是收录&#xff0c;只要在GSC提交网址&#xff0c;等个两三天&#xff0c;一般就能收录&#xff0c;但收录是否会掉&#xff0c;这篇内容收录了是否有展现&#xff0c;排名&#xff0c;就是另外一个课题了&#xff0c;如果不收录&#xff0c;除了说明你的网站有问题&…...

03 Flask-添加配置信息

回顾之前学习的内容 02 Flask-快速上手 Flask 中最简单的web应用组成 1. 导入核心库 Flask from flask import Flask2. 实例化 web应用 注意&#xff1a;不要漏了 app Flask(__name__) 中的 __name__ 表示&#xff1a;是从当前的py文件实例化 app Flask(__name__)3. 创…...

Codes 开源研发项目管理平台——敏捷测试管理创新解决方案

前言 Codes 是国内首款重新定义 SaaS 模式的开源项目管理平台&#xff0c;支持云端认证、本地部署、全部功能开放&#xff0c;并且对30人以下团队免费。它通过整合迭代、看板、度量和自动化等功能&#xff0c;简化测试协同工作&#xff0c;使敏捷测试更易于实施。并提供低成本的…...

耗时一个月,我做了一个网页视频编辑器

最近又肝了一个多月&#xff0c;终于把这个网页视频编辑器做好了&#xff0c;下面我来简单介绍一下如何使用 注意目前该功能还处在测试阶段&#xff0c;可能会有很多问题&#xff0c;后续我会不断修复 体验地址 app.zyjj.cc 界面介绍 整个剪辑界面包括4个区&#xff0c;左边是…...

uniapp 做一个查看图片的组件,图片可缩放移动

因为是手机端&#xff0c;所以需要触摸可移动&#xff0c;双指放大缩小。 首先在components里建个组件 查看图片使用 uni-popup 弹窗 要注意 transform的translate和scale属性在同一标签上不会一起生效 移动就根据触摸效果进行偏移图片 缩放就根据双指距离的变大变小进行缩…...

卡车配置一键启动无钥匙进入手机控车

‌ 卡车智能一键启动无钥匙进入手机控车&#xff0c;通过手机应用程序与汽车内置硬件、软件的无线通信&#xff0c;实现对汽车的远程控制‌。 卡车改装一键启动的步骤包括安装门把手的感应装置、拆卸仪表台和门板&#xff0c;取出内部的待接线束&#xff0c;并将一键启动…...

计算机网络基础概念 交换机、路由器、网关、TBOX

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、VLAN是什么&#xff1f;二 、交换机三、路由器四、网关五、TBOX六、问题1 、网关和交换机的区别2、网关和路由器的区别 总结 前言 工作有感而发&#xff0…...

labview禁用8080端口

需求背景 最近电脑上安装了labview全家桶,发现idea的8080端口项目启动报错,一直提示8080端口被占用。最简单的办法就是找到8080端口的服务,然后关闭这个服务。但是我不想这么做,我想把labview的web服务器的端口给修改了。 操作教程 1、cmd查看8080端口 2、windows进程 同…...

字符串的KMP算法详解及C/C++代码实现

1. 原由 紧接上文&#xff0c;我们知道了暴力匹配的算法在时间运行上的缺陷&#xff0c;假设字符串T的长度为n&#xff0c;字符串P的长度为m&#xff0c;则整个算法的时间复杂度为O( n * m )&#xff0c;而对于一个复杂的现实情况而言 n >> m >> 2 &#xff08;即…...

2024年数学建模比赛题目及解题代码

目录 一、引言 1. 1竞赛背景介绍 1.1.1数学建模竞赛概述 1.1.2生产过程决策问题在竞赛中的重要性 1.2 解题前准备 1.2.2 工具与资源准备 1.2.3 心态调整与策略规划 二、问题理解与分析 三、模型构建与求解 3.1 模型选择与设计 3.1.1 根据问题特性选择合适的数学模型类…...

BERT 论文逐段精读【论文精读】

BERT: 近 3 年 NLP 最火 CV: 大数据集上的训练好的 NN 模型&#xff0c;提升 CV 任务的性能 —— ImageNet 的 CNN 模型 NLP: BERT 简化了 NLP 任务的训练&#xff0c;提升了 NLP 任务的性能 BERT 如何站在巨人的肩膀上的&#xff1f;使用了哪些 NLP 已有的技术和思想&#xff…...

在Flask中实现跨域请求(CORS)

在Flask中实现跨域请求&#xff08;CORS&#xff0c;Cross-Origin Resource Sharing&#xff09;主要涉及到对Flask应用的配置&#xff0c;以允许来自不同源的请求访问服务器上的资源。以下是在Flask中实现CORS的详细步骤和方法&#xff1a; 一、理解CORS CORS是一种机制&…...

在桌面商业分析应用程序中启用高级 Web UI

挑战 Mercur Business Control 应用程序在企业界&#xff0c;尤其是金融领域&#xff0c;拥有悠久的应用历史。它帮助企业处理、可视化和分析海量数据&#xff0c;从而做出明智的商业决策。 随着产品的不断演进和现代化&#xff0c;Mercur Solutions AB 为该应用创建了 Web 客…...

CentOS Stream 8 通过 Packstack 安装开源 OpenStack(V版)

1、环境规划以及网卡配置 controller IP&#xff1a;192.168.235.101 compute IP&#xff1a;192.168.235.102 控制节点 [rootluck ~]# cd /etc/sysconfig/network-scripts/ [rootluck network-scripts]# vi ifcfg-ens160 [rootluck network-scripts]# cat ifcfg-ens160 TYP…...

OpenSSL工具验证RSA证书

openssl x509 是一个用于处理 X.509 证书的命令行工具。常用的 openssl x509 命令&#xff1a; -in <file>&#xff1a;指定输入文件。-out <file>&#xff1a;指定输出文件。-noout&#xff1a;不输出证书信息。-text&#xff1a;以文本格式输出证书信息。-pubke…...

架构师白话分布式系统

对于分布式系统的定义,大致可以理解为如下的两个点 分布式系统从整体的体量来说,它内部是由很多的服务器、服务实例组成。所提供的用户服务是由一组相互独立运行的服务器来提供。对于用户来说,这个多服务器的系统就跟一个服务器一样,感觉不到每个单独的服务器实例的存在。从…...

C++ 中 vector 的常用功能介绍

在 C 中&#xff0c;vector 是一种常用的动态数组容器&#xff0c;提供了方便的自动扩展、内存管理以及各种便捷的操作方法。它是 C 标准模板库&#xff08;STL&#xff09;的一部分&#xff0c;适用于需要动态存储和管理大量元素的场景。 在本文中&#xff0c;我们将简要介绍…...

[QT] QT事件与事件重写

一.事件 事件(event)是由系统或者 Qt本身在不同的场景下发出的。当用户按下鼠标、敲下键盘&#xff0c;或者是窗口关闭等都会发出一个相应的事件。 一些事件在用户操作时发出(如鼠标/键盘事件); 另一些事件则是由系统自动发出(如计时器事件)。 Qt窗口中对于产生的一系列事件都…...

Vim 调用外部命令学习笔记

Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

C++:std::is_convertible

C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

java 实现excel文件转pdf | 无水印 | 无限制

文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

ffmpeg(四):滤镜命令

FFmpeg 的滤镜命令是用于音视频处理中的强大工具&#xff0c;可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下&#xff1a; ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜&#xff1a; ffmpeg…...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)

参考官方文档&#xff1a;https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java&#xff08;供 Kotlin 使用&#xff09; 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计

随着大语言模型&#xff08;LLM&#xff09;参数规模的增长&#xff0c;推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长&#xff0c;而KV缓存的内存消耗可能高达数十GB&#xff08;例如Llama2-7B处理100K token时需50GB内存&a…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)

在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马&#xff08;服务器方面的&#xff09;的原理&#xff0c;连接&#xff0c;以及各种木马及连接工具的分享 文件木马&#xff1a;https://w…...