【项目管理】基于 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)
字段 | 类型 | 说明 |
---|---|---|
id | INTEGER PRIMARY KEY | 用户 ID |
username | TEXT UNIQUE | 用户名 |
password | TEXT | SHA-256 哈希存储 |
status | INTEGER | 0=离线, 1=在线 |
fd | INTEGER | 记录 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_id | INTEGER | 用户 ID |
friend_id | INTEGER | 好友 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_id | INTEGER PRIMARY KEY | 群 ID |
group_name | TEXT UNIQUE | 群名称 |
owner_id | INTEGER | 群主 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_id | INTEGER | 群 ID |
user_id | INTEGER | 用户 ID |
role | TEXT | owner/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;
相关文章:

【项目管理】基于 C 语言的 QQ 聊天室实现(TCP + 多线程 + SQLite3)
基于 C 语言的 QQ 聊天室(TCP + 多线程 + SQLite3) 项目功能基础功能: 登录、注册、添加好友、私聊、创建群聊、群聊扩展功能: 删除好友、注销账号、好友在线状态、群管理(拉人/踢人)、VIP 特权、邮件通知等 功能介绍:模拟QQ聊天客户端:登录界面:1、登录2、注册 //将用…...
Apache Flink:实时数据流处理的终极武器
Apache Flink:实时数据流处理的终极武器 在当今这个数据驱动的世界,实时数据流处理已经成为各行各业的核心需求。从金融风控到电商推荐,从物联网监控到网络安全,毫秒级的响应能力决定了一家公司在市场中的竞争力。而在众多流式计…...

点云处理入门--PointNetPointNet++论文与代码详解
基础知识 点云数据: 点云是一种通过三维扫描设备或计算机图形学技术获取的三维空间数据,通常由一系列点组成,每个点包含其在三维空间中的坐标(如 x,y,z),有时还可能包含颜色、强度等附加信息。 介绍几种常…...
通过Nginx负载均衡+Keepalived实现业务高可用
通过Nginx负载均衡和Keepalived可以实现业务的高可用,以下是详细的实现步骤: 环境准备 假设我们有3台服务器,IP地址分别为: 服务器1(Nginx Keepalived 主节点):192.168.1.100服务器2&#x…...
Spark技术系列(三):Spark算子全解析——从基础使用到高阶优化
Spark技术系列(三):Spark算子全解析——从基础使用到高阶优化 1. 算子核心概念与分类体系 1.1 算子本质解析 延迟执行机制:转换算子构建DAG,行动算子触发Job执行任务并行度:由RDD分区数决定(可通过spark.default.parallelism全局配置)执行位置优化:基于数据本地性的…...
ES6模块化详解:导入与导出方式
在现代 JavaScript 开发中,模块化是代码管理和组织的重要工具。ES6(ECMAScript 2015)引入了模块化的概念,通过 import 和 export 来组织代码,使得模块的管理变得更加清晰和简洁。本文将详细介绍 ES6 中的各种模块导入导…...
每日学习Java之一万个为什么?[MySQL面试篇]
分析SQL语句执行流程中遇到的问题 前言1 MySQL是怎么在一台服务器上启动的2 MySQL主库和从库是同时启动保持Alive的吗?3 如果不是主从怎么在启动的时候保证数据一致性4 ACID原则在MySQL上的体现5 数据在MySQL是通过什么DTO实现的6 客户端怎么与MySQL Server建立连接…...
常用空间数据结构对比
空间数据结构是用来组织和查询多维空间数据的算法结构。它们在地理信息系统 (GIS)、计算机图形学、机器人导航、机器学习等领域非常重要。以下是几种常见空间数据结构的对比: 1. 四叉树(Quadtree) 适用场景:二维空间数据&#x…...

AnythingLLM+LM Studio本地知识库构建
前置操作: 已经安装以下软件,并配置后: DeepSeek-R1-Distill-Llama-8B-Q4_K_M.ggufLM-Studio-0.3.10-6-x64 软件准备: 下载AnythingLLM:AnythingLLM | The all-in-one AI application for everyone 点击"Dow…...
使用 Java 更新 Word 文档中的图表数据-超详细
使用 Java 更新 Word 文档中的图表数据 在日常的工作中,尤其是在数据分析和报告自动化的场景中,可能会遇到需要定期更新 Word 文档中的图表数据的需求。比如,生成数据报告时,我们需要在图表中更新一些动态的数据值。今天…...

