当前位置: 首页 > news >正文

hive-拉链表

目录

  • 拉链表概述
    • 缓慢变化维
    • 拉链表定义
  • 拉链表的实现
    • 常规拉链表
      • 历史数据
      • 每日新增数据
      • 历史数据与新增数据的合并
    • 分区拉链表


拉链表概述

缓慢变化维

通常我们用一张维度表来维护维度信息,比如用户手机号码信息。然而随着时间的变化,某些用户信息会发生改变,这就是所谓的缓慢变化维。需要注意的是,这里的缓慢变化是相对事实表而言的,事实表的变化速度要快得多。

针对缓慢变化维问题,通常有以下几种处理方式:

1)仅保留每个用户最新的一条维度信息

​ 这种方法比较简单粗暴,维度只考虑最新就行,保证了维度值的唯一性。但缺点是无法查看历史信息,在需要回溯查看数据的场景就不适用了,可能需要去原始数据查询,及其不方便。

2)仅保留每个用户最初的一条维度信息

​ 这种就相当于一次填写,终身不允许修改,那么在实际关联数据时,很可能获取的是无效的维度信息。比如某个用户的手机号以及变了,但是维度表中仍然保留最初的手机号,这就导致数据关联结果是错误的。而且对于用户来说,一旦手残录入错误就无法再更改,用户的体验也是不好的。

3)用新增行的方式在维度表中同时保留所有变化的维度信息

​ 这种方式其实跟拉链表很接近了,就是用户每改一次信息,就在维度表中新增一行,只不过这里的历史数据和新增数据如何区分,以及他们的有效时间范围如何区分,就是需要着重考虑的问题了。

4)用新增列的方式在维度表中同时保留所有变化的维度信息

​ 这个方式的优势就是维度表的行数可以不变,只需要新增列,但是缺点也很明显,新增列意味着表结构会一直变化,而且也没有办法确定到底要新增几列。

拉链表定义

拉链表就是记录一个事物从开始到当前状态的变化过程的数据表,主要是用于维度发生变化的场景,也即我们常说的缓慢变化维。

比如说我们用一张维度表记录用户的手机号码,但是随着时间推进,用户可能某一天会换手机号,这时我们的维度表就需要相应的更改,这时我们就可以用拉链表来进行记录,这就实现了保留历史数据的同时,还能查询最新维度信息。可以说拉链表其实是解决缓慢变化维的最佳方案了。

一个简单的拉链表示例如下:

useridtelstart_dtend_dt
011112024010120240601
012222024060299991231
023332024010199991231

每行记录都表示一个用户的属性值以及对应的日期有效范围,如果是最新的数据,则结束日期是99991231。用户01的联系方式发生过变化,因此会有两条数据记录。

拉链表的实现

常规拉链表

历史数据

现在有一批数据如下所示,表示用户的属性值以及传回来的日期和时间戳(单位s):

with data1 as (select '01' as userid, 'ab' as addr, '20220101' as dt, 1641039513 as ts union allselect '01' as userid, 'ab' as addr, '20220103' as dt, 1641211200 as ts union allselect '01' as userid, 'cd' as addr, '20220108' as dt, 1641607200 as ts union allselect '02' as userid, 'ab' as addr, '20220101' as dt, 1641039480 as ts union allselect '02' as userid, 'bc' as addr, '20220104' as dt, 1641261600 as ts union allselect '02' as userid, 'cd' as addr, '20220109' as dt, 1641639600 as ts union allselect '03' as userid, 'ab' as addr, '20220101' as dt, 1641038400 as ts union allselect '03' as userid, 'cd' as addr, '20220101' as dt, 1641002400 as ts union allselect '03' as userid, 'ab' as addr, '20220107' as dt, 1641520800 as ts
)

历史数据的处理规则:

1)同一天仅保留最新一条数据

select userid, addr, dt, ts
from (select userid, addr, dt, tsrow_number() over (partition by userid, dt order by ts desc) rnfrom data1
) ta
where rn = 1;

