Flink时间语义 | 大数据技术

news2024/12/22 19:14:34

简单说两句

✨ 正在努力的小叮当~
💖 超级爱分享,分享各种有趣干货!
👩‍💻 提供:模拟面试 | 简历诊断 | 独家简历模板
🌈 感谢关注,关注了你就是我的超级粉丝啦!
🔒 以下内容仅对你可见~

作者:小叮当撩代码CSDN后端领域新星创作者 |阿里云专家博主

CSDN个人主页:小叮当撩代码

🔎GZH哆啦A梦撩代码

🎉欢迎关注🔎点赞👍收藏⭐️留言📝

文章目录

    • ❤️时间语义
      • 💕时间的分类
    • 💛水位线Watermark
      • ✅水位线
      • 🍏分布式环境下水位线的传播
      • 🍊代码实战
      • 🌽自定义水位线生成器
        • 🌶️周期性水位线生成器(Periodic Generator)
        • 🫑断点式水位线生成器(Punctuated Generator)
      • 🧃迟到数据处理
        • 🫖**设置窗口延迟关闭**
        • ☕️**使用侧流接收迟到的数据**

image-20240506222727961

❤️时间语义

image-20240506222754341

💕时间的分类

Flink中,时间通常分为三类

image-20240502214701589

EventTime:事件(数据)时间,是事件/数据真真正正发生时/产生时的时间

IngestionTime:摄入时间,是事件/数据到达流处理系统的时间

ProcessingTime:处理时间,是事件/数据被处理/计算时的系统的时间

image-20240502214730266

💛水位线Watermark

✅水位线

Flink的三种时间语义中,处理时间摄入时间都可以不用设置Watermark。如果我们要使用事件时间Event Time语义,以下两项配置缺一不可:

  • 使用一个时间戳为数据流中每个事件的Event Time赋值
  • 生成Watermark

​ Event Time是每个事件的元数据,如果不设置,Flink并不知道每个事件的发生时间,我们必须要为每个事件的Event Time赋值一个时间戳。

​ 有了Event Time时间戳,我们还必须生成Watermark。Watermark是Flink插入到数据流中的一种特殊的数据结构,它包含一个时间戳,并假设后续不会有小于该时间戳的数据。下图展示了一个乱序数据流,其中方框是单个事件,方框中的数字是其对应的Event Time时间戳,圆圈为Watermark,圆圈中的数字为Watermark对应的时间戳。

一个包含Watermark的乱序数据流

image-20240502233750045

Watermark = 当前最大的事件时间 - 最大允许的延迟时间(或最大允许的乱序度时间)

Watermark 是一个单独计算出来的时间戳
Watermark可以通过改变窗口的触发时机 在 一定程度上解决数据乱序或延迟达到的问题
Watermark >= 窗口结束时间 时 就会触发窗口计算(窗口中得有数据)
延迟或乱序严重的数据还是丢失, 但是可以通过调大最大允许的延迟时间(乱序度) 来解决, 或 使用侧道输出流来单独收集延迟或乱序严重的数据,保证数据不丢失!

🍏分布式环境下水位线的传播

在多并行度下,每个并行有一个水印

比如并行度是6,那么程序中就有6个watermark

分别属于这6个并行度(线程)

那么,触发条件以6个水印中最小的那个为准

平时测试水位线强烈建议将并行度设为1

🍊代码实战

需求

实时模拟生成订单数据,格式为: (订单ID,用户ID,时间戳/事件时间,订单金额)

要求每隔5s,计算5秒内,每个用户的订单总金额

并添加Watermark来解决一定程度上的数据延迟和数据乱序问题。

我们循序渐进先写一版没有Watermark的

代码清单


import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.flink.api.common.RuntimeExecutionMode;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.datastream.KeyedStream;
import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.functions.source.SourceFunction;
import org.apache.flink.streaming.api.windowing.assigners.TumblingProcessingTimeWindows;
import org.apache.flink.streaming.api.windowing.time.Time;

import java.text.SimpleDateFormat;
import java.util.Random;
import java.util.UUID;

/**
 * @author tiancx
 */
public class WatermarkDemo {


    @Data  // set get toString
    @AllArgsConstructor
    @NoArgsConstructor
    public static class OrderInfo {
        //格式化的时间
        private String time;
        private String orderId;
        private int uid;
        private int money;
        private long timeStamp;
    }

