【Kafka】超详细介绍

news2025/1/19 3:33:11

文章目录

  • 概念
  • 部署方案
    • 磁盘
    • 网络
    • CPU
    • partition的数量
  • 命令
    • 查看版本
    • 找kafka和zookeeper的ip/port
    • topic
      • 创建 topic
      • 查看
        • get topic 列表
        • get topic 详情
      • 修改topic
        • 修改分区级别参数(如增加partition)
      • 删除topic
        • 设置消息大小上限
    • 生产
      • 查看生产
      • 生产消息
    • 查看消费
      • server
    • 查看 offset
    • 查看积压
      • server
    • client has run out of available brokers to talk to (Is your cluster reachable?)报错的调试
  • 原理
  • UI 工具
  • go sarama库使用
    • consumer

概念

Kafka 是消息引擎(Messaging System),其是一组规范。企业利用这组规范在不同系统之间传递语义准确的消息,实现松耦合的异步式数据传递。

实现的目标,就是 系统A 发消息给 消息引擎,系统B 从消息引擎读取 A发送的消息。

Kafka 用二进制存储数据。其同时支持点对点模型、发布/订阅模型两种。

  • 点对点模型:也叫消息队列模型。如果拿上面那个“民间版”的定义来说,那么系统 A 发送的消息只能被系统 B 接收,其他任何系统都不能读取 A 发送的消息。日常生活的例子比如电话客服就属于这种模型:同一个客户呼入电话只能被一位客服人员处理,第二个客服人员不能为该客户服务。
  • 发布 / 订阅模型:与上面不同的是,它有一个主题(Topic)的概念,你可以理解成逻辑语义相近的消息容器。该模型也有发送方和接收方,只不过提法不同。发送方也称为发布者(Publisher),接收方称为订阅者(Subscriber)。和点对点模型不同的是,这个模型可能存在多个发布者向相同的主题发送消息,而订阅者也可能存在多个,它们都能接收到相同主题的消息。生活中的报纸订阅就是一种典型的发布 / 订阅模型。

消息引擎的作用:

  • 削峰填谷:缓冲上下游瞬时突发流量,使其更平滑。特别是对于那种发送能力很强的上游系统,如果没有消息引擎的保护,“脆弱”的下游系统可能会直接被压垮导致全链路服务“雪崩”。但是,一旦有了消息引擎,它能够有效地对抗上游的流量冲击,真正做到将上游的“峰”填满到“谷”中,避免了流量的震荡。
  • 发送方和接收方的松耦合,这也在一定程度上简化了应用的开发,减少了系统间不必要的交互。

名词术语如下:

  • 消息:Record。Kafka 是消息引擎嘛,这里的消息就是指 Kafka 处理的主要对象。
  • 主题:Topic。主题是承载消息的逻辑容器,在实际使用中多用来区分具体的业务。
  • 分区:Partition。一个有序不变的消息序列。每个主题下可以有多个分区。
  • 消息位移:Offset。表示分区中每条消息的位置信息,是一个单调递增且不变的值。
  • 副本:Replica。Kafka 中同一条消息能够被拷贝到多个地方以提供数据冗余,这些地方就是所谓的副本。副本还分为领导者副本和追随者副本,各自有不同的角色划分。副本是在分区层级下的,即每个分区可配置多个副本实现高可用。
  • 生产者:Producer。向主题发布新消息的应用程序。
  • 消费者:Consumer。从主题订阅新消息的应用程序。
  • 消费者位移:Consumer Offset。表征消费者消费进度,每个消费者都有自己的消费者位移。
  • 消费者组:Consumer Group。多个消费者实例共同组成的一个组,同时消费多个分区以实现高吞吐。
  • 重平衡:Rebalance。消费者组内某个消费者实例挂掉后,其他消费者实例自动重新分配订阅主题分区的过程。Rebalance 是 Kafka 消费者端实现高可用的重要手段。

在这里插入图片描述

