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), ®isterResMes)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), ®isterMes)if err != nil {fmt.Println("json.Marshal err = ", err)return}var resMes message.MessageresMes.Type = message.RegisterResMesTypevar registerResMes message.RegisterResMeserr = model.MyUserDao.Register(®isterMes.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")
优化:当一个新的用户上线后,其他已经登录的用户也能获取最新在线用户列表
思路:
- 当用户A上线,服务器九八A用户的上线信息推给所有在线的用户
- 客户端也需要维护一个map,map中记录了他的好友(目前就是所有人)map[int]User
- 客户端和服务器的通讯通道,要依赖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), ¬ifyUserStatusMes)//2. 把这个用户信息,状态保存到客户map[int]User中updateUserStatus(¬ifyUserStatusMes)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), ¬ifyUserStatusMes)//2. 把这个用户信息,状态保存到客户map[int]User中updateUserStatus(¬ifyUserStatusMes)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 遍历硬币和金额,累加所有可能 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.前言 在生产环境中由于一些不明原因,导致 RabbitMQ 重启,在 RabbitMQ 重启期间生产者消息投递失败, 导致消息丢失,需要手动处理和恢复。于是,我们开始思考,如何才能进行 RabbitMQ 的消息可靠投递呢&…...

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

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()函数: 把图像…...

R语言复现:中国Charls数据库一篇现况调查论文的缺失数据填补方法
编者 在临床研究中,数据缺失是不可避免的,甚至没有缺失,数据的真实性都会受到质疑。 那我们该如何应对缺失的数据?放着不管?还是重新开始?不妨试着对缺失值进行填补,简单又高效。毕竟对于统计师来说&#…...

解决Git:Author identity unknown Please tell me who you are.
报错信息: 意思: 作者身份未知 ***请告诉我你是谁。 解决办法: git config --global user.name "你的名字"git config --global user.email "你的邮箱"...

Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
设计模式和设计原则回顾
设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)
1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖
在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会࿰…...

基于SpringBoot在线拍卖系统的设计和实现
摘 要 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统,主要的模块包括管理员;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...

【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看
文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...
【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error
在前端开发中,JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作(如 Promise、async/await 等),开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝(r…...
小木的算法日记-多叉树的递归/层序遍历
🌲 从二叉树到森林:一文彻底搞懂多叉树遍历的艺术 🚀 引言 你好,未来的算法大神! 在数据结构的世界里,“树”无疑是最核心、最迷人的概念之一。我们中的大多数人都是从 二叉树 开始入门的,它…...