自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(81)
  • 收藏
  • 关注

原创 C++实现的高并发内存池

C/C++下内存管理是件很头疼的事,分配足够的内存、追踪内存的分配、在不需要的时候释放内存—这个任务很复杂。如果直接使用系统调用malloc/free、new/delete进行内存分配和释放,则会有以下弊端:内存池(memory pool)是代替直接调用malloc/free、new/delete进行内存管理的常用方法,当我们申请内存空间时,首先到我们的内存池中查找合适的内存块,而不是直接向操作系统申请,优势在于:现代很多的开发环境都是多核多线程,在申请内存的场景下,必然存在激烈的锁竞争问题。malloc本

2022-06-08 14:00:00 2882 3

原创 自主实现的web服务器

web服务器背景描述应用技术一、认识HTTPhttp背景HTTP请求与响应具体http细节说明http请求 - 方法http响应 - 状态码及其描述三、代码细节工具类背景http协议被广泛使用,从移动端,pc端浏览器,http协议无疑是打开互联网应用窗口的重要协议,http在网络应用层 中的地位不可撼动,是能准确区分前后台的重要协议。描述采用C/S模型,编写支持中小型应用的http,并结合mysql,理解常见互联网应用行为,做完该项目,你可以从技术上完全理解从你上网开始,到关闭浏览器的所有操作中的技

2022-05-31 22:33:19 1070 1

原创 HTTP详解

HTTP 是超文本传输协议,也就是HyperText Transfer Protocol。HTTP的名字「超文本协议传输」,它可以拆成三个部分:1xx 类状态码属于提示信息,是协议处理中的一种中间状态,实际用到的比较少。2xx 类状态码表示服务器成功处理了客户端的请求,也是我们最愿意看到的状态。「200 OK」是最常见的成功状态码,表示一切正常。如果是非 HEAD 请求,服务器返回的响应头都会有 body 数据。「204 No Content」也是常见的成功状态码,与 200 OK 基本相同,但响应头没

2022-06-17 15:03:21 23119 1

原创 MySQL索引优化

这里说一下几种常见优化索引的方法:前缀索引顾名思义就是使用某个字段中字符串的前几个字符建立索引,那我们为什么需要使用前缀来建立索引呢?使用前缀索引是为了减小索引字段大小,可以增加一个索引页中存储的索引值,有效提高索引的查询速度。在一些大字符串的字段作为索引时,使用前缀索引可以帮助我们减小索引项的大小。不过,前缀索引有一定的局限性,例如:覆盖索引是指 SQL 中 query 的所有字段,在索引 B+Tree 的叶子节点上都能找得到的那些索引,从二级索引中查询得到记录,而不需要通过聚簇索引查询获得,可以避免回表

2022-06-16 08:00:00 13052 1

原创 MySQL锁

要使用全局锁,则要执行这条命:执行后,整个数据库就处于只读状态了,这时其他线程执行以下操作,都会被阻塞:如果要释放全局锁,则要执行这条命令:当然,当会话断开了,全局锁会被自动释放。全局锁主要应用于做全库逻辑备份,这样在备份数据库期间,不会因为数据或表结构的更新,而出现备份文件的数据与预期的不一样。在全库逻辑备份期间,假设不加全局锁的场景,看看会出现什么意外的情况。如果在全库逻辑备份期间,有用户购买了一件商品,一般购买商品的业务逻辑是会涉及到多张数据库表的更新,比如在用户表更新该用户的余额,然后在商品

2022-06-16 00:41:05 369 1

原创 Redis哨兵

在 Redis 的主从架构中,由于主从模式是读写分离的,如果主节点(master)挂了,那么将没有主节点来服务客户端的写操作请求,也没有主节点给从节点(slave)进行数据同步了。这时如果要恢复服务的话,需要人工介入,选择一个「从节点」切换为「主节点」,然后让其他从节点指向新的主节点,同时还需要通知上游那些连接 Redis 主节点的客户端,将其配置中的主节点 IP 地址更新为「新主节点」的 IP 地址。这样也不太“智能”了,要是有一个节点能监控「主节点」的状态,当发现主节点挂了 ,它自动将一个「从节点」切

