自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 JVM之回收堆区

5、终结器引用(常规开发中,不会使用):指对象需要被回收时,对象将会被放入在Finalizer类中的引用队列中,并稍后由一条由FinalizerThread线程从队列中获取对象,然后执行对象的finalizer方法。创建出来的对象会放入Eden伊甸园区,随着对象增多,如果Eden满了,新建的对象放不下,就会触发年轻代的GC,成为Minor GC或者Young GC。2、软引用:相比于强引用是一种比较弱的引用关系,如果一个对象只有软引用关联它,当程序内存不够时,就会将软引用的对象回收。

2024-05-18 14:20:32 681

原创 JVM之方法区的回收

通过垃圾回收器来对不在使用的对象完成自动的回收,垃圾回收器主要负责对堆上的内存的回收。这个新建的类加载器必须是自定义的类加载器,由于系统类加载器加载的类不会被卸载,并且只加载一次,所以普通项目很难获取到类卸载的日志。所以想要看到跟踪类卸载的日志,我们需要使用自定义的类加载器。下面我们通过代码来测试一下:我们新建一个类加载器,用这个类加载器去加载一个类,然后在把该类实例化。依次对实例对象没有全被回收、类加载器没被回收、Class对象被引用进行测试,看看能不能被回收。2、加载该类的类加载器已经被回收。

2024-05-18 11:13:04 280

原创 JVM之运行时数据区

方法区: (是一个虚拟概念,每款JAVA虚拟机上都各不相同,jdk8之后的版本,将方法区存放在元空间中,元空间位于操作系统维护的直接内存中,独立于JAVA虚拟机内存之外)。实例方法中的序号为0的位置存放的是this,指的是当前调用方法的对象,运行时会在内存中存对实例对象的地址。JAVA服务端程序开发时,建议将-Xmx和-Xms设置为相同的值,这样在程序启动后可使用的总内存就是最大内存,而无需向JAVA虚拟机再次申请,减少了申请并分配内存时间上的开销,同时也不会出现内存过剩之后的堆收缩的情况。

2024-05-12 12:16:36 1098 2

原创 JVM组成之类加载器

spi中使用了上下文中保存的类加载器进行类的加载,这个类一般就是应用类加载器,由此spi可以获取到应用类加载器。在自己的项目中创建一个java.lang.string类(在启动类加载器中已有相同类名的类被加载),不会被加载,会返回启动类中已被加载的string类。内容:当一个类加载器接收到加载类的任务时,会自下而上查找是否被加载过,在由顶向下进行加载(根据类的加载路径选择加载到哪个类加载器中)。如果一个类重复出现在三个类加载器的加载位置,英国由启动类加载器加载,根据双亲委派机制,它的优先级最高。

2024-05-05 20:35:48 718

原创 JVM之类的生命周期

类的生命周期:加载,连接(该阶段比较复杂,可以被分为验证、准备、解析,这三个阶段),初始化(最重要,因为程序员可以干涉),使用,卸载。

2024-05-05 18:19:54 579

原创 Java虚拟机(JVM)之字节码文件

软件打开的文件的头几个字节(文件头)去校验文件的类型,如果文件软件不支持该种类型就会出错。3、服务器环境用arthas:arthas是 一款先上个监控诊断产品,通过全局视角实时查看应用load、内存、gc、线程的状态信息(即查看运行中程序的字节码文件),并能在不修改应用代码的情况下,对业务问题进行诊断,大大提升线上问题排查效率。1、本地文件用java-v命令:是jdk自带的反编译工具,可以通过控制台查看字节码文件的内容。图中它返回给我4个线程,前面的数字是它们的序号,冒号后面是线程号,线程的路径和类名。

2024-04-29 20:00:48 948 1

原创 springboot结合elasticJob

应用程序启动时,在其内嵌的elastic-job-lite组件会向zookeeper注册该实例的信息,并触发选举,从众多实例中选举出一个leader,让其执行任务。App:应用程序,内部包含任务调度业务逻辑和Elastic-job-Lite组件,其中执行任务需要实现ElasticJob接口完成与Elastic-job-Lite组件的集成,并进行任务的相关配置。无中心化,是指没有调度中心这一概念,每个运行在集群中的作业都是对等的,各个作业节点是自治的、平等的、节点直接通过注册中心进行分布式协调。

