精华内容
下载资源
问答
  • 信息窗口都是讲什么
    2020-12-03 11:42:03

    本文实例讲述了python实现根据窗口标题调用窗口的方法。分享给大家供大家参考。具体分析如下:

    当你知道一个windows窗口的标题后,可以用下面的代码调用窗口,甚至向窗口内写入内容。

    #-*-coding:utf-8-*-

    import win32gui,win32con

    #下面的是窗口的标题名称,这样是一定错的,但在控制台就可以正常使用

    #写在文件里要用U编码

    a=u"bitsCN.com"

    dlg=win32gui.FindWindow(None,a)

    //用控件的ID取得控件的句柄,模拟写入输入框文本并按下提交按键

    t1=win32gui.GetDlgItem(dlg,1012)

    t2=win32gui.GetDlgItem(dlg,1001)

    k1=win32gui.GetDlgItem(dlg,1605)

    win32gui.SendMessage(t1,win32con.WM_SETTEXT,None,'902723')

    win32gui.SendMessage(t2,win32con.WM_SETTEXT,None,'761209')

    win32gui.SendMessage(k1,win32con.BM_CLICK,None,None)

    希望本文所述对大家的Python程序设计有所帮助。

    本文原创发布php中文网,转载请注明出处,感谢您的尊重!

    更多相关内容
  • 本文实例讲述了C#调用dos窗口获取相关信息的方法。分享给大家供大家参考。具体实现方法如下: /// /// 调用dos窗口获取相关信息 /// /// 如:netstat-ano或者ipconfig /// <returns></returns> static string Get...
  • 本文实例讲述了jQuery实现鼠标悬停显示提示信息窗口的方法。分享给大家供大家参考。具体实现方法如下: <!DOCTYPE html PUBLIC -//W3C//DTD XHTML 1.0 Transitional//EN ...<...鼠标悬停显示提示信息窗口<...
  • 本帖要讲述的是注意事项,请注意,调用多次标签的反馈事件的时候,实际上为单线程进行处理,为什么这么说,看下面的例子 测试例子说明: 点击A按钮,将调用一个标签的反馈事件,效果为轮训五次(间隔一秒),并在...
  • 滑动窗口和拥塞窗口

    千次阅读 2021-09-07 12:57:15
    滑动窗口和拥塞窗口 (1)窗口分为滑动窗口和拥塞窗口 滑动窗口是接受数据端使用的窗口大小,用来告知发送端接收端的缓存大小,以此可以控制发送端发送数据的大小,从而达到流量控制的目的。 拥塞窗口是数据的发送...

    滑动窗口和拥塞窗口

    (1)窗口分为滑动窗口和拥塞窗口

    • 滑动窗口是接受数据端使用的窗口大小,用来告知发送端接收端的缓存大小,以此可以控制发送端发送数据的大小,从而达到流量控制的目的。
    • 拥塞窗口是数据的发送端,拥塞窗口不代表缓存,拥塞窗口指某一源端数据流在一个RTT内可以最多发送数据包

    (2)实现一个靠谱的协议:TCP 协议使用的也是同样的模式。为了保证顺序性,每一个包都有一个 ID。在建立连接的时候,会商定起始的 ID 是什么,然后按照 ID 一个个发送。为了保证不丢包,对于发送的包都要进行应答,但是这个应答也不是一个一个来的,而是会应答某个之前的 ID,表示都收到了,这种模式称为累计确认或者累计应答(cumulative acknowledgment),目的是节省时间,提高效率!

    ACK:通常被理解为收到数据后给出的一个确认ACK

    • 一是期望接收到的下一字节的序号n,该n代表接收方已经接收到了前n-1字节数据
    • 二是当前的窗口大小m,假定当前发送方已发送到第x字节,则可以发送的字节数就是y=m-(x-n).这就是滑动窗口控制流量的基本原理.

    **解决的问题:**发送端的缓存里是按照包的ID一个个排列的。 因为TCP协议是全双工通信协议。 所以客户端既是发送端,也是接收端。 服务器端既是接收端,也是发送端。 所以客户端既有发送端缓存,也有接收端缓存。 而服务器端既有接收端缓存,也有发送端缓存。

    滑动窗口包含:已发送未反馈+准备发送但未发送的数据。

    发送端:

    发送端缓存会被分为4部分:

    • 第一部分,已经发送并且已经确认的包
    • 第二部分,已经发送但是尚未确认的包
    • 第三部分,尚未发送但是马上准备发送的包
    • 第四部分,尚未发送但是暂时不准备发送的包。

    其中:

    • LastByteAcked:第一部分和第二部分的分界线
    • LastByteSent:第二部分和第三部分的分界线

    请添加图片描述

    ex:滑动窗口大小:12-4+1=9; 已经发送到:9 希望接受的下一序号:10

    则可以发送的数据=12-10+1=3

    我们使用三个术语来描述窗口左右边沿的运动:

    • 窗口左边沿向右边沿靠近为窗口合拢。
      • 这种现象发生在数据被发送和确认时。
    • 当窗口右边沿向右移动时将允许发送更多的数据,我们称之为窗口张开。
      • 这种现象发生在另一端的接收进程读取已经确认的数据并释放了TCP的接收缓存时

    当接收端的缓冲区满了,发送端接收到接收端的窗口大小为0,这个时候停止发送数据,这个时候发送端会过了超时重发的时间,发送一个窗口探测的包,此数据端仅含一个字节以获取最新的窗口大小信息

    接收端:

    • 第一部分:接受并且确认过的
    • 第二部分:还没接收,但是马上就能接收的
    • 第三部分:还没接收,也没法接收的。

    其中:

    • MaxRcvBuffer:最大缓存的量;
    • LastByteRead: 之后是已经接收了,但是还没被应用层读取的;
    • NextByteExpected :是第一部分和第二部分的分界线。

    请添加图片描述

    联系发送端和接收端看:

    (1)1、2、3 没有问题,双方达成了一致。

    (2)4、5 接收方说 ACK 了,但是发送方还没收到,有可能丢了,有可能在路上。

    (3)6、7、8、9 肯定都发了,但是 8、9 已经到了,但是 6、7 没到,出现了乱序,缓存着但是没办法 ACK。

    根据以上状态引入几个知识点:

    • 确认与重发的机制
      • 发送包丢失或ACK包其中一方丢失,都会导致重传。实际场景是:假设 4 的确认到了,不幸的是,5 的 ACK 丢了,6、7 的数据包丢了。
        • 超时重试:每一个发送了,但是没有 ACK 的包,都有设一个定时器,超过了一定的时间,就重新尝试。
        • 重试时间:数据包重传需要一个算法去计算超时的时间,时间太短的话包还没发送到就丢了,需要重新传,时间太长的话访问会变慢,时间必须大于往返时间 RTT
        • 在重传时间也就是往返的RTT的估计中引入自适应重传算法(Adaptive Retransmission Algorithm):估计往返时间,需要 TCP 通过采样 RTT 的时间,然后进行加权平均,算出一个值,而且这个值还是要不断变化的,因为网络状况不断地变化。除了采样 RTT,还要采样 RTT 的波动范围,计算出一个估计的超时时间。
    • TCP对于超时的策略是:超时间隔加倍,每当遇到一次超时重传的时候,都会将下一次超时时间间隔设置为先前值的两倍,两次超时,说明网络环境差,不宜频繁反复的发送
    • 快速重传的机制:当接收方收到一个序号大于下一个所期望的报文段时,就会检测到数据流中的一个间隔,于是它就会发送冗余的 ACK,仍然 ACK 的是期望接收的报文段。而当客户端收到三个冗余的 ACK 后,就会在定时器过期之前,重传丢失的报文段。

    ex:

    超时重传及时间:如果过一段时间,5、6、7 都超时了,就会重新发送。接收方发现 5 原来接收过,于是丢弃 5;6 收到了,发送 ACK,要求下一个是 7,7 不幸又丢了。当 7 再次超时的时候,有需要重传的时候,TCP 的策略是超时间隔加倍。每当遇到一次超时重传的时候,都会将下一次超时时间间隔设为先前值的两倍。两次超时,就说明网络环境差,不宜频繁反复发送。

    快速重传:接收方发现 6 收到了,8 也收到了,但是 7 还没来,那肯定是丢了,于是发送 6 的 ACK,要求下一个是 7。接下来,收到后续的包,仍然发送 6 的 ACK,要求下一个是 7。当客户端收到 3 个重复 ACK,就会发现 7 的确丢了,不等超时,马上重发。

    区别:

    • 快速重传:由接收端控制的,接收端会反复告诉发送端,我需要前面的包,中间丢了一个。
    • 超时重传:发送端在超过定时器的时间间隔后没有接到已发包的ack确认,超时重发。

    流量控制问题

    发送端发送的每一个数据包,服务端都要给一个确认包(ACK).确认它收到了。 服务端给发送端发送的确认包(ACK包)中,同时会携带一个窗口的大小。

    窗口大小 = 接收端最大缓存量 - 接收已确认但还未被应用层读取的部分

    发送窗口大小和接受窗口应用层读取的速度有关

    • 读取速度>窗口 窗口会不断变大
    • 读取速度<窗口 窗口会不断变小,极端情况下为0
    • 读取速度=窗口 窗口不变

    拥塞控制问题

    发送未确认<={cwnd, rwnd}

    Advertised window:接收端给发送端报的窗口大小,滑动窗口包含:已发送未反馈,准备发送但未发送的数据。

    rwnd:receiver window,接收方滑动窗口,用于防止接收方缓存占满

    cwnd:congestion window,拥塞窗口,用于控制将带宽占完也就是怕把网络塞满

    TCP 的拥塞控制主要来避免两种现象

    • 包丢失
    • 超时重传

    ex:如图所示,假设往返时间为 8s,去 4s,回 4s,每秒发送一个包,每个包 1024byte。已经过去了 8s,则 8 个包都发出去了,其中前 4 个包已经到达接收端,但是 ACK 还没有返回,不能算发送成功。5-8 后四个包还在路上,还没被接收。这个时候,整个管道正好撑满,在发送端,已发送未确认的为 8 个包,正好等于带宽,也即每秒发送 1 个包,乘以来回时间 8s。
    请添加图片描述

    如果我们在这个基础上再调大窗口,使得单位时间内更多的包可以发送,原来发送一个包,从一端到达另一端,假设一共经过四个设备,每个设备处理一个包时间耗费 1s,所以到达另一端需要耗费 4s,如果发送的更加快速,则单位时间内,会有更多的包到达这些中间设备,这些设备还是只能每秒处理一个包的话,多出来的包就会丢失,这是我们不想看到的。这个时候,我们可以想其他的办法,例如这个四个设备本来每秒处理一个包,但是我们在这些设备上加缓存,处理不过来的在队列里面排着,这样包就不会丢失,但是缺点是会增加时延,这个缓存的包,4s 肯定到达不了接收端了,如果时延达到一定程度,就会超时重传,也是我们不想看到的。

    拥塞窗口大小控制原则:

    • 一条 TCP 连接开始,cwnd 设置为一个报文段,一次只能发送一个,之后2,4,8,16…可以看出这是指数性的增长。

    • 涨到一个值 ssthresh 为 65535 个字节,当超过这个值的时候,就要改成线性增长。每收到一个确认后,cwnd 增加 1/cwnd。

    出现拥塞之后重传方案:

    • 拥塞的一种表现形式是丢包,需要超时重传,这个时候,将 sshresh 设为 cwnd/2,将 cwnd 设为 1,重新开始慢启动。这真是一旦超时重传,马上回到解放前。但是这种方式太激进了,将一个高速的传输速度一下子停了下来,会造成网络卡顿。
    • 前面我们讲过快速重传算法。当接收端发现丢了一个中间包的时候,发送三次前一个包的 ACK,于是发送端就会快速地重传,不必等待超时再重传。TCP 认为这种情况不严重,因为大部分没丢,只丢了一小部分,cwnd 减半为 cwnd/2,然后 sshthresh = cwnd,当三个包返回的时候,cwnd = sshthresh + 3,也就是没有一夜回到解放前,而是还在比较高的值,呈线性增长。

    请添加图片描述
    但是以上拥塞控制存在两个问题:

    • 丢包并不代表着通道满,例如公网上带宽不满也会丢包,这个时候就认为拥塞了,退缩了,其实是不对的。
    • TCP 的拥塞控制要等到将中间设备都填充满了,才发生丢包,从而降低速度,这时候已经晚了。其实 TCP 只要填满管道就可以了,不应该接着填,直到连缓存也填满。

    为了解决以上问题引入了TCP BBR 拥塞算法。它企图找到一个平衡点,就是通过不断地加快发送速度,将管道填满,但是不要填满中间设备的缓存,因为这样时延会增加,在这个平衡点可以很好的达到高带宽和低时延的平衡。

    总结

    • 顺序问题、丢包问题、流量控制都是通过滑动窗口来解决的、

      • 顺序问题,重传
      • 丢包问题,重传
      • 流量控制,包的确认中,同时会携带一个窗口的大小,如果这时候接收端缓存中的接受已确认一直不被应用层拿走,那么,就会使得等待接受未确认的窗口变为0,就会给发送端发送窗口为0。
    • 拥塞控制是通过拥塞窗口来解决的,相当于往管道里面倒水,快了容易溢出,慢了浪费带宽,要摸着石头过河,找到最优值。

    展开全文
  • 滑动窗口详解

    万次阅读 多人点赞 2021-10-18 19:57:16
    什么情况可以用滑动窗口来解决实际问题呢? 一般给出的数据结构是数组或者字符串 求取某个子串或者子序列最长最短等最值问题或者求某个目标值时 该问题本身可以通过暴力求解 核心思路 窗口的形成 在具体使用之前,...

    滑动窗口

    基本概念

    滑动窗口是一种基于双指针的一种思想,两个指针指向的元素之间形成一个窗口。

    分类:窗口有两类,一种是固定大小类的窗口,一类是大小动态变化的窗口。

    应用

    利用滑动窗口获取平滑的数据,如一段连续时间的数据平均值,能够有更好的稳定性,如温度监测。

    什么情况可以用滑动窗口来解决实际问题呢?

    1. 一般给出的数据结构是数组或者字符串
    2. 求取某个子串或者子序列最长最短等最值问题或者求某个目标值时
    3. 该问题本身可以通过暴力求解

    核心思路

    窗口的形成

    在具体使用之前,我们知道窗口实际是两个指针之间形成的区域,那关键就是这两个指针是如何移动的。

    1. 初始时,左右指针left,right都指向第0个元素,窗口为[left,right),注意这里是左闭右开,因此初始窗口[0,0)区间没有元素,符合我们的初始定义
      在这里插入图片描述

    2. 开始循环遍历整个数组元素,判断当前right指针是否超过整个数组的长度,是退出循环,否则执行第3步

    3. 然后right指针开始向右移动一个长度,并更新窗口内的区间数据

    在这里插入图片描述

    1. 当窗口区间的数据满足我们的要求时,右指针right就保持不变,左指针left开始移动,直到移动到一个不再满足要求的区间时,left不再移动位置

    在这里插入图片描述

    1. 执行第2步

    这中间,窗口的更新与维护是很重要的一环,新元素加入窗口,旧元素移出窗口,都需要及时地更新与这个窗口范围相关的数据。

    上述说明主要是两个while循环,可以简单抽象成一个模板如下:

    int left = 0,right =0;
    while(right指针未越界){
      char ch = arr[right++];
      //右指针移动,更新窗口
      ...
      
      //窗口数据满足条件 对于固定窗口而言,就是窗口的大小>=固定值;对于动态窗口,就是从left出发,窗口不断扩充,第一次满足题意的位置
      while(窗口数据满足条件){
      	//记录或者更新全局数据
      	...
      	
      	//右指针不动,左指针开始移动一位
      	char tmp = arr[left++];
      	
      	//左指针移动,窗口缩小,更新窗口数据
      	...
      }
      //返回结果
      ...
    }
    

    下面就结合所说的方法来看实际的栗子,主要的变化是窗口数据满足的条件,应该根据不同的要求来具体实现。

    实战

    LC438. 找到字符串中所有字母异位词

    给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。
    
    异位词 指由相同字母重排列形成的字符串(包括相同的字符串)。
    
    输入: s = "cbaebabacd", p = "abc"
    输出: [0,6]
    解释:
    起始索引等于 0 的子串是 "cba", 它是 "abc" 的异位词。
    起始索引等于 6 的子串是 "bac", 它是 "abc" 的异位词。
    

    分析

    题目的意思从字符串s中选取固定长度的子串,使得子串和给出的p字符串的字符种类相同,且每一种字符的数量也相同,称之为异位词。要求求出所有符合要求的子串的起始位置。

    暴力的解法是选取所有子串然后与给定的字符串p进行比较,复杂度较高。

    使用滑动窗口的方法来解决,并且是个固定大小的滑动窗口。

    窗口内数据满足条件后,开始进行收缩,这个条件是窗口内的字符串和给出的字符串,字符种类一样,且每一类字符的数量也一致。从这个描述来看可以使用两个个map来记录数据,一个记录窗口内的字符种类和数量,记作window,这个map需要根据窗口的变化来实时更新;一个记录给定字符串的种类和数量,记作map,这是一个固定的map,不会更新。

    如果存在一个窗口,window和map相同,即字符种类和大小完全一样,那么当前的left是一个可行的位置,将其添加到集合。那如何判断map和window是一样的呢?暴力的方法,就是按每类字符去对比,字符种类一样,每类数量一致,复杂度是O(n),那有没有更好的方法呢?
    在这里插入图片描述

    事实上,我们就是要在移动指针形成窗口的过程中,判断window和map是否一致。map是固定的,可以按每一类字符来比较,初始化一个计数器valid=0,如果窗口内某类字符完全一致,那么valid加1,最后如果valid==map.size()那么说明我们找到了一个解。

    当然我们引入的valid,就需要根据窗口的更新来更新。

    窗口更新(移入数据)

    更新window:如果该字符在map中,那么需要加入到window计数器中;否则计数器不更新

    更新valid:数据移入窗口时,如果当前字符在给定的map中,我们要的字符种类出现了,如果这类字符的数量和给定map中该类字符的数量也一致,那么说明该类字符我们就搞定了。

    窗口更新(移出数据)

    更新valid:数据移出窗口时,如果该字符在map中,说明是我们要处理的字符,其字符数量和map中一致时,此时要移出窗口,valid要减1。

    更新window:如果该字符在map中,那window计数器对于该计数器需要减1

    具体代码如下:

        public List<Integer> findAnagrams(String s, String p) {
            List<Integer> res = new ArrayList<>();
    
            Map<Character, Integer> map = new HashMap<>();
            Map<Character, Integer> window = new HashMap<>();
    
            char[] pattern = p.toCharArray();
            char[] arr = s.toCharArray();
    
            for (char a : pattern) {
                map.put(a, map.getOrDefault(a, 0) + 1);
            }
            int left = 0, right = 0;
            int valid = 0;
            while (right < s.length()) {
                char ch = arr[right];
                right++;
                /**
                 * 新元素加入窗口:什么时候当前元素可以加入窗口并新增valid计数?
                 * 当前元素在 map 中,那么把它加入到window中,加入后,如果在窗口内 该元素的数量和要求该元素数量一致,那么valid++,即该元素满足要求
                 */
                if (map.containsKey(ch)) {
                    //加入窗口
                    window.put(ch, window.getOrDefault(ch, 0) + 1);
                    // 不能写== 比较的是两个地址
                    if (window.get(ch).equals(map.get(ch))) {
                        valid++;
                    }
                }
                //判断窗口内元素是否满足条件,两个条件:1)固定窗口,当前窗口数量等于 模式字符串p的长度 2)当前窗口内组成的字符串和模式字符串 是异位词
                while (right - left == p.length()) {
                    //固定窗口,判断当前窗口是否是异位词,如果是说明找到了一个位置,把left加入到结果集中
                    if (valid == map.size()) {
                        res.add(left);
                    }
                    //right 不动,左指针开始向右,arr[left]元素移出窗口,同时该元素在window中对于的数目也要减去1
                    char tmp = arr[left];
                    left++;
                    if (map.containsKey(tmp)) {
                        if (map.get(tmp).equals(window.get(tmp))) {
                            valid--;
                        }
                        window.put(tmp, window.get(tmp) - 1);
                    }
                }
            }
            return res;
        }
    

    LC76. 最小覆盖子串

    分析

    和LC438很相似,但是本题是一个动态窗口,解题方法同LC438也一致,只是不需要对窗口的大小进行限制。当窗口内的数据满足条件时,就可以进行窗口的收缩了。

    代码如下:

        public String minWindow(String s, String t) {
            int start = 0, len = s.length() + 1;
            char[] pattern = t.toCharArray();
            char[] arr = s.toCharArray();
            Map<Character, Integer> map = new HashMap<>();
            Map<Character, Integer> window = new HashMap<>();
    
            for (char a : pattern) {
                map.put(a, map.getOrDefault(a, 0) + 1);
            }
            int left = 0, right = 0, valid = 0;
            while (right < s.length()) {
                char ch = arr[right++];
                if (map.containsKey(ch)) {
                    window.put(ch, window.getOrDefault(ch, 0) + 1);
                    if (window.get(ch).equals(map.get(ch))) {
                        valid++;
                    }
                }
                //满足条件的窗口 这里不是固定窗口,对窗口大小不限制,当map和window中的数据一致,满足条件,开始收缩
                while (valid == map.size()) {
                    // 当前已经满足要求,更新并记录数据,同时收缩窗口
                    if (right - left < len) {
                        start = left;
                        len = right - left;
                    }
                    char tmp = arr[left++];
                    if (map.containsKey(tmp)) {
                 // 当前要移出的字符种类和数量和map一致,移出后不一致,valid--
                        if (window.get(tmp).equals(map.get(tmp))) {
                            valid--;
                        }
                        window.put(tmp, window.get(tmp) - 1);
                    }
                }
            }
            return len == s.length()+1 ? "" : s.substring(start, start + len);
        }
    

    事实上,当valid==map.size()时,在窗口window内可能出现比map中对应字符数量多的情况,但是valid并没有变大,是因为在更新valid的时候,只有与map中字符数目相同才更新,如果已经满足了该条件,那么只更新window,不更新valid。

    举个例子,s=“BBNAC”,t=“ABC”

    第一个满足条件的窗口,B字符出现了2次,但map中只出现了1次。

    在移出的时候,只有当当前窗口中该移出字符的数量刚好等于map中该字符的数量时,valid才会-1,表示当前窗口已经不满足要求了,第二个while循环也就不会再继续了,又开始进行right指针的移动了。
    在这里插入图片描述

    最后

    本文对滑动窗口类的一些问题进行了分析,总结了一个模板,并结合Leetcode上的一些例子进行了应用实战。Leetcode相关类型的例子还有LC3、LC513、LC1052等,可以参考利用上述方法进行练习。

    迟来的本周更新总算赶上了,希望后续能够保持,与君共勉!

    更多信息可关注微信公众号:惊鸿只为卿
    在这里插入图片描述

    欢迎点赞、关注、分享、在看!

    展开全文
  • 本文实例讲述了JavaScript弹出新窗口后向父窗口输出内容的方法。分享给大家供大家参考。具体如下: 下面的JS代码演示了如何通过window.open方法打开一个弹出窗口,然后通过弹出窗口的句柄向父窗口输出信息的方法 &...
  • 本文实例讲述了js实现浏览器窗口大小被改变时触发事件的方法。分享给大家供大家参考。具体分析如下: 当浏览器的窗口大小被改变时触发的事件[removed] 为事件指定代码: 代码如下:[removed] = function(){ } 例如:...
  • Flink窗口-时间窗口

    千次阅读 热门讨论 2021-05-23 22:25:10
    时间窗口中,时间是什么时间?时间窗口特点是什么

    (一)时间窗口的本质

    前篇中,我们已经初略讲解了Flink中的数量窗口与时间窗口。

    无论是哪一种窗口,他们的作用都类似于计算器(计算数量、时间)仅仅只是让数据堆积(不会像默认的流处理,来一条处理一条),只有当满足触发计算时机的时候,便开始计算,比如五个数据才计算,或者五秒钟才计算一次…

    image-20210523163345564

    时间窗口的核心,便是时间的定义,与数据窗口不同的是,我们只能定义时间窗口的时间范围,无法从定义上确定每个时间窗口元素的个数;比如我们定义了时间窗口五秒钟触发一次,但我们无法确定,上一个五秒与下一个五秒窗口中数据量一致…

    那么时间窗口究竟如何使用呢?时间指的是什么时间呢?哎,让我们来一探究竟!

    (二)Time

    时间窗口中时间指的是什么时间呢?

    Flink程序支持针对三种时间进行数据处理:EventTime、IngestionTime、ProcessingTime

    EventTime:事件时间

    即事件元素中本身的时间(通常指时间元素中含有某时间列)

    IngestionTime:摄入时间

    事件元素到达Flink的时间

    ProcessingTime:处理时间

    事件元素经过第一个Flink算子处理时的时间

    1.12版本默认是根据EventTime,之前版本默认是采用ProcessingTime

    我们可以手动指定根据什么时间来处理事件

    Ex:

    image-20210523221211689

    渐渐的,摄入时间(IngestionTime)越来越不推荐使用了,实际上就生产而言,我们更多选择是根据业务采用不同的窗口分配器,选择根据事件时间还是处理时间进行计算。

    image-20210523221358301

    (三)基于处理时间的时间窗口

    (1)滚动窗口

    官网示例

    image-20210524212020340

    时间滚动窗口核心代码

    image-20210524212228548

    时间间隔可以通过使用Time.milliseconds(x)Time.seconds(x)Time.minutes(x)…等等指定窗口大小(毫秒、秒、分、时、天…)。

    EX:设置了每隔五秒滚动一次,即每五秒触发一次窗口计算逻辑

    TumblingProcessingTimeWindows.of(Time.seconds(5))
    

    如果按照窗口区间来划分的话,将会是这样(假如第一个事件元素的处理时间为12点,那么每五秒滚动窗口生命周期将会按照如下进行)

    image-20210523222433020

    即每五秒窗口执行一次,但需要注意的是,由于我们采用了KeyBy ,每个不同的KEY 均会有各自的窗口不断触发,但仍每个并行度的subTask只能同时处理一个KEY的数据。

    代码示例

    image-20210524210518602

    public class TumbleWindowFunction extends RichWindowFunction<Location,List<Location>, Integer,TimeWindow> {
        public TumbleWindowFunction() {}
        String uuid;
        /**
         * @param window 当前窗口
         * @param locations 入站数据集合
         * @param out 出站数据收集器 泛型为出站数据类型
         */
        @Override
        public void apply(Integer integer, TimeWindow window, Iterable<Location> locations, Collector<List<Location>> out) {
            out.collect(Lists.newArrayList(locations));
        }
    
        @Override
        public void open(Configuration parameters) throws Exception {
            uuid = UUID.randomUUID().toString();
            System.out.println(uuid + "窗口打开了");
        }
    
        @Override
        public void close() throws Exception {
            System.out.println(uuid + "窗口关闭了");
        }
    }
    

    image-20210524210625885

    滚动窗口也是支持时间偏移量的

    // TumblingEventTimeWindows.of(窗口大小, 偏移量) 例如窗口大小为5s,偏移时间为5s
    TumblingEventTimeWindows.of(Time.seconds(5), Time.seconds(5))
    

    image-20210524213101420

    注意:偏移量必须小于窗口大小

    image-20210524213509213

    image-20210524213250285


    (2)滑动窗口

    image-20210524213633885

    image-20210524211627254

    时间滑动窗口核心代码

    // 设置窗口为滑动处理时间滑动窗口,且窗口大小为10s,滑动为5s 即每十秒,计算一次最近五秒的数据
    SlidingProcessingTimeWindows.of(Time.seconds(10), Time.seconds(5))
    

    滑动窗口也支持偏移量设置

    image-20210524213728699

    image-20210524214416337

    (3)偏移量说明

    如果窗口是基于事件时间,在中国时区内,必须指定的偏移量Time.hours(-8)


    (四)基于事件时间的时间窗口

    (1)为什么需要事件时间

    有时候,我们的业务决定了我们必须以事件事件进行处理

    比如,某用户在2021-05-24 11:59:28进行了支付操作,由于某原因(网络延迟、数据量过大…)此条支付消息到Flink时已经 2021-05-24 12:01:10了,如果我们现在要计算平台在2021-05-24 11:00-2021-05-24 12:00这个时间段的支付总量,那么此条数据就应包括进来…如果按照处理时间计算,那么此条数据归属窗口则是2021-05-24 12:01:10之内(后)了,就会导致2021-05-24 11:00-2021-05-24 12:00这个时间段的支付总量漏计算了数据。

    正是由于这些场景的存在,Flink推出了基于事件时间的处理窗口,根据事件本身的事件进行归属窗口分配,然后触发对应窗口计算

    (2)什么是事件时间

    事件时间,就是事件元素中,本身携带着的一列时间属性(必须为1970后的时间戳)

    (3)事件时间示例

    image-20210524222632865

    模拟定位数据源产生

    image-20210524222959442

    核心代码

    指定窗口分配器为TumblingEventTimeWindows,且窗口大小为10s

    TumblingEventTimeWindows.of(Time.seconds(10))
    

    启动Job发现…报错

    image-20210524222812703

    完整错误信息:

    Caused by: java.lang.RuntimeException: Record has Long.MIN_VALUE timestamp (= no timestamp marker).
        Is the time characteristic set to 'ProcessingTime', or did you forget to call 
        'DataStream.assignTimestampsAndWatermarks(...)'?
    

    错误意思是当前时间没有时间戳标记,您需要将其切换为基于处理时间ProcessTime进行作业或者是您忘记了设置Watermarks

    image-20210524223321045

    这难道不是时间戳标记吗?为什么还是提示说找不到时间戳标记呢?

    因为Flink不会识别事件中的时间列(避免属性中出现多个时间列无法选择),我们必须要手动指定事件元素的时间列属性

    根据错误提示,我们便来玩上一玩

    image-20210524223711088

    指定水印,设置事件时间列

    dataStreamSource.assignTimestampsAndWatermarks();

    我们先将DEMO跑起来,后边有watermaker-blog详细讲解水印机制

    EX:

    SingleOutputStreamOperator<Location> watermarks = locationSource.
        assignTimestampsAndWatermarks(WatermarkStrategy.
                                      <Location>forBoundedOutOfOrderness(Duration.ofSeconds(5))
                                      // 设置事件时间为devTime属性
                                      .withTimestampAssigner((event, timestamp) -> event.getDevTime()));
    

    image-20210524224049886
    先放出设置后运算结果吧,WaterMaker后边会详细讲到以及验证!

    image-20210526202050360

    (五)时间窗口大小说明

    时间窗口大小由size决定

    image-20210526223636949

    时间窗口运行示例:

    image-20210526223711582

    注意点:时间窗口大小为左闭右开属性,即**image-20210526223809615**窗口中,包含着12:00:05的数据,但不含12:00:10的数据

    注意:一个事件窗口窗口中最大的时间(根据窗口的类型 ,ex:所有元素中 最大的摄入时间、处理时间、事件时间)为窗口结束毫秒时间戳-1


    (六)时间窗口的生命周期

    (1)默认

    一旦应属于该窗口的第一个元素到达,就会创建一个窗口,并且当时间(事件时间、处理时间、摄入时间)超过其结束时间戳(可加上用户指定的时间)后 ,该窗口将被完全删除,Flink只会删除基于时间的窗口。

    Ex:采用基于处理时间的开窗策略,该策略每5分钟创建一次不重叠(或翻滚)的窗口

    现在第一个元素的处理时间为2021-05-26:12:00,那么Flink会创建一个2021-05-26 12:00 - 2021-05-26 12:05的时间窗口,当处理时间大于等于12:05时,便会触发该窗口进行计算,且计算后将此窗口删除,后续在无法打开2021-05-26 12:00 - 2021-05-26 12:05这个窗口

    (2)设置延迟

    但在使用事件时间窗口时,元素可能会延迟到达,Flink 用来跟踪事件时间进度的水印已经超过了元素所属窗口的结束时间戳。有关Flink 如何处理事件时间的更深入讨论,请参阅 事件时间,尤其是后期元素

    默认情况下,当水印超过窗口末尾时,将删除后期元素。但是,Flink 允许为窗口操作符指定最大允许延迟。Allowed lateness 指定元素在被丢弃之前可以延迟多少时间,其默认值为 0。 在 watermark 已经通过窗口末尾之后但在它通过窗口末尾之前到达的元素加上允许的延迟,仍然添加到窗口中。根据使用的触发器,延迟但未丢弃的元素可能会导致窗口再次触发。对于EventTimeTrigger.

    为了完成这项工作,Flink 会保持窗口的状态直到它们允许的延迟到期。一旦发生这种情况,Flink 会移除窗口并删除其状态,如窗口生命周期部分所述。

    默认情况下,允许的延迟设置为0。也就是说,到达水印之后的元素将被丢弃。

    展开全文
  • JAVA 窗口

    2018-06-16 19:32:16
    窗口一个基于GUI的应用程序应当提供一个能和操作系统直接交互的容器,该容器可以被直接显示、绘制在操作系统所控制的平台上,例如显示器上,这样的容器被称作GUI设计中的底层容器,Java提供的JFrame类的实例就是一个...
  • 滑动窗口机制

    千次阅读 多人点赞 2021-09-21 11:13:16
    ​ 从上图中可以看到,发送端每发送一个数据包,需要得到接收端的确认应答以后,才可以发送下一个数据包。这种一发一收的方式大大浪费了时间。为了避免这种情况,TCP引入了窗口概念,其可以一次发送多条数据,并...
  • 我先在的问题是,一但我在主窗口中调用这个login()的子窗口时,虽然子串口能显示,但是他的输入框里面的变量v1n_ip = StringVar()无论我输入什么都是空。。。。新手不知道问题出在哪里?求教大佬
  • Java 窗口

    2021-03-01 10:49:51
    需要注意的是,窗口默认地被系统添加到 显示器屏幕上,因此窗口不能和其它窗口嵌套,即不能将一个窗口添加到另一个窗口中.Frame有下列常用方法Frame() 该构造方法可以创建一个无标题的窗口窗口的默认布局的...
  • Flink 中的时间和窗口

    千次阅读 2022-03-29 10:26:11
      在分布式系统中,节点“各自为政”,是没有统一时钟的,数据和控制信息都通过网络进行传输。比如现在有一个任务是窗口聚合,我们希望将每个小时的数据收集起来进行统计处理。而对于并行的窗口子任务,它们所在...
  • TCP可靠传输-滑动窗口

    千次阅读 2022-04-18 15:31:52
    在上一篇叙述停止等待协议时,我们提到了信道利用率这个概念,那么什么是信道利用率呢? 信号利用率其实就是在指定时间能能传输的数据分组的多少,我们当然是希望在保证可靠传输的情况下,使用最短的时间传输完数据...
  •   对于UE来,根据窗口句柄(以下函数)来获取其是否有父窗口并不能用来获取进程的主窗口。 HWND parent = GetParent(h);   每一个创建出来的窗口(SWindow)是根窗口,因此想要获得进程主窗口,只能通过...
  • 而不是自身窗口的window 父页面中:父页面向子页面发送跨域信息,window就是在父页面中嵌入的iframe指向的子页面的window,即:iFrame.contentWindow 子页面中:子页面想父页面发送跨域信息,window就是父页面的...
  • Python 脚本自动窗口截图

    千次阅读 2020-12-30 05:20:29
    利用Python自带的win32api和win32...今天Python实用宝典就来讲讲怎么在Python中实现截图功能,以下教程默认您已经安装好了Python哦,没有的话见这个教程:python详细安装指南:1.获取窗口左上角及右下角坐标import...
  • Win32子窗口及其创建应用

    千次阅读 2019-08-22 17:54:02
    后面所的子窗口控件是一种特殊的子窗口。子窗口控件不需要我们来定义窗口类,系统已经帮我们定义好了,我们自己引用就好。 这里我们先介绍普通子窗口。 一、子窗口的创建 创建过程: 1.注册窗口类(我们在主...
  • Android窗口设计之Dialog、PopupWindow、系统窗口的实现

    千次阅读 热门讨论 2020-12-19 16:07:43
        窗口设计之Dialog、PopupWindow、系统窗口的实现 Android应用程序窗口设计系列博客: Android应用程序窗口设计之Window及WindowManager的创建 Android应用程序窗口设计之setContentView布局加载的实现 普法...
  • windows窗口分析,父窗口,子窗口,所有者窗口

    万次阅读 多人点赞 2016-12-14 11:50:57
    (本文尝试通过一些简单的实验,来分析Windows的窗口机制,并对微软的设计理由进行一定的猜测,需要读者具备C++、Windows编程及MFC经验,还得有一定动手能力。文中可能出现一些术语不统一的现象,比如“子窗口”,有...
  • Windows编程系列——第三:创建窗口 这里介绍的是典型的win32窗口应用程序结构,通常需要以下7个步骤: 程序入口点(WinMain函数) 注册窗口类(RegisterClass/EX) 创建窗口类(CreateWindow/ex) 显示主窗口...
  • 上篇文章了如何编写一个弹出对话框的程序,这篇文章就来讲讲如何在C\C++下创建一个窗口。来简单介绍下 Windows窗口程序 的创建过程:首先我们需要注册一个窗口类,可以使用RegisterClass函数,接着使用...
  • 手把手教你写第一个Windows窗口

    千次阅读 2022-04-23 23:56:12
    手把手教你写第一个Windows窗口,快速上手,你学会了吗
  • 文章目录七、实现步骤(十)创建窗口界面...目前只是创建一个可以显示出来和关闭的主界面窗口,等到将各个功能模块窗口界面完成了,我们会修改代码,给出主窗口界面的最终版。 MainFrame继承JFrame类 添加构造方法
  • 【Qt】Qt窗口程序

    千次阅读 2021-03-22 14:50:52
    程序要实现的功能是:运行开始出现一个对话框,按下登录主界面按钮后该对话框消失并进入主窗口,如果直接关闭这个对话框,便不能进入主窗口,整个程序也将退出。进入主窗口后,按下显示对话框按钮,会弹出一个对话框...
  • PyQt5-多窗口数据传输

    千次阅读 2020-12-22 14:02:33
    #窗口之间数据传递(通过属性方式)from PyQt5.QtWidgets import QDialogButtonBox, QDateTimeEdit,QDialog,QComboBox,QTableView,QAbstractItemView,QHeaderView,QTableWidget, QTableWidgetItem, QMessageBox,...
  • java 窗口

    千次阅读 2018-06-18 21:48:17
    窗口一个基于GUI的应用程序应当提供一个能和操作系统直接交互的容器,该容器可以被直接显示、绘制在操作系统所控制的平台上,例如显示器上,这样的容器被称作GUI设计中的底层容器,Java提供的JFrame类的实例就是一个...
  • 下面贤集网小编就给大家讲讲脱机使用打印机是什么意思以及脱机打印机状态显示错误怎么办。一、脱机使用打印机是什么意思有时候我们在使用打印机时,打印机的任务窗口的标题栏会显示脱机使用打印机(有些品牌的打印机...
  • TCP滑动窗口与流量控制

    万次阅读 2018-09-19 10:53:26
    TCP连接的两端交互作用,互相提供数据流的相关信息,包括报文段序列号、ACK号和窗口大小(即接收端的可用空间)。发送端根据这些信息动态调节窗口大小来控制发送,以达到流量控制的目的。每个TCP头部的窗口大小字段...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 191,570
精华内容 76,628
热门标签
关键字:

信息窗口都是讲什么

友情链接: Calculator.rar