Flume实战--Flume中的拦截器详解与操作

news2024/9/29 11:37:42

        在处理大规模数据流时,Apache Flume 是一款功能强大的数据聚合工具,它可以通过拦截器在运行时对Event进行修改或丢弃。本文将详细讲解Flume中的拦截器,包括时间戳拦截器、Host添加拦截器、静态拦截器以及如何自定义拦截器。

拦截器

拦截器的作用

拦截器用于在事件流经Flume时,对其进行拦截、处理(比如修改、增强)、或者丢弃。

1. 时间戳拦截器

        时间戳拦截器是Flume中非常实用的一个功能,它会自动为每个Event的header添加一个当前的时间戳。这对于后续的数据存储和分析非常有用,尤其是在需要时间序列数据的场景中。

使用场景

        当数据需要带有时间戳存储到HDFS,并且HDFS的目录结构中包含时间转义字符时,这个拦截器非常有用。

配置示例

a1.sources.r1.interceptors = i1   
i1 是拦截器的名字,自己定义的
a1.sources.r1.interceptors.i1.type = timestamp   
指定i1 这个拦截器的类型

hdfs中,如果文件夹使用了时间相关的转义字符,比如

a1.channels = c1
a1.sinks = k1
a1.sinks.k1.type = hdfs
a1.sinks.k1.channel = c1
a1.sinks.k1.hdfs.path = /flume/events/%y-%m-%d/%H%M/%S
a1.sinks.k1.hdfs.filePrefix = events-
a1.sinks.k1.hdfs.round = true
a1.sinks.k1.hdfs.roundValue = 10
a1.sinks.k1.hdfs.roundUnit = minute

a1.sinks.k1.hdfs.useLocalTimeStamp =true

也可以使用时间戳拦截器


a1.sources = r1
a1.channels = c1
a1.sources.r1.type = exec
a1.sources.r1.command = tail -F /opt/data/c.txt

a1.sources.r1.channels = c1

a1.channels.c1.type = memory
a1.channels.c1.capacity = 10000
a1.channels.c1.transactionCapacity = 10000

a1.sinks = k1
a1.sinks.k1.type = hdfs
a1.sinks.k1.channel = c1
a1.sinks.k1.hdfs.path = /flume/events/%y-%m-%d/%H%M/
# round 用于控制含有时间转义符的文件夹的生成规则
a1.sinks.k1.hdfs.round = true
a1.sinks.k1.hdfs.roundValue = 10
a1.sinks.k1.hdfs.roundUnit = minute
# i1 是拦截器的名字,自己定义的
a1.sources.r1.interceptors = i1    
a1.sources.r1.interceptors.i1.type = timestamp

因为必须保证header中有时间戳timestamp这个KV键值对。

假如hdfs中使用了时间转义字符,此时必须指定时间,两种方案

1)使用本地时间戳

a1.sinks.k1.hdfs.useLocalTimeStamp =true

2)使用时间拦截器

a1.sources.r1.interceptors = i1

a1.sources.r1.interceptors.i1.type = timestamp

 

2. Host添加拦截器

        Host拦截器可以将数据来源的主机名或IP地址添加到Event的header中。这对于追踪数据来源和进行数据分析时识别数据源非常有用。

配置示例

a1.sources = r1  
a1.channels = c1
a1.sinks = s1

a1.sources.r1.type= http
a1.sources.r1.bind = bigdata01
a1.sources.r1.port = 6666

a1.sources.r1.interceptors=i2

a1.sources.r1.interceptors.i2.type=host
a1.sources.r1.interceptors.i2.preserveExisting=false
a1.sources.r1.interceptors.i2.useIP=true
a1.sources.r1.interceptors.i2.hostHeader=hostname
# hostname=192.168.233.128
a1.channels.c1.type=memory
a1.channels.c1.capacity=1000
a1.channels.c1.transactionCapacity=100

a1.sinks.s1.type=hdfs
a1.sinks.s1.hdfs.path=/flume/%Y/%m/%d/%H%M
a1.sinks.s1.hdfs.filePrefix=%{hostname}
a1.sinks.s1.hdfs.fileSuffix=.log

a1.sinks.s1.hdfs.rollInterval=60

