实现秒传与限速!深度解析万亿GB网盘系统架构

1. 系统需求与挑战

1.1 DBox核心功能

在设计一个面向万亿GB的网盘系统时,我们需要首先明确系统的核心功能需求。DBox 作为一个高并发、高可靠的网盘系统,核心功能需求主要包括以下几点:

  • 海量存储:支持存储海量数据,满足用户上传和下载需求。
  • 秒传功能:快速上传相同文件,避免重复存储和传输相同内容。
  • 限速功能:根据用户权限进行上传和下载速度的限制。
  • 高可用性:系统在任何时候都能提供服务,确保文件的安全性与可用性。
  • 数据安全性:提供文件的加密存储与传输,支持多方式的权限控制。

1.2 用户需求与使用场景

用户对网盘系统的需求主要体现在以下几个使用场景:

  • 个人用户:用于存储个人文件,实现数据备份和跨设备访问。个人用户对存储空间的需求相对较小,但对共享和便捷访问的要求较高。
  • 企业用户:需要存储和管理团队文件,支持多人协作和版本控制。企业用户通常需要较大的存储空间和更高的数据安全性。
  • 开发者与应用:一些开发者和应用服务使用网盘作为存储后端,要求提供丰富的API支持、高性能和稳定性。

1.3 面临的主要技术挑战

实现这样一个大规模网盘系统,面临以下几方面的技术挑战:

  • 大规模存储与管理:如何管理和存储海量数据,以及确保这些数据的高可用和可靠性。
  • 高并发访问:面对大量用户同时上传和下载文件,系统需要具备高并发处理能力。
  • 秒传与去重:如何快速判断文件是否已存在,并避免重复存储相同的文件。
  • 精细化限速:根据用户等级、文件类型等因素设置灵活的限速策略。
  • 数据一致性与安全性:在多副本存储和分布式环境下,确保数据的一致性和传输的安全性。

2. 如何实现秒传

2.1 MD5 hash判断文件是否存在

秒传的核心在于判定用户上传的文件是否已经存在于系统中。在用户上传文件时,首先计算文件的MD5值,因为MD5算法能够高效地生成文件的唯一标识。系统根据上传文件的MD5值,查询是否已存在同样的文件。

import java.io.FileInputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class FileMD5 {
    public static String getFileMD5(String filePath) {
        try (FileInputStream fis = new FileInputStream(filePath)) {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] dataBytes = new byte[1024];
            int bytesRead;
            
            while ((bytesRead = fis.read(dataBytes)) != -1) {
                md.update(dataBytes, 0, bytesRead);
            }
            
            byte[] mdBytes = md.digest();
            StringBuilder sb = new StringBuilder();
            for (byte b : mdBytes) {
                sb.append(String.format("%02x", b));
            }
            return sb.toString();
        } catch (IOException | NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }
    }
    
    public static void main(String[] args) {
        String filePath = "path/to/your/file";
        System.out.println("MD5: " + getFileMD5(filePath));
    }
}

2.2 文件块(Block)的设计与管理

为了支持大文件的秒传和部分文件更新,文件按块(Block)进行管理。每个块都有一个唯一的标识,上传时分块计算其MD5值,每个块的MD5值存入数据库。

块存储设计:

  • Block表:存放每个块的数据与相关信息。
  • 文件块索引表:记录文件与块的对应关系,方便管理和查找。
CREATE TABLE Block (
  BlockID CHAR(32) PRIMARY KEY,
  Data BLOB,
  Size INT,
  MD5 CHAR(32)
);

CREATE TABLE FileBlockMapping (
  FileID CHAR(32),
  BlockID CHAR(32),
  BlockIndex INT,
  PRIMARY KEY (FileID, BlockID, BlockIndex)
);

2.3 从MD5到更严格判断

单纯依赖MD5可能存在碰撞风险,系统可以引入SHA-256或其他方式进行更严格的文件完整性校验。

