【Python百宝箱】分布式魔法:穿越分布式奇境的导航

Python 交响曲:优雅构建分布式系统的奇妙之旅

前言

随着现代应用程序的发展,分布式系统已经成为应对高负载和复杂任务的关键。在这个领域,Python以其灵活性和强大的生态系统展现出了令人惊叹的实力。本文将带您踏上一场神奇之旅,深入剖析 Python 在构建强大分布式系统方面的各种神奇之处。

欢迎订阅专栏:Python库百宝箱:解锁编程的神奇世界

文章目录

  • Python 交响曲:优雅构建分布式系统的奇妙之旅
    • 前言
    • 1. **`Celery`**
      • 1.1 基础概念
      • 1.2 特性和优势
      • 1.3 使用场景
      • 1.4 高级特性:任务结果和错误处理
        • 1.4.1 任务结果
        • 1.4.2 错误处理
      • 1.5 集成与拓展:Celery与Django
        • 1.5.1 安装Celery和Django插件
        • 1.5.2 Django项目配置
        • 1.5.3 创建Celery实例
        • 1.5.4 在Django中使用Celery
    • 2. **`RabbitMQ`**
      • 2.1 基础概念
      • 2.2 特性和优势
      • 2.3 与分布式系统的集成
      • 2.4 高级特性:RabbitMQ交换机和绑定
        • 2.4.1 创建Exchange和Queue
        • 2.4.2 绑定Exchange和Queue
        • 2.4.3 发布消息到Exchange
      • 2.5 高级用法:RabbitMQ Topic Exchange
        • 2.5.1 创建Topic Exchange和Queue
        • 2.5.2 绑定Exchange和Queue
        • 2.5.3 发布消息到Exchange
      • 2.6 拓展:RabbitMQ与Spring Boot
        • 2.6.1 添加依赖
        • 2.6.2 配置RabbitMQ连接
        • 2.6.3 创建消息生产者
        • 2.6.4 创建消息消费者
        • 2.6.5 示例:发送和接收消息
  • 拓展:Python库与分布式系统
    • 3. **`Dask`**
      • 3.1 基础概念
      • 3.2 特性和优势
      • 3.3 使用场景
      • 3.4 高级特性:Dask与分布式集群
        • 3.4.1 创建Dask集群
        • 3.4.2 使用Dask集群进行计算
      • 3.5 高级用法:Dask与分布式机器学习
        • 3.5.1 集成Dask和Scikit-Learn
        • 3.5.2 使用Dask进行分布式机器学习
    • 4. **`Apache Kafka`**
      • 4.1 基础概念
      • 4.2 特性和优势
      • 4.3 与Python的集成
      • 4.4 高级特性:Kafka Topic和Partition
        • 4.4.1 创建Topic和发送消息
        • 4.4.2 消费者消费消息
        • 4.4.3 分区与水平扩展
      • 4.5 高级用法:Kafka与Spark Streaming
        • 4.5.1 Spark Streaming连接Kafka
        • 4.5.2 创建Spark Streaming应用
    • 5. **`PySpark`**
      • 5.1 基础概念
      • 5.2 特性和优势
      • 5.3 使用场景
      • 5.4 高级特性:PySpark SQL和DataFrame
        • 5.4.1 创建DataFrame
        • 5.4.2 使用SQL查询
        • 5.4.3 数据转换和操作
      • 5.5 高级用法:PySpark MLlib
        • 5.5.1 导入MLlib库
        • 5.5.2 创建机器学习模型
    • 6. **`Consul`**
      • 6.1 基础概念
      • 6.2 特性和优势
      • 6.3 在Python分布式系统中的应用
      • 6.4 高级特性:Consul健康检查和故障恢复
        • 6.4.1 添加健康检查
        • 6.4.2 故障恢复
      • 6.5 高级用法:Consul配置管理
        • 6.5.1 注册配置
        • 6.5.2 获取配置
    • 总结

1. Celery

1.1 基础概念

