点击上方“zhisheng”,选择“设为星标”

公众号(zhisheng)内回复:ffa 可以获取到所有 PPT 和视频

随着云计算、大数据等新一代IT技术在各行业的深入应用,政企机构IT规模和复杂程度不断提高,网络流量、日志等各类数据规模大幅提升。与此同时,网络攻防日益激烈,网络安全威胁逐渐凸显出来,这对于SOC/SIEM产品的性能提出了一个很大的挑战。因此,奇安信独立研发了国内首款流式分布式关联分析引擎Sabre,搭载于公司旗下态势感知与安全运营平台(下文简称NGSOC),从而大幅提升NGSOC的数据分析能力和网络安全检测能力。

本文将从技术研发的角度,全面阐述Sabre的由来。

1.Sabre是什么?

Sabre是奇安信研发的新一代流式分布式关联分析引擎,是CEP(Complex Event Processing,复杂事件处理)技术在大数据领域的一个具体实现。奇安信研发关联引擎已有数年历史,中间经历了三次主要的技术演进,在2015年之前,奇安信使用的是基于开源CEP软件Esper研发的关联引擎,由于一些架构和设计上的问题,整体性能不是非常理想,也不支持多机扩展;在2016-2017年,用C++开发了一个高性能引擎,代号Dolphin,可以在单机上实现很高的性能;在2018年,从技术上全面转向Flink框架,极大增强了系统的可扩展性,推出了Sabre引擎作为NGSOC的核心检测引擎。

Sabre应用于奇安信的态势感知与安全运营平台(NGSOC)产品中,NGSOC主要服务于中大型政企客户,目前已经成功应用于200+大型政企机构,在国内安全管理平台市场占有率第一,其中搭载的Sabre引擎提供了核心的安全检测能力。和很多互联网公司内部自建数据处理平台不同的是,Sabre更注重的是技术的工程化交付,因此在设计和实现上和一般基于Flink的业务系统相比会有较大差异。

2.为什么要开发Sabre?

随着网络应用规模和复杂度的不断提高,网络中传输的数据量急剧上升,网络攻防对抗日趋激烈,企业内部新的安全问题开始显现,实时关联分析引擎,作为NGSOC检测体系中的核心组件,也遇到了越来越多的挑战:

(1) 性能优化问题。主要针对随着新型攻击的不断出现,关联分析规则规模不断上升导致的性能问题。传统开源关联引擎往往加载几十条规则即达到了性能瓶颈,而NGSOC的应用场景中,关联引擎需要支撑规模上千的关联规则。在有限的硬件资源条件下,如何避免系统整体性能随规则条数上升而发生线性下降,成为关联引擎的一个主要挑战。

(2) 规则的语义扩展问题。在网络安全事件井喷式发生的今天,安全需求迅速扩展。为了能够在有限时间内对特定语义的快速支持,关联引擎的整体架构必须异常灵活,才能适应未来安全分析场景的各种需求,而基于开源关联引擎实现的产品会在激烈的需求变化时遇到很多问题。

(3) 系统扩展性问题。主要指分布式环境下节点的扩展。随着企业网络流量和业务资产的不断扩容,NGSOC的系统处理能力必须能随企业业务规模的不断扩张而动态扩展。未来的分布式关联分析引擎需要支持数百节点的规模,以能够与现有的大数据平台无缝集成。

与Storm、Spark Streaming等流式计算框架相比,Flink具有编程接口丰富、自带多种Window算子、支持Exactly-Once、高性能分布式检查点、批流计算模式统一等优点。且Flink发展较为迅速,开源社区极为活跃,是目前最具发展潜力的流式计算框架,是未来实时计算执牛耳者。由于Flink为事件驱动的实时关联分析引擎在底层框架上提供了有力支持,因此奇安信的下一代关联分析引擎Sabre是基于Flink流式计算框架实现的。

在选择了Flink之后,发现Flink开源方案直接应用于安全检测领域,仍有很大的技术障碍。

