文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

fastdfs详解

2023-08-18 22:04

关注

概述

分布式文件系统

FastDFS

在linux-minimal上安装fastdfs

#先安装第三方库(gcc编译器、libevent库) 否则配置/编译时可能会报错yum install gcc libevent libevent-devel -y#从github中下载(若显示连不上github则需要自己手动下载 手动下载后用tar -zxvf命令解压缩)、编译且安装libfastcommon库#libfastcommon库是从fastdfs中分离出来的c语言公用函数库git clone https://github.com/happyfish100/libfastcommon.git --depth 1cd libfastcommon./make.sh./make.sh install#从github中下载、编译且安装libserverframe库#注意 若不安装libserverframe库则在编译fastdfs时会出现错误:../common/fdfs_global.h:15:26: fatal error: sf/sf_global.h: No such file or directorygit clone https://github.com/happyfish100/libserverframe.git --depth 1cd libserverframe./make.sh./make.sh install#从github中下载、编译且安装fastdfsgit clone https://github.com/happyfish100/fastdfs.git --depth 1cd fastdfs./make.sh./make.sh install#fastdfs的编译出来的文件在/usr/bin目录下(以fdfs开头)#fastdfs的配置文件在/etc/fdfs目录下#复制fastdfs的conf目录下的两个文件到/etc/fdfs目录下 否则实际应用时可能会出现奇奇怪怪的问题cp http.conf /etc/fdfscp mime.types /etc/fdfs#备份配置文件cd /etc/fdfscp client.conf client.conf.samplecp storage.conf storage.conf.samplecp storage_ids.conf storage_ids.conf.samplecp tracker.conf tracker.conf.sample#修改tracker.conf文件#base_path为存储tracker的数据与日志文件的目录路径base_path = /opt/fastdfs/tracker#修改storage.conf文件#base_path为存储storage的数据与日志文件的目录路径base_path = /opt/fastdfs/storage#store_path为存储真正文件的目录 可以写多个 结尾为0、1、..的数字 若写多个 则要改store_path_countstore_path0 = /opt/fastdfs/storage/files#store_path1 = /home/yuqing/fastdfs1store_path_count = 1#tracker_server表示将此storage注册到哪个tracker下tracker_server = 192.168.190.131:22122#测试时使用一个tracker即可 剩余的要么注释掉要么删除掉#tracker_server = 192.168.209.122:22122#创建上述目录mkdir -p /opt/fastdfs/trackermkdir -p /opt/fastdfs/storage/files#启动fastdfs#启动tracker(在任意目录下)fdfs_trackerd /etc/fdfs/tracker.conf#启动storage(在任意目录下)#首次启动storage后会在$store_path$/data目录下新建256^2个存储文件的目录fdfs_storaged /etc/fdfs/storage.conf#查看storage是否已经注册到了tracker下fdfs_monitor /etc/fdfs/storage.conf#若有此信息说明注册成功tracker server is 192.168.190.131:22122#重启trackerfdfs_trackerd /etc/fdfs/tracker.conf restart#重启storagefdfs_storaged /etc/fdfs/storage.conf restart#关闭trackerfdfs_trackerd /etc/fdfs/tracker.conf stop#关闭storagefdfs_storaged /etc/fdfs/storage.conf stop#或kill命令关闭#但不建议使用kill -9命令强制关闭 因为可能会产生文件信息不同步的问题

本地上传本地访问

