SQL解析过程

2023-05-16

转载自: http://blog.aliyun.com/733

简介

SQL任务是ODPS中使用最频繁的一类作业,大部分用户开始使用ODPS时要做的第一件事情就是学习怎么写ODPS的SQL。ODPS SQL是一种非常灵活的语言,兼容大部分的SQL92规范,也对大规模计算场景做了一些特别的定制。有些用户写出的SQL让人看了之后茅塞顿开的感觉,也有一些神级用户经常写一些1000多行的SQL,让人看的只想撞墙。本文会介绍一下SQL是如何分析解析,并拆解成分布式飞天任务的一些实现原理。

ps.由于一些历史包袱和工程实现的原因,ODPS某些内部实现细节可能与本文提到的不一致

1. 编译

语法分析的作用是将一个输入的‘字符串’变换为一个描述这个字符串的‘结构体’,让计算机可以更容易的理解用户输入的字符串是什么意义。这个阶段包含三个过程,分别是词法分析、语法分析、输出抽象语法树。

1.1词法分析

词法分析器是一个确定有限自动机(DFA),可以按照我们定义好的词法,将输入的字符集转换为‘单词’。如下:

1


  

1.2语法分析

在词法分析之后,接下来的过程就是语法分析了,词法分析的结果会作为语法分析的输入,语法分析在词法分析的基础上,来判断用户输入的单词是否符合语法逻辑,*SELECT FOO+100 FROM POKES*就是一个符合语法的句子,而*SELECT FOO+100 FROM*,是个不合法的语句,因为在FROM之后,一定要跟着一个表名。此时语法分析器会报错:

2

1.3抽象语法树

抽象语法树(AST)的英文全拼是:*abstract syntax tree*,这是用户输入语句的树形结构的表现形式,树上的每一个节点都是一个单词,树的结构体现了语法。抽象语法树是随着语法分析的过程构造的,当语法分析正常结束后,语法分析器就会输出一个抽象语法树,用户的输入和抽象语法树的结构内容是一一对应的,至此,用户输入的‘字符串’完完全全的变成了一个‘结构体’, SELECT FOO+100 FROM POKES转换为抽象语法树后如下所示:
3
ps.在ODPS中,真实的抽象语法树会复杂许多,为了方便大家理解,我将输出的抽象语法树做了一些简化。

编译的过程在过去曾经是最为复杂繁琐的,涉及到很多编译原理的理论,但是现在,开源的编译器工具已经足够的多,我们可以定义好语法,让编译器工具来帮我们完成这个转换。目前我们使用编译工具:Antlr来完成我们的编译。

2.语义分析

语义分析阶段是SQL解析过程中最为复杂最有难度的一环,涉及到SQL标准,SQL优化,和MapReduce的相关理论和概念。在这里,接着上面环输出的抽象语法树,语意分析后会输出一个查询计划,这个查询计划会指导着物理执行算子一步步的运行在我们的分布式系统之上,去读取表的内容,根据SQL的语意做运算,最后输入用户的内容。接下来我们会逐步分解语义分析的过程,揭开庐山真面目

语义分析阶段包含两大块,先逻辑分析物理分析,逻辑分析基本上是纯代数的分析过程,与底层的分布式环境无关,而物理分析则是将逻辑分析后的结果做变换,与底层的执行环境密切相关。如我们使用飞天的分布式环境,物理分析时就需要确定在MapReduce时如何将数据分区、排序、读取数据量的大小、启动多少个进程来执行任务,等等。

2.1逻辑分析

顾名思义,逻辑分析过程就是要分析一下输入的SQL语句到底是干什么的,都有哪些操作。一般来讲,一个SQL语句总有一个输入,一个输出,输入数据经过SQL加工后得到输出数据,

2.1.1语句的执行顺序

SQL语句基本可以分解成下面7大块:

(5)SELECT (6)DISTINCT < select list >
(1)FROM < table source >
(2)WHERE < condition >
(3)GROUP BY < group by list >
(4)HAVING < having condition >
(7) ORDER BY < order by list >

