自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(64)
  • 资源 (1)
  • 收藏
  • 关注

原创 RPC框架实战之手写RPC框架 第四章 个人总结复习

第四章增加Kryo序列化器,上一章中使用JSON序列化器有一个问题,就是如果反序列化的是对象中有Object类型的属性,反序列化会出错,通常会把Object属性直接反序列化为String类型,因此还需要其他参数辅助序列化,并且JSON序列化器是基于字符串(JSON串)的,占用空间大并且速度慢。Kryo是一个快速高效的Java对象序列化器,特点就是高性能、高效、易用。它是基于字节的序列化,对空间利用率高,在网络传输时可以减小体积,并且在序列化时记录属性对象的类型信息,因此在反序列化时不会出现类型错误的情况

2022-02-24 11:15:25 1508

原创 RPC框架实战之手写RPC框架 第三章 个人总结复习

第三章使用Netty传输数据,使用效率更高的Nio方式传输数据,因为原先使用的是传统BIO方式,现在为了支持Netty方式,需要抽象出接口,增加扩展性,这样也满足了设计模式六大原则中的依赖倒置原则。抽象为接口RpcServer和RpcClient抽象为接口NettyServer实现RpcServer,NettyClient实现RpcClientpublic interface RpcClient{ Object sendRequest(RpcRequest rpcRequest);}

2022-02-24 11:14:19 786

原创 Netty面试题整理(个人复习)

Netty面试题整理1、什么是Netty?Netty是基于NIO开发的网络通信框架,使用Netty可以极大的简化TCP和UDP套接字服务器等网络编程,并且性能以及安全性等很多方面都更好。平常使用的开源框架,Dubbo、RocketMQ、ES等都使用到了Netty。大部分微服务框架底层涉及到网络通信的部分都是基于Netty来做的。2、BIO、NIO、AIO的区别?BIO:同步阻塞模式,读取写入数据在同一个线程内阻塞等待完成,客户端数量不高的情况下是没有问题的,但如果是高并发场景下有有些无能为力了

2022-02-21 15:36:24 4345

原创 Redis面试题整理(二)Redis的线程模型,如何保证Redis中存的是热点数据,数据库和缓存的数据不一致问题

9、Redis的线程模型Redis内部使用文件事件处理器file event handler,这个文件事件处理器是单线程的,所以Redis才叫单线程的模型。采用IO多路复用机制同时监听多个Socket,根据Socket上的事件来选择对应的事件处理器进行处理。文件事件处理器的结构包含四个部分:多个SocketIO多路复用程序文件事件分派器事件处理器(连接应答处理器、命令请求处理器、命令回复处理器)多个Socket可能会并发的产生不同的操作,因为一个服务器可能会连接多个Socket,每个操作对

2022-02-18 19:10:10 550

原创 Redis面试题复习整理(一)缓存穿透、缓存击穿、缓存雪崩、内存淘汰策略、Redis持久化机制

1、Redis有哪些数据结构基本的数据结构有:String字符串List列表Hash哈希对象Set集合SortedSet有序集合,set基础上增加了分值。高级数据结构有:Hyper log log,不精确的去重计数功能,比较适合用来做大规模的去重统计,例如网站的UV,访问量。Bitmap,位图,支持按bit为来存储信息,可以用来实现布隆过滤器。Stream,主要用于消息队列,类似于Kafka,可以认为是pub/sub的改进版。提供了消息的持久化和主备复制功能,可以让任何客户端访问任

2022-02-18 11:07:46 1053

原创 RPC框架实战之手写RPC框架 第二章 个人总结复习

