从0到1:构建强大且易用的规则引擎

引言

2016年07月恰逢美团点评的业务进入“下半场”,需要我们在各个环节优化体验、提升效率、降低成本。技术团队需要怎么做来适应这个变化?这个问题直接影响着之后的工作思路。

美团外卖的CRM业务步入成熟期,规则类需求几乎撑起了这个业务所有需求的半边天。一方面规则唯一不变的是“多变”,另一方面开发团队对“规则开发”的感受是乏味、疲惫和缺乏技术含量。如何解决规则开发的效率问题,最大化解放开发团队成为目前的一个KPI。

规则引擎作为常见的维护策略规则的框架很快进入我的思路。它能将业务决策逻辑从系统逻辑中抽离出来,使两种逻辑可以独立于彼此而变化,这样可以明显降低两种逻辑的维护成本。

分析规则引擎如何设计正是本文的主题,过程中也简单介绍了实现方案。

案例

首先回顾几个美团点评的业务场景。通过这些场景大家能更好地理解什么是规则,规则的边界是什么。在每个场景后面都介绍了业务系统现在使用的解决方案以及主要的优缺点。

门店信息校验

场景

美团点评合并前的美团平台事业部中,门店信息入口作为门店信息的第一道关卡,有一个很重要的职责,就是质量控制,其中第一步就是针对一些字段的校验规则。

下面从流程的角度看下门店信息入口业务里校验门店信息的规则模型(已简化),如下图。

门店信息校验规则

规则主体包括3部分:

  • 分支条件。分支内逻辑条件为“==”和“<”。
  • 简单计算规则。如:字符串长度。
  • 业务定制计算规则。如:逆地址解析、经纬度反算等。

方案——硬编码

由于历史原因,门店信息校验采用了硬编码的方式,伪代码如下:

if (StringUtil.isBlank(fieldA)|| StringUtil.isBlank(fieldB)|| StringUtil.isBlank(fieldC)|| StringUtil.isBlank(fieldD)) {return ResultDOFactory.createResultDO(Code.PARAM_ERROR, "门店参数缺少必填项");
}
if (fieldA.length() < 10) {return ResultDOFactory.createResultDO(Code.PARAM_ERROR, "门店名称长度不能少于10个字符");
}
if (!isConsistent(fieldB, fieldC, fieldD)) {return ResultDOFactory.createResultDO(Code.PARAM_ERROR, "门店xxx地址、行政区和经纬度不一致");
}

优点

  • 当规则较少、变动不频繁时,开发效率最高。
  • 稳定性较佳:语法级别错误不会出现,由编译系统保证。

缺点

  • 规则迭代成本高:对规则的少量改动就需要走全流程(开发、测试、部署)。
  • 当存量规则较多时,可维护性差。
  • 规则开发和维护门槛高:规则对业务分析人员不可见。业务分析人员有规则变更需求后无法自助完成开发,需要由开发人员介入开发。

门店审核流程

场景

流程控制中心(负责在运行时根据输入参数选择不同的流程节点从而构建一个流程实例)会根据输入门店信息中的渠道来源和品牌等特征确定本次审核(不)走哪些节点,其中选择策略的模型如下图。

门店审核流程

规则主体是分支条件:

  • 分支条件主体是“==”,参与计算的参数是固定值和用户输入实体的属性(比如:渠道来源和品牌类型)。

方案——开源Drools从入门到放弃

经过一系列调研团队选择基于开源规则引擎Drools来配置流程中审核节点的选择策略。使用Drools后的规则配置流程如下图。

规则配置流程

上图中DSL即是规则主体,规则内容如下:

rule "1.1"whenpoi : POI( source == 1 && brandType == 1 )thenSystem.out.println( "1.1 matched" );poi.setPassedNodes(1);endrule "1.2"whenpoi : POI( source == 1 && brandType == 2 )thenSystem.out.println( "1.2 matched" );endrule "2.1"whenpoi : POI( source == 2 && brandType == 1 )thenSystem.out.println( "2.1 matched" );poi.setPassedNodes(2);endrule "2.2"whenpoi : POI( source == 2 && brandType == 2 )thenSystem.out.println( "2.2 matched" );poi.setPassedNodes(3);end

在实践中,我们发现Drools方案有以下几个优缺点:

优点

  • 策略规则和执行逻辑解耦方便维护。