a1.sinks.s1.hdfs.round=true
a1.sinks.s1.hdfs.roundValue=10
a1.sinks.s1.hdfs.roundUnit=second
a1.sinks.s1.hdfs.useLocalTimeStamp=true

a1.sources.r1.channels=c1
a1.sinks.s1.channel=c1


这个例子可以完美的说明host拦截器是干嘛的,拦截住之后 在Header中添加一个 hostname=192.168.32.128
在hdfs想使用hostname的时候,就可以通过%{hostname}

9870 hdfs的web访问端口
9820 是hdfs底层进行通信的端口

jps -ml 查看java进行,带详细信息

 测试

curl 起始就是通过命令模拟浏览器
curl http://www.baidu.com
curl http://bigdata01:9870/dfshealth.html#tab-overview
curl -X POST -d '[{"headers":{"state":"USER"},"body":"this my multiplex to c1"}]' http://bigdata01:6666

3. 静态拦截器

        静态拦截器允许我们在Event的header中添加自定义的静态键值对。这在需要为数据添加额外信息时非常有用,比如添加特定的标签或分类信息。

配置示例

a1.sources.r1.interceptors = i3
a1.sources.r1.interceptors.i3.type = static
a1.sources.r1.interceptors.i3.key = name
a1.sources.r1.interceptors.i3.value = zhangsan

自定义拦截器

        Flume支持自定义拦截器,这为处理特定的数据格式或进行复杂的数据转换提供了可能。通过编写Java代码实现自定义的拦截器,我们可以对接收到的数据进行任意形式的处理。

实现步骤

  1. 创建Maven项目:导入必要的Flume和JSON处理库(如Jackson或Fastjson)。
  2. 实现Interceptor接口:编写拦截器逻辑。
  3. 打包:将编写的拦截器打包成JAR文件,并放入Flume的lib目录下。
  4. 在Flume配置文件中配置自定义拦截器。

需求

处理数据样例:
log='{
"host":"www.baidu.com",
"user_id":"13755569427",
"items":[
    {
        "item_type":"eat",
        "
        
        
        active_time":156234
    },
    {
        "item_type":"car",
        "active_time":156233
    }
 ]
}'

结果样例:
[{"active_time":156234,"user_id":"13755569427","item_type":"eat","host":"www.baidu.com"},
{"active_time":156233,"user_id":"13755569427","item_type":"car","host":"www.baidu.com"}]

创建一个maven项目