Celery是一个异步任务队列,通过将任务分发到多个工作者(workers)来实现异步执行。基本概念包括任务(Task)、消息代理(Broker)、执行者(Worker)等。

1.2 特性和优势

  • 支持分布式部署: Celery可以在多台机器上运行,实现任务的分布式执行。
  • 定时任务调度: 支持定时执行任务,类似于Cron的功能。
  • 多任务执行器: Celery可以同时执行多个任务,提高系统的并发处理能力。

1.3 使用场景

  • 异步任务处理: 例如发送邮件、生成报表等异步操作。
  • 分布式系统解耦: 通过Celery将系统中的模块解耦,提高系统的可维护性。
  • 延迟任务执行: 支持延迟执行任务,以应对系统高峰期。
# 示例代码 - 定义一个异步任务
from celery import Celeryapp = Celery('tasks', broker='pyamqp://guest@localhost//')@app.task
def add(x, y):return x + y

1.4 高级特性:任务结果和错误处理

除了基本概念和特性,Celery还提供了一些高级特性,如处理任务的执行结果和错误。

1.4.1 任务结果

Celery允许你获取异步任务的执行结果,通过AsyncResult对象来实现。以下是一个示例:

from celery.result import AsyncResult# 提交异步任务
result = add.delay(4, 4)# 获取任务执行结果
result_value = result.get()
print("任务执行结果:", result_value)
1.4.2 错误处理

在Celery中,你可以使用on_failure来处理任务执行失败的情况,以下是一个简单的例子:

from celery import Celeryapp = Celery('tasks', broker='pyamqp://guest@localhost//')@app.task(bind=True)
def div(self, x, y):try:result = x / yexcept ZeroDivisionError as e:self.on_failure(exc=e)raisereturn result

在这个例子中,如果除法操作中出现ZeroDivisionError,任务将会被标记为失败,并触发on_failure中定义的处理逻辑。

这些高级特性使得Celery更加灵活和强大,能够满足更复杂的业务需求。

1.5 集成与拓展:Celery与Django

Celery在Django项目中的集成是常见的应用场景,特别是用于处理异步任务。下面是一个简单的示例,展示了如何在Django中使用Celery。

1.5.1 安装Celery和Django插件

首先,确保你已经安装了Celery和Django插件:

pip install celery
pip install django-celery-results
1.5.2 Django项目配置

在Django项目的settings.py文件中,添加Celery配置:

# settings.py# Celery配置
CELERY_BROKER_URL = 'pyamqp://guest@localhost//'
CELERY_RESULT_BACKEND = 'django-db'
1.5.3 创建Celery实例

在Django项目的根目录下,创建一个名为celery.py的文件:

# celery.pyfrom __future__ import absolute_import, unicode_literals
import os
from celery import Celery# 设置Django环境变量
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'your_project.settings')# 创建Celery实例
app = Celery('your_project')# 使用Django配置文件设置Celery
app.config_from_object('django.conf:settings', namespace='CELERY')# 从所有已注册的Django app配置中加载任务模块
app.autodiscover_tasks()
1.5.4 在Django中使用Celery

在Django中定义异步任务,例如:

# tasks.py in one of your Django appfrom celery import shared_task@shared_task
def add(x, y):return x + y

在Django视图中调用Celery任务:

# views.py in one of your Django appfrom your_project.tasks import adddef some_view(request):result = add.delay(4, 4)return HttpResponse(f"Task {result.task_id} is being processed.")

这样,你就成功地在Django项目中集成了Celery,并可以使用异步任务提高系统性能和响应速度。


2. RabbitMQ

2.1 基础概念

RabbitMQ是一个消息代理,用于支持异步任务和分布式系统的消息传递。基本概念包括生产者(Producer)、消费者(Consumer)、交换机(Exchange)等。

2.2 特性和优势

  • 支持多种消息传递模式: 包括点对点、发布/订阅等多种模式。
  • 消息持久化: 可以将消息保存在磁盘上,防止消息丢失。
  • 高可用性和可伸缩性: 具备集群和分布式部署的能力。

