Redis执行用户命令的过程,你了解过吗!

Redis执行用户命令的过程,居然是这样的! Redis想必每一个后端人员都是非常熟悉,在我日常的开发中,基本上使用Redis作为缓存中间件,而且使用Redis让我们完成很多需求、解决了不少业务问题,这里问个问题看看你会怎么答?Redis怎么执行命令的呢?面对这个问题想必大部分朋友心里的答案是:客户端发送命令给到服务端,服务端收到执行之后再处理将命令执行结果返回给客户端,简单来说如下图:那么具体的更细节呢过程?继续追问的话,能回答上来的还是比较少的,可能跟我之前一样无法表述出来,或者根本没深入了解学习过。 阅读详情

前言

Redis想必每一个后端人员都是非常熟悉,在我日常的开发中,基本上使用Redis作为缓存中间件,而且使用Redis让我们完成很多需求、解决了不少业务问题,这里问个问题看看你会怎么答?

Redis怎么执行命令的呢?

面对这个问题想必大部分朋友心里的答案是:客户端发送命令给到服务端,服务端收到执行之后再处理将命令执行结果返回给客户端,简单来说如下图:

那么具体的更细节呢过程?

继续追问的话,能回答上来的还是比较少的,可能跟我之前一样无法表述出来,或者根本没深入了解学习过。

但是从今天开始我们讲能轻松应对,今天的文章将会深入Redis到底是如何执行我们输入的命令的,看了本文肯定能对你进阶学习Redis有很大的帮助!无论从面试角度,还是积累知识厚度方面都能有一个全面的认识。

有兴趣的同学可以看看之前关于MySQL的Select、Update执行过程的文章,做个知识积累。

小许code:一条Update语句的执行过程是怎样的?15 赞同 · 1 评论文章!

分享文章内容前,老规矩,贴个文章大纲给大家,提前了解要讲的知识点。

📚 全文字数 : 5k+

⏳ 阅读时长 : 7min

📢 关键词 : Redis 、Socket、RESP协议、I/O多路复用

命令执行流程

在Redis中有两个重要的角色,一个是客户端Client,一个是服务器Server。而且它们是一对多的关系,也就是说Server会保存每个与之相连接的Client的状态信息。

我们一起看看一条Redis操作命令从客户端发送到服务器如何接受、处理并返回的具体实现。

启动建立连接

我们先看Redis服务端的启动,这也是客户端能建立连接的前提。

Redis服务器启动后,需要经过一些列的初始化及配置的设置,比如状态参数、用户配置、初始化数据结构等,主要包括下面这些。

Redis 客户端和服务器端是基于 socket 通信的,服务器端在初始化时会创建了一个 socket 监听,用于监听接客户端的 socket 连接

了解过源码的都知道,在 【redis.h/redisServer】 中redisServer结构体存储Redis服务器的所有信息,包括但不限于数据库、配置参数、命令表、监听端口与地址、客户端列表、若干统计信息、RDB与AOF持久化相关信息、主从复制相关信息、集群相关信息等。

而客户端连接服务器之前需要创建socket(一套固定的模式),然后根据设定的IP和端口号与服务器进行连接。

这里有个重要的知识点:在通过网络与redis服务器连接的普通客户端和lua脚本的客户端,服务器都会创建相对应的client 结构,用于记录他们的状态信息。

//客户端在redisServer结构中的属性
struct redisServer {
    ...
    // 存放普通客户端的列表
    list *clients;   /* List of active clients */
    // 存放lua脚本客户端
    client *lua_client;    /* The "fake client" to query Redis from Lua */
    ...
};

Redis客户端其实有三种类型:1:负责执行Lua脚本的伪客户端,2:用来加载aof文件的伪客户端,3:通过网络连接的普通客户端

到这里Redis客户端和服务端就完成连接,接下来继续看到底如何传输执行用户指令的!

客户端发送命令

当用户在客户端输入一条执行命令时,客户端会将这个命令请求转换成Redis相关的通信协议格式,然后通过连接到服务器的套接字,将协议格式的命令请求发送给服务器。

Redis 通讯协议(RESP 协议,REdis Serialization Protocol)

比如我们输入 set xkey xiaoxu 命令会转换成如下格式:

看看转换后的格式注释,就知道各部分代表什么意思了

*3        //参数个数是*开头,3个参数
$3        //参数长度是$开头,命令长度
SET       //命令名称SET
$4        //参数长度是$开头,key长度
xkey      //key的内容
$6        //参数长度是$开头,value长度
xiaoxu      //value内容
参数个数是*开头,参数长度是$开头,每个参数通过\r\n隔开
回复协议格式:
* 状态回复(status reply)的第一个字节是 “+”,如:+ok\r\n
* 错误回复(error reply)的第一个字节是 “-“,如:-ERR unknown command xxx\r\n

服务端读取命令

通过连接套接字让客户端的写入而变得可读,服务端将读取协议内容,并存储到客户端的缓冲区,这里的缓冲区是client结构的输入缓冲区。

我们了解到每个连接到服务端的客户端,会保存在redisServer结构体中的clients链表中

typedef struct client {
    ...
    // 客户端状态的输入缓冲区,保存客户端的命令请求
    sds querybuf;           /* Buffer we use to accumulate client queries. */
    // 下面这两个是解析出来的命令和参数
    int argc;               /* Num of arguments of current command. */
    robj **argv;            /* Arguments of current command. */
    // 一个是根据argv[0]解析出来的命令,一个是最后一次执行的命令
    struct redisCommand *cmd, *lastcmd;  /* Last command executed. */
    ...
} 

接着会对输入缓冲区中的命令请求进行分析,提取解析出命令请求中包含的命令参数,以及命令参数的个数,然后分别将参数和参数个数保存到客户端状态的argv属性和argc属性里面。

关于插播个Socket小知识!这回事

每个 socket 被创建后,会分配两个缓冲区,输入 (发送)缓冲区和输出 (接收)缓冲区。在执行 send 之后,数据只是拷贝到了socket输入缓冲区,而什么时候向网络中输出,是由操作系统安排决定的。 一旦将数据写入到缓冲区,函数就可以成功返回,在识别到是 TCP协议后,再由 TCP 协议将数据从缓冲区一路发送到目标机器。 读取函数也是如此,它也是从输入缓冲区中读取数据,而不是直接从网络中读取。 注意:数据有可能刚被写入缓冲区就发送到网络,也可能在缓冲区中不断积压,多次写入的数据被一次性发送到网络,这取决于当时的网络情况、当前线程是否空闲等诸多因素,不由程序员控制

服务端处理执行命令

恭喜你,看到这里,你已经知道用户的操作命令令怎么传输和服务端怎么获取到指令了!继续往下看

查找命令

命令执行器根据客户端状态的argv[0]参数,在命令表中查找参数所指定的命令,本文中的argv[0]参数就是 set ,找到命令后保存到客户端状态的cmd属性。

命令表:其实就是一个字典,字典的键是命令名称,比如"set"、“get”、“del”;而值则是一个个redisCommand结构,每个redisCommand结构记录了一个Redis命令的实现信息。

上图中:

SET命令的名字为"set",实现函数为setCommand;命令的参数个数为-3,表示命令接受三个或以上数量的参数;命令的标识为"wm",表示SET命令是一个写入命令。

GET命令的名字为 “get”,实现函数为getCommand函数;命令的参数个数为2,表示命令只接受两个参数;命令的标识为"r",表示这是一个只读命令。

执行准备:参数、权限、内存校验

获得了执行需要的命令、参数后,服务器还需要做一些校验:

命令校验:检查客户端状态的cmd指针是否指向NULL。

参数校验:根据客户端cmd属性指向的redisCommand结构的arity属性,检查命令请求所给定的参数个数是否正确。

权限校验:检查客户端是否已经通过了身份验证,未通过身份验证的客户端只能执行AUTH命令。

内存检测:如果服务器打开了maxmemory功能,那么在执行命令之前,先检查服务器的内存占用情况,并在有需要时进行内存回收,从而使得接下来的命令可以顺利执行

其他校验…

调用命令实现函数

服务器将要执行命令的实现保存到了客户端状态的cmd属性里面,并将命令的参数和参数个数分别保存到了客户端状态的argv属性和argv属性里面,当服务器执行命令时,只需要一个指向客户端状态的指针作为参数,调用实际执行函数。

