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

《Hadoop大数据技术与实践》+ 数仓版本

基础概念

随着数字化时代的到来,数据量的爆炸性增长使得传统的数据处理和分析方法变得不够高效,因此大数据技术应运而生。

数据分类

  1. 结构化数据:固定格式的SQL数据库等
  2. 半结构化数据:json
  3. 非结构化数据:图片、音视频

为什么会有大数据?
大数据场景下,结构化数据单机处理速度慢,扩展麻烦;非结构化和半结构化数据里NoSQL数据库只负责存储;程序处理时涉及到数据移动,速度慢。

大数据的特征 – (个人总结也就是4V特性)

  • 数据规模巨大(Volume)
  • 生成和处理速度极快(Velocity)
  • 数据类型多样(Variety)
  • 价值巨大但密度较低(Value)

大数据思路

大数据技术提供的思路是分而治之移动计算而非移动数据。(个人的科研项目里也应用到了这个特性)

  • 分而治之
    在HDFS中,分而治之的思想体现在数据的分布式存储和备份机制上。
    HDFS将大规模数据分成多个数据块,并将这些数据块分布存储在集群的不同节点上,同时通过复制机 制实现数据的备份,保证数据的可靠性和容错性。这样一来,即使集群中的某个节点发生故障,数据也能够通过备份副本进行恢复,不会造成数据的丢失或损坏。
  • 移动计算而非移动数据
    在YARN中实现的移动计算而非移动数据,则体现在将计算任务调度到数据所在的节点上进行处理。YARN是Hadoop的资源管理和作业调度系统,它负责管理集群中的计算资源,并为作业分配合适的资源。通过YARN,计算任务可以在数据所在的节点上运行,而不需要将数据传输到计算节点,从而避免了数据移动的开销和网络带宽的限制。这种移动计算而非移动数据的方式能够充分利用集群中的计算资源,提高数据处理的效率和性能,同时减少了数据传输可能带来的安全风险和延迟问题。

离线与实时场景

  1. 离线处理场景:数据在任意时刻是在同一个阶段,数据仓库、 搜索与检索
  2. 实时处理场景:数据可能会同时存在不同阶段,一边生成一边分析,比如监控数据,实时流处理

大数据发展时间线

  • 2003 Google发表了Google File System论文
  • 2004 Google发表了MapReduce论文
  • 2006 第一个Apache Hadoop版本发布
  • 2006 Google发表了Bigtable论文
    google大数据的三驾马车齐了(GG好牛🐂),后面就有了HBase、Hive、ZooKeeper、YARN、Spark…

生态架构

在这里插入图片描述

数据部分 – > HDFS数据存储 – > Yarn资源管理 – > MapReduce / Spark 通用计算 – > Hive数据分析
对于结构化数据,一般使用sqoop组件通过JDBC方式连接到数据库,抽取到大数据存储平台(主流是HDFS);对于半结构化和非结构化数据,一般用Flume进行实时监控,一旦数据产生,一般要先放到一个消息队列里面进行缓冲,起到一个抗压作用,这个消息队列我们常用的就是kafka,然后用处理平台进行处理,得到最终结果后再放到HDFS存储平台里。
由于HDFS本质上是一个文件系统,不好用,我们一般都是把数据存到数据库里而不是文件系统里,所以就有了HBase。所以数据可以存在HDFS里也可以存在Hbase里,根据应用场景来选择。
那数据存起来之后就要计算使用了,计算组件就是MapReduce和Spark,但是这里有个前提,要把任务分发到计算节点上去计算,那谁来做这个移动分发的操作,早期是MapReduce来承担,但是因为效率原因,后面就有了分布式资源调度框架YARN,YARN在部署的时候是和我们的存储系统在一起的,比如说现在我们有3台存储节点,那就会在这三台节点上分别部署一个YARN,用来管理当前节点的计算资源(CPU内存等),Spark的计算任务就由YARN在存储节点上来分配计算资源,任务结束后再由YARN进行资源回收。
那么现在呢,我们虽然计算有了MapReduce有了Spark,但是易用性还是差点意思,为什么呢,因为我们在开发的时候,对于结构化数据我们一般都是用sql,半结构化和非结构化数据我们一般是用API。然后现在我们把数据抽取到了大数据平台,那这些SQL、API就都不能用了,只能用提供的MapReduce和Spark来数据处理,那之前业务系统里的SQL和API是不是还要进行迁移,那这个工作量就比较大了。所以为了让我们开发的过程易用性更好,这就又来了一些框架比如Hive,就是帮我们把SQL转换为通用计算的MapReduce和Spark,这样之前用SQL的现在依然可以用。
那除了这些之外一般还要有一个分布式协调服务,用的ZooKeeper比较多,,因为大数据的产品一般都是分布式架构的,如果有节点新增或者挂掉,ZooKeeper就能自动识别到。

