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

集群聊天服务器各个类进行详解

1.dh.h

类定义概要

类名: MySQL

功能: 简化MySQL的连接、查询和更新操作,提供接口给上层应用使用。


成员变量

private:MYSQL *_conn;
  • _conn:指向MYSQL结构体的指针,用于代表数据库连接实例。由mysql_init()初始化,之后通过mysql_real_connect建立连接。

构造与析构函数

MySQL()

  • 作用: 初始化数据库连接对象,调用mysql_init(nullptr)
  • 功能: 为连接准备一个空的MYSQL实例。

~MySQL()

  • 作用: 释放数据库连接资源。
  • 调用: mysql_close(_conn),关闭连接,释放资源。

成员函数(公共接口)

bool connect()

  • 用途: 建立实际的数据库连接。
  • 实现细节:
    • 调用mysql_real_connect,连接到配置信息中的数据库(serveruserpassworddbname、端口3306)。
    • 连接成功后,设置字符集为gbkmysql_query(_conn, "set names gbk"))。
    • 连接成功则输出日志“connect mysql success!”。
    • 连接失败则输出详细的错误信息,包含错误原因和连接参数。
  • 返回值:
    • true:连接成功
    • false:连接失败

bool update(string sql)

  • 用途: 执行SQL更新操作(INSERT、UPDATE、DELETE等)。
  • 实现细节:
    • 调用mysql_query(_conn, sql.c_str())执行SQL。
    • 若失败,输出错误,返回false
    • 成功返回true
  • 示例: 插入新用户或修改数据。

MYSQL_RES *query(string sql)

  • 用途: 执行SQL查询语句(SELECT),返回结果集。
  • 实现细节:
    • 调用mysql_query(_conn, sql.c_str())执行查询。
    • 若失败,输出错误信息,返回nullptr
    • 若成功,调用mysql_use_result(_conn)获取结果集。
  • 返回值:
    • MYSQL_RES*:结果集指针,调用者需负责释放。

MYSQL* getConnection()

  • 用途: 提供底层连接指针,便于更多的低级操作或调试。
  • 返回: _conn指针。

其他细节

  • 连接信息存储:

    • server127.0.0.1
    • userroot
    • passwordSf523416&111
    • dbnamechat

    这些信息是静态变量(static string),方便在整个程序中使用。

  • 日志输出:

    • 使用 muduo/base/Logging.h 提供的日志宏 LOG_INFO 和 LOG_ERROR,方便调试和监控。

总结

这个 MySQL 类封装了:

  • 连接管理: 内部维护一个MYSQL*连接句柄。
  • 连接方法: connect(),连接数据库。
  • 数据操作:
    • update() 执行写操作(增删改)。
    • query() 执行读操作,返回结果集指针。
  • 资源管理: 在析构函数中释放连接。

它为上层应用提供了简洁、封装的数据库访问接口,并加入了错误信息输出和日志记录,非常适合在实际的C++服务器项目中使用。

2.FriendModel

让我们一起来详细分析这个FriendModel类,它主要负责维护和处理好友关系相关的操作。这个类封装了操作好友信息的两个核心功能:添加好友关系和查询好友列表。


类定义概述

#ifndef FRIENDMODEL_H
#define FRIENDMODEL_H#include "user.hpp"
#include <vector>
using namespace std;class FriendModel
{
public:// 添加好友关系void insert(int userid, int friendid);// 返回用户好友列表vector<User> query(int userid);
};#endif

成员方法概述

1. void insert(int userid, int friendid)
  • 功能: 在好友关系表中插入一条新的好友关系。
2. vector<User> query(int userid)
  • 功能: 查询某个用户的所有好友,返回一个User对象的向量(好友列表)。

方法详细解读

1. 添加好友关系:void insert(int userid, int friendid)

实现逻辑:

  • 构造SQL语句,格式为:
    insert into friend values(userid, friendid)
    
  • 创建MySQL对象,并连接数据库。
  • 如果连接成功,执行update()方法插入好友关系。

