自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 javaEE进阶——SpringBoot与SpringMVC第一讲

首先想要知道什么是SpringMVC我们就要先知道它的意思,首先什么是MVC呢?MVC即模型,视图,控制器其实SpringMVC全名应该叫做SpringWebMVC,它其实是基于servlet来构建的一个原始web框架从一开始就包含在了spring框架中。那么通过上面的介绍我们知道SpringMVC的两个基本信息第一个:它是一个web矿建第二个:它是基于servlet的api构建出的一个框架模型视图控制器其实是我们软件架构模式中的一种,它把软件系统分为了这三个部分我们来分别进行解析一下。

2024-05-15 21:29:55 424

原创 JAVAEE—servlet的概念及使用

答案是一个mavean项目,那么创建好之后我们还要引入servlet的各种接口那么这里的引入和我门平时的引入是有一些区别的,这里的引入呢是在配置文件中进行导入那么具体该怎么做呢?我们所说的动态页面和静态页面其实指的是说这个页面在不同的条件下它的内容会发生改变,而静态页面则是指不同用户,在不同地点的不同时间打开这个页面的时候这个页面的内容并没有发生任何的改变。其中我们主要的代码就是这样用到的方法也就是这两个方法那么我们先运行一下,那么我们运行起来之后我们如何用浏览器去访问呢?然后我们来看一下最终的效果。

2024-04-30 22:22:00 888

原创 JAVAEE—HTTPS和ssl证书

HTTPS 也是一个应用层协议. 是在 HTTP 协议的基础上引入了一个加密层.HTTP 协议内容都是按照文本的方式明文传输的. 这就导致在传输过程中出现一些被篡改的情况而HTTPS则是新采用加密的方式进行传输首先什么是对称密钥呢?我们还是以上面为列,慈溪太后在拿到这张内容的时候要用破洞的纸对信的内容做解密,那么传给他这封信的那个人,在写下这个内容的时候是不是也需要用这张破洞的纸把自己想要写的内容写在这个洞对应的位置下啊?

2024-04-25 15:10:20 1109

原创 JAVAEE—HTTP

原因也很简单因为我们发现get请求中的数据会在url中显示包括我们的用户名啊密码啊之类的,这其实也是第二个原因的延深因为我们get一般会把自己传递的数据query string中这就导致我们的用户名和密码都是显示出来的而我们的post则是会放在,body中因此我们的隐私信息不会被显示出来,这个说法其实也是不对的,首先我们说的安全性一般指的是自己的密码等个人信息是否容易被破解,其次对于黑客来说,你的个人信息保存在query string还是body中其实都一样因为我们通过抓包工具仍然是可以抓取到的。

2024-04-24 23:40:53 1022

原创 JAVAEE——IP协议

我们上面说了IP地址目前用的最广泛的两个一个是IPV4一个是IPv6这两个,这两个表示地址的方式也是不一样的,IPV4协议的表示出来的是一个2^32的一个数字大概就是42亿9千万吧,这样一个数字呢很大,但是在我们网络如此发达的今天这个明显是不够用的,目前全世界网民的数目已经数十亿人了,如果给这数十亿人没人都分配一个IP地址的话那么这个42亿九千万这个数字是完全不够用的,而IPv6则能很好的解决这个麻烦因为IPv6的数字更大,几乎是用不完的。因为我们的IP协议形态其实是可以发生改变的,这八位是如何构成的呢?

2024-04-21 23:05:02 608

原创 TCP传输的粘包问题和各种异常情况

这里我们表示一个字节流这里面的消息就是我们即将发送的消息,那么这里面就是以字节为单位的数据,但是我们知道计算机在某一时刻传输多少字节是不知道的,我们并不知道自己的这些信息一次会被发出去多少,假如说按照我输入的情况我第一次要发送的是aaa第二次是bbb但是由于上面情况的发生,因此我们发送的情况可能是第一次发送的数据是aa第二次是abbb。那就是我们每一次要发送出去的数据前面都有一个数字,这个数字表示了我们要发送的数据的长度,而有了长度也就有了边界了,每一次的发送我们只需要读取一下前面的数字就可以了。

2024-04-18 13:51:28 849

