Flink学习——处理不同数据源的流数据,存入不同的Sink端

news2024/11/25 12:52:19

目录

一、单机版安装

(一)添加依赖

(二)数据源——Source

1.加载元素数据

2.加载集合数据

3.加载文件目录

4.加载端口

5.加载kafka的topic——重要&常用

6.加载自定义数据源

(三)输出端——Sink

1.读取文件中的数据,处理后输出到另一个文件

2.Source——文件&Sink——Mysql

3.读取kafka的数据,处理后传入mysql中

4.加载kafka中topic的数据,处理后传入另一个topic


一、单机版安装

Flink单机版的安装只需要把压缩包解压即可。

[root@ant168 install]# ls
flink-1.13.2-bin-scala_2.12.tgz  mongodb-linux-x86_64-4.0.10.tgz
kafka_2.12-2.8.0.tgz             zookeeper-3.4.5-cdh5.14.2.tar.gz
[root@ant168 install]# tar -zxf /opt/install/flink-1.13.2-bin-scala_2.12.tgz -C /opt/soft/

# 开启flink客户端
[root@ant168 flink-1.13.2]# ./bin/start-cluster.sh 

[root@ant168 flink-1.13.2]# jps
9050 Jps
1628 StandaloneSessionClusterEntrypoint
1903 TaskManagerRunner

WebUI:localhost:8081

二、IDEA操作Flink

(一)添加依赖

