自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

mango_love的专栏

习而简之,简而精之

  • 博客(116)
  • 资源 (3)
  • 收藏
  • 关注

原创 设计模式学习目录

设计模式的定义设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结,使用设计模式是为了可重用代码、让代码更容易被他人理解并且保证代码可靠性。UML类图基础知识:UML类图介绍和元素信息UML类图对应关系和对应代码面向对象的七种设计原则:1.开闭原则(Open-Closed Principle)2.单一职责原则(...

2019-05-29 14:59:15 505

原创 Redis分布式基础主从同步

​在使用Redis的时候首先开始是从单台Redis服务器开始,随着业务和用户量的增长,单机会暴漏一些问题,比如单台服务器的响应达到了上限、Redis服务器宕机所有请求全部越过缓存等等一系列问题。那么我们最简单的就是有一个备用的Redis服务器,当主服务器挂了从服务器就顶替主服务器继续服务,提高可用性。我们拥有了主从两台Redis服务器之后,当主服务器挂掉之后从服务器就替换上去继续为我们服务,原来的主服务器恢复正常后我们两台服务器的数据又不一样了,那么我们如何保证这两台服务器的数据一致性问题呢呢?

2020-07-08 12:49:23 2883

原创 Redis解读持久化RDB和AOF原理

我们知道关系型数据库比如MySQL支持全备、差备、增备。为了保证Redis故障重启后仍然可用我们的Redis支持全备(RDB快照备份)和增备(AOF日志连续增量备份),下面我们就来解读Redis持久化的原理。RDB基础知识RDB文件存在是以一个压缩后的二进制文件,这个RDB文件一般是保存在Redis安装目录下,通过启动Redis服务器执行rdbLoad函数加载RDB文件,执行rdbSave函数保存RDB文件。RDB保存rdbSave函数负责将内存中的数据库数据以RDB格式保存到磁盘中,如

2020-07-04 18:44:24 4755

原创 Redis数据库实现原理(划重点)

Redis服务器将所有数据库都保存在服务器状态redis.h/redisServer结构的db数组中,db数组的每一项都是一个redis.h/redisDb结构,每个redisDb结构代表一个数据库,服务器设置dbnum属性为初始数据库的个数,这个属性一般由数据库服务器配置conf文件中的database节点来配置,默认情况下这个初始值是16。struct redisServer{//数据库redisDb*db;//服务器数量intdbnum;};数据库切换...

2020-06-29 01:32:26 6199

原创 Redis实现消息队列之发布订阅模式

发布订阅(pub/sub)是一种消息通信模式:发送者(pub)在某一频道发送消息,订阅者(sub)接收消息。发布订阅模式类似与微博关注,比如说博主mango被张三、李四、王五关注,那么mango发一篇微博的时候张李王三人都会从关注里看到这条微博。那么发布订阅和生产消费有何异同之处呢?生产消费主要是生成一个消息只能被一个客户端消费,而发布订阅可以理解为发布一条消息,在该频道中的所有客户端都会收到,所以有时候我们这个发布订阅类似广播。注意pubsub是一个数据结构。Pub/Sub(发布订阅)

2020-06-18 01:06:09 4716

原创 Redis实现消息队列之生产消费模式

简单的介绍下消息队列,使用消息队列首先我们得有一个队列,那么这个队列之前讲过就是先进先出的一个数据结构;那么有了队列以后我们还需要有人在队列里面放东西,那么这个放东西的人我们称之为生产者;有了生产者对应的需要一个消费者,没有消费者这个队列满了就会溢出。简单队列实现那么我们Redis刚好有一个数据类型符合这个就是List。list可以实现队列(先进先出)和栈(先进后出),那么这个list又有两种插入数据的方式:头插法和尾插法。所以我们今天使用的结构是队列,使用尾插法,关键的命令有rpush(尾插)

2020-06-15 11:22:05 6748

原创 Redis缓存穿透、击穿、雪崩来解释个明白

随着用户的增长,用户的请求也越来越频繁,为了保证服务器在高并发的情况能正常提供服务,我们首先引入了缓存Redis,减少数据库的压力和数据的安全性同时提高了接口反应效率,解决了用户的请求直接与数据库建立连接。但是在使用Redis的时候,随之而来的问题也会越来越多,有些请求甚至会直接越过Redis直接请求数据库,今天我们来了解Redis数据库经常会谈及的问题缓存雪崩、缓存击穿、缓存穿透。缓存雪崩在某一时刻,大量的key失效,用户大量请求直接请求数据库,导致数据库宕机。此时的Redis形同虚设,用户.

2020-06-08 13:44:57 18933 3

原创 Redis管道(Pipeline)详解

在讲解管道前,我们首先来了解一下redis的交互,redis的一次交互是由客户端发起,由服务端接收,那么我们连续操作一些指令,如下图所示:客户端请求一个指令到服务器到服务器返回数据这个过程非常复杂,既要保证数据能够快速传到也要保证不丢包,那么每次请求响应这个过程中数据传输和客户端接收数据的网络消耗非常大,那么我们怎么来提升这个性能呢?上面说了,我们来回几次消耗大,那么可以一次性请求,一次性接收吗?当然是可以的,redis可以利用管道来提高性能。Redis客户端与服务器之间使用TCP协议进

2020-06-05 20:53:31 4323

原创 Redis通讯协议RESP详解

Redis的作者认为数据库系统的瓶颈一般不在于网络流量,而是数据库自身内部逻辑处理上。所以即使Redis使用了浪费流量的文本协议,依然可以取得极高的访问性能。Redis将所有数据都放在内存,用一个单线程对外提供服务,单个节点在跑满一个CPU核心的情况下可以达到了10w/s的超高QPS。RESP(RedisSerializationProtocol)RESP是Redis序列化协议的简写。它是一种直观的文本协议,优势在于实现异常简单,解析性能极好。Redis协议将传输的结构数据分为5种最小单元类型,..

2020-06-04 20:37:34 1394

原创 Redis线程IO模型的秘密知多少

​在前面事务里面讲过Redis是一个单线程应用程序,当然我们比较有代表性的单线程还有Node.js、Nginx等。那么既然是单线程的为什么还这么快呢?Redis的数据都在内存里面,所有的运算都是内存级别,处理数据是非常快速的,所以这里得注意一些复杂度为O(n)的指令,可能会导致服务器卡顿。那么Redis是一个单线程是如何处理并发客户端的连接呢?这就是接下来要讲的非阻塞IO、多路复用和事件轮询API。非阻塞IO那什么是阻塞IO模型?即在读写数据过程中会发生阻塞现象。当用户线程发出I

2020-06-03 23:55:50 4264

原创 Redis单线程模型事务的实现原理

在使用关系型数据库的时候,为了保证数据的ACID(Atomicity:原子性,Consistency:一致性,Isolation:隔离性,Durability:持久性)我们经常会使用事务,要么全部提交成功,要么失败全部失败,不会存在中间状态。那么我们Redis也会有事务,只不过它不能保证原子性,Redis已经在系统内部进行功能简化,这样可以确保更快的运行速度,因为Redis不需要事务回滚的能力。redis为我们的事务提供了四个指令:multi(开启事务),discard(丢弃),exec(执行),wat

2020-06-02 00:31:00 1568

原创 Redis分布式锁如何提高可用性

在编程中我们时常考虑高并发带来的数据访问不安全问题,那么我们在redis中是否也要考虑呢?答案是肯定的,有人会问:redis不是单线程的吗?对它是单线程,但是在某些情况他会出现信息更新,用户没有拿到最新数据,然后导致操作有误,看下图我们可以看到张三和李四同时请求这个number,但是李四执行set后张三拿到的数据是没有更新的,而后执行了set命令,这样这个number应该是30才对。Redis分布式锁简介redis给我们提供了分布式锁,开启锁的指令是setnx(set if not exis

2020-06-01 12:22:45 11317

原创 Redis高并发限流策略之漏斗限流算法

在双11活动当天凌晨,打折活动开始前多少名客户下单可以半折甚至是免单优惠,客户当然不会放过这个一年一次的机会,疯狂开始。这时候我们程序员小哥哥就苦了,稍一个不注意,服务器驾崩了,次日头条见。那么为了防止在当天凌晨压死服务器的并发,我们想到了一个很好的策略,一分钟搞不定的事情,我们可以两分钟搞定,至少保证我们的服务器不会瘫痪,就是说,假如我们的服务器并发量是1w左右,那么我们可以限制在9000的并发量,超过这个预警我们就严格限制请求访问量不能做越过这个警戒线,做到削峰或者说是平滑这个爆发点。很快我们程序员

2020-05-30 16:24:33 23547

原创 Redis如何实现刷抖音不重复-布隆过滤器(Bloom Filter)

刷抖音的时候是否曾想过,我们刷过的视频很难在重复刷到那么它到底是如何实现的呢?如果说我们每刷一个视频并且把视频id和用户的id组合成一条数据保存到数据库中每次推荐视频的时候都去数据检测是否已经刷过了,嗯,这样可以实现这个功能,但是存在多个问题,频繁操作数据表对数据库造成很大的负担,每次推荐视频时都得保存数据,人流量一多,数据库很快就扛不住。那么我们可否使用缓存redis中的set来实现呢?当然是可以的,redis4.0版本给我们提供了更加快捷更加节省空间的数据结构--布隆过滤器(Bloom Filt

2020-05-28 23:48:52 13333 5

原创 Redis站点流量统计HyperLogLog

在我们做站点流量统计的时候一般会统计页面UV(独立访客:unique visitor)和PV(即页面浏览量:page view),那么我们最常见的处理方式就是用户点击一次就插入一条数据到数据库,统计的时候通过查询表来达到统计流量的效果。那么我们如果是通过redis来处理,我们可以使用string类型然后自增计数即可达到统计PV,统计UV可以使用set,每个用户id是唯一的可以放到这个集合里,统计的时候只需要执行scard获取集合大小即可。这两种方式都是可以实现站点的流量统计,但是如果说当站点流量非常

2020-05-28 00:43:48 15486

原创 Redis快速扫描Scan

在平时我们维护线上Redis的时候需要从n个key里面找到某些特定规则的key,可能查看某些key可能清理某些不需要的key,可能我们第一印象就是keys这个指令,我们可以使用这个指令匹配我们想要的key,下面我们来试试。keys指令基本用法>msetname1aname2ana1meana2meaOK> keys name*1) "name"2) "name2"3) "name1"> keys na*me1) "name"2) "na1me"3)"na2me...

