当前位置:   article > 正文

Java经典面试宝典及答案(持续收录)_java面试宝典

java面试宝典

文章目录


前言

持续更新中

一、Java基础

1、Java中有几种基本数据类型?

    Java分成四个大类–即四类八种:

整形浮点型字符型布尔型
byte 、short 、int 、longfloat 、 doublecharboolean
2、equals 和 == 的区别?

     ==是判断两个变量或实例是不是指向同一个内存空间 equals是判断两个变量或实例所指向的内存空间的值是不是相同
     注意:1.==可用于基本类型以及引用类型的比较,2.基本类型无equals方法,3.Object类的equals方法比较的是地址值

3、 Integer a =128; Integer b = Integer.valueOf(128); 为什么a与b不相等?

       虽然Integer a=128底层也是调用了Integer.valueOf()方法,但已经超出-128~127 这个范围,此时会重新new一个Integer对象,当使用==运算符时,比较的是对象的地址

	    public static Integer valueOf(int i) {
	        if (i >= IntegerCache.low && i <= IntegerCache.high)
	            return IntegerCache.cache[i + (-IntegerCache.low)];
	        return new Integer(i);
	    }
  • 1
  • 2
  • 3
  • 4
  • 5
4、 String str=”ab”,与String str=new String(“ab”)一样吗?

      1、 不一样的。前者会被分配到JVM的常量池中,后者将被分配到JVM的堆中
      2、 第一种,创建的”aaa”是常量,JVM都将其分配在常量池中。
      3、 第二种创建的是一个对象,JVM将其值分配在堆内存中。

5、 如何将String对象放入到常量池?

      1、“XXX” 双引号String 对象会自动放入常量池
      2、调用String的intern 方法也会将对象放入到常量池中。

6、new string(“ab”)共创建几个对象(前提条件:所有对象首次创建)?

      共创建两个对象 :
      对象1:new string(xxxx)方法
      对象2:常量池中的"ab"

7、String str = new String(“a”) + new String(“b”)共创建几个对象(前提条件:所有对象首次创建)?

      共创建六个对象:
      对象1:new StringBuilder()

      对象2:new String(“a”)

      对象3:常量池中的"a"

      对象4:new String(“b”)

      对象5:常量池中的"b"

      对象6:new String(“ab”)

8、 什么是常量池、运行时常量池、字符串常量池?

      1、常量池
每个class一份,存在于字节码文件中。常量池中有字面量(数量值、字符串值)和符号引用(类符号引用、字段符号引用、方法符号引用),虚拟机指令根据这张常量表找到要执行的类名、方法名、参数类型、字面量等类型

      2、运行时常量池
每个class一份,存在于方法区中(元空间)。当类加载到内存中后,jvm就会将class常量池中的内容存放到运行时常量池中,经过解析(resolve)之后,也就是把符号引用替换为直接引用,解析的过程会去查询全局字符串池,也就是下面的StringTable,以保证运行时常量池所引用的字符串与全局字符串池中所引用的是一致的。

      3、字符串常量池
每个JVM中只有一份,存在于堆中。全局字符串池里的内容是在类加载完成,经过验证,准备阶段之后在堆中生成字符串对象实例,然后将该字符串对象实例的引用值存到string pool中(string pool中存的是引用值而不是具体的实例对象,具体的实例对象是在堆中开辟的一块空间存放的)。 在HotSpot VM里实现的string pool功能的是一个StringTable类,它是一个哈希表,里面存的是驻留字符串(用双引号括起来的引用而不是驻留字符串实例本身),也就是说在堆中的某些字符串实例被这个StringTable引用之后就等同被赋予了”驻留字符串”的身份。

9、String、StringBuffer、StringBuilder有什么区别?

      1、String的内容不可修改,每次对String类型的改变时都会生成一个新的对象。StringBuffer与StringBuilder的内容可以修改.
      2、StringBuffer与StringBuilder大部分功能是相似的,StringBuffer采用同步处理,属于线程安全操作;而StringBuilder未采用同步处理,属于线程不安全操作。性能对比:StringBuilder > StringBuffer > String