Kafka的副本为何不允许对外提供服务?

  • 如果允许follower副本对外提供读服务(主写从读),首先会存在数据一致性的问题,消息从主节点同步到从节点需要时间,可能造成主从节点的数据不一致。主写从读无非就是为了减轻leader节点的压力,将读请求的负载均衡到follower节点,如果Kafka的分区相对均匀地分散到各个broker上,同样可以达到负载均衡的效果,没必要刻意实现主写从读增加代码实现的复杂程度

Consumer Group:

  • 在一个消费者组下,一个分区只能被一个消费者消费,但一个消费者可能被分配多个分区,因而在提交位移时也就能提交多个分区的位移。
  • 如果Consumer Group内 consumer的数量 > partition 的数量,则有一个消费者将无法分配到任何分区,处于idle状态。

Producer:

  • 如果producer指定了要发送的目标分区,消息自然是去到那个分区;否则就按照producer端参数partitioner.class指定的分区策略来定;如果你没有指定过partitioner.class,那么默认的规则是:看消息是否有key,如果有则计算key的murmur2哈希值%topic分区数;如果没有key,按照轮询的方式确定分区。

监控:

  • JMXTrans + InfluxDB + Grafana(推荐)
  • Kafka manager
  • kafka eagle

部署方案

磁盘

根据保留的消息数量,预估磁盘占用:

  • 新增消息数
  • 消息留存时间
  • 平均消息大小
  • 备份数
  • 是否启用压缩
假设你所在公司有个业务每天需要向 Kafka 集群发送 1 亿条消息,每条消息保存两份以防止数据丢失,另外消息默认保存两周时间。现在假设消息的平均大小是 1KB,那么你能说出你的 Kafka 集群需要为这个业务预留多少磁盘空间吗?

我们来计算一下:每天 1 亿条 1KB 大小的消息,保存两份且留存两周的时间,那么总的空间大小就等于 1 亿 * 1KB * 2 / 1000 / 1000 = 200GB。一般情况下 Kafka 集群除了消息数据还有其他类型的数据,比如索引数据等,故我们再为这些数据预留出 10% 的磁盘空间,因此总的存储容量就是 220GB。既然要保存两周,那么整体容量即为 220GB * 14,大约 3TB 左右。Kafka 支持数据的压缩,假设压缩比是 0.75,那么最后你需要规划的存储空间就是 0.75 * 3 = 2.25TB。

网络

根据QPS和带宽,预估服务器数量:(注意:业界带宽资源一般用Mbps而不是MBps衡量)

假设你公司的机房环境是千兆网络,即 1Gbps,现在你有个业务,其业务目标或 SLA 是在 1 小时内处理 1TB 的业务数据。那么问题来了,你到底需要多少台 Kafka 服务器来完成这个业务呢?

让我们来计算一下,由于带宽是 1Gbps,即每秒处理 1Gb 的数据,假设每台 Kafka 服务器都是安装在专属的机器上,也就是说每台 Kafka 机器上没有混布其他服务,毕竟真实环境中不建议这么做。通常情况下你只能假设 Kafka 会用到 70% 的带宽资源,因为总要为其他应用或进程留一些资源。

根据实际使用经验,超过 70% 的阈值就有网络丢包的可能性了,故 70% 的设定是一个比较合理的值,也就是说单台 Kafka 服务器最多也就能使用大约 700Mb 的带宽资源。

稍等,这只是它能使用的最大带宽资源,你不能让 Kafka 服务器常规性使用这么多资源,故通常要再额外预留出 2/3 的资源,即单台服务器使用带宽 700Mb / 3 ≈ 240Mbps。需要提示的是,这里的 2/3 其实是相当保守的,你可以结合你自己机器的使用情况酌情减少此值。

好了,有了 240Mbps,我们就可以计算 1 小时内处理 1TB 数据所需的服务器数量了。根据这个目标,我们每秒需要处理 2336Mb 的数据,除以 240,约等于 10 台服务器。如果消息还需要额外复制两份,那么总的服务器台数还要乘以 3,即 30 台。

