目录

三、Impala OLAP 实例

1. 建立 olap 库、表、视图

2. 初始装载数据

3. 修改销售订单定期装载脚本

4. 定义 OLAP 需求

5. 执行 OLAP 查询


三、Impala OLAP 实例

        本节使用前面销售订单的例子说明如何使用 Impala 做 OLAP 类型的查询,以及实际遇到的问题及解决方案。为了处理 SCD 和行级更新,我们前面的 ETL 使用了 Hive ORCFile 格式的表,可惜到目前为止,Impala 还不支持 ORCFile。用 Impala 查询 ORCFile 表时,错误信息如下图所示。

        这是一个棘手的问题。如果我们再建一套和 dw 库中表结构一样的表,但使用 Impala 能够识别的文件类型,如 Parquet,又会引入两个新的问题:一是 CDH 5.7.0 的 Hive 版本是 1.1.0,有些数据类型不支持,如 date。另一个更大的问题是增量装载数据问题。dw 库的维度表和事实表都有 update 操作,可 Impala 只支持数据装载,不支持 update 和 delete 等 DML 操作。如果每天都做 insert overwrite 覆盖装载全部数据,对于大数据量来说很不现实。

        尽管 Impala 不支持 update 语句,但通过使用 HBase 作为底层存储可是达到同样的效果。相同键值的数据被插入时,会自动覆盖原有的数据行。这样只要在每天定期 ETL 时,记录当天产生变化(包括修改和新增)的记录,只将这些记录插入到 Impala 表中,就可以实现增量数据装载。这个方案并不完美,毕竟冗余了一套数据,既浪费空间,又增加了 ETL 的额外工作。其实前面 ETL 的 Hive 表也可以使用 HBase 做底层存储而不用 ORCFile 文件类型,利用 HBase 的特性,既可以用 Hive 做 ETL,又可以用 Impala 做 OLAP,真正做到一套数据,多个引擎。这个方案也需要一些额外的工作,如安装 HBase,配置 Hive、Impala 与 HBase 协同工作等,它最主要的问题是 Impala 在 HBase 上的查询性能并不适合 OLAP 场景。

        如果没有累积快照事实表,可以对相对较小的维度表全量覆盖插入,而对大的事实表增量插入,这也是本实例中采用的方案。也就是说,为了保证查询性能和数据装载可行性,牺牲了对累积快照事实表的支持。希望 Impala 尽快支持 ORCFile 并能达到和 Parquet 同样的性能,这样就可以省却很多麻烦。

1. 建立 olap 库、表、视图

        用下面的查询语句从 MySQL 的 hive 库生成建表文件。

use hive;
select concat('create table ', t1.tbl_name, ' (',group_concat(concat(t2.column_name,' ',t2.type_name) order by t2.integer_idx),') stored as parquet;') into outfile '/data/hive/create_table.sql'from (select t1.tbl_id,t1.tbl_name from TBLS t1, DBS t2where t1.db_id = t2. db_id and t2.name = 'dw' and tbl_type <> 'VIRTUAL_VIEW' and (tbl_name like '%dim' or tbl_name like '%fact')) t1,(select case when v.column_name = 'date' then 'date1' else v.column_name end column_name,replace(v.type_name,'date','timestamp') type_name,v.integer_idx,t.tbl_idfrom COLUMNS_V2 v, CDS c, SDS s, TBLS twhere v.cd_id = c.cd_idand c.cd_id = s.cd_idand s.sd_id = t.sd_id) t2where t1.tbl_id = t2.tbl_idgroup by t1.tbl_name;

        生成的 create_table.sql 文件包含所有维度表和事实表的建表语句,例如:

create table product_dim (product_sk int,product_code int,product_name varchar(30),product_category varchar(30),version int,effective_date timestamp,expiry_date timestamp) stored as parquet;

        用下面的查询语句从 MySQL 的 hive 库生成建视图文件。

