自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 安卓相关知识

Activity(活动)是一个为实现交互而提供的Android应用组件。每个Activity都有一个窗口,该窗口可以全屏幕填充,也可以是一个小窗口浮动在其他窗口上。一个应用程序通常由多个Activity组成,它会指定应用程序中的某个Activity作为主Activity,这意味着当用户第一次启动应用程序时呈现给用户的活动,并且Activity可以相互跳转来执行不同的操作。

2022-10-13 20:40:01 887 1

原创 TCP协议的相关特性

TCP全称为 “传输控制协议(Transmission Control Protocol”)。TCP拥有8大特性来保证稳定性)(1.确认应答,2.超时重传,3.连接管理,4.流量控制,5.拥塞控制)以及其性能(1.滑动窗口,2.捎带应答,3.延时应答)。TCP协议段格式:​URG:紧急指针ACK:是否确认应答消息RST:复位标识SYN:同步序列号标识(tcp建立连接时使用)FIN:结束序列号标识(TCP断开连接时使用)16位窗口:记录接收缓冲区的大小,如果大小为0,就不会发送

2022-07-19 21:35:48 767

原创 计算机组成原理基本知识总结

冯诺依曼体系:指令只是一种特殊一些的数据处理器(CPU) = 运算器+控制器存储器(Memory) = 内存 storage(二级存储)、memory(内存)输入设备、输出设备.以上就是冯诺依曼体系的组成.程序 = 指令 + 数据指令:表现为一种特殊的数据需要存储在内存中,它是一组预规定的动作,利用编码表规定(opcode),只要给CPU支持的所有动作都编码一个唯一的数字,例如 吃 01 ,喝 03。数据:同样需要存储在内存中。广义数据在内存中的存储问题{数|非数的数据}

2022-05-17 15:32:42 288

原创 计算机网络中的基本知识

OSI分层(7层)物理层、数据链路层、网络层、运输层、会话层、表示层、应用层TCP/IP分层(4层)网络接口层、网络层、运输层、应用层五层协议(5层)物理层、数据链路层、网络层、运输层、应用层五层结构的概述应用层:通过应用进程间的交互来完成特定网络应用数据:报文协议:HTTP, SMTP(邮件), FTP(文件传送)运输层:向两个主机进程之间的通信提供通用的数据传输服务。数据:TCP:报文段,UDP:用户数据报协议:TCP, UDP网络层:为分组交换网上的不同主机提供通信服务数据

2022-05-17 15:31:43 334

原创 线程安全问题的原因和解决方案

