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

2.经典项目-海量用户即使通讯系统

1.实现功能-完成注册用户

完成用户注册的步骤(客户端)
1.将User移动到common/message文件夹下
2.在message中新增注册用户的结构体

const (LoginMesType       = "LoginMes"LoginResMesType    = "LoginResMes"RegisterMesType    = "RegisterMes"RegisterResMesType = "RegisterResMes"
)type RegisterMes struct {User User `json:"user"` //类型就是User机构体
}
type RegisterResMes struct {Code  int    `json:"code"`  //返回状态码 400表示该用户已存在 200表示注册成功Error string `json:"error"` //返回错误信息
}

3.在client/process/userProcess.go中添加注册函数


func (this *UserProcess) Register(userId int, userPwd, userName string) (err error) {conn, err := net.Dial("tcp", "localhost:8889")if err != nil {fmt.Println("net.Dial err = ", err)return}defer conn.Close()var mes = message.Message{}mes.Type = message.RegisterMesTyperegisterMes := message.RegisterMes{}registerMes.User.UserId = userIdregisterMes.User.UserPwd = userPwdregisterMes.User.UserName = userNamedata, err := json.Marshal(registerMes)if err != nil {fmt.Println("json.Marshal err = ", err)return}mes.Data = string(data)data, err = json.Marshal(mes)if err != nil {fmt.Println("json.Marshal err = ", err)return}tf := &utils.Transfer{Conn: conn,}err = tf.WritePkg(data)if err != nil {fmt.Println("注册发送信息错误 err = ", err)return}//处理服务器端返回的消息mes, err = tf.ReadPkg() //mes就是 RegisterResMesif err != nil {fmt.Println("utils.ReadPkg(conn) err = ", err)return}var registerResMes message.RegisterResMeserr = json.Unmarshal([]byte(mes.Data), &registerResMes)if registerResMes.Code == 200 {fmt.Println("注册成功,请重新登录")} else {fmt.Println(registerResMes.Error)}return
}

4.在client/main/main.go中修改注册相关代码

		case 2:fmt.Println("注册用户")fmt.Println("请输入用户id:")fmt.Scanf("%d\n", &userId)fmt.Println("请输入用户密码:")fmt.Scanf("%s\n", &userPwd)fmt.Println("请输入用户名称:")fmt.Scanf("%s", &userName)up := &process2.UserProcess{}up.Register(userId, userPwd, userName)

完成用户注册的步骤(服务器端)
1.在model/userDao.go中添加

func (this *UserDao) Register(user *message.User) (err error) {conn := this.pool.Get()defer conn.Close()_, err = this.getUserById(conn, user.UserId)if err == nil {err = ERROR_USER_EXISTSreturn}//账户不存在,则可以正常注册data, err := json.Marshal(user) //序列化if err != nil {return}//入库_, err = conn.Do("HSet", "users", user.UserId, string(data))if err != nil {fmt.Println("保存注册用户错误 err = ", err)return}return
}

2.在process/userProcess.go中添加

func (this *UserProcess) ServerProcessRegister(mes *message.Message) (err error) {var registerMes message.RegisterMeserr = json.Unmarshal([]byte(mes.Data), &registerMes)if err != nil {fmt.Println("json.Marshal err = ", err)return}var resMes message.MessageresMes.Type = message.RegisterResMesTypevar registerResMes message.RegisterResMeserr = model.MyUserDao.Register(&registerMes.User)if err != nil {if err == model.ERROR_USER_EXISTS {registerResMes.Code = 505registerResMes.Error = err.Error()} else {registerResMes.Code = 506registerResMes.Error = "注册发生未知错误"}} else {registerResMes.Code = 200fmt.Println("用户注册成功")}data, err := json.Marshal(registerResMes)if err != nil {fmt.Println("json.Marshal err = ", err)return}resMes.Data = string(data)data, err = json.Marshal(resMes)if err != nil {fmt.Println("json.Marshal err = ", err)return}// 发送data,将其封装到writePkg函数//因为使用分层模式(mvc)需要先创建一个Transfer实例,然后读取tf := &utils.Transfer{Conn: this.Conn,}err = tf.WritePkg(data)return
}