原创 JAVAEE—UDP协议TCP协议/三次握手四次挥手

有的人可能会疑惑这个time_waite是什么东西,这个其实就是等待状态,也就是当A端回复了最后一个ACK之后会进入等待,等待一段时间后再断开,那么为什么要这样呢?我们可以想一下如果没有这个状态会发生什么?首先假如说A端发送的最后一个ACK,然后没有time_waite这个状态直接进行close,那么假如说这个ACK丢失了呢?

2024-04-18 00:42:00 1206

原创 JAVAEE—实现一个UDP通信的demo

因此我们说他是无连接的,既然是无连接的那么每一次我们发送的消息其实这个信息中不止包含我们想要发送的消息,还包含了对方的IP地址和端口号以及自己的IP地址和端口号。这里跟我们的无连接性其实是有关系的,由于UDP是没有连接的即不会保存通信双方的信息,因此每一次的发送都需要我们将要发送的数据以及发送方的IP地址端口号以及接受方的IP地址端口号进行打包。这要跟他的传输方式有关因为UDP的传输时尽自己最大能力的传输消息因此它并不保证这个消息能够准确并且完整的传输到对方的手中因此我们说他是不可靠的。

2024-04-10 21:17:04 799

原创 JAVAEE——网络初始

在没有集线器的时候主机(可以理解为电脑)之间是通过一根网线进行直链接的,这时候有一个弊端那就是这里面的消息会通过这一根网线传向所有的电脑并且,更为严重的问题是假如我们的电脑越多,那么这一根网线的传输效率就非常的慢,这时候怎么 解决呢?那么有了上面的基础我们来认识一下协议,什么是协议呢?但是这时候只是解决了当需要链接的主机过多,导致的网线太长之类的问题还没有解决我们的数据传输的问题呢,因为集线器发送消息就像老师点名一样把自己的数据发给与自己相连的所有主机,那么就没有私密性可言了,所以人们又发明了交换机。

2024-04-09 00:13:59 585

原创 JAVAEE——文件IO之文件操作

Java 中通过 java.io.File 类来对一个文件(包括目录)进行抽象的描述。注意,有 File 对象,并不代表真实存在该文件。那么File有哪些常用属性和构造方法呢?修饰以及类型属性说明依赖于系统的路径分隔符,String类型的表示依赖于系统的路径分隔符,char类型的表示。

2024-04-04 21:16:40 770

原创 JAVAEE——文件IO

我们先来理解一下什么是文件,那么想要知道什么是文件的话,我们首先要知道文件是干嘛的,文件其实就是用来保存数据的,我们知道我们电脑产生的数据是保存在了硬盘里的,可是那么多的数据如果我们不进行分类保管的话就会导致所有的数据乱作一团,因此就有了文件,当我们想要进行数据保存时,往往不是保存成一个整体,而是独立成一个个的单位进行保存,这个独立的单位就被抽象成文件的概念,就类似办公桌上的一份份真实的文件一般,那么我们创建了一个文件但是不往里面写东西那么这个文件有内存吗?

2024-04-04 20:46:23 1505

原创 JAVAEE—Callable接口,ReentrantLock,synchronized的工作过程

偏向锁你可以理解为钓鱼,因为偏向锁其实并不是真的加锁,而是加了一个标记记录这个锁属于哪个线程,但是此时并没有加锁,那么当出现另一个线程也去申请这个锁的时候,那么第一个线程才会对其加锁。偏向锁本质上相当于 “延迟加锁” . 能不加锁就不加锁, 尽量来避免不必要的加锁开销. 但是该做的标记还是得做的, 否则无法区分何时需要真正加锁.

2024-04-03 00:31:10 1035

原创 JAVAEE进阶——CAS,ABA问题

CAS:全称是Compare and swap也就是比较并交换什么是比较并交换呢?我们来举个例子假如说原内存中的数据是V,旧的预期值是A需要修改的值是B首先比较A与V是否相等如果相等的话那就更改将B写入V返回操作是否成功ABA问题:假设存在两个线程有一个共享的变量叫做num初始值为1接下来线程t1想使用CAS把这个变量修改成2;那么需要进行下面的这个操作先读取num的值计入到oldnum中使用CAS判定当前的num值是否为1如果是1那就使其变为2.

