使用gitee自动备份文件
需求
舍友磁盘前两天gg了,里面的论文没有本地备份,最后费劲巴拉的在坚果云上找到了很早前的版本。我说可以上传到github,建一个私人仓库就行了,安全性应该有保证,毕竟不是啥学术大亨,不会有人偷你论文。但是他嫌每次写完还得手动操作,能不能写一个自动检测修改的软件,然后修改后就自动上传到github上。
第一反应是,需要word提供的接口,使用观察者模式,从而检测修改,然后通过github的API,开发一个上传文件的软件。但是通过word开发实在是太难了。
然后今天想了想,完全不需要,直接写个定时任务,10分钟检查下是否有文件进行修改就行了。本来就不要求较高的实时性,所以根本用不到观察者模式。
这样的话就有两种选择了,第一通过Java调用git然后进行文件的提交和上传,第二就是自己开发一个类似于git的工具,针对文件的创建,修改和删除进行对应的github仓库修改。
今天的话,是想着使用第二种方式的,确实有点难,用了一下午时间,才完成了文件的上传功能。
使用第二种方式,需要分析:
- git add .和git commit实现的功能
- git pull和push实现的功能
使用第一种方式,就简单许多
- 监听时间
- 使用jgit进行上传文件
简单设计
- 监听类 Listenner :负责监听目录/文件等的变化。
- 上传类 UpLoader : 负责将文件上传到github或者gitee或者其他云盘上
- GiteeUpLoader
- GithubUpLoader
- GitUploader
- 主类 Main
- utils类
- 常量(使用接口),异常,还有配置文件,工具文件等
差不多类似于这样吧,忽略chapter1,这个是之前的项目。