Qt常用控件之下拉框QComboBox
下拉框QComboBox QComboBox 是一个下拉框控件。 1. QComboBox属性 属性说明currentText当前选中的文本。currentIndex当前选中的条目下标(从 0 开始,如果没有条目被选中则该值为 -1)。editable是否允许被修改。为 true 时,QCom…...
Qt 中集成mqtt协议
一,引入qmqtt 库 我是将整个头文件/源文件都添加到了工程中进行编译,这样 跨平台时 方便,直接编译就行了。 原始仓库路径:https://github.com/emqx/qmqtt/tree/master 二,使用 声明一个单例类,将订阅到…...
2024年第十五届蓝桥杯大赛软件赛省赛Python大学A组真题解析
文章目录 试题A: 拼正方形(本题总分:5 分)解析答案试题B: 召唤数学精灵(本题总分:5 分)解析答案试题C: 数字诗意解析答案试题A: 拼正方形(本题总分:5 分) 【问题描述】 小蓝正在玩拼图游戏,他有7385137888721 个2 2 的方块和10470245 个1 1 的方块,他需要从中挑出一些…...
AI大模型-提示工程学习笔记19-自我反思
目录 1. 自我反思的核心思想 (1) LLM 的局限性 (2) Reflexion 的解决方案 2. Reflexion 的工作流程 (1) 任务输入 (2) 初始生成 (3) 反思 (Reflection) (4) 调整与改进 (5) 迭代 (6) 结果输出 3. Reflexion 的关键组件 (1) 大语言模型 (LLM) (2) 反思者 (Reflector…...
GaussDB 学习实战指南:从部署到高并发优化的全流程解析
引言 GaussDB 作为华为推出的高性能分布式数据库,凭借其 分布式架构、高可用性、云原生支持 等特性,成为企业级应用的核心选择。本文将以 实战操作为核心,覆盖 集群部署、数据分片、性能调优、容灾备份、云上迁移 五大场景,通过真实案例与代码示例,助你快速掌握 GaussDB …...
vue3 Props的使用
Props是什么? 官方地址:Props | Vue.js 在 Vue 中,props 是父组件向子组件传递数据的一种机制。 props 是子组件中定义的自定义属性,父组件通过这些属性向子组件传递数据。 它们是单向数据流的一部分,意味着数据只能…...

Ecode前后端传值
说明 在泛微 E9 系统开发过程中,使用 Ecode 调用后端接口并进行传值是极为常见且关键的操作。在上一篇文章中,我们探讨了 Ecode 调用后端代码的相关内容,本文将深入剖析在 Ecode 中如何向后端传值,以及后端又该如何处理接收这些值…...

【Linux】进程状态(二)
目录 前言: 一、进程状态: 1.运行状态(时间片) 2.阻塞状态 3.阻塞挂起状态 二、Linux进程状态: 1.运行状态(R)和阻塞状态(S) 2.深度睡眠状态(D) 3.停止状态(T) 3.1使进程在后台运行 4.追踪暂停状态(t) 5.死亡状态(X)和僵尸状态…...

domain 网络安全 网络安全域
🍅 点击文末小卡片 ,免费获取网络安全全套资料,资料在手,涨薪更快 文章目录 1、域的概述 1.1、工作组与域1.2、域的特点1.3、域的组成1.4、域的部署概述1.5、活动目录1.6、组策略GPO 2、域的部署实验 2.1、建立局域网…...
链表和STL —— list 【复习笔记】
1. 链表 1.1 链表的定义和类型 和顺序表一样,链表也是一种线性表,线性表存储结构为链式存储就是链表 链式存储不仅要保存数据元素,还要保存数据元素间的关系,这两个部分信息形成了结点。结点有两个域:数据域&#x…...

【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...

大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...

10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...

华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...
作为测试我们应该关注redis哪些方面
1、功能测试 数据结构操作:验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化:测试aof和aof持久化机制,确保数据在开启后正确恢复。 事务:检查事务的原子性和回滚机制。 发布订阅:确保消息正确传递。 2、性…...