缺点

  • 业务分析师无法独立完成规则配置:由于规则主体DSL是编程语言(支持Java, Groovy, Python),因此仍然需要开发工程师维护。
  • 规则规模变大以后也会变得不好维护,相对硬编码的优势便不复存在。
  • 规则的语法仅适合扁平的规则,对于嵌套条件语义(then里嵌套when…then子句)的规则只能将条件进行笛卡尔积组合以后进行配置,不利于维护。

由于Drools的问题较多,最后这个方案还是放弃了。

绩效指标计算

场景

美团外卖业务发展非常迅速,绩效指标规则需要快速迭代才能紧跟业务发展步伐。绩效考核频率是一个月一次,因此绩效规则的迭代频率也是每月一次。因为绩效规则系统是硬编码实现,因此开发团队需要投入大量的人力满足规则更新需求。

2016年10月底我受绩效团队委托成立一个项目组,开发部署了一套绩效指标配置系统,系统上线直接减少了产品经理和技术团队70%的工作量。

下面我们首先分析下绩效指标计算的规则模型,如下图:

绩效指标计算规则

规则主体是结构化数据处理逻辑:

  • 规则逻辑是从若干数据源获取数据,然后进行一系列聚合处理(可以采用结构化查询SQL语句+少量代码实现),最后输出到目标数据源。

方案——业务定制规则引擎

绩效规则主体是数据处理,但我们认为数据处理同样属于规则的范畴,因此我们将其放在本文进行分析。

下图是绩效指标配置系统。触发器负责定时驱动引擎进行计算;视图负责给商业分析师提供规则配置界面,规则表达能力取决于视图;引擎负责将配置的规则解析成Spark原语进行计算。

指标配置系统

优点

  • 规则配置门槛低:视图和引擎内部数据模型完全贴合绩效业务模型,因此业务分析师很容易上手。
  • 系统支持规则热部署。

缺点

  • 适用范围有限:因为视图和引擎的设计完全基于绩效业务模型,因此很难低成本修改后推广到别的业务。

探索全新设计

“案例”一节中三种落地方案的问题总结如下:

  • 硬编码迭代成本高。
  • Drools维护门槛高。视图对非技术人员不友好,即使对于技术人员来说维护成本也不比硬编码低。
  • 绩效定制引擎表达能力有限且扩展性差,无法推广到别的业务。

由于“高效配置规则”是业务里长期存在的刚需,且行业内又缺乏符合需求的解决方案,2017年02月我在团队内部设立了一个虚拟小组专门负责规则引擎的设计研发。引擎设计指标是要覆盖工作中基础的规则迭代需求(包括但不限于“案例”一节中的多个场景),同时针对“案例”一节中已有解决方案扬长避短。下面分3节来重现这个项目的设计过程。首先“需求模型”一节会基于“案例”一节的场景尝试抽象出规则模型,同时提炼出系统设计大纲。然后“Maze框架”一节会基于需求模型设计一个规则引擎。最后“Maze框架能力模型”一节会介绍Maze框架的特点。

需求模型

对规则引擎来说,世界皆规则。通过“案例”一节的分析,我们对规则以及规则引擎该如何构建的思路正逐渐变得清晰,下面两节分别定义规则数据模型和规则引擎的系统模型,目标是对“Maze框架”一节中的规则引擎产品进行框架性指导。

规则数据模型

规则本质是一个函数,由n个输入、1个输出和函数计算逻辑3部分组成。

y = f(x1, x2, …, xn)

具体结合“案例”一节中的场景我们梳理出的规则模型如下图所示。

规则模型

主要由三部分构成:

  • FACT对象:用户输入的事实对象,作为决策因子使用。

  • 规则:LHS(Left Hand Side)部分即条件分支逻辑。RHS(Right Hand Side)部分即执行逻辑。LHS和RHS部分是由一个或多个模式构成的。模式是规则内最小单位。模式的输入参数可以是另一个模式或FACT对象(比如逻辑与运算[参数1] && [参数2]中参数1可以是另一个表达式)。模式需要支持以下3种类别:

    • 客户定义方法:FACT对象的实例方法、静态方法。
    • 常规表达式:逻辑运算、算数运算、关系运算、对象属性处理等。
    • 结构化查询。
  • 结果对象:规则处理完毕后的结果。需要支持自定义类型或者简单类型(Integer、Long、Float、Double、Short、String、Boolean等)。

