【hive】简单介绍hive的几种join

文章目录

    • 前言
    • 1. Common Join
    • 2. Map Join
      • 介绍:
      • 使用方法:
      • 限制:
    • 3. Bucket Map Join
      • 介绍:
      • 好处:
      • 使用条件:
      • 使用方法:
    • 4. Sort Merge Bucket Map Join
      • 介绍:
      • 如何使用:
    • 5. Skew Join
      • 介绍:
      • 如何使用:
      • 如何处理倾斜:
    • 6. Left Semi Join
    • 7. common join 的内部join
      • 准备数据
        • CUSTOMERS 数据
        • 建表
        • orders 表
        • 建表
      • 1. 内连接(Inner join)
      • 2. 左外连接(Left Outer Join)
      • 3. 右外连接(RIGHT OUTER JOIN)
      • 4. 全外连接(FULL OUTER JOIN)
      • 5. 笛卡尔积(CROSS JOIN)
      • 特殊点

前言

  • common join 主要是针对数据/业务逻辑的join。
  • Map join,Bucket Map Join, SMB Map Join , Skew Join是hive 针对特殊数据、场景 进行的优化。
  • Left Semi Join 则是Sql 语句的优化,并且也可以应用上面的优化方案。

1. Common Join

如果不指定MapJoin或者不符合MapJoin的条件,那么Hive解析器会将Join操作转换成Common Join,即:在Reduce阶段完成join.
整个过程包含Map、Shuffle、Reduce阶段。

  • Map阶段

读取源表的数据,Map输出时候以Join on条件中的列为key,如果Join有多个关联键,则以这些关联键的组合作为key;
Map输出的value为join之后所关心的(select或者where中需要用到的)列;同时在value中还会包含表的Tag信息,用于标明此value对应哪个表;
按照key进行排序

  • Shuffle阶段

根据key的值进行hash,并将key/value按照hash值推送至不同的reduce中,这样确保两个表中相同的key位于同一个reduce中

  • Reduce阶段
    根据key的值完成join操作,期间通过Tag来识别不同表中的数据。

以下面的HQL为例,图解其过程:

SELECT
a.id,a.dept,b.age
FROM a join b
ON (a.id = b.id);

img

最为普通的join策略,不受数据量的大小影响,也可以叫做reduce side join ,最没效率的一种join 方式. 它由一个mapreduce job 完成.

首先将大表和小表分别进行map 操作, 在map shuffle 的阶段每一个map output key 变成了table_name_tag_prefix + join_column_value , 但是在进行partition 的时候它仍然只使用join_column_value 进行hash.

每一个reduce 接受所有的map 传过来的split , 在reducce 的shuffle 阶段,它将map output key 前面的table_name_tag_prefix 给舍弃掉进行比较. 因为reduce 的个数可以由小表的大小进行决定,所以对于每一个节点的reduce 一定可以将小表的split 放入内存变成hashtable. 然后将大表的每一条记录进行一条一条的比较.

2. Map Join

介绍:

MAP JION会把小表全部加载到内存中,在map阶段直接拿另外一个表的数据和内存中表数据做匹配,由于在map端是进行了join操作,省去了reduce运行的时间,算是hive中的一种优化。

img

如上图中的流程,首先Task A在客户端本地执行,负责扫描小表b的数据,将其转换成一个HashTable的数据结构,并写入本地的文件中,之后将该文件加载到DistributeCache中。

接下来的Task B任务是一个没有Reduce的MapReduce,启动MapTasks扫描大表a,在Map阶段,根据a的每一条记录去和DistributeCache中b表对应的HashTable关联,并直接输出结果,因为没有Reduce,所以有多少个Map Task,就有多少个结果文件。

使用方法:

SELECT /*+ MAPJOIN(b) */ a.key, a.value
FROM a JOIN b ON a.key = b.key;

前提b表是一张小表,具体小表有多小,由参数hive.mapjoin.smalltable.filesize来决定,默认值是25M。开启hive.auto.convert.join=true参数时,默认值是false,满足条件的话Hive在执行时候会自动转化为MapJoin,或使用hint提示 /*+ mapjoin(table) */执行MapJoin。