在执行时,按照1-7的标号顺序执行,有些子句是可选的,比如where子句。当没有出现的时候就跳过这步。我们发现,写在最前面的select子句其实并不是最先执行的,这是因为SQL语句设计时为了让用SQL的人更容易与自己的思维相衔接。

2.1.2逻辑算子

根据上述的几个SQL基本操作,我们抽象出了一些逻辑算子(Operator),这些算子的功能是单一的不可再拆分的单位。分别是:

4

这些奇怪的算子是干什么用的呢?说白了,一个逻辑查询计划就是由这些算子组成的一个有向无环图(DAG),每一个算子都描述了SQL操作里的不同动作,由算子组成的有向无环图(DAG)描述了数据流的方向.

对于大部分算子而言,都有一个输入数据集,和一个输出数据集。JoinOperator和UnionAllOperator比较特殊,拥有两个或者两个以上的输入数据集,因为这两个算子的操作就是要将多个数据集做关联。我们将算子的输入数据集输出数据集称之为虚表(vtable)

用户是看不到虚表(vtable)的,它只用来做内部分析,是算子和算子之间的桥梁,如下图所示:

5

2.1.3表达式分析

在SQL里,有很多子句都可以带有表达式,比如

6

其中SELECT子句中,GROUP BY子句中, WHERE子句中都带有表达式。表达式的解析和计算贯穿着整个SQL解析的过程,所以这里单独讲讲表达式。

1.类型推导

在分析表达式时,会遇到用户输入的常量,我们需要通过类型推导给输入的每一个常量做标记,识别SQL中常量的类型,规则较为简单,如:

7

2.隐式类型转换

所有的编程语言都会遇到隐式类型转换的问题,即当调用一个函数时,如果输入参数类型不符合函数签名时,就要尝试对输入的参数做隐式类型转换。当然,并不一定每次隐式类型转换都是成功的,如果发现无法无论如何转换都无法满足函数的签名,就会有异常抛出,终止分析过程。

 8

3.布尔表达式分析

布尔表达式的分析主要作用是可以让之后的SQL优化更容易的进行下去,如Join时的条件下推优化,分区裁剪优化,都需要使用布尔表达式分析后的结果来进行。这步分析会用到很多布尔代数的知识,目的只有一个,那就是将用户输入的冗长的布尔表达式变换为最简合取范式,简而言之,就是将用户输入的一大推’and’ ‘or’组成的布尔表达式变换成由’and’连接的最简形式,如:

9

看起来这是一个很神奇的变换,实际上已经有很现成的算法来解决这个问题了。总共需要2步:

  1. 利用Quine McCluskey 算法对输入的布尔表达式生成合取范式(CNF)
  2. 利用Petrick’s method 算法对第一步生成的CNF计算最简合取范式(Minimal CNF)

4.CASE WHEN表达式的分析

CASE WHEN表达式是一个略显奇葩的表达式,它本身上是一个值函数(ScalarFunction),但又有逻辑判断,返回值又不固定,并且还可以嵌套使用,而且在语法上还有两种形式(简单CASE函数和CASE搜索函数) – -! 想在计算机里优雅的记录表达这个CASE WHEN真的很不容易。

10


  

condition参数是casewhen子句的条件,returnvalue1代表这THEN后的返回值,returnvalue2代表ELSE后的返回值。这样,我们就可以很好的在计算机中结构化的表达,如:


11  

 

2.1.4逻辑查询计划生成

有了以上的基础,我们就可以开始生成我们的查询计划了。严格按照SQL语句的执行顺序来遍历编译阶段生成的AST树,遇到什么操作就生成什么样的算子,遇到表达式就调用之前的表达式分析,真是兵来将挡水来土掩。
举个例子:


  

12需要注意的是,在聚合函数里的值函数、Group by列表中的值函数,需要在聚合操作以前就计算完成,否则无法进行聚合操作,于是乎,出现了一个叫初始投影的东西,本质上这是一个SelectOperator,只是用来计算一下聚合需要用到的表达式。

题外话,在很久以前,group by 列表中和聚合函数里都是不允许使用表达式的,只能使用单一的值或者列,所以那时也不需要初始投影。用户想使用类似功能时只能通过子查询来实现。后来SQL语法扩展了,支持了group by、聚合函数中调用值函数,于是,在SQL解析时要先判断一下是否需要初始投影