HDFS

HDFS是Hadoop的分布式文件系统,用于存储大规模数据集。它具有高容错性、高可靠性和高可扩展性的特点,通过将数据分割成多个块并在集群中多个节点上存储多个副本来实现这些特点。HDFS的设计旨在适应常见的硬件故障,并提供了对大文件的 高吞吐量访问。

HDFS优缺点

1. 优点
海量数据存储(典型文件大小GB~TB,百万以上文件数量, PB以上数据规模)
高容错(多副本策略)、高可用(HA,安全模式)、高扩展(10K节点规模)
构建成本低、安全可靠(构建在廉价商用机器上,提供容错机制)
适合大规模离线批处理(流式数据访问,数据位置暴露给计算框架)
2. 缺点
不适合低延迟数据访问
不适合大量小文件存储(元数据占用NameNode大量空间,移动计算时任务数量增加)
不支持并发写入
不支持文件随机修改(仅支持追加写入)

HDFS写、读过程

在这里插入图片描述
在这里插入图片描述

HDFS 使用语法 (个人感觉和linux差不多,只是加个前缀的事)

HDFS操作语法大部分用法和Linux Shell类似,可通过help查看帮助

hadoop fs 语法最终会转换为 hdfs dfs
hadoop fs -help
hadoop fs -get /user/hadoop/file localfile 拷贝文件到本地系统
hadoop fs -cp、hadoop fs -mv 

HDFS控制台运维

HDFS提供了Web管理界面,可以很方便地查看HDFS相关信息。在浏览器地址栏中输入http://node01:50070
Overview、Datanodes、Utilities工具中有Browse the fifile system可以直观查看HDFS文件。

YARN

YARN是Hadoop的资源管理器,负责管理和分配集群中的资源,以供不同类型的应用程序使用。它通过资源管理和作业调度,为Hadoop集群中的应用程序提供资源,它可以对提交到集群中的任务进行查看,并可以强制结束这些任务。YARN的出现使得Hadoop集群能够运行不仅限于MapReduce的各种计算框架和应用程序,如Apache Spark、Apache Flink等。

为什么MapReduce不适合资源管理

最初的资源管理是由MapReduce做的,身兼计算框架 + 资源管理框架。

  • 任务太重,开销过大
  • 存在单点故障
  • 资源描述模型过于简单,资源利用率较低
  • 仅把Task数量看作资源,没有考虑CPU和内存

YARN 资源调度策略

  1. FIFO先进先出调度器
    核心思想:将所有任务放入一个队列,先进队列的先获得资源,排在后面的任务只有等待 。
    缺点:资源利用率低,无法交叉运行任务 ;灵活性差,如:紧急任务无法插队,耗时长的任务拖慢耗时短的任务
  2. 容量调度器
    核心思想:提前做预算,在预算指导下分享集群资源
    调度策略
  • 集群资源由多个队列分享
  • 每个队列都要预设资源分配的比例(提前做预算)
  • 空闲资源优先分配给“实际资源/预算资源”比值最低的队列
  • 队列内部采用FIFO调度策略
  1. 公平调度器
    调度策略
  • 多队列公平共享集群资源
  • 通过平分的方式,动态分配资源,无需预先设定资源分配比例
  • 队列内部可配置调度策略:FIFO、Fair(默认)
  • 终止其他队列的任务,使其让出所占资源,然后将资源分配给占用资源量少于最小资源量限制的队列
  • 当队列中有任务等待,并且集群中有空闲资源时,每个队列可以根据权重获得不同比例的空闲资源

YARN命令

yarn application -list
yarn application -kill <ApplicationId>
yarn application -status <ApplicationId>

CTRL + C不能终止任务,只是停止其在控制台的信息输出,任务仍在集群中运行
正确方法:先使用yarn application -list获取进程号,再使用-kill终止任务
基本配置文件:yarn-site.xml YARN局部配置
监控:访问资源管理的8088端口,进入监控页面,可以查看所有提交到Yarn集群的任务情况

