深入解析数据仓库ADS层-从理论到实践的全面指南

news2024/11/25 4:47:38

在大数据时代,数据仓库已经成为企业进行数据分析和决策的核心系统。而在数据仓库的分层架构中,ADS(Application Data Store)层作为最上层的数据应用层,直接面向业务应用和分析需求,其重要性不言而喻。然而,很多数据从业者对ADS层的理解还停留在表面,不清楚如何构建高效的ADS层来支撑复杂的业务场景。
本文将带您深入剖析ADS层的本质,全面介绍ADS层的设计原则、实现方法和最佳实践,帮助您构建一个真正能够驱动业务价值的数据应用层。
image.png

目录

    • 什么是ADS层?为什么它如此重要?
    • ADS层的设计原则
      • 1. 业务导向
      • 2. 性能优先
      • 3. 口径一致
      • 4. 可扩展性
      • 5. 安全可控
    • ADS层的实现方法
      • 1. 确定数据集市
      • 2. 设计星型模型
      • 3. 实现预计算
      • 4. 优化查询性能
      • 5. 实现数据安全
      • 6. 提供数据字典
    • ADS层的最佳实践
      • 1. 增量更新机制
      • 2. 版本控制
      • 3. 监控和告警
      • 4. 文档和元数据管理
      • 5. 性能调优
      • 6. 数据生命周期管理
      • 7. 持续优化和迭代
    • ADS层的未来展望
    • 结语

什么是ADS层?为什么它如此重要?

ADS层全称Application Data Store,即应用数据存储层,是数据仓库分层架构中最接近应用的一层。它直接面向业务应用、报表系统、数据产品等,提供结构化的主题数据集市(Data Mart)。
image.png

与其他数据仓库层级相比,ADS层具有以下特点:

  1. 面向应用:数据模型和粒度完全匹配具体应用需求
  2. 高度汇总:通常是多维度的汇总数据,而非原子级数据
  3. 查询性能优:采用星型模型等OLAP友好的模式设计
  4. 变更频繁:随业务需求变化而不断调整
  5. 数据量适中:通过汇总降低了数据量级

ADS层的重要性主要体现在:

  1. 屏蔽底层复杂性,为应用提供简单视图
  2. 提升查询性能,支持交互式分析
  3. 确保数据口径一致性,避免"数出多门"
  4. 灵活应对多变的业务需求
  5. 支撑数据产品开发,释放数据价值

可以说,ADS层的设计好坏直接决定了整个数据仓库能否真正发挥作用、为业务赋能。那么,如何构建一个优秀的ADS层呢?让我们一步步深入探讨。

ADS层的设计原则

要构建一个优秀的ADS层,我们需要遵循以下关键设计原则:
image.png

1. 业务导向

ADS层的首要原则是业务导向。每个数据集市都应该对应明确的业务主题,如销售分析、用户画像、供应链优化等。在设计时,我们需要深入理解业务需求,包括:

  • 关键业务问题是什么?
  • 需要哪些维度进行分析?
  • 关注哪些指标?
  • 数据的时效性要求如何?
  • 查询模式是怎样的?

只有充分理解业务需求,才能设计出真正有价值的ADS模型。

2. 性能优先

ADS层直接面向应用查询,性能至关重要。我们需要从多个角度保证查询性能:

  • 模型设计:采用星型模型等OLAP友好的模式
  • 预计算:提前计算常用的聚合指标
  • 分区:根据查询模式合理设置分区策略
  • 物化视图:为高频查询路径创建物化视图
  • 索引优化:根据查询特征创建合适的索引

3. 口径一致

ADS层是确保全公司数据口径一致性的最后一道防线。我们需要:

  • 统一维度定义:如时间维度的粒度、客户分类的标准等
  • 统一指标口径:如GMV、DAU等关键指标的计算规则
  • 提供数据字典:详细解释每个字段的含义和计算逻辑

4. 可扩展性

业务需求是不断变化的,ADS层的设计必须具备良好的可扩展性:

  • 使用通用的维度和事实表设计,便于横向扩展
  • 预留冗余字段,为未来可能的需求变更做准备
  • 采用模块化的设计,便于垂直扩展新的数据集市

5. 安全可控

作为直接面向应用的数据层,ADS层的安全至关重要:

  • 实现细粒度的访问控制,确保数据只对有权限的用户可见
  • 对敏感信息进行脱敏处理
  • 实现完整的操作审计,记录所有数据访问行为

