基于 Flink 的淘寶實時數據管道設計:商品詳情流式處理與異構存儲

引言

在電子商務領域,實時數據處理能力已成為企業核心競爭力的重要組成部分。淘寶作為中國領先的電商平臺,每天產生海量的商品數據,這些數據需要被實時處理、分析并分發到各種存儲系統中,以支持搜索、推薦、庫存管理等關鍵業務。本文將介紹基于 Apache Flink 構建的淘寶商品詳情實時數據管道,探討其架構設計、核心技術實現及異構存儲集成方案。

系統架構設計

淘寶商品詳情實時數據管道采用分層架構設計,主要包含以下幾個部分:

  1. 數據采集層:負責從各個業務系統采集商品詳情數據,主要通過 Canal 監聽 MySQL binlog 和業務應用直接發送消息到 Kafka 實現
  2. 數據處理層:基于 Apache Flink 進行實時數據清洗、轉換、富集和計算
  3. 數據存儲層:將處理后的數據分發到異構存儲系統,包括 Elasticsearch(搜索)、Redis(緩存)、MySQL(交易數據)和 HBase(歷史歸檔)
  4. 監控告警層:監控整個數據管道的運行狀態,及時發現并告警異常情況

架構圖如下:

業務系統 → Kafka(接入層) → Flink(處理層) → 異構存儲層(ES/Redis/MySQL/HBase)↓監控告警系統

核心技術實現

1. 環境準備與依賴配置

首先需要配置 Flink 項目依賴,主要包括 Flink 核心依賴、Kafka 連接器、各類存儲系統連接器等。

<dependencies><!-- Flink Core --><dependency><groupId>org.apache.flink</groupId><artifactId>flink-java</artifactId><version>1.14.4</version></dependency><dependency><groupId>org.apache.flink</groupId><artifactId>flink-streaming-java_2.12</artifactId><version>1.14.4</version></dependency><!-- Kafka Connector --><dependency><groupId>org.apache.flink</groupId><artifactId>flink-connector-kafka_2.12</artifactId><version>1.14.4</version></dependency><!-- Elasticsearch Connector --><dependency><groupId>org.apache.flink</groupId><artifactId>flink-connector-elasticsearch7_2.12</artifactId><version>1.14.4</version></dependency><!-- Redis Connector --><dependency><groupId>org.apache.flink</groupId><artifactId>flink-connector-redis_2.12</artifactId><version>1.1.5</version></dependency><!-- JDBC Connector for MySQL --><dependency><groupId>org.apache.flink</groupId><artifactId>flink-connector-jdbc_2.12</artifactId><version>1.14.4</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.28</version></dependency><!-- HBase Connector --><dependency><groupId>org.apache.flink</groupId><artifactId>flink-connector-hbase-2.2_2.12</artifactId><version>1.14.4</version></dependency><!-- JSON Processing --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.79</version></dependency>
</dependencies>

2. 商品數據模型定義

定義商品詳情的數據模型,包含淘寶商品的核心屬性:

import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;public class ProductDetail {// 商品IDprivate Long productId;// 商品名稱private String productName;// 商品價格private BigDecimal price;// 商品分類IDprivate Long categoryId;// 商品分類名稱private String categoryName;// 商品描述private String description;// 商品圖片URL列表private String[] imageUrls;// 商品屬性鍵值對private Map<String, String> attributes;// 庫存數量private Integer stock;// 銷量private Integer salesCount;// 商家IDprivate Long sellerId;// 商家名稱private String sellerName;// 上架時間private Date上架Time;// 數據更新時間private Date updateTime;// 數據來源private String dataSource;// 構造函數、getter和setter方法public ProductDetail() {}// Getters and Setterspublic Long getProductId() {return productId;}public void setProductId(Long productId) {this.productId = productId;}public String getProductName() {return productName;}public void setProductName(String productName) {this.productName = productName;}// 其他屬性的getter和setter方法省略...@Overridepublic String toString() {return "ProductDetail{" +"productId=" + productId +", productName='" + productName + '\'' +", price=" + price +", updateTime=" + updateTime +'}';}
}