3.修改main/processor.go

func (this *Processor) ServerProcessMes(mes *message.Message) (err error) {switch mes.Type {case message.LoginMesType://处理登录//创建UserPorcess实例up := &process2.UserProcess{Conn: this.Conn,}err = up.ServerProcessLogin(mes)case message.RegisterMesType:up := &process2.UserProcess{Conn: this.Conn,}err = up.ServerProcessRegister(mes)default:fmt.Println("消息类型不存在,无法处理...")}return
}

2.实现功能-完成登录时能返回当前在线用户

1.在服务器端维护一个onlineUsers map[int] *UserProcess
2.创建一个新的文件userMgr.go,完成功能对onlineUsers的增删改查
3.在LoginResMess增加一个字段Users []int //保存在线用户id
4.当用户登录后可以显示当前在线用户列表

代码实现
新增server/process/userMgr.go

package processimport "fmt"// 因为UserMgr实例在服务器端有且仅有一个,在很多机房会用到
// 因此将其定义为全局变量
var (userMgr *UserMgr
)type UserMgr struct {onlineUsers map[int]*UserProcess
}// 完成对UserMgr初始化工作
func init() {userMgr = &UserMgr{onlineUsers: make(map[int]*UserProcess, 1024),}
}// 完成对onlineUsers添加
func (this *UserMgr) AddOnlineUser(up *UserProcess) {this.onlineUsers[up.UserId] = up
}// 删除
func (this *UserMgr) DelOnlineUser(userId int) {delete(this.onlineUsers, userId)
}// 返回当前所有在线用户
func (this *UserMgr) GetAllOnlineUser() map[int]*UserProcess {return this.onlineUsers
}// 根据id返回对应的值
func (this *UserMgr) GetOnlineUserById(userId int) (up *UserProcess, err error) {//从map取出一个值,带检测方式up, ok := this.onlineUsers[userId]if !ok { //说明,要找的用户当前不在线err = fmt.Errorf("用户%d 不在线", userId)return}return
}

修改server/process/userProcess.go

type UserProcess struct {Conn net.Conn//增加一个字段,表示该Conn是哪个用户UserId int
}
	} else {loginResMes.Code = 200//将登录成功的用户的userId赋给thisthis.UserId = loginMes.UserId//将登录成功的用户放入userMgr中userMgr.AddOnlineUser(this)//将当前在线用户的id放到loginResMes.UserIds中for id, _ := range userMgr.onlineUsers {loginResMes.UserIds = append(loginResMes.UserIds, id)}fmt.Println(user.UserName, "账户登录成功")

修改message.go

type LoginResMes struct {Code    int    `json:"code"`    //返回状态码 500 表示该用户未注册 200表示登录成功UserIds []int  `json:"userIds"` //增加字段保存userid的切片Error   string `json:"error"`   //返回错误信息
}

修改client/process/userProcess.go

	if loginResMes.Code == 200 {//可以显示当前在线用户列表fmt.Println("当前在线用户列表如下:")for _, v := range loginResMes.UserIds {//不显示自己if v == userId {continue}fmt.Println("用户id:\t", v)}fmt.Print("\n\n")

优化:当一个新的用户上线后,其他已经登录的用户也能获取最新在线用户列表
思路:

  1. 当用户A上线,服务器九八A用户的上线信息推给所有在线的用户
  2. 客户端也需要维护一个map,map中记录了他的好友(目前就是所有人)map[int]User
  3. 客户端和服务器的通讯通道,要依赖serverProcessMes协程

代码实现
在message.go中增加

const (LoginMesType            = "LoginMes"LoginResMesType         = "LoginResMes"RegisterMesType         = "RegisterMes"RegisterResMesType      = "RegisterResMes"NotifyUserStatusMesType = "NotifyUserStatusMes"
)// 定义几个用户状态常量
const (UserOnline = iotaUserOfflineUserBusyStatus
)// 为了配合服务器端推送用户状态变化的消息
type NotifyUserStatusMes struct {UserId int `json:"userId"` //用户idStatus int `json:"status"` //用户状态
}

修改user.go

// 定义一个用户的结构体
type User struct {//确定字段信息//为了序列化和反序列化成功,需保证用户信息的json字符串的key 和结构体的字段对应的tag名字一致UserId     int    `json:"userId"`UserPwd    string `json:"userPwd"`UserName   string `json:"userName"`UserStatus int    `json:"userStatus"` //用户在线状态
}

修改server/process/userProcess.go

	} else {loginResMes.Code = 200//将登录成功的用户的userId赋给thisthis.UserId = loginMes.UserId//将登录成功的用户放入userMgr中userMgr.AddOnlineUser(this)//通知其他在线用户this.NotifyOtherOnlineUser(this.UserId)//将当前在线用户的id放到loginResMes.UserIds中for id, _ := range userMgr.onlineUsers {loginResMes.UserIds = append(loginResMes.UserIds, id)}fmt.Println(user.UserName, "账户登录成功")}

在server/process/userProcess.go中增加

// 编写通知所有在线的用户的方法
func (this *UserProcess) NotifyOtherOnlineUser(userId int) {//遍历onlineUsers 然后一个个发送NotifyUserStatusMesfor id, up := range userMgr.onlineUsers {//过滤自己if id == userId {continue}up.NotifyMeOnline(userId)}
}func (this *UserProcess) NotifyMeOnline(userId int) {//组装我们的NotifyUserStatusMesvar mes message.Messagemes.Type = message.NotifyUserStatusMesTypevar notifyUserStatusMes message.NotifyUserStatusMesnotifyUserStatusMes.UserId = userIdnotifyUserStatusMes.Status = message.UserOnline//将notifyUserStatusMes序列化data, err := json.Marshal(notifyUserStatusMes)if err != nil {fmt.Println("json.Marshal err = ", err)return}//将序列化后的notifyUserStatusMes复制给mes.Datames.Data = string(data)//对mes再次序列化,准备发送data, err = json.Marshal(mes)if err != nil {fmt.Println("json.Marshal err = ", err)return}//发送,Transfer实例tf := &utils.Transfer{Conn: this.Conn,}err = tf.WritePkg(data)if err != nil {fmt.Println("NotifyMeOnline err = ", err)return}
}

修改client/process/server.go

		case 1:fmt.Println("显示在线用户列表")outpuOnlineUser()
// 和服务器保持通讯
func serverProcessMes(Conn net.Conn) {//创建一个Transfer实例,不停地读取服务器发送的消息tf := &utils.Transfer{Conn: Conn,}for {fmt.Println("客户端正在等待读取服务器发送的消息")mes, err := tf.ReadPkg()if err != nil {fmt.Println("tf.ReadPkg err = ", err)return}//如果读到消息,进入下一步处理逻辑switch mes.Type {case message.NotifyUserStatusMesType: //有人上线//处理//1. 取出NotifyUserStatusMesvar notifyUserStatusMes message.NotifyUserStatusMesjson.Unmarshal([]byte(mes.Data), &notifyUserStatusMes)//2. 把这个用户信息,状态保存到客户map[int]User中updateUserStatus(&notifyUserStatusMes)default:fmt.Println("服务器端返回了未知的消息类型")}//fmt.Printf("mes = %v\n", mes)}
}

新增client/process/userMgt.go

package processimport ("fmt""project/common/message"
)// 客户端维护的map
var onlineUsers map[int]*message.User = make(map[int]*message.User, 10)// 在客户端显示当前在线的用户
func outpuOnlineUser() {//遍历onlilneUsersfmt.Println("当前在线用户列表:")for id, _ := range onlineUsers {fmt.Println("用户id:\t", id)}
}// 编写一个方法,处理返回的NotifyUserStatusMes
func updateUserStatus(notifyUserStatusMes *message.NotifyUserStatusMes) {user, ok := onlineUsers[notifyUserStatusMes.UserId]if !ok {user = &message.User{UserId: notifyUserStatusMes.UserId,}}user.UserStatus = notifyUserStatusMes.StatusonlineUsers[notifyUserStatusMes.UserId] = useroutpuOnlineUser()
}

修改client/process/userProcess.go

	if loginResMes.Code == 200 {//可以显示当前在线用户列表fmt.Println("当前在线用户列表如下:")for _, v := range loginResMes.UserIds {//不显示自己if v == userId {continue}fmt.Println("用户id:\t", v)//完成客户端的onlineUsers初始化user := &message.User{UserId:     v,UserStatus: message.UserOnline,}onlineUsers[v] = user}fmt.Print("\n\n")

3.实现功能-完成登录用户群聊

3.1 完成客户端发送消息

思路
1.新增一个消息结构体smsMes…
2.新增一个model/CurUser
3.在smsProcess.go增加相应的方法SendGroupMes发送一个群聊消息

代码实现
在message中新增

const (LoginMesType            = "LoginMes"LoginResMesType         = "LoginResMes"RegisterMesType         = "RegisterMes"RegisterResMesType      = "RegisterResMes"NotifyUserStatusMesType = "NotifyUserStatusMes"SmsMesType              = "SmsMes"
)// 增加一个SmsMes发送消息
type SmsMes struct {Content string `json:"content"` //消息内容User           //匿名结构体,集继承
}

新增client/model/curUser.go

package modelimport ("net""project/common/message"
)// 在客户端很多地方要用到,需声明为全局
type CurUser struct {Conn net.Connmessage.User
}

在client/process/userMgr.go中新增

var CurUser model.CurUser //在用户登录成功后,完成对CurUser初始化

在client/process/userProcess.go修改

	if loginResMes.Code == 200 {//初始化CurUserCurUser.Conn = connCurUser.UserId = userIdCurUser.UserStatus = message.UserOnline

在client/process/smsProcess.go新增

package processimport ("encoding/json""fmt""project/common/message""project/common/utils"
)type SmsProcess struct {
}// 发送群聊消息
func (this *SmsProcess) SendGroupMes(content string) (err error) {//1.创建一个Mesvar mes message.Messagemes.Type = message.SmsMesType//2.创建一个SmsMes实例var smsMes message.SmsMessmsMes.Content = contentsmsMes.UserId = CurUser.UserIdsmsMes.UserStatus = CurUser.UserStatus//3.序列化smsMesdata, err := json.Marshal(smsMes)if err != nil {fmt.Println("SendGroupMes json.Marshal err = ", err.Error())return}mes.Data = string(data)//4.对mes再次序列化data, err = json.Marshal(mes)if err != nil {fmt.Println("SendGroupMes json.Marshal err = ", err.Error())return}//5.将mes发送给服务器tf := &utils.Transfer{Conn: CurUser.Conn,}//6.发送err = tf.WritePkg(data)if err != nil {fmt.Println("sendGroupMes err = ", err.Error())return}return
}

修改client/process/server.go

		var key intvar content string//用到SmsProcess实例较为频繁,因此定义在外部smsProcess := &SmsProcess{}fmt.Scanf("%d\n", &key)switch key {case 1:fmt.Println("显示在线用户列表")outpuOnlineUser()case 2:fmt.Println("你想对大家说什么:")fmt.Scanf("%s\n", &content)smsProcess.SendGroupMes(content)
3.2 服务器接收群发消息,并发送消息(发送者除外)

思路
1.在服务器端接收到SmsMes消息
2.在server/process/smsProcess.go文件增加群发消息的方法
3.在客户端还要增加去处理服务器转发的群发消息

代码实现
在server/process/smsProcess.go中添加

package processimport ("encoding/json""fmt""net""project/common/message""project/common/utils"
)type SmsProcess struct {
}func (this *SmsProcess) SendGroupMes(mes *message.Message) {var smsMes message.SmsMeserr := json.Unmarshal([]byte(mes.Data), &smsMes)if err != nil {fmt.Println("json.Unmarshal err = ", err)return}data, err := json.Marshal(mes)if err != nil {fmt.Println("json.Marshal err = ", err)return}for id, up := range userMgr.onlineUsers {//过滤自己if id == smsMes.UserId {continue}this.SendMesToEachOnlineUser(data, up.Conn)}}func (this *SmsProcess) SendMesToEachOnlineUser(data []byte, conn net.Conn) {tf := &utils.Transfer{Conn: conn,}err := tf.WritePkg(data)if err != nil {fmt.Println("群发消息失败")return}
}

修改server/main/processor.go

func (this *Processor) ServerProcessMes(mes *message.Message) (err error) {switch mes.Type {case message.LoginMesType://处理登录//创建UserPorcess实例up := &process2.UserProcess{Conn: this.Conn,}err = up.ServerProcessLogin(mes)case message.RegisterMesType:up := &process2.UserProcess{Conn: this.Conn,}err = up.ServerProcessRegister(mes)case message.SmsMesType:smsProcess := &process2.SmsProcess{}smsProcess.SendGroupMes(mes)default:fmt.Println("消息类型不存在,无法处理...")}return
}

新增client/process/smsMgr.go

package processimport ("encoding/json""fmt""project/common/message"
)func outputGroupMes(mes *message.Message) {var smsMes message.SmsMeserr := json.Unmarshal([]byte(mes.Data), &smsMes)if err != nil {fmt.Println("json.Unmarshal err = ", err.Error())return}//显示信息info := fmt.Sprintf("用户id:\t%d 对大家说:\t%s", smsMes.UserId, smsMes.Content)fmt.Println(info)fmt.Println()
}

修改client/process/server.go

		//如果读到消息,进入下一步处理逻辑switch mes.Type {case message.NotifyUserStatusMesType: //有人上线//处理//1. 取出NotifyUserStatusMesvar notifyUserStatusMes message.NotifyUserStatusMesjson.Unmarshal([]byte(mes.Data), &notifyUserStatusMes)//2. 把这个用户信息,状态保存到客户map[int]User中updateUserStatus(&notifyUserStatusMes)case message.SmsMesType: //有人群发消息outputGroupMes(&mes)default:fmt.Println("服务器端返回了未知的消息类型")}

相关文章:

2.经典项目-海量用户即使通讯系统

1.实现功能-完成注册用户 完成用户注册的步骤(客户端) 1.将User移动到common/message文件夹下 2.在message中新增注册用户的结构体 const (LoginMesType "LoginMes"LoginResMesType "LoginResMes"RegisterMesType "RegisterMes"…...

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的交通标志识别系统详解(深度学习模型+UI界面代码+训练数据集)

摘要:本篇博客详细介绍了利用深度学习构建交通标志识别系统的过程,并提供了完整的实现代码。该系统采用了先进的YOLOv8算法,并与YOLOv7、YOLOv6、YOLOv5等早期版本进行了性能评估对比,分析了性能指标如mAP、F1 Score等。文章深入探…...

VMware下创建虚拟机

Centos7是比较常用的一个Linux发行版本,在国内的使用比例比较高 安装完VMware一定要检查虚拟网卡有没有安装成功,如果没有VMnet1和VMnet8 虚拟机是无法上网的,就需要卸载重启电脑重新安装 控制面板—网络和Internet—网络连接 快捷方式打开&a…...

基于Ambari搭建大数据分析平台

一、部署工具简介 1. Hadoop生态系统 Hadoop big data ecosystem in Apache stack 2. Hadoop的发行版本 Hadoop的发行版除了Apache的开源版本之外,国外比较流行的还有:Cloudera发行版(CDH)、Hortonworks发行版(HDP)、MapR等&am…...

Vue template到render过程,以及render的调用时机

Vue template到render过程 vue的模版编译过程主要如下:template -> ast -> render函数(1)调用parse方法将template转化为ast(抽象语法树)(2)对静态节点做优化(3)生…...

阿里云服务器Ngnix配置SSL证书开启HTTPS访问

文章目录 前言一、SSL证书是什么?二、如何获取免费SSL证书三、Ngnix配置SSL证书总结 前言 很多童鞋的网站默认访问都是通过80端口的Http服务进行访问,往往都会提示不安全,很多人以为Https有多么高大上,实际不然,他只是…...

12 list的使用

文档介绍 文档介绍 1.list是可以在常数范围内的任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代 2.list的底层是带头双向链表循环结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和…...

控件交互与视图交互的区别

在实际应用中,控件交互和视图交互的区别主要体现在以下几个方面: (1)关注的对象不同:控件交互更关注于界面中的单个控件如何响应用户的操作,例如按钮的点击、列表项的滑动等。而视图交互则更关注于整个界面的布局、导航和交互设计…...

打包 加載AB包 webGl TextMeshPro 變紫色的原因

1.打包 加載AB包 webGl TextMeshPro 變紫色的原因 編輯器命令行https://docs.unity3d.com/cn/2019.4/Manual/CommandLineArguments.html 1.UnityHub 切換命令行參數 -force-gles 2.-force-gles(仅限 Windows)| 使 Editor 使用 OpenGL for Embedded Sys…...

美易官方:去年全球企业派息1.66万亿美元创新高

去年全球企业派息总额达到了1.66万亿美元,创下了历史新高。这一数字不仅彰显了全球企业的盈利能力和财务稳健性,也反映了它们对股东的责任感和对未来发展的信心。在这一背景下,微软和苹果这两家科技巨头在派息方面的表现尤为引人注目。 微软是…...

基于Springboot的面向智慧教育的实习实践系统设计与实现(有报告)。Javaee项目,springboot项目。

演示视频: 基于Springboot的面向智慧教育的实习实践系统设计与实现(有报告)。Javaee项目,springboot项目。 项目介绍: 采用M(model)V(view)C(controller&…...

【数据库-黑马笔记】基础-SQL

本文参考b站黑马数据库视频,总结详细全面的笔记 ,可结合视频观看1~26集 MYSQL 的基础知识框架如下 目录 一、MYSQL概述 1、数据库相关概念 2、MYSQL的安装及启动 二、SQL 1、DDL【Data Defination】 2、DML【Data Manipulation】 ①、插入 ②、更新和删除 3、 DQL【Data…...

MySQL性能分析:性能模式和慢查询日志的使用

目录 一、性能模式 步骤1. 启用性能模式 步骤2. 查询性能数据 步骤3. 分析性能数据 步骤4. 优化与调整 注意事项 二、慢查询日志 步骤1. 启用慢查询日志...

【哈希表算法题记录】15. 三数之和,18. 四数之和——双指针法

题目链接 15. 三数之和 思路 这题虽然放在哈希表的分类里面,但是用双指针法会更高效。 之前的双指针我们要么是一头left一尾right,要么是快fast慢slow指针。这里是要计算三个数的和,我们首先对数组进行从小到大的排序,先固定一…...

代码随想录算法训练营Day44 ||leetCode 完全背包 || 518. 零钱兑换 II || 377. 组合总和 Ⅳ

完全背包 518. 零钱兑换 II 遍历硬币和金额&#xff0c;累加所有可能 class Solution { public:int change(int amount, vector<int>& coins) {vector<int> dp(amount1,0);dp[0]1;for (int i 0; i < coins.size();i){for(int j coins[i]; j < amount;…...

RabbitMQ发布确认高级版

1.前言 在生产环境中由于一些不明原因&#xff0c;导致 RabbitMQ 重启&#xff0c;在 RabbitMQ 重启期间生产者消息投递失败&#xff0c; 导致消息丢失&#xff0c;需要手动处理和恢复。于是&#xff0c;我们开始思考&#xff0c;如何才能进行 RabbitMQ 的消息可靠投递呢&…...

【阿里云系列】-基于云效构建部署Springboot项目到ACK

介绍 为了提高项目迭代的速度加速交付产品给客户&#xff0c;我们通常会选择CICD工具来减少人力投入产生的成本&#xff0c;开源的工具比如有成熟的Jenkins&#xff0c;但是本文讲的是阿里云提高的解决方案云效平台&#xff0c;通过配置流水线的形式实现项目的快速部署到服务器…...

PyTorch搭建LeNet训练集详细实现

一、下载训练集 导包 import torch import torchvision import torch.nn as nn from model import LeNet import torch.optim as optim import torchvision.transforms as transforms import matplotlib.pyplot as plt import numpy as npToTensor()函数&#xff1a; 把图像…...

R语言复现:中国Charls数据库一篇现况调查论文的缺失数据填补方法

编者 在临床研究中&#xff0c;数据缺失是不可避免的&#xff0c;甚至没有缺失&#xff0c;数据的真实性都会受到质疑。 那我们该如何应对缺失的数据&#xff1f;放着不管&#xff1f;还是重新开始?不妨试着对缺失值进行填补&#xff0c;简单又高效。毕竟对于统计师来说&#…...

解决Git:Author identity unknown Please tell me who you are.

报错信息&#xff1a; 意思&#xff1a; 作者身份未知 ***请告诉我你是谁。 解决办法&#xff1a; git config --global user.name "你的名字"git config --global user.email "你的邮箱"...

测试微信模版消息推送

进入“开发接口管理”--“公众平台测试账号”&#xff0c;无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息&#xff1a; 关注测试号&#xff1a;扫二维码关注测试号。 发送模版消息&#xff1a; import requests da…...

生成 Git SSH 证书

&#x1f511; 1. ​​生成 SSH 密钥对​​ 在终端&#xff08;Windows 使用 Git Bash&#xff0c;Mac/Linux 使用 Terminal&#xff09;执行命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" ​​参数说明​​&#xff1a; -t rsa&#x…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

深度学习习题2

1.如果增加神经网络的宽度&#xff0c;精确度会增加到一个特定阈值后&#xff0c;便开始降低。造成这一现象的可能原因是什么&#xff1f; A、即使增加卷积核的数量&#xff0c;只有少部分的核会被用作预测 B、当卷积核数量增加时&#xff0c;神经网络的预测能力会降低 C、当卷…...

管理学院权限管理系统开发总结

文章目录 &#x1f393; 管理学院权限管理系统开发总结 - 现代化Web应用实践之路&#x1f4dd; 项目概述&#x1f3d7;️ 技术架构设计后端技术栈前端技术栈 &#x1f4a1; 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 &#x1f5c4;️ 数据库设…...

基于TurtleBot3在Gazebo地图实现机器人远程控制

1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...

GO协程(Goroutine)问题总结

在使用Go语言来编写代码时&#xff0c;遇到的一些问题总结一下 [参考文档]&#xff1a;https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现&#xff1a; 今天在看到这个教程的时候&#xff0c;在自己的电…...

为什么要创建 Vue 实例

核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...

大数据治理的常见方式

大数据治理的常见方式 大数据治理是确保数据质量、安全性和可用性的系统性方法&#xff0c;以下是几种常见的治理方式&#xff1a; 1. 数据质量管理 核心方法&#xff1a; 数据校验&#xff1a;建立数据校验规则&#xff08;格式、范围、一致性等&#xff09;数据清洗&…...

聚六亚甲基单胍盐酸盐市场深度解析:现状、挑战与机遇

根据 QYResearch 发布的市场报告显示&#xff0c;全球市场规模预计在 2031 年达到 9848 万美元&#xff0c;2025 - 2031 年期间年复合增长率&#xff08;CAGR&#xff09;为 3.7%。在竞争格局上&#xff0c;市场集中度较高&#xff0c;2024 年全球前十强厂商占据约 74.0% 的市场…...