说明:

这个操作假设friend表有两列(例如:userid 和 friendid),代表一对好友关系。


2. 查询好友列表:vector<User> query(int userid)

实现逻辑:

  • 构造SQL语句,使用内部连接(inner join),查询用户的好友信息:

    select a.id, a.name, a.state
    from user a
    inner join friend b on b.friendid = a.id
    where b.userid = userid
    

    这条语句的作用:

    • user表中选出所有该用户的好友信息。
    • 通过friend关系表关联用户ID。
  • 创建一个vector<User>存放好友信息。

  • 建立数据库连接,执行查询:

    • 若成功,遍历MYSQL_RES结果集:

      • 利用mysql_fetch_row()读取每一行数据。

      • 创建一个User对象,设置其字段(idnamestate)。

      • User加入结果向量中。

    • 释放MYSQL_RES资源。

  • 返回好友列表vector<User>


类成员变量

// 目前该类没有显式成员变量,只有成员方法

备注:

  • 这个类设计中没有持久的成员变量,每次操作时都新建MySQL对象以连接数据库。这是一种简单实现,适合关系不频繁变动的场景。

其他细节

  • 数据库操作:

    • 插入关系时调用mysql.update(sql),没有事务控制,简单插入。
    • 查询好友信息时调用mysql.query(sql),处理结果集。
  • 安全性:

    • 使用sprintf拼接SQL语句,可能存在SQL注入风险;实际应用中建议用参数化查询。
  • 性能:

    • 每次操作都新建数据库连接,不复用连接,可能影响效率。

总结

这个FriendModel类提供了两个主要功能

  1. 添加好友关系insert()

    • 将两用户的好友关系存入数据库。
  2. 查询好友列表query()

    • 根据用户ID,查找所有好友信息,返回User对象的数组(好友列表)。

该设计结构简洁,直接,但在性能优化和安全性方面可以进一步增强(如连接池、参数化查询等)。

同时,它依赖于数据库表结构(friend表和user表)合理设计。

3.类比FriendModel类,还有usermodel, groupmodel,OfflinMegModel

这是数据操作模型层,负责在业务逻辑和数据存储之间传递信息。它知道如何把业务需求(如添加好友)转化为数据库操作,也懂得如何把数据库查询结果转化为业务可用的对象。

4.group.hpp,groupuser.hpp,user.hpp

 让我们详细分析这三个类(UserGroupUserGroup)的设计与作用,它们都是典型的 ORM(对象关系映射)类,用于映射数据库中的表结构到 C++ 对象中,方便开发中对数据的操作。

1. User 类(用户基础表的ORM类)

class User
{
public:User(int id = -1, string name = "", string pwd = "", string state = "offline"){this->id = id;this->name = name;this->password = pwd;this->state = state;}void setId(int id) { this->id = id; }void setName(string name) { this->name = name; }void setPwd(string pwd) { this->password = pwd; }void setState(string state) { this->state = state; }int getId() { return this->id; }string getName() { return this->name; }string getPwd() { return this->password; }string getState() { return this->state; }protected:int id;string name;string password;string state;
};

作用与设计:

  • 表示“用户”实体,将用户表中的字段(idnamepasswordstate)映射为类成员。
  • 提供了构造函数、getter、setter方法,方便操作。
  • 典型的ORM类,用于在程序中封装用户信息。

2. GroupUser 类(群组用户,扩展了User,添加角色信息)

复制代码

class GroupUser : public User
{
public:void setRole(string role) { this->role = role; }string getRole() { return this->role; }private:string role; // 用户在群组中的角色(如管理员、普通成员)
};

作用与设计:

  • 继承自User,意味着“群组内的用户”具有用户的所有基本属性(如ID、用户名、密码、状态)。
  • 增加role属性,表示用户在群组中的角色。
  • 设计理念:一个群组中的用户不仅仅算作普通用户,还需区分角色,因此在群组关系中,添加了角色字段。