导入jar包

 xml文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.bigdata</groupId>
    <artifactId>MyInterceptor</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.apache.flume/flume-ng-core -->
        <dependency>
            <groupId>org.apache.flume</groupId>
            <artifactId>flume-ng-core</artifactId>
            <version>1.9.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.48</version>
        </dependency>
    </dependencies>

    <!--可以使用maven中的某些打包插件,不仅可以帮助我们打包代码还可以打包所依赖的jar包-->

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.1.1</version>
                <configuration>
                    <!-- 禁止生成 dependency-reduced-pom.xml-->
                    <createDependencyReducedPom>false</createDependencyReducedPom>
                </configuration>
                <executions>
                    <!-- Run shade goal on package phase -->
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <relocations>
                                <relocation>
                                    <!-- 解决包冲突 进行转换-->
                                    <pattern>com.google.protobuf</pattern>
                                    <shadedPattern>shaded.com.google.protobuf</shadedPattern>
                                </relocation>
                            </relocations>
                            <artifactSet>
                                <excludes>
                                    <exclude>log4j:*</exclude>
                                </excludes>
                            </artifactSet>
                            <filters>
                                <filter>
                                    <!-- Do not copy the signatures in the META-INF folder.
                                    Otherwise, this might cause SecurityExceptions when using the JAR. -->
                                    <artifact>*:*</artifact>
                                    <excludes>
                                        <exclude>META-INF/*.SF</exclude>
                                    </excludes>
                                </filter>
                            </filters>
                            <transformers>
                                <!-- 某些jar包含具有相同文件名的其他资源(例如属性文件)。 为避免覆盖,您可以选择通过将它们的内容附加到一个文件中来合并它们-->
                                <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                                    <resource>reference.conf</resource>
                                </transformer>
                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>mainclass</mainClass>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>


</project>

打包插件: 

builder --> plugins --> plugin

插件
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-shade-plugin</artifactId>
  <version>3.1.1</version>
  <configuration>
    <!-- 禁止生成 dependency-reduced-pom.xml-->
    <createDependencyReducedPom>false</createDependencyReducedPom>
  </configuration>
  <executions>
    <!-- Run shade goal on package phase -->
    <execution>
      <phase>package</phase>
      <goals>
        <goal>shade</goal>
      </goals>
      <configuration>
        <relocations>
          <relocation>
            <!-- 解决包冲突 进行转换-->
            <pattern>com.google.protobuf</pattern>
            <shadedPattern>shaded.com.google.protobuf</shadedPattern>
          </relocation>
        </relocations>
        <artifactSet>
          <excludes>
            <exclude>log4j:*</exclude>
          </excludes>
        </artifactSet>
        <filters>
          <filter>
            <!-- Do not copy the signatures in the META-INF folder.
                                    Otherwise, this might cause SecurityExceptions when using the JAR. -->
            <artifact>*:*</artifact>
            <excludes>
              <exclude>META-INF/*.SF</exclude>
            </excludes>
          </filter>
        </filters>
        <transformers>
          <!-- 某些jar包含具有相同文件名的其他资源(例如属性文件)。 为避免覆盖,您可以选择通过将它们的内容附加到一个文件中来合并它们-->
          <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
            <resource>reference.conf</resource>
          </transformer>
          <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
            <mainClass>mainclass</mainClass>
          </transformer>
        </transformers>
      </configuration>
    </execution>
  </executions>
            </plugin>
示例代码

先测试一下:

json --> java 代码解析 json --> 实体 ,实体-->json 字符串 都需要使用工具

jackson、fastjson(阿里巴巴)

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class TestJson {

    public static void main(String[] args) {
        String log="{\n" +
        "                 'host':'www.baidu.com',\n" +
        "                 'user_id':'13755569427',\n" +
        "                 'items':[\n" +
        "                     {\n" +
        "                         'item_type':'eat',\n" +
        "                         'active_time':156234\n" +
        "                        },\n" +
        "                     {\n" +
        "                         'item_type':'car',\n" +
        "                         'active_time':156233\n" +
        "                     }\n" +
        "                  ]\n" +
        "}";

        JSONObject jsonObject = JSON.parseObject(log);
        String host = jsonObject.getString("host");
        String user_id = jsonObject.getString("user_id");
        System.out.println(host);
        System.out.println(user_id);
        JSONArray items = jsonObject.getJSONArray("items");

        List list =new ArrayList<Map<String,String>>();



        for (Object item : items) {
            // {"active_time":156234,"item_type":"eat"}
            Map map = new HashMap<String,String>();
            String itemStr = item.toString();
            JSONObject jsonItem = JSON.parseObject(itemStr);
            String active_time = jsonItem.getString("active_time");
            String item_type = jsonItem.getString("item_type");
            System.out.println(active_time);
            System.out.println(item_type);
            map.put("active_time",active_time);
            map.put("user_id",user_id);
            map.put("item_type",item_type);
            map.put("host",host);
            list.add(map);
        }

        /**
         *  需要转化为:
         *      *      * [{"active_time":156234,"user_id":"13755569427","item_type":"eat","host":"www.baidu.com"},
         *      *      * {"active_time":156233,"user_id":"13755569427","item_type":"car","host":"www.baidu.com"}]
         */


        String jsonString = JSON.toJSONString(list);
        System.out.println(jsonString);
    }
}
package com.bigdata;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.flume.Context;
import org.apache.flume.Event;
import org.apache.flume.interceptor.Interceptor;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class DemoInterceptor implements Interceptor {
    @Override
    public void initialize() {

    }

    // 只需要关注 这个方法的写法
    /**
     *  需求:
     *  log='{
     * "host":"www.baidu.com",
     * "user_id":"13755569427",
     * "items":[
     *     {
     *         "item_type":"eat",
     *         "active_time":156234
     *     },
     *     {
     *         "item_type":"car",
     *         "active_time":156233
     *     }
     *  ]
     * }'
     *
     * 需要转化为:
     * [{"active_time":156234,"user_id":"13755569427","item_type":"eat","host":"www.baidu.com"},
     * {"active_time":156233,"user_id":"13755569427","item_type":"car","host":"www.baidu.com"}]
     */
    @Override
    public Event intercept(Event event) {
        // 解析 文本数据变为另一种格式
        byte[] body = event.getBody();
        String content = new String(body);
        /**
         *  {
         *      "host":"www.baidu.com",
         *      "user_id":"13755569427",
         *      "items":[
         *          {
         *              "item_type":"eat",
         *              "active_time":156234
         *          },
         *          {
         *              "item_type":"car",
         *              "active_time":156233
         *          }
         *       ]
         *   }
         */
        // 将一个json字符串变为 json 对象
        JSONObject jsonObject = JSON.parseObject(content);
        // 通过对象 获取 json 中的值
        String host = jsonObject.getString("host");
        String user_id = jsonObject.getString("user_id");
        // 通过对象获取json 数组
        JSONArray items = jsonObject.getJSONArray("items");

        // 定义一个集合,集合中是map
        ArrayList<HashMap<String, String>> list = new ArrayList<>();

        for (Object object: items) {

            String obj = object.toString();
            JSONObject jobj = JSON.parseObject(obj);
            String item_type = jobj.getString("item_type");
            String active_time = jobj.getString("active_time");

            HashMap<String, String> map = new HashMap<>();
            map.put("active_time",active_time);
            map.put("item_type",item_type);
            map.put("host",host);
            map.put("user_id",user_id);

            list.add(map);
        }

        // 将对象变为字符串
        String s = JSON.toJSONString(list);
        event.setBody(s.getBytes());

        return event;
    }

    // 这个方法可以调取 上面这个方法
    @Override
    public List<Event> intercept(List<Event> list) {

        for (int i=0;i<list.size();i++) {
            Event oldEvent = list.get(i);
            Event newEvent = intercept(oldEvent);
            list.set(i,newEvent);
        }
        return list;
    }

    @Override
    public void close() {

    }

    // 作用只有一个,就是new 一个自定义拦截器的类
    public static class BuilderEvent implements Builder{

        @Override
        public Interceptor build() {
            return new DemoInterceptor();
        }

        @Override
        public void configure(Context context) {

        }
    }
}

 

