范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

Flink操练(十一)之DS简介(11)基于时间和窗口的操作符(三)

  1 基于时间的双流Join
  数据流操作的另一个常见需求是对两条数据流中的事件进行联结(connect)或Join。Flink DataStream API中内置有两个可以根据时间条件对数据流进行Join的算子:基于间隔的Join和基于窗口的Join。本节我们会对它们进行介绍。
  如果Flink内置的Join算子无法表达所需的Join语义,那么你可以通过CoProcessFunction、BroadcastProcessFunction或KeyedBroadcastProcessFunction实现自定义的Join逻辑。
  注意,你要设计的Join算子需要具备高效的状态访问模式及有效的状态清理策略。 1.1 基于间隔的Join
  基于间隔的Join会对两条流中拥有相同键值以及彼此之间时间戳不超过某一指定间隔的事件进行Join。
  下图展示了两条流(A和B)上基于间隔的Join,如果B中事件的时间戳相较于A中事件的时间戳不早于1小时且不晚于15分钟,则会将两个事件Join起来。Join间隔具有对称性,因此上面的条件也可以表示为A中事件的时间戳相较B中事件的时间戳不早于15分钟且不晚于1小时。
  基于间隔的Join目前只支持事件时间以及INNER JOIN语义(无法发出未匹配成功的事件)。下面的例子定义了一个基于间隔的Join。 input1   .intervalJoin(input2)   .between(, ) // 相对于input1的上下界   .process(ProcessJoinFunction) // 处理匹配的事件对
  Join成功的事件对会发送给ProcessJoinFunction。下界和上界分别由负时间间隔和正时间间隔来定义,例如between(Time.hour(-1), Time.minute(15))。在满足下界值小于上界值的前提下,你可以任意对它们赋值。例如,允许出现B中事件的时间戳相较A中事件的时间戳早1~2小时这样的条件。
  基于间隔的Join需要同时对双流的记录进行缓冲。对第一个输入而言,所有时间戳大于当前水位线减去间隔上界的数据都会被缓冲起来;对第二个输入而言,所有时间戳大于当前水位线加上间隔下界的数据都会被缓冲起来。注意,两侧边界值都有可能为负。上图中的Join需要存储数据流A中所有时间戳大于当前水位线减去15分钟的记录,以及数据流B中所有时间戳大于当前水位线减去1小时的记录。不难想象,如果两条流的事件时间不同步,那么Join所需的存储就会显著增加,因为水位线总是由"较慢"的那条流来决定。
  例子:每个用户可点击Join这个用户最近10分钟内的浏览
  scala version object IntervalJoinExample {   def main(args: Array[String]): Unit = {     val env = StreamExecutionEnvironment.getExecutionEnvironment     env.setParallelism(1)     env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)      /*     A.intervalJoin(B).between(lowerBound, upperBound)     B.intervalJoin(A).between(-upperBound, -lowerBound)      */      val stream1 = env       .fromElements(         ("user_1", 10 * 60 * 1000L, "click"),         ("user_1", 16 * 60 * 1000L, "click")       )       .assignAscendingTimestamps(_._2)       .keyBy(r => r._1)      val stream2 = env       .fromElements(         ("user_1", 5 * 60 * 1000L, "browse"),         ("user_1", 6 * 60 * 1000L, "browse")       )       .assignAscendingTimestamps(_._2)       .keyBy(r => r._1)      stream1       .intervalJoin(stream2)       .between(Time.minutes(-10), Time.minutes(0))       .process(new ProcessJoinFunction[(String, Long, String), (String, Long, String), String] {         override def processElement(in1: (String, Long, String), in2: (String, Long, String), context: ProcessJoinFunction[(String, Long, String), (String, Long, String), String]#Context, collector: Collector[String]): Unit = {           collector.collect(in1 + " => " + in2)         }       })       .print()      stream2       .intervalJoin(stream1)       .between(Time.minutes(0), Time.minutes(10))       .process(new ProcessJoinFunction[(String, Long, String), (String, Long, String), String] {         override def processElement(in1: (String, Long, String), in2: (String, Long, String), context: ProcessJoinFunction[(String, Long, String), (String, Long, String), String]#Context, collector: Collector[String]): Unit = {           collector.collect(in1 + " => " + in2)         }       })       .print()      env.execute()   } }
  java version object IntervalJoinExample {   def main(args: Array[String]): Unit = {     val env = StreamExecutionEnvironment.getExecutionEnvironment     env.setParallelism(1)     env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)      /*     A.intervalJoin(B).between(lowerBound, upperBound)     B.intervalJoin(A).between(-upperBound, -lowerBound)      */      val stream1 = env       .fromElements(         ("user_1", 10 * 60 * 1000L, "click"),         ("user_1", 16 * 60 * 1000L, "click")       )       .assignAscendingTimestamps(_._2)       .keyBy(r => r._1)      val stream2 = env       .fromElements(         ("user_1", 5 * 60 * 1000L, "browse"),         ("user_1", 6 * 60 * 1000L, "browse")       )       .assignAscendingTimestamps(_._2)       .keyBy(r => r._1)      stream1       .intervalJoin(stream2)       .between(Time.minutes(-10), Time.minutes(0))       .process(new ProcessJoinFunction[(String, Long, String), (String, Long, String), String] {         override def processElement(in1: (String, Long, String), in2: (String, Long, String), context: ProcessJoinFunction[(String, Long, String), (String, Long, String), String]#Context, collector: Collector[String]): Unit = {           collector.collect(in1 + " => " + in2)         }       })       .print()      stream2       .intervalJoin(stream1)       .between(Time.minutes(0), Time.minutes(10))       .process(new ProcessJoinFunction[(String, Long, String), (String, Long, String), String] {         override def processElement(in1: (String, Long, String), in2: (String, Long, String), context: ProcessJoinFunction[(String, Long, String), (String, Long, String), String]#Context, collector: Collector[String]): Unit = {           collector.collect(in1 + " => " + in2)         }       })       .print()      env.execute()   } }1.2 基于窗口的Join
  顾名思义,基于窗口的Join需要用到Flink中的窗口机制。其原理是将两条输入流中的元素分配到公共窗口中并在窗口完成时进行Join(或Cogroup)。
  下面的例子展示了如何定义基于窗口的Join。 input1.join(input2)   .where(...)       // 为input1指定键值属性   .equalTo(...)     // 为input2指定键值属性   .window(...)      // 指定WindowAssigner   [.trigger(...)]   // 选择性的指定Trigger   [.evictor(...)]   // 选择性的指定Evictor   .apply(...)       // 指定JoinFunction
  下图展示了DataStream API中基于窗口的Join是如何工作的。
  两条输入流都会根据各自的键值属性进行分区,公共窗口分配器会将二者的事件映射到公共窗口内(其中同时存储了两条流中的数据)。当窗口的计时器触发时,算子会遍历两个输入中元素的每个组合(叉乘积)去调用JoinFunction。同时你也可以自定义触发器或移除器。由于两条流中的事件会被映射到同一个窗口中,因此该过程中的触发器和移除器与常规窗口算子中的完全相同。
  除了对窗口中的两条流进行Join,你还可以对它们进行Cogroup,只需将算子定义开始位置的join改为coGroup()即可。Join和Cogroup的总体逻辑相同,二者的唯一区别是:Join会为两侧输入中的每个事件对调用JoinFunction;而Cogroup中用到的CoGroupFunction会以两个输入的元素遍历器为参数,只在每个窗口中被调用一次。
  注意,对划分窗口后的数据流进行Join可能会产生意想不到的语义。例如,假设你为执行Join操作的算子配置了1小时的滚动窗口,那么一旦来自两个输入的元素没有被划分到同一窗口,它们就无法Join在一起,即使二者彼此仅相差1秒钟。
  scala version object TwoWindowJoinExample {   def main(args: Array[String]): Unit = {     val env = StreamExecutionEnvironment.getExecutionEnvironment     env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)     env.setParallelism(1)      val stream1 = env       .fromElements(         ("a", 1000L),         ("a", 2000L)       )       .assignAscendingTimestamps(_._2)      val stream2 = env       .fromElements(         ("a", 3000L),         ("a", 4000L)       )       .assignAscendingTimestamps(_._2)      stream1       .join(stream2)       // on A.id = B.id       .where(_._1)       .equalTo(_._1)       .window(TumblingEventTimeWindows.of(Time.seconds(5)))       .apply(new JoinFunction[(String, Long), (String, Long), String] {         override def join(in1: (String, Long), in2: (String, Long)): String = {           in1 + " => " + in2         }       })       .print()      env.execute()   } }
  java version public class TwoWindowJoinExample {     public static void main(String[] args) throws Exception {         StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();         env.setParallelism(1);         env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);          DataStream> stream1 = env                 .fromElements(                         Tuple2.of("a", 1000L),                         Tuple2.of("b", 1000L),                         Tuple2.of("a", 2000L),                         Tuple2.of("b", 2000L)                 )                 .assignTimestampsAndWatermarks(                         WatermarkStrategy                                 .>forMonotonousTimestamps()                                 .withTimestampAssigner(                                         new SerializableTimestampAssigner>() {                                             @Override                                             public long extractTimestamp(Tuple2 stringLongTuple2, long l) {                                                 return stringLongTuple2.f1;                                             }                                         }                                 )                 );          DataStream> stream2 = env                 .fromElements(                         Tuple2.of("a", 3000L),                         Tuple2.of("b", 3000L),                         Tuple2.of("a", 4000L),                         Tuple2.of("b", 4000L)                 )                 .assignTimestampsAndWatermarks(                         WatermarkStrategy                                 .>forMonotonousTimestamps()                                 .withTimestampAssigner(                                         new SerializableTimestampAssigner>() {                                             @Override                                             public long extractTimestamp(Tuple2 stringLongTuple2, long l) {                                                 return stringLongTuple2.f1;                                             }                                         }                                 )                 );          stream1                 .join(stream2)                 .where(r -> r.f0)                 .equalTo(r -> r.f0)                 .window(TumblingEventTimeWindows.of(Time.seconds(5)))                 .apply(new JoinFunction, Tuple2, String>() {                     @Override                     public String join(Tuple2 stringLongTuple2, Tuple2 stringLongTuple22) throws Exception {                         return stringLongTuple2 + " => " + stringLongTuple22;                     }                 })                 .print();          env.execute();     } }2 处理迟到的元素
  水位线可以用来平衡计算的完整性和延迟两方面。除非我们选择一种非常保守的水位线策略(最大延时设置的非常大,以至于包含了所有的元素,但结果是非常大的延迟),否则我们总需要处理迟到的元素。
  迟到的元素是指当这个元素来到时,这个元素所对应的窗口已经计算完毕了(也就是说水位线已经没过窗口结束时间了)。这说明迟到这个特性只针对事件时间。
  DataStream API提供了三种策略来处理迟到元素 直接抛弃迟到的元素 将迟到的元素发送到另一条流中去 可以更新窗口已经计算完的结果,并发出计算结果。 2.1 抛弃迟到元素
  抛弃迟到的元素是event time window operator的默认行为。也就是说一个迟到的元素不会创建一个新的窗口。
  process function可以通过比较迟到元素的时间戳和当前水位线的大小来很轻易地过滤掉迟到元素。 2.2 重定向迟到元素
  迟到的元素也可以使用侧输出(side output)特性被重定向到另外的一条流中去。迟到元素所组成的侧输出流可以继续处理或者sink到持久化设施中去。
  例子
  scala version val readings = env   .socketTextStream("localhost", 9999, " ")   .map(line => {     val arr = line.split(" ")     (arr(0), arr(1).toLong * 1000)   })   .assignAscendingTimestamps(_._2)  val countPer10Secs = readings   .keyBy(_._1)   .timeWindow(Time.seconds(10))   .sideOutputLateData(     new OutputTag[(String, Long)]("late-readings")   )   .process(new CountFunction())  val lateStream = countPer10Secs   .getSideOutput(     new OutputTag[(String, Long)]("late-readings")   )  lateStream.print()
  实现 CountFunction  :class CountFunction extends ProcessWindowFunction[(String, Long),   String, String, TimeWindow] {   override def process(key: String,                        context: Context,                        elements: Iterable[(String, Long)],                        out: Collector[String]): Unit = {     out.collect("窗口共有" + elements.size + "条数据")   } }
  java version public class RedirectLateEvent {      private static OutputTag> output = new OutputTag>("late-readings"){};      public static void main(String[] args) throws Exception {         StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();         env.setParallelism(1);         env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);          DataStream> stream = env                 .socketTextStream("localhost", 9999)                 .map(new MapFunction>() {                     @Override                     public Tuple2 map(String s) throws Exception {                         String[] arr = s.split(" ");                         return Tuple2.of(arr[0], Long.parseLong(arr[1]) * 1000L);                     }                 })                 .assignTimestampsAndWatermarks(                         WatermarkStrategy.                                 // like scala: assignAscendingTimestamps(_._2)                                 >forMonotonousTimestamps()                                 .withTimestampAssigner(new SerializableTimestampAssigner>() {                                     @Override                                     public long extractTimestamp(Tuple2 value, long l) {                                         return value.f1;                                     }                                 })                 );          SingleOutputStreamOperator lateReadings = stream                 .keyBy(r -> r.f0)                 .timeWindow(Time.seconds(5))                 .sideOutputLateData(output) // use after keyBy and timeWindow                 .process(new ProcessWindowFunction, String, String, TimeWindow>() {                     @Override                     public void process(String s, Context context, Iterable> iterable, Collector collector) throws Exception {                         long exactSizeIfKnown = iterable.spliterator().getExactSizeIfKnown();                         collector.collect(exactSizeIfKnown + " of elements");                     }                 });          lateReadings.print();         lateReadings.getSideOutput(output).print();          env.execute();     } }
  下面这个例子展示了ProcessFunction如何过滤掉迟到的元素然后将迟到的元素发送到侧输出流中去。
  scala version val readings: DataStream[SensorReading] = ... val filteredReadings: DataStream[SensorReading] = readings   .process(new LateReadingsFilter)  // retrieve late readings val lateReadings: DataStream[SensorReading] = filteredReadings   .getSideOutput(new OutputTag[SensorReading]("late-readings"))   /** A ProcessFunction that filters out late sensor readings and   * re-directs them to a side output */ class LateReadingsFilter     extends ProcessFunction[SensorReading, SensorReading] {    val lateReadingsOut = new OutputTag[SensorReading]("late-readings")    override def processElement(       SensorReading r,       ctx: ProcessFunction[SensorReading, SensorReading]#Context,       out: Collector[SensorReading]): Unit = {      // compare record timestamp with current watermark     if (r.timestamp < ctx.timerService().currentWatermark()) {       // this is a late reading => redirect it to the side output       ctx.output(lateReadingsOut, r)     } else {       out.collect(r)     }   } }
  java version public class RedirectLateEvent {      private static OutputTag output = new OutputTag("late-readings"){};      public static void main(String[] args) throws Exception {         StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();         env.setParallelism(1);         env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);          SingleOutputStreamOperator> stream = env                 .socketTextStream("localhost", 9999)                 .map(new MapFunction>() {                     @Override                     public Tuple2 map(String s) throws Exception {                         String[] arr = s.split(" ");                         return Tuple2.of(arr[0], Long.parseLong(arr[1]) * 1000L);                     }                 })                 .assignTimestampsAndWatermarks(                         WatermarkStrategy.                                 >forMonotonousTimestamps()                                 .withTimestampAssigner(new SerializableTimestampAssigner>() {                                     @Override                                     public long extractTimestamp(Tuple2 value, long l) {                                         return value.f1;                                     }                                 })                 )                 .process(new ProcessFunction, Tuple2>() {                     @Override                     public void processElement(Tuple2 stringLongTuple2, Context context, Collector> collector) throws Exception {                         if (stringLongTuple2.f1 < context.timerService().currentWatermark()) {                             context.output(output, "late event is comming!");                         } else {                             collector.collect(stringLongTuple2);                         }                      }                 });          stream.print();         stream.getSideOutput(output).print();          env.execute();     } }2.3 使用迟到元素更新窗口计算结果
  由于存在迟到的元素,所以已经计算出的窗口结果是不准确和不完全的。我们可以使用迟到元素更新已经计算完的窗口结果。
  如果我们要求一个operator支持重新计算和更新已经发出的结果,就需要在第一次发出结果以后也要保存之前所有的状态。但显然我们不能一直保存所有的状态,肯定会在某一个时间点将状态清空,而一旦状态被清空,结果就再也不能重新计算或者更新了。而迟到的元素只能被抛弃或者发送到侧输出流。
  window operator API提供了方法来明确声明我们要等待迟到元素。当使用event-time window,我们可以指定一个时间段叫做allowed lateness。window operator如果设置了allowed lateness,这个window operator在水位线没过窗口结束时间时也将不会删除窗口和窗口中的状态。窗口会在一段时间内(allowed lateness设置的)保留所有的元素。
  当迟到元素在allowed lateness时间内到达时,这个迟到元素会被实时处理并发送到触发器(trigger)。当水位线没过了窗口结束时间+allowed lateness时间时,窗口会被删除,并且所有后来的迟到的元素都会被丢弃。
  Allowed lateness可以使用allowedLateness()方法来指定,如下所示: val readings: DataStream[SensorReading] = ...  val countPer10Secs: DataStream[(String, Long, Int, String)] = readings   .keyBy(_.id)   .timeWindow(Time.seconds(10))   // process late readings for 5 additional seconds   .allowedLateness(Time.seconds(5))   // count readings and update results if late readings arrive   .process(new UpdatingWindowCountFunction)    /** A counting WindowProcessFunction that distinguishes between   * first results and updates. */ class UpdatingWindowCountFunction     extends ProcessWindowFunction[SensorReading,       (String, Long, Int, String), String, TimeWindow] {    override def process(       id: String,       ctx: Context,       elements: Iterable[SensorReading],       out: Collector[(String, Long, Int, String)]): Unit = {      // count the number of readings     val cnt = elements.count(_ => true)      // state to check if this is     // the first evaluation of the window or not     val isUpdate = ctx.windowState.getState(       new ValueStateDescriptor[Boolean](         "isUpdate",         Types.of[Boolean]))      if (!isUpdate.value()) {       // first evaluation, emit first result       out.collect((id, ctx.window.getEnd, cnt, "first"))       isUpdate.update(true)     } else {       // not the first evaluation, emit an update       out.collect((id, ctx.window.getEnd, cnt, "update"))     }   } }
  java version public class UpdateWindowResultWithLateEvent {     public static void main(String[] args) throws Exception {         StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();         env.setParallelism(1);         env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);          DataStreamSource stream = env.socketTextStream("localhost", 9999);          stream                 .map(new MapFunction>() {                     @Override                     public Tuple2 map(String s) throws Exception {                         String[] arr = s.split(" ");                         return Tuple2.of(arr[0], Long.parseLong(arr[1]) * 1000L);                     }                 })                 .assignTimestampsAndWatermarks(                         WatermarkStrategy.>forBoundedOutOfOrderness(Duration.ofSeconds(5))                         .withTimestampAssigner(new SerializableTimestampAssigner>() {                             @Override                             public long extractTimestamp(Tuple2 stringLongTuple2, long l) {                                 return stringLongTuple2.f1;                             }                         })                 )                 .keyBy(r -> r.f0)                 .timeWindow(Time.seconds(5))                 .allowedLateness(Time.seconds(5))                 .process(new UpdateWindowResult())                 .print();          env.execute();     }      public static class UpdateWindowResult extends ProcessWindowFunction, String, String, TimeWindow> {         @Override         public void process(String s, Context context, Iterable> iterable, Collector collector) throws Exception {             long count = 0L;             for (Tuple2 i : iterable) {                 count += 1;             }              // 可见范围比getRuntimeContext.getState更小,只对当前key、当前window可见             // 基于窗口的状态变量,只能当前key和当前窗口访问             ValueState isUpdate = context.windowState().getState(                     new ValueStateDescriptor("isUpdate", Types.BOOLEAN)             );              // 当水位线超过窗口结束时间时,触发窗口的第一次计算!             if (isUpdate.value() == null) {                 collector.collect("窗口第一次触发计算!一共有 " + count + " 条数据!");                 isUpdate.update(true);             } else {                 collector.collect("窗口更新了!一共有 " + count + " 条数据!");             }         }     } }

皮实耐造巨能装,说的就是24英寸地平线8号行李箱引言行李箱是旅行必备神器,一款出色的旅行箱,我认为需要具备两点第一,皮实耐用第二,可以收纳更多的物品,例如,日常衣物办公设备零食等等。今天给大家推荐一款,我最近在用的行李箱24英寸轻薄便携长续航?宏碁蜂鸟FUN笔记本电脑做到了引言大家好,我是科技好物菌。双十一购物狂欢节开幕啦!大家的好物筛选得怎么样呢?购物车还能装下笔记本电脑吗?(狗头。jpg)如题所述,这次我给大家分享的好物是宏碁蜂鸟FunS50笔记11万多入手五菱高端MPV,长近4。9米带尊享座椅,车主不输奥德赛我身边的人要么喜欢轿车,要么喜欢SUV,但我和他们不一样,我一直想买的车是座位数较多的家用车,可能我比较喜欢人多热闹吧。估计很多人这时会想到奥德赛GL8之类,但说实话它们并没有宣传冬天要来了,探岳330车主准备好了吗?堵塞会迟到,但绝不会缺席从今年5月份开始,大众探岳330车型的颗粒捕捉器堵塞事件大面积发生,如今已经持续发酵了4个月了,貌似近期网上的声音越来越小了,难道是这个问题解决了吗?然而并没有,在维权这条路上消费9万买一台顶配SUV,现代ix25车主开了宝骏RS3之后,后悔买错车了我买车的时候对选国产车还是选合资车不是特别看重,我觉得现在的国产车合资车质量都差不多,只要选对品牌,很难会出现质量方面的问题。所以我更想要买一款符合我实际需求,各方面都能让我觉得满国内车企售后服务排行榜,为什么你的车出问题没人管?找找答案吧回想20多年国内消费者更倾向于选择低价物品,原因是那时候大多数人的手头都不宽裕,没有选择大品牌的经济基础,但随着时间的推移,如今人们相对富裕了,在选择大件物品时更倾向于选择知名品牌维权车主反被特斯拉起诉,要求赔偿500万,这诉求合法却不合理作为全球新能源汽车行业的领头羊,特斯拉在三电方面的技术确是挺强,但问题在于特斯拉的品控却不算太好,最明显的就是各类维权事件不断发生,近期最火热的莫过于两位维权车主现在反被特斯拉起诉思域的兄弟车型终于来了,广汽本田型格亮相,说实话有些太敷衍国内很多主流车型都采用南北双车战略来扩大销量,当然也是为了完善南北车企之间各自的产品线,像是A级轿车中的朗逸卡罗拉凌派都是如此,不过几款A级车型一直还没有推出兄弟车型,比如速腾思域母亲节儿女送耳福,推荐漫步者辅听1号前言母亲节即将来临,你还在为选购礼物而烦恼吗?本文可能就是你临时的佛脚。话说今年五一假期,在我返回老家前,我就打算给老爸购买一件礼物,在京东商场寻寻觅觅找了好几拨,最终找到了一件能从电源到散热,从机箱到显卡,这套攒机清单今年双十二值得收藏引言电脑装机是一个大市场,在这个市场里面有无数的电脑主机配件厂商,但是出色的靠谱的配件厂商却屈指可数,而九州风神就是这个大市场里不可忽视的品牌。今天,我给大家分享的是九州风神装机配飞利浦智能水冷空调扇清风徐来,冰爽一夏前言炎炎夏日,何以解热?答案是空调风扇冰激凌。但是,以上三者,我更倾向于风扇。因为风扇相比空调对人身体伤害更小,大家应该都有感受,长时间吹空调,人身体着不住,把握不好更容易把人吹感
亚马逊日本站PrimeDay临近,爆单选品指南来了PrimeDay是亚马逊一年一度的购物假日,目标客户是订阅其购物娱乐服务的优质会员。PrimeDay除了是买家的购物节外,也是跨境卖家年度重要大促。据亚马逊2022年第一季度的财报微信上线性能检测功能微信在近日又进行了一次更新,其中更新的内容也随着微信支持手机温度监控的词条上了热搜,这是怎么一回事,一起来看看。QQ一直在花里胡哨的道路上奔驰着,所以对于QQ的更新都不会觉得很奇怪拓商电商浅析拼多多官方活动有哪些?拼多多商家参加活动能够让店铺销量翻倍,如果店铺营业很久却没有人进店购买,参加拼多多官方活动能改善店铺的状态。那么,今天拓商电商为您介绍一下拼多多的官方活动。以及参加活动带给店铺哪些新车城市代步新选择?长安糯玉米到店,竞争五菱宏光MINIEV文懂车帝原创高帅鹏懂车帝原创产品继4月22日首发亮相后,长安全新电动车LUMIN糯玉米实车到店。作为三门四座微型电动车,该车定位为城市代步车,与之处于同级车型包括五菱宏光MINIE北京车娃娃科技发展有限公司探索汽车延保新模式来源人民网人民日报北京车娃娃科技发展有限公司(简称车娃娃),是一家专业的汽车延保服务公司。当车辆在非外力作用下因自身质量问题引起故障,购买汽车延保服务的车主可享受免费修车服务。近年显示IP地址后竟能以此获利?灰色产业链曝光,此行为侵犯隐私?近日,随着头条微博微信小红书抖音在内的主流APP纷纷开通显示IP地址服务后引发众多热议。有人支持有人吐槽的同时也有人在谋取暴利。所谓IP地址,就如同随身携带的GPS,简单来说,就是智己汽车规划首轮公开融资,过去一年新能源汽车赛道融资总额增长181。7记者周姝祺实习记者李紫晴编辑近日,智己汽车联席CEO刘涛表示,智己汽车首轮公开融资已在规划当中。成立于2020年末的智己汽车是由上汽集团张江高科和阿里巴巴集团共同打造的高端电动汽车特斯拉ampampquot车顶维权ampampquot车主回应温州车主道歉信,称未蛊惑其维权5月10日消息,昨日,温州特斯拉失控车主陈先生发布道歉信称,自己捏造特斯拉自动加速刹车失灵等言论,承认错把油门当刹车。其还提到事发后,河南车主张女士和天津车主韩先生都曾与其联系。张马斯克警告说,他可能会在神秘的情况下死去马斯克周一在推特上告诉他的追随者,如果他死了在神秘的情况下,很高兴认识你。这位SpaceX和特斯拉巨头此前曾与一名俄罗斯官员发生冲突,但他的声明引发的笑话多于担忧。马斯克周一早上在WIN11关闭屏幕或睡眠后唤醒黑屏(有鼠标)官方说是显卡驱动问题网上到处都是按ctrlAItDeI打开任务管理,别信,按了一点反应都没有,都黑屏了,有反应又如何。可以在头条搜索一下Windows11开机黑屏的原因及不完全的解决方法这个文章,我进网友6300买iPhone13ProMax坦言赚到了结果简直不要太意外iPhone13ProMax是今年苹果的旗舰机型,价格一直比较坚挺稳定,销量也一样。但是今天网友跟我说他在某鱼捡漏的这台iPhone13ProMax却非常便宜,仅仅只要6300元,