10、JVM 有哪些运行时内存区域?(JDK8)

      1、 The pc Register,程序计数器

      2、 Java Virtual Machine Stacks,Java 虚拟机栈

      3、 Heap,堆

      4、 Metaspace,元数据空间

      5、 Native Method Stacks,本地方法栈

11、JVM怎么判断一个对象是不是要回收?

      1、引用计数法(缺点是对于相互引用的对象,无法进行清除):通过判断对象的引用数量来决定对象是否可以被回收

      2、可达性分析:通过判断对象的引用链是否可达来决定对象是否可以被回收

12、简述分代垃圾回收器是怎么工作的?
	分为新生代和老年代,新生代默认占总空间的 1/3,老年代默认占 2/3。
	新生代使用复制算法,有 3 个分区:Eden、To Survivor、From Survivor,它们的默认占比是 8:1:1。
	当新生代中的 Eden 区内存不足时,就会触发 Minor GC,过程如下:
	1、 在 Eden 区执行了第一次 GC 之后,存活的对象会被移动到其中一个 Survivor 分区;
	2、 Eden 区再次 GC,这时会采用复制算法,将 Eden 和 from 区一起清理,存活的对象会被复制到 to 区
	3、 移动一次,对象年龄加 1,对象年龄大于一定阀值会直接移动到老年代
	4、 Survivor 区相同年龄所有对象大小的总和 (Survivor 区内存大小 * 这个目标使用率)时,
	大于或等于该年龄的对象直接进入老年代。其中这个使用率通过 -XX:TargetSurvivorRatio 指定,
	默认为 50%
	5、 Survivor 区内存不足会发生担保分配
	6、 超过指定大小的对象可以直接进入老年代
	Major GC,指的是老年代的垃圾清理,但并未找到明确说明何时在进行Major GC
	FullGC,整个堆的垃圾收集,触发条件:
	1、 每次晋升到老年代的对象平均大小>老年代剩余空间
	2、 MinorGC后存活的对象超过了老年代剩余空间
	3、 元空间不足
	4、 System.gc() 可能会引起
	5、 CMS GC异常,promotion failed:MinorGC时,survivor空间放不下,对象只能放入老年代,
	而老年代也放不下造成;concurrent mode failure:GC时,同时有对象要放入老年代,
	而老年代空间不足造成
	6、 堆内存分配很大的对象
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
13、简述JVM类加载机制?

        JVM 类加载机制分为五个部分:加载,验证,准备,解析,初始化

14、简述JVM双亲委派模型?

        双亲委派模型:
         1、向上委托:如果一个类加载器收到了类加载请求,它并不会自己先去加载,而是把这个请求委托给父类的加载器去执行,如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归,请求最终将到达顶层的启动类加载器。如果父类加载器可以完成类加载任务,就成功返回;(采用递归)
         2、向下委派:倘若父类加载器无法完成此加载任务,子加载器才会尝试自己去加载。

15、Java中有几种方法可以实现一个线程?

        1、继承 Thread 类
        2、实现 Runnable 接口
        3、实现 Callable 接口,需要实现的是 call() 方法

16、Java线程具有五中基本状态?

        1、 新建状态(New):当线程对象对创建后,即进入了新建状态,如:Thread t = new MyThread();

        2、 就绪状态(Runnable):当调用线程对象的start()方法(t.start();),线程即进入就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,随时等待CPU调度执行,并不是说执行了t.start()此线程立即就会执行;

        3、 运行状态(Running):当CPU开始调度处于就绪状态的线程时,此时线程才得以真正执行,即进入到运行状态。注:就 绪状态是进入到运行状态的唯一入口,也就是说,线程要想进入运行状态执行,首先必须处于就绪状态中;

        4、 阻塞状态(Blocked):处于运行状态中的线程由于某种原因,暂时放弃对CPU的使用权,停止执行,此时进入阻塞状态,直到其进入到就绪状态,才 有机会再次被CPU调用以进入到运行状态。

