【大数据学习 | kafka】kafka的偏移量管理

news2024/11/7 5:57:46

1. 偏移量的概念

消费者在消费数据的时候需要将消费的记录存储到一个位置,防止因为消费者程序宕机而引起断点消费数据丢失问题,下一次可以按照相应的位置从kafka中找寻数据,这个消费位置记录称之为偏移量offset。

kafka0.9以前版本将偏移量信息记录到zookeeper中

新版本中偏移量信息记录在__consumer_offsets中,这个topic是系统生成的,不仅仅帮助管理偏移量信息还能分配consumer给哪个coordinator管理,是一个非常重要的topic

它的记录方式和我们知道的记录方式一样 groupid + topic + partition ==> offset

其中存储到__consumer_offsets中的数据格式也是按照k-v进行存储的,其中k是groupid + topic + partition
value值为offset的偏移量信息。

[hexuan@hadoop106 ~]$ kafka-topics.sh --bootstrap-server hadoop106:9092 --list
__consumer_offsets
topic_a
topic_b
topic_c
topic_e
topic_f
topic_g

可以看到系统生成的topic

因为之前我们消费过很多数据,现在可以查看一下记录在这个topic中的偏移量信息

其中存在一个kafka-consumer-groups.sh 命令

# 查看消费者组信息
kafka-consumer-groups.sh --bootstrap-server hadoop106:9092 --list
# 查询具体信息
kafka-consumer-groups.sh --bootstrap-server hadoop106:9092 --describe --group my-group
# 查看活跃信息
kafka-consumer-groups.sh --bootstrap-server hadoop106:9092 --describe --group my-group --members

查看消费者组信息:

[hexuan@hadoop106 ~]$ kafka-consumer-groups.sh --bootstrap-server hadoop106:9092 --list
hainiu_group
hainiu_group2

当前使用组信息:

[hexuan@hadoop106 ~]$ kafka-consumer-groups.sh --bootstrap-server hadoop106:9092 --describe --group hainiu_group

GROUP           TOPIC           PARTITION  CURRENT-OFFSET  LOG-END-OFFSET  LAG             CONSUMER-ID                                                  HOST            CLIENT-ID
hainiu_group    topic_c         0          0               0               0               consumer-hainiu_group-1-41a9ebd6-99a3-4d83-b1d7-88a2a9295054 /192.168.154.1  consumer-hainiu_group-1
hainiu_group    topic_b         1          1438            1438            0               -                                                            -               -
hainiu_group    topic_b         0          1440            1440            0               -                                                            -               -
hainiu_group    topic_b         3          1417            1417            0               -                                                            -               -
hainiu_group    topic_b         4          1473            1473            0               -                                                            -               -
hainiu_group    topic_b         5          1440            1440            0               -                                                            -               -
hainiu_group    topic_b         2          1407            1407            0               -                                                            -               -
hainiu_group    topic_b         6          1391            1391            0               -  

当前组消费偏移量信息:

GROUP:组名 
TOPIC:topic信息           
PARTITION:分区  
CURRENT-OFFSET:当前消费偏移量  
LOG-END-OFFSET:这个分区总共存在多少数据  
LAG:还差多少没消费             
CONSUMER-ID:随机消费者id                                                  
HOST:主机名            
CLIENT-ID:客户端id

同时我们也可以查询__consumer_offset中的原生数据:

kafka-console-consumer.sh  --bootstrap-server hadoop106:9092 \
--topic __consumer_offsets --from-beginning --formatter \
kafka.coordinator.group.GroupMetadataManager\$OffsetsMessageFormatter

使用元数据格式化方式查看偏移量信息数据

key展示的是groupid,topic,partition ,  value值展示的是当前的偏移量信息

并且在这个topic中是追加形式一致往里面写入的

2. 偏移量的自动管理

那么我们已经看到了偏移量的存储但是偏移量究竟是怎么提交的呢?

首先我们没有设置任何的偏移量提交的代码,这个是默认开启的,其中存在两个参数

