中间件(三)- Kafka(二)

news2024/10/5 18:28:01

Kafka

    • 6. 高效读写&Zookeeper作用
      • 6.1 Kafka的高效读写
      • 6.2 Kafka中zookeeper的作用
    • 7. 事务
      • 7.1 Producer事务
      • 7.2 Consumer事务
    • 8. API生产者流程
    • 9. 通过python调用kafka
      • 9.1 安装插件
      • 9.2 生产者(Producer)与消费者(Consumer)
      • 9.3 消费者进阶操作
        • 1. 初始化参数
        • 2. 手动commit
        • 3. 查看kafka堆积剩余量
      • 9.4 topic操作
        • 1. 获取所有的topic
        • 2. 创建、删除topic
        • 3. 获取topic配置信息
        • 4.获取消费组信息
    • 10. Kafka监控Eagle
    • 11. 常见面试题

在这里插入图片描述

6. 高效读写&Zookeeper作用

6.1 Kafka的高效读写

顺序写磁盘
Kafka的producer生产数据,需要写入到log文件中,写的过程是追加到文件末端,顺序写的方式,官网有数据表明,同样的磁盘,顺序写能够到600M/s,而随机写只有200K/s,这与磁盘的机械结构有关,顺序写之所以快,是因为其省去了大量磁头寻址的时间。

零复制技术

Kafka的零拷贝技术
在这里插入图片描述
NIC:Network Interface Controller网络接口控制器

  • 常规读取
    在这里插入图片描述
    这是常规的读取操作:

    • 操作系统将数据从磁盘文件中读取到内核空间的页面缓存
    • 应用程序将数据从内核空间读入到用户空间缓冲区
    • 应用程序将读到的数据写回内核空间并放入到socket缓冲区
    • 操作系统将数据从socket缓冲区复制到网卡接口,此时数据通过网络发送给消费者
  • 零拷贝技术
    在这里插入图片描述
    零拷贝技术只用将磁盘文件的数据复制到页面缓存中一次,然后将数据从页面缓存直接发送到网络中(发送给不同的订阅者时,都可以使用同一个页面缓存),从而避免了重复复制的操作。

如果有10个消费者,传统方式下,数据复制次数为4*10=40次,而使用“零拷贝技术”只需要1+10=11次,一次为从磁盘复制到页面缓存,10次表示10个消费者各自读取一次页面缓存。

6.2 Kafka中zookeeper的作用

Kafka集群中有一个broker会被选举为Controller,负责管理集群broker的上下线、所有topic的分区副本分配和leader的选举等工作。Controller的工作管理依赖于zookeeper
在这里插入图片描述

7. 事务

kafka从0.11版本开始引入了事务支持,事务可以保证Kafka在Exactly Once语义的基础上,生产和消费可以跨分区的会话,要么全部成功,要么全部失败。

7.1 Producer事务

为了按跨分区跨会话的事务,需要引入一个全局唯一的Transaction ID,并将Producer获得的PID(可以理解为Producer ID)和Transaction ID进行绑定,这样当Producer重启之后就可以通过正在进行的Transaction ID获得原来的PID。

为了管理Transaction,Kafka引入了一个新的组件Transaction Coordinator,Producer就是通过有和Transaction Coordinator交互获得Transaction ID对应的任务状态,Transaction Coordinator还负责将事务信息写入内部的一个Topic中,这样即使整个服务重启,由于事务状态得到保存,进行中的事务状态可以恢复,从而继续进行。

7.2 Consumer事务

对于Consumer而言,事务的保证相比Producer相对较弱,尤其是无法保证Commit的信息被精确消费,这是由于Consumer可以通过offset访问任意信息,而且不同的Segment File声明周期不同,同一事务的消息可能会出现重启后被删除的情况。

8. API生产者流程

Kafka的Producer发送消息采用的是异步发送的方式,在消息发送的过程中,涉及到了两个线程:main线程和Sender线程,以及一个线程共享变量RecordAccumulator,main线程将消息发送给RecordAccumulator,Sender线程不断从RecordAccumulator中拉取消息发送到Kafka broker中。
在这里插入图片描述

9. 通过python调用kafka

这里用的是kafka插件,可以操作kafka的插件还有pykafka等

9.1 安装插件

插件下载地址: https://pypi.org/project/kafka/#files