和互联网企业内部使用的大型集群相比,NGSOC面向的企业级应用集群规模较小,硬件资源受限,且客户的定制需求较多,导致安全监测的规则要求更严格,引擎发布成本较高。但是,现有的Flink开源解决方案,或者需要根据业务需求进行改造,或者性能较差,均不能较好地解决上述问题。首先,原生Flink只提供了函数式编程模式,即需要直接编写复合特定业务需求的固定程序代码,由此导致开发测试周期较长,不便于动态更新规则,可复用性较弱,且不能从全局语义层面进行优化,性能较差。其次,Flink-CEP仅是一个受限的序列算子,在运行时需要将所有数据传输到CEP算子,然后在CEP算子中串行执行各个条件语句。这种汇集到单点的运行模式,较多的冗余数据需要执行条件匹配,产生了不必要的网络负载,而且降低了CPU利用率。再次,还存在一些非官方开源的轻量级CEP引擎,比如Flink-siddhi,功能简单,不是一个完整的解决方案。

面向企业级的网络安全监测引擎具有一些特定需求,当前解决方案对此支持较差。比如,现实情况,客户对算子实例和Taskmanager概念较为模糊,真正关心的运行状态的基本单位是规则。而Flink监控页面显示的是算子实例及Taskmanager进程整体内存的运行状态,而在网络安全监控的业务场景中,对运行状态和资源的监控均需要细化到规则层面。其次,在算子层面,Flink原生Window算子,没有较好的资源(CPU/内存)保护机制,且存在大量重复告警,不符合网络安全监测领域的业务需求。再次,Flink缺乏一些必要算子,例如不支持“不发生算子”。一个较为常见的应用场景,某条规则指定在较长时间内没收到某台服务器的系统日志,则认为此台服务器发生了异常,需要及时通知用户。

综上所述,现有解决方案应用于网络安全监测领域均会遇到问题,由此奇安信集团基于Flink构建了一种全新的CEP引擎。

3.Sabre如何处理数据?

上图为NGSOC的数据处理架构图,展示了整个系统的数据流。自下而上,NGSOC的数据处理过程由四部分组成,其核心是由“流式分布式关联分析引擎Sabre”构成的数据处理层PROCESS,且Sabre运行的硬件环境是由多个节点组成的分布式集群。右侧的规则配置管理模块供专业的安全人员使用,可通过类Visio图的界面较为友好便捷地配置规则;规则管理模块具有添加、删除、编辑和查找规则的功能,并可批量启动/停用多个规则,规则管理模块会将处于启动状态的有效规则统一发送给Sabre引擎。
最上方的绿色部分为结果处理层RESULT,Sabre会将处理结果“告警”或“关联事件”发送给下级响应模块,实现响应联动、分析调查及追踪溯源等功能。最下方的蓝色部分为日志采集层COLLECT,主要有“网络流量日志采集器”、“设备及系统日志采集器”和“其他类型的日志采集器(比如:防火墙、入侵检测系统IDS、入侵防护系统IPS、高级威胁监测系统APT等等)”三大类。中间部分为日志解析层PARSE,网络流量日志和系统安全日志格式多种多样,须将上述两类原始日志数据格式化,而其他类型的日志(比如:威胁情报、漏洞、资产)本身即为格式化数据,最终所有格式化数据均需统一存储到高性能消息队列Kafka。

4.Sabre的关键技术

(1) 系统架构

上图为Sabre系统整体架构图。Sabre整体架构包含三大核心模块,中间是Sabre-server,左侧是配置端,右侧是Sabre运行端。核心数据流存在两条主线,红线表示规则的提交、编译、发布和运行流程。绿线表示状态监控的生成、收集、统计和展示流程。如图所示,此架构与Hive极为相似,是一种通用的大数据OLAP系统架构。下面详细介绍三大核心模块和两大核心数据流。

首先,通过规则配置端创建规则,采用性能保护配置端修改性能保护策略,然后将任务所属的规则文件和性能保护策略文件一并推送到Sabre-server提供的REST接口,该接口会调用文件解析及优化方法构建规则有向无环图。接着执行词法语法分析方法,将规则有向无环图中各个节点的EPL转换为与其对应的AST(Abstract Syntax Tree,抽象语法树),再将AST翻译为任务java代码。最后调用maven命令打包java代码为任务jar包,并将任务jar包及基础运行库一并提交到Flink-on-YARN集群。

Flink有多种运行模式(例如 standalone Flink cluster、Flink cluster on YARN、Flink job on YARN等),Sabre采用了“Flink job on YARN”模式,在奇安信NGSOC应用的特定场景下,采用YARN可统一维护硬件资源,并且使用 Flink job on YARN 可与Hadoop平台进行无缝对接,以此实现了很好的任务间资源隔离。

