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

Apache Hive 如何在大数据中发挥能量

Apache Hive开源项目

https://github.com/apache/hive

Apache Hive (TM) 数据仓库软件使用 SQL 轻松读取、写入和管理分布式存储中的大型数据集。它基于 Apache Hadoop (TM) 构建,提供以下功能:

  • 通过 SQL 轻松访问数据的工具,从而支持数据仓库任务,例如提取/转换/加载 (ETL)、报告和数据分析;
  • 对各种数据格式施加结构的机制;
  • 访问直接存储在 Apache HDFS (TM) 或其他数据存储系统(例如 Apache HBase (TM))中的文件;
  • 使用 Apache Tez 框架执行查询,该框架专为交互式查询而设计,与 MapReduce 相比,开销大幅降低。

Hive 提供标准 SQL 功能,包括许多 2003 年和 2011 年后期推出的分析功能。

这些功能包括 OLAP 函数、子查询、通用表表达式等。Hive 的 SQL 还可以通过用户定义函数 (UDF)、用户定义聚合 (UDAF) 和用户定义表函数 (UDTF) 使用用户代码进行扩展。Hive 并非设计用于在线事务处理。它最适合用于传统的数据仓库任务,因为这些任务需要处理的数据量足够大,需要使用分布式系统。Hive 旨在最大限度地提高可扩展性(通过向 Hadoop 集群动态添加更多机器来实现横向扩展)、性能、可扩展性、容错性以及与输入格式的松散耦合。

我将为您详细解答Apache Hive如何实现大数据查询,以及将数据导入Hive的各种途径和方式。

Apache Hive数据的查询和导入途径

Apache Hive 如何实现大数据查询?

简单来说,Hive 的核心思想是:将结构化的数据文件映射为一张数据库表,并提供一种类似 SQL 的查询语言(HiveQL 或 HQL),最终将这些查询转换为分布式计算任务(如 MapReduce, Tez, Spark)在 Hadoop 集群上执行。

下面是其实现查询的详细步骤和核心组件:

1. 核心组件与架构

  • 用户接口(CLI, JDBC/ODBC, Web UI): 用户通过这些接口提交 HiveQL 查询。

  • 驱动器(Driver):

    • 解析器(Parser): 对 HiveQL 语句进行词法分析、语法分析,生成抽象语法树(AST)。

    • 编译器(Compiler): 将 AST 编译成一个逻辑执行计划,然后通过元数据(Metastore)进行优化,最终生成一个物理执行计划(通常是一个 MapReduce/Tez/Spark 的 DAG 有向无环图)。

    • 优化器(Optimizer): 对执行计划进行优化,例如谓词下推、列剪裁等,以减少数据处理量。

    • 执行器(Executor): 将优化后的物理执行计划提交给底层的计算引擎(如 MapReduce)执行。

  • 元数据存储(Metastore): 这是 Hive 的“大脑”,通常存储在关系型数据库(如 MySQL, PostgreSQL)中。它存储了:

    • 表的名称、列名、数据类型。

    • 表是内部表还是外部表。

    • 数据在 HDFS 上的存储路径。

    • 数据的序列化/反序列化方式(SerDe)。

    • 表的分区信息。

  • 计算引擎(Execution Engine): 默认是 MapReduce,但现在更流行性能更好的 Tez 或 Spark。它们负责在 Hadoop 集群上分布式地执行任务。

  • 存储(HDFS, S3等): 实际的数据文件存储在分布式文件系统上。Hive 不管理数据的存储,只管理元数据。

2. 查询执行流程

  1. 提交查询: 用户通过 Hive CLI 或 Beeline 等客户端提交一条 SELECT ... FROM ... WHERE ... 语句。

  2. 解析与编译: Driver 接收语句,Parser 将其解析为 AST,Compiler 结合 Metastore 中的元数据,生成执行计划。

  3. 优化: Optimizer 对执行计划进行优化。

  4. 执行: Executor 将执行计划交给 Tez 或 Spark。计算引擎会启动多个任务(Map Task, Reduce Task),在各个数据节点上并行处理 HDFS 中的数据块。

  5. 返回结果: 计算引擎将最终结果返回给 Driver,Driver 再将结果返回给用户接口。