    public static class MySource implements SourceFunction<OrderInfo> {
        boolean flag = true;

        @Override
        public void run(SourceFunction.SourceContext ctx) throws Exception {
            // 源源不断的产生数据
            Random random = new Random();
            while (flag) {
                OrderInfo orderInfo = new OrderInfo();
                orderInfo.setOrderId(UUID.randomUUID().toString());
                orderInfo.setUid(random.nextInt(3));
                orderInfo.setMoney(random.nextInt(101));
                orderInfo.setTimeStamp(System.currentTimeMillis());
                long timeStamp = orderInfo.getTimeStamp();
                //转成yyyy-MM-dd HH:mm:ss
                String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(timeStamp);
                orderInfo.setTime(format);
                System.out.println("数据:" + orderInfo);
                ctx.collect(orderInfo);
                Thread.sleep(1000);// 间隔1s
            }
        }

        // source 停止之前需要干点啥
        @Override
        public void cancel() {
            flag = false;
        }
    }

    public static void main(String[] args) throws Exception {
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        env.setRuntimeMode(RuntimeExecutionMode.AUTOMATIC);
        //加载数据
        DataStreamSource<OrderInfo> source = env.addSource(new MySource());
        //keyby分组
        KeyedStream<OrderInfo, Integer> keyBy = source.keyBy(OrderInfo::getUid);
        //开窗计算(滚动窗口)
        SingleOutputStreamOperator<OrderInfo> sum = keyBy.window(TumblingProcessingTimeWindows.of(Time.seconds(5)))
                .sum("money");
        sum.print();
        env.execute();
    }


}

我们再写一版有水位线的

代码清单


import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.flink.api.common.RuntimeExecutionMode;
import org.apache.flink.api.common.eventtime.SerializableTimestampAssigner;
import org.apache.flink.api.common.eventtime.WatermarkStrategy;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.datastream.KeyedStream;
import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.functions.source.SourceFunction;
import org.apache.flink.streaming.api.functions.windowing.WindowFunction;
import org.apache.flink.streaming.api.windowing.assigners.TumblingEventTimeWindows;
import org.apache.flink.streaming.api.windowing.time.Time;
import org.apache.flink.streaming.api.windowing.windows.TimeWindow;
import org.apache.flink.util.Collector;

import java.text.SimpleDateFormat;
import java.time.Duration;
import java.util.Random;
import java.util.UUID;

/**
 * @author tiancx
 */
public class WatermarkDemo {


    @Data  // set get toString
    @AllArgsConstructor
    @NoArgsConstructor
    public static class OrderInfo {
        //格式化的时间
        private String time;
        private String orderId;
        private int uid;
        private int money;
        private long timeStamp;
    }

    public static class MySource implements SourceFunction<OrderInfo> {
        boolean flag = true;

        @Override
        public void run(SourceFunction.SourceContext ctx) throws Exception {
            // 源源不断的产生数据
            Random random = new Random();
            while (flag) {
                OrderInfo orderInfo = new OrderInfo();
                orderInfo.setOrderId(UUID.randomUUID().toString());
                orderInfo.setUid(random.nextInt(3));
                orderInfo.setMoney(random.nextInt(101));
                orderInfo.setTimeStamp(System.currentTimeMillis() - 1000 * 2);
                long timeStamp = orderInfo.getTimeStamp();
                //转成yyyy-MM-dd HH:mm:ss
                String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(timeStamp);
                orderInfo.setTime(format);
//                System.out.println("数据:" + orderInfo);
                ctx.collect(orderInfo);
                Thread.sleep(1000);// 间隔1s
            }
        }

        // source 停止之前需要干点啥
        @Override
        public void cancel() {
            flag = false;
        }
    }