2.3 与分布式系统的集成

  • Celery与RabbitMQ的集成: 使用Celery时,RabbitMQ作为消息代理来传递异步任务。
# 示例代码 - 使用RabbitMQ作为Celery的消息代理
app = Celery('tasks', broker='pyamqp://guest@localhost//')

2.4 高级特性:RabbitMQ交换机和绑定

在RabbitMQ中,交换机(Exchange)负责将消息路由到一个或多个队列。绑定(Binding)决定了交换机如何将消息发送到队列。以下是一个简单的例子:

2.4.1 创建Exchange和Queue

首先,在RabbitMQ中创建一个直连交换机(Direct Exchange)和一个队列:

# 创建Exchange和Queue
import pikaconnection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()# 创建直连交换机
channel.exchange_declare(exchange='direct_exchange', exchange_type='direct')# 创建队列
channel.queue_declare(queue='direct_queue')
2.4.2 绑定Exchange和Queue

将队列绑定到交换机,指定路由键(Routing Key):

# 将队列绑定到交换机
channel.queue_bind(exchange='direct_exchange', queue='direct_queue', routing_key='direct_key')
2.4.3 发布消息到Exchange

发布消息到交换机,指定路由键:

# 发布消息到交换机
channel.basic_publish(exchange='direct_exchange', routing_key='direct_key', body='Hello, RabbitMQ!')

这样,消息就会被发送到名为direct_queue的队列中。

2.5 高级用法:RabbitMQ Topic Exchange

RabbitMQ的Topic Exchange允许你使用通配符将消息路由到多个队列。以下是一个简单的例子:

2.5.1 创建Topic Exchange和Queue

创建一个Topic Exchange和两个队列:

# 创建Topic Exchange和Queue
import pikaconnection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()# 创建Topic Exchange
channel.exchange_declare(exchange='topic_exchange', exchange_type='topic')# 创建两个队列
channel.queue_declare(queue='topic_queue_1')
channel.queue_declare(queue='topic_queue_2')
2.5.2 绑定Exchange和Queue

将队列按照通配符绑定到交换机:

# 将队列按照通配符绑定到交换机
channel.queue_bind(exchange='topic_exchange', queue='topic_queue_1', routing_key='topic.*.key')
channel.queue_bind(exchange='topic_exchange', queue='topic_queue_2', routing_key='topic.#')
2.5.3 发布消息到Exchange

发布消息到交换机,使用通配符的路由键:

# 发布消息到交换机,使用通配符的路由键
channel.basic_publish(exchange='topic_exchange', routing_key='topic.message.key', body='Hello, RabbitMQ Topic Exchange!')

这样,消息将被发送到两个队列中。

RabbitMQ的交换机和绑定机制提供了更灵活的消息路由方式,能够满足不同场景下的需求。

2.6 拓展:RabbitMQ与Spring Boot

在Java生态系统中,Spring Boot与RabbitMQ的集成是非常常见的。Spring Boot通过Spring AMQP模块提供了与RabbitMQ的无缝集成。以下是一个简单的示例:

2.6.1 添加依赖

在Spring Boot项目中,通过Maven或Gradle添加Spring AMQP和RabbitMQ依赖:

Maven:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

Gradle:

implementation 'org.springframework.boot:spring-boot-starter-amqp'
2.6.2 配置RabbitMQ连接

application.propertiesapplication.yml中配置RabbitMQ连接信息:

spring:rabbitmq:host: localhostport: 5672username: guestpassword: guest
2.6.3 创建消息生产者

创建一个简单的消息生产者,用于发送消息到RabbitMQ:

import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class RabbitMQProducer {@Autowiredprivate AmqpTemplate amqpTemplate;public void sendMessage(String message) {amqpTemplate.convertAndSend("exchange", "routingKey", message);System.out.println("Message sent: " + message);}
}
2.6.4 创建消息消费者