被调用的命令实现函数会执行指定的操作,并产生相应的命令回复,这些回复会被保存在客户端状态的输出缓冲区里面(buf属性和reply属性),之后实现函数还会为客户端的套接字关联命令回复处理器,这个处理器负责将命令回复返回给客户端

后续:命令、参数、AOF

执行完毕后,会有一些后续操作,包括慢日志记录、redisCommand结构属性更新、AOF持久化记录、主从复制命令传播等。

回复消息给客户端

命令实现函数会将命令回复保存到客户端的输出缓冲区里面,并为客户端的套接字关联命令回复处理器,当客户端套接字变为可写状态时,服务器就会执行命令回复处理器,将保存在客户端输出缓冲区中的命令回复发送给客户端。

发送完毕后,回复处理器会清空客户端状态的输出缓冲区,为下一个命令请求做好准备。

当客户端接收到协议格式的命令回复之后,它会将这些回复转换成人类可读的格式,并打印给用户观看。

比如之前的 set xkey xiaoxu,服务器发送的 “+OK\r\n”,通过协议转换成 “OK\n”

redis > set xkey xiaoxu
OK

ok,到这里其实整个发送命令和接收回复的流程就完成了,大家可以通过下图,加深下印象!

事件和IO模型

事件机制

Redis服务器是一个事件驱动程序,它主要处理以下两种事件。

文件事件(file event):利用I/O复用机制,监听Socket等文件描述符上发生的事件,这类事件主要由客户端(或其他Redis服务器)发送网络请求触发,根据不同执行的任务来为套接字关联不同的事件处理器。

时间事件(time event):定时触发的事件,负责完成redis内部定时任务,如生成RDB文件、清除过期数据等

文件事件为不同的套接字关联了不同的处理器,组成部分分别是:套接字、I/O多路复用程序、文件事件分派器(dispatcher),文件事件处理器。

我们主要看下文件事件,它跟文章内容息息相关。

Redis 客户端与 Redis 服务端建立连接,发送命令,Redis 服务器响应命令都是需要通过事件机制。

AE_READABLE 事件:客户端与 Redis 服务器发起建立连接,监听套接字产生 AE_READABLE 事件。

AE_WRITEABLE 事件:响应客户端操作完成后,将产生 socket 的 AE_WRITEABLE 事件,命令回复处理器完成处理后,将解除 AE_WRITEABLE 事件与命令恢复处理器的关联。

I/O多路复用

I/O多路复用机制主要是为了减少线程切换带来的开销,同时也避免了 I/O 阻塞操作,从而大大提高了 Redis 的运行效率。

IO多路复用程序会同时监听多个socket,当被监听的socket准备好执行accept、read、write、close等操作时,与这些操作相对应的文件事件就会产生。

IO多路复用程序会把所有产生事件的socket压入一个队列中,然后有序地每次仅分配其中的一个socket发送给文件事件分派器,

文件事件分派器接收到socket之后会根据socket产生的事件类型调用对应的事件处理器进行处理。

总结

我们知道了一条Redis命令请求从发送到完成的步骤,答题如下:

  1. Redis客户端发送命令请求到服务器
  2. 服务器读取命令请求,解析命令参数
  3. 命令执行器根据命令参数查找命令的实际实现函数,然后执行,接着回复执行结果给客户端

服务器的Server结构使用Clients链表来链接多个客户端的状态,包括我们的输入请求和输出结果、解析的命令参数等。

同样我们也了解了Socket简单知识

好了,今天关于Redis命令的执行过程就分享到这!希望大家喜欢!

文末安利一波:

欢迎朋友们关注我的同名公众号📢📢:【小许code】,等你哦!🤣🤣

欢迎点赞 👍、收藏 💙、关注 💡 三连支持一下~🎈

🎈知道的越多,不知道的也越多,我是小许,下期见~🙇💻

参考:

《Redis设计与实现》

从redis原理的角度认知Set命令的执行过程 本篇文章主要讲解 ,同样会附带了解下面几个问题为了了解redis请求流程,首先先了解下redis的网络模型。redis 支持 4中网络模式, select、poll、epoll、kqueue ,其中epoll 模型我个人认为是应用最广泛的模型,所以本篇文章以epoll 模型为 demo 进行讲解。 阅读详情