use hive;
select concat('create view ', t1.tbl_name, ' as ', replace(replace(t1.view_original_text,'\n',' '),' date,',' date1,'), ';')  into outfile '/data/hive/create_view.sql'from TBLS t1, DBS t2where t1.db_id = t2.db_id and t2.name = 'dw' and t1.tbl_type = 'VIRTUAL_VIEW';

        生成的 create_view.sql 文件包含所有建立视图的语句,例如:

create view allocate_date_dim as SELECT date_sk, date, month, month_name, quarter, year, promo_ind FROM date_dim;

        从 Hive 命令行执行建立库、表、视图的脚本。

hive -e 'create database olap;use olap;source /data/hive/create_table.sql;source /data/hive/create_view.sql;'

2. 初始装载数据

        用下面的查询语句从 MySQL 的 hive 库生成装载数据脚本文件。

use hive;
select concat('insert overwrite table olap.', t1.tbl_name, ' select ', group_concat(t2.column_name order by t2.integer_idx),' from dw.', t1.tbl_name ,';') into outfile '/data/hive/insert_table.sql'from (select t1.tbl_id,t1.tbl_name from TBLS t1, DBS t2where t1.db_id = t2. db_id and t2.name = 'dw' and tbl_type <> 'VIRTUAL_VIEW' and (tbl_name like '%dim' or tbl_name like '%fact')) t1,(select v.column_name,replace(v.type_name,'date','timestamp') type_name,v.integer_idx,t.tbl_idfrom COLUMNS_V2 v, CDS c, SDS s, TBLS twhere v.cd_id = c.cd_idand c.cd_id = s.cd_idand s.sd_id = t.sd_id) t2where t1.tbl_id = t2.tbl_idgroup by t1.tbl_name;

        生成的 insert_table.sql 文件包含所有 insert olap 表的语句,例如:

insert overwrite table olap.product_dim select product_sk,product_code,product_name,product_category,version,effective_date,expiry_date from dw.product_dim;

        从 Hive 命令行执行初始装载数据的脚本:

hive -e 'source /data/hive/insert_table.sql;'

3. 修改销售订单定期装载脚本

        首先将 dw 和 olap 库中的事实表变更为动态分区表,这样在向 olap 库中装载数据时,或是在 olap 库上进行查询时,都可以有效地利用分区消除来提高性能。这里只修改了每日定时装载所涉及的两个表 product_count_fact 和 sales_order_fact,其他事实表的修改类似。因为分区字段只能在表定义的最后,可能会改变字段的顺序,所以还要修改相关的 ETL 脚本。

        执行下面的语句修改 dw 库的事实表。

use dw;set hive.exec.dynamic.partition=true;  
set hive.exec.dynamic.partition.mode=nonstrict;  
set hive.exec.max.dynamic.partitions.pernode=1000; -- product_count_fact表
create table product_count_fact_part
(product_sk int)
partitioned by (product_launch_date_sk int);insert overwrite table product_count_fact_part partition (product_launch_date_sk)
select product_sk,product_launch_date_sk from product_count_fact;drop table product_count_fact;
alter table product_count_fact_part rename to product_count_fact;-- sales_order_fact表
create table sales_order_fact_part
(order_number int,customer_sk int,customer_zip_code_sk int,shipping_zip_code_sk int,product_sk int,sales_order_attribute_sk int,order_date_sk int,allocate_date_sk int,allocate_quantity int,packing_date_sk int,packing_quantity int,ship_date_sk int,ship_quantity int,receive_date_sk int,receive_quantity int,request_delivery_date_sk int,order_amount decimal(10,2),order_quantity int)
partitioned by (entry_date_sk int)
clustered by (order_number) into 8 buckets      
stored as orc tblproperties ('transactional'='true');insert overwrite table sales_order_fact_part partition (entry_date_sk)
select order_number,customer_sk,customer_zip_code_sk,shipping_zip_code_sk,product_sk,sales_order_attribute_sk,order_date_sk,allocate_date_sk,allocate_quantity,packing_date_sk,packing_quantity,ship_date_sk,ship_quantity,receive_date_sk,receive_quantity,request_delivery_date_sk,order_amount,order_quantity,entry_date_skfrom sales_order_fact;drop table sales_order_fact;
alter table sales_order_fact_part rename to sales_order_fact;

        执行下面的语句修改 olap 库的事实表,和上面的语句类似,只是表的存储类型为 parquet。