2024-04-21 19:01:40 1210 2

原创 延时消息及代码实现

每个queue中的消息是按消息投递时间排序的,一个queue中的消息的延时消息是一样的,但topic可能不同。投递延时消息:broker内部有一个延时消息服务类ScheuleMessageService,其会消费SCHEDULE_TOPIC_XXXX中的消息,即按照每条消息的投递消息,将延时消息投递到目标topic中。延迟等级是从1开始计数的,从1开始及其后面的每个延迟等级对应的时间是1s,5s,10s,30s,1m,2m,3m,4m,5m,6m,7m,8m,9m,10m,20m,30m,1h,2h等等。

2024-03-30 16:20:36 253

原创 顺序消息及代码实现

顺序消费:分区有序(不同queue之间的消息是同一topic类型,但没有联系,不同queue中的消息之间没有先后顺序,同一queue中的消息必须有先后顺序):当有多个queue参与时,实现queue的分区有序,在定义producer时可以指定消息队列选择器;若是当前consumer需要消费的消息就直接消费,不是就不消费。如果当前consumer拉取到了不需要消费的选择key的消息,不做处理,但该消息会被视为已被消息,该consumer group的另一个消费该选择key的consumer不能再获取该消息。

2024-03-30 16:14:35 198

原创 消费幂等、消息堆积及其解决方案

但对于顺序消息是不同的,顺序消息并发度等于topic的queue分区数量(因为queue的处理不是并发的,而是queue处理完一个,才能处理下一个)。消息堆积:消息处理过程中,如果consumer的消费速度跟不上producer的发送速度,MQ中未处理的消息就会越来越多,这部分消息就被称为堆积消息。消费幂等:重复消费的结果与消费一次的结果是相同的,并且多次消费并未对业务产生任何负面影响,那么这个消费过程就是消费幂等。消息堆积主要瓶颈在客户端的消费能力,消费能力有消费耗时和消费并发度决定。

2024-03-30 15:59:46 256

原创 消费模式及rebalance机制

消费进度保存着在consumer端,该模式下consumer group中的每一个consumer都会消费所有消息,且每个consumer之间的进度不需要保持一致。消费重复:rebalance后consumer在消费分配给自己的队列时,必须接着之间的原来rebalance前消费该队列的consumer提交到broker的消费进度offset进行消费。消费进度保存在broker中,consumer group 中的所有consumer共同消费同一个topic中的所有消息,一条消息只被消费一次,且进度共享。

2024-03-30 14:50:10 330

原创 rocketMQ中store目录解释

每个broker都会包含一组indexFIle,每个indexFIle都是以一个时间戳命名的(这个indexFile文件被创建的时间)。当第一条含key的消息发送到broker后,若indexFile文件,就是立即创建一个indexFile文件。当一个indexFile文件中挂载的seindex索引单元数量超出了2000w个时,就会创建系的indexFile。每个queueId目录中有个consumequeue文件,该文件是commitlog的索引文件,可以定位到commitlog中的具体消息。

2024-03-30 14:21:41 470

原创 broker集群

多master多slave模式-异步模式:broker由多个master构成,每个master又配置了多个slave(配置了RAID磁盘阵列情况下,一个master配置一个slave即可)。不过由于slave切换为master会有短暂的延迟(毫秒级),所以当master宕机后,可能会存在少量的消息丢失问题。多master:broker集群仅有多个master构成,不存在slave,一个topic的多个queue会平均的分配到多个master节点上。0为master,非0为slave。

2024-03-30 13:48:06 247

原创 rocketMQ的基本认识

路由注册:nameService通常也是以集群的方式部署的,不过,nameService是无状态的,即nameService集群中的各个节点是无差异的,各节点互相不进行信息通讯,不会有数据同步。rocketMQ中的消息消费者都是以消费者组的形式出现的。消费者组似的在消息消费方面,实现负载均衡(是queue的负载均衡,不是消息的)和容错(一个消息者在消费一个queue过程中崩了,该消费者组中的另一个消费者会接受这个未消费完的queue继续消费,而不是从头开始消费)的目标变得非常容易。