事件监听
Gitee文件上传类
package autoSendFiles.uploaders;import autoSendFiles.constants.UploadConstants;
import autoSendFiles.exception.NullPropertiesException;import java.io.*;import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;import autoSendFiles.interfaces.Uploader;
import okhttp3.*;
import org.apache.commons.lang3.StringUtils;/*** @author: Zekun Fu* @date: 2024/3/17 12:12* @Description: 通过调用git的方式,将文件上传到Gited中*/
public class GiteeUploader implements Uploader {private String accessToken;private String username;private String repository;private String branch;public GiteeUploader() throws NullPropertiesException {// 读取参数,如果没有配置,抛出异常try (InputStream input = new FileInputStream(UploadConstants.APP_PROPERTIES_PATH)) {Properties properties = new Properties();// 加载 properties 文件properties.load(input);// 获取属性值this.accessToken = properties.getProperty("gitee.accessToken");this.username = properties.getProperty("gitee.username");this.repository = properties.getProperty("gitee.repository");this.branch = properties.getProperty("gitee.branch");if (StringUtils.isAnyEmpty(accessToken, username, repository, branch))throw new NullPropertiesException("未配置Gitee属性,请先配置!");} catch (IOException e) {System.out.println("系统异常!请联系管理员");e.printStackTrace();}}public List<File> upload(List<File> files) {return uploadHelper(files);}private List<File> uploadHelper(List<File>files) {List<File>failUploadFiles = new ArrayList<>();for (File file : files) {// 如果没有上传成功,需要放入到传输失败列表中try {if (!upload(file))failUploadFiles.add(file);} catch (IOException e) {failUploadFiles.addAll(files);e.printStackTrace();}}return failUploadFiles;}private boolean upload(File file) throws IOException {// 生成路径,提交信息,以及提交文件的base64编码String savePath = getSavePath(file);String message = generatorSendMessage();String content = this.fileBase64(file);// 创建 http 客户端String apiUrl = String.format(UploadConstants.UPLOAT_URL, this.username, this.repository, savePath);OkHttpClient client = new OkHttpClient();// 创建请求体RequestBody requestBody = new MultipartBody.Builder().setType(MultipartBody.FORM).addFormDataPart(UploadConstants.ACCESS_TOKEN, this.accessToken).addFormDataPart(UploadConstants.CONTENT, content).addFormDataPart(UploadConstants.MESSAGE, message).addFormDataPart(UploadConstants.BRANCH, this.branch).build();// 创建 http 请求Request request = new Request.Builder().url(apiUrl).post(requestBody).build();// 接收响应Response response = client.newCall(request).execute();// 上传if (response.isSuccessful()) {System.out.println("文件上传成功!");return true;} else {System.out.println("文件上传失败:" + response.code() + " " + response.message());return false;}}private String generatorSendMessage() {LocalDateTime currentDateTime = LocalDateTime.now();DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm");String formattedDateTime = currentDateTime.format(formatter);String msg = formattedDateTime + "提交";return msg;}private String fileBase64(File file) throws IOException {return Base64.getEncoder().encodeToString(fileToByteArray(file));}private byte[] fileToByteArray(File file) throws IOException {byte[] data = new byte[(int) file.length()];try (FileInputStream fis = new FileInputStream(file)) {fis.read(data);}return data;}/*** @return 生成路径, 如果为空,说明生成错了,没有.git文件夹* */private String getSavePath(File file) {StringBuffer savePath = new StringBuffer();return UploadConstants.DIR_SPLIT + findGitDirectory(file, savePath);}/*** @return 递归获取路径,直到碰到.git为止* */private String findGitDirectory(File directory, StringBuffer savePath) {StringBuffer curPath = new StringBuffer(directory.getName());if (!StringUtils.isEmpty(savePath)) curPath.append(UploadConstants.DIR_SPLIT).append(savePath);File gitDirectory = new File(directory, UploadConstants.ROOT_DIR);if (gitDirectory.exists() && gitDirectory.isDirectory()) {return savePath.toString();} else {File parentDirectory = directory.getParentFile();if (parentDirectory != null) {return findGitDirectory(parentDirectory, curPath);} else {return null;}}}public static void testGenerateSendMesage(GiteeUploader uploader) {System.out.println("提交msg为:" + uploader.generatorSendMessage());}public static void testGetPath(GiteeUploader uploader, File file) {// 1. 如果不包含.git文件// 2. Linux的和windows的分隔符不一样// 3. 其他特殊情况String filePath = uploader.getSavePath(file);if (!StringUtils.isEmpty(filePath)) {System.out.println("当前的保存路径为:" + filePath);}else System.out.println("测试失败,无法获取当前文件的路径");}public static GiteeUploader testCreateUploader() throws IOException, NullPropertiesException{GiteeUploader uploader = new GiteeUploader();return uploader;}public static void testBase64(GiteeUploader uploader, File file) throws IOException {String content = uploader.fileBase64(file);if (StringUtils.isEmpty(content)) {System.out.println("base64编码后的内容为空!");return ;}System.out.println("base64编码后的内容为:" + content);}public static void testUpLoad() throws IOException, NullPropertiesException {String FilePath = "D:\\learning\\论文\\毕业论文\\毕业论文备份\\test.txt";GiteeUploader uploader = new GiteeUploader();File file = new File(FilePath);uploader.upload(new File(FilePath));}public static void test() throws NullPropertiesException, IOException {System.out.println("测试开始...");String FilePath = "D:\\learning\\论文\\毕业论文\\毕业论文备份\\test.txt";GiteeUploader uploader = testCreateUploader();testGenerateSendMesage(uploader);File file = new File(FilePath);testGetPath(uploader, file);testBase64(uploader, file);testUpLoad();System.out.println("测试完成...");}public static void main(String[] args) throws NullPropertiesException, IOException{test();}
}
定时监听
项目架构

运行效果

运行结果:固定时间进行扫描提交

时间监听器
package autoSendFiles.Listener;import autoSendFiles.constants.ApplicationConstants;
import autoSendFiles.constants.PropertyConstants;
import autoSendFiles.interfaces.Listenner;
import autoSendFiles.interfaces.Uploader;
import autoSendFiles.utils.AppPropertiesUtils;/*** @author: Zekun Fu* @date: 2024/3/17 23:02* @Description:*/
public class TimeListenner implements Listenner, Runnable{private Thread thread;private Uploader uploader;private int listenTime;public TimeListenner(Uploader uploader) {this.uploader = uploader;this.listenTime = Integer.parseInt(AppPropertiesUtils.getProperty(PropertyConstants.LISTEN_TIME));}@Overridepublic void run() {System.out.println("线程监听开始...");while (true) {if (this.thread.isInterrupted()) {// 实际结束线程的地方break;}try {// 上传修改的文件System.out.println("同步中...");this.uploader.uploadAllChanges();System.out.println("同步完成...");// 睡眠Thread.sleep(ApplicationConstants.TO_SECONDS * this.listenTime);} catch (InterruptedException e) {// 这里处理善后工作// 重新进行标记,从而可以结束线程this.thread.interrupt();}}}@Overridepublic void listen() {// 开启线程进行监听System.out.println("开启新线程,启动监听...");this.thread = new Thread(this);thread.start();}public void stop() {this.thread.interrupt();}
}
主线程
package autoSendFiles;import autoSendFiles.Listener.TimeListenner;
import autoSendFiles.constants.ApplicationConstants;
import autoSendFiles.constants.PropertyConstants;
import autoSendFiles.exception.NullPropertiesException;
import autoSendFiles.interfaces.Uploader;
import autoSendFiles.uploaders.GitUploader;
import autoSendFiles.utils.AppPropertiesUtils;import javax.imageio.IIOException;
import java.io.File;
import java.util.ArrayList;
import java.util.List;/*** @author: Zekun Fu* @date: 2024/3/17 12:12* @Description:*/
public class Main {public static void main(String[] args) throws NullPropertiesException, IIOException {Uploader uploader = new GitUploader();TimeListenner listenner = new TimeListenner(uploader);listenner.listen();try {int times = Integer.parseInt(AppPropertiesUtils.getProperty(PropertyConstants.RUN_TIME));Thread.sleep(times * ApplicationConstants.TEN_MINUTES);} catch (InterruptedException e) {e.printStackTrace();}// 100min后结束listenner.stop();}
}
Git上传器
package autoSendFiles.uploaders;import autoSendFiles.constants.ApplicationConstants;
import autoSendFiles.constants.PropertyConstants;
import autoSendFiles.constants.UploadConstants;
import autoSendFiles.exception.NullPropertiesException;
import autoSendFiles.interfaces.Uploader;
import autoSendFiles.utils.AppPropertiesUtils;
import autoSendFiles.utils.DateUtils;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jgit.api.AddCommand;
import org.eclipse.jgit.api.CommitCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.PushCommand;
import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.transport.RefSpec;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import org.eclipse.jgit.util.IO;import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;/*** @author: Zekun Fu* @date: 2024/3/17 22:20* @Description: 静态常量设计的不行! gitee和github的不分了。* 重新开启一个文件叫做参数常量文件就行了。*/
public class GitUploader implements Uploader {private String workDir;private String remoteName;private String branch;private String password;private String username;public GitUploader() throws NullPropertiesException {workDir = AppPropertiesUtils.getProperty(PropertyConstants.WORK_DIR);remoteName = AppPropertiesUtils.getProperty(PropertyConstants.GITEE_REMOTE_NAME);branch = AppPropertiesUtils.getProperty(PropertyConstants.GITEE_BRANCH);password = AppPropertiesUtils.getProperty(PropertyConstants.GITEE_PASSWORD);username =AppPropertiesUtils.getProperty(PropertyConstants.GITEE_USERNAME);if (StringUtils.isAnyEmpty(workDir, remoteName, branch, password)) {throw new NullPropertiesException("没有配置工作文件夹,检查配置文件!");}}@Overridepublic List<File> upload(List<File> files) {List<File>failList = this.uploadHelper(files);this.commit();this.push();return failList;}@Overridepublic void uploadAllChanges() {this.pushAllChanges();}/*** 完成所有修改文件的同步* */private void pushAllChanges() {this.addAll();this.commit();this.push();}public boolean add(String filePath) {try (Git git = Git.open(new File(this.workDir))) {AddCommand addCommand = git.add();addCommand.addFilepattern(filePath);addCommand.call();System.out.println(filePath + " 添加完成。");return true;} catch (Exception e) {e.printStackTrace();return false;}}public void addAll() {try (Git git = Git.open(new File(this.workDir))) {AddCommand addCommand = git.add();addCommand.addFilepattern(".");addCommand.call();System.out.println("Git add . 操作完成。");} catch (Exception e) {e.printStackTrace();}}public void commit() {try (Git git = Git.open(new File(this.workDir))) {CommitCommand commitCommand = git.commit();commitCommand.setMessage(this.getCommitMessage());commitCommand.call();System.out.println("Git commit 操作完成。");} catch (Exception e) {e.printStackTrace();}}public void commit(String msg) {try (Git git = Git.open(new File(this.workDir))) {CommitCommand commitCommand = git.commit();commitCommand.setMessage(msg);commitCommand.call();System.out.println("Git commit 操作完成。");} catch (Exception e) {e.printStackTrace();}}public void push() {try (Git git = Git.open(new File(this.workDir))) {PushCommand pushCommand = git.push();pushCommand.setRemote(remoteName);pushCommand.setRefSpecs(new RefSpec(this.branch));// 用户密码验证CredentialsProvider credentialsProvider = new UsernamePasswordCredentialsProvider(this.username, this.password);pushCommand.setCredentialsProvider(credentialsProvider);pushCommand.call();System.out.println("Git push 操作完成。");} catch (Exception e) {e.printStackTrace();}}private List<File>uploadHelper(List<File> files) {List<File>failedFile = new ArrayList<>();for (File f : files) {if (!this.add(f.getName()))failedFile.add(f);}return failedFile;}private String getCommitMessage() {return DateUtils.getCurTime(ApplicationConstants.MIN_PATTERN) + "提交";}public static void testGitUploader() throws IOException, NullPropertiesException {Uploader uploader = new GitUploader();List<File> fileList = new ArrayList<>();String[] filePathList = {"D:\\projects\\java\\projects\\autoCommit\\test3.txt", "D:\\projects\\java\\projects\\autoCommit\\test4.txt"};for (String filePath : filePathList) {fileList.add(new File(filePath));}List<File>failedFiles = uploader.upload(fileList);if (failedFiles.size() != 0) {System.out.println("上传失败的文件有:");for (File file : failedFiles) {System.out.println(file.getName());}}}public static void main(String[] args) throws NullPropertiesException , IOException{
// new GitUploader().push();GitUploader uploader = new GitUploader();uploader.add("test3.txt");}
}
工具文件
package autoSendFiles.utils;import autoSendFiles.constants.UploadConstants;
import autoSendFiles.exception.NullPropertiesException;
import org.apache.commons.lang3.StringUtils;import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;/*** @author: Zekun Fu* @date: 2024/3/17 21:50* @Description:*/
public class AppPropertiesUtils {private static Properties properties = new Properties();static {// 读取参数,如果没有配置,抛出异常try (InputStream input = new FileInputStream(UploadConstants.APP_PROPERTIES_PATH)) {// 加载 properties 文件properties.load(input);} catch (IOException e) {System.out.println("系统异常!请联系管理员");e.printStackTrace();}}public static String getProperty(String key) {return properties.getProperty(key);}
}
package autoSendFiles.utils;import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;/*** @author: Zekun Fu* @date: 2024/3/17 21:43* @Description:*/
public class DateUtils {public static String getCurTime(String pattern) {LocalDateTime currentDateTime = LocalDateTime.now();DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);return currentDateTime.format(formatter);}
}
配置文件
# gitee配置
gitee.accessToken=你的口令
gitee.branch=本地分支
gitee.username=用户名
gitee.password=密码
gitee.repository=仓库
gitee.remoteName=远程分成# 监听的git路径
work.dir=D:/projects/java/projects/autoCommit# 监听的时间间隔10min
listen.time=10# 程序运行时间100min
run.time=100
常量文件
package autoSendFiles.constants;/*** @author: Zekun Fu* @date: 2024/3/17 21:45* @Description:*/
public interface ApplicationConstants {String MIN_PATTERN = "yyyy/MM/dd HH:mm";int TEN_MINUTES = 1000 * 60 * 10;int TWENTY_MINUTES = 1000 * 60 * 20;int TO_SECONDS = 1000;int TO_MIMUTES = 1000 * 60;
}
package autoSendFiles.constants;/*** @author: Zekun Fu* @date: 2024/3/17 22:39* @Description: 配置Key的常量*/
public interface PropertyConstants {String GITEE_BRANCH = "gitee.branch";String GITEE_REMOTE_NAME="gitee.remoteName";String WORK_DIR = "work.dir";String GITEE_PASSWORD = "gitee.password";String GITEE_USERNAME = "gitee.username";String LISTEN_TIME = "listen.time";String RUN_TIME = "run.time";
}
package autoSendFiles.constants;/*** @author: Zekun Fu* @date: 2024/3/17 20:01* @Description:*/
public interface UploadConstants {String UPLOAT_URL = "https://gitee.com/api/v5/repos/%s/%s/contents/%s";String ACCESS_TOKEN = "access_token";String CONTENT = "content";String MESSAGE = "message";String BRANCH = "branch";String ROOT_DIR = ".git";String DIR_SPLIT = "/";String APP_PROPERTIES_PATH = "src/main/resources/application.properties";
}
异常类
package autoSendFiles.exception;/*** @author: Zekun Fu* @date: 2024/3/17 18:18* @Description:*/
public class NullPropertiesException extends Exception{public NullPropertiesException(String msg) {super(msg);}
}
maven依赖
<dependencies><!-- Apache HttpClient Core --><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.13</version></dependency><!-- Apache HttpClient Mime --><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpmime</artifactId><version>4.5.13</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.12.0</version></dependency><dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId><version>4.9.3</version></dependency><dependency><groupId>org.eclipse.jgit</groupId><artifactId>org.eclipse.jgit</artifactId><version>5.13.0.202109080827-r</version></dependency></dependencies>
总结
- 没有实现事件监听器,可以通过listenner进行扩展
- 文件上传器,接口设计的不好,应该单一职责,这里两个职责了。一个是上传文件,一个是上传所有变化的文件
- 没有实现图像化结面
下一步
- 实现
git pull的功能,进行文件的覆盖 - 实现事件监听功能
相关文章:
使用gitee自动备份文件
需求 舍友磁盘前两天gg了,里面的论文没有本地备份,最后费劲巴拉的在坚果云上找到了很早前的版本。我说可以上传到github,建一个私人仓库就行了,安全性应该有保证,毕竟不是啥学术大亨,不会有人偷你论文。但是…...
智慧城市新篇章:数字孪生的力量与未来
随着信息技术的迅猛发展和数字化浪潮的推进,智慧城市作为现代城市发展的新模式,正在逐步改变我们的生活方式和社会结构。在智慧城市的构建中,数字孪生技术以其独特的优势,为城市的规划、管理、服务等方面带来了革命性的变革。本文…...
python讲解(2)
目录 一.变量与赋值 二.字符串类型 引号: 三引号: 字符串拼接 三.len函数 四.注释 注释的方法 一.# 二.文档字符串 注释的要求 群体注释 五.python的报错 六.bool类型 一.变量与赋值 python中的变量是不需要声明的,直接定义即…...
安卓安装Magisk面具以及激活EdXposed
模拟器:雷电模拟器 安卓版本: Android9 文中工具下载链接合集:https://pan.baidu.com/s/1c1X3XFlO2WZhqWx0oE11bA?pwdr08s 前提准备 模拟器需要开启system可写入和root权限 一、安装Magisk 1. 安装magisk 将magisk安装包拖入模拟器 点击:…...
C到C++的敲门砖-1
文章目录 关键字命名空间输入和输出缺省参数函数重载 关键字 相较于C语言32个关键字: autodoubleintstructbreakelselongswitchcaseenumregistertypedefcharexternreturnunionconstfloatshortunsignedcontinueforsignedvoiddefaultgotosizeofvolatiledoifwhilesta…...
Qt文件以及文件夹相关类(QDir、QFile、QFileInfo)的使用
关于Qt相关文件读写操作以及文件夹的一些知识,之前也写过一些博客: Qt关于路径的处理(绝对路径、相对路径、路径拼接、工作目录、运行目录)_qt 相对路径-CSDN博客 C/Qt 读写文件_qt c 读取文本文件-CSDN博客 C/Qt读写ini文件_…...
ChatGPT编程实现简易聊天工具
ChatGPT编程实现简易聊天工具 今天借助[[小蜜蜂]][https://zglg.work]网站的ChatGPT练习socket编程,实现一个简易聊天工具软件。 环境:Pycharm 2021 系统:Mac OS 向ChatGPT输入如下内容: ChatGPT收到后,根据返回结…...
C#-用于Excel处理的程序集
在.NET开发中,处理Excel文件是一项常见的任务,而有一些优秀的Excel处理包可以帮助开发人员轻松地进行Excel文件的读写、操作和生成。本文介绍了NPOI、EPPlus和Spire.XLS这三个常用的.NET Excel处理包,分别详细介绍了它们的特点、示例代码以及…...
HTTPS基础
目录 HTTPS简介 HTTP与HTTPS的区别 CA证书 案例 服务器生成私钥与证书 查看证书和私钥存放路径 Cockpit(图像化服务管理工具) HTTPS简介 超文本传输协议HTTP协议被用于在Web浏览器和网站服务器之间传递信息。HTTP协议以明文方式发送内容,不提供任何方式的数据加密&…...
【Flink SQL】Flink SQL 基础概念(四):SQL 的时间属性
《Flink SQL 基础概念》系列,共包含以下 5 篇文章: Flink SQL 基础概念(一):SQL & Table 运行环境、基本概念及常用 APIFlink SQL 基础概念(二):数据类型Flink SQL 基础概念&am…...
文字弹性跳动CSS3代码
文字弹性跳动CSS3代码,源码由HTMLCSSJS组成,记事本打开源码文件可以进行内容文字之类的修改,双击html文件可以本地运行效果,也可以上传到服务器里面,重定向这个界面 下载地址 文字弹性跳动CSS3代码...
前端小白的学习之路(事件流)
提示:事件捕获,事件冒泡,事件委托 目录 事件模型(DOM事件流) 1.事件是什么 2.事件流 1).事件流的三个阶段 3.参考代码 二、事件委托 1.概念 2.使用案例 3.阻止冒泡行为 事件模型(DOM事件流) 1.事件是什么 1). 事件是HTML和Javascr…...
电脑文件误删除如何恢复?分享三个简单数据恢复方法
在日常使用电脑的过程中,文件误删除的情况时有发生。无论是由于操作失误还是病毒感染,丢失的文件都可能对我们的工作和学习造成极大的影响。因此,掌握文件恢复的方法显得尤为重要。下面围绕“电脑文件误删除如何恢复”这一主题,给…...
MySQL实战:监控
监控指标 性能类指标 名称说明QPS数据库每秒处理的请求数量TPS数据库每秒处理的事务数量并发数数据库实例当前并行处理的会话数量连接数连接到数据库会话的数量缓存命中率Innodb的缓存命中率 功能类指标 名称说明可用性数据库是否正常对外提供服务阻塞当前是否有阻塞的会话…...
MySQL自增主键自动生成的主键重置
需求描述: 从主键1开始,insert操作自增了五个,库里五条数主键是1、2、3、4、5; 然后把主键是3、4、5的三条数据给删了,再继续insert,主键就是6了 因为这里表会把最大的数即5记住,下次自增即为…...
reverse_iterator实现
对于实现reverse_iterator,我们可以学栈和队列的实现过程,利用适配器,实现如下; #pragma oncetemplate<class Iterator,class Ref,class Ptr> class reverse_Iterator { public://构造函数:reverse_Iterator(Iterator it):…...
C++:什么情况下函数应该声明为纯虚函数
在C中,函数应该在以下情况下声明为纯虚函数: 抽象基类:当你希望定义一个基类,该基类不能被实例化,只能作为其他类的基类时,你应该在基类中声明至少一个纯虚函数。这样的基类被称为抽象基类。纯虚函数通过在…...
【全面了解自然语言处理三大特征提取器】RNN(LSTM)、transformer(注意力机制)、CNN
目录 一 、RNN1.RNN单个cell的结构2.RNN工作原理3.RNN优缺点 二、LSTM1.LSTM单个cell的结构2. LSTM工作原理 三、transformer1 Encoder(1)position encoding(2)multi-head-attention(3)add&norm 残差链…...
区块链推广海外市场怎么做,CloudNEO服务商免费为您定制个性化营销方案
随着区块链技术的不断发展和应用场景的扩大,区块链项目希望能够进入海外市场并取得成功已成为越来越多公司的目标之一。然而,要在海外市场推广区块链项目,需要采取有效的营销策略和措施。作为您的区块链项目营销服务商,CloudNEO将…...
【S5PV210】 | ARM的指令集合
【S5PV210】 | ARM的指令集合 时间:2024年3月17日23:32:06 目录 文章目录 【S5PV210】 | ARM的指令集合目录 ARM指令集具有一系列显著的特点。首先,它属于RISC(精简指令集计算机)架构,这意味着译码机制相对简单。在AR…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...
IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
Java + Spring Boot + Mybatis 实现批量插入
在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法:使用 MyBatis 的 <foreach> 标签和批处理模式(ExecutorType.BATCH)。 方法一:使用 XML 的 <foreach> 标签ÿ…...
Go语言多线程问题
打印零与奇偶数(leetcode 1116) 方法1:使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...
MySQL:分区的基本使用
目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区(Partitioning)是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分(分区)可以独立存储、管理和优化,…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...
认识CMake并使用CMake构建自己的第一个项目
1.CMake的作用和优势 跨平台支持:CMake支持多种操作系统和编译器,使用同一份构建配置可以在不同的环境中使用 简化配置:通过CMakeLists.txt文件,用户可以定义项目结构、依赖项、编译选项等,无需手动编写复杂的构建脚本…...
Xela矩阵三轴触觉传感器的工作原理解析与应用场景
Xela矩阵三轴触觉传感器通过先进技术模拟人类触觉感知,帮助设备实现精确的力测量与位移监测。其核心功能基于磁性三维力测量与空间位移测量,能够捕捉多维触觉信息。该传感器的设计不仅提升了触觉感知的精度,还为机器人、医疗设备和制造业的智…...