use olap;set hive.exec.dynamic.partition=true;  
set hive.exec.dynamic.partition.mode=nonstrict;  
set hive.exec.max.dynamic.partitions.pernode=1000; -- product_count_fact表
create table product_count_fact_part
(product_sk int)
partitioned by (product_launch_date_sk int)
stored as parquet;insert overwrite table product_count_fact_part partition (product_launch_date_sk)
select product_sk,product_launch_date_sk from product_count_fact;drop table product_count_fact;
alter table product_count_fact_part rename to product_count_fact;-- sales_order_fact表
create table sales_order_fact_part
(order_number int,customer_sk int,customer_zip_code_sk int,shipping_zip_code_sk int,product_sk int,sales_order_attribute_sk int,order_date_sk int,allocate_date_sk int,allocate_quantity int,packing_date_sk int,packing_quantity int,ship_date_sk int,ship_quantity int,receive_date_sk int,receive_quantity int,request_delivery_date_sk int,order_amount decimal(10,2),order_quantity int)
partitioned by (entry_date_sk int)
stored as parquet;insert overwrite table sales_order_fact_part partition (entry_date_sk)
select order_number,customer_sk,customer_zip_code_sk,shipping_zip_code_sk,product_sk,sales_order_attribute_sk,order_date_sk,allocate_date_sk,allocate_quantity,packing_date_sk,packing_quantity,ship_date_sk,ship_quantity,receive_date_sk,receive_quantity,request_delivery_date_sk,order_amount,order_quantity,entry_date_skfrom sales_order_fact;drop table sales_order_fact;
alter table sales_order_fact_part rename to sales_order_fact;

        下面修改数据仓库每天定期装载脚本,需要做以下三项修改。

  • 添加 olap 库中维度表的覆盖装载语句。
  • 根据分区定义修改 dw 事实表的装载语句。
  • 添加 olap 库中事实表的增量装载语句。

        下面显示了修改后的 regular_etl.sql 定期装载脚本(只部分显示)。