public String getFileSHA256(String filePath) {
    try (FileInputStream fis = new FileInputStream(filePath)) {
        MessageDigest digest = MessageDigest.getInstance("SHA-256");
        byte[] dataBytes = new byte[1024];
        int bytesRead;
        
        while ((bytesRead = fis.read(dataBytes)) != -1) {
            digest.update(dataBytes, 0, bytesRead);
        }
        
        byte[] hashBytes = digest.digest();
        StringBuilder sb = new StringBuilder();
        for (byte b : hashBytes) {
            sb.append(String.format("%02x", b));
        }
        return sb.toString();
    } catch (IOException | NoSuchAlgorithmException e) {
        e.printStackTrace();
        return null;
    }
}

2.4 物理文件表和逻辑文件表的设计

物理文件表记录实际存储在系统中的文件信息,逻辑文件表记录用户对文件的操作,如文件重命名、移动等。这样设计能够有效进行文件去重,同时保留用户的操作记录。

CREATE TABLE PhysicalFiles (
  FileID CHAR(32) PRIMARY KEY,
  StoragePath VARCHAR(256),
  MD5 CHAR(32),
  SHA256 CHAR(64),
  Size INT,
  UploadTime TIMESTAMP
);

CREATE TABLE LogicalFiles (
  LogicalFileID CHAR(32) PRIMARY KEY,
  PhysicalFileID CHAR(32),
  UserID CHAR(32),
  FileName VARCHAR(256),
  UploadTime TIMESTAMP,
  CONSTRAINT FK_PhysicalFileID FOREIGN KEY (PhysicalFileID) REFERENCES PhysicalFiles(FileID)
);

3. 文件存储架构设计

3.1 元数据与文件内容的分离

在设计网盘系统时,将文件的元数据和实际文件内容进行分离非常重要。元数据包含文件名、大小、上传时间等信息,实际文件内容则是用户上传的文件数据。这种分离有利于优化访问性能,简化存储管理。

  • 元数据存储:存储在高性能数据库中,如 MySQL 或 PostgreSQL,用于快速查询。
  • 文件内容存储:存储在高可用的分布式文件系统中,如 Ceph,以确保大文件的高效存储和传输。

3.2 API服务器与Block服务器的角色

网盘系统通常由多个服务器模块组成,每个模块承担不同的职能。

  • API服务器:处理用户请求,如文件上传、下载、删除等操作。API服务器与数据库交互,管理元数据,并与Block服务器协作传输文件内容。
  • Block服务器:负责文件的数据存储和分发,处理文件的分块上传和下载。Block服务器直接与存储文件的存储系统(如Ceph)进行交互。

3.3 对象存储(Ceph)的选用理由

Ceph 是一个开源的分布式存储系统,适用于对象存储、块存储等场景。选用 Ceph 作为网盘系统的存储后端,主要基于以下几方面的考虑:

  • 高可扩展性:Ceph无中心化设计,具备良好的横向扩展能力,可以方便地增加存储节点。
  • 高可靠性:支持多副本和纠删码,可以确保数据的高可靠性。
  • 灵活性:支持对象存储、块存储和文件系统三种接口,适应不同应用场景。

3.3.1 Ceph 配置示例

global:
  fsid: {{ ceph_fsid }}
  mon_host: {{ ceph_mon_host }}
  public_network: {{ ceph_public_network }}

osd:
  osd_objectstore: bluestore

mon:
  mon_data_avail_warn: 10
  mon_clock_drift_allowed: 0.05
  mon_osd_min_down_reporters: 1

mgr:
  mgr_init_modules: dashboard

3.4 文件上传与下载的时序图

3.4.1 文件上传时序图

file

3.4.2 文件下载时序图

file

通过这种架构设计,能充分利用 API 服务器处理用户请求的高并发能力,以及 Block 服务器对大文件传输的优化,从而提供网盘系统的高效存储和传输性能。

4. 限速设计方案

4.1 用户付费类型的决定因素

首先,我们需要根据用户的付费类型和使用情况对用户进行限速。通常有以下几种用户类型:

  • 免费用户:对上传和下载速度进行严格限制,以降低系统负担。
  • 付费用户:根据付费等级提供不同的上传和下载速度。
  • 企业用户:根据合同条款提供定制化的限速服务。

针对不同类型用户,我们可以在API服务器进行请求参数的解析和速率控制。

public class User {
    private String userId;
    private UserType userType;
    private int uploadSpeed; // 单位: KB/s
    private int downloadSpeed; // 单位: KB/s

