自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 架构速成笔记:七大专题,1425 页考点

前言我们都知道,在程序员的职业生涯中,有多个发展方向,不过就数据表明,近年来选择架构师方向的开发人员也越来越多。对于架构师的发展前途,我相信是已经没有争议的,但这个“概念”对于很多开发人员来说,并没有太清晰的认识,怎样才能成为架构师,是很多程序员心里的疑问。所以,就架构师需要掌握的技术来说,我们特此整理一份 Java 架构速成笔记分享给你,包含七大专题,共 1425 页经典考点,希望吃透后的你能够轻松挑战 P8 岗。以下会展示「Java 架构速成笔记」的大致内容及部分截图,篇幅有限,需完整

2021-09-18 19:34:55 246

原创 感谢百万年薪大佬分享的 Java 面试进阶解析笔记

面试就是大家身边总是存在各种各样的可能,而自身又具备这样的能力,就忍不住想试一试,尤其是到了年关,是一个好的蓄势并且认真积累的阶段。当然面试套路众多,但对于技术面试来说,主要是考察一个人的技术能力和沟通能力。不同类型的面试官根据自身的理解问的问题也不尽相同,没有规律可循。“面试造火箭,工作拧螺丝”首先咱得能拧,才有造火箭的可能啊,这一年整理很多面试的高频问点也做了解析,自己也在很多平台获得过一些面试技术点的学习视频,今天在这分享给大家Java 相关面试问题基础这个东西在每个大厂都是一个重中之重,

2021-09-18 17:31:32 319 1

原创 Spring+SpringMVC+Mybatis框架整合

1.1 目录结构Spring+Mybatis1.2 依赖整理<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper&l

2021-09-16 20:27:06 252

原创 用好 Java 中的枚举,让你的工作效率飞起来!

1.概览在本文中,我们将看到什么是 Java 枚举,它们解决了哪些问题以及如何在实践中使用 Java 枚举实现一些设计模式。enum关键字在 java5 中引入,表示一种特殊类型的类,其总是继承java.lang.Enum类,更多内容可以自行查看其官方文档。枚举在很多时候会和常量拿来对比,可能因为本身我们大量实际使用枚举的地方就是为了替代常量。那么这种方式由什么优势呢?以这种方式定义的常量使代码更具可读性,允许进行编译时检查,预先记录可接受值的列表,并避免由于传入无效值而引起的意外行为。.

2021-09-16 20:25:32 263

原创 一文带你落地DDD

一.前言hello,everyone,好久不见。最近几周部门有个大版本发布,一直没有抽出时间来写博。由于版本不断迭代,功能越做越复杂,系统的维护与功能迭代越来越困难。前段领导找我说,能不能在架构上动手做做文章,将架构迁移到DDD。哈哈哈哈,当时我听到这个话的时候瞬间来了精神。说实话,从去年开始从大厂的一些朋友那里接触到DDD,自己平时也会时不时的阅读相关的文章与开源项目,但是一直没有机会在实际的工作中实施。正好借着这次机会可以开始实践一下。本文由于本文的重点为MVC三层架构如何迁移DDD,因此将

2021-09-16 20:24:34 882

原创 一文搞懂回滚和持久化

redo log事务的支持是数据库区分文件系统的重要特征之一,事务的四大特性:原子性:所有的操作要么都做,要么都不做,不可分割。 一致性:数据库从一种状态变成另一种状态的的结果最终是一致的,比如A给B转账500,A最终少了500,B最终多了500,但是A+B的值始终没变。 隔离性:事务和事务之前相互隔离,互不干扰。 持久性:事务一旦提交,它对数据的变更是永久性的。本篇文章主要说说持久性相关的知识。当我们在事务中更新一条记录的时候,比如:update user set age=11

2021-09-16 20:12:34 218

原创 雪花算法,什么情况下发生 ID 冲突?

