Kafka Schema Registry | 学习Avro Schema

2023-10-14 23:40

本文主要是介绍Kafka Schema Registry | 学习Avro Schema,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.目标

在这个Kafka Schema Registry教程中,我们将了解Schema Registry是什么以及为什么我们应该将它与Apache Kafka一起使用。此外,我们将看到Avro架构演变的概念,并使用Kafka Avro Serializers设置和使用Schema Registry。此外,我们将学习使用Schema Registry的REST接口管理Avro Schemas。 
那么,让我们讨论一下Apache Kafka Schema Registry。

Kafka Schema Registry

Apache Kafka架构注册表

2.什么是Kafka Schema Registry?

基本上,对于Kafka Producers和Kafka Consumer,Kafka的 Schema Registry都存储Avro Schemas。

  • 它提供了一个用于管理Avro架构的RESTful界面。
  • 它允许存储版本化模式的历史记录。
  • 此外,它还支持检查Kafka的架构兼容性。
  • 使用Avro Schema,我们可以配置兼容性设置以支持Kafka模式的发展。

学习Apache Kafka用例和应用程序

基本上,Kafka Avro序列化项目提供了序列化程序。在Avro和Kafka Schema Registry的帮助下,使用Kafka Avro序列化的Kafka Producers和Kafka Consumer都处理模式管理以及记录的序列化。

Kafka Schema Registry

Kafka Schema Registry简介

此外,生产者在使用Kafka中的Confluent Schema Registry时不必发送模式,只需要唯一的模式ID。因此,为了从Confluent模式注册表中查找完整模式(如果尚未缓存),使用者使用模式ID。这意味着不必使用每组记录发送模式,这样也可以节省时间。 

但是,Kafka制作人也创建了一条记录/消息,即Avro记录。该记录包含模式ID和数据。此外,如果需要,还会注册架构,然后使用Kafka Avro Serializer序列化数据和架构ID。 
我们来讨论Apache Kafka架构及其基本概念

3.为什么在Kafka中使用Schema Registry? 

消费者的架构可能与生产者的架构不同。在定义消费者模式时,消费者期望记录/消息符合要求。执行检查时,如果两个模式不匹配但兼容,则通过Avma Schema Evolution和Schema Registry进行有效负载转换。此外,Kafka记录可以有一个键和一个值,两者都可以有一个模式。

4. Kafka Schema注册局运营

但是,对于Kafka记录的键和值,Schema Registry可以存储模式。此外,它按主题列出模式。此外,它可以列出主题(模式)的所有版本。此外,它可以按版本或ID检索架构。并且可以获得最新版本的模式。
Apache Kafka架构注册表的一些兼容级别是向后,向前,完整,无。此外,我们可以通过REST API使用Schema注册表管理模式。
修改Apache Kafka操作和命令。

5. Kafka Schema兼容性设置

让我们了解所有兼容性级别。基本上,向后兼容性是指使用较旧模式编写的数据,可以使用较新的模式进行读取。此外,向前兼容性是指使用旧模式可读取使用较新模式编写的数据。此外,完全兼容性是指新版本的模式是向后兼容的。并且,“无”状态,意味着它禁用模式验证,不建议这样做。因此,Schema Registry只存储模式,如果我们将级别设置为“none”,它将不会验证兼容性。

一个。架构注册表配置

无论是全球还是每个主题。
兼容性值为:
A。无
表示不检查架构兼容性。
B.转发
说,检查以确保最后一个模式版本与新模式向前兼容。
C.向后(默认)
这意味着确保新模式向后兼容最新模式。
D. Full 
“Full”表示确保新模式从最新到最新以及从最新到最新都是向前和向后兼容的。
阅读Storm Kafka与配置和代码的集成

6.架构演变

虽然,如果使用该架构的旧版本,在将数据写入存储后会更改Avro架构,那么当我们尝试读取该数据时,Avro可能会进行架构演变。
但是,从Kafka的角度来看,模式演变只发生在消费者的反序列化(阅读)中。并且,如果可能,则在反序列化期间自动修改值或键,以便在消费者的模式与生产者的模式不同时符合消费者的读取模式。
简而言之,它是消费者模式版本与生产者放入Kafka日志的模式之间的Avro模式的自动转换。但是,当消费者模式与用于序列化Kafka记录的生产者模式不同时,将对Kafka记录的键或值执行数据转换。虽然,如果模式匹配,则无需进行转换。

