【转载翻译】消息队列 - ActiveMQ、RabbitMQ、Kafka、ZeroMQ

news2024/11/20 4:04:29

转载自本人博客:【转载翻译】消息队列 - ActiveMQ、RabbitMQ、Kafka、ZeroMQ

转载自:The System Design Cheat Sheet: Message Queues - ActiveMQ, RabbitMQ, Kafka, ZeroMQ

本文由 Aleksandr Gavrilenko 发布于2023年12月21日

1. 前言

消息队列是异步服务到服务通信的一种形式。它们对于增强系统的可扩展性、可靠性和可维护性非常重要。

主要功能包括:

  1. 异步通信:允许系统的不同部分进行通信,而无需立即响应,从而更有效地使用资源。
  2. 服务解耦:使服务能够独立运行,降低系统的复杂度,增强可维护性和可扩展性。
  3. 负载均衡:将消息均匀分布在不同的服务或工作线程之间,有助于管理工作负载并提高系统性能。
  4. 有序保留:某些消息队列可以确保消息按照发送顺序进行处理,这对于特定应用程序至关重要。
  5. 可扩展性:通过添加更多使用者或资源来处理增加的消息流,从而促进应用程序的轻松扩展。
  6. 速率限制:控制消息处理的速率,这对于管理资源和防止系统过载非常重要。
  7. 扇出功能:消息队列通常包含扇出机制,该机制允许将单个消息同时传递给多个使用者或服务。
  8. 数据持久性:提供将消息存储在磁盘或内存中的能力,直到它们被成功处理,确保在系统故障的情况下数据不会丢失。
  9. **消息过滤和路由:**允许根据特定条件或内容路由或过滤消息,从而实现更有针对性和更高效的处理。

2. 组件

对于消息队列的内容,核心的概念是生产者(Producer)消费者(Consumer)消息(Message)

  1. 生产者(Producer) 是一个应用程序或服务,负责创建消息并将其发送到消息队列。它不需要知道谁将处理消息或何时处理消息。
  2. **消费者(Consumer)**是从队列中检索和处理消息的应用程序或服务。它作用于生产者发送的数据。
  3. **消息(Message)**是从生产者发送到消费者的数据包。它们的大小和格式可能有所不同,范围从简单的文本字符串到复杂的数据结构(如 JSON 或 XML)。
  4. 消息代理(Message Broker) 是一个中间件工具,它通过接收来自发送方的消息并将其路由到适当的接收方,从而促进不同应用程序或服务之间的通信。它通常提供消息队列、路由、转换和传递保证等功能。

3. 消息传递模型

3.1 两种通用消息传递模型

总的来说,有两种类型的消息传递:点对点消息传递和发布-订阅消息传递。

3.1.1 点对点(Point-to-Point)

  • 生产者发送的消息被放置在队列(Queue)中,并由单个使用者使用。
  • 它确保每条消息仅由一个接收者处理一次。
3.1.2 发布-订阅(Publish-Subscribe)

  • 消息将发布到特定主题(Topic),而不是队列,不仅给单个使用者使用。
  • 多个消费者可以订阅一个主题,并接收广播到该主题的消息。

3.2 额外消息交换模式

但是,某些消息传递协议和支持它们的代理使用额外的交换(Exchange)组件进行路由。在这种情况下,消息将首先发布到代理中的交换模块。Exchange 充当路由代理,使用其路由规则将这些消息转发到相应的队列。

区分了以下交换模式:

3.2.1 直接交换(Direct exchange)

  • 消息被路由到其绑定键与消息的路由键匹配的队列。
3.2.2 话题交换(Topic exchange)

  • 主题交换将在路由键和绑定中指定的路由模式之间执行通配符匹配,以将消息发布到队列。
3.2.3 扇出交换(Fanout exchange)

  • 发送到扇出交换的消息将被复制并转发到绑定到该交换的所有队列。
3.2.4 标头交换(Header exchange)

  • 标头交换将使用消息标头属性进行路由。
3.2.5 死亡信件(Dead letter)

  • 死亡信件队列收集由于各种原因(如处理错误、消息过期或传递问题)而无法成功处理的消息。

4. 协议

消息代理负责将消息从生产者传递到使用者。它们使用特定的协议来定义消息传递的规则和格式。

此域中最受欢迎的协议为以下几种:

4.1 AMQP

