当前位置: 首页 > news >正文

使用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,这个是之前的项目。

image-20240317212206535

事件监听

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();}
}

定时监听

项目架构

image-20240317234653713

运行效果

image-20240317234741826

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

image-20240317235255019

时间监听器

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了&#xff0c;里面的论文没有本地备份&#xff0c;最后费劲巴拉的在坚果云上找到了很早前的版本。我说可以上传到github&#xff0c;建一个私人仓库就行了&#xff0c;安全性应该有保证&#xff0c;毕竟不是啥学术大亨&#xff0c;不会有人偷你论文。但是…...

智慧城市新篇章:数字孪生的力量与未来

随着信息技术的迅猛发展和数字化浪潮的推进&#xff0c;智慧城市作为现代城市发展的新模式&#xff0c;正在逐步改变我们的生活方式和社会结构。在智慧城市的构建中&#xff0c;数字孪生技术以其独特的优势&#xff0c;为城市的规划、管理、服务等方面带来了革命性的变革。本文…...

python讲解(2)

目录 一.变量与赋值 二.字符串类型 引号&#xff1a; 三引号&#xff1a; 字符串拼接 三.len函数 四.注释 注释的方法 一.# 二.文档字符串 注释的要求 群体注释 五.python的报错 六.bool类型 一.变量与赋值 python中的变量是不需要声明的&#xff0c;直接定义即…...

安卓安装Magisk面具以及激活EdXposed

模拟器&#xff1a;雷电模拟器 安卓版本: Android9 文中工具下载链接合集&#xff1a;https://pan.baidu.com/s/1c1X3XFlO2WZhqWx0oE11bA?pwdr08s 前提准备 模拟器需要开启system可写入和root权限 一、安装Magisk 1. 安装magisk 将magisk安装包拖入模拟器 点击&#xff1a…...

C到C++的敲门砖-1

文章目录 关键字命名空间输入和输出缺省参数函数重载 关键字 相较于C语言32个关键字&#xff1a; autodoubleintstructbreakelselongswitchcaseenumregistertypedefcharexternreturnunionconstfloatshortunsignedcontinueforsignedvoiddefaultgotosizeofvolatiledoifwhilesta…...

Qt文件以及文件夹相关类(QDir、QFile、QFileInfo)的使用

关于Qt相关文件读写操作以及文件夹的一些知识&#xff0c;之前也写过一些博客&#xff1a; Qt关于路径的处理&#xff08;绝对路径、相对路径、路径拼接、工作目录、运行目录&#xff09;_qt 相对路径-CSDN博客 C/Qt 读写文件_qt c 读取文本文件-CSDN博客 C/Qt读写ini文件_…...

ChatGPT编程实现简易聊天工具

