《计算机操作系统》第七章 - 文件管理

一、前言

大家好!今天我们来系统梳理《计算机操作系统》第七章 "文件管理" 的核心知识点,从基础概念到代码实现,力求通俗易懂,每个核心知识点都会搭配实战案例和架构图 / 流程图,帮助大家彻底吃透文件管理的底层逻辑。所有代码均采用C++98 标准编写,可直接编译运行,注释详尽,方便动手实操。

二、核心知识点讲解

7.1 文件和文件系统

1. 核心概念

文件:是操作系统中存储信息的基本单位,由一系列字符 / 字节组成,具有唯一文件名,存储在外部存储介质(磁盘、U 盘等)上。文件系统:是操作系统中负责管理和存储文件信息的软件集合,核心功能包括文件创建 / 删除、读写、目录管理、权限控制等。

2. 架构图
3. 实战案例:模拟文件系统基础结构(C++98)
cpp 复制代码
#include <iostream>
#include <string>
#include <ctime>
using namespace std;

// 遵循C++98标准,模拟文件的基本属性和操作
// 文件属性结构体(对应文件系统中文件的元数据)
struct FileAttribute {
    string fileName;    // 文件名
    int fileSize;       // 文件大小(字节)
    time_t createTime;  // 创建时间
    time_t modifyTime;  // 修改时间
    string fileType;    // 文件类型(文本/二进制等)
};

// 文件系统基础类
class FileSystem {
public:
    // 构造函数:初始化文件系统
    FileSystem() {
        cout << "文件系统初始化完成!" << endl;
    }

    // 创建文件:初始化文件属性
    void createFile(const string& name, const string& type, int size) {
        FileAttribute file;
        file.fileName = name;
        file.fileSize = size;
        file.fileType = type;
        // 获取当前时间作为创建/修改时间(先赋值给变量,再取地址)
        file.createTime = time(NULL);
        file.modifyTime = file.createTime;

        cout << "文件创建成功!" << endl;
        cout << "文件名:" << file.fileName << endl;
        cout << "文件大小:" << file.fileSize << " 字节" << endl;
        cout << "文件类型:" << file.fileType << endl;
        cout << "创建时间:" << ctime(&file.createTime);
    }

    // 删除文件
    void deleteFile(const string& name) {
        cout << "文件 " << name << " 删除成功!" << endl;
    }

    // 读取文件(模拟)
    void readFile(const string& name) {
        cout << "正在读取文件:" << name << endl;
        cout << "文件内容(模拟):Hello, File System!" << endl;
    }

    // 写入文件(模拟)- 修复临时值取地址问题
    void writeFile(const string& name, const string& content) {
        cout << "向文件 " << name << " 写入内容:" << content << endl;
        // 修复点:先将time(NULL)的结果赋值给变量(左值),再取地址
        time_t currentTime = time(NULL);
        cout << "文件修改时间更新为:" << ctime(&currentTime);
    }
};

// 主函数:测试文件系统基础操作
int main() {
    // 创建文件系统实例
    FileSystem fs;

    // 创建文本文件
    fs.createFile("test.txt", "文本文件", 1024);

    // 读取文件
    fs.readFile("test.txt");

    // 写入文件
    fs.writeFile("test.txt", "这是测试文件的内容!");

    // 删除文件
    fs.deleteFile("test.txt");

    return 0;
}
4. 代码说明
  • 定义FileAttribute结构体模拟文件元数据(文件名、大小、时间等),对应文件系统中存储的文件属性;
  • FileSystem类封装文件系统核心操作(创建、删除、读写),符合 C++98 语法规范;
  • 主函数中完成完整的文件操作流程,可直接编译运行(g++ -std=c++98 文件名.cpp -o 可执行文件)。

7.2 文件的逻辑结构

1. 核心概念

文件的逻辑结构是用户视角下文件的组织形式,分为两类:

  • 流式文件:无结构,由字符 / 字节流组成(如.txt 文件);
  • 记录式文件:有结构,由多条记录组成(如数据库表、CSV 文件)。
2. 流程图
3. 实战案例:模拟流式文件和记录式文件(C++98)
复制代码
#include <iostream>
#include <string>
#include <vector>
#include <iomanip>
using namespace std;

// 遵循C++98标准,模拟两种文件逻辑结构

// 1. 流式文件类(无结构,字节流)
class StreamFile {
private:
    string fileName;
    string content;  // 字节流形式存储内容
public:
    StreamFile(const string& name) : fileName(name) {}