创建一个消息消费者,用于接收并处理RabbitMQ中的消息:

import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;@Component
public class RabbitMQConsumer {@RabbitListener(queues = "queue")public void receiveMessage(String message) {System.out.println("Message received: " + message);}
}
2.6.5 示例:发送和接收消息

在任意Spring Boot组件中,使用消息生产者发送消息:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;@Component
public class AppRunner implements CommandLineRunner {@Autowiredprivate RabbitMQProducer rabbitMQProducer;@Overridepublic void run(String... args) throws Exception {rabbitMQProducer.sendMessage("Hello, RabbitMQ from Spring Boot!");}
}

这样,消息就会被发送到名为queue的队列中,并被消息消费者接收并处理。

Spring Boot的集成大大简化了与RabbitMQ的交互,开发者能够更加便捷地在应用程序中使用消息队列。


拓展:Python库与分布式系统

3. Dask

3.1 基础概念

Dask是一个并行计算库,用于大规模数据处理和任务调度。

3.2 特性和优势

  • 大规模数据处理: 适用于超大规模数据集的处理和分析。
  • 弹性分布式计算: 能够根据需求自动扩展计算资源。

3.3 使用场景

  • 数据分析和处理: 用于处理超大规模的数据集。
  • 分布式机器学习: 支持大规模机器学习任务。
# 示例代码 - 使用Dask进行数据处理
import dask.array as dax = da.ones((1000, 1000), chunks=(100, 100))
y = x + x.T
z = y.mean(axis=0)result = z.compute()

3.4 高级特性:Dask与分布式集群

Dask最强大的特性之一是其能够与分布式计算集群无缝集成,实现在大规模数据集上的并行计算。以下是一个简单的例子:

3.4.1 创建Dask集群

首先,你需要创建一个Dask集群,可以选择本地集群或连接到远程集群。这里以本地集群为例:

# 创建本地Dask集群
from dask.distributed import Clientclient = Client(n_workers=4)
3.4.2 使用Dask集群进行计算

接下来,你可以将任务提交到Dask集群上进行分布式计算:

# 在Dask集群上进行计算
import dask.array as dax = da.ones((1000, 1000), chunks=(100, 100))
y = x + x.T
z = y.mean(axis=0)result = z.compute()

通过创建Dask集群,你可以充分利用集群中的多个计算资源,实现在分布式环境中进行大规模数据处理和计算。

3.5 高级用法:Dask与分布式机器学习

Dask不仅仅用于数据处理,还可以与分布式机器学习库结合,实现大规模机器学习任务的分布式计算。以下是一个简单的例子:

3.5.1 集成Dask和Scikit-Learn

首先,确保你已经安装了Dask和Scikit-Learn:

pip install dask scikit-learn
3.5.2 使用Dask进行分布式机器学习

使用Dask和Scikit-Learn结合,实现分布式机器学习的训练和预测:

# 使用Dask进行分布式机器学习
import dask.array as da
from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression
from dask_ml.model_selection import train_test_split
from dask_ml.metrics import accuracy_score# 生成示例数据
X, y = make_classification(n_samples=100000, n_features=20, random_state=42)# 转换为Dask数组
X_dask = da.from_array(X, chunks=1000)
y_dask = da.from_array(y, chunks=1000)# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X_dask, y_dask, test_size=0.2, random_state=42)# 分布式机器学习模型
model = LogisticRegression(max_iter=1000)# 分布式训练模型
model.fit(X_train, y_train)# 分布式预测
y_pred = model.predict(X_test)# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print("Accuracy:", accuracy)

这样,你就可以在分布式环境中使用Dask进行机器学习任务的训练和预测。


4. Apache Kafka

4.1 基础概念

Apache Kafka是一个分布式流处理平台,用于高吞吐量的消息传递。

4.2 特性和优势

  • 高吞吐量的消息传递: 适用于大规模的实时数据流处理。
  • 横向可扩展: 可以随着数据量的增加而水平扩展。