相关推荐

《Redis设计与实现》读书笔记-一条命令执行过程

一个命令请求从发送到获得回复的过程中,客户端和服务器需要完成一系列操作。举个例子,如果我们使用客户端执行以下命令:OK那么从客户端发送 SET KEY VALUE 命令到获得回复OK 期间,客户端和服务器共需要1)客户端向服务器发送命令请求 SET KEY VALUE。2)服务器接收并处理客户端发来的命令请求 SET KEY VALUE,在数据库中进行设置操作,并产生命令回复OK。3)服务器将命令回复 OK 发送给客户端。4)客户端接收服务器返回的命令回复OK,并将这个回复打印给用户观看。

逆行者 1117

redis——命令请求的执行过程

发送命令请求 当用户在客户端中键入一个命令请求时, 客户端会将这个命令请求转换成协议格式, 然后通过连接到服务器的套接字, 将协议格式的命令请求发送给服务器。 读取命令请求 当客户端与服务器之间的连接套接字因为客户端的写入而变得可读时, 服务器将调用命令请求处理器来执行以下操作: 读取套接字中协议格式的命令请求, 并将其保存到客户端状态的输入缓冲区里面。 对输入缓冲区中的命令请求进行分析...

少说,多做。 4241

Redis——Redis命令执行原理

当问到一些面试者:Redis 是如何执行的?收到的答案往往是:客户端发命令给服务器端,服务端收到执行之后再返回给客户端。然而对于执行细节却避而不谈,当继续追问服务器端是如何执行的?能回答上来的人更是寥寥无几。

庄小焱 1964

化繁为简,批量执行Redis命令的4种方式!

在我们的印象中Redis命令好像都是一个个单条进行执行的,如果有人问你如何批量执行Redis命令,你能回答的上吗,或者说能答出几种方式呢?最容易想到的是Redis的一些批量命令,例如MGET今天小许就这个问题给大家总结一下!

m0_46995061的博客 1344

Auto.js实战:从解锁手机到自动阅读的全流程避坑指南(MIUI系统适配版)

本文详细介绍了Auto.js在MIUI系统下的自动化操作全流程优化指南,包括设备唤醒、应用启动、界面交互等关键环节的实战技巧。特别针对MIUI系统的变速检测机制和电源管理策略,提供了有效的避坑方案和性能优化建议,帮助开发者实现从解锁手机到自动阅读的稳定运行。

醉三国 246

madgwick算法基于MPU9250姿态融合漂移问题的原因

基于MPU9250的madgwick算法姿态漂移问题原因 0、声明 因为这个是现象是不是共性目前本人还没研究过,只是在个体问题研究的基础上得出的结论,或许我买到的MPU9250是一个盗版:),所以只具备参考性。 1、现象 使用MPU9250的加速度计、角速度计、磁力计(AK8963)原始数据输入到madgwick算法中,得到的姿态最终会在停止姿态变化后仍然漂移一小段时间。其中加速度计和角速度计读取速率为400hz,磁力计为100hz,加速度计采样范围±2g,角速度计采样范...

GreedyZombie的博客 3872

redis系列三:redis命令的执行过程

redis命令的执行过程

HK_KIKY的博客 2628

电荷灵敏前置放大器噪声优化策略:从理论到实践

本文深入探讨了电荷灵敏前置放大器的噪声优化策略,从理论分析到实践应用。文章系统解析了并联电流噪声与串联电压噪声的来源,并引入噪声等效原理与“冷电容”模型作为统一分析工具。通过详解a、b、c三类噪声的频谱特性,为实战优化提供了清晰指导。核心策略包括选用高跨导、低漏电流FET,优化静态工作点,采用共源-共基结构,精心设计反馈网络,以及实施严格的PCB布局、屏蔽与接地,旨在全面提升微弱信号检测系统的信噪比。

weixin_29292431的博客 467

深入Redis命令的执行过程

