最新要闻
- 世界球精选!创维造车:主打座舱养生续命、碰撞测试0分!真是讽刺他妈给讽刺开门
- 环球即时:反转!国内油价明晚大概率下跌 预计下调0.07元/升
- 《暗黑4》本周末开测 世界BOSS刷新时间公布
- 天天关注:巴奴火锅下架富硒土豆!消费者可获赠500元储值卡:领取有条件
- 天天热推荐:百度发布文心一言AI模型:可实现文字、图片与视频智能生成
- 喝的人越来越少!星巴克向中国三四线城市进军:30多一杯咖啡县城青年能爱多久
- 孙海洋是湖北哪里人?
- 鲶鱼效应是什么意思?鲶鱼效应的经典案例是什么?
- 首店经济是什么意思?首店经济是谁提出的?
- 快报:权志龙演唱会门票多少钱2020_权志龙演唱会门票多少钱
- 今头条!RTX 40笔记本新品翻车?别急 先升级NVIDIA新驱动再说
- 每日精选:官宣!《炉石传说》被移出杭州亚运会项目:职业选手难过
- 环球快消息!360发布年度手机安全报告:受骗男性占七成 女性三成
- 天天最资讯丨800V电气架构打造 全新起亚EV9发布:二三排可面对面乘坐
- 扣上的安全带会自动打开?本田在美国召回近45万辆汽车
- 每日短讯:强冷空气来袭!河南三门峡3月下雪:厚厚一层一夜回冬
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
世界微动态丨得物从0到1自研客服IM系统的技术实践之路
本文由得物技术王卫强分享,为了更好的阅读体验,有较多的内容修订和排版优化。
一、引言
客服IM的核心业务其实就是在线沟通,客服IM的好处是使得客服与用户通过实时沟通的方式可以在最短的时间内帮助用户解决问题。
为了快速支撑公司业务发展需求,我们客服IM在发展初期是基于第三方的云IM SDK进行二次开发而来。虽然提升了项目进展,但同时也埋下了问题定位困难、特殊功能实现成本高等隐患。
(资料图)
随着公司业务的高速发展,客服对IM聊天的性能和体验都有了更高的要求,在第三方云IM SDK消息通信上逐渐遇到了技术瓶颈。为解决租用第三方云IM SDK接入带来的潜在隐患、提升IM的稳定性和高扩展性,自研一套可控、稳定、灵活的IM系统已是迫在眉睫了。
本篇文章将基于工程实践,分享我们从0到1自研一套客服IM系统时在各种关键技术点上的设计思路和实践方法。
注:为了简化内容,本文分享的技术栈主要是以Web客服端为主。
相关文章:
- 1)从零到卓越:京东客服即时通讯系统的技术架构演进历程;
- 2)瓜子IM智能客服系统的数据架构设计(整理自现场演讲,有配套PPT)。
学习交流:
- 移动端IM开发入门文章:《新手入门一篇就够:从零开发移动端IM》
- 开源IM框架源码:https://github.com/JackJiang2011/MobileIMSDK(备用地址点此)
(本文已同步发布于:http://www.52im.net/thread-4153-1-1.html)
二、业务场景
客服与用户在聊天的过程中,直观上就是客服在输入文案,然后通过网络发送给用户。
但是IM聊天SDK该如何设计才能使客服在发送消息过程中感知不到卡顿?这一点是非常关键的,要避免卡顿就要设计合理的发送策略以及避免大量JS脚本执行。
举个客服与用户聊天的例子:
- 1)客服发送了“客服小冰为您服务”这个文案,通过业务侧调用SDK的接口,传入到SDK;
- 2)再将该数据存储到数据池中,序列化后把这个数据对象data传递给socket接口,通过网络通道发送到网关;
- 3)网关侧接收到消息后,再反序列化,传递到数据池中进行处理,组装成业务可识别的model,推送到业务侧使用。
针对第1)点,SDK会先创建消息体,即把这个字符串封装成一个自定义的结构体model。
其聊天流程如下图所示:
从上图中可以清晰的看出一条消息发送和接收的完整流程链路。如果IM的SDK设计不合理,发送消息和接收消息流程出现了卡顿,将直接影响用户的体验。
三、自研框架架构图概览
下图是我们的自研IM系统架构原理图:
我们整体的技术改造主要是两个方面:
- 1)对消息链路的抽象改造:主要是消息数据存储和消息排序的重构;
- 2)业务接入侧的抽象改造:主要是将业务逻辑和SDK源码进行解耦,做到代码分层更加的清晰。
下面我们将针对主要的技术点进行详细地总结和分享。
四、消息链路发布/订阅实现
在IM SDK自研开发过程中,如何解耦框架代码和业务代码,做到灵活的消息监听,前期调研之后使用了RxJS。
这里简单介绍几个RxJS的核心概念:
- 1)Observable(可观察对象):表示一个可调用的未来值或事件的集合;
- 2)Observer(观察者):监听由Observable提供的值;
- 3)Subscription(订阅):表示 Observable 的执行。
注:Subscription 有一个重要的方法,即 unsubscribe,它不需要任何参数,只是用来清理由 Subscription 占用的资源主要用于取消 Observable 的执行。
SDK底层在接收到数据后需要同步到业务侧,之前的做法是通过监听方式实现,这种方式不具备取消订阅的能力,维护成本相对较高。而使用RxJS可以清晰的梳理出数据流向,通过发布订阅的方式实现数据的通信。
RxJS在发布订阅的实现流程如下:
从上图可以看到消息处理的整个流向非常清晰,框架底层接收消息,订阅者消费消息。
五、消息框架的分层结构概览
在我们整个自研的IM消息通信框架中,主要结构分成三层:
- 1)网络层;
- 2)数据链路层;
- 3)应用层。
具体如下图所示:
接下来我将详细分享各层的设计和实现思路。
六、消息框架的分层实现:网络层
网络层作为消息发送的最底层,负责TCP的连接、消息发送和接收。
网络协议我们选择的是TCP协议。我们为什么没有选择UDP呢?因为UDP是无连接的、不够安全、无法提供可靠传输的服务,通过TCP连接传送的数据可以无差别、不丢失、不重复且按序到达。
PS:尺有所短、寸有所长,TCP和UDP的优劣应该客观看待,感兴趣可以深入学习下面的文章:
《快速理解TCP和UDP的差异》
《一泡尿的时间,快速搞懂TCP和UDP的区别》
《快速理解为什么说UDP有时比TCP更有优势》
《深入地理解UDP协议并用好它》
《如何让不可靠的UDP变的可靠?》
我们整个IM SDK的通信方式采用的是WebSocket+ JSON、grpc +protobuf。(如果你对WebSocket和Protobuf不熟悉,可以详细学习《WebSocket从入门到精通,半小时就够!》、《Protobuf从入门到精通,一篇就够!》)
首先我们要做的就是建立Websocket连接:代码层面我们会先创建一个Connection的抽象类,主要处理网络连接相关配置、超时后重新连接的补偿实现,和一些继承类需要实现的抽象方法。
如上述代码所示:核心在处理超时重连,传统的重试策略是每隔一段时间重试一次,由于是固定的时间间隔重试,重试时又会有大量的请求在同一时刻涌入,会不断地造成限流。(这里使用了指数退避的方式,指数退避是一种通过反馈,成倍地降低某个过程的速率,以逐渐找到合适速率的算法,可根据时隙和重试尝试次数来决定延迟重试。)
其实现算法大致如下:
Websocket连接我们是通过继承Connect类实现的:
至此:网络层连接就已完成了,相对比较简单,都是一些socket api的封装,核心的点在用指数退避算法实现消息发送失败重连接。
七、消息框架的分层实现:数据链路层
数据链路层是IM SDK的核心层,主要涉及到用户信息、聊天消息、数据池等等,我们来一步步对每个模块进行分析。
首先梳理一下客服在登录到用户进线发送消息和接收消息的全过程。
过程有如下几个阶段:
7.1、协议类型消息协议类型非常重要,是消息发送的基石。初始化协议数据体,可以用于后续各种消息、事件的发送。
在IM自研的SDK通信协议类型主要有如下几种:
具体解释一下:
- 1)Hi:发送客户端基础信息,告诉server当前client的版本、设备类型、语言等信息;
- 2)Login: 登录,token验证,获取或创建当前用户topic信息;
- 3)Sub: 订阅topic或更新topic数据;
- 4)Leave: 取消订阅,解绑之前的订阅关系;
- 5)Pub: 发送数据消息给指定topic的订阅者;
- 6)Get: 获取topic的metadata信息,例如:获取订阅者列表、历史数据等;
- 7)Set: 更新topic的metadata信息,例如:删除消息或删除topic;
- 8)Del: 用于删除操作,包括删除消息、删除订阅关系、删除topic等;
- 9)Note: client发送通知给topic的订阅者,例如消息已收到,消息已读,当前正在输入等;
- 10)Action: 触发的事件,例如:切换客服状态、获取机器人问题等;
- 11)Datares: ack机制,告诉网关已收到该消息。
7.2、创建连接
对网络层消息链接实例化,实现消息的正常发送和接收。
其实现如下:
7.3、消息定义
客服要发送一条消息,肯定有对应的消息结构体model,即需要对消息体进行设计,这里会设计一下message类,每次创建新的消息体都会new一个实例,通过对实例的操作可以更新消息状态等。
如下所示:
针对单个消息,我们也要定义好消息状态,用于聊天过程中消息状态的更新。
如下:
7.4、数据池
消息类创建好之后,就需要有消息数据池来存储。
消息池结构定义如下:
这里还涉及到消息体的一些基本操作方法对数据池中的数据进行操作,就不做过多的阐述。
7.5、用户维度
上面都是在分析公共模块,但是客服和用户是一对多的关系存在,还需要设计一个用户维度模块,后续在业务侧的操作基本都是以用户维度来操作,需要从单个用户维度设计对应的订阅关系、消息发送、删除等等。
其实现大致如下:
7.5.1发送消息链路分析
针对客服发送消息,我们首先要站在客服角度考虑消息是否已发出去,优先展示的聊天页面,而不是等网关给了回复后在展示到聊天页面。
根据已往经验来看,只要回车消息就要立即展示到聊天页面,否则客服会认为出现了卡顿,体验效果不佳,鉴于这种场景的需求,在设计发送消息链路的时候就要充分考虑到这一点。
所以设计流程如下:
如上图所示:先在SDK内进行处理对应的消息,处理完成后返回到业务侧完成渲染后再进行消息发送到网关,正常情况下都在一帧之内,客服是感知不到有延迟的。这里要关注消息体序列化、反序列化的时机,避免无谓的性能浪费。
上述图中有个虚拟seq:主要是为了在未收到IM网关响应之前进行排序用的,比如图片、视频、断网发送消息、消息发送失败,或收到IM网关回复缺少seq(场景:敏感词)等情况都需要通过虚拟seq进行准确排序。
7.5.2接收消息链路分析
接收消息过程相对比较简单,收到消息进行反序列化后更新相关数据,然后在数据池中完成去重(重试机制)、排序后更新到业务侧渲染即可(如下图所示)。
7.5.3消息的可靠传递
IM消息的可靠投递主要是指:消息在发送接收过程中,能够做到不丢消息、消息不重复、消息顺序不错乱。
我们先来分析以下2种情况。
第一种情况:如果客服A在把消息发送到IM网关的过程中:
- 1)由于网络不通等原因失败了;
- 2)或者IM网关接收到消息进行存储时失败了;
- 3)或者IM网关一直没有返回结果,导致超时。
以上这些情况客服A都会被提示消息发送失败。
第二种情况:消息在IM网关存储完后,客服A被告知消息发送成功了,然后IM网关把消息推送给用户A的在线设备:
- 1)在推送的准备阶段或者把消息写入到内存后,如果服务端出现掉电,也会导致消息不能成功推送给用户A;
- 2)如果用户A的设备在接收到消息,在后续处理过程中出现问题,也会导致消息丢失。
针对第2)点,具体场景比如:用户A的设备在把消息写入本地DB时,出现异常导致落库失败,这种情况下,由于网络层面实际上已经成功传输,但用户A却看不到消息。
我们客服IM对于消息丢失的处理方案主要是参考TCP协议的ACK机制,实现了一套基于业务层的ACK协议。
添加ACK之前消息发送的时序图如下:
7.5.3.1)ACK 机制:
在TCP协议中,默认提供了ACK机制,通过一个协议自带的标准的ACK数据包,来对通信方接收的数据进行确认,告知通信发送方已确认成功接收了数据。ACK机制也是类似,需要解决的是:IM网关推送后如何确认消息是否成功送达接收方并明确被接收方所接收。
具体实现的时序图如下:
客服或用户在发送消息的过程中都会携带一个msgid(32位的uuid,类似TCP的sequenceId),IM网关在接收到消息后,会根据msgid到数据库中查询是否存在该条消息,如果存在就不落库,如果不存在就落库。
然后再推送到接收方,接收方在收到消息后会回复ACK,ACK包中会携带上当前最新的seqid,IM网关收到ACK回复后会对最大的seqid进行更新。
这里为什么要更新最大seqid呢?这么设计肯定有一定道理的,IM网关在收到发送方发送的消息后除了到数据库中检测该消息是否存在外,还会对比当前接收到消息的seq和最大seqid两者之间的差值,会把[seq, seqid)之间的数据全部推到接收方,正常情况下都是[n, n-1),如果IM网关没有收到接收方ACK,n-1就不会更新,推送的消息个数就大于1了。如果seq和seqid相等那就是发送方重复推送的消息,这个时候就不会向接收方推送。这里就涉及到了消息重试,继续向下分析吧。
PS:有关IM消息ID或序列号生成的专题文章可以阅读:
《IM消息ID技术专题(一):微信的海量IM聊天消息序列号生成实践(算法原理篇)》
《IM消息ID技术专题(三):解密融云IM产品的聊天消息ID生成策略》
《IM消息ID技术专题(四):深度解密美团的分布式ID生成算法》
《IM消息ID技术专题(五):开源分布式ID生成器UidGenerator的技术实现》
《IM消息ID技术专题(六):深度解密滴滴的高性能ID生成器(Tinyid)》
7.5.3.2)ACK机制中的消息重试:
消息推给A的过程中丢失了怎么办,比如:
- 1)A网络实际已经不可达,但IM网关还没有感知到(ping出现问题);
- 2)消息在中间网络途中被某些中间设备丢掉了。
解决这个问题也是参考了TCP协议的重传机制。我们会在客服端、IM网关、用户端都维护一个超时计时器,一定时间内如果没有收到对方回的ACK包,会重新取出该消息进行重推。在重试一定次数后,如果还是没有收到ACK,视为放弃。
前端代码结构和效果如下:
上述图片中的数据只是模拟消息重试,真实场景中执行频次肯定要比这个时间更久一些。
7.5.3.3)消息重复推送的问题:
如果在一定时间内没有收到ACK包,就会触发重试机制。收不到ACK的情况有两种,除了推送的消息真正丢失导致A不回ACK外,还可能是A回的ACK包本身丢了。
解决方案是:发送方在发送消息时携带一个msgid,msgid是全局唯一的,针对同一条重推的消息msgid不变,接收方根据这个唯一的msgid进行去重,这样经过去重后,对于A来说,在聊天界面是不会看到重复的消息,不影响使用体验。
7.5.3.4)保证消息不会乱序:
消息的一致性是非常重要的,在聊天过程中消息顺序不能错乱。
我们是这样考虑的:
- 1)以发送方的本地时间戳为序号,但是这样有比较大的问题,发送方的时间戳是可以被改动的,这种方式不可取;
- 2)IM网关服务是集群部署,会通过topic和seqid做为唯一索引,在接收到消息落库之前会生成seqid,客服端和用户端接收到发送消息的回执时需要根据返回的seqid(IM网关自增)进行消息排序,这种方式可取。
通过以上的分析:客服IM消息的可靠性就是通过ACK机制、重试机制、去重机制、排序机制来确保每一条消息的完整触达和准确排序。
八、消息框架的分层实现:应用层
业务侧使用的时候直接实例化SDK即可,在消息链路发布订阅中已经提到了RxJS,此时在业务侧订阅使用即可。
需要注意的是在实例化SDK的时候传递了一个filterMsgItem方法,主要是为特殊业务场景提供使用的。
就拿我们客服业务来说:有些特定消息是不需要展示到聊天页面的(比如:用户发送消息被篡改等)。当然我们在业务侧重新对数据过滤或者渲染的时候也是可以做过滤的,这样操作是没什么问题,但是没有必要,如果不从源头过滤数据,后续参与二分、倒序查找的源数据也会增加。会有一些不必要的浪费。当然也可以不添加这个参数,SDK都是全兼容的。
至此我们就完成了整个SDK的实现以及在业务侧的使用,消息发送和接收也都正常。
效果如下:
九、本文小结
自研IM SDK还是蛮有挑战的一件事情,从单纯的基于第三方SDK二次开发到自研SDK并与我们的实际业务场景相对完美的结合。
在SDK的整体设计以及和业务侧如何更完美的结合并不是一蹴而就的,都是在实际业务场景中不断积累经验,不断尝试才找到相对完美的解决方案。
这里列举一个简单的案例吧。
例如消息发送,需要考虑到断网场景下:
1)该如何进行消息显示、排序、重新发送?
2)发送失败的场景下重新发送再次失败后又该如何显示、排序?
3)弱网场景下发送消息触发重试机制该如何以最优的方式去重、排序?
4)发送消息触发敏感词该如何处理?
5)断网重连后对于发送失败和触发敏感词的消息又该如何处理?
6)如果在涉及到文件又该如何处理?
……
在自研过程中除了关注业务场景外,还调研了行业内比较好的一些Web应用在某些特殊场景的处理方式。很多优秀的方案也都只能是借鉴一些核心思想,还是要以业务为核心,真正通过技术手段解决业务痛点才是最重要的。
自研SDK收益还是非常大的,也积累了很多IM方面的经验,完成自研IM SDK也只是一个开始,后续我们将会在耗时任务、数据安全等方面持续深耕细作。
十、参考资料
[1]从零到卓越:京东客服即时通讯系统的技术架构演进历程
[2]瓜子IM智能客服系统的数据架构设计(整理自现场演讲,有配套PPT)
[3]从游击队到正规军(一):马蜂窝旅游网的IM系统架构演进之路
[4]一套高可用、易伸缩、高并发的IM群聊、单聊架构方案设计实践
[5]浅谈IM系统的架构设计
[6]简述移动端IM开发的那些坑:架构设计、通信协议和客户端
[7]一套海量在线用户的移动端IM架构设计实践分享(含详细图文)
[8]一套原创分布式即时通讯(IM)系统理论架构方案
[9]一套亿级用户的IM架构技术干货(上篇):整体架构、服务拆分等
[10]从新手到专家:如何设计一套亿级消息量的分布式IM系统
[11]企业微信的IM架构设计揭秘:消息模型、万人群、已读回执、消息撤回等
[12]阿里IM技术分享(三):闲鱼亿级IM消息系统的架构演进之路
[13]基于实践:一套百万消息量小规模IM系统技术要点总结
[14]跟着源码学IM(十):基于Netty,搭建高性能IM集群(含技术思路+源码)
[15]一套十万级TPS的IM综合消息系统的架构实践与思考
[16]直播系统聊天技术(八):vivo直播系统中IM消息模块的架构实践
[17]融云技术分享:全面揭秘亿级IM消息的可靠投递机制
(本文已同步发布于:http://www.52im.net/thread-4153-1-1.html)
关键词:
世界微动态丨得物从0到1自研客服IM系统的技术实践之路
天天看热讯:性能优化搞得好,Tomcat少不了。| 博学谷狂野架构师
世界观天下!笔记本水冷改造记录
世界球精选!创维造车:主打座舱养生续命、碰撞测试0分!真是讽刺他妈给讽刺开门
环球即时:反转!国内油价明晚大概率下跌 预计下调0.07元/升
《暗黑4》本周末开测 世界BOSS刷新时间公布
天天关注:巴奴火锅下架富硒土豆!消费者可获赠500元储值卡:领取有条件
天天热推荐:百度发布文心一言AI模型:可实现文字、图片与视频智能生成
喝的人越来越少!星巴克向中国三四线城市进军:30多一杯咖啡县城青年能爱多久
麦芒11什么时候上市的?麦芒11手机参数配置
华为电视怎么投屏?华为电视怎么下载第三方软件?
孙海洋是湖北哪里人?
鲶鱼效应是什么意思?鲶鱼效应的经典案例是什么?
首店经济是什么意思?首店经济是谁提出的?
快报:权志龙演唱会门票多少钱2020_权志龙演唱会门票多少钱
环球讯息:用图技术搞定附近好友、时空交集等 7 个典型社交网络应用
GPT-4测评,大家先别急,图片输入还没来
全球时讯:C#使用ObjectPool提高StringBuilder性能
今头条!RTX 40笔记本新品翻车?别急 先升级NVIDIA新驱动再说
每日精选:官宣!《炉石传说》被移出杭州亚运会项目:职业选手难过
环球快消息!360发布年度手机安全报告:受骗男性占七成 女性三成
天天最资讯丨800V电气架构打造 全新起亚EV9发布:二三排可面对面乘坐
扣上的安全带会自动打开?本田在美国召回近45万辆汽车
【独家焦点】虹科案例|虹科Visokio商业智能平台在疫后帮酒店业打好翻身仗!
环球今热点:python 二分法查找
环球实时:面试问题-密码
Fortran语言在线代码运行编译工具推荐
Scrapy中的response对象的属性及方法,附加mate属性的使用方法
每日短讯:强冷空气来袭!河南三门峡3月下雪:厚厚一层一夜回冬
环球要闻:爱立信CEO:印度是全球推出5G速度最快的国家之一
上映25周年纪念:3D重制版《泰坦尼克号》国内定档
真凉了!暴雪网易闹掰 《炉石传说》或被移出杭州亚运会项目
世界快看:B站投资 网红爆款:理然男士沐浴露29.9元狂促
更改 ESX 或 ESXi 主机的主机名称
每日快讯!作业DNS服务配置
NOI 2008 志愿者招募 题解 (神奇费用流)
NutUI-React 京东移动端组件库 2月份上新!欢迎使用!
传递“坚持”背后的感人力量
环球新资讯:恒生中国发布2022年ESG报告 持续提升绿色金融产品与服务质量
日本央行削减购债引发政策转向猜测 超长端日债收益率显著回升
天天精选!中银香港完成5亿绿色人民币逆回购交易
世界今日讯!预购玩家可抢先游玩:《暗黑破坏神4》已开启Beta测试预载
天天看点:8999元 联想小新Pro27 2023一体机来了:13代i9、锐炫A370M独显
苦情戏直播涉事公司被查处!央视315点名诱骗老人直播间均已被封
比降价还狠!最帅国产猎装车极氪001限时福利:数万元升级包免费选
398元烫发烫完变成3980元 商家:把头发分成10个区域 每个区域398元
Linux进程通信 | 信号
GPT-4:不了不了,这些我还做不到
每日信息:前端设计模式——迭代器模式
Django-4
每日消息!Minio架构简介
环球观焦点:女子住酒店被毒蛇咬伤 酒店拒担全责有啥能证明引热议:律师发声
世界即时:奇葩创维汽车:碰撞试验0分 开创维汽车寿命延长30岁
环球微头条丨70岁赵雅芝踏青 短裤白衫引网友惊叹:真不老女神
热点!或12万起售对刚比亚迪海豚 大众微型电动车ID.2all概念车首发
世界快报:曾引发隐私争议 谷歌眼睛正式停售:退出科技舞台
【时快讯】海报丨人民武警忠诚党
天天热议:使用旧电脑玩Linux
起底汕头赤脚踩腌菜涉事公司:成立才1年时间
天天微动态丨阿根廷游戏制作人感谢中国玩家 理解了什么是“精神阿根廷人”
全球微动态丨年轻人看不上!瓦工年收入或超25万元仍招不到人 网友感慨能秒杀多数白领
Tesseract5+OpenCV4(VS2017+win10)实现OCR识别
【全球新要闻】微微一笑很倾城里面的游戏_微微一笑很倾城里面的游戏是什么
报道:河南兄弟俩花光父亲百万死亡赔偿金打赏女主播 平台:想退款拿出依据
世界热头条丨印度计划强制要求手机厂商允许删除预装应用:印度制造还要模仿中国互联网产业
焦点日报:Tiffany被曝一钻两卖 当事人交18.6万后被告知已卖掉:网友唏嘘钻石真不值钱
焦点要闻:读Java性能权威指南(第2版)笔记18_垃圾回收E
人民网评东方甄选疑似售假:东方甄选要选真的
当前信息:养殖虾当野生虾卖 东方甄选深夜道歉:公司承担 不要攻击主播
天天热点!IDEA2022.3.2破解安装教程
每日时讯!SpringCloud Alibaba 学习圣经,10万字实现 SpringCloud 自由
天天播报:免费领取:尼恩技术圣经PDF!带你实现 微服务自由、Docker自由、K8S自由…(史上最全)
世界消息!软件中间件,你知道哪些?
世界微头条丨2023年央视315晚会一文看懂:12大消费陷阱防不胜防
针对315曝光问题 各地连夜行动:已调查免费评书机骗局、售卖水军公司等
无视4G/5G信号打电话!中国电信今年将在深圳率先部署VoWiFi
世界速看:针对央视315曝光问题 各地连夜行动!2259.8万粉丝大V瞬间被封
全球观察:iQOO回应难以删除数据:只是测试演示 问题与品牌无关
与或门常用表达式_与或门
环球热推荐:论文阅读—第一篇《ImageNet Classification with Deep Convolutional Neural Networks》
天天播报:胃食管反流病发病机制_胃食管反流病怎么调养
吴宇森执导美版《喋血双雄》主演敲定!《速激》女星出演
天天新动态:央视315揭秘恢复出厂设置:并非彻底清除手机数据
环球微动态丨央视315晚会曝光直播间苦情戏 2000多万粉丝的网红被秒封
当前视讯!16次全胜!长征十一火箭成功发射试验十九号卫星
5.9 GDT与IDT的初始化(harib02i)
环球快资讯:谈谈GPT-4模型的亮点
世界头条:ChatGPT对跟踪算法以及跟踪轨迹问题的解答
今日热讯:央视315晚会曝光直播间苦情戏:“儿子”们专骗老人、1.2元“神药”卖9.9元
全球滚动:任天堂:Switch 2将给玩家新惊喜和新玩法
即时看!央视3·15曝光:水军操盘直播间诱导跟风下单 一台手机操控2万个
day04-实现SpringBoot底层机制
焦点报道:有监督学习——支持向量机、朴素贝叶斯分类
当前动态:Windows 下 JNA 调用动态链接库 dll
Java并发小结02
【新视野】区块链技术入门教程 - Decert
热门:512GB售价8999元:雷克沙发布新款CFexpress Type-B存储卡
今日热闻!459元 腾达发布首款面板AP:10秒下载一部电影
2023央视3·15晚会第一曝 “泰国香米”竟是香精勾兑!渉事公司食品许可证已失效
快播:第130篇:BOM(window对象)