2020-05-26 23:23:19 8507

原创 Redis之GeoHash

在生活中我们有时候需要点外卖、骑共享单车等等,我们打开软件找到附近餐厅、离我最近的单车,那么他们是怎么快速定位到的呢?我们把地图看作一个二维平面,我们在某个点上然后找到附近10km内的所有餐厅,这时候我们知道求两点直接的距离是需要一个公式,且需要知道两点的x,y轴坐标才能计算出距离,通过计算出距离然后进行排列,那么我们就能过找到离我最近的一个餐厅了。那么这里我们考虑几个问题,我每次搜索的时候需要计算我离餐厅的距离,那么我们能不能把这个距离保存起来呢?如果我保存了,我下次在另一个地方那是不是还得重新计..

2020-05-26 00:29:11 11464

原创 Redis位图

上课签到时间到了,张三老师开始点名了,每点一名同学就新增加一条记录,我们数据库会把这条记录写到学生考勤表里,到学期末考核的时候汇总根据学生迟到次数计算总学分。假设一个班级50个学生,一天4课时,一个星期就要记录1000条记录,那么如果说我们根据学生的学号顺序记录学生签到信息,通过“0”和“1”来表示,“1”就代表学生签到,“0”代表学生迟到,那么我们一个星期只要保存20条数据即可。Redis也有这样的结构名叫位图,位图最小的单位是bit,每个bit是由0或1构成,我们的字符串就是由很多个bit数组组成的