还有很多结构的SQL没有讲到,比如JOIN, UNION ALL, WINDOWN FUNCTION,由于篇幅原因,这里先不提了,感兴趣的同学可以来找我们私下交流。

2.1.5子查询

SQL语法本身就是一个递归的结构,支持在FROM之后写一个子查询,如:

13

面对这样的语句,我们只要先去生成子查询的逻辑查询计划,将子查询的的结果虚表作为父查询的输入即可,在逻辑上很方便去应对。上面这个示例的查询计划如下图所示:
14

2.1.6逻辑优化

生成逻辑查询计划后,需要先对查询计划做一次优化,将一些显而易见的点优化掉,避免冗余的计算。主要包含三个优化:

  • 常量表达式的计算举个例子:

    SELECT 1+2 FROM POKES
    1+2“就是一个常量表达式,此时,我们可以将1+2的结果先计算出来,然后将结果放入查询计划,避免在执行时,对每一行数据都去计算这个固定结果的表达式。

  • 列裁剪在生成查询计划时,默认会把全表中没一列的数据都读取出来,但现实的情况是用户可能只需要其中的某几列做计算,其他的列就变成了冗余数据,读取出来耗时耗力,但没有被用到。此时,我们就使用列裁剪这个优化去把不必要的列裁剪掉。
  • Predict Push Down在遇有JOIN运算时,用户很有可能还要在JOIN之后做WHERE运算,此时就要从代数逻辑上分析,WHERE中计算的条件是否可以被提前到JOIN之前运算,以此来减少JOIN运算的数据量,提升效率,千言万语不胜一张图,(又称no pic you say a bird):

    SELECT * FROM A JOIN B ON A.ID=B.ID WHERE A.AGE>10 AND B.AGE>5

    15

    左面的是未优化前的查询计划,在FIL_4中计算了A.AGE>10 AND B.AGE>5这个表达式,右面的是优化后的查询计划,将A.AGE>10放入了FIL_7计算并且提前,将B.AGE>5放入了FIL_8中计算并且提前,最后将原有的FIL_4删除,以此来达到减少JOIN输入数据量的目的。

至此,逻辑查询与逻辑优化就结束了,逻辑查询计划和逻辑优化在所有的SQL系统中都是差不多的,下面来讲讲与我们分布式系统MapReduce相关的物理查询计划。

2.2物理分析

物理查询计划是通过之前产生的逻辑查询计划生成的,在转换的过程中,要与飞天的MapReduce编程框架做适配,生成飞天系统可以识别的DAG

2.2.1物理算子

飞天的DAG是一个类似MapReduce的编程框架,想把刚刚一个SQL跑在分布式的飞天系统上,就需要按照分布式系统编程框架来抽象出一些新的物理运算符。

  • Shuffle-Sort算子(在ODPS中,这个算子叫ReduceSink)在飞天系统上,我们如果想做Group by或者Join操作,那么必须把相同key的数据放到同一个进程节点上来执行,而在这直线,这些相同key的数据也许是被打散在各个进程里的,这时我们就需要一个专门的算子来做数据的重新分区、排序的操作
  • GroupBy的不同阶段在飞天系统上,我们想实现一个GroupBy需要有4步:
    1. 准备阶段(AggregationPrepare), 在做一些非线性的聚合函数操作时,比如AVG求平均值,需要将AVG()拆解成SUM(),COUNT()两个线性的聚合函数,最后再使用SUM()/COUNT()来算出AVG()的值。在这步,只做拆解。
    2. 本地聚合(SemiHashAggregation), 对于Group by来说,需要将所有Group by 列表的字段数据放倒一个机器上才可以进行完全聚合,但是出于优化考虑,我们可以在数据片不全的时候先做一次聚合,虽然这次聚合操作不完全,但是可以减少输出的数据量,并且可以保证数据的正确性
    3. 流式聚合(StremAggregation), 这个聚合有个前提,一定是要求前趋的虚表Group by 列表中的数据都会在这一个进程里,并且排好序。一般而言,在本地聚合之后,数据会通过Shuffle-Sort运算数据重新分区和排序,再输入到流式聚合算子中
    4. 合并(FinalAggregation),这里输入的其实是已经聚合好的结果了,但是由于第一步提到的原因,有些非线性聚合函数被分解成了线性聚合函数,这里要将他们合并。如:AVG()=SUM()/COUNT()

    在只有线性聚合函数时,上面的1,4步可以省略。

  • MapJoin 算子和MergeJoin算子
  1. MergeJoinMergeJoin是最常见的一种Join算子,一般而言,MergeJoin是要求输入数据的虚表按照Join的Key分区并且排序的,所以MergeJoin一般出现在Shuffle-Sort算子之后。
  2. MapJoin使用过的人应该都知道有一种Join的优化叫MapJoin,这个名字的本意是Map-side JOIN,就是JOIN运算在MapReduce的Map阶段完成。如果用户在做Join时,知道有一个数据表的数据量很小,可以选择使用MapJoin,MapJoin算子会在每一个进程里都把小表中的数据加载到内存,与打表一一做Join。这样可以减少一次Shuffle-Sort,提升执行效率。