打包,上传至 flume 下的lib 下。

测试

编写一个flume脚本文件

testInter.conf

a1.sources = s1
a1.channels = c1
a1.sinks = r1

a1.sources.s1.type = TAILDIR

#以空格分隔的文件组列表。每个文件组表示要跟踪的一组文件
a1.sources.s1.filegroups = f1
#文件组的绝对路径
a1.sources.s1.filegroups.f1=/home/b.log

#使用自定义拦截器
a1.sources.s1.interceptors = i1
a1.sources.s1.interceptors.i1.type = com.bigdata.DemoInterceptor$BuilderEvent

a1.channels.c1.type = file
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100


a1.sinks.r1.type = hdfs
a1.sinks.r1.hdfs.path = /flume/202409
a1.sinks.r1.hdfs.fileSuffix= .log

# 将上传的数据格式使用text类型,便于查看
a1.sinks.r1.hdfs.fileType=DataStream
a1.sinks.r1.hdfs.writeFormat=Text


a1.sources.s1.channels = c1
a1.sinks.r1.channel = c1
运行该脚本
flume-ng agent -c ./ -f testInterceptor.conf -n a1 -Dflume.root.logger=INFO,console

 出现错误

此时,说明我们打包的时候没有将这个jar包打包到自定义的jar包,可以通过手动的提交的方式解决这个问题。

将fast-json.jar 放入到 flume/lib

通过网盘分享的文件:fastjson-1.2.48.jar

假如你使用了打包插件,已经将这个 fast-json 打入了你的 jar 包中,无需该操作。

{"host":"www.baidu.com","user_id":"13755569427","items":[{"item_type":"eat","active_time":156234},{"item_type":"car","active_time":156233}]}

接着开始进行测试,必须先启动flume

编写一个脚本,模拟 b.log 中不断的产生json数据的场景。