2020-05-24 17:52:58 9872

原创 十大经典排序算法(动态演示+代码)

时间复杂度是指程序执行函数或方法的效率常用大写的O表示,比如执行一个循环我们记做O(n),执行一个加法运算或者执行一个if操作我们记为O(1)​。​时间、空间复杂度比较1 冒泡排序算法思想: 比较相邻的元素。如果第一个比第二个大,就交换他们两个。 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。 针对所有的元素重复以上的步骤,除了最后一个。 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要

2020-05-23 09:51:22 4261

原创 Redis-集合(Set)基础

Redis集合包括Set(无序集合)和ZSet(有序集合),这里的Set实现相当于Java中的HashSet,它内部实现了一个特殊的字典,字典中所有的value都是一个值NULL。下面我们来熟悉下set的常用的命令Set>saddname hello(integer)1>saddnamehello#重复,不能插入(integer)0>saddnamei am ok(integer)3>smembers name"hello""i""am""ok">s...

2020-05-22 19:37:25 215

原创 Redis-字典(hash)基础

Redis的字典数据结构跟Java的HashMap一样,也是数组+链表结构,数组是hash的位置,hash碰撞的值保存到链表种。但是跟HashMap不同的是Redis字典存储的值都是字符串类型的,而HashMap存储的值是所有数据类型常见操作>hset user name mango(ingeter)1>hmset user age 18 gender "男" OK>hlen user (ingeter)3 >hget user name "mango"