pip install kafka-1.3.5-py2.py3-none-any.whl
pip install kafka_python-2.0.2-py2.py3-none-any.whl

笔者使用的python2.7版本

9.2 生产者(Producer)与消费者(Consumer)

生产者和消费者的简易Demo

#coding:utf-8
from kafka import KafkaProducer, KafkaConsumer
from kafka.errors import kafka_errors
import traceback
import json

def producer_demo():
    # 假设生产的消息为键值对(不是一定要键值对),且序列化方式为json
    producer = KafkaProducer(
        bootstrap_servers=['192.168.71.251:9092'],
        key_serializer=lambda k: json.dumps(k).encode(),
        value_serializer=lambda v: json.dumps(v).encode())
    # 发送三条消息
    for i in range(0, 3):
        future = producer.send(
            'demo1',
            key='count_num',  # 同一个key值,会被送至同一个分区
            value=str(i),
            partition=1)  # 向分区1发送消息
        print("send {}".format(str(i)))
        try:
            future.get(timeout=10) # 监控是否发送成功
        except kafka_errors:  # 发送失败抛出kafka_errors
            traceback.format_exc()


def consumer_demo():
    consumer = KafkaConsumer(
        'demo1',
        bootstrap_servers='192.168.71.251:9092',
        group_id='test'
    )
    for message in consumer:
        print("receive, key: {}, value: {}".format(
            json.loads(message.key.decode()),
            json.loads(message.value.decode())
            )
        )

if __name__ == '__main__':
    producer_demo()
    #consumer_demo()

这里建议起两个terminal,或者两个jupyter notebook页面来验证。

先执行消费者:

consumer_demo()

再执行生产者:

producer_demo()

会看到如下输出:

>>> producer_demo()
send 0
send 1
send 2


>>> consumer_demo()
receive, key: count_num, value: 0
receive, key: count_num, value: 1
receive, key: count_num, value: 2

9.3 消费者进阶操作

1. 初始化参数

列举一些Kafka Consumer初始化时的重要参数:

  • topic
    topic的名称,表示当前消费者从那个topic监听并读取消息。

  • group_id
    高并发量,则需要有多个消费者协作,消费进度,则由group_id统一管理。例如消费者A与消费者B,在初始化时使用同一个group_id。在进行消费时,一条消息被消费者A消费后,在kafka中会被标记,这条消息不会再被B消费(前提是A消费后正确commit)。

  • key_deserializer, value_deserializer
    与生产者中的参数一致,自动解析。

  • auto_offset_reset
    消费者启动的时刻,消息队列中或许已经有堆积的未消费消息,有时候需求是从上一次未消费的位置开始读(则该参数设置为earliest),有时候的需求为从当前时刻开始读之后产生的,之前产生的数据不再消费(则该参数设置为latest)。

    earliest:自动重置到最早的offset。
    latest:看上去重置到最晚的offset。
    none:如果边更早的offset也没有的话,就抛出异常给consumer,告诉consumer在整个consumer group中都没有发现有这样的offset。

  • enable_auto_commit, auto_commit_interval_ms
    是否自动commit,当前消费者消费完该数据后,需要commit,才可以将消费完的信息传回消息队列的控制中心。enable_auto_commit设置为True后,消费者将自动commit,并且两次commit的时间间隔为auto_commit_interval_ms。

2. 手动commit

def consumer_demo():
    consumer = KafkaConsumer(
        'demo1',
        bootstrap_servers='192.168.71.251:9092',
        group_id='test',
        enable_auto_commit=False,
		#auto_commit_interval_ms=5000
    )
    for message in consumer:
        print("receive, key: {}, value: {}".format(
            json.loads(message.key.decode()),
            json.loads(message.value.decode())
            )
        )
        consumer.commit()

3. 查看kafka堆积剩余量

在线环境中,需要保证消费者的消费速度大于生产者的生产速度,所以需要检测kafka中的剩余堆积量是在增加还是减小。可以用如下代码,观测队列消息剩余量

#coding:utf-8
from kafka import TopicPartition
from kafka import KafkaProducer, KafkaConsumer


topic = 'demo1'
#consumer = KafkaConsumer(topic, **kwargs)
consumer = KafkaConsumer(
        'demo1',
        bootstrap_servers='192.168.71.251:9092',
        group_id='test',
        enable_auto_commit=False,
		#auto_commit_interval_ms=5000
    )
