kafka中partition数量与消费者对应关系以及Java实践(Spring 版本)

news2024/9/28 5:31:37

文章目录

          • 分区理解
          • 一、单播模式,只有一个消费者组
            • 1. topic只有1个partition
            • 2. topic有多个partition,该组内有多个消费者
          • 二、广播模式,多个消费者组
            • 2.1. 多个消费者组,1个partition
            • 2.2. 多个消费者组,多个partition
          • 三、Java实践-producer
            • 3.1. 引入依赖
            • 3.2. 导入配置
            • 3.3. kafka工具类
            • 3.4. 发送消息
            • 3.5. 消息序列化
          • 四、Java实践-producer
            • 4.1. 引入依赖
            • 4.2. 导入配置
            • 4.3. kafka监听
            • 4.4. kafka消息反序列化
            • 4.5. 通用工具类
          • 五、集群测试
            • 5.1. 创建kafka主题
            • 5.2. 启动一个生产者
            • 5.3. 启动3个消费者
            • 5.4. 发送消息测试
            • 5.5. 数据分析总结
          • 六、命令版本集群验证
            • 6.1. 创建kafka主题
            • 6.2. 发送5笔消息
            • 6.3. 克隆3个终端窗口模拟消费者
            • 6.4. 数据分析总结
            • 6.5. 总结
            • 6.6. 使用kafkaManager为topic增加partition数量

kafka是由Apache软件基金会开发的一个开源流处理平台。kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者在网站中的所有动作流数据。

分区理解

kafka中partition类似数据库中的分表数据,可以起到水平扩展数据的目的,比如有a,b,c,d,e,f 6个数据,某个topic有两个partition,一般情况下partition-0存储a,c,e3个数据,partition-1存储b,d,f另外3个数据。

消费者组数量的不同以及partition数量的不同对应着不同的消费情况,下面分别进行梳理之:

一、单播模式,只有一个消费者组
1. topic只有1个partition

(1)topic只有1个partition,该组内有多个消费者时,此时同一个partition内的消息只能被该组中的一个consumer消费。当消费者数量多于partition数量时,多余的消费者是处于空闲状态的,如图1所示。topic,pis-business只有一个partition,并且只有1个group,G1,该group内有多个consumer,只能被其中一个消费者消费,其他的处于空闲状态。
在这里插入图片描述

2. topic有多个partition,该组内有多个消费者

该topic有多个partition,该组内有多个消费者,

  • 第一种场景:
    比如pis-business 有3个partition,该组内有2个消费者,那么可能就是C0对应消费p0,p1内的数据,c1对应消费p2的数据;

  • 第二种场景:
    如果有3个消费者,就是一个消费者对应消费一个partition内的数据了这种模式在集群模式下使用是非常普遍的,比如我们可以起3个服务,对应的topic设置3个partiition,这样就可以实现并行消费,大大提高处理消息的效率。

在这里插入图片描述

二、广播模式,多个消费者组

如果想实现广播的模式就需要设置多个消费者组,这样当一个消费者组消费完这个消息后,丝毫不影响其他组内的消费者进行消费,这就是广播的概念。

2.1. 多个消费者组,1个partition

该topic内的数据被多个消费者组同时消费,当某个消费者组有多个消费者时也只能被一个消费者消费,如图所示:
在这里插入图片描述

2.2. 多个消费者组,多个partition

该topic内的数据可被多个消费者组多次消费,在一个消费者组内,每个消费者又可对应该topic内的一个或者多个partition并行消费,如图所示:
在这里插入图片描述

三、Java实践-producer

这里使用Java服务进行实践,模拟3个parition,然后同一个组内有3个消费者的情况:

3.1. 引入依赖
       <!--kafka-spring 集成-->
        <dependency>
            <groupId>org.springframework.kafka</groupId>
            <artifactId>spring-kafka</artifactId>
            <version>1.3.10.RELEASE</version>
        </dependency>
        <!--自定义kafka序列化消息和反序列化消息用途-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.5.4</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.83</version>
        </dependency>