在Sabre任务执行过程中,Kafka数据源向引擎提供原始事件。引擎处理结果分为回注事件和告警事件两类。告警事件会直接输出到目的Kafka,供下级应用消费。回注事件表示一条规则的处理结果可直接回注到下级规则,作为下级规则的数据源事件,由此可实现规则的相互引用。

绿线流程表示任务执行过程中会定时输出节点的运行监控消息到Sabre-server的监控消息缓存器,然后监控消息统计器再汇总各个规则实例的运行监控消息,统计为整条规则的运行监控状态,最后通过Sabre-server提供的REST接口推送给规则监控端。

(2) 功能设计

算子的设计和实现是构建CEP的重要组成部分。

上图展示了Flink和Sabre算子的比较关系。包含三列:Flink原生算子、Sabre算子、两者之间的比较结果(相同、实现、优化、新增)。Sabre共有13种完全自研的核心算子,其中Datasource、CustomKafkaSink和CustomDatabase按照 Flink接口要求做了具体实现,Filter、Key、Join和Aggregation按照Flink原有算子的语义做了重新实现,CustomWindow和Sequence在Flink原有算子语义的基础上做了优化实现。

由于Flink原有FilterFunction算子只能简单返回布尔值,以致输出结果的控制能力较差,而重新实现的Filter算子可同时执行多种业务逻辑,将一个“原始事件”输出一个或多个“处理事件”。Sabre还实现了一种针对窗口的全局触发器Trigger,Trigger能够将多个子计算性算子组合为复杂表达式,并实现了具有GroupBy/Distinct功能的Key算子以适配此Trigger算子。众所周知,Join和Aggregation的时间范围由Window限定,而Flink原有Window算子不适合网络安全监测需求,为此Sabre设计了一种“自定义Window算子”,且重新实现了与“自定义Window算子”相匹配的Join和Aggregation算子。

上图展示了Sabre算子间的关联关系。序列Sequence、聚合Aggregation、不发生NotOccur、流式机器学习StreamML和连接Join均属于Window执行时间包含的计算性算子。蓝色虚线表示引用动态数据,紫色虚线表示Filter无须经过Window可直连输出组件。

如上图所示,为满足复杂场景需求,一种规则的输出可直接作为另一种规则的输入。通过这种规则拆分的方式,能分层构造较为复杂的“多级规则”。如:上面的“暴力探测”规则结果可以直接回注到下面的“登陆成功 ”规则,而无须额外的通信组件。

(3) 性能优化

因为采用了Flink作为底层运行组件,所以Sabre具有与Flink等同的执行性能。并且,针对网络安全监测领域的特定需求,还做了如下的性能优化工作:

1)全局组件(数据源、动态表)引用优化。由于Kafka类型的数据源topic有限,而规则数量可动态扩展,导致多个规则会有极大概率共用同一个数据源,根据EPL语义等价原则合并相同的数据源,进而可以减少数据输入总量及线程总数。

2)全新的匹配引擎。序列Sequence算子采用了新颖的流式状态机引擎,复用了状态机缓存的状态,提升了匹配速度。类似优化还包含大规模IP匹配引擎和大规模串匹配引擎。

3)表计算表达式优化。对于规则中引用的动态表,会根据表达式的具体特性构建其对应的最优计算数据结构,以避免扫描全表数据,进而确保了执行的时间复杂度为常量值。

4)自定义流式Window算子。采用“时间槽”技术实现了乱序纠正功能,并具有可以实时输出无重复、无遗漏告警的特性。

5)字段自动推导,优化事件结构。根据规则前后逻辑关系,推导出规则中标注使用的原始日志相关字段,无须输出所有字段,以此优化输出事件结构,减少输出事件大小。

6)数据分区自动推导,优化流拓扑。由于功能需要,Window往往会缓存大量数据,以致消耗较多内存。通过对全局窗口Hash优化,避免所有全局窗口都分配到同一个Taskmanager进程,由此提高了引擎整体内存的利用率。

(4) 机器学习

机器学习在网络异常检测上已经越来越重要,为适应实时检测的需求,Sabre没有使用Flink MachineLearning,而是引入了自研的流式机器学习算子StreamML。Flink MachineLearning是一种基于批模式DataSetApi实现的机器学习函数库,而StreamML是一种流式的机器学习算子,其目的是为了满足网络安全监测的特定需求。与阿里巴巴开源的Alink相比,StreamML允许机器学习算法工程师通过配置规则的方式即可快速验证算法模型,无需编写任何程序代码。并且,流式机器学习算子StreamML实现了“模型训练/更新”与“模型使用”统一的理念。其核心功能是通过算法、技术及模型实现数据训练及对新数据检测。该流式机器学习算子StreamML引入的输入有三类,分别是:事件流、检测对象和对象属性;输出也包含三类,分别是:事件、告警和预警。

