自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 JavaEE 初阶篇-深入了解 I/O 高级流(缓冲流、交换流、数据流和序列化流)

缓冲流(Buffered Stream)来提高 I/O 操作的效率,缓冲流是对字节流和字符流的一种封装,通过缓冲区来减少 I/O 操作的次数,从而提高程序的运行效率。简单来说,InputStreamReader 将读取的字节流转化为字符流,并且如果读取的是用 GBK 编码集进行编码的,在 UTF 环境下进行编码时,则需要指定用 GBK 编码集进行编码。序列化流是 Java I/O 中的一种特殊流,用于将对象转换为字节序列以便存储或传输,或将字节序列转换回对象。主要是为了,方便取数据而不是给程序员看的。

2024-04-26 20:12:30 832 41

原创 JavaEE 初阶篇-深入了解 UDP 通信与 TCP 通信(综合案例:实现 TCP 通信群聊)

先创建 ServerSocket 类,用有参构造器 ServerSocket(int port) 创建指定端口号的对象,再用 accept() 方法来等待接收来自客户端发送来的连接请求,客户端与服务端连接完毕之后,就会返回一个 Socket 对象给服务端,该 Socket 对象可以理解为管道的服务器的一端,客户端已经有 Socket 对象了,该对象就可以理解为管道的客户端的一端。用于创建客户端、服务端。由于 IP 的限制(IP 为内网),不能让其他的机器连接目前的机器,所以只能本机的程序连接本地的程序。

2024-04-25 15:34:53 1465 64

原创 JavaEE 初阶篇-深入了解网络通信相关的基本概念(三次握手建立连接、四次挥手断开连接)

第一次握手(SYN):客户端向服务器发送一个带有 SYN 标志的数据包,表示请求建立连接。此时客户端进入 SYN_SENT 状态。简单来说,第一次握手可以说明:客户端此时是否具备发消息的能力。第二次握手(SYN + ACK):服务器接收到客户端发送的 SYN 数据包后,向客户端发送一个带有 SYN 和 ACK 标志的数据包,表示确认收到请求,并同意建立连接。此时服务器进入 SYN_RECV 状态。简单来说,第二次握手可以说明:假设服务端收到了来自客

2024-04-24 15:06:06 1185 63

原创 JavaEE 初阶篇-深入了解 I/O 流(FileInputStream 与 FileOutputStream 、Reader 与 Writer)

如果文件已存在,会覆盖原有内容,也可以给构造器中再传入一个参数 true ,以支持继续追加,不会覆盖原有的内容。每次调用 read() 方法会读取一个字节,并返回读取的字节数据(以 int 类型表示,范围为 0 到 255),如果已到达文件末尾,则返回 -1。如果文件过大,创建的字节数组也会过大,可能引起内存溢出。字符输出流写出数据后,必须刷新流,或者关闭流,写出去的数据才能生效。定义一个与文件一样大小的字节数组,一次性读取完文件的全部字节。使用字节流读取中文,如何保证输出不乱码,怎么解决?

2024-04-21 22:31:12 1723 95

原创 JavaEE 初阶篇-深入了解 File 文件操作(实现文件搜索、非空文件夹删除)

在 Java 中,File 类是用于表示文件和目录路径的类,它提供了一组方法来操作文件系统中的文件和目录。File 类位于 java.io 包中,是 Java 中处理文件和目录的基本类之一。文件是非常重要的存储方式,在计算机硬盘中,即便断电,或者程序终止了,存储在硬盘文件中的数据也不会丢失。通过 File 类可以创建文件对象,从而获取文件信息(大小,文件名,修改时间),判断文件的类型,删除文件/文件夹等等。重点要注意的是:File 类只能文件本身进行操作,不能读写文件里面存储的数据。

2024-04-21 18:26:49 1114 35

原创 Java 算法篇-深入了解 BF 与 KMP 算法

KMP 是一种高效的字符串匹配算法,用于在一个主串中查找一个模式串的出现位置。KMP 算法的核心思想是利用已匹配的信息来尽量减少不必要的比较,从而提高匹配效率。KMP 算法的时间复杂度为 O(m+n),其中 m 是主串的长度,n 是模式串的长度。相比于 BF 暴力匹配算法,KMP 算法具有更高的效率,尤其在处理大规模文本匹配时表现优异。简单来说,KMP 算法比 BF 算法有更高的效率,是 BF 一个升级的算法。