关键点: Hive 适用于高延迟、高吞吐量批处理场景,而不是低延迟的交互式查询。它的优势在于处理 PB 级别的数据,但查询的响应时间可能是分钟甚至小时级别。


导入数据到 Hive 的途径和方式

将数据导入 Hive,本质上是让 Hive 的元数据与数据文件建立关联。以下是主要的几种方式,可根据数据源和场景选择。

方式 1:从文件系统直接加载(LOAD DATA)

这是最直接的方式,适用于数据已经在 HDFS 或本地文件系统中的情况。

  • 从本地文件系统加载(数据会被复制到 Hive 的仓库目录):

    sql

    LOAD DATA LOCAL INPATH '/path/to/local/datafile' 
    INTO TABLE my_table;
  • 从 HDFS 加载(数据会被移动到 Hive 的仓库目录):

    sql

    LOAD DATA INPATH '/path/on/hdfs/datafile' 
    INTO TABLE my_table;
  • 覆盖加载(使用 OVERWRITE):

    sql

    LOAD DATA INPATH '/path/on/hdfs/datafile' 
    OVERWRITE INTO TABLE my_table; -- 清空表中原有数据,然后加载新数据

方式 2:使用外部表(External Table)

这是非常重要和常用的方式,特别适用于数据需要被多个框架(如 Spark, Pig)共享的场景。

  • 概念: Hive 只管理表的元数据,而不管理数据本身。删除外部表只会删除元数据,而不会删除实际的数据文件

  • 语法:

    sql

    CREATE EXTERNAL TABLE my_external_table (column1 INT,column2 STRING
    )
    ROW FORMAT DELIMITED
    FIELDS TERMINATED BY ',' 
    LOCATION '/path/on/hdfs/to/data/directory/';
  • 操作: 创建外部表后,只需将数据文件(如 CSV, JSON)直接上传或通过 hadoop fs -put 命令放到指定的 LOCATION 路径下,然后执行 MSCK REPAIR TABLE my_external_table; 来刷新分区元数据(如果表是分区表),即可直接查询。

方式 3:通过查询插入数据(INSERT ... SELECT)

适用于从已有的 Hive 表或其他查询结果中转换和导入数据。

  • 基本插入:

    sql

    INSERT INTO TABLE target_table 
    SELECT * FROM source_table WHERE condition;
  • 覆盖插入:

    sql

    INSERT OVERWRITE TABLE target_table 
    SELECT * FROM source_table WHERE condition;
  • 动态分区插入: 非常强大,可以根据查询结果的某一列自动创建分区。

    sql

    -- 首先设置允许动态分区
    SET hive.exec.dynamic.partition = true;
    SET hive.exec.dynamic.partition.mode = nonstrict;INSERT OVERWRITE TABLE partitioned_table 
    PARTITION (country) 
    SELECT name, age, country FROM source_table;

方式 4:在创建表的同时插入数据(CTAS)

CTAS(Create Table As Select)可以方便地基于查询结果创建一张新表并导入数据。

sql

CREATE TABLE new_table AS
SELECT column1, column2 
FROM existing_table 
WHERE condition;

方式 5:使用 Sqoop 从关系型数据库导入

Sqoop 是 Hadoop 生态系统中专门用于在 Hadoop 和关系型数据库(如 MySQL, Oracle, PostgreSQL)之间传输数据的工具。

  • 导入命令示例:

    bash

    sqoop import \
    --connect jdbc:mysql://localhost/mydatabase \
    --username myuser \
    --password mypass \
    --table my_table \
    --hive-import \              # 直接导入到Hive
    --create-hive-table \        # 如果Hive表不存在,则创建
    --hive-table my_hive_table \
    --target-dir /user/hive/warehouse/mydb.db/my_hive_table \ # HDFS路径
    -m 1                         # 使用1个map任务(并行度)