2024-03-16 18:41:05 232

原创 nacos配置管理

nacos不仅可以作注册中心,还可以做配置管理实现热更新和对多个服务统一进行配置管理(需要更改配置时,就不用一个一个的去服务中改了),就是把需要变动的配置(比如开关配置)写在nacos配置管理中,服务启动时执行的是服务本身的配置加上nacos中的配置。且更改nacos中的配置,服务不需要重启就可以立即更新执行。在服务读取nacos中的配置之前,服务肯定要知道nacos的地址,但这个地址肯定不能写在本地配置中(application.yml),因为在访问完nacos配置后才会去访问本地配置。

2024-02-25 18:42:43 602

原创 nacos服务分级模型

nacos中服务存储和数据存储的最外层都是一个名为namespace的东西,用来做最外层的隔离,是对服务做隔离。每一个地域的多个实例的集合被叫做集群。我们都知道在服务消费者调用服务提供者的服务时,如果服务提供者的服务有多个实例的话,我们只需要调用其中一个实例就可以了。查看命名空间,发现其中已经有了一个public(保留空间),这是nacos自动默认帮我们创建的,我们前面的所有nacos上的服务都是在该环境下进行的。nacos中心还提供配置不同实例的权重的功能,就是调整每个实例被负载均衡调用的概率。

2024-02-25 13:50:14 349

原创 nacos注册中心之服务注册

这样nacos注册中心中就有了所有微服务的相关信息,在服务消费者需要调用服务提供者的服务时,就只需要向nacos注册中心根据服务名称去拉取对应的服务,nacos注册中心就会把调用该服务需要的所有信息发送给服务消费者,这样服务消费者就可以根据获取的端口和服务名称发送远程调用了。但问题也就有了,我们在开发一个项目时,肯定要开发不止3,4个微服务,需要开发上百个微服务都是有可能的,且每个微服务实现的功能都很单一,在我们进行复杂一点的操作时就需要多个微服务互相调用。服务提供者:一次业务中,被其他微服务调用的服务。

2024-02-25 11:25:11 843

原创 开发实体类

为了解决这种问题,就有了逻辑删除,就是数据库表中新增一个字段,该属性用于指明该员工是否还在本公司工作,这样公司在需要删除员工小明信息的时候,就不用删除小明的信息了,只需要修改数据库中小明的该字段信息,让其信息为该公司设置的已辞退的数据就可以了。先来简单解释一下什么是逻辑删除:就比如公司某销冠员工小明辞职了,该公司就需要把关于员工小明的所有信息删除,但如果删除了那么在公司进行总结时,属于销冠的那部分销售记录与盈利金额都会被删除,这就造成了公司实际的销售额与数据库中的不符合。deleted为新增的字段。

2024-02-16 12:22:45 728

原创 MybatisPlus

在继承的baseMapper类中已经写好了我们需要的增删改查的各种方法。但是我们需要指定我们要进行操作的实体类对象的范型。方式二:lambda格式条件查询,解决了wrapper.lt("", )中条件的属性名写错时把不报错的问题。方式三:lambda格式条件查询,简化了wrapper.lambda()只有在表中的有id为11的同时type属性为2的信息才会被查询到。根据book表中type属性查询数目并进行分组。查询type字段中包含spring的所有信息。查询字段:只查询表中的特定几列。

2024-02-16 11:50:33 550

原创 rest风格开发controller层

删除方法delete 只能用delete请求并传入id参数进行访问http://localhost:3306/usershttp://localhost:3306/users/1。getById根据id查询,需要传入id值, http://localhost:3306/usershttp://localhost:3306/users/1。新增方法save 只能用post请求访问 http://localhost:3306/usershttp://localhost:3306/users。

2024-02-02 15:29:09 461

原创 springMVC

springMVC中的bean仅仅指的是表现层的bean,不包括数据层和业务逻辑层的bean,为了避免springConfig错误的加载到springMVC的bean,我们需要在springConfig加载控制的bean时去掉springMVC控制的bean,也就是表现层的bean。并把参数传入,注意访问路径中的参数与方法中形参的名字要一致。传入引用类型的数据:对引用类型数据的默认处理是先把引用类型数据创建出一个对象,然后把获取的数据参数insert到对象中。法二:把表现层的bean从扫描的范围中去掉。

