java基础知识之面试题(二)

简介: 目录前言区别前言JVM是不能独立安装的。JRE和JDK都是可以独立安装的层层嵌套,jvm包括jdk,jdk包括jre区别JRE:java运行环境JDK:Java开发工具箱JVM:java虚拟机主要讲解jdk与jre的区别jdk(Java Development Kit):java 开发工具包jre(Java Runtime Environment):java 运行环境层层嵌套主要记住,==jvm包括jdk,jdk包括jre==即可而且主要的区分点是看你用在什么方面在编写jav

前言

主要讲解java的一些基础知识以及容易混淆的概念
实时更新汇总

如果想补充一些细节概念或者知识点可看
java零基础从入门到精通(全)
javaSE从入门到精通的十万字总结(全)

java语言有哪些特点?
面向对象、可靠性、安全性、支持多线程(c++调用操作系统的的多线程)、支持网络编程、编译与解释并存

1. JDK、JRE和JVM区分

JVM是不能独立安装的。
JRE和JDK都是可以独立安装的
层层嵌套

JDK = JRE + 开发工具集(例如Javac编译工具等)
JRE = JVM + Java SE 标准类库

  • JRE:java运行环境
  • JDK:Java开发工具箱
  • JVM:java虚拟机

主要讲解jdk与jre的区别
jdk(Java Development Kit):java 开发工具包
jre(Java Runtime Environment):java 运行环境

层层嵌套主要记住,==jvm包括jdk,jdk包括jre==即可

而且主要的区分点是看你用在什么方面
在编写java程序的时候,jdk很适合,因为要开发工具箱
如果在编译java的时候,jre很适合,因为需要java的运行环境

2. == 和 equals 的区别

java常考的面试中也有一个这个
主要是容易混淆并且记乱
主要的区分度是

  • == 在基本类型中是值比较,对于引用类型是地址比较
  • equals 是引用比较,但在多数类中(比如String、Integer 等)重写equals方法,导致很多都是值比较

equals( )∶它的作用也是判断两个对象是否相等,它不能用于比较基本数据类型的变量。

情况1:类没有覆盖equals()方法。则通过equals()比较该类的两个对象时,等价于通过“==”比较这两个对象。使用的默认是0bject类equals()方法。
情况2:类覆盖了equals()方法。一般,我们都覆盖equals()方法来两个对象的内容相等;若它们的内容相等,则返回true(即,认为这两个对象相等)。

为了更好的显示这种区分度,下面以代码展示演示
先展示==的代码比较
注意下面的代码区分度
新建的空间比较不同是因为开辟了新空间,而且比较的时候比较的是引用类型(记住)

String x = "A";
String y = "A";
String z = new String("A");
System.out.println(x==y); // true
System.out.println(x==z); // false
System.out.println(x.equals(y)); // true
System.out.println(x.equals(z)); // true

在这里插入图片描述

equals中比如在新建对象的时候,两个相同的数据对象为fasle

ceshi c1 = new ceshi("A");
ceshi c2 = new ceshi("A");
System.out.println(c1.equals(c2)); // false


//查看其源码
public boolean equals(Object obj) {
        return (this == obj);
}

而String改写了equals方法
所以比较的时候是比较值

String s1 = new String("A");
String s2 = new String("A");
System.out.println(s1.equals(s2)); // true

//查看其源码
public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = value.length;
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

3. 抽象类和接口类细节区分

先回顾其两者特点:

抽象类是类和类之间的共同特征,将这些共同特征进一步形成抽象类,由于类本身不存在,所以抽象类无法创建对象。
类到对象是实例化,对象到类是抽象
抽象方法不能被 final 修饰,因为抽象方法就是被子类实现的

  • 采用 abstract 关键字定义的类就是抽象类,采用 abstract 关键字定义的方法就是抽象方法
  • 抽象的方法只需在抽象类中,提供声明,不需要实现
  • 如果一个类中含有抽象方法,那么这个类必须定义成抽象类。抽象类中不一定有抽象方法,抽象方法必须出现在抽象类中
  • final和abstract不能同时同时使用,这两个关键字是对立的
  • 抽象类的子类可以是抽象类。也可以是非抽象类
  • 一个非抽象的类,继承抽象类,必须将抽象类中的抽象方法进行覆盖/重写/实现

接口是特殊的抽象类,类与类是继承extends,类与接口是实现implements,其实都是继承

  • 接口是一种“引用数据类型”,完全抽象的,支持多继承,且一个接口可以继承多个接口,只有常量+抽象方法
  • 所有的元素都是public修饰的,抽象方法的public abstract可以省略,常量的public static final可以省略,方法不能有方法体

通过其特点也可以讲述其不同
比如

  • 抽象类可以有构造函数;接口不能有
  • 类可以实现很多个接口;抽象类只能继承一个
  • 接口中的方法默认使用 public 修饰;抽象类中的方法可以是任意访问修饰符

