万字梳理,带你拿下 Java 面试题!
Posted CSDN
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了万字梳理,带你拿下 Java 面试题!相关的知识,希望对你有一定的参考价值。
-
并发性的:你可以在其中执行许多语句,而不必一次执行它; -
面向对象的:基于类和面向对象的编程语言; -
独立性的:支持一次编写,到处运行的独立编程语言,即编译后的代码可以在支持 Java 的所有平台上运行。
-
简单,Java 会让你的工作变得更加轻松,使你把关注点放在主要业务逻辑上,而不必关心指针、运算符重载、内存回收等与主要业务无关的功能。 -
便携性,Java 是平台无关性的,这意味着在一个平台上编写的任何应用程序都可以轻松移植到另一个平台上。 -
安全性, 编译后会将所有的代码转换为字节码,人类无法读取。它使开发无病毒,无篡改的系统/应用成为可能。 -
动态性,它具有适应不断变化的环境的能力,它能够支持动态内存分配,从而减少了内存浪费,提高了应用程序的性能。 -
分布式,Java 提供的功能有助于创建分布式应用。使用远程方法调用(RMI),程序可以通过网络调用另一个程序的方法并获取输出。您可以通过从互联网上的任何计算机上调用方法来访问文件。这是革命性的一个特点,对于当今的互联网来说太重要了。 -
健壮性,Java 有强大的内存管理功能,在编译和运行时检查代码,它有助于消除错误。 -
高性能,Java 最黑的科技就是字节码编程,Java 代码编译成的字节码可以轻松转换为本地机器代码。通过 JIT 即时编译器来实现高性能。 -
解释性,Java 被编译成字节码,由 Java 运行时环境解释。 -
多线程性,Java支持多个执行线程(也称为轻量级进程),包括一组同步原语。这使得使用线程编程更加容易,Java 通过管程模型来实现线程安全性。
-
值传递是指在调用函数时将实际参数复制一份到函数中,这样的话如果函数对其传递过来的形式参数进行修改,将不会影响到实际参数 -
引用传递是指在调用函数时将对象的地址直接传递到函数中,如果在对形式参数进行修改,将影响到实际参数的值。
-
对于基本数据类型来说, == 判断的是两边的值是否相等;
public class DoubleCompareAndEquals {
Person person1 = new Person(24,"boy");
Person person2 = new Person(24,"girl");
int c = 10;
private void doubleCompare(){
int a = 10;
int b = 10;
System.out.println(a == b);
System.out.println(a == c);
System.out.println(person1.getId() == person2.getId());
}
}
-
对于引用类型来说, == 判断的是两边的引用是否相等,也就是判断两个对象是否指向了同一块内存区域。
private void equals(){
System.out.println(person1.getName().equals(person2.getName()));
}
-
自反性:对于任何非空引用 x 来说,x.equals(x) 应该返回 true。 -
对称性:对于任何非空引用 x 和 y 来说,若x.equals(y)为 true,则y.equals(x)也为 true。 -
传递性:对于任何非空引用的值来说,有三个值,x、y 和 z,如果x.equals(y) 返回true,y.equals(z) 返回true,那么x.equals(z) 也应该返回true。 -
一致性:对于任何非空引用 x 和 y 来说,如果 x.equals(y) 相等的话,那么它们必须始终相等。 -
非空性:对于任何非空引用的值 x 来说,x.equals(null) 必须返回 false。
-
首先会判断要比较的两个字符串它们的引用是否相等。如果引用相等的话,直接返回 true ,不相等的话继续下面的判断; -
然后再判断被比较的对象是否是 String 的实例,如果不是的话直接返回 false,如果是的话,再比较两个字符串的长度是否相等,如果长度不想等的话也就没有比较的必要了;长度如果相同,会比较字符串中的每个 字符 是否相等,一旦有一个字符不相等,就会直接返回 false。
if (this == anObject) {
return true;
}
private void StringOverrideEquals(){
String s1 = "aaa";
String s2 = "aa" + new String("a");
String s3 = new String("aaa");
System.out.println(s1.intern().equals(s1));
System.out.println(s1.intern().equals(s2));
System.out.println(s3.intern().equals(s1));
}
-
首先 s1.intern.equals(s1) 这个无论如何都返回 true,因为 s1 字符串创建出来就已经在常量池中存在了。 -
然后第二条语句返回 false,因为 s1 返回的是常量池中的对象,而 s2 返回的是堆中的对象 -
第三条语句 s3.intern.equals(s1),返回 true ,因为 s3 对象虽然在堆中创建了一个对象,但是 s3 中的 "aaa" 返回的是常量池中的对象。
String str1 = "通话";
String str2 = "重地";
-
如果在 Java 运行期间对同一个对象调用 hashCode 方法后,无论调用多少次,都应该返回相同的 hashCode,但是在不同的 Java 程序中,执行 hashCode 方法返回的值可能不一致; -
如果两个对象的 equals 相等,那么 hashCode 必须相同; -
如果两个对象 equals 不相等,那么 hashCode 也有可能相同,所以需要重写 hashCode 方法,因为你不知道 hashCode 的底层构造(反正我是不知道,有大牛可以传授传授),所以你需要重写 hashCode 方法,来为不同的对象生成不同的 hashCode 值,这样能够提高不同对象的访问速度; -
hashCode 通常是将地址转换为整数来实现的。
-
不可变对象的内部属性都是 final 的; -
不可变对象的内部属性都是 private 的; -
不可变对象不能提供任何可以修改内部状态的方法、setter 方法也不行; -
不可变对象不能被继承和扩展。
-
修饰变量,static 修饰的变量称为静态变量、也称为类变量,类变量属于类所有,对于不同的类来说,static 变量只有一份,static 修饰的变量位于方法区中;static 修饰的变量能够直接通过 类名.变量名 来进行访问,不用通过实例化类再进行使用; -
修饰方法,static 修饰的方法被称为静态方法,静态方法能够直接通过 类名.方法名 来使用,在静态方法内部不能使用非静态属性和方法; -
static 可以修饰代码块,主要分为两种,一种直接定义在类中,使用 static{},这种被称为静态代码块,一种是在类中定义静态内部类,使用 static class xxx 来进行定义; -
static 可以用于静态导包,通过使用 import static xxx 来实现,这种方式一般不推荐使用; -
static 可以和单例模式一起使用,通过双重检查锁来实现线程安全的单例模式。
-
修饰类,final 修饰的类不能被继承,不能被继承的意思就是不能使用 extends 来继承被 final 修饰的类; -
修饰变量,final 修饰的变量不能被改写,不能被改写的意思有两种,对于基本数据类型来说,final 修饰的变量,其值不能被改变,final 修饰的对象,对象的引用不能被改变,但是对象内部的属性可以被修改。final 修饰的变量在某种程度上起到了不可变的效果,所以,可以用来保护只读数据,尤其是在并发编程中,因为明确的不能再为 final 变量进行赋值,有利于减少额外的同步开销; -
修饰方法,final 修饰的方法不能被重写; -
final 修饰符和 Java 程序性能优化没有必然联系。
-
抽象级别不同:类、抽象类、接口其实是三种不同的抽象级别,抽象程度依次是 接口 > 抽象类 > 类。在接口中,只允许进行方法的定义,不允许有方法的实现,抽象类中可以进行方法的定义和实现;而类中只允许进行方法的实现,我说的方法的定义是不允许在方法后面出现 {} -
使用的关键字不同:类使用 class 来表示;抽象类使用 abstract class 来表示;接口使用 interface 来表示 -
变量:接口中定义的变量只能是公共的静态常量,抽象类中的变量是普通变量。
-
子父级关系不同,重写是针对子级和父级的不同表现形式,而重载是在同一类中的不同表现形式; -
概念不同,子类重写父类的方法一般使用 @override 来表示;重写后的方法其方法的声明和参数类型、顺序必须要与父类完全一致;重载是针对同一类中概念,它要求重载的方法必须满足下面任何一个要求:方法参数的顺序,参数的个数,参数的类型任意一个保持不同即可。
-
父类不同:HashMap 继承了 AbstractMap 类,而 HashTable 继承了 Dictionary 类:
-
空值不同:HashMap 允许空的 key 和 value 值,HashTable 不允许空的 key 和 value 值。HashMap 会把 Null key 当做普通的 key 对待。不允许 null key 重复。
-
线程安全性:HashMap 不是线程安全的,如果多个外部操作同时修改 HashMap 的数据结构比如 add 或者是 delete,必须进行同步操作,仅仅对 key 或者 value 的修改不是改变数据结构的操作。可以选择构造线程安全的 Map 比如 Collections.synchronizedMap或者是 ConcurrentHashMap。而 HashTable 本身就是线程安全的容器。 -
性能方面:虽然 HashMap 和 HashTable 都是基于单链表的,但是 HashMap 进行 put 或者 get 以上是关于万字梳理,带你拿下 Java 面试题!的主要内容,如果未能解决你的问题,请参考以下文章
这个疯子整理的十万字Java面试题汇总,终于拿下40W offer!(JDK源码+微服务合集+并发编程+性能优化合集+分布式中间件合集)