2.2.2生成物理查询计划

逻辑查询计划是物理查询计划的输入,我们按照拓扑序去遍历逻辑查询计划上的每一个逻辑算子,生成物理算子,当我们认为虚表需要重新分区排序才能满足下一个阶段的运算时,我们就在中间加入一个Shuffle-Sort运算符.
还是使用逻辑查询计划生成的那个例子来描述一下物理查询计划是什么样子:

 16

17

2.2.3物理优化

现在,又进入了一个优化的环节。此时的优化与底层的分布式系统更相关,主要目标就是减少读取的数据量,减少整个SQL执行的过程中,数据分区排序落地的过程。以此来提高执行效率。

  • 分区裁剪大家知道,我们的业务表一般都是有分区的,而且一般都是按照时间来分区。大部分情况下不需要全表扫描,只需读出几个分区的数据就可以完成我们的业务逻辑。于是,分区裁剪优化诞了。
    我们会分析用户写在WHERE子句中的分区字段,将分区字段的条件拿出来,再去metastore中读取所有的分区信息,用WHERE子句中的条件做过滤,最后,我们就知道哪些分区是需要读取的了,我们把要读取的分区信息放入对应的TableScanOperator,在执行是时,就不用读取不必要的数据了。

    需要注意的是,并不是所有的WHERE条件中的分区条件都可以做裁剪,当用户写了LEFT JOIN,RIGHT JOIN, FULL OUTER JOIN时,如果在JOIN条件中涉及到了分区字段,那么很有可能就无法完成分区裁剪的优化,因为裁剪后SQL的结果就不对了。

  • 减少不必要的Shuffle-Sort有时我们会写出这样的语句:
    18
    

    在上面这个例子中,Join 后做Group by ,应该在Join和Group by之间加入一个Shuffle-Sort算子,以保证Group by 算子的输入虚表按照固定的A.ID来排序,但是我们发现,JOIN之后A.ID这个字段本来就是有序的,所以,我们可以将中间这个Shuffle-Sort算子删除,减少数据的网络传输和落地。

2.2.4生成飞天的DAG

物理查询计划已经生成好了,下一步就是按照飞天的DAG编程模型把物理查询计划的算子适配进去。飞天DAG的单位是Stage,由多个Stage组成了DAG,Stage和Stage之间可以进行对数据的分区和排序,有点想Map和Reduce的关系。

生成飞天DAG的规则也很简单:

  • 按照拓扑序遍历物理查询计划上的每一个算子,每一个算子都在一个独立的集和里。如果两个算子相连接,则将这两个集和合并。当遇到Shuffle-Sort算子时终止,并开始新一轮的合并集和过程。
    19
    

对于上面这个语句,按照规则生成DAG后的样子如下:
20