#!/bin/bash
log='{
"host":"www.baidu.com",
"user_id":"13755569427",
"items":[
{
"item_type":"eat",
"active_time":156234
},
{
"item_type":"car",
"active_time":156233
}
]
}'
echo $log >> /home/b.log

保存,并且赋予权限:

chmod 777 createJson.sh

执行这个脚本,就可以模拟不断的向  b.log中传输数据了
./createJson.sh

 视频链接

10-时间戳拦截器_哔哩哔哩_bilibili

11-host拦截器_哔哩哔哩_bilibili

12-静态拦截器_哔哩哔哩_bilibili

13-自定义拦截器一_哔哩哔哩_bilibili

14-自定义拦截器二_哔哩哔哩_bilibili

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

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

相关文章

《HelloGitHub》第 102 期

兴趣是最好的老师&#xff0c;HelloGitHub 让你对编程感兴趣&#xff01; 简介 HelloGitHub 分享 GitHub 上有趣、入门级的开源项目。 github.com/521xueweihan/HelloGitHub 这里有实战项目、入门教程、黑科技、开源书籍、大厂开源项目等&#xff0c;涵盖多种编程语言 Python、…

LeetCode - #124 二叉树中的最大路径和(Top 100)

文章目录 前言1. 描述2. 示例3. 答案关于我们前言 本题为 LeetCode 前 100 高频题 我们社区陆续会将顾毅(Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 LeetCode 算法到目前我们已经更新到 123 期…

Electron 隐藏顶部菜单

隐藏前&#xff1a; 隐藏后&#xff1a; 具体设置代码&#xff1a; 在 main.js 中加入这行即可&#xff1a; // 导入模块 const { app, BrowserWindow ,Menu } require(electron) const path require(path)// 创建主窗口 const createWindow () > {const mainWindow ne…

Qemu开发ARM篇-6、emmc/SD卡AB分区镜像制作并通过uboot进行挂载启动

文章目录 1、AB分区镜像制作2、uboot修改3、镜像启动 在上一篇 Qemu开发ARM篇-5、buildroot制作根文件系统并挂载启动中&#xff0c;我们通过buildroot制作了根文件系统&#xff0c;并通过 SD卡的形式将其挂载到设备并成功进行了启动&#xff0c;但上一章中&#xff0c;我们的…

启动 Ntopng 服务前需先启动 redis 服务及 Ntopng 常用参数介绍

启动Ntopng服务之前需要先启动redis服务&#xff0c;因为Ntopng服务依赖于redis服务的键值存储。 服务重启 服务启动 Ntopng常用参数&#xff1a; -d 将 Ntopng 进程放入后台执行。默认情况下&#xff0c;Ntop 在前台运行。 -u 指定启动Ntopng执行的用户&#xff0c;默认为…

[论文精读]TorWard: Discovery, Blocking, and Traceback of Malicious Traffic Over Tor

期刊名称&#xff1a;IEEE Transactions on Information Forensics and Security 发布链接&#xff1a;TorWard: Discovery, Blocking, and Traceback of Malicious Traffic Over Tor | IEEE Journals & Magazine | IEEE Xplore 中文译名&#xff1a;TorWard&#xff1a;…

2024大二上js高级+ES6学习9.26(闭包,递归函数)

9.26.2024 1.闭包 什么是闭包&#xff1a; 闭包的作用&#xff1a; Return 的函数作为fn的子函数&#xff0c;可以使用fn的局部变量num&#xff0c;局部变量num要等所有使用它的函数调用完毕后才销毁 2.闭包的案例 点击li会发现输出4 在 JavaScript 中&#xff0c;事件处理器&…

C语言 | Leetcode C语言题解之第443题压缩字符串

题目&#xff1a; 题解&#xff1a; void swap(char *a, char *b) {char t *a;*a *b, *b t; }void reverse(char *a, char *b) {while (a < b) {swap(a, --b);} }int compress(char *chars, int charsSize) {int write 0, left 0;for (int read 0; read < charsSi…

软考论文《论模型驱动架构设计方法及其应用》精选试读

论文真题 模型驱动架构设计是一种用于应用系统开发的软件设计方法&#xff0c;以模型构造、模型转换和精化为核心&#xff0c;提供了一套软件设计的指导规范。在模型驱动架构环境下&#xff0c;通过创建出机器可读和高度抽象的模型实现对不同问题域的描述&#xff0c;这些模型…

【HTTP(3)】(状态码,https)

【认识状态码】 状态码最重要的目的&#xff0c;就是反馈给浏览器:这次请求是否成功&#xff0c;若失败&#xff0c;则出现失败原因 常见状态码: 200:OK&#xff0c;表示成功 404:Not Found&#xff0c;浏览器访问的资源在服务器上没有找到 403:Forbidden&#xff0c;访问被…

你还在用Java8吗?

Java 11 在企业中&#xff0c;Java的不同版本使用情况随着时间在不断变化。根据最新的数据报告&#xff0c;以下是一些关键点&#xff1a; Java 11 和 Java 17 成为企业中最常用的长期支持&#xff08;LTS&#xff09;版本&#xff0c;使用率分别为 48% 和 45%&#xff0c;而 …

rtp协议:rtp固定头部介绍

前言&#xff1a; 大家好&#xff0c;今天开始给大家分享rtp协议的相关详细介绍&#xff0c;关于rtsp的介绍&#xff0c;大家可以暂时看官方的文档&#xff1a; https://datatracker.ietf.org/doc/html/rfc2326 本文主要是介绍rtp协议&#xff0c;也就是在开发rtsp过程进行传输…

微积分-反函数6.3(对数函数)

如果 b > 0 b > 0 b>0 且 b ≠ 1 b \neq 1 b1&#xff0c;则指数函数 f ( x ) b x f(x) b^x f(x)bx 不是递增就是递减&#xff0c;因此它是通过水平线测试的单调函数。所以它具有反函数 f − 1 f^{-1} f−1&#xff0c;称为以 b b b 为底的对数函数&#xff…

【数据结构】链表(2)

【LinkedList的模拟实现】 这是java中的一个集合类&#xff0c;可以当成链表来使用&#xff0c;作为链表时&#xff0c;它视为包含三个域&#xff0c;是一个双向链表 【构建LinkedList框架】 public class MyLinkedList {static class ListNode{public int val;public ListNo…

Qt/C++如何选择使用哪一种地图内核/不同地图的优缺点/百度高德腾讯地图/天地图/谷歌地图

一、前言说明 最近花了大半年时间&#xff0c;专门研究这个地图组件&#xff0c;几乎把各种地图的官网的手册翻了个遍&#xff0c;亲自写代码验证了一遍&#xff0c;各种API函数接口和功能全部实战一遍&#xff0c;然后从中提取共性&#xff0c;做出了基类&#xff0c;以及通用…

使用 Light Chaser 进行大屏数据可视化

引言 在当今数据驱动的世界中&#xff0c;数据可视化变得越来越重要。Light Chaser 是一款基于 React 技术栈的大屏数据可视化设计工具&#xff0c;通过简单的拖拽操作&#xff0c;你可以快速生成漂亮、美观的数据可视化大屏和看板。本文将介绍如何使用 Light Chaser 进行数据…

改善大模型 RAG 效果:结合检索和重排序模型

最近这一两周不少大厂都已经开始秋招面试了。 不同以往的是&#xff0c;当前职场环境已不再是那个双向奔赴时代了。求职者在变多&#xff0c;HC 在变少&#xff0c;岗位要求还更高了。 最近&#xff0c;我们又陆续整理了很多大厂的面试题&#xff0c;帮助一些球友解惑答疑&am…

【含文档】基于Springboot+Vue的个人博客系统(含源码+数据库+lw)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 系统定…

【吊打面试官系列-MySQL面试题】优化MySQL数据库的方法?

大家好&#xff0c;我是锋哥。今天分享关于【优化MySQL数据库的方法?】面试题&#xff0c;希望对大家有帮助&#xff1b; 优化MySQL数据库的方法? 1、选取最适用的字段属性&#xff0c;尽可能减少定义字段宽度&#xff0c;尽量把字段设置 NOTNULL&#xff0c; 例如’省份’、…

大数据新视界 --大数据大厂之基于 MapReduce 的大数据并行计算实践

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…