- 博客(116)
- 收藏
- 关注
原创 [杂学笔记] TCP和UDP的区别,对http接口解释 , Cookie和Session的区别 ,http和https的区别 , 智能指针 ,断点续传
更细一点就是 : 在双方操作系统中,发数据并不是把数据发送给对方,也不是发送到网络,而是拷贝到操作系统底层的tcp发送缓冲区,所以tcp传输控制的时候就可以根据流量控制,拥塞控制,捎带应答,快重传,各种可靠性策略,效率策略把数据发送给对方,再往下谈,滑动窗口,每一次对应的数据段也不直接发送给对方,而是交给了ip报文,在这里也添加了自己的ip报头,这里也有分片和组装的问题…而udp是无连接的,不可靠。3、HTTP 和 HTTPS 使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
2025-03-11 16:53:46
1272
原创 [杂学笔记] 封装、继承、多态,堆和栈的区别,堆和栈的区别 ,托管与非托管 ,c++的垃圾回收机制 , 实现一个单例模式 注意事项
存储函数内部定义的局部变量和函数传递的参数,当函数被调用的时候,这些局部变量都会被分配内存,函数调用结束之后,又会将这些占用的内存自动释放掉。比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象同一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息,这种方式简化了在复杂环境下的配置管理。但在底层实际上是,创建子类的时候,子类重写的虚函数会覆盖虚函数表中的地址,父类指针指向子类对象的时候,访问虚函数表地址访问的就是子类覆盖后的地址。
2025-03-04 20:48:10
975
原创 八大排序算法,快排的三种递归非递归实现,归并的递归非递归实现,排序算法复杂度及稳定性分析【有图解】
3、在走的过程中,若R遇到小于key的数,则将该数抛入坑位,并在此处形成一个坑位,这时L再向后走,若遇到大于key的数,则将其抛入坑位,又形成一个坑位,如此循环下去,直到最终L和R相遇,这时将key抛入坑位即可。3、在走的过程中,若R遇到小于key的数,则停下,L开始走,直到L遇到一个大于key的数时,将L和R的内容交换,R再次开始走,如此进行下去,直到L和R最终相遇,此时将相遇点的内容与key交换即可。(选取最左边的值作为key)三数取中,当中的三数指的是:最左边的数、最右边的数以及中间位置的数。
2025-01-04 20:04:54
818
原创 二叉树相关的题,判断二叉树是否是单值二叉树,相同的树,对称二叉树,另一棵树的子树,KY11 二叉树遍历
若在遍历过程中发现镜像对称的某两个结点值不同,则无需继续遍历,此时已经可以判断该树不是对称二叉树,只有当红蓝轨迹成功遍历完毕后,才能断定该树是对称二叉树。判断 subRoot 是否是二叉树 root 的子树,即检验 root 中是否包含和 subRoot 具有相同结构和结点值的子树,其中 root 和 subRoot 均为非空二叉树。因为是镜像对称,所以左子树的遍历方式和右子树的遍历方式是不同的,准确来说,左子树和右子树的遍历是反方向进行的。3.判断以根的左孩子为根的二叉树是否是单值二叉树。
2025-01-02 13:18:00
859
原创 链式二叉树的基本操作,前序、中序以及后序遍历(递归实现,非递归实现)【有图解】
设二叉树的根节点所在层数为1,层序遍历就是从所在二叉树的根节点出发,首先访问第一层的树根节点,然后从左到右访问第2层上的节点,接着是第三层的节点,以此类推,自上而下,自左至右逐层访问树的结点的过程就是层序遍历。访问结点所做的操作依赖于具体的应用问题。既然是链式二叉树,那必须得有自己的结点类型,以下是链式二叉树结点类型的定义,为了避免过多重复的代码,下面的问题都统一使用该结点类型。相对于根结点的第k层结点的个数 = 相对于以其左孩子为根的第k-1层结点的个数 + 相对于以其右孩子为根的第k-1层结点的个数。
2024-12-28 20:59:39
997
原创 堆【Heap】的基本功能实现, 堆的应用 --- TopK问题
堆:如果有一个关键码的集合K={k0,k1,k2,…,kn-1},把它的所有元素按完全二叉树的顺序存储方式存储在一个一维数组中,并满足ki=k2i+2),其中i=0,1,2,…,则称该集合为堆。小堆:将根结点最小的堆叫做小堆,也叫最小堆或小根堆。大堆:将根结点最大的堆叫做大堆,也叫最大堆或大根堆。
2024-12-27 12:49:27
1075
原创 服务端高并发分布式结构革新之路
负载均衡器的流量承担能力是远远超过应用服务器的,因为它只用单纯的分配任务,服务器是需要进行执行任务的,所花时间是更长的。为了减少管理成本,就可以把一个复杂的服务器,拆分成更多的,功能单一的,更小的服务器(微服务),就有利于划分组织结构,分多组进行管理。用户的请求通过负载均衡分发到不同的应⽤服务器之后,可以并⾏处理了,并且可以随着业务的增⻓,可以动态扩张服务器的数量来缓解压⼒。数据库中存储的还是完整的数据,只是将热点数据放到缓存中了,缓存的速度非常快,但是容量小,成本高,也是Redis出现的位置。
2024-11-19 20:05:51
1013
原创 基于 Protobuf 实现一个简便 网络版通讯录
Protobuf 还常用于通讯协议、服务端数据交换场景。那么在这个示例中,我们将实现一个网络版本的通讯录,模拟实现客户端与服务端的交互,通过 Protobuf 来实现各端之间的协议序列化。需求如下:新增⼀个联系人删除⼀个联系人查询通讯录列表查询⼀个联系人的详细信息服务端提供增、删、查能力,并需要持久化通讯录。客户端、服务端间的交互数据使用 Protobuf 来完成。
2024-11-15 15:50:57
846
原创 基于 Protobuf 实现一个简便通讯录
在单个.proto⽂件中可以定义多个消息体,且⽀持定义嵌套类型的消息(任意多层)。每个消息体中的字段编号可以重复。// -------------------------- 嵌套写法 -------------------------// -------------------------- ⾮嵌套写法 -------------------------
2024-11-14 13:14:18
957
原创 随机链表的复制(图文解析)
从原节点开始遍历,共分两种情况:若为当前结点cur的random为空则为空,cur的random的next是需被拷贝的新结点,当前结点的next的random是需修改的新结点。随机指针不是单纯的拷贝,而是将拷贝节点的随机指针指向与原链表中关系对应的拷贝节点。3.原链表中节点的next指针拷贝,拷贝节点成为单独的新链表。这部分没什么好说的,采用新建头结点的形式来创建新链表,2.原链表中节点的随机指针拷贝。
2024-11-10 16:49:25
367
原创 环形链表问题(图 + 证明 + 题)
假设链表带环,两个指针最后都会进入环,快指针先进环,慢指针后进环。我们可以定义两个指针(快慢指针),两个指针均从表头开始同时遍历链表,快指针一次走两步,慢指针一次走一步。让一个指针从链表起始位置开始遍历链表,同时让一个指针从判环时相遇点的位置开始绕环运行,两个指针都是每次均走一步,最终肯定会在入口点的位置相遇。根据最终推论可以得出结论:若一个指针从出发点开始走,另一个指针从相遇点开始走,则他们最终会在入口点处相遇。因此:在满指针走到一圈之前,快指针肯定是可以追上慢指针的,即相遇。
2024-11-10 15:53:58
435
原创 Linux进程信号
忽略此信号。执行该信号的默认处理动作。提供一个信号处理函数,要求内核在处理该信号时切换到用户态执行这个处理函数,这种方式称为捕捉(Catch)一个信号。
2024-11-10 13:14:09
756
原创 栈和队列相关题 , 用队列实现栈, 用栈实现队列 ,设计循环队列 C/C++双版本
环形队列的队尾不能像常规队列中队尾一样指向最后一个数据,如果这样的话,我们将不能区别环形队列的状态是空还是满,因为此时队头和队尾都指向同一个位置。这就意味着,我们必须留出一个空间,这个空间不能存放数据,这样我们才能很好的区别环形队列的状态是空还是满。当队列不为空时,队头指向插入的第一个数据,队尾指向最后一个数据的下一个位置。当需要输出数据,但第二个栈为空时,先将第一个栈中的数据一个一个导入到第二个栈,然后第二个栈再输出数据即可。使用两个栈,第一个栈只用于数据的输入,第二个栈只用于数据的输出。
2024-11-06 17:17:49
647
原创 队列(Queue)的介绍与实现
需要注意的是:若队列中原本无数据,那么我们只需让队头和队尾均指向这个新申请的结点即可。队列与普通链表又有所不同,普通链表只需要知道链表的头指针,而队列的信息包括了队头和队尾,所以我们需要再创建一个结构体用于存放队列的队头和队尾。出队列,即释放队头指针指向的结点并改变队头指针的指向即可。队列中的每一个结点所占用的内存空间都是动态开辟的,当我们使用完队列后需要及时释放队列中的每一个结点。入队列:队列的插入操作叫做入队列,进行插入操作的一端称为队尾。出队列:队列的删除操作叫做出队列,进行删除操作的一端称为队头。
2024-11-04 21:19:35
382
原创 栈(Stack)的介绍与实现
栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。出栈:栈的删除操作叫做出栈。出数据也在栈顶。。
2024-11-04 21:01:54
349
原创 C++11 【 function包装器,bind包装器】
function包装器 也叫作适配器。C++中的function本质是一个类模板,也是一个包装器。模板参数说明:Ret: 被调用函数的返回类型Args…:被调用函数的形参包装示例function包装器可以对可调用对象进行包装,包括函数指针(函数名)、仿函数(函数对象)、lambda表达式、类的成员函数。public:class Pluspublic:int main()//1、包装函数指针(函数名)//2、包装仿函数(函数对象)//3、包装lambda表达式。
2024-11-02 19:35:51
904
原创 C++11 【 lambda表达式】
随着C++语法的发展,人们开始觉得上面的写法太复杂了,每次为了实现一个algorithm算法, 都要重新去写一个类,如果每次比较的逻辑不一样,还要去实现多个类,特别是相同类的命名,这些都给编程者带来了极大的不便。实际当我们以[&]或[=]的方式捕获变量时,编译器也不一定会把父作用域中所有的变量捕获进来,编译器可能只会对lambda表达式中用到的变量进行捕获,没有必要把用不到的变量也捕获进来,这个主要看编译器的具体实现。实际编译器在底层对于lambda表达式的处理方式,完全就是按照函数对象的方式处理的。
2024-11-02 15:55:36
808
原创 模拟算法 (算法详解+例题)
模拟是对真实事物或者过程的虚拟。在编程时为了实现某个功能,可以用语言来模拟那个功能,模拟成功也就相应地表示编程成功。
2024-10-28 22:57:26
1931
原创 位运算算法及习题 ,丢弃的数字 , 两整数之和 ,只出现一次的数字II
假设题目给我们的是如图所示的数组,只有一个元素出现了1次,其他的都出现了3次.我们将数组元素十进制转化为二进制,就会发现,如果我们将所有元素的某一个二进制位加起来,得到的结果去%3,得到的就一定是[只出现一次]的那个数的对应比特位.比如:我们将所有元素的第0比特位相加,那么就会得到4,4 % 3 = 1,那么99的第0位比特位就是0。这里是引用我们完全的数字范围与 给定的数组合成一个新数组.假设我们的数组是:[2,3],那么数据范围就是1,2,3,4,那么新的数组就是:1,2,2,3,3,4;
2024-10-27 21:56:52
718
原创 前缀和 有图文 【模板】前缀和, 【模板】二维前缀和 ,寻找数组的中心下标 , 和为 K 的子数组
从图中我们很容易看出,整个外围蓝色矩形面积s[i][j] = 绿色面积s[i - 1][j] + 紫色面积s[i][j - 1] - 重复加的红色的面积s[i - 1][j - 1] + 小方块的面积a[i][j];紫色面积是指(1, 1)左上角到(i, j - 1)右下角的矩形面积, 绿色面积是指(1, 1)左上角到(i - 1, j )右下角的矩形面积。我们对数组 0~i 位置分析,以 i 位置为结尾的所有的子数组 , 然后我们只需要找在【0,i-1】区间内,有多少个前缀和等于 sum[i] - k;
2024-10-23 22:59:46
597
原创 二分查找算法 (算法详解+模板+例题)
二分查找算法并不是针对在数组有序的情况下,通过后面的题我们就会知道实际上只要是满足"二段性"的题目,都可以通过二分查找算法来实现我们可以分成三种情况朴素的二分查找(最简单,但是基本不涉及)查找左边界的二分查找查找右边界的二分查找第二第三基本是万能的,但细节较多我们来看一张二分查找与遍历查找的效率对比图。题目链接我们先寻找左端点:通过上图,我们会很容易地看出,左端点将数组划分为左区间和右区间,这不就就是我们在一开始就强调的"二段性",那么我们就可以利用二分查找来寻找这个左端点。
2024-10-21 22:00:00
7105
3
原创 滑动窗口,水果成篮 , 找到字符串中所有字母异位词 ,串联所有单词的子串
滑动窗口(Sliding Window)是一种在计算机科学中用于解决各种子数组或子字符串问题的技术。滑动窗口技术通过维护一个固定大小的窗口在数组或字符串上移动,从而使得可以在较短的时间内解决一些复杂的问题。这种方法在处理一系列数据时特别高效。滑动窗口(Sliding Window)是一种在计算机科学中用于解决各种子数组或子字符串问题的技术。滑动窗口技术通过维护一个固定大小的窗口在数组或字符串上移动,从而使得可以在较短的时间内解决一些复杂的问题。这种方法在处理一系列数据时特别高效。
2024-10-20 22:32:24
739
原创 滑动窗口,长度最小的子数组 ,无重复字符的最长子串 ,最大连续1的个数 III ,将 x 减到 0 的最小操作数
滑动窗口(Sliding Window)是一种在计算机科学中用于解决各种子数组或子字符串问题的技术。滑动窗口技术通过维护一个固定大小的窗口在数组或字符串上移动,从而使得可以在较短的时间内解决一些复杂的问题。这种方法在处理一系列数据时特别高效。滑动窗口(Sliding Window)是一种在计算机科学中用于解决各种子数组或子字符串问题的技术。滑动窗口技术通过维护一个固定大小的窗口在数组或字符串上移动,从而使得可以在较短的时间内解决一些复杂的问题。这种方法在处理一系列数据时特别高效。
2024-10-20 13:05:19
918
原创 链表题, 合并两个有序链表, 链表分割, 链表的回文结构 ,相交链表
我们假设这两个链表的结点个数之差为count,我们可以让指向较长链表的指针先向后移动count步,然后指向长链表的指针和指向短链表的指针再同时向后移动,这样这两个指针最后会同时走到各自的链表结尾(NULL)。该题的思路比较简单,我们只需创建一个头结点,然后从两个链表的表头开始依次比较传入的两个链表的结点的大小,并将两个链表中较小的结点尾插到新链表的后面即可。创建两个链表,遍历一遍传入的链表,将值大于x的结点和值小于x的结点依次尾插到两个链表中,最后再将这两个链表链接起来,并返回第一个结点的位置即可。
2024-10-16 15:08:20
901
原创 链表题, 反转链表 , 链表的中间结点 , 删除链表的倒数第 N 个结点 , 移除链表元素
所以我们可以先让快指针(fast)先走k步,然后慢指针(slow)再和快指针一起往后走,这样,当快指针走到NULL时,慢指针指向的结点就是倒数第k个结点。思路: 将原链表的结点,从头到尾一个个地拿下来头插到一个新链表中,这个新链表起始时为一个空链表。思路 : 快慢指针,快指针走两步,慢指针走一步,快指针走到头慢指针到中间。prev:记录待排查结点的前一个结点位置(previous)。slow:记录已经遍历过的结点的中间结点。next:记录待排查结点的后一个结点(next)。
2024-10-13 19:46:42
462
原创 MySQL事务管理
对MySQL中的隔离级别总结如下:说明:隔离级别越严格,安全性越高,但数据库的并发性能也就越低,在选择隔离级别时往往需要在两者之间找一个平衡点。表中只写出了各种隔离级别下进行读操作时是否需要加锁,因为无论哪种隔离级别,只要需要进行写操作就一定需要加锁。
2024-10-12 14:12:35
953
原创 仿RabbitMQ实现消息队列三种主题的调试及源码
只有queue2对应的news.music.sport可以接收到对应的hello linux,符合主题交换。在进行不同测试下,消费者客户端只需要改变交换机的类型就可以了,现在为广播交换。在进行不同测试下,消费者客户端只需要改变交换机的类型就可以了。在进行不同测试下,消费者客户端只需要改变交换机的类型就可以了。只有queue1可以拿到消息,queue2没有任何反应。本项目已开源到下面链接下的仓库当中。2. 打开消费者客户端。
2024-10-05 01:01:14
681
原创 仿RabbitMQ实现消息队列客户端
在RabbitMQ中,提供服务的是信道,因此在客⼾端的实现中,弱化了Client客⼾端的概念,也就是说在RabbitMQ中并不会向⽤⼾展⽰⽹络通信的概念出来,⽽是以⼀种提供服务的形式来体现。同样的,客⼾端也有信道,其功能与服务端⼏乎⼀致,或者说不管是客⼾端的channel还是服务端的channel都是为了⽤⼾提供具体服务⽽存在的,只不过服务端是为客⼾端的对应请求提供服务,⽽客⼾端的接⼝服务是为了⽤⼾具体需要服务,也可以理解是⽤⼾通过客⼾端channel的接⼝调⽤来向服务端发送对应请求,获取请求的服务。
2024-10-04 17:30:44
1555
1
原创 仿RabbitMQ实现消息队列服务端(二)
在RabbitMQ中,虚拟主机是可以随意创建/删除的,但是咱们此处为了实现简单,并没有实现虚拟主机的管理,因此我们默认就只有⼀个虚拟主机的存在,但是在数据结构的设计上我们预留了对于多虚拟主机的管理,从⽽保证不同虚拟主机中的Exchange、Queue、Binding、Message等资源都是相互隔离的。具体通信的过程我们使⽤Muduo库来实现,使⽤TCP作为通信的底层协议,同时在这个基础上⾃定义应⽤层协议,完成客⼾端对服务器功能的远端调⽤。使⽤⼆进制的⽅式设计应⽤层协议。
2024-10-04 16:52:42
1318
原创 仿RabbitMQ实现消息队列服务端(一)
因为protobuf中⾃带了序列化和反序列化功能,因此操作起来会简便⼀些。需要特别说明的是,消息的存储并没有使⽤数据库,因为消息⻓度通常不定,且有些消息可能会⾮常庞⼤,因此并不适合存储在数据库中,因此我们的处理⽅式(包括RabbitMQ)是直接将消息存储在⽂件中进⾏管理,⽽内存中管理的消息只需要记录好⾃⼰在⽂件中的所在位置和⻓度即可。为了便于管理,消息管理以队列为单元进⾏管理,因此每个队列都会有⾃⼰独⽴的数据存储⽂件。
2024-10-04 14:57:17
1592
原创 工具模块及项目整体模块框架
消费者在客⼾端的存在感⽐较低,因为在⽤⼾的使⽤⻆度中,只要创建⼀个信道后,就可以通过信道完成所有的操作,因此对于消费者的感官更多是在订阅的时候传⼊了⼀个消费者标识,且当前的简单实现也仅仅是⼀个信道只能创建订阅⼀个队列,也就是只能创建⼀个消费者,它们⼀⼀对应,因此更是弱化了消费者的存在。本质上,咱们仿照实现的服务器是通过muduo库来实现底层通信的,⽽这⾥的连接管理,更多的是对muduo库中的Connection进⾏⼆次封装管理,并额外提供项⽬所需操作。上述数据结构,既需要在内存中存储,也需要在硬盘中存储。
2024-10-03 21:13:08
1222
原创 异步操作实现线程池
在这个函数当中,就是一个经典的调用异步操作来执行的操作,对于函数参数来说,Fn表示的是这是一个要执行的函数,后面的args表示的是这个函数的参数,而对于这个函数来说,它存在一种函数的重载,这个函数的重载可以在最前面加上一个调用的策略,可以使得是立刻进行执行和获取函数的返回值,或者是在调用get函数再进行函数返回值的获取,下面使用一个实例代码来进行演示。基于线程池执⾏任务的时候,⼊⼝函数内部执⾏逻辑是固定的,因此选择std::packaged_task加上std::future的组合来实现。
2024-10-02 21:12:43
905
原创 基于muduo库函数实现protobuf协议的通信
先使用protobuf库创建我们所要完成的业务请求类型,英译汉和加法服务器和客⼾端。创建request.proto//接下来定义rpc翻译请求信息结构//接下来定义rpc翻译响应信息结构//定义rpc加法请求信息结构//定义rpc加法响应信息结构。
2024-10-02 12:53:51
1432
原创 BFS 解决拓扑排序 , 课程表 , 课程表 II , 火星词典
像这样只能从一个点到另一个点有方向的图,并且不构成环状就是有向无环图如果像这样,4,5,6就构成环状了,就不是有向无环图了。出度是指一个顶点作为起点出发的边的数量,而入度是指指向该顶点的边的数量。
2024-09-26 20:57:39
705
原创 BFS 解决最短路径问题, 迷宫中离入口最近的出口,最小基因变化,单词接龙,为高尔夫比赛砍树
但是本题是有限制条件就是每一次基因变化都要能在基因库中找到,因此单层处理逻辑中需要遍历基因库,找到库中与当前基因相差一个字符的就是下一步变化的基因,这时步数 num+1 并进入下一层。具体的大概思路就是利用回溯的方式是逐个改变基因中的字符(A、C、G、T),当改变后的基因在基因库中 步数 num+1 并进入下一层。跟上面那道题思路完全一样,留给各位练习使用。边权为1的最短路径问题。
2024-09-25 23:15:59
515
原创 动态规划11,完全背包模板,零钱兑换,零钱兑换 II
问题一:求这个背包至多能装多大价值的物品?状态表示:经验+题目要求dp[i][j] 表示 从前i个物品中挑选,总体积不超过j,所有选法中,能选出来的最大价值。状态转移方程根据最后一步的状态:选还是不选,选的话选几个这里有一个化简的过程初始化i为0,表示从前0个物品选,当然全为0;j为0,表示从前i个物品选,总体积不超过0,也全为0;填表顺序从上往下填每一行每一行从左往右问题二:若背包恰好装满,求至多能装多大价值的物品?状态表示:经验+题目要求。
2024-09-24 20:05:58
514
原创 MySQL索引特性
需要注意的是,尽管两次IO是在同一时刻发出的,但如果它们请求的扇区地址相差很大,那也只能称为随机访问,因为连续访问中的连续指的是访问的扇区地址的连续,而不是访问时间的连续,由于连续访问不需要过多的定位,因此效率比较高。MySQL作为一款应用软件,可以想象成是一种特殊的文件系统,它有着更高频的IO场景,因此为了提高基本的IO效率,MySQL与磁盘交互的基本单位是16KB,这个基本数据单元在MySQL这里也叫做Page。但最终当我们查看表中的数据时,却发现显示出来的数据是按照主键进行有序排列的。
2024-09-20 22:26:13
1254
原创 Muduo库介绍及使用
用户可以使用 connect() 和 disconnect() 控制连接,并通过 setConnectionCallback() 和 setMessageCallback() 设置回调函数,处理连接状态的变更和消息的接收。它提供一系列操作来读取和处理存储在缓冲区中的数据,支持网络字节序的转换和数据的基本处理,如读取、检索和删除操作。它的设计使得每个连接可以独立地处理其生命周期内的各种事件。由于所有连接都在一个事件循环中处理,处理时间较长的连接可能会影响到其他连接的响应时间,从而导致一些连接得不到及时响应。
2024-09-09 15:38:44
1168
原创 Protobuf库的使用
proto⽂件规范消息(message):要定义的结构化对象,我们可以给这个结构化对象中定义其对应的属性内容。在⽹络传输中,我们需要为传输双⽅定制协议。定制协议说⽩了就是定义结构体或者结构化数据,⽐如,tcp,udp报⽂就是结构化的。再⽐如将数据持久化存储到数据库时,会将⼀系列元数据统⼀⽤对象组织起来,再进⾏存储。ProtoBuf就是以message的⽅式来⽀持我们定制协议字段,后期帮助我们形成类和⽅法来使⽤。为contacts.proto(通讯录demo)新增联系⼈message定义消息字段。
2024-09-08 20:35:18
1038
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人