根据阻塞产生的原因不同,阻塞状态又可以分为三种:

                1、 等待阻塞:运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态;

                2、 同步阻塞:线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态;

                3、 其他阻塞:通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。

        5、 死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

17、一个线程运行时发生异常会怎样?

        如果异常没有被捕获,该线程将会停止执行。Thread.UncaughtExceptionHandler是用于处理未捕获异常造成线程突然中断情况的一个内嵌接口。当一个未捕获异常将造成线程中断的时候JVM会使用Thread.getUncaughtExceptionHandler()来查询线程的UncaughtExceptionHandler并将线程和异常作为参数传递给handler的uncaughtException()方法进行处理。

18、在 Java 程序中怎么保证多线程的运行安全?

        出现线程安全问题的原因一般都是三个原因:

        1、 线程切换带来的原子性问题 解决办法:使用多线程之间同步synchronized或使用锁(lock)。

        2、 缓存导致的可见性问题 解决办法:synchronized、volatile、LOCK,可以解决可见性问题

        3、 编译优化带来的有序性问题 解决办法:Happens-Before 规则可以解决有序性问题

19、volatile 类型变量提供什么保证?

        1、 对于可见性,Java 提供了 volatile 关键字来保证可见性和禁止指令重排。 volatile 提供 happens-before 的保证,确保一个线程的修改能对其他线程是可见的。当一个共享变量被 volatile修饰时,它会保证修改的值会立即被更新到主内存中,当有其他线程需要读取时,它会去内存中读取新值。

        2、 从实践角度而言,volatile 的一个重要作用就是和 CAS 结合,保证了原子性,详细的可以参见 java.util.concurrent.atomic 包下的类,比如 AtomicInteger。

        3、 volatile 常用于多线程环境下的单次操作(单次读或者单次写)。。

20、线程的 run()和 start()有什么区别?

        1、 每个线程都是通过某个特定Thread对象所对应的方法run()来完成其操作的,run()方法称为线程体。通过调用Thread类的start()方法来启动一个线程。

        2、 start() 方法用于启动线程,run() 方法用于执行线程的运行时代码。run() 可以重复调用,而 start() 只能调用一次。

        3、 start()方法来启动一个线程,真正实现了多线程运行。调用start()方法无需等待run方法体代码执行完毕,可以直接继续执行其他的代码; 此时线程是处于就绪状态,并没有运行。 然后通过此Thread类调用方法run()来完成其运行状态, run()方法运行结束, 此线程终止。然后CPU再调度其它线程。

        4、 run()方法是在本线程里的,只是线程里的一个函数,而不是多线程的。 如果直接调用run(),其实就相当于是调用了一个普通函数而已,直接待用run()方法必须等待run()方法执行完毕才能执行下面的代码,所以执行路径还是只有一条,根本就没有线程的特征,所以在多线程执行时要使用start()方法而不是run()方法。

21、Java 中的 HashSet,内部是如何工作的?

        HashSet 的内部采用 HashMap来实现。由于 Map 需要 key 和 value,所以所有 key 的都有一个默认 value。类似于 HashMap,HashSet 不允许重复的 key,只允许有一个null key,意思就是 HashSet 中只允许存储一个 null 对象

二、Java框架

1、什么是Spring的依赖注入?

         依赖注入(Dependency Injection)和控制反转(Inversion of Control)是同一个概念。具体含义是:当某个角色(可能是一个Java实例,调用者)需要另一个角色(另一个Java实例,被调用者)的协助时,在 传统的程序设计过程中,通常由调用者来创建被调用者的实例。但在Spring里,创建被调用者的工作不再由调用者来完成,因此称为控制反转;创建被调用者 实例的工作通常由Spring容器来完成,然后注入调用者,因此也称为依赖注入。

