【大数据学习 | kafka】producer之拦截器,序列化器与分区器

1. 自定义拦截器

interceptor是拦截器,可以拦截到发送到kafka中的数据进行二次处理,它是producer组成部分的第一个组件。

public static class MyInterceptor implements ProducerInterceptor<String,String>{@Overridepublic ProducerRecord<String, String> onSend(ProducerRecord<String, String> record) {return null;}@Overridepublic void onAcknowledgement(RecordMetadata metadata, Exception exception) {}@Overridepublic void close() {}@Overridepublic void configure(Map<String, ?> configs) {}}

实现拦截器需要实现ProducerInterceptor这个接口,其中的泛型要和producer端发送的数据的类型一致。

onSend方法是最主要的方法用户拦截数据并且处理完毕发送
onAcknowledgement 获取确认应答的方法,这个方法和producer端的差不多,只能知道结果通知
close是执行完毕拦截器最后执行的方法
configure方法是用于获取配置文件信息的方法

我们拦截器的实现基于场景是获取到producer端的数据然后给数据加上时间戳。

整体代码如下:

package com.hainiu.kafka.producer;/*** ClassName : producer_intercepter* Package : com.hainiu.kafka.producer* Description** @Author HeXua* @Create 2024/10/31 22:56* Version 1.0*/import org.apache.kafka.clients.producer.*;
import org.apache.kafka.common.serialization.StringSerializer;import java.util.Date;
import java.util.Map;
import java.util.Properties;public class producer_intercepter {public static class MyInterceptor implements ProducerInterceptor<String,String>{@Overridepublic ProducerRecord<String, String> onSend(ProducerRecord<String, String> record) {String value = record.value();Long time = new Date().getTime();String topic = record.topic();//获取原始数据并且构建新的数据,增加时间戳信息return new ProducerRecord<String,String>(topic,time+"-->"+value);}@Overridepublic void onAcknowledgement(RecordMetadata metadata, Exception exception) {//获取确认应答和producer端的代码逻辑相同String topic = metadata.topic();int partition = metadata.partition();long offset = metadata.offset();if(exception == null ){System.out.println("success"+" "+topic+" "+partition+" "+offset);}else{System.out.println("fail"+" "+topic+" "+partition+" "+offset);}}@Overridepublic void close() {//不需要任何操作//no op}@Overridepublic void configure(Map<String, ?> configs) {//不需要任何操作//no op}}public static void main(String[] args) {Properties pro = new Properties();pro.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,"hadoop106:9092");pro.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());pro.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());pro.put(ProducerConfig.ACKS_CONFIG, "all");pro.put(ProducerConfig.RETRIES_CONFIG,3 );pro.put(ProducerConfig.BATCH_SIZE_CONFIG, 16*1024);pro.put(ProducerConfig.LINGER_MS_CONFIG, 0);pro.put(ProducerConfig.INTERCEPTOR_CLASSES_CONFIG,MyInterceptor.class.getName());//设定拦截器KafkaProducer<String, String> producer = new KafkaProducer<String, String>(pro);ProducerRecord<String, String> record = new ProducerRecord<>("topic_a", "this is hainiu");for(int i=0;i<5;i++){producer.send(record, new Callback() {@Overridepublic void onCompletion(RecordMetadata metadata, Exception exception) {String topic = metadata.topic();int partition = metadata.partition();long offset = metadata.offset();if(exception == null ){System.out.println("success"+" "+topic+" "+partition+" "+offset);}else{System.out.println("fail"+" "+topic+" "+partition+" "+offset);}}});}producer.close();}
}

ack返回的元数据信息。

success topic_a 0 17
success topic_a 0 17
success topic_a 0 18
success topic_a 0 18
success topic_a 0 19
success topic_a 0 19
success topic_a 0 20
success topic_a 0 20
success topic_a 0 21
success topic_a 0 21

查看consumer端消费的数据。

f287b3bf12054f0bbeea073f9b3dcd66.png

在客户端消费者中可以打印出来信息带有时间戳。

拦截器一般很少人为定义,比如一般producer在生产环境中都是有flume替代,一般flume会设定自己的时间戳拦截器,指定数据采集时间,相比producer更加方便实用。

2. 自定义序列化器

kafka中的数据存储是二进制的byte数组形式,所以我们在存储数据的时候要使用序列化器进行数据的转换,序列化器的结构要和存储数据的kv的类型一致。

比如我们要实现系统的String类型序列化器。

2.1 实现String类型的序列化器

package com.hainiu.kafka.producer;/*** ClassName : producer_String_Serializer* Package : com.hainiu.kafka.producer* Description** @Author HeXua* @Create 2024/10/31 23:12* Version 1.0*/
import org.apache.kafka.clients.producer.*;
import org.apache.kafka.common.serialization.Serializer;
import org.apache.kafka.common.serialization.StringSerializer;import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Properties;public class producer_String_Serializer {public static void main(String[] args) {Properties pro = new Properties();//bootstrap-server key value batch-size linger.ms ack retries interceptorpro.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,"hadoop106:9092");// 自定义生产记录的key和value的序列化器pro.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, MyStringSerializer.class.getName());pro.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, MyStringSerializer.class.getName());pro.put(ProducerConfig.BATCH_SIZE_CONFIG,16*1024);pro.put(ProducerConfig.LINGER_MS_CONFIG,0);pro.put(ProducerConfig.ACKS_CONFIG,"all");pro.put(ProducerConfig.RETRIES_CONFIG,3);KafkaProducer<String, String> producer = new KafkaProducer<String, String>(pro);for (int i = 0; i < 100; i++) {ProducerRecord<String, String> record = new ProducerRecord<>("topic_a", "hainiu","message_" + i);producer.send(record);}producer.close();}public static class MyStringSerializer implements Serializer<String>{@Overridepublic byte[] serialize(String topic, String data) {return data.getBytes(StandardCharsets.UTF_8);}}
}

消费者消费数据:

message_0
message_1
message_2
message_3
message_4
message_5
message_6
message_7
message_8
message_9
message_10
message_11
message_12
..........

2.2 序列化对象整体

package com.hainiu.kafka.producer;/*** ClassName : producer_Student_Serializer* Package : com.hainiu.kafka.producer* Description** @Author HeXua* @Create 2024/10/31 23:20* Version 1.0*/import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.common.serialization.Serializer;
import org.apache.kafka.common.serialization.StringSerializer;import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.nio.charset.StandardCharsets;
import java.util.Properties;/*** producerRecord==> key:string,value:student*/
public class producer_Student_Serializer {public static class Student implements Serializable{private int id;private String name;private int age;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public Student() {}public Student(int id, String name, int age) {this.id = id;this.name = name;this.age = age;}}public static class MyStudentSerializer implements Serializer<Student>{//        ByteArrayOutputStream
//        ObjectOutputStream@Overridepublic byte[] serialize(String topic, Student data) {ByteArrayOutputStream byteOS = null;ObjectOutputStream objectOS = null;try {byteOS =new ByteArrayOutputStream();objectOS = new ObjectOutputStream(byteOS);objectOS.writeObject(data);} catch (IOException e) {throw new RuntimeException(e);}finally {try {byteOS.close();objectOS.close();} catch (IOException e) {throw new RuntimeException(e);}}return byteOS.toByteArray();}}public static void main(String[] args) {Properties pro = new Properties();//bootstrap-server key value batch-size linger.ms ack retries interceptorpro.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,"hadoop106:9092");pro.put(ProducerConfig.BATCH_SIZE_CONFIG,16*1024);pro.put(ProducerConfig.LINGER_MS_CONFIG,0);pro.put(ProducerConfig.ACKS_CONFIG,"all");pro.put(ProducerConfig.RETRIES_CONFIG,3);pro.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());pro.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,MyStudentSerializer.class.getName());KafkaProducer<String, Student> producer = new KafkaProducer<>(pro);Student s1 = new Student(1, "zhangsan", 20);Student s2 = new Student(2, "lisi", 30);ProducerRecord<String, Student> r1 = new ProducerRecord<>("topic_a", "hainiu", s1);ProducerRecord<String, Student> r2 = new ProducerRecord<>("topic_a", "hainiu", s2);producer.send(r1);producer.send(r2);producer.close();}

消费的数据:

[hexuan@hadoop107 kafka]$ kafka-console-consumer.sh --bootstrap-server hadoop106:9092 --topic topic_a
¬첲=com.hainiu.kafka.producer.producer_Student_Serializer$Student8Ӯ¥ClOIageIidLnametLjava/lang/String;xpzhangsan
¬첲=com.hainiu.kafka.producer.producer_Student_Serializer$Student8Ӯ¥ClOIageIidLnametLjava/lang/String;xptlisi
XshellXshell

2.3 序列化对象字段信息

比如我们想要发送一个Student对象,其中包含id name age等字段,这个数据需要对应的序列化器

序列化器的实现需要指定类型并且实现。

需要实现serializer接口,并且实现serialize的方法用于将数据对象转换为二进制的数组

整体代码如下:

package com.hainiu.kafka.producer;/*** ClassName : producer_Student_Serializer2* Package : com.hainiu.kafka.producer* Description** @Author HeXua* @Create 2024/10/31 23:30* Version 1.0*/
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.common.serialization.Serializer;
import org.apache.kafka.common.serialization.StringSerializer;import java.nio.charset.Charset;
import java.util.Properties;public class producer_Student_Serializer2 {public static void main(String[] args) {Properties pro = new Properties();pro.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,"hadoop106:9092");pro.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());//key因为没有放入任何值,所以序列化器使用原生的就可以pro.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StudentSeria.class.getName());//value的序列化器需要指定相应的student序列化器pro.put(ProducerConfig.BATCH_SIZE_CONFIG, 16*1024);pro.put(ProducerConfig.LINGER_MS_CONFIG, 0);KafkaProducer<String, Student> producer = new KafkaProducer<String, Student>(pro);//producer生产的数据类型也必须是string,student类型的kvStudent student = new Student(1, "zhangsan", 30);ProducerRecord<String, Student> record = new ProducerRecord<>("topic_a", student);producer.send(record);producer.close();}public static class Student{private int id;private String name;private int age;public int getId() {return id;}public Student() {}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public Student(int id, String name, int age) {this.id = id;this.name = name;this.age = age;}}public static class StudentSeria implements Serializer<Student> {@Overridepublic byte[] serialize(String topic, Student data) {String line =data.getId()+" "+data.getName()+" "+data.getAge();//获取student对象中的所有数据信息return line.getBytes(Charset.forName("utf-8"));//转换为byte数组返回}}
}

消费者消费数据:

[hexuan@hadoop107 kafka]$ kafka-console-consumer.sh --bootstrap-server hadoop106:9092 --topic topic_a
1 zhangsan 30

3. 分区器

首先在kafka存储数据的时候topic中的数据是分为多个分区进行存储的,topic设定分区的好处是可以进行分布式存储和分布式管理,那么好的分区器可以让数据尽量均匀的分布到不同的机器节点,数据更加均匀,那么kafka中的分区器是如果实现的呢?

2a56135210124f0bab06d60d1dfbbd20.png

根据图我们可以看出数据首先通过分区器进行分类在本地的累加器中进行存储缓存然后在复制到kafka集群中,所以分区器产生作用的位置在本地的缓存之前。

kafka的分区规则是如何实现的呢?

ProducerRecord<String, Student> record = new ProducerRecord<>("topic_a", student);
producer.send(record);

kafka的生产者数据发送是通过上面的方法实现的

首先要构造一个ProducerRecord对象,然后通过producer.send来进行发送数据。

其中ProducerRecord对象的构造器种类分为以下几种。

1. 构造器指定分区,包含key, value。

2. 构造器没有指定分区,但有key,有value。

3. 构造器只有value。

/*** Creates a record to be sent to a specified topic and partition** @param topic The topic the record will be appended to* @param partition The partition to which the record should be sent* @param key The key that will be included in the record* @param value The record contents*/
public ProducerRecord(String topic, Integer partition, K key, V value) {this(topic, partition, null, key, value, null);}/*** Create a record to be sent to Kafka* * @param topic The topic the record will be appended to* @param key The key that will be included in the record* @param value The record contents*/
public ProducerRecord(String topic, K key, V value) {this(topic, null, null, key, value, null);
}/*** Create a record with no key* * @param topic The topic this record should be sent to* @param value The record contents*/
public ProducerRecord(String topic, V value) {this(topic, null, null, null, value, null);
}

我们想要发送一个数据到kafka的时候可以构造以上的ProducerRecord但是构造的方式却不同,大家可以发现携带的参数也有所不同,当携带不同参数的时候数据会以什么样的策略发送出去呢,这个时候需要引入一个默认分区器,就是在用户没有指定任何规则的时候系统自带的分区器规则。

在ProducerConfig源码中看到:

public static final String PARTITIONER_CLASS_CONFIG = "partitioner.class";private static final String PARTITIONER_CLASS_DOC = "A class to use to determine which partition to be send to when produce the records. Available options are:" +"<ul>" +"<li>If not set, the default partitioning logic is used. " +"This strategy will try sticking to a partition until " + BATCH_SIZE_CONFIG + " bytes is produced to the partition. It works with the strategy:" +"<ul>" +"<li>If no partition is specified but a key is present, choose a partition based on a hash of the key</li>" +"<li>If no partition or key is present, choose the sticky partition that changes when " + BATCH_SIZE_CONFIG + " bytes are produced to the partition.</li>" +"</ul>" +"</li>" +"<li><code>org.apache.kafka.clients.producer.RoundRobinPartitioner</code>: This partitioning strategy is that " +"each record in a series of consecutive records will be sent to a different partition(no matter if the 'key' is provided or not), " +"until we run out of partitions and start over again. Note: There's a known issue that will cause uneven distribution when new batch is created. " +"Please check KAFKA-9965 for more detail." +"</li>" +"</ul>" +"<p>Implementing the <code>org.apache.kafka.clients.producer.Partitioner</code> interface allows you to plug in a custom partitioner.";

在producerConfig对象中我们可以看到源码指示,如果没有任何人为分区器规则指定,那么默认使用的DefaultPartitioner的规则.

package org.apache.kafka.clients.producer.internals;import org.apache.kafka.clients.producer.Partitioner;
import org.apache.kafka.common.Cluster;import java.util.Map;/*** NOTE this partitioner is deprecated and shouldn't be used.  To use default partitioning logic* remove partitioner.class configuration setting.  See KIP-794 for more info.** The default partitioning strategy:* <ul>* <li>If a partition is specified in the record, use it* <li>If no partition is specified but a key is present choose a partition based on a hash of the key* <li>If no partition or key is present choose the sticky partition that changes when the batch is full.* * See KIP-480 for details about sticky partitioning.*/
@Deprecated
public class DefaultPartitioner implements Partitioner {private final StickyPartitionCache stickyPartitionCache = new StickyPartitionCache();public void configure(Map<String, ?> configs) {}/*** Compute the partition for the given record.** @param topic The topic name* @param key The key to partition on (or null if no key)* @param keyBytes serialized key to partition on (or null if no key)* @param value The value to partition on or null* @param valueBytes serialized value to partition on or null* @param cluster The current cluster metadata*/public int partition(String topic, Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster) {return partition(topic, key, keyBytes, value, valueBytes, cluster, cluster.partitionsForTopic(topic).size());}/*** Compute the partition for the given record.** @param topic The topic name* @param numPartitions The number of partitions of the given {@code topic}* @param key The key to partition on (or null if no key)* @param keyBytes serialized key to partition on (or null if no key)* @param value The value to partition on or null* @param valueBytes serialized value to partition on or null* @param cluster The current cluster metadata*/public int partition(String topic, Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster,int numPartitions) {if (keyBytes == null) {return stickyPartitionCache.partition(topic, cluster);}return BuiltInPartitioner.partitionForKey(keyBytes, numPartitions);}public void close() {}/*** If a batch completed for the current sticky partition, change the sticky partition. * Alternately, if no sticky partition has been determined, set one.*/@SuppressWarnings("deprecation")public void onNewBatch(String topic, Cluster cluster, int prevPartition) {stickyPartitionCache.nextPartition(topic, cluster, prevPartition);}
}

而打开DefaultPartitioner以后可以看到他的分区器规则,就是在构建ProducerRecord的时候

new ProducerRecord(topic,partition,k,v);
//指定分区直接发送数据到相应分区中
new ProducerRecord(topic,k,v);
//没有指定分区就按照k的hashcode发送到不同分区
new ProducerRecord(topic,v);
//如果k和partition都没有指定就使用粘性分区

partition方法中,如果key为空就放入到粘性缓冲中,它的意思就是如果满足batch-size或者linger.ms就会触发应用执行,将数据复制到kafka中,并且再次随机到其他分区,所以简单来说粘性分区就是可一个分区放入数据,一旦满了以后才会改变分区,粘性分区规则使用主要是为了让每次复制数据更加快捷方便都赋值到一个分区中。

而如果key不为空那么就按照hashcode值进行取余处理。(哈希分区器)

总的来说就是分为默认分区分为三种情况:

1. 如果指定了分区,就复制到kafka集群指定的分区。

2. 如果没有指定分区,但又有key存在,那么将会对key求哈希值再取余。

即 key.hashCode()%numPartition,将得到一个数字,消息将会被复制到kafka集群的该数字对应的分区。

3. 如果没有指定分区,并且不存在key,只有value。那么我们会采用粘性分区策略。

即产生一个随机值k,并将没有key的记录都放入粘性缓冲,如果满足batch-size或者linger.ms就会触发应用执行,将粘性缓冲的消息复制到kafka集群随机一个分区。然后重复此步骤。

 

 

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

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

相关文章

基于Spring Boot的高校物品捐赠管理系统设计与实现,LW+源码+讲解

摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装高校物品捐赠管理系统软件来发挥其高效地信息处理的作用&a…

推荐FileLink数据跨网摆渡系统 — 安全、高效的数据传输解决方案

在数字化转型的浪潮中&#xff0c;企业对于数据传输的需求日益增加&#xff0c;特别是在不同网络环境之间的文件共享和传输。为了满足这一需求&#xff0c;FileLink数据跨网摆渡系统应运而生&#xff0c;为企业提供了一种安全、高效的数据传输解决方案。 安全第一&#xff0c;保…

C++_day2

目录 1. 引用 reference&#xff08;重点&#xff09; 1.1 基础使用 1.2 特性 1.3 引用参数 2. C窄化&#xff08;了解&#xff09; 3. 输入&#xff08;熟悉&#xff09; 4. string 字符串类&#xff08;掌握&#xff09; 4.1 基础使用 4.2 取出元素 4.3 字符串与数字转换 5. …

服务器数据恢复—RAID5阵列硬盘坏道掉线导致存储不可用的数据恢复案例

服务器存储数据恢复环境&#xff1a; 一台EqualLogic存储中有一组由16块SAS硬盘组建的RAID5阵列。上层划分了4个卷&#xff0c;采用VMFS文件系统&#xff0c;存放虚拟机文件。 服务器存储故障&#xff1a; 存储RAID5阵列中磁盘出现故障&#xff0c;有2块硬盘对应的指示灯亮黄灯…

25国考照片处理器使用流程图解❗

1、打开“国家公务员局”网站&#xff0c;进入2025公务员专题&#xff0c;找到考生考务入口 2、点击下载地址 3、这几个下载链接都可以 4、下载压缩包 5、解压后先看“使用说明”&#xff0c;再找到“照片处理工具”双击。 6、双击后会进入这样的界面&#xff0c;点击&…

2024年云手机推荐榜单:高性能云手机推荐

无论是手游玩家、APP测试人员&#xff0c;还是数字营销工作者&#xff0c;云手机都为他们带来了极大的便利。本文将为大家推荐几款在市场上表现优异的云手机&#xff0c;希望这篇推荐指南可以帮助大家找到最适合自己的云手机&#xff01; 1. OgPhone云手机 OgPhone云手机是一款…

浅谈RPC的实现原理与RPC实战

浅谈RPC的实现原理与RPC实战 什么是RPC?RPC框架基本原理gRPC框架介绍Http/2ProtoBuf gRPC实战一、创建项目二、导入依赖三、编写proto文件编写服务端编写客户端 什么是RPC? RPC(Remote Procedore Call)&#xff0c;及远程过程调用&#xff0c;是一种在分布式系统中用于进程间…

JeecgBoot入门

最近在了解低代码平台&#xff0c;其中关注到gitee上开源项目JeecgBoot&#xff0c;JeecgBoot官方也有比较完整的入门教学文档&#xff0c;这里我们将耕者官方教程学习&#xff0c;并将其记录下来。 一、项目简介 JeecgBoot 是一款基于代码生成器的低代码开发平台拥有零代码能力…

探索开源语音识别的未来:高效利用先进的自动语音识别技术20241030

&#x1f680; 探索开源语音识别的未来&#xff1a;高效利用自动语音识别技术 &#x1f31f; 引言 在数字化时代&#xff0c;语音识别技术正在引领人机交互的新潮流&#xff0c;为各行业带来了颠覆性的改变。开源的自动语音识别&#xff08;ASR&#xff09;系统&#xff0c;如…

.eslintrc.js 的解释

如果您的项目中没有 .eslintrc.js 文件&#xff0c;您可以按以下步骤创建并配置 ESLint&#xff1a; 1. 创建 ESLint 配置文件 在您的项目根目录下创建一个新的文件&#xff0c;命名为 .eslintrc.js。 2. 配置 ESLint 规则 在 .eslintrc.js 文件中添加以下内容&#xff0c;…

【Centos】在 CentOS 9 上使用 Apache 搭建 PHP 8 教程

在 CentOS 9 上使用 Apache 搭建 PHP 8 教程 1. 更新系统 确保你的系统是最新的&#xff1a; sudo dnf update2. 安装 EPEL 和 Remi 仓库 安装 Remi 仓库以获取 PHP 8&#xff1a; sudo dnf install epel-release sudo dnf install https://rpms.remirepo.net/enterprise/…

如何应对Oracle SQL语句的数据去重问题,应该考虑哪几个方面?

引言 在数据管理和数据库设计中,数据去重是一个重要的课题。随着信息技术的快速发展,数据的产生速度和数量都在急剧增加,如何有效地管理和维护这些数据成为了一个亟待解决的问题。 数据去重不仅可以减少存储空间的占用,还可以提高数据查询的效率,确保数据的准确性和一致…

Java基础语法①Java特点+环境安装+IDEA使用

目录 1. Java的概念和用途 1.1 Java的概念和发展史 1.2 Java的重要性 1.3 Java的特点 2. Java环境 2.1 JVM 和 JDK 2.2 Java环境安装 2.3 安装IntelliJ IDEA并使用 2.4 IntelliJ IDEA常见快捷键 2.4.1 普通快捷键 2.4.2 调试快捷键 2.4.3 代码生成快捷键 本篇完 写…

鸿蒙ArkTS中的面向对象编程

ArkTS是TypeScriptS的超集&#xff0c;而TS又是JavaScript的超集&#xff0c;意味着有JavaScript编程基础、结合一些TypeScript的使用经验就可以很快上手ArkTS。 作为一门面向对象语言的学习&#xff0c;了解和掌握这门语言的面向对象&#xff08;封装、继承、多态&#xff09;…

来了解一下!!!——React

React 是一个用于构建用户界面的 JavaScript 库&#xff0c;特别适合用于创建单页面应用程序&#xff08;SPA&#xff09;。它由 Facebook 维护&#xff0c;并且拥有一个活跃的社区&#xff0c;这使得 React 成为了目前最流行的前端框架之一。以下是关于 React 的一些重要信息和…

刷题(question)

Description 比赛之路多艰&#xff0c;做题方得提升。努力刷题的人在比赛中往往能取得很好的成绩&#xff0c;小红就是这样的人。 为了继续提升自己的编程实力&#xff0c;小红整理了一份刷题题单&#xff0c;并选中了题单中的 n 道编程题&#xff0c;将它们从 1 到 n 编号&a…

windows与windows文件共享

目录 基础设置主机共享文件端设置从机接受文件端设置 基础设置 1、先确保两台电脑直接能够ping通&#xff0c;这是文件共享的前提&#xff0c;如果ping不通就去查找对应的原因&#xff0c;一般都是防火墙的原因。 在ping通的情况下&#xff1a; 2、先找到高级共享设置 3、对专…

Unity3D 开发教程:从入门到精通

Unity3D 开发教程&#xff1a;从入门到精通 Unity3D 是一款强大的跨平台游戏引擎&#xff0c;广泛应用于游戏开发、虚拟现实、增强现实等领域。本文将详细介绍 Unity3D 的基本概念、开发流程以及一些高级技巧&#xff0c;帮助你从零基础到掌握 Unity3D 开发。 目录 Unity3D…

第二届新生程序设计竞赛热身赛(C语言)

A:饥饿的XP XP迷失在X星球&#xff0c;他醒来时已经很久很久很久没有吃过东西了。他突然发现身边有一张地图&#xff0c;上面有X星球上每一个食物供给点的位置。太好了&#xff0c;XP跳了起来。他决定先把肚子填饱再去寻找其他伙伴。现在已知XP的位置(X, Y)&#xff0c;以及他的…

[算法初阶]第二集 滑动窗口(已完结)

大家好啊,好久没有更新了,最近比较忙,所以来更新初阶算法,正好复习一下,感谢大家的观看,如有错误欢迎指出。 下面我们来看题目吧&#xff01; 1.209. 长度最小的子数组 这题大家想必一眼就看出了解法一暴力法 这个解法很简单 代码如下,不做多的解释 class Solution { publi…