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

news2024/11/16 9:58:06

文章目录

    • 前言
    • 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

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

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

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

相关文章

银河麒麟服务器v10 sp1 .Net6.0 Serilog 运行时不创建日志文件

上一篇&#xff1a;银河麒麟服务器v10 sp1 .Net Core 上传文件错误_csdn_aspnet的博客-CSDN博客 在代码中常用的日志记录相关重要或错误日志等&#xff0c;如Serilog、Log4net等&#xff0c;本文使用Serilog&#xff0c;在Program.cs的main方法中&#xff0c;代码如下图&#…

【GitLab私有仓库】如何在Linux上用Gitlab搭建自己的私有库并配置cpolar内网穿透?

文章目录 前言1. 下载Gitlab2. 安装Gitlab3. 启动Gitlab4. 安装cpolar5. 创建隧道配置访问地址6. 固定GitLab访问地址6.1 保留二级子域名6.2 配置二级子域名 7. 测试访问二级子域名 前言 GitLab 是一个用于仓库管理系统的开源项目&#xff0c;使用Git作为代码管理工具&#xf…

K8S核心组件etcd详解(下)

1 k8s如何使用etcd 在k8s中所有对象的manifest都需要保存到某个地方&#xff0c;这样他们的manifest在api server重启和失败的时候才不会丢失。 只有api server能访问etcd&#xff0c;其它组件只能间接访问etcd的好处是 增强乐观锁系统及验证系统的健壮性 方便后续存储的替换…

pyqt5 窗口居中、退出按钮、状态栏、窗口标题、水平布局、程序图标、

import sys# QT的基类 from PyQt5.QtWidgets import QApplication# 说明创建的是主窗体 QMainWindow from PyQt5.QtWidgets import QMainWindow# 添加控件&#xff1a;按钮、主控件&#xff08;窗口&#xff09; from PyQt5.QtWidgets import QPushButton, QWidget# 添加布局&a…

ssm单位人事管理系统源码和文档

ssm单位人事管理系统源码和文档033 开发工具&#xff1a;idea 数据库mysql5.7 数据库链接工具&#xff1a;navcat,小海豚等 技术&#xff1a;ssm 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳…

进程|详解~什么是进程 以及 进程创建原理和过程

1.什么是进程 进程是正在运行的程序。 UNIX标准将进程定义为&#xff1a;其中运行着一个或者多个线程的地址空间和这些线程所需要的系统资源(分配给线程线程共享系统资源)。 组成&#xff1a;进程由程序代码、数据、变量(占用着系统内存)、打开的文件(文件描述符)、环境组成…

经典文献阅读之--LIW-OAM(LiDAR-IMU-编码器融合SLAM)

0. 简介 我们之前经常接触的是使用激光雷达和惯性测量单元(IMU)的互补信息&#xff0c;但是实际使用的过程中IMU如果发生剧烈的颠簸&#xff0c;有可能会导致IMU失效。在广泛使用的迭代最近点&#xff08;ICP&#xff09;算法只能为姿态提供约束&#xff0c;而速度只能由IMU预…

Linux系统的历史记录添加时间和IP信息

1 系统history记录优化 默认情况下&#xff0c;系统是不会记录我们执行命令的时间等相关信息的。 1.1 HISTCONTROL 介绍 使用HISTCONTROL变量&#xff0c;您可以控制 bash 如何存储您的命令历史记录。您可以告诉它忽略重复的命令和/或忽略具有前导空格的命令。 在命令行工作…

亚马逊新品如何快速上首页

将亚马逊新品快速上首页是许多卖家的目标&#xff0c;但要注意&#xff0c;这涉及到多种因素&#xff0c;包括产品质量、市场竞争、营销策略等。以下是一些可能帮助您的亚马逊新品快速上首页的方法&#xff1a; 1、优化产品信息&#xff1a;确保您的产品标题、描述和关键词字段…

Scratch 之 如何制作鼠标框(1)—— 绘制鼠标框