2024-04-01 11:53:10 943

原创 JAVAEE——多线程进阶,锁策略

假如说甲乙两位同学向老师请问问题,那么甲是一个悲观的人,乙是一个乐观的人,甲突然去找老师,老师肯定在忙碌无法给自己将题目,因此会先给老师发个消息询问老师是否在忙碌当得到老师的答复之后再决定是继续等待还是直接过去,而乙则是比较乐观,认为自己现在过去不会打扰到老师,老师可以立即解答自己的疑惑,因此乙就会直接过去询问老师问题,这时候可能老师确实没有忙碌可以直接解决问题也有可能老师是在忙碌的,这时候乙就需要进行等待了。公平锁遵守先来后到的原则B比C先来的那么当A释放锁之后B就会比C先获取到释放的锁。

2024-03-31 21:43:38 886

原创 JAVAEE——线程池

我们先来说一下什么是线程池,线程池这个名字大家应该能够有一定的了解,我们计算机中进程会用到池化技术,所谓池化技术,它其实就跟蓄水池一样,也就是提前创建好一批线程,并且不让其销毁,等到需要他们去做任务的时候再将其唤醒,这样子就可以有效的提高性能,至于为什么可以提高性能呢?我们通过一个例子来说明一下。比如说我们要去银行取钱,那么有两种方式第一种就是通过柜台取钱,第二种就是通过ATM机自动取钱。这时候就有了两种应对方式,如果是柜台的话你需要签名,出示证件,初始银行卡,然后输入密码,确认额度等等。

2024-03-28 20:12:17 812

原创 BFS离入口最近的出口

因为我们想一下我们逐层遍历每一层就是它的上下左右,那么它的上下左右中我们遇到的第一个出口就一定是我们的最近的出口那么最近的出口的距离多少呢?其实就是我们遍历的层数就是我们的距离.那么代码如下。这里有个巧妙的做法那就是我们用一个数组去记录一下出口然后我们判断的时候只需要判断此时的坐标在这个二维数组中的值是不是1就可以知道是不是出口了.这个题目的意思就是说一个人在一个入口处要求找到一个出口使得这个出口距离入口最近出口,那么什么是出口呢?这里四条边上的就是出口.其中加号是墙,'.'是可以走的路.

2024-03-26 23:20:25 231

原创 JAVAEE—实现多线程版本的定时器

首先定时器是什么呢?定时器是我们在开发中比较常用的一个组件,类似于一个闹钟,当某个你设置的时间到了之后就开始去执行特定的任务。System . out . println("2秒以后打印");System . out . println("我爱老婆");} }System . out . println("2秒以后打印");System . out . println("我爱老婆");} }Timer;System . out . println("2秒以后打印");

2024-03-26 21:41:05 1133

原创 FloodFill算法——力扣被围绕的区域

很简单那就是求没有被围绕的O然后将这些O变成随便的一个字符只要不是X或者O就行然后再将此时剩下的O全部变成X把你当时转换的字符重新转换成O就可以了,那么我们就要知道哪些O是不能被围绕的呢?我们来解读一下这个题目,这个题目的意思就是求出被X围绕的O有多少个,那么什么是被围绕呢?也就是没有出路并且连通的O不能到四条边上,这就算是被围绕了,可是即使知道了这些信息我们依旧头大因为,太难分析了我们遇到一个O之后还得去看看这一块儿O是不是被围绕的如果不是被围绕的还得去将他们回复成原来的O很难的了。

2024-03-24 23:19:32 298

原创 JAVAEE——多线程的设计模式,生产消费模型,阻塞队列

首先我们要先明白什么是设计模式呢?举个栗子,设计模式就像我们下棋的棋谱一样按照某种需求按照一定的规则来进行特定的应对软件开发中也有很多情景。因此大佬们总结了一套经典的设计模式其中面试经常问的当然就是单例模式了。

2024-03-24 17:54:47 1232

原创 有人相爱,有人夜里开车看海,有人leetcode第一题都做不出来。