3.2. 导入配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 1.定义producer的参数 -->
    <bean id="producerProperties" class="java.util.HashMap">
        <constructor-arg>
            <map>
                <!-- 配置kafka的broke -->
                <entry key="bootstrap.servers" value="192.168.105.125:9092,192.168.105.129:9092,192.168.105.130:9092"/>
                <!-- 配置组-->
                <entry key="max.request.size" value="10000"/>
                <entry key="acks" value="-1"/>
                <entry key="retries" value="3"/>
                <entry key="batch.size" value="4096"/>
                <entry key="linger.ms" value="10000"/>
                <entry key="buffer.memory" value="40960"/>
                <entry key="key.serializer" value="org.apache.kafka.common.serialization.StringSerializer"/>
                <entry key="value.serializer" value="com.gblfy.kafka.encode.EncodeingKafka"/>
                <!--自定义的kafka反序列化类-->
            </map>
        </constructor-arg>
    </bean>

    <!-- 2.创建 kafkaTemplate 需要使用的 producerFactory Bean -->
    <bean id="producerFactory" class="org.springframework.kafka.core.DefaultKafkaProducerFactory">
        <constructor-arg ref="producerProperties"/>
    </bean>

    <!-- 3.创建 kafkaTemplate Bean,使用的时候只需要注入这个bean,即可使用kafkaTemplate的 send 消息方法 -->
    <bean id="kafkaTemplate" class="org.springframework.kafka.core.KafkaTemplate">
        <constructor-arg ref="producerFactory"/>
        <constructor-arg name="autoFlush" value="true"/>
        <property name="defaultTopic" value="pis-business"/>
    </bean>

</beans>

3.3. kafka工具类
package com.gblfy.kafka;

import org.apache.kafka.clients.producer.RecordMetadata;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.support.SendResult;
import org.springframework.stereotype.Service;
import org.springframework.util.concurrent.ListenableFuture;


/**
 * kafka发送工具类
 *
 * @author gblfy
 * @date: 2022-11-18
 **/
@Service
public class KafkaProducerService {
    @Autowired
    private KafkaTemplate kafkaTemplate;

    // @Autowired
    // private xxxMapper xxxMMapper;TODO 数据库轨迹Mapper

    /**
     * @param topic   topic分区
     * @param message kafka消息
     * @return 发送Kafka成功并返回请求响应信息
     */
    public void sendMessageForgetResult(String topic, String message) {
        try {
            System.out.println("---------topic-------" + topic);
            ListenableFuture<SendResult<String, String>> listenableFuture = kafkaTemplate.send(topic, message);
            SendResult<String, String> sendResult = listenableFuture.get();
            RecordMetadata recordMetadata;
            if (sendResult != null) {
                recordMetadata = sendResult.getRecordMetadata();
                System.out.println("发送成功!");
                System.out.println("topic:" + recordMetadata.topic());
                System.out.println("partition:" + recordMetadata.partition());
                System.out.println("offset:" + recordMetadata.offset());
            }

            // TODO 设置消息发送状态
            // TODO 更新数据落库
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("--------kafka发送失败---------!");
            // TODO 设置消息发送状态
            // TODO 更新数据落库
        }
        System.out.println("发送成功!");
    }

}
3.4. 发送消息
package com.gblfy.producer;

import com.alibaba.fastjson.JSON;
import com.gblfy.kafka.KafkaProducerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

/**
 * 监听类的实现
 *
 * @author gblfy
 * @date 2022-11-18
 */
@RestController
@RequestMapping("kafka")
public class KafkaProducer {

    @Autowired
    private KafkaProducerService kafkaProducerService;
    //kafka发送的主题
    public static final String KAFKA_TOPIC = "pis-business";

    /**
     * 消息发送
     * http://localhost:8080/springmvc-producer/kafka/producer?value=123
     */
    @GetMapping("producer")
    public String producer(@RequestParam String value) {
        Map map = new HashMap<>();
        map.put("key", value);

        String message = JSON.toJSONString(map);

        // 发送kafka
        kafkaProducerService.sendMessageForgetResult(KAFKA_TOPIC, message);
        return "已发送";
    }

}

3.5. 消息序列化
package com.gblfy.kafka.encode;

import com.gblfy.kafka.BeanUtils;
import org.apache.kafka.common.serialization.Serializer;
import org.springframework.stereotype.Component;

import java.util.Map;

@Component
public class EncodeingKafka implements Serializer<Object> {
    @Override
    public void configure(Map configs, boolean isKey) {

    }

    @Override
    public byte[] serialize(String topic, Object data) {
        return BeanUtils.bean2Byte(data);
    }

    /*
     * producer调用close()方法是调用
     */
    @Override
    public void close() {
        System.out.println("EncodeingKafka is close");
    }
}

四、Java实践-producer