pro.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, true);
//开启自动提交偏移量信息
pro.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG, 5000);
//默认提交间隔5s

官网的设置参数为两个true和5000。

所以我们在没有开启默认提交的时候已经自动提交了

为了演示自动提交的效果我们引入一个参数

auto.offset.reset

这个参数用于控制没有偏移量存储的时候,应该从什么位置进行消费数据

(因为偏移量自动提交默认是5秒一次,如果数据在5秒内消费完毕,则会造成偏移量并没有存储的情况)

其中参数值官网中给出三个

[latest, earliest, none]

latest:从最新位置消费

earliest:最早位置消费数据

none:如果不指定消费的偏移量直接报错

一定要记得一点,如果有偏移量信息那么以上的设置是无效的.

官方文档显示给出的该参数的默认值为lastest,即从最新位置开始消费。

现在我们设置读取位置为最早位置,并且消费数据,看看可不可以记录偏移量,断点续传

思路:

首先修改组id为一个新的组,然后从最早位置消费数据,如果记录了偏移量,那么重新启动消费者会看到,没有任何数据,因为之前记录了消费数据的位置

整体代码如下:

package com.hainiu.kafka;

import org.apache.kafka.clients.consumer.*;
import org.apache.kafka.common.TopicPartition;
import org.apache.kafka.common.serialization.StringDeserializer;

import java.time.Duration;
import java.util.*;

public class Consumer1 {
    public static void main(String[] args) {
        Properties pro = new Properties();
        pro.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG,"nn1:9092");
        pro.put(ConsumerConfig.GROUP_ID_CONFIG,"new_group");
        pro.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
        pro.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
        pro.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, true);
        pro.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
        pro.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG, 5000);

        KafkaConsumer<String, String> consumer = new KafkaConsumer<String, String>(pro);
        List<String> topics = Arrays.asList("topic_d","topic_e");
        consumer.subscribe(topics);

        while (true){
            ConsumerRecords<String, String> records = consumer.poll(Duration.ofSeconds(1));
            Iterator<ConsumerRecord<String, String>> it = records.iterator();
            while(it.hasNext()){
                ConsumerRecord<String, String> record = it.next();
                System.out.println(record.topic()+"->"+record.partition()+"->"+ record.offset()+"->"+record.key()+"->"+record.value());
            }
        }
    }
}

运行完毕打印数据

这个时候我们需要在5s之内关闭应用,然后重新启动,因为提交的间隔时间是5s

再次启动

我们发现数据依旧被消费出来了,证明之前的偏移量存储没有任何效果和作用,因为间隔时间是5s

现在我们等待5s后在关闭应用

发现没有任何数据产生,因为偏移量已经提交了

3. 偏移量的手动提交

如上的案例我们发现偏移量的管理如果交给系统自己管理,我们没有办法及时的修改和管理偏移量信息,这个时候我们需要手动来提交给管理偏移量,更加及时和方便

这个时候引入两个方法

consumer.commitAsync();
consumer.commitSync();

commitAsync 异步提交方式:只提交一次,不管成功与否不会重试

commitSync 同步提交方式:同步提交方式会一直提交到成功为止

一般我们都会选择异步提交方式,他们的功能都是将拉取到的一整批数据的最大偏移量直接提交到__consumer_offsets中,但是同步方式会很浪费资源,异步方式虽然不能保证稳定性但是我们的偏移量是一直递增存储的,所以偶尔提交不成功一个两个不影响我们的使用

 pro.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, false);
//设定自动提交为false
consumer.commitSync();
consumer.commitAsync();
//设定提交方式为手动提交

整体代码如下:

package com.hainiu.kafka.consumer;

/**
 * ClassName : consumer_offsets
 * Package : com.hainiu.kafka.consumer
 * Description
 *
 * @Author HeXua
 * @Create 2024/11/5 21:30
 * Version 1.0
 */

import org.apache.kafka.clients.consumer.*;
import org.apache.kafka.common.TopicPartition;
import org.apache.kafka.common.serialization.StringDeserializer;

