首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >flink cep

flink cep

作者头像
IT云清
发布于 2022-08-07 04:52:26
发布于 2022-08-07 04:52:26
54900
代码可运行
举报
文章被收录于专栏:IT云清IT云清
运行总次数:0
代码可运行

1.cep适合做什么

CEP: Complex Event Processing缩写,复杂事件处理。

CEP是一种事件流上的模式匹配技术,与传统的先存储后查询数据的方式不同:CEP预先设置查询条件,然后让实时数据通过这些查询条件,引擎抓取符合条件的数据,这种查询是连续不断的,连续到达的事件与提前定义好的复杂模式进行匹配,然后输出满足复杂模式的事件。

CEP用于分析低延迟、频繁产生的不同来源的事件流,可以做到感知(实时事件的检测)、分析(聚合各类事件)、响应(更新预期);

2.flink cep基本概念与使用流程:

Flink CEP内部是用NFA(非确定有限自动机)来实现的,由点和边组成的一个状态图,以一个初始状态作为起点,经过一系列的中间状态,达到终态。

点分为起始状态、中间状态、最终状态三种,边分为take、ignore、proceed三种。

take:必须存在一个条件判断,当到来的消息满足take边条件判断时,把这个消息放入结果集,将状态转移到下一状态。 ignore:当消息到来时,可以忽略这个消息,将状态自旋在当前不变,是一个自己到自己的状态转移。 proceed:又叫做状态的空转移,当前状态可以不依赖于消息到来而直接转移到下一状态。

flink cep的使用,核心分为2个部分:定义事件模式,匹配结果处理;

1.模式pattern

模式可以理解为,事件流中,某个事件具有的某个特征,或者某种行为模式,或者处理事件的规则。

模式定义好后用来提取事件流中符合模式规则的事件序列。当源源不断的事件流经过时,只有符合我们定义的复杂模式的事件,才会被提取处理。

个体模式:一个单独的模式定义,即为一个个体模式。

组合模式:多个个体模式组合起来形成一个组合模式。也叫模式序列;模式序列必须以一个初始序列开始;

模式组:将一个模式序列作为条件嵌套在个体模式里;待定。

个体模式又分为:单例(singleton)模式,循环(looping)模式

单例模式接收单个事件,循环模式可以接收多个事件。

每个模式,可以有一个或者多个条件,模式基于条件接受事件。

2.条件condition

1.个体模式条件

每个模式都要指定触发条件,作为模式是否接受事件进入结果集的判断依据。

当事件进入模式进行匹配时,如果事件不满足当前模式的条件,则事件会被丢弃,否则会加入到当前模式对应的缓存结果集中,或者流入下一个模式,进行后续匹配。

单个模式条件主要通过:.where() .or() .until来指定条件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Pattern<TradeEvent, TradeEvent> pattern = Pattern.<TradeEvent>begin("start")
.where(new SimpleCondition<TradeEvent>() { //where 可以有多个,相当于and
    @Override
    public boolean filter(TradeEvent tradeEvent) throws Exception {
        return tradeEvent.getAccountName().equals("张三") ;
    }
}).or(new SimpleCondition<TradeEvent>() { //or
    @Override
    public boolean filter(TradeEvent tradeEvent) throws Exception {
        return tradeEvent.getAccountName().equals("李四");
    }
}).where(new IterativeCondition<TradeEvent>() { //迭代条件
    @Override
    public boolean filter(TradeEvent tradeEvent, Context<TradeEvent> context) throws Exception {
        Iterable<TradeEvent> start = context.getEventsForPattern("start"); //能够对模式之前所接受的所有事件进行处理
        return tradeEvent.getDealTime().before(new Date(tradeEvent.getOpenDate().getTime() + 30 * ONE_DAY_LONG));
    }
}).until(new SimpleCondition<TradeEvent>() { //终止条件
    @Override
    public boolean filter(TradeEvent tradeEvent) throws Exception {
        return tradeEvent.getTradeType().equals("扣息");
    }
}).within(Time.hours(1));//1小时以内 为模式指定事件约束,在多久内匹配有效。

2.模式序列条件

模式序列的条件有3种:

严格临近 Strict Contiguity:要求一个event之后必须紧跟下一个符合条件的event,中间不允许有其他事件。对应.next(); 宽松临近Relaxed Contiguity:和上一种不同的是,该模式允许中间有其他无关的event,会对他们进行忽略。对应.followedBy(); 非确定性宽松临近 Non-Deterministic Relaxed Contiguity:非确定性宽松连续性,可以对已经匹配的事件就行忽略,对接下来的事件继续匹配。对应.followedByAny() 3.匹配之后的跳过策略 在给定的pattern中,当同一事件符合多种模式条件组合之后,需要执行AfterMatchSkipStrategy来确定到底输出哪种匹配。主要有4中策略:

1 NO_SKIP 输出所有可能匹配的事件进行输出,不忽略任何一条

2 SKIP_PAST_LAST_EVENT. 忽略开始触发到当前触发pattern的所有部分匹配。只保留最近的匹配

3 SKIP_TO_FIRST[patternName]。忽略第一个匹配指定patternName的pattern之前的所有部分匹配。保留第一个匹配 和 第一个能够匹配patternName之后的所有匹配,

4 SKIP_TO_LAST[patternName]。忽略第一个匹配和 最后一个匹配PatternName 之间的所有部分匹配。 保留第一个匹配 和最后一个能匹配PatternName的匹配,只保留2个

5 SKIP_TO_NEXT. 忽略所有部分和第一个匹配有同样开始的匹配。保留第一个匹配,以后后面不和第一个匹配有同样开始的匹配

3.模式检测

当定义好模式和事件流后,指定输入流和模式,当有事件到达时,即可开始匹配。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
PatternStream<TradeEvent> patternStream = CEP.pattern(source, pattern);//给定的输入流指定模式

4.匹配事件提取

创建了PatternStream后,就可以从符合模式序列的事件序列中提取事件了。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SingleOutputStreamOperator<Object> process = patternStream.process(new PatternProcessFunction<TradeEvent, Object>() {
    @Override
    public void processMatch(Map<String, List<TradeEvent>> map, Context context, Collector<Object> collector) throws Exception {
        for (Map.Entry<String, List<TradeEvent>> entry : map.entrySet()) {
            //key是模式的名称,value是此模式下接收的所有的事件
            logger.info("##########结果为 key={},value={}",entry.getKey(),entry.getValue().toString());
        }
    }
});

由于模式中可以指定超时时间,部分事件序列可能会因为超过时间窗口长度而被丢弃。这一部分根据具体业务可能还需要指定超时时间处理程序。

5.案例

1.事件序列

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
new TradeEvent(2,"张三","一类账户","充值",40.00,openDate1,dateFormat.parse("2022-04-04 12:03:00")),
new TradeEvent(3,"张三","一类账户","购买",30.00,openDate1,dateFormat.parse("2022-04-04 12:04:00")),
new TradeEvent(6,"李四","一类账户","登陆",0.00,openDate1,dateFormat.parse("2022-04-04 13:00:00")),
new TradeEvent(7,"李四","一类账户","充值",40.00,openDate1,dateFormat.parse("2022-04-04 13:02:00")),
new TradeEvent(8,"李四","一类账户","充值",21.00,openDate1,dateFormat.parse("2022-04-04 13:03:00")),
new TradeEvent(9,"王二","一类账户","充值",60.00,openDate1,dateFormat.parse("2022-04-04 13:03:00")),
new TradeEvent(10,"王二","一类账户","购买",60.00,openDate1,dateFormat.parse("2022-04-04 13:03:00")),
new TradeEvent(11,"李四","一类账户","购买",30.00,openDate1,dateFormat.parse("2022-04-04 13:04:00")),
new TradeEvent(12,"李四","一类账户","送礼",30.00,openDate1,dateFormat.parse("2022-04-04 13:06:00")),
new TradeEvent(13,"李四","一类账户","送礼",10.00,openDate1,dateFormat.parse("2022-04-04 13:08:00")),
new TradeEvent(4,"张三","一类账户","送礼",30.00,openDate1,dateFormat.parse("2022-04-04 12:06:00")),
new TradeEvent(5,"张三","一类账户","送礼",10.00,openDate1,dateFormat.parse("2022-04-04 12:08:00")),
new TradeEvent(14,"张三","一类账户","退出",0.00,openDate1,dateFormat.parse("2022-04-04 12:10:00"))