方式 6:使用 Flume 进行实时数据采集

Flume 是一个高可用的、高可靠的分布式日志采集系统,常用于将流式日志数据(如网站点击流)近乎实时地导入到 HDFS,然后 Hive 可以通过外部表或定期加载来查询这些数据。

方式 7:编程方式(JDBC/ODBC或Spark等)

通过 Java/Python/Scala 等编程语言,使用 Hive 的 JDBC/ODBC 驱动或 Spark DataFrame API 将数据写入 Hive。

  • Spark 示例(PySpark):

    python

    df = spark.read.csv("hdfs://path/to/data.csv")
    df.write.saveAsTable("my_hive_table") # 写入Hive表
    # 或者
    df.write.format("hive").mode("overwrite").saveAsTable("my_hive_table")

总结与选择建议

场景推荐方式优点
数据文件已在本地/HDFSLOAD DATA 或 外部表简单快速。外部表更灵活,不移动数据。
从已有Hive表转换数据INSERT ... SELECT 或 CTAS利用HiveQL的强大处理能力进行ETL。
从关系型数据库(RDBMS)导入Sqoop专为数据库设计,高效可靠。
实时/准实时日志采集Flume + 外部表构建数据管道,支持流式数据。
数据需要被多框架共享外部表避免数据被意外删除,共享性强。
通过程序(如Spark)处理数据后写入Spark DataFrame API适合复杂的数据处理和数据科学工作流。

如何感知Apache Hive使用的计算引擎

Hive 将查询转换为任务,如:MapReduce, Tez, Spark 。这三者的分布式计算任务,程序员如何感知?下面我们来探讨这个话题。

程序员在使用 Hive 时,对底层计算引擎(MapReduce、Tez、Spark)的感知程度是分层次的,从几乎无感知深度可控。下面我将从不同维度详细解释程序员如何感知这些计算任务。


层次一:基本无感知(透明化使用)

对于大多数日常的数据分析任务,程序员可以完全不用关心底层是哪个引擎。

1. 统一的 HiveQL 接口

无论底层是 MR、Tez 还是 Spark,程序员都使用相同的 HiveQL 进行查询。

sql

-- 对于程序员来说,这条查询语句是一样的
SELECT department, AVG(salary) 
FROM employees 
WHERE country = 'China' 
GROUP BY department;

Hive 负责将这条 HQL 翻译成不同引擎的任务。这是最主要的感知方式:不需要感知。

2. 引擎选择(配置层面)

程序员通过一个简单的配置参数来切换引擎,而不需要重写代码。

sql

-- 设置为 MapReduce(默认,但已过时)
SET hive.execution.engine=mr;-- 设置为 Tez(推荐,性能更好)
SET hive.execution.engine=tez;-- 设置为 Spark(同样高性能)
SET hive.execution.engine=spark;

这种感知是声明式的,只需指定“用什么”,而不需关心“怎么用”。


层次二:通过日志和UI间接感知

当查询提交后,程序员可以通过多种方式观察和感知任务的执行情况。

1. Hive CLI / Beeline 输出日志