import java.time.Duration;
import java.util.*;

public class Consumer_CommitSync {
    public static void main(String[] args) {
        Properties pro = new Properties();
        pro.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG,"hadoop106:9092");
        pro.put(ConsumerConfig.GROUP_ID_CONFIG,"hainiu_group2");
        pro.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
        pro.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
        pro.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, false);
        pro.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
//        pro.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG, 5000);

        KafkaConsumer<String, String> consumer = new KafkaConsumer<String, String>(pro);
        List<String> topics = Arrays.asList("topic_h");
        consumer.subscribe(topics);

        while (true){
            ConsumerRecords<String, String> records = consumer.poll(Duration.ofSeconds(1));
            Iterator<ConsumerRecord<String, String>> it = records.iterator();
            while(it.hasNext()){
                ConsumerRecord<String, String> record = it.next();
                System.out.println(record.topic()+"->"+record.partition()+"->"+ record.offset()+"->"+record.key()+"->"+record.value());
            }
            consumer.commitAsync();
//            consumer.commitSync();
        }
    }
}

现在先在topic中输入部分数据

然后启动消费者,当存在数据打印的时候马上关闭掉应用,在此启动会发现数据不会重新消费

topic_h->5->12->null->1
topic_h->5->13->null->2
topic_h->5->14->null->3
topic_h->5->15->null->4
topic_h->5->16->null->5
topic_h->5->17->null->6

偏移量已经提交不会重复消费数据

4. 断点消费数据

在没有偏移量的时候我们可以设定

auto.offset.reset进行数据的消费

可选参数有 latest earliest none等位置

但是如果存在偏移量以上的设定就不在好用了,我们需要根据偏移量的位置进行断点消费数据

但是有的时候我们需要指定位置消费相应的数据

这个时候我们需要使用到

consumer.seek();
//可以指定位置进行数据的检索

但是我们不能随意的指定消费者消费数据的位置,因为在启动消费者的时候,一个组中会存在多个消费者,每个人拿到的对应分区是不同的,所以我们需要知道这个消费者能够获取的分区是哪个,然后再指定相应的断点位置

这里我们就需要监控分区的方法展示出来所有订阅的分区信息

 consumer.subscribe(topics, new ConsumerRebalanceListener() {
            @Override
            public void onPartitionsRevoked(Collection<TopicPartition> partitions) {

            }

            @Override
            public void onPartitionsAssigned(Collection<TopicPartition> partitions) {

            }
        });

为了演示效果我们使用生产者在topic_d中增加多个消息

package com.hainiu.kafka.consumer;

/**
 * ClassName : Producer2
 * Package : com.hainiu.kafka.consumer
 * Description
 *
 * @Author HeXua
 * @Create 2024/11/5 23:01
 * 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.StringSerializer;

import java.util.Properties;

public class Producer2 {
    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());
        KafkaProducer<String, String> producer = new KafkaProducer<String, String>(pro);
        for (int i = 0; i < 1000; i++) {
            ProducerRecord<String, String> record = new ProducerRecord<String, String>("topic_d", "" + i, "message"+i);
            producer.send(record);
        }
        producer.close();
    }
}

随机发送数据到不同的节点,使用随机key

然后使用断点消费数据

不设置任何的偏移量提交操作和断点位置

package com.hainiu.kafka.consumer;

/**
 * ClassName : ConsumerWithUDOffset
 * Package : com.hainiu.kafka.consumer
 * Description
 *
 * @Author HeXua
 * @Create 2024/11/5 23:03
 * Version 1.0
 */
import org.apache.kafka.clients.consumer.*;
import org.apache.kafka.common.TopicPartition;
import org.apache.kafka.common.serialization.StringDeserializer;

import java.time.Duration;
import java.util.*;