总结:

  • GroupUser是一个“关系类”,表示某个用户在某个群组中的身份信息(不仅仅是用户,还包括角色属性)。
  • 这样设计方便在多对多关系中存储角色信息(如用户属于哪个群,角色怎样)。

3. Group 类(群组类)

class Group
{
public:Group(int id = -1, string name = "", string desc = ""){this->id = id;this->name = name;this->desc = desc;}void setId(int id) { this->id = id; }void setName(string name) { this->name = name; }void setDesc(string desc) { this->desc = desc; }int getId() { return this->id; }string getName() { return this->name; }string getDesc() { return this->desc; }vector<GroupUser> &getUsers() { return this->users; }private:int id;               // 群组IDstring name;          // 群组名称string desc;          // 群组描述vector<GroupUser> users; // 包含的成员列表(每个成员带角色信息)
};

作用与设计:

  • 表示“群组”实体,映射群组表。
  • 含有ID、名称、描述字段。
  • users 成员变量用来存储群组的所有成员(GroupUser对象),实现多对多关系(一个群组有多个用户,一用户可能在多个群组)。
  • 提供了基本的getter/setter方法。

关系与整体架构理解

  • User:代表整个系统的用户信息,映射用户表。
  • GroupUser:继承用户信息,并附加角色信息,代表某用户在特定群组中的角色(多对多关系中的中间表/关系实体)。
  • Group:代表群组实体,含其成员(GroupUser的集合)信息。

这套设计体现了面向对象方式对数据库关系的封装:

  • 通过Group类管理群组信息和成员列表;
  • 通过GroupUser类描述用户和角色之间的关系;
  • 通过User类描述用户基础信息。

总结:

  • 这三类共同组成了一个与“群组聊天”功能相关的对象模型架构。
  • 设计充分利用继承(GroupUser继承User)来复用代码,增强扩展性。
  • 使得程序能够以对象的方式操作数据库中的用户、群组与成员关系。

5.Redis 类

这份redis.hppredis.cpp实现了一个封装了Redis发布订阅(Pub/Sub)功能的类,方便在C++项目中使用Redis进行消息通信。下面我会详细介绍这个类中的成员变量和成员函数,帮助你理解它的设计思想和使用方法。


Redis 类成员和方法详解

1. 成员变量

复制代码

private:redisContext *_publish_context;   // 负责发布消息的上下文redisContext *_subcribe_context;  // 负责订阅消息的上下文function<void(int, string)> _notify_message_handler; // 消息接收时的回调函数
  • _publish_context:用来连接和操作Redis的发布(PUBLISH)命令,用于向频道发送消息。
  • _subcribe_context:用来连接和操作Redis的订阅(SUBSCRIBE)命令,用于监听和接收频道的消息。
  • _notify_message_handler:业务层定义的回调函数,用于通知业务层收到的消息。

2. 构造函数和析构函数

复制代码

Redis();  // 构造函数,初始化成员指针为空
~Redis(); // 析构函数,释放连接
  • 构造函数:初始化指针为nullptr
  • 析构函数:如果指针不为空,调用redisFree()释放资源,避免内存泄漏。

3. 核心功能成员方法

connect()

复制代码

bool connect();
  • 连接本地Redis服务器(默认地址为 127.0.0.1:6379)。
  • 分别创建两个连接:一个用于发布,一个用于订阅。
  • 连接成功后,启动一个独立线程调用observer_channel_message(),不断监听订阅通道中的消息,异步通知业务层。
publish()

复制代码

bool publish(int channel, string message);
  • 向指定频道发布消息。
  • 使用redisCommand()执行PUBLISH命令。
  • 如果成功,返回true,否则返回false
subscribe()

复制代码

bool subscribe(int channel);
  • 订阅指定频道。
  • 使用redisAppendCommand()redisBufferWrite()向Redis服务器发出SUBSCRIBE命令。
  • 注意:订阅操作是非阻塞的,只是发出订阅命令,接收消息由后台线程监听。