4.3 与Python的集成

  • Kafka-Python库的使用: 通过Kafka-Python库实现Python与Kafka的集成。
# 示例代码 - 使用Kafka-Python库进行消息生产
from kafka import KafkaProducerproducer = KafkaProducer(bootstrap_servers='localhost:9092')
producer.send('my_topic', b'Hello, Kafka!')

4.4 高级特性:Kafka Topic和Partition

在Apache Kafka中,Topic是消息的逻辑分类,而Partition是Topic的分片,每个分片是一个独立的队列。以下是一个简单的例子:

4.4.1 创建Topic和发送消息

首先,你需要创建一个Topic,然后发送消息到该Topic:

# 创建Topic和发送消息
from kafka import KafkaProducerproducer = KafkaProducer(bootstrap_servers='localhost:9092')# 创建Topic
producer.send('my_topic', b'Hello, Kafka!')
4.4.2 消费者消费消息

创建一个消费者来消费Topic中的消息:

# 消费者消费消息
from kafka import KafkaConsumerconsumer = KafkaConsumer('my_topic', group_id='my_group', bootstrap_servers='localhost:9092')for message in consumer:print(f"Received message: {message.value}")
4.4.3 分区与水平扩展

在Kafka中,Topic可以分为多个Partition,每个Partition是一个有序的日志队列。分区的使用可以提高消息的并发处理能力:

# 发送消息到指定分区
producer.send('my_topic', value=b'Message for Partition 0', partition=0)
producer.send('my_topic', value=b'Message for Partition 1', partition=1)

通过合理划分Topic的Partition,你可以实现消息的水平扩展,提高整个系统的吞吐量。

4.5 高级用法:Kafka与Spark Streaming

Kafka与Apache Spark的结合可以实现实时流处理。以下是一个简单的示例:

4.5.1 Spark Streaming连接Kafka

首先,确保你的环境中已经安装了Apache Spark和PySpark:

pip install pyspark
4.5.2 创建Spark Streaming应用

创建一个Spark Streaming应用,连接到Kafka,接收消息并进行处理:

from pyspark.streaming import StreamingContext
from pyspark.streaming.kafka import KafkaUtils# 创建StreamingContext
ssc = StreamingContext(sparkContext, 2)  # 每2秒批处理一次# 连接Kafka
kafka_params = {"bootstrap.servers": "localhost:9092"}
kafka_stream = KafkaUtils.createDirectStream(ssc, ['my_topic'], kafka_params)# 处理消息
lines = kafka_stream.map(lambda x: x[1])
lines.pprint()# 启动Spark Streaming应用
ssc.start()
ssc.awaitTermination()

这样,你就成功地创建了一个Spark Streaming应用,实时接收并处理来自Kafka的消息流。


5. PySpark

5.1 基础概念

PySpark是Apache Spark的Python API,用于大规模数据处理和分布式计算。

5.2 特性和优势

  • 大规模数据处理和分析: 适用于处理PB级别的数据。
  • 分布式计算引擎: 具备强大的分布式计算能力。

5.3 使用场景

  • 复杂数据处理任务: 处理需要大量计算资源的复杂数据任务。
  • 分布式机器学习应用: 在大规模数据上进行机器学习模型训练。
# 示例代码 - 使用PySpark进行数据处理
from pyspark.sql import SparkSessionspark = SparkSession.builder.appName('example').getOrCreate()
# 在此添加更多PySpark代码

5.4 高级特性:PySpark SQL和DataFrame

PySpark提供了高级的SQL查询和DataFrame API,使得大规模数据的处理更加方便。以下是一个简单的例子:

5.4.1 创建DataFrame

首先,你可以通过PySpark SQL的DataFrame API创建一个DataFrame:

# 创建DataFrame
from pyspark.sql import SparkSessionspark = SparkSession.builder.appName('example').getOrCreate()data = [('Alice', 1), ('Bob', 2), ('Charlie', 3)]
columns = ['Name', 'Age']df = spark.createDataFrame(data, columns)
df.show()
5.4.2 使用SQL查询

