云备份项目
云备份项目
1. 云备份认识
自动将本地计算机上指定文件夹中需要备份的文件上传备份到服务器中。并且能够随时通过浏览器进行查看并且下载,其中下载过程支持断点续传功能,而服务器也会对上传文件进行热点管理,将非热点文件进行压缩存储,节省磁盘空间。
2. 实现目标
这个云备份项目需要我们实现两端程序,其中包括部署在用户机的客户端程序,上传需要备份的文件,以及运行在服务器上的服务端程序,实现备份文件的存储和管理,两端合作实现总体的自动云备份功能。
3. 功能划分
3.1 服务端
3.1.1 服务端程序负责功能
- 针对客户端上传的文件进行备份存储
- 能够对文件进行热点文件管理,对非热点文件进行压缩存储,节省磁盘空间。
- 支持客户端浏览器查看访问文件列表。
- 支持客户端浏览器下载文件,并且下载支持断点续传。
3.1.2. 服务端功能模块划分
- 数据管理模块:负责服务器上备份文件的信息管理。
- 网络通信模块:搭建网络通信服务器,实现与客户端通信。
- 业务处理模块:针对客户端的各个请求进行对应业务处理并响应结果。
- 热点管理模块:负责文件的热点判断,以及非热点文件的压缩存储。
3.2 客户端
3.2.1 客户端程序负责功能
- 能够自动检测客户机指定文件夹中的文件,并判断是否需要备份
- 将需要备份的文件逐个上传到服务器
3.2.2 客户端功能模块划分
- 数据管理模块:负责客户端备份的文件信息管理,通过这些数据可以确定一个文件是否需要备份。
- 文件检测模块:遍历获取指定文件夹中所有文件路径名称。
- 网络通信模块:搭建网络通信客户端,实现将文件数据备份上传到服务器。
4. 第三方库
4.1 jsoncpp
json
是一种数据交换格式,采用完全独立于编程语言的文本格式来存储和表示数据。
json
数据类型:对象:使用花括号{}
括起来的表示一个对象。数组:使用中括号[]
括起来的表示一个数组。字符串:使用常规双引号""
括起来的表示一个字符串。数字:包括整形和浮点型,直接使用。
例如:小明同学的学生信息
char name = "小明";
int age = 18;
float score[3] = {88.5, 99, 58};
则json这种数据交换格式是将这多种数据对象组织成为一个字符串:
[{"姓名" : "小明","年龄" : 18,"成绩" : [88.5, 99, 58]},{"姓名" : "小黑","年龄" : 18,"成绩" : [88.5, 99, 58]}
]
jsoncpp
库用于实现json
格式的序列化和反序列化,完成将多个数据对象组织成为json
格式字符串,以及将json
格式字符串解析得到多个数据对象的功能。
这其中主要借助三个类以及其对应的少量成员函数完成:
//Json数据对象类
class Json::Value{Value &operator=(const Value &other); //Value重载了[]和=,因此所有的赋值和获取数据都可以通过Value& operator[](const std::string& key);//简单的方式完成 val["姓名"] = "小明";Value& operator[](const char* key);Value removeMember(const char* key);//移除元素const Value& operator[](ArrayIndex index) const; //val["成绩"][0]Value& append(const Value& value);//添加数组元素val["成绩"].append(88); ArrayIndex size() const;//获取数组元素个数 val["成绩"].size();std::string asString() const;//转string string name = val["name"].asString();const char* asCString() const;//转char* char *name = val["name"].asCString();Int asInt() const;//转int int age = val["age"].asInt();float asFloat() const;//转floatbool asBool() const;//转 bool
};//json序列化类,低版本用这个更简单
class JSON_API Writer {virtual std::string write(const Value& root) = 0;
}
class JSON_API FastWriter : public Writer {virtual std::string write(const Value& root);
}
class JSON_API StyledWriter : public Writer {virtual std::string write(const Value& root);
}
//json序列化类,高版本推荐,如果用低版本的接口可能会有警告
class JSON_API StreamWriter {virtual int write(Value const& root, std::ostream* sout) = 0;
}
class JSON_API StreamWriterBuilder : public StreamWriter::Factory {virtual StreamWriter* newStreamWriter() const;
}//json反序列化类,低版本用起来更简单
class JSON_API Reader {bool parse(const std::string& document, Value& root, bool collectComments = true);
}
//json反序列化类,高版本更推荐
class JSON_API CharReader {virtual bool parse(char const* beginDoc, char const* endDoc, Value* root, std::string* errs) = 0;
}
class JSON_API CharReaderBuilder : public CharReader::Factory {virtual CharReader* newCharReader() const;
}
4.2 bundle数据压缩库
GitHub链接
BundleBundle
是一个嵌入式压缩库,支持23种压缩算法和2种存档格式。使用的时候只需要加入两个文件bundle.h
和 bundle.cpp
即可。
namespace bundle
{// low level API (raw pointers)bool is_packed( *ptr, len );bool is_unpacked( *ptr, len );unsigned type_of( *ptr, len );size_t len( *ptr, len );size_t zlen( *ptr, len );const void *zptr( *ptr, len );bool pack( unsigned Q, *in, len, *out, &zlen );bool unpack( unsigned Q, *in, len, *out, &zlen );// medium level API, templates (in-place)bool is_packed( T );bool is_unpacked( T );unsigned type_of( T );size_t len( T );size_t zlen( T );const void *zptr( T );bool unpack( T &, T );bool pack( unsigned Q, T &, T );// high level API, templates (copy)T pack( unsigned Q, T );T unpack( T );
}
4.3. httplib库
GitHub链接
httplib
库,一个C++11
单文件头的跨平台HTTP/HTTPS
库。安装起来非常容易。只需包含httplib.h
在你的代码中即可。
httplib
库实际上是用于搭建一个简单的http
服务器或者客户端的库,这种第三方网络库,可以让我们免去搭建服务器或客户端的时间,把更多的精力投入到具体的业务处理中,提高开发效率。
namespace httplib{struct MultipartFormData {std::string name;std::string content;std::string filename;std::string content_type;};using MultipartFormDataItems = std::vector<MultipartFormData>;struct Request {std::string method;std::string path;Headers headers;std::string body;// for serverstd::string version;Params params;MultipartFormDataMap files;Ranges ranges;bool has_header(const char *key) const;std::string get_header_value(const char *key, size_t id = 0) const;void set_header(const char *key, const char *val);bool has_file(const char *key) const;MultipartFormData get_file_value(const char *key) const;};struct Response {std::string version;int status = -1;std::string reason;Headers headers;std::string body;std::string location; // Redirect locationvoid set_header(const char *key, const char *val);void set_content(const std::string &s, const char *content_type);};class Server {using Handler = std::function<void(const Request &, Response &)>;using Handlers = std::vector<std::pair<std::regex, Handler>>;std::function<TaskQueue *(void)> new_task_queue;Server &Get(const std::string &pattern, Handler handler);Server &Post(const std::string &pattern, Handler handler);Server &Put(const std::string &pattern, Handler handler);Server &Patch(const std::string &pattern, Handler handler); Server &Delete(const std::string &pattern, Handler handler);Server &Options(const std::string &pattern, Handler handler);bool listen(const char *host, int port, int socket_flags = 0);};class Client {Client(const std::string &host, int port);Result Get(const char *path, const Headers &headers);Result Post(const char *path, const char *body, size_t content_length,const char *content_type);Result Post(const char *path, const MultipartFormDataItems &items);}
}
5. 服务端工具类实现
5.1 文件实用工具类设计
不管是客户端还是服务端,文件的传输备份都涉及到文件的读写,包括数据管理信息的持久化也是如此,因此首先设计封装文件操作类,这个类封装完毕之后,则在任意模块中对文件进行操作时都将变的简单化。
C++17中filesystem手册
/*util.hpp*/
class FileUtil{private:std::string _name;public:FileUtil(const std::string &name);size_t FileSize();time_t LastATime();time_t LastMTime();std::string FileName();bool GetPosLen(std::string *content, size_t pos, size_t len);bool GetContent(std::string *content);bool SetContent(std::strint *content);bool Compress(const std::string &packname);bool UnCompress(const std::string &filename);bool Exists();bool CreateDirectory();bool ScanDirectory(std::vector<std::string> *arry);
};
5.2 json实用工具类设计
/*util.hpp*/
class JsonUtil{public:static bool Serialize(const Json::Value &root, std::string *str);static bool UnSerialize(const std::string &str, Json::Value *root);
};
6. 服务端配置信息模块实现
6.1 系统配置信息
使用文件配置加载一些程序的运行关键信息可以让程序的运行更加灵活。
配置信息:
- 热点判断时间
- 文件下载URL前缀路径
- 压缩包后缀名称
- 上传文件存放路径
- 压缩文件存放路径
- 服务端备份信息存放文件
- 服务器访问
IP
地址 - 服务器访问端口
{"hot_time" : 30,"server_port" : 8888,"server_ip" : "172.19.54.175", "download_prefix" : "/download/","packfile_suffix" : ".lz","pack_dir" : "./packdir/","back_dir" : "./backdir/","backup_file" : "./cloud.dat"
}
6.2 单例文件配置类设计
使用单例模式管理系统配置信息,能够让配置信息的管理控制更加统一灵活。
#define CONFIG_FILE "./cloud.conf"
#ifndef __M_CONFIG_H__
#define __M_CONFIG_H__
#include <mutex>
#include "util.hpp"
namespace cloud
{class Config{private:Config(){}static Config *_instance;static std::mutex _mutex;private:int _hot_time; // 热点判断时间int _server_port; // 服务器监听端口std::string _server_ip; // 服务器IP地址std::string _download_prefix; // 下载url前缀路径std::string _packfile_suffix; // 压缩包后缀名称std::string _pack_dir; // 压缩包存放目录std::string _back_dir; // 备份文件存放目录std::string _backup_file; // 数据信息存放文件bool ReadConfigFile(){}public:static Config *GetInstance(){}int GetHotTime(){}int GetServerPort(){}std::string GetServerIP(){}std::string GetDownloadPrefix(){}std::string GetPackFileSuffix(){}std::string GetPackDir(){}std::string GetBackDir(){}std::string GetBackupFile(){}};Config *Config::_instance = nullptr;std::mutex Config::_mutex;
}
#endif
6.3 管理的数据信息
- 文件实际存储路径
- 文件是否压缩标志
- 压缩包存储路径
- 文件访问URL
- 文件最后一次修改时间
- 文件最后一次访问时间
- 文件大小
6.4 如何管理数据
- 内存中以文件访问URL为key,数据信息结构为val,使用哈希表进行管理,查询速度快。使用url作为key是因为往后客户端浏览器下载文件的时候总是以
url
作为请求。 - 采用文件形式对数据进行持久化存储(序列化方式采用
json
格式或者自定义方式)
6.5 数据管理类的设计
/*data.hpp*/
#ifndef __M_DATA_H__
#define __M_DATA_H__
#include <unordered_map>
#include <pthread.h>
#include "util.hpp"
#include "config.hpp"
namespace cloud
{typedef struct BackupInfo{bool pack_flag; // 是否压缩标志size_t fsize; // 文件大小time_t atime; // 最后一次访问时间time_t mtime; // 最后一次更改时间std::string real_path; // 文件实际存储路径std::string pack_path; // 压缩文件储存路径std::string url_path; //bool NewBackupInfo(const std::string &realpath){} } BackupInfo;class DataManager{public:DataManager(){}~DataManager(){} bool Insert(const BackupInfo &info){} bool Update(const BackupInfo &info){} bool GetOneByURL(const std::string &url, BackupInfo *info){}bool GetOneByRealPath(const std::string &realpath, BackupInfo *info){}bool GetAll(std::vector<BackupInfo> *array){} bool Storage(){}bool InitLoad(){}private:std::string _backup_file;pthread_rwlock_t _rwlock; // 读写锁 - 读共享,写互斥std::unordered_map<std::string, BackupInfo> _table;};
}
#endif
7. 服务端热点管理模块实现
7.1 热点管理实现思路
服务器端的热点文件管理是对上传的非热点文件进行压缩存储,节省磁盘空间。
而热点文件的判断在于上传的文件的最后一次访问时间是否在热点判断时间之内,比如如果一个文件一天都没有被访问过我们就认为这是一个非热点文件,其实就是当前系统时间,与文件最后一次访问时间之间的时间差是否在一天之内的判断。
而我们需要对上传的文件每隔一段时间进行热点检测,相当于遍历上传文件的存储文件夹,找出所有的文件,然后通过对逐个文件进行时间差的判断,来逐个进行热点处理。
基于这个思想,我们需要将上传的文件存储位置与压缩后压缩文件的存储位置分开。这样在遍历上传文件夹的时候不至于将压缩过的文件又进行非热点处理了。
关键点:
- 上传文件有自己的上传存储位置,非热点文件的压缩存储有自己的存储位置
- 遍历上传存储位置文件夹,获取所有文件信息。
- 获取每个文件最后一次访问时间,进而完成是否热点文件的判断。
- 对非热点文件进行压缩存储,删除原来的未压缩文件。
7.2 热点管理类的设计
#ifndef __M_HOT_H__
#define __M_HOT_H__
#include <unistd.h>
#include "data.hpp"
//因为数据管理是要在多个模块中访问的,因此将其作为全局数据定义,在此处声明使用即可
extern cloud::DataManager *_data;
namespace cloud
{class HotManager{public:HotManager(){}bool RunModule(){} private:// 非热点文件-假 热点文件-真bool HotJudge(const std::string &filename){}private:std::string _back_dir;std::string _pack_dir;std::string _pack_suffix;int _hot_time;};
}
#endif
8. 服务端业务处理模块实现
8.1 业务处理实现思路
云备份项目中 ,业务处理模块是针对客户端的业务请求进行处理,并最终给与响应。而整个过程中包含以下要实现的功能:
- 借助网络通信模块httplib库搭建http服务器与客户端进行网络通信
- 针对收到的请求进行对应的业务处理并进行响应(文件上传,列表查看,文件下载(包含断点续传))
8.2 网络通信接口设计
业务处理模块要对客户端的请求进行处理,那么我们就需要提前定义好客户端与服务端的通信,明确客户端发送什么样的请求,服务端处理后应该给与什么样的响应,而这就是网络通信接口的设计。
HTTP文件上传:
POST /upload HTTP/1.1
Content-Length:11
Content-Type:multipart/form-data;boundary= ----WebKitFormBoundary+16字节随机字符
------WebKitFormBoundary
Content-Disposition:form-data;filename="a.txt";
hello world
------WebKitFormBoundary--
HTTP/1.1 200 OK
Content-Length: 0
HTTP文件列表获取:
GET /list HTTP/1.1
Content-Length: 0
HTTP/1.1 200 OK
Content-Length:
Content-Type: text/html<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Page of Download</title></head><body><h1>Download</h1><table><tr><td><a href="/download/a.txt"> a.txt </a></td><td align="right"> 1994-07-08 03:00 </td><td align="right"> 27K </td></tr></table></body>
</html>
HTTP文件下载:
GET /download/a.txt http/1.1
Content-Length: 0
HTTP/1.1 200 OK
Content-Length: 100000
ETags: "filename-size-mtime一个能够唯一标识文件的数据"
Accept-Ranges: bytes文件数据
HTTP断点续传:
GET /download/a.txt http/1.1
Content-Length: 0
If-Range: "文件唯一标识"
Range: bytes=89-999
HTTP/1.1 206 Partial Content
Content-Length:
Content-Range: bytes 89-999/100000
Content-Type: application/octet-stream
ETag: "inode-size-mtime一个能够唯一标识文件的数据"
Accept-Ranges: bytes对应文件从89到999字节的数据。
8.3 业务处理类设计
//因为业务处理的回调函数没有传入参数的地方,因此无法直接访问外部的数据管理模块数据
//可以使用lamda表达式解决,但是所有的业务功能都要在一个函数内实现,于功能划分上模块不够清晰
//因此将数据管理模块的对象定义为全局数据,在这里声明一下,就可以在任意位置访问了
#ifndef __M_SERVICE_H__
#define __M_SERVICE_H__
#include <sstream>
#include "data.hpp"
#include "httplib.h"
extern cloud::DataManager *_data;
namespace cloud
{class Service{public:Service(){} bool RunModule(){} private:static void Upload(const httplib::Request &req, httplib::Response &rsp){} // 静态成员函数不能调用非静态成员函数 -- 没有this指针static std::string TimetoStr(time_t t){} static void ListShow(const httplib::Request &req, httplib::Response &rsp){} static std::string GetETag(const BackupInfo &info){} static void Download(const httplib::Request &req, httplib::Response &rsp){}private:std::string _server_ip; // IP地址int _server_port; // 端口号std::string _download_prefix; // 下载前缀httplib::Server _server; // http对象};
}
#endif
9. 客户端数据管理模块实现
9.1 数据信息设计
客户端要实现的功能是对指定文件夹中的文件自动进行备份上传。但是并不是所有的文件每次都需要上传,我们需要能够判断,哪些文件需要上传,哪些不需要,因此需要将备份的文件信息给管理起来,作为下一次文件是否需要备份的判断。因此需要被管理的信息包含以下:
- 文件路径名称
- 文件唯一标识:由文件名,最后一次修改时间,文件大小组成的一串信息
9.2 文件操作实用类设计
这个其实与服务端的文件实用工具类雷同,只是功能需求并没有服务端那么多。
#ifndef __M_SERVICE_H__
#define __M_SERVICE_H__
#include <sstream>
#include "data.hpp"
#include "httplib.h"
extern cloud::DataManager *_data;
namespace cloud
{class Service{public:Service(){} bool RunModule(){}private:static void Upload(const httplib::Request &req, httplib::Response &rsp){}// 静态成员函数不能调用非静态成员函数 -- 没有this指针static std::string TimetoStr(time_t t){} static void ListShow(const httplib::Request &req, httplib::Response &rsp){}static std::string GetETag(const BackupInfo &info){}static void Download(const httplib::Request &req, httplib::Response &rsp){}private:std::string _server_ip; // IP地址int _server_port; // 端口号std::string _download_prefix; // 下载前缀httplib::Server _server; // http对象};
}
#endif
9.3 数据管理类设计
#ifndef __M_SERVICE_H__
#define __M_SERVICE_H__
#include <sstream>
#include "data.hpp"
#include "httplib.h"
extern cloud::DataManager *_data;
namespace cloud
{class Service{public:Service(){} bool RunModule(){} private:static void Upload(const httplib::Request &req, httplib::Response &rsp){}// 静态成员函数不能调用非静态成员函数 -- 没有this指针static std::string TimetoStr(time_t t)static void ListShow(const httplib::Request &req, httplib::Response &rsp){}static std::string GetETag(const BackupInfo &info){} static void Download(const httplib::Request &req, httplib::Response &rsp){}private:std::string _server_ip; // IP地址int _server_port; // 端口号std::string _download_prefix; // 下载前缀httplib::Server _server; // http对象};
}
#endif
9.4 文件备份类设计
#ifndef __M_SERVICE_H__
#define __M_SERVICE_H__
#include <sstream>
#include "data.hpp"
#include "httplib.h"
extern cloud::DataManager *_data;
namespace cloud
{class Service{public:Service(){}bool RunModule(){}private:static void Upload(const httplib::Request &req, httplib::Response &rsp){}// 静态成员函数不能调用非静态成员函数 -- 没有this指针static std::string TimetoStr(time_t t)static void ListShow(const httplib::Request &req, httplib::Response &rsp){}static std::string GetETag(const BackupInfo &info){}static void Download(const httplib::Request &req, httplib::Response &rsp){}private:std::string _server_ip; // IP地址int _server_port; // 端口号std::string _download_prefix; // 下载前缀httplib::Server _server; // http对象};
}
#endif
10. 项目总结
项目名称:云备份系统
项目功能:搭建云备份服务器与客户端,客户端程序运行在客户机上自动将指定目录下的文件备份到服务器,并且能够支持浏览器查看与下载,其中下载支持断点续传功能,并且服务器端对备份的文件进行热点管理,将长时间无访问文件进行压缩存储。
开发环境:centos7.6/vim、g++、gdb、makefile
以及windows11/vs2022
技术特点:http
客户端/服务器搭建,json
序列化,文件压缩,热点管理,断点续传,线程池,读写锁,单例模式
项目模块:
- 服务端:
- 数据管理模块:内存中使用hash表存储提高访问效率,持久化使用文件存储管理备份数据
- 业务处理模块:搭建
http
服务器与客户端进行通信处理客户端的上传,下载,查看请求,并支持断点续传 - 热点管理模块:对备份的文件进行热点管理,将长时间无访问文件进行压缩存储,节省磁盘空间。
- 客户端
- 数据管理模块:内存中使用hash表存储提高访问效率,持久化使用文件存储管理备份数据
- 文件检索模块:基于
c++17
文件系统库,遍历获取指定文件夹下所有文件。 - 文件备份模块:搭建
http
客户端上传备份文件。
相关文章:
云备份项目
云备份项目 1. 云备份认识 自动将本地计算机上指定文件夹中需要备份的文件上传备份到服务器中。并且能够随时通过浏览器进行查看并且下载,其中下载过程支持断点续传功能,而服务器也会对上传文件进行热点管理,将非热点文件进行压缩存储&…...

基础算法(一)
目录 一.排序 快速排序: 归并排序: 二.二分法 整数二分模板: 浮点二分: 一.排序 快速排序: 从数列中挑出一个元素,称为 "基准"重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面&#…...

Consider defining a bean of type问题解决
Consider defining a bean of type问题解决 Consider defining a bean of type问题解决 包之后,发现项目直接报错Consider defining a bean of type。 会有一些包你明明Autowired 但是还是找不到什么bean 导致你项目启动不了 解决方法一: 这个问题主要是因为项目拆包…...

Android 1.2.1 使用Eclipse + ADT + SDK开发Android APP
1.2.1 使用Eclipse ADT SDK开发Android APP 1.前言 这里我们有两条路可以选,直接使用封装好的用于开发Android的ADT Bundle,或者自己进行配置 因为谷歌已经放弃了ADT的更新,官网上也取消的下载链接,这里提供谷歌放弃更新前最新…...

Llama-7b-hf和vicuna-7b-delta-v0合并成vicuna-7b-v0
最近使用pandagpt需要vicuna-7b-v0,重新过了一遍,前段时间部署了vicuna-7b-v3,还是有不少差别的,transforms和fastchat版本更新导致许多地方不匹配,出现很多错误,记录一下。 更多相关内容可见Fastchat实战…...
Centos、OpenEuler系统安装mysql
要在CentOS上安装MySQL并设置开机自启和root密码,请按照以下步骤进行操作: 确保您的CentOS系统已连接到Internet,并且具有管理员权限(root或sudo访问权限)。打开终端或SSH会话,使用以下命令安装MySQL&…...

如何在Win10系统上安装WSL(适用于 Linux 的 Windows 子系统)
诸神缄默不语-个人CSDN博文目录 本文介绍的方法不是唯一的安装方案,但在我的系统上可用。 文章目录 1. 视频版2. 文字版和代码3. 本文撰写过程中使用到的其他网络参考资料 1. 视频版 B站版:在Windows上安装Linux (WSL, 适用于 Linux 的 Windows 子系统…...

单片机通用学习-什么是寄存器?
什么是寄存器? 寄存器是一种特殊的存储器,主要用于存储和检查微机的状态。CPU寄存器用于存储和检查CPU的状态,具体包括计算中途数据、程序因中断或子程序分支时的返回地址、计算结果为零时的负值、计算结果为零时的信息、进位值等。 由于CP…...

【C语言】文件操作详解
文章目录 前言一、文件是什么二、文件具体介绍1.文件名2.文件类型3.文件缓冲区4.文件指针5.文件的打开和关闭 三、文件的顺序读写1.字符输入函数(fgetc)2.字符输出函数(fputc)3.文本行输入函数(fgets)4.文本…...

栈(Stack)的详解
目录 1.栈的概念 2.栈的模拟实现 1.栈的方法 2.模拟栈用(整型)数组的形式呈现 2.1栈的创建 2.2压栈 2.3栈是否为空 2.4出栈 2.5获取栈中有效元素个数 2.6获取栈顶元素 2.7完整代码实现 1.栈的概念 从上图中可以看到, Stack 继承了…...

深入了解GCC编译过程
关于Linux的编译过程,其实只需要使用gcc这个功能,gcc并非一个编译器,是一个驱动程序。其编译过程也很熟悉:预处理–编译–汇编–链接。在接触底层开发甚至操作系统开发时,我们都需要了解这么一个知识点,如何…...

leetcode 594.最长和谐子序列(滑动窗口)
⭐️ 题目描述 🌟 leetcode链接:最长和谐子序列 思路: 第一步先将数组排序,在使用滑动窗口(同向双指针),定义 left right 下标,比如这一组数 {1,3,2,2,5,2,3,7} 排序后 {1,2,2,2,3,…...
深入剖析云计算与云服务器ECS:从基础到实践
云计算已经在不断改变着我们的计算方式和业务模式,而云服务器ECS(Elastic Compute Service)作为云计算的核心组件之一,为我们提供了灵活、可扩展的计算资源。在本篇长文中,我们将从基础开始,深入探讨云计算…...

苍穹外卖技术栈
重难点详解 1、定义全局异常 2、ThreadLocal ThreadLocal 并不是一个Thread,而是Thread的一个局部变量ThreadLocal 为每一个线程提供独立的存储空间,具有线程隔离的效果,只有在线程内才能取到值,线程外则不能访问 public void …...
重新开始 杂类:C++基础
目录 1.输入输出 2 . i 与 i 3.结构体 4.二进制 1.输入输出 #include<cstdio>//cin>>,cout #include<iostream>//printf,scanf (1) cin , cout输入输出流可直接用于数字,字符 (2)scanf(&quo…...
自用的markdown与latex特殊符号
\triangleq \approx \xlongequal[y\arctan x]{x\tan y} \sum_{\substack{j1 \\ j\neq i}} \iiint\limits_\Omega \overset{\circ}{\vec{r}} \varphi \checkmark \stackrel{\cdot\cdot\cdot}{x}≜ ≈ y arctan x x tan y ∑ j 1 j ≠ i ∭ Ω r ⃗ ∘ φ ✓ x ⋅ ⋅ ⋅…...

【20期】说一说Java引用类型原理
Java中一共有4种引用类型(其实还有一些其他的引用类型比如FinalReference):强引用、软引用、弱引用、虚引用。 其中强引用就是我们经常使用的Object a new Object(); 这样的形式,在Java中并没有对应的Reference类。 本篇文章主要是分析软引用、弱引用、…...

无锡布里渊——厘米级分布式光纤-锅炉安全监测解决方案
无锡布里渊——厘米级分布式光纤-锅炉安全监测解决方案 厘米级分布式光纤-锅炉安全监测解决方案 1、方案背景与产品简介: 1.1:背景简介: 锅炉作为一种把煤、石油或天燃气等化石燃料所储藏的化学能转换成水或水蒸气的热能的重要设备ÿ…...
GREASELM: GRAPH REASONING ENHANCED LANGUAGE MODELS FOR QUESTION ANSWERING
本文是LLM系列文章,针对《GREASELM: GRAPH REASONING ENHANCED LANGUAGE MODELS FOR QUESTION ANSWERING》的翻译。 GREASELM:图推理增强的问答语言模型 摘要1 引言2 相关工作3 提出的方法:GREASELM4 实验设置5 实验结果6 结论 摘要 回答关…...

QT C++ 实现网络聊天室
一、基本原理及流程 1)知识回顾(C语言中的TCP流程) 2)QT中的服务器端/客户端的操作流程 二、代码实现 1)服务器 .ui .pro 在pro文件中添加network库 .h #ifndef WIDGET_H #define WIDGET_H#include <QWidget>…...

工业安全零事故的智能守护者:一体化AI智能安防平台
前言: 通过AI视觉技术,为船厂提供全面的安全监控解决方案,涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面,能够实现对应负责人反馈机制,并最终实现数据的统计报表。提升船厂…...

边缘计算医疗风险自查APP开发方案
核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...