2、什么是AOP?

         AOP的全称是Aspect-Oriented Programming,即面向切面编程(也称面向方面编程)。它是面向对象编程(OOP)的一种补充,目前已成为一种比较成熟的编程方式

        a.目前最流行的AOP框架有两个,分别为Spring AOP和AspectJ。

        b.Spring AOP使用纯Java实现,不需要专门的编译过程和类加载器,在运行期间通过代理方式向目标类织入增强的代码。

        c.AspectJ是一个基于Java语言的AOP框架,从Spring 2.0开始,Spring AOP引入了对AspectJ的支持,AspectJ扩展了Java语言,提供了一个专门的编译器,在编译时提供横向代码的织入

3、Spring、SpringBoot、SpringMVC的区别?

        1、 Spring框架就像一个家族,有众多衍生产品,例如boot、mvc、jpa等等。但他们的基础都是Spring的ioc、aop。ioc提供了依赖注入的容器,aop解决了面向横切面编程,然后在此两者的基础上实现了其它延伸产品的高级功能;

        2、 springMVC是基于Servlet的一个MVC框架主要解决WEB开发的问题

        3、 为了简化开发的使用,从而创造性地推出了SpringBoot框架,默认优于配置

4、@SpringBootApplication注释在内部有什么用处?

        作为Spring引导文档,@SpringBootApplication注释等同于同时使用@Configuration、@EnableAutoConfiguration和@ComponentScan及其默认属性。SpringBoot允许开发人员使用单个注释而不是多个注释。但是,众所周知,Spring提供了松散耦合的特性,我们可以根据项目需要为每个注释使用这些特性。

5、SpringBoot 的核心注解是哪个?它主要由哪几个注解组成的?

        启动类上面的注解是@SpringBootApplication,它也是 SpringBoot 的核心注解,主要组合包含了以下 3 个注解:

@SpringBootConfiguration:组合了 @Configuration 注解,实现配置文件的功能。

@EnableAutoConfiguration:打开自动配置的功能,也可以关闭某个自动配置的选项,如关闭数据源自动配置功能:@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })。

@ComponentScan:Spring组件扫描。

6、SpringCloud 断路器的作用是什么?

        在分布式架构中,断路器模式的作用也是类似的,当某个服务单元发生故障(类似用电器发生短路)之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个错误响应,而不是长时间的等待。这样就不会使得线程因调用故障服务被长时间占用不释放,避免了故障在分布式系统中的蔓延。

7、SpringBoot 有哪几种读取配置的方式?

        @PropertySource
        @Value
        @Environment
        @ConfigurationPropertie

8、SpringBoot 中的监视器是什么?

        Spring boot actuator 是 spring 启动框架中的重要功能之一。Spring boot 监视器可帮助您访问生产环境中正在运行的应用程序的当前状态。有几个指标必须在生产环境中进行检查和监控。即使一些外部应用程序可能正在使用这些服务来向相关人员触发警报消息。监视器模块公开了一组可直接作为 HTTP URL 访问的REST 端点来检查状态。

9、请描述Spring MVC的工作流程?描述一下 DispatcherServlet 的工作流程?

        1、 用户发送请求至前端控制器DispatcherServlet;
        2、 DispatcherServlet收到请求后,调用HandlerMapping处理器映射器,请求获取Handle;
        3、 处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet;
        4、 DispatcherServlet 调用 HandlerAdapter处理器适配器;
        5、 HandlerAdapter 经过适配调用 具体处理器(Handler,也叫后端控制器);
        6、 Handler执行完成返回ModelAndView;
        7、 HandlerAdapter将Handler执行结果ModelAndView返回给DispatcherServlet;
        8、 DispatcherServlet将ModelAndView传给ViewResolver视图解析器进行解析;
        9、 ViewResolver解析后返回具体View;
        10、DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)
        11、DispatcherServlet响应用户。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/码创造者/article/detail/838285
推荐阅读
相关标签
  

闽ICP备14008679号