这里使用Java服务进行实践,模拟3个parition,然后同一个组内有3个消费者的情况:

4.1. 引入依赖
       <!--kafka-spring 集成-->
        <dependency>
            <groupId>org.springframework.kafka</groupId>
            <artifactId>spring-kafka</artifactId>
            <version>1.3.10.RELEASE</version>
        </dependency>
        <!--自定义kafka序列化消息和反序列化消息用途-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.5.4</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.83</version>
        </dependency>
4.2. 导入配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">

    <context:annotation-config/>

    <!-- 1.定义 consumer 的参数 -->
    <bean id="consumerProperties1" class="java.util.HashMap">
        <constructor-arg>
            <map>
                <entry key="bootstrap.servers" value="192.168.105.125:9092,192.168.105.129:9092,192.168.105.130:9092"/>
                <entry key="group.id" value="pis "/>
                <entry key="enable.auto.commit" value="false"/>
                <entry key="request.timeout.ms" value="65000"/>
                <entry key="session.timeout.ms" value="63000"/>
                <entry key="key.deserializer" value="org.apache.kafka.common.serialization.StringDeserializer"/>
                <entry key="value.deserializer" value="com.gblfy.kafka.encode.DecodeingKafka"/>
                <entry key="auto.offset.reset" value="earliest"/><!--后加上的属性-->
            </map>
        </constructor-arg>
    </bean>

    <!-- 2.创建 consumerFactory bean -->
    <bean id="consumerFactory1" class="org.springframework.kafka.core.DefaultKafkaConsumerFactory">
        <constructor-arg ref="consumerProperties1"/>
    </bean>

    <!-- 3.配置消费端 Kafka 监听实现类(自己实现) -->
    <bean id="kafkaConsumerListener" class="com.gblfy.kafka.listener.KafkaConsumerListener"/>

    <!-- 4.消费者容器配置 -->
    <bean id="containerProperties1" class="org.springframework.kafka.listener.config.ContainerProperties">
        <constructor-arg name="topics">
            <list>
                <!-- 这里可以是多个主题-->
                <value>pis-business</value>
            </list>
        </constructor-arg>
        <property name="messageListener" ref="kafkaConsumerListener"/>
        <!-- 设置如何提交offset 手动提交 -->
        <property name="ackMode" value="MANUAL_IMMEDIATE"/>
    </bean>

    <!-- 5.消费者并发消息监听容器 -->
    <bean id="messageListenerContainer" class="org.springframework.kafka.listener.KafkaMessageListenerContainer">
        <constructor-arg ref="consumerFactory1"/>
        <constructor-arg ref="containerProperties1"/>
    </bean>

    <!-- 消费者容器配置信息 -->
    <bean id="kafkaConsumerProperties1" class="org.springframework.kafka.listener.config.ContainerProperties">
        <constructor-arg name="topics" value="pis-bussiness"/><!--topic对应的名称-->
        <property name="messageListener" ref="kafkaConsumerListener"/>
        <!-- 设置如何提交offset 手动提交 -->
        <property name="ackMode" value="MANUAL_IMMEDIATE"/>
    </bean>

    <bean id="ListenerContainer1" class="org.springframework.kafka.listener.ConcurrentMessageListenerContainer">
        <constructor-arg ref="consumerFactory1"/>
        <constructor-arg ref="kafkaConsumerProperties1"/>
        <!--禁止自动启动-->
        <!--<property name="autoStartup" value="false" />-->
        <property name="concurrency" value="1"/> <!--单线程消费 -->
    </bean>

</beans>

4.3. kafka监听
package com.gblfy.kafka.listener;

import com.alibaba.fastjson.JSONObject;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.springframework.kafka.listener.AcknowledgingMessageListener;
import org.springframework.kafka.support.Acknowledgment;

/**
 * 监听类的实现
 *
 * @author gblfy
 * @date 2022-11-18
 */
public class KafkaConsumerListener implements AcknowledgingMessageListener<String, String> {

    @Override
    public void onMessage(ConsumerRecord<String, String> data, Acknowledgment acknowledgment) {
        String topic = data.topic();
        System.out.println("消费的topic主题:-----" + topic);
        System.out.println("消费-----" + data.partition() + "分区的消息");
        System.out.println("offset-----" + data.offset());
        System.out.println("message-----" + data.value());


        /*获取kafka数据*/
        JSONObject pardeData = (JSONObject) JSONObject.parse(data.value());
        String value1 = pardeData.getString("key");
        System.out.println("value1-----" + value1);


        // TODO 业务逻辑处理

        //消费完成后提交offset
        if (acknowledgment != null) {
            acknowledgment.acknowledge();
        }
    }
}

