Java经典面试题下包含答案

这篇具有很好参考价值的文章主要介绍了Java经典面试题下包含答案。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Java经典面试题下包含答案,Java开发面试,java,开发语言,jvm,intellij-idea

21.String、StringBuffer和StringBuilder的区别是什么?

线程安全:

  • String中的对象是不可变的,线程安全
  • StringBuffer对方法加了同步锁,所以是线程安全的
  • StringBuilder没有对方法加同步锁,所以是非线程安全的

使用效率:

  • String进行操作时,每次都会生成一个新的String对象,然后将指针指向新的String对象。
  • 而StringBuffer和StringBuilder每次都会对本身进行操作而不是生成新对象。StringBuilder比StringBuffer使用效率较高,但线程不安全

可变性:
String:
Java经典面试题下包含答案,Java开发面试,java,开发语言,jvm,intellij-idea
fianl修饰的类不能被继承,修饰的方法不能被重写,修饰的基本类型数据不能改变,修饰的引用类型则不能在指向其他对象。因为final修饰的数组并不是String不可变的根本原因,因为这个数组保存的内部数据是可变的,真正的原因有以下几点:

  1. 字符串数组被final修饰并且为私有,并且String没有提供修改这个字符串的方法
  2. String类被final修饰导致不能被继承,避免了子类破坏String不可变

StringBuilder与StringBuffer:
Java经典面试题下包含答案,Java开发面试,java,开发语言,jvm,intellij-idea
StringBuilder与StringBuffer都继承于AbstractStringBuilder,该抽象类也是使用字符数组保存字符串,但没有使用final和private修饰。而且还提供很多操作字符串的方法
Java经典面试题下包含答案,Java开发面试,java,开发语言,jvm,intellij-idea
如何选择三者:

  • 少量操作使用String
  • 单线程下大量操作使用StringBuilder
  • 多线程下大量操作使用StringBuffer

字符串拼接使用 + 还是StringBuilder?

public static void main(String[] args) {
        String str = "";
        long start = System.currentTimeMillis();
        for (int i = 0; i < 100000; i++) {
            str += "a";
        }
        long end = System.currentTimeMillis();
        System.out.println("String拼接100000次花费时间: " + (end - start));
        StringBuilder stringBuilder = new StringBuilder();
        start = System.currentTimeMillis();
        for (int i = 0; i < 100000; i++) {
            stringBuilder.append("a");
        }
        end = System.currentTimeMillis();
        System.out.println("StringBuilder拼接100000次花费时间: " + (end - start));
    }

Java经典面试题下包含答案,Java开发面试,java,开发语言,jvm,intellij-idea
首先我们可以得出当数据量很大时,StringBuilder的拼接效率远远高于String拼接,那么为什么呢?

因为String通过"+“进行拼接时,实现会先创建StringBuilder然后调用append()调用toString()得到一个String对象。当我们在循环里使用”+"进行拼接时,会创建大量的StringBuilder对象,每循环一次就会创建一个

字符串常量池:
字符串常量池主要是为了提升性能并减少内存消耗,给字符串专门开辟了一块区域,为了防止字符串重复创建

public static void main(String[] args) {
        // 将字符串"abc"保存在字符串常量池
        String s1 = "abc";
        // 从字符串常量池直接返回"abc"的引用
        String s2 = "abc";
        System.out.println(s1 == s2);
    }

Java经典面试题下包含答案,Java开发面试,java,开发语言,jvm,intellij-idea
String s = new String(“a”) 会创建几个对象?
这里分两种情况:

  1. 常量池存在"abc"的引用,那么只会在堆空间中创建一个对象
  2. 常量池中不存在"abc"的引用,首先会在字符串常量池中创建,然后再堆中创建,那么共创建2个字符串对象

intern()是做什么的?
intern()是一个native方法,作用是将字符串保存在常量池中,也分为以下两种情况:

  1. 字符串常量池存在该字符串的引用,直接返回该引用
  2. 字符串常量池不存在该字符串的引用,就在常量池创建一个指向该字符串对象并将引用返回

String变量与常量做+运算时发生了什么?

public static void main(String[] args) {
        String str1 = "abc";
        String str2 = "efg";
        String str3 = "abc" + "efg";
        String str4 = str1 + str2;
        String str5 = "abcefg";
        System.out.println(str3 == str4);
        System.out.println(str3 == str5);
        System.out.println(str4 == str5);
    }