-- 设置环境与时间窗口  
!run /root/set_time.sql   set hive.exec.dynamic.partition=true;  
set hive.exec.dynamic.partition.mode=nonstrict;  
set hive.exec.max.dynamic.partitions.pernode=1000;-- 装载customer维度    
...-- 装载olap.customer_dim表
insert overwrite table olap.customer_dim select * from customer_dim;-- 装载product维度    
...-- 装载olap.product_dim表
insert overwrite table olap.product_dim select * from product_dim;-- 装载product_count_fact表
truncate table product_count_fact;
insert into product_count_fact partition (product_launch_date_sk)
select product_sk,date_skfrom (select a.product_sk product_sk,a.product_code product_code,b.date_sk date_sk,row_number() over (partition by a.product_code order by b.date_sk) rnfrom product_dim a,date_dim bwhere a.effective_date = b.date) twhere rn = 1;-- 全量装载olap.product_count_fact表
truncate table olap.product_count_fact;
insert into olap.product_count_fact partition (product_launch_date_sk)
select * from product_count_fact;-- 装载销售订单事实表 
-- 前一天新增的销售订单,因为分区键字段在最后,所以这里把entry_date_sk字段的位置做了调整。
-- 后面处理分配库房、打包、配送和收货四个状态时,同样也要做相应的调整。 
INSERT INTO sales_order_fact partition (entry_date_sk)
SELECT    a.order_number,    customer_sk,i.customer_zip_code_sk,  j.shipping_zip_code_sk,    product_sk, g.sales_order_attribute_sk,e.order_date_sk,null,null,null,null,null,null,null,null,f.request_delivery_date_sk,order_amount,    quantity,h.entry_date_sk    FROM    rds.sales_order a,     customer_dim c,    product_dim d,    order_date_dim e,  request_delivery_date_dim f, sales_order_attribute_dim g,entry_date_dim h,customer_zip_code_dim i,  shipping_zip_code_dim j,  rds.customer k, rds.cdc_time lWHERE a.order_status = 'N'
AND a.customer_number = c.customer_number    
AND a.status_date >= c.effective_date    
AND a.status_date < c.expiry_date 
AND a.customer_number = k.customer_number  
AND k.customer_zip_code = i.customer_zip_code  
AND a.status_date >= i.effective_date  
AND a.status_date <= i.expiry_date  
AND k.shipping_zip_code = j.shipping_zip_code  
AND a.status_date >= j.effective_date  
AND a.status_date <= j.expiry_date    
AND a.product_code = d.product_code    
AND a.status_date >= d.effective_date    
AND a.status_date < d.expiry_date    
AND to_date(a.status_date) = e.order_date
AND to_date(a.entry_date) = h.entry_date   
AND to_date(a.request_delivery_date) = f.request_delivery_date
AND a.verification_ind = g.verification_ind  
AND a.credit_check_flag = g.credit_check_flag  
AND a.new_customer_ind = g.new_customer_ind  
AND a.web_order_flag = g.web_order_flag 
AND a.entry_date >= l.last_load AND a.entry_date < l.current_load ;    -- 重载PA客户维度    
...-- 装载olap.pa_customer_dim表
insert overwrite table olap.pa_customer_dim select * from pa_customer_dim;-- 处理分配库房、打包、配送和收货四个状态
...-- 增量装载olap.sales_order_fact表
insert into olap.sales_order_fact partition (entry_date_sk)
select t1.* from sales_order_fact t1,entry_date_dim t2,rds.cdc_time t3where t1.entry_date_sk = t2.entry_date_skand t2.entry_date >= t3.last_load and t2.entry_date < t3.current_load ;-- 更新时间戳表的last_load字段    
INSERT OVERWRITE TABLE rds.cdc_time SELECT current_load, current_load FROM rds.cdc_time;

4. 定义 OLAP 需求

        要做好 OLAP 类的应用,需要对业务数据有深入的理解。只有了解了业务,才能知道需要分析哪些指标,从而有的放矢地剖析相关数据,得出可信的结论来辅助决策。下面就用前面销售订单数据仓库的例子,提出若干问题,然后用 Impala 查询数据以回答这些问题:

  • 每种产品类型以及单个产品的累积销售量和销售额是多少?
  • 每种产品类型以及单个产品在每个州以及每个城市的月销售量和销售额趋势是什么?
  • 每种产品类型销售量和销售额和同比如何?
  • 每个州以及每个城市的客户数量及其消费金额汇总是多少?
  • 迟到的订单比例是多少?
  • 客户年消费金额为“高”、“中”、“低”档的人数及消费金额所占比例是多少?
  • 每个城市按销售金额排在前三位的商品是什么?

5. 执行 OLAP 查询

        使用 impala-shell 命令行工具执行 olap 库上的查询,回答上一步提出的问题。进入 impala-shell,连接 impalad 所在主机,同步元数据,切换到 olap 库,这些操作使用的命令如下图所示。

(1)每种产品类型以及单个产品的累积销售量和销售额是多少? 

        impala 目前只支持最基本的 group by,尚不支持 rollup、cube、grouping set 等操作,所幸支持 union。