    // 写入字节流(流式文件核心操作)
    void writeStream(const string& data) {
        content += data;  // 直接追加,无结构限制
        cout << "流式文件 " << fileName << " 写入成功,当前内容长度:" << content.size() << " 字节" << endl;
    }

    // 读取字节流
    string readStream() {
        cout << "读取流式文件 " << fileName << " 内容:" << endl;
        return content;
    }
};

// 2. 记录式文件:单条记录结构体
struct Record {
    int id;         // 记录ID
    string name;    // 姓名
    int age;        // 年龄
};

// 记录式文件类
class RecordFile {
private:
    string fileName;
    vector<Record> records;  // 按记录组织内容(C++98支持vector)
public:
    RecordFile(const string& name) : fileName(name) {}

    // 添加记录(记录式文件核心操作,有固定结构)
    void addRecord(int id, const string& name, int age) {
        Record r;
        r.id = id;
        r.name = name;
        r.age = age;
        records.push_back(r);
        cout << "记录式文件 " << fileName << " 添加记录成功,当前记录数:" << records.size() << endl;
    }

    // 读取指定记录
    Record readRecord(int id) {
        for (vector<Record>::iterator it = records.begin(); it != records.end(); ++it) {  // C++98迭代器写法
            if (it->id == id) {
                cout << "找到记录 ID=" << id << ":" << endl;
                return *it;
            }
        }
        cout << "未找到记录 ID=" << id << endl;
        return Record();  // 返回空记录
    }

    // 打印所有记录
    void printAllRecords() {
        cout << "记录式文件 " << fileName << " 所有记录:" << endl;
        cout << setw(5) << "ID" << setw(10) << "姓名" << setw(5) << "年龄" << endl;
        for (vector<Record>::iterator it = records.begin(); it != records.end(); ++it) {
            cout << setw(5) << it->id << setw(10) << it->name << setw(5) << it->age << endl;
        }
    }
};

// 主函数:测试两种文件逻辑结构
int main() {
    // 1. 测试流式文件
    StreamFile sFile("stream.txt");
    sFile.writeStream("Hello, Stream File!");
    sFile.writeStream("这是流式文件的追加内容,无结构限制。");
    cout << sFile.readStream() << endl << endl;

    // 2. 测试记录式文件
    RecordFile rFile("record.csv");
    rFile.addRecord(1, "张三", 20);
    rFile.addRecord(2, "李四", 22);
    rFile.printAllRecords();
    Record r = rFile.readRecord(1);
    cout << "读取到的记录:ID=" << r.id << ",姓名=" << r.name << ",年龄=" << r.age << endl;

    return 0;
}
4. 代码说明
  • 流式文件类StreamFile:通过字符串直接存储字节流,写入时无结构限制,模拟.txt 等无结构文件;
  • 记录式文件类RecordFile:通过vector存储固定结构的Record结构体,模拟 CSV / 数据库表等有结构文件;
  • 全部采用 C++98 语法(如迭代器写法、无 C++11 的 auto 关键字),可直接编译运行。

7.3 文件目录

1. 核心概念

文件目录(文件夹)是操作系统为管理文件而建立的索引结构,核心作用是映射文件名和文件物理存储地址,常见结构:

  • 单级目录:所有文件存于一个目录,无层级;
  • 两级目录:分为用户目录和文件目录;
  • 树形目录(最常用):多级层级结构(如 Windows 的 C:\Users\XXX)。
2. 思维导图
3. 实战案例:模拟树形文件目录(C++98)
复制代码
#include <iostream>
#include <string>
#include <vector>
using namespace std;

// 遵循C++98标准,模拟树形文件目录结构

// 目录节点类(可包含文件或子目录)
class DirNode {
private:
    string name;                // 目录/文件名
    bool isDir;                 // 是否为目录(true=目录,false=文件)
    DirNode* parent;            // 父目录指针
    vector<DirNode*> children;  // 子节点(文件/子目录)

public:
    // 构造函数:初始化节点
    DirNode(const string& name, bool isDir, DirNode* parent) 
        : name(name), isDir(isDir), parent(parent) {}

    // 析构函数:释放子节点内存(C++98手动管理内存)
    ~DirNode() {
        for (vector<DirNode*>::iterator it = children.begin(); it != children.end(); ++it) {
            delete *it;
        }
    }