4. final关键字

  • final 修饰的类不能被继承
  • final 修饰的方法不能被覆盖
  • final 修饰的变量不能被修改
  • 构造方法不能被 final 修饰

变量在没有赋值的时候可以定义可以声明
但如果输出变量就必须给予定义以及赋值

5. String类细节

String不是基本数据类型,String属于引用类型
String类是一个final类,因此不能被继承

6. String、StringBuffer 和 StringBuilder 区别

String是一个final类表示的类容不可改变
StringBuffer表示的内容可以修改

StringBuffer 和 StringBuilder 区别:
StringBuffer是线程安全的可以在多线程中使用
StringBuilder是线程不安全的,但是运行效率非常高
具体详细的区别可看
探秘Java中的String、StringBuilder以及StringBuffer

7. super和this对比

this:

  • this 是一个引用,保存内存地址指向自己
  • this 不能出现在静态方法中
  • this 大部分情况下可以省略,在方法中区分实例变量和局部变量的时候不能省略
  • “this(实际参数列表)”出现在构造方法第一行,通过当前的构造方法去调用

本类当中其它的构造方法

super:
super 代表了当前对象中从父类继承过来的那部分特征。this 指向一个独立的对象

super与this共有的

  • super 和 this 都可以使用在实例方法当中
  • super 不能使用在静态方法当中,因为 super 代表了当前对象上的父类型特征,静态方法中没有 this,肯定也是不能使用 super 的
  • super 也有这种用法:“super(实际参数列表);”,这种用法是通过当前的构造方法调用父类的构造方法

==this 和 super 都是无法使用在静态方法当中的==

8. static与this对比

static和this指针的结合代码演示
static 的方法中不能直接访问实例变量,要访问实例变量必须先自己创建一个对象,通过“引用”可以去访问,不能通过 this 访问,因为在 static 方法中是不能存在 this 的

public class ThisTest {
    int i = 10;

    public static void main(String[] args) {
//这肯定是不行的,因为 main 方法带有 static,不能用 this
//System.out.println(this.i);
//可以自己创建一个对象
        ThisTest tt = new ThisTest();
//通过引用访问
        System.out.println(tt.i);
    }
}    

方法也同理,需要用对象去调用
实例方法必须先创建对象,通过引用去调用,在以上的 main 方法中并没有创建对象,更没有 this。

//错误代码示列:
public class ThisTest {
    public static void main(String[] args) {
        doSome();
    }
    public void doSome(){
        System.out.println("do some...");
    } }

正确代码示列:

public class ThisTest {
    public static void main(String[] args) {
        ThisTest tt = new ThisTest();
        tt.doSome();
    }
    public void doSome(){
        System.out.println("do some...");
    } }

总结:

this 不能使用在 static 的方法中,可以使用在实例方法中,代表当前对象,多数情况下 this 是可以省略不写的,但是在区分局部变量和实例变量的时候不能省略,在实例方法中可以直接访问当前对象实例变量以及实例方法,在 static 方法中无法直接访问实例变量和实例方法

9. 重写和重载对比

重写是⼦类对⽗类的允许访问的⽅法的实现过程进⾏重新编写, 返回值和形参都不能改变。即 外壳不变,核⼼重写!重写⽅法不能抛出新的检查异常或者⽐被重写⽅法申明更加宽泛的异常。

重载是在⼀个类⾥⾯,⽅法名字相同,⽽参数不同。返回类型可以相同也可以不同。

  • 重载:发生在同一个类中,方法名必须相同,参数类型不同、个数不同、顺序不同,方法返回值和访问修饰符可以不同。
  • 重写:发生在运行期,是子类对父类的允许访问的方法的实现过程进行重新编写。

1.返回值类型、方法名、参数列表必须相同,抛出的异常范围小于等于父类,访问修饰符范围大于等于父类。
2.如果父类方法访问修饰符为private/final/static则子类就不能重写该方法,但是被static修饰的方法能够被再次声明。
3.构造方法无法被重写

10. 静态方法和实例方法对比

  1. 在外部调⽤静态⽅法时,可以使⽤"类名.⽅法名"的⽅式,也可以使⽤"对象名.⽅法名"的⽅式。(调⽤静态⽅法可以⽆需创建对象。)

实例⽅法只有"对象名.⽅法名"这种⽅式。

  1. 静态⽅法在访问本类的成员时,只允许访问静态成员(即静态成员变量和静态⽅法), ⽽不允许访问实例成员变量和实例⽅法;实例⽅法则⽆此限制

11. 静态变量和实例变量对比

静态变量: 静态变量由于不属于任何实例对象,属于类的,所以在内存中只会有⼀份,在类的加载过程中,JVM只为静态变量分配⼀次内存空间。