select * from
(
select t2.product_category pro_category,'' pro_name,sum(order_quantity) sum_quantity,sum(order_amount) sum_amount from sales_order_fact t1, product_dim t2where t1.product_sk = t2.product_skgroup by pro_categoryunion all 
select t2.product_category pro_category,t2.product_name pro_name,     sum(order_quantity) sum_quantity,sum(order_amount) sum_amount from sales_order_fact t1, product_dim t2where t1.product_sk = t2.product_skgroup by pro_category, pro_name) torder by pro_category, pro_name;

        查询结果如下图所示。

(2)每种产品类型以及单个产品在每个州以及每个城市的月销售量和销售额趋势是什么?

select * from
(
-- 明细
select t2.product_category pro_category,t2.product_name pro_name,t3.state state,t3.city city,t4.year*100 + t4.month ym,sum(order_quantity) sum_quantity,sum(order_amount) sum_amount from sales_order_fact t1 inner join product_dim t2 on t1.product_sk = t2.product_skinner join customer_zip_code_dim t3 on t1.customer_zip_code_sk = t3.zip_code_skinner join order_date_dim t4 on t1.order_date_sk = t4.date_skgroup by pro_category, pro_name, state, city, ymunion all
-- 按产品分类汇总 
select t2.product_category pro_category,'' pro_name,t3.state state,t3.city city,t4.year*100 + t4.month ym,sum(order_quantity) sum_quantity,sum(order_amount) sum_amount from sales_order_fact t1 inner join product_dim t2 on t1.product_sk = t2.product_skinner join customer_zip_code_dim t3 on t1.customer_zip_code_sk = t3.zip_code_skinner join order_date_dim t4 on t1.order_date_sk = t4.date_skgroup by pro_category, pro_name, state, city, ymunion all
-- 按产品分类、州汇总
select t2.product_category pro_category,'' pro_name,t3.state state,'' city,t4.year*100 + t4.month ym,sum(order_quantity) sum_quantity,sum(order_amount) sum_amount from sales_order_fact t1 inner join product_dim t2 on t1.product_sk = t2.product_skinner join customer_zip_code_dim t3 on t1.customer_zip_code_sk = t3.zip_code_skinner join order_date_dim t4 on t1.order_date_sk = t4.date_skgroup by pro_category, pro_name, state, city, ym) torder by pro_category, pro_name, state, city, ym;

        查询部分结果如下图所示。

(3)每种产品类型销售量和销售额和同比如何?

        这个查询使用了前面进阶技术——周期快照中定义的 month_end_sales_order_fact 表。Impala 支持视图和 left、right、full 外连接。

create view v_product_category_month as
select t2.product_category,t3.year,t3.month,t1.month_order_amount,t1.month_order_quantityfrom month_end_sales_order_fact t1inner join product_dim t2 on t1.product_sk = t2.product_skinner join month_dim t3 on t1.order_month_sk = t3.month_sk;select t1.product_category,t1.year,t1.month,(t1.month_order_quantity - nvl(t2.month_order_quantity,0)) / nvl(t2.month_order_quantity,0) pct_quantity,	   cast((t1.month_order_amount - nvl(t2.month_order_amount,0)) as double) / cast(nvl(t2.month_order_amount,0) as double) pct_amountfrom v_product_category_month t1 left join v_product_category_month t2on t1.product_category = t2.product_categoryand t1.year = t2.year + 1and t1.month = t2.month;

        查询结果如下图所示。由于没有 2015 年的数据,分母是 0,除 0 结果是 Infinity 而不报错。

(4)每个州以及每个城市的客户数量及其消费金额汇总是多少?