CPU

通常情况下Kafka不太占用CPU,因此没有这方面的最佳实践出来。但有些情况下Kafka broker是很耗CPU的:

  1. server和client使用了不同的压缩算法;
  2. server和client版本不一致造成消息格式转换;3
  3. broker端解压缩校验

不过相比带宽资源,CPU通常都不是瓶颈

partition的数量

网上有一些分区制定的建议,我觉得这个粗粒度的方法就很好,值得一试:

  1. 首先你要确定你业务的SLA,比如说你希望你的producer TPS是10万条消息/秒,假设是T1
  2. 在你的真实环境中创建一个单分区的topic测试一下TPS,假设是T2
  3. 你需要的分区数大致可以等于T1 / T2

命令

2.2以上用–bootstrap-server, 2.2以下用–zookeeper

查看版本

cd kafka/libs
其中有kafka_2.12-2.8.0.jar,则版本为2.8.0

找kafka和zookeeper的ip/port

root@master~# kubectl get svc -n kafka -o wide
NAME        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)             AGE   SELECTOR
bootstrap   ClusterIP   10.109.83.55    <none>        9092/TCP            15d   app=kafka
broker      ClusterIP   None            <none>        9092/TCP            15d   app=kafka
outside-0   NodePort    10.108.34.0     <none>        32400:32400/TCP     15d   app=kafka,kafka-broker-id=0
outside-1   NodePort    10.104.65.215   <none>        32401:32401/TCP     15d   app=kafka,kafka-broker-id=1
outside-2   NodePort    10.99.118.241   <none>        32402:32402/TCP     15d   app=kafka,kafka-broker-id=2
pzoo        ClusterIP   None            <none>        2888/TCP,3888/TCP   15d   app=zookeeper,storage=persistent
zoo         ClusterIP   None            <none>        2888/TCP,3888/TCP   15d   app=zookeeper,storage=persistent-regional
zookeeper   ClusterIP   10.103.22.130   <none>        2181/TCP            15d   app=zookeeper

topic

  • 如果遇到client向某些topic建立producer时报错kafka: client has run out of available brokers to talk to (Is your cluster reachable?), 可以手动删掉topic再手动重建topic

创建 topic

./kafka-topics.sh --zookeeper 10.103.22.130:2181 --create --topic ttt1 --partitions 1 --replication-factor 1

查看

get topic 列表

./kafka-topics.sh  --list --bootstrap-server 192.168.2.165:9092
./kafka-topics.sh --zookeeper 10.103.22.130:2181/kafka --list

# out
__consumer_offsets
topic1
kafka-image-topic2

get topic 详情

./kafka-topics.sh --zookeeper 10.103.22.130:2181 --describe --topic topic-a

修改topic

修改分区级别参数(如增加partition)

./kafka-topics.sh --zookeeper 10.103.22.130:2181 --alter --topic ttt1 --partitions 2

## out
WARNING: If partitions are increased for a topic that has a key, the partition logic or ordering of the messages will be affected
Adding partitions succeeded

删除topic

  • 前提是把kafka配置文件server.properties中的delete.topic.enable设置为true
./kafka-topics.sh --zookeeper 192.168.2.165:2181 --delete  --topic <topic_name>

设置消息大小上限

  • topic级别静态参数用–zookeeper, 动态参数才用–bootstrap-server
./kafka-configs.sh --zookeeper 10.103.22.130:2181 --entity-type topics --entity-name ttt1 --alter --add-config max.message.bytes=10485760

## out
Completed Updating config for entity: topic 'ttt1'.

生产

查看生产

./kafka-console-producer.sh --broker-list 192.168.2.158:9092 --topic topic-a

生产消息

./kafka-console-producer.sh --topic topic-a --bootstrap-server broker:9092
> 进站去重车数据如下:
> {"Ts":1677507305663,"Data":"99990000","Info":1080}}

参考

