【Java面试题】Java基础语法

JDK、JRE和JVM的关系

JDK、JRE和JVM的关系:

  • JDK(Java Development Kit)是Java开发工具包的缩写,包含了Java编译器、Java运行时环境(JRE)和其他开发工具。JDK是开发Java应用程序的必备工具,它提供了编写、编译、调试和运行Java程序所需的所有组件。
  • JRE(Java Runtime Environment)是Java运行时环境的缩写,包含了Java虚拟机(JVM)和Java类库。JRE提供了Java程序运行的环境,包括了Java虚拟机和Java类库,可以让Java程序在任何支持Java虚拟机的操作系统上运行。
  • JVM(Java Virtual Machine)是Java虚拟机的缩写,是Java程序执行的核心组件。JVM是一个虚拟计算机,它可以在任何支持Java虚拟机的操作系统上执行Java程序。JVM负责将Java源代码编译成字节码,并在运行时解释执行字节码。

因此,可以简单地将JDK看作是开发工具包,JRE看作是Java程序运行的环境,而JVM则是Java程序执行的核心组件。在实际使用中,通常需要安装JDK来开发Java应用程序,然后通过命令行或集成开发环境(IDE)来运行JRE来测试和调试Java程序,最终通过JVM来执行Java程序。

在这里插入图片描述
在这里插入图片描述

https://javaguide.cn/java/basis/java-basic-questions-01.html#jvm-vs-jdk-vs-jre
在这里插入图片描述

栈和堆分别存的什么数据

栈和堆是计算机内存中的两种数据结构,它们分别用于存储不同类型的数据。

  1. 栈(Stack):栈是一种后进先出(LIFO)的数据结构,也就是说最后进入栈的数据会最先被弹出。栈通常用于存储函数调用时的参数、局部变量、返回地址等数据。在Java中,基本类型数据(如int、float、char等)和对象引用都属于栈上数据,而数组元素也是栈上数据。

  2. 堆(Heap):堆是一种先进先出(FIFO)的数据结构,也就是说最先进入堆的数据会最先被弹出。堆通常用于存储动态分配的内存,比如Java中的new操作符创建的对象、数组等。在Java中,对象实例和数组元素都属于堆上数据。

补充:堆是一种树形数据结构,它可以动态地分配和回收内存,支持高效的插入、删除和排序等操作。

需要注意的是,Java中的垃圾回收机制会自动管理堆上的内存分配和释放,程序员不需要手动进行内存管理。

在这里插入图片描述

异步和同步

异步调用和同步调用都是指程序中不同组件之间的调用方式。

在同步调用中,**程序的某个组件会在调用另一个组件时等待该组件完成后,才会继续执行下一步操作。**也就是说,在同步调用过程中,程序的运行会阻塞等待被调用组件的响应结果。

而在异步调用中,程序的调用不会等待被调用组件返回结果,而是继续执行下一步操作。被调用组件会通过回调函数或事件通知的方式返回结果,程序在收到结果后再对其进行处理。也就是说,在异步调用过程中,程序的运行不会被阻塞,可以同时执行多个调用操作。

异步调用通常用于网络请求、GUI编程和其他需要同时处理多个任务的场景中,而同步调用通常用于需要依次处理任务的场景中。

线程和进程区别

在这里插入图片描述

线程和进程是操作系统中用于实现多任务处理的两个基本概念,它们有以下区别:

  1. 资源占用:一个进程可以独立占用系统资源,如内存、CPU等;而一个线程只能占用一定的系统资源,如栈空间、寄存器等。
  2. 调度:进程是操作系统中的独立实体,它可以被操作系统分配资源和调度执行;而线程是在进程内部的执行单元,它的调度由进程管理。
  3. 通信:由于进程之间是相互独立的,它们之间的通信需要通过进程间通信(IPC)机制来实现;而线程之间共享同一个进程的内存空间,因此可以直接进行通信。
  4. 数据保护:由于每个进程都有自己独立的内存空间,因此不同进程之间的数据是相互隔离的;而线程共享同一个进程的内存空间,因此需要注意数据保护的问题。

总之,线程和进程都是实现多任务处理的基本概念,它们各自具有不同的特点和优缺点,在实际应用中需要根据具体的需求选择合适的方式。

补充:**一个进程可以包含多个线程,这些线程共享同一个进程的内存空间和系统资源。**在Java中,一个进程可以包含多个线程,这些线程可以通过继承Thread类或实现Runnable接口来创建。

java的数据类型有哪些