    public User(String userId, UserType userType) {
        this.userId = userId;
        this.userType = userType;
        switch (userType) {
            case FREE:
                this.uploadSpeed = 500;
                this.downloadSpeed = 500;
                break;
            case PREMIUM:
                this.uploadSpeed = 2000;
                this.downloadSpeed = 2000;
                break;
            case ENTERPRISE:
                this.uploadSpeed = 10000;
                this.downloadSpeed = 10000;
                break;
            default:
                this.uploadSpeed = 100;
                this.downloadSpeed = 100;
        }
    }
    
    // Getter and Setter methods...
}

4.2 API服务器的分配策略

API服务器在处理用户请求时需要进行流量控制,根据用户类型的不同来分配带宽和并发资源。我们可以使用令牌桶 (Token Bucket)算法实现这种控制。

public class RateLimiter {
    private final int maxTokens;
    private int currentTokens;
    private final long refillInterval;
    private long lastRefillTimestamp;

    public RateLimiter(int maxTokens, long refillInterval) {
        this.maxTokens = maxTokens;
        this.currentTokens = maxTokens;
        this.refillInterval = refillInterval;
        this.lastRefillTimestamp = System.nanoTime();
    }

    public synchronized boolean tryConsume(int tokens) {
        refill();
        if (tokens <= currentTokens) {
            currentTokens -= tokens;
            return true;
        }
        return false;
    }
    
    private void refill() {
        long now = System.nanoTime();
        long elapsed = now - lastRefillTimestamp;
        int tokensToAdd = (int) (elapsed / refillInterval);
        if (tokensToAdd > 0) {
            currentTokens = Math.min(maxTokens, currentTokens + tokensToAdd);
            lastRefillTimestamp = now;
        }
    }
}

4.3 Block服务器的并发与传输控制

Block服务器接收API服务器的请求后,需要进行传输速率控制,根据用户等级和当前的网络情况来动态调整传输速率。从技术实现上看,我们可以通过调整网络的QoS (Quality of Service) 策略以及使用传输协议中的窗口大小来控制。

public void sendFileBlock(Socket socket, byte[] data, int speedLimitKBps) throws IOException {
    OutputStream out = socket.getOutputStream();
    int chunkSize = speedLimitKBps * 1024;
    int offset = 0;
    
    while (offset < data.length) {
        int length = Math.min(chunkSize, data.length - offset);
        out.write(data, offset, length);
        out.flush();
        offset += length;
        // 每秒传输KBps限制的大小
        Thread.sleep(1000);
    }
}

对于具体实现情况,可以进一步结合网络实际情况进行性能测试与优化,确保在高并发环境下依然能够有效控制网速。

5. 系统的高并发与高可靠设计

5.1 高可用服务与高可靠存储要求

在设计网盘系统时,高可用服务和高可靠存储是两个关键要素。高可用服务涉及到系统的负载均衡、服务熔断和快速恢复,而高可靠存储则关注数据的持久性、多副本存储和数据恢复能力。

  • 高可用服务:通过负载均衡(如Nginx、HAProxy)和微服务架构,确保在服务节点故障时,系统能够快速切换,不影响用户使用。
  • 高可靠存储:通过分布式存储系统(如Ceph),确保数据多副本存储,当某个存储节点发生故障时,数据能够快速恢复。

5.2 分布式对象存储(Ceph)的高可靠

Ceph通过CRUSH算法在集群中分布数据,确保数据的高可靠性和可用性。CRUSH(Controlled, Scalable, Decentralized Placement of Replicated Data)算法控制数据存储的位置,避免集中化的单点故障。

5.2.1 Ceph的高可靠性设计包括:

  • 多副本存储:每份数据有多个副本存储在不同的节点上。
  • 纠删码:在多副本存储的基础上,进一步通过纠删码技术减少存储开销,同时保证高可靠性。
  • 自动恢复:当某个存储节点故障后,Ceph能够自动感知并将数据副本恢复到其他健康节点。

5.3 数据库的分片存储设计

为了在高并发环境下保证数据库的读写性能,使用数据库分片(Sharding)技术,将数据水平拆分到不同的数据库实例中。

CREATE TABLE UserFileShard1 (
  FileID CHAR(32) PRIMARY KEY,
  UserID CHAR(32),
  FileName VARCHAR(256),
  UploadTime TIMESTAMP
);