深入Redis命令的执行过程 Redis 服务器: Redis 服务器实现与多个客户端的连接,并处理这些客户端发送过来的请求,同时保存客户端执行命令所产生的数据到数据库中。Redis 服务器依靠资源管理器来维持自身的运转,其主要作用是管理 Redis 服务。 服务器处理命令的过程 我们向客户端发送了一条命令:SET city〝beijing〝 第一步 用户将命令 SET city〝beijing...

weixin_31323635的博客 1002

simulink的Sine Wave 模块详解

模块是 Simulink 中的一个信号源模块,用于生成正弦波信号。该模块可以根据设定的幅值、频率、相位和偏移量,在仿真过程中产生周期性的正弦波形。模块都能提供强有力的支持。通过深入了解其参数的影响及结合 MATLAB 脚本的应用,读者可以更加有效地利用这一模块进行仿真和研究。此外,通过实际应用场景的扩展以及常见问题解答部分的帮助,能够更好地掌握。模块是一个非常实用的工具,适用于需要生成正弦波信号的各种场景。模块的参数,可以进一步增强学习体验。模块参数的影响,下面我们将详细探讨每个参数如何影响仿真结果。

xiaoheshang_123的博客 1052

Android软键盘系统深度解析:架构、原理与实现

Android软键盘系统深度解析:架构与实现原理 本文系统剖析了Android软键盘的核心工作机制。作为系统级输入服务,软键盘具有双重属性:既是可安装的独立应用,又深度集成于系统框架中。文章详细解读了软键盘的系统架构,包括其与InputMethodManagerService(IMMS)和WindowManagerService(WMS)的交互机制,以及通过InputConnection实现的跨进程通信流程。同时分析了输入法窗口的特殊管理策略、布局调整模式,并深入探讨了输入预测引擎的实现原理,包括词典加载、

保持专注,保持热爱 115

Redis 实战之命令请求的执行过程

一个命令请求从发送到完成主要包括以下步骤: 1. 客户端将命令请求发送给服务器;2. 服务器读取命令请求,并分析出命令参数;3. 命令执行器根据参数查找命令的实现函数,然后执行实现函数并得出命令回复;4. 服务器将命令回复返回给客户端。serverCron 函数默认每隔 100 毫秒执行一次, 它的工作主要包括更新服务器状态信息, 处理服务器接收的 SIGTERM 信号, 管理客户端资源和数据库状态, 检查并执行持久化操作, 等等。

奔走的蚂蚁的博客 1295

手把手教你双目测距理论及生成视差图,深度图,点云图像

Stereo Vision, 也叫双目立体视觉,它的研究可以帮助我们更好的理解人类的双眼是如何进行深度感知的。双目视觉在许多领域得到了应用,例如城市三维重建、3D模型构建(如kinect fusion)、视角合成、3D跟踪、机器人导航(自动驾驶)、人类运动捕捉(Microsoft Kinect)等等。双目测距也属于双目立体视觉的一个应用领域,双目测距的基本原理主要是三角测量原理,即通过视差来判定物体的远近。

qq_53545309的博客 2280

redis命令请求的执行过程

一个命令请求从发送到获得回复的过程中,客户端和服务器需要完成一系列操作。举个例子,如果我们使用客户端执行以下命令: 那么从客户端发送SET KEY VALUE命令到获得回复OK期间,客户端和服务器共需要执行以下操作: 1)客户端向服务器发送命令请求SET KEY VALUE。 2)服务器接收并处理客户端发来的命令请求SET KEY VALUE,在数据库中进行设置操作,并产生命令回复OK。...

奔跑的海星的博客 1120

Python爬虫实战:使用Scrapy+Playwright高效爬取全球专利数据库

本文将详细介绍如何使用Python最新技术栈(Scrapy+Playwright)构建一个高效的专利数据库爬虫系统。我们将从爬虫基础知识讲起,逐步深入到反爬应对策略、分布式爬虫架构以及数据存储方案,最终实现一个完整的专利数据采集系统。专利数据是技术创新领域的重要信息资源,包含技术描述、权利要求、申请人信息等宝贵数据。中国国家知识产权局(CNIPA)美国专利商标局(USPTO)欧洲专利局(EPO)世界知识产权组织(WIPO)

2201_76125261的博客 1384

使用MATLAB进行灰色预测 GM(1,1)

使用MATLAB进行灰色预测 GM(1,1)