partitions = [TopicPartition(topic, p) for p in consumer.partitions_for_topic(topic)]
print partitions
print("start to cal offset:")

# total
toff = consumer.end_offsets(partitions)
toff = [(key.partition, toff[key]) for key in toff.keys()]
toff.sort()
print("total offset: {}".format(str(toff)))

# current
coff = [(x.partition, consumer.committed(x)) for x in partitions]
coff.sort()
print("current offset: {}".format(str(coff)))

# cal sum and left
toff_sum = sum([x[1] for x in toff])
cur_sum = sum([x[1] for x in coff if x[1] is not None])
left_sum = toff_sum - cur_sum
print("kafka left: {}".format(left_sum))
------------------------------------------------------------------------------------------------
[TopicPartition(topic='demo1', partition=0), TopicPartition(topic='demo1', partition=1)]
start to cal offset:
total offset: [(0, 5), (1, 49)]
current offset: [(0, 5), (1, 49)]
kafka left: 0

9.4 topic操作

1. 获取所有的topic

#coding:utf-8
from kafka import KafkaConsumer,TopicPartition


servers=['192.168.71.251:9092']
# 获取topic列表以及topic的分区列表
def retrieve_topics():
    consumer = KafkaConsumer(bootstrap_servers=servers)
    print(consumer.topics())

# 获取topic的分区列表
def retrieve_partitions(topic):
    consumer = KafkaConsumer(bootstrap_servers=servers)
    print(consumer.partitions_for_topic(topic))

# 获取Consumer Group对应的分区的当前偏移量
def retrieve_partition_offset():
    consumer = KafkaConsumer(bootstrap_servers=servers,
                             group_id='kafka-group-id')
    tp = TopicPartition('kafka-topic', 0)
    consumer.assign([tp])
    print("starting offset is ", consumer.position(tp))

retrieve_topics()
retrieve_partitions('demo1')
retrieve_partition_offset()
---------------------------------------------------------------------------
set([u'demo', u'kafka_demo', u'demo1'])
set([0, 1])
('starting offset is ', 0)

2. 创建、删除topic

#coding:utf-8
from kafka import KafkaConsumer,TopicPartition


servers=['192.168.71.251:9092']

from kafka import KafkaAdminClient
from kafka.admin import NewTopic
from kafka.errors import TopicAlreadyExistsError

admin = KafkaAdminClient(bootstrap_servers=servers)

# 获取topic列表以及topic的分区列表
def retrieve_topics():
    consumer = KafkaConsumer(bootstrap_servers=servers)
    print(consumer.topics())

# 获取topic的分区列表
def retrieve_partitions(topic):
    consumer = KafkaConsumer(bootstrap_servers=servers)
    print(consumer.partitions_for_topic(topic))


# 创建topic
def create_topic():
    try:
        new_topic = NewTopic("create-topic", 6, 1)#num_partitions 6,replication_factor:1
        admin.create_topics([new_topic])
        print "create 'create-topic'"
    except TopicAlreadyExistsError as e:
        print(e.message)

# 删除topic
def delete_topic():
    admin.delete_topics(["create-topic"])
    print "delete 'create-topic'"
if __name__ == '__main__':
    create_topic()
    retrieve_topics()
    retrieve_partitions("create-topic")
    delete_topic()
    retrieve_topics()
-----------------------------------------------------------------------------------------------
create 'create-topic'
set([u'demo', u'kafka_demo', u'demo1', u'create-topic', u'kafka-topic'])
set([0, 1, 2, 3, 4, 5])
delete 'create-topic'
set([u'demo', u'kafka_demo', u'demo1', u'kafka-topic'])

3. 获取topic配置信息

#coding:utf-8


from kafka import KafkaAdminClient
from kafka.admin import ConfigResource, ConfigResourceType

servers=['192.168.71.251:9092']

admin = KafkaAdminClient(bootstrap_servers=servers)
# 获取topic的配置信息
def get_topic_config():
    resource_config = ConfigResource(ConfigResourceType.TOPIC, "demo1")
    config_entries = admin.describe_configs([resource_config])
    print(config_entries)