#启动/重启fastdfsfdfs_trackerd /etc/fdfs/tracker.conf (restart)fdfs_storaged /etc/fdfs/storage.conf (restart)#修改client.conf文件以测试文件上传#base_path为存储client的日志文件的目录路径base_path = /opt/fastdfs/client#tracker_server表示将此client注册到哪个tracker下tracker_server = 192.168.190.131:22122#创建上述目录mkdir -p /opt/fastdfs/client#测试文件上传fdfs_test /etc/fdfs/client.conf upload /opt/fastdfs-6.09.tar.gz-----------------------------------------------------------------------------------#tracker查询到有一个storage注册到它的名下tracker_query_storage_store_list_without_group: server 1. group_name=, ip_addr=192.168.190.131, port=23000group_name=group1, ip_addr=192.168.190.131, port=23000#此为上传的文件的信息且fastdfs会对上传的文件进行重新命名storage_upload_by_filenamegroup_name=group1, remote_filename=M00/00/00/wKi-g2NE2l-AGCKaAAw1cLkA25I.tar.gzsource ip address: 192.168.190.131file timestamp=2022-10-11 10:52:15file size=800112file crc32=3103841170#/group1为组名(非cluster下默认只有一个组group1)#/M00为linux的虚拟磁盘名#/00/00为目录名#/wKi-g2NE2l-AGCKaAAw1cLkA25I.tar.gz为文件名example file url: http://192.168.190.131/group1/M00/00/00/wKi-g2NE2l-AGCKaAAw1cLkA25I.tar.gz#此为上传的文件的从文件的信息#一般的 上传的文件只需要存一份主文件即可#在存放图片时需要存放它的大图与小图时可以存放从文件storage_upload_slave_by_filenamegroup_name=group1, remote_filename=M00/00/00/wKi-g2NE2l-AGCKaAAw1cLkA25I_big.tar.gzsource ip address: 192.168.190.131file timestamp=2022-10-11 10:52:15file size=800112file crc32=3103841170example file url: http://192.168.190.131/group1/M00/00/00/wKi-g2NE2l-AGCKaAAw1cLkA25I_big.tar.gz-----------------------------------------------------------------------------------#查看上传的文件情况cd /opt/fastdfs/storage/files/data/00/00ll#此为从文件wKi-g2NE2l-AGCKaAAw1cLkA25I_big.tar.gz#此为从文件的属性信息(m为meta)wKi-g2NE2l-AGCKaAAw1cLkA25I_big.tar.gz-m#此为主文件wKi-g2NE2l-AGCKaAAw1cLkA25I.tar.gz#此为主文件的属性信息(m为meta)wKi-g2NE2l-AGCKaAAw1cLkA25I.tar.gz-m#删除测试文件#删除主文件及其属性信息fdfs_delete_file /etc/fdfs/client.conf group1/M00/00/00/wKi-g2NE2l-AGCKaAAw1cLkA25I.tar.gz#删除从文件及其属性信息fdfs_delete_file /etc/fdfs/client.conf group1/M00/00/00/wKi-g2NE2l-AGCKaAAw1cLkA25I_big.tar.gz

本地上传远程访问

#通过nginx访问已经上传到fastdfs中的文件#从github中下载fastdfs-nginx模块#注意 在nginx的安装过程中才能配置fastdfs-nginx模块 因此得重新安装一遍nginxgit clone https://github.com/happyfish100/fastdfs-nginx-module.git --depth 1#下载并解压nginxwget https://nginx.org/download/nginx-1.22.0.tar.gztar -zxvf nginx-1.22.0.tar.gz#先安装第三方库(gcc编译器、openssl库、pcre库、zlib库) 否则配置/编译nginx时可能会报错yum install gcc openssl openssl-devel pcre pcre-devel zlib zlib-devel -y#配置nginx的安装路径以及要添加的模块的源代码路径cd nginx-1.22.0./configure --prefix=/opt/nginx --add-module=/opt/fastdfs-nginx-module/src#编译且安装nginxmakemake install#拷贝文件 否则可能不能正常启动nginxcp /opt/fastdfs-nginx-module/src/mod_fastdfs.conf /etc/fdfs#修改mod_fastdfs.conf文件#base_path为存储fastdfs-nginx模块的日志文件的目录路径base_path=/opt/fastdfs/fastdfs-nginx#tracker_server表示将此fastdfs-nginx模块注册到哪个tracker下tracker_server=192.168.190.131:22122#若url中带有组名则设为true 默认为falseurl_have_group_name = true#store_path为storage存储真正文件的目录 可以写多个 若写多个 则要改store_path_countstore_path0=/opt/fastdfs/storage/files#store_path1=/home/yuqing/fastdfs1store_path_count=1#创建上述目录mkdir -p /opt/fastdfs/fastdfs-nginx#配置nginx#表示拦截此请求路径并用fastdfs的nginx模块进行转发#ngx_fastdfs_module:此指令非nginx提供 而是由fastdfs-nginx模块提供的 而nginx根据此指令会找到mod_fastdfs.conf文件 进而找到tracker与storagelocation ~ /group[1-9]/M0[0-9] {ngx_fastdfs_module;}#启动nginx./nginx -c /opt/nginx/conf/nginx.conf#启动/重启fastdfsfdfs_trackerd /etc/fdfs/tracker.conf (restart)fdfs_storaged /etc/fdfs/storage.conf (restart)#测试文件上传cp /opt/fastdfs-6.09/conf/http.conf /opt/a.txtfdfs_test /etc/fdfs/client.conf upload /opt/a.txt#访问http://192.168.190.131/group1/M00/00/00/wKi-g2NFIHaAE1jiAAADxfUPwyI976.txt