hello&#xff0c;大家好&#xff0c;今天给大家带来如何绘制鼠标框 我们正式开始 首先&#xff0c;让我们绘制一个空角色 然后让我们来编代码 1、准备工作 &#xff08;1&#xff09;拓展 画笔 添加这个拓展↑ &#xff08;2&#xff09;变量 实际上&#xff0c;你只需…

Systemverilog 接口 interface modport使用说明

一、接口的定义   SystemVerilog在Verilog语言基础上扩展了“接口”&#xff08;interface&#xff09;结构&#xff0c;SystemVerilog增加了新的端口类型—接口&#xff0c;接口允许许多信号合成一组由一个端口表示&#xff0c;只需在一个地方对组成接口的信号进行声明&am…

4G无线网络草坪音箱,4G石头音箱

SV-7042UG 4G无线网络草坪音箱&#xff0c;4G石头音箱 一、描述 SV-7042UG是深圳锐科达电子有限公司的一款壁挂式4G无线网络草坪音箱&#xff0c;通过4G无线卡联网&#xff0c;可将网络音源通过自带的功放和喇叭输出播放&#xff0c;其采用防水设计&#xff0c;功率40W。SV-70…

chatgpt 翻译整本英文电子书,效果非常好

1. 注册chatgpt账号&#xff0c;登录后设置好API token。 https://platform.openai.com/account/api-keys 一定要把生成的token先复制保存好&#xff0c;对话框消失后就无法看到完整token了。 2. 配置免费的cloudflare workers 代理&#xff0c;否则很容易被封号 参考文档 h…

【Windows系统编程】05.内存操作与InlineHook(详解InlineHook实现)

文章目录 内存相关InlineHook完整实现代码&#xff08;dll&#xff09;&#xff1a; InlineHook测试&#xff1a; 内存相关 内存信息 头文件&#xff1a;#include <Psapi.h> //检索有关系统当前使用物理内存和虚拟内存的信息MEMORYSTATUSEX mst;GlobalMemoryStatusEx…

docker 容器满了常用处理方法

docker 容器满了常用处理方法 1、运行 df -h 查看剩余磁盘占用情况 2、进入到docker目录 cd /var/lib/docker 3、运行du -h --max-depth1 &#xff08;检索文件的最大深度1&#xff0c;即只检索汇总计算当前目录下的文件&#xff09; 4、进入占用最大的 /containers文件夹&am…

pg各种条件判断语句

1.基本查询 搜索语句&#xff1a; select (distinct&#xff08;去重&#xff09;) 内容&#xff08;*代表所有&#xff09; as 别名 from 表 注释&#xff1a; -- 快速查询&#xff1a;select 内容 AS 别名 没有表一般当做计算器来用 2.条件查询 null只能用is 或者is…

7.11 Java方法重写

7.11 Java方法重写 这里首先要确定的是重写跟属性没有关系&#xff0c;重写都是方法的重写&#xff0c;与属性无关 带有关键字Static修饰的方法的重写实例 父类实例 package com.baidu.www.oop.demo05;public class B {public static void test(){System.out.println("这…

CLion 创建Qt工程

环境 CLion &#xff1a;2019.3.6 Qt &#xff1a;5.9.6&#xff08;MinGW&#xff09; Clion 配置 编译环境配置 添加Qt MinGW编译环境 添加Qt工具 创建工程 正常创建C工程 CMakeLists cmake_minimum_required(VERSION 3.8) project(QtApp)set(CMAKE_CXX_STANDARD 11)…

APB register脚本

[github repo]根据Excel表格自动生成寄存器RTL/RALF/C header的脚本 - wudayemen - 博客园 (cnblogs.com) 在芯片设计中&#xff0c;常常会使用APB总线配置每个模块的寄存器。这一部分可以使用脚本生成相应RTL代码和对应的验证所需文件比如RALF&#xff0c;和C语言的头文件&am…

【仿写tomcat】三、通过socket读取http请求信息

仿写tomcat 建立Socket连接获取连接信息查看HTTP信息 建立Socket连接 这里我们也是创建一个专门管理socket的类 package com.tomcatServer.socket;import java.io.*; import java.net.ServerSocket;/*** 套接字存储** author ez4sterben* date 2023/08/15*/ public class Soc…