使用PySpark SQL的SQL查询功能:

# 使用SQL查询
df.createOrReplaceTempView('people')
result = spark.sql('SELECT * FROM people WHERE Age > 1')
result.show()
5.4.3 数据转换和操作

对DataFrame进行各种数据转换和操作:

# 数据转换和操作
result = df.filter(df['Age'] > 1).groupBy('Age').count()
result.show()

通过DataFrame API和SQL查询,你可以更方便地对大规模数据进行处理和分析。

5.5 高级用法:PySpark MLlib

PySpark MLlib是Apache Spark的机器学习库,支持大规模数据上的分布式机器学习。以下是一个简单的示例:

5.5.1 导入MLlib库

首先,确保你的环境中已经安装了PySpark和MLlib:

pip install pyspark
5.5.2 创建机器学习模型

使用PySpark MLlib创建一个简单的线性回归模型:

# 创建机器学习模型
from pyspark.ml.regression import LinearRegression
from pyspark.ml.feature import VectorAssembler# 准备数据
data = [(1.0, 2.0, 3.0), (2.0, 3.0, 4.0), (3.0, 4.0, 5.0)]
columns = ['feature_1', 'feature_2', 'label']
df = spark.createDataFrame(data, columns)# 特征向量化
assembler = VectorAssembler(inputCols=['feature_1', 'feature_2'], outputCol='features')
df = assembler.transform(df)# 创建线性回归模型
lr = LinearRegression(featuresCol='features', labelCol='label')
model = lr.fit(df)# 查看模型参数
print("Coefficients:", model.coefficients)
print("Intercept:", model.intercept)

通过PySpark MLlib,你可以在大规模数据上构建和训练机器学习模型。


6. Consul

6.1 基础概念

Consul是一个用于服务发现和配置管理的分布式系统工具。

6.2 特性和优势

  • 健康检查和故障恢复: 自动监测服务健康状态,并进行故障恢复。
  • 动态服务注册: 支持服务动态注册和注销。

6.3 在Python分布式系统中的应用

  • 服务发现与负载均衡: 通过Consul实现服务发现,并结合负载均衡策略。
  • 配置管理的实践: 使用Consul进行分布式系统的配置管理。
# 示例代码 - 使用Consul进行服务注册
import consul# 创建Consul客户端
consul_client = consul.Consul()# 服务注册
service_definition = {"id": "example-service-1","name": "example-service","address": "127.0.0.1","port": 5000,"tags": ["web", "api"],
}consul_client.agent.service.register(**service_definition)

6.4 高级特性:Consul健康检查和故障恢复

Consul提供了健康检查和故障恢复的功能,确保服务始终处于可用状态。以下是一个简单的示例:

6.4.1 添加健康检查

在服务注册时,添加健康检查的定义:

# 添加健康检查
service_definition['checks'] = [{"http": "http://127.0.0.1:5000/health","interval": "10s",
}]
consul_client.agent.service.register(**service_definition)

在这个例子中,Consul将每隔10秒向服务的/health端点发起HTTP请求,确保服务正常运行。

6.4.2 故障恢复

如果服务不再响应健康检查,Consul会自动将其标记为不健康状态,从服务发现中移除。当服务再次响应健康检查时,Consul会自动将其重新加入服务发现。

通过健康检查和故障恢复机制,Consul帮助你确保分布式系统中的服务始终保持可用状态。

6.5 高级用法:Consul配置管理

Consul还提供了配置管理的功能,可以动态地管理应用程序的配置。以下是一个简单的示例:

6.5.1 注册配置

将应用程序的配置信息注册到Consul中:

# 注册配置
config_data = {"database_url": "mysql://user:password@localhost:3306/mydb"}
consul_client.kv.put('config/app', json.dumps(config_data))
6.5.2 获取配置

在应用程序中获取Consul中注册的配置:

# 获取配置
config_result = consul_client.kv.get('config/app')
if config_result is not None and config_result[1] is not None:config_data = json.loads(config_result[1]['Value'])print("Database URL:", config_data.get("database_url"))

通过Consul的配置管理功能,你可以动态地更新应用程序的配置,而无需重启应用程序。


通过以上示例代码,读者可以更深入地了解每个Python库的基本使用方法以及在分布式系统中的应用场景。这些库的结合使用能够构建强大的、高性能的分布式系统,适用于不同规模和类型的应用程序。在实际项目中,根据具体需求选择合适的库,合理搭配可以提升系统的可扩展性、可靠性和性能。

总结

在这篇文章中,我们探索了 Python 在分布式系统中的多个关键领域。我们深入了解了 Celery、RabbitMQ、Dask、Apache Kafka、PySpark 以及 Consul 这些库的基础概念和高级特性。通过实例代码和详细解释,读者将获得在构建和维护分布式系统时所需的知识和技能。

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

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

相关文章

NDIS协议驱动开发指南

文章目录 NDIS协议驱动开发指南1. 技术概览2. NDIS协议驱动2.1 BindAdapterHandlerEx2.2 SendNetBufferListsCompleteHandler2.3 ReceiveNetBufferListsHandler2.4 ProtocolNetPnpEvent 3. NET_BUFFER_LIST4. ndisprot实例5. 总结 NDIS协议驱动开发指南 我们知道&#xff0c;在…

【Proteus】绘制简单的电路图

参考书籍&#xff1a;微机原理与接口技术——基于8086和Proteus仿真&#xff08;第3版&#xff09;&#xff08;作者&#xff1a;顾晖等&#xff09;&#xff0c;p111 1.放置元件 以8086为例&#xff1a; 确保处于元件模式&#xff0c;点击对应的按钮&#xff1a; 在元件库中…

PyQt6 QGroupBox分组框控件

​锋哥原创的PyQt6视频教程&#xff1a; 2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~共计37条视频&#xff0c;包括&#xff1a;2024版 PyQt6 Python桌面开发 视频教程(无废话…

Python自动化测试selenium核心技术处理弹框

页面上的弹框一般有三种&#xff1a; &#xff08;1&#xff09;alert&#xff1a;用来提示 &#xff08;2&#xff09;confirm&#xff1a;用来确认 &#xff08;2&#xff09;prompt&#xff1a;输入内容 示例网站&#xff1a;Sahi Tests 示例场景&#xff1a;打开Sahi T…

Spring Boot 在启动之前还做了哪些准备工作?

目录 一:初始化资源加载器 二:校验主要源 三:设置主要源 四:推断 Web 应用类型<

mysql面试题分享带答案

数据库索引的原理&#xff0c;为什么要用B树&#xff0c;为什么不用二叉树&#xff1f; 可以从几个维度去看这个问题&#xff0c;查询是否够快&#xff0c;效率是否稳定&#xff0c;存储数据多少&#xff0c;以及查找磁盘次数&#xff0c;为什么不是二叉树&#xff0c;为什么不…

23 动态规划解买卖股票的最佳时机含手续费

问题描述&#xff1a;给定一个整数数组prices&#xff0c;其中第i各元素代表了第i填的股票价格&#xff1b;非负整数fee代表了交易股票是的手续费用&#xff0c;你可以无限次的完成交易&#xff0c;但是你眉笔交易都需要付手续费&#xff0c;如果你已经购买了一个股票&#xff…

深入了解 CPU 的型号、代际架构与微架构!

CPU 在整个计算机硬件中、技术体系中都算是最最重要的东西了。在 10 月 16 号的时候&#xff0c;Intel 正式发布了第 14 代的酷睿处理器。但很多同学看不懂这种发布会上发布的各种 CPU 参数。 今天借着这个时机&#xff0c;从 CPU 硬件相关的技术细节切入&#xff0c;来深入地…

基于SSM的物资物流系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

