项目准备及自我介绍

项目准备及自我介绍

1. 自我介绍

面试官你好,我叫XXX,就读于重庆邮电大学;实验室是国家信息无障碍研发中心;研究生期间,参与两起机器人项目,一是基于SLAM的清洁机器人,实现了建图、导航、路径规划、弓字型清扫和自动回充等功能;二是基于SLAM的导盲机器人,初步实现了室内外导航功能;本科期间累计获得艺术类省级奖项一次,创业类国家级一等奖一次;研究生期间两次获得学业二等奖学金,目前已发表机器人相关论文EI会议两篇。

2. 清洁机器人项目

2.1项目简介

这个项目叫做基于SLAM的清洁机器人,从我研一刚来的时候就在做,一直到研二;它分为上位机和下位机,下位机是STM32F4 ,上位机用的是Nvidia的TX2。上位机安装ROS,使用ROS中的一些工具来开发我们需要的功能并且可以可视化机器人的状态;ROS是一种分布式软件框架,节点可以运行在不同的计算平台上,通过Topic进行通信,话题属于异步数据流通信;平时在调试时我们配置好网络之后,将机器人设为master(主机),我电脑上的Ubuntu通过ssh命令远程连接机器人,就可以通过ROS中的话题通信了。

然后下层就是负责运动控制、传感器数据采集等;就比如要实现机器人手动导航,上层通过cmd_vel这个话题给下层发线速度和角速度,下层和上层通过串口通信,下层收到了这个话题,再根据机器人运动学模型(我们那个是差分的),算出左右的轮子的速度,再通过PID来调电机。手动导航整个控制的过程就是这样。

要实现更加复杂的功能,可以加更多的传感器,我们的项目加了激光雷达,红外,imu,超声波等;可以实现建图、导航、弓字形清扫、自动充电等功能;项目大概就是这样,谢谢。

2.2 项目难点

2.2.1 红外充电

自动回充的过程:

从底层到上层,整体配合实现充电;充电桩有四个红外发射器,清洁机器人前面有两个红外接收器,充电桩发出1248,底层的接收器接受充电桩发出的信号,再通过串口通信以话题的形式发给上层,上层收到红外信号,根据红外信号来调整机器人的姿态;最后直至充上电;

红外数据读取:

采用单片机的输入捕获功能,在红外编码的下降沿捕捉计数器的值,记录两次下降沿捕捉到的计数器的值,然后后- -次减前一次即可得到时间差,从而判断是编码0还是编码1.

2.3 ROS话题通信(异步)

  • talker向master注册发布者信息
  • listener同上操作
  • master通过RPC向listener发送talker的地址信息
  • listener接收到地址信息,通过RPC向talker发送连接请求
  • talker确认连接请求,通过RPC向listener确认连接
  • listener尝试与talker建立连接
  • 发送数据

总结:前五步的通信协议都是RPC,最后传输数据才用TCP

3. 集群聊天服务器项目

3.1 项目简介

这个项目分为了四个模块,

第一个网络模块,采用的是开源的muduo网络库,好处就是解耦了网络模块代码和业务模块代码,封装了epoll,让开发者专注于业务模块的代码的开发,

服务层用了一些c++11的技术,比如bind 绑定器,消息发生之后,回调操作的绑定,当网络IO有消息请求的话,通过消息请求,从消息里边解析出json,得到消息ID,通过回调来处理这个消息,就是这么的一个过程。

数据存储层,用了关系型数据库MySQL,对于项目上的一些关键数据,进行存储,比如用户的账号,用户离线消息,好友列表,群组列表关系,都是在MySQL里面存储的;

单台服务器下,主要就是这几个模块,单台服务器下,它的并发能力是有限的,为了提高并发能力,项目要支持多机扩展,要部署多台网络服务器的话,需要负载均衡,我这个项目因为主要是基于TCP协议自己去搭建的CS通信,所以是基于Nginx TCP负载均衡,要做一个长连接,长连接应用的是消息聊天通信,客户端不仅仅要主动给服务器发消息,服务器还要主动给客户端推消息,必须得用长连接,短连接,服务端没办法给客户端直接推消息,另外在负载均衡里边,因为我是每个服务器里,有不同的用户进行注册,那在不同服务器上注册的用户要进行通信的话,主要是引入了Redis 作为一个MQ消息队列的一个功能,利用它的发布订阅,在这里边实现了跨服务器的消息通信,

3.2 数据明文传输的安全问题(json)

数据加密和解密

3.2.1 对称加密算法

客户端和服务端使用的同一套密钥

加解密效率高 AES加解密算法

3.2.2 非对称加密算法

公钥加密的,只能用私钥来解密,私钥加密的,只能用公钥来解密。

加密复杂,效率慢,但安全,RSA加解密算法

具体用在项目上,服务端会有一个RSA的私钥,客户端代码里边集成了一个RSA的公钥,

结合的方法:

用RSA公钥加密AES密钥key 传输到服务端,服务端用RSA私钥也解密AES密钥key 后面就用对称加密算法来传输