2024-02-02 14:59:51 761

原创 纯注解开发bean

Qualifier("bookDao5"):如果依赖注入的bean有多个实现类,就采用按名称装配,然后加上该注解,括号中写的要进行配置的bean的名称,且该注解必须依赖上面那个@Autowire注解。这时候就需要@ComponentScan("")注解了,这个注解用于扫描配置了注解的类的标签,该注解用于设定扫描路径,此注解只能添加一次,多个数据请用数组格式: ({"","",""})下面是对spring配置文件的处理:因为我们是纯注解开发,所以我们不要spring的配置文件,采用注解来设置。

2024-01-23 13:40:12 378

原创 Spring framework之配置文件实现容器和连接池注入

其=后面的是复制的xmlns="http://www.springframework.org/schema/beans",然后把其中的beans改成context。system-properties-mode="NEVER"意思是不加载系统属性,用于解决自己写的配置资源中的变量名与系统本身的变量名相同而产生的冲突。因为map是管理键值对的,所以不能直接用value标签,应该用ertry标签的key和value属性分别声明对应的键名和值。数据库连接池:我们先导入下面数据库连接池所需要的依赖包。

2024-01-23 11:55:36 398

原创 Spring framework之配置文件实现依赖注入的方式

引用类型:在类中为传入的属性提供对应的set方法,然后在配置文件中使用property标签 name属性指定哪个属性,ref属性注入。简单类型:把需要传入的属性作为形参写入构造方法,构造文件中,一样用contructor-arg标签代替property标签,用value属性指明传入的具体的值。简单类型:在类中为属性提供set方法,然后配置文件中使用property标签,name属性指定为哪个属性赋值,value属性是值的内容。要用type属性进行赋值,前提是形参中各个属性的基本类型都不一样。

2024-01-23 11:08:47 449

原创 Spring framework之配置文件实现IoC控制反转

这时还有一个问题,上面我们仅仅是完成了在外部创建对象的工作,当我们运行service时,如果IoC容器只提供给我们service的对象是不能到达效果的,因为service层的运行是需要依靠dao层的,所以IoC容器应该把这俩个对象都传给我们,并建立依赖。如果不写factory-method属性 该bean创建的是factory工厂的对象,但我们需要的是工厂中的方法所返回的对象,所以我们需要用factory-method指明运用工厂中的哪个方法来返回对象。其实这个建立依赖的工作,IoC容器是可以帮我们做的。

2024-01-22 17:14:38 1002

原创 vue的简单认识

简单说就是,我们会把操作数据库的程序简单分为3层:展现层,业务逻辑层和数据层,如果不用vue,我们想在展示层上展示出数据层的信息或者信息的变化,我们只能通过业务逻辑层向数据层获取数据然后在把数据传给展示层把数据呈现在页面上,不能让展示层和数据层直接交互;可我们用了vue之后,我们就可以实现展示层和数据层的双向绑定,实现展现层和数据层的直接交互,我们不需要做任何操作就可以让展示层呈现的数据实时跟随数据层数据的变化而变化。v-if、v-else、v-else-if:条件性的渲染某元素。

2024-01-18 11:07:55 545

原创 AJAX和Axios异步框架

作用:1、与服务器进行数据交换,通过AJAX可以给服务器发送请求,并获取服务器响应数据。2、异步交互:可以在不重新加载该页面的情况下,与服务器进行交换数据并更新部分网页的技术。就比如在用百度搜索时,我们需要完要搜索的内容,还没点搜索或者回车时,网页会自动给出很多类似的搜索内容。通过上面我们就可以对AJAX发送请求有了一个简单的认识,知道了我们可以运行AJAX简单的实现什么功能和基础代码应该怎么写。我们下好文件后,我们最好在webapp项目下创建一个js包,然后把前面下好的文件复制一个到这个包中。

2024-01-18 10:05:22 558

原创 Cookie Session和过滤器Filter

