欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java面试总结:Java基础篇(1)

程序员文章站 2022-05-06 16:51:12
...

最近想督促自己在做码农的同时增加自己的知识储备;所以开了一个专题,也算一个笔记;主要从各大牛人博客和一些资料中总结一些比价常见的面试题;

1.谈谈你对Java平台的理解;“Java是解释执行”,这句话对吗?

回答:
1.Java本身是一种面向对象的语言;有最显著的两个方面:1:一次编译,到处运行;2.有自己的回收机制(GC)。
我们日常接触到JRE,JDK也就是Java环境,包含了很多JVM和Java类库,以及一些模块。而JDK包含了JRE,同时也提供了很多工具,,比如编译器等等。Java能一次编译,到处运行的前提是JVM,因为Java提供了不同平台的JVM,所以能做到一次编译,到处运行。
2.Java不是解释执行的语言,应该说并不全是。一个Java程序写出来后,编译器首先会将Java代码转换成(通过Javac)字节码文件,然后JVM内嵌的解释器会将字节码文件转换成计算机看得懂的机器码,让我们的程序跑起来。但是在常见的JVM中,比如说Oracle JDK提供的JVM,JIT(Just-In-Time)编译器,能够将热点代码编译成机器码,这种属于编译执行,而不是解释执行。也就是说,JIT编译的这一段代码直接是转成了机器码,而不是先转成.class代码,再让JVM去解析成机器码。
知识拓展:
1.在我们回答这个问题的时候,可以加上Java语言面向对象的三大特性,和一些Lambda等语言特性。包含了一些基础的类库,比如IO,NIO,网络等等;
2.或者可以谈一下虚拟机;

关于JIT知识点链接
知识点链接:https://www.cnblogs.com/insistence/p/5901457.html

2.Exception和Error有什么区别;运行时异常和一般异常有什么区别

回答:Exception和Error都继承了Throwable类;

  • Exception:Exception分为检查异常不检查异常;可检查异常要在我们编写代码的时候显示地进行捕获和处理。这在我们写代码的时候,编译器会提醒我们;不检查异常则是在我们程序运行的时候会抛出的异常;比如我们常见的NullPointerException,ArrayIndexOutOfBoundsException;这类异常通常是我们的逻辑出错。
  • Error:是指在正常情况下,不太可能出现的错误。比如常见OutOfMemoryError之类的
    知识拓展:
    NoClassDefFoundError和ClassNOtFoundException两种异常有什么区别?
    回答:
    1.从两个异常的命名我们可以看出来,这两个异常应该是发生在不同阶段,一个是Error,一个是Exception;那么NoClassDefFoundError应该是发生在JVM阶段,而ClassNOtFoundException应该是发生在编译阶段。
    2.ClassNotFoundException发生的原因:
    当我们使用Class.forName方法动态加载类的时候,我们是需要指定类的路径在哪的;如果编译器没找到这个类,就会出现ClassNotFoundException;这时候我们就要检查一下,自己的类名有没有写错;还有一种情况就是,A类已经将某个类加载到内存里面了,B类也要尝试动态地去加载这个类,这个时候也会出现ClassNotFoundException。这个时候我们就要去控制一下动态加载类的顺序
    3.NoClassDefFoundError发生的原因:
    当JVM尝试从我们已经编译好的.class文件解释成机器码的时候,或者ClassLoader实例尝试加载类的时候却发现找不到这个类了。就会导致NoClassDefFoundError这种错误的出现。
    造成中问题的原因可能是打包过程中这个类丢失了
    知识点链接:https://blog.csdn.net/wdw131409/article/details/78316919

3.final,finally,finalize;

这三个玩意压根就没什么联系,之所以会用来做经典的面试题,应该是因为他们长的有点像。
final:常用来修饰类,变量,方法;被修饰的类为final的话,将不可以继承,修饰变量的话则该变量不可以被修改,final方法则不可以被覆盖
finally:是保证重点代码一定会被执行的一种机制。可以使用finally块,来关闭数据库连接等等。
finalize:保证对象在被垃圾收集前完成特定资源的回收。

4.String,StringBuilder,StringBuffer有什么区别

String是Java语言中非常基础和重要的类,提供了构造和管理字符串的各种基本逻辑。我们实际开发中对字符串的操作也占了大多数。String是典型的Immutable(不可变)类,被声明final class,所有的属性也是final的。也由于它的不可变性,类似拼接字符串等一些动作,都会产生新的String对象。其运行机制是:创建一个字符串的时候,首先检查常量池中是否有相同的字符串,有的话则直接返回查到的对象的引用。如果没有则创建新的串,然后返回对象的引用,并将新的对象放入池中。而通过new方式的创建String对象,是不检查常量池的直接在堆里创建一个对象。

 String a = "AB";//会放进常量池
 String b  = new String("AB");//放入非常量池
 System.out.println(a == b);//false

注意:String提供了inter()方法。调用该方法时,如果常量池中包括了一个等于此String对象的字符串(由equals方法确定),则返回池中的字符串。否则,将此String对象添加到池中,并且返回此池中对象的引用。

String c = a.iner();
 System.out.println(a == c);//true

总结:

String的特性

  • 不可变性;不可变的主要作用在于当一个对象需要被多线程共享,并且访问频繁时,可以省略同步和锁等待的时间,从而大幅度提高系统性能。不可变模式是一个可以提高多线程程序的性能,降低多线程程序复杂度的设计模式。因此,当我们考虑一个对象的线程安全性的时候,可以直接将这个类设计为final。
  • 常量池。当2个String对象拥有相同的值时,他们只引用常量池中的同一个拷贝。

StringBuilder是为了解决String字符串拼接,从而产生很多新对象的问题而产生的一个类。我们可以用append方法,直接拼接字符串。

StringBuffer本质是一个线程安全的可修改字符序列,StringBuffer类中方法定义前面都会有synchronize关键字。为此,StringBuffer的性能要远低于StringBuilder。保证了线程安全。同时也会带来了一些开销。除非有线程安全的需要,不然还是推荐使用StringBuilder
知识拓展
应用场景:
1.在字符串内容不经常发生变化的业务场景优先使用String类。例如:常量声明、少量的字符串拼接操作等。如果有大量的字符串内容拼接,避免使用String与String之间的“+”操作,因为这样会产生大量无用的中间对象,耗费空间且执行效率低下(新建对象、回收对象花费大量时间)。
2.在频繁进行字符串的运算(如拼接、替换、删除等),并且运行在多线程环境下,建议使用StringBuffer,例如XML解析、HTTP参数解析与封装。
3.在频繁进行字符串的运算(如拼接、替换、删除等),并且运行在单线程环境下,建议使用StringBuilder,例如SQL语句拼装、JSON封装等。
参考:
公号:Java大后端