查看消费

server

# 输入
   ./kafka-console-consumer.sh --bootstrap-server 192.168.2.111:9092   --topic topic-a
或 ./kafka-console-consumer.sh --zookeeper        127.0.0.1:2181/kafka --topic topic-a


./kafka-console-consumer.sh --bootstrap-server 192.168.2.142:32400   --topic ttt

```bash
zk启动 brew services start zookeeper或zkServer start
/usr/local/Cellar/kafka/2.4.0/libexec/bin

查看 offset

如果希望根据时间,找offset,可以有如下方法:

  • 找到指定时间的 *.index 和 *.log 文件,文件名即为 offset。
-rw-r--r--  1 root root       43 Nov 28  2021 partition.metadata
-rw-r--r--  1 root root       10 Nov  8 12:30 00000000000000380329.snapshot
-rw-r--r--  1 root root 10485756 Nov  8 12:31 00000000000000380329.timeindex
-rw-r--r--  1 root root 10485760 Nov  8 12:31 00000000000000380329.index
drwxr-xr-x  2 root root     4096 Nov  8 12:31 ./
-rw-r--r--  1 root root     3622 Nov  8 12:33 00000000000000380329.log
drwxr-xr-x 77 root root     4096 Nov  8 12:34 ../

查看积压

server

# 输入
cd ~/deep/kafka/kafka/bin
watch -n 1 ./kafka-consumer-groups.sh --bootstrap-server 192.168.2.111:9092 --describe --group topic-a

# 输出:其中lag有值表示积压。
Note: This will only show information about consumers that use the Java consumer API (non-ZooKeeper-based consumers).
TOPIC                          PARTITION  CURRENT-OFFSET  LOG-END-OFFSET  LAG        CONSUMER-ID                                       HOST                           CLIENT-ID
topic-a                 0          159955          159955          0          UBUNTU.local-61e8b3d0-1456-49ce-8656-fe18cab4026a    

client has run out of available brokers to talk to (Is your cluster reachable?)报错的调试

  • kafka基于zookeeper做一致性校验,一个topic必须对应一个broker才行,如果importer出现报错 [ERROR] kafka %v create producer failed:client has run out of available brokers to talk to (Is your cluster reachable?) 的话,可能是kafka有问题,可能是因为offset不一致导致紊乱,比较暴力的方式是删掉zookeeper和kafka的日志。

原理

  • producer=》分为多个partition存(例如分为p1、p2、p3…p10)=》每个consumer分别从一个不同的partition读(consumer1读p1的话,consumer2就不能读p1了)。

UI 工具

Kafka Offset Explorer 支持Mac、Win、Linux

go sarama库使用

Shopify/sarama库

consumer

可以用 NewConsumerGroup() 创建,也可以先 NewClient() 再 NewConsumerGroupFromClient() 创建。

我们需要实现 Setup()、ConsumeClaim()、CleanUp() 三个回调函数,sarama 库会调度上述函数。

如果需要重置 Offset,可以在 Setup() 内通过 ResetOffset() 实现。

完整代码如下:

package kafka

import (
	"context"
	"github.com/Shopify/sarama"
	log "github.com/siruspen/logrus"
	"lonk/configs"
	"strconv"
	"time"
)

func StartConsumerGroup(ctx context.Context, conf *configs.KafkaInputConfig, msgHandler KafkaMsgHandler) {
	cli, err := newConsumerGroup(conf) // 新建一个 client 实例
	if err != nil {
		log.Fatalf("[newConsumerGroup] conf: %v, err: %v", conf, err)
	}
	k := kafkaConsumerGroup{
		msgHandler:                msgHandler,
		ready:                     make(chan bool, 0), // 标识 consumer 是否 ready
		partitionInitialOffsetMap: conf.PartitionInitialOffsetMap,
	}
	go func() {
		defer cli.Close()
		for {
			// Consume().newSession().newConsumerGroupSession() 先调用 Setup(); 再开多个协程(每个协程都用for循环持续调用consume().ConsumeClaim()来处理消息); Consume() 内部的 <-sess.ctx.Done() 会阻塞
			if err := cli.Consume(ctx, []string{conf.Topic}, &k); err != nil {
				log.Errorln("Error from consumer", err)
			}
			if ctx.Err() != nil { // 若 ctx.cancel() 而会引发 cli.Consume() 内部对 ctx.Done() 的监听,从而结束 cli.Consume() 的阻塞, 并
				return
			}
			k.ready = make(chan bool, 0) // 当 rebalanced 时 cli.Consume() 会退出且 ctx.Err() == nil, 则重置此 channel, 继续在下一轮 for 循环调用 Consume()
		}
	}()
	<-k.ready // 直到 close(consumer.ready) 解除阻塞
	log.Infoln("Sarama consumer up and running!...")
}

func newConsumerGroup(conf *configs.KafkaInputConfig) (sarama.ConsumerGroup, error) {
	sConf := sarama.NewConfig()
	sConf.Version = sarama.V2_8_0_0
	sConf.Consumer.Offsets.Initial = sarama.OffsetOldest
	sConf.Consumer.Offsets.Retention = 7 * 24 * time.Hour
	cli, err := sarama.NewClient(conf.Brokers, sConf)
	if err != nil {
		log.Fatalf("[NewClient] conf: %v, err: %v", sConf, err)
	}
	consumerGroup, err := sarama.NewConsumerGroupFromClient(conf.Group, cli)
	if err != nil {
		log.Fatalf("[NewConsumerGroupFromClient] conf: %v, err: %v", sConf, err)
	}
	return consumerGroup, nil
}

// Consumer represents a Sarama consumer group consumer
type kafkaConsumerGroup struct {
	msgHandler                func(message *sarama.ConsumerMessage)
	ready                     chan bool
	partitionInitialOffsetMap map[string]int64
}

// Setup 回调函数 is run at the beginning of a new session, before ConsumeClaim
func (k *kafkaConsumerGroup) Setup(session sarama.ConsumerGroupSession) error {
	for topic, partitions := range session.Claims() {
		for _, partition := range partitions {
			initialOffset, ok := k.partitionInitialOffsetMap[strconv.Itoa(int(partition))]
			if !ok {
				log.Fatalf("invalid topic:%v, partition: %v", topic, partition)
			}
			log.Infof("Sarama Consumer is resetting offset to %v:%v:%v", topic, partition, initialOffset)
			session.ResetOffset(topic, partition, initialOffset, "")
		}
	}
	close(k.ready) // 启动后此处会标记 ready, 使 StartKafkaConsumer() 不再阻塞
	return nil
}

// Cleanup 回调函数 is run at the end of a session, once all ConsumeClaim goroutines have exited
func (k *kafkaConsumerGroup) Cleanup(sarama.ConsumerGroupSession) error {
	log.Infoln("Sarama Consumer is cleaning up!...")
	return nil
}

// ConsumeClaim 回调函数 must start a consumer loop of ConsumerGroupClaim's Messages().
func (k *kafkaConsumerGroup) ConsumeClaim(session sarama.ConsumerGroupSession, claim sarama.ConsumerGroupClaim) error {
	// NOTE: Do not move the code below to a goroutine. The `ConsumeClaim` itself is called within a goroutine, see: https://github.com/Shopify/sarama/blob/master/consumer_group.go#L27-L29
	for {
		select {
		case message := <-claim.Messages():
			k.msgHandler(message)
			session.MarkMessage(message, "")
		// Should return when `session.Context()` is done. If not, will raise `ErrRebalanceInProgress` or `read tcp <ip>:<port>: i/o timeout` when kafka rebalance. see: https://github.com/Shopify/sarama/issues/1192
		case <-session.Context().Done():
			return nil
		}
	}
}

参考:官方 consumerGroup 的 example
参考:sarama consumer group 的使用
参考:sarama partition consumer 根据 time 指定 offset

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

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

相关文章

车载电子之汽车HUD技术

一、什么是HUD技术 HUD&#xff08;head up display抬头显示器&#xff09;是将重要信息显示在挡风玻璃上的一种显示系统&#xff0c;基本原理是&#xff1a;投影仪发出的光信息&#xff0c;经过一系列的折射、反射等投影到挡风玻璃上&#xff0c;人眼就能看到投射在上面的信息…

springboot+vue广场舞团系统(java项目源码+文档)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的广场团舞系统。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 &#x1f495;&#x1f495;作者&#xff1a;风歌&a…

Jmeter接口测试-websocket测试

壹 Jmeter接口测试-websocket测试 测试之前的准备工作,需要websocket插件 方式一: 去github下载: https://github.com/maciejzaleski/JMeter-WebSocketSampler/wiki/Dependencies jetty-http-9.1.2.v20140210.jarjetty-io-9.1.2.v20140210.jarjetty-util-9.1.2.v20140210…

华为OD机试真题 Java 实现【云短信平台优惠活动】【2023Q1 200分】,附详细解题思路

一、题目描述 某云短信厂商&#xff0c;为庆祝国庆&#xff0c;推出充值优惠活动。 现在给出客户预算&#xff0c;和优惠售价序列&#xff0c;求最多可获得的短信总条数。 二、输入描述 第一行客户预算M&#xff0c;其中 0<M<1000000。 第二行给出售价表&#xff0c…

华为OD机试真题B卷 Java 实现【小朋友排队】

一、题目描述 小明今年升学到了小学1年级&#xff0c;来到新班级后&#xff0c;发现其他小朋友身高参差不齐&#xff0c;然后就想基于每个小朋友和自己的身高差&#xff0c;对他们进行排序&#xff0c;请帮他实现排序。 二、输入描述 第一行为正整数h和n。 0 < h < 2…

算法基础学习笔记——⑤离散化\区间和并

✨博主&#xff1a;命运之光 ✨专栏&#xff1a;算法基础学习 目录 ✨简述 特指整数离散化 &#x1f353;离散化模板&#xff1a; ✨区间和并 &#x1f353;区间和并模板&#xff1a; 前言&#xff1a;算法学习笔记记录日常分享&#xff0c;需要的看哈O(∩_∩)O&#xff0…

【树上差分+LCA】篮球杯 砍树

省赛的题现在来补 感觉什么都不会&#xff0c;已经要没了 题意&#xff1a; 思路&#xff1a; 考虑一条边&#xff0c;两端有两棵子树 有这样的性质&#xff1a; 这条边两端的结点的经过次数M 因此每加一个点对&#xff0c;都对其路径1 s[u]M时&#xff0c;与该点连着的…

大数据Doris(二十八):Broker Load通配符导入HDFS数据并指定列顺序

文章目录 Broker Load通配符导入HDFS数据并指定列顺序 一、创建Doris表 2、准备HDFS数据

Maven学习笔记(基础篇)22版

1. 概述部分 1. 什么是 Maven&#xff1f; 为什么要学习Maven&#xff1f; 管理规模庞大的 jar 包&#xff0c;需要专门工具。脱离 IDE 环境执行构建操作&#xff0c;需要专门工具。 1、构建 Java 项目开发过程中&#xff0c;构建指的是使用『原材料生产产品』的过程。 原…

二叉树的镜像 JZ27

目录 链接 描述 示例 代码 演示结果 链接 二叉树的镜像_牛客题霸_牛客网 描述 示例 代码 /*** struct TreeNode {* int val;* struct TreeNode *left;* struct TreeNode *right;* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}* };*/ class Solution …

花朵识别系统Python实现,深度学习卷积神经网络算法

一、背景 花朵识别系统&#xff0c;基于Python实现&#xff0c;深度学习卷积神经网络&#xff0c;通过TensorFlow搭建卷积神经网络算法模型&#xff0c;并对数据集进行训练最后得到训练好的模型文件&#xff0c;并基于Django搭建可视化操作平台。 在当今信息化社会&#xff0c…

算法基础学习笔记——⑥链表\栈\队列

✨博主&#xff1a;命运之光 ✨专栏&#xff1a;算法基础学习 目录 ✨单链表 &#x1f353;单链表模板&#xff1a; ✨双链表 &#x1f353;双链表模板&#xff1a; &#x1f353;循环链表图&#xff1a; ✨栈 &#x1f353;栈模板&#xff1a; ✨队列 &#x1f353;队…

【脚本工具】SVG路径中的A指令转DXF的圆弧和椭圆弧 C++代码实现

文章目录 一、SVG路径的A指令的语法说明二、DXF中的圆弧和椭圆弧对象2.1 圆弧对象2.2 椭圆弧对象 三、转DXF圆弧3.1 数学公式3.2 代码实现3.3 转换效果展示 四、转DXF椭圆弧4.1 数学公式4.2 代码实现4.3 转换效果展示 一、SVG路径的A指令的语法说明 目前Svg的Arc的参数字符串如…

leetcode--分隔链表(java)

分割链表 leetcode 86 分割链表 &#xff08;中等&#xff09;解题思路&#xff1a;链表专题 leetcode 86 分割链表 &#xff08;中等&#xff09; leetcode 86 分割链表 原题链接&#xff0c;可以直接测试 给你一个链表的头节点 head 和一个特定值 x &#xff0c;请你对链表进…

怎么给苹果手机设备画面投屏到电脑上面?

虽然使用苹果设备自带的AirPlay功能&#xff0c;搭配其推出的Apple TV设备&#xff0c;可实现苹果设备的投屏播放&#xff0c;但相信很多人都不会花大价钱去购入Apple TV&#xff0c;如果是土豪的话请随意。 那么&#xff0c;没有Apple TV&#xff0c;苹果设备就不能投屏了吗&…

sql注入学习-知识点大合集

目录 &#xff08;一&#xff09;sql注入了解&#xff1a; 1.1什么是sql注入 1.2 sql注入的分类 &#xff08;二&#xff09;sql注入详解&#xff1a; 2.1.MySQL注入 2.2.1在MySQL注入中&#xff0c;会用到的知识 2.2.2mysql常用语句与常见 2.2.3msyql注入内容详解 2.2…

首发出炉Yolov5/Yolov7涨点神器:华为诺亚2023极简的神经网络模型 VanillaNet---VanillaBlock助力检测,实现暴力涨点

在​crack缺陷检测项目map 0.954提升至 0.979,涨点明显,博主多个数据集亲测有效,实现暴力涨点; 1.VanillaNet 论文:https://arxiv.org/pdf/2305.12972.pdf 来自华为诺亚、悉尼大学的研究者们提出了一种极简的神经网络模型 VanillaNet,以极简主义的设计为理念,网络中仅仅…

connect reset/timeout/reject 排查

异常排查 问题描述问题处理初步分析http配置即服务整体情况整体排查服务重启gcCPUJVM 暂存疑问点总结启动参数要配全监控体系健全科学使用jar包降配参数是参数得动态变 问题描述 最初出现的时候&#xff0c;是在每天的早上8-10这个时间范围内&#xff0c;服务A上的有一个接口时…

第一行代码 第十二章 Material Design实战

第12章 Material Design实战 其实长久以来&#xff0c;大多数人都认为Android系统的UI并不算美观&#xff0c;至少没有iOS系统的美观。以至于很多IT公司在进行应用界面设计的时候&#xff0c;为了保证双平台的统一性&#xff0c;强制要求Android端的界面风格必须和iOS端一致。…

Java08——继承

1. 继承 父类&#xff1a; package com.zsq.extend.improve_; //是pupil和graduate的父类 public class Student {public String name;public int age;private double score;public void info(){System.out.println("姓名&#xff1a;" name " 年龄&#xff1…