2)获取每个用户每个属性最早的一条数据

with data2 as (select userid, addr, dt, tsfrom (select userid, addr, dt, ts,row_number() over (partition by userid, dt order by ts desc) rnfrom data1) tawhere rn = 1
)
select userid, addr, dt, ts
from (selectuserid, addr, dt, ts,row_number() over (partition by userid, addr order by dt) rnfrom data2
) tb
where rn = 1;

这样处理以后数据如下所示:
在这里插入图片描述

3)获取当前行的下一行日期数据并处理截止日期

这一步我们需要得到每个用户每个属性的下一行,用来获取当前属性的截止日期。截止日期的处理条件:如果为空则用99991231填充,否则就用next_dt减一天来填充。

上一步的处理结果我们放到data3中,部分代码会做省略处理:

with data3 as (select userid, addr, dt, tsfrom (selectuserid, addr, dt, ts,row_number() over (partition by userid, addr order by dt) rnfrom data2) tbwhere rn = 1
)
selectuserid, addr, dt start_dt,if(next_dt is null, '99991231', date_format(date_add(from_unixtime(unix_timestamp(next_dt, 'yyyyMMdd'), 'yyyy-MM-dd'), -1), 'yyyyMMdd')) end_dt
from (selectuserid, addr, dt, ts,lead(dt) over (partition by userid order by dt) next_dtfrom data3
) tc

得到的结果如下:
在这里插入图片描述

完整的代码如下:

with data1 as (select '01' as userid, 'ab' as addr, '20220101' as dt, 1641039513 as ts union allselect '01' as userid, 'ab' as addr, '20220103' as dt, 1641211200 as ts union allselect '01' as userid, 'cd' as addr, '20220108' as dt, 1641607200 as ts union allselect '02' as userid, 'ab' as addr, '20220101' as dt, 1641039480 as ts union allselect '02' as userid, 'bc' as addr, '20220104' as dt, 1641261600 as ts union allselect '02' as userid, 'cd' as addr, '20220109' as dt, 1641639600 as ts union allselect '03' as userid, 'ab' as addr, '20220101' as dt, 1641038400 as ts union allselect '03' as userid, 'cd' as addr, '20220101' as dt, 1641002400 as ts union allselect '03' as userid, 'ab' as addr, '20220107' as dt, 1641520800 as ts
)
, data2 as (select userid, addr, dt, tsfrom (select userid, addr, dt, ts,row_number() over (partition by userid, dt order by ts desc) rnfrom data1) tawhere rn = 1
)
, data3 as (select userid, addr, dt, tsfrom (selectuserid, addr, dt, ts,row_number() over (partition by userid, addr order by dt) rnfrom data2) tbwhere rn = 1
)
selectuserid, addr, dt start_dt,if(next_dt is null, '99991231', date_format(date_add(from_unixtime(unix_timestamp(next_dt, 'yyyyMMdd'), 'yyyy-MM-dd'), -1), 'yyyyMMdd')) end_dt
from (selectuserid, addr, dt, ts,lead(dt) over (partition by userid order by dt) next_dtfrom data3
) tc

每日新增数据

新增数据如下:

with new_data1 as (select '01' as userid, 'ab' as addr, '20220121' as dt, 1642723200 as ts union allselect '02' as userid, 'cd' as addr, '20220121' as dt, 1642723200 as ts union allselect '04' as userid, 'ef' as addr, '20220121' as dt, 1642723200 as ts union allselect '04' as userid, 'xg' as addr, '20220121' as dt, 1642723300 as ts union allselect '05' as userid, 'xy' as addr, '20220127' as dt, 1642723200 as ts
)

新增数据的处理:

1)保留最新一条数据

新增数据的处理很简单,因为一般是增量读取某一天的数据,因此我们只要保证每个用户只保留最新一条数据即可。

select userid, addr, dt, ts
from (select userid, addr, dt, ts,row_number() over (partition by userid, dt order by ts desc) rnfrom new_data1
) ta
where rn = 1