    public static void main(String[] args) throws Exception {
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        env.setRuntimeMode(RuntimeExecutionMode.AUTOMATIC);
        env.setParallelism(1);
        //加载数据
        DataStreamSource<OrderInfo> source = env.addSource(new MySource());
        // 在转换算子之前,加载数据之后,添加水印
        // 添加使用event以及watermark进行操作
        SingleOutputStreamOperator<OrderInfo> watermarks = source.assignTimestampsAndWatermarks(
                WatermarkStrategy.<OrderInfo>forBoundedOutOfOrderness(Duration.ofSeconds(3))
                        .withTimestampAssigner(new SerializableTimestampAssigner<OrderInfo>() {
                            @Override
                            public long extractTimestamp(OrderInfo element, long recordTimestamp) {
                                System.out.println("数据:" + element + "系统时间:" + recordTimestamp);
                                return element.getTimeStamp();
                            }
                        }));
        //keyby分组
        KeyedStream<OrderInfo, Integer> keyBy = watermarks.keyBy(OrderInfo::getUid);
        //开窗计算(滚动窗口)
        SingleOutputStreamOperator<String> sum = keyBy.window(TumblingEventTimeWindows.of(Time.seconds(5)))
                .apply(new WindowFunction<OrderInfo, String, Integer, TimeWindow>() {
                    @Override
                    public void apply(Integer key, TimeWindow window, Iterable<OrderInfo> input, Collector<String> out) throws Exception {
                        String startTime = DateFormatUtils.format(window.getStart(), "yyyy-MM-dd HH:mm:ss");
                        String endTime = DateFormatUtils.format(window.getEnd(), "yyyy-MM-dd HH:mm:ss");
                        String waterTime = DateFormatUtils.format(window.maxTimestamp(), "yyyy-MM-dd HH:mm:ss");
                        int sumMoney = 0;
                        for (OrderInfo orderInfo : input) {
                            sumMoney += orderInfo.getMoney();
                        }
                        out.collect("uid=" + key + ",starttime=" + startTime + ",endTime=" + endTime + ",totalMoney=" + sumMoney);
                    }
                });
        sum.print("窗口计算:");
        env.execute();
    }

我们看下运行结果

image-20240504165256836

🌽自定义水位线生成器

我们上面使用的是Flink帮我们内置的

我们还可以使用自定义水位线生成器

🌶️周期性水位线生成器(Periodic Generator)

假如我们想周期性地生成Watermark,这个周期是可以设置的,默认情况下是每200毫秒生成一个Watermark,或者说Flink每200毫秒调用一次生成Watermark的方法。我们可以在执行环境中设置这个周期:

env.getConfig.setAutoWatermarkInterval(1000L)

使用方式

DataStream<MyType> stream = ...

DataStream<MyType> withTimestampsAndWatermarks = stream
        .assignTimestampsAndWatermarks(
            WatermarkStrategy
                .forGenerator(...)
                .withTimestampAssigner(...)
        );

代码清单

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.flink.api.common.RuntimeExecutionMode;
import org.apache.flink.api.common.eventtime.*;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.datastream.KeyedStream;
import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.functions.source.SourceFunction;
import org.apache.flink.streaming.api.functions.windowing.WindowFunction;
import org.apache.flink.streaming.api.windowing.assigners.TumblingEventTimeWindows;
import org.apache.flink.streaming.api.windowing.time.Time;
import org.apache.flink.streaming.api.windowing.windows.TimeWindow;
import org.apache.flink.util.Collector;

import java.text.SimpleDateFormat;
import java.util.Random;
import java.util.UUID;

/**
 * @author tiancx
 */
public class WatermarkDemo {


    @Data  // set get toString
    @AllArgsConstructor
    @NoArgsConstructor
    public static class OrderInfo {
        //格式化的时间
        private String time;
        private String orderId;
        private int uid;
        private int money;
        private long timeStamp;
    }

    public static class MySource implements SourceFunction<OrderInfo> {
        boolean flag = true;

        @Override
        public void run(SourceFunction.SourceContext ctx) throws Exception {
            // 源源不断的产生数据
            Random random = new Random();
            while (flag) {
                OrderInfo orderInfo = new OrderInfo();
                orderInfo.setOrderId(UUID.randomUUID().toString());
                orderInfo.setUid(random.nextInt(3));
                orderInfo.setMoney(random.nextInt(101));
                orderInfo.setTimeStamp(System.currentTimeMillis() - 1000 * 2);
                long timeStamp = orderInfo.getTimeStamp();
                //转成yyyy-MM-dd HH:mm:ss
                String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(timeStamp);
                orderInfo.setTime(format);
//                System.out.println("数据:" + orderInfo);
                ctx.collect(orderInfo);
                Thread.sleep(1000);// 间隔1s
            }
        }

        // source 停止之前需要干点啥
        @Override
        public void cancel() {
            flag = false;
        }
    }