系统模型

我们需要设计一个系统能配置、加载、解释执行上节中的数据模型,另外设计时还需要规避“案例”一节3个方案的缺点。最终我们定义了如下图所示的系统模型。

系统模型

主要由3个模块构成:

  • 规则引擎:负责执行规则。
    • 调度器:根据规则的依赖关系以及硬件资源驱动模式执行器执行模式,目标是达到最大吞吐或最低延迟。
    • 模式执行器:负责直接执行模式。执行器可以根据业务的表达能力需求选择基于Drools、Aviator等第三方引擎,甚至可以基于ANTLR定制。

Maze框架

基于”需求模型”一节的定义,我们开发了Maze框架(Maze是迷宫的意思,寓意:迷宫一样复杂的规则)。

Maze框架分两个引擎:MazeGO(策略引擎)和MazeQL(结构化数据处理引擎)。其中MazeGO内解析到结构化数据处理模式会调用SQLC驱动MazeQL完成计算(比如:从数据库里查询某个BD的月交易额,如果交易额超过30万则执行A逻辑否则执行B逻辑,这个语义的规则即需要执行结构化查询),MazeQL内解析到策略计算模式会调用VectorC驱动MazeGO进行计算(比如:有一张订单表,其中第一列是商品ID,第二列是商品购买数量,第三列是此商品的单价,我们需要计算每类商品的总价则需要对结构化查询到的结果的每一行执行第二列 * 第三列这样的策略模式计算)。

Maze框架

名词解释:

  • VectorC指向量计算,针对矩阵的行列进行计算。有三种计算方式:
    1. 针对一行的多列进行策略计算。
    2. 针对一列进行计算。
    3. 针对分组聚合(GroupBy)后的每一组内的列进行运算。
  • SQLC指结构化查询。拥有执行SQL的能力。

MazeGO

MazeGO核心主要由3部分构成:资源管理器、知识库和MazeGO引擎。另外两个辅助模块是流量控制器和规则效果分析模块。基本构成如下图:

MazeGO

3个核心模块(引擎、知识库和资源管理器)的职责见“需求模型”一节中“系统模型”一节。下面只介绍下和“系统模型”不同的部分。

  1. MazeGO引擎:
    • 规则管理模块。职责如下:
      • 预加载规则实例。首先为了避免访问规则时需要实时执行远程调用而造成较大的时延,另外规则并不是时刻发生变更没有必要每次访问时拉取一次最新版本,基于以上两个原因规则管理模块会在引擎初始化阶段将有效版本的规则实例缓存在本地并且监听规则变更事件(监听可以基于ZooKeeper实现)。
      • 预编译规则实例。因为规则每次编译执行会导致性能问题,因此会在引擎初始化和规则有变更这两个时机将增量版本的规则预编译成可执行代码。
  2. 流量控制器:负责不同版本规则的调度。方便业务方修改规则后,灰度部分流量到新规则。
  3. 规则效果分析:规则新增或修改后,业务方需要分析效果。本模块会提供:规则内部执行路径、运行时参数和结果的镜像数据,数据可以存储在hbase上。

MazeQL

MazeQL核心主要由3部分构成:配置中心、MazeQL引擎和平台。

MazeQL

  1. MazeQL引擎:
    • 规则管理模块。职责如下:
      • 预加载规则实例。首先为了避免访问规则时需要实时执行远程调用而造成较大的时延,另外规则并不是时刻发生变更没有必要每次访问时拉取一次最新版本,基于以上两个原因规则管理模块会在引擎初始化阶段将有效版本的规则实例缓存在本地并且监听规则变更事件(监听可以基于ZooKeeper实现)。
      • 预解析规则实例。因为规则每次解析执行会导致性能(大对象)问题,因此会在引擎初始化阶段解析为运行时可用的调度栈帧。
    • 运行时模块。分为调度器和QL驱动器。
      • 调度器。SQLC和VectorC类规则大多由多个规则组合而成(对于SQLC而言可以将依赖的规则简单的理解为子查询),因此也需要和“系统模型”一节一样的调度管理,实现层面完全一致。
      • QL驱动器。驱动平台进行规则计算。因为任务的实际执行平台有多种(会在下一个“平台”部分介绍),因此QL驱动器也有多种实现。
  2. 平台:负责实际执行规则逻辑。分两种运行模式:一种是以嵌入式方式运行在客户端进程内部,好处是实时性更好,时延更低,适合小批量数据处理;另一种是以远程方式运行在Spark平台,适合离线大规模数据处理。
    • QL执行器。负责执行结构化查询逻辑。两种不同的运行模式下QL执行器在执行SQL模式时会选择两种不同的QL执行器实现,两种实现分别是:
      • 嵌入式模式下是基于Mysql和Derby等实时性较好的数据库实现的。
      • 在Spark平台上是基于Spark SQL实现的。
  3. 配置中心:提供规则配置视图。
    • 版本管理。同“系统模型”一节。
    • 数据源绑定。即是定义参与计算的SQL逻辑中使用到的数据源,便于系统进行管理。
    • 结构查询定义。即是定义SQL规则,这是主体规则内容。
    • 向量计算定义。定义VectorC类计算(VectorC见“Maze框架”章节开头的介绍)。