处理之后结果如下所示,可以看到每个用户只剩下了最新的一条数据:
在这里插入图片描述

2)结束日期均设置为99991231

with new_data2 as (select userid, addr, dt, tsfrom (select userid, addr, dt, ts,row_number() over (partition by userid, dt order by ts desc) rnfrom new_data1) tawhere rn = 1
)
select userid, addr, dt start_dt, '99991231' end_dt
from new_data2;

历史数据与新增数据的合并

1)历史数据与新增数据的全连接

取历史数据的开链数据(结束日期为99991231)与新增数据进行全连接:

select t1.userid old_userid, t1.addr old_addr, t1.start_dt old_start_dt, t1.end_dt old_end_dt,t2.userid new_userid, t2.addr new_addr, t2.start_dt new_start_dt, t2.end_dt new_end_dt
from (select userid, addr, start_dt, end_dtfrom history_datawhere end_dt = '99991231'
) t1
full join new_data t2
on t1.userid = t2.userid
;

全连接的结果如下:
在这里插入图片描述

2)全连接以后的条件处理

a)新旧属性相同或新旧属性不同且旧属性开始日期较大,则仅保留old数据

主要针对两种情况:

一是当新旧属性相同时,仅保留旧属性,这是因为大多数情况下旧属性的日期比较早。不过如果出现重刷数据时,可能新属性的日期早于旧属性,这时应当只保留旧属性。

二是当新旧属性不同,且旧属性的开始日期大于新属性的开始日期时,这也是发生了回刷数据的情况,此时仅保留旧属性。

selectold_userid userid, old_addr addr, old_start_dt start_dt, old_end_dt end_dt
from data_join
where old_addr = new_addr or (old_addr != new_addr and old_start_dt >= new_start_dt);

需要处理的数据是这一条:
在这里插入图片描述

b)新旧属性不同,new不为空时保留new,否则保留old

此时针对的是三种情况:

一是只有old数据则保留old数据;二是只有new数据则保留new数据;三是old与new都不为空且不相同时,仅保留new数据。

selectcoalesce(new_userid, old_userid) userid,coalesce(new_addr, old_addr) addr,coalesce(new_start_dt, old_start_dt) start_dt,coalesce(new_end_dt, old_end_dt) end_dt
from data_join
where old_addr is null or new_addr is null or (old_addr != new_addr and old_start_dt < new_start_dt);

这里处理的数据是这几条:
在这里插入图片描述

c)old与new同时不为空且不相同,保留old数据并对old数据的结束日期做处理

此时这条数据的new部分已经在第二种情形中做了保留,而old数据需要做一个闭链处理,也就是用新增数据的开始日期做填充。

selectold_userid userid,old_addr addr,old_start_dt start_dt,date_format(from_unixtime(unix_timestamp(new_start_dt, 'yyyyMMdd')-24*3600, 'yyyy-MM-dd'), 'yyyyMMdd') end_dt
from data_join
where old_addr != new_addr and old_start_dt < new_start_dt;

这里处理的是这条数据:
在这里插入图片描述

完整的代码如下:

with history_data as (select '01' as userid, 'ab' as addr, '20220101' as start_dt, '20220107' as end_dt union allselect '01' as userid, 'cd' as addr, '20220108' as start_dt, '99991231' as end_dt union allselect '02' as userid, 'ab' as addr, '20220101' as start_dt, '20220103' as end_dt union allselect '02' as userid, 'bc' as addr, '20220104' as start_dt, '20220108' as end_dt union allselect '02' as userid, 'cd' as addr, '20220109' as start_dt, '99991231' as end_dt union allselect '03' as userid, 'ab' as addr, '20220101' as start_dt, '99991231' as end_dt
)
, new_data as (select '01' as userid, 'ab' as addr, '20220121' as start_dt, '99991231' as end_dt union allselect '02' as userid, 'cd' as addr, '20220121' as start_dt, '99991231' as end_dt union allselect '04' as userid, 'xg' as addr, '20220121' as start_dt, '99991231' as end_dt union allselect '05' as userid, 'xy' as addr, '20220121' as start_dt, '99991231' as end_dt
)
, data_join as (select t1.userid old_userid, t1.addr old_addr, t1.start_dt old_start_dt, t1.end_dt old_end_dt,t2.userid new_userid, t2.addr new_addr, t2.start_dt new_start_dt, t2.end_dt new_end_dtfrom (select userid, addr, start_dt, end_dtfrom history_datawhere end_dt = '99991231') t1full join new_data t2on t1.userid = t2.userid
)
selectold_userid userid, old_addr addr, old_start_dt start_dt, old_end_dt end_dt
from data_join
where old_addr = new_addr or (old_addr != new_addr and old_start_dt >= new_start_dt)
union all
selectcoalesce(new_userid, old_userid) userid,coalesce(new_addr, old_addr) addr,coalesce(new_start_dt, old_start_dt) start_dt,coalesce(new_end_dt, old_end_dt) end_dt
from data_join
where old_addr is null or new_addr is null or (old_addr != new_addr and old_start_dt < new_start_dt)
union all
selectold_userid userid,old_addr addr,old_start_dt start_dt,date_format(from_unixtime(unix_timestamp(new_start_dt, 'yyyyMMdd')-24*3600, 'yyyy-MM-dd'), 'yyyyMMdd') end_dt
from data_join
where old_addr != new_addr and old_start_dt < new_start_dt;

最终的结果如下:
在这里插入图片描述

分区拉链表

分区拉链表其实只要将end_dt当作分区日期即可,这样每次取历史数据的开链数据与新增数据计算,得到的数据中包含了一部分99991231分区数据,一部分是新增日期分区(通常是该日期前一天)数据。之后采用动态分区写入的方式,覆盖写指定分区即可。

分区拉链表的优势:

  • 写入时只需要按分区写入,不需要全表覆盖写,当数据表的体量较大时,优势比较大;

相关文章:

hive-拉链表

目录 拉链表概述缓慢变化维拉链表定义 拉链表的实现常规拉链表历史数据每日新增数据历史数据与新增数据的合并 分区拉链表 拉链表概述 缓慢变化维 通常我们用一张维度表来维护维度信息&#xff0c;比如用户手机号码信息。然而随着时间的变化&#xff0c;某些用户信息会发生改…...

高并发内存池(六):补充内容

目录 有关大于256KB内存的申请和释放处理方法 处理大于256KB的内存申请 补充内容1 补充内容2 补充内容3 处理大于256KB的内存释放 新增内容1 新增内容2 测试函数 使用定长内存池替代new 释放对象时不传对象大小 补充内容1 补充内容2 补充内容3 补充内容4 测试…...

高性能存储 SIG 月度动态:优化 fuse 提升 AI 存储接入能力,erofs 工具发布新版本

本次月报综合了 SIG 在 7、8 两个月的工作进展&#xff0c;包含多项新特性、优化、Bugfix 等。 SIG 整体进展 fuse 支持 failover&#xff0c;并优化 background 读写公平性&#xff0c;提升 AI 存储接入场景的能力。 erofs page cache 共享特性已发到上游社区&#xff0c;re…...

2024 年最新 Protobuf 结构化数据序列化和反序列化详细教程

Protobuf 序列化概述 Protobuf&#xff08;Protocol Buffers&#xff09;是由Google开发的一种语言中立、平台中立、可扩展的序列化结构数据的方法。它用于在不同系统之间高效地交换数据。Protobuf使用定义文件&#xff08;.proto&#xff09;来描述数据结构&#xff0c;并通过…...

【小程序】微信小程序课程 -4 项目实战

目录 1、 效果图 2、创建项目 2.1 创建小程序端 2.1.1 先创建纯净项目 2.1.2 删除components 2.1.4 删除app.json红色部分 2.1.5 删除index.json红色部分 2.1.6 删除index.wxss全部内容 2.1.7 删除index.wxml全部内容 2.1.8 app.json创建4个页面 2.1.9 app.json添加…...