get_topic_config()
-------------------------------------------------------------------------------------
[DescribeConfigsResponse_v2(throttle_time_ms=0, resources=[(error_code=0, error_message=u'', resource_type=2, resource_name=u'demo1', config_entries=[(config_names=u'compression.type', config_value=u'producer', read_only=False, config_source=5, is_sensitive=False, config_synonyms=[]), (config_names=u'leader.replication.throttled.replicas', config_value=u'', read_only=False, config_source=5, is_sensitive=False, config_synonyms=[]), (config_names=u'message.downconversion.enable', config_value=u'true', read_only=False, config_source=5, is_sensitive=False, config_synonyms=[]), (config_names=u'min.insync.replicas', config_value=u'1', read_only=False, config_source=5, is_sensitive=False, config_synonyms=[]), (config_names=u'segment.jitter.ms', config_value=u'0', read_only=False, config_source=5, is_sensitive=False, config_synonyms=[]), (config_names=u'cleanup.policy', config_value=u'delete', read_only=False, config_source=5, is_sensitive=False, config_synonyms=[]), (config_names=u'flush.ms', config_value=u'9223372036854775807', read_only=False, config_source=5, is_sensitive=False, config_synonyms=[]), (config_names=u'follower.replication.throttled.replicas', config_value=u'', read_only=False, config_source=5, is_sensitive=False, config_synonyms=[]), (config_names=u'segment.bytes', config_value=u'1073741824', read_only=False, config_source=5, is_sensitive=False, config_synonyms=[]), (config_names=u'retention.ms', config_value=u'604800000', read_only=False, config_source=5, is_sensitive=False, config_synonyms=[]), (config_names=u'flush.messages', config_value=u'9223372036854775807', read_only=False, config_source=5, is_sensitive=False, config_synonyms=[]), (config_names=u'message.format.version', config_value=u'3.0-IV1', read_only=False, config_source=5, is_sensitive=False, config_synonyms=[]), (config_names=u'file.delete.delay.ms', config_value=u'60000', read_only=False, config_source=5, is_sensitive=False, config_synonyms=[]), (config_names=u'max.compaction.lag.ms', config_value=u'9223372036854775807', read_only=False, config_source=5, is_sensitive=False, config_synonyms=[]), (config_names=u'max.message.bytes', config_value=u'1048588', read_only=False, config_source=5, is_sensitive=False, config_synonyms=[]), (config_names=u'min.compaction.lag.ms', config_value=u'0', read_only=False, config_source=5, is_sensitive=False, config_synonyms=[]), (config_names=u'message.timestamp.type', config_value=u'CreateTime', read_only=False, config_source=5, is_sensitive=False, config_synonyms=[]), (config_names=u'preallocate', config_value=u'false', read_only=False, config_source=5, is_sensitive=False, config_synonyms=[]), (config_names=u'min.cleanable.dirty.ratio', config_value=u'0.5', read_only=False, config_source=5, is_sensitive=False, config_synonyms=[]), (config_names=u'index.interval.bytes', config_value=u'4096', read_only=False, config_source=5, is_sensitive=False, config_synonyms=[]), (config_names=u'unclean.leader.election.enable', config_value=u'false', read_only=False, config_source=5, is_sensitive=False, config_synonyms=[]), (config_names=u'retention.bytes', config_value=u'-1', read_only=False, config_source=5, is_sensitive=False, config_synonyms=[]), (config_names=u'delete.retention.ms', config_value=u'86400000', read_only=False, config_source=5, is_sensitive=False, config_synonyms=[]), (config_names=u'segment.ms', config_value=u'604800000', read_only=False, config_source=5, is_sensitive=False, config_synonyms=[]), (config_names=u'message.timestamp.difference.max.ms', config_value=u'9223372036854775807', read_only=False, config_source=5, is_sensitive=False, config_synonyms=[]), (config_names=u'segment.index.bytes', config_value=u'10485760', read_only=False, config_source=5, is_sensitive=False, config_synonyms=[])])])]

4.获取消费组信息

#coding:utf-8
from kafka import KafkaAdminClient
from kafka.admin import ConfigResource, ConfigResourceType

servers=['192.168.71.251:9092']

admin = KafkaAdminClient(bootstrap_servers=servers)
# 获取消费组信息
def get_consumer_group():
    # 显示所有的消费组
    print(admin.list_consumer_groups())

    # 显示消费组的offsets
    print(admin.list_consumer_group_offsets("test"))