3. 實時數據管道核心實現

下面是基于 Flink 的商品詳情實時數據管道核心代碼實現,包括數據讀取、處理和寫入異構存儲系統:

import org.apache.flink.api.common.functions.FilterFunction;
import org.apache.flink.api.common.functions.MapFunction;
import org.apache.flink.api.common.serialization.SimpleStringSchema;
import org.apache.flink.configuration.Configuration;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.connectors.elasticsearch.ElasticsearchSinkFunction;
import org.apache.flink.streaming.connectors.elasticsearch.RequestIndexer;
import org.apache.flink.streaming.connectors.elasticsearch7.ElasticsearchSink;
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer;
import org.apache.flink.streaming.connectors.redis.RedisSink;
import org.apache.flink.streaming.connectors.redis.common.config.FlinkJedisPoolConfig;
import org.apache.flink.streaming.connectors.redis.common.mapper.RedisCommand;
import org.apache.flink.streaming.connectors.redis.common.mapper.RedisCommandDescription;
import org.apache.flink.streaming.connectors.redis.common.mapper.RedisMapper;
import org.apache.flink.streaming.api.functions.sink.RichSinkFunction;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.flink.connector.jdbc.JdbcConnectionOptions;
import org.apache.flink.connector.jdbc.JdbcSink;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.client.Requests;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;public class ProductDataPipeline {public static void main(String[] args) throws Exception {// 1. 初始化Flink執行環境final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();env.enableCheckpointing(5000); // 每5秒觸發一次checkpoint// 2. 配置Kafka消費者Properties kafkaProps = new Properties();kafkaProps.setProperty("bootstrap.servers", "kafka-broker1:9092,kafka-broker2:9092");kafkaProps.setProperty("group.id", "product-detail-consumer-group");// 3. 從Kafka讀取商品詳情數據FlinkKafkaConsumer<String> kafkaConsumer = new FlinkKafkaConsumer<>("taobao-product-detail",  // Kafka主題new SimpleStringSchema(), // 反序列化器kafkaProps);// 設置從最早位置開始消費kafkaConsumer.setStartFromEarliest();// 創建輸入數據流DataStream<String> rawDataStream = env.addSource(kafkaConsumer);// 4. 數據轉換:JSON字符串 -> ProductDetail對象DataStream<ProductDetail> productStream = rawDataStream.map(new MapFunction<String, ProductDetail>() {@Overridepublic ProductDetail map(String jsonString) throws Exception {// 解析JSON字符串JSONObject json = JSON.parseObject(jsonString);// 轉換為ProductDetail對象ProductDetail product = new ProductDetail();product.setProductId(json.getLong("productId"));product.setProductName(json.getString("productName"));product.setPrice(json.getBigDecimal("price"));product.setCategoryId(json.getLong("categoryId"));product.setCategoryName(json.getString("categoryName"));product.setDescription(json.getString("description"));product.setImageUrls(json.getJSONArray("imageUrls").toArray(new String[0]));product.setAttributes(json.getObject("attributes", Map.class));product.setStock(json.getInteger("stock"));product.setSalesCount(json.getInteger("salesCount"));product.setSellerId(json.getLong("sellerId"));product.setSellerName(json.getString("sellerName"));product.set上架Time(json.getDate("上架Time"));product.setUpdateTime(json.getDate("updateTime"));product.setDataSource(json.getString("dataSource"));return product;}})// 過濾無效數據.filter(new FilterFunction<ProductDetail>() {@Overridepublic boolean filter(ProductDetail product) throws Exception {return product.getProductId() != null && product.getProductName() != null && product.getPrice() != null;}});// 5. 數據處理:補充商品分類路徑信息DataStream<ProductDetail> enrichedProductStream = productStream.map(new MapFunction<ProductDetail, ProductDetail>() {private Map<Long, String> categoryPathMap;@Overridepublic void open(Configuration parameters) throws Exception {super.open(parameters);// 實際應用中,這里可能從數據庫或緩存加載分類路徑信息categoryPathMap = new HashMap<>();categoryPathMap.put(1001L, "服飾鞋包>女裝>連衣裙");categoryPathMap.put(1002L, "電子數碼>手機>智能手機");// ... 更多分類}@Overridepublic ProductDetail map(ProductDetail product) throws Exception {// 補充分類路徑信息到商品屬性中String categoryPath = categoryPathMap.getOrDefault(product.getCategoryId(), "未知分類");product.getAttributes().put("categoryPath", categoryPath);return product;}});// 6. 寫入異構存儲系統// 6.1 寫入Elasticsearch(用于商品搜索)configureEsSink(enrichedProductStream);// 6.2 寫入Redis(用于熱門商品緩存)configureRedisSink(enrichedProductStream);// 6.3 寫入MySQL(用于交易和核心業務)configureMySqlSink(enrichedProductStream);// 6.4 寫入HBase(用于歷史數據歸檔)configureHBaseSink(enrichedProductStream);// 7. 執行Flink作業env.execute("Taobao Product Detail Real-time Pipeline");}/*** 配置Elasticsearch Sink*/private static void configureEsSink(DataStream<ProductDetail> productStream) {// 配置Elasticsearch節點Map<String, String> esConfig = new HashMap<>();esConfig.put("cluster.name", "taobao-es-cluster");esConfig.put("bulk.flush.max.actions", "1000");esConfig.put("hosts", "es-node1:9200,es-node2:9200");// 創建ElasticsearchSinkFunctionElasticsearchSinkFunction<ProductDetail> esSinkFunction = new ElasticsearchSinkFunction<ProductDetail>() {@Overridepublic void process(ProductDetail product, RuntimeContext ctx, RequestIndexer indexer) {// 構建索引請求Map<String, Object> json = new HashMap<>();json.put("productId", product.getProductId());json.put("productName", product.getProductName());json.put("price", product.getPrice());json.put("categoryId", product.getCategoryId());json.put("categoryName", product.getCategoryName());json.put("categoryPath", product.getAttributes().get("categoryPath"));json.put("description", product.getDescription());json.put("imageUrls", product.getImageUrls());json.put("attributes", product.getAttributes());json.put("stock", product.getStock());json.put("salesCount", product.getSalesCount());json.put("sellerId", product.getSellerId());json.put("sellerName", product.getSellerName());json.put("上架Time", product.get上架Time().getTime());json.put("updateTime", product.getUpdateTime().getTime());IndexRequest request = Requests.indexRequest().index("taobao_products").id(product.getProductId().toString()).source(json);indexer.add(request);}};// 創建并添加Elasticsearch SinkElasticsearchSink.Builder<ProductDetail> esSinkBuilder = new ElasticsearchSink.Builder<>(esConfig, esSinkFunction);productStream.addSink(esSinkBuilder.build());}/*** 配置Redis Sink*/private static void configureRedisSink(DataStream<ProductDetail> productStream) {// 配置Redis連接FlinkJedisPoolConfig redisConfig = new FlinkJedisPoolConfig.Builder().setHost("redis-node1").setPort(6379).setMaxTotal(20).build();// 創建RedisMapperRedisMapper<ProductDetail> redisMapper = new RedisMapper<ProductDetail>() {@Overridepublic RedisCommandDescription getCommandDescription() {// 使用Hash結構存儲商品信息return new RedisCommandDescription(RedisCommand.HSET, "taobao:products");}@Overridepublic String getKeyFromData(ProductDetail product) {return product.getProductId().toString();}@Overridepublic String getValueFromData(ProductDetail product) {// 將商品信息序列化為JSON字符串return JSON.toJSONString(product);}};// 創建并添加Redis SinkRedisSink<ProductDetail> redisSink = new RedisSink<>(redisConfig, redisMapper);productStream.addSink(redisSink);}/*** 配置MySQL Sink*/private static void configureMySqlSink(DataStream<ProductDetail> productStream) {// MySQL連接配置String mysqlUrl = "jdbc:mysql://mysql-node1:3306/taobao_product_db?useSSL=false";String username = "db_user";String password = "db_password";// 創建JDBC SinkproductStream.addSink(JdbcSink.sink("INSERT INTO product_details " +"(product_id, product_name, price, category_id, category_name, " +"stock, sales_count, seller_id, update_time) " +"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) " +"ON DUPLICATE KEY UPDATE " +"product_name = VALUES(product_name), price = VALUES(price), " +"category_id = VALUES(category_id), category_name = VALUES(category_name), " +"stock = VALUES(stock), sales_count = VALUES(sales_count), " +"seller_id = VALUES(seller_id), update_time = VALUES(update_time)",(PreparedStatement stmt, ProductDetail product) -> {stmt.setLong(1, product.getProductId());stmt.setString(2, product.getProductName());stmt.setBigDecimal(3, product.getPrice());stmt.setLong(4, product.getCategoryId());stmt.setString(5, product.getCategoryName());stmt.setInt(6, product.getStock());stmt.setInt(7, product.getSalesCount());stmt.setLong(8, product.getSellerId());stmt.setTimestamp(9, new java.sql.Timestamp(product.getUpdateTime().getTime()));},new JdbcConnectionOptions.JdbcConnectionOptionsBuilder().withUrl(mysqlUrl).withUsername(username).withPassword(password).withDriverName("com.mysql.cj.jdbc.Driver").build()));}/*** 配置HBase Sink*/private static void configureHBaseSink(DataStream<ProductDetail> productStream) {productStream.addSink(new RichSinkFunction<ProductDetail>() {private Connection hbaseConnection;private Table productTable;@Overridepublic void open(Configuration parameters) throws Exception {super.open(parameters);// 配置HBase連接org.apache.hadoop.conf.Configuration hbaseConfig = HBaseConfiguration.create();hbaseConfig.set("hbase.zookeeper.quorum", "zk-node1,zk-node2,zk-node3");hbaseConfig.set("hbase.zookeeper.property.clientPort", "2181");hbaseConnection = ConnectionFactory.createConnection(hbaseConfig);productTable = hbaseConnection.getTable(TableName.valueOf("taobao:product_details"));}@Overridepublic void invoke(ProductDetail product, Context context) throws Exception {// 創建HBase Put對象Put put = new Put(Bytes.toBytes(product.getProductId().toString()));// 添加列族數據put.addColumn(Bytes.toBytes("info"),Bytes.toBytes("product_name"),Bytes.toBytes(product.getProductName()));put.addColumn(Bytes.toBytes("info"),Bytes.toBytes("price"),Bytes.toBytes(product.getPrice().toString()));put.addColumn(Bytes.toBytes("info"),Bytes.toBytes("category_id"),Bytes.toBytes(product.getCategoryId().toString()));put.addColumn(Bytes.toBytes("info"),Bytes.toBytes("category_name"),Bytes.toBytes(product.getCategoryName()));put.addColumn(Bytes.toBytes("info"),Bytes.toBytes("update_time"),Bytes.toBytes(product.getUpdateTime().getTime()));// 插入數據productTable.put(put);}@Overridepublic void close() throws Exception {super.close();if (productTable != null) {productTable.close();}if (hbaseConnection != null) {hbaseConnection.close();}}});}
}

4. 數據傾斜處理與性能優化

在實際生產環境中,商品數據處理可能面臨數據傾斜問題,特別是熱門商品的更新頻率遠高于普通商品。針對這一問題,我們可以采取以下優化策略:

  1. 動態負載均衡:基于商品 ID 的哈希值動態調整 Flink 算子的并行度
  2. 熱點分離:將熱門商品與普通商品分離處理,熱門商品采用更高的并行度
  3. 異步 I/O:使用 Flink 的 Async I/O 機制優化與外部存儲系統的交互
  4. 狀態后端優化:采用 RocksDB 作為狀態后端,提高狀態管理效率
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.functions.partition.KeySelector;
import org.apache.flink.streaming.api.partitioning.FlinkPartitioner;// 優化的數據分區策略,解決熱點問題
public class OptimizedProductPartitioner implements FlinkPartitioner<ProductDetail> {private static final long serialVersionUID = 1L;// 熱門商品ID列表(實際應用中可動態加載)private static final Set<Long> HOT_PRODUCT_IDS = new HashSet<>();static {HOT_PRODUCT_IDS.add(100001L);HOT_PRODUCT_IDS.add(100002L);// 更多熱門商品ID...}@Overridepublic int partition(ProductDetail product, int numPartitions) {// 對于熱門商品,使用更多的分區來分散負載if (HOT_PRODUCT_IDS.contains(product.getProductId())) {// 熱門商品使用后半部分的分區int hotStartPartition = numPartitions / 2;return hotStartPartition + (int)(product.getProductId() % (numPartitions - hotStartPartition));} else {// 普通商品使用前半部分的分區return (int)(product.getProductId() % (numPartitions / 2));}}
}// 在主程序中應用優化的分區策略
public class ProductDataPipelineOptimized {public static void main(String[] args) throws Exception {// 初始化環境...(同上)// 應用優化的分區策略DataStream<ProductDetail> rebalancedStream = enrichedProductStream.partitionCustom(new OptimizedProductPartitioner(), new KeySelector<ProductDetail, Long>() {@Overridepublic Long getKey(ProductDetail product) throws Exception {return product.getProductId();}});// 設置更高的并行度處理熱門商品rebalancedStream.setParallelism(16);// 寫入存儲系統...(同上)env.execute("Optimized Taobao Product Detail Pipeline");}
}

監控與運維

為確保數據管道的穩定運行,需要建立完善的監控體系:

  1. Flink metrics 監控:監控作業的吞吐量、延遲、Checkpoint 成功率等關鍵指標
  2. 數據質量監控:對輸入輸出數據進行抽樣檢查,確保數據完整性和準確性
  3. 告警機制:當出現異常時(如數據延遲超過閾值、處理失敗率上升等),通過郵件、短信等方式及時告警
  4. 自動恢復:配置 Flink 的 Savepoint 機制,在作業失敗時能夠快速恢復

結論與展望

基于 Flink 的淘寶商品詳情實時數據管道實現了商品數據的實時采集、處理和分發,滿足了電商平臺對實時性的高要求。通過異構存儲系統的集成,能夠同時支持搜索、推薦、交易等多種業務場景。

未來,我們將在以下方面進行優化和擴展:

  1. 智能化路由:基于商品特性和業務需求,實現數據的智能路由和存儲選擇
  2. 流批一體:構建流批一體的數據處理架構,簡化數據鏈路
  3. 實時分析:集成實時分析能力,支持商品熱度、趨勢等實時指標計算
  4. 多租戶支持:優化架構以支持多租戶模式,滿足不同業務部門的個性化需求

該數據管道架構不僅適用于淘寶的商品詳情處理,也可以推廣到其他電商平臺或需要實時處理異構數據的業務場景中。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/95572.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/95572.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/95572.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

面試題:【多線程問題,三個線程A,B,C;C線程依賴B線程的結果執行,怎么控制】

在 Java 中&#xff0c;若需要控制線程間的依賴關系&#xff08;如 C 線程依賴 B 線程的結果&#xff09;&#xff0c;可以通過以下幾種方式實現&#xff1a; 方案 1&#xff1a;使用 CountDownLatch CountDownLatch 是一個同步工具類&#xff0c;允許一個或多個線程等待其他線…

React useMemo 深度指南:原理、誤區、實戰與 2025 最佳實踐

把“為什么用、怎么用、用錯了怎么辦”一次講透&#xff0c;附 React 19 自動優化前瞻。一、useMemo 是什么&#xff1f; 一句話&#xff1a; useMemo 記住&#xff08;緩存&#xff09;昂貴計算結果&#xff0c;只在依賴變化時重新計算。 const memoValue useMemo(() > {…

[ HTML 前端 ] 語法介紹和HBuilderX安裝

目錄 一. HTML 1.概述 2. 安裝前端開發工具 (1)HBuilderX下載 (2)創建html項目和使用 3. HTML基礎 1.標簽 (1).標簽定義: (2).標簽結構: (3).標簽屬性: 2.常用標簽: 3.特殊符號: 4.表格(table) (1)基本標簽: (2)基本結構: (3)表格屬性: 5.表單(form) (1). 表單概述…

Spring Cloud系列—Alibaba Sentinel熔斷降級

上篇文章&#xff1a; Spring Cloud系列— Alibaba Sentinel限流https://blog.csdn.net/sniper_fandc/article/details/149944260?fromshareblogdetail&sharetypeblogdetail&sharerId149944260&sharereferPC&sharesourcesniper_fandc&sharefromfrom_link…

Spring Boot 使用 @NotBlank + @Validated 優雅校驗參數

在日常開發中&#xff0c;我們常用 if (isBlank(...)) 來判斷參數是否為空&#xff0c;但這種方式不僅繁瑣&#xff0c;而且容易遺漏。 Spring 生態中推薦使用 JSR-303 校驗注解&#xff08;NotBlank、NotNull 等&#xff09;配合 Validated 實現自動校驗&#xff0c;大幅減少手…

網絡安全(Java語言)簡單腳本匯總 (一)

文章目錄敏感信息探測腳本源代碼思路URL批量存活探測器源代碼思路端口掃描器源代碼思路 敏感信息探測腳本 源代碼/*** description 該腳本通過分析HTTP響應頭&#xff0c;來檢測可能暴露服務器信息的安全隱患*/import java.io.IOException; import java.net.HttpURLConnection;…

buuctf_NSBlogin_http_upload(極客2019+ACTF2020新生賽)

今天做三1個web 題目&#xff1a;NSB_login用戶名有admin&#xff0c;看源碼&#xff1a;I like rockyou&#xff01;今天學習到&#xff0c;kali里面有密碼爆破的文件叫rockyou.txt&#xff08;/usr/share/wordlists/&#xff09;&#xff08;沒kali也可以去https://gitcode.c…

IDEA如何引用brew安裝的openjdk

因為 brew 安裝的 openjdk@21 目錄結構和 IDEA 期望的 JDK 目錄不一樣。所以默認brew安裝的jdk,在IDEA中是無法識別到的。 一、創建軟連接 sudo mkdir -p /Library/Java/JavaVirtualMachines sudo ln -sfn /usr/local/opt/openjdk@21/libexec/openjdk.jdk /Library/Java/Java…

【Unity3D】Spine黑線(預乘問題)、貼圖邊緣裁剪問題

一、黑線問題 Spine正確的導出和Unity導入設置&#xff08;解決黑邊/彩條帶問題&#xff09;_spine導出的圖片有黑邊-CSDN博客 采用&#xff08;已解決問題&#xff09; Texture 打包器啟用 Premultiply alpha ,禁用Bleed Unity Texture 設置中禁用 sRGB (Color Texture) 和…

嵌入式系統學習Day18(文件編程-系統調用文件IO)

- open#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h>int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode); 功能:打開文件 參數:pathname --- 文件名 flags 必選:O_RDONLYO_WRONLY…

Vue淺學

概述在最近的學習任務中了解了 Vue&#xff0c;并對其產生了濃厚的興趣&#xff0c;現在分享一下我的學習所得關鍵字其一statestate 是 Vuex 存儲中的“狀態對象”&#xff0c;用于存儲整個應用的共享數據&#xff08;如用戶信息、令牌、權限等&#xff09;&#xff0c;比如&am…

機器翻譯:Hugging Face庫詳解

文章目錄一、Hugging Face概述1.1 Hugging Face介紹1.2 核心理念&#xff1a;模型即服務&#xff0c;但以開源形式二、核心架構2.1 Transformers庫&#xff1a;模型交互的統一接口2.2 Datasets庫&#xff1a;高效的數據處理引擎2.3 Tokenizers庫&#xff1a;文本與模型的“翻譯…

服務器安裝gielab社區版

第一步&#xff1a;安裝Gitlab 1,使用的是CentOs鏡像(服務器最低配置為4核8g內存才行要不然帶不動) 登錄目標實例。 2,執行如下命令&#xff0c;安裝所需依賴。 1 sudo yum install -y curl policycoreutils-python openssh-server 3,執行如下命令&#xff0c;啟動SSH服務…

C#報錯:System.NullReferenceException:“未將對象引用設置到對象的實例。”

C#使用自定義的類創建數組時&#xff0c;使用時報錯&#xff0c;報錯內容如下圖&#xff1a;原因&#xff1a;C#中的數組是引用類型。當聲明自定義類數組時&#xff0c;數組本身會被創建&#xff0c;但其元素&#xff08;即自定義類的實例&#xff09;默認未被實例化&#xff0…

Maven 的 module 管理

一、Maven 的 module 管理 1. 什么是 Maven module&#xff1f; Maven module&#xff08;模塊&#xff09;&#xff0c;是 Maven 多模塊項目結構&#xff08;multi-module project&#xff09;中的核心概念。它允許你將一個大型項目拆分為若干獨立的小項目&#xff08;模塊&am…

現在都是APP,小程序搶購,支持瀏覽器不支持 SSE

在 APP 和小程序搶購場景中&#xff0c;通常不原生支持SSE&#xff08;Server-Sent Events&#xff09;&#xff0c;這與瀏覽器對 SSE 的支持情況不同&#xff0c;具體如下&#xff1a;APP&#xff1a;一般情況下&#xff0c;APP 端不支持原生 SSE。若使用 UniApp 開發&#xf…

Spring Boot 深度解析:從原理到實踐

一、Spring Boot 本質與核心價值 1.1 什么是 Spring Boot&#xff1f; Spring Boot 是 Spring 生態的革命性框架&#xff0c;旨在解決傳統 Spring 開發的復雜性。它通過"約定優于配置"&#xff08;Convention Over Configuration&#xff09;理念&#xff0c;提供開箱…

WebSocket-java篇

問題引入消息推送的方式我們要實現&#xff0c;服務器把消息推送到客戶端&#xff0c;可以輪訓&#xff0c;長輪訓還有sseWebSocket理論WebSocket 的由來與核心價值誕生背景&#xff1a;解決 HTTP 協議在實時通信中的固有缺陷&#xff08;單向請求-響應模式&#xff09;核心驅動…

用Python從零開始實現神經網絡

反向傳播算法用于經典的前饋人工神經網絡。 它仍然是訓練大型深度學習網絡的技術。 在這個教程中&#xff0c;你將學習如何用Python從頭開始實現神經網絡的反向傳播算法。 完成本教程后&#xff0c;您將了解&#xff1a; 如何將輸入前向傳播以計算輸出。如何反向傳播錯誤和…

算法148. 排序鏈表

題目&#xff1a;給你鏈表的頭結點 head &#xff0c;請將其按 升序 排列并返回 排序后的鏈表 。示例 1&#xff1a;輸入&#xff1a;head [4,2,1,3] 輸出&#xff1a;[1,2,3,4] 示例 2&#xff1a;輸入&#xff1a;head [-1,5,3,4,0] 輸出&#xff1a;[-1,0,3,4,5] 示例 3&a…