远程上传远程/本地访问

fastdfs-java

添加依赖

    org.csource    fastdfs-client-java    1.29-SNAPSHOT

拷贝源码包的fdfs_client.conf文件到resources目录中并修改

tracker_server = 192.168.190.131:22122

编写文件上传、下载、删除的代码

public class FastDFS {    public static void main(String[] args) {        fileUpload();    }        public static void fileUpload() {        try {            //获取StorageClient对象            StorageClient sc = getStorageClient();            //local_filename为需要上传的文件的绝对路径            //file_ext_name为需要上传的文件的扩展名            //meta_list为需要上传的文件的属性信息 通常为null 即不用上传            //返回值为String[] strings[0]为组名(如group1) strings[1]为远程文件名(如M00/00/00/wKi-g2NFYm6AYYnwAAEXDUO_9AI243.png)            //此返回值很重要 建议存入数据库            String[] result = sc.upload_file("D:/001.png", "png", null);            for (String s : result) {                System.out.println(s);            }        } catch (IOException | MyException e) {            e.printStackTrace();        }    }        public static void fileDownload() {        try {            //获取StorageClient对象            StorageClient sc = getStorageClient();            //group_name为需要下载的文件的组名            //remote_filename为需要下载的文件的远程文件名            //local_filename为需要下载的文件保存到哪个位置的绝对路径名            //返回值为int 若为0则表示下载成功 其它值都表示下载失败            int result = sc.download_file("group1",                    "M00/00/00/wKi-g2NFYm6AYYnwAAEXDUO_9AI243.png",                    "D:/002.png");            System.out.println(result);        } catch (IOException | MyException e) {            e.printStackTrace();        }    }        public static void fileDelete() {        try {            //获取StorageClient对象            StorageClient sc = getStorageClient();            //group_name为需要删除的文件的组名            //remote_filename为需要删除的文件的远程文件名            //返回值为int 若为0则表示删除成功 其它值都表示删除失败            int result = sc.delete_file("group1",                    "M00/00/00/wKi-g2NFYm6AYYnwAAEXDUO_9AI243.png");            System.out.println(result);        } catch (IOException | MyException e) {            e.printStackTrace();        }    }        public static StorageClient getStorageClient() {        StorageClient sc = null;        try {            //读取fastdfs的配置文件以将所有的tracker_server地址读取到内存中            //默认从classpath中读取            ClientGlobal.init("fdfs_client.conf");            //创建TrackerClient对象以获取TrackerServer对象与StorageServer对象            TrackerClient tc = new TrackerClient();            TrackerServer ts = tc.getTrackerServer();            StorageServer ss = tc.getStoreStorage(ts);            //通过TrackerServer对象与StorageServer对象来获取StorageClient对象            //使用StorageClient对象以实现对文件的操作            sc = new StorageClient(ts, ss);        } catch (IOException | MyException e) {            e.printStackTrace();        }        return sc;    }}

启动nginx、fastdfs以进行测试

#永久关闭防火墙systemctl stop firewalldsystemctl disable firewalld#启动nginx./nginx -c /opt/nginx/conf/nginx.conf#启动fastdfsfdfs_trackerd /etc/fdfs/tracker.conffdfs_storaged /etc/fdfs/storage.conf#访问http://192.168.190.131/group1/M00/00/00/wKi-g2NFYm6AYYnwAAEXDUO_9AI243.png或查看fastdfs的存储文件的目录

fastdfs-web

配置pom

添加依赖