2024-04-19 17:38:58 2070 67

原创 Java 笔试强训篇- Day1

他每次“点击”,可以把字符串中相邻两个相同字母消除,例如,字符串"abbc"点击后可以生成"ac"。牛牛想把字符串变得尽可能短。他想知道,当他点击了足够多次之后,字符串的最终形态是什么?一个字符串,为“点击消除”后的最终形态。若最终的字符串为空串,则输出0。一个字符串,仅由小写字母组成。(字符串长度不大于300000)但相同而不相邻、不相同的相邻字母都是不可以被消除的。牛牛拿到了一个字符串。

2024-04-16 16:15:46 1986 33

原创 JavaEE 初阶篇-线程安全的集合类、多线程环境使用 ArrayList、队列、哈希表(HashMap 、ConCurrentHashMap 、HashTable 的区别)

只对写操作进行加锁,加锁的方式仍然是 synchronized ,但是不是锁整个对象,而是“锁桶”,每一个链表的头节点作为锁对象,大大降低了锁冲突的概率。由于哈希表是由数组与链表或者红黑树组成的,数组的长度很长,因此相对链表的长度来说,链表的长度就很短了,所以在多线程中,对数组中的某一个链表大概率是不会冲突的,因此即使每一个链表都上锁了,这个锁也大概率是偏向锁,大概率是没有加锁和解锁的开销。扩容期间,新老数组同时存在。是一个线程安全的集合类,所有对 HashTable 的操作都是同步的,即线程安全的。

2024-04-14 22:33:41 1375 23

原创 JavaEE 初阶篇-深入了解 CAS 机制中的 ABA 问题、synchronized 加锁过程、 ReentrantLock 与 synchronized 的区别、常见信号量操作等

举个例子讲述 ABA 的问题:假设:现在有两个线程 T1、T2 ,对共享变量 num 进行操作,num 的初识值为 A。接下来,T1 线程想要将 num 的值改为 Z ,根据 CAS 机制可知,首先将 num 从主内存中读取到 T1 线程的工作内存中,接着就是比较当前主内存的 num 中的值与工作内存中的值是否相同。如果主内存 num 的值还是 A 时,则默认会认为没有其他线程“动过”该变量,这时就可以将 num 的值改为 Z 后,交换到主内存中。

2024-04-14 20:38:22 839 1

原创 JavaEE 初阶篇-深入了解 CAS 机制与12种锁的特征(如乐观锁和悲观锁、轻量级锁与重量级锁、自旋锁与挂起等待锁、可重入锁与不可重入锁等等)

轻量级锁和重量级锁是 Java 中用于实现同步的两种锁机制,用于保护共享资源在多线程环境下的访问。它们的设计目的是为了在不同情况下提供更高效的并发控制。synchronized 是轻量级锁也是重量级锁。自旋锁和挂起等待锁是两种不同的锁机制,它们在处理线程同步和互斥时有不同的实现方式和特点。synchronized 是自旋锁也是挂起锁。公平锁和非公平锁是两种不同的锁策略,它们主要影响了锁的获取顺序和公平性。synchronized 是非公平锁。

2024-04-12 22:04:08 1680 101

原创 JavaEE 初阶篇-深入了解定时器、工厂模式和比较器

定时器(Timer)是 Java 中用于执行定时任务的工具类,可以在指定的时间点执行某个任务,也可以按照一定的时间间隔重复执行任务。定时器提供了一种简单而有效的方式来安排任务的执行。定义一个任务类 MyTask ,成员变量有Runnable 类型 runnable 变量long 类型的 time 变量。利用构造方法获取值即可。其中换算成具体什么时间执行。该 Task 类需要实现Comparable 接口重写 compareTo() 方法。

2024-04-11 17:35:10 1358 59

原创 JavaEE 初阶篇-深入了解线程池(线程池创建、线程池如何处理任务)