    // 添加子节点(文件/子目录)
    void addChild(const string& childName, bool isChildDir) {
        DirNode* child = new DirNode(childName, isChildDir, this);
        children.push_back(child);
        cout << (isChildDir ? "目录" : "文件") << " " << childName << " 创建成功!" << endl;
    }

    // 遍历当前目录下的所有节点
    void listChildren() {
        cout << "当前目录 " << name << " 下的内容:" << endl;
        for (vector<DirNode*>::iterator it = children.begin(); it != children.end(); ++it) {
            cout << ((*it)->isDir ? "[目录] " : "[文件] ") << (*it)->name << endl;
        }
    }

    // 查找子节点(返回指针,用于进入子目录)
    DirNode* findChild(const string& childName) {
        for (vector<DirNode*>::iterator it = children.begin(); it != children.end(); ++it) {
            if ((*it)->name == childName && (*it)->isDir) {
                return *it;
            }
        }
        cout << "未找到目录 " << childName << endl;
        return NULL;
    }

    // 获取当前节点名称
    string getName() { return name; }
};

// 主函数:模拟树形目录操作(如Linux/macOS的cd、ls、mkdir、touch)
int main() {
    // 1. 创建根目录(/)
    DirNode* root = new DirNode("/", true, NULL);
    DirNode* currentDir = root;  // 当前工作目录

    // 2. 在根目录创建子目录和文件
    currentDir->addChild("home", true);    // 创建home目录
    currentDir->addChild("etc", true);     // 创建etc目录
    currentDir->addChild("readme.txt", false);  // 创建readme.txt文件
    currentDir->listChildren();
    cout << "------------------------" << endl;

    // 3. 进入home目录
    currentDir = currentDir->findChild("home");
    cout << "当前目录切换到:" << currentDir->getName() << endl;

    // 4. 在home目录创建用户目录和文件
    currentDir->addChild("user1", true);   // 创建user1目录
    currentDir->addChild("user2", true);   // 创建user2目录
    currentDir->addChild("profile.cfg", false);  // 创建配置文件
    currentDir->listChildren();

    // 5. 释放内存
    delete root;

    return 0;
}
4. 代码说明
  • DirNode类模拟目录节点,包含名称、类型(目录 / 文件)、父节点、子节点列表;
  • 实现添加子节点、遍历目录、切换目录等核心操作,模拟树形目录的层级管理;
  • 手动管理内存(析构函数释放子节点),符合 C++98 的内存管理规范。

7.4 文件共享

1. 核心概念

文件共享是指多个用户 / 进程同时访问同一个文件,常见实现方式:

  • 基于索引节点(i 节点):多个目录项指向同一个 i 节点(存储文件元数据);
  • 符号链接(软链接):创建指向原文件的快捷方式;
  • 硬链接:多个文件名指向同一物理存储。
2. 流程图
3. 实战案例:模拟文件共享(C++98)
cpp 复制代码
#include <iostream>
#include <string>
#include <map>
using namespace std;

// 遵循C++98标准,模拟文件共享(i节点+硬链接+软链接)

// 模拟i节点(存储文件元数据,不存储文件名)
struct INode {
    string fileData;  // 文件实际内容
    int linkCount;    // 硬链接计数
    string filePath;  // 文件物理路径
};

// 文件共享管理器
class FileShareManager {
private:
    map<int, INode> inodeMap;        // i节点表(i节点ID→i节点)
    map<string, int> fileNameToInode;// 文件名→i节点ID(硬链接)
    map<string, string> symLinkMap;  // 软链接表(链接名→原文件名)
    int nextInodeId;                 // 下一个可用i节点ID

public:
    FileShareManager() : nextInodeId(1) {}

    // 创建文件,初始化i节点
    void createFile(const string& fileName, const string& data) {
        INode inode;
        inode.fileData = data;
        inode.linkCount = 1;
        inode.filePath = "/disk/" + fileName;

        int inodeId = nextInodeId++;
        inodeMap[inodeId] = inode;
        fileNameToInode[fileName] = inodeId;

        cout << "文件 " << fileName << " 创建成功,i节点ID:" << inodeId << endl;
    }