CREATE TABLE UserFileShard2 (
  FileID CHAR(32) PRIMARY KEY,
  UserID CHAR(38),
  FileName VARCHAR(256),
  UploadTime TIMESTAMP
);

分片策略可以基于用户ID的哈希值、文件ID前缀等多种方式。

public class ShardingService {
    private static final int SHARD_COUNT = 2;

    public int getShardIndex(String userId) {
        return userId.hashCode() % SHARD_COUNT;
    }

    public void storeFile(String userId, File file) {
        int shardIndex = getShardIndex(userId);
        // 根据 shardIndex 决定存储到哪个分片数据库
        // 存储逻辑
    }
}

5.4 查询性能优化与缓存策略

在高并发环境下,频繁的数据库查询可能成为瓶颈,通过引入缓存机制可以显著提高系统性能。常见的缓存方案包括:

  • 内存缓存:如Redis、Memcached,用于存储热门数据,减少数据库访问频次。
  • 分布式缓存:在多个节点之间共享缓存,提高系统的横向扩展能力。
// 使用Redis缓存查询结果示例
public class FileService {
    private RedisCache redisCache;
    private DatabaseService databaseService;

    public File getFileMetadata(String fileId) {
        String cacheKey = "file_metadata:" + fileId;
        File metadata = redisCache.get(cacheKey);
        if (metadata == null) {
            metadata = databaseService.getFileMetadata(fileId);
            redisCache.put(cacheKey, metadata);
        }
        return metadata;
    }
}

通过上述设计,文件元数据的查询性能显著提升,同时在高并发环境下,缓存有效减少了数据库的读操作压力。

6. 实战案例分析与解决方案

6.1 用户海量文件导致的分片不均衡

在实际运作中,用户上传的海量文件可能会导致某些分片存储的负载过高,从而造成数据不均衡。这种情况可以通过以下方案来解决:

  • 哈希一致性:使用一致性哈希算法来分配文件到不同的分片,避免因哈希均匀性不足导致的数据分布不均衡。
  • 动态分片:对存储资源进行动态扩展,在发现某个分片负载过高时,系统可以自动增加新的分片,并将部分数据转移到新的分片上。
public class ConsistentHashing {
    private SortedMap<Integer, String> circle = new TreeMap<>();

    public void add(String node) {
        int hash = hash(node);
        circle.put(hash, node);
    }

    public void remove(String node) {
        int hash = hash(node);
        circle.remove(hash);
    }

    public String get(String key) {
        if (circle.isEmpty()) {
            return null;
        }
        int hash = hash(key);
        if (!circle.containsKey(hash)) {
            SortedMap<Integer, String> tailMap = circle.tailMap(hash);
            hash = tailMap.isEmpty() ? circle.firstKey() : tailMap.firstKey();
        }
        return circle.get(hash);
    }

    private int hash(String key) {
        return key.hashCode() & 0xfffffff; // 简化版哈希函数
    }
}

6.2 上传巨大文件的MD5计算耗时问题

在上传巨大文件时,计算整个文件的MD5值耗时较长,可以采用分片计算MD5的方式,分块并行计算每一块的MD5值,最终整合每个块的MD5值进行再一次哈希计算,得到文件的最终哈希值。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.security.MessageDigest;

public class ParallelMD5 {
    private static final int BLOCK_SIZE = 64 * 1024; // 64KB

    public static String getFileMD5(String filePath) throws Exception {
        FileInputStream fis = new FileInputStream(filePath);
        long fileSize = new File(filePath).length();
        int blocks = (int) Math.ceil((double) fileSize / BLOCK_SIZE);

        ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
        List<Future<byte[]>> futures = new ArrayList<>();

        for (int i = 0; i < blocks; i++) {
            final int blockIndex = i;
            futures.add(executor.submit(() -> {
                byte[] buffer = new byte[BLOCK_SIZE];
                int bytesRead = fis.read(buffer, 0, BLOCK_SIZE);
                MessageDigest md = MessageDigest.getInstance("MD5");
                return md.digest(Arrays.copyOf(buffer, bytesRead));
            }));
        }

        MessageDigest md = MessageDigest.getInstance("MD5");
        for (Future<byte[]> future : futures) {
            md.update(future.get());
        }

        executor.shutdown();
        byte[] mdBytes = md.digest();
        StringBuilder sb = new StringBuilder(32);
        for (byte b : mdBytes) {
            sb.append(String.format("%02x", b));
        }
        return sb.toString();
    }
}