流式机器学习算子StreamML的组件栈包含三部分,从下往上依次为:机器学习方法、应用场景和产品业务。通过基本的机器学习算法(比如:统计学习算法、序列分析算法、聚类分析算法),流式机器学习算子StreamML可满足具体特定的安全监测应用场景(比如:行为特征异常检测、时间序列异常检测、群组聚类分析),进而为用户提供可理解的产品业务(比如:基线、用户及实体行为分析UEBA)。

行为特征异常检测:根据采集的样本数据(长时间)对统计分析对象建立行为基线,并以此基线为准,检测发现偏离正常行为模式的行为。例如:该用户通常从哪里发起连接?哪个运营商?哪个国家?哪个地区?这个用户行为异常在组织内是否为常见异常?

时间序列异常检测:根据某一个或多个统计属性,判断按时间顺序排列的数值序列是否异常,由此通过监测指标变化来发现安全事件。例如:监测某网站每小时的访问量以防止DDOS攻击;建模每个账号传输文件大小的平均值,检测出传输文件大小的平均值离群的账号。

群组聚类分析:对数据的特征属性间潜在相关性进行挖掘,将具有类似特征值的数据进行分组聚类。例如:该用户是否拥有任何特殊特征?可执行权限/特权用户?基于执行的操作命令和可访问的实体,来识别IT管理员、DBA和其它高权限用户。

5.Sabre如何快速适配复杂的客户环境?

由于客户规模较大,项目种类较多,部署环境较为复杂,或者存在多种Yarn集群版本,或者Sabre需作为单一Flink应用发布到客户已部署的Flink集群。如何节省成本及提高实施效率,快速适配上述复杂的部署环境是个亟需解决的问题,为此Sabre的设计原则是仅采用Flink的分布式计算能力,业务代码尽可能减少对API层的依赖,以便于兼容多种Flink版本。如图所示,Deploy、Core、APIs、Libraries四层是大家熟知的Flink基本的组件栈。Sabre对API层的依赖降到了最低,只引用了DataStream、KeyedStream和SplitStream三种数据流API。函数依赖则包括DataStream的assignTimestamps、flatMap、union、keyBy、split、process、addSink等函数,KeyedStream最基础的process函数,以及SplitStream的select函数。由于依赖的Flink API较少,Sabre可以很容易适配到各个Flink版本,从而具有良好的Flink版本兼容性。

6.如何保障Sabre稳定运行?

为减少引擎的维护成本,需要保障引擎在超限数据量的条件下亦然能够稳定运行,Sabre主要做了两个优化:流量控制和自我保护。

为了增强Sabre引擎的健壮性,避免因规则配置错误,导致生成大量无效告警,在输出端做了流量控制,以更好地保护下级应用。当下级抗压能力较弱时(例如数据库),整个系统会做输出降级。

另一个问题是,跑在JVM上的程序,经常会遇到由于长时间 Full GC导致OOM的错误,并且此时CPU占用率往往非常高,Flink同样存在上述问题。自我保护功能采用了同时兼顾“Window隶属规则的优先级”及“Window引用规则数量”两个条件的加权算法,以此根据全局规则语义实现自动推导Window优先级,并根据此优先级确定各个Window的自我保护顺序。实时监控CPU及内存占用,当超过一定阈值时,智能优化事件分布,以防出现CPU长期过高或内存使用率过大而导致的OOM问题。

目前,基于Flink构建的Sabre引擎还在继续开发新的功能,并会持续优化引擎性能。未来将总结凝练项目中的优秀实践,并及时回馈给Apache Flink社区。

作者:奇安信集团高级研发总监韩鹏
地址:https://www.aqniu.com/tools-tech/59894.html

如果觉得文章对你有帮助,请转发朋友圈、点在看,让更多人获益,感谢您的支持!

END

关注我

公众号(zhisheng)里回复 面经、ES、Flink、 Spring、Java、Kafka、监控 等关键字可以查看更多关键字对应的文章。

Flink 实战