unsubscribe()

复制代码

bool unsubscribe(int channel);
  • 取消订阅某个频道。
  • 使用类似subscribe()的方式发出UNSUBSCRIBE命令。
observer_channel_message()

复制代码

void observer_channel_message();
  • 运行在后台线程中,持续调用redisGetReply()接收Redis服务器推送的消息。
  • 解析收到的消息数组(reply->element):
    • reply->element[2]->str:消息内容
    • reply->element[1]->str:频道编号
  • 调用_notify_message_handler()通知业务层收到新消息。
init_notify_handler()

复制代码

void init_notify_handler(function<void(int, string)> fn);
  • 初始化消息通知的回调函数。
  • 用户在业务层定义处理逻辑后,调用此函数注册。

其他细节说明

  • 连接管理:在connect()中创建两个redisContext,方便分别处理发布和订阅的连接,避免竞争和阻塞。
  • 多线程
    • 订阅消息的监听在observer_channel_message()中运行在单独的线程,保证异步处理。
  • 内存管理
    • 使用freeReplyObject()释放redisReply资源。
  • 命令执行
    • 发布:redisCommand()
    • 订阅/取消订阅:redisAppendCommand() + redisBufferWrite(),避免阻塞调用。
  • 错误处理
    • 连接失败和命令失败都输出错误信息,返回false

总结:

这个Redis类封装了Redis的Pub/Sub基本操作:

  • 连接connect()
  • 发布消息publish()
  • 订阅频道subscribe()
  • 取消订阅unsubscribe()
  • 异步监听消息:在后台线程中自动调用observer_channel_message(),收到消息后通过回调通知业务逻辑。
  • 回调机制:用户可以注册自己的消息处理函数。

它实现了异步订阅模型,能很好地应用在类似聊天服务器、实时通知等场景,非常实用。

6.ChatServer类

你的代码基于知名的 Muduo 网络库,实现了一个高效、易维护的聊天服务器主控类。下面按照结构–成员变量–成员方法详细分析:


一、ChatServer 类的结构作用

ChatServer 封装了实际的网络服务器逻辑,负责:

  • 初始化服务器、设置参数
  • 监听和管理客户端连接
  • 管理消息收发和业务处理
  • 调度事件循环(事件驱动)

二、成员变量讲解

private:TcpServer _server; // 组合muduo库,实现服务器功能的类对象EventLoop *_loop;  // 指向事件循环对象(相当于主线程的事件分发器)

1. TcpServer _server

  • Muduo 中封装的 TCP 服务器核心类。
  • 能自动监听端口,负责底层 epoll、多线程 I/O、连接管理等“苦力活”。
  • ChatServer 通过它实现与客户端的所有网络交互。

2. EventLoop *_loop

  • 事件循环指针。
  • 实际上是主 Reactor 的事件分发器,用于响应 I/O 事件。

三、成员方法详解

构造函数:ChatServer(EventLoop*, const InetAddress&, const string&)

ChatServer(EventLoop *loop, const InetAddress &listenAddr, const string &nameArg): _server(loop, listenAddr, nameArg), _loop(loop)
{// 注册链接回调_server.setConnectionCallback(std::bind(&ChatServer::onConnection, this, _1));// 注册消息回调_server.setMessageCallback(std::bind(&ChatServer::onMessage, this, _1, _2, _3));// 设置线程数量_server.setThreadNum(4);
}

作用总结与细节分析:

  • 初始化 _server,告诉 muduo 用哪台主机 IP/端口监听(listenAddr)、取什么名字(nameArg)、用哪个 event loop。
  • setConnectionCallback():绑定"有新连接/断开"时执行 onConnection 方法。
  • setMessageCallback():绑定"收到消息"时执行 onMessage 方法。
  • setThreadNum(4):用 4 个工作线程处理 I/O,提升吞吐量。

void start()