select * from 
(
select t3.state state,t3.city city,count(distinct t2.customer_sk) sum_customer_num,sum(order_amount) sum_order_amount from sales_order_fact t1inner join customer_dim t2 on t1.customer_sk = t2.customer_skinner join customer_zip_code_dim t3 on t1.customer_zip_code_sk = t3.zip_code_skgroup by state, cityunion all
select t3.state state,'' city,count(distinct t2.customer_sk) sum_customer_num,sum(order_amount) sum_order_amount from sales_order_fact t1inner join customer_dim t2 on t1.customer_sk = t2.customer_skinner join customer_zip_code_dim t3 on t1.customer_zip_code_sk = t3.zip_code_skgroup by state, city) torder by state, city;

        查询结果如下图所示。

(5)迟到的订单比例是多少?

select sum_total, sum_late, round(sum_late/sum_total,4) late_pctfrom
(
select sum(case when order_date_sk < entry_date_sk then 1 else 0 end) sum_late,count(*)	sum_total
from sales_order_fact) t;

        查询结果如下图所示。

(6)客户年消费金额为“高”、“中”、“低”档的人数及消费金额所占比例是多少?

        这个查询使用了前面进阶技术——分段维度中定义的表。

select year, bn, c_count, sum_band, sum_total, round(sum_band/sum_total,4) band_pct from 
(
select count(a.customer_sk) c_count, sum(annual_order_amount) sum_band,c.year year,  band_name bn  from annual_customer_segment_fact a,  annual_order_segment_dim b,  year_dim c,  annual_sales_order_fact d where a.segment_sk = b.segment_sk  and a.year_sk = c.year_sk  and a.customer_sk = d.customer_sk  and a.year_sk = d.year_skand b.segment_name = 'grid'group by year, bn) t1,
(select sum(annual_order_amount) sum_total from annual_sales_order_fact) t2order by year, bn;

        查询结果如下图所示。

(7)每个城市按销售金额排在前三位的商品是什么?

        此查询使用了 Impala 支持的窗口分析函数 row_number() 取得排名。

select t2.city, t3.product_name, t1.sum_order_amount, t1.rnfrom 
(
select customer_zip_code_sk,product_sk,sum_order_amount,row_number() over (partition by customer_zip_code_sk order by sum_order_amount desc) rnfrom 
(
select customer_zip_code_sk, product_sk, sum(order_amount) sum_order_amountfrom sales_order_fact t1group by customer_zip_code_sk, product_sk) t) t1inner join customer_zip_code_dim t2 on t1.customer_zip_code_sk = t2.zip_code_skinner join product_dim t3 on t1.product_sk = t3.product_skwhere t1.rn <= 3order by t1.customer_zip_code_sk, t1.rn;

        查询结果如下图所示。

        以上几个查询都在 1 秒左右得到结果。虽然测试数据很少,但即便这样的数据量在 Hive 上执行相同的查询也要几分钟时间。Impala 的优势在于查询速度快,然而相对于 Hive 或 SparkSQL,当前的 Impala 仍有诸多不足:不支持 update、delete 操作;不支持 Date 类型;不支持 XML 和 JSON 相关函数;不支持 covar_pop、covar_samp、corr、percentile、 percentile_approx、histogram_numeric、collect_set 等聚合函数;不支持 rollup、cube、grouping set 等操作;不支持数据抽样(Sampling)等等。看来要想日臻完美,Impala 还有很多工作要做。

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

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

相关文章

如何不让android studio自动换行

一、关闭逗号后自动换行设置 打开设置界面 进入 File → Settings &#xff08;Windows/Linux&#xff09;或 Preferences &#xff08;macOS&#xff09;。 导航至 Editor → Code Style → 选择语言&#xff08;如 Java 或 Kotlin &#xff09;。 二、修改换行规则…

Jenkinsfile 报错

Started by user 六件套Obtained Jenkinsfile from git https://gitee.com/duoshuijiao/vitepress-jenkins-cicd-demoorg.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:WorkflowScript: 28: Expected a step line 28, column 66.fingerprint:…

工业一体机全封闭抗干扰赋能自动化产线高效作业