4.4. kafka消息反序列化
package com.gblfy.kafka.encode;

import com.gblfy.kafka.BeanUtils;
import org.apache.kafka.common.serialization.Deserializer;
import org.springframework.stereotype.Component;

import java.util.Map;

@Component
public class DecodeingKafka implements Deserializer<Object> {

    @Override
    public void configure(Map<String, ?> configs, boolean isKey) {
    }

    @Override
    public Object deserialize(String topic, byte[] data) {
        return BeanUtils.byte2Obj(data);
    }

    @Override
    public void close() {

    }
}

4.5. 通用工具类

生产者和消费者一样

package com.gblfy.kafka;

import java.io.*;

public class BeanUtils {
    private BeanUtils() {}
    /**
     * 对象序列化为byte数组
     *
     * @param obj
     * @return
     */
    public static byte[] bean2Byte(Object obj) {
        byte[] bb = null;
        try (ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
             ObjectOutputStream outputStream = new ObjectOutputStream(byteArray)){
            outputStream.writeObject(obj);
            outputStream.flush();
            bb = byteArray.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bb;
    }
    /**
     * 字节数组转为Object对象
     *
     * @param bytes
     * @return
     */
    public static Object byte2Obj(byte[] bytes) {
        Object readObject = null;
        try (ByteArrayInputStream in = new ByteArrayInputStream(bytes);
             ObjectInputStream inputStream = new ObjectInputStream(in)){
            readObject = inputStream.readObject();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return readObject;
    }
}

五、集群测试
5.1. 创建kafka主题

创建kafka主题名称为pis-business
分区3个 副本数量3个

kafka-topics.sh -zookeeper 192.168.105.125:2181 --create --partitions 3 --replication-factor 3 --topic pis-business
5.2. 启动一个生产者

在这里插入图片描述

5.3. 启动3个消费者

这里使用同一个消费者项目,启动一个项目后修改端口依次启动,端口分别为8081、082、8083
在这里插入图片描述

5.4. 发送消息测试
  • 发送3笔消息
    消费者1 端口8081 消费的分区2的消息
    在这里插入图片描述
    消费者2 端口8082消费的分区1的消息
    在这里插入图片描述

    消费者3 端口8083 消费的分区0的消息
    在这里插入图片描述

-发送5笔消息
清空控制台,重新发送5笔消息测试
消费者1 端口8081 消费的分区2的1笔消息
在这里插入图片描述

消费者2 端口8082消费的分区1的2笔消息
在这里插入图片描述

消费者3 端口8083 消费的分区0的2笔消息
在这里插入图片描述

5.5. 数据分析总结

从第二轮测试结果数据分析来看:
生产者:投递5笔消息,有2笔投递到了分区模型0中,有2笔投递到了分区模型1中,有1笔投递到了分区模型2中。

消费者:
消费1端口8081分区模型2中1笔消息,
消费2端口8082分区模型1中2笔消息,
消费3端口8083分区模型0中2笔消息,
从消费者消费来看,是按照分区模型来消费的,起到了均衡消费的效果,目前没有出现,一个消费者消费不同分取模型中的消息对吧。

  • 总结
    所以在微服务的集群中,我们可以通过给topic设置多个partition,然后让每一个实例对应消费1个partition的数据,从而实现并行的处理数据,可以显著地提高处理消息的速度。
六、命令版本集群验证
6.1. 创建kafka主题

创建kafka主题名称为pis-business
分区3个 副本数量3个

kafka-topics.sh -zookeeper 192.168.105.125:2181 --create --partitions 3 --replication-factor 3 --topic pis-business
6.2. 发送5笔消息
kafka-console-producer.sh --broker-list 192.168.105.125:9092 --topic pis-business

消息内容

1
2
3
4
5

在这里插入图片描述

6.3. 克隆3个终端窗口模拟消费者
bin/kafka-console-consumer.sh --bootstrap-server 192.168.105.125:9092  --from-beginning --topic pis-business

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

6.4. 数据分析总结

消费者1消费消息数量2笔,消息内容为2和5
消费者2消费消息数量2笔,消息内容为1和4
消费者3消费消息数量1笔,消息内容为3

6.5. 总结

所以在微服务的集群中,我们可以通过给topic设置多个partition,然后让每一个实例对应消费1个partition的数据,从而实现并行的处理数据,可以显著地提高处理消息的速度。

6.6. 使用kafkaManager为topic增加partition数量

在这里插入图片描述
首先点击 Add Partitions 增加partition的数量,然后点击Generate Partition Assignments ,此时系统自动会为每个分区下的副本分配broker, 最后点击 Reassign Partitions,可以平衡集群的负载 。

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

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

相关文章

谈谈JS二进制:File、Blob、FileReader、ArrayBuffer、Base64

当互联网进入存量时代&#xff0c;增量正在成为行业的稀缺资源。而本地生活服务恰恰是当前互联网行业为数不多的增量。 前瞻产业研究院数据显示&#xff0c;2021年中国互联网本地生活服务行业市场规模达到2.6万亿元&#xff0c;到2025年&#xff0c;其市场规模有望达到4万亿元&…

吉林优美姿文化:抖音店铺怎么优化页面?

要知道&#xff0c;新手开始做直播间影响人气的三大要素就是在线人数&#xff0c;互动量&#xff0c;以及留存率&#xff0c;那么当这些要素都非常高的时候&#xff0c;抖音系统就会自动把你的直播间推荐给更多的观众&#xff0c;获取更多的流量&#xff0c;那么抖音新手怎么开…

简单了解Vue

1、vue概述 Vue是一套前端框架&#xff0c;可以免除原生JavaScript中的DOM操作&#xff0c;简化书写。 基于MVVM&#xff08;Model-View-View Model&#xff09;思想&#xff0c;实现数据的双向绑定&#xff0c;将编程的关注点放在数据上 vue的官网&#xff1a;https://cn.v…

猿如意---Python3.10版本手把手教学安装和下载.

亲自为大家示范如何使用猿如意以及在猿如意当中下载&#xff0c;安装和使用python3.10版本&#xff0c;让大家喜欢上这款好用的app—猿如意。 文章目录前言一、手把手教你猿如意的安装、下载二、手把手教你Python3.10版本的安装、下载1.找到我需要的工具2.我需要的工具的安装、…

Docker容器

1.什么是Docker&#xff1f; 1.为什么会出现docker&#xff1f; 我们写的代码会接触到好几个环境&#xff1a;开发环境、测试环境以及生产环境等等。多种环境去部署同一份代码&#xff0c;由于环境原因往往会出现软件跨环境迁移的问题&#xff08;也就是“水土”不服&#xf…

Android车载应用开发——DLNA开发浅析

DNLA的建立 DLNA 成立于2003 年6 月24 日, 其前身是DHWG &#xff08;Digital Home Working Group 数字家庭工作组&#xff09;&#xff0c;由Sony、Intel、Microsoft等发起成立、旨在解决个人PC &#xff0c;消费电器&#xff0c;移动设备在内的无线网络和有线网络的互联互通…

基于x86架构的CentOS7虚拟机通过qemu安装ARM架构OpenEuler虚拟机

【原文链接】基于x86架构的CentOS7虚拟机通过qemu安装ARM架构OpenEuler虚拟机 &#xff08;1&#xff09;首先需要有一台CentOS虚拟机&#xff0c;如没有可参考 VMWare安装CentOS7操作系统的虚拟机 安装一台CentOS虚拟机 &#xff08;2&#xff09;安装基础命令 yum install…

17:00面试,17:09就出来了 ,问的实在是太...

从外包出来&#xff0c;没想到算法死在另一家厂子 自从加入这家公司&#xff0c;每天都在加班&#xff0c;钱倒是给的不少&#xff0c;所以也就忍了。没想到8月一纸通知&#xff0c;所有人不许加班&#xff0c;薪资直降30%&#xff0c;顿时有吃不起饭的赶脚。 好在有个兄弟内…

java基于PHP+MySQL教务选课管理系统的设计与实现

基于PHP的教务管理系统主要高校内部提供服务,系统分为管理员,教师用户和学生用户三部分。 在基于PHP的教务管理系统中分为管理员用户,教师用户和学生用户三部分,其中管理员用户主要是用来管理教师信息,学生信息,公告信息,课程信息,专业信息和班级信息等内容,教师用户主要是用来…

Cartesi 2022 年 11 月回顾

查看你不想错过的更新2022年12月1日 &#xff0c;欢迎新的建设者加入Cartesi 生态系统并认识更多的新的开发者社区。 从紧张繁忙的11月到12月&#xff0c;11月 ETH Global 因为在旧金山举办了迄今为止最盛大的黑客马拉松活动而轰动一时。有13位才华横溢的学者加入了我们的 Hack…

原生JS的拖拽属性draggable(详解)

摘要 作为h5新增的属性draggable&#xff0c;它能够给与一切的html元素拖动的效果。而在这个属性之下&#xff0c;也有着关于拖动效果的各个方法。 而这一篇文章&#xff0c;主要就是说一下关于draggable属性的使用以及工作场景。 1.了解draggable属性的使用 对我来讲&#…

【单片机基础】初始51单片机

文章目录学习单片机需要掌握的基础知识1、用一句话说透什么是单片机&#xff1a;2、单片机上集成了什么&#xff1f;3、STC89C51/52单片机过时了吗&#xff1f;4、STC89C51和STC89C52有什么区别&#xff1f;5、单片机时序的概念&#xff08;基础知识很重要&#xff09;6、单片机…

基于功能安全的车载计算平台开发:系统层面

相对于功能安全概念阶段&#xff0c;系统阶段更专注于产品的详细设计&#xff0c;涉及系统工程、安全工程和架构设计等不同技术领域。同时&#xff0c;系统阶段也经常扮演着供应链上、下游功能安全的DIA交互阶段&#xff0c;是功能安全中非常重要且考验技术水平的阶段。 01 应…

微服务框架 SpringCloud微服务架构 8 Gateway 网关 8.6 过滤器链执行顺序

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式&#xff0c;系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 SpringCloud微服务架构 文章目录微服务框架SpringCloud微服务架构8 Gateway 网关8.6 过滤器链执行顺序8.6.1 过滤器执行顺序8.6.2 总结8 Gat…

【毕业设计】大数据房价数据分析可视化 - python

文章目录0 前言1 课题背景2 数据爬取2.1 爬虫简介2.2 房价爬取3 数据可视化分析3.1 ECharts3.2 相关可视化图表4 最后0 前言 &#x1f525; Hi&#xff0c;大家好&#xff0c;这里是丹成学长的毕设系列文章&#xff01; &#x1f525; 对毕设有任何疑问都可以问学长哦! 这两…

深度讲解风险策略的调优|附实操案例

量化风控审核过程中的通过率在贷前策略中是一大重要的内容&#xff0c;另外一个是逾期率。二者之间的因果关系就是通过率高低变化决定了逾期率风险的走势&#xff0c;通过率决定了逾期率的结果&#xff0c;而逾期率又对通过率起到了一个制衡的作用。 我们在本周早前详细谈过这个…

先验 后验 似然估计

一、完备事件组 设E是随机试验&#xff0c;Ω是相应的样本空间&#xff0c;A1&#xff0c;A2&#xff0c;...An为Ω的一个事件组&#xff0c;若 &#xff08;1&#xff09;AiAj&#xff08;ij&#xff09; &#xff08;2&#xff09;A1A2...AnΩ 则称A1A2...An为样本空间的…

web安全之MySQL手工注入的原理讲解和实验分析

目录 前提知识 靶场搭建 手工注入 高权限注入 sql注入之文件读写 基础防御 前提知识 数据库及sql语句知识&#xff0c;web相关知识。union合并查询的两个特征&#xff1a;前后查询互不干扰&#xff0c;前后查询的字段可以不同但是数量必须一致。order by 通过测试来猜解表…

解决SpringBoot整合Mybatis和Mybatis-Plus不能公用(版本兼容性问题)

1 前言 虽然Mybatis-Plus很好使&#xff0c;可以帮助我们生成CRUD的接口&#xff0c;但是有的情况下我们需要联合其他表进行多表查询&#xff0c;这时候Mybatis可以手写SQL的优势就体现出来了&#xff0c;一般在开发中&#xff0c;很多项目都是Mybatis和Mybatis-Plus公用的&am…

Markdowm使用手册

Markdown使用手册 目录Markdown使用手册一、基础语法1.1 书写各级标题1.2 字体加粗/斜体1.2.1 字体加粗1.2.2 字体倾斜1.3 线条使用1.3.1 删除线1.3.2 高亮线1.3.3 下划线二、插入工具2.1 插入代码2.1.1 插入某一行的代码2.1.2 插入整块的代码2.2 插入链接2.3 插入数学公式2.4 …