Java经典面试题下包含答案,Java开发面试,java,开发语言,jvm,intellij-idea
为什么会出现这种情况呢?
因为对于编译器可以确定的字符串,也就是字符串常量,JVM会将其存入字符串常量池。也会将拼接后的字符串常量在编译器就存入字符串常量池,得益于编译器优化。

例如:

		String str3 = "abc" + "efg";
        String str3 = "abcefg";

大家需要注意不是所有常量都可以进行折叠(常量折叠是将常量表达式的值嵌入在最终代码中,这是Javac编译器堆源代码做的优化),只有在编译器可以确定的常量才可以:

  • final修饰的基本数据类型和字符串变量
  • 基本数据类型基于字符串常量

上述str4是引用的值在编译器是无法确定的,所以我们编译器无法对其进行优化
它相当于:

String str4 = new StringBuilder().append(str1).append(str2).toString();

但是如果我们给字符串变量加上final修饰后,就可以让编译器将其当作常量来处理

public static void main(String[] args) {
        final String str1 = "abc";
        final String str2 = "efg";
        String str3 = "abc" + "efg";
        String str4 = str1 + str2;
        String str5 = "abcefg";
        System.out.println(str3 == str4);
        System.out.println(str3 == str5);
        System.out.println(str4 == str5);
    }

Java经典面试题下包含答案,Java开发面试,java,开发语言,jvm,intellij-idea
我们给str1,str2加上final修饰后,String会被编译器当作常量进行处理,在编译期就可以确定它的值,相当于常量访问。

22.方法常见知识

静态方法为什么不能调用非静态成员?
1.静态方法是属于类的,在类加载的时候就会分配内存,可以通过类名直接访问。而非静态成员是属于实例对象的,只有对象实例化之后才存在,需要通过类的实例对象去访问
2.在类的非静态成员不存在时静态方法就已经存在了,此时调用内存中不存在的非静态成员是非法的

静态方法和实例方法有什么不同?
1.调用方式:
在调用静态方法时,可以使用类名.方法名 ,也可以使用对象.方法名 的方式,而实例方法只能使用后面这种方法,静态方法不依赖对象
但是我们为了避免混淆静态方法和非静态方法,我们一般建议使用类名.方法名的方式来调用静态方法

2.访问类成员是否存在限制
静态方法在访问本类成员时,只需要访问静态成员和方法,不能访问实例成员和方法。

什么是可变长参数?
从Java5开始,Java支持可变长参数,也就是允许调用方法时可以传入不定长度的参数,比如:

public static int add(int... n) {
        int sum = 0;
        for (int i : n) {
            sum += i;
        }
        return sum;
    }

Java经典面试题下包含答案,Java开发面试,java,开发语言,jvm,intellij-idea
需要注意的是,可变参数只能作为函数的最后一个参数,前面可以有任意个参数,包含0个

public static int add(String name,int... n) {
}

如果方法重载了,优先调用固定参数还是可变参数呢?
这里是会优先匹配固定参数的方法,因为固定参数的方法匹配度更高

public static int add(int n) {
        return 0;
    }
    public static int add(int... n) {
        return 1;
    }

Java经典面试题下包含答案,Java开发面试,java,开发语言,jvm,intellij-idea
实际上,我们Java中的可变参数在编译后会被转换成一个数组

23.数值运算精度问题

为什么浮点数运算的时候会有精度丢失问题?

public static void main(String[] args) {
        float a = 2.6f - 1.7f;
        float b = 1.6f - 0.7f;
        System.out.println(a);
        System.out.println(b);
        System.out.println(a == b);
    }

Java经典面试题下包含答案,Java开发面试,java,开发语言,jvm,intellij-idea
与计算机在保存浮点数的方式有关系。我们计算机是二进制表示的,计算一个数字时宽度是有限的,无限循环的小树存储在计算机时只能被截断,这也是为什么浮点数没有办法用二进制精确表示

如何解决浮点数运算精度丢失问题?
我们可以使用BigDecimal来实现对浮点数的运算,大部分对运算精度要求比较高的业务场景,都是通过BigDecimal来做的

public static void main(String[] args) {
        BigDecimal a = new BigDecimal("3.0");
        BigDecimal b = new BigDecimal("2.0");
        BigDecimal c = new BigDecimal("1.0");
        System.out.println(a.subtract(b));
        System.out.println(b.subtract(c));
        System.out.println(a.subtract(b).equals(b.subtract(c)));
    }

