【项目管理】基于 C 语言的 QQ 聊天室实现(TCP + 多线程 + SQLite3)

基于 C 语言的 QQ 聊天室(TCP + 多线程 + SQLite3)

项目功能基础功能: 登录、注册、添加好友、私聊、创建群聊、群聊扩展功能: 删除好友、注销账号、好友在线状态、群管理(拉人/踢人)、VIP 特权、邮件通知等
功能介绍:模拟QQ聊天客户端:登录界面:1、登录2、注册		//将用户注册账户/密码信息存储在数据里3、注销服务器:转发信息:主要实现私聊和群聊的功能,只要通过服务器进行数据传输,最好都先用json在客户端打包,然后在服务器中解包处理信息:将从客户端发来的数据存储到数据库等操作主界面:1、添加好友			//是否需要同意2、查看我的好友		//显示好友当前状态,是否在线3、与好友私聊		//离线的信息怎么处理4、删除好友			//单删5、创建群聊6、开始群聊			//禁言7、拉好友进群		//群主和管理员的权限8、踢人				//群主和管理员的权限9、查看群中好友		//显示群主和管理员的权限、群员的权限10、注销账号11、公共朋友圈		//朋友圈//小游戏推荐使用TCP通信来实现,因为TCP只需要将客户端的fd存储在数据库,那么我们就可以随时想要客户端的fd然后给其发送信息。
==========================================================
1、画架构图--->实现什么功能
2、设置结构体
3、设置协议
4、设置函数
===================================================
客户端:>显示界面printf("1、登录    2、注册   3、退出  4、注销");单独写函数化界面Switch(){case 1:loginbreakcase 2:zhucebreakcase 3:logoutbreakcase 4:	zhuxiaobreak}//用户名:密码:...........send到服务器中---》数据存入数据库==================================================================服务器:1、并发服务器		考虑使用--->进程?线程?2、接受客户端的数据3、数据的转发数据库:1>打开数据库注册---写入登录---读取并匹配2>可以添加相关功能3>关闭数据库参考:服务器可以使用多路复用取创建线程,每一个线程都是单独和一个客户端进行通信客户端登录完成后,创建线程,专门用来接受服务器发送给客户端的信息数据库:需要多个table用户总表:储存注册的用户和密码,登录后将他的fd也放进去,下线后再次登录就更新。好友表:每当一个用户注册就创建一个好友表,里面储存该用户的好友名群聊总表:存储所有被创建的群聊名群聊成员总表:存储群聊里面的成员名=====================================================================

1. 系统架构设计

🔹 服务器端

	监听客户端连接多线程处理每个客户端使用 SQLite3 存储用户/好友/群信息解析 JSON 数据包转发私聊/群聊消息

🔹 客户端

	建立 TCP 连接JSON 格式封装数据交互界面(菜单选择私聊/群聊等)子线程接收服务器消息

🔹 1.1 架构图

+--------------------+          +------------------+
|      客户端       |    TCP/IP  |      服务器      |
+--------------------+ <------> +------------------+
| 1. 登录/注册      |             | 1. 处理用户请求  |
| 2. 添加好友       |             | 2. 保存数据到DB  |
| 3. 私聊/群聊      |             | 3. 发送/转发消息 |
| 4. 退出/注销      |             | 4. 维护在线状态  |
+--------------------+          +------------------+

聊天室实现流程图:(实现框架)
聊天室实现流程图

实现聊天室的登陆、注册流程图

注册:
注册
登陆:登陆
以上实现的编程思路逻辑为:

注册:
1、服务器要先启动,监听客户端的连接;
2、客户端启动,首先连接服务器,并显示登陆、注册界面;
3、服务器接收到客户端连接后,会创建一个子线程专门用于于客户端的通信;
4、选择注册后,提示输入用户名、密码,封装注册信息到结构体变量msg中,并发送该信令给服务器;
5、服务器接收到客户端注册信息后,进入注册处理流程;
6、注册功能:首先在数据库表中查找该用户名是否存在,如果不存在则使flage值为1,并且在数据库表中将该用户名密码保存到数据库中,并返回注册成功的信令;
否则使flage值为-1,并返回 错误信息;
7、客户端接收到服务器注册处理指令后,会打印提示信息,并显示步骤2的菜单。登陆:
1、服务器要先启动,监听客户端的连接;
2、客户端启动,首先连接服务器,并显示登陆、注册界面;
3、服务器接收到客户端连接后,会创建一个子线程专门用于于客户端的通信;
4、选择登陆后,提示输入用户名、密码,封装登陆信息到结构体变量msg中,并发送该信令给服务器;
5、服务器接收到客户端注册信息后,进入登陆处理流程;
6、登陆功能:首先查找该用户名、密码是否在数据库表中存在匹配项,找到返回对应的下标,并将于该客户端相连接的套接字保存到对应的条目中,返回登陆成功信息给客户端;如果没有找到,则返回-1,并返回错误信息给客户端;
7、客户端接收到服务器注册处理指令后,会打印提示信息,并设置客户端在线的标记login_f 为1,此时会显示 聊天功能对应的菜单。

客户端与服务端:私聊私聊

私聊流程:
1、客户端从菜单选择私聊功能;
2、输入要聊天的对象和聊天信息;
3、发送聊天信息给服务器;
4、服务器的子线程收到私聊数据之后,进入私聊流程;
5、向指定用户发送该私聊信息;

客户端与服务端:公聊
公聊

公聊流程:
1、客户端从菜单选择公聊功能;
2、输入要聊天信息;
3、回车发送聊天信息;
4、服务器的子线程收到公聊数据之后,进入公聊流程;
5、查找所有在线用户,向所有的在线用户发送该公聊信息;
6、客户端进入聊天后会创建一个子线程,该子线程会循环接收所有服务器发送的数据信息。

🔹 1.2 技术选型

组件技术方案
通信协议TCP(稳定可靠)
数据格式JSON(使用 cJSON 解析)
服务器模型I/O 多路复用(select 或 epoll)+ 线程池
数据库SQLite3(轻量级)
加密密码 SHA-256 哈希存储

2. 数据库设计

🔹 2.1 用户表(users)

字段类型说明
idINTEGER PRIMARY KEY用户 ID
usernameTEXT UNIQUE用户名
passwordTEXTSHA-256 哈希存储
statusINTEGER0=离线, 1=在线
fdINTEGER记录 socket 连接
CREATE TABLE users (id INTEGER PRIMARY KEY AUTOINCREMENT,username TEXT UNIQUE NOT NULL,password TEXT NOT NULL,status INTEGER DEFAULT 0,fd INTEGER DEFAULT -1
);

🔹 2.2 好友表(friends)

记录用户之间的好友关系。

字段类型说明
user_idINTEGER用户 ID
friend_idINTEGER好友 ID
CREATE TABLE friends (user_id INTEGER,friend_id INTEGER,FOREIGN KEY (user_id) REFERENCES users(id),FOREIGN KEY (friend_id) REFERENCES users(id)
);

🔹 2.3 群聊表(groups)

记录群聊信息。

字段类型说明
group_idINTEGER PRIMARY KEY群 ID
group_nameTEXT UNIQUE群名称
owner_idINTEGER群主 ID
CREATE TABLE groups (group_id INTEGER PRIMARY KEY AUTOINCREMENT,group_name TEXT UNIQUE NOT NULL,owner_id INTEGER NOT NULL,FOREIGN KEY (owner_id) REFERENCES users(id)
);

🔹 2.4 群成员表(group_members)

记录群聊成员及身份。

字段类型说明
group_idINTEGER群 ID
user_idINTEGER用户 ID
roleTEXTowner/admin/member
CREATE TABLE group_members (group_id INTEGER,user_id INTEGER,role TEXT CHECK(role IN ('owner', 'admin', 'member')) DEFAULT 'member',FOREIGN KEY (group_id) REFERENCES groups(group_id),FOREIGN KEY (user_id) REFERENCES users(id)
);

3. 通信协议(TCP)

请添加图片描述

🔹 3.1 数据包格式(JSON)

{"type": "login","username": "Alice","password": "123456"
}

🔹 3.2 主要消息类型

操作type 值附加字段
登录“login”username, password
注册“register”username, password
私聊“private_chat”from, to, message
群聊“group_chat”group_id, from, message
添加好友“add_friend”from, to
删除好友“delete_friend”from, to

4. 服务器端实现