YARN控制台运维

一般提交到集群中的任务,我们会使用浏览器访问Resource Manager的8088端口,进入监控页面,http://192.168.31.41:8088,来查看任务运行的具体情况。
菜单栏Applications,可以查看集群中的所有任务。
访问Scheduler界面(左侧菜单栏最后一列),可以查看集群调度策略和队列使用情况

MapReduce

MapReduce是Hadoop最早的分布式计算框架,用于并行处理大规模数据集。它由两个主要阶段组成:Map阶段和Reduce阶段。在Map阶段,数据被分割成多个片段并在各个节点上进行并行处理;在Reduce阶段,将Map阶段输出的中间结果合并和汇总,生成最终的输出结果。
MapReduce 框架只对 <key, value> 形式的键值对进行处理。MapReduce会将任务的输入当成一组<key, value> 键值对,最后也会生成一组 <key, value> 键值对作为结果。常见的输入为文件,此时读取的行偏移量会作为Key,文件内容作为Value。
key 和 value 的类必须由框架来完成序列化,所以需要实现其中的可写接口(Writable)。MapReduce任务由Map和Reduce两个过程,所以需要分别进行编写。Map的实现需要继承Mapper 类,实现map方法完成数据处理;Reduce则要继承Reduer类,实现reduce方法完成数据聚合。

Spark

大规模分布式通用计算引擎。3.5.1版本的Spark与Hadoop 3.X版本兼容
MapReduce局限性

  • 执行效率不高,发布时间早,当时内存硬件昂贵,里面大量与磁盘交互(而Spark是基于内存的)。
  • 功能太单一,MapReduce主要用于大规模的离线处理的场景,对于一些计算需要结合其他的框架比如要做交互式计算就需要再装一个Hive组件,用Hive把sql转换为mapreduce
    那spark也是一整套解决方案,底层是spark core,这个就是对标mapreduce的,但是比mapreduce的执行速度快很多,它在官网上给的实验结果是比mapreduce快100倍。上层有spark sql接口,帮我们把sql转换为底层的spark core,还有spark streaming接口做实时流处理的,spark MLlib:机器学习库,提供常见的机器学习算法。
    在Apache Spark中,弹性分布式数据集(RDD)是最基本的数据抽象,它代表了一个不可变的、分布式的数据集合,可以并行操作。RDD的创建是Spark数据处理的第一步。

数据仓库

数据仓库诞生背景

数仓诞生的原因主要有两个:历史数据堆积、企业数据分析需要。
随着业务的进行,线上的业务系统会源源不断的产生数据,这些数据都会保存在数据库里比如oracle、mysql等等,当积压的数据越来越多,那就会对我们的数据库产生负载,又影响到了我们的业务系统。那这些堆积的数据里面,有相当一部分都是冷数据,这部分数据调用的频率其实已经很低了,所以我们一般会定期把这些冷数据从我们的业务数据库里面转移出去,存到一个专门用来存储历史数据的仓库里面,这个仓库就是数据仓库。所以之后业务数据库里的高频数据就用来支持我们线上业务的正常运行,用到历史数据的时候再去我们的数据仓库里操作。
没有建立数仓之前,我们要分析数据就要直接去业务数据库抽取数据,然后分析运算最后汇聚成报表的形式,但这样其实有点问题,比如两个不同的部门都来抽取数据,一个早上抽的一个下午抽的,虽然是同一天但是因为抽取数据的时间不一致,所以有可能结果是不同的。而且每个部门都来操作数据库,那这个数据库权限管理也是有风险的。所以说用数据仓库就是为各个部门建立了一个统一的数据视图。

数据仓库特点

核心理念就是为数据分析提供服务,数据分析一般都是有一个明确的主题,比如数据库里的表是用户表、商品表、订单表等等,那我们现在要分析这个用户购买商品的行为,就需要把这些零散的表做一个聚合,聚合成一个用户行为表大宽表,然后再做具体的分析任务。
然后有的数据是不同数据源的,比如男女字段在A数据源是01表示,在B数据源是xy表示,那我们在做分析之前也需要一个清洗转换的过程。
非易失:历史数据不允许修改只允许查询分析,定期接收新数据反应出数据的变化趋势。