2022-06-15 07:58:52 6578 2

原创 缓存雪崩、击穿、穿透

用户的数据一般都是存储于数据库,数据库的数据是落在磁盘上的,磁盘的读写速度可以说是计算机里最慢的硬件了。当用户的请求,都访问数据库的话,请求数量一上来,数据库很容易就奔溃的了,所以为了避免用户直接访问数据库,会用 Redis 作为缓存层。因为 Redis 是内存数据库,我们可以将数据库的数据缓存在 Redis 里,相当于数据缓存在内存,内存的读写速度比硬盘快好几个数量级,这样大大提高了系统性能。引入了缓存层,就会有缓存异常的三个问题,分别是缓存雪崩、缓存击穿、缓存穿透。通常我们为了保证缓存中的数据与数据库

2022-06-14 08:00:00 202

原创 Redis主从复制

由于数据都是存储在一台服务器上,如果出事就完犊子了,比如:要避免这种单点故障,最好的办法是将数据备份到其他服务器上,让这些服务器也可以对外提供服务,这样即使有一台服务器出现了故障,其他服务器依然可以继续提供服务。多台服务器要保存同一份数据,这里问题就来了。这些服务器之间的数据如何保持一致性呢?数据的读写操作是否每台服务器都可以处理?Redis 提供了主从复制模式,来避免上述的问题。这个模式可以保证多台服务器的数据一致性,且主从服务器之间采用的是「读写分离」的方式主服务器可以进行读写操作,当发生写操作时自动

2022-06-13 22:34:31 244

原创 RDB持久化

Redis 是内存数据库,但是它为数据的持久化提供了两个技术。分别是「 AOF 日志和 RDB 快照」。这两种技术都会用各用一个日志文件来记录信息,但是记录的内容是不同的。所谓的快照,就是记录某一个瞬间东西,比如当我们给风景拍照时,那一个瞬间的画面和信息就记录到了一张照片。所以,RDB 快照就是记录某一个瞬间的内存数据,记录的是实际数据,而 AOF 文件记录的是命令操作的日志,而不是实际的数据。因此在 Redis 恢复数据时, RDB 恢复数据的效率会比 AOF 高些,因为直接将 RDB 文件读入内存就可以

2022-06-13 08:00:00 647 1

原创 AOF持久化

当Rides进程关闭时,我们可以通过持久化对数据进行恢复。Redis虽说是内存数据库,但是Redis其实是会把缓存数据保存到硬盘的,只要保存缓存数据的文件没有丢,缓存数据自然就能恢复。Rdedis共有两种持久化技术,分别是AOF日志和RDB快照Redis默认会开启RDB快照,所以Redis重启下,之前缓存的数据就会被重新加载。试想一下,如果 Redis 每执行一条写操作命令,就把该命令以追加的方式写入到一个文件里,然后重启 Redis 的时候,先去读取这个文件里的命令,并且执行它,这不就相当于恢复了缓存数据

2022-06-12 17:10:36 236

原创 Redis数据结构

Rides为什么那么快?除了它是内存数据库,使得所有的操作都在内存上进行之外,还有一个重要因素,它实现的数据结构,使得我们对数据进行增删查改操作时,Redis 能高效的处理。注意,Redis 数据结构并不是指 String(字符串)对象、List(列表)对象、Hash(哈希)对象、Set(集合)对象和 Zset(有序集合)对象,因为这些是 Redis 键值对中值的数据类型,也就是数据的保存形式,这些对象的底层实现的方式就用到了数据结构Redis 的键值对中的 key 就是字符串对象,而 value 可以

2022-06-09 15:55:40 9707 3

原创 Redis事务