js实现富文本

当涉及到使用 JavaScript 实现富文本时&#xff0c;一种常见的方法是使用一些现成的富文本编辑器库&#xff0c;比如&#xff1a; Quill&#xff1a;一个功能强大、易于集成的富文本编辑器&#xff0c;支持自定义样式和格式&#xff0c;提供丰富的插件和API。 TinyMCE&#xf…

Distilling the Knowledge in a Neural Network(2015.5)(d补)

文章目录 Abstract1 Introduction2 Distillation2.1 Matching logits is a special case of distillation Results 论文链接 Abstract 提高几乎所有机器学习算法性能的一种非常简单的方法是在相同的数据上训练许多不同的模型&#xff0c;然后对它们的预测进行平均[3]。不幸的是…

C++之类和对象(下)

目录 初始化列表 static成员 C11对于非静态成员变量初始化 友元 友元函数 友元类 总结 初始化列表 我们知道&#xff0c;在学习构造函数时&#xff0c;我们知道对象的成员变量的初始化我们是在构造函数函数体内进行初始化的&#xff0c;还有没有其它初始化成员变量的方…

【Linux】telnet命令使用

telnet命令 telnet命令用于使用telnet协议与另一台主机进行通信。如果在没有主机参数的情况下调用telnet&#xff0c;它将进入命令模式&#xff0c;由其提示&#xff08;telnet>&#xff09;指示。在这种模式下&#xff0c;它接受并执行下面列出的命令。如果使用参数调用它…

十年阿里大牛谈软件测试面试的几个建议

首先从准备软件测试工作的简历说起。 如何准备一个好的简历呢&#xff1f; 好的简历要描述出你的技能&#xff0c;经验和特长。不要拿同样的简历去应聘不同的职位&#xff08;每个职位的要求是不同的&#xff09;&#xff0c;稍作修改就可以让你的机会大增。比方说&#xff0…

深入理解强化学习——马尔可夫决策过程:过程控制

分类目录&#xff1a;《深入理解强化学习》总目录 策略评估是指给定马尔可夫决策过程和策略&#xff0c;我们可以估算出价值函数的值。本文将阐述如果我们只有马尔可夫决策过程&#xff0c;我们应该如何寻找最佳的策略&#xff0c;从而得到最佳价值函数&#xff08;Optimal Val…

数字化时代的保镖:实人认证API在身份验证中的角色

前言 随着数字化时代的迅猛发展&#xff0c;个人信息的安全性和隐私保护成为了当今社会中备受关注的话题。在这个背景下&#xff0c;实人认证API崭露头角&#xff0c;成为数字领域中的一项重要技术&#xff0c;为身份验证提供了全新的保障机制。本文将探讨实人认证API在身份验…

本地启动tomcat,打印的日志中中文乱码

修改配置文件 /conf/logging.properties 修改配置项 java.util.logging.ConsoleHandler.encoding 从UTF-8改成GBK

力扣226:翻转二叉树

力扣226&#xff1a;翻转二叉树 给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 示例 1&#xff1a; 输入&#xff1a;root [4,2,7,1,3,6,9] 输出&#xff1a;[4,7,2,9,6,3,1] 示例 2&#xff1a; 输入&#xff1a;root [2,1,3]…

git submodule 用法

子仓库启蒙 在根目录执行&#xff1a; git submodule add gitgitee.com:liaosp/dcat-admin-basic-interface.git想要子模块指定的分支&#xff1a; git submodule add -b dev <仓库地址> <子模块路径>这样相当于在根目录上添加了 .gitmodules 信息&#xff0c;相…

java内部类详解

文章目录 一、介绍二、为什么要使用内部类三、非静态内部类四、静态内部类五、局部内部类六、匿名内部类七、lambda表达式内部类八、成员重名九、序列化十、如何选择内部类 一、介绍 在java中&#xff0c;我们被允许在编写一个类(外部类OuterClass)时&#xff0c;在其内部再嵌…