2020-05-21 00:33:32 219

原创 Redis-字符串(string)基础

redis是以keyvalue的数据结构存储的,每个key都是唯一的,字符串是redis里面最简单的数据结构,它的内部其实是一个字符数组。redis里面的字符串是一个动态字符数组,有点类似Java里的arrayList,采用预分配冗余的方式来减少内存的频繁分配,内部为当前字符串分配的实际空间 capacity一般要高于实际字符串长度len。当字符串长度小于1MB时,扩容都是加倍现有的空间。如果字符串长度超过1MB,扩容时一次只会多扩1MB 的空间,字符串最大长度为 512MB。下面我们尝试常用的..

2020-05-19 21:06:51 208

原创 Redis-列表(List)基础

Redis的列表是一个双链结构,跟java里面的LinkedList一样,对于链表插入数据非常快时间复杂度为O(1),但是查询需要遍历这个链表时间复杂度为O(n),对于双链表来说既可以从头到尾遍历也可以从尾遍历的双向遍历,这个结构有点跟我们的队列和栈非常相似,该结构常用来做异步队列,将需要延后处理的任务结构体序列化成字符串,放入Redis列表,另一个线程从这个列表中轮询进行处理当然,我们的列表也提供这样的操作,下面我们来试试常见的的命令操作。队列(先进先出)列表是一个先进先出的数据结构,常用于消息队

2020-05-19 21:04:03 913

原创 Tomcat的使用

Tomcat下载tomcat官网:http://tomcat.apache.org安装直接将下载的tomcat压缩包解压即可*注意:此处建议不要安装在有空格或中文目录下卸载直接将解压的文件删除即可目录解析(apache开源项目通用结构)bin 可执行文件conf 配置文件lib 依赖j...

2020-05-06 20:44:40 352

原创 Java代码块

静态代码块首先我们来回顾一下static关键字,static关键字可以修饰类和类的成员还有构造函数,特点就是在类创建对象前加载并且是所有对象共享的资源,比如静态方法可以直接类名打点调用,不需要使用new关键字来创建对象。关于静态方法和非静态方法的比较静态方法:静态方法只可以调用静态成员不可以调用非静态成员 没有this对象非静态方法:非静态方法既可以调用非静态成员也可以调用...

2020-05-05 22:19:36 4805

原创 Redis安装

直接点我网页练习使用Docker安装# 拉取 redis 镜像 > docker pull redis # 运行 redis 容器 > docker run --name myredis -d -p6379:6379 redis # 执行容器中的 redis-cli,可以直接使用命令行操作 redis > docker exec -it myredi...

2020-04-28 17:34:29 159

原创 Scrum敏捷开发

什么是Scrum敏捷开发Scrum是敏捷开发的一种,是一种以人为本,迭代式增量软件开发的过程,以英式橄榄球争球队形(Scrum)为名,因此可以想象,整个团队是高效而富有激情的。以人为本,即Scrum开发特别强调沟通,要求团队所有人员都坐着一起工作,通过高效的沟通解决问题。为什么要敏捷开发传统的软件公司大都是使用瀑布开发模式,流程是以下这样的:瀑布开发模式瀑布开发模式一般都需...