全称 Advanced Message Queuing Protocol(高级消息队列协议)

一种二进制协议,专为面向消息的中间件而设计,具有鲁棒性、安全性和互操作性。适用于复杂而可靠的企业消息传递系统。

  • **使用案例:**企业应用程序、财务系统和业务流程
  • **消息模型:**点对点、发布-订阅
  • **安全性:**TLS/SSL、SASL、PLAIN
  • **寻址:**使用具有路由功能的基于交换和队列的寻址
  • **架构实现:**基于代理库

4.2 MQTT

全称 Message Queuing Telemetry Transport,消息队列遥测传输

一种轻量级的发布-订阅网络协议,针对高延迟或不可靠的网络进行了优化,非常适合 IoT 方案。

  • **使用案例:**物联网设备、家庭自动化、移动消息应用程序
  • **消息传递模型:**发布-订阅
  • **安全:**TLS/SSL、SASL、普通
  • **寻址:**它使用基于主题的寻址,其中消息将发布到主题
  • **架构实现:**基于代理库

4.3 JMS

全称 Java Message Service,Java 消息服务

基于 Java 的消息传递标准为 Java 应用程序中的点对点和发布-订阅消息传递模式提供了接口。

  • **使用案例:**企业 Java 应用程序,集成多个基于 Java 的系统
  • **消息模型:**点对点、发布-订阅
  • **安全:**依赖于底层 Java EE 安全模型
  • **寻址:**使用 JNDI 查找队列和主题
  • **架构实现:**它通常在企业服务总线或应用程序服务器之上实现。

4.4 STOMP

全称 Simple Text Oriented Messaging Protocol,面向简单文本的消息传递协议

一种简单的基于文本的协议,易于实现,适用于不需要优先考虑高级消息传递功能的方案。

  • **使用案例:**快速开发环境和简单的消息传递应用程序
  • **消息模型:**点对点、发布-订阅
  • **安全:**平原;依赖于底层传输协议进行加密
  • **寻址:**基于帧,带有目标、内容类型等的标题。
  • **架构实现:**基于代理库

4.5 Kafka

全称 Kafka Protocol,Kafka协议

与 Apache Kafka 相关联,Apache Kafka 是一个能够处理高吞吐量数据流的分布式流式处理平台。

  • **使用案例:**实时分析、数据管道、流处理应用程序
  • **消息传递模型:**发布-订阅
  • **安全:**SSL/TLS、SASL
  • **寻址:**基于主题,具有可伸缩性分区功能。
  • **架构实现:**具有代理和协调的分布式系统架构。

4.6 ZMTP

全称 ZeroMQ Message Transport Protocol,ZeroMQ 消息传输协议

ZeroMQ 的底层协议是一个高性能异步消息传递库,用于构建可扩展的分布式应用程序。

  • **使用案例:**高吞吐量、低延迟应用程序、微服务架构。
  • **消息模型:**请求-回复、发布-订阅、流水线、独占对等。
  • **安全:**PLAIN、CurveZMQ 和 ZAP
  • **寻址:**使用套接字灵活寻址
  • **架构实现:**基于库,支持无代理设计或各种代理配置

5. 代理库

ActiveMQRabbitMQKafkaZeroMQ
编写语言JAVAErlangScalaC++
跨平台是的是的是的是的
开源是的是的是的是的
多种语言是的是的是的是的
支持协议AMQP、AUTO、MQTT、OpenWire、REST、RSS 和 Atom、Stomp、WSIF、WS 通知、XMPP、WebSocketAMQP、STOMP、MQTT、HTTP基于 TCP 的二进制文件TCP、UDP、inproc、PGM、IPC、TIPC、NORM、SOCKS5
服务质量至少一次 最多一次至少一次 最多一次至少一次,最多一次,恰好一次一次至少一次 最多一次
消息模式队列、Pub-Sub队列、Pub-Sub、RPC发布-订阅Request-Reply、Pub-Sub、Push-Pull、Dealer and Router、Pair、Exclusive Pair等
持性久磁盘、数据库内存、磁盘磁盘-

5.1 ActiveMQ

Apache ActiveMQ 是由 Apache 设计的开源、多协议、基于 Java 的消息代理。它以其稳健性和灵活性而闻名,支持各种消息传递协议和客户端,使其成为集成不同系统的多功能选择。