获取的Session有一个id属性,tomcat在浏览器做出响应的时候会自动把这个id属性当作一个Cookie发送给浏览器键值对为set-cookie:JSESSIONID=...,然后客户端就把这个浏览器在带着cookie头访问服务端来获取Session对象。因为http协议是无状态的,每次浏览器向服务器请求时,服务器都会将该请求视为新的请求,因此我们需要会话跟踪技术来实现会话内资源共享。会话:用户打开浏览器,访问web服务器的资源,会话建立,直到有一方断开连接,会话结束。这时硬盘中的文件已经消失了。

2024-01-09 17:08:52 862

原创 tomcat对数据库信息对进行添加操作和修改操作

在brand.jsp中我们通过设置了新增按钮来添加信息,<input type="button" value="新增" id="addBrand"><br>。我们想调用该servlet根据id查询详细信息,需要先知道该信息的id,所以在跳转到该servlet时应把id传过来。下面是修改操作:想对特定某条信息进行修改,需要先根据id查询到特定的信息,然后在进行修改。完成后设置表单提交给添加的servlet,下面开始写添加的servlet。这样我们在打开修改页面的时候,该产品原本的信息会自动填写在文本框中。

2024-01-09 16:07:14 588

原创 运用tomcat在浏览器中对数据库信息进行查询

注意:,只有声明该配置,才能应用pom文件中配置的工具jstl依赖。因为操作数据库过程中用到了mybatis,所以需要配置相应的xml文件,详细的配置过程在前面的Mybatis简化JDBC开发文章中写过。在该Servlet中调用前面声明的查询数据库的方法,获取数据库信息后,在将获取的brands数据转发到brand.jsp页面中。下面到了写jsp页面中信息的来源了 Servlet。

2024-01-09 11:29:28 555

原创 CSS与JavaScript的简单认识

提示:在html文档中,可以在任何地方,放置任意数量的script标签。1、string:按照字符串的字母值,转换为数字,如果字面值不是数字,例如var str=‘abc’,则转换为NaN。boolean:布尔。window:弹框方法:alert()弹出警告框和comfirm()弹出有确认和取消按钮的对话框。let关键字来定义变量,用法与var类似,但是声明的变量,只能在let关键字所在的代码块内有效,且不允许重复声明变量名相同的变量。Element对象中的俩个常用属性: style:设置元素css样式。

2023-12-31 14:11:15 1101

原创 html网页编写语言

h1-h6>:定义标题,h1最大,h6最小。<font>:定义文本的字体face,字体尺寸size,字体颜色color。<b>:定义粗体文本。解释:html标签,html的根标签 head标签,展示资源信息和title标题 body标签,浏览器网页要显示的内容。target:指定打开资源的方式,为_self时,是默认值,在当前页面打开。td标签:定义单元格:rowspan属性:规定单元格可横跨的行数。<div>:定义html文档中的一个区域部分,经常与CSS一起使用,用来布局网页。

2023-12-23 16:57:28 922

原创 MyBatis添加,修改,删除操作

useGeneratedKeys="true" keyProperty="id" 用于设置主键返回 keyProperty后的id为brand中的实体属性,不是数据库中的字段。另外如果我们想执行添加操作的同时返回生成的主键id,目前的代码是无法实现该功能的,因为在写sql语句时,我们没有写关于主键id的任何语句。不用<set>标签,用set,这样写有俩个问题,问题一:逗号问题,如果最后一个if不存在,那么sql语句最后会多一个逗号,导致报错。2、动态修改,只需要其中的部分条件,未声明要修改的不变。

2023-12-18 14:27:32 766

原创 MyBatis有参查询及动态查询

定义好方法后,selectById下面会有红波浪线报错,这是因为在Mapper.xml文件中找不到对应的方法,我们需要在Mapper.xml文件中声明对应的方法。Mapper.xml文件中这样写<select>标签,like是模糊查询,比如你city输入一个字母c,那么 数据库中city列中所有包含字母c的都会被查到。接下来是动态的单条件查询,查询时客户可能一个条件也不选,这样sql语句中where后就什么也没有了,sql语句会报错。上一篇博客中写了如何实现最简单的selectAll()查询所有的方法。

2023-12-17 16:11:51 1012

原创 MyBatis简化JDBC开发