并发 :当有多个线程在操作时,如果系统只有一个CPU,他根本不可能真正同时进行一个以上的线程,他只能把CPU运行时间划分成若干时间段,再将时间段分配给各个线程执行,在一个时间段的线程代码运行时,其他线程处于挂起状态并行:当系统有一个以上CPU时,则线程的操作有可能非并发。当一个CPU执行一个线程时,另一个CPU可以执行另一个线程,两个线程相互不想占CPU资源,可以同时进行,这种方式我们称之为并行redis pipeline 是一个客户端提供的,而不是服务端提供的;对于request操作,只是将数据写到

2022-06-07 08:00:00 177

原创 Redis数据存储

redis的数据存储

2022-06-05 21:32:27 2723

原创 MySQL事务

事务一、事务是什么事务组成事务特征二、使用步骤1.引入库2.读入数据总结一、事务是什么事务组成简单的来说事务可以由一条简单的sql语句组成,也可以由一组复杂的sql语句组成(事务是一个程序逻辑单元)事务特征在数据库针对事务进行提交的时候,要么是所有的修改都保存,要么所有的修改都丢弃 (原子性,要么整个事务全部完成,要么整个事务全部丢弃)事务是访问并更新数据库各种数据项的一个程序执行单元mysql的innodb 引擎是支持事务的, myisam 是不支持事务的, innodb中每一条sql语句

2022-06-05 08:00:00 205 1

原创 MySQL索引

索引一、索引是什么二、认识磁盘2.读入数据总结一、索引是什么索引:提高数据库的性能,索引是物美价廉的东西了。不用加内存,不用改程序,不用调sql,只要执行正确的create index ,查询速度就可能提高成百上千倍。但是天下没有免费的午餐,查询速度的提高是以插入、更新、删除的速度为代价的,这些写操作,增加了大量的IO。所以它的价值,在于提高一个海量数据的检索速度。常见索引分为:主键索引(primary key)唯一索引(unique)普通索引(index)全文索引(fulltext)–解决中

2022-06-04 09:00:00 198

原创 C++的类型转换

C++的类型转换一、C语言中的类型转换二、为什么C++需要四种类型转换三、C++强制类型转换static_castreinterpret_castconst_castdynamic_castexplicit四、RTTI一、C语言中的类型转换在C语言中,如果赋值运算符左右两侧类型不同,或者形参与实参类型不匹配,或者返回值类型与接收返回值类型不一致时,就需要发生类型转化,C语言中总共有两种形式的类型转换:隐式类型转换和显式类型转换。隐式类型转化:编译器在编译阶段自动进行,能转就转,不能转就编译失败显式

2022-06-02 08:15:00 1693

原创 C++智能指针

智能指针一、为什么需要智能指针?二、内存泄漏内存泄漏分类如何避免内存泄漏三、智能指针的使用及原理RAII智能指针的原理std::auto_ptrstd::unique_ptrstd::shared_ptr线程安全问题四、C++11和boost中智能指针的关系一、为什么需要智能指针?下面我们先分析一下下面这段程序有没有什么内存方面的问题?#include <vector>void _MergeSort(int* a, int left, int right, int* tmp) {

2022-06-01 10:00:00 264

原创 C++ 异常

文章目录一、C语言传统的处理错误的方式二、C++异常概念三、异常的使用异常的抛出和捕获异常的重新抛出异常安全异常规范四、自定义异常体系五、C++标准库的异常体系六、异常的优缺点C++异常的优点C++异常的缺点一、C语言传统的处理错误的方式传统的错误处理机制:终止程序,如assert,缺陷:用户难以接受。如发生内存错误,除0错误时就会终止程序。返回错误码,缺陷:需要程序员自己去查找对应的错误。如系统的很多库的接口函数都是通过把错误码放到errno中,表示错误C 标准库中setjmp和longjmp

2022-05-31 09:15:00 3101 2

原创 C++ 11特性