具体参数:

1、小表自动选择Mapjoin
set hive.auto.convert.join=true;
默认值:false。该参数为true时,Hive自动对左边的表统计量,若是小表就加入内存,即对小表使用Map join
2、小表阀值
set hive.mapjoin.smalltable.filesize=25000000;
默认值:25M
hive.smalltable.filesize (replaced by hive.mapjoin.smalltable.filesize in Hive 0.8.1)

限制:

  • 不支持以下内容。
    • unoin 后跟一个 MapJoin
    • Lateral View 后跟MapJoin
    • Reduce Sink (Group By/Join/Sort By/Cluster By/Distribute By) 后跟 MapJoin`
    • MapJoin``,然后是``Union
    • MapJoin`` 后跟 Join
    • MapJoin其次是 MapJoin

3. Bucket Map Join

介绍:

Bucket Map Join 也属于是一个 map join。 是hive join的一个优化方案。主要是针对分桶表的优化。

common join中,如果表很大,MapReduce 中的Reducer端就会负载过大。 因为从join键和值接收所有数据,并且随着更多数据shuffle,性能也会下降。 因此,当我们join在分桶列上分桶和连接的表时,我们可以使用 Hive Bucket Map Join 功能。

好处:

在分桶表中,数据是以桶的形式组织的。每个存储桶都根据存储桶键/列保存/包含某些行。因此这意味着当我们join时仅获取所需的存储桶,而不是在完整的表上获取。

只有匹配的小表桶才会复制到每个mapper上。

使用条件:

  1. 当我们join的两个表的 join keybucket column 的时候,就可以使用。
  2. 一个表中的存储桶数应是另一个表中的存储桶数的倍数。

假设如果一个表有 2 个存储桶,那么另一个表必须有 2 个存储桶或 2 个存储桶的倍数(2、4、6 等)。否则,将执行正常的内部 join。

  1. 开启 set hive.optimize.bucketmapjoin = true; 配置。

使用方法:

假设有两个表,table1 和 table2,并且两个表的数据都使用emp_id作为分桶键,存储桶个数为 8 和 4 个。如果我们对这两张表的 emp_id 列执行join 操作,并且如果可以将两个表的 bucket1 发送到单个mapper,我们可以实现大量的优化。这完全是通过执行 Hive 作业中的Bucket Map Join完成的。

-- 创建 table1 表
hive> CREATE TABLE IF NOT EXISTS table1 (emp_id int, emp_name string, emp_city string, gender String) clustered by(emp_id) into 8 buckets row format delimited fields terminated BY ‘,’;

-- 创建 table2 表
hive> CREATE TABLE IF NOT EXISTS table2 (emp_id int, job_title string) clustered by(emp_id) into 4 buckets row format delimited fields terminated BY ‘,’;

-- 加载数据
hive> load data local inpath '/relativePath/data1.csv' into table table1;

-- 加载数据
hive> load data local inpath '/relativePath/data2.csv' into table table2;

-- 开启优化
hive> set hive.optimize.bucketmapjoin=true;

-- 查询
hive> SELECT /*+ MAPJOIN(table2) */ table1.emp_id, table1.emp_name, table2.job_title FROM table1 JOIN table2 ON table1.emp_id = table2.emp_id;

- table1 是张大表,table2 远小于 table1.

123

每个 Mapper 进程从 Table2(较大的表)中拆分的文件时,都会检索 Table1(较小的表)中唯一对应的存储桶来完成join任务。

img2

4. Sort Merge Bucket Map Join

介绍:

Bucket Map Join 并没有解决 map join 在小表必须完全装载进内存的限制, 如果想要在一个reduce 节点的大表和小表都不用装载进内存,必须使两个表都在join key 上有序才行,你可以在建表的时候就指定 sorted by join key 或者使用index 的方式.

使用 SMB Map join 就要保证两张表都是已经sort 过的。

如何使用:

开启如下配置进行 SMB Map join:

set hive.auto.convert.sortmerge.join=true;
set hive.optimize.bucketmapjoin = true;
set hive.optimize.bucketmapjoin.sortedmerge = true;

有一个选项可以使用以下配置设置大表选择策略:

set hive.auto.convert.sortmerge.join.bigtable.selection.policy 
= org.apache.hadoop.hive.ql.optimizer.TableSizeBasedBigTableSelectorForAutoSMJ;

默认情况下,选择策略为平均分区大小。与哈希和流式处理相比,大表选择策略有助于确定仅为流式处理选择哪个表。

可用的选择策略包括:

org.apache.hadoop.hive.ql.optimizer.AvgPartitionSizeBasedBigTableSelectorForAutoSMJ (default)

org.apache.hadoop.hive.ql.optimizer.LeftmostBigTableSelectorForAutoSMJ

org.apache.hadoop.hive.ql.optimizer.TableSizeBasedBigTableSelectorForAutoSMJ

5. Skew Join

介绍:

如何定义一张倾斜表:这张表的一个value 值于其他数据相比,其值在表中大量存在。

在 Hive 中,当表中一个或多个键的值明显多于其他键时,就会发生倾斜联接。这可能会导致性能问题,因为由于数据分布不均匀,联接操作会变慢得多。为了解决此问题,Hive 提供了几种可用于减少倾斜联接和提高查询性能的技术。

Skew Join

当我们join的列中有一个包含倾斜数据的表时,我们可以使用倾斜连接功能。

如何使用:

hadoop 中默认的 Reducer 处理的数据大小为:

hive.exec.reducers.bytes.per.reducer = 1000000000

也就是每个节点的reduce 默认是处理1G大小的数据,如果你的join 操作也产生了数据倾斜,那么你可以在hive 中设定

set hive.optimize.skewjoin = true; 
set hive.skewjoin.key = skew_key_threshold (default = 100000)

如何处理倾斜:

在运行时,会对数据进行扫描并检测哪个key会出现倾斜,对于会倾斜的key,用map join做处理,不倾斜的key正常处理。

举个栗子:
表 A 和表 B join,并且在 ID 为12345 时发生了数据倾斜,假设在表 B 中倾斜的数据量比表 A 少,则把 B 中所有的倾斜了的数据拿出来,存到内存中(可以用一个哈希表来存)。
对于表 A ,如果是倾斜的数据,则通过 B 存放在内存中的哈希表来 join;如果不是倾斜的 key,则按正常的 reduce 端 join 流程进行。
这样就在map端完成了倾斜数据的处理,不会让某一个reducer中数据量爆炸,从而拖累处理速度。

要查看语句是否用到了 Skew Join,可以 explain 一下你的 SQL,如果在 Join Operator 和 Reduce Operator Tree 下的 handleSkewJoin 为 true,那就是用了Skew Join啦。

6. Left Semi Join

hive 中没有in/exist 这样的子句,所以需要将这种类型的子句转成left semi join. left semi join 是只传递表的join key给map 阶段 , 如果key 足够小还是执行map join, 如果不是则还是common join.

SELECT a.key, a.val
FROM a LEFT SEMI JOIN b ON (a.key = b.key)

如果被连接的表都很小,则可以将join作为map join作业来执行。如:

SELECT /*+ MAPJOIN(b) */ a.key, a.value
FROM a JOIN b ON a.key = b.key

不需要Reducer。对于 A 的每个Mapper,B 被完全读取。限制是不能执行全/右外连接 b 表。

同样当我们的 join 的key 如果满足 map join, bucket Map join, SMB Map join 条件,只需要我们开启对应的配置,就可以自动进行优化。

7. common join 的内部join

HiveQL Select Joins

常见的 common join 有如下几种:

  1. Inner join
  2. Left Outer Join
  3. Right Outer Join
  4. Full Outer Join
  5. CROSS JOIN

准备数据

CUSTOMERS 数据

ID	Name	Age	Address	Salary
1	Ross	32	Ahmedabad	2000
2	Rachel	25	Delhi	1500
3	Chandler	23	Kota	2000
4	Monika	25	Mumbai	6500
5	Mike	27	Bhopal	8500
6	Phoebe	22	MP	4500
7	Joey	24	Indore	10000

建表

CREATE TABLE CUSTOMERS (
    ID INT PRIMARY KEY,
    Name VARCHAR(255),
    Age INT,
    Address VARCHAR(255),
    Salary INT
);

-- 导入数据
INSERT INTO CUSTOMERS (ID, Name, Age, Address, Salary)
VALUES
    (1, 'Ross', 32, 'Ahmedabad', 2000),
    (2, 'Rachel', 25, 'Delhi', 1500),
    (3, 'Chandler', 23, 'Kota', 2000),
    (4, 'Monika', 25, 'Mumbai', 6500),
    (5, 'Mike', 27, 'Bhopal', 8500),
    (6, 'Phoebe', 22, 'MP', 4500),
    (7, 'Joey', 24, 'Indore', 10000);

orders 表

OID	Date	Customer_ID	Amount
102	2016-10-08 00:00:00	3	3000
100	2016-10-08 00:00:00	3	1500
101	2016-11-20 00:00:00	2	1560
103	2015-05-20 00:00:00	4	2060

建表

-- 创建表
CREATE TABLE ORDERS (
    OID INT PRIMARY KEY,
    Date DATETIME,
    Customer_ID INT,
    Amount INT
);

-- 插入数据
INSERT INTO ORDERS (OID, Date, Customer_ID, Amount)
VALUES
    (102, '2016-10-08 00:00:00', 3, 3000),
    (100, '2016-10-08 00:00:00', 3, 1500),
    (101, '2016-11-20 00:00:00', 2, 1560),
    (103, '2015-05-20 00:00:00', 4, 2060);

1. 内连接(Inner join)

内连接返回两个表中满足连接条件的行,丢弃不匹配的行

查询语句:

SELECT c.ID, c.NAME, c.AGE, o.AMOUNT
FROM CUSTOMERS c JOIN ORDERS o
ON (c.ID = o.CUSTOMER_ID);

结果如下:

+----+----------+------+--------+
| ID | NAME     | AGE  | AMOUNT |
+----+----------+------+--------+
|  3 | Chandler |   23 |   1500 |
|  2 | Rachel   |   25 |   1560 |
|  3 | Chandler |   23 |   3000 |
|  4 | Monika   |   25 |   2060 |
+----+----------+------+--------+

2. 左外连接(Left Outer Join)

左外连接返回左表中所有行,以及满足连接条件的右表中的匹配行。如果右表中没有匹配行,则右表的结果为 NULL

查询语句:

 SELECT c.ID, c.NAME, o.AMOUNT, o.DATE
FROM CUSTOMERS c
LEFT OUTER JOIN ORDERS o
ON (c.ID = o.CUSTOMER_ID);

结果如下:

+----+----------+--------+---------------------+
| ID | NAME     | AMOUNT | DATE                |
+----+----------+--------+---------------------+
|  3 | Chandler |   1500 | 2016-10-08 00:00:00 |
|  2 | Rachel   |   1560 | 2016-11-20 00:00:00 |
|  3 | Chandler |   3000 | 2016-10-08 00:00:00 |
|  4 | Monika   |   2060 | 2015-05-20 00:00:00 |
|  1 | Ross     |   NULL | NULL                |
|  5 | Mike     |   NULL | NULL                |
|  6 | Phoebe   |   NULL | NULL                |
|  7 | Joey     |   NULL | NULL                |
+----+----------+--------+---------------------+

3. 右外连接(RIGHT OUTER JOIN)

右外连接与左外连接类似,但是返回右表中所有行,以及满足连接条件的左表中的匹配行。如果左表中没有匹配行,则左表的结果为 NULL。

查询语句:

SELECT c.ID, c.NAME, o.AMOUNT, o.DATE FROM CUSTOMERS c RIGHT OUTER JOIN ORDERS o ON (c.ID = o.CUSTOMER_ID);

结果如下:

+------+----------+--------+---------------------+
| ID   | NAME     | AMOUNT | DATE                |
+------+----------+--------+---------------------+
|    3 | Chandler |   1500 | 2016-10-08 00:00:00 |
|    2 | Rachel   |   1560 | 2016-11-20 00:00:00 |
|    3 | Chandler |   3000 | 2016-10-08 00:00:00 |
|    4 | Monika   |   2060 | 2015-05-20 00:00:00 |
+------+----------+--------+---------------------+

4. 全外连接(FULL OUTER JOIN)

全外连接返回左表和右表中所有行,同时在任何一方没有匹配行的地方填充 NULL。

查询语句:

SELECT c.ID, c.NAME, o.AMOUNT, o.DATE
FROM CUSTOMERS c
FULL OUTER JOIN ORDERS o
ON (c.ID = o.CUSTOMER_ID);

结果如下:

+------+----------+--------+---------------------+
| ID   | NAME     | AMOUNT | DATE                |
+------+----------+--------+---------------------+
|    1 | Ross     |   NULL |                NULL |
|    2 | Rachel   |   1560 | 2016-11-20 00:00:00 |
|    3 | Chandler |   1500 | 2016-10-08 00:00:00 |
|    3 | Chandler |   3000 | 2016-10-08 00:00:00 |
|    4 | Monika   |   2060 | 2015-05-20 00:00:00 |
|    5 | Mike     |   NULL |                NULL |
|    6 | Phoebe   |   NULL |                NULL |
|    7 | Joey     |   NULL |                NULL |
+------+----------+--------+---------------------+

5. 笛卡尔积(CROSS JOIN)

这个查询会返回 “employees” 表中的每一行与 “ORDERS” 表中的每一行的组合,从而产生两个表的笛卡尔积。

请注意,笛卡尔积可能会产生非常大的结果集,因此在使用 CROSS JOIN 时需要谨慎。在实际使用中,应确保只在需要时使用笛卡尔积操作,以避免性能问题。

查询语句:

SELECT c.*, o.*
FROM CUSTOMERS c
CROSS JOIN ORDERS o;
c.ID | c.Name  | c.Age | c.Address   | c.Salary | o.OID | o.Date               | o.Customer_ID | o.Amount
-----|---------|-------|-------------|----------|-------|---------------------|--------------|----------
1    | Ross    | 32    | Ahmedabad   | 2000.00  | 102   | 2016-10-08 00:00:00 | 3            | 3000
1    | Ross    | 32    | Ahmedabad   | 2000.00  | 100   | 2016-10-08 00:00:00 | 3            | 1500
1    | Ross    | 32    | Ahmedabad   | 2000.00  | 101   | 2016-11-20 00:00:00 | 2            | 1560
1    | Ross    | 32    | Ahmedabad   | 2000.00  | 103   | 2015-05-20 00:00:00 | 4            | 2060
...   ...       ...     ...           ...        ...     ...                  ...              ...

特殊点

对于inner join 左表和右表 当有非等值过滤条件时,可以按照过滤条件进行过滤。

  • 左表有过滤条件,只过滤左表,右表不过滤

  • 右表有过滤条件,只过滤右表,左表不过滤

  • 左右表有过滤条件,同时过滤

案例如下:

explain dependency select * from student_part a inner join student_part_parquet b
on a.s_name = b.s_name and a.s_age <23;

img

左4 右7

explain dependency select * from student_part a inner join student_part_parquet b
on a.s_name = b.s_name and b.s_age <23;

img

左7 右4

explain dependency select * from student_part a inner join student_part_parquet b
on a.s_name = b.s_name and b.s_age <23 and a.s_age >24;

img

左2 右3

对于 left join

  • 只过滤左表 左表无过滤 右表有过滤

  • 只过滤右表 左表无过滤 右表有过滤

  • 同时过滤左右表 左表无过滤 右表有过滤

只过滤左表 —结果 左7 右 7 无过滤

explain dependency select * from student_part a left outer join student_part_parquet b
on a.s_name = b.s_name and a.s_age <23;

img
只过滤右表 —结果 左7 右 3 左表无过滤,右表有过滤

explain dependency select * from student_part a left outer join student_part_parquet b
on a.s_name = b.s_name and b.s_age <23;

img

同时过滤左右表 —结果 左7 右 3 左表无过滤,右表有过滤

explain dependency select * from student_part a left outer join student_part_parquet b
on a.s_name = b.s_name and b.s_age <23 and a.s_age >25;

img

所以建议尽早在子查询中,提前过滤数据。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用 HTML、CSS 和 JavaScript 创建多步骤表单

使用 HTML、CSS 和 JavaScript 创建多步骤表单 为了处理又长又复杂的表单&#xff0c;我们需要将它们分成多个步骤。通过一次只在屏幕上显示一些输入&#xff0c;表单会感觉更容易理解&#xff0c;并防止用户感到被大量的表单字段淹没。 在本文中&#xff0c;我将逐步指导如何…

OSI七层模型及TCP/IP四层模型

目录 OSI七层模型 TCP/IP四层模型 OIS七层模型和TCP/IP模型图 七层详解 两种模型比较 为什么OSI七层体系结构不常用 四层详解 网络为什么要分层&#xff1f; 说说 OSI 七层模型和 TCP/IP 四层模型的关系和区别 OSI七层模型 OSI&#xff08;Open System Interconnect&a…

编译redis-5.0.9报错zmalloc.h:50:31: 致命错误:jemalloc/jemalloc.h:没有那个文件或目录问题解决

上图 解决&#xff1a; make && make install MALLOClibc原因: 原因是jemalloc重载了Linux下的ANSI C的malloc和free函数。

【Spring Boot】构建RESTful服务 — 实战:实现Web API版本控制

实战&#xff1a;实现Web API版本控制 前面介绍了Spring Boot如何构建RESTful风格的Web应用接口以及使用Swagger生成API的接口文档。如果业务需求变更&#xff0c;Web API功能发生变化时应该如何处理呢&#xff1f;可以通过Web API的版本控制来处理。 1.为什么进行版本控制 …

JVM中对象和GC Root之间的四种引用关系

1. 强引用 只有所有 GC Roots 对象都不通过【强引用】引用该对象&#xff0c;该对象才能被垃圾回收 由GC Root直接new出来的对象是强引用&#xff0c;只有当GC Root不再引用该对象的时候&#xff0c;才会被回收 例子&#xff1a; List<String> list new ArrayList<&…

【STM32】FreeRTOS事件组学习

事件组&#xff08;Event Group&#xff09; 一个任务执行之前需要经过多个条件进行判断&#xff0c;当条件全部满足或多个条件中的某一个条件满足才执行。 实验&#xff1a;创建两个任务&#xff0c;一个事件组&#xff0c;当按键一二三都按过一遍才打印。 实现&#xff1a…

STM32 CubeMX (Freertos任务通信:队列、信号量、互斥量,事件组,任务通知)第二步

STM32 CubeMX STM32 CubeMX ____Freertos任务通信&#xff1a;队列、信号量、互斥量&#xff0c;事件组&#xff0c;任务通知 STM32 CubeMX一、STM32 CubeMX设置时钟配置HAL时基选择TIM1&#xff08;不要选择滴答定时器&#xff1b;滴答定时器留给OS系统做时基&#xff09;使用…

【STM32+ESP8266上云连载①】给ESP8266烧录AT固件

文章目录 一、给NodeMCU烧录固件1.1硬件准备1.2软件准备1.3AT固件下载1.4配置设置1.5开始烧录 二、给ESP8266-01S烧录固件2.1硬件准备2.2AT固件下载2.3连线2.4烧录配置 三、给ESP-12E/F/S单片烧录固件四、指令测试4.1HTTP测试4.2MQTT测试 我在使用ESP8266的时候遇到了一些问题&…

智能仓储管理系统(自动化仓库管理解决方案)

企业实际的仓储管理中&#xff0c;往往会出现那样这样的错误&#xff0c;归根结底&#xff0c;主要是由于没使用合适的仓库管理工具。相反&#xff0c;人工使用合适的仓库管理工具&#xff0c;不仅可以在日常仓库管理方法中根据采集到的产品信息数据&#xff0c;大大地提高管理…

vue3学习笔记(一)

一、API风格 Vue 的组件可以按两种不同的风格书写&#xff1a;选项式 API 和组合式 API。 二、组合式API 1.&#xff08;组合式 API 的核心思想是直接在函数作用域内定义响应式状态变量&#xff0c;并将从多个函数中得到的状态组合起来处理复杂问题。这种形式更加自由&#x…

vue项目根据word模版导出word文件

一、安装依赖 //1、docxtemplaternpm install docxtemplater pizzip -S//2、jszip-utilsnpm install jszip-utils -S//3、pizzipnpm install pizzip -S//4、FileSaver npm install file-saver --save二、创建word模版 也就是编辑一个word文档&#xff0c;文档中需要动态取值的…

用 React+ts 实现无缝滚动的走马灯

一、走马灯的作用 走马灯是一种常见的网页交互组件&#xff0c;可以展示多张图片或者内容&#xff0c;通过自动播放或者手动切换的方式&#xff0c;让用户能够方便地浏览多张图片或者内容。 本次实现的不是轮播图而是像传送带一样的无限滚动的形式。 二、需求梳理 走马灯可设…

大数据培训前景怎么样?企业需求量大吗

大数据行业对大家来说并不陌生&#xff0c;大数据行业市场人才需求量大&#xff0c;越早入行越有优势&#xff0c;发展机会和上升空间等大。不少人通过大数据培训来提升自己的经验和自身技术能力&#xff0c;以此来获得更好的就业机会。 2023大数据培训就业前景怎么样呢?企业需…

034_小驰私房菜_[问题复盘] Qcom平台,某些三方相机拍照旋转90度

全网最具价值的Android Camera开发学习系列资料~ 作者:8年Android Camera开发,从Camera app一直做到Hal和驱动~ 欢迎订阅,相信能扩展你的知识面,提升个人能力~ 【一、问题】 某些三方相机,预览正常,拍照旋转90度 【二、问题排查】 1 ) HAL这边Jpeg编码数据在哪个地方…

Baumer工业相机堡盟工业相机如何通过BGAPI SDK设置相机的固定帧率(C++)

Baumer工业相机堡盟工业相机如何通过BGAPI SDK设置相机的固定帧率&#xff08;C&#xff09; Baumer工业相机Baumer工业相机的固定帧率功能的技术背景CameraExplorer如何查看相机固定帧率功能在BGAPI SDK里通过函数设置相机固定帧率 Baumer工业相机通过BGAPI SDK设置相机固定帧…

Python发送QQ邮件

使用Python的smtplib可以发送QQ邮件&#xff0c;代码如下 #!/usr/bin/python3 import smtplib from email.mime.text import MIMEText from email.header import Headersender 111qq.com # 发送邮箱 receivers [222qq.com] # 接收邮箱 auth_code "abc" # 授权…

大数据-玩转数据-Flink RedisSink

一、添加Redis Connector依赖 具体版本根据实际情况确定 <dependency><groupId>org.apache.flink</groupId><artifactId>flink-connector-redis_2.11</artifactId><version>1.1.5</version> </dependency>二、启动redis 参…

两个案例熟悉String的基本操作

1、第一个案例 Java语言规范要求完全相同的字符串字面量&#xff0c;应该包含同样的Unicode字符序列&#xff08;包含同一份码点序列的常量&#xff09;&#xff0c;并且必须是指向同一个String类实例。 package string; public class StringTest4 {public static void main(St…

AutoSAR系列讲解(深入篇)13.3-Mcal Dio配置

目录 一、Dio port配置 二、Dio pin配置 一、Dio port配置 同之前的Port一样,双击进入Dio配置界面后会看到几乎差不多的配置界面。General和Port类似,我们不再赘述,主要讲解Dio的配置 1. 其实Dio并没有什么实质的作用,主要起到了一个重命名的功能。双击DioConfig_0进入下…

文本图片怎么转Excel?分享一些好用的方法

在处理数据时&#xff0c;Excel 是一个非常强大的工具&#xff0c;但有时候需要将文本和图片转换为 Excel 格式&#xff0c;这可能会让人感到困惑。在本文中&#xff0c;我们将介绍一些好用的方法&#xff0c;以便您能够轻松地将文本和图片转换成 Excel 格式。 将文本图片为Exc…