实例变量: 每次创建对象,都会为每个对象分配成员变量内存空间,实例变量是属于实例对象 的,在内存中,创建⼏次对象,就有⼏份成员变量

12. final、finally与finalize对比

  • final是一个关键字。表示最终的。不变的
  • finally也是一个关键字,和try联合使用,使用在异常处理机制中
  • finalize()是Object类中的一个方法。作为方法名出现,finalize是标识符。这个方法是由垃圾回收器GC负责调用的

hashcode()与equals()

hashCode()的作用是获取哈希码,也称为散列码;它实际上是返回一个int 整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。散列表存储的是键值对(key-value),它的特点是:能根据“键"快速的检索出对应的“值”。这其中就利用到了散列码!(可以快速找到所需要的对象)

为什么重写equals()也要重写hashcode()方法
如果两个对象相等,则hashcode一定也是相同的。两个对象相等,对两个对象分别调用equals方法都返回true。但是,两个对象有相同的hashcode值,它们也不一定是相等的。因此,equals方法被覆盖过,则hashCode方法也必须被覆盖。

以"HashSet如何检查重复”为例子来说明为什么要有hashCode?
当把对象加入HashSet时,HashSet 会先计算对象的hashcode值来判断对象加入的位置,同时也会与其他已经加入的对象的hashcode值作比较,如果没有相符的hashcode,HashSet会假设对象没有重复出现。但是如果发现有相同hashcode值的对象,这时会调用equals ()方法来检查hashcode相等的对象是否真的相同。如果两者相同,HashSet就不会让其加入操作成功。如果不同的话,就会重新散列到其他位置。

深拷贝与浅拷贝

  • 浅拷贝:对基本数据类型进行值传递,对引用数据类型进行引用传递般的拷贝,此为浅拷贝。
  • 深拷贝:对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容,此为深拷贝。
相关文章
|
1月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
76 2
|
25天前
|
Java 程序员
Java社招面试题:& 和 && 的区别,HR的套路险些让我翻车!
小米,29岁程序员,分享了一次面试经历,详细解析了Java中&和&&的区别及应用场景,展示了扎实的基础知识和良好的应变能力,最终成功获得Offer。
64 14
|
1月前
|
存储 缓存 算法
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
本文介绍了多线程环境下的几个关键概念,包括时间片、超线程、上下文切换及其影响因素,以及线程调度的两种方式——抢占式调度和协同式调度。文章还讨论了减少上下文切换次数以提高多线程程序效率的方法,如无锁并发编程、使用CAS算法等,并提出了合理的线程数量配置策略,以平衡CPU利用率和线程切换开销。
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
|
1月前
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
|
1月前
|
存储 缓存 Oracle
Java I/O流面试之道
NIO的出现在于提高IO的速度,它相比传统的输入/输出流速度更快。NIO通过管道Channel和缓冲器Buffer来处理数据,可以把管道当成一个矿藏,缓冲器就是矿藏里的卡车。程序通过管道里的缓冲器进行数据交互,而不直接处理数据。程序要么从缓冲器获取数据,要么输入数据到缓冲器。
Java I/O流面试之道
|
1月前
|
Java 编译器 程序员
Java面试高频题:用最优解法算出2乘以8!
本文探讨了面试中一个看似简单的数学问题——如何高效计算2×8。从直接使用乘法、位运算优化、编译器优化、加法实现到大整数场景下的处理,全面解析了不同方法的原理和适用场景,帮助读者深入理解计算效率优化的重要性。
35 6
|
1月前
|
存储 缓存 Java
大厂面试必看!Java基本数据类型和包装类的那些坑
本文介绍了Java中的基本数据类型和包装类,包括整数类型、浮点数类型、字符类型和布尔类型。详细讲解了每种类型的特性和应用场景,并探讨了包装类的引入原因、装箱与拆箱机制以及缓存机制。最后总结了面试中常见的相关考点,帮助读者更好地理解和应对面试中的问题。
61 4
|
1月前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
128 4
|
2月前
|
存储 安全 算法
Java面试题之Java集合面试题 50道(带答案)
这篇文章提供了50道Java集合框架的面试题及其答案,涵盖了集合的基础知识、底层数据结构、不同集合类的特点和用法,以及一些高级主题如并发集合的使用。
123 1
Java面试题之Java集合面试题 50道(带答案)
|
2月前
|
存储 Java 程序员
Java面试加分点!一文读懂HashMap底层实现与扩容机制
本文详细解析了Java中经典的HashMap数据结构,包括其底层实现、扩容机制、put和查找过程、哈希函数以及JDK 1.7与1.8的差异。通过数组、链表和红黑树的组合,HashMap实现了高效的键值对存储与检索。文章还介绍了HashMap在不同版本中的优化,帮助读者更好地理解和应用这一重要工具。
70 5