ADS层的实现方法

理解了设计原则,接下来让我们看看如何具体实现ADS层。

1. 确定数据集市

image.png

首先需要根据业务需求,确定需要构建哪些数据集市。常见的数据集市包括:

  • 销售分析集市
  • 用户画像集市
  • 商品分析集市
  • 营销效果分析集市
  • 供应链优化集市
  • 财务分析集市

每个数据集市都应该对应一个明确的业务主题和应用场景。

2. 设计星型模型

image.png

对于每个数据集市,我们通常采用星型模型进行设计。以销售分析集市为例:

-- 销售事实表
CREATE TABLE fact_sales (
    sale_id BIGINT,
    date_key INT,
    product_key INT,
    customer_key INT,
    store_key INT,
    promotion_key INT,
    sales_amount DECIMAL(10,2),
    sales_quantity INT,
    profit DECIMAL(10,2),
    PRIMARY KEY (sale_id)
);

-- 日期维度表
CREATE TABLE dim_date (
    date_key INT,
    date DATE,
    year INT,
    quarter INT,
    month INT,
    week INT,
    day_of_week INT,
    is_holiday BOOLEAN,
    PRIMARY KEY (date_key)
);

-- 商品维度表
CREATE TABLE dim_product (
    product_key INT,
    product_id VARCHAR(50),
    product_name VARCHAR(100),
    brand VARCHAR(50),
    category VARCHAR(50),
    subcategory VARCHAR(50),
    unit_price DECIMAL(10,2),
    PRIMARY KEY (product_key)
);

-- 客户维度表
CREATE TABLE dim_customer (
    customer_key INT,
    customer_id VARCHAR(50),
    customer_name VARCHAR(100),
    gender VARCHAR(10),
    age INT,
    city VARCHAR(50),
    membership_level VARCHAR(20),
    PRIMARY KEY (customer_key)
);

-- 门店维度表
CREATE TABLE dim_store (
    store_key INT,
    store_id VARCHAR(50),
    store_name VARCHAR(100),
    city VARCHAR(50),
    state VARCHAR(50),
    country VARCHAR(50),
    store_type VARCHAR(20),
    PRIMARY KEY (store_key)
);

-- 促销维度表
CREATE TABLE dim_promotion (
    promotion_key INT,
    promotion_id VARCHAR(50),
    promotion_name VARCHAR(100),
    promotion_type VARCHAR(50),
    start_date DATE,
    end_date DATE,
    discount_rate DECIMAL(5,2),
    PRIMARY KEY (promotion_key)
);

这个星型模型包含了一个销售事实表和多个维度表,可以支持多维度的销售分析。

3. 实现预计算

image.png

为了提升查询性能,我们需要预先计算一些常用的聚合指标。例如,我们可以创建一个每日销售汇总表:

CREATE TABLE agg_daily_sales AS
SELECT 
    d.date_key,
    p.product_key,
    c.customer_key,
    s.store_key,
    SUM(f.sales_amount) AS total_sales,
    SUM(f.sales_quantity) AS total_quantity,
    SUM(f.profit) AS total_profit,
    COUNT(DISTINCT f.sale_id) AS transaction_count
FROM 
    fact_sales f
    JOIN dim_date d ON f.date_key = d.date_key
    JOIN dim_product p ON f.product_key = p.product_key
    JOIN dim_customer c ON f.customer_key = c.customer_key
    JOIN dim_store s ON f.store_key = s.store_key
GROUP BY 
    d.date_key, p.product_key, c.customer_key, s.store_key;

这个汇总表大大简化了日常的销售分析查询。

4. 优化查询性能

image.png

除了预计算,我们还可以通过以下方式优化查询性能:

  • 合理设置分区:
ALTER TABLE fact_sales 
PARTITION BY RANGE (date_key) (
    PARTITION p2021 VALUES LESS THAN (20220101),
    PARTITION p2022 VALUES LESS THAN (20230101),
    PARTITION p2023 VALUES LESS THAN (20240101)
);
  • 创建合适的索引:
CREATE INDEX idx_fact_sales_date ON fact_sales (date_key);
CREATE INDEX idx_fact_sales_product ON fact_sales (product_key);
CREATE INDEX idx_fact_sales_customer ON fact_sales (customer_key);
  • 使用物化视图:
CREATE MATERIALIZED VIEW mv_monthly_sales AS
SELECT 
    DATE_TRUNC('month', d.date) AS month,
    p.category,
    SUM(f.sales_amount) AS total_sales
FROM 
    fact_sales f
    JOIN dim_date d ON f.date_key = d.date_key
    JOIN dim_product p ON f.product_key = p.product_key
GROUP BY 
    DATE_TRUNC('month', d.date), p.category;

5. 实现数据安全

image.png

为了保证数据安全,我们需要实现细粒度的访问控制:

-- 创建角色
CREATE ROLE sales_analyst;
CREATE ROLE marketing_analyst;

-- 授权
GRANT SELECT ON fact_sales TO sales_analyst;
GRANT SELECT ON dim_product TO sales_analyst, marketing_analyst;
GRANT SELECT ON dim_customer TO marketing_analyst;

-- 行级别的访问控制
CREATE POLICY store_access_policy ON dim_store
    USING (store_id IN (SELECT store_id FROM user_store_access WHERE user_id = CURRENT_USER));

对于敏感信息,我们可以使用视图进行脱敏:

CREATE VIEW v_customer_safe AS
SELECT 
    customer_key,
    MASK(customer_name) AS customer_name,
    gender,
    FLOOR(age/10)*10 AS age_group,
    city,
    membership_level
FROM 
    dim_customer;

6. 提供数据字典

image.png

最后,我们需要为ADS层提供详细的数据字典,解释每个表和字段的含义。例如:

# 销售分析数据集市

## 事实表: fact_sales

| 字段名 | 类型 | 描述 | 示例 |
|--------|------|------|------|
| sale_id | BIGINT | 销售记录唯一标识 | 1234567 |
| date_key | INT | 日期维度外键 | 20230601 |
| product_key | INT | 商品维度外键 | 101 |
| customer_key | INT | 客户维度外键 | 1001 |
| store_key | INT | 门店维度外键 | 50 |
| promotion_key | INT | 促销维度外键 | 10 |
| sales_amount | DECIMAL(10,2) | 销售金额 | 199.99 |
| sales_quantity | INT | 销售数量 | 2 |
| profit | DECIMAL(10,2) | 利润 | 59.99 |

## 维度表: dim_date

| 字段名 | 类型 | 描述 | 示例 |
|--------|------|------|------|
| date_key | INT | 日期唯一标识 | 20230601 |
| date | DATE | 具体日期 | 2023-06-01 |
| year | INT | 年份 | 2023 |
| quarter | INT | 季度 | 2 |
| month | INT | 月份 | 6 |
| week | INT | 周数 | 22 |
| day_of_week | INT | 周几(1-7) | 4 |
| is_holiday | BOOLEAN | 是否节假日 | false |

...(其他维度表的说明)

ADS层的最佳实践

在实际工作中,构建ADS层还需要注意以下最佳实践:

1. 增量更新机制

ADS层的数据通常来源于DWS层,我们需要实现高效的增量更新机制:

-- 使用merge语句进行增量更新
MERGE INTO ads_layer.fact_sales t
USING (
    SELECT * FROM dws_layer.fact_sales 
    WHERE etl_date = CURRENT_DATE
) s
ON (t.sale_id = s.sale_id)
WHEN MATCHED THEN 
    UPDATE SET 
        t.sales_amount = s.sales_amount,
        t.sales_quantity = s.sales_quantity,
        t.profit = s.profit
WHEN NOT MATCHED THEN
    INSERT (sale_id, date_key, product_key, customer_key, store_key, promotion_key, sales_amount, sales_quantity, profit)
    VALUES (s.sale_id, s.date_key, s.product_key, s.customer_key, s.store_key, s.promotion_key, s.sales_amount, s.sales_quantity, s.profit);

2. 版本控制

ADS层的表结构和数据处理逻辑应该纳入版本控制系统,例如使用Git管理SQL脚本:

git init ads_layer
cd ads_layer
touch create_tables.sql update_logic.sql
git add .
git commit -m "Initial commit for ADS layer"

3. 监控和告警

我们需要对ADS层的数据质量和更新情况进行实时监控:

import pandas as pd
from great_expectations.dataset import PandasDataset

# 加载数据
df = pd.read_sql("SELECT * FROM fact_sales WHEREdate_key = CURRENT_DATE", connection)