C++ 11一、C++11简介二、列表初始化C++98中{}的初始化问题自定义类型的列表初始化三、变量类型推导decltype类型推导四、范围循环for五、final与override六、智能指针七、新增加容器--静态数组array、forward_list以及unordered系列八、默认成员函数控制显式缺省函数删除默认函数九、右值引用左值和右值引用与右值引用比较一、C++11简介在2003年C++标准委员会曾经提交了一份技术勘误表(简称TC1),使得C++03这个名字已经取代了C++98称为C++1

2022-05-30 10:45:00 199

原创 STL总结

STL总结一、STL的本质二、STL的六大组件容器算法总结一、STL的本质通过前面的学习以及使用,我们对STL已经有了一定的认识。通俗说:STL是Standard Template Library(标准模板库),是高效的C++程序库,其采用泛型编程思想对常见数据结构(顺序表,链表,栈和队列,堆,二叉树,哈希)和算法(查找、排序、集合、数值运算…)等进行封装,里面处处体现着泛型编程程序设计思想以及设计模式,已被集成到C++标准程序库中。具体说:STL中包含了容器、适配器、算法、迭代器、仿函数以及空间配置器

2022-05-29 21:05:11 319

原创 哈希及其原理

哈希一、unordered系列关联式容器unordered_mapunordered_set在线OJ二、哈希哈希概念一、unordered系列关联式容器在C++98中,STL提供了底层为红黑树结构的一系列关联式容器,在查询时效率可达到 ,即最差情况下需要比较红黑树的高度次,当树中的节点非常多时,查询效率也不理想。最好的查询是,进行很少的比较次数就能够将元素找到,因此在C++11中,STL又提供了4个unordered系列的关联式容器,这四个容器与红黑树结构的关联式容器使用方式基本类似,只是其底层结构不同

2022-05-29 08:45:00 378

原创 红黑树介绍

红黑树一、红黑树的概念红黑树的性质红黑树节点的定义红黑树结构二、使用步骤1.引入库2.读入数据总结一、红黑树的概念红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。 通过任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍,因而是接近平衡的。红黑树的性质每个结点不是红色就是黑色根节点是黑色的如果一个节点是红色的,则它的两个孩子结点是黑色的对于每个结点,从该结点到其所有后代叶结点的简单路径上,均 包含相同数

2022-05-28 10:30:00 43428 7

原创 AVL平衡二叉树

、文章目录前言一、pandas是什么?二、使用步骤1.引入库2.读入数据总结前言提示:这里可以添加本文要记录的大概内容:例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。提示:以下是本篇文章正文内容,下面案例可供参考一、pandas是什么?示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。二、使用步骤1.引入库代码如下(示例):import numpy as npimp

2022-05-27 11:00:00 126

原创 map和set

map和set一、关联式容器二、键值对三、树形结构的关联式容器四、setset的使用set的构造set的迭代器set的容量set修改操作set的使用举例五、mapmap的使用map的模板参数说明map的构造map的迭代器map的容量与元素访问map中元素的修改六、multisetmultiset的使用七、multimapmultimap的使用一、关联式容器关联式容器也是用来存储数据的,与序列式容器不同的是,其里面存储的是<key, value>结构的键值对,在数据检索时比序列式容器效率更高。

2022-05-26 11:00:00 134

原创 二叉搜索树

二叉树进阶前言二叉搜索树二叉搜索树概念二叉搜索树操作二叉搜索树的实现二叉搜索树的应用二叉搜索树的性能分析二叉树进阶OJ前言map和set特性需要先铺垫二叉搜索树,而二叉搜索树也是一种树形结构二叉搜索树的特性了解,有助于更好的理解map和set的特性二叉搜索树二叉搜索树概念二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树:若它的左子树不为空,则左子树上所有节点的值都小于根节点的值若它的右子树不为空,则右子树上所有节点的值都大于根节点的值它的左右子树也分别为二叉搜索树

2022-05-25 09:45:00 127

原创 C++多态