2.基础配置

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 //账户在登录后,马上进行充值(5分钟),充值后立马买礼物(5分钟),买完立即送人(5分钟),且充值金额与送礼金额接近。
DataStream<TradeEvent> source = env.fromElements(eventList)
.assignTimestampsAndWatermarks(new BoundedOutOfOrdernessTimestampExtractor<TradeEvent>(Time.milliseconds(500L)) {
    @Override
    public long extractTimestamp(TradeEvent payEvent) {
        //时间戳,这里选择了TradeEvent对象内部的时间字段,则状态机接收事件时,时间的先后顺序以TradeEvent中的dealTime判断
        return payEvent.getDealTime().getTime();
    }
}).keyBy(new KeySelector<TradeEvent, Object>() {
    @Override
    public Object getKey(TradeEvent value) throws Exception {
        //用accountName分区 每个accountName都会有一个自己的NFA实例
        return value.getAccountName();
    }
});

3.模式定义

登陆->充值->购买->送礼 松散匹配,忽略之间不符合的事件。

超时之前/完全匹配之前,符合部分条件的数据,会常驻状态的结果集中(内存)。直到超时或者序列满足,才会被拿出处理/清理;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private static Pattern<TradeEvent, TradeEvent> getPattern() {
    Pattern<TradeEvent, TradeEvent> pattern =
            Pattern.<TradeEvent>begin("登陆").where(new SimpleCondition<TradeEvent>() {
                @Override
                public boolean filter(TradeEvent tradeEvent) throws Exception {
                    return tradeEvent.getTradeType().equals("登陆") ;
                }
            }).followedBy("充值").where(new SimpleCondition<TradeEvent>() {
                @Override
                public boolean filter(TradeEvent tradeEvent) throws Exception {
                    return tradeEvent.getTradeType().equals("充值");
                }
            }).followedBy("购买").where(new SimpleCondition<TradeEvent>() {
                @Override
                public boolean filter(TradeEvent tradeEvent) throws Exception {
                    return tradeEvent.getTradeType().equals("购买");
                }
            }).followedBy("送礼1").where(new SimpleCondition<TradeEvent>() {
                @Override
                public boolean filter(TradeEvent tradeEvent) throws Exception {
                    return tradeEvent.getTradeType().equals("送礼");
                }
            }).followedBy("送礼2").where(new IterativeCondition<TradeEvent>(){
                @Override
                public boolean filter(TradeEvent value, Context<TradeEvent> ctx) throws Exception {
                    Iterable<TradeEvent> charge = ctx.getEventsForPattern("充值");
                    //关联处理 可以获取充值阶段的数据
                    return false;
                }
            }).times(1).within(Time.minutes(7));
    return pattern;
}

4.结果处理

1.打印出符合模式的事件序列中送礼的详细数据;

2.组装简单指标数据存储

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 SingleOutputStreamOperator<Object> outputStreamOperator = patternStream.process(new PatternProcessFunction<TradeEvent, Object>() {
 
        /**
         * 结果集数据获取
         * @param match
         * @param ctx
         * @param out
         * @throws Exception
         */
        @Override
        public void processMatch(Map<String, List<TradeEvent>> match, Context ctx, Collector<Object> out) throws Exception {
            //把符合模式序列的结果集中,送礼模式的结果集打印出来
            List<TradeEvent> songli = match.get("送礼");
            logger.info("##########送礼结果为:{}", songli.toString());
 
            songli.stream().forEach(event -> insertIndex(event.getAccountName()+"_登陆_充值_送礼_5min内",1));
            logger.info("--------------------\r\r\r");
        }
    });
    env.execute("execute");
    System.out.println("===============================");
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
2022-04-26 17:58:19.573  INFO   --- [pOperator (1/1)] com.java4all.mycep.pattern.BasicPattern  : ##########送礼结果为:[TradeEvent{id=4, accountName='张三', accountType='一类账户', tradeType='送礼', tradeMoney=30.0, openDate=Fri Jan 01 00:00:00 CST 2021, dealTime=Mon Apr 04 00:06:00 CST 2022}]
2022-04-26 17:58:19.583  INFO   --- [pOperator (1/1)] com.java4all.mycep.pattern.BasicPattern  : 写入指标:key=张三_登陆_充值_送礼_5min内,value=1
 
2022-04-26 17:58:19.587  INFO   --- [pOperator (1/1)] com.java4all.mycep.pattern.BasicPattern  : ##########送礼结果为:[TradeEvent{id=12, accountName='李四', accountType='一类账户', tradeType='送礼', tradeMoney=30.0, openDate=Fri Jan 01 00:00:00 CST 2021, dealTime=Mon Apr 04 13:06:00 CST 2022}]
2022-04-26 17:58:19.588  INFO   --- [pOperator (1/1)] com.java4all.mycep.pattern.BasicPattern  : 写入指标:key=李四_登陆_充值_送礼_5min内,value=1

