分布式文件存储系统FastDFS
文章目录
- 1 分布式文件存储
- 1_分布式文件存储的由来
- 2_常见的分布式存储框架
- 2 FastDFS介绍
- 3 FastDFS安装
- 1_拉取镜像文件
- 2_构建Tracker服务
- 3_构建Storage服务
- 4_测试图片上传
- 4 客户端操作
- 1_Fastdfs-java-client
- 2_文件上传
- 3_文件下载
- 4_获取文件信息
- 5_问题
- 5 SpringBoot整合
1 分布式文件存储
1_分布式文件存储的由来
在我们的项目中有很多需要存储的内容出现,比如图片,视频,文件等等,在早期的时候用户量不大,产生的文件也不是很多,这时我们可以把文件和服务程序放在一个服务器中。
后面随着文件越来越多,服务器的资源会被文件资源大量占据,从而影响到服务器的稳定,这时我们可以单独的把文件服务器拆出来。
拆解出来后,文件服务的使用不会影响到我们的系统服务的稳定,但是当用户量越来越大,存储的文件就会越来越多,这时如果还是单台的文件服务,比如100T的文件,这时是存储不下去的,这时就产生了我们将的分布式文件存储,
也就是我们解决如何将这100T的文件分散的存储到各个节点上,然后当我们需要读取文件的时候又能非常快的帮我们把文件找到。这个就是分布式文件系统帮我们解决的问题了。
2_常见的分布式存储框架
接下来我们看看在国内常用的分布式存储的框架选择有哪些
分布式框架 | 说明 |
---|---|
FastDFS | 我们介绍的主角,国产 |
HDFS | Hadoop组件中分布式存储框架 |
MinIO | MinIO是在Apache下的产品,最适合存储非结构化的数据,比如照片,视频,日志文件,备份和容器等。 |
阿里云对象存储 | 当然我们还可以花费一点费用来使用其他厂商提供的对象存储服务 |
2 FastDFS介绍
FastDFS是余庆(国人,淘宝)开发的一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储、文件同步、文件访问(文件上传、文件下载)等,解决了大容量存储和负载均衡的问题。
特别适合以文件为载体的在线服务,如相册网站、视频网站等等。
FastDFS为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标,使用FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。
FastDFS的特点:
- FastDFS是一个轻量级的开源分布式文件系统
- FastDFS主要解决了大容量的文件存储和高并发访问的问题,文件存取时实现了负载均衡
- FastDFS实现了软件方式的RAID,可以使用廉价的IDE硬盘进行存储
- 支持存储服务器在线扩容
- 支持相同内容的文件只保存一份,节约磁盘空间
- FastDFS只能通过Client API访问,不支持POSIX访问方式
- FastDFS特别适合大中型网站使用,用来存储资源文件(如:图片、文档、音频、视频等等)
架构图:
相关术语讲解:
名词 | 描述 |
---|---|
Tracker Server | 跟踪服务器,主要做调度工作,在访问上起负载均衡的作用。记录storage server的状态,是连接Client和Storage server的枢纽 |
Storage Server | 存储服务器,文件和meta data都保存到存储服务器上 |
group | 组,也可称为卷。同组内服务器上的文件是完全相同的 |
文件标识 | 包括两部分:组名和文件名(包含路径) |
meta-data | 文件相关属性,键值对(Key Value Pair)方式,如:width=1024,heigth=768 |
架构解读:
- 只有两个角色,tracker server和storage server,不需要存储文件索引信息。
- 所有服务器都是对等的,不存在Master-Slave关系。
- 存储服务器采用分组方式,同组内存储服务器上的文件完全相同(RAID 1)。
- 不同组的storage server之间不会相互通信。
- 由storage server主动向tracker server报告状态信息,tracker server之间不会相互通信。
3 FastDFS安装
FastDFS的安装我们还是通过Docker来安装实现吧,直接在Linux上还装还是比较繁琐的,但就学习而言Docker安装还是非常高效的。
Docker环境请自行安装哦,不清楚的可以看看我的Docker专题的内容。
1_拉取镜像文件
首先我们可以通过 docker search fastdfs
来查询下有哪些镜像文件。
我们看到搜索到的镜像还是蛮多的,这里我们使用 delron/fastdfs
你也可以尝试使用其他的镜像来安装,你也可以制作自己的镜像来给别人使用哦,只是不同的镜像在使用的时候配置会有一些不一样,有些镜像没有提供Nginx的相关配置,使用的时候会繁琐一点。
接下来通过 docker pull delron/fastdfs
命令把镜像拉取下来(YGQYGQ2/fastdfs-nginx)。
2_构建Tracker服务
准备基本环境
mkdir -p /mydata/fastdfs/tracker
mkdir -p /mydata/fastdfs/storage
首先我们需要通过Docker命令来创建Tracker服务。命令为
docker run -d --name tracker --network=host -v /mydata/fastdfs/tracker:/var/fdfs delron/fastdfs tracker
tracker服务默认的端口为22122,-v 实现了容器和本地目录的挂载操作。
3_构建Storage服务
接下来创建Storage服务,具体的执行命令如下
docker run -d --name storage --network=host -e TRACKER_SERVER=192.168.200.129:22122 -v /mydata/fastdfs/storage:/var/fdfs -e GROUP_NAME=group1 delron/fastdfs storage
在执行上面命令的时候要注意对应的修改下,其中TRACKER_SERVER中的IP要修改为你的Tracker服务所在的服务IP地址。
默认情况下在Storage服务中是帮我们安装了Nginx服务的,相关的端口为
服务 | 默认端口 |
---|---|
tracker | 22122 |
storage | 23000 |
Nginx | 8888 |
当然如果你发现这些相关的端口被占用了,或者想要修改对应的端口信息也可以的。
不过这需要配置,你可以先进入容器中查看下相关的配置文件信息。
# 进入容器
docker exec -it storage bash
# 进入目录
cd /etc/fdfs
# 查看配置问价
ls
然后查看storage.conf文件(可以设置group、storage端口和nginx端口)
这个是storage监听的Nginx的端口8888,如果要修改那么我们还需要修改Nginx中的服务配置,这块的配置在 /usr/local/nginx/conf
目录下
查看下文件
所以要修改端口号的话,这两个位置都得修改了,当然本文我们就使用默认的端口号来使用了。
4_测试图片上传
好了,安装我们已经完成了,那么到底是否可以使用呢?我们来测试下。
首先在/mydata/fastdfs/storage
下保存一张图片。
然后我们再进入到storage容器中。并且进入到 /var/fdfs
目录下,可以看到我们挂载的文件了
然后执行如下命令即可完成图片的上传操作
/usr/bin/fdfs_upload_file /etc/fdfs/client.conf 1.jpg
通过上面的提示我们看到文件上传成功了,而且返回了文件在storage中存储的信息。
这时我们就可以通过这个信息来拼接访问的地址在浏览器中访问了:http://192.168.200.129:8888/group1/M00/00/00/wKjIgWf19-mAWO23AABSIMuaaeU816.jpg(如果访问不到可以尝试关闭防火墙)
到这儿FastDFS的服务安装成功了。
4 客户端操作
1_Fastdfs-java-client
首先我们来看下如何实现FastDFS中提供的JavaAPI来直接实现对应的文件上传和下载操作。
创建一个普通的maven项目,然后引入对应的依赖
<dependencies><dependency><groupId>cn.bestwu</groupId><artifactId>fastdfs-client-java</artifactId><version>1.27</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.4</version></dependency>
</dependencies>
然后编写FastDFS的配置文件,内容如下:注意ip修改为你自己对应的ip即可
connect_timeout = 10
network_timeout = 30
charset = UTF-8
http.tracker_http_port = 8080
tracker_server = 192.168.200.129:22122
然后导入对应的工具类,在工具类中完成了StorageClient的实例化,并提供了相关的上传和下载的方法。
package org.duration.fastdfs.config;import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.*;import java.io.*;
import java.util.Objects;@Slf4j
public class FastDFSClient {private static final String CONF_FILENAME = Objects.requireNonNull(Thread.currentThread().getContextClassLoader().getResource("")).getPath() + "fastdfs-config.conf";private static StorageClient storageClient = null;/*只加载一次.*/static {try {ClientGlobal.init(CONF_FILENAME);TrackerClient trackerClient = new TrackerClient(ClientGlobal.g_tracker_group);TrackerServer trackerServer = trackerClient.getConnection();StorageServer storageServer = trackerClient.getStoreStorage(trackerServer);storageClient = new StorageClient(trackerServer, storageServer);} catch (Exception e) {log.error(e.getMessage(), e);}}/*** @param inputStream 上传的文件输入流* @param fileName 上传的文件原始名* @return 【group,file_path】*/public static String[] uploadFile(InputStream inputStream, String fileName) {try {// 文件的元数据NameValuePair[] meta_list = new NameValuePair[2];// 第一组元数据,文件的原始名称meta_list[0] = new NameValuePair("file name", fileName);// 第二组元数据meta_list[1] = new NameValuePair("file length", inputStream.available() + "");// 准备字节数组byte[] file_buff = null;if (inputStream.available() > 0) {// 查看文件的长度int len = inputStream.available();// 创建对应长度的字节数组file_buff = new byte[len];// 将输入流中的字节内容,读到字节数组中。int read = inputStream.read(file_buff);}// 上传文件。参数含义:要上传的文件的内容(使用字节数组传递),上传的文件的类型(扩展名),元数据return storageClient.upload_file(file_buff, getFileExt(fileName), meta_list);} catch (Exception ex) {log.error(ex.getMessage(), ex);return null;}}/*** @param file 文件* @param fileName 文件名* @return 返回Null则为失败*/public static String[] uploadFile(File file, String fileName) {FileInputStream fis = null;try {NameValuePair[] meta_list = null; // new NameValuePair[0];fis = new FileInputStream(file);byte[] file_buff = null;int len = fis.available();if (len > 0) {file_buff = new byte[len];int read = fis.read(file_buff);}return storageClient.upload_file(file_buff, getFileExt(fileName), meta_list);} catch (Exception ex) {return null;} finally {if (fis != null) {try {fis.close();} catch (IOException e) {log.error(e.getMessage(), e);}}}}/*** 根据组名和远程文件名来删除一个文件** @param groupName 例如 "group1" 如果不指定该值,默认为group1* @param remoteFileName 例如"M00/00/00/wKgxgk5HbLvfP86RAAAAChd9X1Y736.jpg"* @return 0为成功,非0为失败,具体为错误代码*/public static int deleteFile(String groupName, String remoteFileName) {try {return storageClient.delete_file(groupName == null ? "group1" : groupName, remoteFileName);} catch (Exception ex) {return 0;}}/*** 修改一个已经存在的文件** @param oldGroupName 旧的组名* @param oldFileName 旧的文件名* @param file 新文件* @param fileName 新文件名* @return 返回空则为失败*/public static String[] modifyFile(String oldGroupName, String oldFileName, File file, String fileName) {String[] fileids = null;try {// 先上传fileids = uploadFile(file, fileName);if (fileids == null) {return null;}// 再删除int delResult = deleteFile(oldGroupName, oldFileName);if (delResult != 0) {return null;}} catch (Exception ex) {return null;}return fileids;}/*** 文件下载** @param groupName 卷名* @param remoteFileName 文件名* @return 返回一个流*/public static InputStream downloadFile(String groupName, String remoteFileName) {try {byte[] bytes = storageClient.download_file(groupName, remoteFileName);return new ByteArrayInputStream(bytes);} catch (Exception ex) {return null;}}public static NameValuePair[] getMetaDate(String groupName, String remoteFileName) {try {return storageClient.get_metadata(groupName, remoteFileName);} catch (Exception ex) {log.error(ex.getMessage(), ex);return null;}}/*** 获取文件后缀名(不带点).** @return 如:"jpg" or "".*/private static String getFileExt(String fileName) {if (StringUtils.isBlank(fileName) || !fileName.contains(".")) {return "";} else {return fileName.substring(fileName.lastIndexOf(".") + 1); // 不带最后的点}}}
然后我们就可以来测试上传的操作了。
2_文件上传
先来看下文件上传的流程
上传流程的文字梳理为:
- 客户端访问Tracker
- Tracker 返回Storage的IP和端口
- 客户端直接访问Storage,把文件内容和元数据发送过去。
- Storage返回文件存储id。包含了组名和文件名
//不可获取元数据信息
public static void fileUpload() {File file = new File("D:\\WorkSpace\\IdeaProject\\fastdfs_demo\\src\\main\\resources\\10937845.jpg");String[] strings = FastDFSClient.uploadFile(file, file.getName());if (strings == null) {return;}System.out.println("文件上传成功" + Arrays.asList(strings));
}
//可获取元数据
public static void fileUploadByMetaData() {File file = new File("D:\\WorkSpace\\IdeaProject\\fastdfs_demo\\src\\main\\resources\\10937845.jpg");try (InputStream is = new FileInputStream(file)) {String[] strings = FastDFSClient.uploadFile(is, file.getName());if (strings == null) {return;}System.out.println("文件上传成功" + Arrays.asList(strings));} catch (Exception e) {log.error(e.getMessage(), e);}
}
访问即可:http://192.168.200.129:8888/group1/M00/00/00/wKjIgWf2Ju-AZEFGAAAqSN2jiTQ329.jpg
返回后的字符串的结构说明
3_文件下载
文件下载的流程,如下
文件下载的流程为:
- client询问tracker需要下载的文件的storage,参数为文件的标识(group加文件名)。
- tracker根据客户端的参数返回一台可用的storage。
- client根据返回的storage直接完成对应的文件的下载。
有了上面的基础,文件下载就非常简单了,我们只需要根据前面上传的文件的group和文件的存储路径就可以通过StorageClient中提供的downloadFile方法把对应的文件下载下来了,具体的代码如下
public static void downloadFile() {String[] params = {"group1", "M00/00/00/wKjIgWf2Ju-AZEFGAAAqSN2jiTQ329.jpg"};try (InputStream is = FastDFSClient.downloadFile(params[0], params[1]);OutputStream os = new FileOutputStream("D:\\WorkSpace\\IdeaProject\\fastdfs_demo\\src\\main\\resources\\12.jpg")) {if (is == null) {return;}int index = 0;while ((index = is.read()) != -1) {os.write(index);}os.flush();} catch (IOException e) {log.error(e.getMessage(), e);}
}
4_获取文件信息
获取文件元数据信息
public static void getFileInfo() {String[] params = {"group1", "M00/00/00/wKjIgWf2NPqAamQdAAAqSN2jiTQ216.jpg"};NameValuePair[] metaDate = FastDFSClient.getMetaDate(params[0], params[1]);if (metaDate == null) {return;}for (NameValuePair nameValuePair : metaDate) {log.info("信息如下:{}={}", nameValuePair.getName(), nameValuePair.getValue());}
}
还有一些其他接口比如获取文件扩展名,可自行测试
5_问题
注意:StorageClient是线程不安全的。那么我们的解决方案
- 对文件的操作的每个方法我们做同步处理
- 每次操作文件的时候我们都获取一个新的StorageClient对象(全局变局部)
第一种方式效率肯定是最低的,第二种方式每次都要建立新的连接效率同样的会受到影响,这时最好的方式其实是把StorageClient交给我们自定义的连接池来管理
5 SpringBoot整合
我们在实际工作中基本都是和SpringBoot整合在一起来使用的,那么我们就来看看FastDFS是如何在SpringBoot项目中来使用的。
首先创建一个普通的SpringBoot项目,然后导入fastdfs-spring-boot-starter
这个依赖。
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope>
</dependency>
<dependency><groupId>com.luhuiguo</groupId><artifactId>fastdfs-spring-boot-starter</artifactId><version>0.2.0</version>
</dependency>
既然是一个starter,那么必然会在spring.factories文件中提供对应的自动配置类。
可以看到给我们提供的配置类为FdfsAutoConfiguration进入后可以看到帮我们注入了很多的核心对象。
然后可以看到系统提供的配置信息,前缀为 fdfs
然后我们就可以在application.yaml
中配置FastDFS的配置信息了。
fdfs:connect-timeout: 1000so-timeout: 1000tracker-list: 192.168.200.129:22122
配置完成后我们就可以测试文件的上传下载操作了
@SpringBootTest
class FastDfsSpringBootApplicationTests {@Autowiredpublic FastFileStorageClient storageClient;@Testvoid contextLoads() throws Exception{File file = new ClassPathResource("10937845.jpg").getFile();StorePath path = storageClient.uploadFile(null, new FileInputStream(file), file.length(), file.getName().substring(file.getName().lastIndexOf(".") + 1));System.out.println(path.getFullPath());}}
文件操作成功
相关文章:
分布式文件存储系统FastDFS
文章目录 1 分布式文件存储1_分布式文件存储的由来2_常见的分布式存储框架 2 FastDFS介绍3 FastDFS安装1_拉取镜像文件2_构建Tracker服务3_构建Storage服务4_测试图片上传 4 客户端操作1_Fastdfs-java-client2_文件上传3_文件下载4_获取文件信息5_问题 5 SpringBoot整合 1 分布…...
DNS域名解析(以实操为主)
目录 一.正向解析(在Linux下) 1.1什么是正向解析 1.2具体操作 1编辑主配置文件 /etc/named.conf 2编辑域名文件 /etc/named.rfc1912.zones 3根据域名文件中定义的名称,来建立数据库文件 4重启服务 5验证 二.正向解析(在…...
Spark运行架构 RDD相关概念Spark-Core编程
以下是今天学习的知识点: 第三节 Spark运行架构 运行架构 Spark 框架的核心是一个计算引擎,整体来说,它采用了标准 master-slave 的结构。 核心组件 对于 Spark 框架有两个核心组件: Driver Spark 驱动器节点,用…...
校园智能硬件国产化的现状与意义
以下是校园智能硬件国产化的现状与意义: 现状 政策支持力度大:近年来,国家出台了一系列政策推动教育数字化和国产化发展。如2022年教育部等六部门印发《关于推进教育新型基础设施建设构建高质量教育支撑体系的指导意见》,明确提出…...
Android里面如何优化xml布局
在 Android 开发中,以下是系统化的优化方案,从基础到高级分层解析: 一、基础优化策略 1. 减少布局层级 问题:每增加一层布局,测量/布局时间增加 1-2ms 解决方案: <!-- 避免嵌套 --> <LinearLayo…...
Android10.0 framework第三方无源码APP读写断电后数据丢失问题解决
1.前言 在10.0中rom定制化开发中,在某些产品开发中,在某些情况下在App用FileOutputStream读写完毕后,突然断电 会出现写完的数据丢失的问题,接下来就需要分析下关于使用FileOutputStream读写数据的相关流程,来实现相关 功能 2.framework第三方无源码APP读写断电后数据丢…...
LabVIEW驱动开发的解决思路
在科研项目中,常面临将其他语言开发的定制采集设备驱动转换为 LabVIEW 适用形式的难题。特别是当原驱动支持匮乏、开发人员技术支持不足时,如何抉择解决路径成为关键。以下提供具体解决思路,助力高效解决问题。 一、评估现有驱动死磕的可…...
【C++】 —— 笔试刷题day_13
一、牛牛冲钻五 题目描述 题目说,牛牛在玩炉石传说,现在牛牛进行了n场游戏,让我们判断牛牛上了几颗星。 首先输入一个T,表示T组数据; 然后输入n和k,表示一个进行了n场数据,k表示连胜三场及以上…...
【ROS】分布式通信架构
【ROS】分布式通信架构 前言环境要求主机设置(Master)从机设置(Slave)主机与从机通信测试本文示例启动ROS智能车激光雷达节点本地计算机配置与订阅 前言 在使用 ROS 时,我们常常会遇到某些设备计算能力不足的情况。例…...
【第39节】windows编程:打造MFC版本任务管理器
目录 一、项目概述 二、项目开发的各种功能关键 2.1 进程信息的获取 2.2 线程信息的获取 2.3 进程模块信息的获取 2.3.1 模块快照 2.3.2 枚举模块 2.4 进程堆信息的获取 2.5 窗口信息的获取 2.6 文件信息的获取 2.7 内存信息和CPU占用率的获取 2.7.1 内存信息相关结…...
1.认识C语言
上层:应用软件 下层:操作系统、硬件 C语言擅长于下层方面 计算机语言的发展:低级 ——> 高级 用计算机的二进制指令写代码(低级语言) —— > 汇编指令(低级语言,用到了助记符ÿ…...
MySQL下200GB大表备份,利用传输表空间解决停服发版表备份问题
MySQL下200GB大表备份,利用传输表空间解决停服发版表备份问题 问题背景 在停服发版更新时,需对 200GB 大表(约 200 亿行数据)进行快速备份以预防操作失误。 因为曾经出现过有开发写的发版语句里,UPDATE语句的WHERE条…...
《Sqoop 快速上手:安装 + 测试实战》
推荐原文 见:http://docs.xupengboo.top/bigdata/di/sqoop.html Sqoop(SQL-to-Hadoop) 是 Apache 开源的工具,专门用于在 Hadoop 生态系统(如 HDFS、Hive、HBase) 和 关系型数据库(如 MySQL、O…...
MySQL体系架构(二)
MySQL中的目录和文件 2.2.1.bin目录 在MysQL的安装目录下有一个特别特别重要的bin目录,这个目录下存放着许多可执行文件。 其他系统中的可执行文件与此的类似。这些可执行文件都是与服务器程序和客户端程序相关的。 2.2.1.1.启动MySQL服务器程序 在UNIX系统中用来启动MySO…...
为什么反激采用峰值电流控制模式而非电压模式
电压模式控制是传统的控制方法,通过检测输出电压,与参考电压比较,然后调整PWM的占空比。这种方法的优点是简单,只需要一个电压反馈环路。但缺点可能包括对输入电压变化的响应较慢,动态性能不足,尤其是在负载…...
JavaScript逆向工程中的插桩技术完全指南
一、什么是插桩技术? 插桩(Instrumentation)是逆向工程中的核心技术之一,指的是在不改变程序原有逻辑的前提下,向目标程序中插入额外的代码或监控点,用于收集运行时信息、修改程序行为或进行调试分析。 插…...
LLM应用实战1-基本概念
文章目录 基本概念1. 提示词工程(Prompt Engineering)2. AI Agent(智能代理)3. Model Context Protocol (MCP)4. Function Calling(函数调用)5. Retrieval-Augmented Generation (RAG)6. FineTuning&#x…...
数据结构--堆
一、堆的定义 堆是一棵完全二叉树,树中的每个结点的值都不小于(或不大于)其左右孩子结点的值。其中,如果父亲结点的值始终大于或等于孩子结点的值,那么称这样的堆为大顶堆,这时每个结点的值都是以它为根节…...
第37次CCF计算机软件能力认证 / T4 / 集体锻炼
题目 代码 #include <bits/stdc.h> using namespace std; using LL long long;const int N 1e6 10; const int mod 998244353; int a[N]; int st[N][22];int get(int l, int r) {int x r - l 1;int k log2(x);return __gcd(st[l][k], st[r - (1 << k) 1][…...
ES6规范新特性总结
ES6新特性 var、let和const不存在变量提升暂时性死区不允许重复声明 解构赋值用途:交换变量的值从函数返回多个值提取JSON数据遍历map结构输入模块的制定方法 字符串的扩展codePointAt()String.fromCharCode()at()includes(),startsWith(),endsWith()repeat()padSta…...
AI模型多阶段调用进度追踪系统设计文档
AI模型多阶段调用进度追踪系统设计文档 一、系统概述 为解决AI模型处理大型文件时响应时间长的问题,我们设计并实现了一套异步进度追踪系统。该系统采用Server-Sent Events (SSE) 技术,建立从服务器到客户端的单向实时通信通道,使前端能够实…...
[MSPM0开发]最新版ccs20.0安装、配置及导入第一个项目
一、ccs20.0 下载与安装 Code Composer Studio™ 集成式开发环境 (IDE),适用于 TI 微控制器和处理器的集成开发环境 (IDE)。它包含一整套丰富的工具,用于构建、调试、分析和优化嵌入式应用。 ccs下载地址 链接 安装比较简单,在次略过。 二、…...
Win10怎么关闭远程控制?
对于Windows 10用户来说,Win10关闭远程桌面可以有效防止不必要的远程连接,从而保护个人数据和系统安全。那么,Win10怎么关闭远程控制功能呢?接下来,我们将详细介绍Win10关闭远程控制的具体操作步骤。 步骤1.双击桌面上…...
AI重构知识生态:大模型时代的学习、创作与决策革新
📝个人主页🌹:慌ZHANG-CSDN博客 🌹🌹期待您的关注 🌹🌹 一、引言:从知识的获取到知识的共生 过去,我们对“知识”的理解,大多依赖书籍、老师、经验和专业的培训体系。而在大语言模型(Large Language Models, LLM)崛起之后,AI成为了一种新的“知识界面”:…...
牛客 小红杀怪
通过枚举所有使用y技能的次数来枚举出所有方案,选出最合适的 #include<iostream> #include<cmath> #include<algorithm> using namespace std;int a, b, x, y; int ans500;int main() {ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);cin>&…...
Spring入门概念 以及入门案例
Spring入门案例 Springspring是什么spring的狭义与广义spring的两个核心模块IoCAOP Spring framework特点spring入门案例不用new方法,如何使用返回创建的对象 容器:IoC控制反转依赖注入 Spring spring是什么 spring是一款主流的Java EE轻量级开源框架 …...
SpringAI调用硅基流动免费模型
一、引入Spring AI 新建一个Spring Boot的工程,在工程中引入Spring AI的依赖,Spring AI支持Ollma、类OpenAI的接口,这两个引入的pom不一样,这里示例中是使用的硅基流动的模型 <!-- Spring Boot版本要 2.x 或者 3.x以上-->…...
Java 开发中主流安全框架的详细对比,涵盖 认证、授权、加密、安全策略 等核心功能,帮助开发者根据需求选择合适的方案
以下是 Java 开发中主流安全框架的详细对比,涵盖 认证、授权、加密、安全策略 等核心功能,帮助开发者根据需求选择合适的方案: 1. 主流安全框架对比表 框架名称类型核心功能适用场景优点缺点官网/文档Spring Security企业级安全框架认证、授…...
【TVM教程】在支持 CMSIS-NN 的 Arm(R) Cortex(R)-M55 CPU 和 Ethos(TM)-U55 NPU 裸机上运行 TVM
Apache TVM是一个深度的深度学习编译框架,适用于 CPU、GPU 和各种机器学习加速芯片。更多 TVM 中文文档可访问 →https://tvm.hyper.ai/ 作者:Grant Watson 本节使用示例说明如何使用 TVM 在带有 CMSIS-NN 的 Arm Cortex-M55 CPU 和 Ethos™-U55 NPU 的…...
【Ai/Agent】Windows11中安装CrewAI过程中的错误解决记录
CrewAi是什么,可以看之下之前写的 《初识CrewAI多智能代理团队协框架》 (注:这篇是基于linux系统下安装实践的) 基于以下记录解决问题后,可以再回到之前的文章继续进行CrewAI的安装 遇到问题 在windows系统中安装 CrewAi 不管是使用 pip 或者…...
洛谷 P11962:[GESP202503 六级] 树上漫步 ← dfs + 邻接表
【题目来源】 https://www.luogu.com.cn/problem/P11962 【题目描述】 小 A 有一棵 n 个结点的树,这些结点依次以 1,2,⋯,n 标号。 小 A 想在这棵树上漫步。具体来说,小 A 会从树上的某个结点出发,每⼀步可以移动到与当前结点相邻的结点&…...
Linux shell脚本编程
什么是Shell程序设计? 也就是给计算机发命令,让它帮你做事,你通过shell 的小工具,用键盘输入指令,linux就会根据这些指令去执行任务,就像你法号一个指令一样。 shell的强大之处? 文件处理&a…...
嵌入式硬件篇---Uart和Zigbee
文章目录 前言一、UART(通用异步收发传输器)1. 基本概念2. 工作原理帧结构起始位数据位校验位停止位 异步通信波特率 3. 特点优点缺点 4. 典型应用 二、ZigBee1. 基本概念2. 技术细节工作频段2.4GHz868MHz 网络拓扑星型网络网状网络簇状网络 协议栈物理层…...
Linux Makefile-概述、语句格式、编写规则、多文件编程、Makefile变量分类:自定义变量、预定义变量
目录 1.make 1.1 make 命令格式 2.Makefile 核心概念 2.1创建并运行 Makefile步骤 3. Makefile编写 3.1最基础Makefile 3.1.1使用默认make命令 3.1.2使用make -f 命令 3.1.3 gcc编译常用组合选项 3.1.4 make 和 make all区别 3.1.4.1 all 是默认目标 3.1.4.2 al…...
Kotlin日常使用函数记录
文章目录 前言字符串集合1.两个集合的差集2.集合转数组2.1.集合转基本数据类型数组2.2.集合转对象数组 Map1.合并Map1.1.使用 操作符1.2.使用 操作符1.3.使用 putAll 方法1.4.使用 merge 函数 前言 记录一些kotlin开发中,日常使用的函数和方式之类的,…...
【JavaScript】异步编程
个人主页:Guiat 归属专栏:HTML CSS JavaScript 文章目录 1. 异步编程基础1.1 同步与异步1.1.1 同步执行1.1.2 异步执行 1.2 JavaScript 事件循环 2. 回调函数2.1 基本回调模式2.2 错误处理2.3 回调地狱 3. Promise3.1 Promise 基础3.2 Promise 链式调用3…...
批量合并多张 jpg/png 图片为长图或者 PDF 文件,支持按文件夹合并图片
我们经常会碰到需要将多张图片拼成一张图片的场景,比如将多张图片拼成九宫格图片,或者将多张图片拼成一张长图。还有可能会碰到需要将多张图片合并成一个完整的 PDF 文件来方便我们进行打印或者传输等操作。那这些将图片合并成一张图片或者一个完整的文档…...
使用docker 安装向量数据库Milvus
Miluvs 官网 www.milvus.io/ https://milvus.io/docs/zh/install_standalone-docker-compose-gpu.md 一、基本概念 向量数据库:Milvus是一款云原生向量数据库,它支持多种类型的向量,如浮点向量、二进制向量等,并且可以处理大规模…...
在线PDF文件拆分工具,小白工具功能实用操作简单,无需安装的文档处理工具
小白工具中的在线 PDF 文件拆分工具是一款功能实用、操作便捷的文档处理工具,以下是其具体介绍: 操作流程 上传 PDF 文档:打开小白工具在线PDF文件拆分工具 - 快速、免费拆分PDF文档 - 小白工具的在线 PDF 文件拆分页面,通过点击 …...
Blender画图——阵列使用
如图我需要多个图示的图形,并且排成一个阵列效果。 如图依次点击效果。不要用相对偏移,要用恒定偏移。 如图设置数量。 如图完成x方向的画图后,我们需要在y方向再用一个阵列。...
VSCode 常用快捷键
Visual Studio Code (VSCode) 提供了许多快捷键,以帮助开发者提高编码效率。以下是一些常用的 VSCode 快捷键,这些快捷键适用于大多数操作系统,但在 macOS 上可能会有所不同(通常是将 Ctrl 替换为 Cmd)。 1. 文件和编…...
缓存相关问题
Redis 持久化机制 缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级等问题 热点数据和冷数据是什么 Memcache与Redis的区别都有哪些? 单线程的redis为什么这么快 redis的数据类型,以及每种数据类型的使用场景,Redis 内部结构 redis的过期策略以及内存淘汰机制 Redis 为什么…...
每日一题(小白)暴力娱乐篇22
为什么要经常学习暴力和一些娱乐呢?因为对于我们来说,暴力是最直接的方式是肯定能满足一部分答案的方法,娱乐是为了让算法变得更有趣,你愿意多去尝试多去练习,这才是最要紧的。 由题意知,就是计算两个数字…...
深入理解 Vuex:核心概念、API 详解与最佳实践
目录 Vuex 简介核心概念与工作流程核心 API 详解模块化开发 (modules)插件(Plugins)与扩展高级技巧与最佳实践 Vuex 简介 Vuex 是 Vue.js 的官方状态管理库,专为复杂应用设计,用于集中管理所有组件的共享状…...
成为一种国家战略范畴的新基建的智慧园区开源了。
智慧园区场景视频监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒,省去繁琐重复的适配流程,实现芯片、算法、应用的全流程组合,从而大大减少企业级应用约95%的开发成本。用户只需在界…...
拜特科技助力科达制造,资金管理信息化迈入新阶段
近日,拜特科技成功签约科达制造股份有限公司(以下简称“科达制造”)资金管理系统升级项目。科达制造通过资金管理系统的不断迭代升级和优化,能够更加高效地管理和运用资金,提高企业的资金利用效率,满足企业…...
每日一题(小白)暴力娱乐篇20
这个题用瞪眼法解决,snakeaekns 代码如下👇 public static void main(String[] args) {Scanner scannew Scanner(System.in);System.out.println("aekns");scan.close();} 第二种方式:将snack拆解,按照大小进行排序。…...
Flutter iOS 项目中 VolumeControllerPlugin 报错解决方案
Flutter iOS 项目中 VolumeControllerPlugin 报错解决方案 在开发 Flutter 应用时,有时会遇到 iOS 项目构建失败的情况,其中一种较为常见的错误是与 VolumeControllerPlugin 相关的报错,错误信息如下: Could not build the prec…...
Java实战报错 tcp
为什么报错tcp Preview 从图片中的错误信息来看,程序遇到了 java.net.BindException,具体错误信息是 "Address already in use: bind"。这意味着你的程序试图绑定到一个已经被其他进程占用的端口(在本例中是9999端口)。…...
【补题】P10424 [蓝桥杯 2024 省 B] 好数(数位dp)
题意: 一个整数如果按从低位到高位的顺序,奇数位(个位、百位、万位……)上的数字是奇数,偶数位(十位、千位、十万位……)上的数字是偶数,我们就称之为“好数”。 给定一个正整数 N…...