一个。模式演变过程中允许的修改

可以将具有默认值的字段添加到架构。我们可以删除具有默认值的字段。此外,我们可以更改字段的订单属性。此外,我们可以将字段的默认值更改为其他值,或者将默认值添加到没有字段的字段中。
但是,可以删除或添加字段别名,但这可能会导致某些依赖别名的使用者中断。此外,我们可以将类型更改为包含原始类型的联合。上述更改将导致我们的架构在使用旧架构读取时可以使用Avro的架构演变。

湾 修改架构的道路规则

如果我们想让我们的架构可以进化,我们必须遵循这些准则。首先,我们需要为模式中的字段提供默认值,因为这允许我们稍后删除该字段。请记住,永远不要更改字段的数据类型。此外,在向架构添加新字段时,我们必须为字段提供默认值。并且,请确保不要重命名现有字段(而是使用别名)。
我们来讨论Apache Kafka Streams | 流处理拓扑
例如:

  • 员工示例Avro架构:
  1. {"namespace": "com.dataflair.phonebook","type": "record","name": "Employee","doc" : "Represents an Employee at a company","fields": [{"name": "firstName", "type": "string", "doc": "The persons given name"},{"name": "nickName", "type": ["null", "string"], "default" : null},{"name": "lastName", "type": "string"},{"name": "age",  "type": "int", "default": -1},{"name": "emails", "default":[], "type":{"type": "array", "items": "string"}},{"name": "phoneNumber",  "type":[ "null",{ "type": "record",   "name": "PhoneNumber","fields": [{"name": "areaCode", "type": "string"},{"name": "countryCode", "type": "string", "default" : ""},{"name": "prefix", "type": "string"},{"name": "number", "type": "string"}]}]},{"name":"status", "default" :"SALARY", "type": { "type": "enum", "name": "Status","symbols" : ["RETIRED", "SALARY", "HOURLY", "PART_TIME"]}}]
    }

     

7. Avro Schema Evolution场景

假设在模式的版本1中,我们的员工记录没有年龄因素。但现在我们要添加一个默认值为-1的年龄字段。所以,假设我们有一个消费者使用版本1没有年龄,生产者使用模式的版本2与年龄
现在,通过使用Employee模式的版本2生产者,创建一个com.dataflair.Employee记录设置年龄字段到42,然后将其发送给Kafka主题new-Employees。之后,使用版本1,使用者将使用Employee架构的新员工记录。因此,在反序列化期间删除age字段只是因为使用者正在使用模式的版本1。

您是否知道Kafka和RabbitMQ之间的区别
此外,同一个消费者修改了一些记录,然后将记录写入NoSQL商店。因此,它写入NoSQL存储的记录中缺少age字段。现在,使用模式的第2版,另一个具有年龄的客户端从NoSQL存储中读取记录。因此,由于Consumer使用版本1编写它,因此记录中缺少age字段,因此客户端读取记录并将age设置为默认值-1。
因此,Schema Registry可以拒绝该模式,并且生产者永远不会将其添加到Kafka日志中,如果我们添加了年龄并且它不是可选的,即age字段没有默认值。

8.使用Schema Registry REST API

此外,通过使用以下操作,Kafka中的Schema Registry允许我们管理模式:

  1. 存储Kafka记录的键和值的模式
  2. 按主题列出模式
  3. 列出主题的所有版本(架构)
  4. 按版本检索架构
  5. 按ID检索架构
  6. 检索最新版本的架构
  7. 执行兼容性检查
  8. 全局设置兼容级别

您是否知道Apache Kafka职业范围及其薪资趋势
然而,所有这些都可通过REST API与Kafka中的Schema Registry一起获得。
我们可以执行以下操作,以便发布新架构:

一个。发布新架构

  1. curl -X POST -H "Content-Type:
    application/vnd.schemaregistry.v1+json" \--data '{"schema": "{\"type\": …}’ \http://localhost:8081/subjects/Employee/versions

     

湾 列出所有模式

curl -X GET http:// localhost:8081 / subject
我们基本上可以通过Schema Registry的REST接口执行上述所有操作,只有你有一个好的HTTP客户端。例如,Schema Registry使用Square中的OkHttp客户端(com.squareup.okhttp3:okhttp:3.7.0+)稍微好一点,如下所示:

  • 使用REST端点尝试所有Schema Registry选项:

  1. package com.dataflair.kafka.schema;
    import okhttp3.*;
    import java.io.IOException;
    public class SchemaMain {private final static MediaType SCHEMA_CONTENT =MediaType.parse("application/vnd.schemaregistry.v1+json");private final static String Employee_SCHEMA = "{\n" +" \"schema\": \"" +" {" +" \\\"namespace\\\": \\\"com.dataflair.phonebook\\\"," +" \\\"type\\\": \\\"record\\\"," +" \\\"name\\\": \\\"Employee\\\"," +" \\\"fields\\\": [" +" {\\\"name\\\": \\\"fName\\\", \\\"type\\\": \\\"string\\\"}," +" {\\\"name\\\": \\\"lName\\\", \\\"type\\\": \\\"string\\\"}," +" {\\\"name\\\": \\\"age\\\",  \\\"type\\\": \\\"int\\\"}," +" {\\\"name\\\": \\\"phoneNumber\\\",  \\\"type\\\": \\\"string\\\"}" +" ]" +" }\"" +"}";public static void main(String... args) throws IOException {System.out.println(Employee_SCHEMA);final OkHttpClient client = new OkHttpClient();//POST A NEW SCHEMARequest request = new Request.Builder().post(RequestBody.create(SCHEMA_CONTENT, Employee_SCHEMA)).url("http://localhost:8081/subjects/Employee/versions").build();String output = client.newCall(request).execute().body().string();System.out.println(output);//LIST ALL SCHEMASrequest = new Request.Builder().url("http://localhost:8081/subjects").build();output = client.newCall(request).execute().body().string();System.out.println(output);//SHOW ALL VERSIONS OF Employeerequest = new Request.Builder().url("http://localhost:8081/subjects/Employee/versions/").build();output = client.newCall(request).execute().body().string();System.out.println(output);//SHOW VERSION 2 OF Employeerequest = new Request.Builder().url("http://localhost:8081/subjects/Employee/versions/2").build();output = client.newCall(request).execute().body().string();System.out.println(output);//SHOW THE SCHEMA WITH ID 3request = new Request.Builder().url("http://localhost:8081/schemas/ids/3").build();output = client.newCall(request).execute().body().string();System.out.println(output);//SHOW THE LATEST VERSION OF Employee 2request = new Request.Builder().url("http://localhost:8081/subjects/Employee/versions/latest").build();output = client.newCall(request).execute().body().string();System.out.println(output);//CHECK IF SCHEMA IS REGISTEREDrequest = new Request.Builder().post(RequestBody.create(SCHEMA_CONTENT, Employee_SCHEMA)).url("http://localhost:8081/subjects/Employee").build();output = client.newCall(request).execute().body().string();System.out.println(output);//TEST COMPATIBILITYrequest = new Request.Builder().post(RequestBody.create(SCHEMA_CONTENT, Employee_SCHEMA)).url("http://localhost:8081/compatibility/subjects/Employee/versions/latest").build();output = client.newCall(request).execute().body().string();System.out.println(output);// TOP LEVEL CONFIGrequest = new Request.Builder().url("http://localhost:8081/config").build();output = client.newCall(request).execute().body().string();System.out.println(output);// SET TOP LEVEL CONFIG// VALUES are none, backward, forward and fullrequest = new Request.Builder().put(RequestBody.create(SCHEMA_CONTENT, "{\"compatibility\": \"none\"}")).url("http://localhost:8081/config").build();output = client.newCall(request).execute().body().string();System.out.println(output);// SET CONFIG FOR Employee// VALUES are none, backward, forward and fullrequest = new Request.Builder().put(RequestBody.create(SCHEMA_CONTENT, "{\"compatibility\": \"backward\"}")).url("http://localhost:8081/config/Employee").build();output = client.newCall(request).execute().body().string();System.out.println(output);}
    }

     

我们建议运行该示例以尝试强制不兼容的架构到架构注册表,并且还要注意各种兼容性设置的行为。

让我们修改Kafka vs Storm

C。运行Kafka架构注册表:

$ cat~ / tools / confluent-3.2.1 / etc / schema-registry / schema-registry.properties 
listeners = http://0.0.0.0:8081 
kafkastore.connection.url = localhost:2181 
kafkastore.topic = _schemas 
debug = false 
~ / tools / confluent-3.2.1 / bin / schema-registry-start~ / tools / confluent-3.2.1 / etc / schema-registry / schema-registry.properties

9.撰写消费者和生产者 

在这里,我们将要求启动指向ZooKeeper集群的Schema Registry服务器。此外,我们可能需要将Kafka Avro Serializer和Avro JAR导入我们的Gradle项目。之后,我们将要求配置生产者使用Schema Registry和KafkaAvroSerializer。此外,我们将要求将其配置为使用Schema Registry并使用KafkaAvroDeserializer来编写使用者。
因此,此构建文件显示了我们需要的Avro JAR文件。
阅读Apache Kafka Security | Kafka的需求和组成部分

  • Kafka Avro Serializer示例的Gradle构建文件:
  1. plugins {id "com.commercehub.gradle.plugin.avro" version "0.9.0"
    }
    group 'dataflair'
    version '1.0-SNAPSHOT'
    apply plugin: 'java'
    sourceCompatibility = 1.8
    dependencies {compile "org.apache.avro:avro:1.8.1"compile 'com.squareup.okhttp3:okhttp:3.7.0'testCompile 'junit:junit:4.11'compile 'org.apache.kafka:kafka-clients:0.10.2.0'compile 'io.confluent:kafka-avro-serializer:3.2.1'
    }
    repositories {jcenter()mavenCentral()maven {url "http://packages.confluent.io/maven/"}
    }
    avro {createSetters = falsefieldVisibility = "PRIVATE"
    }

     

请记住包括Kafka Avro Serializer lib(io.confluent:kafka-avro-serializer:3.2.1)和Avro lib(org.apache.avro:avro:1.8.1)。

一个。写一个制片人

让我们按如下方式编写制作人。

  • 使用Kafka Avro Serialization和Kafka Registry的制作人:
package com.dataflair.kafka.schema;
import com.dataflair.phonebook.Employee;
import com.dataflair.phonebook.PhoneNumber;
import io.confluent.kafka.serializers.KafkaAvroSerializerConfig;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.common.serialization.LongSerializer;
import io.confluent.kafka.serializers.KafkaAvroSerializer;
import java.util.Properties;
import java.util.stream.IntStream;

 

public class AvroProducer {private static Producer<Long, Employee> createProducer() {Properties props = new Properties();props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");props.put(ProducerConfig.CLIENT_ID_CONFIG, "AvroProducer");props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG,LongSerializer.class.getName());// Configure the KafkaAvroSerializer.
      props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,KafkaAvroSerializer.class.getName());// Schema Registry location.
       props.put(KafkaAvroSerializerConfig.SCHEMA_REGISTRY_URL_CONFIG,"http://localhost:8081");return new KafkaProducer<>(props);}private final static String TOPIC = "new-Employees";public static void main(String... args) {Producer<Long, Employee> producer = createProducer();Employee bob = Employee.newBuilder().setAge(35).setFirstName("Bob").setLastName("Jones").setPhoneNumber(PhoneNumber.newBuilder().setAreaCode("301").setCountryCode("1").setPrefix("555").setNumber("1234").build()).build();IntStream.range(1, 100).forEach(index->{producer.send(new ProducerRecord<>(TOPIC, 1L * index, bob));});producer.flush();producer.close();}
}

 

另外,请确保我们将Schema Registry和KafkaAvroSerializer配置为生成器设置的一部分。

我们来讨论Kafka主题

  1. // Configure the KafkaAvroSerializer.
    props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,KafkaAvroSerializer.class.getName());
    // Schema Registry location.        props.put(KafkaAvroSerializerConfig.SCHEMA_REGISTRY_URL_CONFIG,"http://localhost:8081");

     