第二章第一章中我们的服务端测试代码中只能注册一个服务,这一章对其进行优化,可以注册多个服务。服务注册表首先需要一个注册表来存放注册的服务,并且可以返回需要的服务实例。package com.lany.rpc.registry;/** * @author liuyanyan * @date 2021/12/22 14:10 */public interface RpcRegistry { <T> void register(T service); Object

2022-01-15 16:35:38 1792

原创 装饰器模式

装饰器模式Decorator Pattern在不改变原有类的基础上,给其增加新的功能。就像人们冬天穿棉袄,夏天穿短袖,以应对不同的需求,而人本身并没有改变,只给其增加不同的装饰来满足不同的需求。装饰器类需要继承原有类的同时还要关联原有类,并在有参构造中传入原有类。FilterInputStream就是一个装饰器类。想对InputStream进行扩展增加一些功能,使用装饰器模式对InputStream进行关联publicclass FilterInputStream extends InputSt

2022-01-12 18:41:44 133

原创 RPC框架实战之手写RPC框架 第一章 个人总结复习

第一章第一部分首先实现简单的RPC远程通信,流程如下:客户端调用接口的方法,通过代理将要调用的方法信息传输给服务端服务端通过socket监听,当接收到数据后,就创建一个线程去执行通过客户端传输过来的数据反射找到对应的方法,并执行获取到对应的数据将数据封装进response中返回给客户端客户端收到数据后打印。因为是简单的实现,因此直接指定了服务端的地址,后续会进行优化完善。让我们开始吧!项目的整体模块如下:myrpcrpc-api:接口相关的类rpc-common:通用模块,例

2022-01-12 15:12:08 1899

原创 netty之Tomcat

netty之Tomcat创建一个Tomcat,使用原生api手写一个简单的Tomcat服务器,需要的东西有:request和response,分别处理请求和响应,当用户发送http请求时,request负责接收发送过来的请求体,然后进行解析,调用对应的servlet进行业务处理,然后通过response响应给客户端。首先需要定义一个servlet负责处理get请求或post 请求。用户通过创建servlet继承我们提供的servlet来自定义自己的方法,执行自己的业务逻辑还需要创建request

2021-12-24 22:30:40 253

原创 LeeCode 142. 环形链表II (快慢双指针+数学运算 巧妙)

LeeCode 142. 环形链表II给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。不允许修改 链表。示例 1:输入:head = [3,2,0,-4], pos = 1

2021-12-01 22:39:59 113

原创 操作系统学习 面试准备(分页,分段,页面置换算法,快表)

操作系统的内存管理主要做什么?负责内存的分配和回收(malloc:申请内存,free:释放内存)将逻辑地址转化为相应的物理地址分页分页就是把内存空间划分为大小相等且固定的块,作为主存的基本单位。因为程序数据存储在不同的页面中,而页面又离散的分布在内存中,因此需要一个页表来记录映射关系,以实现从页号到物理地址块号的映射。访问分页系统中内存数据需要两次的内存访问(一次是从内存中访问页表,从中找到指定的物理块号,加上页内偏移得到实际物理地址;第二次就是根据第一次得到的物理地址访问内存取出数据)。

2021-12-01 22:22:06 1064

原创 LeetCode 19. 删除链表的倒数第N个结点(快慢双指针)

LeetCode 19. 删除链表的倒数第N个结点给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。示例 1:输入:head = [1,2,3,4,5], n = 2输出:[1,2,3,5]示例 2:输入:head = [1], n = 1输出:[]示例 3:输入:head = [1,2], n = 1输出:[1]这题的解法很巧妙,定义两个指针,一个快指针a,一个慢指针b,首先定义一个虚拟节点,放在头结点之前,然后a,b分别指向这个虚拟节点,开始时让这个快指针先走

2021-11-30 22:31:50 475

原创 剑指Offer 52.两个链表的第一个公共节点

剑指Offer 52.两个链表的第一个公共节点输入两个链表,找出它们的第一个公共节点。如下面的两个链表:在节点 c1 开始相交。示例 1:输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3输出:Reference of the node with value = 8输入解释:相交节点的值为 8 (注意,如果两个列表相交则不能为 0)。从各自的表头开始算起,链表 A 为

2021-11-30 22:22:10 79

原创 操作系统学习 面试准备(死锁产生的条件,死锁避免,死锁预防)

死锁产生的必要条件互斥:每个资源要么已经分配给了一个进程,要么就是可用的。占有和等待:已经得到了某个资源的进程可以在请求新的资源。不可抢占:已经分配给一个进程的资源不能强制性地被抢占,它只能被占有它的进程显式地释放。环路等待:有两个或者两个以上的进程组成一条环路,该环路中的每个进程都在等待下一个进程所占有的资源。处理方法鸵鸟策略死锁检测与死锁恢复死锁预防死锁避免鸵鸟策略鸵鸟策略就是不采取任何措施,因为解决死锁问题的代价很高,因此这种策略可以获得更高的性能。死锁检测和恢复死锁

2021-11-28 17:30:01 664

原创 操作系统学习笔记 面试准备(进程通信)

进程通信进程同步与进程通信不一样,区别在于:进程同步:控制多个进程按一定顺序执行。进程通信:进程间传输信息。进程通信是一种手段,而进程同步是一种目的。也可以说,为了能够达到进程同步的目的,需要让进程之间进行通信,传输一些进程同步所需要的信息。关于进程间的通信有三个问题:一个进程如何传递消息给其他进程如何确保两个或多个进程间不会相互干扰,例如:两个航空公司都试图为不同的顾客抢购飞机上的最后一个座位。数据的先后顺序问题,如果进程A产生数据并且进程B打印数据,则进程B打印数据之前需要先等A产

2021-11-28 14:50:09 328

原创 操作系统学习笔记 面试准备(进程同步,进程的状态,进程调度算法)

操作系统是什么?管理计算机硬件和软件资源的程序内核与外壳分别是什么?内核是能操作硬件的程序内核管理 系统的进程、内存、设备驱动程序、文件、网络等,决定着系统的性能和稳定性外壳就是围绕内核的应用程序系统调用是什么,有哪几类根据进程访问资源的特点,可以将进程在系统上的运行分为两个级别:用户态:用户态下的进程可以直接读取用户程序的数据内核态:内核态下的进程几乎可以访问计算机的任何资源,不受限制我们运行的程序基本都是运行在用户态,如果需要调用操作系统提供的内核态级别的功能的时候,就需要使用系

2021-11-27 18:33:52 542

原创 Elasticsearch学习笔记(二)

高级查询查看所有文档查看匹配的文档、向ES服务器发送GET请求:localhost:9200/shopping/_search{ "query":{ "match":{ "title":"西游记" } }}查看全部的文档{ "query":{ "match_all":{ } }}分页查询{ "query":{ "ma

2021-11-11 22:55:35 1519

原创 Elasticsearch学习笔记(一)创建索引,添加文档

ElasticSearch学习笔记Elasticsearch学习笔记(一)Elasticsearch是一个分布式的、RESTful风格的搜索和数据分析引擎。安装Elasticsearch安装Elasticsearch,这里选择在Windows电脑中安装。[Elasticsearch官网Windows下载地址](Past Releases of Elastic Stack Software | Elastic)下载完之后打开解压文件,进入文件夹进入到bin目录打开elasticsearch.ba

2021-11-10 19:49:13 4542

原创 秒杀系统学习笔记,限时抢购,抢购接口隐藏

限时抢购的实现使用Redis来记录秒杀商品的时间,对秒杀过期的请求进行拒绝处理!将秒杀商品放入Redis中并设置过期时间使用String类型以kill+商品id的形式作为key以商品id作为value设置一定的过期时间(这里设置为180秒)引入Redis依赖<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-d

2021-11-05 20:31:59 532 1

原创 秒杀系统学习笔记(编程不良人)

秒杀系统学习笔记秒杀系统秒杀场景电商抢购限量商品买演唱会门票或者票抢座12306…保护措施乐观锁和悲观锁令牌桶限流Redis缓存消息队列异步处理订单…防止超卖业务分析创建数据库-- ------------------------------ Table structure for stock-- ----------------------------DROP TABLE IF EXISTS `stock`;CREATE TABLE `stock` (

2021-11-03 17:09:59 407 4

原创 Redis面试知识点(缓存穿透、缓存击穿、缓存雪崩及解决办法,主从复制)

Redis复习知识点(二)缓存穿透查询根本不存在的数据,使得请求直达存储层,导致其负载过大,甚至宕机解决方案:缓存空对象存储层未命中后,仍然将空值存入缓存层再次访问该数据时,缓存层会直接返回空值。布隆过滤器将所有存在的key提前存入布隆过滤器,在访问缓存层之前,先通过过滤器拦截,若请求的是不存在的key,则直接返回空值。缓存击穿某一个热点数据,访问量非常大。在器缓存失效瞬间大量请求直达存储层,导致服务崩溃。解决方案加互斥锁对数据的访问加互斥锁,当一个线程访问该数据时

2021-10-14 22:43:50 90

原创 Redis面试知识点(常见数据结构,淘汰策略,持久化机制,使用场景,AOF重写原理)

Redis复习知识点(一)Redis是单线程还是多线程的?redis4之前redis是完全单线程的redis4.0时引入了多线程,但是只是用来做后台处理,核心流程还是完全单线程的。(接受命令、解析命令、执行命令、返回结果等)redis6.0多线程用于网络IO阶段,在接受命令和写会结果阶段,执行命令时还是单线程的。redis是基于内存的,redis的瓶颈最有可能是机器的内存大小或者网络带宽。,使用多线程会造成额外的性能开销为什么redis使用单线程也很快?Redis是基于内存的操作Red

2021-10-14 20:43:03 102

原创 设计模式之代理模式 静态代理 动态代理

设计模式之代理模式静态代理package designpattern.proxy;public class staticsubject implements Subject { private ConcretSubject concretSubject; @Override public void request() { concretSubject = new ConcretSubject(); System.out.println("前置

2021-08-30 14:34:35 213

原创 设计模式之单例模式

饿汉式(静态变量)//饿汉式(静态变量)public class singleton01 { public static void main(String[] args) { single single = designpattern.single.getInstance(); single single2 = designpattern.single.getInstance(); System.out.println(single == sing

2021-08-24 20:09:36 71 1

原创 类加载机制(五)双亲委派模型,类的生命周期

类加载机制(五)类的生命周期类的加载过程CLass文件需要加载到虚拟机中才能运行和使用,那么虚拟机是如何加载这些Class文件呢?系统加载Class类型的文件主要三步:加载、连接、初始化。连接过程有可分为验证、准备、解析。加载(Loading)类加载过程的第一步,主要完成一下三个事情:通过一个类的全限定名来获取定义此类的二进制字节流。将这个字节流所代表的的静态存储结构转化为方法区的运行时数据结构。在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据

2021-08-22 21:19:45 137

原创 JVM垃圾收集器(三)

JVM垃圾收集器(三)垃圾回收(GC)线程与应用线程保持相对独立,当系统需要执行垃圾回收任务时,先停止工作线程,然后命令GC线程工作,以串行模式工作的收集器,称为Serial Collector,即串行收集器;与之相对的是以并行模式工作的收集器,称为Paraller Collector,即并行收集器。并行收集:指多条垃圾收集线程并行工作,但此时用户线程仍处于等待状态。并发收集:指用户线程与垃圾收集线程同时工作(不一定是并行的,会交替执行)。用户程序在继续运行,而垃圾收集程序运行在另一个CPU上。吞吐

2021-08-21 10:50:01 69

原创 Java内存回收(二)垃圾收集算法、分代垃圾回收

垃圾收集算法标记清除算法标记清除算法分为标记,清除两个步骤,首先标记算法对可回收的对象进行标记,然后垃圾收集器根据标记清除相应的内容。不是说将内存空间的字节清零,而是记录下这段内存的其实结束地址,下一次分配内存的时候,会直接覆盖这段内存。标记清除算法是最基础的算法,后续收集算法大多都是标记清除算法为基础的,对其缺点进行改进的主要有两个缺点:执行效率不稳定,如果Java堆中包含大量对象,并且其中大部分是需要被回收的,这时必须进行大量标记和清除的动作,导致标记和清除两个过程会的执行效率对随着数

2021-08-17 23:15:31 147

原创 JVM垃圾回收(一) 强引用、软引用、弱引用、虚引用

Java垃圾回收(一)如何判断一个对象可以被回收?引用计数算法如果一个对象被其他对象所引用,则该对象的引用计数+1,如果该对象被多次引用,则该对象的引用计数没被引用一次就+1,如果有对对象不在引用该对象,则该对象的引用计数-1,当该对象的引用计数为0时,说明该对象可以被回收。缺点:如果出现循环引用的情况,例如:两个对象互相引用,且没有其他对象引用他们,就会导致这两个对象无法被回收,从而出现内存泄漏的问题。内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内

2021-08-17 17:16:55 246

原创 【剑指offer】第07题,重建二叉树

【剑指offer】第07题,重建二叉树输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如,给出前序遍历 preorder = [3,9,20,15,7]中序遍历 inorder = [9,3,15,20,7]返回如下的二叉树: 3 / \ 9 20 / \ 15 7限制:0 <= 节点个数 <= 5000题解:含注释class Solution { int[

2021-06-12 23:11:09 108 2

原创 Spring面试题复习(一)

Spring面试题复习(一)一、Spring是什么?Spring是一个轻量级的开发框架,常说的Spring框架,就是指Spring Framework,它是很多模块的集合,这些模块可以帮助我们开发人员简化开发,这些模块有核心容器、数据访问/继承、web、AOP、消息和测试模块。主要有以下几个重要的模块:Spring Core:核心类库,Spring框架几乎所有的功能都依赖于此类库,主要提供IOC依赖注入功能。Spring Context:提供框架式的Bean访问方式,以及企业级功能(定时任务等);

2021-06-12 20:44:58 279

原创 什么是JDBC?

什么是JDBC?JDBC(Java Database Connectivity),Java数据库连接,是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法。JDBC API主要位于JDK中的java.sql包中(之后扩展的内容位于javax.sql包中)包括:DriverManager:负责加载各种不同的驱动程序,并根据不同的请求,向调用者返回相应的数据库连接(connection)Driver:驱动程序,将自身加载到DriverManager中

2021-06-11 22:49:43 1054

原创 【已解决】springboot整合redis,连接redis遇到的问题

springboot整合redis,连接redis遇到的问题在学习redis的时候,使用springboot连接redis时出现的问题:首先,连接虚拟机上的redis服务时,需要把虚拟机的防火墙关闭这样外部才能访问到redis命令如下:systemctl status firewalld.service查看虚拟机的防火墙systemctl stop firewalld.service关闭虚拟机的防火墙关闭之后,还需要将redis-conf文件中的protected-mode yes设置为n

2021-05-29 15:48:12 1025

原创 LeetCode84. 柱状图中最大的矩形(单调栈)

LeetCode84. 柱状图中最大的矩形给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。求在该柱状图中,能够勾勒出来的矩形的最大面积。以上是柱状图的示例,其中每个柱子的宽度为 1,给定的高度为 [2,1,5,6,2,3]。图中阴影部分为所能勾勒出的最大矩形面积,其面积为 10 个单位。示例:输入: [2,1,5,6,2,3]输出: 10一、暴力解法class Solution { public int largestRectangle

2021-05-19 18:32:00 92

原创 LeetCode42. 接雨水(单调栈、动态规划、暴力解法、双指针)

LeetCode42. 接雨水给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。示例 1:输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]输出:6解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 示例 2:输入:height = [4,2,0,3,2,5]输出:9提示:n == height.length0

2021-05-19 18:26:18 256

原创 计算机网络之物理层、链路层、网络层

计算机网络之物理层、链路层、网络层OSI参考模型:应用层:应用层是直接为应用进程提供服务的。其作用是在实现多个系统应用进程相互通信的同时,完成一系列业务处理所需的服务。包括文件传输、电子邮件远程登录和远端接口调用等协议。表示层:向上对应用进程服务,向下接受会话层提供的服务,表示层位于OSI标准模型的第六层,表示层的主要作用就是将设备的固有数据格式转换为网络标准传输格式。数据处理(编码解码、加密解密等)。会话层:会话层位于OSI标准模型的第五层,他是建立在传输层之上,利用传输层提供的服务建立和维持会

2021-05-15 21:52:34 7632

原创 Synchronized锁升级过程

Synchronized锁升级过程锁在jdk1.6之前只有两种状态:无锁和有锁两种状态,在jdk1.6之后,对synchronized进行了优化,增加了两种状态,现在锁一共有四种状态:无锁、偏向锁、轻量级锁、重量级锁。无锁也是一种状态,锁的类型和状态存在对象头的MarkWord中,在申请锁、锁升级等过程中JVM都需要读取对象的MarkWord中的数据。偏向锁为什么要引入偏向锁呢?因为进过HotSpot的作者大量的研究发现,大多数情况下,锁不仅不存在多线程竞争,而且总是由同一个线程多次获得,为了让线

2021-05-05 16:32:29 137

原创 Synchronized同步的原理

Synchronized同步的原理Java中利用synchronized实现同步基础,可以有一下三种形式:对于普通同步方法,锁是当前实例对象。对于静态同步方法,锁是当前类的Class对象对于同步方法块,锁是Synchronized括号里配置的对象1.synchronized同步语句块的情况public class SynchronizedDemo { public void method() { synchronized (this) { System.out.println("syn

2021-05-05 12:50:37 613

原创 使用PicGo+Gitee+Typora搭建个人图床

使用PicGo+Gitee+Typora搭建个人图床一、首先下载 picgo下载.exe结尾的文件二、打开picgo安装插件三、打开gitee,创建仓库四、打开设置,获取个人token个人token只能在第一次创建时查看,因此需要记住自己的个人token五、打开图床设置,找到giteerepo:为gitee用户名+仓库名六、打开typora进行设置进入偏好设置,进入图像,选择picgo的安装位置,接着点击验证图片上传选项,可以测试是否设置成功。以后当截完图后,ctrl+v粘

2021-05-05 11:57:41 149

原创 使用Notepad++查看class文件

使用Notepad++查看class文件notepad++查看class文件需要下载HEX-Editor插件打开插件管理,搜索HEX-Editor,版本号为0.9.5安装之后就可以查看字节码文件了。打开要查看的class文件,按快捷键 Ctrl+Alt+Shift+H 用16进制的方法查看。只看第一行数据,前面8个字节CA FE BA BE 是固定的,之后4个字节00 00 是次版本号,次版本号后面的4个字节00 34 是jdk的版本号,如我这里使用的是jdk1.8。以下为版本对照表:

2021-05-05 10:43:51 3520 1

原创 【LeetCode176】查询第二高的薪水

【LeetCode176】第二高的薪水MySQL在查询的字段没有内容时,返回null编写一个 SQL 查询,获取 Employee 表中第二高的薪水(Salary) 。+----+--------+| Id | Salary |+----+--------+| 1 | 100 || 2 | 200 || 3 | 300 |+----+--------+第一种解法:子查询加分页查询当使用select distinct Salary from Employ

2021-05-03 18:01:54 71

jsp九大内置对象.xmind

JSP九大内置对象思维导图,对正在学习JSP的同学很有帮助。session、request、response、application等等。

2020-07-20

空空如也

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

TA关注的人

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