    public static void main(String[] args) throws Exception {
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        env.setRuntimeMode(RuntimeExecutionMode.AUTOMATIC);
        env.setParallelism(1);
        //加载数据
        DataStreamSource<OrderInfo> source = env.addSource(new MySource());
        // 在转换算子之前,加载数据之后,添加水印
        // 添加使用event以及watermark进行操作
        SingleOutputStreamOperator<OrderInfo> watermarks = source.assignTimestampsAndWatermarks(
                WatermarkStrategy.forGenerator(x -> new MyPeriodicGenerator())
                        .withTimestampAssigner(new SerializableTimestampAssigner<OrderInfo>() {
                            @Override
                            public long extractTimestamp(OrderInfo element, long recordTimestamp) {
                                System.out.println("数据:" + element + "系统时间:" + recordTimestamp);
                                return element.getTimeStamp();
                            }
                        }));
        //keyby分组
        KeyedStream<OrderInfo, Integer> keyBy = watermarks.keyBy(OrderInfo::getUid);
        //开窗计算(滚动窗口)
        SingleOutputStreamOperator<String> sum = keyBy.window(TumblingEventTimeWindows.of(Time.seconds(5)))
                .apply(new WindowFunction<OrderInfo, String, Integer, TimeWindow>() {
                    @Override
                    public void apply(Integer key, TimeWindow window, Iterable<OrderInfo> input, Collector<String> out) throws Exception {
                        String startTime = DateFormatUtils.format(window.getStart(), "yyyy-MM-dd HH:mm:ss");
                        String endTime = DateFormatUtils.format(window.getEnd(), "yyyy-MM-dd HH:mm:ss");
                        String waterTime = DateFormatUtils.format(window.maxTimestamp(), "yyyy-MM-dd HH:mm:ss");
                        int sumMoney = 0;
                        for (OrderInfo orderInfo : input) {
                            sumMoney += orderInfo.getMoney();
                        }
                        out.collect("uid=" + key + ",starttime=" + startTime + ",endTime=" + endTime + ",totalMoney=" + sumMoney);
                    }
                });
        sum.print("窗口计算:");
        env.execute();
    }

    public static class MyPeriodicGenerator implements WatermarkGenerator<OrderInfo> {
        private long maxOutOfOrderness = 3000; // 3 seconds
        private long currentMaxTimestamp;

        @Override
        public void onEvent(OrderInfo event, long eventTimestamp, WatermarkOutput output) {
            // 更新currentMaxTimestamp为当前遇到的最大值
            currentMaxTimestamp = Math.max(currentMaxTimestamp, eventTimestamp);
        }

