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

云备份项目

云备份项目

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.hbundle.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序列化,文件压缩,热点管理,断点续传,线程池,读写锁,单例模式

项目模块:

  1. 服务端:
    1. 数据管理模块:内存中使用hash表存储提高访问效率,持久化使用文件存储管理备份数据
    2. 业务处理模块:搭建http服务器与客户端进行通信处理客户端的上传,下载,查看请求,并支持断点续传
    3. 热点管理模块:对备份的文件进行热点管理,将长时间无访问文件进行压缩存储,节省磁盘空间。
  2. 客户端
    1. 数据管理模块:内存中使用hash表存储提高访问效率,持久化使用文件存储管理备份数据
    2. 文件检索模块:基于c++17文件系统库,遍历获取指定文件夹下所有文件。
    3. 文件备份模块:搭建http客户端上传备份文件。

相关文章:

云备份项目

云备份项目 1. 云备份认识 自动将本地计算机上指定文件夹中需要备份的文件上传备份到服务器中。并且能够随时通过浏览器进行查看并且下载&#xff0c;其中下载过程支持断点续传功能&#xff0c;而服务器也会对上传文件进行热点管理&#xff0c;将非热点文件进行压缩存储&…...

基础算法(一)

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

Consider defining a bean of type问题解决

Consider defining a bean of type问题解决 Consider defining a bean of type问题解决 包之后&#xff0c;发现项目直接报错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.前言 这里我们有两条路可以选&#xff0c;直接使用封装好的用于开发Android的ADT Bundle&#xff0c;或者自己进行配置 因为谷歌已经放弃了ADT的更新&#xff0c;官网上也取消的下载链接&#xff0c;这里提供谷歌放弃更新前最新…...

Llama-7b-hf和vicuna-7b-delta-v0合并成vicuna-7b-v0

最近使用pandagpt需要vicuna-7b-v0&#xff0c;重新过了一遍&#xff0c;前段时间部署了vicuna-7b-v3&#xff0c;还是有不少差别的&#xff0c;transforms和fastchat版本更新导致许多地方不匹配&#xff0c;出现很多错误&#xff0c;记录一下。 更多相关内容可见Fastchat实战…...

Centos、OpenEuler系统安装mysql

要在CentOS上安装MySQL并设置开机自启和root密码&#xff0c;请按照以下步骤进行操作&#xff1a; 确保您的CentOS系统已连接到Internet&#xff0c;并且具有管理员权限&#xff08;root或sudo访问权限&#xff09;。打开终端或SSH会话&#xff0c;使用以下命令安装MySQL&…...

如何在Win10系统上安装WSL(适用于 Linux 的 Windows 子系统)

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

单片机通用学习-​什么是寄存器?​

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

【C语言】文件操作详解

文章目录 前言一、文件是什么二、文件具体介绍1.文件名2.文件类型3.文件缓冲区4.文件指针5.文件的打开和关闭 三、文件的顺序读写1.字符输入函数&#xff08;fgetc&#xff09;2.字符输出函数&#xff08;fputc&#xff09;3.文本行输入函数&#xff08;fgets&#xff09;4.文本…...

栈(Stack)的详解

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

深入了解GCC编译过程

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

leetcode 594.最长和谐子序列(滑动窗口)

⭐️ 题目描述 &#x1f31f; leetcode链接&#xff1a;最长和谐子序列 思路&#xff1a; 第一步先将数组排序&#xff0c;在使用滑动窗口&#xff08;同向双指针&#xff09;&#xff0c;定义 left right 下标&#xff0c;比如这一组数 {1,3,2,2,5,2,3,7} 排序后 {1,2,2,2,3,…...

深入剖析云计算与云服务器ECS:从基础到实践

云计算已经在不断改变着我们的计算方式和业务模式&#xff0c;而云服务器ECS&#xff08;Elastic Compute Service&#xff09;作为云计算的核心组件之一&#xff0c;为我们提供了灵活、可扩展的计算资源。在本篇长文中&#xff0c;我们将从基础开始&#xff0c;深入探讨云计算…...

苍穹外卖技术栈

重难点详解 1、定义全局异常 2、ThreadLocal ThreadLocal 并不是一个Thread&#xff0c;而是Thread的一个局部变量ThreadLocal 为每一个线程提供独立的存储空间&#xff0c;具有线程隔离的效果&#xff0c;只有在线程内才能取到值&#xff0c;线程外则不能访问 public void …...

重新开始 杂类:C++基础

目录 1.输入输出 2 . i 与 i 3.结构体 4.二进制 1.输入输出 #include<cstdio>//cin>>,cout #include<iostream>//printf,scanf &#xff08;1&#xff09; cin , cout输入输出流可直接用于数字&#xff0c;字符 &#xff08;2&#xff09;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)&#xff1a;强引用、软引用、弱引用、虚引用。 其中强引用就是我们经常使用的Object a new Object(); 这样的形式&#xff0c;在Java中并没有对应的Reference类。 本篇文章主要是分析软引用、弱引用、…...

无锡布里渊——厘米级分布式光纤-锅炉安全监测解决方案