get_consumer_group()
-------------------------------------------------------------------
[(u'test-consumer-group', u'consumer'), (u'test', u'consumer')]
{TopicPartition(topic=u'demo1', partition=0): OffsetAndMetadata(offset=5, metadata=u''), TopicPartition(topic=u'demo1', partition=1): OffsetAndMetadata(offset=49, metadata=u'')}

10. Kafka监控Eagle

Eagle

Eagle是开源的额可视化和管理软件,允许查询、可视化、提醒和探索存储在任何地方的指标,简而言之,Eagle为您提供了将Kafka集群数据转换为漂亮的图形和可视化的工具。

实质上是一个运行在tomcat上的web应用。

具体安装可参考kafka 监控工具 eagle 的安装(内附高速下载地址)

11. 常见面试题

Kafka 中的 ISR(InSyncRepli)、 OSR(OutSyncRepli)、 AR(AllRepli)代表什么?

ISR:速率和leader相差低于10s的follower的集合
OSR:速率和leader相差大于10s的follwer
AR:所有分区的follower

Kafka 中的 HW、 LEO 等分别代表什么?

HW:High Water高水位,根据同一分区中最低的LEO决定(Log End Offset)
LEO:每个分区最大的Offset

Kafka 中是怎么体现消息顺序性的?

在每个分区内,每条消息都有offset,所以消息在同一分区内有序,无法做到全局有序性

Kafka 中的分区器、序列化器、拦截器是否了解?它们之间的处理顺序是什么?

分区器Partitioner用来对分区进行处理的,即消息发送到哪一个分区的问题。
序列化器,这个是对数据进行序列化和反序列化的工具。
拦截器,即对于消息发送进行一个提前处理和收尾处理的类Interceptor
处理顺利首先通过拦截器=>序列化器=>分区器

Kafka 生产者客户端的整体结构是什么样子的?使用了几个线程来处理?分别是什么?

使用两个线程:main和sender 线程,main线程会一次经过拦截器、序列化器、分区器将数据发送到RecoreAccumulator线程共享变量,再由sender线程从共享变量中拉取数据发送到kafka broker
batch.size达到此规模消息才发送,linger.ms未达到规模,等待当前时长就发送数据。

消费组中的消费者个数如果超过 topic 的分区,那么就会有消费者消费不到数据”这句话是否正确?

这句话是对的,超过分区个数的消费者不会在接收数据,主要原因是一个分区的消息只能够被一个消费者组中的一个消费者消费。

消费者提交消费位移时提交的是当前消费到的最新消息的 offset 还是 offset+1?

生产者发送数据的offset是从0开始的,消费者消费的数据的offset是从1开始,故最新消息是offset+1

有哪些情形会造成重复消费?

先消费后提交offset,如果消费完宕机了,则会造成重复消费

那些情景会造成消息漏消费?

先提交offset,还没消费就宕机了,则会造成漏消费

当你使用 kafka-topics.sh 创建(删除)了一个 topic 之后, Kafka 背后会执行什么逻辑?

会在 zookeeper 中的/brokers/topics 节点下创建一个新的 topic 节点,如:/brokers/topics/first
触发 Controller 的监听程序
kafka Controller 负责 topic 的创建工作,并更新 metadata cache

topic 的分区数可不可以增加?如果可以怎么增加?如果不可以,那又是为什么?

可以增加,修改分区个数–alter可以修改分区个数

topic 的分区数可不可以减少?如果可以怎么减少?如果不可以,那又是为什么?

不可以减少,减少了分区之后,之前的分区中的数据不好处理

Kafka 有内部的 topic 吗?如果有是什么?有什么所用?

有,__consumer_offsets主要用来在0.9版本以后保存消费者消费的offset

Kafka 分区分配的概念?

Kafka分区对于Kafka集群来说,分区可以做到负载均衡,对于消费者来说分区可以提高并发度,提高读取效率

简述 Kafka 的日志目录结构?

每一个分区对应着一个文件夹,命名为topic-0/topic-1…,每个文件夹内有.index和.log文件。

如果我指定了一个 offset, Kafka Controller 怎么查找到对应的消息?

