![](https://img-blog.csdnimg.cn/20201014180756923.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
java
++自学者
这个作者很懒,什么都没留下…
展开
-
对Integer和Double类型判断相等
Integer、Double不能直接进行比较,这包括:不能用==进行直接比较,因为它们是不同的数据类型;不能转为字符串进行比较,因为转为字符串后,浮点值带小数点,整数值不带,这样它们永远都不相等;不能使用compareTo方法进行比较,虽然它们都有compareTo方法,但该方法只能对相同类型进行比较。整数、浮点类型的包装类,都继承于Number类型,而Number类型分别定义了将数字转换为byte、short、int、long、float、double的方法。所以,可以将Integer、Do原创 2022-12-29 16:56:33 · 477 阅读 · 1 评论 -
自动装箱、自动拆箱的应用场景
自动装箱、自动拆箱是JDK1.5提供的功能。自动装箱:可以把一个基本类型的数据直接赋值给对应的包装类型;自动拆箱:可以把一个包装类型的对象直接赋值给对应的基本类型;通过自动装箱、自动拆箱功能,可以大大简化基本类型变量和包装类对象之间的转换过程。比如,某个方法的参数类型为包装类型,调用时我们所持有的数据却是基本类型的值,则可以不做任何特殊的处理,直接将这个基本类型的值传入给方法即可原创 2022-12-29 16:54:20 · 287 阅读 · 0 评论 -
实例变量的默认值
实例变量若为引用数据类型,其默认值一律为null。若为基本数据类型,其默认值如下:byte:0short:0int:0long:0Lfloat:0.0Fdouble:0.0char:'\u0000'boolean:false注意事项上述默认值规则适用于所有的成员变量,所以对于类变量也是适用的。原创 2022-12-29 16:50:35 · 227 阅读 · 0 评论 -
全局变量和局部变量的区别
Java中的变量分为成员变量和局部变量,它们的区别如下:成员变量:1. 成员变量是在类的范围里定义的变量;2. 成员变量有默认初始值;3. 未被static修饰的成员变量也叫实例变量,它存储于对象所在的堆内存中,生命周期与对象相同;4. 被static修饰的成员变量也叫类变量,它存储于方法区中,生命周期与当前类相同。局部变量:1. 局部变量是在方法里定义的变量;2. 局部变量没有默认初始值;3. 局部变量存储于栈内存中,作用的范围结束,变量空间会自动的释放原创 2022-12-29 16:48:40 · 112 阅读 · 0 评论 -
Java的数据类型
Java数据类型包括基本数据类型和引用数据类型两大类。基本数据类型有8个,可以分为4个小类,分别是整数类型(byte/short/int/long)、浮点类型(float/double)、字符类型(char)、布尔类型(boolean)。其中,4个整数类型中,int类型最为常用。2个浮点类型中,double最为常用。另外,在这8个基本类型当中,除了布尔类型之外的其他7个类型,都可以看做是数字类型,它们相互之间可以进行类型转换。引用类型就是对一个对象的引用,根据引用对象类型的不同,可以将引用原创 2022-12-29 16:44:38 · 268 阅读 · 0 评论 -
Java访问权限符
java语言为我们提供了三种访问修饰符,即private、protected、public,在使用这些修饰符修饰目标时,一共可以形成四种访问权限,即private、default、protected、public,注意在不加任何修饰符时为default访问权限。在修饰成员变量/成员方法时,该成员的四种访问权限的含义如下:private:该成员可以被该类内部成员访问;default:该成员可以被该类内部成员访问,也可以被同一包下其他的类访问;protected:该成员可以被该类内部成员访问,也原创 2022-12-29 16:42:37 · 319 阅读 · 0 评论 -
Java文件里可以有多个类
1. 一个java文件里可以有多个类,但最多只能有一个被public修饰的类;2. 如果这个java文件中包含public修饰的类,则这个类的名称必须和java文件名一致。原创 2022-12-29 16:38:46 · 2179 阅读 · 0 评论 -
Java代码可以实现一次编写、到处运行
JVM(Java虚拟机)是Java跨平台的关键。在程序运行前,Java源代码(.java)需要经过编译器编译成字节码(.class)。在程序运行时,JVM负责将字节码翻译成特定平台下的机器码并运行,也就是说,只要在不同的平台上安装对应的JVM,就可以运行字节码文件。同一份Java源代码在不同的平台上运行,它不需要做任何的改变,并且只需要编译一次。而编译好的字节码,是通过JVM这个中间的“桥梁”实现跨平台的,JVM是与平台相关的软件,它能将统一的字节码翻译成该平台的机器码。注意事项1. 编译的原创 2022-12-29 16:37:58 · 322 阅读 · 0 评论 -
分片上传简介
1、什么是分片上传分片上传,就是将所要上传的文件,按照一定的大小,将整个文件分隔成多个数据块(我们称之为Part)来进行分别上传,上传完之后再由服务端对所有上传的文件进行汇总整合成原始的文件。2、分片上传的场景1.大文件上传2.网络环境环境不好,存在需要重传风险的场景原创 2022-12-15 18:15:26 · 378 阅读 · 0 评论 -
1、什么是Mybatis
1、Mybatis是一个半ORM(对象关系映射)框架,它内部封装了JDBC,开发时只需要关注SQL语句本身,不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。程序员直接编写原生态sql,可以严格控制sql执行性能,灵活度高。2、MyBatis 可以使用 XML 或注解来配置和映射原生信息,将 POJO映射成数据库中的记录,避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。3、通过xml 文件或注解的方式将要执行的各种 statement 配置起来,并通过java原创 2022-12-13 18:42:05 · 84 阅读 · 0 评论 -
mysql建索引应遵循原则
1.选择唯一性索引唯一性索引的值是唯一的,可以更快速的通过该索引来确定某条记录。例如,学生表中学号是具有唯一性的字段。为该字段建立唯一性索引可以很快的确定某个学生的信息。如果使用姓名的话,可能存在同名现象,从而降低查询速度。2.为经常需要排序、分组和联合操作的字段建立索引经常需要ORDER BY、GROUP BY、DISTINCT和UNION等操作的字段,排序操作会浪费很多时间。如果为其建立索引,可以有效地避免排序操作。3.为常作为查询条件的字段建立索引如果某个字段经常用来做查询条件,那原创 2022-12-12 13:02:31 · 112 阅读 · 0 评论 -
Comparable和Comparator的区别
ComparableComparable可以认为是一个内比较器,实现了Comparable接口的类有一个特点,就是这些类是可以和自己比较的,至于具体和另一个实现了Comparable接口的类如何比较,则依赖compareTo方法的实现。如果add进入一个Collection的对象想要Collections的sort方法帮你自动进行排序的话,那么这个对象必须实现Comparable接口。compareTo方法的返回值是int,有三种情况: 比较者大于被比较者,返回正整数 比较者等于被原创 2022-12-11 21:37:59 · 72 阅读 · 0 评论 -
Java序列化与反序列化
Java序列化是指把Java对象转换为字节序列的过程,而Java反序列化是指把字节序列恢复为Java对象的过程: 序列化:对象序列化的最主要的用处就是在传递和保存对象的时候,保证对象的完整性和可传递性。序列化是把对象转换成有序字节流,以便在网络上传输或者保存在本地文件中。核心作用是对象状态的保存与重建。 反序列化:客户端从文件中或网络上获得序列化后的对象字节流,根据字节流中所保存的对象状态及描述信息,通过反序列化重建对象。 为什么需要序列化与反序列化?为什么要序列化,那就是说一原创 2022-12-11 21:30:38 · 714 阅读 · 0 评论 -
CopyOnWriteArrayList的迭代器不支持增删改
privatestaticvoidCopyOnWriteArrayListTest(){CopyOnWriteArrayList<String>list=newCopyOnWriteArrayList<>();list.add("test1");list.add("test2");list.add("test3");list.add("test4");Iterator<String>it原创 2022-12-09 12:45:40 · 535 阅读 · 0 评论 -
CopyOnWriteArrayList是弱一致性的
publicIterator<E>iterator(){returnnewCOWIterator<E>(getArray(),0);}staticfinalclassCOWIterator<E>implementsListIterator<E>{/**Snapshotofthearray*/privatefinalObject[]snapshot;/**Index原创 2022-12-09 12:44:59 · 223 阅读 · 0 评论 -
CopyOnWriteArrayList内存占用过多
CopyOnWrite,顾名思义就是写的时候会将共享变量新复制一份出来,这样做的好处是读操作完全无锁。CopyOnWriteArrayList的add()方法publicbooleanadd(Ee){//获取独占锁finalReentrantLocklock=this.lock;lock.lock();try{//获取arrayObject[]elements=getArray();原创 2022-12-09 12:43:09 · 409 阅读 · 0 评论 -
LinkedList的插入速度不一定比ArrayList快
学习数据结构的时候,我们就已经得出了结论 对于数组,随机元素访问的时间复杂度是0(1), 元素插入操作是O(n); 对于链表,随机元素访问的时间复杂度是O(n), 元素插入操作是0(1). 元素插入对于链表来说应该是他的优势但是他就一定比数组快? 我们执行插入1000w次的操作privatestaticvoidtest(){StopWatchstopWatch=newStopWatch();intelementCount=100000;原创 2022-12-09 12:40:27 · 437 阅读 · 0 评论 -
ArrayList中的 subList 强转 ArrayList 导致异常
阿里《Java开发手册》上提过[强制] ArrayList的sublist结果不可強转成ArrayList,否则会抛出ClassCastException异常,即java.util.RandomAccesSubList cannot be cast to java. util.ArrayList.说明: subList 返回的是ArrayList 的内部类SubList, 并不是ArrayList ,而是ArrayList的一个视图,対于SubList子列表的所有操作最终会反映到原列表上。原创 2022-12-09 08:33:26 · 758 阅读 · 0 评论 -
java.util.ArrayList如果不正确操作也不支持增删操作
在第二个坑的时候,我们说到了Arrays.asList返回的 List 不支持增删操作,是因为他的自己实现了一个内部类ArrayList,这个内部类继承了AbstractList没有实现add()和remove()方法导致操作失败。但是第三个坑的时候,我们利用java.util.ArrayList包装了返回的 List,进行增删操作还是会失败,那是为什么呢?删除方法逻辑:在foreach中操作增删,因为因为modCount会被修改,与第一步保存的数组修改次原创 2022-12-09 08:26:27 · 183 阅读 · 0 评论 -
Arrays.asList返回的List不支持增删操作
我们将数组对象转成List数据结构之后,竟然不能进行增删操作了privatestaticvoidasListAdd(){String[]arr={"1","2","3"};List<String>strings=newArrayList<>(Arrays.asList(arr));arr[2]="4";System.out.println(strings.toString());Iterator<原创 2022-12-09 08:09:16 · 352 阅读 · 0 评论 -
秒杀实现技巧
需求分析“秒杀”这个词在电商行业中出现的频率较高,如京东或者淘宝平台的各种“秒杀”活动,最典型的就是“双11抢购”。“秒杀”是指在有限的时间内对有限的商品数量进行抢购的一种行为,这是商家以“低价量少”的商品来获取用户的一种营销手段。01. 功能性需求其实,整个秒杀的业务场景并不复杂,可即查看参与秒杀的商品信息,加上购买和支付的动作,如下图所示。秒杀业务最大的挑战在于3点: 瞬时:持续时间极短,对于热门且具备极强竞争力的商品通常只有一秒。 流量巨大:因为价格低廉,原创 2022-12-04 17:40:29 · 805 阅读 · 0 评论 -
SpringBoot参数校验
简单使用Java API规范(JSR303)定义了Bean校验的标准validation-api,但没有提供实现。hibernate validation是对这个规范的实现,并增加了校验注解如@Email、@Length等。Spring Validation是对hibernate validation的二次封装,用于支持spring mvc参数自动校验。接下来,我们以spring-boot项目为例,介绍Spring Validation的使用。引入依赖如果spring-boot版本小于原创 2022-12-04 10:41:12 · 874 阅读 · 0 评论 -
100000行级别数据的 Excel 导入优化
需求说明项目中有一个 Excel 导入的需求:缴费记录导入由实施 / 用户 将别的系统的数据填入我们系统中的 Excel 模板,应用将文件内容读取、校对、转换之后产生欠费数据、票据、票据详情并存储到数据库中。在接手之前可能由于之前导入的数据量并不多没有对效率有过高的追求。但是到了 4.0 版本,预估导入时Excel 行数会是 10w+ 级别,而往数据库插入的数据量是大于 3n 的,也就是说 10w 行的 Excel,则至少向数据库插入 30w 行数据。因此优化原来的导入代码是势在必行的。逐步分析和优原创 2022-12-04 10:13:28 · 544 阅读 · 0 评论 -
@ControllerAdvice
默认情况下,@ControllerAdvice 中的方法应用于全局所有的 Controller。而使用选择器 annotations(),basePackageClasses() 和 basePackages() (或其别名 value())来定义更小范围的目标 Controller 子集。如果声明了多个选择器,则应用 OR 逻辑,这意味着所选的控制器应匹配至少一个选择器。请注意,选择器检查是在运行时执行的,因此添加许多选择器可能会对性能产生负面影响并增加复杂性。@ControllerAdvice原创 2022-12-03 22:22:27 · 590 阅读 · 0 评论 -
@Configuration
@Configuration 表明在一个类里可以声明一个或多个 @Bean 方法,并且可以由 Spring 容器处理,以便在运行时为这些 bean 生成 bean 定义和服务请求,例如:@ConfigurationpublicclassAppConfig{@BeanpublicMyBeanmyBean(){//instantiate,configureandreturnbean...}}我们可以通过 Annotation翻译 2022-12-03 22:17:57 · 738 阅读 · 0 评论 -
将一个类声明为 Spring 的 bean 的注解有哪些?
@Component :通用的注解,可标注任意类为 Spring 的组件。如果一个 Bean 不知道属于哪个层,可以使用 @Component 注解标注。@Repository :对应持久层即 Dao 层,主要用于数据库相关操作。@Service :对应服务层,主要设计一些复杂的逻辑,需要用到 Dao 层。@Controller :对应 Spring MVC 控制层,主要用来接受用户请求并调用 Service 层返回数据给前端页面。@Configuration :声明该类为一个配置类,可以在原创 2022-12-03 22:13:14 · 807 阅读 · 0 评论 -
业务开发时,接口不能对外暴露的解决方案
1.内外网接口微服务隔离将对外暴露的接口和对内暴露的接口分别放到两个微服务上,一个服务里所有的接口均对外暴露,另一个服务的接口只能内网服务间调用。该方案需要额外编写一个只对内部暴露接口的微服务,将所有只能对内暴露的业务接口聚合到这个微服务里,通过这个聚合的微服务,分别去各个业务侧获取资源。该方案,新增一个微服务做请求转发,增加了系统的复杂性,增大了调用耗时以及后期的维护成本。2.网关 + redis 实现白名单机制在 redis 里维护一套接口白名单列表,外部请求到达网关时,从 redi原创 2022-12-03 22:01:09 · 1487 阅读 · 0 评论 -
实现生成订单 30 分钟未支付,则自动取消
该方案是利用 JDK 自带的 DelayQueue 来实现,这是一个无界阻塞队列,该队列只有在延迟期满的时候才能从中获取元素,放入 DelayQueue 中的对象,是必须实现 Delayed 接口的。该方案通常是在小型项目中使用,即通过一个线程定时的去扫描数据库,通过订单时间来判断是否有超时的订单,然后进行 update 或 delete 等操作。take():获取并移除队列的超时元素,如果没有则 wait 当前线程,直到有元素满足超时条件,返回结果。在开发中,往往会遇到一些关于延时任务的需求。原创 2022-12-02 09:03:05 · 337 阅读 · 0 评论 -
ConcurrentHashMap的实现原理
1. HashMap在高并发的环境下,执行put操作会导致HashMap的Entry链表形成环形数据结构,从而导致Entry的next节点始终不为空,因此产生死循环获取Entry2. HashTable虽然是线程安全的,但是效率低下,当一个线程访问HashTable的同步方法时,其他线程如果也访问HashTable的同步方法,那么会进入阻塞或者轮训状态。3. 在jdk1.6中ConcurrentHashMap使用锁分段技术提高并发访问效率。原创 2022-11-15 15:00:00 · 411 阅读 · 0 评论 -
线程池拒绝策略(4)
在调⽤者线程中执⾏该任务。该策略实现了⼀种调节机制,该策略既不会抛弃任务,也不会抛出异常,⽽是将任务回退到调⽤者(调⽤线程池执⾏任务的主线程),由于执⾏任务需要⼀定时间,因此主线程⾄少在⼀段时间内不能提交任务,从⽽使得线程池有时间来处理完正在执⾏的任务。抛弃阻塞队列中最⽼的任务,相当于就是队列中下⼀个将要被执⾏的任务,然后重新提交被拒绝的任务。如果阻塞队列是⼀个优先队列,那么“抛弃最旧的”策略将导致抛弃优先级最⾼的任务,因此最好不要将该策略和优先级队列放在⼀起使⽤。什么都不做,直接抛弃被拒绝的任务。原创 2022-11-13 14:00:00 · 214 阅读 · 0 评论 -
线程池的核⼼属性(7)
handler(拒绝策略):往线程池添加任务时,将在下⾯两种情况触发拒绝策略:1)线程池运⾏状态不是 RUNNING;keepAliveTime(保持存活时间):如果线程池当前线程数超过 corePoolSize,则多余的线程空闲时间超过 keepAliveTime 时会被终⽌。corePoolSize(核⼼线程数):当线程池运⾏的线程少于 corePoolSize 时,将创建⼀个新线程来处理请求,即使其他⼯作线程处于空闲状态。maximumPoolSize(最⼤线程数):线程池允许开启的最⼤线程数。原创 2022-11-13 14:30:00 · 214 阅读 · 0 评论 -
synchronized 各种加锁场景的作⽤范围
2)作⽤于静态⽅法,锁住的是类的Class对象,因为Class的相关数据存储在永久代元空间,元空间是全局共享的,因此静态⽅法锁相当于类的⼀个全局锁,会锁所有调⽤该⽅法的线程。3)作⽤于 Lock.class,锁住的是 Lock 的Class对象,也是全局只有⼀个。5)作⽤于静态成员变量,锁住的是该静态成员变量对象,由于是静态变量,因此全局只有⼀个。1)作⽤于⾮静态⽅法,锁住的是对象实例(this),每⼀个对象实例有⼀个锁。4)作⽤于 this,锁住的是对象实例,每⼀个对象实例有⼀个锁。原创 2022-11-13 14:30:00 · 362 阅读 · 0 评论 -
线程的 sleep() ⽅法和 yield() ⽅法有什么区别
线程执⾏ sleep() ⽅法后进⼊超时等待(TIMED_WAITING)状态,⽽执⾏ yield() ⽅法后进⼊就绪 (READY)状态。sleep() ⽅法给其他线程运⾏机会时不考虑线程的优先级,因此会给低优先级的线程运⾏的机会; yield() ⽅法只会给相同优先级或更⾼优先级的线程以运⾏的机会。原创 2022-11-13 14:15:00 · 179 阅读 · 0 评论 -
wait() 和 sleep() ⽅法的区别
来源不同:sleep() 来⾃ Thread 类,wait() 来⾃ Object 类。对于同步锁的影响不同:sleep() 不会该表同步锁的⾏为,如果当前线程持有同步锁,那么 sleep 是不会让线程释放同步锁的。wait() 会释放同步锁,让其他线程进⼊ synchronized 代码块执⾏。使⽤范围不同:sleep() 可以在任何地⽅使⽤。wait() 只能在同步控制⽅法或者同步控制块⾥⾯使⽤,否则会抛 IllegalMonitorStateException。恢复⽅式不同:两者会暂停当前线程,但是在原创 2022-11-13 15:00:00 · 203 阅读 · 0 评论