    // 创建硬链接:新增文件名→同一i节点
    void createHardLink(const string& linkName, const string& origName) {
        if (fileNameToInode.find(origName) == fileNameToInode.end()) {
            cout << "原文件 " << origName << " 不存在!" << endl;
            return;
        }

        int inodeId = fileNameToInode[origName];
        fileNameToInode[linkName] = inodeId;
        inodeMap[inodeId].linkCount++;  // 硬链接计数+1

        cout << "硬链接 " << linkName << " 指向 " << origName << " 创建成功!" << endl;
        cout << "当前i节点 " << inodeId << " 硬链接数:" << inodeMap[inodeId].linkCount << endl;
    }

    // 创建软链接:存储原文件路径(不关联i节点)
    void createSymLink(const string& linkName, const string& origName) {
        if (fileNameToInode.find(origName) == fileNameToInode.end()) {
            cout << "原文件 " << origName << " 不存在!" << endl;
            return;
        }

        symLinkMap[linkName] = origName;
        cout << "软链接 " << linkName << " 指向 " << origName << " 创建成功!" << endl;
    }

    // 读取文件(支持硬链接/软链接)- 修复const参数修改问题
    void readFile(const string& fileName) {
        // 修复点:创建临时变量存储文件名,避免修改const参数
        string actualFileName = fileName;
        
        // 1. 先判断是否是软链接
        if (symLinkMap.find(actualFileName) != symLinkMap.end()) {
            string origName = symLinkMap[actualFileName];
            cout << "软链接 " << actualFileName << " 指向原文件:" << origName << endl;
            actualFileName = origName;  // 修改临时变量,而非const参数
        }

        // 2. 判断是否是硬链接/原文件
        if (fileNameToInode.find(actualFileName) == fileNameToInode.end()) {
            cout << "文件 " << actualFileName << " 不存在!" << endl;
            return;
        }

        int inodeId = fileNameToInode[actualFileName];
        cout << "读取文件 " << actualFileName << "(i节点ID:" << inodeId << ")内容:" << endl;
        cout << inodeMap[inodeId].fileData << endl;
    }

    // 删除文件(硬链接计数为0时才真正删除i节点)
    void deleteFile(const string& fileName) {
        if (fileNameToInode.find(fileName) == fileNameToInode.end()) {
            cout << "文件 " << fileName << " 不存在!" << endl;
            return;
        }

        int inodeId = fileNameToInode[fileName];
        fileNameToInode.erase(fileName);  // 删除文件名映射
        inodeMap[inodeId].linkCount--;    // 硬链接计数-1

        cout << "文件 " << fileName << " 已删除,当前i节点 " << inodeId << " 硬链接数:" << inodeMap[inodeId].linkCount << endl;

        // 硬链接计数为0,删除i节点
        if (inodeMap[inodeId].linkCount == 0) {
            inodeMap.erase(inodeId);
            cout << "i节点 " << inodeId << " 已释放!" << endl;
        }
    }
};

// 主函数:测试文件共享
int main() {
    FileShareManager fsm;

    // 1. 创建原文件
    fsm.createFile("data.txt", "这是共享文件的内容!");

    // 2. 创建硬链接
    fsm.createHardLink("data_hardlink.txt", "data.txt");

    // 3. 创建软链接
    fsm.createSymLink("data_symlink.txt", "data.txt");

    // 4. 读取硬链接/软链接
    cout << "------------------------" << endl;
    fsm.readFile("data_hardlink.txt");
    cout << "------------------------" << endl;
    fsm.readFile("data_symlink.txt");

    // 5. 删除原文件(硬链接仍可用)
    cout << "------------------------" << endl;
    fsm.deleteFile("data.txt");
    fsm.readFile("data_hardlink.txt");  // 硬链接仍可读取

    // 6. 删除硬链接(i节点释放)
    cout << "------------------------" << endl;
    fsm.deleteFile("data_hardlink.txt");

    // 7. 软链接失效
    cout << "------------------------" << endl;
    fsm.readFile("data_symlink.txt");

    return 0;
}
4. 代码说明
  • INode结构体模拟 i 节点,存储文件实际内容和硬链接计数;
  • 硬链接:多个文件名映射到同一 i 节点 ID,计数 > 0 时文件不真正删除;
  • 软链接:单独存储链接名→原文件名,原文件删除则链接失效;
  • 全部操作符合 C++98 标准,模拟 Linux 系统的文件共享逻辑。

7.5 文件保护

1. 核心概念

文件保护是防止文件被未授权访问 / 修改,常见方式:

  • 访问控制列表(ACL):为每个文件指定用户 / 组的访问权限(读 R、写 W、执行 X);
  • 口令保护:访问文件需输入口令;
  • 加密保护:文件内容加密存储,只有解密后才能访问。
