自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 【超详细】一文学会链表解题

前言如果说数据结构是算法的基础,那么数组和链表就是数据结构的基础。因为像堆,栈,对,图等比较复杂的数组结基本上都可以由数组和链表来表示,所以掌握数组和链表的基本操作十分重要。今天就来看看链表的基本操作及其在面试中的常见解题思路,本文将从以下几个点来讲解链表的核心知识什么是链表,链表的优缺点链表的表示及基本操作面试中链表的常见解题思路—翻转面试中链表的常见解题思路—快慢指针什么是链表相信大家已经开始迫不及待地想用链表解题了,不过在开始之前我们还是要先来温习下链表的定义,以及它的优势与劣势,磨

2021-04-26 17:40:46 164

原创 绝处逢生JVM快速入门之前戏篇

什么是JVMJVM是可以运行在Java代码的虚拟的计算机,既然是虚拟的计算机,当然也包含自己的CPU、字节码指令集、寄存器、栈、垃圾回收、堆和存储方法域,我们可以理解成JVM自己就是一套操作系统。Java从编译到执行Virtual Machine是物理机器的软件实现。Java是用在VM上运行的WORA(Write Once Run Anywhere)概念而开发的。编译器将Java文件编译为Java .class文件,然后将.class文件输入到JVM中,JVM会加载并执行类文件,如下图所示:1. 编

2021-03-03 21:52:51 236 1

原创 回顾Java面向对象基础