执行查询时,命令行会打印出任务执行进度。从日志信息的不同,可以明显感知到底层引擎。

  • MapReduce 引擎的日志:

    text

    Query ID = user_20240923_102030_12345abc
    Total jobs = 1
    Launching Job 1 out of 1
    Number of reduce tasks not specified. Estimated from input data size: 1
    In order to change the average load for a reducer (in bytes):
    set hive.exec.reducers.bytes.per.reducer=<number>
    In order to limit the maximum number of reducers:
    set hive.exec.reducers.max=<number>
    In order to set a constant number of reducers:
    set mapreduce.job.reduces=<number>
    Starting Job = job_123456789_12345, Tracking URL = http://resourcemanager:8088/proxy/application_123456789_12345/
    Kill Command = /opt/hadoop/bin/hadoop job -kill job_123456789_12345
    Hadoop job information for Stage-1: number of mappers: 2; number of reducers: 1

    感知点: 日志中会出现 mapreduceStage 等典型的 MapReduce 术语。进度显示为 Map: x% Reduce: 0%

  • Tez 引擎的日志:

    text

    Query ID = user_20240923_102030_12345abc
    Total jobs = 1
    Session is already open. Session id = tez_session_id_12345
    Status: Running (Executing on YARN cluster with App id application_123456789_12345)
    Dag name: insert overwrite directory... (stage-1)
    Vertices:Map 1 [ROOT_EDGE] ->  Map 3 [BROADCAST_EDGE],  Map 2 [SIMPLE_EDGE]Map 2 [SIMPLE_EDGE] ->  Reducer 4 [SIMPLE_EDGE]Reducer 4 [SIMPLE_EDGE] ->  Reducer 5 [SIMPLE_EDGE]Map 3 [BROADCAST_EDGE] ->  Reducer 5 [SIMPLE_EDGE]

    感知点: 日志中不再有传统的 Map/Reduce 进度,而是出现了 Vertices(顶点)和 DAG(有向无环图)的概念。Tez 会将多个 MR 作业融合成一个更复杂的 DAG,效率更高。

  • Spark 引擎的日志:

    text

    Query ID = user_20240923_102030_12345abc
    Status: Running (Executing on YARN cluster with App id application_123456789_12345)
    Job Progress (by Stage):
    Stage 0: Map: 2  Reducer: 1  Cumulative CPU: 45.32 sec
    Stage 1: Map: 1  Reducer: 1  Cumulative CPU: 12.11 sec

    感知点: 日志风格类似 MR,但也有 DAG 的概念。最明显的感知是可以看到 Spark 独有的 Web UI 地址(通常是 http://spark-driver-host:4040)。

2. 集群资源管理器 Web UI

这是最直观的感知方式。程序员可以通过 YARN 的 ResourceManager UI 查看任务。

  • 访问方式: http://<resourcemanager-host>:8088

  • 感知点:

    • 在 UI 中可以看到运行的 Application

    • Application Type 会明确显示是 MAPREDUCETEZ 还是 SPARK

    • 可以点击进入查看详细的任务计数器、日志和资源使用情况。

3. 引擎特定的 Web UI

  • Tez UI: Tez 有自己专用的 UI(通常通过 Tez AM 访问),可以可视化地看到整个 DAG 的执行流程,哪个顶点(Vertex)是瓶颈一目了然。

  • Spark UI: Spark 的 UI 非常强大(默认端口 4040),可以查看详细的 DAG 可视化图、每个 Stage 的执行时间、任务分配、数据倾斜情况等。这是 Spark 引擎带给程序员的独特且强大的感知工具。


层次三:通过调优参数深度感知和控制

当需要进行性能调优时,程序员必须对底层引擎有深入的了解,并通过设置大量参数来干预任务的执行。

1. 资源调优(感知容器和资源)

无论哪种引擎,最终都跑在 YARN 上,所以都需要设置类似参数:

sql

-- 设置每个Map任务的容器内存
SET tez.task.resource.memory.mb = 4096; -- For Tez
SET spark.executor.memory = 4g;        -- For Spark
SET mapreduce.map.memory.mb = 4096;    -- For MR-- 设置并行度(Reducer数量或Spark分区数)
SET hive.exec.reducers.bytes.per.reducer = 67108864; -- 通用Hive参数
SET spark.sql.shuffle.partitions = 200; -- For Spark

2. 引擎特异性调优(深度感知差异)

这时,程序员必须明确知道当前使用的是哪个引擎,并设置对应的优化参数。

  • MapReduce 调优:

    sql

    -- 启用Map端输出压缩
    SET mapreduce.map.output.compress=true;
    -- 设置Combine类以减少Shuffle数据量
    SET hive.exec.combine=true;
  • Tez 调优:

    sql

    -- 启用动态分区优化
    SET tez.dynamic.partition.pruning=true;
    -- 设置Container的重用(Tez的一大优势)
    SET tez.am.container.reuse.enabled=true;
  • Spark 调优(参数最多,最复杂):

    sql

    -- 设置序列化方式(Kryo性能更好)
    SET spark.serializer=org.apache.spark.serializer.KryoSerializer;
    -- 处理数据倾斜
    SET spark.sql.adaptive.skew.enabled=true;
    -- 设置广播join的阈值
    SET spark.sql.autoBroadcastJoinThreshold=10485760; -- 10MB

    感知点: 调优 Spark 任务时,程序员几乎需要以 Spark 开发者的思维方式去考虑分区、缓存、Shuffle 等概念。


总结:程序员的感知维度

感知维度描述感知程度
查询语言使用统一的 HiveQL无感知
引擎切换通过 hive.execution.engine 配置轻度感知(知道选了哪个)
执行日志在 CLI 中观察任务提交和进度信息中度感知(能从日志风格区分引擎)
Web UI通过 YARN/Tez/Spark UI 监控任务高度感知(直观看到引擎差异和任务细节)
性能调优设置引擎特定的性能参数深度感知(必须深刻理解引擎原理)

核心思想: Hive 的设计目标是让程序员专注于“做什么”(声明式编程),而不是“怎么做”(命令式编程)。因此,在大多数简单场景下,程序员可以无需感知底层引擎。但当任务变得复杂、出现性能瓶颈时,对底层引擎的感知和理解能力就成为了区分普通程序员和高级大数据开发工程师的关键。

Apache Hive 和 Apache Spark 的数据对接场景

Apache Hive 和 Apache Spark 的数据对接场景非常丰富,两者在大数据生态系统中形成了强大的互补关系。以下是主要的对接场景,从简单到复杂排列:


1. 使用 Spark SQL 直接读写 Hive 表(最常见场景)

这是最直接、最常用的对接方式。Spark 可以直接读取 Hive Metastore 中的元数据,并处理存储在 HDFS 上的 Hive 表数据。

场景特点:

  • 数据共享:Hive 作为"数据仓库",Spark 作为"计算引擎"

  • 元数据统一:使用相同的 Hive Metastore(通常基于 MySQL/PostgreSQL)

  • 存储统一:数据都存储在 HDFS 或对象存储上

代码示例:

python

from pyspark.sql import SparkSession# 创建支持Hive的SparkSession
spark = SparkSession.builder \.appName("HiveIntegration") \.config("spark.sql.warehouse.dir", "/user/hive/warehouse") \.enableHiveSupport() \.getOrCreate()# 直接读取Hive表
df = spark.sql("SELECT * FROM hive_db.sales_table WHERE date = '2024-01-01'")# 或者使用DataFrame API
df = spark.table("hive_db.sales_table")# 使用Spark进行复杂处理
result_df = df.filter(df.amount > 1000) \.groupBy("category") \.agg({"amount": "sum", "id": "count"})# 将结果写回Hive表
result_df.write.mode("overwrite").saveAsTable("hive_db.sales_summary")

配置要点:

bash

# 需要将hive-site.xml复制到Spark的conf目录下
cp $HIVE_HOME/conf/hive-site.xml $SPARK_HOME/conf/

2. Hive on Spark(Hive 使用 Spark 作为执行引擎)

在这种场景下,Hive 将 Spark 作为底层的计算引擎来执行 HiveQL 查询。

场景特点:

  • 保持 Hive 接口:业务人员继续使用熟悉的 HiveQL

  • 提升性能:用 Spark 替换传统的 MapReduce 引擎

  • 平滑迁移:无需重写现有 Hive 脚本

配置方式:

sql

-- 在Hive会话中设置执行引擎为Spark
SET hive.execution.engine=spark;-- 设置Spark相关参数
SET spark.master=yarn-cluster;
SET spark.executor.memory=2g;-- 然后执行正常的HiveQL查询
SELECT count(*) FROM large_table;

架构关系:

text

HiveQL → Hive编译器 → Spark执行计划 → Spark集群 → HDFS数据

3. ETL 流水线协作场景

Hive 和 Spark 在数据预处理和数据分析阶段分工协作。

典型工作流:

text

原始数据 → Spark进行复杂清洗/转换 → 写入HiveODS层 → Hive进行ETL加工 → Hive数据仓库 → Spark ML/分析

场景示例:

python

# Stage 1: Spark进行数据清洗和预处理
raw_data = spark.read.json("hdfs:///raw/logs/2024-01-01/*.json")
cleaned_data = raw_data.filter("user_id IS NOT NULL") \.dropDuplicates(["user_id", "timestamp"])# 写入Hive ODS层(原始数据层)
cleaned_data.write.mode("append").saveAsTable("hive_ods.user_behavior")# Stage 2: Hive进行传统的ETL处理
# (在Hive中执行,利用Hive的稳定性和SQL兼容性)
hive_query = """
INSERT INTO hive_dwd.user_daily_stats
SELECT user_id,date,COUNT(*) as page_views,SUM(CASE WHEN action='purchase' THEN 1 ELSE 0 END) as purchases
FROM hive_ods.user_behavior
GROUP BY user_id, date
"""# Stage 3: Spark读取Hive处理后的数据进行机器学习
training_data = spark.sql("SELECT * FROM hive_dwd.user_daily_stats")
# ... 进行机器学习训练

4. 增量数据同步和实时分析场景

结合 Hive 的批处理能力和 Spark Streaming/Structured Streaming 的流处理能力。

典型架构:

text

Kafka实时数据流 → Spark Streaming处理 → 写入Hive分区表 → Hive定期 compaction → Spark离线分析

代码示例:

python

# Spark Structured Streaming 处理实时数据并写入Hive
from pyspark.sql.functions import *streaming_df = spark.readStream \.format("kafka") \.option("kafka.bootstrap.servers", "kafka-broker:9092") \.option("subscribe", "user_events") \.load()# 解析和处理数据
parsed_df = streaming_df.select(get_json_object("value", "$.user_id").alias("user_id"),get_json_object("value", "$.event_time").alias("event_time"),get_json_object("value", "$.action").alias("action")
)# 按时间窗口聚合
windowed_df = parsed_df \.withWatermark("event_time", "10 minutes") \.groupBy(window("event_time", "5 minutes"),"action").count()# 写入Hive分区表
query = windowed_df.writeStream \.outputMode("update") \.format("parquet") \.option("path", "/user/hive/warehouse/streaming_events") \.option("checkpointLocation", "/tmp/checkpoint") \.partitionBy("action") \.start()

5. 数据湖查询加速场景

在数据湖架构中,Hive 用于数据目录管理,Spark 用于高性能查询。

架构模式:

text

数据湖(HDFS/S3) ↓
Hive Metastore(元数据管理)↓
Spark(高速查询引擎) + Hive(DDL管理)

配置示例:

python

# Spark使用Hive Metastore查询数据湖中的表
spark.conf.set("spark.sql.catalogImplementation", "hive")# 创建基于数据湖位置的外部表(Hive管理元数据)
spark.sql("""
CREATE EXTERNAL TABLE IF NOT EXISTS lakehouse.sales
(id BIGINT,amount DOUBLE,category STRING
)
STORED AS PARQUET
LOCATION 's3a://my-bucket/data-lake/sales/'
""")# Spark进行高性能查询
result = spark.sql("""
SELECT category, AVG(amount) as avg_amount
FROM lakehouse.sales 
WHERE amount > 100
GROUP BY category
""")

6. 机器学习和高级分析场景

Hive 负责数据准备和特征存储,Spark MLlib 负责模型训练和预测。

工作流程:

python

# 从Hive中读取特征数据
feature_data = spark.sql("""
SELECT user_id,recent_purchase_count,avg_order_value,days_since_last_purchase,churn_label
FROM hive_dwd.user_features
WHERE dt = '2024-01-01'
""")# 使用Spark ML进行机器学习
from pyspark.ml.feature import VectorAssembler
from pyspark.ml.classification import RandomForestClassifier# 特征向量化
assembler = VectorAssembler(inputCols=["recent_purchase_count", "avg_order_value", "days_since_last_purchase"],outputCol="features"
)feature_vector = assembler.transform(feature_data)# 训练模型
rf = RandomForestClassifier(featuresCol="features", labelCol="churn_label")
model = rf.fit(feature_vector)# 将预测结果写回Hive
predictions = model.transform(feature_vector)
predictions.select("user_id", "prediction") \.write.mode("overwrite") \.saveAsTable("hive_dws.user_churn_predictions")

7. 统一数据服务平台场景

在企业级数据平台中,Hive 和 Spark 共同构成完整的数据服务栈。

平台架构:

text

数据源↓
Spark数据采集 & 实时处理↓
Hive数据仓库 & 数据治理↓
Spark数据分析 & 机器学习↓
数据服务API

总结对比

场景Hive角色Spark角色主要优势
Spark读写Hive表数据存储/元数据管理计算引擎性能提升,代码复用
Hive on Spark查询接口/SQL层执行引擎平滑迁移,保持兼容性
ETL流水线协作批处理/数据加工复杂转换/数据清洗各司其职,优势互补
增量数据同步批量存储/历史数据流处理/实时计算实时+批量统一处理
数据湖加速元数据目录高速查询引擎数据湖性能优化
机器学习特征存储/数据准备模型训练/预测完整的AI流水线
统一数据平台数据治理/质量管理多样化计算引擎企业级全栈解决方案

这些场景展示了 Hive 和 Spark 如何协同工作,充分发挥 Hive 在数据管理和 Spark 在计算性能方面的各自优势,构建高效的大数据解决方案。

http://www.dtcms.com/a/397916.html

相关文章:

  • CSS——实现盒子在页面居中
  • RocketMQ相对于RabbitMQ 的优势
  • ELK 企业级日志分析系统(完整版)
  • WaveTerminal+cpolar:提升远程协作效率的开发利器
  • 【记录】Ubuntu系统实现从远程服务器上传下载文件
  • 通过串口控制RDA5807收音模块(stm32+c#上位机)
  • hive表元数据修复脚本
  • React中的Hook
  • React简单例子
  • Playwright MCP 服务器对比高层级的 MCP 服务器解决方案
  • app下载网站模板wordpress将公网ip改为域名
  • 个人做网站如何推广安全优化大师
  • jupyter notebook用简易python代码跑本地模型
  • Android 安卓RIL介绍
  • 开源 java android app 开发(十五)绘图定义控件--仪表盘
  • Android如何自动弹出软键盘?
  • Linux Shell 脚本:从零到进阶的实战笔记
  • MR 一体机市场报告:2031全球规模突破 1.98亿美元,中国 40.8% 市占率成核心增长极
  • 网站管理员权限权重高的网站有哪些
  • 【Spark+Hive+hadoop】基于spark+hadoop基于大数据的全球用水量数据可视化分析系统大数据毕设
  • 07.【Linux系统编程】进程控制(进程创建fork、进程终止exit等、进程等待waitwaitpid、进程替换execl等)
  • 百度Qianfan-VL系列上线:推出3B/8B/70B三款视觉理解模型,覆盖不同算力需求
  • 基于 Python Keras 实现 猫狗图像的精准分类
  • 点云-标注-分类-航线规划软件 (一)点云自动分类
  • 挑战用R语言硬干一百万单细胞数据分析
  • 如何自己弄个免费网站wordpress前端登陆
  • npm install 时包库找不到报错解决
  • 【开题答辩实录分享】以《城市网约车服务预约与管理小程序的设计与实现》为例进行答辩实录分享
  • 网站建设软件哪个最好wordpress转发插件
  • C#异步协同常用例子