Hou_____的博客 998

Redis命令执行全过程

这个问题说简单也很简单,无非就是客户端发送命令请求,服务器读取命令请求,然后是命令执行器查找命令实现,执行预备操作,调用命令实现函数,执行后续工作。 但是我们想要了解的不能简简单单的就是这些。下面我们详细的来分析一下Redis命令执行的全过程。

会呼吸的鱼 1989

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Redis命令的执行过程

Redis 服务器: Redis 服务器实现与多个客户端的连接,并处理这些客户端发送过来的请求,同时保存客户端执行命令所产生的数据到数据库中。Redis 服务器依靠资源管理器来维持自身的运转,其主要作用是管理 Redis 服务。 服务器处理命令的过程 我们向客户端发送了一条命令:SET city〝beijing〝 第一步 用户将命令 SET city〝beijing〝输入客户端,客户端接收到此命令。 第二步 客户端会先将接收到的命令转化为服务器可以识别的协议格式,然后利用连接到服务器的套接字,将转化为合法

xishilife的专栏 671

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

redis命令_深入Redis命令的执行过程

深入Redis命令的执行过程 Redis 服务器: Redis 服务器实现与多个客户端的连接,并处理这些客户端发送过来的请求,同时保存客户端执行命令所产生的数据到数据库中。Redis 服务器依靠资源管理器来维持自身的运转,其主要作用是管理 Redis 服务。 服务器处理命令的过程 我们向客户端发送了一条命令:SET city〝beijing〝 第一步 用户将命令 SET city〝beijing...

weixin_39932458的博客 80

【Redis】命令处理过程

我们知道 Redis 是一个基于内存的高性能键值数据库, 它支持多种数据结构, 提供了丰富的命令, 可以用来实现缓存、消息队列、分布式锁等功能。而在享受 Redis 带来的种种好处时, 是否曾好奇过 Redis 是如何处理我们发往它的命令的呢?本文将以的形式简单分析一下 Redis 命令处理的过程, 探讨其背后的机制。

LCN29的博客 1591

Redis命令请求的执行过程(一)

Redis服务器的命令请求来自Redis客户端,当用户在客户端中键入一个命令请求时,客户端会将这个命令转换成协议格式,然后通过连接到服务器的套接字,将协议格式的命令请求发送给服务器

Cover_sky的博客 737

redis之命令请求执行过程

一个命令请求从客户端发送到获得响应过程中,客户端和服务端要完成一系列操作。例如在客户端操作如下命令: redis> set key value 1 客户端向服务端发送命令请求 set key value; 服务器接收并处理该命令请求,在数据库中进行设置操作,并产生命令回复 1; 服务器将命令回复发送给客户端; 客户端接收服务器返回信息,并将信息打印给用户。 一、发送命令请求 当用户在客户端键入命令后,客户端会先对命令转换协议格式,然后通过连接到服务器的套接...

lucas1018的博客 684

redis 接收int类型最大值_深入Redis命令的执行过程

深入Redis命令的执行过程 Redis 服务器: Redis 服务器实现与多个客户端的连接,并处理这些客户端发送过来的请求,同时保存客户端执行命令所产生的数据到数据库中。Redis 服务器依靠资源管理器来维持自身的运转,其主要作用是管理 Redis 服务。 服务器处理命令的过程 我们向客户端发送了一条命令:SET city〝beijing〝 第一步 用户将命令 SET city〝beijing...

weixin_36484714的博客 1047

【Redis笔记】一起学习Redis | 大海捞针,了解scan命令

一起学习Redis | 大海捞针,重点讲解scan命令 为了避免keys扫描的耗时阻塞,所以需要用scan去替代 从海梁数据查找满足铁定前缀的key列表 前提概要 为什么要使用scan代替keys 在平时线上的Redis维护过程中,有时候需要从Redis实例中的成千上万个key中找到特定前缀的key集合。可能是批量删除,也可能是批量修改,查询等等。这样就延伸出了一个问题,如何从海量的ke...

长路漫漫的歇脚处 2217
上一篇: Go 程序启动流程你了解过吗?
下一篇: 工作中如何打造优雅的Git工作流和Commit规范!
小许code
博客等级 码龄3年 286粉丝 20原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值