offset表示当前消息的编号,首先可以通过二分法定位当前消息属于哪个.index文件中,随后采用seek定位的方法查找到当前offset在.index中的位置,此时可以拿到初始的偏移量。通过初始的偏移量再通过seek定位到.log中的消息即可找到。

聊一聊 Kafka Controller 的作用?

Kafka集群中有一个broker会被选举为Controller,负责管理集群broker的上下线、所有topic的分区副本分配和leader的选举等工作。Controller的工作管理是依赖于zookeeper的。

Kafka 中有那些地方需要选举?这些地方的选举策略又有哪些?

在ISR中需要选举出Leader,选择策略为先到先得。在分区中需要选举,需要选举出Leader和follower。

失效副本是指什么?有那些应对措施?

失效副本为速率比leader相差大于10s的follower,ISR会将这些失效的follower踢出,等速率接近leader的10s内,会重新加入ISR

Kafka 的哪些设计让它有如此高的性能?

Kafka天生的分布式架构
对log文件进行了分segment,并对segment建立了索引
对于单节点使用了顺序读写,顺序读写是指的文件的顺序追加,减少了磁盘寻址的开销,相比随机写速度提升很多
使用了零拷贝技术,不需要切换到用户态,在内核态即可完成读写操作,且数据的拷贝次数也更少。

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

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

相关文章

【实验】SegViT: Semantic Segmentation with Plain Vision Transformers

想要借鉴SegViT官方模型源码部署到本地自己代码文件中 1. 环境配置 官网要求安装mmcv-full1.4.4和mmsegmentation0.24.0 在这之前记得把mmcv和mmsegmentation原来版本卸载 pip uninstall mmcv pip uninstall mmcv-full pip uninstall mmsegmentation安装mmcv 其中&#xff…

你若在患难之日胆怯,你的力量便微小

如果你在做一件事情之前就过分放大它的困难,这就会逐渐降低自己去做它的动机和动力,还没开始你就已经削弱了自己的行动能力,在气势上就已经输了。 不要害怕困难,勇敢的去面对问题,解决问题,你就会在气势上更…

RK平台烧录固件的几种模式

在RK平台开发过程中,我们在使用烧录工具烧写固件的时候经常可以看到烧录工具会显示当前PC识别到的设备类型,一般有:MASKROM,LOADER,ADB,MSC等等。能烧录固件的模式有MASKROM模式和LOADER模式,下…

Python基础教程:第八章_Python文件操作

文件的编码 学习目标 掌握文件编码的概念和常见编码 思考:计算机只能识别:0和1,那么我们丰富的文本文件是如何被计算机识别,并存储在硬盘中呢? 答案:使用编码技术(密码本)将内…

STM32WB55_NUCLEO开发(12)----FUS 更新

概述 在 STM32WB 微控制器中,FUS(Firmware Upgrade Services)是用于固件升级的一种服务。这项服务可以让你更新设备上的无线栈固件(如蓝牙、Zigbee或 Thread 栈),以及无线 MCU (microcontroller unit) 的系…

day5 - 利用阈值勾勒

阈值处理在计算机视觉技术中占有十分重要的位置,他是很多高级算法的底层逻辑之一。本实验将练习使用图像阈值处理技术来处理不同的情况的图像,并获得图像轮廓。 完成本期内容,你可以: 了解图像阈值处理技术的定义和作用 掌握各阈…

PyQt5 使用 pyinstaller打包文件(speed)