这个小鸟图标就是我们前面下的MyBatisX插件的作用,只要我们点击一下红头巾的小鸟,就会跳转到对应的蓝头巾小鸟处,同样只要我们点击一下蓝头巾的小鸟,就会跳转到对应的红头巾小鸟处,这样等以后方法越写越多时,我们就不要在众多的方法中找我们需要的那个了,方便我们迅速找到对应的方法。<select>标签中的id是为该组sql语句定义一个名字,最好与我们定义的对应的接口方法一致,resultType是对应的实体类的路径。在实体类中,声明与数据库中字段相应的属性,并写好对应的get和set方法。

2023-12-17 15:05:07 956

原创 Javaweb之JDBC操作数据库部分的学习

sql分类:1、DDL:数据定义语言,用来定义数据库对象:数据库,表,列;在实现对数据库的不同操作时,其中只有第2,4,6步的细节需要变动。JDBC定义了一套操作所有关系型数据库的规则,本质就是接口,我们可以通过接口操作各种数据库,而操作数据库的实现类是由数据库本身提供,也就是数据库的驱动jar包。JDBC与web的联系 :想再web网页中显示数据库中的信息,先通过JDBC与数据库建立联系并获取数据,然后把每一组数据封装成一个对象,然后把每个对象放入一个List集合中,最后在web中显示集合中各个元素。

2023-12-10 15:14:55 729

原创 三层架构和与数据库建立联系的部分方法

业务逻辑层:主要负责对数据库的操作,就是从数据访问层获取数据进行一系列操作,该操作是引用数据访问层对数据进行相关操作的增删改查等按照不同顺序执行的一个复杂操作。数据访问层:只有看数据层中包不包含逻辑处理,主要是访问数据库中的文件,它的各个函数主要完成各个对数据文件的操作,不管其他操作。表现层可以说就是我们的界面,客户把需求告诉表现层,表现层在把需求传递给业务逻辑层,然后表现层再把业务逻辑层返回的数据呈现给客户。数据访问层,首先在数据访问层在创建一个baseDao类,其中定义了数据访问层中最基础的方法。

2023-11-19 12:54:22 92

原创 UML动态建模和部分静态模型图

状态图的历史状态:在转换成某个复合状态时,(复合状态是一个大的状态由多个小状态组成)它会进入历史状态,不是进入复合状态中的第一个小状态而是会随机进入一个小状态根据上次历史。顺序图的7种元素:角色actor,对象object,生命线lifeLIne,控制焦点activation,消息message,自关联消息,组合片段。协作图,注重在对象参与交互时,对象之间如何进行连接和传递的什么消息,按时间和空间的顺序描述系统对象之间的交互过程,侧重于描述消息的组成关系。链:表示对象之间的关系,链是关联的一个实例。

2023-11-11 14:43:08 360

原创 UML建模的初步认识

俩类之间的关联关系可以有一对一,一对多和多对多关系,在选择关系时会用0,1,0..1,0..n,*等选项,0代表没有,1代表就是一对一或一对多当中的一,0..1代表0到1个,*代表多个。在类的数目足够多时,我们很难在写代码的同时还能准确记住类与类之间的关系并把关系通过代码写出来,这时候我们就需要建模工具帮我们提前把应该有哪些类和类与类之间的关系表达清楚,这样我们写代码时就只需要想着怎么把模型的关系转换成代码就可以了。动态建模是描述系统的动作和行为,就是描述类中的方法,展示类与类之间如何交互。

2023-11-05 11:17:19 37

原创 Java访问者模式

这种类型的代码,想增加一些新的状态的话,只需在新的状态类中写好对应的男人和女人的方法就可以了。但想增加一种新类型的人的话,不仅要写好类本身中的方法,还要修改各个状态类增加对应的方法。在男人和女人类中用多个if连用来判断情况,现在只写了3种状态,等状态多起来if语句就会显的过长,不太好,而且想增加新的状态的话,我们需要更改已有的方法,违反了封闭-开放原则。访问者适用于数据结构稳定的情况,它将数据结构和作用于数据结构的操作分离,使作用于数据结构的操作更容易的派生出新的操作,而数据结构就不容易发生变化。

2023-10-29 11:19:09 20

空空如也

空空如也

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

TA关注的人

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