在这里插入图片描述

3.3 历史消息存储

3.3.1 本地消息存储
3.3.2 云消息存储

在这里插入图片描述

3.4 客户端消息如何按序显示

消息添加序列号seq

在这里插入图片描述

3.5 Redis实现功能不稳定,还有哪些组件可用

服务器中间件:其他相似MQ消息队列!!!

在这里插入图片描述

kafka

zeromq

rabbitmq Topic主题

rocketmq

3.6 redis运行不稳定,挂了的话怎么办

redis 消息积累的过快, 消息消费得过慢,

redis实现得发布订阅功能还是比较简单,实际应用中,非关键业务或者流量不是非常大用到得异步通知订阅功能,还是可以用redis,

如果依赖发布订阅实现核心功能,聊天功能,就需要采用专业级的消息队列 来实现消息传输。

3.7 Redis核心功能 key-value 缓存数据库如何用在项目上

可以把用户的登录的状态存在Redis里边,要查用户的状态,先在Redis里面查,查到了直接返回,没查到,再去数据库里边查,查完了再往Redis里面写,

3.8 为什么要用Redis作为跨服务器通信的组件 为什么各个server不能直接相互通信呢

​ 如果六台服务器,跨服务器通信的时候,因为不在一个服务器上注册的,两个用户要聊天,我的服务器要把我发的消息再转发到你的服务器上,任务服务器上的用户,都有可能跟我通信,如果服务器两两直连,所有的server又要当客户端,又要当服务器,整个设计就很复杂,这个会造成服务器之间耦合性太高,而且,为了检测其他服务器是否在线,还得不断跟其他服务器保持一个心跳机制。

​ 在这里边,由于一台服务器发生故障,那么其他服务器会花很大的力气去维持这个心跳,心跳维持不住了,会拆除这个连接,当我们新去增加一台服务器时,还要想办法让其他服务器去连接这一台服务器,然后这台服务器作为客户端连接所有的其他服务器,这样的设计不适合服务器集群,也就没有服务器中间件的必要了。

​ 进行跨服务器通信的时候,都是引入消息队列,用消息队列来解耦服务器的耦合程度,所有的服务器不需要感知其他服务器的存在,有服务器挂掉的话,不影响其他的服务器,

在这里插入图片描述

3.9 如果网络拥塞严重,Server端如何感知客户端在线还是掉线了

增加心跳机制

在这里插入图片描述

在这里插入图片描述

3.10 项目不足的地方

3.10.1 加好友问题

加好友的时候应该像QQ那样发送请求,然后等待对方接受再写入

3.10.2 单台服务器关闭时,数据库更新用户在线状态的问题

该项目中用redis的发布-订阅功能进行多台服务器间的通信功能。目前考虑的是所有服务器同时关闭的情况。如若是仅仅关闭一台服务器,那么mysql库的更新用户在线状态的功能是不合理的,如表的结构以及mysql语句所示,一台服务器关闭时会将mysql库中所有用户的在线重置为下线状态。

我的想法是:在user表中增加一列,该列记录的是该次登陆的服务器的ip及端口号,不在线的用户该列可以置为-1。这样当我们仅仅关闭一台服务器时,就可以在数据库中区分开登陆在该服务器中的用户然后选择性得更改其状态。

3.11 项目遇到的问题

3.11.1.离线消息存储

当一个用户有多条离线消息时,登陆成功后只显示一条消息

原因:在设计offlinemessage数据表时对id字段设置为了主键,导致表中不能有重复id,这样使得每个用户只能有一条离线数据。解决也很简单将id字段的主键属性去掉,使得id可以重复。

3.11.2 客户端和服务器 异常退出的问题

(49条消息) C++搭建集群聊天室(十一):客户端 || 服务器 异常退出解决方案_看,未来的博客-CSDN博客

客户端异常推出:此前我们对客户端退出的操作仅仅就是将连接释放掉,没有跟业务联系起来

异常下线原因:没有正常发送json 字符串

现在我们的解决方案是:

  1. 从用户连接表里 之前用map存储的,找到,然后删除这个用户的链接信息,

  2. 用户异常推出,相当于下线,根据用户的id在redis中取消订阅通道

  3. 更新用户的状态信息,设置成离线

服务端异常退出:当服务器断开以后,表里边的用户状态还是online,下一次服务器运行的时候,用户去做登录操作的时候,总是报账号已登录

产生的原因:如果我们用ctrl+c强制结束服务器运行的话,就没有机会去修改用户的登录状态,

解决办法:

在main函数中设置信号捕捉

写一个重置方法,把online状态的用户,设置成offline,

update user set state =“offline” where state =“offline”;

户状态还是online,下一次服务器运行的时候,用户去做登录操作的时候,总是报账号已登录

产生的原因:如果我们用ctrl+c强制结束服务器运行的话,就没有机会去修改用户的登录状态,

解决办法:

在main函数中设置信号捕捉

写一个重置方法,把online状态的用户,设置成offline,

update user set state =“offline” where state =“offline”;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值