6.状态的结果集

NFA运行时,状态数据是保存在内存中的,通过内存队列存放半匹配和已匹配数据。源码如下,目前,未发现支持对接外部存储的拓展方式。

由于数据较多时,可能内存数据集较大,flinkcep 基于论文实现了一套数据结构

其中图a、b、c是原始的R1、R2、R3缓存,图d则是整合在一起的共享版本缓存。它会将所有序列的前向指针附加上一个版本号(采用杜威十进制法,点号分隔),并且遵循以下两个规则:

迁移到下一个状态时,版本号增加一位,如a[1]状态的版本号是1(为了符合习惯写作1.0),a[i]状态的版本号是1.0、1.1,b状态的版本号是1.0.0、1.1.0……以此类推;

当序列发生分裂时,处于当前状态的版本号位加1。例如e3事件产生了2.0版本,e6事件产生了1.1版本。

依照这种规则,就可以根据前向指针上版本号的递增规律和前缀来回溯出正确的序列了。Flink CEP中将此缓存设计为SharedBuffer类,但是版本的设计有些不同。

7.总结:

优点:

1.模式定义较为灵活,丰富的java api,方便开发;

2.量词,组合模式,连续策略,跳过策略等语义支持丰富;

缺点:

1.一个模式中不支持多个不同的时间窗口;

2.由于状态的结果集在内存中,难以支持超长时间窗口数据处理;

3.对标准的事件序列数据处理较好,其他回溯统计类难以处理;

4.无不发生算子;