架构特点:

  • 多协议支持:ActiveMQ支持多种消息传递协议,包括AMQP、MQTT、OpenWire、STOMP、JMS等,对不同客户端需求的适应性强。
  • JMS Provider:作为 JMS Provider,ActiveMQ 遵循 JMS API,该 API 允许 Java 应用程序的松耦合、异步通信和可靠性。
  • 基于代理的架构:ActiveMQ 使用代理架构,其中中央代理处理消息路由、传递和队列。
  • 可插拔持久化和存储:提供消息持久化选项,包括数据库存储(持久化)和文件系统存储,支持高性能和高持久化场景。
  • 集群和负载均衡:支持集群和负载均衡,实现高可用性和可扩展性。
  • 客户端确认:提供不同的消息确认选项,增强消息可靠性。

使用场景:

  • 企业集成:非常适合在企业内集成不同的系统,主要是在使用基于 Java 或多个协议的情况下。
  • 异步通信:在必须解耦系统组件的情况下很有用,例如在微服务体系结构中。
  • 分布式计算(Distributed Computing):促进分布式系统中的消息通信,保证数据的一致性和可靠性。
  • 物联网通信:可用于物联网设置,尤其是在首选 MQTT 的情况下。

优点:

  • 协议支持的多功能性:ActiveMQ 的主要优势之一是它支持多种协议,在各种环境中提供灵活性。
  • 可靠性和耐久性:提供可靠的消息传递和持久的存储。
  • 集群和高可用性:支持集群以实现负载均衡和高可用性。
  • **JMS 支持:**对 JMS API 的全面支持使其成为基于 Java 的系统的有力候选者。

缺点:

  • 性能:虽然 ActiveMQ 很强大,但可能无法与一些较新的消息代理的性能匹配,尤其是在吞吐量要求极高的场景中。
  • 复杂配置:可能难以配置和管理,尤其是在集群设置中。
  • 资源使用:可能需要大量资源,尤其是在重负载下,以获得最佳性能。
  • 管理和监控: 虽然它提供了管理工具,但它们可能不如一些较新的经纪人全面和用户友好。

5.2 RabbitMQ

RabbitMQ 是一个开源的消息代理软件,被称为面向消息的中间件。它是用 Erlang 编写的,基于 Open Telecom Platform 框架构建,用于集群和故障转移。RabbitMQ 广泛用于处理异步处理,通过各种消息传递协议(主要是 AMQP(高级消息队列协议))实现分布式系统之间的通信。

架构特点:

  • 支持多种消息传递协议:虽然 RabbitMQ 主要以 AMQP 而闻名,但它也通过插件支持 MQTT、STOMP 和其他协议。
  • 生产者-消费者模型:它遵循标准的生产者-消费者模式,其中生产者发送消息,消费者接收消息,RabbitMQ 充当代理。
  • Exchange-Queue 绑定:RabbitMQ 中的消息被发布到交换,然后根据路由键和模式路由到绑定队列。
  • 持久消息传递和瞬态消息传递:支持持久消息(在磁盘上持久保存)和瞬态消息(内存中)消息。
  • 集群和高可用性:RabbitMQ 可以集群以实现高可用性和可扩展性,在多个节点之间分配队列。
  • **灵活的路由:**为不同的路由逻辑提供多种交换类型(如直接、主题、扇出和标头)。
  • 可插拔认证和授权:支持可插拔认证模块,包括 LDAP。

使用场景:

  • 异步处理:非常适合解耦 Web 应用程序中的繁重处理任务,确保响应式用户界面。
  • 服务间通信:在微服务架构中用于服务之间的通信。
  • 任务队列:非常适合处理后台任务,如发送电子邮件或处理图像。
  • 分布式系统:促进分布式系统中的消息通信,保持一致性和可靠性。

优点:

  • 可靠性:RabbitMQ 以其可靠性和确保消息传递的能力而闻名。
  • 灵活的路由能力:其路由能力比许多消息代理的路由能力更先进。
  • 可扩展性和高可用性:支持可扩展的集群,这对于大规模应用程序至关重要。
  • 广泛的协议支持:支持多种消息传递协议的能力提高了适应性。
  • 管理界面:带有用户友好的管理界面,可简化监视和管理消息流。