此外,我们按预期使用生产者

B 写一个消费者

之后,我们将写信给消费者。

  • 使用Kafka Avro序列化和架构注册表的Kafka Consumer:
  1. package com.dataflair.kafka.schema;
    import com.dataflair.phonebook.Employee;
    import io.confluent.kafka.serializers.KafkaAvroDeserializer;
    import io.confluent.kafka.serializers.KafkaAvroDeserializerConfig;
    import org.apache.kafka.clients.consumer.Consumer;
    import org.apache.kafka.clients.consumer.ConsumerConfig;
    import org.apache.kafka.clients.consumer.ConsumerRecords;
    import org.apache.kafka.clients.consumer.KafkaConsumer;
    import org.apache.kafka.common.serialization.LongDeserializer;
    import java.util.Collections;
    import java.util.Properties;
    import java.util.stream.IntStream;
    public class AvroConsumer {private final static String BOOTSTRAP_SERVERS = "localhost:9092";private final static String TOPIC = "new-Employee";private static Consumer<Long, Employee> createConsumer() {Properties props = new Properties();props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, BOOTSTRAP_SERVERS);props.put(ConsumerConfig.GROUP_ID_CONFIG, "KafkaExampleAvroConsumer");props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG,LongDeserializer.class.getName());//Use Kafka Avro Deserializer.
           props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG,KafkaAvroDeserializer.class.getName());  //<----------------------//Use Specific Record or else you get Avro GenericRecord.props.put(KafkaAvroDeserializerConfig.SPECIFIC_AVRO_READER_CONFIG, "true");//Schema registry location.
           props.put(KafkaAvroDeserializerConfig.SCHEMA_REGISTRY_URL_CONFIG,"http://localhost:8081"); //<----- Run Schema Registry on 8081return new KafkaConsumer<>(props);}public static void main(String... args) {final Consumer<Long, Employee> consumer = createConsumer();consumer.subscribe(Collections.singletonList(TOPIC));IntStream.range(1, 100).forEach(index -> {final ConsumerRecords<Long, Employee> records =consumer.poll(100);if (records.count() == 0) {System.out.println("None found");} else records.forEach(record -> {Employee EmployeeRecord = record.value();System.out.printf("%s %d %d %s \n", record.topic(),record.partition(), record.offset(), EmployeeRecord);});});}
    }

     

