Google A2A协议解析:构建分布式异构多Agent系统
一、A2A 是什么?有什么用?
1.1 A2A 是什么?
A2A(Agent-to-Agent Protocol)是Google最新推出的一项开源协议,旨在为AI智能体(Agents)提供标准化的通信方式。它允许不同框架(如LangChain、CrewAI)或不同供应商开发的智能体无缝协作,打破智能体间的隔离状态。A2A通过统一的通信格式和交互规则,让智能体像网络服务一样自由“对话”。
[图片来源于Google A2A官网文档]
核心目标:
- 互操作性:无论智能体基于何种技术栈,A2A都提供通用的通信“语言”。
- 模块化:支持智能体动态发现彼此并灵活组合,完成复杂任务。
- 安全性:内置认证和授权机制,确保通信安全。
- 开放性:A2A采用Apache 2.0许可,得到Atlassian、Salesforce、Cohere等50多家企业的支持。
1.2 A2A 有什么用?
A2A解决的是AI系统中智能体碎片化的问题。例如,在企业中,HR系统可能使用Salesforce智能体管理员工数据,而财务系统使用SAP智能体处理报销。如果这些智能体无法直接通信,用户需要手动传递数据,效率低下。
A2A的价值:
- 协作简化:智能体间直接交换数据和任务,例如HR智能体请求财务智能体验证报销状态。
- 任务自动化:支持任务委派和状态跟踪,减少人工干预。
- 生态扩展:开发者可构建专用智能体,通过A2A集成到更大生态中。
- 企业应用:支持实时通信、安全认证,适应复杂企业场景。
应用场景:
- 招聘流程:HR智能体筛选候选人,委托LinkedIn智能体搜索简历,再由日历智能体安排面试。
- 客户服务:客服智能体接收请求,调用库存智能体检查商品,再通过支付智能体完成交易。
1.3 A2A与 MCP的关系
什么是 MCP?
MCP(Model Context Protocol)是一个协议,专注于为 AI 代理提供对工具、数据和上下文的标准化访问。它主要作用于单个代理层面,通过集成外部资源来增强代理的内部能力。MCP 通常与基于语言模型的代理相关联,帮助它们更高效地执行任务。
维度 | A2A | MCP |
---|---|---|
目的 | 促进 AI 代理之间的通信和协作 | 为 AI 代理提供对工具、数据和上下文的标准化访问 |
关注点 | 代理之间的外部交互,强调多代理协同 | 代理的内部能力,提升资源利用效率 |
使用场景 | 代理需要相互配合的场景,如任务委派、信息共享或协调行动 | 代理需要调用外部工具或数据的场景,如处理文档或执行特定功能 |
适用范围 | 适用于任何类型的 AI 代理,具有通用性 | 主要针对基于语言模型的代理,应用范围更具体 |
模态支持 | 支持多种模态(文本、音频、视频等),适合多样化的通信需求 | 主要处理文本交互,未明确强调多模态通信 |
示例 | 代理与代理或用户通信,如请求信息、协调行动 | 代理调用具体工具,如执行物理操作或处理数据 |
互补关系 | 侧重于代理间的协作,适合多代理系统 | 侧重于代理的资源访问,增强单个代理的能力 |
建议应用程序将 A2A 智能体建模为 MCP 资源(由其智能体卡片表示)。然后,这些框架可以使用 A2A 与用户、远程智能体以及其他智能体进行通信。
A2A与MCP整体集成方式如下:
[图片来源于A2A官网说明]
总结
- A2A:专注于代理之间的通信和协作,适用于多代理协同工作的场景。
- MCP:专注于代理对工具和数据的访问,旨在提升单个代理的内部能力。
- 互补性:A2A 实现代理间的“对话”,MCP 提供代理“做事”的能力,两者可以结合使用以构建更强大的 AI 系统。
二、A2A 的核心原理
A2A基于HTTP+JSON协议,设计灵感来自分布式系统和微服务架构。以下是其核心概念和工作流程。
2.1 核心概念
-
Agent Card(智能体名片)
- 一个公开的JSON元数据文件(通常位于
/.well-known/agent.json
),描述智能体的名称、能力、端点URL和认证要求。 - 其他智能体通过Agent Card发现目标智能体的功能。
- 示例:
{"name": "EchoAgent","description": "A simple echo agent that repeats messages","url": "http://localhost:5000","authentication": {"schemes": ["none"]},"capabilities": {"streaming": false, "pushNotifications": false} }
- 一个公开的JSON元数据文件(通常位于
-
A2A Server
- 智能体暴露的HTTP服务端点,实现A2A协议的方法(如
tasks/send
)。 - 负责接收请求、执行任务并返回结果。
- 智能体暴露的HTTP服务端点,实现A2A协议的方法(如
-
A2A Client
- 向A2A Server发送请求的应用或智能体,用于发起任务或对话。
- 通过Agent Card定位Server。
-
Task(任务)
- A2A的基本工作单元,通过
tasks/send
或tasks/sendSubscribe
发起。 - 任务有唯一ID,支持状态管理:
submitted
、working
、input-required
、completed
、failed
、canceled
。
- A2A的基本工作单元,通过
-
Message(消息)
- 客户端(
user
角色)与智能体(agent
角色)之间的单次通信。 - 由多个
Part
组成,支持文本、文件或结构化数据。
- 客户端(
2.2 工作流程
- 发现:客户端通过Agent Card了解目标智能体的能力。
- 任务发起:客户端发送
POST /tasks/send
请求,附带任务详情。 - 任务执行:Server处理任务,可能请求额外输入(
input-required
状态)。 - 状态更新:Server通过响应或推送通知更新任务状态。
- 结果返回:任务完成后,Server返回结果。
第三部分:A2A 实践教程 - 构建两个简单的Python智能体
本节参考Google A2A官方Python示例代码(https://github.com/google/A2A/tree/main/samples/python),详细构建一个客户端-服务器智能体系统。我们将创建一个“回声智能体”(Echo Agent),它接收消息并返回相同内容。通过分步构建、代码解读和执行结果分析,帮助读者掌握A2A的实践应用。
3.1 环境准备
-
安装Python
确保系统安装Python 3.8+。
安装依赖库:pip install flask requests
-
获取A2A示例代码
克隆Google A2A GitHub仓库:git clone https://github.com/google/A2A.git
示例代码位于
samples/python
目录。我们将基于此构建。
3.2 创建A2A Server(回声智能体)
我们使用Flask框架创建一个A2A Server,提供Agent Card和任务处理端点。
3.2.1 代码构建过程
步骤1:初始化Flask应用
创建一个名为server.py
的文件,导入Flask并初始化应用:
from flask import Flask, request, jsonifyapp = Flask(__name__)
步骤2:实现Agent Card端点
添加/.well-known/agent.json
端点,返回智能体的元数据:
@app.route('/.well-known/agent.json')
def agent_card():return jsonify({"name": "EchoAgent","description": "A simple echo agent that repeats messages","url": "http://localhost:5000","authentication": {"schemes": ["none"]},"capabilities": {"streaming": false,"pushNotifications": false}})
步骤3:实现任务处理端点
添加/tasks/send
端点,接收任务请求并返回回声响应:
@app.route('/tasks/send', methods=['POST'])
def handle_task():data = request.jsontask_id = data.get('taskId', 'task-001')messages = data.get('messages', [])# 解析用户消息并构造回声响应for message in messages:if message['role'] == 'user':for part in message['parts']:if part['type'] == 'text/plain':user_text = part['data']response = {"taskId": task_id,"state": "completed","messages": [{"role": "agent","parts": [{"type": "text/plain","data": user_text}]}]}return jsonify(response)# 处理无效请求return jsonify({"error": "Invalid request"}), 400
步骤4:运行服务
添加启动代码:
if __name__ == '__main__':app.run(port=5000)
完整代码(server.py
):
from flask import Flask, request, jsonifyapp = Flask(__name__)@app.route('/.well-known/agent.json')
def agent_card():return jsonify({"name": "EchoAgent","description": "A simple echo agent that repeats messages","url": "http://localhost:5000","authentication": {"schemes": ["none"]},"capabilities": {"streaming": false,"pushNotifications": false}})@app.route('/tasks/send', methods=['POST'])
def handle_task():data = request.jsontask_id = data.get('taskId', 'task-001')messages = data.get('messages', [])for message in messages:if message['role'] == 'user':for part in message['parts']:if part['type'] == 'text/plain':user_text = part['data']response = {"taskId": task_id,"state": "completed","messages": [{"role": "agent","parts": [{"type": "text/plain","data": user_text}]}]}return jsonify(response)return jsonify({"error": "Invalid request"}), 400if __name__ == '__main__':app.run(port=5000)
3.2.2 代码解读
Agent Card端点
- 路径:
/.well-known/agent.json
- 功能:返回智能体的元数据,包括名称、描述、服务URL、认证方式和能力(如是否支持流式传输或推送通知)。
- 作用:这是A2A协议中智能体发现的基础,客户端通过此端点了解Server信息。
任务处理端点
- 路径:
/tasks/send
- 方法:POST
- 逻辑:
- 解析请求JSON,提取
taskId
和messages
。 - 遍历
messages
,找到role
为user
的消息。 - 检查消息的
parts
,提取text/plain
类型的data
(用户文本)。 - 构造响应,包含相同的文本,设置
state
为completed
,role
为agent
。 - 如果请求无效,返回400错误。
- 解析请求JSON,提取
3.2.3 运行与验证
运行Server:
python server.py
验证Agent Card:
访问http://localhost:5000/.well-known/agent.json
,预期输出:
{"name": "EchoAgent","description": "A simple echo agent that repeats messages","url": "http://localhost:5000","authentication": {"schemes": ["none"]},"capabilities": {"streaming": false,"pushNotifications": false}
}
3.3 创建A2A Client
客户端将向Server发送消息并显示响应。
3.3.1 代码构建过程
步骤1:初始化客户端
创建client.py
,导入所需库并定义Server URL:
import requests
import jsonSERVER_URL = "http://localhost:5000"
步骤2:获取Agent Card
添加函数以获取Server的Agent Card:
def get_agent_card():response = requests.get(f"{SERVER_URL}/.well-known/agent.json")return response.json()
步骤3:发送任务
添加函数构造并发送任务请求:
def send_task(message):payload = {"taskId": "task-001","messages": [{"role": "user","parts": [{"type": "text/plain","data": message}]}]}response = requests.post(f"{SERVER_URL}/tasks/send", json=payload)return response.json()
步骤4:测试客户端
添加主函数,调用上述功能:
if __name__ == '__main__':# 获取Agent Cardcard = get_agent_card()print("Agent Card:", json.dumps(card, indent=2))# 发送测试消息message = "Hello, A2A!"result = send_task(message)print("Task Result:", json.dumps(result, indent=2))
完整代码(client.py
):
import requests
import jsonSERVER_URL = "http://localhost:5000"def get_agent_card():response = requests.get(f"{SERVER_URL}/.well-known/agent.json")return response.json()def send_task(message):payload = {"taskId": "task-001","messages": [{"role": "user","parts": [{"type": "text/plain","data": message}]}]}response = requests.post(f"{SERVER_URL}/tasks/send", json=payload)return response.json()if __name__ == '__main__':card = get_agent_card()print("Agent Card:", json.dumps(card, indent=2))message = "Hello, A2A!"result = send_task(message)print("Task Result:", json.dumps(result, indent=2))
3.3.2 代码解读
获取Agent Card
- 函数:
get_agent_card
- 功能:通过GET请求获取Server的Agent Card,验证智能体信息。
发送任务
- 函数:
send_task
- 逻辑:
- 构造JSON payload,包含
taskId
和messages
。 messages
包含一个user
角色的消息,parts
为text/plain
类型的文本。- 发送POST请求到
/tasks/send
,返回Server响应。
- 构造JSON payload,包含
3.3.3 运行与结果分析
运行Client:
确保Server运行后,执行:
python client.py
预期输出:
Agent Card: {"name": "EchoAgent","description": "A simple echo agent that repeats messages","url": "http://localhost:5000","authentication": {"schemes": ["none"]},"capabilities": {"streaming": false,"pushNotifications": false}
}
Task Result: {"taskId": "task-001","state": "completed","messages": [{"role": "agent","parts": [{"type": "text/plain","data": "Hello, A2A!"}]}]
}
结果分析:
- Agent Card:客户端成功获取Server元数据,确认智能体名称、描述和能力。
- 任务执行:客户端发送消息"Hello, A2A!",Server返回相同内容,任务状态为
completed
。 - 通信流程:展示了A2A的发现(Agent Card)和任务处理(
/tasks/send
)完整过程。
3.4 扩展功能
-
添加认证
修改Agent Card支持OAuth2:"authentication": {"schemes": ["oauth2"],"credentials": "your-token-endpoint" }
在Server中验证请求头中的令牌。
-
支持推送通知
在Agent Card中启用pushNotifications: true
,使用WebSocket实现状态更新。 -
集成LLM
将Server与语言模型(如OpenAI)集成,生成动态响应而非简单回声。
第四部分:A2A 的进阶应用与注意事项
在掌握 A2A 协议的基础功能和初步实践后,进一步探索其在复杂场景中的应用以及实施时的注意事项,可以显著提升技术能力并充分发挥 A2A 的潜力。作为一种智能体协作协议,A2A 不仅是通信工具,更是构建高效、灵活的企业级 AI 系统的基石。本节将通过详细的场景分析和实现方法,深入讲解其进阶应用,并结合具体注意事项,确保系统在实际部署中的可靠性与高效性。
4.1 进阶应用
A2A 协议在多智能体协作、动态交互和企业级部署中展现了强大的能力。
4.1.1 多智能体协作
多智能体协作是 A2A 的核心优势之一,尤其在需要多个智能体协同完成复杂任务的场景中。例如,在企业招聘流程中,HR 智能体、LinkedIn 智能体和 Google Calendar 智能体可以通过 A2A 协议无缝协作,实现从候选人搜索到面试安排的全流程自动化。
实现过程:
设想一家公司需要招聘一名 Python 开发人员。流程从 HR 智能体开始:它首先生成一个唯一的任务 ID(如 task-001
),然后向 LinkedIn 智能体发送一个请求,内容可能是这样的 JSON 格式消息:
{"task_id": "task-001","action": "search_candidates","parameters": {"role": "Python developer","location": "remote","experience": "3-5 years"}
}
LinkedIn 智能体接收到请求后,利用其内置的搜索功能在平台上查找匹配的候选人,并将结果整理为一个候选人列表,例如:
{"task_id": "task-001","status": "completed","result": [{"name": "Alice", "skills": ["Python", "Django"], "experience": "4 years"},{"name": "Bob", "skills": ["Python", "Flask"], "experience": "3 years"}]
}
HR 智能体接收到这个响应后,筛选出合适的候选人(例如 Alice),然后向 Google Calendar 智能体发送一个新请求:
{"task_id": "task-002","action": "schedule_interview","parameters": {"candidate": "Alice","date": "2023-11-10","time": "14:00-15:00"}
}
Google Calendar 智能体检查日程安排,确认时间可用后,返回确认消息:
{"task_id": "task-002","status": "completed","result": {"confirmation": "Interview scheduled for Alice on 2023-11-10, 14:00-15:00"}
}
应用价值:
这种协作模式通过任务状态(如“working”、“completed”)管理每个步骤,确保流程透明且可追溯。A2A 的消息传递机制让智能体之间能够清晰分工,类似人类团队中的协作。除了招聘,这种模式还可以扩展到客户服务(智能体分配工单)、库存管理(智能体协调供应链)等场景,大幅提升企业的自动化水平和运营效率。
4.1.2 表单交互
A2A 协议支持动态的用户交互,尤其适用于需要用户提供额外信息的场景。以企业报销流程为例,报销智能体可以在任务执行过程中请求用户填写费用详情,从而实现灵活的交互。
实现过程:
假设一名员工需要提交报销请求。他首先通过客户端发送一个初始请求:
{"task_id": "expense-001","action": "submit_expense_report","user": "John"
}
报销智能体接收到请求后,发现需要更多信息,于是返回一个“input-required”状态的响应,并附带一个 HTML 表单:
{"task_id": "expense-001","status": "input-required","form": "<form><label>Amount:</label><input name='amount'><label>Date:</label><input name='date' type='date'></form>"
}
客户端将这个表单渲染给用户,用户填写费用金额(如 $200
)和日期(如 2023-11-01
),然后提交一个新请求:
{"task_id": "expense-001","action": "submit_form","data": {"amount": 200,"date": "2023-11-01"}
}
报销智能体接收到数据后,验证信息无误,完成任务并返回确认:
{"task_id": "expense-001","status": "completed","result": {"message": "Expense report submitted successfully"}
}
应用价值:
通过“input-required”状态和 HTML 表单,A2A 实现了智能体与用户之间的动态交互。这种机制非常适合需要用户输入的场景,如客户服务中的问题澄清、数据收集中的字段填写等。表单的灵活性还允许开发者根据任务需求调整字段,提升系统的适应性和用户体验。
4.1.3 企业级部署
A2A 协议支持将智能体部署到云端,实现高可用性和自动扩展。以 Google Cloud Run 为例,开发者可以将 A2A 智能体容器化并部署到云端,利用 Serverless 架构简化运维并支持高并发。
实现过程:
假设我们要部署一个处理招聘任务的 HR 智能体。首先,编写一个简单的 Dockerfile:
FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["python", "hr_agent.py"]
接着,将智能体代码和依赖打包成 Docker 镜像,并在本地构建:
docker build -t hr-agent:latest .
然后,将镜像推送到 Google Container Registry(GCR):
docker tag hr-agent:latest gcr.io/my-project/hr-agent:latest
docker push gcr.io/my-project/hr-agent:latest
最后,通过 Google Cloud Run 部署镜像:
gcloud run deploy hr-agent \--image gcr.io/my-project/hr-agent:latest \--platform managed \--region us-central1 \--allow-unauthenticated
部署完成后,Cloud Run 会返回一个服务 URL(如 https://hr-agent-abc123-uc.a.run.app
),智能体即可通过此 URL 接收 A2A 请求。为了增强安全性,可以启用 OAuth2 认证,只允许授权用户访问。
应用价值:
Cloud Run 的 Serverless 特性让智能体能够根据请求量自动扩展,无需手动管理服务器。同时,Google Cloud 的负载均衡功能确保服务在高并发下的稳定性。这种部署方式简化了运维,支持快速迭代和多区域部署,非常适合全球化企业的需求。
4.2 注意事项
在实施 A2A 时,需要关注多个方面,以确保系统的安全性、性能和用户体验。以下是对每个注意事项的详细分析和建议。
4.2.1 安全性
安全性是企业级应用的重中之重。A2A 协议提供了多种机制来保护系统和数据。
例如,在招聘场景中,HR 智能体可能需要访问敏感的员工数据。为了防止未授权访问,可以通过 OAuth2 认证为每个智能体分配一个访问令牌。请求示例:
{"task_id": "task-001","action": "search_candidates","auth_token": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
此外,所有通信都应强制使用 HTTPS 协议,确保数据在传输过程中加密。权限管理也很关键:HR 智能体只能访问员工数据,而报销智能体只能处理财务信息,通过细粒度的角色控制防止数据滥用。
4.2.2 性能优化
在高并发场景下,性能优化尤为重要。以招聘流程为例,如果同时有数百个招聘任务,系统需要高效处理请求。
开发者可以使用 FastAPI 替代传统的 Flask,因为 FastAPI 支持异步处理,能显著提升并发能力。此外,对于频繁访问的静态数据(如 Agent Card),可以引入 Redis 缓存:
import redis
cache = redis.Redis(host='localhost', port=6379)
cache.set('agent_card', json.dumps(agent_card_data))
在部署时,可以结合 Google Cloud Load Balancer,将流量分发到多个智能体实例,确保系统稳定运行。
4.2.3 错误处理
良好的错误处理能提升系统的健壮性。例如,如果 LinkedIn 智能体因网络问题无法返回候选人列表,应返回详细错误信息:
{"task_id": "task-001","status": "failed","error": {"code": 503, "message": "Service unavailable, please try again later"}
}
同时,使用 Python 的 logging
模块记录每次请求和响应,方便调试:
import logging
logging.basicConfig(level=logging.INFO)
logging.info(f"Task {task_id} failed: {error_message}")
客户端还可以实现指数退避重试策略,应对临时性网络问题。
4.2.4 兼容性
A2A 的兼容性直接影响多智能体协作的效果。开发者应使用 jsonschema
验证消息格式,例如:
from jsonschema import validate
schema = {"type": "object", "properties": {"task_id": {"type": "string"}}}
validate(instance=request, schema=schema)
在集成不同框架(如 LangChain、CrewAI)的智能体时,需进行互操作性测试,确保消息传递无误。此外,跟踪 A2A 协议的版本更新,及时适配新功能。
4.2.5 任务状态管理
任务状态管理是 A2A 的核心。例如,招聘任务可能经历“submitted”、“working”、“completed”等状态。开发者应设计清晰的状态机,并设置超时机制:
import time
if time.time() - task_start_time > 300: # 5分钟超时task_status = "failed"
使用 SQLite 持久化状态,确保系统重启后任务进度不丢失。
4.2.6 消息设计
A2A 支持多种消息类型。例如,报销智能体可能需要传递图像(如收据扫描件),可以使用嵌套 JSON:
{"task_id": "expense-001","data": {"text": "Receipt for dinner","image": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQ..."}
}
这种结构化设计确保数据完整且易于解析。
4.2.7 用户体验
优秀的用户体验能提升系统满意度。例如,通过 WebSocket 实时推送任务进度:
async def notify_user(websocket, task_id, status):await websocket.send_json({"task_id": task_id, "status": status})
为“input-required”任务提供直观的 UI,并确保错误提示清晰易懂,如“金额必须为正数”。
第五部分:总结与下一步
5.1 总结
通过本教程,你可能了解了Google A2A:
- 基础:掌握A2A的用途、核心概念和工作原理。
- 实践:基于官方Python示例,构建并运行了回声智能体。
- 进阶:学习了多智能体协作、表单交互和企业部署。
- 注意事项:了解安全性、性能等关键实践。
A2A的开放性和标准化特性使其成为构建智能体生态的理想选择。
5.2 下一步如何学习
- 探索示例:尝试A2A仓库中的其他样本,如多轮对话智能体。
- 社区参与:加入Google A2A GitHub讨论。
- 企业集成:对接Salesforce等平台,验证真实场景。
- 持续学习:关注Google A2A 官网更新。
相关文章:
Google A2A协议解析:构建分布式异构多Agent系统
一、A2A 是什么?有什么用? 1.1 A2A 是什么? A2A(Agent-to-Agent Protocol)是Google最新推出的一项开源协议,旨在为AI智能体(Agents)提供标准化的通信方式。它允许不同框架…...
【Android读书笔记】读书笔记记录
文章目录 一. Android开发艺术探索1. Activity的生命周期和启动模式1.1 生命周期全面分析 一. Android开发艺术探索 1. Activity的生命周期和启动模式 1.1 生命周期全面分析 onPause和onStop onPause后会快速调用onStop,极端条件下直接调用onResume 当用户打开新…...
支持selenium的chrome driver更新到135.0.7049.84
最近chrome释放新版本:135.0.7049.84 如果运行selenium自动化测试出现以下问题,是需要升级chromedriver才可以解决的。 selenium.common.exceptions.SessionNotCreatedException: Message: session not created: This version of ChromeDriver only su…...
【玩泰山派】MISC(杂项)- 使用vscode远程连接泰山派进行开发
文章目录 前言流程1、安装、启动sshd2、配置一下允许root登录3、vscode中配置1、安装remote插件2、登录 **注意** 前言 有时候要在开发板中写一写代码,直接在终端中使用vim这种工具有时候也不是很方便。这里准备使用vscode去通过ssh远程连接泰山派去操作࿰…...
利用阿里云企业邮箱服务实现Python群发邮件
目录 一、阿里云企业邮箱群发邮件全流程实现 1. 准备工作与环境配置 2. 收件人列表管理 3. 邮件内容构建 4. 附件添加实现 5. 邮件发送核心逻辑 二、开发过程中遇到的问题与解决方案 1. 附件发送失败问题 2. 中文文件名乱码问题 3. 企业邮箱认证失败 三、完整工作流…...
中文编码,GB系列,UTF
图片来源:https://zhuanlan.zhihu.com/p/701690894 文章目录 ASCIIGB系列编码UTF编码 ASCII American Standard Code for Information Interchange 一个字节,但其实只用了一半: 128个字符 GB系列编码 “国标” 和ASCII是兼容的。 GB2312…...
车载以太网-TLS
文章目录 车载以太网与TLS的技术背景核心定位车载以太网TLS的技术架构车载TLS的核心安全机制TLS报文结构详解TLS工作机制密钥交换与计算流程标题完整握手流程(1-RTT)数据传输加密流程车载TLS的独特优化策略车载TLS的安全威胁相关标准车载以太网TLS(Transport Layer Security…...
【大英赛】大英赛准备笔记
听力 总结 提醒专注 一题一个听力时,听是重点 抓紧时间往后审题 比较容易的部分:secA & secD中的dictation,在大致审当前的基础上,分别利用这个时间提前看后面的secB√& summery secA 听之前应当大致审选项&#x…...
有序数组的平方
暴力排序 每个数平方以后排个序 class Solution { public:vector<int> sortedSquares(vector<int>& nums) {int slow0,fast0;int nnums.size();while(fast<n){nums[slow]nums[fast]*nums[fast];fast;slow;}sort(nums.begin(),nums.end());return nums;} }…...
Python基于Django的房屋信息可视化及价格预测系统(附源码,文档说明)
博主介绍:✌IT徐师兄、7年大厂程序员经历。全网粉丝15W、csdn博客专家、掘金/华为云//InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇dz…...
【5G-A学习】ISAC通信感知一体化学习小记
通信感知一体化(Integrated Sensing and Communication, ISAC)是一种将无线通信与环境感知功能深度融合的技术,通过共享硬件、频谱和信号处理流程,实现通信与感知的协同增效。其核心原理及无人机与飞鸟的识别方式如下:…...
深入解析@Validated注解:Spring 验证机制的核心工具
一、注解出处与核心定位 1. 注解来源 • 所属框架:Validated 是 Spring Framework 提供的注解(org.springframework.validation.annotation 包下)。 • 核心定位: 作为 Spring 对 JSR-380(Bean Validation 2.0&#…...
学生考勤管理系统(jsp+ssh+mysql5.x)含文档
学生考勤管理系统(jspsshmysql5.x)含万字详细文档 学生考勤管理系统是一个用于管理学生出勤和请假的系统,系统登录页面提供账号和密码输入框,用户可以选择角色进行登录。系统主菜单包括班级管理、用户管理、课程表管理和考勤情况…...
【响应式编程】Reactor 常用操作符与使用指南
文章目录 一、创建操作符1. just —— 创建包含指定元素的流2. fromIterable —— 从集合创建 Flux3. empty —— 创建空的 Flux 或 Mono4. fromArray —— 从数组创建 Flux5. fromStream —— 从 Java 8 Stream 创建 Flux6. create —— 使用 FluxSink 手动发射元素7. generat…...
为什么我们需要if __name__ == __main__:
[目录] 0.前言 1.什么是 __name__? 2.if __name__ __main__: 的作用 3.为何Windows更需if __name__ ?前言 if __name__ __main__: 是 Python 中一个非常重要的惯用法,尤其在使用 multiprocessing 模块或编写可导入的模块时。它的作用是区分…...
Week 1: Time Complexity, Rectangle Geometry
问题集 Square PastureBucket BrigadeBlocked BillboardBlocked Billboard IIWord ProcessorDo You Know Your ABCs?The Cow-SignalD3C - White Sheet 视频解析 Square Pasture Bucket Brigade Blocked Billboard Blocked Billboard II Word Processor Do You Know Your AB…...
论文学习:《通过基于元学习的图变换探索冷启动场景下的药物-靶标相互作用预测》
原文标题:Exploring drug-target interaction prediction on cold-start scenarios via meta-learning-based graph transformer 原文链接:https://www.sciencedirect.com/science/article/pii/S1046202324002470 药物-靶点相互作用(DTI&…...
STM32 HAL库 OLED驱动实现
一、概述 1.1 OLED 显示屏简介 OLED(Organic Light - Emitting Diode)即有机发光二极管,与传统的 LCD 显示屏相比,OLED 具有自发光、视角广、响应速度快、对比度高、功耗低等优点。在嵌入式系统中,OLED 显示屏常被用…...
UE5蓝图之间的通信------接口
一、创建蓝图接口 二、双击创建的蓝图接口,添加函数,并重命名新函数。 三、在一个蓝图(如玩家角色蓝图)中实现接口,如下图: 步骤一:点击类设置 步骤二:在细节面板已经实现的接口中…...
封装Tcp Socket
封装Tcp Socket 0. 前言1. Socket.hpp2. 简单的使用介绍 0. 前言 本文中用到的Log.hpp在笔者的历史文章中都有涉及,这里就不再粘贴源码了,学习地址如下:https://blog.csdn.net/weixin_73870552/article/details/145434855?spm1001.2014.3001…...
深入解析 Android 图形系统:Canvas、Skia、OpenGL 与 SurfaceFlinger 的协作
在 Android 应用开发中,流畅的 UI 渲染是用户体验的核心。但你是否好奇,一个简单的 View 是如何从代码中的 onDraw() 方法一步步变成屏幕上的像素的?本文将从底层图形系统的视角,解析 Android 中 Canvas、Skia、OpenGL ES 和 Surf…...
LeetCode每日一题4.13
1922. 统计好数字的数目 问题 问题分析 题目要求我们找到长度为 n 且满足特定条件(偶数下标处为偶数,奇数下标处为质数)的数字字符串的总数,并对 (10^9 7) 取余。 思路 1.枚举 生成所有可能的数字字符串:对于长度…...
Java学习——day29(并发控制高级工具与设计模式)
文章目录 1. 并发控制高级工具简介1.1 CountDownLatch1.2 CyclicBarrier1.3 Semaphore1.4 并发设计模式 2. 扩展生产者—消费者示例2.1 示例代码 3. 代码详解3.1 主类 ExtendedProducerConsumerDemo3.2 Buffer 类3.3 Producer 类3.4 Consumer 类 4. 编译与运行结果4.1 编译4.2 …...
使用FormData格式上传图片
为什么要使用FormData格式上传图片 1. 为什么使用 FormData? FormData 是一种专门用于构建表单数据的对象,它能够以 multipart/form-data 格式发送数据,这是文件上传的标准格式。以下是使用 FormData 的主要原因: 简单易用 直…...
Tkinter表格与列表框应用
在图形用户界面(GUI)开发中,表格和列表框是常用的控件,用于显示和管理大量的数据。Tkinter提供了Listbox控件来显示简单的列表数据,而对于更复杂的表格数据,可以使用Treeview控件(属于ttk模块)来实现。这一章将介绍如何使用Listbox和Treeview来显示和操作数据,帮助您处…...
【Excel】数据透视表月度数据排序不正确
【问题】 插入数据透视表后,月度列显示的日期,是按照文本格式排序的,显然与实际月份排序并不相符。 【目的】 按照从1月份到12月份进行自然月度排序。 【方法】 步骤一: 在任意一处,输入“1月”-“12月”&#…...
HCIP第十天
OSPF的数据包 OSPF是跨层封装协议,直接封装在网络层之上 --- 需要IP协议使用一个协议号来标定 OSPF --- 89 OSPF的头部 版本 --- OSPF的版本 --- 2 类型 --- OSPF数据包的类型 --- hello -- 1 DBD -- 2 LSR -- 3 LSU -- 4 LSACK -- 5 路由器ID --- RID --- 携带的是发出O…...
Vue2,Vue3知识大全
Vue 1.了解vue,快速上手 vue是一个用于构建用户的界面的渐进式框架. vue的两种使用方法: vue核心包开发 场景:局部模块改造 vue核心包&vue插件 工程化开发 场景:整站开发 1.创建一个vue实例: 2.插值表达式 1.插值表达式是一种Vue的模版语法 作用:利用表达式进行插值…...
java面向对象02:回顾方法
回顾方法及加深 定义方法 修饰符 返回类型 break:跳出switch和return的区别 方法名 参数列表 package com.oop.demo01;//Demo01类 public class Demo01 {//main方法public static void main(String[] args) {}/*修饰符 返回值类型 方法名(...){//方法体return…...
【Ubuntu】【树莓派】Linux系统的远程终端登录、远程图形桌面访问、 X图形窗口访问和文件传输操作
目录 一、Ubuntu远程终端并实现文件上传下载 1.1Ubuntu桥接模式设置和新用户的创建 1.2Ubuntu的远程登录并上传和下载文件 1.3在Xming中进行Ubuntu的图形访问 二、树莓派远程登录并实现文件上传下载 2.1树莓派在putty上的远程登录 2.2使用ftp远程登录并实现文件上传下载…...
Linux Kernel 2
地址空间(Address Space) 一、物理地址空间(Physical Address Space) 物理地址空间 是指 RAM 和设备内存 在系统内存总线上所呈现的地址布局。 举例:在典型的 32 32 32 位 Intel 架构中, RAM(…...
二.springBoot项目集成ElasticSearch及使用
二.springBoot项目集成ElasticSearch及使用 1.依赖引入2.ElasticSearch常见用法 1.依赖引入 <!--elasticsearch搜索引擎--> <!--高版本7.0后TransportClient已被淘汰,用rest-high-level-client代替--> <dependency><groupId>org.elasticse…...
从三次方程到复平面:复数概念的奇妙演进(一)
注:本文为 “复数 | 历史 / 演进” 相关文章合辑。 因 csdn 篇幅限制分篇连载,此为第一篇。 生料,不同的文章不同的点。 机翻,未校。 Reflections on the History of Complex Numbers 复数的历史回顾 The first occurrence o…...
Day52 | 6. Z 字形变换、8. 字符串转换整数 (atoi)、22. 括号生成、38. 外观数列
6. Z 字形变换 题目链接:6. Z 字形变换 - 力扣(LeetCode) 题目难度:中等 代码: class Solution {public String convert(String s, int numRows) {if(numRows<2) return s;List<StringBuilder> rowsnew A…...
每日OJ_牛客_ruby和薯条_排序+二分/滑动窗口_C++_Java
目录 ruby和薯条_排序二分/滑动窗口 题目解析 C代码 Java代码 ruby和薯条_排序二分/滑动窗口 ruby和薯条 描述: ruby很喜欢吃薯条。 有一天,她拿出了n根薯条。第i根薯条的长度为ai。 ruby认为,若两根薯条的长度之差在l和r之间ÿ…...
快速幂运算
快速幂运算 一、快速幂运算快速幂运算(Exponentiation by Squaring)基本思想算法实现(②③为非递归)① 递归运算② 普通 除模运算(不带 **模数** 与 带 **模数**)③ 按位与运算 使用示例示例代码 复杂度分析…...
vue @import引入CSS scoped无效 造成全局样式污染
引入css文件导致全局样式污染 1.写在单组件的style里面css样式,如果标签内不加scoped可能会影响其他组件的样式 <style lang"scss" scoped> </style> 2.通过import引入的外部css文件,这种引入方式是全局的,也会影响其…...
基于Flask-Login简单登录和权限控制实践
1. 关于Flask-Login Flask-Login 是一个为python Flask Web框架设计的扩展,用于管理用户会话(用户登录状态)。它提供了简单的接口来处理用户登录、注销、记住用户等功能,同时确保用户会话的安全性。以下是 Flask-Login 的一些关键特性和功能: 1.1. 主要功能 用户会话管理…...
文件流---------获取文件的内容到控制台
总流程:先创建一个文本文件------->里面写入一些内容(纯字母和字母加文字)-----------> 然后通过输入流获取文件里面的内容,两种方式。 1.第一种,获取单个的字符 ,先创建文件 ,java.txt…...
idea 2024 build菜单不见了
Q如题 idea 2024 新版UI添加build和recompile菜单 A如图,右键顶部栏之后,点击Add to Main Toolbar菜单,在里面就能找到Build菜单,添加接口。 Recompile菜单的话在Customize Toolbar中搜索添加才行。...
深入理解计算机操作系统(持续更新中...)
文章目录 一、计算机系统漫游1.1信息就是位上下文 一、计算机系统漫游 1.1信息就是位上下文 源程序实际上就是一个由值0和1组成的位(又称为比特),八个位被组织成一组,称为字节。每个字节表示程序中的某些文本字符 大部分现代计…...
[dp8_子数组] 乘积为正数的最长子数组长度 | 等差数列划分 | 最长湍流子数组
目录 1.乘积为正数的最长子数组长度 2.等差数列划分 3.最长湍流子数组 写代码做到,只用维护好自己的一小步 1.乘积为正数的最长子数组长度 链接:1567. 乘积为正数的最长子数组长度 给你一个整数数组 nums ,请你求出乘积为正数的最长子数…...
量子机器学习(Quantum Machine Learning, QML)在优化测试组合
量子机器学习(Quantum Machine Learning, QML)在优化测试组合选择中展现出显著潜力,通过量子计算的并行性和量子态叠加特性,可高效解决传统方法难以处理的组合爆炸问题。以下是其技术实现路径、优势及落地案例: 一、QML优化测试组合的核心原理 1. 量子并行性加速搜索 经典…...
Go语言Slice切片底层
Go语言(Golang)中切片(slice)的相关知识、包括切片与数组的关系、底层结构、扩容机制、以及切片在函数传递、截取、增删元素、拷贝等操作中的特性。并给出了相关代码示例和一道面试题。关键要点包括: 数组特性…...
导入 Excel 批量替换文件夹名称
文件夹重命名的需求是多种多样的,前面我们介绍过按照规则修改文件夹名称的方法。但是在某些场景下,这个方法可能是不适用的,比如我们修改文件夹的规则是多种多样的,是无规律的。那我们应该怎么做呢?今天我们就给大家介…...
数据库或表数据迁移(使用Navicat迁移MySQL数据库表数据)
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 数据库或表数据迁移(使用Navicat…...
Matlab Add Legend To Graph-图例添加到图
Add Legeng To Graph: Matlab的legend()函数-图例添加到图 将图例添加到图 ,图例是标记绘制在图上的数据序列的有用方法。 下列示例说明如何创建图例并进行一些常见修改,例如更改位置、设置字体大小以及添加标题。您还可以创建具有多列的图…...
【Linux】what is pam?PAM模块学习笔记
文章目录 1. pam模块简介2. pam验证的工作流程3. pam模块配置文件3.1 配置文件的格式3.1.1 验证类别type3.1.2 验证的控制标识 control flag3.1.3 pam模块 4. login的PAM验证机制流程5. 补充:其他pam相关文件6. 参考内容 1. pam模块简介 PAM: Pluggable Authentica…...
5.1 GitHub订阅监控系统实战:FastAPI+SQLAlchemy高效架构设计与核心源码揭秘
GitHub Sentinel Agent 分析报告功能设计与实现 关键词:订阅管理 API 设计、GitHub API 集成、SQLAlchemy ORM、JWT 认证、单元测试框架 1. 订阅管理功能架构设计 订阅管理模块采用分层架构设计,通过 FastAPI 构建 RESTful 接口,结合 SQLAlchemy ORM 实现数据持久化: #me…...
【BEPU V1物理】BEPUphysics v1 入门指南 汉化笔记#1
BEPUphysics v1 入门指南 前言下载获取库工程1.创建物理模拟环境2.添加物理实体3.与物理系统交互4.发射物体5.构建环境6.事件处理7. 进阶学习 前言 本文档记录完成 BEPUphysics 物理引擎的基础设置。 文档链接:https://github.com/bepu/bepuphysics1/blob/master/Documentatio…...