无锡布里渊——厘米级分布式光纤-锅炉安全监测解决方案 厘米级分布式光纤-锅炉安全监测解决方案 1、方案背景与产品简介&#xff1a; 1.1&#xff1a;背景简介&#xff1a; 锅炉作为一种把煤、石油或天燃气等化石燃料所储藏的化学能转换成水或水蒸气的热能的重要设备&#xff…...

GREASELM: GRAPH REASONING ENHANCED LANGUAGE MODELS FOR QUESTION ANSWERING

本文是LLM系列文章&#xff0c;针对《GREASELM: GRAPH REASONING ENHANCED LANGUAGE MODELS FOR QUESTION ANSWERING》的翻译。 GREASELM&#xff1a;图推理增强的问答语言模型 摘要1 引言2 相关工作3 提出的方法&#xff1a;GREASELM4 实验设置5 实验结果6 结论 摘要 回答关…...

QT C++ 实现网络聊天室

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

每日一道面试题之什么是上下文切换?

上下文切换是指在计算机操作系统中&#xff0c;当多个进程或线程同时运行时&#xff0c;系统需要将当前运行进程或线程的状态&#xff08;包括程序计数器、寄存器值、内存映像等&#xff09;保存起来&#xff0c;然后切换到另一个进程或线程继续执行的过程。上下文切换通常由操…...

2023.9.3 关于 AVL 树

目录 二叉搜索树 二叉搜索树的简介&#xff1a; 二叉搜索树的查找&#xff1a; 二叉搜索树的效率&#xff1a; AVL树 AVL 树的简介&#xff1a; AVL 树的实现&#xff1a; AVL树的旋转 右单旋 左单旋 左右双旋 右左双旋 完整 AVL树插入代码 验证 AVL 树 AVL 树的性…...

机器学习课后习题 --- 机器学习实践

&#xff08;一&#xff09;单选题 1.以下关于训练集、验证集和测试集说法不正确的是( )。 A:测试集是纯粹是用于测试模型泛化能力B:训练集是用来训练以及评估模型性能 C:验证集用于调整模型参数 D:以上说法都不对 2.当数据分布不平衡时&#xff0c;我们可采取的措施不包括…...

git常用操作

删除分支 例&#xff1a;例如想删除的分支是dev_delete,那么可以按照如下的操作进行 #查看当前所在分支 git branch#如果在当前dev_delete分支上&#xff0c;就要切换到其他分支才能删除该分支 git checkout 其他分支#删除本地名为dev_delete的分支 git branch -d dev_delete…...

QT的补充知识

一、文件 QFile QT提供了QFile类用于对文件进行读写操作&#xff0c;也提供了其他的两个类&#xff1a;文本流&#xff08;QTextSream&#xff09;和数据流&#xff08;QDataStream&#xff09; 文本流&#xff08;QTextSream&#xff09;&#xff1a;用于对文本数据的处理&am…...

【力扣周赛】第 360 场周赛(贪心 ⭐树上倍增)

文章目录 竞赛链接Q1&#xff1a;8015. 距离原点最远的点&#xff08;贪心&#xff09;Q2&#xff1a;8022. 找出美丽数组的最小和&#xff08;贪心&#xff09;Q3&#xff1a;2835. 使子序列的和等于目标的最少操作次数&#xff08;贪心&#xff09;思路竞赛时丑陋代码&#x…...

企业如何防止数据外泄——【部署智能透明加密防泄密系统】

为防止公司文件泄密&#xff0c;可以采取以下措施&#xff1a; www.drhchina.com 分部门部署&#xff1a;根据不同的部门需要&#xff0c;为不同部门用户部署灵活的加密方案。例如&#xff0c;对研发部、销售部、运营部的机密资料进行强制性自动加密&#xff0c;对普通部门的文…...

【聚类】DBCAN聚类

OPTICS是基于DBSCAN改进的一种密度聚类算法&#xff0c;对参数不敏感。当需要用到基于密度的聚类算法时&#xff0c;可以作为DBSCAN的一种替代的优化方案&#xff0c;以实现更优的效果。 原理 基于密度的聚类算法&#xff08;1&#xff09;——DBSCAN详解_dbscan聚类_root-ca…...

通过安装cpolar内网穿透在Kali上实现SSH远程连接的步骤指南

文章目录 1. 启动kali ssh 服务2. kali 安装cpolar 内网穿透3. 配置kali ssh公网地址4. 远程连接5. 固定连接SSH公网地址6. SSH固定地址连接测试 简单几步通过cpolar 内网穿透软件实现ssh 远程连接kali! 1. 启动kali ssh 服务 默认新安装的kali系统会关闭ssh 连接服务,我们通…...

UDP和TCP协议报文格式详解

在初识网络原理(初识网络原理_蜡笔小心眼子&#xff01;的博客-CSDN博客)这篇博客中,我们简单的了解了一下TCP/IP五层网络模型,这篇博客将详细的学习一下五层网络模型中传输层的两个著名协议:UDP和TCP 目录 一, 传输层的作用 二, UDP 1,UDP协议的特点 2,UDP报文格式 三, TC…...