假设用户发起一个请求,后台就需要创建一个新线程来处理,下次新任务来了肯定又要创建新线程处理的,而创建新线程的开销是很大的,并且请求过多时,肯定会产生大量的线程出来,这样会严重影响系统的性能。该方法创建出来的线程池特点为,当任务越多时候,线程池中的线程数量也会随之增加。很惊奇的发现,核心线程竟然是 0 个,而临时线程数量的最大值是非常非常大的,如果线程任务执行完毕且空闲了 60 s则会被回收掉。将 Runnable 类型的任务交给线程池,线程池就会自动创建线程,自动执行 run() 方法且自动启动线程。

2024-04-07 17:28:58 2014 99

原创 JavaEE 初阶篇-生产者与消费者模型(线程通信)

实现生产者,就是实现一个 put 方法,先判断数组中的 size 与 数组大小关系,若 size >= arr.length 时,先唤醒其他全部线程,然后当前线程则进入等待状态;生产者与消费者之间必须进行有效的同步和协调,以避免生产者在缓冲区满时继续生产物品,或消费者在缓冲区为空时尝试消费物品,从而导致竞争条件和数据不一致的问题。循环数组的实现思路,定义三个变量:当前存储的个数 size ,头队列的索引也是取出数据的索引:head 和 尾队列的索引也是放入数据的索引处:tail。

2024-04-06 20:38:21 1500 55

原创 JavaEE 初阶篇-深入了解单例模式(经典单例模式:饿汉模式、懒汉模式)

单例模式是一种常见的设计模式,其核心思想是确保一个类只有一个实例,并提供一个全局访问点来访问这个实例。单例模式通常用于需要全局访问点且只需要一个实例的情况。单例特点包括:1)一个类只有一个实例对象。2)提供全局访问点,允许其对象访问这个实例。3)通过静态方法或静态变量实现。常见的单例模式实现方法包括:1)饿汉式单例:在类加载时即创建实例。2)懒汉式单例:在第一次使用时创建实例。使用单例模式的好处:使用单例模式可以避免多次实例化对象,节省内存资源,并且提供一个统一的访问点,方便管理和维护。

2024-04-02 15:08:32 2685 79

原创 JavaEE 初阶篇-深入了解多线程安全问题(指令重排序、解决内存可见性与等待通知机制)

指令重排序是指编译器或处理器为了提高性能,在不改变程序执行结果的前提下,可以对指令序列进行重新排序的优化技术。这种优化技术可以使得计算机在执行指令时更高效地利用计算资源,提高程序的执行效率。在多线程编程中,由于线程之间的执行是并发的,每个线程有自己的工作内存,共享变量存储在主内存中,线程在执行过程中会将共享变量从主内存中拷贝到自己的工作内存中进行操作,操作完成后再将结果写回主内存。这里的工作内存指的是:寄存器或者是缓存。线程的等待通知机制是多线程编程中常用的一种同步机制,用于实现线程间的协作和通信。

2024-04-01 11:56:26 1496 55

原创 JavaEE 初阶篇-深入了解多线程安全问题(出现线程不安全的原因与解决线程不安全的方法)

死锁的四个必要条件:互斥条件、不可剥夺条件、请求保持条件、循环等待条件。何如避免死锁?对于不可剥夺条件来说:如果一个线程无法获取资源,那么释放线程所持有的资源;对于请求保持条件来说:一次性获取该线程所有资源;对于循环等待条件来说:按照顺序获取资源。

2024-03-30 19:31:40 1526 64

原创 JavaEE 初阶篇-深入了解多线程等待与多线程状态

t1.start() 立即创建 t1 线程,再 t2.start() 创建线程,t1 没有任何阻塞就会直接执行代码,而 t2 遇到了阻塞,需要等待 t1 执行完毕之后,t2 才会解除阻塞,同时由于 main 线程阻塞了,需要等待 t2 执行完毕,当 t2 执行完毕之后,main 线程解除阻塞了,执行 main 线程中的代码。main 线程调用 thread.join() ,就会阻塞 main 线程继续执行,会让 thread 线程执行完毕之后,main 线程解除阻塞,继续执行下去。

2024-03-29 16:20:35 1510 65