🔹 4.1 服务器初始化

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <pthread.h>#define PORT 8080
#define MAX_CLIENTS 100void *handle_client(void *sockfd) {int client_sock = *(int *)sockfd;char buffer[1024];while (1) {memset(buffer, 0, sizeof(buffer));int bytes = recv(client_sock, buffer, sizeof(buffer), 0);if (bytes <= 0) {printf("客户端断开连接\n");break;}printf("收到消息: %s\n", buffer);send(client_sock, "消息收到", strlen("消息收到"), 0);}close(client_sock);return NULL;
}int main() {int server_sock, client_sock;struct sockaddr_in server_addr, client_addr;socklen_t client_size = sizeof(client_addr);server_sock = socket(AF_INET, SOCK_STREAM, 0);server_addr.sin_family = AF_INET;server_addr.sin_addr.s_addr = INADDR_ANY;server_addr.sin_port = htons(PORT);bind(server_sock, (struct sockaddr*)&server_addr, sizeof(server_addr));listen(server_sock, MAX_CLIENTS);printf("服务器启动, 监听端口 %d...\n", PORT);while (1) {client_sock = accept(server_sock, (struct sockaddr*)&client_addr, &client_size);printf("新客户端连接: %d\n", client_sock);pthread_t thread;pthread_create(&thread, NULL, handle_client, &client_sock);pthread_detach(thread);}close(server_sock);return 0;
}

5. 客户端实现

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>#define SERVER_IP "127.0.0.1"
#define SERVER_PORT 8080int main() {int sock = socket(AF_INET, SOCK_STREAM, 0);struct sockaddr_in server_addr;server_addr.sin_family = AF_INET;server_addr.sin_port = htons(SERVER_PORT);inet_pton(AF_INET, SERVER_IP, &server_addr.sin_addr);connect(sock, (struct sockaddr*)&server_addr, sizeof(server_addr));char buffer[1024];while (1) {printf("输入消息: ");fgets(buffer, sizeof(buffer), stdin);send(sock, buffer, strlen(buffer), 0);memset(buffer, 0, sizeof(buffer));recv(sock, buffer, sizeof(buffer), 0);printf("服务器: %s\n", buffer);}close(sock);return 0;
}

5. 线程池优化(使用 epoll 处理多个客户端)

#include <sys/epoll.h>int epfd = epoll_create(1);
struct epoll_event event, events[MAX_CLIENTS];event.events = EPOLLIN;
event.data.fd = server_sock;
epoll_ctl(epfd, EPOLL_CTL_ADD, server_sock, &event);while (1) {int n = epoll_wait(epfd, events, MAX_CLIENTS, -1);for (int i = 0; i < n; i++) {if (events[i].data.fd == server_sock) {int client_sock = accept(server_sock, NULL, NULL);event.data.fd = client_sock;epoll_ctl(epfd, EPOLL_CTL_ADD, client_sock, &event);} else {char buffer[1024];recv(events[i].data.fd, buffer, sizeof(buffer), 0);printf("收到: %s\n", buffer);}}
}

以上为项目结构 和 模块化的编程思想,下面提供完整代码:

✅ 使用 TCP + JSON 进行消息传输;
✅ 基于 SQLite3 存储用户、好友、群聊信息;
✅ 服务器采用 多线程 + I/O 多路复用(epoll) 支持高并发。

客户端(client)

头文件集合

my.h

#ifndef __MY_H__
#define __MY_H__
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<poll.h>
#include<stdbool.h>
#include<json/json.h>
#include<sqlite3.h>
#include<sys/time.h>
#include<signal.h>
#include<semaphore.h>
#include<pthread.h>
#include<errno.h>typedef struct msg{
char usr_name[20];
char passwd[20];
char qq_group[20];
char buf[100];
int qq;
int cmd;
}msg_q,*msg_p;extern void struct_init(msg_p* qt);
extern void json_init(msg_p * p);
extern const char * json_pack(msg_p p);
extern msg_p json_unpack(const char * buf1);
extern int user_insert(int fd);
extern int login_qq(int fd);
extern int add_friend(int fd);
extern int sql_into(msg_p qt);
extern int del_friend(int fd);
extern int sql_del(int qq);
extern int tuichu_qq(int fd);
extern int siliao_friend(int fd);
extern int group_fd(int fd);
extern int group_creat(msg_p qt);
extern int add_f_gp(int fd);
extern int table_show();
extern int fun1(void* arg,int col,char** str,char** name);
extern int qunliao(int fd);
extern int del_g_f(int fd);
extern int chakan();
extern int chakan_gf(int fd);
extern int qun_lib();#endif