【期刊】论文索引库-SCI\SSCI\IE\南大核心\北大核心\CSCD等

外文期刊检索 SCI SCI即《科学引文索引》(Science Citation Index),是由美国科学信息研究所(Institute for Scientific Information)创建于1961年,收录文献的作者、题目、源期刊、摘要、关键词,不仅可以从文献引证的角度评估文章的学术价值,还可以迅速方便地组建研究课…...

开源链动 2+1 模式 S2B2C 商城小程序:社交电商团队为王的新引擎

摘要&#xff1a;本文深入探讨在社交电商领域中&#xff0c;团队的重要性以及如何借助开源链动 21 模式 S2B2C 商城小程序&#xff0c;打造具有强大竞争力的团队&#xff0c;实现个人价值与影响力的放大&#xff0c;创造被动收入&#xff0c;迈向财富自由之路&#xff0c;同时为…...

使用Fiddler Classic抓包工具批量下载音频资料

1. 通过F12开发者工具&#xff0c;下载音频文件 浏览器打开音频列表->F12快捷键->网络->媒体&#xff0c;播放一个音频文件&#xff0c;右边媒体下生成一个音频文件&#xff0c;右击“在新标签页中打开”&#xff0c;可以下载这个音频文件。 2.通过Fiddler Classic抓…...

QT开发:基于Qt实现的交通信号灯模拟器:实现一个带有倒计时功能的图形界面应用

介绍 本文将介绍如何使用Qt框架实现一个简单的交通信号灯控制程序。本程序包括一个图形界面&#xff0c;显示红、黄、绿三色信号灯&#xff0c;并通过定时器控制信号灯的切换。同时&#xff0c;我们还将实现一个带有按钮的界面&#xff0c;用于展示信号灯的状态。 1. 安装Qt开…...

【编程基础知识】网络I/O模型详解:从阻塞到异步

引言 网络I/O模型是网络编程的核心&#xff0c;它们决定了应用程序如何进行读写操作以与网络进行数据交换。了解不同的网络I/O模型对于设计高效、可扩展的网络应用程序至关重要。 一、阻塞I/O&#xff08;Blocking I/O&#xff09; 1. 定义 阻塞调用&#xff1a;当应用程序…...

yolo自动化项目实例解析(六)自建UI(主窗口、预览窗口)

前面我们大致把各个代码块梳理出来了&#xff0c;但是还是不知道从那块开始&#xff0c;我们这里主要先通过ui页面的元素去推理整个执行过程&#xff0c;我们首先需要知道ui功能里面有那些组件 qt设计师基础控件 Qt Designer 是一个图形界面设计工具&#xff0c;用于创建 Qt 应…...

Unity优质教程分类汇总 【持续更新中】

以下收录的均为作者自己看过的觉得比较好的教程 基础 Unity入门&#xff1a; https://www.bilibili.com/video/BV1HX4y1V71E?p13 生命周期 https://docs.unity.cn/cn/2022.3/uploads/Main/monobehaviour_flowchart.svg https://zhuanlan.zhihu.com/p/551294000 编程技巧…...

真正掌握left join on 和 where 的差别

总结 用 where 是先连接然后再筛选用 on 是先筛选再连接数据库在通过连接两张或多张表来返回记录时&#xff0c;都会生成一张中间的临时表&#xff0c;然后再将这张临时表返回给用户。在使用left jion时&#xff0c;on和where条件的区别如下&#xff1a; on条件是在生成临时表…...

神经网络在多分类问题中的应用

作者简介:热爱数据分析,学习Python、Stata、SPSS等统计语言的小高同学~个人主页:小高要坚强的博客当前专栏:Python之机器学习本文内容:神经网络在多分类问题中的应用作者“三要”格言:要坚强、要努力、要学习 目录 1. 引言 2.数据构造 3.划分数据集 4.神经网络实现多…...

nginx的安装和使用