其中每一个灰色的方块代表Fuxi的一个Stage。TS_1在STAGE1中读取表A,RS_3进按A.ID进行分区排序,TS_2在STAGE2中读取表B,RS_4按照B.ID进行分区排序。JOIN_5在STAGTE3中,按照A.ID=B.ID做MergeJoin, SEMIHASH_7为Group by A.AGE做半聚合,通过RS_8将数据按照A.AGE重新分区排序。 STAGE3的第一算子是STREAMEDAGG_9,接收按照A.AGE排序后的数据做流式聚合,最后SEL_10将数据做投影,FS_11将数据写出到磁盘。

3.结语

洋洋洒洒写了这么多,SQL解析的逻辑基本就结束了,SQL解析是一个逻辑非常复杂繁琐的过程,有很多细节和恶心的坑本文中还没有提到,稍有不慎就可能引起SQL正确性的错误。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SQL解析过程 的相关文章

  • MYSQL中收盘价的简单移动平均线计算和更新表

    我可以使用一些帮助 最好是虚拟指南 来更新下表 CREATE TABLE SYMBOL day date NOT NULL open decimal 8 3 DEFAULT NULL high decimal 8 3 DEFAULT NUL
  • 如何在MyBatis foreach中迭代HashMap?

    我正在尝试在 mybatis 中生成如下所示的 sql SELECT COL C FROM TBLE 1 WHERE COL A COL B in kp kar srt sach 而我的输入参数类型是HashMap 现在如何从映射器 xml
  • 如何使用 SQL 查询在 Access 中的字段上设置验证规则?

    我正在使用 MS Access 2016 Office 365 目前遇到问题 下面是一个演示此问题的示例 这里我创建了一个表 名为节点家庭链接 由两个字段组成 NodeID 和 FamilyID 如下所示 现在 NodeID 是从另一个表
  • 插入后用触发器更新多行(sql server)

    我有一个表 orderDetails 包含订单的产品 产品编号 color size quantity 和一个表库存 产品编号 size color stock 订单完成后 我使用此查询将项目插入表中orderDetails INSERT
  • 为什么此 SQL 更新失败(“列名无效”)?

    我有一个 SQL Server CE 表 如下所示 我正在尝试像这样更新其唯一记录 update workTables set fileType INV 但我得到 Why UPDATE 请查看相关问题here https stackover
  • 通过货币换算获取每种产品类型的最低价格

    我想选择每种产品类型中最便宜的 包括运费 价格转换为当地货币 最便宜 产品 价格 产品 运费 seller to aud 我的数据库有如下表 PRODUCTS SELLERS id type id seller id price shipp
  • Sql Server:如何在 WHERE 子句中使用 MAX 等聚合函数

    我想获得该记录的最大值 请帮我 SELECT rest field1 FROM mastertable AS m INNER JOIN SELECT t1 field1 field1 t2 field2 FROM table1 AS T1
  • 将 UPDATE 转换为 INSERT INTO ON DUPLICATE KEY UPDATE 语句

    我有这个 UPDATE MySQL 语句 效果很好 UPDATE table1 Inner Join table2 ON table2 id table1 gw id SET table1 field1 1 table1 field2 2
  • 模式更新后 jOOQ 生成的类的运行时验证?

    我用org jooq util DefaultGenerator在构建过程中生成 jOOQ 类来表示我的数据库模式 当应用程序运行时 架构预计会在应用程序不知情的情况下发生更改 此类更改可能与已生成的代码兼容 也可能不兼容 如何在运行时检测
  • 插入多行并返回主键时 Sqlalchemy 的奇怪行为

    插入多行并返回主键时 我注意到一些奇怪的事情 如果我在 isert 查询中添加使用参数值 我会得到预期的行为 但是当将值传递给游标时 不会返回任何内容 这可能是一个错误还是我误解了什么 我的sqlachemy版本是0 9 4 下面如何重现错
  • Oracle 中的 SQL 调优 [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 是否有任何文章 链接可以让我找到 SQL 调优 Oracle 的示例 如果能用例子来解释那就太好了 我需
  • 对于数据库来说,选择正确的数据类型会影响性能吗?

    如果是这样 为什么 我的意思是 tinyint 的搜索速度比 int 快吗 如果是这样 性能上的实际差异是什么 是的 根据数据类型 它确实有所不同 int vs tinyint不会在速度上产生明显的差异 但会在数据大小上产生差异 假设tin
  • 将 SQL 数据中的一行映射到 Java 对象

    我有一个 Java 类 其实例字段 以及匹配的 setter 方法 与 SQL 数据库表的列名相匹配 我想优雅地从表中获取一行 到 ResultSet 中 并将其映射到此类的实例 例如 我有一个 Student 类 其中包含实例字段 FNA
  • 复选框上的数据绑定

    我目前正在将数据从 SQL 数据库之一提取到我的应用程序中 我可以让它适用于我的文本框和其他项目 但是 我似乎无法让它适用于复选框 这是我正在使用的代码 DataTable dt new DataTable dt using SqlConn
  • 更改迁移中的自动​​增量值(PostgreSQL 和 SQLite3)

    我有一个托管在 Heroku 上的项目 想要更改表的自动增量起始值 我在本地使用 SQLite3 Heroku 使用 PostgreSQL 这是我在迁移中所拥有的 class CreateMytable lt ActiveRecord Mi
  • Mysql 检索所有有限制的行

    我想检索特定用户的所有行 限制为 0 x 所以我只是想问是否有任何方法可以检索 mysql 中的所有行 而不调用返回 x 的 count id 的方法 而不重载现有函数 该函数在查询中根本没有限制 与我们的 string Relace 功能
  • 如何在使用连接池时强制 SqlConnection 物理关闭?

    我明白 如果我实例化一个 SqlConnection 对象 我实际上是从连接池中获取一个连接 当我调用 Open 时 它将打开连接 如果我对该 SqlConnection 对象调用 Close 或 Dispose 方法 它将返回到连接池 但
  • Mysql 中 UNION 子句的替代方案

    我有两张桌子 表 a 表 b table a ID 1 2 3 4 5 7 table b ID 2 3 4 5 6 我必须得到这样的输出而无需UNION命令 ID 1 2 3 4 5 6 7 注意 我有一个联合解决方案 select fr
  • sql server 按组排名

    问题看似简单 但我却无法理解 这是针对 sql 服务器的 what I have in a table What I need as a output cksum id cksum id 2162514679 204 2162514679
  • MySQL 按重复项从上到下排序

    我有一个lammer问题 因为我不是mysql专业人士 我有类似的字段 id color 1 red 2 green 3 yellow 4 green 5 green 6 red 我想按重复项进行分组 最常见的重复项先进行分组 所以应该这样

随机推荐

  • Qt中 QString 和int, char等的“相互”转换

    原文链接 xff1a https blog csdn net ei nino article details 7297791 Qt中 int float double转换为QString 有两种方法 1 使用QString number 如
  • 计算器第二版:C语言,VC++6.0

    使用栈实现 xff0c 前缀表达式变后缀表达式的原理 xff0c 但是没有转换 xff0c 是边转换边实现 xff1a include lt stdio h gt include lt stdlib h gt include lt coni
  • 计算器第三版:C语言,递归,VC++6.0

    参考文章 xff1a https blog csdn net u011692041 article details 49796343 https blog csdn net u011692041 article details 497991
  • 计算器第四版:C++,QT

    核心算法和第二版一样 xff1a 头文件 xff1a calculate h ifndef CALCULATE H define CALCULATE H include lt QMainWindow gt include lt QPushB
  • USB协议概念学习

    1 USB总线结构 usb的总线拓扑结构如下所示 xff1a 从USB总线结构可以看出 xff0c 主要由3部分组成 xff1a USB主机 Host USB线缆 USB设备 hub Func等 USB主机 xff1a 一般成为USB Ho
  • 创新工场两道笔试题0919

    题目1 字符串去重 xff0c 老题目 xff0c 只是要求不能开辟新空间用来复制原字符串 思路 xff1a 使用布尔型的简单hash表可以节省空间 xff0c 用来存储字符是否出现的信息 xff0c 刚开始hash表里面都是false x
  • ROS仿真机器人学习笔记二:创建4轮小车模型及相关xraco文件修改

    系列文章目录 提示 xff1a 这里可以添加系列文章的所有文章的目录 xff0c 目录需要自己手动添加 例如 xff1a 第一章 Python 机器学习入门之pandas的使用 提示 xff1a 写完文章后 xff0c 目录可以自动生成 x
  • 旧电脑升级Windows11时检查CPU和TPM2.0不满足的解决方案(慎重)

    上个月微软发布了Windows11 22H2正式版 xff0c 不少新电脑也接收到了推送 xff0c 楼主的台式 xff08 i3 8100 军规星H310M xff09 也接收到了推送 xff0c 但是碍于Win11蛋疼的右键和状态栏消息
  • windows下安装docker

    windows下安装docker 0 前置条件 环境说明 xff1a windows11 家庭中文版 开启Hyper V xff08 可以百度如何开启 xff09 如何添加Hyper V 创建hyper txt xff0c 复制如下内容 x
  • STM32CubeMX配置生成FreeRTOS项目

    文章目录 1 安装STM32CubeMX软件1 1 下载安装1 2 安装要用到的芯片软件包 2 配置FreeRTOS项目2 1 创建工程2 2 配置SYS2 3 配置RCC2 4 配置系统运行时钟2 5 配置UART1串口作为调试代码2 6
  • ScrumMaster的教练职责

    ScrumMaster是Scrum团队的敏捷教练 Ken Rubin说 xff0c 类似于运动团队的教练 xff0c ScrumMaster观察团队使用Scrum的过程 xff0c 帮助团队提高工作绩效 教练不是顾问 xff0c 不提供解决
  • Autoware.Auto avp仿真详解

    1 定位 定位节点启动的是 ndt localizer 61 Node package 61 39 ndt nodes 39 executable 61 39 p2d ndt localizer exe 39 namespace 61 39
  • VMware + ubuntu16.04 + ROS kinetic 下配置realsense D435i 遇到的问题

    在配置Realsense D435i 的过程中 xff0c 遇到一个问题 执行 scripts patcg realsebse ubuntu lts sh 下载速度奇慢 10K s左右 而且会在接受到36 的时候不动了 xff0c 等了一晚
  • 白话tensorflow分布式部署和开发

    关于tensorflow的分布式训练和部署 xff0c 官方有个英文的文档介绍 xff0c 但是写的比较简单 xff0c 给的例子也比较简单 xff0c 刚接触分布式深度学习的可能不太容易理解 在网上看到一些资料 xff0c 总感觉说的不够
  • 全息投影技术

    1 概念 全息投影技术 xff08 front projectedholographic display xff09 也称 虚拟成像 技术是利用干涉和衍射原理记录并再现物体真实的 三维 图像的技术 全息投影技术不仅可以产生立体的空中幻像 x
  • Ardupilot飞控添加使用诺瓦泰GPS

    Ardupilot飞控添加使用诺瓦泰双天线GPS航向角的设置 一 添加诺瓦泰GPS heading角数据包解析代码 1 打开libraries AP GPS AP GPS NOVA h xff0c 添加如下代码 xff1a struct P
  • SD标准以及规范

    SD标准及规范 SD应用 SD标准让制造商能生产高性能之产品来提升数百万计消费者的体验 xff0c 包含听音乐 录制视频 摄影 数据储存以及使用移动电话 身为一个产业的标准 xff0c SD标准被用于行动存储产业的多个市场领域中 xff0c
  • 《视觉SLAM十四讲》学习笔记-状态估计问题

    最大后验与似然 经典slam模型可表示为 xff1a x k 61 f x k 1 u k 43 w k z k j 61 h y j x k 43 v
  • 机器人学领域的顶级期刊和会议

    印象中 xff0c 机器人学涉及机械 控制 计算机和电子等领域 xff0c 十足的交叉学科 xff0c 所以涉及到的概念和技术也非常多 因工作关系 xff0c 看了三周的SLAM入门 xff0c 用的是高翔的 视觉SLAM十四讲 这本教材
  • SQL解析过程

    转载自 xff1a http blog aliyun com 733 简介 SQL任务是ODPS中使用最频繁的一类作业 大部分用户开始使用ODPS时要做的第一件事情就是学习怎么写ODPS的SQL ODPS SQL是一种非常灵活的语言 兼容大