# 创建Great Expectations数据集
ge_df = PandasDataset(df)

# 定义期望
ge_df.expect_column_values_to_not_be_null("sales_amount")
ge_df.expect_column_values_to_be_between("profit", min_value=0, max_value=1000000)

# 验证期望
results = ge_df.validate()

# 如果有失败的期望,发送告警
if not results["success"]:
    send_alert("ADS层数据质量异常")

4. 文档和元数据管理

除了数据字典,我们还需要维护完整的文档,包括数据血缘关系、更新周期、用户指南等。可以使用专门的元数据管理工具,如Apache Atlas:

import pyatlas

# 连接Atlas服务
client = pyatlas.AtlasClient('http://atlas-server:21000', ('username', 'password'))

# 创建ADS层表的元数据
table_metadata = {
    "name": "fact_sales",
    "description": "销售事实表",
    "owner": "data_team",
    "createTime": int(time.time() * 1000),
    "updateFrequency": "daily",
    "columns": [
        {"name": "sale_id", "type": "bigint", "comment": "销售记录唯一标识"},
        {"name": "date_key", "type": "int", "comment": "日期维度外键"},
        # ... 其他列 ...
    ]
}

# 将元数据注册到Atlas
client.entity.create(data=table_metadata)

5. 性能调优

随着数据量的增长和查询复杂度的提高,我们需要不断对ADS层进行性能调优:

  1. 使用查询分析工具识别慢查询:
SELECT 
    query,
    calls,
    total_time,
    mean_time,
    rows
FROM 
    pg_stat_statements
ORDER BY 
    total_time DESC
LIMIT 10;
  1. 对慢查询进行优化,可能的措施包括:

    • 调整查询逻辑
    • 添加或修改索引
    • 调整分区策略
    • 使用物化视图
    • 增加预计算步骤
  2. 定期进行表统计信息更新:

ANALYZE fact_sales;
  1. 考虑使用列式存储或内存数据库来提升OLAP性能

6. 数据生命周期管理

image.png

ADS层的数据并非永久保存,我们需要制定合理的数据生命周期管理策略:

  1. 定义数据保留期限,例如:

    • 详细数据保留1年
    • 月度汇总数据保留5年
    • 年度汇总数据永久保留
  2. 实现自动归档和清理机制:

-- 将1年前的数据移动到归档表
INSERT INTO fact_sales_archive
SELECT * FROM fact_sales
WHERE date_key < DATE_PART('year', CURRENT_DATE) - 1;

-- 删除1年前的数据
DELETE FROM fact_sales
WHERE date_key < DATE_PART('year', CURRENT_DATE) - 1;
  1. 提供数据恢复机制,以应对误删或特殊查询需求

7. 持续优化和迭代

image.png

ADS层的建设是一个持续优化的过程,我们需要:

  1. 定期与业务方沟通,了解新的分析需求
  2. 收集用户反馈,识别痛点和改进机会
  3. 跟踪技术发展,适时引入新的工具和方法
  4. 进行A/B测试,验证优化措施的效果

例如,我们可以通过以下方式收集和分析用户查询模式:

CREATE TABLE query_log (
    query_id SERIAL PRIMARY KEY,
    user_id INT,
    query_text TEXT,
    execution_time INTERVAL,
    row_count INT,
    timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE OR REPLACE FUNCTION log_query()
RETURNS TRIGGER AS $$
BEGIN
    INSERT INTO query_log (user_id, query_text, execution_time, row_count)
    VALUES (CURRENT_USER, TG_ARGV[0], NEW.total_exec_time, NEW.rows);
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER log_query_trigger
AFTER INSERT ON pg_stat_statements
FOR EACH ROW
EXECUTE FUNCTION log_query(NEW.query);

通过分析这些日志,我们可以识别出最常用的查询模式,从而针对性地进行优化。

ADS层的未来展望

image.png

随着技术的发展,ADS层也在不断演进。以下是一些值得关注的趋势:

  1. 实时数据集市

    随着实时分析需求的增加,ADS层正在向实时方向发展。例如,使用Apache Flink构建实时数据集市:

StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
StreamTableEnvironment tableEnv = StreamTableEnvironment.create(env);

// 创建实时销售流
tableEnv.executeSql("CREATE TABLE sales_stream (" +
    "sale_id BIGINT," +
    "product_id INT," +
    "customer_id INT," +
    "sale_time TIMESTAMP(3)," +
    "amount DECIMAL(10, 2)" +
    ") WITH (" +
    "'connector' = 'kafka'," +
    "'topic' = 'sales'," +
    "'properties.bootstrap.servers' = 'localhost:9092'," +
    "'format' = 'json'" +
    ")");

// 创建实时销售汇总视图
tableEnv.executeSql("CREATE VIEW real_time_sales AS " +
    "SELECT " +
    "TUMBLE_START(sale_time, INTERVAL '1' MINUTE) AS window_start, " +
    "product_id, " +
    "SUM(amount) AS total_sales, " +
    "COUNT(DISTINCT customer_id) AS unique_customers " +
    "FROM sales_stream " +
    "GROUP BY TUMBLE(sale_time, INTERVAL '1' MINUTE), product_id");

// 将结果写入到Elasticsearch
tableEnv.executeSql("CREATE TABLE es_sales (" +
    "window_start TIMESTAMP(3)," +
    "product_id INT," +
    "total_sales DECIMAL(10, 2)," +
    "unique_customers BIGINT" +
    ") WITH (" +
    "'connector' = 'elasticsearch-7'," +
    "'hosts' = 'http://localhost:9200'," +
    "'index' = 'real_time_sales'" +
    ")");

tableEnv.executeSql("INSERT INTO es_sales SELECT * FROM real_time_sales");

env.execute("Real-time Sales Analysis");
  1. 机器学习集成

    ADS层正在与机器学习模型更紧密地集成,实现更智能的数据分析。例如,使用MLflow管理机器学习模型:

import mlflow
import mlflow.sklearn
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_squared_error

# 加载ADS层数据
X, y = load_ads_data()

# 训练模型
model = RandomForestRegressor(n_estimators=100)
model.fit(X, y)

# 记录模型性能
mse = mean_squared_error(y, model.predict(X))
mlflow.log_metric("mse", mse)

# 保存模型
mlflow.sklearn.log_model(model, "random_forest_model")
  1. 图数据模型

    对于复杂关系的分析,图数据模型正在成为ADS层的有力补充。例如,使用Neo4j构建客户关系图:

// 创建客户节点
LOAD CSV WITH HEADERS FROM 'file:///customers.csv' AS row
CREATE (:Customer {id: toInteger(row.customer_id), name: row.customer_name})

// 创建产品节点
LOAD CSV WITH HEADERS FROM 'file:///products.csv' AS row
CREATE (:Product {id: toInteger(row.product_id), name: row.product_name})

// 创建购买关系
LOAD CSV WITH HEADERS FROM 'file:///purchases.csv' AS row
MATCH (c:Customer {id: toInteger(row.customer_id)})
MATCH (p:Product {id: toInteger(row.product_id)})
CREATE (c)-[:PURCHASED {date: date(row.purchase_date), amount: toFloat(row.amount)}]->(p)

// 查询客户的购买网络
MATCH (c:Customer {name: 'John Doe'})-[:PURCHASED]->(p:Product)<-[:PURCHASED]-(other:Customer)
RETURN c, p, other
  1. 自然语言查询接口

    为了让业务用户更容易访问ADS层数据,自然语言查询接口正在兴起。例如,使用OpenAI的GPT模型构建自然语言到SQL的转换:

import openai

openai.api_key = 'your-api-key'

def nl_to_sql(nl_query):
    prompt = f"将以下自然语言查询转换为SQL:\n{nl_query}\n\nSQL查询:"
    response = openai.Completion.create(
        engine="text-davinci-002",
        prompt=prompt,
        max_tokens=150
    )
    return response.choices[0].text.strip()

# 使用示例
nl_query = "显示过去30天销售额最高的5个产品"
sql_query = nl_to_sql(nl_query)
print(sql_query)

结语

构建一个优秀的ADS层是一项复杂而富有挑战性的工作,它需要我们深入理解业务需求,精通数据建模技术,并且能够灵活运用各种数据库优化策略。一个设计良好的ADS层不仅能够提供高性能的数据服务,还能够真正释放数据的价值,为企业决策提供强有力的支持。

在大数据和人工智能快速发展的今天,ADS层正在向着更实时、更智能、更易用的方向演进。作为数据从业者,我们需要不断学习和实践,才能在这个充满机遇和挑战的领域中保持竞争力。

希望本文能为您构建ADS层提供一些有价值的思路和方法。记住,没有一劳永逸的解决方案,最好的ADS层是那些能够不断适应业务需求变化、持续优化改进的数据应用层。让我们一起努力,构建能够真正驱动业务价值的数据仓库ADS层!

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

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

相关文章

2024年全国青少信息素养大赛python编程复赛集训第十一天编程题分享

整理资料解析答案非常不容易,感谢各位大佬给个点赞和分享吧,谢谢 今天题目较简单:适合小学组 大家如果不想阅读前边的比赛内容介绍,可以直接跳过:拉到底部看集训题目 (一)比赛内容: 【小学组】 1.了解输入与输出的概念,掌握使用基本输入输出和简单运算 为主的标准…

归并排序+堆,P1631 序列合并

一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 序列合并 - 洛谷 二、解题报告 1、思路分析 不难想到 a[0] b[0] < a[0] b[1] < a[0] b[2] < ... < a[0] b[n - 1] a[1] b[0] < a[1] b[1] < a[1] b[2] < ... < a[1] b[n…

如何拯救LoRA初始化?LoRA-GA:性能显著提升+收敛速度更快!

文章链接&#xff1a;https://arxiv.org/pdf/2407.05000 亮点直击 提出了 LoRA-GA&#xff0c;一种新颖的 LoRA 初始化方法&#xff0c;通过近似低秩矩阵的梯度与全权重矩阵的梯度来加速收敛。确定了在非零初始化下的缩放因子&#xff0c;该因子确保适配器输出的方差不受适配器…

PCIe学习笔记(17)

延迟容忍报告(LTR)消息 LTR消息可选地用于报告有关其读/写服务延迟容忍度的设备行为。 &#xff08;通过 LTR&#xff0c;PCIe 设备可以告知系统它们能容忍的最大响应延迟是多少&#xff0c;只要系统在这个时间之内对 PCIe 设备提出的请求做出响应即可。&#xff09; LTR消息…

统信UOS微信常见问题

统信UOS微信常见问题 1. 家庭版如何激活&#xff1f; ①注册Union ID账号 ②绑定微信 ③登录Union ID激活系统 2. 应用商店微信qq下载失败&#xff0c;进行系统更新&#xff0c;提示依赖错误&#xff0c;检查更新失败怎么解决&#xff1f; 问题描述 安装应用商店内的应用无法…

【Linux操作系统】关于深度睡眠与浅度睡眠进程的理解

目录 一、可中断的睡眠状态&#xff08;S浅度睡眠状态&#xff09;二、不可中断的睡眠状态&#xff08;D深度睡眠状态&#xff09;三、关于S浅度睡眠状态与D深度睡眠状态的理解 一、可中断的睡眠状态&#xff08;S浅度睡眠状态&#xff09; S&#xff08;sleeping&#xff09;…

利用阿里云镜像仓库创建属于自己的私有镜像仓库

阿里云官网&#xff1a;https://www.aliyun.com/ 在阿里云官网注册账号&#xff0c;然后进入控制台 选择容器镜像服务 创建命名空间 创建镜像仓库 选择命名空间&#xff0c;仓库类型&#xff08;设为私有的话&#xff0c;镜像不能随意拉取&#xff09; 点管理 按以下步骤将…

炒黑豆:营养与美味的黑色宝藏

在众多的美食中&#xff0c;炒黑豆宛如一颗低调的黑色珍珠&#xff0c;散发着独特的魅力。食家巷炒黑豆&#xff0c;看似简单&#xff0c;却蕴含着不简单的营养价值。黑豆本身富含蛋白质、维生素、矿物质等多种营养成分&#xff0c;经过炒制之后&#xff0c;其香味被进一步激发…

(javaweb)Http协议

目录 一.http概述 二.Http-请求协议 三.Http响应协议 四.Http协议解析 一.http概述 ---复制这个位置会自动前面有http 浏览器给服务器发送请求携带请求数据&#xff0c;服务器解析数据&#xff0c;服务器前提需要知道具体格式等等--约定 服务器处理完请求&#xff0c;需要给…

jpg图片怎么批量转为png?jpg图片批量转为png的几种方法

jpg图片怎么批量转为png&#xff1f;在处理大批量的jpg图片&#xff0c;并将它们转换为png格式时&#xff0c;选择合适的工具和策略至关重要。这种转换通常涉及到不同的应用场景和需求&#xff0c;例如在网页设计中需要透明背景&#xff0c;或者在打印工作中需要更高的图像质量…

AOP学习

AOP概述 AOP&#xff08;Aspect Oriented Programming&#xff09;&#xff1a;⾯向切⾯编程&#xff0c;它是⼀种思想&#xff0c;它是对某⼀类事情的集中处理。 什么是SpringAOP? ⽽ AOP 是⼀种思想&#xff0c;⽽ Spring AOP 是⼀个框架&#xff0c;提供了⼀种对 AOP 思…

速看!2025第三届深圳国际生态环境监测产业博览会

2025第三届深圳国际生态环境监测产业博览会 展会主题&#xff1a;生态环境智慧监测创新&#xff0c;助力生态环境高水平保护 展会时间&#xff1a;2025年7月24-26日 展会地点&#xff1a;深圳会展中心&#xff08;福田&#xff09; 主办单位&#xff1a; 广东省环境监测协…

Flutter 学习之旅

本文只针对个人学习所遇问题&#xff0c;以及解决方案进行记录&#xff0c;不深刨原理。 不深刨原理是因为我也才开始学习&#xff0c;讲不明白&#xff0c;有可能还误导大家 &#xff0c;希望多多包涵。 问题一&#xff1a; 如何通过appBar去设置状态栏字体颜色以及状态栏透…

关于消息队列,共享内存相关作业

1>使用消息队列完成两个进程之间相互通信 1.c #include<myhead.h> //消息类型 struct msgbuf {long mtype; //消息类型char mtext[1024];//消息数据 }; #define SIZE sizeof(struct msgbuf)-sizeof(long) int main(int argc, const char *argv[]) {//创建一个进程pid…

虚拟机能访问网页但ping不通百度

最近遇到了奇怪的问题&#xff0c;虚拟机能访问网页&#xff0c;但ping不通百度&#xff0c;记录一下问题的排查过程。 能访问网页&#xff0c;说明DNS、TCP和HTTP没有问题&#xff0c;ping不通&#xff0c;说明ICMP应该出了问题。 首先通过traceroute追踪报文的转发过程&…

算法板子:最短路问题——包含朴素Dijkstra算法、堆优化版的Dijkstra算法、SPFA算法、Floyd算法

目录 1. 几种算法的用途2. Dijkstra算法——求源点到其他所有点的最短路径(不能处理负边权)&#xff08;1&#xff09;朴素Dijkstra算法——适用于稠密图&#xff08;2&#xff09;堆优化版的Dijkstra算法——适用于稀疏图 4. SPFA算法——求源点到其他所有点的最短路径、判断是…

孤独行走的视频素材去哪里找?孤独的人的视频素材哪里找啊

在视频创作和情感表达的项目中&#xff0c;选择合适的孤独行走视频素材尤为重要&#xff0c;因为这种素材能够有效传递人物的情绪状态&#xff0c;增强作品的情感层次。下面将介绍几个优质的视频素材平台&#xff0c;以帮助您更方便地寻找到适合表达孤独与深思的高质量视频素材…

C#基础——泛型

泛型 C# 中的泛型是一种强大的编程特性&#xff0c;它允许你编写类型安全且灵活的代码。泛型允许你定义类、结构体、接口、方法和委托&#xff0c;而不必在编译时指定具体的数据类型。相反&#xff0c;你可以使用类型参数来定义泛型类型或方法&#xff0c;然后在使用时指定具体…

免费的SD-WAN服务

SD-WAN&#xff0c;SASE&#xff0c;零信任是近年来比较火的概念&#xff0c;SD-WAN发展已经很久了&#xff0c;但是真正能够自主研发做SD-WAN的企业其实并不算太多。 比扬云的SD-WAN产品是自主研发的&#xff0c;可控性强&#xff0c;最重要的是具有免费版本&#xff0c;可以免…

C#使用NPOI进行Excel和Word文件处理(二)

文章目录 使用NPOI在C#中处理Excel和Word文件1. 什么是NPOI&#xff1f;2. 安装NPOI2.1 VisualStudio2019引入NPOI 3. 处理Excel文件读取Excel文件写入Excel文件 4. 处理Word文件读取Word文件写入Word文件 总结Github 地址链接参考例子 使用NPOI在C#中处理Excel和Word文件 在C…