类型占用字节取值范围包装类默认值
byte(字节型)1-128~127(-2的7次方到2的7次方-1)Byte0
short(短整型)2-32768~32767(-2的15次方到2的15次方-1)Short0
int(整型)4-2147483648~2147483647(-2的31次方到2的31次方-1)Integer0
long(长整型)8-9223372036854774808~9223372036854774807(-2的63次方到2的63次方-1)Long0L
float(浮点型)43.402823e+38~1.401298e-45(e+38 表示乘以10的38次方,而e-45 表示乘以10的负45次方Float0.0f
double(双精度浮点型)81.797693e+308~4.9000000e-324(e+38 表示乘以10的38次方,而e-45 表示乘以10的负45次方Double0.0d
boolean(布尔型)2true falseBooleanfalse
char(字符型)1汉字字母都可以Character\u0000

equals和HashCode重写的问题?

在Java中,Object类中提供了equals()和hashCode()方法用于比较对象是否相等以及生成对象的哈希码。默认情况下,equals()方法会比较对象的内存地址,而hashCode()方法则会根据对象的属性值计算出一个整数值作为哈希码。

重写equals方法后,即使两个对象的属性值完全相同,它们也被认为是相等的。这是因为equals方法比较的是对象是否相等,而不是对象的哈希码是否相等。

因此,如果我们不重写hashCode方法,那么即使两个对象相等,它们的哈希码也可能不同。这会导致在使用哈希表等数据结构时出现意外的结果。

另外,如果多个对象具有相同的属性值,那么它们可能会被认为相等,从而出现在哈希表中出现多次的情况。这会影响哈希表的性能和正确性。

因此,为了保证对象在哈希表中的正确性和性能,我们需要重写hashCode方法,确保每个对象都有唯一的哈希码。通常的做法是将每个属性的值取反后再进行求和,这样可以避免哈希冲突的问题。

一般情况下,我们保证,当两个对象的Hashcode相同的时候对象不一定相同,但是当两个对象的equals方法相同时,这两个对象一定相同。

**举例:**如果我们有1000万个对象,这个时候要找出外界输入的对象,判断和我们1000万个对象中哪个对象相等,这个时候我们会先调用hashcode方法,去大大的缩小范围,然后再使用equals方法,这样就可以大大提高我们寻找对象的速度。

深拷贝和浅拷贝的区别

**浅拷贝:**浅拷贝是指只复制对象本身的值,不复制它所引用的对象,因此新旧对象共享同一个引用对象。在 Java 中,可以通过实现 Cloneable 接口和覆盖 clone() 方法来实现浅拷贝。

**深拷贝:**深拷贝是指复制对象本身和所有它所引用的对象,因此新旧对象不共享任何引用对象。在 Java 中,可以通过实现 Serializable 接口和使用序列化/反序列化来实现深拷贝。例如:

==和equals的区别

  • == 既可以比较基本类型也可以比较引用类型,对于基本类型就是比较值,对于引用类型及时比较内存的地址

  • equals的话,他是属于java.lang.Object类里面的方法,如果该方法没有被重写过,默认也是== ,我们可以看到String等类的equals方法是被重写过的,而且String类在日常开发中用的比较多,久而久之,形成了equasl是比较值的错误观点.

  • 具体要看自定义类里面有没有重写Object的equals方法来判断

  • 通常情况下,重写equals方法,会比较类中的属性是否相等

/**
 * ==和equals的区别
 */
public class Test_01 {
    public static void main(String[] args) {

        /**
         * 比较基本数据类型
         */
        int a=1;
        double b=1.0;
        char c=1;
        System.out.println(a==b);  //true
        System.out.println(a==c);  //true


        /**
         * 引用数据类型
         */
        Customer c1 = new Customer("小明", 20);
        Customer c2 = new Customer("小明", 20);
        System.out.println(c1 == c2);       //false
        System.out.println(c1.equals(c2));  //false


//      String
        String str1 = new String("sth");
        String str2 = new String("sth");
        System.out.println(str1 == str2);      // false
        System.out.println(str1.equals(str2)); // true


//      java中String new和直接赋值的区别
//      对于字符串:其对象的引用都是存储在栈中的,如果是编译期已经创建好(直接用双引号定义的)的就存储在常量池中,
//      如果是运行期(new出来的)才能确定的就存储在堆中。对于equals相等的字符串,在常量池中永远只有一份,在堆中有多份。
        String s1="123"; //在常量池中
        String s2="123";
        System.out.println(s1==s2);  //true
        String s3 = new String("123");  //存储在堆内存中
        System.out.println(s1==s3);
        
        /**
         * Integer
         */
        Integer i1=1;
        Integer i2=1;
        System.out.println(i1==i2); //true

        Integer i3=128;
        Integer i4=128;
        System.out.println(i3==i4); //false
        System.out.println(i3.equals(i4));
    }
}
class Customer {
    private String namg;
    private int age;

    public Customer(){

    }

    public Customer(String namg, int age) {
        this.namg = namg;
        this.age = age;
    }

    public String getNamg() {
        return namg;
    }

    public void setNamg(String namg) {
        this.namg = namg;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

常见的运行时异常有哪些?

ArithmeticException(算术异常)

ClassCastException(类转换异常)

IllegalArgumentException(非法参数异常)

IndexOutOfBoundsException(下标越界异常)

NullPointerException(空指针异常)

SecurityException(安全异常)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wei *

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值