分布式系统中,有一些需要使用全局唯一 ID 的场景,这种时候为了防止 ID 冲突可以使用 36 位的 UUID,但是 UUID 有一些缺点,首先他相对比较长,另外 UUID 一般是无序的有些时候我们希望能使用一种简单些的 ID,并且希望 ID 能够按照时间有序生成公众号:龙台的技术笔记GitHub:acmenlt什么是雪花算法Snowflake 中文的意思是雪花,所以常被称为雪花算法,是 Twitter 开源的分布式 ID 生成算法Twitter 雪花算法生成后是一个 64bit

2021-09-16 19:54:57 459

原创 Java面试宝典(2021版)

一、Java 基础1. JDK 和 JRE 有什么区别?JDK:Java Development Kit 的简称,java 开发工具包,提供了 java 的开发环境和运行环境。 JRE:Java Runtime Environment 的简称,java 运行环境,为 java 的运行提供了所需环境。具体来说 JDK 其实包含了 JRE,同时还包含了编译 java 源码的编译器 javac,还包含了很多 java 程序调试和分析的工具。简单来说:如果你需要运行 java 程序,只需安装 JRE 就

2021-09-15 15:18:08 1225

原创 100+经典Java面试题及答案解析

面向对象编程(OOP)Java是一个支持并发、基于类和面向对象的计算机编程语言。下面列出了面向对象软件开发的优点: 代码开发模块化,更易维护和修改。 代码复用。 增强代码的可靠性和灵活性。 增加代码的可理解性。 面向对象编程有很多重要的特性,比如:封装,继承,多态和抽象。下面的章节我们会逐个分析这些特性。封装封装给对象提供了隐藏内部特性和行为的能力。对象提供一些能被其他对象访问的方法来改变它内部的数据。在Java当中,有3种修饰符:publ

2021-09-15 15:16:50 405

原创 面试官问我MySQL索引,我

面试官:我看你简历上写了MySQL,对MySQL InnoDB引擎的索引了解吗?候选者:嗯啊,使用索引可以加快查询速度,其实上就是将无序的数据变成有序(有序就能加快检索速度)候选者:在InnoDB引擎中,索引的底层数据结构是B+树面试官:那为什么不使用红黑树或者B树呢?候选者:MySQL的数据是存储在硬盘的,在查询时一般是不能「一次性」把全部数据加载到内存中候选者:红黑树是「二叉查找树」的变种,一个Node节点只能存储一个Key和一个Value候选者:B和B+树跟红黑树不一样,它们算

2021-09-15 15:12:30 72

原创 各大厂面试整理 20 道 Java 后端开发面试题总结

1、Zookeeper 中都有哪些服务器角色?LeaderLeader服务器是整个ZooKeeper集群工作机制中的核心,其主要工作有以下两个。1)事务请求的唯一调度和处理者,保证集群事务处理的顺序性。2)集群内部各服务器的调度者。Follower从角色名字上可以看出,Follower服务器是ZooKeeper集群状态的跟随者,其主要工作有以下三个。1)处理客户端的非事务请求,转发事务请求给Leader服务器。2)参与事务请求Proposal的投票。3)参与Leader选

2021-09-15 15:10:45 134

原创 java面试准备之基础概念与常识(2)

Java 中的几种基本数据类型是什么?对应的包装类型是什么?各自占用多少字节呢?自动装箱与拆箱java在背后做的事情如下:一个坑 Integer在-128-127时可以使用== 比较即Integer默认的缓存区间为-128 127 如果我们使用这区间的值时会直接指向定义好的地址,但是如果超过这个区间jvm就会创建新对象如下面就会开两个新对象 所以地址空间不同 结果为false Integer i1=500; Inte

2021-09-15 14:52:53 57

原创 Java手写算法面试题