6.3 秒传功能的实际用户体验优化

为了进一步优化秒传和减少用户的等待时间,可以将秒传功能的校验步骤前置。即用户选择文件后,在文件正式上传前,迅速计算文件的校验值(MD5、SHA-256),并与服务器上的文件进行对比,如果文件存在则直接秒传成功。这个过程可以通过前端与后端协同完成:

// 前端代码示例 (假设使用的是JavaScript)
document.getElementById('uploadFile').addEventListener('change', async function() {
    const file = this.files[0];
    const fileMD5 = await calculateFileMD5(file);

    const response = await fetch('/checkFileExists', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({ md5: fileMD5 })
    });

    const result = await response.json();
    if (result.exists) {
        alert('文件已存在,秒传成功');
    } else {
        // 继续上传流程
    }
});

async function calculateFileMD5(file) {
    const arrayBuffer = await file.arrayBuffer();
    const hashBuffer = await crypto.subtle.digest('MD5', arrayBuffer);
    return Array.from(new Uint8Array(hashBuffer)).map(b => b.toString(16).padStart(2, '0')).join('');
}

通过优化这些环节,可以显著提高用户的秒传体验,同时减轻后端的计算负担,提升系统整体的响应速度。

7. 技术选型与架构展望

7.1 对象存储的选择与比较(HDFS vs Ceph)

在构建一个高效的网盘系统时,选择合适的对象存储是至关重要的。这里我们将重点比较HDFS(Hadoop Distributed File System)和Ceph两种常用的分布式存储系统。

7.1.1 HDFS 的特点

  • 高吞吐量:HDFS 设计之初就是为了解决大数据存储和处理问题,能提供非常高的数据访问吞吐量。
  • 数据分片存储:将文件切分为若干块并存储在集群的不同节点上。
  • 主从架构:NameNode 管理元数据,DataNode 存储实际数据,单点故障的NameNode是系统的瓶颈。
  • 适用场景:适合大文件的批处理存储场景,不适用于频繁的小文件读写。

7.1.2 Ceph 的特点

  • 无中心化设计:通过CRUSH算法将数据分布到各个OSD,实现数据无中心化存储。
  • 高可靠性:数据存储支持副本和纠删码,提高数据的可靠性和存储效率。
  • 强一致性:Ceph 提供了强一致性的存储访问接口,确保数据的读写一致性。
  • 灵活性:支持对象存储、块存储和文件系统,适应不同的业务需求。
  • 适用场景:能很好地支持大文件和小文件的混合存储与读取,适合云存储和企业数据存储。

综合比较来看,Ceph 更加适合网盘系统这样需要兼顾大文件和小文件读写的场景,而且其无中心化设计和强一致性也符合高可用和高可靠的要求。

7.2 未来可能的技术迭代与升级

随着业务的发展和技术的进步,网盘系统在未来可能会进行多个方面的技术迭代与升级。以下是一些可能的方向:

7.2.1 使用更加高效的存储引擎

随着存储技术的发展,一些新的存储引擎如RocksDB、LevelDB等,提供了更高的读写性能和存储压缩率,可以在部分场景中替代传统的存储方案。

// 示例代码:使用RocksDB进行文件元数据存储
import org.rocksdb.*;

public class RocksDBExample {
    private RocksDB db;

    public RocksDBExample(String dbPath) throws RocksDBException {
        Options options = new Options().setCreateIfMissing(true);
        this.db = RocksDB.open(options, dbPath);
    }

    public void put(String key, String value) throws RocksDBException {
        db.put(key.getBytes(), value.getBytes());
    }

    public String get(String key) throws RocksDBException {
        byte[] value = db.get(key.getBytes());
        return value != null ? new String(value) : null;
    }

    public void close() {
        if (db != null) {
            db.close();
        }
    }
}

7.2.2 引入机器学习优化存储与传输

利用机器学习算法对用户行为进行分析和预测,可以进一步优化文件的存储与传输策略。例如,通过学习用户的访问模式,提前将常用文件缓存到用户附近的存储节点,从而提高访问速度。