public class ConsumerWithUDOffset {
    public static void main(String[] args) {
        Properties pro = new Properties();
        pro.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG,"hadoop106:9092");
        pro.put(ConsumerConfig.GROUP_ID_CONFIG,"new1");
        pro.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
        pro.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
        pro.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG,"earliest");
        pro.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG,6000);
        pro.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG,false);

        KafkaConsumer<String, String> consumer = new KafkaConsumer<String, String>(pro);
        List<String> topics = Arrays.asList("topic_h");
        // range roundRobin sticky cooperativeSticky
        consumer.subscribe(topics, new ConsumerRebalanceListener() {
            @Override
            public void onPartitionsRevoked(Collection<TopicPartition> collection) {

            }

            @Override
            public void onPartitionsAssigned(Collection<TopicPartition> collection) {
                for (TopicPartition topicPartition : collection) {
                    consumer.seek(topicPartition,195);
                }
            }
        });

        while (true){
            ConsumerRecords<String, String> records = consumer.poll(Duration.ofSeconds(1));
            Iterator<ConsumerRecord<String, String>> it = records.iterator();
            while(it.hasNext()){
                ConsumerRecord<String, String> record = it.next();
                System.out.println(record.topic()+"->"+record.partition()+"->"+ record.offset()+"->"+record.key()+"->"+record.value());
            }
            consumer.commitAsync();
        }
    }
}

5. 时间断点

kafka没有给大家提供直接根据时间找到断点位置的方法,我们需要根据时间找到偏移量,然后根据偏移量进行数据消费

consumer.offsetsForTimes();
//通过这个方法找到对应时间的偏移量位置
consumer.seek();
//然后在通过这个方法根据断点进行消费数据

整体代码如下

package com.hainiu.kafka;

import org.apache.kafka.clients.consumer.*;
import org.apache.kafka.common.TopicPartition;
import org.apache.kafka.common.serialization.StringDeserializer;

import java.time.Duration;
import java.util.*;

public class Consumer1 {
    public static void main(String[] args) {
        Properties pro = new Properties();
        pro.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG,"nn1:9092");
        pro.put(ConsumerConfig.GROUP_ID_CONFIG,"new_group221");
        pro.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
        pro.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
        pro.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG,false);

        KafkaConsumer<String, String> consumer = new KafkaConsumer<String, String>(pro);
        List<String> topics = Arrays.asList("topic_e");
        consumer.subscribe(topics, new ConsumerRebalanceListener() {
            @Override
            public void onPartitionsRevoked(Collection<TopicPartition> partitions) {
                // no op
            }

            @Override
            public void onPartitionsAssigned(Collection<TopicPartition> partitions) {
                HashMap<TopicPartition, Long> map = new HashMap<>();
                for (TopicPartition partition : partitions) {
                    map.put(partition,1675076400000L);
                    //将时间和分区绑定在一起,然后合并在一起放入到检索方法中
                }
                Map<TopicPartition, OffsetAndTimestamp> offsets = consumer.offsetsForTimes(map);
                //根据时间获取时间对应的偏移量位置
                for (Map.Entry<TopicPartition, OffsetAndTimestamp> en : offsets.entrySet()) {
                    System.out.println(en.getKey()+"-->"+en.getValue());
                    if(en.getValue() != null){
                        consumer.seek(en.getKey(),en.getValue().offset());
                        //获取每个分区的偏移量的位置,使用seek进行找寻数据
                    }
                }

            }
        });

        while (true){
            ConsumerRecords<String, String> records = consumer.poll(Duration.ofSeconds(1));
            Iterator<ConsumerRecord<String, String>> it = records.iterator();
            while(it.hasNext()){
                ConsumerRecord<String, String> record = it.next();
                System.out.println(record.topic()+"->"+record.partition()+"->"+ record.offset()+"->"+record.key()+"->"+record.value());
            }
//            consumer.commitAsync();
        }
    }
}

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

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

相关文章

专业 UI 设计公司:为您开启交互设计新征程

在当今数字化时代&#xff0c;UI设计不仅是产品外观的呈现&#xff0c;更是用户体验的核心组成部分。专业的UI设计公司凭借其深厚的设计底蕴、前沿的设计理念以及丰富的项目经验&#xff0c;能够为企业开启全新的交互设计征程&#xff0c;提升产品的市场竞争力。以下是对一家专…