缺点:

  • 学习曲线:对于初学者来说,了解 RabbitMQ 的路由和设置可能很复杂。
  • 内存使用:它可能占用大量内存,尤其是在重负载下,需要适当的监控和调整。
  • Erlang 依赖性:基于 Erlang 构建,它引入了一个额外的技术堆栈,团队可能需要熟悉这些技术堆栈。
  • 高负载下的性能:虽然通常性能较高,但在极高负载或复杂的路由方案中,可能需要进行性能调整。

5.3 Kafka

Apache Kafka是由 LinkedIn 开发的开源流处理软件平台,后来捐赠给了 Apache 软件基金会。它旨在处理大量数据并实现实时数据处理。Kafka 是一种分布式、分区和复制的提交日志服务。

架构特点:

  • 生产者-消费者模型:Kafka 以生产者-消费者模型运行。生产者向 Kafka 主题发布消息,消费者订阅这些主题以阅读消息。
  • 主题和分区:Kafka 中的数据分为多个主题。每个主题都可以拆分为多个分区,从而允许并行数据处理。分区还使 Kafka 能够水平扩展。
  • 分布式系统:Kafka 在一台或多台服务器上作为集群运行,Kafka 集群将记录流存储在称为主题的类别中。
  • 复制:Kafka 跨多个节点(代理)复制数据,以确保容错性。如果一个节点发生故障,可以从其他节点检索数据。
  • Zookeeper 协调:Kafka 使用 ZooKeeper 进行集群管理和协调,保证集群间的一致性。
  • 提交日志存储:Kafka 将所有数据存储为一系列记录(或提交日志),提供持久的消息存储。

使用场景:

  • 实时数据处理:非常适合实时分析和监控系统,在这些系统中,快速数据处理至关重要。
  • 事件溯源:适用于记录应用程序中的事件序列。
  • 日志聚合:有效用于收集和处理来自多个服务的日志。
  • 流处理:可用于复杂的流处理任务,如聚合数据流或实时过滤。
  • 与大数据技术集成:通常与大数据工具一起使用,进行数据处理和分析。

优点:

  • 高吞吐量:可以处理大量数据和许多并发事务。
  • 可扩展性:易于水平和垂直扩展。
  • 持久性和可靠性:提供持久的消息存储。
  • 容错性:由于数据复制,容错性高。
  • 灵活性:可用于广泛的用例,从消息传递系统到活动跟踪和日志聚合。

缺点:

  • 复杂性:设置和管理可能很复杂,尤其是对于大型集群。
  • 资源密集型:可能是资源密集型的,需要大量的内存和 CPU。
  • **对 ZooKeeper 的依赖性:**依赖 ZooKeeper 进行协调,添加额外的组件进行管理。
  • 延迟:虽然速度很快,但可能不适合需要极低延迟的用例。

5.4 ZeroMQ

ZeroMQ(ØMQ、0MQ 或 ZMQ)是用于分布式或并发应用程序的高性能异步消息库。它不是一个消息代理,而是一个库,它将套接字通信抽象为面向消息的中间件,从而更容易以可扩展的方式实现复杂的通信模式。ZeroMQ是用C++开发的,可以通过绑定在各种编程语言中使用。

架构特点:

  • 基于套接字的通信:ZeroMQ 使用套接字来抽象出低级网络编程的复杂性。这些套接字可用于发布-订阅、请求-回复和扇出等模式。
  • 无代理设计:与传统的消息代理不同,ZeroMQ 是无代理的,允许端点之间直接通信,而无需中央消息代理。
  • **可扩展的多线程:**提供了一种通过基于套接字的通信管理多个线程的方法,从而促进了可扩展的 I/O 绑定操作。
  • 异步 I/O:支持非阻塞、异步 I/O 操作,这对于构建响应迅速的高性能应用程序至关重要。
  • **与语言无关:**为多种编程语言提供绑定,使其可以从不同的技术堆栈进行访问。

使用场景:

  • 微服务:非常适合微服务架构中的服务间通信。
  • 高性能计算:用于性能至关重要的并行处理系统。
  • 分布式系统:适合需要复杂的分布式消息传递模式的场景,而不需要代理的开销。
  • 实时通信:在需要低延迟、实时数据交换的系统中有效。