7.2.3 分层存储策略

随着云存储技术的发展,采用分层存储策略,将热数据存储在高性能存储(如SSD),冷数据存储在低成本存储(如HDD),这样既能保证访问速度,又能控制存储成本。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

面粉厂/木材厂选择防爆客流统计系统的原因

在面粉厂和木材厂这样的特殊行业中&#xff0c;存在着一系列的痛点问题。 对于面粉厂而言&#xff0c;面粉粉尘的存在使其面临着爆炸的潜在危险&#xff0c;而人员的随意流动和不确切统计可能会进一步加剧安全风险。同时&#xff0c;难以精确掌握不同区域的人员分布情况&#x…

SploitScan:一款多功能实用型安全漏洞管理平台

关于SploitScan SploitScan是一款功能完善的实用型网络安全漏洞管理工具&#xff0c;该工具提供了用户友好的界面&#xff0c;旨在简化广大研究人员识别已知安全漏洞的相关信息和复现过程。 SploitScan可以帮助网络安全专业人员快速识别和测试已知安全漏洞&#xff0c;如果你需…

解线性方程组——最速下降法及图形化表示 | 北太天元 or matlab

文章所对应的视频讲解 最速下降法 解线性方程组 一、思路转变 A为对称正定矩阵&#xff0c; A x b Ax b Axb 求解向量 x x x这个问题可以转化为一个求 f ( x ) f(x) f(x)极小值点的问题&#xff0c;为什么可以这样&#xff1a; f ( x ) 1 2 x T A x − x T b c f(x) \f…

大数据数据治理

大数据数据治理介绍 大数据数据治理是一个复杂的过程&#xff0c;涉及到数据的标准化、融通、关联、解析、聚合等一系列活动。其核心目标是在确保数据安全的基础上&#xff0c;提高大数据资源和资产的可用性、易用性和可靠性&#xff0c;从而显著提升大数据资源和资产的价值7。…

从0开始学人工智能测试节选:Spark -- 结构化数据领域中测试人员的万金油技术(四)

上一章节我们了解了 shuffle 相关的概念和原理后其实可以发现一个问题&#xff0c;那就是 shuffle 比较容易造成数据倾斜的情况。 例如上一节我们看到的图&#xff0c;在这批数据中&#xff0c;hello 这个单词的行占据了绝大部分&#xff0c;当我们执行 groupByKey 的时候触发了…

FL Studio21.2.8中文版水果音乐制作的革新之旅!

在数字化浪潮的推动下&#xff0c;音乐制作领域经历了翻天覆地的变化。从最初的模拟技术到如今的全数字化处理&#xff0c;音乐制作的门槛被大幅降低&#xff0c;越来越多的音乐爱好者和专业人士开始尝试自行创作和编辑音乐。在这个过程中&#xff0c;各种专业音乐制作软件成为…

孵化器补贴政策提问模板

对于一些需要创业的人来说&#xff0c;找场地是非常非常难的&#xff0c;一个好的场地能够提高创业的成功率&#xff0c;下面这些内容对于孵化器产业园的政策有一个好的提问&#xff0c;可以帮助你们了解这个孵化器合不合适。需要创业的人可以收藏 某孵化器政策示例 提问模板 …

Java进制转换

进制介绍 二进制&#xff1a;0B开头&#xff0c;0-1 八进制&#xff1a;0开头&#xff0c;0-7 十进制&#xff1a;0-9 十六进制&#xff1a;0x开头&#xff0c;0-9和A-F public class Binary{public static void main(String[] args){//二进制 10int n10B1010//十进制 1010int…

短视频动画脚本:成都鼎茂宏升文化传媒公司

短视频动画脚本&#xff1a;创作与魅力的探索 在数字化时代的浪潮中&#xff0c;短视频动画以其独特的魅力迅速崛起&#xff0c;成为大众娱乐和信息传播的重要载体。成都鼎茂宏升文化传媒公司作为一名原创文章编辑&#xff0c;我深入探索了短视频动画脚本的创作过程&#xff0…

揭秘GPU技术新趋势:从虚拟化到池化