【神经科学学习笔记】基于分层嵌套谱分割(Nested Spectral Partition)模型分析大脑网络整合与分离的学习总结

一、前言 1.学习背景 最近在学习脑网络分析方法时&#xff0c;笔者偶然读到了一篇发表在Physical Review Letters上的文章&#xff0c;文章介绍了一种名为嵌套谱分割(Nested-Spectral Partition, NSP)的方法&#xff0c;用于研究大脑功能网络的分离和整合特性。 传统的脑网络分…

初识C++(上) -- C++的关键字、命名空间、缺省参数以及函数的重载

目录 一、C的关键字&#xff08;C98&#xff09; 二、命名空间 1、命名冲突 2、命名空间 2.1 命名空间的定义 (1). 命名空间定义的例子以及命名空间的嵌套&#xff1a; (2). 同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中&#xff1a; 2…

计算机网络socket编程(1)_UDP网络编程实现echo server

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 计算机网络socket编程(1)_UDP网络编程实现echo server 收录于专栏【计算机网络】 本专栏旨在分享学习计算机网络的一点学习笔记&#xff0c;欢迎大家在评论区交…

[安洵杯 2019]easy_web 详细题解

知识点: 编码转换 命令执行 linux空格_关键字绕过 打开页面 发现url 是 /index.php?imgTXpVek5UTTFNbVUzTURabE5qYz0&cmd 有img参数和cmd参数 cmd参数是没赋值的,随便赋值为123456 页面没有反应 鼠标移动到图片下面时发现有东西,当然直接查看页面源代码也可以发现 尝…

免费,基于React + ECharts 国产开源 IoT 物联网 Web 可视化数据大屏

文末查看开源项目地址 Light Chaser 是一款国产开源免费的基于 React18、Vite5、TypeScript5 技术栈实现的 Web 可视化大屏设计工具&#xff0c;支持Docker方式部署&#xff0c;支持MySQL、PostgreSQL、SQL Server、Oracle 数据源。 你可以简单快速地搭建数据可视化展示、数据报…

Linux服务管理-DHCP

DHCP DHCP&#xff08;Dynamic Host Configuration Protocol&#xff0c;动态主机配置协议&#xff09;是一个局域网的网络协议&#xff0c;它允许服务器自动地将IP地址和其他网络配置参数分配给网络中的计算机。DHCP极大地简化了网络管理&#xff0c;尤其是当大量设备需要接入…

如何使用Netdata部署高性能的服务器监控平台

简介 Netdata 是一个开源的、实时的性能和健康监控工具&#xff0c;专为系统、应用程序、SNMP 设备等而设计。它以其高度交互的 Web 仪表板和极低的资源开销而闻名。 主要特点&#xff1a;实时监控、全面监控、零配置、轻量级、交互式仪表板、可扩展性、警报和通知、分布式监…

【MySQL】深度学习与解析 : 库的操作知识整合

前言&#xff1a;本节内容是MySQL库的操作&#xff0c; 内容较少&#xff0c; 大体内容为创建库、删除库、修改库、库备份操作。 ps:本节内容适合安装了MySQL的友友们进行观看&#xff0c; 实操更有利于记住哦。 目录 创建数据库 查看数据库列表 创建数据库 删除数据库 …

计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-11-01

计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-11-01 目录 文章目录 计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-11-01目录1. A Perspective for Adapting Generalist AI to Specialized Medical AI Applications and Their Challenges2. Synergi…

白杨SEO:百度在降低个人备案类网站搜索关键词排名和流量?怎样应对?【参考】

很久没有写百度或者网站这块内容了&#xff0c;一是因为做百度网站朋友越来越少&#xff0c;不管是个人还是企业&#xff1b;二是百度上用户搜索与百度给到网站的流量都越来越少。 为什么想到今天又来写这个呢&#xff1f;因为上个月有个朋友来咨询我说网站百度排名全没了&…