题目很简单那就是在一个数组中找到两个数字使其相加的和等于k并返回这两个数的下标即可那么直接就是两层for循环就可以了。第一层for循环确定第一个数,第二个for循环在第一个的前提下逐个遍历看看能否找到与其相加等于k的数字从而返回。有人相爱,有人夜里开车看海,有人leetcode第一题都做不出来。那么我们今天就来看看力扣的第一题吧。

2024-03-23 23:47:28 150 1

原创 JAVA——volatile,wait,notife

从这张图种我们可以清除的看到其实我们的创建的线程在工作的时候,我们的数据并不是直接加到主内存中的,这里的主内存我们可以理解成硬盘内存,而工作内存其实就是jvm为每个线程独立开辟的一块内存,而线程在工作中所产生的各种变量啊资源啊其实并不是直接加载到主内存中的而是先加载到工作内存中在加载到主内存中,而工作内存其实就是在我们的cpu和寄存器中临时开辟的一块儿内存。我们可以知道工作内存和主内存是独立的,各个工作内存之间也是独立的,当线程创建或者修改某个变量时将会将这个变量传递给工作内存再由工作内存加载到主内存中。

2024-03-23 15:57:00 1024

原创 FloodFill算法——岛屿数量

那么这个问题应该采取何种思路和方法呢?还记得BFS的步骤嘛?走前走后走左右,顾前顾后顾左右,满足要求改为true,不满要求不进队,那么这个题目我们按照我编的这个句子来看一下,首先用两层for循环取遍历这里面所有的节点,当节点为1的时候我们就来看看,它的前后左右如果,然后将他的前后左右满足条件的进入队列,并将 加入队列的元素逐个遍历去获取他们的前后左右,并且这还不是最主要的是需要对我们遍历到的节点进行标记。从而保证符合要求的节点只会被我们遍历一次。

2024-03-22 22:51:36 274

原创 FloodFill算法——图像渲染

从上面对于算法的解析种我们其实应该是对每一个遍历到的节点加一个标志位的但是这个题目不用因为这个题目的主要要求是,符合条件的节点的值全部转换为题目要求的值因此我们可以发现即使没有标记位只需要记录初始位置的值然后逐个匹配即可。这个题目的意思在这类题目中也是非常标准的,就是给我们一个二维数组然后会再给我们一个坐标要求是我们以这个坐标为起点向四周延申,在这个过程中只有等于我们初始坐标这个值然后让这些值赋值为题目要求的值即可。我们来解读一下题目内容这个题目的意思其实就是有一个如下图所示的二维矩阵。

2024-03-22 22:16:00 307

原创 JAVAEE多线程——锁

首先我们来解释一下什么是锁呢?JAVA中的锁其实严格来说更像是一个门,我们在进行某个代码操作的时候如果先对这个代码上锁那么就会使得在一个时间内只有一个线程进行这类代码,最终的结果就是当我们对一个资源做修改的时候只有一个线程在进行。

2024-03-20 20:32:16 1218

原创 javaEE——线程的等待和结束

因为我们看一下上面的对这些的方法的介绍。其实就是我们第一种方法定义的一个boolean的变量一样那么清除标志位就相当于把这个标志位重新设置成了false那样子,设置标志位就相当于将其设置为true,那么带着这种理解我们来看一下这两种方法首先是public static boolean interrupted()这个方法就像是一个自动开关一样,当你检查的时候相当于把灯打开了,当你检查完毕后又把灯给重新随手关上了public boolean isInterrupted()而这个则是不会关闭。

2024-03-16 17:47:07 820

原创 [JAVAEE]—进程和多线程的认识

首先想知道什么是线程就得先搞明白什么是进程,关于进程呢,我们说进程是系统进行资源分配的基本单位但是光知道这句话远远不够,因为我们不知道什么是资源分配,我们可以简单的将计算机理解为钱包。那么资源就是钱包里的钱,至于进程就是我们要做的事情或者说要买的东西,比如说旅游啊买衣服啊。我们把资源(也就是钱)进行了划分,那一部分用来旅游哪一部分用来买衣服做了明确的划分,而这就是资源分配,至于买衣服啊之类的就是我们的进程。我们运行一个代码那么操作系统就要管理我们运行的程序代码怎么管理呢?那就是先描述再组织。