json.h

#ifndef _JSON_H_
#define _JSON_H_
#include <stdio.h>
#include <string.h>
#include <json/json.h>
#include <stdlib.h>typedef struct msg{char usr_name[20];char passwd[20];char qq_group[20];char buf[100];int qq;int cmd;
}msg_q,*msg_p;extern void json_init(msg_p * p);
extern const char *json_pack(msg_p p);
extern msg_p json_unpack( const char *buf1);#endif
主函数

client.c

#include"my.h"
int fd;
extern int sdnum;
int main(int argc, char const *argv[])   //./client server_ip server_port
{if (argc!=3){printf("usage : %s <server_ip> <server_port>\n",argv[0]);//传参:服务器ip + 端口号exit(1);} msg_p qq;msg_p qq1;json_init(&qq);json_init(&qq1);const char* auf;char buf[521];fd=socket(AF_INET,SOCK_STREAM,0);if (fd<0){perror("socket");exit(1);}int ret;struct sockaddr_in server_addr;server_addr.sin_family=AF_INET;server_addr.sin_port=htons(atoi(argv[2]));server_addr.sin_addr.s_addr=inet_addr(argv[1]);ret=connect(fd,(struct sockaddr *)&server_addr,sizeof(server_addr));if (ret<0){perror("connect");exit(1);}/* fd_set myset;while(1){FD_ZERO(&myset); FD_SET(0,&myset);FD_SET(fd,&myset);select(fd+1, &myset, NULL,NULL,NULL);if(FD_ISSET(0,&myset)){*/
end:
while(1)
{fd_set myset;while(1){FD_ZERO(&myset); FD_SET(0,&myset);printf("-------------\n");printf("----1.注册---\n");printf("----2.登录---\n");printf("----3.退出---\n");printf("-------------\n");struct_init(&qq);printf("please chose:\n");select(fd+1, &myset, NULL,NULL,NULL);scanf("%d",&qq->cmd);if(FD_ISSET(0,&myset)){switch(qq->cmd){case 1:user_insert(fd);//注册bzero(buf,sizeof(buf));struct_init(&qq1);recv(fd,buf,sizeof(buf),0);qq1=json_unpack(buf);if(qq1->cmd==1){printf("注册成功\n");printf("你的QQ号为:%d\n",qq1->qq);}elseprintf("注册失败\n");break;case 2:login_qq(fd);//登录bzero(buf,sizeof(buf));struct_init(&qq1);recv(fd,buf,sizeof(buf),0);qq1=json_unpack(buf);if(qq1->cmd==1){printf("正在登录...\n");sleep(2);}else{printf("帐号或密码错误\n");break;}// menu();while(1){fd_set myset;while(1){
begin:FD_ZERO(&myset); FD_SET(0,&myset);FD_SET(fd,&myset);int qq_num;int i;//sleep(5);system("clear");printf("4.添加好友\n");printf("5.删除好友\n");printf("6.与好友私聊\n");printf("7.创建群聊\n");printf("8.拉好友进群\n");printf("9.开始群聊\n");printf("10.查看我的好友\n");printf("11.查看群中的好友\n");printf("12.退出登录\n");printf("请输入数字选择相应操作\n");select(fd+1, &myset, NULL,NULL,NULL);if(FD_ISSET(fd,&myset)){ do{bzero(buf,sizeof(buf));ret=recv(fd,buf,sizeof(buf),0);struct_init(&qq1);qq1=json_unpack(buf);			printf("%s\n",qq1->buf);if(qq1->cmd==1000){goto begin;}}while(qq1->cmd!=0);sleep(3);break;}scanf("%d",&i);if(FD_ISSET(0,&myset)){switch(i){case 4:add_friend(fd);//添加好友sleep(2);break;case 5:printf("请输入你要删除好友的QQ:");scanf("%d",&qq_num);//del_friend(fd);bzero(buf,sizeof(buf));struct_init(&qq1);qq1->cmd=5;qq1->qq=qq_num;auf=json_pack(qq1);send(fd,auf,strlen(auf),0);recv(fd,buf,sizeof(buf),0);qq1=json_unpack(buf);if(qq1->cmd==1){sql_del(qq_num);printf("删除成功\n");sleep(2);break;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/27789.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vscode 都有哪些大模型编程插件

VSCode 中有许多基于大模型的编程插件&#xff0c;这些插件通过集成人工智能技术&#xff0c;显著提升了开发者的编程效率和体验。以下是一些主要的大模型编程插件及其功能&#xff1a; GitHub Copilot GitHub Copilot 是由 OpenAI 开发的插件&#xff0c;能够根据代码上下文自…

每日一题洛谷普及/提高-P1154 奶牛分厩c++

无注释版 #include<iostream> #include<cstring> #include<cstdlib> using namespace std; bool ju(int n, int s[], int len, bool a[]) {memset(a, 0, n * sizeof(bool));for (int j 0; j < len; j) {if (a[s[j] % n]) {return false;}a[s[j] % n] t…

[liorf_localization_imuPreintegration-2] process has died

使用liorf&#xff0c;编译没报错&#xff0c;但是roslaunch报错如下&#xff1a; 解决方法&#xff1a; step1: 如果你之前没有安装 GTSAM&#xff0c;可以尝试安装它 step2: 检查是否缺少依赖库 ldd /home/zz/1210/devel/lib/liorf_localization/liorf_localization_imuPr…

Jmeter+ant+jenkins接口自动化测试

平台简介 一个完整的接口自动化测试平台需要支持接口的自动执行&#xff0c;自动生成测试报告&#xff0c;以及持续集成。Jmeter 支持接口的测试&#xff0c;Ant 支持自动构建&#xff0c;而 Jenkins 支持持续集成&#xff0c;所以三者组合在一起可以构成一个功能完善的接口自动…

springboot425-基于SpringBoot的BUG管理系统(源码+数据库+纯前后端分离+部署讲解等)

&#x1f495;&#x1f495;作者&#xff1a; 爱笑学姐 &#x1f495;&#x1f495;个人简介&#xff1a;十年Java&#xff0c;Python美女程序员一枚&#xff0c;精通计算机专业前后端各类框架。 &#x1f495;&#x1f495;各类成品Java毕设 。javaweb&#xff0c;ssm&#xf…

如何将飞书多维表格与DeepSeek R1结合使用:效率提升的完美搭档

将飞书的多维表格与DeepSeek R1结合使用&#xff0c;就像为你的数据管理和分析之旅装上一台涡轮增压器。两者的合作&#xff0c;不仅仅在速度上让人耳目一新&#xff0c;更是将智能化分析带入了日常的工作场景。以下是它们如何相辅相成并改变我们工作方式的一些分享。 --- 在…

leetcode 148. 排序链表

题目如下 数据范围 通过代码 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(nullptr) {}* ListNode(int x, ListNode *next) : va…

关于对机器中的人工智能进行基准测试

大家读完觉得有帮助记得及时关注和点赞&#xff01;&#xff01;&#xff01; 抽象 最近的基准研究声称&#xff0c;AI 在各种认知任务上的表现已经接近甚至超过人类的“水平”。然而&#xff0c;本立场文件认为&#xff0c;当前的 AI 评估范式不足以评估类似人类的认知能力。我…

C# OnnxRuntime部署DAMO-YOLO交通标识检测

目录 说明 效果 模型信息 项目 代码 下载 参考 说明 效果 模型信息 Model Properties ------------------------- --------------------------------------------------------------- Inputs ------------------------- name&#xff1a;input tensor&#xff1a;Floa…

【开源-鸿蒙土拨鼠大理石系统】鸿蒙 HarmonyOS Next App+微信小程序+云平台

✨本人自己开发的开源项目&#xff1a;土拨鼠充电系统 ✨踩坑不易&#xff0c;还希望各位大佬支持一下&#xff0c;在GitHub给我点个 Start ⭐⭐&#x1f44d;&#x1f44d; ✍GitHub开源项目地址&#x1f449;&#xff1a;https://github.com/cheinlu/HarmonyOS-groundhog-mar…

QT实现单个控制点在曲线上的贝塞尔曲线

最终效果: 一共三个文件 main.cpp #include <QApplication> #include "SplineBoard.h" int main(int argc,char** argv) {QApplication a(argc, argv);SplineBoard b;b.setWindowTitle("标准的贝塞尔曲线");b.show();SplineBoard b2(0.0001);b2.sh…

深入探索Python机器学习算法:监督学习(线性回归,逻辑回归,决策树与随机森林,支持向量机,K近邻算法)

文章目录 深入探索Python机器学习算法&#xff1a;监督学习一、线性回归二、逻辑回归三、决策树与随机森林四、支持向量机五、K近邻算法 深入探索Python机器学习算法&#xff1a;监督学习 在机器学习领域&#xff0c;Python凭借其丰富的库和简洁的语法成为了众多数据科学家和机…

二、QT和驱动模块实现智能家居-----问题汇总1

1、文件地址改变后必须在QT下更改地址 2、指定了QT内Kits下的Sysroot头文件地址&#xff0c;但是还是找不到头文件&#xff1a; 3、提示无法执行QT程序&#xff1a;先干掉之前的QT程序 ps //查看程序PIDkill -9 PID 4、无法执行QT程序 1&#xff09;未设置环境变量 …

【Linux专栏_1】Linux中常用的指令

文章目录 前言1、查看Linux主机ip2、 Linux下的常用指令集合(1)、ls指令(2)、pwd指令(3)、cd指令(4)、touch指令(5)、mkdir指令(6)、rmdir和rm删除指令(7)、man指令(8)、cp指令(9)、mv指令(10)、cat指令(11)、more指令(12)、date指令(13)、cal指令(14)、find指令(15)、which指令…

Android+SpringBoot的老年人健康饮食小程序平台

感兴趣的可以先收藏起来&#xff0c;还有大家在毕设选题&#xff0c;项目以及论文编写等相关问题都可以给我留言咨询&#xff0c;我会一一回复&#xff0c;希望帮助更多的人。 系统介绍 我将从经济、生活节奏、技术融合等方面入手&#xff0c;详细阐述居家养老管理模式兴起的…

yoloV5的学习-pycharm版本

真的很让人气愤的一点&#xff0c;老师把我的pycharm给卸载了&#xff0c;我那个上面不仅有gpu-torch&#xff0c;还有gpu-torch&#xff0c;他给俺删了&#xff0c;删了很久&#xff0c;我心都碎了&#xff0c;过几天我就去找他负责&#xff0c;让他给我装回来我的环境&#x…

DeepSeek搭配Excel,制作自定义按钮,实现办公自动化!

今天跟大家分享下我们如何将DeepSeek生成的VBA代码&#xff0c;做成按钮&#xff0c;将其永久保存在我们的Excel表格中&#xff0c;下次遇到类似的问题&#xff0c;直接在Excel中点击按钮&#xff0c;就能10秒搞定&#xff0c;操作也非常的简单. 一、代码准备 代码可以直接询问…

零信任架构和传统网络安全模式的

零信任到底是一个什么类型的模型&#xff1f;什么类型的思想或思路&#xff0c;它是如何实现的&#xff0c;我们要做零信任&#xff0c;需要考虑哪些问题&#xff1f; 零信任最早是约翰金德瓦格提出的安全模型。早期这个模型也是因为在安全研究上考虑的一个新的信任式模型。他最…

Leetcode 刷题记录 02 —— 双指针

本系列为笔者的 Leetcode 刷题记录&#xff0c;顺序为 Hot 100 题官方顺序&#xff0c;根据标签命名&#xff0c;记录笔者总结的做题思路&#xff0c;附部分代码解释和疑问解答。 目录 01 移动零 02 盛最多水的容器 03 三数之和 04 接雨水 01 移动零 //双指针法 class Sol…

双碳战略下的智慧能源实践:安科瑞储能管理系统助力企业绿色转型

在全球碳中和目标加速推进的背景下&#xff0c;中国“十四五”规划明确提出构建以新能源为主体的新型电力系统&#xff0c;储能技术成为支撑能源结构转型的核心要素。安科瑞储能能量管理系统作为企业级智慧能源解决方案的核心载体&#xff0c;凭借其技术创新与场景适配能力&…