确保,我们必须告诉消费者在哪里找到注册表,与生产者一样,我们必须配置Kafka Avro反序列化器。

  • 为消费者配置架构注册表:
  1. //Use Kafka Avro Deserializer.
    props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG,KafkaAvroDeserializer.class.getName());
    //Use Specific Record or else you get Avro GenericRecord.
    props.put(KafkaAvroDeserializerConfig.SPECIFIC_AVRO_READER_CONFIG, "true");
    //Schema registry location.        props.put(KafkaAvroDeserializerConfig.SCHEMA_REGISTRY_URL_CONFIG,"http://localhost:8081"); //<----- Run Schema Registry on 8081

     

此外,使用生成的Employee对象版本。因为,如果我们没有,而不是我们生成的Employee对象,那么它将使用Avro GenericRecord,这是一个SpecificRecord。
而且,我们需要启动Kafka和ZooKeeper,运行上面的例子:

  • 运行ZooKeeper和Kafka:
  1. kafka/bin/zookeeper-server-start.sh kafka/config/zookeeper.properties &
    kafka/bin/kafka-server-start.sh kafka/config/server.properties

     

所以,这完全是关于Kafka Schema Registry的。希望你喜欢我们的解释。
体验最好的Apache Kafka Quiz Part-1 | 准备迎接挑战

10.结论

因此,我们看到Kafka Schema Registry为Kafka消费者和Kafka生产商管理Avro Schemas。此外,Avro还提供模式迁移,这对于流式传输和大数据架构非常重要。因此,我们已经向Kafka Schema Registry学习了整个概念。在这里,我们讨论了Kafka中Schema注册表的需求。

此外,我们还学习了模式注册表操作和兼容性设置。最后,我们看到了Kafka Avro Schema并使用了Schema Registry Rest API。最后,我们转向使用Schema注册表和Avro Serialization编写Kafka使用者和生产者

转载于:https://www.cnblogs.com/a00ium/p/10853032.html

这篇关于Kafka Schema Registry | 学习Avro Schema的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/213921

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

搭建Kafka+zookeeper集群调度

前言 硬件环境 172.18.0.5        kafkazk1        Kafka+zookeeper                Kafka Broker集群 172.18.0.6        kafkazk2        Kafka+zookeeper                Kafka Broker集群 172.18.0.7        kafkazk3

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

线性代数|机器学习-P36在图中找聚类

文章目录 1. 常见图结构2. 谱聚类 感觉后面几节课的内容跨越太大,需要补充太多的知识点,教授讲得内容跨越较大,一般一节课的内容是书本上的一章节内容,所以看视频比较吃力,需要先预习课本内容后才能够很好的理解教授讲解的知识点。 1. 常见图结构 假设我们有如下图结构: Adjacency Matrix:行和列表示的是节点的位置,A[i,j]表示的第 i 个节点和第 j 个