在自动化产线智能设备等工业场景中&#xff0c;工业一体机的应用面临多重挑战&#xff1a;高温、粉尘、电磁干扰等恶劣环境易导致设备误操作&#xff0c;传统工控机平均无故障时间不足4000小时&#xff1b;封闭车间散热效率低下&#xff0c;风扇散热失效风险增加&#xff0c;产…

鸿蒙NEXT开发笔记(二十八)仿抖音快手App的把位图数据转存为图片

上一节我们利用Scroller实现了列表项的自动滚动功能&#xff0c;对于图像列表来说&#xff0c;被选做封面的图像需要保存为图片文件&#xff0c;以便向服务器上传封面图片。 由于avImageGenerator从视频提取的图像帧数据为image.PixelMap&#xff08;位图格式&#xff09;&…

四、搭建springCloudAlibaba2021.1版本分布式微服务-加入openFeign远程调用和sentinel流量控制

OpenFeign远程调用 1、OpenFeign OpenFeign是一种声明式、模板化的HTTP客户端。在Spring Cloud中使用OpenFeign&#xff0c;可以做到使用HTTP请求访问远程服务&#xff0c;就像调用本地方法一样的&#xff0c;开发者完全感知不到这是在调用远程方法&#xff0c;更感知不到在访问…

网络安全威胁——APT攻击_apt攻击预测案例

APT攻击 1. 基本概念2. APT的攻击阶段3. APT的典型案例参考 1. 基本概念 高级持续性威胁&#xff08;APT&#xff0c;Advanced Persistent Threat&#xff09;&#xff0c;又叫高级长期威胁&#xff0c;是一种复杂的、持续的网络攻击&#xff0c;包含高级、长期、威胁三个要…

顺时针旋转N * N 的矩阵

顺时针旋转题目描述数据范围实现逻辑代码实现题目描述 有一个NxN整数矩阵&#xff0c;请编写一个算法&#xff0c;将矩阵顺时针旋转90度。给定一个NxN的矩阵&#xff0c;和矩阵的阶数N,请返回旋转后的NxN矩阵。数据范围 0<n<300&#xff0c;矩阵中的值满足 0≤val≤100…

原生C++实现信号与槽机制:原理详解

信号与槽机制是一种广泛应用于事件驱动系统和GUI框架&#xff08;如Qt&#xff09;的设计模式。它允许组件之间通过订阅-发布模式进行通信&#xff0c;从而实现松耦合的设计。本文将详细讲解如何在原生C中从零开始实现信号与槽机制&#xff0c;并深入探讨其工作原理。一、信号与…

【人工智能】OpenAI的AI代理革命:通向超拟人交互的未来之路

人工智能代理(AI Agent)正引领一场深刻的技术变革,其核心在于赋予AI系统感知、规划、行动和学习的能力,以自主完成复杂任务。OpenAI作为这一领域的先驱,通过其大型语言模型(LLMs)如GPT系列,极大地推动了AI代理的发展,使其在自然语言理解、生成和工具使用方面达到了前所…

Ubuntu虚拟机介绍、命令、安装软件指令(一)

Ubuntu介绍 Ubuntu 是一个基于 Debian 的开源 Linux 操作系统&#xff0c;由 Canonical 公司赞助开发。它是目前全球最流行的 Linux 发行版之一&#xff0c;以其用户友好性、稳定性和强大的社区支持著称。 核心特性 1.免费开源 完全免费使用和分发&#xff0c;遵循 GNU GPL…

企业微信服务商创建第三方应用配置数据回调url和指令回调url的java代码实现

关键区别说明&#xff08;指令回调 vs 数据回调&#xff09;特性指令回调数据回调触发场景授权/取消授权等管理事件通讯录变更、应用菜单点击等业务事件关键字段InfoTypeEvent ChangeType典型事件suite_auth, cancel_authchange_contact, suite_ticket响应要求必须返回加密的&…

LazyLLM教程 | 第2讲:10分钟上手一个最小可用RAG系统