Java经典面试题下包含答案,Java开发面试,java,开发语言,jvm,intellij-idea
超过long整型的数据应该如何表示?
在Java中,64位long整型是最大的整型类型,但如果超过这个范围就会有数值溢出的风险

public static void main(String[] args) {
        long a = Long.MAX_VALUE;
        System.out.println(a+1);
    }

Java经典面试题下包含答案,Java开发面试,java,开发语言,jvm,intellij-idea
我们可以使用BigInteger来表示:

public static void main(String[] args) {
        BigInteger a = new BigInteger("111111111111111111111111111111111111111");
        BigInteger b = new BigInteger("111111111111111111111111111111111111111");
        System.out.println(a.add(b));
    }

Java经典面试题下包含答案,Java开发面试,java,开发语言,jvm,intellij-idea
Java经典面试题下包含答案,Java开发面试,java,开发语言,jvm,intellij-idea
我们可以发现BigInteger内部使用int[ ]数组来存储任意大小的整型数据,但BigInteger的运算效率相对较低

24.异常

Java(Throwable)的结构可分为三种类型:错误(Error)、被检查的异常(CheckedException)、运行时异常(RuntimeException)
Java经典面试题下包含答案,Java开发面试,java,开发语言,jvm,intellij-idea
Exception和Error有什么关系?
Java中,所有的异常都有一个公共祖先:java.lang包中的Throwable类,而Exception和Error为Throwable类中两个重要子类:

Error: 当资源不足,约束失败,或者是其他程序无法继续运行的条件发生时,就产生Error,程序无法处理的错误。比如:虚拟机内存不够错误(OutOfMemoryError)、虚拟机运行错误(Virtual MachineError)、类加载错误(NoClassDefFoundError)等。当发生这些异常时,JVM会选择终止该线程

Exception: 程序本身可以处理的异常,我们可以通过try - catch进行捕获异常,Exception可以分为必须处理的受检查异常(Checked Exception) 和 可以不处理的非受查异常(Unchecked Exception)

Checked Exception 和 Unchecked Exception 有什么区别?

Unchecked Exception: 该种类型的错误,Java编译器不会检查,当出现该种异常时,即使没有通过throws声明抛出它,也没有使用try-catch语句捕捉它,仍然会编译通过。
RuntimeException及子类都统称为非受查异常,比如:

  • NullPointerException:空指针异常
  • illegalArgumentException:参数异常
  • ArrayIndexOutOfBoundsException:数组越界异常
  • ClassCastException:类型转换异常
  • ArithmeticException:算数异常
  • SecurityException:安全异常
  • IllegalStateException:非法状态异常
  • UnsupportedOperationException:不支持的操作异常
  • NumberFormatException:数值格式异常
    Java经典面试题下包含答案,Java开发面试,java,开发语言,jvm,intellij-idea

Checked Exception: 受查异常,如果没有被catch或者throws处理的话,就无法通过编译器。除了RuntimeException及子类外,其他Exception类及子类都属于受查异常,常见的有:

  • ClassNotFoundException
  • IOException
  • FileNotFoundException
  • SQLException

总结:受查异常通常不是程序引起的错误,比如:读取文件时文件不存在引发的:FileNotFoundException。而非受查异常通常是因为糟糕的编程引起的,比如:在没有确保对象引用非空时就使用而引起的:NullPointerException

Throwable有哪些常见方法?
Java经典面试题下包含答案,Java开发面试,java,开发语言,jvm,intellij-idea

  • String getMessage():返回异常的简要描述
  • String toString():返回异常的详细信息
  • void printStackTrace():在控制台打印Throwable对象封装的异常信息
  • String getLocalizedMessage():返回异常对象的本地化信息。使用Throwable子类重写该方法,可以生成本地化信息。如果没有重写,那么与getMessage()返回结果相同

25.OOM你遇到过哪些情况,SOF你遇到过哪些情况

OOM
1.OutOfMemoryError异常:
除了程序计算器外,虚拟机内存的其他几个区域都有可能发生OOM异常的可能。
Java Heap溢出:一般异常信息为java.lang.OutOfMemoryError:Java heap spacess
Java堆用于存储对象实例,只要我们不断地创建对象,并且保证GC Roots到对象之间有可达路径来避免垃圾回收机制来清理这些对象,就会在对象数量达到最大堆容量限制后产生内存溢出异常,当出现该异常时,我们一般先通过内存映像分析工具(Eclipse Memory Analyzer) 堆dump除了的对转存快照进行分析,重点是确认内存中的对象是否是必要的,分清是因为内存泄漏(Memory Leak)还是内存溢出(Memory Overflow)
如果内存泄漏,可进一步通过工具查看泄露对象到GCRoots的引用链,排查是怎样的路径与GCRoots关联导致垃圾收集器无法自动回收