多态一、多态的概念二、多态的定义及实现多态的构成条件虚函数虚函数的重写C++11 override 和 final重载、覆盖(重写)、隐藏(重定义)的对比三、抽象类接口继承和实现继承四、多态的原理虚函数表总结一、多态的概念多态的概念:通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同的状态。举个栗子:比如买票这个行为,当普通人买票时,是全价买票;学生买票时,是半价买票;军人买票时是优先买票。二、多态的定义及实现多态的构成条件多态是在不同继承关系的类对象,去调用同一

2022-05-24 09:30:00 213

原创 C++中的继承

继承一、继承的概念及定义继承的概念继承定义继承关系和访问限定符继承基类成员访问方式的变化二、基类和派生类对象赋值转换三、继承中的作用域四、派生类的默认成员函数五、继承与友元六、继承与静态成员七、复杂的菱形继承及菱形虚拟继承虚拟继承解决数据冗余和二义性的原理八、继承的总结和反思总结一、继承的概念及定义继承的概念继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次

2022-05-23 08:30:00 147

原创 stack和queue

stack和queue一、 stack的介绍和使用stack的使用stack的模拟实现二、queue的介绍和使用queue的使用queue的模拟实现三、priority_queue的介绍和使用priority_queue的使用四、容器适配器STL标准库中stack和queue的底层结构五、deque简单介绍deque的原理介绍deque的缺陷一、 stack的介绍和使用stack的文档介绍翻译:stack是一种容器适配器,专门用在具有后进先出操作的上下文环境中,其删除只能从容器的一端进行元素的插入

2022-05-22 16:00:00 192

原创 C++ list

list一、list的介绍及使用list的介绍list的使用list的构造list iterator的使用list modifierslist的迭代器失效二、list与vector的对比一、list的介绍及使用list的介绍list的文档介绍list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后一个元素。list与forward_list非常相似

2022-05-22 08:30:00 137 1

原创 C++ vector

vector一、vector的介绍及使用vector的定义vector iterator 的使用vector 空间增长问题vector 增删查改vector迭代器失效问题vector相关OJ二、vector深度剖析动态二维数组理解一、vector的介绍及使用vector的文档介绍vector是表示可变大小数组的序列容器。就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问,和数组一样高效。但是又不像数组,它的大小是可以动态改变的,而且它的大

2022-05-21 16:34:05 618

原创 C++ string

string类前言一、标准库中的string类二、string类常用接口string类常见构造string类对象的容量操作string类对象的访问及遍历操作string类对象的修改操作string类非成员函数前言C语言中的字符串:C语言中,字符串是以’\0’结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。一、标准库中的string类string类的文档介绍

2022-05-21 15:16:45 6475

原创 高级IO通信

高级IO前言一、五种IO模型阻塞IO非阻塞IO信号驱动IOIO多路转接异步IO二、高级IO对比同步通信 vs 异步通信阻塞 vs 非阻塞三、I/O多路转接之selectselect函数原型前言I/O等于等待+拷贝读I/O等于等待读事件就绪+内核数据拷贝至用户空间写I/O等于写事件就绪+用户空间数据拷贝至内核空间高效I/O的本质是尽可能地减少等的比重一、五种IO模型阻塞IO在内核将数据准备好之前, 系统调用会一直等待. 所有的套接字, 默认都是阻塞方式.非阻塞IO如果内核还未将数据准备好

2022-05-21 11:10:13 408

原创 网络基础2

网络基础2一、网络层IP协议基本概念协议头格式网段划分特殊的IP地址二、使用步骤1.引入库2.读入数据总结一、网络层网络层就是在复杂的网络环境中确定一个合适的路径。IP协议IP给通信双方提供一种能力,将数据从A主机跨网络送到B主机的能力。基本概念主机:配有IP地址,但是不进行路由控制的设备;路由器:即配有IP地址,又能进行路由控制;节点:主机和路由器的统称。协议头格式4位版本号:指定IP协议的版本,对于IPv4来说,就是4.4位头部长度:IP头部的长度是多少个32bit,也就是le