贴心小梗概本文将介绍使用LazyLLM搭建最基础的RAG的流程。首先介绍使用LazyLLM搭建RAG系统的必要环境配置&#xff0c;然后简单回顾RAG的基本流程&#xff0c;接下来分别介绍RAG中文档加载、检索组件、生成组件三个关键部分的参数和基本使用方法&#xff0c;最后利用LazyLLM实现…

android9-PMS-常见问题及分析步骤

以下是基于 Android 9 的 Package Manager Service (PMS) 常见问题及分析步骤&#xff0c;结合系统原理与优化实践整理&#xff1a; &#x1f527; 一、开机性能问题 现象 开机时间随应用增多显著延长&#xff0c;卡在“正在启动应用”阶段。 分析步骤 ① 确认扫描阶段耗时adb…

生成模型实战 | GLOW详解与实现

生成模型实战 | GLOW详解与实现0. 前言1. 归一化流模型1.1 归一化流与变换公式1.2 RealNVP 的通道翻转2. GLOW 架构2.1 ActNorm2.2 可逆 11 卷积2.3 仿射耦合层2.4 多尺度架构3. 使用 PyTorch 实现 GLOW3.1 数据处理3.2 模型构建3.3 模型训练0. 前言 GLOW (Generative Flow) 是…

行业案例:杰和科技为智慧教育构建数字化硬件底座

清晨8点10分&#xff0c;深圳某学生踏入校园&#xff0c;智慧门闸识别身份&#xff0c;并同步发给家长&#xff1b;走廊里的“智慧班牌”向他们展示今日的课表&#xff1b;课堂上&#xff0c;教室前方的多媒体播放器里&#xff0c;老师引导学生学习“居民楼消防隐患”知识&…

Redis与MySQL数据同步:从“双写一致性”到实战方案

Redis与MySQL数据同步&#xff1a;从“双写一致性”到实战方案 在分布式系统中&#xff0c;Redis作为高性能缓存被广泛使用——它能将热点数据从MySQL中“搬运”到内存&#xff0c;大幅降低数据库压力、提升接口响应速度。但随之而来的核心问题是&#xff1a;当MySQL数据更新时…

Java源码构建智能名片小程序

在移动互联网时代&#xff0c;纸质名片的局限性日益凸显——信息更新不便、客户管理困难、营销效果难以追踪。智能电子名片小程序以其便捷、高效、智能的特点&#xff0c;正成为商务人士的"数字营销门户"。而基于Java技术栈开发的智能名片系统&#xff0c;凭借其稳定…

如何在短时间内显著提升3D效果图渲染速度?

在建筑设计、游戏开发、影视制作等行业&#xff0c;3D效果图的渲染速度是项目进度与效率的关键瓶颈。面对复杂场景时&#xff0c;漫长的渲染等待尤为突出。要在保证质量的前提下大幅缩短渲染时间&#xff0c;以下优化策略至关重要&#xff1a; 1. 升级硬件配置&#xff1a;渲染…

配置daemon.json使得 Docker 容器能够使用服务器GPU【验证成功】

&#x1f947; 版权: 本文由【墨理学AI】原创首发、各位读者大大、敬请查阅、感谢三连 文章目录&#x1f50d;你遇到的错误&#xff1a;&#x1f50d; 根本原因✅ 解决方案&#xff1a;正确安装 NVIDIA Container Toolkit✅ 第一步&#xff1a;卸载旧版本&#xff08;如果存在&…

Linux 系统进程管理与计划任务详解

Linux 系统进程管理与计划任务详解 一、程序与进程的基本概念 程序&#xff1a;保存在外部存储介质中的可执行机器代码和数据的静态集合。进程&#xff1a;在CPU及内存中处于动态执行状态的计算机程序。关系&#xff1a;每个程序启动后&#xff0c;可创建一个或多个进程。 二、…