java笔试手写算法面试题大全含答案1、统计一篇英文文章单词个数。public class WordCounting {public static void main(String[] args) {try(FileReader fr = new FileReader("a.txt")) {int counter = 0;boolean state = false;int currentChar;while((currentChar= fr.read()) != -1) {if(cu

2021-09-15 14:50:03 265

原创 JAVA面试精选【java -redis 面试题】

一、Redis基础概述1、什么是Redis,有哪些优缺点?Redis 是一个使用 C 语言编写的,开源的高性能非关系型(NoSQL)的键值对数据库。Redis 可以存储键和五种不同类型的值之间的映射。键的类型只能为字符串,值支持五种数据类型:字符串、列表、集合、散列表、有序集合。Redis 的数据是存在内存中的,所以读写速度非常快,因此 redis 被广泛应用于缓存方向,每秒可以处理超过 10万次读写操作Redis 支持事务 、持久化、LUA脚本、LRU驱动事件、多种集群方案。整体的

2021-09-15 14:43:52 139

原创 Java 对象头分析与使用(Synchronized相关)

前言从上篇文章我们了解到:synchronized修饰代码块/修饰方法,最终都是在对象头上做文章,因此对象头是深入理解synchronized 各种锁变化的基础。接下来就来深入分析对象头在synchronized里的作用。通过本篇文章,你将了解到:1、对象在内存的构成2、对象头的构成3、对象头源码实现4、调试查看对象头1、对象在内存的构成先看一个简单的类: class Student { int age; String name;

2021-09-15 14:37:59 80

原创 轻松理解Java并发wait() 方法,notify() 方法和notifyAll()方法

简单了解wait 方法和 notify方法wait() 使得线程进入阻塞状态,它有两种形式,一种允许 指定以毫秒为单位的一段时间作为参数,另一种没有参数,前者当对应的 notify() 被调用或者超出指定时间时线程重新进入可执行状态,后者则必须对应的 notify() 被调用。他们是Object类的方法,也就是说每个对象都有这一对方法,可能初看不太好理解,但是,因为每个对象都有锁,调用任意对象的 wait() 方法导致线程阻塞,并且该对象上的锁被释放。而调用任意对象的notify()方法则导致因调用

2021-09-14 15:24:20 303

原创 聊聊使用lombok @Builder踩到的坑

前言什么是lombokLombok项目是一个Java库,它会自动插入编辑器和构建工具中,Lombok提供了一组有用的注释,用来消除Java类中的大量样板代码。对lombok不熟悉的朋友,可以阅读一下官方文档,再来看本文。官方文档如下projectlombok.org/正文我们先来看一个小例子提问: main函数会输出什么?答案:空指针异常Exception in thread "main" java.lang.NullPointerException at c

2021-09-14 15:17:49 912

原创 SSM学习笔记-Spring

1. Spring是什么Spring是一个轻量级框架,以loC(反转控制)和AOP(面向切面编程)为内核。2. Spring的优势方便解耦,简化开发 AOP编程的支持 声明式事务的支持 方便程序的测试 方便集成各种优秀的框架 降低JavaEE API的使用难度3. Spring程序的开发步骤导入Spring开发的基本包坐标 便携Dao接口和实现类 创建Spring核心配置文件 在Spring配置文件中配置UserDaompl 使用Spring的API获得Bean实例4.

2021-09-14 15:17:08 87

原创 JVM原理-jvm相关问题,相同问题不同理解

jvm是什么? 先来解释一下这个问题:JVM是Java Virtual Machine它是整个java实现跨平台的最核心的部分,所有的Java程序会首先被编译为.class的类文件,这种类文件可以在虚拟机上执行,也就是说class并不直接与机器的操作系统相对应,而是经过虚拟机间接与操作系统交互,由虚拟机将程序解释给本地系统执行。JVM是Java平台的基础,和实际的机器一样,它也有自己的指令集,并且在运行时操作不同的内存区域。JVM通过抽象操作系统和CPU结构,提供了一种与平台无关的代码执行方法,即与

2021-09-14 15:14:36 72

原创 手写实现一个JDK Stream - River

项目地址:github.com/zexho994/Ri…实现目标支持和JDK Stream一样的功能, 提供与Stream一样的API,后续会进行更多的API扩展。类型 方法 创建操作 of(T...t) 中间操作 map()limit()sort()peek()skip()filter()distinct() 终结操作 toArray()reduce()collect()max()anyMatch()findFirst()等 同时River还需要具备延迟

2021-09-14 15:14:06 254

原创 JAVA-数据结构与算法-修路问题(普里姆算法)和公交站问题(克鲁斯卡尔算法)

修路问题(普里姆算法)最小生成树,给定一个带权的无向连通图,如何选择一颗生成树,使树上所有边上权的总和为最小;N个顶点,N-1条边 普里姆算法,在包含n个顶点的连通图中,找出只有n-1条边,包含所有n个顶点的连通子图,极小连通子图 创建最小生成树,每个顶点的之间都选去最小的权值作为连通点;由于每个顶点都有两种状态访问过/没有被访问过,那么两层for循环,就可以保证所有顶点都被扫描到,再通过mGraph.weight[i][j] < minWeight,保证再一次子图的遍历中,获取的边(向外生长

2021-09-14 15:12:00 890

原创 Java求两个List集合的交集、并集、差集

在项目中经常会求解集合的交集、并集、差集,这里做个记录。首先创建两个集合list1、list2以及添加元素。List<String> list1 = new ArrayList<>();list1.add("a");list1.add("b");List<String> list2 = new ArrayList<>();list2.add("b");list2.add("c");复制代码交集list1.retainAll(list

2021-09-14 15:09:45 507

原创 JAVA-GUI程序概述

GUI概述GUI 即图形用户界面,使用图形方式,借助于窗口中的菜单、按钮等界面元素和鼠标操作,帮助用户方便地向计算机系统发布指令、启动操作,并将系统运行的结果同样以图形方式显示给用户。GUI就是用户与计算机之间交互的图形化操作界面,又称为图形用户接口,通过GUI允许用户与Java应用程序或小程序进行交互操作。Java语言提供两个处理图形用户界面的类库: Java.awt包和Javax.swing包。awtJava.awt包提供了基本的Java程序的GUI设计工具。 主要包括三个设计工具:

2021-09-14 15:08:03 307

原创 「线程间的高性能消息框架」深入浅出Disruptor的使用和原理

前提概要简单回顾 jdk 里的队列:阻塞队列:ArrayBlockingQueue主要通过:数组(Object[])+ 计数器(count)+ ReetrantLock的Condition (notEmpty:非空、notFull:非饱和)进行阻塞。入队操作:操作不阻塞: add:添加失败,则会直接进行返回。 offer:添加失败后(满了)直接抛出异常,注意:offer(E o, long timeout, TimeUnit unit):可以设定等待的时间,如果在指定的时间内,

2021-09-14 15:04:37 413

原创 万丈高楼平地起的建造者模式

定义建造者模式(Builder Pattern)是将一个复杂对象的构建过程与它的表示分离,使得同样的构建过程可以创建不同的表示,属于创建型模式。使用建造者模式对于用户而言只需指定需要建造的类型就可以获得对象,建造过程及细节不需要了解。建造者模式适用于创建对象需要很多步骤,但是步骤的顺序不一定固定。如果一个对象有非常复杂的内部结构(很多属性),可以将复杂对象的创建和使用进行分离。组装电脑一般建造者模式是搭配着链式编程一起写的,所以这里不介绍传统的写法,直接介绍链式写法。这里以组装电脑为例,新建

2021-09-14 15:03:02 86

原创 Java并发编程:深入剖析ThreadLocal

想必很多朋友对ThreadLocal并不陌生,今天我们就来一起探讨下ThreadLocal的使用方法和实现原理。首先,本文先谈一下对ThreadLocal的理解,然后根据ThreadLocal类的源码分析了其实现原理和使用需要注意的地方,最后给出了两个应用场景。  以下是本文目录大纲:  一.对ThreadLocal的理解  二.深入解析ThreadLocal类  三.ThreadLocal的应用场景  若有不正之处请多多谅解,并欢迎批评指正。  请尊重作者劳动成果,转载请标明原文链

2021-09-13 15:00:59 59

原创 java提高篇(八)----详解内部类

可以将一个类的定义放在另一个类的定义内部,这就是内部类。 内部类是一个非常有用的特性但又比较难理解使用的特性(鄙人到现在都没有怎么使用过内部类,对内部类也只是略知一二)。第一次见面 内部类我们从外面看是非常容易理解的,无非就是在一个类的内部在定义一个类。public class OuterClass { private String name ; private int age; public String getName() { ...

2021-09-13 14:59:39 56

原创 Java并发编程:线程池的使用

在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题:  如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间。  那么有没有一种办法使得线程可以复用,就是执行完一个任务,并不被销毁,而是可以继续执行其他的任务?  在Java中可以通过线程池来达到这样的效果。今天我们就来详细讲解一下Java的线程池,首先我们从最核心的ThreadPoolExecutor类中的方法

2021-09-13 14:59:03 46

原创 Java IO流学习总结

Java流操作有关的类或接口:Java流类图结构:流的概念和作用流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。IO流的分类根据处理数据类型的不同分为:字符流和字节流 根据数据流向不同分为:输入流和输出流字符流和字节流字符流的由来: 因为数据编码的不同,而有了对字符进行高效操作的流对象。本质其实就是基于字节流读取时,去查了指定的码.

2021-09-13 14:57:01 58

原创 java提高篇(一)-----理解java的三大特性之封装

从大二接触java开始,到现在也差不多三个年头了。从最基础的HTML、CSS到最后的SSH自己都是一步一个脚印走出来的,其中开心过、失落过、寂寞过。虽然是半道出家但是经过自己的努力也算是完成了“学业”。期间参加过培训机构,但是极其不喜欢那种培训方式,于是毅然的放弃了选择自学(可怜我出了6000块钱啊),虽然自学途中苦很多,但是乐更多,当中的付出和收获只有自己知道。黄天不负有心人,鄙人愚钝,在大四第一学期终于自学完成java(其中走了弯路,荒废半年),并且凭借它得到了一份不错的工作,不胜感激!...

2021-09-13 14:55:37 114

原创 java提高篇(二三)-----HashMap

HashMap也是我们使用非常多的Collection,它是基于哈希表的 Map 接口的实现,以key-value的形式存在。在HashMap中,key-value总是会当做一个整体来处理,系统会根据hash算法来来计算key-value的存储位置,我们总是可以通过key快速地存、取value。下面就来分析HashMap的存取。一、定义 HashMap实现了Map接口,继承AbstractMap。其中Map接口定义了键映射到值的规则,而AbstractMap类提供 Map 接口的骨干实现,...

2021-09-13 14:51:53 68

原创 JAVA回调机制(CallBack)详解

序言最近学习java,接触到了回调机制(CallBack)。初识时感觉比较混乱,而且在网上搜索到的相关的讲解,要么一言带过,要么说的比较单纯的像是给CallBack做了一个定义。当然了,我在理解了回调之后,再去看网上的各种讲解,确实没什么问题。但是,对于初学的我来说,缺了一个循序渐进的过程。此处,将我对回调机制的个人理解,按照由浅到深的顺序描述一下,如有不妥之处,望不吝赐教!开始之前,先想象一个场景:幼稚园的小朋友刚刚学习了10以内的加法。第1章. 故事的缘起幼师在黑板上写一个式子 “1 +

2021-09-13 14:51:11 955

原创 Java并发之AQS详解

一、概述  谈到并发,不得不谈ReentrantLock;而谈到ReentrantLock,不得不谈AbstractQueuedSynchronizer(AQS)!  类如其名,抽象的队列式的同步器,AQS定义了一套多线程访问共享资源的同步器框架,许多同步类实现都依赖于它,如常用的ReentrantLock/Semaphore/CountDownLatch...。  以下是本文的目录大纲: 概述 框架 源码详解 简单应用   若有不正之处,请谅解和批评指正,不胜感激。 

2021-09-13 14:49:49 51

原创 java提高篇(四)-----理解java的三大特性之多态

面向对象编程有三大特性:封装、继承、多态。 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据。对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法。 继承是为了重用父类代码。两个类若存在IS-A的关系就可以使用继承。,同时继承也为实现多态做了铺垫。那么什么是多态呢?多态的实现机制又是什么?请看我一一为你揭开: 所谓多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行...

2021-09-13 14:48:57 73

原创 简述 Java总结篇系列的Java泛型

一. 泛型概念的提出(为什么需要泛型)?首先,我们看下下面这段简短的代码: 1 public class GenericTest { 2 3 public static void main(String[] args) { 4 List list = new ArrayList(); 5 list.add("qqyumidi"); 6 list.add("corn"); 7 list.add(100); 8

2021-09-13 14:44:47 52

原创 Java 中如何实现线程间通信

世界以痛吻我,要我报之以歌 —— 泰戈尔《飞鸟集》虽然通常每个子线程只需要完成自己的任务,但是有时我们希望多个线程一起工作来完成一个任务,这就涉及到线程间通信。关于线程间通信本文涉及到的方法和类包括:thread.join()、object.wait()、object.notify()、CountdownLatch、CyclicBarrier、FutureTask、Callable。接下来将用几个例子来介绍如何在Java中实现线程间通信:如何让两个线程依次执行,即一个线程等待另一个线程执.

2021-09-10 16:00:35 136

原创 HashMap实现原理和源码详细分析

HashMap实现原理和源码详细分析ps:本博客基于Jdk1.8学习要点: 1、知道HashMap的数据结构 2、了解HashMap中的散列算法 3、知道HashMap中put、remove、get的代码实现 4、HashMap的哈希冲突是什么?怎么处理的? 5、知道HashMap的扩容机制1、什么是HashMap?HashMap 基于哈希表的 Map 接口实现,是以 key-value 存储形式存在 ,HashMap 的实现不是同步的,这意味着它不是线程安全的。它的 key、value

2021-09-10 15:59:58 80

原创 Java基础之SPI机制

SPI 机制,全称为 Service Provider Interface,是一种服务发现机制。它通过在 ClassPath 路径下的 META-INF/services 文件夹查找文件,自动加载文件里所定义的类。这一机制为很多框架扩展提供了可能,比如在 Dubbo、JDBC 中都使用到了 SPI 机制。本文介绍了 Java SPI 机制以及在模块化和非模块话项目中的实现方式(此处的模块化指 Java9 引入的模块化)SPI 机制介绍SPI 全称 Service Provider Interface

2021-09-10 15:58:06 118

原创 CountDownLatch 闭锁源码分析

功能简介闭锁是一种同步工具类,可以延迟线程的进度直到其到达终止状态【CPJ 3.4.2】。闭锁的作用相当于一扇门∶ 在闭锁到达结束状态之前,这扇门一直是关闭的,并且没有任何线程能通过,当到达结束状态时,这扇门会打开并允许所有的线程通过。当闭锁到达结束状态后,将不会再改变状态,因此这扇门将永远保持打开状态。闭锁可以用来确保某些活动直到其他活动都完成后才继续执行,例如∶确保某个计算在其需要的所有资源都被初始化之后才继续执行。二元闭锁(包括两个状态)可以用来表示"资源R已经被初始化",而所有需要 R 的操

2021-09-10 15:53:03 82

转载 原来这就是比 ThreadLocal 更快的玩意?

你好,我是yes。继上一篇之后我把 ThreadLocal 能问的,都写了之后,咱们再来盘一盘 FastThreadLocal ,这个算是 ThreadLocal 的进阶版,是 Netty 针对 ThreadLocal 自己造的轮子,所以对 ThreadLocal 没有完全理解的话,建议先看上一篇文章,打个基础。那了解 FastThreadLocal 之后呢,对平日的一些优化可能可以提供一些思路,或者面试就能装个x。面试官:ThreadLocal 竟然有xxx这个缺点,那怎么优化啊?你就把

2021-09-10 15:51:33 182

空空如也

空空如也

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

TA关注的人

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