5.新增模式困难;需要自研某种机制;

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-08-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
从今天起,不用再纠结没有Google Play了——APKPure
对于国内的大多数安卓用户来说,想要在自家手机上安装一个Play商店,应该都是比较麻烦的,再加上混乱的软件环境,充满广告的APP,自己的手机并不是很安全,想必这也是一些人选择iOS的原因。 •从今天起,再也不愁找不到想要的APP了——酷安 •从今天起,再也不愁找不到想玩的游戏了——taptap 前两天的这两篇内容本质上都是试图寻找Google Play商店的代替品,但由于在国内,又由于一些众所周知的原因,很多APP是不会上架的,今天,则为大家推荐一款能作为Play商店的克隆产品的——APKPure •可以在公
课代表
2018/06/29
8K0
猎豹(金山),你可长点心吧。
还记得12年开始使用自己的第一个安卓手机的时候,课代表手机上就有了几个必不可少的APP,QQ、UC浏览器、猎豹清理大师、KingRoot,后来换了苹果手机,对安卓的APP大多数还停留在很久以前,虽然有时不时的弹窗或者通知,忍忍也就过去了。
课代表
2018/12/19
7450
看书必备!安卓+iOS 看小说神器!!
看网络小说的小伙伴们应该都知道笔趣阁这三个字,最早的笔趣阁是哪一个,什么时候被ban已经不可考,但这个三个字已经成为小说界的一个大IP,百度出来一大串,什么笔趣阁阅读,新笔趣阁,没有什么真的假的,就看
课代表
2018/06/29
2.3K0
如何以2RMB一月的低价开通YouTube Premium之阿根廷区
YouTube Premium,前称YouTube Red、Music Key,是一个提供给世界多个国家地区的YouTube付费流媒体订阅服务,服务范围包括美国、澳大利亚、墨西哥、新西兰、韩国、日本、中国台湾、马来西亚、中国香港、印度、中南美洲以及欧洲各国------维基百科
冬冬i
2022/04/09
8.1K0
如何以2RMB一月的低价开通YouTube Premium之阿根廷区
登录GitHub要求2FA了,你想了解的免费解决办法
笔者近期收到了GitHub官方的通知邮件,要求用户启用双因素身份验证(2FA)。
程序熵
2023/09/25
10.9K2
登录GitHub要求2FA了,你想了解的免费解决办法
ChatGPT飙升苹果商店榜首,每周订阅需7.99美元,结果是个假的???
衡宇 发自 凹非寺 量子位 | 公众号 QbitAI ChatGPT出App版了,苹果商店下载就能使用?? 打开美国Apple Store搜索,下载后软件内每周付费7.99美元,即可享受与它无次数限制畅聊。 不过别忙着付费! 这个ChatGPT Chat GPT AI With GPT-3,跟Open AI、ChatGPT的创建者本身没有半毛钱关系。 更戏剧性一幕发生了: 它成功跻身App Store生产率类别中“免费”应用程序的前列,一度登顶。 因为引发公众舆论,截至发稿时间,这个App已经被下架。 但
量子位
2023/02/28
2K0
ChatGPT飙升苹果商店榜首,每周订阅需7.99美元,结果是个假的???
2021年国产VR头显红黑榜揭晓,赢家是……
(VRPinea 1月21日讯)转眼2022年已经过去大半个月,农历新年越来越接近,首先还是要感谢大家这一年来对小P的关注和支持!在过去的2021年,国产VR头显赛道相当激烈。经盘点,2021年各大国内厂商共发布了八款VR一体机和两款PC VR。虽然大部分产品在上新初期,小P就已详细测评过,但年底还是有必要全面盘点一下,唤起大家的记忆。需要说明的是,本期盘点不针对使用场景,有特定场景需求的小伙伴,请结合我们之前的详细测评,配合“食用”,效果更佳。
VRPinea
2022/03/11
1.8K1
2021年国产VR头显红黑榜揭晓,赢家是……
APP Store也无法幸免,恶意软件是如何逃过应用商店的审查?
Google Play和APP Store作为我们日常生活中最耳熟能详的两大应用商店,在提供便利的同时,也藏匿着诸多安全风险。Google Play因其宽松的网络环境,成为了恶意软件繁育的温床。而苹果生态虽然是出了名的“干净”,但也难逃恶意软件的伪装。
FB客服
2023/10/10
9920
APP Store也无法幸免,恶意软件是如何逃过应用商店的审查?
亲身体验后,为你安利 3 个远程桌面控制软件~
小詹最近入手了一台mac pro,很是轻便,以后出差开会或者在家都不用背着那台服役了6年都厚板砖了。
小小詹同学
2019/06/20
1.4K0
亲身体验后,为你安利 3 个远程桌面控制软件~
开源软件求捐赠也要被谷歌抽税?开发者:直接改成GitHub链接
机器之心报道 编辑:泽南、小舟 要免费就彻底免费,谷歌商店这方面很严格。 谷歌最近把一个叫 Language Transfer 的应用从 Play 商店移除了。 这是一个免费的语言学习应用,由个人开发者 Mihalis Eleftheriou 制作。它摆脱了传统语言学习过程中对单词和短语无休止的记忆的要求,鼓励你通过体验的方式来学习语言。 在首次提交发布版本时,这款 app 因为内含 Patreon 链接而被谷歌拒绝上架。 Patreon 是一个专门用于捐助艺术家和开发者的平台,粉丝可以通过购买个人的「月度
机器之心
2023/03/29
9360
开源软件求捐赠也要被谷歌抽税?开发者:直接改成GitHub链接
Google Play商店漏洞:黑客可远程在你的安卓手机上安装恶意APP
安全研究人员发现Google Play商店中两个严重安全漏洞,可以允许攻击者远程在用户的安卓设备上安装并下载恶意APP(应用)。 Metasploit框架的技术领导Tod Beardsley在Rapid7上提醒说: 一个X-Frame-Options(XFO)漏洞结合一个最近的安卓WebView(Jelly Bean)漏洞,就可以创造出一种新的攻击方式——通过该方式黑客可以利用google play商店悄无声息地向受害者的安卓设备安装任何恶意APP,即使没有征得用户允许。 受影响的用户 该漏洞影响安卓4
FB客服
2018/02/05
2.1K0
Google Play商店漏洞:黑客可远程在你的安卓手机上安装恶意APP
最棒的Chrome插件去哪找?这里有一份榜单
上个月给大家介绍了重大更新后的 扩展迷 Extfans 网站,当时也说到:可以把它当成是一个 Chrome 商店的镜像版,可以无障碍下载安装 Chrome 扩展。
kbsc13
2019/09/26
9290
最棒的Chrome插件去哪找?这里有一份榜单
Google Play:使用深度学习,根据用户环境实现个性化 App 推荐
【新智元导读】本文是 Google Play 的 “App 发现”系列文章的第二篇,谷歌 App发现团队讨论了如何使用深度学习,根据用户曾经下载过的 App 和用户的使用环境,为用户提供个性化的app推荐。 在“App 发现”系列的第一部分,我们讨论了如何使用机器学习更深入地理解与 App 相关的主题,以在 Google Play 商店上提供更好的 App 搜索和发现体验。在本文中,我们将讨论深度学习框架如何根据用户曾经下载过的 App 和用户的使用环境,为用户提供个性化的App 推荐。 我们的 App 发
新智元
2018/03/26
1.4K0
Google Play:使用深度学习,根据用户环境实现个性化 App 推荐
不能错过的十款谷歌浏览器插件
我之前一直在用 Safari 浏览器,最喜欢的就是阅读器功能。不过后来发现谷歌浏览器有那么多各种各样神奇的插件后,就逐渐开始使用谷歌浏览器。之后看到有意思的插件就下载下来尝试一下,不好用就再删掉,这样反反复复的最终留下来了几款感觉还挺实用的免费插件给小伙伴们推荐一下。(以下排名不分先后)
壹言
2020/04/12
2.8K0
不能错过的十款谷歌浏览器插件
Google Play Store启动漏洞赏金计划保护Android应用
Google终于发布了Google Play Store的漏洞赏金计划,安全人员可以寻找或者报告Android应用中存在的漏洞。 这个项目的名称为 “Google Play安全奖金”,赏金会发放给那些
FB客服
2018/02/27
1.2K0
Google Play Store启动漏洞赏金计划保护Android应用
常用的20个在线工具类网站清单
最近开始使用的一款网盘工具,和百度网盘类似,不过没有下载速度的限制,并且可以支持自定义分享文件的下载次数(需要开会员)。
测试开发技术
2020/05/26
3.6K0
常用的20个在线工具类网站清单
Google Play十周年,恶意软件泛滥问题仍悬而未决
2012年7月26日,谷歌将Android Market重新命名,变为如今大家耳熟能详的Google Play。作为整个安卓系统最重要、最为官方的应用下载市场,10年来,Google Play已经服务了来自全球190多个国家地区的25亿用户。但正所谓树大招风,Google Play也早已被众多恶意软件盯上,成为它们的集散中心。 【图:为庆祝Google Play十周年,谷歌设计了新的标志】 近两年,Google Play恶意软件泛滥的问题已经引起了越来越多安全机构的注意,根据2020年的一项调查研究,Go
FB客服
2023/03/30
1.2K0
Google Play十周年,恶意软件泛滥问题仍悬而未决
为Android开发者整理的Google I/O开发者大会第一弹
今天凌晨的Google I/O开发者大会不像以往的历届,貌似今年的人工智能和智能家居抢走了Android系统的风头。以往每年应该都是 Android 新系统的发布才是重点。看来人工智能和虚拟现实确实是未来的趋势和重点,再怎么抢风头,它们的发展也离不开我们的智能手机啊,所以作为 Android 开发者我们继续努力吧,今天我们就重点介绍跟我们Android开发相关的内容,下面是我的整理。 简单介绍 今天,Google一年一度的 I/O 开发者大会在加州山景城开幕。Google I/O是由Google举行的网络开
非著名程序员
2018/02/02
2.7K0
为Android开发者整理的Google I/O开发者大会第一弹
用手机也能轻松玩转matlab编程了【软件分享】
因为下载渠道是google play商店的缘故,安卓版用户可能获取最新版matlab比较费劲。为了让大家能在移动端畅通无阻地编写执行matlab程序,公众号专门为大家分享两款最新版移动端matlab。今后只要有版本更新,公众号就会为大家在网盘中实时上传。
巴山学长
2020/10/23
2.3K0
用手机也能轻松玩转matlab编程了【软件分享】
浏览 GitHub 太卡了?教你两招!
GitHub 访问起来比较卡,这个看起来貌似无解。国内的 gitee 网速倒是可以,但是无法代替 GitHub,个人感觉 gitee 上还是开源项目多一些,工具类库要少一些。
江南一点雨
2019/09/05
6140
浏览 GitHub 太卡了?教你两招!
推荐阅读
相关推荐
从今天起,不用再纠结没有Google Play了——APKPure
更多 >
LV.1
这个人很懒,什么都没有留下~
目录
  • 1.cep适合做什么
  • 2.flink cep基本概念与使用流程:
    • 1.模式pattern
    • 2.条件condition
      • 1.个体模式条件
      • 2.模式序列条件
    • 3.模式检测
    • 4.匹配事件提取
    • 5.案例
      • 1.事件序列
      • 2.基础配置
      • 3.模式定义
      • 4.结果处理
  • 6.状态的结果集
  • 7.总结:
    • 优点:
    • 缺点:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档