数据仓库 VS 数据库

  • 数据库面向事务设计,属于OLTP(在线事务处理)系统,主要操作是随机读写;在设计时尽量避免冗余,常采用符合范式规范来设计
  • 数据仓库是面向主题设计的,属于OLAP(在线分析处理)系统,主要操作是批量读写;关注数据整合,以及分析、处理性能;会有意引入冗余,采用反范式方式设计。
    在这里插入图片描述

传统数仓 VS 大数据数仓

  1. 传统数仓
    MPP架构优先考虑的是C(一致性),其次才是A(可用性)
    传统数仓是由单机数据库发展而来的,单机不能满足数据量大的问题,那就把大量的单机数据库组成集群,每个节点负责一部分数据的数据存储和运算任务,这也就是MPP架构,这是传统的数仓,传统数仓在数据量没有达到一定量级的时候是比较好的解决方案,但随着互联网的发展数据的规模越来越庞大,它的两个问题就暴露出来了,一个是扩展性问题,一个是热点问题。
    因为它里面的每个节点实际上都是独立的数据库,都有自己的软硬件管理,需要节点间进行数据通信然后聚合的时候就需要网络进行传输,所以不可能无限制扩展,有上限要求。
    一个大表有100W行数据,拆成10份给10台节点存储每台10W行,如果正好第一个10W行数据就是热点数据,都分给了第一台节点,那第一台节点后面就有可能承受不了那么高的负载,成为整个数据仓库的瓶颈短板,可用性也就越低。(加盐可以解决,就是加前缀再随机)
  2. 大数据数仓
    分布式架构,优先考虑的是P(分区容错性)和A(可用性)
    另一种数仓实现方案就是大数据数仓。
    大数据数仓是以大数据为基础的数据仓库,利用大数据的分布式存储和分布式计算来形成的一种架构,所以相比于传统数仓有更好的扩展性。
    第二个优点是解决了传统数仓的热点问题,因为大数据底层存储的时候为了保证数据的高可靠是要进行冗余副本存储的,那后面计算任务过来之后要拿的数据是可选的,可以选择一个相对较为空闲的节点来执行任务。
    它在诞生初期有个问题就是易用性差一些,因为,它有自己的计算引擎也就是有自己特定的语法,而企业里数据库存的数据大部分都是结构化数据,一般用SQL进行处理。所以如果要用大数据平台就必须要做大量的业务迁移工作,把SQL转换成大数据的处理语法,所以后面就出现了一些分布式SQL引擎来帮助我们完成从SQL到大数据语法的一个转换。
    事务对于数仓来说没有那么重要,因为数仓最主要的工作就是数据分析
    大数据不适合数据量较小的场景,因为它是完全分布式的,在计算任务运行的时候会进行任务拆分然后调度到各个节点,执行结束后再对结果进行汇总合并,整个过程比较粗犷,所以如果数据量没有达到一定的量级,只这些任务的分发调度汇总都会花费很多时间。只有数据量超过某个量级,那大数据的优势就体现出来了,这个时候整个集群都在高吞吐的工作,调度的时间可能会远远小于计算时间。所以在数据量没有那么大的时候还是不能够盲目的追求数仓
    传统数仓的技术比较成熟,易用性更优秀,大数据,数仓它整体的技术比较新,落地也需要一定的过渡,因为我们主要的数据仓库理论还是集中在传统数仓这里

数仓架构