1、《从0到1学习Flink》—— Apache Flink 介绍
2、《从0到1学习Flink》—— Mac 上搭建 Flink 1.6.0 环境并构建运行简单程序入门
3、《从0到1学习Flink》—— Flink 配置文件详解
4、《从0到1学习Flink》—— Data Source 介绍
5、《从0到1学习Flink》—— 如何自定义 Data Source ?
6、《从0到1学习Flink》—— Data Sink 介绍
7、《从0到1学习Flink》—— 如何自定义 Data Sink ?
8、《从0到1学习Flink》—— Flink Data transformation(转换)
9、《从0到1学习Flink》—— 介绍 Flink 中的 Stream Windows
10、《从0到1学习Flink》—— Flink 中的几种 Time 详解
11、《从0到1学习Flink》—— Flink 读取 Kafka 数据写入到 ElasticSearch
12、《从0到1学习Flink》—— Flink 项目如何运行?
13、《从0到1学习Flink》—— Flink 读取 Kafka 数据写入到 Kafka
14、《从0到1学习Flink》—— Flink JobManager 高可用性配置
15、《从0到1学习Flink》—— Flink parallelism 和 Slot 介绍
16、《从0到1学习Flink》—— Flink 读取 Kafka 数据批量写入到 MySQL
17、《从0到1学习Flink》—— Flink 读取 Kafka 数据写入到 RabbitMQ
18、《从0到1学习Flink》—— 你上传的 jar 包藏到哪里去了
19、大数据“重磅炸弹”——实时计算框架 Flink
20、《Flink 源码解析》—— 源码编译运行
21、为什么说流处理即未来?
22、OPPO数据中台之基石:基于Flink SQL构建实时数据仓库
23、流计算框架 Flink 与 Storm 的性能对比
24、Flink状态管理和容错机制介绍
25、原理解析 | Apache Flink 结合 Kafka 构建端到端的 Exactly-Once 处理
26、Apache Flink 是如何管理好内存的?
27、《从0到1学习Flink》——Flink 中这样管理配置,你知道?
28、《从0到1学习Flink》——Flink 不可以连续 Split(分流)?
29、Flink 从0到1学习—— 分享四本 Flink 的书和二十多篇 Paper 论文
30、360深度实践:Flink与Storm协议级对比
31、Apache Flink 1.9 重大特性提前解读
32、如何基于Flink+TensorFlow打造实时智能异常检测平台?只看这一篇就够了
33、美团点评基于 Flink 的实时数仓建设实践
34、Flink 灵魂两百问,这谁顶得住?
35、一文搞懂 Flink 的 Exactly Once 和 At Least Once
36、你公司到底需不需要引入实时计算引擎?
37、Flink 从0到1学习 —— 如何使用 Side Output 来分流?
38、一文让你彻底了解大数据实时计算引擎 Flink
39、基于 Flink 实现的商品实时推荐系统(附源码)
40、如何使用 Flink 每天实时处理百亿条日志?
41、Flink 在趣头条的应用与实践
42、Flink Connector 深度解析
43、滴滴实时计算发展之路及平台架构实践
44、Flink Back Pressure(背压)是怎么实现的?有什么绝妙之处?
45、Flink 实战 | 贝壳找房基于Flink的实时平台建设
46、如何使用 Kubernetes 部署 Flink 应用
47、一文彻底搞懂 Flink 网络流控与反压机制
48、Flink中资源管理机制解读与展望
49、Flink 实时写入数据到 ElasticSearch 性能调优
50、深入理解 Flink 容错机制
51、吐血之作 | 流系统Spark/Flink/Kafka/DataFlow端到端一致性实现对比

Flink 源码解析

知识星球里面可以看到下面文章

朕已阅 