2024-03-13 00:53:03 824

原创 基本计算器II

最后一步就简单了我门只需要将栈中元素逐个弹出并且相加即可。

2024-03-10 01:17:38 286

原创 java——枚举,lambda

首先我们要明白什么是函数式接口呢?函数式接口意思就是这个接口中有且只有一个抽象方法。如果一个接口只有一个抽象方法,那么该接口就是一个函数式接口如果我们在某个接口上声明了 @FunctionalInterface 注解,那么编译器就会按照函数式接口的定义来要求该接口,这样如果有两个抽象方法,程序编译就会报错的。所以,从某种意义上来说,只要你保证你的接口中只有一个抽象方法,你可以不加这个注解。加上就会自动进行检测的。定义方式//注意:只能有一个方法但是下面这种方式也是可以的。

2024-03-09 16:23:41 1176

原创 力扣——删除字符串所有相邻重复项

我们来看一下这个题目这个题目其实跟我们的消消乐一样,首先就是给你一个字符串然后呢两个相邻的字符串如果相等的话就消除,但是大家注意消除后可能原本相同但是不相邻的元素会变得相邻因此我们要处理好这种情况那么该怎么办呢?在这里我们发现此时栈顶的元素和接下来要放入的元素相同了因此此时我们可以让栈顶元素出栈并且接下来要放入的元素不放入就达到了消除的效果我们来看一下。然后我们发现接下来要放入的元素又跟此时的栈顶元素相同因此重复上面的步骤。然后我们发现此时栈为空那么接下来就需要我们进行继续入栈了。

2024-03-09 00:53:26 326

原创 力扣——合并k个升序链表

我们假设每个链表的节点个数为n总共有m个链表那么每一次都需要两两比对,并且每一次新的链表长度都会增加,因此最终的时间复杂度是O(mn^2)这个时间复杂度是很可怕的,因为如果m和n的数字比较接近的话那么时间复杂度就直逼三次方了。利用优先级队列进行优化,我们可以将这些链表的头节点放入一个优先级队列中之后每当出去一个节点就将出去的这个节点的next节点放入优先级队列中。这个题目的思想运用过来我们合并两个链表的时候是用两个指针那么我们合并多个链表的时候也可以两两合并啊。那么这样子的话我们的时间复杂度如何呢?

2024-03-09 00:37:08 481

原创 java之——反射

class的字节码文件,jvm此时就要去解读.class文件,被编译过后的java文件,class也被jvm解析为一个对象,这个对象就是java.lang.Class这样当程序在运行时每个java文件最终变成了Class类对象的一个实例,我们通过java的反射机制应用道这个实例,就可以去获得甚至去添加改变这个类的属性和动作,使得这个类变成一个动态的类。其实就是实例出一个Class的对象便于我们后期的使用,因为接下来我们想要实列化出相应的对象就需要此时实例出的cl这里我们也需要一个列子就是Student类。

2024-03-06 21:56:46 745

原创 Java—[优先级队列]堆

我们学习过了队列的知识点知道了队列是一种先进先出的数据结构那么也就是说普通队列是按照时间进行的优先级,越早进去的越早出来,那么有没有一种数据结构可以改变优先级呢?比如说普通队列是进入时间作为优先级,越早的进入优先级越高,那么如果我想让值越小的越早出来该怎么做到呢?因此就有了下面这个数据结构也就是堆。或者叫优先级队列。

2024-02-29 16:36:16 977

原创 数据结构——java实现顺序表

首先什么是顺序表呢?先看一下官方概念顺序表(Sequence List)是一种线性表的实现方式,它是一种顺序存储结构,即数据元素存储在一块连续的存储空间中。顺序表通过数组实现,数组的每个元素存储一个数据元素,元素之间的顺序与其在数组中的位置相对应。这里听着感觉非常的绕,那有没有我们现在正在使用的列子呢?有的其实我们现在用的数组就是一个顺序表。那么我们按照数组的概念去套入一下顺序表的概念。首先要是连续的空间得是顺序存储其次存储元素的位置和其内存中的地址一一对应。

2024-02-22 14:50:18 987