2022-05-20 15:39:07 826

原创 网络基础1

网络基础1一、应用层HTTP协议认识URLHTTP协议格式二、使用步骤1.引入库2.读入数据总结一、应用层我们程序员写的一个个解决我们实际问题, 满足我们日常需求的网络程序, 都是在应用层HTTP协议虽然我们说, 应用层协议是我们程序猿自己定的.但实际上, 已经有大佬们定义了一些现成的, 又非常好用的应用层协议, 供我们直接参考使用. HTTP(超文本传输协议)就是其中之一.认识URL平时我们俗称的 “网址” 其实就是说的 URL这里有一个问题URL和URI的区别:URL是统一资源定位

2022-05-19 17:36:58 139

原创 网络套接字编程

网络基础一、网络背景二、使用步骤1.引入库2.读入数据总结一、网络背景示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。二、使用步骤1.引入库代码如下(示例):import numpy as npimport pandas as pdimport matplotlib.pyplot as pltimport seaborn as snsimport warningswarnings.filterwarnings('ignore')import

2022-05-18 22:46:30 444

原创 性能测试与loadrunner

性能测试loadrunner一、为什么要做性能测试二、性能测试实施流程三、性能的概念和术语四、性能测试分类一、为什么要做性能测试系统是否可以处理预期的用户负载;系统是否可以处理业务所需要的事务数量;(事务是一系列密切相关的操作集合)系统可以处理非预期情况下的用户负载;系统能在预期和非预期的情况下获得稳定运行;用户可以获得舒服的体验;二、性能测试实施流程分析性能测试需求根据性能测试的目标,设计性能测试的场景开发性能测试场景和性能测试脚本分析性能测试报告根据性能测试报告排查和定能系统的性

2022-04-04 13:39:45 4300 15

原创 Selenium自动化测试

Selenium自动化测试一、为什么还要学Python?二、Selenium自动化测试工具三、发展方向总结一、为什么还要学Python?Python 学习成本低Python 少量的代码构建出丰富的功能Python 拥有成熟的程序包资源库Python 在数据科学领域广泛使用。Python 是跨平台且开源的。Python 易于被其他编程需要集成,例如 CPythonPython 普遍在大学课程中使用二、Selenium自动化测试工具1.自动化测试工具性能自动化测试工具:loadrunn

2022-04-02 17:57:52 20624 13

原创 C++模板初阶

C++模板初阶一、泛型编程二、函数模板函数模板格式函数模板的原理函数模板的实例化模板参数的匹配原则三、类模板一、泛型编程如何实现一个通用的交换函数呢?void Swap(int& left, int& right) { int temp = left; left = right; right = temp; }void Swap(double& left, double& right) { double temp = left; left

2022-03-30 15:40:16 155 5

原创 C&C++内存管理

C&C++内存管理一、C/C++内存分布二、C语言中动态内存管理方式三、C++内存管理方式new/delete操作内置类型new和delete操作自定义类型四、operator new与operator delete函数operator new与operator delete函数一、C/C++内存分布我们先来看下面的一段代码和相关问题:int globalVar = 1;static int staticGlobalVar = 1;void Test(){ static int sta

2022-03-27 11:11:21 113 7

原创 软件测试进阶篇

进阶&管理一、测试技能图二、按开发阶段分测试金字塔一、测试技能图二、按开发阶段分测试金字塔(1)从下到上,定位问题越来越困难(2)从下到上测试效率越来越低(1)单元测试测试阶段:开发前(TDD),开发后。测试人员:白盒测试工程师/黑盒测试工程师测试内容:模块接口测试,局部数据结构测试,边界测试,错误处理测试,逻辑结构测试TDD Test-Driven-Development测试人员先写测试脚本开发人员根据脚本的异常去进行开发(2)集成测试按照一定的策略把单元功能

2022-03-26 11:44:32 3254 10

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除