Maze框架能力模型

Maze框架是一个适用于非技术背景人员,支持复杂规则的配置和计算引擎。

Maze框架能力模型

规则迭代安全性

规则支持热部署:系统通过版本控制,可以灰度一部分流量,增加上线信心。

规则表达能力

框架的表达能力覆盖绝大部分代码表达能力。下面用伪代码的形式展示下Maze框架的规则部分具有的能力。

// 输入N个FACT对象
function(Fact[] facts) {   // 从FACT对象里提取模式     String xx= facts[0].xx;  // 从某个数据源获取特征数据,SQLC数据处理能力远超sql语言本身能力,SQLC具有编程+SQL的混合能力List<Fact> moreFacts = connection.executeQuery("select * from xxx where xx like '%" + xx + "%');  // 对特征数据和FACT对象应用用户自定义计算模式UserDefinedClass userDefinedObj = userDefinedFuntion(facts, moreFacts);  // 使用系统内置表达式模式处理特征                      int compareResult = userDefinedObj.getFieldXX().compare(XX); // 声明用户自定义对象         UserDefinedResultClass userDefinedResultObj = new UserDefinedResultClass();  // 使用系统内置条件语句模式处理特征                              if (compareResult  == 0) {     userDefinedResultObj.setCompareResult(Boolean.FALSE);} else if (compareResult > 0) {userDefinedResultObj.setCompareResult(Boolean.FALSE);} else {userDefinedResultObj.setCompareResult(Boolean.TRUE);}// 将结果返回给客户return userDefinedResultObj;        }

规则执行效率

执行效率分三方面:

  1. 引擎的调度模块会确保吞吐优先,并且调度并发度等系统配置可以根据资源情况调整。
  2. 引擎运行过程中没有远程通信开销。
  3. 引擎执行代码实现编译或解析后执行,运行效率较高。

规则接入成本

开发人员接入

  1. 首先,开发人员在项目工程里导入一个MazeGO jar包。
  2. 然后,开发人员在项目工程里需要调用计算规则的地方引入MazeGO client(如下代码片段)。

    // 初始化MazeGO client,建议在本应用程序的初始化阶段执行
    MazeGOReactor reactor = new MazeGOReactor();
    reactor.setMazeIds(Arrays.asList(<mazeId>));
    reactor.init();// 调用MazeGO client执行规则
    reactor.go(<mazeId>, <fact>);// 销毁MazeGO client,建议在本应用程序的销毁阶段执行
    reactor.destroy();
    

规则配置

规则配置基本实现由业务分析师、产品经理或运营人员自助完成。

规则配置

业务分析师在MazeGO上配置规则的视图如下图所示。

视图

总结

本文开头介绍了几个工作中的规则使用场景,顺带引出了多个不同的解决方案,最后介绍了Maze框架的设计,基本上展现了我们对这个框架思考和设计的整个过程。

作者简介

张宁,美团点评技术专家。2015年加入美团,先后在美团数据中心、外卖CRM等业务线工作,目前在外卖技术部,负责代理商和CRM效能相关业务,致力于通过技术手段提升商务拓展团队的工作效率、降低客户关系维护成本。

【思考题】

世界皆规则,业务开发工程师的日常工作又都是实现业务逻辑。那当通用规则引擎表达能力能够覆盖大部分业务逻辑,且配置成本低于开发工程师直接开发时,业务逻辑这一亩三分地里通用规则引擎和代码的边界是什么?我们是否还需要严格恪守规则引擎只是用来“隔离变化”、“解耦决策逻辑”等原则?

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

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

相关文章

LintCode 563. 背包问题 V(DP)

1. 题目 给出 n 个物品, 以及一个数组, nums[i] 代表第i个物品的大小, 保证大小均为正数, 正整数 target 表示背包的大小, 找到能填满背包的方案数。 每一个物品只能使用一次 样例 给出候选物品集合 [1,2,3,3,7] 以及 target 7 结果的集合为: [7] [1,3,3] 返回 22. 解题 dp[…

汽车博主因眼睛小被辅助驾驶误判为开车睡觉!何小鹏亲自回应 蔚来已成立专门研究小组...

源 | 每日经济新闻近日&#xff0c;一位汽车博主表示&#xff0c;他在驾驶小鹏汽车&#xff0c;使用小鹏辅助驾驶功能的时候&#xff0c;因为自己的眼睛比较小&#xff0c;所以被系统判定为“开车睡觉”&#xff0c;从而被扣除了智驾分。据了解&#xff0c;“智驾分”是小鹏汽车…

投资127亿!深圳,再添一所985

源 | 青塔综合转自 | 募格学术据深圳卫视近日消息&#xff0c;中山大学深圳校区多栋建筑将在暑假交付。报道称&#xff0c;中山大学深圳校区主楼正在进行工程最后收尾工作&#xff0c;预计本月底就能竣工验收&#xff0c;确保秋季新学期开始前投入使用。校区总建筑面积约127万平…

Android OOM案例分析

在Android&#xff08;Java&#xff09;开发中&#xff0c;基本都会遇到java.lang.OutOfMemoryError&#xff08;本文简称OOM&#xff09;&#xff0c;这种错误解决起来相对于一般的Exception或者Error都要难一些&#xff0c;主要是由于错误产生的root cause不是很显而易见。由…

NAACL最佳方法论文:课本上的A*搜索算法可以提升文本生成效果!

文 | Yimin_饭煲相信大多数学习过人工智能课程的读者&#xff0c;当听到算法的时候&#xff0c;都会有一种既熟悉又陌生的感觉。说算法熟悉&#xff0c;是因为一听到这个算法&#xff0c;就想起那本厚厚的《人工智能——一种现代的方法》&#xff0c;想起这个算法似乎是人工智能…

LeetCode 6. Z 字形变换(找规律)

1. 题目 将一个给定字符串根据给定的行数&#xff0c;以从上往下、从左到右进行 Z 字形排列。 比如输入字符串为 “LEETCODEISHIRING” 行数为 3 时&#xff0c;排列如下&#xff1a; L C I R E T O E S I I G E D H N之后&#xff0c;你的输出需要从左往右逐行…

美团点评移动网络优化实践

本文根据第16期美团点评技术沙龙“移动开发实践&#xff08;上海站&#xff09;”演讲内容整理而成。 第18期沙龙&#xff1a;高可用系统背后的基础架构&#xff08;3月25日&#xff09;火热来袭&#xff01;快快点击报名吧。 网络优化对于App产品的用户体验至关重要&#xff0…

我终于逃离了互联网,却陷入了迷茫

大家好&#xff0c;我是卖萌酱。昨天跟一位成功逃离互联网的好姐妹小A约了个饭&#xff0c;这位姐妹的早期经历可以说是略带传奇色彩了&#xff0c;过程却比较崎岖&#xff0c;结局心情复杂&#xff0c;但却对普通人来说却很有启发意义。经过小A允许&#xff0c;卖萌酱将小A的故…

LintCode 633. 寻找重复的数(这个题要复习)

1. 题目 给出一个数组 nums 包含 n 1 个整数&#xff0c;每个整数是从 1 到 n (包括边界)&#xff0c;保证至少存在一个重复的整数。假设只有一个重复的整数&#xff0c;找出这个重复的数。 样例 1: 输入: [5,5,4,3,2,1] 输出: 5样例 2: 输入: [5,4,4,3,2,1] 输出: 4注意事项…

业务赋能利器之外卖特征档案

应用背景及现状 美团外卖业务自2013年9月启动至今已运营三年时间。截至2016年12月&#xff0c;美团点评整个外卖平台的日订单超过900万。从发展速度和体量上看&#xff0c;外卖业务仍处在迅猛发展的上升期。与早期飞速增长的状态相比&#xff0c;随着规模的不断扩大&#xff0c…

训练双塔检索模型,可以不用query-doc样本了?明星机构联合发文

文 | QvQ对于开放域检索式QA系统而言&#xff0c;其本质是计算question和doc的本文相似度&#xff0c;而作为老生常谈的文本相似度问题&#xff0c;有监督方法的性能历来是要好于无监督算法的。今天要介绍的文章&#xff0c;反其道而行之&#xff0c;不仅采用了无监督算法&…

MGW——美团点评高性能四层负载均衡

本文整理自美团点评技术沙龙第14期&#xff1a;美团背后的故事&#xff0d;你不知道的美团云。 美团点评技术沙龙由美团点评技术团队主办&#xff0c;每月一期。每期沙龙邀请美团点评及其他互联网公司的技术专家分享来自一线的实践经验&#xff0c;覆盖各主要技术领域。 目前沙…

剑指Offer - 面试题36. 二叉搜索树与双向链表(中序循环/递归)

1. 题目 输入一棵二叉搜索树&#xff0c;将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点&#xff0c;只能调整树中节点指针的指向。 特别地&#xff0c;我们希望可以就地完成转换操作。当转化完成以后&#xff0c;树中节点的左指针需要指向前驱&#…

知乎高赞:拼多多和国家电网,选哪个?

源 | 知乎、AINLP最近在知乎上看到一个关于职业选择的问题&#xff0c;虽然都是老生常谈的话题了&#xff0c;但是几个知友的回答获得非常多的赞同&#xff0c;拿来和大家分享一下。知乎上有人问本人是某top3本硕&#xff0c;EE专业&#xff0c;秋招拿到了老家不差的地级市国网…

大众点评订单系统分库分表实践

原大众点评的订单单表早就已经突破两百G&#xff0c;由于查询维度较多&#xff0c;即使加了两个从库&#xff0c;优化索引&#xff0c;仍然存在很多查询不理想的情况。去年大量抢购活动的开展&#xff0c;使数据库达到瓶颈&#xff0c;应用只能通过限速、异步队列等对其进行保护…

NLP未来,路在何方?从学术前沿和业界热点谈起

近两年&#xff0c;人工智能的应用越来越“卷”了&#xff0c;每隔一段时间就会出现一个让人大呼“respect”的技术。AI好像也更加懂人类&#xff0c;越来越接近“人的智能”。就好比今年高考期间被各大科技媒体反复拿来讲的AI高考的案例。如今的“AI做题家”不光能参加高考&am…

剑指Offer - 面试题46. 把数字翻译成字符串(DP)

1. 题目 给定一个数字&#xff0c;我们按照如下规则把它翻译为字符串&#xff1a; 0 翻译成 “a” &#xff0c; 1 翻译成 “b”&#xff0c;……&#xff0c; 11 翻译成 “l”&#xff0c;……&#xff0c; 25 翻译成 “z”。 一个数字可能有多个翻译。请编程实现一个函数&a…

美团数据库运维自动化系统构建之路

本文整理自美团点评技术沙龙第10期&#xff1a;数据库技术架构与实践。 美团点评技术沙龙由美团点评技术团队主办&#xff0c;每月一期。每期沙龙邀请美团点评及其它互联网公司的技术专家分享来自一线的实践经验&#xff0c;覆盖各主要技术领域。 目前沙龙会分别在北京、上海和…

推荐一个开源的炼丹神器MegPeak!算法工程师的仪表盘

在算力需求爆炸的大背景下&#xff0c;如何发挥出已有硬件的最大算力变得非常重要&#xff0c;直观一点是&#xff1a;我们需要对现有算法针对特定的处理器进行极致的性能优化&#xff0c;尽量满足目前AI算法对算力的高要求。为了能够做到极致的性能优化&#xff0c;我们可能的…

LintCode 390. 找峰值 II

1. 题目 给定一个整数矩阵 A, 它有如下特性: 相邻的整数不同矩阵有 n 行 m 列。对于所有的 i < n, 都有 A[i][0] < A[i][1] && A[i][m - 2] > A[i][m - 1]对于所有的 j < m, 都有 A[0][j] < A[1][j] && A[n - 2][j] > A[n - 1][j] 我们定…