2. 架构图
3. 实战案例:模拟文件权限保护(C++98)
cpp 复制代码
#include <iostream>
#include <string>
#include <map>
using namespace std;

// 遵循C++98标准,模拟文件访问权限保护(ACL)

// 用户类型枚举(C++98支持enum)
enum UserType {
    OWNER,   // 文件所有者
    GROUP,   // 同组用户
    OTHER    // 其他用户
};

// 文件权限结构体
struct FilePermission {
    bool read;   // 读权限
    bool write;  // 写权限
    bool exec;   // 执行权限

    // C++98兼容:添加默认构造函数(避免初始化问题)
    FilePermission() : read(false), write(false), exec(false) {}

    // 带参数的构造函数(方便初始化)
    FilePermission(bool r, bool w, bool e) : read(r), write(w), exec(e) {}
};

// 文件保护管理器
class FileProtectManager {
private:
    // 修复点1:C++98要求嵌套模板的>>必须分开写为> >
    map<string, map<UserType, FilePermission> > permMap;
    // 用户-文件所有者映射
    map<string, string> userFileOwnerMap;
    // 模拟用户口令
    map<string, string> userPwdMap;

public:
    // 初始化:添加测试用户和口令
    FileProtectManager() {
        userPwdMap["user1"] = "123456";  // 文件所有者
        userPwdMap["user2"] = "654321";  // 同组用户
        userPwdMap["user3"] = "000000";  // 其他用户
    }

    // 创建文件并设置权限(所有者默认拥有全部权限)
    void createFileWithPerm(const string& fileName, const string& owner) {
        // 记录文件所有者
        userFileOwnerMap[fileName] = owner;

        // 设置所有者权限(R/W/X)- 使用C++98的构造函数初始化
        FilePermission ownerPerm(true, true, true);
        // 设置同组用户权限(R/X)
        FilePermission groupPerm(true, false, true);
        // 设置其他用户权限(仅R)
        FilePermission otherPerm(true, false, false);

        permMap[fileName][OWNER] = ownerPerm;
        permMap[fileName][GROUP] = groupPerm;
        permMap[fileName][OTHER] = otherPerm;

        cout << "文件 " << fileName << " 创建成功!" << endl;
        cout << "所有者:" << owner << endl;
        cout << "权限设置:" << endl;
        cout << "  所有者:读(R)=是,写(W)=是,执行(X)=是" << endl;
        cout << "  同组用户:读(R)=是,写(W)=否,执行(X)=是" << endl;
        cout << "  其他用户:读(R)=是,写(W)=否,执行(X)=否" << endl;
    }

    // 用户登录验证
    bool userLogin(const string& userName, const string& pwd) {
        if (userPwdMap.find(userName) == userPwdMap.end()) {
            cout << "用户 " << userName << " 不存在!" << endl;
            return false;
        }
        if (userPwdMap[userName] != pwd) {
            cout << "口令错误!" << endl;
            return false;
        }
        cout << "用户 " << userName << " 登录成功!" << endl;
        return true;
    }

    // 判断用户对文件的权限
    FilePermission checkPerm(const string& userName, const string& fileName) {
        if (permMap.find(fileName) == permMap.end()) {
            cout << "文件 " << fileName << " 不存在!" << endl;
            // 修复点2:使用C++98的构造函数返回空权限,而非列表初始化
            return FilePermission(false, false, false);
        }

        // 判断用户类型
        string owner = userFileOwnerMap[fileName];
        UserType ut;
        if (userName == owner) {
            ut = OWNER;
        } else if (userName == "user2") {  // 模拟同组用户
            ut = GROUP;
        } else {
            ut = OTHER;
        }

        cout << "用户 " << userName << " 对文件 " << fileName << " 的权限类型:" 
             << (ut == OWNER ? "所有者" : (ut == GROUP ? "同组用户" : "其他用户")) << endl;
        return permMap[fileName][ut];
    }

    // 执行文件操作(检查权限)
    void doFileOperation(const string& userName, const string& fileName, const string& op) {
        FilePermission perm = checkPerm(userName, fileName);
        bool allowed = false;

        if (op == "read" && perm.read) {
            allowed = true;
        } else if (op == "write" && perm.write) {
            allowed = true;
        } else if (op == "exec" && perm.exec) {
            allowed = true;
        }

        if (allowed) {
            cout << "允许执行 " << op << " 操作!" << endl;
        } else {
            cout << "拒绝执行 " << op << " 操作:权限不足!" << endl;
        }
    }
};