编写界面 import sys,math from PyQt5.QtWidgets import * from PyQt5.QtCore import Qt from PyQt5.QtGui import *class RightBottomButton(QWidget) :def __init__(self):super(RightBottomButton,self).__init__()self.setWindowTitle("界面One")self.resize(400…

1.8G专网工业路由器促进4G智能电力建设,赋能配电站远程监控管理

TD-LTE已是当下成熟的4G通信技术,应用无线专网的场景也越来越多,4G技术在电力物联网中也得到了广泛应用。依托传统的人工监管方式,效率低、成本高、维护难,为促进4G智能电力建设迫切需要方便快捷的在线监控方式来及时发现电力配网…

xss跨站,订单,shell箱子反杀记

打开一个常见的订单靶场,老师自己搭建的 这个是可以进行xss漏洞的测试,凡是有这种数据交互的地方,前端有一个数据的接受,后端是数据的显示,这个过程就符合漏洞产生的前提条件,将输入的数据进行个显示&#…

BUUCTF-Basic部分(4道)

目录 Linux Labs BUU LFI COURSE 1 BUU BRUTE 1 BUU SQL COURSE 1 Linux Labs 第一个界面,给出了SSH ssh 用户名:root 密码:123456 地址和端口为动态分配的 以及映射地址和端口(这个地址端口是随机的) node4.buuoj.c…

R语言实践——使用 rWCVP 生成自定义清单

使用 rWCVP 生成自定义清单 介绍1. 特有物种清单2. 近特有物种清单2.1 在塞拉利昂和另一地区出现的物种2.2 在塞拉利昂和相邻地区出现的物种 3. 生成自定义报告 介绍 除了允许用户从世界维管植物名录(WCVP)创建清单外,rWCVP还提供了修改清单…

在小公司“混”了2年,我只认真做了5件事,如今顺利拿到字节 Offer

前言 是的,我一家小公司工作了整整两年时间,在入职这家公司前,也就是两年前,我就开始规划了我自己的人生,所以在两年时间里,我并未懈怠。 现如今,我已经跳槽到了字节,入职字节测试…

傅里叶级数 傅里叶变换 及应用

傅里叶级数和傅立叶变换是傅里叶分析的两个主要工具,它们之间有密切的关系。 什么是傅里叶级数 傅里叶级数是将一个周期函数分解为一系列正弦和余弦函数的和。它适用于周期性信号,可以将周期函数表示为一组振幅和相位不同的谐波分量的和。傅里叶级数展…

Netty编解码机制(二)

1.Netty入站和出站机制 1.1.基本介绍 1>.netty的组件设计: Netty的主要组件有Channel、EventLoop、ChannelFuture、ChannelHandler、ChannelPipe等; 2>.ChannelHandler充当了处理入站和出站数据的应用程序逻辑的容器.例如,实现ChannelInboundHandler接口(或ChannelInb…

Unity之如何接入google cardboard-xr-plugin实现android手机VR

前言 我们提到VR,总是会想到Oculus,HTC Vive,Pico等头戴VR设备,但是别忘了,最早Google就通过再手机端实现VR了,而且还推出过Cardboard手机盒子,让我们可以用最低的成本体验到VR效果。 插件下载 先说明一下,Unity在1028版本之前,支持过GoogleVR,但是后来因为统一…

Chapter8 :Physical Constraints(ug903)

8.1About Physical Constraints(关于物理约束) XilinxVivado集成设计环境(IDE)允许通过设置对象属性值对设计对象进行物理约束。示例包括: •I/O约束,如位置和I/O标准 •布局约束&…

惨败字节,苦心备战两个月斩获阿里offer,这份“258页软件测试面试宝典”也太顶了

测试三年有余,很多新学到的技术不能再项目中得到实践,同时薪资的涨幅很低,于是萌生了跳槽大厂的想法。 但大厂不是那么容易进的,前面惨败字节,为此我辛苦准备了两个月,又从小公司开始面试了半个月有余&…

k8s pv pvc的介绍|动态存储|静态存储

k8s pv pvc的介绍|动态存储|静态存储 1 emptyDir存储卷2 hostPath存储卷3 nfs共享存储卷4 PVC 和 PVNFS使用PV和PVC 4 搭建 StorageClass NFS,实现 NFS 的动态 PV 创建 1 emptyDir存储卷 当Pod被分配给节点时,首先创建emptyDir卷,并且只要该…

FPGA—可乐机拓展训练题(状态机)

题目:以可乐机为背景,一瓶可乐的价格还是 2.5 元。用按键控制投币(加入按键消抖功能),可以投 0.5 元硬币和 1 元硬币,投入 0.5 元后亮一个灯,投入 1 元后亮 2 个灯,投入 1.5 元后亮 …

【统计模型】学生课程类型选择影响因素分析

目录 学生课程类型选择影响因素分析 一、研究目的 二、数据来源和相关说明 三、描述性分析 3.1 样本描述 3.2 样本可视化 3.2.1 直方图 3.2.2 列联表 3.2.3 箱线图与折线图 3.2.4 相关性热力图 四、数学建模 4.1 无序多分类logistic回归模型 4.1.1 无序多分类logist…