            org.springframework.boot        spring-boot-starter-thymeleaf                org.springframework.boot        spring-boot-starter-web                org.mybatis.spring.boot        mybatis-spring-boot-starter        2.2.2                mysql        mysql-connector-java        runtime                org.projectlombok        lombok        true                org.springframework.boot        spring-boot-starter-test        test                    org.csource        fastdfs-client-java        1.29-SNAPSHOT    

配置build

                        org.springframework.boot            spring-boot-maven-plugin                                                                        org.projectlombok                        lombok                                                                                    org.mybatis.generator            mybatis-generator-maven-plugin            1.4.1                                                            GeneratorMapper.xml                true                true                                                src/main/java                            ***.xml                        false                            src/main/resources                            **    public static String[] fileUpload(byte[] file_buff, String file_ext_name, NameValuePair[] meta_list) {        try {            //获取StorageClient对象            StorageClient sc = getStorageClient();            //file_buff为需要上传的文件的字节数组            //file_ext_name为需要上传的文件的扩展名            //meta_list为需要上传的文件的属性信息 通常为null 即不用上传            //返回值为String[] strings[0]为组名(如group1) strings[1]为远程文件名(如M00/00/00/wKi-g2NFYm6AYYnwAAEXDUO_9AI243.png)            //此返回值很重要 建议存入数据库            String[] result = sc.upload_file(file_buff, file_ext_name, meta_list);            return result;        } catch (IOException | MyException e) {            e.printStackTrace();        }        return null;    }        public static byte[] fileDownload(String group_name, String remote_filename) {        try {            //获取StorageClient对象            StorageClient sc = getStorageClient();            //group_name为需要下载的文件的组名            //remote_filename为需要下载的文件的远程文件名            //返回值为int 若为0则表示下载成功 其它值都表示下载失败            byte[] result = sc.download_file(group_name, remote_filename);            return result;        } catch (IOException | MyException e) {            e.printStackTrace();        }        return null;    }        public static Integer fileDelete(String group_name, String remote_filename) {        try {            //获取StorageClient对象            StorageClient sc = getStorageClient();            //group_name为需要删除的文件的组名            //remote_filename为需要删除的文件的远程文件名            //返回值为int 若为0则表示删除成功 其它值都表示删除失败            int result = sc.delete_file(group_name, remote_filename);            return result;        } catch (IOException | MyException e) {            e.printStackTrace();        }        return null;    }        public static StorageClient getStorageClient() {        StorageClient sc = null;        try {            //读取fastdfs的配置文件以将所有的tracker_server地址读取到内存中            //默认从classpath中读取            ClientGlobal.init("fdfs_client.conf");            //创建TrackerClient对象以获取TrackerServer对象与StorageServer对象            TrackerClient tc = new TrackerClient();            TrackerServer ts = tc.getTrackerServer();            StorageServer ss = tc.getStoreStorage(ts);            //通过TrackerServer对象与StorageServer对象来获取StorageClient对象            //使用StorageClient对象以实现对文件的操作            sc = new StorageClient(ts, ss);        } catch (IOException | MyException e) {            e.printStackTrace();        }        return sc;    }}

在resources下生成fdfs_client.conf文件

connect_timeout = 2network_timeout = 30charset = UTF-8http.tracker_http_port = 8080http.anti_steal_token = nohttp.secret_key = FastDFS1234567890tracker_server = 192.168.190.131:22122connection_pool.enabled = trueconnection_pool.max_count_per_entry = 500connection_pool.max_idle_time = 3600connection_pool.max_wait_time_in_ms = 1000

创建controller

@Controllerpublic class UserController {    @Resource    private UserService userService;    @GetMapping("/")    public String selectAll(Model model) {        List list = userService.selectAll();        model.addAttribute("list", list);        return "index";    }    @GetMapping("/toUpload/{id}")    public String toUpload(Model model, @PathVariable Integer id) {        User user = userService.selectById(id);        model.addAttribute("user", user);        return "upload";    }    //MultipartFile为spring提供的一个接口 专门用来获取文件的数据    //注意 MultipartFile的参数名必须与表单中的文件的name属性保持一致 否则获取不到MultipartFile    @PostMapping("/upload")    public String upload(Model model, Integer id, MultipartFile myFile) {        try {            System.out.println(myFile.getOriginalFilename());            //myFile.getName()获取的是表单中的文件的name属性            System.out.println(myFile.getName());            System.out.println(myFile.getContentType());            System.out.println(myFile.getSize());            System.out.println(myFile.isEmpty());            byte[] file_buff = myFile.getBytes();            String filename = myFile.getOriginalFilename();            //注意 有些文件是没有扩展名的 因此此处并不能这样写 而要做逻辑控制 但此处为测试 因此不做处理            String file_ext_name = filename.substring(filename.lastIndexOf(".") + 1);            String[] result = FastDFSUtil.fileUpload(file_buff, file_ext_name, null);            User user = new User();            user.setId(id);            user.setFilename(myFile.getOriginalFilename());            user.setFilesize(myFile.getSize());            user.setGroupname(result[0]);            user.setRemotefilepath(result[1]);            int ret = userService.updateUser(user);            if (ret == 1) {                model.addAttribute("message", "文件上传成功,点击 确定 返回主页面!");            } else {                model.addAttribute("message", "文件上传失败,点击 确定 返回主页面!");            }            model.addAttribute("url", "/");        } catch (IOException e) {            e.printStackTrace();        }        return "result";    }    //ResponseEntity为spring提供的一个类    @GetMapping("/download/{id}")    public ResponseEntity download(@PathVariable Integer id) {        User user = userService.selectById(id);        byte[] result = FastDFSUtil.fileDownload(user.getGroupname(), user.getRemotefilepath());        //创建响应头对象以设置其属性        HttpHeaders httpHeaders = new HttpHeaders();        //设置响应头的类型为流类型        httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);        //设置响应头的文件大小 用来提供下载器的属性(如下载速度)显示        httpHeaders.setContentLength(user.getFilesize());        //设置下载文件时的文件名为user.getFilename() 也可以使用时间戳+扩展名的方式        httpHeaders.setContentDispositionFormData("attachment",                //处理下载的文件的文件名的中文乱码问题                new String(user.getFilename().getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));        //创建响应体对象        //body为响应数据 此数据可以为html代码/js代码/字符串/一个文件的流/..        //headers为响应头的信息        //status为响应后想要显示的状态码        ResponseEntity responseEntity = new ResponseEntity<>(result, httpHeaders, HttpStatus.OK);        return responseEntity;    }    @GetMapping("/delete/{id}")    public String delete(Model model, @PathVariable Integer id) {        User user = userService.selectById(id);        //此处应添加事务控制 但此处为测试 因此不做处理        int ret = userService.deleteUserById(id);        Integer result = FastDFSUtil.fileDelete(user.getGroupname(), user.getRemotefilepath());        if (result == 0 && ret == 1) {            model.addAttribute("message", "文件删除成功,点击 确定 返回主页面!");        } else {            model.addAttribute("message", "文件删除失败,点击 确定 返回主页面!");        }        model.addAttribute("url", "/");        return "result";    }}

在templates下创建对应的页面

        index
序号 姓名 文件名称 文件大小 操作
序号 姓名 文件名称 文件大小 上传 下载 删除
        upload
姓名:
文件:
        result

result

确定

测试

fastdfs-cluster

环境搭建

安装7个linux-minimal

安装fastdfs与nginx

#先安装linux-minimal缺少的但常用的工具库yum install git lrzsz wget vim unzip net-tools -y#再安装fastdfs与nginx所需要的第三方库 否则配置/编译时可能会报错yum install gcc openssl openssl-devel pcre pcre-devel zlib zlib-devel libevent libevent-devel -y#下载、编译且安装libfastcommon库git clone https://github.com/happyfish100/libfastcommon.git --depth 1cd /opt/libfastcommon-1.0.62./make.sh./make.sh install#下载、编译且安装libserverframe库git clone https://github.com/happyfish100/libserverframe.git --depth 1cd /opt/libserverframe-1.1.21./make.sh./make.sh install#从github中下载、编译且安装fastdfs、nginx、fastdfs-nginx模块#下载、编译且安装fastdfsgit clone https://github.com/happyfish100/fastdfs.git --depth 1cd /opt/fastdfs-6.09./make.sh./make.sh install#下载并解压nginxwget https://nginx.org/download/nginx-1.22.0.tar.gztar -zxvf nginx-1.22.0.tar.gz#下载fastdfs-nginx模块git clone https://github.com/happyfish100/fastdfs-nginx-module.git --depth 1#配置nginx的安装路径以及要添加的模块的源代码路径cd /opt/nginx-1.22.0#对tracker与入口即192.168.190.131的nginx的配置./configure --prefix=/opt/nginx#对storage的配置./configure --prefix=/opt/nginx --add-module=/opt/fastdfs-nginx-module/src#编译且安装nginxmakemake install

修改配置文件

#先拷贝/备份文件cp /opt/fastdfs-6.09/conf/http.conf /etc/fdfscp /opt/fastdfs-6.09/conf/mime.types /etc/fdfscd /etc/fdfscp client.conf client.conf.samplecp storage.conf storage.conf.samplecp storage_ids.conf storage_ids.conf.samplecp tracker.conf tracker.conf.sample#tracker不需要 storage才需要cp /opt/fastdfs-nginx-module/src/mod_fastdfs.conf /etc/fdfs#修改tracker.conf文件base_path = /opt/fastdfs/tracker#修改fastdfs的负载均衡策略#0为轮询组 1为指定组(若为1 则还要配置store_group来指定哪个组) 2为选择剩余空间最大的组(默认值)store_lookup=0#创建上述目录mkdir -p /opt/fastdfs/tracker#修改storage.conf文件#X修改成具体的值group_name=groupXbase_path = /opt/fastdfs/storagestore_path0 = /opt/fastdfs/storage/filestracker_server = 192.168.190.132:22122tracker_server = 192.168.190.133:22122#创建上述目录mkdir -p /opt/fastdfs/storage/files#修改mod_fastdfs.conf文件#tracker不需要 storage才需要base_path=/opt/fastdfs/fastdfs-nginxtracker_server=192.168.190.132:22122tracker_server=192.168.190.133:22122#X修改成具体的值group_name=groupXurl_have_group_name = truestore_path0=/opt/fastdfs/storage/filesgroup_count=2#在末尾添加[group1]group_name=group1storage_server_port=23000store_path_count=1store_path0=/opt/fastdfs/storage/files[group2]group_name=group2storage_server_port=23000store_path_count=1store_path0=/opt/fastdfs/storage/files#创建上述目录mkdir -p /opt/fastdfs/fastdfs-nginx

配置nginx

#对tracker的配置location ~ /group[1-9]/M0[0-9] {proxy_pass http://fastdfs_server;}upstream fastdfs_server {server 192.168.190.134:80;server 192.168.190.135:80;server 192.168.190.136:80;server 192.168.190.137:80;}#对storage的配置location ~ /group[1-9]/M0[0-9] {ngx_fastdfs_module;}#对入口的配置location ~ /group[1-9]/M0[0-9] {proxy_pass http://fastdfs_server;}upstream fastdfs_server {server 192.168.190.132:80;server 192.168.190.133:80;}

启动fastdfs与nginx

#永久关闭防火墙systemctl stop firewalldsystemctl disable firewalld#启动fastdfs#对trackerfdfs_trackerd /etc/fdfs/tracker.conf#对storagefdfs_storaged /etc/fdfs/storage.conf#启动nginxcd /opt/nginx/sbin./nginx -c /opt/nginx/conf/nginx.conf -t./nginx -c /opt/nginx/conf/nginx.conf

测试文件上传、下载、删除

来源地址:https://blog.csdn.net/dddddd_hdysj/article/details/127298755

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-服务器
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