源码安装 1.环境准备&#xff1a;卸载其他方式安装的web应用&#xff0c;防止端口冲突 2.下载nginx源码包 wget https://nginx.org/download/nginx-1.20.2.tar.gz 3.源码编译安装 yum install -y gcc pcre-devel zlib-devel #安装依赖包 useradd -M -s /sbin/nologin ngi…...

js采用覆盖键、覆盖鼠标滑动事件实现禁止网页通过 ctrl + +/- 和 ctrl + 滚轮 对页面进行缩放

一、兼容电脑端的禁止通过 ctrl /- 和 ctrl 滚轮 对页面进行缩放 const keyCodeMap {// 91: true, // command61: true,107: true, // 数字键盘 109: true, // 数字键盘 -173: true, // 火狐 - 号187: true, // 189: true, // -};二、覆盖ctrl||command ‘’/‘-’ // 覆…...

某客户Oracle RAC无法启动故障快速解决

某日&#xff0c;9:50左右接到好友协助需求&#xff0c;某个客户Oracle RAC无法启动&#xff0c;并发过来一个报错截图&#xff0c;如下&#xff1a; 和客户维护人员对接后&#xff0c;远程登录服务端进行故障分析。 查看hosts信息&#xff0c;首先进行心跳测试&#xff0c;测…...

【计算机网络 - 基础问题】每日 3 题(二十八)

✍个人博客&#xff1a;Pandaconda-CSDN博客 &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/fYaBd &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞&#x1f44d;收藏&…...

探索甘肃非遗:Spring Boot网站开发案例

1 绪论 1.1 研究背景 当前社会各行业领域竞争压力非常大&#xff0c;随着当前时代的信息化&#xff0c;科学化发展&#xff0c;让社会各行业领域都争相使用新的信息技术&#xff0c;对行业内的各种相关数据进行科学化&#xff0c;规范化管理。这样的大环境让那些止步不前&#…...

产品管理- 互联网产品(6):产品测试

可用性测试 招募有代表性用户作为测试代表参与者&#xff0c;评估某产品符合特定可用性及符合程度。以具有代表性的用户为测试样本。 测试中多关注用户表情与动作。多鼓励与测试的用户更多的操作以用户角度发现问题。同时要做好询问工作&#xff0c;耐心聆听用户的意见&#x…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

反向工程与模型迁移:打造未来商品详情API的可持续创新体系

在电商行业蓬勃发展的当下&#xff0c;商品详情API作为连接电商平台与开发者、商家及用户的关键纽带&#xff0c;其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息&#xff08;如名称、价格、库存等&#xff09;的获取与展示&#xff0c;已难以满足市场对个性化、智能…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命

在华东塑料包装行业面临限塑令深度调整的背景下&#xff0c;江苏艾立泰以一场跨国资源接力的创新实践&#xff0c;重新定义了绿色供应链的边界。 跨国回收网络&#xff1a;废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点&#xff0c;将海外废弃包装箱通过标准…...

Java 加密常用的各种算法及其选择

在数字化时代&#xff0c;数据安全至关重要&#xff0c;Java 作为广泛应用的编程语言&#xff0c;提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景&#xff0c;有助于开发者在不同的业务需求中做出正确的选择。​ 一、对称加密算法…...

SpringCloudGateway 自定义局部过滤器

场景&#xff1a; 将所有请求转化为同一路径请求&#xff08;方便穿网配置&#xff09;在请求头内标识原来路径&#xff0c;然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕&#xff0c;#AI 监考一度冲上热搜。当AI深度融入高考&#xff0c;#时间同步 不再是辅助功能&#xff0c;而是决定AI监考系统成败的“生命线”。 AI亮相2025高考&#xff0c;40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕&#xff0c;江西、…...

C++:多态机制详解

目录 一. 多态的概念 1.静态多态&#xff08;编译时多态&#xff09; 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1&#xff09;.协变 2&#xff09;.析构函数的重写 5.override 和 final关键字 1&#…...

Windows安装Miniconda

一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...