优点:

  • 高性能:ZeroMQ专为高吞吐量和低延迟而设计,适用于性能关键型应用。
  • 消息传递模式的灵活性:支持多种消息传递模式,为不同的通信场景提供灵活性。
  • 降低复杂性:无代理架构简化了部署,降低了系统复杂性。
  • 可扩展性:通过对多个连接的有效处理,方便了应用程序的扩展。
  • 轻量级:与传统消息传递代理相比,资源密集程度更低。

缺点:

  • 没有内置持久性或消息持久性:缺乏内置的消息持久性或持久性支持,必须在外部处理。
  • 需要显式管理连接:开发人员需要管理连接,重试和错误处理,这可能会增加应用程序逻辑的复杂性。
  • 学习曲线:理解和有效使用ZeroMQ的模式可能需要一个陡峭的学习曲线。
  • 缺乏中央代理:虽然这可能是一个优势,但它也意味着需要对消息传递系统进行更集中的管理、监控和控制。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

NASA:ATLAS/ICESat-2 L3B 平均内陆地表水数据 V002

目录 简介 摘要 代码 引用 网址推荐 0代码在线构建地图应用 机器学习 ATLAS/ICESat-2 L3B Mean Inland Surface Water Data V002 ATLAS/ICESat-2 L3B 平均内陆地表水数据 V002 简介 ATLAS/ICESat-2 L3B Mean Inland Surface Water Data V002是由NASA的ICESat-2 (Ice,…

JavaScript break与continue语句

break语句和continue语句都具有跳转作用&#xff0c;可以让代码不按既有的顺序执行。 break break语句用于跳出代码块或循环 for(i0;i<100;i){if(i5){break;}console.log(i);} continue continue语句用于应即终止本轮循环,返回循环结构的头部&#xff0c;开始下一轮循环。…

【从零开始实现stm32无刷电机FOC】【实践】【7.2/7 完整代码编写】

目录 stm32cubemx配置芯片选择工程配置stm32基础配置SPI的配置定时器的配置ADC的配置中断优先级的配置生成工程 工程代码编写FOC代码结构搭建电机编码器角度读取PWM产生FOC开环代码编写确定电机正负旋转方向电机旋转速度计算多圈逻辑角度电流采样极对数转子角度确定 闭环控制控…

两个月冲刺软考——网络与信息安全知识

1. 什么是网络监听&#xff1f; 网络监听是主机的一种工作模式&#xff0c;在这种模式下&#xff0c;主机可以接收到本网段在同一条物理通道上传输的所有信息。 2. 客户端与服务器建立连接的步骤 域名解析 建立TCP连接 发送HTTP请求 服务器处理请求 发送HTTP响应 客户端…

uniapp 上了原生的 echarts 图表插件了 兼容性还行

插件地址&#xff1a;echarts - DCloud 插件市场 兼容性这块儿不知道后期会不会支持其他浏览器 H5 的话建议可以用原生的不用这个插件

【单片机】单片机map表详细解析

1、RO Size、RW Size、ROM Size分别是什么 首先将map文件翻到最下面&#xff0c;可以看到 1.1 RO Size&#xff1a;只读段 Code&#xff1a;程序的代码部分&#xff08;也就是 .text 段&#xff09;&#xff0c;它存放了程序的指令和可执行代码。 RO Data&#xff1a;只读…

二叉树进阶练习——根据二叉树创建字符串

1.题目解析 题目来源&#xff1a;606.根据二叉树创建字符串 测试用例 2.算法原理 根据上面的题目我们知道这里需要根据前序遍历来创建字符串&#xff0c;并且需要将每棵子树使用括号括起来&#xff0c;但是要根据实际情况省略括号&#xff0c;比如当右子树为空左子树为空就可…

基于opencv-C++dnn模块推理的yolov5 onnx模型

前言 由于最近手边的项目要求&#xff0c;本人需要在一块算力吃紧的板端上部署yolov5目标检测模型&#xff08;纯CPU推理&#xff09;&#xff0c;考虑到python在板端上的运行速率和其运行时所占内存过大&#xff0c;因此使用torch.hub.load对训练好后的pt模型进行加载和运行不…

rtmp协议转websocketflv的去队列积压

websocket server的优点 websocket server的好处&#xff1a;WebSocket 服务器能够实现实时的数据推送&#xff0c;服务器可以主动向客户端发送数据 1 不需要客户端不断轮询。 2 不需要实现httpserver跨域。 在需要修改协议的时候比较灵活&#xff0c;我们发送数据的时候比较…

使用默认不可变的Rust变量会踩什么坑

讲动人的故事&#xff0c;写懂人的代码 Rust的变量真的是名不副实。名字中明明有个“变”字&#xff0c;却默认不可变。还美其名曰“不可变变量”。要想让变量名副其实&#xff0c;还必须费心额外加个mut关键字&#xff0c;并必须称其为“可变变量”&#xff0c;才能与前者区分…

对比学习与图像去雾在24TIP和CVPR经典图像去雾论文中的良好结合,展示出模型良好的泛化能力(本期内容较详细 多)

今天主要内容是图像去雾&#xff0c;对比学习&#xff0c;无监督学习&#xff0c;要分享的三篇论文分别是&#xff1a; 21CVPR Contrastive Learning for Compact Single Image Dehazing 24 TIP UCL-Dehaze: Toward Real-World Image Dehazing via Unsupervised Contrastive Le…

stm32f103调试,程序与定时器同步设置

在调试定时器相关代码时&#xff0c;注意到定时器的中断位总是置1&#xff0c;怀疑代码有问题&#xff0c;经过增大定时器的中断时间&#xff0c;发现定时器与代码调试并不同步&#xff0c;这一点对于调试涉及定时器的代码是非常不利的&#xff0c;这里给出keil调试stm32使定时…

HTB:Vaccine[WriteUP]

目录 连接至HTB服务器并启动靶机 1.Besides SSH and HTTP, what other service is hosted on this box? 2.This service can be configured to allow login with any password for specific username. What is that username? 3.What is the name of the file downloaded…

Kafka和RabbitMQ区别

RabbitMQ的消息延迟是微秒级&#xff0c;Kafka是毫秒级&#xff08;1毫秒1000微秒&#xff09; 延迟消息是指生产者发送消息发送消息后&#xff0c;不能立刻被消费者消费&#xff0c;需要等待指定的时间后才可以被消费。 Kafka的单机呑吐量是十万级&#xff0c;RabbitMQ是万级…

10.4 Linux_并发_线程

概述 线程的共享资源&#xff1a; 可执行的指令、静态数据、文件描述符、当前工作目录、用户ID、用户组ID 线程的私有资源&#xff1a; 线程ID、程序计数器PC和相关寄存器、堆栈、错误号、优先级、执行状态和属性 线程编译&#xff1a; gcc <.c文件> -l pthread -o…

数据集-目标检测系列- 螃蟹 检测数据集 crab >> DataBall

数据集-目标检测系列- 螃蟹 检测数据集 crab >> DataBall 数据集-目标检测系列- 螃蟹 检测数据集 crab >> DataBall 数据量&#xff1a;3k 想要进一步了解&#xff0c;请联系。 DataBall 助力快速掌握数据集的信息和使用方式&#xff0c;会员享有 百种数据集&a…

加密与安全_TOTP 一次性密码生成算法

文章目录 PreTOTP是什么TOTP 算法工作原理TOTP 生成公式TOTP 与 HOTP 的对比Code生成TOTP验证 TOTP使用场景小结 TOTP 与 HOTP 的主要区别TOTP 与 HOTP应用场景比较TOTP 与 HOTP安全性分析 Pre 加密与安全_HTOP 一次性密码生成算法 https://github.com/samdjstevens/java-tot…

YOLO11改进|卷积篇|引入可变核卷积AKConv

目录 一、AKConv卷积1.1AKConv卷积介绍1.2MLCA核心代码 五、添加MLCA注意力机制5.1STEP15.2STEP25.3STEP35.4STEP4 六、yaml文件与运行6.1yaml文件6.2运行成功截图 一、AKConv卷积 1.1AKConv卷积介绍 AKConv允许卷积参数的数量以线性方式增加或减少&#xff0c;而不是传统的平…

C# 表达式与运算符

本课要点&#xff1a; 1、表达式的基本概念 2、常用的几种运算符 3、运算符的优先级 4、常见问题 一 表达式 表达式是由运算符和操作数组成的。、-、*和/等都是运算符&#xff0c;操作数包括文本、常量、变量和表达式等。 二 算术运算符 2.1 算术运算符的使用 三 常见错误 …

Cocotb 学习记录--V01

1. Windows 下安装cocotb pip install cocotb 其他参考&#xff1a; 1.Welcome to cocotb’s documentation! — cocotb 1.9.1 documentation