最新要闻
- 当前热点-灵感来自微信:微软计划开发一站式“超级应用”
- 环球即时看!惊险!SUV被货车顶上铁轨 火车驶来瞬间逃离
- 玩家们都嫌太贵!曝英伟达考虑将RTX 4080降价
- 世界讯息:AI生成裸照谁之过?真相恐怕和你想的不一样
- 3小时超值!《阿凡达2》电影票价普遍低于50元 IMAX版80元
- “抽烟哥”红到国外 田协紧急倡议应积极正向:全马冲进3个半小时是狠人
- 世界百事通!RTX 4080全球销售疲软:太贵了我再等等
- 《阿凡达2》伦敦首映式
- 惊险一幕!后车记录仪拍下特斯拉失控瞬间 网友分析司机被特斯拉辅助“救”两次
- 今日大雪:仲冬时节正式开始 全国大部气温回升雨雪稀少
- 每日观察!《原神》3.3版本今日上线:风元素新角色来了 还有原石可领
- 葡萄牙6-1大胜瑞士 C罗31场首发终结:加练千个西班牙点球大战仍出局 连续三届无缘8强
- 看齐QQ音乐?Apple Music新功能来了:支持iPhone、iPad唱卡拉OK
- 安兔兔11月iOS设备好评榜出炉:iPhone 14全系未上榜
- 世界今亮点!不止是中药 连花清瘟新专利来了 可用于制作口罩、内衣、防护服等
- 时讯:200元耳机降噪效果比肩2000元!贝壳王子MO3 2代上手:同价位天花板
手机
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
票房这么火爆,如何请视障人士“看”一场电影?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
- 票房这么火爆,如何请视障人士“看”一场电影?
家电
最近沉迷Redis网络模型,无法自拔!终于知道Redis为啥这么快了
1. 用户空间和内核态空间
1.1 为什么要区分用户和内核
服务器大多都采用 Linux 系统,这里我们以 Linux 为例来讲解:
ubuntu 和 Centos 都是 Linux 的发行版,发行版可以看成对 linux 包了一层壳,任何 Linux 发行版,其系统内核都是 Linux 。我们的应用都需要通过 Linux 内核与硬件交互
(相关资料图)
用户的应用,比如 redis ,mysql 等其实是没有办法去执行访问我们操作系统的硬件的,所以我们可以通过发行版的这个壳子去访问内核,再通过内核去访问计算机硬件
计算机硬件包括,如 cpu,内存,网卡等等,内核(通过寻址空间)可以操作硬件的,但是内核需要不同设备的驱动,有了这些驱动之后,内核就可以去对计算机硬件去进行 内存管理,文件系统的管理,进程的管理等等
我们想要用户的应用来访问,计算机就必须要通过对外暴露的一些接口,才能访问到,从而简介的实现对内核的操控,但是内核本身上来说也是一个应用,所以他本身也需要一些内存,cpu 等设备资源,用户应用本身也在消耗这些资源,如果不加任何限制,用户去操作随意的去操作我们的资源,就有可能导致一些冲突,甚至有可能导致我们的系统出现无法运行的问题,因此我们需要把用户和内核隔离开
1.2 进程寻址空间
进程的寻址空间划分成两部分:内核空间、用户空间
什么是寻址空间呢?我们的应用程序也好,还是内核空间也好,都是没有办法直接去物理内存的,而是通过分配一些虚拟内存映射到物理内存中,我们的内核和应用程序去访问虚拟内存的时候,就需要一个虚拟地址,这个地址是一个无符号的整数。
比如一个 32 位的操作系统,他的带宽就是 32,他的虚拟地址就是 2 的 32 次方,也就是说他寻址的范围就是 0~2 的 32 次方, 这片寻址空间对应的就是 2 的 32 个字节,就是 4GB,这个 4GB,会有 3 个 GB 分给用户空间,会有 1GB 给内核系统
在 linux 中,他们权限分成两个等级,0 和 3,用户空间只能执行受限的命令(Ring3),而且不能直接调用系统资源,必须通过内核提供的接口来访问内核空间可以执行特权命令(Ring0),调用一切系统资源,所以一般情况下,用户的操作是运行在用户空间,而内核运行的数据是在内核空间的,而有的情况下,一个应用程序需要去调用一些特权资源,去调用一些内核空间的操作,所以此时他俩需要在用户态和内核态之间进行切换。
比如:
Linux 系统为了提高 IO 效率,会在用户空间和内核空间都加入缓冲区:
- 写数据时,要把用户缓冲数据拷贝到内核缓冲区,然后写入设备
- 读数据时,要从设备读取数据到内核缓冲区,然后拷贝到用户缓冲区
针对这个操作:我们的用户在写读数据时,会去向内核态申请,想要读取内核的数据,而内核数据要去等待驱动程序从硬件上读取数据,当从磁盘上加载到数据之后,内核会将数据写入到内核的缓冲区中,然后再将数据拷贝到用户态的 buffer 中,然后再返回给应用程序,整体而言,速度慢,就是这个原因,为了加速,我们希望 read 也好,还是 wait for data 也最好都不要等待,或者时间尽量的短。
2. 网络模型
2.1 阻塞IO
- 过程 1:应用程序想要去读取数据,他是无法直接去读取磁盘数据的,他需要先到内核里边去等待内核操作硬件拿到数据,这个过程是需要等待的,等到内核从磁盘上把数据加载出来之后,再把这个数据写给用户的缓存区。
- 过程 2:如果是阻塞 IO,那么整个过程中,用户从发起读请求开始,一直到读取到数据,都是一个阻塞状态。
用户去读取数据时,会去先发起 recvform 一个命令,去尝试从内核上加载数据,如果内核没有数据,那么用户就会等待,此时内核会去从硬件上读取数据,内核读取数据之后,会把数据拷贝到用户态,并且返回 ok,整个过程,都是阻塞等待的,这就是阻塞 IO
总结如下:
顾名思义,阻塞 IO 就是两个阶段都必须阻塞等待:
阶段一:
- 用户进程尝试读取数据(比如网卡数据)
- 此时数据尚未到达,内核需要等待数据
- 此时用户进程也处于阻塞状态
阶段二:
- 数据到达并拷贝到内核缓冲区,代表已就绪
- 将内核数据拷贝到用户缓冲区
- 拷贝过程中,用户进程依然阻塞等待
- 拷贝完成,用户进程解除阻塞,处理数据
可以看到,阻塞 IO 模型中,用户进程在两个阶段都是阻塞状态。
2.2 非阻塞 IO
顾名思义,非阻塞 IO 的 recvfrom 操作会立即返回结果而不是阻塞用户进程
阶段一:
- 用户进程尝试读取数据(比如网卡数据)
- 此时数据尚未到达,内核需要等待数据
- 返回异常给用户进程
- 用户进程拿到 error 后,再次尝试读取
- 循环往复,直到数据就绪
阶段二:
- 将内核数据拷贝到用户缓冲区
- 拷贝过程中,用户进程依然阻塞等待
- 拷贝完成,用户进程解除阻塞,处理数据
- 可以看到,非阻塞 IO 模型中,用户进程在第一个阶段是非阻塞,第二个阶段是阻塞状态。虽然是非阻塞,但性能并没有得到提高。而且忙等机制会导致 CPU 空转,CPU 使用率暴增。
2.3 信号驱动
信号驱动 IO 是与内核建立 SIGIO 的信号关联并设置回调,当内核有 FD 就绪时,会发出 SIGIO 信号通知用户,期间用户应用可以执行其它业务,无需阻塞等待。
阶段一:
- 用户进程调用 sigaction ,注册信号处理函数
- 内核返回成功,开始监听 FD
- 用户进程不阻塞等待,可以执行其它业务
- 当内核数据就绪后,回调用户进程的 SIGIO 处理函数
阶段二:
- 收到 SIGIO 回调信号
- 调用 recvfrom ,读取
- 内核将数据拷贝到用户空间
- 用户进程处理数据
当有大量 IO 操作时,信号较多,SIGIO 处理函数不能及时处理可能导致信号队列溢出,而且内核空间与用户空间的频繁信号交互性能也较低。
2.4 异步 IO
这种方式,不仅仅是用户态在试图读取数据后,不阻塞,而且当内核的数据准备完成后,也不会阻塞
他会由内核将所有数据处理完成后,由内核将数据写入到用户态中,然后才算完成,所以性能极高,不会有任何阻塞,全部都由内核完成,可以看到,异步 IO 模型中,用户进程在两个阶段都是非阻塞状态。
2.5 IO 多路复用
场景引入
为了更好的理解 IO ,现在假设这样一种场景:一家餐厅
- A 情况:这家餐厅中现在只有一位服务员,并且采用客户排队点餐的方式,就像这样:
每排到一位客户要吃到饭,都要经过两个步骤:
思考要吃什么顾客开始点餐,厨师开始炒菜
由于餐厅只有一位服务员,因此一次只能服务一位客户,并且还需要等待当前客户思考出结果,这浪费了后续排队的人非常多的时间,效率极低。这就是阻塞 IO。
当然,为了缓解这种情况,老板完全可以多雇几个人,但这也会增加成本,而在极大客流量的情况下,仍然不会有很高的效率提升
- B 情况: 这家餐厅中现在只有一位服务员,并且采用客户排队点餐的方式。
每排到一位客户要吃到饭,都要经过两个步骤:
- 思考要吃什么
- 顾客开始点餐,厨师开始炒菜
与 A 情况不同的是,此时服务员会不断询问顾客:“你想吃番茄鸡蛋盖浇饭吗?那滑蛋牛肉呢?那肉末茄子呢?……”
虽然服务员在不停的问,但是在网络中,这并不会增加数据的就绪速度,主要还是等顾客自己确定。所以,这并不会提高餐厅的效率,说不定还会招来更多差评。这就是非阻塞 IO。
- C 情况: 这家餐厅中现在只有一位服务员,但是不再采用客户排队的方式,而是顾客自己获取菜单并点餐,点完后通知服务员,就像这样:
每排到一位客户要吃到饭,还是都要经过两个步骤:
- 看着菜单,思考要吃什么
- 通知服务员,我点好了
与 A B 不同的是,这种情况服务员不必再等待顾客思考吃什么,只需要在收到顾客通知后,去接收菜单就好。这样相当于餐厅在只有一个服务员的情况下,同时服务了多个人,而不像 A B,同一时刻只能服务一个人。此时餐厅的效率自然就提高了很多。
映射到我们的网络服务中,就是这样:
- 客人:客户端请求
- 点餐内容:客户端发送的实际数据
- 老板:操作系统
- 人力成本:系统资源
- 菜单:文件状态描述符。操作系统对于一个进程能够同时持有的文件状态描述符的个数是有限制的,在 linux 系统中 $ulimit -n 查看这个限制值,当然也是可以 (并且应该) 进行内核参数调整的。
- 服务员:操作系统内核用于 IO 操作的线程 (内核线程)
- 厨师:应用程序线程 (当然厨房就是应用程序进程咯)
- 餐单传递方式:包括了阻塞式和非阻塞式两种。
- 方法 A: 阻塞 IO
- 方法 B: 非阻塞 IO
- 方法 C: 多路复用 IO
2.6 多路复用 IO 的实现
目前流程的多路复用 IO 实现主要包括四种: select、poll、epoll、kqueue。下表是他们的一些重要特性的比较:
IO 模型 | 相对性能 | 关键思路 | 操作系统 | JAVA 支持情况 |
---|---|---|---|---|
select | 较高 | Reactor | windows/Linux | 支持,Reactor 模式 (反应器设计模式)。Linux 操作系统的 kernels 2.4 内核版本之前,默认使用 select;而目前 windows 下对同步 IO 的支持,都是 select 模型 |
poll | 较高 | Reactor | Linux | Linux 下的 JAVA NIO 框架,Linux kernels 2.6 内核版本之前使用 poll 进行支持。也是使用的 Reactor 模式 |
epoll | 高 | Reactor/Proactor | Linux | Linux kernels 2.6 内核版本及以后使用 epoll 进行支持;Linux kernels 2.6 内核版本之前使用 poll 进行支持;另外一定注意,由于 Linux 下没有 Windows 下的 IOCP 技术提供真正的 异步 IO 支持,所以 Linux 下使用 epoll 模拟异步 IO |
kqueue | 高 | Proactor | Linux | 目前 JAVA 的版本不支持 |
多路复用 IO 技术最适用的是 “高并发” 场景,所谓高并发是指 1 毫秒内至少同时有上千个连接请求准备好。其他情况下多路复用 IO 技术发挥不出来它的优势。另一方面,使用 JAVA NIO 进行功能实现,相对于传统的 Socket 套接字实现要复杂一些,所以实际应用中,需要根据自己的业务需求进行技术选择。
2.6.1 select
select 是 Linux 最早是由的 I/O 多路复用技术:
linux 中,一切皆文件,socket 也不例外,我们把需要处理的数据封装成 FD,然后在用户态时创建一个 fd_set 的集合(这个集合的大小是要监听的那个 FD 的最大值 + 1,但是大小整体是有限制的 ),这个集合的长度大小是有限制的,同时在这个集合中,标明出来我们要控制哪些数据。
其内部流程:
用户态下:
- 创建 fd_set 集合,包括要监听的 读事件、写事件、异常事件 的集合
- 确定要监听的 fd_set 集合
- 将要监听的集合作为参数传入 select () 函数中,select 中会将 集合复制到内核 buffer 中
内核态:
- 内核线程在得到 集合后,遍历该集合
- 没数据就绪,就休眠
- 当数据来时,线程被唤醒,然后再次遍历集合,标记就绪的 fd 然后将整个集合,复制回用户 buffer 中
- 用户线程遍历 集合,找到就绪的 fd ,再发起读请求。
不足之处:
- 集合大小固定为 1024 ,也就是说最多维持 1024 个 socket,在海量数据下,不够用
- 集合需要在 用户 buffer 和内核 buffer 中反复复制,涉及到 用户态和内核态的切换,非常影响性能
2.6.2 poll
poll 模式对 select 模式做了简单改进,但性能提升不明显。
IO 流程:
- 创建 pollfd 数组,向其中添加关注的 fd 信息,数组大小自定义
- 调用 poll 函数,将 pollfd 数组拷贝到内核空间,转链表存储,无上限
- 内核遍历 fd ,判断是否就绪
- 数据就绪或超时后,拷贝 pollfd 数组到用户空间,返回就绪 fd 数量 n
- 用户进程判断 n 是否大于 0, 大于 0 则遍历 pollfd 数组,找到就绪的 fd
与 select 对比:
- select 模式中的 fd_set 大小固定为 1024,而 pollfd 在内核中采用链表,理论上无上限,但实际上不能这么做,因为的监听 FD 越多,每次遍历消耗时间也越久,性能反而会下降
2.6.3 epoll
epoll 模式是对 select 和 poll 的改进,它提供了三个函数:eventpoll 、epoll_ctl 、epoll_wait
- eventpoll 函数内部包含了两个东西 :
- 红黑树 :用来记录所有的 fd
- 链表 : 记录已就绪的 fd
- epoll_ctl 函数 ,将要监听的 fd 添加到 红黑树 上去,并且给每个 fd 绑定一个监听函数,当 fd 就绪时就会被触发,这个监听函数的操作就是 将这个 fd 添加到 链表中去。
- epoll_wait 函数,就绪等待。一开始,用户态 buffer 中创建一个空的 events 数组,当就绪之后,我们的回调函数会把 fd 添加到链表中去,当函数被调用的时候,会去检查链表(当然这个过程需要参考配置的等待时间,可以等一定时间,也可以一直等),如果链表中没有有 fd 则 fd 会从红黑树被添加到链表中,此时再将链表中的的 fd 复制到 用户态的空 events 中,并且返回对应的操作数量,用户态此时收到响应后,会从 events 中拿到已经准备好的数据,在调用 读方法 去拿数据。
2.6.4 总结:
select 模式存在的三个问题:
- 能监听的 FD 最大不超过 1024
- 每次 select 都需要把所有要监听的 FD 都拷贝到内核空间
- 每次都要遍历所有 FD 来判断就绪状态
poll 模式的问题:
- poll 利用链表解决了 select 中监听 FD 上限的问题,但依然要遍历所有 FD,如果监听较多,性能会下降
epoll 模式中如何解决这些问题的?
- 基于 epoll 实例中的红黑树保存要监听的 FD,理论上无上限,而且增删改查效率都非常高
- 每个 FD 只需要执行一次 epoll_ctl 添加到红黑树,以后每次 epol_wait 无需传递任何参数,无需重复拷贝 FD 到内核空间
- 利用 ep_poll_callback 机制来监听 FD 状态,无需遍历所有 FD,因此性能不会随监听的 FD 数量增多而下降
2.7 基于 epoll 的服务器端流程
一张图搞定:
我们来梳理一下这张图
- 服务器启动以后,服务端会去调用 epoll_create,创建一个 epoll 实例,epoll 实例中包含两个数据
红黑树(为空):rb_root 用来去记录需要被监听的 FD
链表(为空):list_head,用来存放已经就绪的 FD
创建好了之后,会去调用 epoll_ctl 函数,此函数会会将需要监听的 fd 添加到 rb_root 中去,并且对当前这些存在于红黑树的节点设置回调函数。
当这些被监听的 fd 一旦准备就绪,与之相关联的回调函数就会被调用,而调用的结果就是将红黑树的 fd 添加到 list_head 中去 (但是此时并没有完成)
fd 添加完成后,就会调用 epoll_wait 函数,这个函数会去校验是否有 fd 准备就绪(因为 fd 一旦准备就绪,就会被回调函数添加到 list_head 中),在等待了一段时间 (可以进行配置)。
如果等够了超时时间,则返回没有数据,如果有,则进一步判断当前是什么事件,如果是建立连接事件,则调用 accept () 接受客户端 socket ,拿到建立连接的 socket ,然后建立起来连接,如果是其他事件,则把数据进行写出。
2.8 五种网络模型对比:
最后用一幅图,来说明他们之间的区别
3. redis 通信协议
3.1 RESP 协议
Redis 是一个 CS 架构的软件,通信一般分两步(不包括 pipeline 和 PubSub):
- 客户端(client)向服务端(server)发送一条命令,服务端解析并执行命令
- 返回响应结果给客户端,因此客户端发送命令的格式、服务端响应结果的格式必须有一个规范,这个规范就是通信协议。
而在 Redis 中采用的是 RESP(Redis Serialization Protocol)协议:
- Redis 1.2 版本引入了 RESP 协议
- Redis 2.0 版本中成为与 Redis 服务端通信的标准,称为 RESP2
- Redis 6.0 版本中,从 RESP2 升级到了 RESP3 协议,增加了更多数据类型并且支持 6.0 的新特性–客户端缓存
但目前,默认使用的依然是 RESP2 协议。在 RESP 中,通过首字节的字符来区分不同数据类型,常用的数据类型包括 5 种:
- 单行字符串:首字节是 ‘+’ ,后面跟上单行字符串,以 CRLF( “\r\n” )结尾。例如返回”OK”: “+OK\r\n”
- 错误(Errors):首字节是 ‘-’ ,与单行字符串格式一样,只是字符串是异常信息,例如:”-Error message\r\n”
- 数值:首字节是 ‘:’ ,后面跟上数字格式的字符串,以 CRLF 结尾。例如:”:10\r\n”
- 多行字符串:首字节是 ‘$’ ,表示二进制安全的字符串,最大支持 512MB:
- 如果大小为 0,则代表空字符串:”$0\r\n\r\n”
- 如果大小为 - 1,则代表不存在:”$-1\r\n”
- 数组:首字节是 ‘*’,后面跟上数组元素个数,再跟上元素,元素数据类型不限 :
本文由
传智教育博学谷
教研团队发布。如果本文对您有帮助,欢迎
关注
和点赞
;如果您有任何建议也可留言评论
或私信
,您的支持是我坚持创作的动力。转载请注明出处!
最近沉迷Redis网络模型,无法自拔!终于知道Redis为啥这么快了
热点聚焦:行为管理(锐捷行业网关篇)
全球时讯:文盘Rust -- r2d2 实现redis连接池
前端精准测试实践
世界速递!JavaScript中 FileReader 对象详解
【世界报资讯】大数据-数据仓库-实时数仓架构分析
热头条丨JAVA8 函数式编程(1)- Lambda表达式
易基因|m6A去甲基化酶ALKBH5通过降低PHF20 mRNA甲基化抑制结直肠癌进展 | 肿瘤研究
焦点日报:火山引擎 DataTester:如何用 A/B 测试做产品增长?
WTM+InfluxDB时序数据库数据查询并放到DataTable中
中科慧政 & JNPF :全面开启智慧政务,灵活满足政务办公需求
【焦点热闻】南墙WAF-最好的免费Web应用防火墙
天天关注:高光时刻 | 方正璞华联合开发的「人力资源法律服务共享平台」在创新创业大赛中获奖
全球新消息丨95年属猪的2019年运势
【环球热闻】绳责的意思(绳责)
天天动态:水滴筹标题范文(水滴筹标题怎么写)
今头条!应用昆虫学(应用昆虫学报)
环球头条:工厂找哪个网站?
焦点信息:促排卵期间注意哪些事项(促排卵期间注意事项)
天天资讯:越南旅游签证办理流程及费用(越南旅游签证办理流程)
全球快报:空鼻症是什么样(空鼻症是什么病)
【天天新视野】电脑桌面怎么恢复到原来的样子(电脑桌面怎么恢复到原来的样子)
每日信息:闲鱼卖二手
微资讯!西藏万隆虫草鹿鞭王
环球观焦点:77电玩城(77dizhi)
热头条丨低温性能革命性进步!宁德时代:钠电池有望装车500公里续航车型
当前播报:非典是哪一年一共死多少人(非典是哪一年)
天天热讯:空调显示屏上显示df是什么意思(空调运行中显示屏出现字母df是什么意思)
全球报道:我国现存新能源汽车相关企业56.8万家,仅2021年新增17万家
全球要闻:日本电子巨头罗姆将量产下一代半导体:提高用电效率、增加电动车续航里程
环球今日报丨传感器和处理器如何打造更智能、更自主的机器人?
世界即时:如何实现工业自动化?传感器对于工业自动化有什么样的意义
天天新动态:工业自动化如何实现?
当前焦点!使用cpolar(内网穿透)最低成本搭建网站
如何在Windows AD域中驻留ACL后门
当前热点-灵感来自微信:微软计划开发一站式“超级应用”
环球即时看!惊险!SUV被货车顶上铁轨 火车驶来瞬间逃离
玩家们都嫌太贵!曝英伟达考虑将RTX 4080降价
世界讯息:AI生成裸照谁之过?真相恐怕和你想的不一样
3小时超值!《阿凡达2》电影票价普遍低于50元 IMAX版80元
Redis 的 keys 命令你知道有多慢吗?
“抽烟哥”红到国外 田协紧急倡议应积极正向:全马冲进3个半小时是狠人
世界百事通!RTX 4080全球销售疲软:太贵了我再等等
《阿凡达2》伦敦首映式
惊险一幕!后车记录仪拍下特斯拉失控瞬间 网友分析司机被特斯拉辅助“救”两次
今日大雪:仲冬时节正式开始 全国大部气温回升雨雪稀少
每日观察!《原神》3.3版本今日上线:风元素新角色来了 还有原石可领
葡萄牙6-1大胜瑞士 C罗31场首发终结:加练千个西班牙点球大战仍出局 连续三届无缘8强
看齐QQ音乐?Apple Music新功能来了:支持iPhone、iPad唱卡拉OK
安兔兔11月iOS设备好评榜出炉:iPhone 14全系未上榜
SpringBoot构建RESTful风格应用
环球速讯:Kubernetes单机创建MySQL+Tomcat演示程序:《Kubernetes权威指南》第一章demo报错踩坑
全球最新:npm或者yarn安装sharp太慢、失败等问题
世界今亮点!不止是中药 连花清瘟新专利来了 可用于制作口罩、内衣、防护服等
时讯:200元耳机降噪效果比肩2000元!贝壳王子MO3 2代上手:同价位天花板
全国单日票房一度超4000万元:《阿凡达2》万众期待
热门:快升级5G!明年4G网速体验更糟糕:原因很无解
54年了!波音747飞机正式停产 一记录保持37年
焦点播报:MAUI新生3.4-深入理解XAML:数据模板DataTemplate
环球观热点:生成器函数
当前视点!Kubernetes configmap 笔记
画家要失业了?PS母公司Adobe开卖AI图片:侵权赔偿也自己扛
为什么海底火山不会被海水浇灭?
Javascript-极速入门指南-2-BOM与DOM操作-jQuery简介
54个CSS重难点整理,12-24篇,进阶高薪必需要掌握的知识点
国产CPU与国产OS联合 阿里平头哥加入openKylin社区
男子iPhone 13 Pro不到三个月自燃 法院:商品不符合质量要求 可以换新
全球热点!java创建线程的唯一方式
第一百一十篇:内存泄漏和垃圾回收(JS)
新资讯:《阿凡达2》获知名制作人小岛秀夫好评点赞:能够让人焕发激情
当前滚动:进军PC配件!一加将推出旗下首款机械键盘
《巫师3》次时代版“史诗升级”:官方Mod工具终于来了
AMD RX 7900又一非公卡亮相:档次上去了
每日热文:女子被绑浇墨汁?官方:自导自演 直播网红为赚流量博人眼球将严惩
left jon连接查询踩坑记
全球观热点:AMD RX 7900首批供货非常紧张!某品牌明年才能有
环球讯息:约4.1万人民币 法国一公司推出氢能电动自行车:像是助力车
环球焦点!一加11渲染图被网友恶搞:辨识度拉满
中国超越德国成全球第二大出口国!比亚迪自建船队引关注
世界快看点丨福建一景区回应多人推山顶“风动石”:重几十吨 风能吹动人推不动它
天天微头条丨没开发人员,接到开发物联网系统的活儿,干不干?
当前快讯:大笔加码越南!三星电子和LG将追加投资数十亿美元建厂
世界观点:惊了!研究发现蚂蚁竟也产奶 难道它也是哺乳动物?
1.7米长 从头裹到脚:洁丽雅加厚加大浴巾29元抄底
天天快播:“售后、周转、维护” 电动自行车换电池“三不要”
环球微动态丨移动端硬件实时光追落地!第二代骁龙8让游戏画面更逼真
快讯:全同态加密是否完美?
力扣刷题03
热门看点:MySQ 8.0 推出直方图,性能大大提升!
记录--uniapp自定义相机 自定义界面拍照录像闪光灯切换摄像头
世界视点!浙里办单点登陆、令牌获取用户信息
【全球热闻】iOS开发证书发布证书,推送证书,描述文件的生成总集(一)
世界今热点:AirPods Pro 2立大功!苹果占据31%真无线耳机市场
天天热议:网友吐槽买瓶饮料都要下载APP 网友:是我我扭头就走
全球热点!Chrome更新置顶横幅通知:明确不再支持Win7/8.1平台
环球速看:价格屠夫 小米4K双99%色域专业显示器2399元(首发3499)
天天快播:日本队更衣室留千纸鹤表感谢!国际足联再感谢日本球迷清理看台引热议 高素质
世界快讯:日产回应车机更新显示文案待定:车联网激活才可正常使用
手机端光追将至:Basemark推出首个移动设备光追基准测试
奇瑞汽车站起来了!连续6月销量超10万 破百万辆大关