从GPU虚拟化到池化 大模型兴起加剧GPU算力需求&#xff0c;企业面临GPU资源有限且利用率不高的挑战。为打破这一瓶颈&#xff0c;实现GPU算力资源均衡与国产化替代&#xff0c;GPU算力池化成为关键。本文深入探讨GPU设备虚拟化途径、共享方案及云原生实现&#xff0c;旨在优化资…

大模型学习资料整理:如何从0到1学习大模型,搭建个人或企业RAG系统,如何评估与优化(更新中...)

通过本文您可以了解到&#xff1a; 学习&#xff1a;从小白如何入手&#xff0c;从0到1开始学习大模型。RAG系统&#xff1a;我想搭建属于自己或者企业的RAG系统&#xff0c;我该怎么去做&#xff1f;评估&#xff1a;微调后的模型或者RAG系统&#xff0c;如何评估自己的模型和…

软件质量保障——三、四

三、黑盒测试 1.黑盒测试概述 1.1 如何理解黑盒测试&#xff1f; 1.2 黑盒测试有什么特点&#xff1f; 1.3 如何实施黑盒测试&#xff1f; 2. 黑盒测试用例设计和生成方法&#xff08;这里还是要自己找题做&#xff09; 2.1 等价类划分法 步骤&#xff1a; 1.选择划分准…

设置电脑定时关机

1.使用快捷键winR 打开运行界面 2.输入cmd &#xff0c;点击确认&#xff0c;打开命令行窗口&#xff0c;输入 shutdown -s -t 100&#xff0c;回车执行命令&#xff0c;自动关机设置成功 shutdown: 这是主命令&#xff0c;用于执行关闭或重启操作。-s: 这个参数用于指定执行关…

flask音乐交流平台-计算机毕业设计源码57105

摘要 科技进步的飞速发展引起人们日常生活的巨大变化&#xff0c;电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用。信息时代的到来已成为不可阻挡的时尚潮流&#xff0c;人类发展的历史正进入一个新时代。在现实运用中&#xff0c;应用软件的工作规…

kafka-生产者监听器(SpringBoot整合Kafka)

文章目录 1、生产者监听器1.1、创建生产者监听器1.2、发送消息测试1.3、使用Java代码创建主题分区副本1.4、application.yml配置----v1版1.5、屏蔽 kafka debug 日志 logback.xml1.6、引入spring-kafka依赖1.7、控制台日志 1、生产者监听器 1.1、创建生产者监听器 package co…

鸿蒙开发接口安全:【@ohos.abilityAccessCtrl (访问控制管理)】

访问控制管理 说明&#xff1a; 本模块首批接口从API version 8开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 导入模块 import abilityAccessCtrl from ohos.abilityAccessCtrlabilityAccessCtrl.createAtManager createAtManager(): AtMan…

用户管理的小demo --登录:

目录 1、建库、建表 1.1 连接数据库后&#xff0c;在idea中 通过快捷方式 自动导入实体类 1.2 实体类代码 2、idea中的准备工作 2.1 在父工程下 新建子工程 2.2 在子工程下 添加webapp、pom.xml设置为 war的打包方式 2.3 在父工程下的pom.xml中 添加依赖 2.3.1 mysql的…

基于STC12C5A60S2系列1T 8051单片机实现一主单片机与一从单片机相互发送数据的RS485通信功能

基于STC12C5A60S2系列1T 8051单片机实现一主单片机与一从单片机相互发送数据的RS485通信功能的RS485通信功能 STC12C5A60S2系列1T 8051单片机管脚图STC12C5A60S2系列1T 8051单片机串口通信介绍STC12C5A60S2系列1T 8051单片机串口通信的结构基于STC12C5A60S2系列1T 8051单片机串…

力扣hot100学习记录(十一)

24. 两两交换链表中的节点 给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题&#xff08;即&#xff0c;只能进行节点交换&#xff09;。 题意 两两交换链表中的相邻节点 思路 先创建一个…

机器学习知识点总结

简介&#xff1a;随着人工智能&#xff08;AI&#xff09;蓬勃发展&#xff0c;也有越来越多的人涌入到这一行业。下面简单介绍一下机器学习的各大领域&#xff0c;机器学习包含深度学习以及强化学习&#xff0c;在本节的机器学习中主要阐述一下机器学习的线性回归逻辑回归&…