原创 后端基础篇- 社区 IDEA 手动 Maven 创建 SpringBoot 项目、Maven 安装与配置环境变量、IDEA 集成 Maven

一定要去看看 maven 配置中 JDK 版本是否保持一致,即使一开始已经配置好了,但是由于重新加载的原因或者等等原因都要可能会导致 JDK 又回到了原来的版本。(这里都是选择 17 版本,假如,你是安装了 JDK11,那么接下来所有都是设置成同一个版本 11 )去查看 Java 的环境变量是否配置成功,注意 JDK 要求要配置成功!比如配置 maven 的本地仓库、阿里云的私服都需要在 settings.xml 配置文件中进行配置。Maven 主路径,即安装 maven 的路径。选择你自己的本地仓库。

2024-03-27 15:33:29 2615 74

原创 前端基础篇-前端工程化 Vue 项目开发流程(环境准备、Element 组件库、Vue 路由、项目打包部署)

Element 是饿了么团队研发的,一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库。1】Nginx 默认占用 80 端口号,如果 80 端口号被占用,可以在 nginx.conf 中修改端口号。打开浏览器,通过​​​ ​​​​localhost:80 就可以访问到所部署在 web 服务器上的前端工程。Vue - cil 是vue 官方提供的一个脚手架,用于快速生成一个 Vue 的项目。部署:将打包好的 dist 目录下的文件,复制到 nginx 安装目录的 html 目录下。

2024-03-24 13:54:53 2858 63

原创 JavaEE 初阶篇-多线程属性和方法

多线程中断1)会自动清除 Thread.currentThread().isInterrupted() 的布尔值改变为 false ,从而导致了代码中的循环继续运行。简单来说,在 Lambda 表达式或者在匿名内部类中要引用外部作用域的局部变量的话,要求该局部变量是常量或者从头到尾都没有修改的变量。在 Java 中,变量捕获通常指的是在 Lambda 表达式或匿名内部类中引用外部作用域中的局部变量。Thread 对象的生命周期与 PCB 的生命周期是不一定完全一样的。当所有的前台线程都结束时,程序就会退出。

2024-03-23 19:45:13 1790 34

原创 JavaEE 初阶篇-深入了解进程与线程(常见的面试题:进程与线程的区别)

线程是系统调度执行的基本单位。一个进程可以包含一个或多个线程,共享进程的资源,但每个线程有自己的栈空间和执行路径。线程特点:1)线程是进程中的执行单元,可以看作是轻量级的进程。2)同一进程中的线程共享进程的地址空间和资源,可以直接访问进程的全局变量和数据。线程共享进程的资源,减少资源的重复占用,提高资源的利用效率。3)线程之间的切换比进程之间的切换更快速,因为线程共享相同的地址空间。线程的状态:1)就绪态(Ready):进程已经准备好运行,等待系统分配处理器资源。

2024-03-22 15:58:36 2426 84

原创 JavaEE 初阶篇-深入了解操作系统中的进程与 PCB

操作系统(Operating System)是一种系统软件,操作系统既可以管理计算机硬件资源,也可以管理软件资源。操作系统在计算机系统中扮演着重要的角色,它负责管理和协调计算机系统中的各种资源,包括硬件资源和软件资源。1)管理硬件资源:操作系统管理计算机的硬件资源,包括中央处理器(CPU)、内存、硬盘、输入输出设备等。它通过调度算法来分配 CPU 时间片,管理内存的分配和回收,控制硬盘存储和文件系统等,以确保硬件资源能够被有效利用。

2024-03-21 16:35:46 2111 70

原创 前端基础篇-深入了解 Ajax 、Axios

通过 Ajax 可以给服务器发送请求,并获取服务器响应的数据。异步交互是指,可以在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术,如:用户名是否可用的校验等等。简单来说,Ajax 的作用就是用来发送请求给服务器,得到响应后获取数据。

2024-03-19 20:16:30 2924 34

原创 前端基础篇-快速了解 Vue 前端框架(Vue 指令)