2019-11-12 15:22:09 1070

原创 CAP定理和BASE理论

2000 年的时候,Eric Brewer 教授提出了 CAP 猜想,2年后,被 Seth Gilbert 和 Nancy Lynch 从理论上证明了猜想的可能性,从此,CAP 理论正式在学术上成为了分布式计算领域的公认定理。并深深的影响了分布式计算的发展。CAP定理一个分布式系统不可能同时满足一致性(C:Consistency),可用性(A: Availability)和分区容错性(P:...

2019-10-18 14:42:31 2226

原创 表达式目录树(Expression)

表达式目录树什么是表达式目录树呢?用于表示Lambda表达式逻辑的一种数据结构,表达式树也可以称作表达式目录树,它 将代码表示成一个对象树,而不是可执行的代码。这个跟汇编原理一样,我们找到关键字,把这些语句翻译成机器码,我们这里的关键字就是表达式树里面的节点,然后分析语法词法,最后变成机器可识别的指令。表达式目录树有什么作用呢?我们在使用ef框架的时候经常使用linq,使用linq to ...

2019-07-28 16:33:05 10488

原创 迭代器模式(Iterator Pattern)

C#内置迭代器解析迭代器模式:提供一种方法顺序访问一个聚合对象中的各个元素,且不用暴露该对象的内部表示。迭代器模式又称为游标模式。迭代器模式的结构Iterator(抽象迭代器):定义访问遍历元素的接口,声明便利元素的方法public interface Iterator{ void First(); void Next(); void HasN...

2019-07-27 23:16:20 368

原创 解释器模式(Interpreter Pattern)

解释器模式:给定一个语言,定义它的文法的一种表示,并且定义一个解释器,这个解释器使用该表示来解释语言中的句子。解释器模式结构AbstractExpression(抽象表达式):在抽象表达式中声明了抽象的解释操作,它是所有终结符和非终结符表达式的公共父类。abstract class AbstractExpression{ public abstract string I...

2019-07-27 22:16:23 415

原创 命令模式(Command Pattern)

命令模式(Command Pattern):将一个请求封装为一个对象,从而让你可以用不同的请求对客户进行参数化,对请求排队或者记录请求日志,以及支持可撤销操作。命令模式的结构Command(抽象命令类):提供具体类执行方法和撤销方法的一个模板。abstract class Command{ public abstract void Execute();}Concr...

2019-07-20 21:52:25 261

原创 代理模式(Proxy Pattern)

在电子商城新起的时代里,某宝某东的大型电商平台假货也是非常多而且价格还不菲或是在这些电商平台购不到的一些商品,从而衍生出一种专门从海外进行购物的一群人,我们称之为代购,一般来说,代购是从国内接到一些需求,从而到海外进行选购带回国内的一种中间商。在软件开发过程种有一种设计模式可以提供类似代购的功能,由于一些原因客户端不想直接或者不能直接访问到一个对象,此时添加一个代理类,通过这个代理来间接访问这...

2019-07-20 18:03:08 209

原创 职责链模式(Chain of Responsibility Pattern)

职责链模式(Chain Of Responsibility Pattern):避免将一个请求的发送者和接收者耦合在一起,让多个对象都有机会处理请求,将接受请求的对象连接成一条链,并且沿着链传递请求,知道有一个对象能狗处理它为止职责链模式的结构Handler(抽象处理者):它定义一个处理请求的接口,由于不同的具体处理者处理请求不同,因此在处理者中定义一个处理请求的方法,每个处理者...

2019-07-20 18:02:11 728

原创 C#反射破坏单例

单例大家都不陌生,程序从开启到死亡过程中只能存在一个实例,即存在不可创建,今天给大家介绍一种打破这种模式的方法,在程序运行中创建无数个单例实例对象。关于单例模式模糊或者不懂的可以参考C#单例模式上文我们讲到了反射的基本操作,实例化对象、属性、方法、特性等操作,可以参考C#反射咱们切入正题,单例有两种,一种是程序加载时创建,一种是使用时创建,我们这里主要是创建一个加载时创建的单例。我们...

2019-07-20 10:34:55 10284

原创 net core 中间件(MiddleWare)

定义:中间件是被组装成一个应用程序管道来处理请求和响应的软件组件。上图是由微软提供的一个执行图,我们可以看到有多个中间件,每个中间件请求的时候有个next()方法把职责传递给下一个中间件,这里值得注意的是最后一个中间件没有next方法,也就是终止,然后响应。每一个中间件都有它自己的职责,把各个执行分离开执行完成后传递给下一个,直到全部的都执行完成,这有点像职责链模式。那么它内部是怎么实...

2019-07-18 12:15:04 2403

原创 LINQPad工具-linq、sql、IL优化和转换

今天给大家介绍一个非常强大的linq转换和优化工具,它包含linq、sql、il、表达式树的转换,支持现在的主流数据库,甚至包括nosql(需要下载插件,下文介绍)下载地址百度云盘(不能下载私聊或者留言):链接: https://pan.baidu.com/s/1NT-eqmKtM6TnXi3zuaMWdQ 提取码: te25安装双击这个exe接下来就是下一步下一步的...

2019-07-17 11:44:06 1515 1

原创 .Net字符暂存池(String Intern Pool)

字符串在.Net中既有值类型的特点又有引用类型的特点,字符类型也称作为不可变对象类型,字符串类型在使用上可以说占很大的比例,每次使用的时候都要重新开辟一个新的空间,这样会大量消耗内存,所以微软给我们一个名为String Intern Pool的字符暂存池,我在重复使用这个字符串的时候不需要重新开辟一个新的空间,只需要从这个池子里面获取即可。我们在新建一个字符的时候,首先去暂存池获取有没有这...

2019-07-16 17:12:43 8636

原创 享元模式(Flyweight Pattern)

我们知道机器语言识别的只有0和1,我把这两个元素存到一个实例里面,每次使用的时候去调用它,而不是使用的时候直接去new一个对应的对象,这样是非常消耗内存的,我们把这个收藏1和0的容器称之为享元库。享元模式(Flyweight Pattern):运用共享技术有效地支持大量细粒度对象的复用享元模式的结构Flyweight(抽象享元类):抽象享元类通常是接口或者抽象类声明具体享元类...

2019-06-30 12:27:59 292

原创 外观模式(Facade Pattern)

mango公司最新研发了一块app刚刚发布就受到了用户的青睐,用户也提出许多反馈,产品经理根据用户反馈最多的问题来提出迭代一个版本:用户反馈咱们的app主题单一,为了广大用户的需求,需要对app的主题进行扩充。开发小组进行讨论,如果我们添加不同的主题,每个页面就得新增不同的主题页面这样太浪费时间并且工作量巨大。改变主题主要是改变页面的样式,我们只需要多做几套样式,根据用户的切换或者配置给予相应...

2019-06-30 09:26:16 259

dnspy反编译工具c#

dnspy反编译工具c#

2022-08-30

广告终结者使用说明和资源

广告终结者是一个效果很好的弹出广告清理工具,适用于IE浏览器的用户。安装后可以随浏览器启动而自动运行,使用方法非常简单。只需要点击状态条上的K字图标就可以允许与禁止关闭弹出窗口。注册版还提供关闭flash广告与网页警告提示的功能。

2020-07-05

手机端debug工具

我们上线灰度环境测试手机app的时候,有时候不知道接口返回的数据,也不知道是不是我们操作的那样,所以我们需要一个跟pc端调试一样的debug工具,那么这个是你需要的

2018-10-16

C#反编译器dnSpy最新版

dnSpy是一款非常强大的.net语言编程工具,软件能够反汇编编译工具。dnSpy专门针对.NET语言的复杂性,提供了一个更好的替代库的文档,还能够恢复丢失或不可用的源代码,解决定位性能问题,软件可以帮助开发人员分析依赖关系、检查混淆,软件是一款方便实用简单。 适用平台:WinXP/Win2K/Vista/Win7/Win8/Win10

2018-04-26

空空如也

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

TA关注的人

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