如果不存在泄露,就检查虚拟机参数(-Xmx与-Xms)是否合适

2.虚拟机和本地方法栈溢出:
如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError,如果虚拟机在扩展栈时无法申请到足够的内存空间,抛出OutOfMemoryError异常

3.方法区溢出:
方法区用于存放Class的相关信息,如类名、访问修饰符、字段描述、方法描述等。异常信息为:java.lang.OutOfMemoryError:PermGenspace,有可能是方法区保存的class对象没有被及时回收或者class信息占用的内存超出了我们的配置

方法区溢出也是一种我们常见的内存溢出异常,一个类如果要被垃圾收集器回收,判定条件是比较苛刻的。

SOF(StackOverflow栈溢出溢出):
该异常一般当应用程序递归太深而发生堆栈溢出时会抛出该错误

需要注意的是,栈溢出错误往往意味着代码存在问题,过于深的调用层次可能会导致性能和可维护性问题。因此,在解决 StackOverflowError 时,建议对代码进行仔细检查和优化,确保代码的健壮性和性能。

26.语法糖

语法糖:语法糖是指编程语言为了方便程序员开发而设计的一种特殊语法,这种语法对编译语言的功能并没有影响,实现一个相同的功能,基于语法糖写出的代码往往更加简洁。
常见的语法糖有哪些:
泛型、lambda表达式、自动拆装箱、try-with-resources语法、变长参数、增强for循环等

比如:Java中的for-each

public static void main(String[] args) {
        int[] arr = {1,2,3,4,5,6,7};
        for (int i : arr) {
            System.out.println(i);
        }
    }

我们的JVM本身是不能识别语法糖的,Java的语法糖要想被正确执行,需要先通过编译器进行解糖,在编译阶段讲语法糖转为JVM认识的语法。也说明真正支持语法糖的是Java编译器而不是JVM,在compile()中有一部就是desugar(),复负责语法糖解糖的。

27.Java反射的作用与原理

反射:在运行时,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意个对象,都能够调用它的任意一个方法。在java中,只要给定类的名字,就可以通过反射来获得类的所有信息。这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制

哪里会用到反射机制?
jdbc就是典型的反射:

Class.for("com.mysql.jdbc.Drivice.class");//加载MySQL的驱动类

这就是反射。我们大部分都在写业务代码,很少接触到直接使用反射的场景,这并不代表反射没有用,相反,正是因为反射,我们才能这么轻松的使用各种框架。Spring/Spring Boot、MyBatis等框架中都大量使用了反射机制

反射的实现方式:

  1. 获取Class对象:一共有四种方法: 1) Class.forName(“类路径”);2) 类名.class;3)对象名.getClass();4)基本类型的包装类,可以调用包装类的Type属性类获取该包装类的Class对象
Class<?> clazz = Class.forName("com.example.zd")
  1. 获取类的字段:getField(“filename”)方法:可以获取public修饰的字段。getDeclaredField(“filedName”)可以获取指定名称的字段,无论修饰符是什么
Field field = clazz.getDeclaredField("fieldName")
  1. 获取类的方法信息:getMethod(“methodName”,parameterTypes),可获取指定名称和参数类型的公共(public)方法;使用getDeclaredMethod(“methodName”,parameterTypes)方法,可以获取指定名称和参数类型的方法,无论修饰符是什么
Method method = clazz.getDeclaredMethod("methodName", String.class, int.class)
  1. 创建对象实例:使用newInstance()方法,可以通过无参构造函数创建一个对象实例,例如:
Object obj = clazz.newInstance()

使用getConstructor(parameterTypes).newInstacne(arguments)方法可以通过指定构造方法和参数创建对象

Constructor<?> constructor = clazz.getConstructor(String.class, int.class); 
Object obj = constructor.newInstance("arg1", 123)

反射的优缺点:
反射可以让我们的代码更加灵活、为各种框架提供开箱即用的功能提供了便利。不过,反射让我们在运行时有了分析操作类的能力同时,也增加了安全问题,比如:可以无视泛型参数的安全检查(泛型参数的安全检查发生在编译时)。另外,反射的性能也要稍微差点,不过对框架影响不大文章来源地址https://www.toymoban.com/news/detail-523243.html

