java面试题
文章平均质量分 62
java的面试题
无语堵上西楼
这个作者很懒,什么都没留下…
展开
-
SpringBoot 实现异步
通过 CompletableFuture,可以以函数式的风格组合和处理异步任务,支持链式调用、异常处理、超时设置等功能。通过定义自定义事件和监听器,并发布事件,可以实现在应用程序中的不同模块之间进行消息的传递和处理。Java 提供了Executor 框架来实现线程池,通过预先创建一组线程并管理它们的执行,可以有效地处理并发任务,避免线程的频繁创建和销毁。通过在方法上添加 @Async 注解,可以让方法在独立的线程中异步执行,而不会阻塞当前线程。Java 中的基本并发单元,它代表着一个单独的执行线程。原创 2024-04-02 09:20:29 · 288 阅读 · 0 评论 -
SpringBoot 与 Spring 的优缺点有哪些?
Spring 框架是一个非常流行的框架,它为开发者提供了大量的功能和特性,如依赖注入、面向切面编程等。原创 2024-04-02 08:49:22 · 734 阅读 · 0 评论 -
责任链设计模式
又名职责链模式,为了避免请求发送者与多个请求处理者耦合在一起,将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。比较常见的springmvc中的拦截器,web开发中的filter过滤器。原创 2024-03-30 23:36:47 · 424 阅读 · 0 评论 -
工厂+策略的案例
下图是gitee的登录的入口,其中有多种方式可以进行登录用户名密码登录短信验证码登录微信登录QQ登录....原创 2024-03-30 23:19:00 · 756 阅读 · 0 评论 -
线程池使用场景CountDownLatch、Future
CountDownLatch(闭锁/倒计时锁)用来进行线程同步协作,等待所有线程完成倒计时(一个或者多个线程,等待其他多个线程完成某件事情之后才能执行)其中构造参数用来初始化等待计数值await() 用来等待计数归零countDown() 用来让计数减一。原创 2024-03-30 15:35:42 · 445 阅读 · 0 评论 -
JVM实践(调优)
修改TOMCAT_HOME/bin/catalina.sh文件,如下图。原创 2024-03-30 11:34:18 · 631 阅读 · 0 评论 -
gc垃圾收回
新生代和老年代【1:2】,在java7时,还存在一个永久代。对于新生代,内部又被分为了三个区域。Eden区,S0区,S1区【8:1:1】当对新生代产生GC:MinorGC【young GC】当对老年代代产生GC:Major GC当对新生代和老年代产生FullGC: 新生代 + 老年代完整垃圾回收,暂停时间长,应尽力避免应用于新生代和老年代,在**JDK9之后默认使用G1**原创 2024-03-30 11:21:57 · 848 阅读 · 0 评论 -
ArrayBlockingQueue的LinkedBlockingQueue区别
当没有空闲核心线程时,新来任务会加入到此队列排队,队列满会创建救急线程执行任务:基于数组结构的有界阻塞队列,FIFO。:基于链表结构的有界阻塞队列,FIFO。:是一个优先级队列,它可以保证每次出队的任务都是当前队列中执行时间最靠前的:不存储元素的阻塞队列,每个插入操作都必须等待一个移出操作。默认无界,支持有界强制有界底层是链表底层是数组是懒惰的,创建节点的时候添加数据提前初始化Node数组入队会生成新NodeNode需要是提前创建好的两把锁(头尾进行操作)原创 2024-03-29 18:12:30 · 291 阅读 · 0 评论 -
多线程并发,如何保证执行顺序性
还有很多方法都可以实现这个效果,其实它的本质就是保证同一时刻只有一个线程执行临界区的代码,从而保证多线程执行的顺序性,只不过现在要求的是上一个执行者能够指定下一个执行者而已,因此,我们还可以考虑使用 Condition。signal()方法来实现指定一个环境变量的等待区的线程唤醒。这样就可以选择性地唤醒指定的线程。执行完成后,此线程再继续竞争时间片去执行。阻塞调用此方法的线程进入。原创 2024-03-29 15:46:13 · 231 阅读 · 0 评论 -
线程和进程的区别?并行和并发有什么区别?互斥和同步的区别
互斥是指在同一时间只允许一个线程访问共享资源。当一个线程正在使用共享资源时,其他线程需。同步是指多个线程之间按照一定的顺序协调执行,以确保共享资源的正确访问。以相互通信和协调,以便按照预期的顺序执行任务。同步通常使用信号量、条件变量或者其他线程。要等待,直到该线程释放资源。这样可以避免多个线程同时修改共享资源导致的数据不一致性问。互斥通常通过使用锁(如互斥锁、信号量等)来实现。保证共享变量的访问原子性。保证了共享变量在多线程下的正确顺序访问。并行(parallel)是同一时间动手做(doing。原创 2024-03-29 15:11:46 · 95 阅读 · 0 评论 -
阻塞队列ArrayBlockingQueue原理
ArrayBlockingQueue是基于数组结构的阻塞队列,也就是队列元素是存储在一个数组结构里。它的有序性保证是通过加锁来实现的,也就是每个消费者线程去阻塞队列获取任务的时候必须。有任务要处理的时候,这些被阻塞的消费者线程会严格按照。的队列,也就是存储进去的元素符合先进先出的规则。要实现这样的一个阻塞队列,需要用到两个关键的技术。)是在队列的基础上增加了两个附加操作,对于阻塞队列的消费过程,有两种情况。实现线程的阻塞和唤醒,用到了。在阻塞队列里面,使用了。的顺序来唤醒,从而保证了。原创 2024-03-29 15:08:55 · 351 阅读 · 0 评论 -
HashSet底层原理
方法在添加新的键值对时,如果之前没有相同的键值对存在,则返回 null。,说明之前没有同样的元素存在,新元素添加成功;如果返回值非 null。如果存在相同的键值对,则会进行替换,并返回被替换的旧值。来判断是否成功添加了元素。如果返回值为 null。这个双列集合作为底层实现,源自于其的值都丢到。就用一个虚拟对象来占位,没啥用的,就占位。,说明已经存在相同的元素,添加操作失败。它一个单列集合能够以。原创 2024-03-29 14:18:19 · 122 阅读 · 0 评论 -
HashMap多线程下死循环问题
HashMap死循环问题是JDK1.7之前存在问题,主要源于HashMap的自身的工作机制和并发处理导致的问题,而对于JDK1.8后,官方就彻底解决了这个问题,对于死循环问题,我们首先了解一下HashMap数据插入原理在Java的HashMap中,put()操作采用的是头插法,也就是。如有相同的key值插入,会覆盖旧元素。如果新元素的key值在HashMap中不存在,则会新建一个节点并放在链表头部。原创 2024-03-29 12:26:45 · 268 阅读 · 0 评论 -
红黑树和AVL树的区别
规则1:每个节点不是黑色就是红色规则2:根节点为黑色规则3:红色节点的父节点和子节点不能为红色规则4:所有的叶子节点都是黑色(空节点视为叶子节点NIL规则5:每个节点到叶子节点的每个路径黑色节点的个数都相等。规则1:每个节点最多只有两个子节点(二叉)规则2:每个节点的值比它的左子树所有的节点大,比它的右子树所有节点小(有序)规则3:每个节点左子树的高度与右子树高度之差的绝对值不超过1。原创 2024-03-29 12:08:54 · 368 阅读 · 0 评论 -
HashMap底层结构
HashMap的实现结构主要有三个:二叉树红黑树散列表。原创 2024-03-29 12:06:35 · 627 阅读 · 0 评论 -
数组与List转换后的引用传递问题
来构造的集合,在这个集合的构造器中,,跟原来的元素就没啥关系了,所以即使。而已,最终指向的都是同一个内存地址。之后,如果修改了数组的内容,会受影响,因为它的底层使用的。内容,数组不会影响,当调用了。修改了以后,数组也不受影响。转数组后,如果修改了。原创 2024-03-29 10:43:27 · 99 阅读 · 0 评论 -
Spring事务失效
对象的方法调用,并在方法调用前后进行一些操作,比如实现事务管理、缓存处理等。这样,通过代理对象的调用,就可以实现一些横切关注点的统一处理。注解标记的方法中,出现了异常但是该异常被捕获并处理了,并没有抛出异常,那么这个事务就会正常提交,而不是回滚。来在其前后分别设置事务开启和事务提交操作的增强,那么这些的前提是在于,你的操作环境是在于。的实现原理在于以该注解为切面坐标,在扫描动态生成的代理类中以此坐标。况,通常表示程序运行中可能出现的外部错误或不正常情况。是基于动态代理实现的,当创建。的事务管理器拦截,非。原创 2024-03-18 17:47:56 · 369 阅读 · 0 评论 -
Spring中的Bean都是代理Bean?
方法被标记为@Transactional注解,表示该方法需要被事务管理。,则不需要做任何特殊的标记,它会作为原始对象被实例化和注入。代理,以实现事务管理的功能,而OrderService。加载的对象确实大部分是通过代理方式生成的AOP。仍然会作为原始对象被实例化和注入。代理对象,但仍然存在一部分对象是原始对象。会将其作为原始对象进行实例化和注入。都会被声明为需要代理,只有被特定的。初始化时将该代理对象注入到其他需要。则没有任何特殊的注解标记,因此。的配置中,我们可以通过对。代理对象,并在Bean。原创 2024-03-17 00:06:00 · 485 阅读 · 0 评论 -
重写与重载的区别
重载和重写在Java编程中经常被使用,它们分别提供了方法的多态性和继承时的多态性。原创 2024-03-16 17:50:23 · 352 阅读 · 0 评论 -
Maven生命周期、解决依赖冲突、scope
Maven的生命周期并非只有一套,而是有三套,并且这三套生命周期之间是没有关系的。一套生命周期包含很多个不同的阶段,这些不同的阶段是有顺序的,有些阶段必须要在某个阶段完成之后,才能进行。Maven的三套生命周期分别为:clean(清理),default(默认),site(站点)用于清理项目,clean生命周期包括以下3个阶段:pre-clean: 清理前的准备工作;clean:清理上一次构建的结果;post-clean:清理结束后需要完成的工作。default。原创 2024-03-12 21:09:18 · 363 阅读 · 0 评论 -
用户态和内核态
在Java中,程序一般都运行在用户态,通过Java虚拟机提供的接口和功能来访问底层的系统资源和硬件设备。在Java中,用户态和内核态主要是操作系统级别的概念,而不是Java语言本身的概念。Java程序通过Java虚拟机提供的接口和功能来访问底层的系统资源和硬件设备,而无需直接涉及操作系统的内核态。在用户态下,程序只能访问自己的内存空间和受限的系统资源,无法直接访问操作系统的核心功能和硬件设备。Java程序一般运行在用户态,通过Java虚拟机(JVM)提供的接口和功能来访问底层的系统资源和硬件设备。原创 2023-12-22 13:16:32 · 912 阅读 · 0 评论 -
Servlet和jsp的区别
Servlet有良好的生存期的定义,包括加载和实例化、初始化、处理请求以及服务结束。这个生存期由javax.servlet.Servlet接口的init(),service()和destroy方法表达。Servlet被服务器实例化后,容器运行其init方法,请求到达时运行其service方法,service方法自动派遣运行与请求对应的doXXX方法(doGet,doPost)等,当服务器决定将实例销毁的时候调用其destroy方法。web容器加载servlet,生命周期开始。原创 2023-12-17 21:10:56 · 27 阅读 · 0 评论 -
springboot常用注解,项目的开发流程是什么?
当开发使用Spring Boot框架进行接口开发时,注解起着非常重要的作用。注解是一种特殊的标记,可以用于给类、方法、属性等添加元数据和行为信息。通过使用注解,我们可以在代码中添加额外的信息,从而实现一些特定的功能或行为。原创 2023-11-28 09:36:37 · 34 阅读 · 0 评论 -
java的动态代理
动态代理是 Java 语言提供的一种机制,它允许程序在运行时动态地创建代理对象,并将方法调用转发到被代理对象上。动态代理通常被用于实现 AOP(面向切面编程)和某些设计模式中。无侵入式的给方法增强功能。原创 2023-11-26 23:23:12 · 377 阅读 · 0 评论 -
java的方法引用
方法引用的出现原因:在使用Lambda表达式的时候,我们实际上传递进去的代码就是一种解决方案:拿参数做操作那么考虑一种情况:如果我们在Lambda中所指定的操作方案,已经有地方存在相同方案,那是否还有必要再写重复逻辑呢?答案肯定是没有必要那我们又是如何使用已经存在的方案的呢?这就是我们要讲解的方法引用,我们是通过方法引用来使用已经存在的方案代码演示。原创 2023-11-26 22:50:34 · 21 阅读 · 0 评论 -
不可变集合
是一个长度不可变,内容也无法修改的集合。原创 2023-11-26 22:36:45 · 19 阅读 · 0 评论 -
Java之stream流
按照下面的要求完成集合的创建和遍历创建一个集合,存储多个字符串元素把集合中所有以"张"开头的元素存储到一个新的集合把"张"开头的集合中的长度为3的元素存储到一个新的集合遍历上一步得到的集合原始方式示例代码使用Stream流示例代码Stream流的好处直接阅读代码的字面意思即可完美展示无关逻辑方式的语义:获取流、过滤姓张、过滤长度为3、逐一打印Stream流把真正的函数式编程风格引入到Java中代码简洁。原创 2023-11-26 22:35:59 · 24 阅读 · 0 评论 -
函数式接口及Lamda表达式详解
函数式接口应用在函数式编程中,Lambda表达式是函数式编程的体现通过函数式接口和Lambda表达式可以简化代码,提高开发效率。同时可能会不利于代码调试,或者对于不熟悉函数式编程的同事不容易阅读对应代码。原创 2023-11-26 20:29:49 · 28 阅读 · 0 评论 -
java的任务执行
ForkJoinPool可以给我们提供分⽽治之的功能,当我们有⼤量任务需要处理的时候,我们可以将其分为N个批次,然后每个批次开启⼦线程去并发执⾏,当⼦线程都执⾏完毕后,再对结果进⾏汇总计算。这种思想就类似于Hadoop的MapReduce⽅式。其中,fork表示开启⼀个执⾏分⽀,即:创建⼦线程去执⾏某些任务。⽽join我们在前⾯也介绍过,它具有等待的含义,也就是使⽤fork()后系统多了⼀个执⾏分⽀或执⾏线程,所以需要等待这个分⽀执⾏完毕,才能进⾏最后结果汇总的计算。原创 2023-11-20 11:16:19 · 175 阅读 · 0 评论 -
java的并发容器
JDK提供的这些容器⼤部分在java.util.concurrent包中。我们挑选出⼀些⽐较有代表性的并发容器类,来感受⼀下JDK⾃带的并发集合带来的“快感”。ConcurrentLinkedQueue是⼀个基于链接节点的⽆界线程安全队列,它采⽤先进先出的规则对节点进⾏排序,当我们添加⼀个元素的时候,它会添加到队列的尾部,当我们获取⼀个元素时,它会返回队列头部的元素。ConcurrentLinkedQueue算是在⾼并发环境中性能最好的队列。原创 2023-11-20 10:30:42 · 258 阅读 · 0 评论 -
数据结构详解
栈(stack)是限制插入和删除只能在一个位置上进行的表,该位置是表的末端,叫做栈顶(top)。它是后进先出(LIFO)的。对栈的基本操作只有 push(进栈)和 pop(出栈)两种,前者相当于插入,后者相当于删除最后的元素。原创 2023-11-19 11:44:06 · 19 阅读 · 0 评论 -
代码项目日志
slf4j 的全称是 Simple Loging Facade For Java,即它仅仅是一个为 Java 程序提供日志输出的统一接口,并不是一个具体的日志实现方案,就比如 JDBC 一样,只是一种规则而已。所以单独的slf4j 是不能工作的,必须搭配其他具体的日志实现方案,比如 apache 的 org.apache.log4j.Logger,jdk 自带的 java.util.logging.Logger 等。原创 2023-11-18 20:13:31 · 27 阅读 · 0 评论 -
JAVA 内部类
定义在方法中的类,就是局部类。如果一个类只在某个方法中使用,则可以考虑使用局部类。原创 2023-11-18 17:13:00 · 25 阅读 · 0 评论 -
抽象类和接口区别,类的变量初始化顺序
抽象类(Abstract Class)和接口(Interface)是面向对象编程中的两个重要概念,它们都用于实现类与类之间的关系和行为的定义,但在设计和使用上有一些区别。原创 2023-11-18 14:17:53 · 44 阅读 · 0 评论 -
JAVA NIO
NIONIONIO 主要有三大核心部分:Channel(通道),Buffer(缓冲区), Selector。传统 IO 基于字节流和字符流进行操作,而 NIO 基于 Channel 和 Buffer(缓冲区)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。Selector(选择区)用于监听多个通道的事件(比如:连接打开,数据到达)。因此,单个线程可以监听多个数据通道。NIO 和传统 IO 之间第一个最大的区别是,IO 是面向流的,NIO 是面向缓冲区的。原创 2023-11-17 17:15:42 · 15 阅读 · 0 评论 -
JAVA IO/NIO
最传统的一种 IO 模型,即在读写数据过程中会发生阻塞现象。当用户线程发出 IO 请求之后,内核会去查看数据是否就绪,如果没有就绪就会等待数据就绪,而用户线程就会处于阻塞状态,用户线程交出 CPU。当数据就绪之后,内核会将数据拷贝到用户线程,并返回结果给用户线程,用户线程才解除 block 状态。典型的阻塞 IO 模型的例子为:;如果数据没有就绪,就会一直阻塞在 read 方法。当用户线程发起一个 read 操作后,并不需要等待,而是马上就得到了一个结果。原创 2023-11-17 16:50:48 · 18 阅读 · 0 评论 -
CountDownLatch倒计时器,CyclicBarrier循环栅栏,LockSupport线程阻塞⼯具类
CountDownLatch倒计时器CountDownLatch倒计时器CountDownLatch是⼀个多线程控制⼯具。⽤来控制线程的等待。设置需要countDown的数量num,然后每⼀个线程执⾏完毕后,调⽤countDown()⽅法,⽽主线程调⽤await()⽅法执⾏等待,直到num个⼦线程执⾏了countDown()⽅法 ,则主线程开始继续执⾏。CyclicBarrier循环栅栏CyclicBarrier.await()⽅法可能会抛出两种异常:⼀个是。原创 2023-11-17 13:24:45 · 31 阅读 · 0 评论 -
Semaphore信号量,ReadWriteLock读写锁
SemaphoreSemaphore⼴义上说,Semapore信号量是对锁的⼀种扩展;因为⽆论是内部锁synchronized,还是重⼊锁ReentrantLock,⼀次都只允许⼀个线程访问某⼀资源,⽽信号量却可以指定多个线程同时访问某⼀个资源。信息量主要提供了⼀下构造函数,必须要指定信号量的准⼊数,即:同时能申请多少个许可public;// permits:准⼊数public;// permits:准⼊数,fair:是否公平获得锁信息量主要⽅法如下所示:acquire();原创 2023-11-17 13:08:00 · 39 阅读 · 0 评论 -
ReentrantLock重⼊锁
重⼊锁可以完全替代synchronized关键字。在JDK50的早期版本中,重⼊锁的性能远远好于synchronized,但从JDK60开始,JDK在synchronized上做了⼤量的优化,使得两者的性能差距并不⼤。重⼊锁对逻辑控制的灵活性要远远好于synchronized。常⽤⽅法voidlock():获得锁,如果锁已经被占⽤,则等待。void:获得锁,但优先响应中断。booleantryLock():尝试获得锁,如果成功,返回true;如果失败则返回false;原创 2023-11-17 10:27:42 · 24 阅读 · 0 评论 -
对象头具体都包含哪些内容?什么是指针碰撞?什么是空闲列表?什么是TLAB?
对象头对象头在我们常用的Hotspot虚拟机中,对象在内存中布局实际包含3个部分:对象头实例数据对齐填充而对象头包含两部分内容,Mark Word中的内容会随着锁标志位而发生变化,所以只说存储结构就好了。对象自身运行时所需的数据,也被称为Mark Word,也就是用于轻量级锁和偏向锁的关键点。具体的内容包含对象的hashcode、分代年龄、轻量级锁指针、重量级锁指针、GC标记、偏向锁线程ID、偏向锁时间戳。原创 2023-11-16 20:18:13 · 33 阅读 · 0 评论