面向过程思想步骤清晰简单,第一步做什么,第二步做什么…面对过程适合处理一些较为简单的问题面向对象思想物以类聚,分类的思维模式,思考问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考。最后,才对某个分类下的细节进行面向过程的思索。面向对象适合处理复杂的问题,适合处理需要多人协作的问题!对于描述复杂的事物,为了从宏观上把握、从整体上合理分析,我们需要使用面向对象的思路来分析整个系统。但是,具体到微观操作,仍然需要面向过程的思路去处理。什么是面向对象面向对象编程(Object-Orient

2021-03-03 21:48:40 171 1

原创 阿里P8深入讲解Java集合

Collection(集合)常用方法:增add(E e)//添加单一对象addAll(Collection<? extends E> c)//添加一个集合删remove(Object o)//删除一个对象removeAll(Collection<?> c)//删除一个集合判空isEmpty()//判断集合是否为为空清除clear()//将集合元素清空判断是否包含contains(Object o)//判断集合中是否存在改元素containsAll(Coll

2021-03-03 21:34:05 170 1

原创 JVM之Metaspace解密

一:Metaspace介绍我们都知道jdk8之前有perm这一整块内存来存klass等信息,我们的参数里也必不可少地会配置-XX:PermSize以及-XX:MaxPermSize来控制这块内存的大小,jvm在启动的时候会根据这些配置来分配一块连续的内存块,但是随着动态类加载的情况越来越多,这块内存我们变得不太可控,到底设置多大合适是每个开发者要考虑的问题,如果设置太小了,系统运行过程中就容易出现内存溢出,设置大了又总感觉浪费,尽管不会实质分配这么大的物理内存。基于这么一个可能的原因,于是metaspac

2021-02-27 21:44:08 367

原创 Spring系列.Resource接口

接口简介JDK中提供了java.net.URL这个类来用于获取不同种类的资源(根据不同前缀的url可以获取不同种类的资源)。但是URL这个类没有获取classpath和ServletContext下的资源的能力。因此Spring提供了Resource接口,用于获取各种资源。Resource接口spring中的org.springframework.core.io.Resource接口代表着物理存在的任何资源,其继承于org.springframework.core.io.InputStreamSour

2021-02-27 21:42:46 157

原创 Java之Resource接口

接口简介JDK中提供了java.net.URL这个类来用于获取不同种类的资源(根据不同前缀的url可以获取不同种类的资源)。但是URL这个类没有获取classpath和ServletContext下的资源的能力。因此Spring提供了Resource接口,用于获取各种资源。Resource接口spring中的org.springframework.core.io.Resource接口代表着物理存在的任何资源,其继承于org.springframework.core.io.InputStreamSour

2021-02-27 21:39:05 1566

原创 不可不知的 JVM 预热

一、JVM 架构基础JVM 进程启动时,ClassLoader 会将需要的所有类加载到内存,主要分为以下三步:Bootstrap Class: 核心类库,由 “Bootstrap Class Loader”负责加载, 例如基础的运行时类库 JRE\lib\rt.jar。Extension Class: java.ext.dirs 路径下的类,由 ExtClassLoader 负责加载。在实际开发中,如果需要添加额外的类库,通常放置于此位置。Application Class: 实际应用包含的类,由

2021-02-26 21:39:47 348

原创 学习Java两个月吃透Mybatis 基本应用

1. 框架简介1.1 三层架构软件开发常用的架构是三层架构,之所以流行是因为有着清晰的任务划分。一般包括以下三层:a. 持久层:主要完成与数据库相关的操作,即对数据库的增删改查。因为数据库访问的对象一般称为Data Access Object(简称DAO),所以有人把持久层叫做DAO 层。//加入Java开发交流君样:756584822一起吹水聊天b. 业务层:主要根据功能需求完成业务逻辑的定义和实现。因为它主要是为上层提供服务的,所以有人把业务层叫做Service层或Business

2021-02-23 21:55:26 109

原创 Java日期与时间API用法详解

一、时间和日期在系统开发中,日期与时间作为重要的业务因素,起到十分关键的作用,例如同一个时间节点下的数据生成,基于时间范围的各种数据统计和分析,集群节点统一时间避免超时等。在时间和日期中有几个关键概念:日期:通常年月日的组合表示当前日期。时间:通常时分秒的组合表示当前时间。时区:世界各国家与地区经度不同,划分24个标准时区,相邻时区的时间相差一个小时。时间戳:从UTC时间的1970-1-1 00:00:00起到现在的总秒数。日期和时间的用法在系统中通常是获取时间和一些常见的计算与格式转换处理,

2021-02-23 21:29:06 145

原创 学习JVM必不可少的知识

1.Java垃圾回收机制对象被判断为垃圾的标准:没有被其他对象引用2.判断对象是否可被回收(1)引用计数算法  判断对象的引用数量通过判断对象的引用数量来决定对象是否可以被回收每个对象实例都有一个引用计数器,被引用则+1,完成引用则-1任何引用计数为0的对象实例可以被当作垃圾回收优点:执行效率高,程序执行受影响较小缺点:无法检测出循坏引用的情况,导致内存泄露(2)可达性分析算法(引自离线数学的图论)通过判断对象的引用链是否可达来决定对象是否可以被回收可不可达判断:如果从一个对象没

2021-02-21 22:25:36 119

原创 Java ThreadPoolExecutor详解

ThreadPoolExecutor是Java语言对于线程池的实现。池化技术是一种复用资源,减少开销的技术。线程是操作系统的资源,线程的创建与调度由操作系统负责,线程的创建与调度都要耗费大量的资源,其中线程创建需要占用一定的内存,而线程的调度需要不断的切换线程上下文造成一定的开销。同时线程执行完毕之后就会被操作系统回收,这样在高并发情况下就会造成系统频繁创建线程。为此线程池技术为了解决上述问题,使线程在使用完毕后不回收而是重复利用。如果线程能够复用,那么我们就可以使用固定数量的线程来解决并发问题,这样一来

2021-02-21 22:21:21 155

原创 你所不知道的JVM内存管理

要知道JVM内存时如何管理的,我们需要先了解以下JVM整体的架构体系:下面进行分别的介绍:类加载子系统: JVM把类的描述数据加载到内存,并对其进行校验、解析和初始化,最后形成可以被JVM直接使用的java类型//加入Java开发交流君样:756584822一起吹水聊天运行时数据区:Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而一直存在,有些区域则是依赖用户线程的启动和结束而建立和销毁。

2021-02-20 20:49:54 85

原创 JVM 基础篇

1. 什么是JVM:Java 虚拟机, 是class文件的运行载体。JVM可以实现一次编译,到处运行。JVM不是只供Java专用的,JVM是解析class文件的,只要语言编译成class文件就能被JVM解析。2. JVM的架构图3. JVM的运行模式JVM有两种运行模式:Server模式和Client模式两种模式的区别:Client模式启动速度快, Server模式启动较慢进入运行稳定期后,Server模式的程序运行速度要比Client快很多。Server模式启动的JVM是重

2021-02-20 20:40:44 116

原创 SparkCore的调优之开发调优

开发调优调优概述Spark性能优化的第一步,就是要在开发Spark作业的过程中注意和应用一些性能优化的基本原则。开发调优,就是要让大家了解以下一些Spark基本开发原则,包括:RDD lineage设计、算子的合理使用、特殊操作的优化等。在开发过程中,时时刻刻都应该注意以上原则,并将这些原则根据具体的业务以及实际的应用场景,灵活地运用到自己的Spark作业中。原则一:避免创建重复的RDD通常来说,我们在开发一个Spark作业时,首先是基于某个数据源(比如Hive表或HDFS文件)创建一个初始

2021-02-19 22:00:43 64

原创 Java使用Jetty实现嵌入式Web服务器

首先来介绍下 Jetty,根据 wiki 的介绍:Jetty 是一个纯粹的基于 Java 的网页服务器和 Java Servlet 容器。尽管网页服务器通常用来为人们呈现文档,但是 Jetty 通常在较大的软件框架中用于计算机与计算机之间的通信。Jetty 作为 Eclipse 基金会的一部分,是一个自由和开源项目。该网页服务器被用在 Apache ActiveMQ、Alfresco、Apache Geronimo、Apache Maven、Google App Engine、Eclipse、FUSE

2021-02-19 22:00:12 843 1

原创 Spring整合ActiveMq

1、概述多种语言和协议编写客户端。语言: Java, C, C++, C#, Ruby, Perl, Python, PHP。应用协议: OpenWire,Stomp REST,WS Notification,XMPP,AMQP完全支持JMS1.1和J2EE 1.4规范 (持久化,XA消息,事务)对Spring的支持,ActiveMQ可以很容易内嵌到使用Spring的系统里面去,而且也支持Spring2.0的特性通过了常见J2EE服务器(如 Geronimo,JBoss 4, GlassFish,W

2021-02-19 21:59:42 863

原创 如何学习Spring、Struts、Hibernate三大框架?

三大框架:Struts+Hibernate+SpringJava三大框架主要用来做WEN应用。Struts主要负责表示层的显示Spring利用它的IOC和AOP来处理控制业务(负责对数据库的操作)Hibernate主要是数据持久化到数据库再用jsp的servlet做网页开发的时候有个web.xml的映射文件,里面有一个mapping的标签就是用来做文件映射的。当你在浏览器上输入URL得知的时候,文件就会根据你写的名称对应到一个JAVA文件,根据java文件里编写的内容显示在浏览器上,就是一个网页

2021-02-18 22:42:08 177

原创 Java RMI之HelloWorld

Java RMI 指的是远程方法调用 (Remote Method Invocation)。它是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法。可以用此方法调用的任何对象必须实现该远程接口。Java RMI不是什么新技术(在Java1.1的时代都有了),但却是是非常重要的底层技术。大名鼎鼎的EJB都是建立在rmi基础之上的,现在还有一些开源的远程调用组件,其底层技术也是rmi。在大力鼓吹Web Service、SOA的时代,是不是每个应用都应该选用笨拙

2021-02-18 22:35:15 101

原创 百分百让你学会JAVA异常处理

什么是异常?异常就是有异于常态,和正常情况不一样,有错误出错。在java中,阻止当前方法或作用域的情况,称之为异常。java中异常的体系是怎么样的呢?1.Java中的所有不正常类都继承于Throwable类。Throwable主要包括两个大类,一个是Error类,另一个是Exception类;3.Exception类,也就是通常所说的“异常”。主要指编码、环境、用户操作输入出现问题,Exception主要包括两大类,非检查异常(RuntimeException)和检查异常(其他的一些异常)4.R

2021-02-18 22:25:39 80

原创 java:Collection、泛型

第一章 Collection集合1.1 集合概述在前面基础班我们已经学习过并使用过集合ArrayList ,那么集合到底是什么呢?集合:集合是java中提供的一种容器,可以用来存储多个数据。集合和数组既然都是容器,它们有啥区别呢?* 数组的长度是固定的。集合的长度是可变的。    * 数组中存储的是同一类型的元素,可以存储基本数据类型值。集合存储的都是对象。而且对象的类型可以不一致。在开发中一般当对象多的时候,使用集合进行存储。1.2 集合框架JAVASE提供了满足各种需求的API,在使用

2021-02-07 21:12:06 74

原创 Java操作BLOB和CLOB

BLOBBLOB全称为二进制大型对象(Binary Large Object)。它用于存储数据库中的大型二进制对象。可存储的最大大小为4G字节,通常像图片、文件、音乐等信息就用BLOB字段来存储。CLOBCLOB全称为字符大型对象(Character Large Object)。它与LONG数据类型类似,只不过CLOB用于存储数据库中的大型单字节字符数据块,不支持宽度不等的字符集。可存储的最大大小为4G字节,文章或者是较长的文字,就用CLOB存储,这样对以后的查询更新存储等操作都提供很大的方便。Ja

2021-02-07 21:09:16 442

转载 Java高级特性之反射

概念定义什么是反射?JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法,这种动态获取、调用对象方法的功能称为java语言的反射机制。反射是通过Class对象(字节码文件),来知道某个类的所有属性和方法。也就是说通过反射我们可以获取构造器,对象,属性,方法。执行流程获取Class对象的方式Class student = Student.class; //方式一Class<?> forName = Class.

2021-02-06 22:33:44 77

原创 Java BigDecimal详解

引言float和double类型的主要设计目标是为了科学计算和工程计算。他们执行二进制浮点运算,这是为了在广域数值范围上提供较为精确的快速近似计算而精心设计的。然而,它们没有提供完全精确的结果,所以不应该被用于要求精确结果的场合。但是,商业计算往往要求结果精确,这时候BigDecimal就派上大用场啦。先看下面代码 public static void main(String[] args) {//加入Java开发交流君样:756584822一起吹水聊天 System.out.

2021-02-06 22:30:02 111 1

原创 JAVA的StringBuffer类

StringBuffer类和String一样,也用来代表字符串,只是由于StringBuffer的内部实现方式和String不同,所以StringBuffer在进行字符串处理时,不生成新的对象,在内存使用上要优于String类。所以在实际使用时,如果经常需要对一个字符串进行修改,例如插入、删除等操作,使用StringBuffer要更加适合一些。在StringBuffer类中存在很多和String类一样的方法,这些方法在功能上和String类中的功能是完全一样的。但是有一个最显著的区别在于,对于Stri

2021-02-06 22:26:08 160 1

原创 你所不知道的Java十种经典排序算法

算法分类比较排序:在排序的最终结果里,元素之间的次序依赖于他们之间的比较,每个数必须和其他数进行比较,才能确定自己的位置。优势:适用于一切需要排序的情况。不在乎数据的分布,适用于各种规模的数据冒泡排序、快速排序、插入排序、希尔排序 、堆排序、选择排序、归并排序。在冒泡排序之类的排序中,问题规模为n,又因为需要比较n次,所以平均时间复杂度为O(n²)。在归并排序、快速排序之类的排序中,问题规模通过分治法消减为logN次,所以平均时间复杂度为O(nlogn)。非比较排序:只要确定每个元素之

2021-02-05 22:10:53 67

原创 Java异常到底是什么?

什么是异常正如文档开头所说,世界上并没有完美的程序,程序在运行中可能会存在着异常状态,这种异常状态,可能是异常(Exception),也可能是错误(Error),一个健壮性的程序就要考虑程序可能存在的异常状态,并对其进行处理。Throwable类是Java中所有错误和异常的超类,位于java.lang包,从JDK1.0开始引入。Throwable有两个子类Exception(Java中所有异常类的父类)和Error(Java中所有错误类的父类)。错误往往是程序运行时发生,程序员不可控制,对程序造成不可

2021-02-04 22:36:58 148

原创 深入解析Java--变量

变量使用变量是为了解决问题,解决内存中的数据读取比较麻烦这一问题,因为计算机读取内存中的数据时,是通过内存地址地址来读取,内存地址很难记住,16 进制的数据,随机分配。变量就是给内存地址取了一个别名,并且这个别名是可以由开发者自定义的。变量是一个概念,存储在内存中,方便存取内存中的数据,可以自定义变量名,就不用去记系统分配的16进制数据了。是程序中存储数据的基本单元。变量三要素:1、数据类型2、变量名3、变量值如何使用变量1、声明变量的数据类型和变量名。计算机会根据数据类型在内存中开

2021-02-03 22:12:53 128 1

原创 深入解析Java 使用Cipher类实现加密

~~一、先看一个简单加密,解密实现~~1.1 加密/** * content: 加密内容 * slatKey: 加密的盐,16位字符串 * vectorKey: 加密的向量,16位字符串 */public String encrypt(String content, String slatKey, String vectorKey) throws Exception { Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Paddin

2021-02-03 21:52:13 2641

原创 Java 使用Cipher类实现加密

~~一、先看一个简单加密,解密实现~~1.1 加密/** * content: 加密内容 * slatKey: 加密的盐,16位字符串 * vectorKey: 加密的向量,16位字符串 */public String encrypt(String content, String slatKey, String vectorKey) throws Exception { Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Paddin

2021-02-02 22:37:12 631

转载 SparkCore的调优之开发调优

开发调优调优概述Spark性能优化的第一步,就是要在开发Spark作业的过程中注意和应用一些性能优化的基本原则。开发调优,就是要让大家了解以下一些Spark基本开发原则,包括:RDD lineage设计、算子的合理使用、特殊操作的优化等。在开发过程中,时时刻刻都应该注意以上原则,并将这些原则根据具体的业务以及实际的应用场景,灵活地运用到自己的Spark作业中。原则一:避免创建重复的RDD通常来说,我们在开发一个Spark作业时,首先是基于某个数据源(比如Hive表或HDFS文件)创建一个初始

2021-01-31 21:38:05 54

原创 【Java】反射调用与面向对象结合使用产生的惊艳

我在看Spring的源码时,发现了一个隐藏的问题,就是父类方法(Method)在子类实例上的反射(Reflect)调用。初次看到,感觉有些奇特,因为父类方法可能是抽象的或私有的,但我没有去怀疑什么,这可是Spring的源码,肯定不会有错。不过我去做了测试,发现确实是正确的,那一瞬间竟然给我了一丝的惊艳。这其实是面向对象(继承与重写,即多态)和反射结合的产物。下面先来看测试,最后再进行总结。友情提示:测试内容较多,不过还是值得一看。具体方法的继承与重写先准备一个父类,有三个方法,分别是publ.

2021-01-30 21:51:10 65

转载 一个资深程序员对Java泛型的看法

Q:什么是泛型?Java泛型本质:参数化类型从字面意思就可以看出,就是把“类型变成了参数”,如String类型、Integer类型等都作为参数。=================================================================泛型-承担“保安”的角色Q:泛型如何使用?1.List mylist1=new ArrayList();//未使用泛型;2.List mylist2=new ArrayList();//参数化类型;集合类容纳的对象都是

2021-01-30 21:33:51 112

转载 Java 模拟servlet执行、DTD约束、Schema约束、dom4j解析

`模拟servlet执行浏览器请求WEB服务器上的资源,WEB服务器返回给浏览器浏览器的入口不同(访问路径),访问的资源也不同。我们需要使用xml约束(DTD或schema);为了获得xml的内容,我们需要使用dom4j进行解析。XML(不同路径(/hello)执行不同的资源( HeIIoMyServlet))XML可扩展的标记语言 标签可自定义的包下创建xml 文件 new → other → XMLFile粘贴web-app_ 2_ 3.dtd文件复制web-app_ 2_ 3

2021-01-26 22:28:10 129

转载 Java开发之上班摸鱼!写最少的代码!

I 前言 本次分享一下我所知道的如何写最少的代码的小技巧,如果你有更好的方案,欢迎在评论区留言,方案很棒的话,加我交流圈,为你送上冬天的一杯奶茶~Java:我想返回多个返回值秀一下Go的多返回值:package mainimport "fmt"// 返回 X + Y 和 X * Yfunc Computer(X, Y int) (int, int) { return X + Y, X * Y}众所周知,Java仅支持单一返回值,一般情况下如果需要返回多个对象,我们.

2021-01-26 22:27:18 367

转载 看阿里大佬如何深入剖析Java中的transient关键词

1. transient的作用实体类实现了Serilizable接口,就可以被自动序列化,然后有些特殊字段如密码,金钱等不想被序列化就可以使用transient关键词来解决。transient修饰的是变量,不能修饰方法和类。静态变量不能被序列化,不能被序列化的意思的序列化进去和反序列化出来的值可能不是你想要的,而是jvm中当前的值。具体的demo可以参考上面链接里的例子,被transient修饰的字段不是不序列化了,只是反序列化回来后得到的是null。 View Code输出结果:read a

2021-01-26 22:26:31 75

转载 原来是这个导致 java 代码的运行效率low到爆了

代码优化也是一样,如果项目着眼于尽快无BUG上线,那么此时可以抓大放小,代码的细节可以不精打细磨;但是如果有足够的时间开发、维护代码,这时候就必须考虑每个可以优化的细节了,一个一个细小的优化点累积起来,对于代码的运行效率绝对是有提升的。代码优化的目标是减小代码的体积提高代码运行的效率代码优化细节1、尽量指定类、方法的final修饰符带有final修饰符的类是不可派生的。在Java核心API中,有许多应用final的例子,例如java.lang.String,整个类都是final的。为类指定fin

2021-01-26 22:25:42 193

原创 深入解析Java中的锁分类

在读很多并发文章中,会提及各种各样锁如公平锁,乐观锁等等,这篇文章介绍各种锁的分类。介绍的内容如下:公平锁/非公平锁可重入锁独享锁/共享锁互斥锁/读写锁乐观锁/悲观锁分段锁偏向锁/轻量级锁/重量级锁自旋锁上面是很多锁的名词,这些分类并不是全是指锁的状态,有的指锁的特性,有的指锁的设计,下面总结的内容是对每个锁的名词进行一定的解释。公平锁/非公平锁公平锁是指多个线程按照申请锁的顺序来获取锁。非公平锁是指多个线程获取锁的顺序并不是按照申请锁的顺序,有可

2021-01-25 22:44:09 74

原创 Java使用Jetty实现嵌入式Web服务器及Servlet容器

首先来介绍下 Jetty,根据 wiki 的介绍:Jetty 是一个纯粹的基于 Java 的网页服务器和 Java Servlet 容器。尽管网页服务器通常用来为人们呈现文档,但是 Jetty 通常在较大的软件框架中用于计算机与计算机之间的通信。Jetty 作为 Eclipse 基金会的一部分,是一个自由和开源项目。该网页服务器被用在 Apache ActiveMQ、Alfresco、Apache Geronimo、Apache Maven、Google App Engine、Eclipse、FUSE

2021-01-23 22:47:56 297

原创 唬人的Java泛型并不难

泛型public interface Foo {}public interface Bar {}public interface Zar<?> {}上面的代码有什么区别?泛型初探1、为何引入泛型?Java 泛型也是一种语法糖,使用泛型可以在代码编译阶段完成类型的转换,避免代码在运行时强制转换而出现ClassCastException的异常。网络搜索出来一大堆的名称解释,我们先看英文Generic type,从英文大概也能明白,Generic 这里可以理解为普通的,一般的,或者我们

2021-01-22 21:49:12 79

空空如也

空空如也

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

TA关注的人

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