硬核原创|Java 面试题全梳理(一)

简介: 笔记

Java 基础篇


Java 有哪些特点


  • 并发性的:你可以在其中执行许多语句,而不必一次执行它
  • 面向对象的:基于类和面向对象的编程语言。
  • 独立性的:支持一次编写,到处运行的独立编程语言,即编译后的代码可以在支持 Java 的所有平台上运行。

30.png


Java 的特性


Java 的特性有如下这几点

  • 简单,Java 会让你的工作变得更加轻松,使你把关注点放在主要业务逻辑上,而不必关心指针、运算符重载、内存回收等与主要业务无关的功能。
  • 便携性,Java 是平台无关性的,这意味着在一个平台上编写的任何应用程序都可以轻松移植到另一个平台上。
  • 安全性, 编译后会将所有的代码转换为字节码,人类无法读取。它使开发无病毒,无篡改的系统/应用成为可能。
  • 动态性,它具有适应不断变化的环境的能力,它能够支持动态内存分配,从而减少了内存浪费,提高了应用程序的性能。
  • 分布式,Java 提供的功能有助于创建分布式应用。使用远程方法调用(RMI),程序可以通过网络调用另一个程序的方法并获取输出。您可以通过从互联网上的任何计算机上调用方法来访问文件。这是革命性的一个特点,对于当今的互联网来说太重要了。
  • 健壮性,Java 有强大的内存管理功能,在编译和运行时检查代码,它有助于消除错误。
  • 高性能,Java 最黑的科技就是字节码编程,Java 代码编译成的字节码可以轻松转换为本地机器代码。通过 JIT 即时编译器来实现高性能。
  • 解释性,Java 被编译成字节码,由 Java 运行时环境解释。
  • 多线程性,Java支持多个执行线程(也称为轻量级进程),包括一组同步原语。这使得使用线程编程更加容易,Java 通过管程模型来实现线程安全性。

描述一下值传递和引用传递的区别


值传递是指在调用函数时将实际参数复制一份到函数中,这样的话如果函数对其传递过来的形式参数进行修改,将不会影响到实际参数

引用传递 是指在调用函数时将对象的地址直接传递到函数中,如果在对形式参数进行修改,将影响到实际参数的值。


== 和 equals 区别是什么


== 是 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()));
}

equals 是 Java 中所有对象的父类,即 Object 类定义的一个方法。它只能比较对象,它表示的是引用双方的值是否相等。所以记住,并不是说 == 比较的就是引用是否相等,equals 比较的就是值,这需要区分来说的。

equals 用作对象之间的比较具有如下特性

  • 自反性:对于任何非空引用 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。


String 中的 equals 是如何重写的


String 代表的是 Java 中的字符串,String 类比较特殊,它整个类都是被 final 修饰的,也就是说,String 不能被任何类继承,任何 修改 String 字符串的方法都是创建了一个新的字符串。

equals 方法是 Object 类定义的方法,Object 是所有类的父类,当然也包括 String,String 重写了 equals 方法,下面我们来看看是怎么重写的

31.png

  • 首先会判断要比较的两个字符串它们的引用是否相等。如果引用相等的话,直接返回 true ,不相等的话继续下面的判断
  • 然后再判断被比较的对象是否是 String 的实例,如果不是的话直接返回 false,如果是的话,再比较两个字符串的长度是否相等,如果长度不想等的话也就没有比较的必要了;长度如果相同,会比较字符串中的每个 字符 是否相等,一旦有一个字符不相等,就会直接返回 false。

下面是它的流程图

32.png

这里再提示一下,你可能有疑惑什么时候是

if (this == anObject) {
  return true;
}

这个判断语句如何才能返回 true?因为都是字符串啊,字符串比较的不都是堆空间吗,猛然一看发现好像永远也不会走,但是你忘记了 String.intern() 方法,它表示的概念在不同的 JDK 版本有不同的区分

在 JDK1.7 及以后调用 intern 方法是判断运行时常量池中是否有指定的字符串,如果没有的话,就把字符串添加到常量池中,并返回常量池中的对象。

验证过程如下

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" 返回的是常量池中的对象。
    33.png


为什么重写 equals 方法必须重写 hashcode 方法