Vue 是一套前端框架,免除原生 JavaScript 中的 DOM 操作,简化书写。基于 MMVM 思想,实现数据的双向绑定,将编程的关注点放在数据上。View 相当于 HTML 中的标签,在网页中展示出来的数据,而 Model 则是负责存储数据,ViewModel 则负责连接 View 和 Model ,实现数据的双向绑定。双向绑定的意思可以简单的理解为,无论改变 View 还是 Model 的数据都会影响另外一方的数据。Vue.js 正是通过双向数据绑定实现了这种便捷的数据驱动开发模式。

2024-03-18 17:45:42 1596 89

原创 MySQL 篇- Java 连接 MySQL 数据库并实现数据交互

JDBC(Java Database Connectivity)是 Java 编程语言用于与数据库进行交互的标准 API。它提供了一种统一的方式来访问不同数据库系统,并执行 SQL 查询、更新和管理数据库。通过 JDBC,开发人员可以轻松地连接到数据库、执行 SQL 查询、管理事务、处理异常等,实现与数据库的数据交互和管理。简单来说,Java 提出的一套关于数据库操作的接口,各个数据库厂商要把自己的 API 对接到适配到 JDBC 上。程序元只需要掌握一套 API 就

2024-03-17 09:39:14 6275 46

原创 前端基础篇-深入了解 JavaScript(JSON、BOM、DOM 和事件监听)

JSON 可以被看作一种数据载体,键值对的形式存在,用于在不同系统之间传输和交换数据。JSON 本身并不具备逻辑处理能力,而是一种用于表示结构化数据的格式。通过 JSON,可以将数据序列化成字符串形式,并在不同系统之间进行传输和解析。

2024-03-17 09:37:19 1062 3

原创 前端基础篇-深入了解 JavaScript(一)

JavaScript(简称:JS)是一门夸平台、面向对象的脚本语言。使用来控制网页行为,它能够使网页可交互。JavaScript 与 Java 是完全不同的语言,不论是概念还是设计。脚本语言是不用进行编译处理的,直接交给浏览器解析即可,而 Java 等编程语言则是需要通过编译器编译成二进制文件再进一步编译成机器码。

2024-03-14 17:16:39 1500 25

原创 MySQL 篇-深入了解事务四大特性及原理

用简单通俗的话来说,将多条 SQL 语句打包在一起并作为一个逻辑单元执行,可以构成一个事务,如果某一条语句出现错误,则进行回滚操作,最终可以使得数据回复到原来的样子;如果 “打包” 在一起的语句都没有出现错误,则进行提交操作,数据就会进行相应的变化并保持持久性。

2024-03-14 17:13:17 2825 60

原创 前端基础篇-深入了解 HTML 表格标签、表单标签和表单项标签

表格:顾名思义,就是用来定义表格用的标签。在网页中以表格(行、列)形式整齐展示数据,如:班级表。表单:由多个表单项元素组成

2024-03-13 14:42:30 1343 62

原创 前端基础篇-深入了解用 HTML 与 CSS 实现正文排版、正文布局

HTML:HTML 是一种标记语言,用于描述网页的结构和内容。通过使用 HTML 标签,可以定义网页中的文本、图像、链接等元素的结构和排版。HTML 提供了一种标准化的方式来创建网页内容,并且是构建网页的基础。CSS:CSS 是一种样式表语言,用于控制网页的外观和布局。通过使用 CSS 样式规则,可以定义网页元素的样式,如字体、颜色、大小、间距、布局等。CSS 可以将样式和结构分离,使得网页设计更加灵活和易于维护。

2024-03-12 19:29:43 1096 7

原创 MySQL 篇-深入了解索引的内部结构(哈希表、红黑树与 B+ 树)

实际上,在 innodb 存储引擎中底层的数据结构就是 B+ 树的结构,就会按照主键的索引的 B+ 树的叶子节点来保存每一行的数据。如果表中已经创建了主键,自然是通过已经创建的主键索引的 B+ 树来组织所有行;如果没有创建主键,MySQL 其实生成了一个隐藏的主键,按照隐藏主键构造的 B+ 树来组织行。

2024-03-12 19:22:00 2211 51

原创 前端基础篇-深入了解用 HTML 与 CSS 实现标题排版