基于 Flink 构建关联分析引擎的挑战和实践相关推荐

  1. 网络安全公司奇安信集团是如何基于 Flink 构建 CEP 引擎实时检测网络攻击【未来不可忽视的网络安全】

    摘要: 奇安信集团作为一家网络安全公司是如何基于 Flink 构建 CEP 引擎实时检测网络攻击?其中面临的挑战以及宝贵的实践经验有哪些?本文主要内容分为以下四个方面: 背景及现状 技术架构 产品及运 ...

  2. 深度剖析SOC高性能实时事件关联分析引擎

    [引言]安全管理平台(SOC) 的一项关键技术就是事件关联分析.借助实时的事件关联分析引擎,安全管理平台能够发掘出复杂的海量安全日志和事件背后隐藏的信息,引导安全管理人员发现外 部***和内部违规行为 ...

  3. 快手基于 Flink 构建实时数仓场景化实践

    摘要:本文整理自快手数据技术专家李天朔在 5 月 22 日北京站 Flink Meetup 分享的议题<快手基于 Flink 构建实时数仓场景化实践>,内容包括: 快手实时计算场景 快手实 ...

  4. 阿里云实时计算产品经理李佳林:基于 Flink 构建大规模风控系统的技术实战

    本⽂由 Flink 社区志愿者邹志业整理,内容来源⾃阿里云实时计算产品经理李佳林在 7 月 5 日 Flink 峰会(CSDN 云原生系列)的演讲.主要内容包括:基于 Flink 构建风控系统.阿里风 ...

  5. 基于 Flink 构建大规模实时风控系统在阿里巴巴的落地

    目前 Flink 基本服务于集团的所有 BU ,在双十一峰值的计算能力达到 40 亿条每秒,计算任务达到了 3 万多个,总共使用 100 万+ Core :几乎涵盖了集团内的所有具体业务,比如:数据中 ...

  6. 基于Flink构建的实时数据仓库,这才是OPPO数据中台的基础

    一.OPPO 实时数仓的演进思路 1.1.OPPO 业务与数据规模 大家都知道 OPPO 是做智能手机的,但并不知道 OPPO 与互联网以及大数据有什么关系,下图概要介绍了 OPPO 的业务与数据情况 ...

  7. ISME:微生物网络构建与分析面临的挑战

    关注我们 一起探索微生物领域的奥妙 摘要 微生物网络作为当下一种流行的数据分析方法被广泛应用于微生物群落研究.虽然目前已有许多并不断有新的微生物网络构建方法被开发出来,但与数据预处理.混杂因素.网络评 ...

  8. flink读取不到文件_日处理数据量超10亿:友信金服基于Flink构建实时用户画像系统的实践...

    简介: 友信金服公司推行全域的数据体系战略,通过打通和整合集团各个业务线数据,利用大数据.人工智能等技术构建统一的数据资产,如 ID-Mapping.用户标签等.友信金服用户画像项目正是以此为背景成立 ...

  9. 基于Flink构建企业级实时数仓(附项目源码)

    离线数仓是大数据技术发展至今最耀眼的明星,然而随着业务需求的不断升级,对于一些延时较高的场景,要把链路延时降低到秒级,就需要基于 Flink 的实时数仓出马了. 企业级实时数仓的应用场景很多,比如: ...

最新文章

  1. matlab实现单纯型法解线性规划_【运筹学教程】求解线性规划问题的单纯形法
  2. 006-筛选分类排序搜索查找Filter-Classificatio-Sort-Search-Find-Seek-Locate
  3. [Java基础]IO流小结
  4. YBTOJ洛谷P4869:出现位置(线性基)
  5. web后端开发学习路线_学习后端Web开发的最佳方法
  6. java计算集合对称差
  7. apriori算法代码_资源 | 《机器学习实战》及代码(基于Python3)
  8. jq使用教程03_JQData说明书概要
  9. 如何向小白讲述软件架构发展历程?
  10. 全新的Windows Phone 8开发资源汇总
  11. R_ggplot2基础(三)
  12. 参数利用SpringMVC构建REST接口:第七篇 控制层实现
  13. vue移动端下拉切换页面_详解vue移动端 下拉刷新
  14. 漆远离职阿里加盟复旦!大牛纷纷回归学界,大厂AI名存实亡?
  15. FPGA使用ISERDES2过采样
  16. php商城添加加入购物车,php添加购物车,php购物车
  17. mysql自增不连续的问题 ALTER TABLE `表名` AUTO_INCREMENT =1;
  18. Katalon Studio:一款静候你使用的免费自动化测试工具
  19. 有什么比较适合个人日常办公管理的便签软件
  20. Linux deepin 15.11设置:输入时禁用触摸板

热门文章

  1. 【深度学习】医学图像自动分割的评价指标讲解
  2. Myabtis源码分析五-Mybatis配置加载完全图解,建造者模式的使用,涵盖Java各种技术栈
  3. 【java】 【接口】【继承】【抽象类】案例 运动员和教练
  4. linux写画小猪佩奇代码,代码绘制一直小猪佩奇
  5. 17年1月9日,小程序来了。深度解析2017微信公开课
  6. JAVA 操作 excel 并生成 xml
  7. 一文了解 Python 中的生成器
  8. HTML5实战-张晓飞-专题视频课程
  9. AUC的是如何计算的
  10. 多元矩阵乘积的导数问题