线程安全问题出现的根本原因:1.存在俩个或俩个以上的线程共享着一个资源.2.对共享的资源有写的操作.解决方案:就是将多条操作共享数据的线程代码封装起来,当有线程在执行这些代码的时候,其他线程是不可以参与运算的.必需要当前线程把这些都执行完毕之后,其他线程才能参与运算.同步的好处:解决了线程的安全问题.同步的弊端:相对降低了效率,因为同步外的线程都会判断同步锁同步的前提:同步中必须有多个线程争取同一个锁.public class Main { static Obj

2022-05-15 21:03:13 197

原创 线程池的知识总结

为什么要使用线程池?线程池做的工作主要是控制运行的线程的数量,处理过程中将任务放入队列,然后在线程创建后启动这些任务,如果线程的数量超过最大数量,超过数量的线程将排队等候,等其他线程执行完毕,再从队列中取出任务来执行特点:线程复用,控制最大并发数,管理线程一丶降低资源消耗,通过重复利用已创建的线程降低线程创建和销毁造成的消耗二丶提高响应速度,当任务到达时,任务可以不需要等到线程创建就能够立刻执行三丶提高线程的可管理性,线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳

2022-05-15 19:17:01 669

原创 七大排序算法总结

1.稳定性(重要)俩个相等的数据,如果经过排序后,排序算法能保证其相对位置不发生变化,则我们称该算法是具备稳定性的排序算法.例如:某宝商城后台,需要你按照订单的金额排序,原订单是按照时间顺序排的,要求排序后原先的时间先后顺序不变,即为稳定性.这时候就需要我们使用稳定性的排序算法对订单的金额进行升序排序,保证其他信息的先后顺序不发生变化.2.分类:内排序:一次性将所有待排序的数据放入内存中进行的排序,基于元素之间比较的排序.包括七大排序外排序:需要在内外存之间多次交换数据才能进行...

2022-03-22 12:13:39 3706 2

原创 java有关于优先级队列和Map/Set的一些知识点

一:优先级队列优先级对列:按照元素之间的大小动态顺序出队,优先级队列处理的元素个数是动态变化的,有进有出,不像排序处理的集合个数是固定的.JDK中的优先级队列默认是最小堆,所以需要我们去修改compareTo方法.有时候在不同的场景下,对升序和降序都有要求,频繁根据不同场景修改已经写好的代码是大忌,所以我们使用Comparator比较器.Comparator比较器:需要比较的类并不需要实现此接口,而是有一个专门的类实现此接口,这个类就是为了进行比较大小用的.使用Comparator来讲JDK

2022-03-06 21:46:55 887

原创 java内部类?看这就够了

目录一.内部类的定义一. 成员内部类1:定义2.内部类的使用方法/规则:3.成员内部类对象的创建:​4.注意事项 :二.静态内部类1.定义:2.使用方法/规则:3.静态内部类对象的创建4.补充三.方法内部类1.定义四.匿名内部类一.内部类的定义所谓的内部类,就是将类结构的定义套在另一个类的内部。例如现实生活中汽车的发动机和汽车的关系,发动机这个类就套在汽车类的内部,又或者人的心脏和人体的关系,心脏这个类套在人体类的内部。内部类也属于..

2022-01-23 21:22:02 175

原创 Java抽象类和接口

抽象类一.概述抽象类是普通类的超集,只是比普通类多了一些抽象方法而已,现实生活中,抽象类很多(无法映射到具体的对象的类),比如说人类,动物类。1.抽象类无法直接实例化对象,子类继承抽象类,必须覆写抽象类中的所有方法(子类是普通类)2.利用abstract关键字来定义抽象类与抽象方法,抽象方法所在的类一定是抽象类,子类必须覆写所有抽象方法。3.抽象类必须有子类,final 和 abstract 不能同时出现抽象类最大的意义就是强制要求子类覆写所有抽象方法,保证多态的正确运行。抽

2022-01-10 19:20:44 267

原创 面向对象编程---继承和多态

一.概述面向对象程序设计的三大原则是封装性,继承性和多态性。继承性是子类自动共享父类的数据和方法的机制,它是由类的派生功能体现的。继承具有传递性,使得一个类可以继承另一个类的属性和方法,这样通过抽象出共同的属性和方法组成新的类,便于代码的复用。而多态是指不同类型的对象调用相同的方法时产生不同的行为 。当对象接收到调用方法的消息时,根据该对象所属的类,动态选用在该类中指定要实现的算法。二.继承猫,狗,鸟都是动物的一种,分别具有同一样的特征。例如:名字,年龄等。亦拥有同样的行为,如吃这个动作。当

2022-01-09 20:51:37 969

原创 2021年,我做了这些java中的链表知识点总结

链表:逻辑上连续,多个节点采用挂载的方式进行连接,物理上不连续.链表分为单链表和双链表.一丶单链表①链表的实现(增删改查):// 1、无头单向非循环链表实现public class SingleLinkedList { //头插法 public void addFirst(int val){ //尾插法} public void addLast(int val){ //任意位置插入,第一个数据节点为0号下标 } pub..

2021-12-28 22:25:50 472 1

原创 java求最小公倍数

两个或多个整数公有的倍数叫做它们的公倍数,其中除0以外最小的一个公倍数就叫做这几个整数的最小公倍数。整数a,b的最小公倍数记为[a,b],同样的,a,b,c的最小公倍数记为[a,b,c],多个整数的最小公倍数也有同样的记号。import java.util.Scanner;public class Test1129 { public static void main(String[] args) { //求最小公倍数 Scanner scanner = ne

2021-11-29 13:42:41 6899

原创 java中类与对象的认识

一、面向对象简述面向对象是一种现在最为流行的程序设计方法,几乎现在的所有应用都以面向对象为主了,最早的面向对象的概念实际上是由IBM提出的,在70年代的Smaltalk语言之中进行了应用,后来根据面向对象的设计思路,才形成C++,而由C++产生了Java这门面向对象的编程语言。但是在面向对象设计之前,广泛采用的是面向过程,面向过程只是针对于自己来解决问题。面向过程的操作是以程序的基本功能实现为主,实现之后就完成了,也不考虑修改的可能性,面向对象,更多的是要进行子模块化的设计,每一个模块都需要单独存在

2021-11-27 21:59:44 317

原创 java实现汉诺塔问题

汉诺塔(Tower of Hanoi),又称河内塔,是一个源于印度古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。思路是:汉诺塔中n个圆盘,首先将1–n-1个盘子看成一个盘,由于n-1上面的盘都比n-1小,所以用n-1代替1–n-1个盘进行移动,只有两个盘子在汉诺塔上的移动是A->B,A->C,

2021-11-24 21:21:25 219

原创 java查找一个数组中的多数元素

多数元素给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。 你可以假设数组是非空的,并且给定的数组总是存在多数元素。这个问题我们可以用多种方法来解决它,这里列举三个方法多数元素即众数,明白这个道理就变得轻而易举解决这个问题.一丶排序import java.util.Arrays;public class Test { public static void main(String[] args) { ...

2021-11-24 19:24:19 307

原创 java找单身狗(异或的方法和记录次数的方法)

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。一.利用异或的特性异或后相同的值会变为1,0与任何数异或得到自己本身.import java.util.Arrayspublic class Main { public static void main(String[] args) { int n = 0; int[] arr = new int[]{4, 1, 2, 1, 2}; i

2021-11-23 11:00:00 250

原创 Java---方法重载---方法递归

一、如何定义java中的方法所谓方法,就是用来解决一类问题的代码的有序组合,是一个功能模块。方法方便代码的复用。语法:1、 访问修饰符:方法允许被访问的权限范围, 可以是 public、protected、private 甚至可以省略,其中 public 表示该方法可以被其他任何代码调用2、 返回值类型:方法返回值的类型,如果方法不返回任何值,则返回值类型指定为 void ;如果方法具有返回值,则需要指定返回值的类型,并且在方法体中使用 return 语句返回值3、 方法名:定义的.

2021-11-22 17:47:42 94

原创 java- 数组-冒泡排序与判断数组是否有序

一.冒泡排序:冒泡排序(Bubble Sort)也是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢"浮"到数列的顶端。作为最简单的排序算法之一,冒泡排序给我的感觉就像 Abandon 在单词书里出现的感觉一样,每次都在第一页第一位,所以最熟悉。冒泡排序还有一种优化算法,就是立一个 flag,当在一趟序列遍历中元素没有发生

2021-11-21 21:04:02 579

原创 Java中有关于数组的知识点

数组:1.关于数组的初始化操作:静态初始化:声明数组的同时赋值,数据类型[] 数组名称 = {元素的内容}int[ ] arr = {1,2,3,5};动态初始化:声明时可选赋值数据类型[] 数组名称 = new 数据类型[4];int[ ] arr = new int [4]; int[ ] arr = new int [ ]{1,2,3,5};2.关于数组长度的取得和访问元素 数组长度:arr...

2021-11-21 18:37:25 276

原创 利用Java求最大公约数(辗转相除法)

最大公因数,也称最大公约数、最大公因子,指两个或多个整数共有约数中最大的一个。 a,b的最大公约数记为(a,b),同样的,a,b,c的最大公约数记为(a,b,c),多个整数的最大公约数也有同样的记号。 求最大公约数有多种方法,常见的有质因数分解法、短除法、辗转相除法、更相减损法。今天我们用辗转相除法求最大公约数辗转相除法辗转相除法:辗转相除法是求两个自然数的最大公约数的一种方法,也叫欧几里德算法。例如,求(319,377):∵ 319÷377=0(余319)∴(319,377)=.

2021-11-17 19:57:49 4135 1

原创 Java初阶中的逻辑控制程序知识要点

首先说一下java中的命名规则:1.类命名类命名采用大驼峰命名法,例如Tset,从第一个单词开始就首字母大写.2.项目命名全小写,多个单词通过下划线分割,例如exercise_java.3.变量命名单个单词小写,多个单词从第二个单词开始大写.(小驼峰命名法).常量:声明后值不能修改的变量,final 关键字修饰的变量,final又叫终结器.例如:final int a = 10; a = 20;这种写法是错误的.字面型常量:直接写出来的值,这种值称为字面型常量数据类型

2021-11-15 19:47:52 231

原创 C语言小游戏:扫雷小游戏

功能设计扫雷大家应该都玩过,这是一个十分经典的游戏,今天我将给大家讲解如何用C语言实现扫雷,我的这个扫雷有如下几个功能:显示该点周围雷的个数 第一次下子,不炸死 坐标周围没雷,可以实现展开 然后循环实现游戏效果展示:设计思路:我们只要输入坐标就可以扫雷了,是不是很有趣?其实要想实现这也不难,我们要用几个算法模块来模拟游戏规则,需要用函数来调用各个模块使游戏跑起来。那么第一步我们就要构思一个棋盘,看见上面第一张图没,在开始游戏的界面我打印了两个棋盘,有..

2021-11-13 16:46:11 2860

原创 通讯录进阶版(有动态扩容技术,文件操作技术)

基本的东西与前面的类似,只是加了一几个文件操作的函数文件存档函数:void save(AddressBook* addressBook) { FILE* fp = fopen("d:/addressbook.txt","w"); if (fp == NULL) { printf("文件打开失败!"); return; } fwrite(addressBook->persons, sizeof(personInfo), addressBook->size,

2021-11-09 22:01:15 61

原创 动态内存管理的核心知识点

动态内存管理?如何申请一个内存,如何释放一个内存.咋们以前,是通过创建变量的方式来申请内存的,啥时候释放内存,就得看变量是啥样的变量了.内存释放的时机,其实是不太灵活的~如果是全局变量,就跟随程序释放,如果是静态变量,也跟随程序释放,如果是局部变量,也就跟随代码块释放.1.动态内存管理,能够更灵活的决定申请时机和释放时机~2.动态内存管理可以在运行时决定内存申请的大小~动态内存管理主要涉及到的几个关键库函数:malloc,free,calloc,reallocmalloc.

2021-11-07 22:53:47 157

原创 程序的预处理中的核心知识点

首先简单介绍一下编译的过程~1.编译:把.c变成一个exe文件2.运行:把exe跑起来,执行里面的逻辑.此处的"编译"是一个"广义"的编译,这个编译其实还可以再拆成很多个步骤.(1)预处理:编译器先对源代码进行一个初步的处理,会执行代码中的预处理指令,输入内容是.c文件,输出结果还是一个.c文件,在c语言中,以#开头的,都是预处理命令.(2)编译(狭义的编译):把c语言文件变成汇编语言的文件(3).汇编:把汇编语言的文件转换成二进制的机器指令.(4).链接:每个.

2021-11-06 19:25:08 72

原创 C语言文件操作中的核心知识点总结

首先来说一下什么是文件?我们前面写的很多代码,其实都是在使用"变量","内存".内存:容量小,速度快,断电之后数据就消失了.外存(硬盘):容量大,速度慢,断电之后数据依然存在.一.文件的分类1.普通文件①文本文件②二进制文件区别:简单来说,如果使用记事本打开这个文件,看到的结果是乱码,那么就是二进制文件,反之则为文本文件(记事本默认是按文本文件打开的).二.C语言如何操作文件fopen : 打开一个文件fclose : 关闭一个文件fread : 读一个文件

2021-11-04 23:03:40 354

原创 利用C语言简单实现通讯录(没有自动扩容的功能)

一、通讯录通讯录可以用来存储1024个人的信息,每个人的信息包括:姓名丶性别丶年龄丶电话丶地址。功能:添加一个联系人信息 删除指定联系人信息 修改指定联系人信息 查看指定联系人信息 显示所有联系人信息 清空所有联系人信息 以名字排序所有联系人 这是一个简单的通讯录,实现方案是初级版。只能在程序运行期间存在(没有写入文件)。二、菜单实现和用户交互菜单实现和用户的交互添加一个联系人信息 删除指定...

2021-11-03 15:15:37 474

原创 C语言中自定义类型:结构体,枚举,联合体的核心知识点

1.匿名结构体其实没啥用,创建的目的是为了让这个结构体的类型只使用一次,不在后面继续使用了.2.结构体在内存中的布局(结构体内存对齐)①第一个成员在与结构体变量偏移为0的地址处.②其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处.对齐数 =编译器默认的一个对齐数与该成员大小的较小值.(vs中默认的为8)③结构体总体大小为最大对齐数的整数倍④不同的系统上,默认的对齐数可能不一样,如果我们写的程序是要跨平台的,此时就不能由系统自身来指定对齐数了,通过预处理命令#pragma p

2021-11-02 11:53:11 372

原创 C语言自我实现memmove库函数

描述C 库函数void *memmove(void *str1, const void *str2, size_t n)从str2复制n个字符到str1,但是在重叠内存块这方面,memmove() 是比 memcpy() 更安全的方法。如果目标区域和源区域有重叠的话,memmove() 能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中,复制后源区域的内容会被更改。如果目标区域与源区域没有重叠,则和 memcpy() 函数功能相同。声明下面是 memmove() 函数的声明。...

2021-11-01 23:23:48 246

原创 C语言中数据的存储涉及到的知识点

1.如果数组名会参与(加减,&,*,<,<=,>,>=......)会隐式转成指针类型(指向数组首元素的地址)2.函数调用的时候数组也会隐式转成指针.3.sizeof是在求一个内存中占几个字节,strlen是求一个字符串的长度.(从传入的字符串起始位置开始,往后找\0,看经过了几个字符能找到\0.)4.字符数组不能使用strlen,如果用了strlen当找到最后 一个元素时,发现没有\0,会继续往后找,此时就超出了数组的有效范围,访问了非法内存,就成了未定以行为.

2021-10-31 15:11:31 224

原创 C语言内存相关函数的自我实现中的一些核心知识点

mem系列的函数只要是内存,就能够使用.一.memcpy描述C 库函数void *memcpy(void *str1, const void *str2, size_t n)从存储区str2复制n个字节到存储区str1。声明下面是 memcpy() 函数的声明。void *memcpy(void *str1, const void *str2, size_t n)使用void*就可以兼容不同各种类型的指针,实参是int*,char*,结构体*都可以,在函数内部,...

2021-10-31 12:31:17 47

原创 实现一些C语言字符串库函数的知识点总结

首先要对参数的合法性进行校验,利用assert库函数来进行.1.strlen中要注意末尾的'\0',strlen是通过找'\0'来确定长度的2.strcpy要注意将'\0'复制过去,通过找到'\0'3.strcmp通过"字典序"来比较字符串中的字符大小...

2021-10-31 00:54:10 60

原创 5位运动员参加了10米台跳水比赛,有人让他们预测比赛结果A选手说:B第二,我第三;B选手说:我第二,E第四;C选手说:我第一,D第二;D选手说:C最后,我第三;E选手说:我第四,A第一;比

5位运动员参加了10米台跳水比赛,有人让他们预测比赛结果A选手说:B第二,我第三;B选手说:我第二,E第四;C选手说:我第一,D第二;D选手说:C最后,我第三;E选手说:我第四,A第一;比赛结束后,每位选手都说对了一半,请编程确定比赛的名次。思路分析:1.由题目知,在不筛选的情况下每个人都有五种可能,所以第一步先展示出这五种可能,常用for语句2.所有可能情况列出后,就要对这些情况进行筛选,常用if语句#include <stdio.h>#include <st.

2021-10-30 23:57:11 391

原创 C语言strcmp()库函数的自我实现

描述C 库函数int strcmp(const char *str1, const char *str2)把str1所指向的字符串和str2所指向的字符串进行比较。声明下面是 strcmp() 函数的声明。int strcmp(const char *str1, const char *str2)参数str1-- 要进行比较的第一个字符串。 str2-- 要进行比较的第二个字符串。返回值该函数返回值如下:如果返回值小于 0,则表示 str1 小于 str...

2021-10-28 22:41:14 301

原创 C语言实现冒泡排序

我们先给出冒泡排序的定义:冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小、首字母从Z到A)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”。具体的实现我们用数组的方式来实现:#

2021-10-28 09:30:00 108

原创 c语言实现水仙花数

首先解释一下水仙花数的概念:“水仙花数”是指一个n位数,其各位数字的n次方之和确好等于该数本身,如:153=1^3+5^3+3^3,则153是一个“水仙花数”。1.先用for循环来遍历0~1000000之间的所有数字2.每次遍历一个数字,就求出这个数字的位数。3.用这个数模除10,得到它的每一位,在用这个数除以10的结果进行循环,直到这个数除以10的结果为0.再调用库函数pow来计算这个数每一位的位数次方和。4.最后一步判断这个数每一位的位数次方和是否与这个数相等。相等即为水仙花数。以下

2021-10-27 17:37:31 2937

原创 C语言实现三子棋

三子棋是黑白棋的一种。三子棋是一种民间传统游戏,又叫九宫棋、圈圈叉叉、一条龙、井字棋等。将正方形对角线连起来,相对两边依次摆上三个双方棋子,只要将自己的三个棋子走成一条线,对方就算输了。但是,有很多时候会出现和棋的情况。#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>#include <stdlib.h>#include <time.h>#include <windows.h>#def

2021-10-22 20:30:07 154

原创 如何用c语言写一个猜数字游戏

题目要求:用户输入一个数字,与随机产生的数字比较,如果所猜的数字与随机产生的不一致,出现提醒:“大了”还是“小了”。//由于在vs2019中,所以要加这个define#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<stdlib.h>#incclude<time.h>int main() { srand((unsigned int)time(0));//sis为随机数变量 int

2021-10-02 16:03:52 218 4

原创 2021-09-18初学c语言的认识

我是西安科技大学计算机学院的一名普通学生,今年已经是上大学的第三个年头,感觉来到了人生的又一个转折点,不能在无所事事,于是重燃起了当初高考的热血,希望凭借自己的努力,找到一份好工作。我打算每天多敲代码,多思考,多读一些有关编程的书,多在网上看有关的视频,每周花至少48小时在学习C语言吧。我最想进入字节跳动这个公司,听学长说公司福利比较好。...

2021-09-18 11:09:46 60

空空如也

空空如也

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

TA关注的人

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