34.pngequals 方法和 hashCode 都是 Object 中定义的方法,它们经常被一起重写。

equals 方法是用来比较对象大小是否相等的方法,hashcode 方法是用来判断每个对象 hash 值的一种方法。如果只重写 equals 方法而不重写 hashcode 方法,很可能会造成两个不同的对象,它们的 hashcode 也相等,造成冲突。比如

String str1 = "通话";
String str2 = "重地";

它们两个的 hashcode 相等,但是 equals 可不相等。

我们来看一下 hashCode 官方的定义


总结起来就是

  • 如果在 Java 运行期间对同一个对象调用 hashCode 方法后,无论调用多少次,都应该返回相同的 hashCode,但是在不同的 Java 程序中,执行 hashCode 方法返回的值可能不一致。
  • 如果两个对象的 equals 相等,那么 hashCode 必须相同
  • 如果两个对象 equals 不相等,那么 hashCode 也有可能相同,所以需要重写 hashCode 方法,因为你不知道 hashCode 的底层构造(反正我是不知道,有大牛可以传授传授),所以你需要重写 hashCode 方法,来为不同的对象生成不同的 hashCode 值,这样能够提高不同对象的访问速度。
  • hashCode 通常是将地址转换为整数来实现的。
相关文章
|
14天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
44 2
|
2天前
|
Java 程序员
Java社招面试题:& 和 && 的区别,HR的套路险些让我翻车!
小米,29岁程序员,分享了一次面试经历,详细解析了Java中&和&&的区别及应用场景,展示了扎实的基础知识和良好的应变能力,最终成功获得Offer。
24 14
|
18天前
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
|
24天前
|
存储 缓存 Oracle
Java I/O流面试之道
NIO的出现在于提高IO的速度,它相比传统的输入/输出流速度更快。NIO通过管道Channel和缓冲器Buffer来处理数据,可以把管道当成一个矿藏,缓冲器就是矿藏里的卡车。程序通过管道里的缓冲器进行数据交互,而不直接处理数据。程序要么从缓冲器获取数据,要么输入数据到缓冲器。
Java I/O流面试之道
|
20天前
|
存储 缓存 Java
大厂面试必看!Java基本数据类型和包装类的那些坑
本文介绍了Java中的基本数据类型和包装类,包括整数类型、浮点数类型、字符类型和布尔类型。详细讲解了每种类型的特性和应用场景,并探讨了包装类的引入原因、装箱与拆箱机制以及缓存机制。最后总结了面试中常见的相关考点,帮助读者更好地理解和应对面试中的问题。
43 4
|
21天前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
72 4
|
2月前
|
存储 安全 算法
Java面试题之Java集合面试题 50道(带答案)
这篇文章提供了50道Java集合框架的面试题及其答案,涵盖了集合的基础知识、底层数据结构、不同集合类的特点和用法,以及一些高级主题如并发集合的使用。
98 1
Java面试题之Java集合面试题 50道(带答案)
|
2月前
|
存储 Java 程序员
Java面试加分点!一文读懂HashMap底层实现与扩容机制
本文详细解析了Java中经典的HashMap数据结构,包括其底层实现、扩容机制、put和查找过程、哈希函数以及JDK 1.7与1.8的差异。通过数组、链表和红黑树的组合,HashMap实现了高效的键值对存储与检索。文章还介绍了HashMap在不同版本中的优化,帮助读者更好地理解和应用这一重要工具。
55 5
|
2月前
|
存储 Java
[Java]面试官:你对异常处理了解多少,例如,finally中可以有return吗?
本文介绍了Java中`try...catch...finally`语句的使用细节及返回值问题,并探讨了JDK1.7引入的`try...with...resources`新特性,强调了异常处理机制及资源自动关闭的优势。
23 1
|
2月前
|
Java 程序员
Java 面试高频考点:static 和 final 深度剖析
本文介绍了 Java 中的 `static` 和 `final` 关键字。`static` 修饰的属性和方法属于类而非对象,所有实例共享;`final` 用于变量、方法和类,确保其不可修改或继承。两者结合可用于定义常量。文章通过具体示例详细解析了它们的用法和应用场景。
30 3