        @Override
        public void onPeriodicEmit(WatermarkOutput output) {
            // Watermark比currentMaxTimestamp最大值慢3秒
            output.emitWatermark(new Watermark(currentMaxTimestamp - maxOutOfOrderness));
        }
    }


}
🫑断点式水位线生成器(Punctuated Generator)

断点式生成器会不停地检测 onEvent()中的事件,当发现带有水位线信息的事件时,就立

即发出水位线。我们把发射水位线的逻辑写在 onEvent 方法当中即可。

🧃迟到数据处理

waterMark和Window机制解决了流式数据的乱序问题,对于因为延迟而顺序有误的数据,可以根据eventTime进行业务处理,对于延迟的数据Flink也有自己的解决办法:

主要的办法是给定一个允许延迟的时间,在该时间范围内仍可以接受处理延迟数据

设置允许延迟的时间是通过allowedLateness(lateness: Time)设置

保存延迟数据则是通过sideOutputLateData(outputTag: OutputTag[T])保存

获取延迟数据是通过DataStream.getSideOutput(tag: OutputTag[X])获取

🫖设置窗口延迟关闭

​ Flink 的窗口,也允许迟到数据。当触发了窗口计算后,会先计算当前的结果,但是此时并不会关闭窗口。

​ 以后每来一条迟到数据,就触发一次这条数据所在窗口计算(增量计算)。直到wartermark 超过了窗口结束时间+推迟时间,此时窗口会真正关闭。

.window(TumblingEventTimeWindows.of(Time.seconds(5)))

.allowedLateness(Time.seconds(3))

【Tips】: 延迟关闭只能用到event time上

☕️使用侧流接收迟到的数据

侧输出机制:可以将错过水印又错过allowedLateness允许的时间的数据,单独的存放到一个DataStream中,然后开发人员可以自定逻辑对这些超级迟到数据进行处理。

处理主要使用两个方式:

对窗口对象调用sideOutputLateData(OutputTag outputTag)方法,将数据存储到一个地方

对DataStream对象调用getSideOutput(OutputTag outputTag)方法,取出这些被单独处理的数据的DataStream

.windowAll(TumblingEventTimeWindows.of(Time.seconds(5)))

.allowedLateness(Time.seconds(3))

.sideOutputLateData(lateWS)

【都看到这了,点点赞点点关注呗,爱你们】😚😚

蓝白色微信公众号大学生校园清新简单纸飞机动态引导关注简洁新媒体分享中文动态引导关注

💬

✨ 正在努力的小叮当~
💖 超级爱分享,分享各种有趣干货!
👩‍💻 提供:模拟面试 | 简历诊断 | 独家简历模板
🌈 感谢关注,关注了你就是我的超级粉丝啦!
🔒 以下内容仅对你可见~

作者:小叮当撩代码CSDN后端领域新星创作者 |阿里云专家博主

CSDN个人主页:小叮当撩代码

🔎GZH哆啦A梦撩代码

🎉欢迎关注🔎点赞👍收藏⭐️留言📝

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

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

相关文章

抖捧Ai实景直播案例-助力景区商家假期销量爆棚!

出门游玩你会提前做攻略吗&#xff1f;是不是早早就规划好了路线、定好了门票车票。这就是属于消费前置的动作。所以在消费前置的情况&#xff0c;各个景区的商家都铆足劲发展线上流量&#xff0c;短视频直播也成为众多商家必做的宣传渠道&#xff0c;特别是五一假期更让不少商…

C++面向对象程序设计 - 继承与派生进一步讨论

C中所谓“继承”就是在一个已存在的类的基础上建立一个新类&#xff0c;从已有的类那里获得已有特性&#xff0c;叫做类的继承。从另一角度说&#xff0c;从已有的类&#xff08;父类&#xff09;产生一个新的子类&#xff0c;称为类的派生。一个派生类只从一个基类派生&#x…

分布式与一致性协议之ZAB协议(四)

ZAB协议 ZooKeeper是如何选举领导者的。 首先我们来看看ZooKeeper是如何实现成员身份的&#xff1f; 在ZooKeeper中&#xff0c;成员状态是在QuorumPeer.java中实现的&#xff0c;为枚举型变量 public enum ServerState { LOOKING, FOLLOWING, LEADING, OBSERVING }其实&…

权益商城系统源码 现支持多种支付方式

简介&#xff1a; 权益商城系统源码&#xff0c;支持多种支付方式&#xff0c;后台商品管理&#xff0c;订单管理&#xff0c;串货管理&#xff0c;分站管理&#xff0c;会员列表&#xff0c;分销日志&#xff0c;应用配置。 上传到服务器&#xff0c;修改数据库信息&#xff…

AI预测福彩3D第10套算法实战化赚米验证第2弹2024年5月6日第2次测试

由于今天白天事情比较多&#xff0c;回来比较晚了&#xff0c;趁着还未开奖&#xff0c;赶紧把预测结果发出来吧~今天是第2次测试~ 2024年5月6日福彩3D预测结果 6-7码定位方案如下&#xff1a; 百位&#xff1a;3、4、1、7、8、9 十位&#xff1a;4、5、3、7、8、9 个位&#x…

【数据结构(邓俊辉)学习笔记】栈与队列01——栈接口与应用

文章目录 0. 概述1. 操作与接口2. 操作实例3. 实现4. 栈与递归5. 应用5.1 逆序输出5.1.1 进制转换5.1.1.1 思路5.1.1.2 算法实现 5.2 递归嵌套5.2.1 栈混洗5.2.1.1 混洗5.2.1.2 计数5.2.1.3 甄别 5.2.2 括号匹配5.2.2.1 构思5.2.2.2 实现5.2.2.3 实例 5.3 延迟缓冲5.3.1 中缀表…

华为ensp中USG6000V防火墙双机热备VRRP+HRP原理及配置

作者主页&#xff1a;点击&#xff01; ENSP专栏&#xff1a;点击&#xff01; 创作时间&#xff1a;2024年5月6日20点26分 华为防火墙双机热备是一种高可用性解决方案&#xff0c;可以将两台防火墙设备组成一个双机热备组&#xff0c;实现主备切换。当主用防火墙出现故障时&…

企业网站 | 被攻击时该怎么办?

前言 每天&#xff0c;数以千计的网站被黑客入侵。发生这种情况时&#xff0c;被入侵网站可用于从网络钓鱼页面到SEO垃圾邮件或者其它内容。如果您拥有一个小型网站&#xff0c;很容易相信黑客不会对它感兴趣。不幸的是&#xff0c;通常情况并非如此。 黑客入侵网站的动机与所…

书籍推荐|经典书籍ic书籍REUSE METHODOLOGY MANUALFOR等和verilog网站推荐(附下载)

大家好&#xff0c;今天是51过后的第一个工作日&#xff0c;想必大家都还没有完全从节假日的吃喝玩乐模式转变为勤勤恳恳的打工人模式&#xff0c;当然也包括我&#xff0c;因此这次更新主要是分享几篇书籍和verilog相关的学习网站~ 首先是一本数字电路相关的基础书籍&#xf…

深入理解Docker容器镜像

深入理解Docker容器镜像 1 容器是什么&#xff1a;特殊的进程 容器其实是一种沙盒技术。顾名思义&#xff0c;沙盒就是能够像一个集装箱一样&#xff0c;把你的应用“装”起来的技术。这样&#xff0c;应用与应用之间&#xff0c;就因为有了边界而不至于相互干扰&#xff1b;而…

流量分析。

流量分析 在Wireshak抓包可以看到正常的执行流程如下&#xff1a; ● Client向Server发起Load data local infile请求 ● Server返回需要读取的文件路径 ● Client读取文件内容并发送给Server ● PS&#xff1a;在本机上启动服务端与客户端&#xff0c;启动wireshark 抓包&…

navicat 连接 阿里云 RDS mysql 数据库

首先上官方教程连接 下面是我的实操记录 1、先输入正确的账号、密码 2、再加上数据库名称

省公派出国|社科类普通高校教师限期内赴英国访学交流

在国外访问学者申请中&#xff0c;人文社科类相对难度更大&#xff0c;尤其是英语语言学&#xff0c;作为非母语研究并不被国外高校看重。经过努力&#xff0c;最终我们帮助Z老师申请到英国坎特伯雷基督教会大学的访学职位&#xff0c;并在限期内出国。 Z老师背景&#xff1a; …

Chrome浏览器安装React工具

一、如果网络能访问Google商店&#xff0c;直接安装官方插件即可 二、网络不能访问Google商店&#xff0c;使用安装包进行安装 1、下载react工具包 链接&#xff1a;https://pan.baidu.com/s/1qAeqxSafOiNV4CG3FVVtTQ 提取码&#xff1a;vgwj 2、chrome浏览器安装react工具…

io (fscanf fprintf)

20 #include <sys/un.h>21 typedef struct stu22 {23 char name[16];24 int age;25 double score;26 }stu;27 int main(int argc, const char *argv[])28 {29 /* 有如下结构体30 31 申请该结构体数组&#xff0c;容量为5&#xff0c;初始化5个学生的信息32 …

C++:何为,。。。。。。

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

new mars3d.control.MapSplit({实现点击卷帘两侧添加不同图层弹出不同的popup

new mars3d.control.MapSplit({实现点击卷帘两侧添加不同图层弹出不同的popup效果&#xff1a; 左侧&#xff1a; 右侧&#xff1a; 说明&#xff1a;mars3d的3.7.12以上版本才支持该效果。 示例链接&#xff1a; 功能示例(Vue版) | Mars3D三维可视化平台 | 火星科技 相关代…

【6D位姿估计】ZebraPose 层次化分组策略 由粗到细的表面编码

前言 本文介绍6D位姿估计的方法ZebraPose&#xff0c;也可以称为六自由度物体姿态估计&#xff0c;输入单张图片&#xff0c;输出物体的三维位置和三维方向。 它来自CVPR2022的论文&#xff0c;通过层次化分组策略&#xff0c;高效地编码物体表面的信息。 ZebraPose提出了一…

基于Springboot的家具网站

基于SpringbootVue的家具网站设计与实现 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringbootMybatis工具&#xff1a;IDEA、Maven、Navicat 系统展示 用户登录 首页 商家 家具信息 家居资讯 后台管理 后台首页 用户管理 商家管理 家具类型管理 家具…

《Python编程从入门到实践》day20

#尝试在python3.11文件夹和pycharm中site-packages文件夹中安装&#xff0c;最终在scripts文件夹中新建py文件成功导入pygame运行程序 #今日知识点学习 import sysimport pygameclass AlienInvasion:"""管理游戏资源和行为的类"""def __init__(…