创建maven项目,quickstart

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <flink.version>1.13.2</flink.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.apache.flink</groupId>
      <artifactId>flink-java</artifactId>
      <version>${flink.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.flink</groupId>
      <artifactId>flink-streaming-java_2.12</artifactId>
      <version>${flink.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.flink</groupId>
      <artifactId>flink-clients_2.12</artifactId>
      <version>${flink.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-compress</artifactId>
      <version>1.21</version>
    </dependency>
    <dependency>
      <groupId>org.apache.flink</groupId>
      <artifactId>flink-connector-kafka_2.12</artifactId>
      <version>${flink.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.flink</groupId>
      <artifactId>flink-statebackend-rocksdb_2.12</artifactId>
      <version>${flink.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.flink</groupId>
      <artifactId>flink-table-planner_2.12</artifactId>
      <version>${flink.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.flink</groupId>
      <artifactId>flink-table-planner-blink_2.12</artifactId>
      <version>${flink.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.flink</groupId>
      <artifactId>flink-csv</artifactId>
      <version>${flink.version}</version>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.29</version>
    </dependency>
    <!--<dependency>-->
    <!--<groupId>org.apache.bahir</groupId>-->
    <!--<artifactId>flink-connector-redis_2.12</artifactId>-->
    <!--<version>1.0</version>-->
    <!--</dependency>-->

    <!--  scala  -->
    <dependency>
      <groupId>org.apache.flink</groupId>
      <artifactId>flink-scala_2.12</artifactId>
      <version>${flink.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.flink</groupId>
      <artifactId>flink-streaming-scala_2.12</artifactId>
      <version>${flink.version}</version>
    </dependency>

    <dependency>
      <groupId>org.apache.hadoop</groupId>
      <artifactId>hadoop-common</artifactId>
      <version>3.1.3</version>
    </dependency>
    <dependency>
      <groupId>org.apache.hadoop</groupId>
      <artifactId>hadoop-hdfs</artifactId>
      <version>3.1.3</version>
    </dependency>
    <dependency>
      <groupId>org.apache.flink</groupId>
      <!--<artifactId>flink-connector-kafka-0.11_2.11</artifactId>-->
      <artifactId>flink-connector-kafka_2.12</artifactId>
      <version>${flink.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.hbase</groupId>
      <artifactId>hbase-client</artifactId>
      <version>2.3.5</version>
    </dependency>
    <dependency>
      <groupId>org.apache.hbase</groupId>
      <artifactId>hbase-server</artifactId>
      <version>2.3.5</version>
    </dependency>
  </dependencies>

(二)数据源——Source

1.加载元素数据

import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment

object SourceTest {
  def main(args: Array[String]): Unit = {
    // TODO 1.创建环境
    val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
    env.setParallelism(1) // 设置并行度

    // TODO 2.添加数据源
    // TODO 加载元素
    val stream1: DataStream[Any] = env.fromElements(1, 2, 3, 4, 5, "hello")

    // TODO 3.输出
    stream1.print()
    env.execute("sourcetest")
  }
}

运行结果:
1
2
3
4
5
hello

2.加载集合数据

import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment

// 定义一个样例类——温度传感器
case class SensorReading(id: String, timestamp: Long, temperature: Double)

object SourceTest {
  def main(args: Array[String]): Unit = {
    val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
    env.setParallelism(1) 

    val dataList = List(
          SensorReading("sensor_1", 1684201947, 36.8),
          SensorReading("sensor_2", 1684202000, 35.7),
          SensorReading("sensor_3", 1684202064, 36.3),
          SensorReading("sensor_4", 1684202064, 35.8)
        )
    val stream1: DataStream[SensorReading] = env.fromCollection(dataList)

    stream1.print()
    env.execute("sourcetest")
  }
}

运行结果:

SensorReading(sensor_1,1684201947,36.8)
SensorReading(sensor_2,1684202000,35.7)
SensorReading(sensor_3,1684202064,36.3)
SensorReading(sensor_4,1684202064,35.8)

3.加载文件目录

import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment

object SourceTest {
  def main(args: Array[String]): Unit = {
    val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
    env.setParallelism(1)

    val path = "D:\\javaseprojects\\flinkstu\\resources\\sensor.txt"
    val stream1: DataStream[String] = env.readTextFile(path)

    stream1.print()
    env.execute("sourcetest")
  }
}

运行结果:
sensor_1,1684201947,36.8
sensor_7,1684202000,17.7
sensor_4,1684202064,20.3
sensor_2,1684202064,35.8

4.加载端口

虚拟机要下载nc命令,已经下载的可以忽略

yum -y install nc
import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment

object SourceTest {
  def main(args: Array[String]): Unit = {
    // TODO 1.创建环境
    val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
    env.setParallelism(1)    
    val stream1: DataStream[String] = env.socketTextStream("ant168", 7777)
    stream1.print()
    env.execute("sourcetest")
  }
}

5.加载kafka的topic——重要&常用

import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer
import org.apache.kafka.clients.consumer.ConsumerConfig

import java.util.Properties

object SourceTest {
  def main(args: Array[String]): Unit = {
    // TODO 1.创建环境
    val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
    env.setParallelism(1)

    val properties = new Properties()
    properties.setProperty(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "ant168:9092")
    properties.setProperty(ConsumerConfig.GROUP_ID_CONFIG, "sensorgroup1")
    val stream1: DataStream[String] = env.addSource(new FlinkKafkaConsumer[String]("sensor", new SimpleStringSchema(), properties))
    // 注意:重新启动就不会读取topic之前的数据

    stream1.print()
    env.execute("sourcetest")
  }
}

运行结果:

hello
world
# 1.开启zookeeper和kafka
zkServer.sh status
nohup kafka-server-start.sh /opt/soft/kafka212/config/server.properties &

# 2.创建topic
kafka-topics.sh --create --zookeeper ant168:2181 --topic sensor --partitions 1 --replication-factor 1

# 3.开始生产消息
kafka-console-producer.sh --topic sensor --broker-list ant168:9092
>hello
>world

6.加载自定义数据源

import org.apache.flink.streaming.api.functions.source.SourceFunction
import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment

import scala.util.Random

// 定义一个样例类——温度传感器
case class SensorReading(id: String, timestamp: Long, temperature: Double)

object SourceTest {
  def main(args: Array[String]): Unit = {
    val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
    env.setParallelism(1)

   // TODO 读取自定义数据源
    val stream1: DataStream[SensorReading] = env.addSource(new MySensorSource)

    // TODO 3.输出
    stream1.print()
    env.execute("sourcetest")
  }
}

// 自定义数据源
class MySensorSource() extends SourceFunction[SensorReading] {
  override def run(sourceContext: SourceFunction.SourceContext[SensorReading]): Unit = {
    val random = new Random()
    while (true) {
      val i: Int = random.nextInt()
      sourceContext.collect(SensorReading("生成: " + i, 1, 1))
    }
    Thread.sleep(500)
  }

  override def cancel(): Unit = {
  }
}

运行结果:

SensorReading(生成: -439723144,1,1.0)
SensorReading(生成: -937590179,1,1.0)
SensorReading(生成: -40987764,1,1.0)
SensorReading(生成: 525868361,1,1.0)
SensorReading(生成: -840926328,1,1.0)
SensorReading(生成: -998392768,1,1.0)
SensorReading(生成: -1308765349,1,1.0)
SensorReading(生成: -806454922,1,1.0)

(三)输出端——Sink

1.读取文件中的数据,处理后输出到另一个文件

import nj.zb.kb21.source.SensorReading
import org.apache.flink.api.common.serialization.SimpleStringEncoder
import org.apache.flink.core.fs.Path
import org.apache.flink.streaming.api.functions.sink.filesystem.StreamingFileSink
import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment

object SinkTest {
  def main(args: Array[String]): Unit = {
    val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
    env.setParallelism(1)

    val path = "D:\\javaseprojects\\flinkstu\\resources\\sensor.txt"
    val stream1: DataStream[String] = env.readTextFile(path)

    val dataStream: DataStream[SensorReading] = stream1.map(data => {
      val arr: Array[String] = data.split(",")
      SensorReading(arr(0).trim, arr(1).trim.toLong, arr(2).trim.toDouble)
    })

//    dataStream.print()
//    writeAsCsv方法已过时
//    dataStream.writeAsCsv("D:\\javaseprojects\\flinkstu\\resources\\out.txt")

    dataStream.addSink(
      StreamingFileSink.forRowFormat(
      new Path("D:\\javaseprojects\\flinkstu\\resources\\out1.txt"),
      new SimpleStringEncoder[SensorReading]()
    ).build()
    )

    env.execute("sinktest")
  }
}

out1.txt文件内容:

SensorReading(sensor_1,1684201947,36.8)
SensorReading(sensor_7,1684202000,17.7)
SensorReading(sensor_4,1684202064,20.3)
SensorReading(sensor_2,1684202064,35.8)

2.Source——文件&Sink——Mysql

import nj.zb.kb21.source.SensorReading
import org.apache.flink.configuration.Configuration
import org.apache.flink.streaming.api.functions.sink.{RichSinkFunction, SinkFunction}
import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment

import java.sql.{Connection, DriverManager, PreparedStatement}
/**
 * 将flink处理后的数据传入mysql中
 */
object JdbcSinkTest {
  def main(args: Array[String]): Unit = {
    val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
    env.setParallelism(1) 

    // TODO 从文件中读取数据存入mysql中
    val path = "D:\\javaseprojects\\flinkstu\\resources\\sensor.txt"
    val stream1: DataStream[String] = env.readTextFile(path)

    // TODO 处理文件数据
    val dataStream: DataStream[SensorReading] = stream1.map(data => {
      val arr: Array[String] = data.split(",")
      SensorReading(arr(0).trim, arr(1).trim.toLong, arr(2).trim.toDouble)
    })

    dataStream.addSink(new MyJdbcSink)
    env.execute("jdbc sink test")
  }
}

class MyJdbcSink extends RichSinkFunction[SensorReading] {
  var connection: Connection = _

  var insertState: PreparedStatement = _
  var updateState: PreparedStatement = _

  override def open(parameters: Configuration): Unit = {
    connection = DriverManager.getConnection("jdbc:mysql://192.168.180.141:3306/kb21?useSSL=false", "root", "root")

    insertState = connection.prepareStatement("insert into sensor_temp(id,temp) value (?,?)")
    updateState = connection.prepareStatement("update sensor_temp set temp=? where id=?")
  }

  override def invoke(value: SensorReading, context: SinkFunction.Context): Unit = {
    updateState.setDouble(1, value.temperature)
    updateState.setString(2, value.id)
    val i: Int = updateState.executeUpdate()
    println(i)
    // 当原表中没有数据时,就不能执行update语句,所以影响的行数==0,而是执行insert语句
    // 反之,当原表中有数据,就执行update语句,影响的行数为1
    if (i == 0) {
      insertState.setString(1, value.id)
      insertState.setDouble(2, value.temperature)
      insertState.execute()
    }
  }

  override def close(): Unit = {
    insertState.close()
    updateState.close()
    connection.close()
  }
}

数据源:

D:\javaseprojects\flinkstu\resources\sensor.txt

sensor_1,1684201947,36.8
sensor_2,1684202000,17.7
sensor_1,1684202064,20.3
sensor_2,1684202068,35.8

DataGrip操作:

drop table sensor_temp;
create table sensor_temp(
    id varchar(32),
    temp double
);

select * from sensor_temp;

每次只获取最新的数据。

3.读取kafka的数据,处理后传入mysql中

import nj.zb.kb21.source.SensorReading
import org.apache.flink.api.common.serialization.SimpleStringSchema
import org.apache.flink.configuration.Configuration
import org.apache.flink.streaming.api.functions.sink.{RichSinkFunction, SinkFunction}
import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer
import org.apache.kafka.clients.consumer.ConsumerConfig

import java.sql.{Connection, DriverManager, PreparedStatement}
import java.util.Properties

/**
 * 将flink处理kafka后的数据传入mysql中
 */
object KafkaToMysqlSinkTest {
  def main(args: Array[String]): Unit = {
    val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
    env.setParallelism(1) // 设置并行度

    // TODO 从kafka中读取数据
    val properties = new Properties()
    properties.setProperty(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "ant168:9092")
    properties.setProperty(ConsumerConfig.GROUP_ID_CONFIG, "sensorgroup1")

    // TODO 订阅topic
    val stream1: DataStream[String] = env.addSource(new FlinkKafkaConsumer[String]("sensor", new SimpleStringSchema(), properties))

    // TODO 处理topic数据
    val dataStream: DataStream[SensorReading] = stream1.map(data => {
      val arr: Array[String] = data.split(",")
      SensorReading(arr(0).trim, arr(1).trim.toLong, arr(2).trim.toDouble)
    })

    // TODO 处理后的topic数据存入mysql中
    dataStream.addSink(new MysqlSink)
    env.execute("kafka sink test")
  }
}

class MysqlSink extends RichSinkFunction[SensorReading] {
  var connection: Connection = _

  var insertState: PreparedStatement = _
  var updateState: PreparedStatement = _

  override def open(parameters: Configuration): Unit = {
    connection = DriverManager.getConnection("jdbc:mysql://192.168.180.141:3306/kb21?useSSL=false", "root", "root")

    insertState = connection.prepareStatement("insert into sensor_temp(id,temp) value (?,?)")
    updateState = connection.prepareStatement("update sensor_temp set temp=? where id=?")
  }

  override def invoke(value: SensorReading, context: SinkFunction.Context): Unit = {
    updateState.setDouble(1, value.temperature)
    updateState.setString(2, value.id)
    val i: Int = updateState.executeUpdate()
    println(i)
    // 当原表中没有数据时,就不能执行update语句,所以影响的行数==0,而是执行insert语句
    // 反之,当原表中有数据,就执行update语句,影响的行数为1
    if (i == 0) {
      insertState.setString(1, value.id)
      insertState.setDouble(2, value.temperature)
      insertState.execute()
    }
  }

  override def close(): Unit = {
    insertState.close()
    updateState.close()
    connection.close()
  }
}

kafka生产消息:

[root@ant168 opt]# kafka-console-producer.sh --topic sensor --broker-list ant168:9092
>sensor_1,1684201947,36.8
>sensor_1,1684201947,36.10            
>sensor_2,1684202068,35.8

Mysql数据库:

4.加载kafka中topic的数据,处理后传入另一个topic

import nj.zb.kb21.source.SensorReading
import org.apache.flink.api.common.serialization.SimpleStringSchema
import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
import org.apache.flink.streaming.connectors.kafka.{FlinkKafkaConsumer, FlinkKafkaProducer}
import org.apache.kafka.clients.consumer.ConsumerConfig

import java.util.Properties

/**
 * 将flink处理kafka后的数据传入kafka中
 */
object KafkaToKafkaSinkTest {
  def main(args: Array[String]): Unit = {
    val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
    env.setParallelism(1) // 设置并行度

    // TODO 从kafka中读取数据
    val properties = new Properties()
    properties.setProperty(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "ant168:9092")
    properties.setProperty(ConsumerConfig.GROUP_ID_CONFIG, "sensorgroup1")

    // TODO 订阅topic
    val stream1: DataStream[String] = env.addSource(new FlinkKafkaConsumer[String]("sensor", new SimpleStringSchema(), properties))

    // TODO 处理topic数据
    val dataStream: DataStream[String] = stream1.map(data => {
      val arr: Array[String] = data.split(",")
      SensorReading(arr(0).trim, arr(1).trim.toLong, arr(2).trim.toDouble).toString()
    })

    // TODO 处理后的topic数据存入另一个topic中
    dataStream.addSink(
      new FlinkKafkaProducer[String]("ant168:9092","sensorsinkout",new SimpleStringSchema())
    )
    env.execute("kafka sink test")
  }
}

        注意:这里默认是latest提交方式,如果程序中断,kafka生产者此时传入数据,重新开启该程序,后面传入的数据也会被消费。

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

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

相关文章

ESP32设备驱动-振动电机模块驱动

振动电机模块驱动 文章目录 振动电机模块驱动1、振动电机介绍2、硬件准备3、软件准备4、驱动实现1、振动电机介绍 振动电机是用于产生振动的机械装置。 振动的产生是在驱动轴上质量不均匀的电动机的支持下发生的。 它是一种微型直流电机,通过振动让用户知道声音。 在此必须注…

《计算机网络—自顶向下方法》 Wireshark实验(五):UDP 协议分析

用户数据报(UDP)协议是运输层提供的一种最低限度的复用/分解服务&#xff0c;可以在网络层和正确的用户即进程间传输数据。UDP 是一种不提供不必要服务的轻量级运输协议&#xff0c;除了复用/分用功能和简单的差错检测之外&#xff0c;几乎就是 IP 协议了&#xff0c;也可以说它…

RabbitMQ养成记 (10.高级特性:死信队列,延迟队列)

死信队列&#xff08;DLX&#xff09; 这个概念 在其他MQ产品里面也是有的&#xff0c;只不过在Rabbitmq中稍微特殊一点 什么叫私信队列呢&#xff1f; 就是当消息成为 dead message之后&#xff0c;可以重新发到另外一台交换机&#xff0c;这个交换机就是DLX。 注意这里的有翻…

基于OpenCV的人脸检测软件(含Python源码+UI界面+图文详解)

软件功能演示 摘要&#xff1a;人脸检测的目标是找出图像中所有的人脸对应的位置&#xff0c;算法的输出是人脸外接矩形在图像中的坐标&#xff0c;可能还包括姿态如倾斜角度等信息。本文详细介绍了其实现的技术原理&#xff0c;同时给出完整的Python实现代码&#xff0c;并且通…

GeoTools实战指南: 空间坐标系-地理信息科学的核心

GeoTools实战指南: 空间坐标系-地理信息科学的核心 引言 在我们的日常生活中,地图、GPS导航和地理位置服务已经变得司空见惯。但是,你有没有想过这些工具背后的工作原理呢?它们都依赖于一种称为"空间坐标系"的关键概念。本文将深入探讨空间坐标系的基础知识和其…

多线程专题(上)学习随手笔记

JMM&#xff1a;主内存物理内存线程共享&#xff0c;工作内存CPU缓存线程独占volatile&#xff1a;可见性、禁止指令重排&#xff0c;不可保证原子性&#xff1b;用于懒汉单例模式&#xff08;双重检测&#xff09;或状态标记Synchronized&#xff1a;保证代码块或方法同步化执…

Unity的URP下使用SRPBatcher

大家好&#xff0c;我是阿赵。这里继续来讲一下URP相关的东西。 这次主要说的是SRP Batcher的使用 一、在URP下实现SRP Batcher 1、设置 在我们创建的URPAsset文件的高级选项里面&#xff0c;有一个SRP Batcher的开关&#xff0c;默认就是勾上的。 2、修改shader 在把项目转…

小白白也能学会的 PyQt 教程 —— 自定义组件 Switch Button

文章目录 前言思路讲解代码部分 前言 最近在搞 Python 课程设计&#xff0c;想要搞一个好看的 UI&#xff0c;惊艳全班所有人。但打开 Qt Creator&#xff0c;Win7 风格的复古的按钮是在让我难以下手。 其次&#xff0c;我因为想要打造一个 Fluent UI 样式的设置页面&#xff…

详解c++STL—string组件

目录 一、string基本概念 1、本质 2、string和char * 区别&#xff1a; 3、特点&#xff1a; 二、string构造函数 1、构造函数原型 2、示例 三、string赋值操作 1、赋值的函数原型 2、示例 四、string字符串拼接 1、函数原型 2、示例 五、string查找和替换 1、功…

tomcat目录结构

tomcat服务器安装根目录下有很多子目录&#xff0c;这些目录的作用是&#xff1a; (1)bin&#xff1a;存放了tomcat服务器中的可执行的批处理文件(startup.bat shutdown.bat) (2)conf&#xff1a;存放了tomcat相关的配置文件(其中的server.xml是tomcat服务器核心配置文件) …

26. Pandas处理分析网站原始访问日志

Pandas处理分析网站原始访问日志 目标&#xff1a;真实项目的实战&#xff0c;探索Pandas的数据处理与分析 实例&#xff1a; 数据来源&#xff1a;我自己的wordpress博客蚂蚁学Python – 你有没有为写代码拼过命&#xff1f;那你知不知道 人生苦短&#xff0c;我用Python&am…

Python挑选出无Labelme标注文件的图片文件

Python挑选出无Labelme标注文件的图片文件 前言前提条件相关介绍实验环境Python挑选出无Labelme标注文件的图片文件代码实现输出结果 前言 本文是个人使用Python处理文件的电子笔记&#xff0c;由于水平有限&#xff0c;难免出现错漏&#xff0c;敬请批评改正。 (https://blog.…

【设计原则与思想:总结课】38 | 总结回顾面向对象、设计原则、编程规范、重构技巧等知识点

到今天为止&#xff0c;设计原则和思想已经全部讲完了&#xff0c;其中包括&#xff1a;面向对象、设计原则、规范与重构三个模块的内容。除此之外&#xff0c;我们还学习了贯穿整个专栏的代码质量评判标准。专栏的进度已经接近一半&#xff0c;马上就要进入设计模式内容的学习…

Python: 生成ubuntu apt镜像地址

文章目录 1. 目的2. 设计3. 实现4. 调用5. 参考 1. 目的 每次新配置 Ubuntu 系统&#xff0c;免不了配置 apt 源。尽管可以通过 GUI 界面进行选择&#xff0c;但自动化程度不够&#xff0c;不同桌面&#xff08;Unity/Gnome/KDE&#xff09;下的界面也不太一样&#xff1b; 使…

Java基础-sleep和wait的区别

本文介绍Java中sleep和wait方法的使用区别 文章目录 sleep()wait()sleep()和wait()对比区别相同点 sleep() 查看sleep方法&#xff0c;可见其是static native方法 public static native void sleep(long millis) throws InterruptedException;sleep()方法需要指定等待的时间。…

HTTP第14讲——HTTP传输大文件的方法

背景 HTTP 可以传输很多种类的数据&#xff0c;不仅是文本&#xff0c;也能传输图片、音频和视频。 早期互联网上传输的基本上都是只有几 K 大小的文本和小图片&#xff0c;现在的情况则大有不同。网页里包含的信息实在是太多了&#xff0c;随随便便一个主页 HTML 就有可能上百…

java常用集合

java集合又是一个新世界了&#xff0c;从前在我刚接触java的时候&#xff0c;一直在纠结 集合这东西到底有啥用&#xff0c;后来代码写的多了。才开始学习集合 集合也叫容器。顾名思意 就是存放对象的器皿。 主要是由两大接口派生而来 &#xff1a;一个是 Collecton接口&#…

LeetCode高频算法刷题记录2

文章目录 1. 最大子数组和【简单】1.1 题目描述1.2 解题思路1.3 代码实现 2. 合并两个有序链表【简单】2.1 题目描述2.2 解题思路2.3 代码实现 3. 两数之和【简单】3.1 题目描述3.2 解题思路3.3 代码实现 4. 二叉树的层序遍历【中等】4.1 题目描述4.2 解题思路4.3 代码实现 5. …

代码随想录算法训练营第四十二天 | 背包问题

背包问题 理论 基础&#xff1a;二维 文档讲解&#xff1a;代码随想录 (programmercarl.com) 视频讲解&#xff1a;带你学透0-1背包问题&#xff01;| 关于背包问题&#xff0c;你不清楚的地方&#xff0c;这里都讲了&#xff01;| 动态规划经典问题 | 数据结构与算法_哔哩哔哩…

Revit SDK:ErrorHandling

前言 本文介绍 Revit 的错误处理机制。 内容 程序员对错误处理的定义和理解 程序的错误处理机制可以分为两种类型&#xff1a;错误返回码和异常捕捉。 错误返回码是指在程序中遇到错误时&#xff0c;通过函数返回值来表明错误的类型和信息。错误返回码可以在程序中被预测和…