ChatGPT编程实现简易聊天工具 今天借助[[小蜜蜂]][https://zglg.work]网站的ChatGPT练习socket编程&#xff0c;实现一个简易聊天工具软件。 环境&#xff1a;Pycharm 2021 系统&#xff1a;Mac OS 向ChatGPT输入如下内容&#xff1a; ChatGPT收到后&#xff0c;根据返回结…...

C#-用于Excel处理的程序集

在.NET开发中&#xff0c;处理Excel文件是一项常见的任务&#xff0c;而有一些优秀的Excel处理包可以帮助开发人员轻松地进行Excel文件的读写、操作和生成。本文介绍了NPOI、EPPlus和Spire.XLS这三个常用的.NET Excel处理包&#xff0c;分别详细介绍了它们的特点、示例代码以及…...

HTTPS基础

目录 HTTPS简介 HTTP与HTTPS的区别 CA证书 案例 服务器生成私钥与证书 查看证书和私钥存放路径 Cockpit(图像化服务管理工具) HTTPS简介 超文本传输协议HTTP协议被用于在Web浏览器和网站服务器之间传递信息。HTTP协议以明文方式发送内容&#xff0c;不提供任何方式的数据加密&…...

【Flink SQL】Flink SQL 基础概念(四):SQL 的时间属性

《Flink SQL 基础概念》系列&#xff0c;共包含以下 5 篇文章&#xff1a; Flink SQL 基础概念&#xff08;一&#xff09;&#xff1a;SQL & Table 运行环境、基本概念及常用 APIFlink SQL 基础概念&#xff08;二&#xff09;&#xff1a;数据类型Flink SQL 基础概念&am…...

文字弹性跳动CSS3代码

文字弹性跳动CSS3代码&#xff0c;源码由HTMLCSSJS组成&#xff0c;记事本打开源码文件可以进行内容文字之类的修改&#xff0c;双击html文件可以本地运行效果&#xff0c;也可以上传到服务器里面&#xff0c;重定向这个界面 下载地址 文字弹性跳动CSS3代码...

前端小白的学习之路(事件流)

提示&#xff1a;事件捕获&#xff0c;事件冒泡&#xff0c;事件委托 目录 事件模型(DOM事件流) 1.事件是什么 2.事件流 1).事件流的三个阶段 3.参考代码 二、事件委托 1.概念 2.使用案例 3.阻止冒泡行为 事件模型(DOM事件流) 1.事件是什么 1). 事件是HTML和Javascr…...

电脑文件误删除如何恢复?分享三个简单数据恢复方法

在日常使用电脑的过程中&#xff0c;文件误删除的情况时有发生。无论是由于操作失误还是病毒感染&#xff0c;丢失的文件都可能对我们的工作和学习造成极大的影响。因此&#xff0c;掌握文件恢复的方法显得尤为重要。下面围绕“电脑文件误删除如何恢复”这一主题&#xff0c;给…...

MySQL实战:监控

监控指标 性能类指标 名称说明QPS数据库每秒处理的请求数量TPS数据库每秒处理的事务数量并发数数据库实例当前并行处理的会话数量连接数连接到数据库会话的数量缓存命中率Innodb的缓存命中率 功能类指标 名称说明可用性数据库是否正常对外提供服务阻塞当前是否有阻塞的会话…...

MySQL自增主键自动生成的主键重置

需求描述&#xff1a; 从主键1开始&#xff0c;insert操作自增了五个&#xff0c;库里五条数主键是1、2、3、4、5&#xff1b; 然后把主键是3、4、5的三条数据给删了&#xff0c;再继续insert&#xff0c;主键就是6了 因为这里表会把最大的数即5记住&#xff0c;下次自增即为…...

reverse_iterator实现

对于实现reverse_iterator&#xff0c;我们可以学栈和队列的实现过程&#xff0c;利用适配器&#xff0c;实现如下; #pragma oncetemplate<class Iterator,class Ref,class Ptr> class reverse_Iterator { public://构造函数&#xff1a;reverse_Iterator(Iterator it):…...

C++:什么情况下函数应该声明为纯虚函数

在C中&#xff0c;函数应该在以下情况下声明为纯虚函数&#xff1a; 抽象基类&#xff1a;当你希望定义一个基类&#xff0c;该基类不能被实例化&#xff0c;只能作为其他类的基类时&#xff0c;你应该在基类中声明至少一个纯虚函数。这样的基类被称为抽象基类。纯虚函数通过在…...

【全面了解自然语言处理三大特征提取器】RNN(LSTM)、transformer(注意力机制)、CNN

目录 一 、RNN1.RNN单个cell的结构2.RNN工作原理3.RNN优缺点 二、LSTM1.LSTM单个cell的结构2. LSTM工作原理 三、transformer1 Encoder&#xff08;1&#xff09;position encoding&#xff08;2&#xff09;multi-head-attention&#xff08;3&#xff09;add&norm 残差链…...

区块链推广海外市场怎么做,CloudNEO服务商免费为您定制个性化营销方案

随着区块链技术的不断发展和应用场景的扩大&#xff0c;区块链项目希望能够进入海外市场并取得成功已成为越来越多公司的目标之一。然而&#xff0c;要在海外市场推广区块链项目&#xff0c;需要采取有效的营销策略和措施。作为您的区块链项目营销服务商&#xff0c;CloudNEO将…...

【S5PV210】 | ARM的指令集合

【S5PV210】 | ARM的指令集合 时间&#xff1a;2024年3月17日23:32:06 目录 文章目录 【S5PV210】 | ARM的指令集合目录 ARM指令集具有一系列显著的特点。首先&#xff0c;它属于RISC&#xff08;精简指令集计算机&#xff09;架构&#xff0c;这意味着译码机制相对简单。在AR…...

web vue 项目 Docker化部署

Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段&#xff1a; 构建阶段&#xff08;Build Stage&#xff09;&#xff1a…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端&#xff0c;同时完善学生端的构建。本次工作主要包括&#xff1a; 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

3403. 从盒子中找出字典序最大的字符串 I

3403. 从盒子中找出字典序最大的字符串 I 题目链接&#xff1a;3403. 从盒子中找出字典序最大的字符串 I 代码如下&#xff1a; class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

【笔记】WSL 中 Rust 安装与测试完整记录

#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统&#xff1a;Ubuntu 24.04 LTS (WSL2)架构&#xff1a;x86_64 (GNU/Linux)Rust 版本&#xff1a;rustc 1.87.0 (2025-05-09)Cargo 版本&#xff1a;cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...

Redis:现代应用开发的高效内存数据存储利器

一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发&#xff0c;其初衷是为了满足他自己的一个项目需求&#xff0c;即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源&#xff0c;Redis凭借其简单易用、…...

android RelativeLayout布局

<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:gravity&…...

Ubuntu系统复制(U盘-电脑硬盘)

所需环境 电脑自带硬盘&#xff1a;1块 (1T) U盘1&#xff1a;Ubuntu系统引导盘&#xff08;用于“U盘2”复制到“电脑自带硬盘”&#xff09; U盘2&#xff1a;Ubuntu系统盘&#xff08;1T&#xff0c;用于被复制&#xff09; &#xff01;&#xff01;&#xff01;建议“电脑…...

区块链技术概述

区块链技术是一种去中心化、分布式账本技术&#xff0c;通过密码学、共识机制和智能合约等核心组件&#xff0c;实现数据不可篡改、透明可追溯的系统。 一、核心技术 1. 去中心化 特点&#xff1a;数据存储在网络中的多个节点&#xff08;计算机&#xff09;&#xff0c;而非…...

02.运算符

目录 什么是运算符 算术运算符 1.基本四则运算符 2.增量运算符 3.自增/自减运算符 关系运算符 逻辑运算符 &&&#xff1a;逻辑与 ||&#xff1a;逻辑或 &#xff01;&#xff1a;逻辑非 短路求值 位运算符 按位与&&#xff1a; 按位或 | 按位取反~ …...