// 主函数:测试文件保护
int main() {
    FileProtectManager fpm;

    // 1. 创建文件,指定所有者为user1
    fpm.createFileWithPerm("app.exe", "user1");
    cout << "------------------------" << endl;

    // 2. 用户1登录,测试所有操作
    if (fpm.userLogin("user1", "123456")) {
        fpm.doFileOperation("user1", "app.exe", "read");
        fpm.doFileOperation("user1", "app.exe", "write");
        fpm.doFileOperation("user1", "app.exe", "exec");
    }
    cout << "------------------------" << endl;

    // 3. 用户2(同组)登录,测试操作
    if (fpm.userLogin("user2", "654321")) {
        fpm.doFileOperation("user2", "app.exe", "read");
        fpm.doFileOperation("user2", "app.exe", "write");  // 无写权限
        fpm.doFileOperation("user2", "app.exe", "exec");
    }
    cout << "------------------------" << endl;

    // 4. 用户3(其他)登录,测试操作
    if (fpm.userLogin("user3", "000000")) {
        fpm.doFileOperation("user3", "app.exe", "read");
        fpm.doFileOperation("user3", "app.exe", "write");  // 无写权限
        fpm.doFileOperation("user3", "app.exe", "exec");  // 无执行权限
    }

    return 0;
}
4. 代码说明
  • UserType枚举区分用户类型(所有者 / 同组 / 其他),FilePermission存储 R/W/X 权限;
  • FileProtectManager实现用户登录、权限检查、操作鉴权核心逻辑;
  • 模拟不同用户的权限差异,符合操作系统中文件权限管理的核心思想。

三、习题

基础题

  1. 简述文件的逻辑结构分类及各自特点,结合 7.2 的代码说明流式文件和记录式文件的实现差异。
  2. 解释硬链接和软链接的区别,结合 7.4 的代码说明为何硬链接删除原文件后仍可访问,而软链接不行。
  3. 操作系统中文件目录的核心作用是什么?树形目录相比单级目录有哪些优势?

编程题

基于 7.5 的文件保护代码,扩展功能:

  1. 添加 "修改文件权限" 的函数,允许文件所有者修改同组 / 其他用户的 R/W/X 权限;
  2. 增加 "用户组管理" 功能,支持将用户加入 / 移出指定组,动态判断用户权限类型。

四、代码运行说明

  1. 编译命令(确保编译器支持 C++98):

    g++ -std=c++98 文件名.cpp -o 可执行文件名

  2. 运行命令:

    ./可执行文件名 # Linux/macOS

    可执行文件名.exe # Windows

  3. 所有代码无第三方依赖,仅依赖 C++98 标准库,可直接编译运行。

总结

  1. 文件管理核心包括文件 / 文件系统基础、逻辑结构、目录管理、共享、保护五大模块,每个模块均对应操作系统的核心功能;
  2. 实战代码基于 C++98 标准实现,模拟了各模块的核心逻辑(如树形目录、i 节点共享、ACL 权限控制),可直接编译运行;
  3. 各知识点配套架构图 / 流程图(Mermaid 格式),可直接复制到 Mermaid 编辑器生成可视化图形,辅助理解概念。
相关推荐
黎阳之光2 小时前
打破视域孤岛,智追目标全程 —— 公安视频追踪技术革新来袭
人工智能·算法·安全·视频孪生·黎阳之光
jiaguangqingpanda2 小时前
Day28-20260124
java·数据结构·算法
s19134838482d2 小时前
javascript练习题
开发语言·javascript·ecmascript
Java程序员威哥2 小时前
SpringBoot2.x与3.x自动配置注册差异深度解析:从原理到迁移实战
java·大数据·开发语言·hive·hadoop·spring boot·后端
TracyCoder1232 小时前
LeetCode Hot100(2/100)——49. 字母异位词分组 (Group Anagrams)。
算法·leetcode
大哥手下留情2 小时前
Python火车票查询方法介绍
开发语言·python
lixinnnn.2 小时前
字符串拼接:Cities and States S
开发语言·c++·算法
AI街潜水的八角2 小时前
医学图像算法之基于MK_UNet的肾小球分割系统3:含训练测试代码、数据集和GUI交互界面
算法
larance2 小时前
方差和标准差
人工智能·算法·机器学习