到了这里,关于Java经典面试题下包含答案的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 2023金三银四1000道java面试必考题(附答案,赶紧收藏)包含所有大厂高频面试知识点

    我的回答是: 很有必要 。你可以讨厌这种模式,但你一定要去背,因为不背你就进不了大厂。现如今,Java 面试的本质就是八股文,把八股文面试题背好,面试才有可能表现好。金九银十招聘黄金季即将来临!大家在考研和找工作中纠结的时候,不妨先看一下面试题,毕竟我

    2023年04月09日
    浏览(55)
  • Java开发面试题目场景业务提问第十六章:常问日常必备_JAVA_面试题集(含答案)【王大师】

    往期文章   第 十 章 日常_JAVA_面试题集10(含答案)  第十三章:日常_JAVA_面试题集13(含答案)  第十二章:日常_JAVA_面试题集12(含答案)  第十一章:日常_JAVA_面试题集11(含答案)  往期文章大全……

    2024年02月08日
    浏览(49)
  • java经典选择题100例及答案

    1.使用Java语言编写的源程序保存时的文件扩展名是( )。 (A).class (B).java (C).cpp (D).txt 2.设int a=-2,则表达式a3的值为( )。 (A)0 (B)3 (C)8 (D)-1 3.设有数组的定义int[] a = new int[3],则下面对数组元素的引用错误的是( )。 (A)a[0]; (B)a[a.length-1]; (

    2024年02月07日
    浏览(39)
  • 经典java面试题6

    泛型是Java中的一种类型参数化机制,用于在编译时实现类型安全性。 它允许在定义类、接口和方法时使用类型参数,以便在使用时指定具体的类型。 泛型可以提高代码的重用性、可读性和类型检查,并减少类型转换的需求。 函数式接口是指只包含一个抽象方法的接口。 J

    2024年02月16日
    浏览(32)
  • java经典面试题—2023

    1、和的区别? 是位运算符,表示按位与运算,是逻辑运算符,表示逻辑与(and)。 2、final, finally, finalize的区别? final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。 finally是异常处理语句结构的一部分,表示总是执行。 finalize是Object类的一个

    2024年02月11日
    浏览(43)
  • 2023Java面试题(附答案)

    精选Java面试题162道 什么是Java,Java的优点是什么? Java是一种面向对象的编程语言,请解释面向对象的概念是什么? Java编程语言有哪些数据类型? 什么是Java中的Wrapper类?包装类有哪些? Java中的基本类型和其对应的包装类有哪些? 什么是Java中的String类?可以对一个String对

    2024年02月03日
    浏览(42)
  • 对经典Java面试问题1

    Java中的基本数据类型有哪些?它们的大小是多少? Java中的基本数据类型包括以下类型及其大小: byte :8位 short :16位 int :32位 long :64位 float :32位 double :64位 char :16位 boolean :1位 基本数据类型在Java中用于存储基本的数值类型,以及布尔值。它们的大小确定了它们在内

    2024年02月16日
    浏览(38)
  • java面试真题&附参考答案【下册】

    tips:下面简述题为java面试真题,阅读本文且感兴趣的,还有将要面试的小伙伴有条件的准备一下 笔和纸 ,将之转述出来成为自己的知识,希望接下来的面试好运连连 上一册:java面试真题【上册】_CsDn.FF的博客-CSDN博客 目录 11.数据库连接池是什么?为什么需要使用连接池?

    2024年02月15日
    浏览(51)
  • Java经典的List面试题

    你知道的List都有哪些? ArrayList、LinkedList、Vector等。 List和Vector有什么区别? Vector是List接口下线程安全的集合。 List是有序的吗? List是有序的 ArrayList和LinkedList的区别?分别用在什么场景? ArrayList和LinkedList数据结构不一样 ArrayList用在查询较多的场合 LinkedList适用于插入较多

    2023年04月22日
    浏览(33)
  • Java经典的String面试题

    String是基本数据类型吗? String你是基本数据类型 String是可变的话? String是final类型的,不可变 怎么比较两个字符串的值一样,怎么比较两个字符串是否同一对象? 比较字符串的值是否相同用equals,比较字符串对象是否同一用== switch中可以使用String吗? JDK7+中的switch可以使用

    2024年02月01日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包