- 博客(85)
- 收藏
- 关注
原创 软件测试的分类
首先来看看软件测试有哪些分类按开发阶段划分![在这里插入图片描述](https://img-blog.csdnimg.cn/44b2da9efd8842cbb939b41bf0738210.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5L2g6L-Z5a625LyZ,size_20,color_FFFFFF,t_70,g_se,x_16)问题来了:为什么测试金字塔越往上投入
2021-09-10 23:29:14 535
原创 测试用例的设计方法
测试用例的总体设计方法基于需求的设计验证需求的正确性和合理性细分需求,多细致的需求就设置多细致的测试用例(从细分的需求里面,根据每一个功能设计完整的测试用例)如:若用户未收到激活邮件,可在登录界面录入电子邮件及密码后,再次发送激活邮件。2. 每次发送的激活邮件,仅在发送邮件后起24小时之内有效,超过24小时后需重新发送激活邮件。...
2021-09-10 08:48:28 1006 1
原创 软件测试的生命周期和一个软件测试人员如何去简单描述Bug
软件测试的生命周期(软件测试的流程)软件测试的声明周期其实是伴随着一个程序或者软件从无到有的全过程需求分析——测试计划——测试设计/开发——测试执行——测试评估需求分析:测试人员了解需求,对需求进行分解,得出测试的需求测试计划:如测试的范围,时间,人员,工具等计划测试设计:既测试用例测试执行:执行测试用例和补充测试用例测试评估:覆盖范围(测试了哪些功能,哪些没有测试),BUG情况的统计,测试报告如何描述一个Bug正确的描述一个Bug是测试人员所具备的最基础的,因为当你描述一个Bug的之
2021-09-09 18:30:04 370
原创 一个水杯居然能引出这么多测试点
一个软件的诞生就是从无到有的过程,这个软件的诞生同时也伴随着很多的测试,如果性能测试,功能测试,兼容测试……例如来看一个水杯你能引出哪些测试点?
2021-09-09 16:59:17 251
原创 软件开发模型和软件测试模型
随着软件工程学科的发展,人们对计算机软件的认识逐渐深入。软件工作的范围不仅仅局限在程序编写,而是扩展到了整个软件生命周期,如软件基本概念的形成、需求分析、设计、实现、测试、安装部署、运行维护,直到软件被更新和替换新的版本。软件工程还包括很多技术性的管理工作,例如过程管理、产品管理、资源管理和质量管理,在这些方面也逐步地建立起了标准或规范。软件的生命周期软件的生命周期是指从软件产品的设想开始一直到软件不在使用而结束的时间软件的声明周期可以分为六个阶段:需求分析——分析/计划——设计——开发——测试—.
2021-09-09 12:42:18 280
原创 什么是软件测试?和软件开发又有什么区别?
1.什么是软件测试?它其实就是为了满足用户的需求IEEE软件工程标准术语:就是人工或者自动手段来运行或者测试某个系统的过程,其目的就在于检验它是否满足规定的需求或弄清预期结果和实际结果之间的差别。2.软件测试和软件开发的区别软件开发:就是程序开发的方式把用户的需求实现成一个软件(如APP,网站,小程序等)软件测试:就是测试人员进行测试,查看这个程序的实现是否满足需求(因为一个程序的诞生往往是伴随着满足客户的需求,使得用户更方便)想了解测试和开发的区别,那么前提也得知道软件测试和软件调试的区别
2021-09-09 10:24:40 3793
原创 从上到下打印二叉树的三种题型
从上到下打印二叉树(一)也就是我们所熟知的层序遍历思路分析:1.首先它需要返回的是一个数组,那么我们首先要做的就是new一个数组,而数组的大小需要我们遍历这棵二叉树计算出来2. 当我们申请完数组之后,然后借助队列来完成层序遍历3. 首先将根节点放进去,然后当队列不为空的时候,定义一个cur记录这个节点,然后每弹出一个元素,就放进数组里面4. 然后再判断这个节点的左节点和右节点是否不为空,当不为空的时候放进队列//首先获取这棵树有多少个节点 public int getSize(T
2021-08-26 11:06:49 230
原创 Java中int为什么占四个字节?
简单了解计算机为什么要采用二进制表示信息:因为计算机作为一种电子计算机工具,是由大量的电子器件组成的,在这些电子器件中,电路的通断,电位的高低,用两个数字符号“1”和“0”分别表示容易实现,同时二进制的运算法则也很简单,因此计算机内部通常采用二进制代码来作为内部存储,传输和处理数据,二进制数据是用0和1两个数码来表示的数,它的基数为2(逢二进一,借一当二)其实最开始使用的并不是二进制,而是十进制,因为人们有十个手指头,手可以表示十个数字,所以十进制是比较合理的,0的概念是之后很久才诞生的,所以是0-10
2021-08-25 19:59:18 6181 4
原创 MySQL索引、事物
什么是索引索引是一种特殊的文件,包含着对数据表里所有记录的引用指针。可以对表中的一列或多列创建索引,并指定索引的类型,各类索引有各自的数据结构实现(就好像书的目录一样,它的作用就是用来加速数据库查询的)索引的作用数据库中过的表,数据,索引之间的关系,类似书架上的图书,书籍内容和书目录的关系素银所起的作用类似于数据目录,可用于快速定位,检索数据索引对于提高数据库的性能有很大的帮助为什么要有索引因为数据库上的数据都是存储在磁盘上的(而磁盘的操作是非常慢的(10^-3),而内存的操作是非常快的
2021-08-25 16:17:16 194
原创 相关二叉树习题整理
题目描述:给定一棵树的前序遍历 preorder 与中序遍历 inorder。请构造二叉树并返回其根节点。示例一:Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]Output: [3,9,20,null,null,15,7]示例 2:Input: preorder = [-1], inorder = [-1]Output: [-1]思路分析:首先判断数组是否为空,如果有一个为空那么就直接返回null.遍历前序遍历的数组
2021-08-25 12:15:16 175
原创 了解MyBatis框架
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录JDBC编程存在的问题在此之前我们了解的JDBC的操作为:1. 首先创建数据库连接池DataSource2. 通过DataSource获取数据库连接Co.
2021-08-18 13:29:36 226
原创 掌握SpringAOP
我们在了解SpringMVC的时候,我们使用@ControllerAdvice来完成统一异常处理或响应的统一数据格式封装,这其实就是我们的AOP思想,AOP是面向切面编程的一种编程语言,但是和语言无关,那么今天就让你对AOP思想不在陌生背景介绍AOP(Aspect-Oriented Programming):面向切面编程。AOP可以说是OOP(Object Oriented Programming,面向对象编程)的补充和完善。OOP引入封装、继承、多态等概念来建立一种对象层次结构,用于模拟公共行.
2021-08-18 08:53:40 367
原创 SpringMVC的返回值和参数类型
传统的基于Spring Framework的web开发需要大量的 xml 配置,在有SpringBoot以后,Web开发的效率得到了很大的提升,几乎大部分配置可以使用默认约定的规则。我们基于SpringBoot的项目来进行SpringMVC的学习概述SpringMVC框架围绕 DispatcherServlet(前端控制器) 这个核心展开, DispatcherServlet 是SpringMVC框架的总导演、总策划,它负责截获请求并将其分派给相应的处理器处理。MVC设计模式介绍MVC(Mo.
2021-08-16 15:18:52 393
原创 对Spring Boot还陌生吗?
Spring Framework 饱受非议的一点就是大量的XML配置以及复杂的依赖管理,开发人员不仅需要编写XML,而且在一些场景中需要编写繁琐的import语句,Boot描述了如何使用该框架在140个字符内实现可运行的web应用,从而获得了极大的关注度。为什么要使用Spring Boot答: Spring Boot基于约定优于配置的思想,可以让开发人员不必在配置与逻辑业务之间进行思维的切换,全身心的投入到逻辑业务的代码编写中,从而大大提高了开发的效率,一定程度上缩短了项目周期。Spring Bo.
2021-08-15 16:55:31 162
原创 认识Spring核心容器IoC/DI
对于 Java 编程来说,使用 Spring 能完成的更加快速,更容易并更安全。Spring 专注于速度,便捷与开发效率,也正是如此,让Spring成为了全世界最流行的 Java 框架。从配置到安全,web应用到大数据,不管你的应用架构需要啥玩意,Spring都有合适的开发框架来帮你搭建项目。Spring是基于模块化设计的,所以你可以从最小集开始,只使用你需要的。我们主要学习其中 Spring Framework 和Spring Boot1. Spring Framework背景介绍Spring专注.
2021-08-15 13:52:45 112
原创 掌握哈希表
首先来看一个问题?我:在[5,1,4,7,6,5,7,1,6],在这组数据中查找某一个元素有几种方法呢?你:①暴力可以的话,那就可以直接遍历数组嘛;②咱们也可以先把他排个序,然后在使用前面学的二分查找呀;③实在不行,我们可以将他构建成一颗二叉搜索树呀……我:害,你这些都可以,但是你直接遍历的话,时间复杂度就位O(n)了呀,二分查找的时间复杂度为O(logn),二叉搜索树的时间复杂度为O(log2Nlog_2 Nlog2N)了,有没有时间复杂度更低的呀,像O(1)这样的时间复杂度~你:我……我:算
2021-08-12 14:35:53 169
原创 熟悉网络层IP协议和数据链路层
所谓网络层,主要负责两件事,地址管理和路由选择(描述一个路径选择的过程)1. 应用层IP 协议1.1 IP协议头4位版本号(version): 指定IP协议的版本, 对于IPv4来说, 就是4.4位头部长度(header length): IP头部的长度是多少个32bit, 也就是 length * 4 的字节数. 4bit表示最大的数字是15, 因此IP头部最大长度是60字节.8位服务类型(Type Of Service): 3位优先权字段(已经弃用), 4位TOS字段, 和1位保留字段(.
2021-08-11 13:54:28 582
原创 不积跬步无以至千里—day2
两数相加(链表相加)给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。请你将两个数相加,并以相同形式返回一个表示和的链表。你可以假设除了数字 0 之外,这两个数都不会以 0 开头。解题思路:首席按定义一个新链表的虚拟头节点,在定义一个cur每次指向新链表的尾节点,在定义一个carry表示进位其次遍历 l1 和 l2 ,每次拿到 l1 和 l2 的值,因为存在一个链表长一个链表短的情况,所以当遇到链表走到空的时候,就让他的值
2021-08-11 00:11:29 403
原创 被问到TCP的可靠传输和提高网络利用率?
前面讲到的TCP和UDP,在TCP的特性里面知道,他是有连接的,连接管理也是和可靠性是有一定关系的,那么他是如何建立连接,又是如何断开连接的呢?1.连接管理(三次握手四次挥手)连接管理的目的(都是通过建立连接的方式实现的)1.通信双方要验证自己的”发数据“和”收数据“能力是否正常2.通信双方要在通信之前,来协商一些共同的参数1.1如何建立连接(三次握手)1.通信双方要验证自己的”发数据“和”收数据“能力是否正常双方进行一次交互就可以形象的理解为一次握手,当经历了三次握手之后,双方都可以.
2021-08-10 15:25:50 855
原创 传输层协议的UDP和TCP
进行一次通信需要五个信息:协议, 源ip, 源端口,目的ip,目的端口,(ip地址决定了一台主机在网络上的位置,端口号描述了数据报应该交给哪个程序来处理)一个端口号,通常情况下,只能由一个进程来绑定一个进程允许绑定多个端口号再谈端口号端口号(port)标识了一个主机在进行通信的不同的应用程序在TCP/IP协议中,用“源ip”,“源端口号”,“目的ip”,“目的端口号”,“协议号”这样的五元组来标识一个通信(可以通过netstat -n查看)如:...
2021-08-10 08:42:22 511 1
原创 不以跬步无以致千里——Day1
反转链表题目面试描述:输入一个链表,反转链表后,输出新链表的表头。示例1输入:{1,2,3}返回值:{3,2,1}解题分析:1.定义一个前驱节点pre,初始值为null,在定义一个cur指向head2.pre为cur的前驱节点,反转也就是让cur的下一个指向pre3.但是如果cur的next直接指向pre的话,那么cur后面的链表就无法找到了4.所以此时还需要一个临时节点tmp来每次保存cur的next的值5.然后每次当cur的next指向pre之后,之后就让pre=cur,cur
2021-08-09 23:55:55 80
原创 concurrentHashMap
像我们知道的Arraylist,LinkedList,HashMap,HashSet…都是线程不安全的,而Vector,Stack,HashTable是又是线程安全的那么如果想在多线程下使用ArrayList怎么办呢?方法:自己加锁使用synchronizedList使用JUC里面的CopyOnWriteArrayList如果想要在多线程下使用HashMap怎么办呢?方法:HashTable(不太建议使用)ConcurrentHashMap(推荐使用)...
2021-08-09 10:45:27 132
原创 java.util.concurrent.*下的常见类你了解多少?
java.util.concurrent.*是标准库提供的一组工具类,帮我们简化并发编程1.concurrent下的locks锁1.1.locks锁下常见的锁![在这里插入图片描述](https://img-blog.csdnimg.cn/b9bd751d7875497ba5693a76c5da8025.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4u.
2021-08-09 09:08:21 241
原创 锁优化问题
前面我们提到了锁策略问题,那么锁又如何优化的呢?1.锁的实现原理既然要知道锁的优化问题,首先的知道锁的实现原理(以加锁为例):先通过原子操作,检查并更新(CAS完成)一块内存区域,如果修改成功过,则表示加锁成功,否则表示加锁失败(更新的内存区域可以想象成哪个线程持有了这个锁)(用户/内核实现)如果更新失败。表示锁被别的线程占用了(用户/内核实现)如果被占用了,就挂起等待或者自旋或者…(用户/内核实现)如果是挂起等待锁,就把该线程放到一个锁对应的等待队列中,后面锁释放了之后才有机会被唤醒(内.
2021-08-08 13:01:22 114
原创 ++操作你还在使用加锁去保证线程的安全吗?确定不了解一下CAS机制?
什么是CASCAS(Compare and swap),字面意思可以理解为“比较和交换”:它其实就是假设内存中原有的数据为 V ,旧的预期值为 A 需要修改的值为 B,只有当变量的预期值A和内存地址V当中的实际值相同时,才会将内存地址V对应的值修改为B。当多个线程同时对某个资源进行CAS操作,只能有一个线程操作成功,但是并不会阻塞其他线程,其他线程只会收到操作失败的信号。可见 CAS 其实是一个乐观锁。通俗的将就是针对某个内存地址的内容,猜一下里面的值,如果猜对了,就将这个值更换成一个新的值,.
2021-08-08 11:05:54 141
原创 别翻了,常见的锁策略就在这里了~
咱们其他也就不多说了,就直奔主题了~1.乐观锁 VS 悲观锁**悲观锁:**总是假设最坏的情况,每次取拿数据的时候都认为别人会修改,所以在拿数据的时候都会上锁,这样别热你想拿到这个数据就会阻塞直到它拿到锁。(多个线程同时竞争锁)**乐观锁:**乐观锁假设认为数据一般情况下不会产生并发冲突,所以在数据进行提交更新的时候,才会正式堆数据是否并发冲突进行检测,如果并发冲突了,则会返回用户错误信息,让用户决定如何取做。悲观锁存在的问题:认为多个线程同时竞争锁的概率很高,但是愿意花更多的成本来解决锁竞争问题
2021-08-07 23:32:35 202
原创 什么是类加载,又有哪些类加载器你真的了解吗?
类加载1.1.什么是类加载?就是.java代码通过javac编译生成.class文件(文件是保存在磁盘上的),如果想要JVM使用这个类,那就需要将这个类加载到内存中,这个过程成为“类加载”。三个步骤:**1. 加载(loading):**读取.class文件,按照格式来进行解析(.class文件是有固定的格式,javac生成的时候就会按照这个格式来进行组织,JVM加载的时候也会按照这个格式来进行解析)**2. 连接(linking):**一个类可能会依赖其他类,如果想要使用这个类,需要将这个类.
2021-08-07 16:15:19 515
原创 垃圾收集器(CMS收集器 , G1收集器…)
Java堆内存被划分为新生代和年老代两部分,新生代主要使用复制和标记-清除垃圾回收算法,年老代主要使用标记-整理垃圾回收算法,因此java虚拟中针对新生代和年老代分别提供了多种不同的垃圾收集器,以下讲的收集器基于JDK1.7的G1收集器之后的HotSpot虚拟机,这个JVM包含的所有收集器,垃圾回收器有很多,夏淼淼罗列出七种常见的垃圾回收器如下图所示:垃圾收集器为什么有这么多垃圾回收器呢?历史的发展,java的不断更新,GC的不断改进垃圾回收器没有好坏之分,只不过没有人能够解决所有问题,根据.
2021-08-07 11:47:01 191
原创 JVM垃圾回收机制GC详解
JVM 有自己完善的硬件架构,如处理器、堆栈等,还具有相应的指令系统,其本质上就是一个程序,当它在命令行上启动的时候,就开始执行保存在某字节码文件中的指令。Java 语言的可移植性就是建立在 JVM 的基础之上的,任何平台只要装有针对于该平台的 Java 虚拟机,字节码文件(.class)就可以在该平台上运行,这就是“一次编译,多次运行”。除此之外,作为 Java 语言最重要的特性之一的自动垃圾回收机制,也是基于 JVM 实现的。那么,自动垃圾回收机制到底是如何实现的呢?1.GC是干啥的?进行资源的.
2021-08-06 18:37:51 4101
原创 JVM内存区域?
Java程序是运行在JVM(Java虚拟机)上的,在开发程序之前都要配置Java开发环境,其中首先要做的就是JDK的安装和配置,那么JDK、JVM、JRE到底有何联系和区别呢?如下图1.JVM概念**JVM**(Java Virtual Machine的简称),意为Java虚拟机**虚拟机:**指通过软件模拟的具有完整硬件功能的,运行在一个完全隔离的环境中的完整的计算机系统,常见的虚拟机有:JVM, VMwave, Virtual Box。JVM和其他两个虚拟机的区别:VMwave与Vir.
2021-08-05 22:20:33 1648 6
原创 Linux如何搭建Java部署环境
Java具有着跨平台的特性,一次编写,到处运行,如:将Java程序部署到Linux上也可以运行,但是也是需要借助一些工具,如:JDK,MySql,Tomcat等为什么是搭建Java部署环境,而不是开发环境?答:因为Java几乎不会在Linux上直接开发代码,(Linux)上没有图形界面,无法运行想IDEA,Eclipse等开发工具,(同时Java语言脱离IDEA 等开发工具写起来也非常难受),C++ 可能会在Linux上搭建开发环境.文章目录1. 认识yumyum在Linux中更像是一个应用商.
2021-08-04 20:05:43 2973 11
原创 Linux操作系统的常用基本指令
一个完整的操作系统=操作系统内核+配套的应用程序。我们熟知的Linux是一个操作系统(和Windows都是并列的关系),它实际上是一个隐藏的王者,全世界市场份额第一的操作系统,比Windows还高,他可以存在于服务器端,嵌入式设备(如:空调,卫星,路由器……),移动设备(Android),IOS中Linux的发展背景 1991年10月5日,赫尔辛基大学的一名研究生Linus Benedict Torvalds在一个Usenet新闻组(comp.os.minix)中宣布他编制出了一种类似UNIX的.
2021-08-04 13:34:31 257
原创 Servlet如何上传文件? 戳这里
首先对Servlet上传文件的简单理解此前,Servlet本身没有对文件上传提供直接的支持,一般需要使用第三方框架来实现,这样就比较麻烦不过,Servlet3.0之后提供了这个功能,而且使用非常简单,,为此,HTTPServletRequest提供了两个方法用于从请求中解析出上传的文件:Part getPart(String name) //获取请求中给定 name 的文件Collection<Part> getParts() //获取所有的文件其中每一个文件用一个javax
2021-05-13 23:57:00 549 2
原创 Servlet的Cookie和Session机制
Servlet CookiesCookies定义:Cookies是存储在客户端计算机上的文本文件,并保留了用户的各种跟踪信息。Cookies作用:会话保持,如完成用户的登录与状态保持Cookies的工作原理:客户端向服务区发起登录请求服务器脚本(代码)向浏览器发送一组Cookies,例如:姓名,年龄等浏览器将这些信息存储在本地计算机上,以备将来使用当下一次浏览器向web服务器发送任何请求时。浏览器会把这些Cookies信息发送到服务器,服务器将使用这些信息来识别账户Cookies构成C
2021-05-12 20:15:11 1614 12
原创 IDEA 配置Tomcat运行Servlet项目
关于Servlet的运行问题分析开发阶段:idea 中配置 Tomcat 插件,当写完代码之后直接运行 idea(和普通项目是一样的流程)。部署阶段:开发者打一个 war,然后将 war 部署到Tomcat上运行(如果是开发阶段就会略显麻烦,每次都需要进行打包发布)IDEA如何配置Tomcat插件具体步骤:第一步:点击添加配置第二步:点击“+”号,选择Tomcat,然后选择local第三步:点击configure选择本地的Tomcat安装包,你的Tomcat放在哪里,直接选择即可第四.
2021-05-11 22:55:17 9815 9
原创 Servlet的使用你掌握多少?
servlet定位图以及核心作用当用户输入url的时候,他的访问步骤依次如下Servlet标准 API核心包Servlet API有以下3个Java包:javax.servlet(重点):其中包含定义Servlet和Servlet容器之间的类和接口javax.servlet.http(重点):其中包含定义HTTP Servlet和Servlet容器之间的类和接口javax.servlet.annotation:其中包含标注Servlet,Filter,Listener的注解servlet
2021-05-11 21:40:43 1713 15
原创 初识Servlet
1.Servlet简介Servlet(Server Applet),全称Java Servlet,未有中文译文。是用Java编写的服务器端程序。其主要功能在于交互式地浏览和修改数据,生成动态Web内容。狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。Servlet运行于支持Java的应用服务器中。从实现上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP
2021-05-11 00:42:47 130 2
原创 优先级队列
前面我们提到过简单的Java集合框架1.概念队列是一种先进先出的(FIFO)的数据结构,但是在某些特殊情况下啊,操作的数据可能带有优先级,一般出队列时,可能需要优先级高的元素先出队列,所有,在改情况下的时候,使用队列肯定是不合适的。(比如:当你在刷抖音的时候,如果别人给你打电话进来的时候,那么系统应该有限处理打进来的电话。)这种情况下的时候,我们需要依赖优先级队列来进行处理,一个是返回最高优先级对象,一个是添加新的对象。优先级队列底层是一个堆,而堆其实就是一个顺序存储的二叉树2.优先级队列的特性
2021-04-15 22:39:30 112 1
原创 【LeetCode】——根据前序和中序遍历构建二叉树
题目描述:从前序与中序遍历序列构建二叉树注意:你可以假设数中没有重复元素。例如,给出:前序遍历 preorder = [3,9,20,15,7]中序遍历 inorder = [9,3,15,20,7]返回如下二叉树:思路分析:1.遍历前序遍历的数组,每次拿到一个元素(root)之后再中序遍历的数组中找到对应的位置。2.在中序遍历的数组中找到root之后root的左边将会是root的左子树root的右边将会是root的右子树当我们拿到前序遍历的下一个数时,我们再接着区中序遍历中找到
2021-04-13 13:26:03 702 1
原创 一个程序猿必须掌握的HTML的常识
首先什么是HTMLHTML 是用来描述网页的一种语言。HTML 指的是超文本标记语言,无需编译,浏览器可以直接识别和执行HTML 不是一种编程语言,而是一种标记语言标记语言是一套标记标签 (markup tag)HTML 使用标记标签来描述网页HTML 文档包含了HTML 标签及文本内容HTML文档也叫做 web 页面HTML不能进行逻辑执行(如:if语句,for循环等)注意:HTML标签是由尖括号括起来的词,如 , 。标签通常成对出现,例如 和 。一对中的第一个标签是开始标签;第
2021-04-07 22:00:03 148 1
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人