5分钟科普:AI网关是什么?应用场景是什么?有没有开源的选择?

AI网关的功能及其定义 AI网关位于企业应用与内外部大模型调用的交汇点&#xff0c;能够灵活地将请求转发给内部自建模型或外部大模型服务提供商&#xff0c;甚至海外的服务商。它管理着企业所有的AI出口流量&#xff0c;为企业内的不同团队提供了多方面的优势。 对于开发团队…

Java学习Day60:微服务总结!(有经处无火,无火处无经)

1、技术版本 jdk&#xff1a;17及以上 -如果JDK8 springboot&#xff1a;3.1及其以上 -版本2.x springFramWork&#xff1a;6.0及其以上 -版本5.x springCloud&#xff1a;2022.0.5 -版本格林威治或者休斯顿 2、模拟springcloud 父模块指定父pom <parent><…

登录功能设计(php+mysql)

一 登录功能 1. 创建一个登录页面&#xff08;login.php&#xff09;&#xff0c;包含一个表单&#xff0c;用户输入用户名和密码。 2. 在表单的提交事件中&#xff0c;使用PHP代码处理用户输入的用户名和密码。 3. 首先&#xff0c;连接MySQL数据库。然后&a…

【物联网技术】ESP8266 WIFI模块STA、AP、STA+AP、TCP/UDP透传工作模式介绍与AT指令介绍

前言:本文对ESP8266 WIFI模块STA、AP、STA+AP、TCP/UDP透传工作模式进行介绍;以及AT指令介绍,包括基础AT指令,WIFI功能AT指令、TCP/IP相关AT指令、常用AT指令实例进行介绍。 ESP8266 WIFI模块的接线及固件烧写可参考我的这篇博客:正点原子ATK-ESP8266 WIFI模块接线及固件…

【前端】JavaScript 方法速查大全-函数、正则、格式化、转换、进制、 XSS 转义(四)

&#x1f525; 前言 在现代前端开发中&#xff0c;JavaScript 是不可或缺的语言。无论是处理数据、操作 DOM&#xff0c;还是进行复杂的逻辑运算&#xff0c;掌握 JavaScript 的各种方法都是每位开发者的必修课。本文将为您提供一个全面、系统的 JavaScript 方法参考&#xff…

关于路由笔记

路由 定义&#xff1a; 在计算机网络中&#xff0c;路由是将数据包从源节点传输到目标节点的过程。这个过程涉及到网络中的多个设备&#xff0c;如路由器、交换机等&#xff0c;其中路由器起着关键的决策作用。 工作原理示例&#xff1a; 假设你在一个公司的局域网内&#…

25.停车场管理系统(基于web的Java项目)

目录 1.系统的受众说明 2.相关技术与方法 3.系统分析 3.1 可行性分析 3.1.1 技术可行性 3.1.2 经济可行性 3.1.3 操作可行性 3.2 需求分析 3.2.1 系统功能描述 3.2.2 用例图分析 4. 系统设计 4.1 系统类分析 5. 系统详细设计与实现 5.1 用户登录 5.2 系统信…

【含开题报告+文档+源码】基于SpringBoot+Vue智能居民健康检测系统设计与实现

开题报告 随着社会发展和人民生活水平的提高&#xff0c;人们对健康生活的要求越来越高。而广大居民由于条件限制&#xff0c;存在着健康管理服务不足的问题。本文基于JavaWeb技术&#xff0c;设计并实现了一种居民健康检测系统。首先&#xff0c;本文对该平台的需求进行了分析…

SCNU习题 总结与复习

1. P1:构建最大二叉树 【分治】 重点 构树函数需要注意的点&#xff1b; 前序遍历需要注意&#xff0c;本题的输出有点特点。若一个结点无左子&#xff0c;无右子就不再下去遍历&#xff1b; 其他情况都要下去遍历&#xff1b; 2. P2 寻找多数【分治】 没啥&#xff0c;注意…