在这里插入图片描述

  1. ETL 数据同步层
    Extract-Transform-Load
    我们把数据从业务数据库里进行抽取,然后做一些清洗标准化的工作,最终加载到目的地的一个过程。常用的工具有Sqoop、Kattle等等。
  • 数据抽取:抽取的数据源可以分为结构化数据、非结构化数据、半结构化数据,结构化数据一般采用JDBC、数据库日志方式,非结构化和半结构化数据会监听文件变动,然后以全量或者增量的方式进行同步。
  • 数据转换:数据转换要经历数据清洗和转换两个阶段。数据清洗主要是对出现的重复、二义性、不完整、违反业务或逻辑规则等问题的数据进行统一的处理,数据转换主要是对数据进行标准化处理,进行字段、数据类型、数据定义的转换。
  • 数据加载:将最后处理完的数据导入到对应的目标源里
    ETL 规则的设计和实施约占整个数据仓库搭建工作量的 60%~80%
  1. ODS 操作数据源层
    我们在ETL层抽取清洗过的数据会存到ODS层,这一层数据与原业务数据保持一致,还是原始数据,可以增加字段用来进行数据管理,比如一条记录过来了我们加上时间戳和来源字段表示是从哪儿什么时候存进来的,主要提供给业务系统查询使用。
  2. CDM 公共维度模型层
    这一层主要是为数据分析提供服务的,这一层细分为两个子层:一个是DWD数据明细层,另一个是DWS数据汇总层。
    数据明细层会对ODS层的数据进行清洗、标准化、维度退化(时间、分类、地域),因为ODS层存储的数据是和源数据一致的,那存储的各个系统过来的数据就有可能格式不统一,那就要统一格式,把异常数据剔除掉,然后做统一的处理,然后把数据存储到数据明细层,也就是做了统一规范的操作。
    数据仍然满足三范式3NF模型
    数据汇总层:做了统一规范之后,我们要向上层提供数据查询,那就需要按照特定主题进行计算汇总,就比如现在有用户表、商品表、订单表等等,那这些表都是零散的表,现在上层业务需要查询这个用户的行为,如果我们用这些零散的表进行业务分析效率可能就会比较低,所以我们就要按照这个行为主题把这些明细表进行汇总计算,然后得到一个便于分析的宽表。那这部分工作就是DWS数据汇总层做的。
    存储模型已经脱离三范式3NF,而是注重数据聚合,复杂查询、处理性能更优的数仓模型,如维度模型
  3. ADS数据应用层
    数据应用层也被称为数据集市,主要用来存储数据分析的结果,为不同业务场景提供接口,减轻数据仓库的负担。数据仓库擅长数据分析,直接开放业务查询接口,会加重其负担。

OLTP 和OLAP

OLTP 在线事务处理

我们的业务系统都是这种模型,主要是为我们的业务系统提供数据存储和数据操作,这些操作大多是随机读写,为了保证数据一致性、减少冗余,常使用关系模型(E-R)。

OLAP 在线分析处理

这种模型我们从名字上也能看出来,面向的主要场景就是查询分析,主要操作是复杂分析查询;关注数据整合,以及分析、处理性能。
OLAP系统分类:根据数据存储的方式不同,又分为ROLAP关系型、MOLAP多维型、HOLAP前两者的混合。
ROLAP系统典型的数仓建模方法有ER模型、**维度模型(最流行)**等。
维度模型
这个维度什么意思呢,举个例子我们打开京东搜索手机,里面出现许多款,这每款手机都是存在数据库里的一个表里称为事实表,里面有围绕这款手机所展开的一些参数。然后在页面最上方会有按照品牌分类、CPU型号分类、功能分类等等,那这些分类每个就分别是一个维度。再比如我们用SQL查询数据的时候有时候会带上时间限制,比如12月1号-12月10号之间,那这就又是一个维度。所以维度模型里的表被分为事实表和维度表,有了维度表之后我们就可以对数据进行多维的分析,比较灵活,适应互联网行业的灵活性。
维度模型里又可以细分为星型模型、雪花模型(个人感觉用的最多)、星座模型。

  • 星型模型:维度只有一层,分析性能最优。比如:售卖维度表里有商品、出售地点、时间等分别对应一个事实表。
  • 雪花模型:多层维度,接近三范式,比较灵活。比如刚才的售卖维度表里的商品表里的供应字段,又对应一个供应商事实表。
  • 星座模型:基于多个事实表,事实表之间会共享一些维度表,是大型数据仓库中的常态,是业务增长的结果,与模型设计无关。
    宽表模型(用的更多):宽表模型是维度模型的衍生,因为维度模型把数据拆分成了事实表和维度表,那后面在进行分析计算的时候就需要用join消耗太大,所以就把维度冗余到事实表中,形成宽表,以此减少join操作。

数仓样例

在这里插入图片描述

前期工作

生成数据:用户表、订单表、订单详情表、商品表、3个商品明细表(一级二级三级分类)、流水表

ETL抽取

sqoop连接到数据库之后,使用sql对数据进行查询抽取
用sqoop对结构化数据进行抽取,编写抽取脚本,然后用sqoop进行调用。
sqoop脚本:
传两个参数,$1抽取的表名,$2抽取的特定日期
连接数据库、 定义抽取出来后的数据以分隔符作为隔开,指定存储的目标目录(HDFS)
并发数量,查询的sql