原创 java—泛型编程

首先什么是泛型呢?从字面上我们可以理解为广泛的类型,有一定c++基础的程序猿们应该了解,java中的泛型其实就是c++的模板但是使用起来比模板更加简单,那么没有c++基础的呢也没关系,其实泛型它在我们未来的编程中是经常使用的,我们在未来中呢其实并不知道某个方法或者属性应该用一个什么类型,比如说我要你实现一个类这个类里面要有个数组这个数组可以存储任何类型的变量,你应该怎么存储呢?

2024-02-20 23:42:33 946

原创 算法之力扣数青蛙

我们以上面这个图为例,首先弄出一个表格这个表格第一行表示的是croak这五个字符每个字符的个数,然后用一个指针指向开头第一个字符在指针向后移动的过程中去改变表中的数字即可首先先看第一个字符是c因此先将c这个表格弄为1。当下面的指针向后移动到r的时候先查看表格中r前面的那个字符是不是大于0,之后如果大于那就是num[‘r’]++然后num[‘c’]–;之后当指针再次向后移动的时候下一个字符为c我们可以看到c这个字符经过第二步变成了0并且k也是0因此我们让c再++

2024-02-18 17:07:21 424

原创 异常—JAVA

Java 中虽然已经内置了丰富的异常类, 但是并不能完全表示实际开发中所遇到的一些异常,此时就需要维护符合我们实际情况的异常结构.例如, 我们实现一个用户登陆功能System.out.println("登录成功");此时我们在处理用户名密码错误的时候可能就需要抛出两种异常. 我们可以基于已有的异常类进行扩展(继承), 创建和我们业务相关的异常类.具体方式。

2024-02-18 16:10:18 635

原创 String讲解

上面我们讲过字符串是不可变的任何对于字符串的修改严格来说都是重新创建了一个对象在进行修改这使得字符串的修改效率非常的慢因此我们一般都是不对字符串的内容做修改的可是在实际开发中肯定是会遇到一些时候是需要对字符串的内容做修改的地方的那么这时候怎么办呢?字符串的不可变性是指字符串在创建之后字符串的内容事不能在被改变的,换句话说字符串一旦呗创建他的内容就不能在被改变了任何一个尝试修改字符串的手段本质上来说都是用一个新的字符串替换 掉原有的字符串。请看下面的String类的比较。而String内部的变量的关系如图。

2024-02-17 17:44:53 747

原创 java基础实现的图书管理系统

该项目是用的是javase的一些知识包括了类和对象封装,继承多态等面向对象的三大特性。主要是为了让我们能够更好的使用之前学到的知识。接下来给大家讲解一下这个项目的一个特点。首先就是登录登录的时候给大家了两个选择一个是普通用户一个是超级用户,并且这些用户的权限也是不一样的。如果你选择普通用户那么你的操作权限是上面那些超级用户是下面这些。

2024-02-14 20:52:04 899

原创 Linux——网络通信TCP通信常用的接口和tcp服务demo

bind()函数的作用是为了让socket返回的描述符与端口号进行绑定在bind函数之前我们还需要做一个工作就是将我们的信息存入一个结构体sockaddr_in中,struct sockaddr *是一个通用指针类型,myaddr参数实际上可以接受多种协议的sockaddr结构体,而它们的长度各不相同,所以需要第三个参数addrlen指定结构体的长度。connect和bind的参数形式一致, 区别在于bind的参数是自己的地址, 而connect的参数是对方的地址;listen成功返回0 失败则是-1。

2024-02-14 12:25:29 1594

原创 什么你竟然把面向对象的继承和多态讲的这么清楚

什么是继承呢?在面向对象的特性中我们知道面向对象有三大特性。继承*封装*多态那么今天我们要讲的就是继承和多态,什么是继承呢?举一个现实中的例子,我们在未来会身为儿女继承家庭未来的资产,那么在计算机层面上也是一样的身为子类会继承父类的属性和方法等。继承(inheritance)机制:是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特 性的基础上进行扩展,增加新功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构, 体现了由简单到复杂的认知过程。

2024-02-08 00:30:26 945 1

空空如也

空空如也

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

TA关注的人

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