HTML:HTML 是一种标记语言,用于描述网页的结构和内容。通过使用 HTML 标签,可以定义网页中的文本、图像、链接等元素的结构和排版。HTML 提供了一种标准化的方式来创建网页内容,并且是构建网页的基础。CSS:CSS 是一种样式表语言,用于控制网页的外观和布局。通过使用 CSS 样式规则,可以定义网页元素的样式,如字体、颜色、大小、间距、布局等。CSS 可以将样式和结构分离,使得网页设计更加灵活和易于维护。

2024-03-11 14:51:27 1234 61

原创 MySQL 篇-快速了解事务、索引

将 SQL 每一条语句都 “打包” 起来一起执行,如果某一条语句出现错误,则进行回滚操作,最终可以使得数据回复到原来的样子;如果 “打包” 在一起的语句都没有出现错误,则进行提交操作,数据就会进行相应的变化并保持持久性。

2024-03-09 08:59:03 2524 101

原创 MySQL 篇-深入了解多表设计、多表查询

多表设计是指在数据库中将数据分散存储在多个表中的设计方法。这种设计方法通常用于将数据按照不同的实体或属性进行划分,以便更好地组织和管理数据。在多表设计中,不同的表之间通常会通过外键来建立关联关系,从而实现数据之间的引用和关联。这种设计方法有助于减少数据冗余、提高数据的一致性和完整性,并且可以更好地支持数据的查询和分析。

2024-03-06 15:23:55 6853 114

原创 MySQL 篇-深入了解 DML、DQL 语言(二)

DML(数据操作语言)是SQL(结构化查询语言)的一个子集,用于在数据库中操作数据。DML命令包括INSERT、UPDATE、DELETE和MERGE,用于向数据库表中添加、修改或删除数据。DQL(数据查询语言)也是SQL的一个子集,用于从数据库中检索数据。DQL命令包括SELECT,用于根据指定的条件从一个或多个表中检索数据。总而言之,DML用于操作数据库中的数据,而DQL用于查询和检索数据库中的数据。

2024-02-28 15:32:51 2244 90

原创 MySQL 篇-深入了解 DDL 语言(一)

详细讲解:DDL 语言 — 定义数据库操作 、DDL 语言 — 定义表格操作

2024-02-26 11:41:58 4663 82

原创 Java 数据结构篇-深入了解排序算法(动态图 + 实现七种基本排序算法)

1.0 冒泡排序的实现 + 动态演示图 2.0 选择排序的实现 + 动态演示图 3.0 堆排序的实现 + 动态演示图 4.0 插入排序的实现 + 动态演示图 5.0 希尔排序的实现 + 动态演示图 6.0 归并排序的实现 + 动态演示图 7.0 快速排序的实现 + 动态演示图

2024-01-28 22:49:25 6726 103

原创 Java 数据结构篇-实现红黑树的核心方法

手撕红黑树,实现红黑树的更新、添加与删除等核心方法!红黑树是一种自平衡的二叉搜索树,它在每个节点上增加了一个存储位来表示节点的颜色,可以是红色或黑色。与 AVL 树相比之下,红黑树放宽了对平衡的要求,通过牺牲一定的平衡性能来换取更高的插入、删除和查找操作的性能。红黑树的旋转操作相对较少,因此在实际应用中,红黑树更常用于需要高效的动态数据结构,如集合、映射等。而 AVL 树则更适用于对平衡性要求较高的场景,如数据库索引等。总的来说,红黑树也是一种自平衡的二叉搜索树。

2024-01-23 15:10:32 4962 86

原创 Java 数据结构篇-实现 AVL 树的核心方法

AVL 树的说明、AVL 树的成员变量及其构造方法、实现 AVL 树的核心方法、实现 AVL 树的完整代码

2024-01-11 16:17:42 6042 117

原创 Java LeetCode篇-二叉搜索树经典解法(实现:二叉搜索树的最近公共祖先、根据前序遍历建树等)

1.0 判断合法性 、 2.0 求范围和 、 3.0 根据前序遍历结果建树 、 4.0 二叉搜索树的最近祖宗 、 5.0 本篇的完整代码 二叉搜索树的经典解法

2024-01-08 21:57:31 3685 91

空空如也

空空如也

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

TA关注的人

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