然后执行脚本,会提交为mapreduce作业交由yarn生成一个yarn application去运行,可以浏览器进8088端口看yarn里应用的状态,运行完成之后可以50070端口看执行完毕后保存到 HDFS里的文件
ODS层数据接入
现在抽取出来的数据已经存到HDFS中了,接下来就需要把数据导入到ODS里。
这里分为两步,第一步先在Hive里创建ODS所有的表结构,第二步用脚本把数据导入到ODS里。
编写建表sql:和业务数据库建表语句类似,指定数据划分的依据,用hive语法进行执行sql,然后完成数据导入

DWD & DWS 层数据接入

DWD层
对ODS层数据进行清洗和维度退化,三张维度表可以进行维度退化,把三张商品明细表合并到商品表里,相当于是在商品表里加六个字段,也就是每个商品分类表的分类id和分类的名称。
DWS层
将具有相同分析主题的DWD层数据,聚合成宽表模型,便于数据分析与计算。
比如把经过DWD数据清洗和维度退化的几张表聚合成一张用户购买商品宽表,从用户表抽出用户id、从商品表抽出商品id、从订单表抽出购买的次数和下单金额等等。

ADS数据接入

在这里插入图片描述

先用sql进行统计,然后创建复购率数据表,编写sqoop导出脚本,完成数据导入操作
Azkaban自动化调度

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 使用免费图书馆条形码扫描仪快速扫描书籍
  • HarmonyOS应用开发者高级认证(一)
  • AI学习记录 - 自注意力机制中掩码的注意事项
  • 在亚马逊云科技上安全、合规地创建AI大模型训练基础设施并开发AI应用服务
  • 传输层安全性 ——TLS(Transport Layer Security)简介
  • Web Image scr图片从后端API获取基本实现
  • 【源码+论文】基于SpringBoot的网上订餐系统
  • ThinkPHP5漏洞分析之文件包含
  • UE开发中的设计模式(三) —— 对象池模式
  • duilib 之 窗口枚举显示实例 一
  • 高阶数据结构(Java):AVL树插入机制的探索
  • spring boot-18
  • 前端工程化16-什么是节流防抖
  • C#进阶-ASP.NET实现可以缩放和旋转的图片预览页
  • 《Linux运维总结:基于x86_64架构CPU使用docker-compose一键离线部署etcd 3.5.15容器版分布式集群》
  • 【技术性】Search知识
  • C学习-枚举(九)
  • github指令
  • JavaScript服务器推送技术之 WebSocket
  • JAVA并发编程--1.基础概念
  • Laravel5.4 Queues队列学习
  • LeetCode541. Reverse String II -- 按步长反转字符串
  • nodejs实现webservice问题总结
  • 表单中readonly的input等标签,禁止光标进入(focus)的几种方式
  • 看图轻松理解数据结构与算法系列(基于数组的栈)
  • 前端存储 - localStorage
  • 山寨一个 Promise
  • 使用API自动生成工具优化前端工作流
  • 使用阿里云发布分布式网站,开发时候应该注意什么?
  • 因为阿里,他们成了“杭漂”
  • Mac 上flink的安装与启动
  • mysql面试题分组并合并列
  • ​HTTP与HTTPS:网络通信的安全卫士
  • ​io --- 处理流的核心工具​
  • # 再次尝试 连接失败_无线WiFi无法连接到网络怎么办【解决方法】
  • #1014 : Trie树
  • #宝哥教你#查看jquery绑定的事件函数
  • #我与虚拟机的故事#连载20:周志明虚拟机第 3 版:到底值不值得买?
  • (1)svelte 教程:hello world
  • (26)4.7 字符函数和字符串函数
  • (9)目标检测_SSD的原理
  • (创新)基于VMD-CNN-BiLSTM的电力负荷预测—代码+数据
  • (附源码)springboot 房产中介系统 毕业设计 312341
  • (附源码)ssm高校志愿者服务系统 毕业设计 011648
  • (附源码)ssm旅游企业财务管理系统 毕业设计 102100
  • (九十四)函数和二维数组
  • (已解决)vue+element-ui实现个人中心,仿照原神
  • (最完美)小米手机6X的Usb调试模式在哪里打开的流程
  • *上位机的定义
  • .NET BackgroundWorker
  • .net 连接达梦数据库开发环境部署
  • /*在DataTable中更新、删除数据*/
  • /dev下添加设备节点的方法步骤(通过device_create)
  • ?
  • ?.的用法