void ChatServer::start()
{_server.start();
}
  • 真正地启动服务器(让 Muduo 开始监听并接收客户端连接)。

void onConnection(const TcpConnectionPtr&)

void ChatServer::onConnection(const TcpConnectionPtr &conn)
{// 客户端断开链接if (!conn->connected()){ChatService::instance()->clientCloseException(conn);conn->shutdown();}
}

核心作用:

  • 这是连接状态变化时的回调(新连接或断开)。
  • 如果连接断开,则做以下处理:
    • 通知业务服务层进行账号、数据等“下线”处理(clientCloseException)。
    • 主动关闭 socket(conn->shutdown())。

void onMessage(const TcpConnectionPtr&, Buffer *, Timestamp)

void ChatServer::onMessage(const TcpConnectionPtr &conn, Buffer *buffer, Timestamp time)
{string buf = buffer->retrieveAllAsString();try {json js = json::parse(buf);// 检查必须字段if (!js.contains("msgid")) {throw json::exception("Missing 'msgid' field");}auto msgHandler = ChatService::instance()->getHandler(js["msgid"].get<int>());msgHandler(conn, js, time);}catch (const json::exception& e) {LOG_ERROR << "JSON parse error: " << e.what();if (conn->connected()) {json response;response["msgid"] = INVALID_MSG_ACK;response["errno"] = 400;response["errmsg"] = "Invalid JSON format: " + string(e.what());conn->send(response.dump());}}catch (const exception& e) {LOG_ERROR << "Message handling error: " << e.what();}
}

详细流程:

  1. 拿到完整缓冲区数据(收到的一次消息)。
  2. 尝试解析为 JSON 对象。
  3. 检查是否有"msgid"字段(决定了本消息应该怎么处理)。
  4. 调用 ChatService::instance()->getHandler(msgid) 找到对应业务处理函数,然后把消息传给它执行。
  5. 如果解析失败/消息结构有误,则:
    • 打日志报错
    • 给客户端返回错误提示

作用通俗理解:

“服务器收到客户发来的消息,把这消息当成快递包裹拆开看——快递单上写着包裹类型(msgid),然后根据类型分给对应员工(handler)处理。拆快递出错就写个反馈单还回去。”


四、补充说明

成员方法之间的关系

  • start 用于启动服务器。
  • onConnection/onMessage 并不是主动调用,而是事件驱动,在有连接/消息时被 Muduo 框架自动调用。
  • 事件响应机制和reactor思想一致。

和 ChatService 的协作

ChatServer 只管网络部分,具体业务如何处理交由 ChatService,“专人专职”,大大降低耦合。


五、总结

ChatServer 核心成员&方法概览:

名称简要作用
_serverMuduo 的 TCP 服务器,负责监听和通信。
_loop名字叫event loop,事件派发中心。
start()启动服务器。
onConnection()检测连接/断开,并在断开时交给业务进一步下线处理。
onMessage()收到客户端数据时解析json,根据业务类型分发给具体handler处理;出问题自动回错。
构造函数初始化服务器参数并注册各回调,每一步都让ChatServer做最擅长的事情。

这样,不仅代码结构清晰,而且便于扩展和维护,是高性能网络服务推荐的模式!

7.chatservice类

会把这个ChatService类中的所有成员变量和方法,逐个详细讲解,确保你理解每个部分的作用、设计思想以及它们的工作流程,而且会尽力用通俗易懂的语言,让你像听故事一样理解这个“聊天服务”系统。


一、类的整体架构和角色定位

ChatService是一个“聊天服务器”的核心业务类(管理者)。它采用单例模式(确保整个程序中只存在唯一的实例),负责处理所有的“用户登录、注册、点对点聊天、群聊、好友关系、群组操作”等业务逻辑。


二、成员变量(这个类内部存的“存储空间”和“工具箱”)

1. 单例实例

static ChatService *instance();
  • 作用:提供调用的入口,用于获取或创建唯一的ChatService实例(即单例设计模式)。
  • 通俗理解:就像超市只有一个“管理员”实例,这个方法帮你拿到它。

2. 消息处理映射表

unordered_map<int, MsgHandler> _msgHandlerMap;
  • 作用:把不同“消息ID”映射到对应“处理函数”。
  • 比如登录对应login()函数,注册对应reg()函数。
  • 通俗理解:就像菜单点菜表,点“牛排”就知道要做牛排一样。

3. 在线用户连接表

unordered_map<int, TcpConnectionPtr> _userConnMap;
  • 作用:存放已登录、在线用户的“用户ID”和“对应的TCP连接指针”。
  • 用途:当需要向某用户发消息时,先找这个表看用户是否在线,在线了就可以直接推送消息。
  • 通俗理解:像“电话簿”,存着每个谁在线、用哪个电话(连接)。

4. 连接互斥锁

mutex _connMutex;
  • 作用:在多线程环境下,保证对_userConnMap的操作(增删改查)是安全的。
  • 为何需要:因为可能有多个连接同时操作这个表,比如一个用户刚登录、登出,或服务器在同时处理多个请求。

5. 数据模型对象(操作数据库)

复制代码

UserModel _userModel;
OfflineMsgModel _offlineMsgModel;
FriendModel _friendModel;
GroupModel _groupModel;
  • 作用:封装了数据库操作的封装类(操作用户信息,离线消息,好友关系,群组信息)。
  • 例子
    • _userModel:查询或更新用户信息。
    • _offlineMsgModel:存储或读取离线消息。
    • _friendModel:管理好友关系(添加好友等)。
    • _groupModel:管理群聊信息。

6. Redis操作对象

复制代码

Redis _redis;
  • 作用:封装了与Redis(一个高速的数据库和消息队列系统)的交互,用于实现“跨进程”、“多服务器”的消息推送和订阅。

三、主要方法(业务逻辑执行的“技能”)

1. 获取单例实例

复制代码

static ChatService *instance();
  • 作用:返回全局唯一的ChatService对象,确保程序中只有一个“聊天服务”。
  • 实现:用“静态局部变量”,保证只创建一次。

2. 构造函数(注册消息-handler)

复制代码

ChatService::ChatService()
  • 作用
    • 初始化各种消息ID和对应的请求处理函数的映射关系。
    • 链接(连接)Redis,为后续消息订阅做准备。
注册消息响应(通过bind绑定对应成员函数)
  • login注册到LOGIN_MSG

  • register注册到REG_MSG

  • oneChat注册到ONE_CHAT_MSG

  • 还有好友添加、创建群、加入群、群聊的处理方法。

  • 通俗理解:像打电话时拨通不同号码调用不同小姐姐的服务。


3. 业务重置(重要)

复制代码

void reset();
  • 作用
    • 在服务器异常或重启时调用。
    • 将所有“已登录的用户”状态重置为“离线”状态(确保状态同步真实情况)。
  • 调用场景:系统崩溃后,恢复正常工作状态。

4. 获取特定“消息类型”对应的处理函数

复制代码

MsgHandler getHandler(int msgid);
  • 作用
    • 输入msgid,返回对应的处理函数(函数指针或lambda)。
    • 如果找不到,就返回一个“错误处理器”。
  • 设计亮点
    • 动态路由:前端发的不同消息会被路由到不同的处理函数去。

5. 各类具体业务的处理方法(详细讲解)

login()登陆流程
  • 输入:用户ID、密码。
  • 逻辑:-查询用户信息,验证密码。-用户已在线,提示重复登录,否则:-存用户名和连接关系到_userConnMap,方便推送。-在Redis订阅频道(方便跨服务通知)。-更新用户状态为在线。-返回用户信息(包括离线消息、好友列表、群组信息)。
  • 作用:实现实际“登陆”功能。
reg()注册
  • 输入:用户名、密码。
  • 逻辑:-校验格式、长度。-存入数据库。-返回成功或失败。
loginout()退出/注销
  • 作用:-从活跃连接中删除用户。-在Redis取消订阅某渠道(让其他服务器知道该用户已离线)。-更新数据库用户状态。
clientCloseException()
  • 作用:
    • 处理客户端异常断开连接(比如突然关闭窗口,没有正常退出)。
    • 类似loginout,清除连接,更新状态。
oneChat()点对点聊天
  • 输入:接收方toid,消息内容。
  • 机制:-第一步:找_userConnMap,看看对方是否在线(直接推)。-第二步:如不在线,则存离线消息。-第三步:如果对方在线但不在自己服务器(假设多节点),就用Redis发布消息,其他节点会收信息。
addFriend()添加好友
  • 输入:自己ID和好友ID。
  • 操作:存入好友关系表。
createGroup()
  • 输入:发起人ID、群组名、描述。
  • 操作:-在数据库中创建新群。-将发起人加入该群(权限设为“creator”)。
addGroup()加入群组
  • 输入:用户ID、群ID。
  • 操作:将用户加入群组。
groupChat()群聊
  • 输入:群ID、群成员消息。
  • 作用:
    • 中转消息:
      • 先找成员在不在线(在自己连接map里)。
      • 在线了推送。
      • 不在线存离线消息(存到数据库中)。

6. 处理Redis订阅消息

复制代码

void handleRedisSubscribeMessage(int, string);
  • 作用
    • 其他服务器发布同步消息后,调用此函数。
    • 找到对应的用户连接,如果在,推送消息。
    -否则,存离线消息。

四、重点总结(通俗版)

  • ChatService就像一个“指挥官”,协调所有聊天相关的操作。
  • 存放“用户和连接关系”,方便主动“发消息给用户”。
  • 有事注册“事件处理器”:不同的ID对应不同操作(登录、注册、聊天、群聊)。
  • 利用Redis实现多服务消息同步
  • 每个业务都是封装好的函数:登录、注册、点对点聊天等。
  • 整体设计高扩展性、线程安全、结构清晰。
http://www.dtcms.com/a/283828.html

相关文章:

  • LAMP迁移LNMP Nginx多站点配置全流程
  • 大型语言模型(LLM)在网络安全中最具商业价值的应用场景(Grok3 回答 DeepSearch模式)
  • Java-75 深入浅出 RPC Dubbo Java SPI机制详解:从JDK到Dubbo的插件式扩展
  • 新版本flutter(3.32.7) android 端集成百度地图sdk
  • 网络编程7.17
  • cors跨域资源共享
  • Python 网络爬虫 —— 代理服务器
  • 阿里云-通义灵码:隐私保护机制—为数据安全筑起铜墙铁壁
  • Web3.0 实战项目、简历打造、精准投递+面试准备
  • MongoDB 与MySQL 及es的区别
  • 黑客知识-攻击
  • 数据仓库分层经典架构:ODS、DWD、DWS
  • 安卓 GoFasting(间歇性断食)v1.03.35.0708
  • python-字典、集合、序列切片、字符串操作(笔记)
  • cdh6.3.2的hive使用apache paimon格式只能创建不能写报错的问题
  • Thymeleaf 表单绑定与验证详解
  • Rabbitmq direct 模式与 finout区别
  • Apache Ignite 的 Pages Writes Throttling(页面写入节流)
  • C++ - 仿 RabbitMQ 实现消息队列--C++11 异步操作实现线程池
  • InfluxDB 3与Apache Parquet:打造高性能时序数据存储与分析解决方案
  • Apache DolphinScheduler介绍与部署
  • UE5 Nanite使用
  • 下班倒计时
  • 链路聚合实训
  • 管家婆价格折扣跟踪管理:查询、新增、修改、删除
  • JAVA中的Map集合
  • 【01背包】P1466 [USACO2.2] 集合 Subset Sums
  • 华为云容器产品分析
  • HTML表格基础
  • 【Linux】第一个小程序—进度条