Java 面试考点总结

Java 面试考点总结

一、Java基础

  1. 请你说明String和StringBuffer的区别
    可变性:
    String类中使用字符数组保存字符串,private、final、char、value[],所以String对象是不可变的。StringBuffer与StringBuilder都继承自AbstractStringBuilder类,在AbstractStringBuilder中也是使用字符数组保存字符串,char[] value,这两种对象都是可变的。
    线程安全:
    String中的对象是不可变的,也就可以理解为常量,线程安全。
    StringBuilder是非线程安全的,StringBuffer是线程安全的。
    性能:
    每次对String类型进行改变的时候,都会从新生成一个新的String对象。StringBuffer每次都会对StringBuffer对象本身进行操作,而不是生成新的对象并改变对象的引用。相同情况下StringBuilder相比使用StringBuffer仅能获得10%-15%左右的性能提升,但却要冒多线程不安全的风险
    对于三者使用的总结:
    如果要操作少量的数据用:String
    单线程操作字符串缓冲区下操作大量数据:StringBuilder
    多线程操作字符串缓冲区下操作大量数据:StringBuffer

  2. 请你说明一下int和Integer有什么区别

    int是基本类型儿Integer是int的包装类

  3. 数组(Array)和列表(ArrayList)的区别?什么时候应该用Array而不是ArrayList?

    Array可以储存基本数据类型和对象,ArrayList只能储存对象。
    Array是固定大小的,ArrayList大小是自动扩展的。
    Array内置方法没有ArrayList多,比如addAll、iteration等方法只有ArrayList有。

  4. 什么是值传递和引用传递?
    值传递:值的是在方法调用的时候,传递的参数是按值的拷贝传递,传递的是值的拷贝,也就是说传递后就互相不相关了。
    引用传递:指的是在方法调用时,传递的参数是按引用进行传递,其实传递的引用地址,也就是变量所对应的内存空间地址。传递的是值的引用,也就是说传递前和传递后都指向同一个引用(也就是同一个空间)

  5. Java支持的数据类型
    基本数据类型:
    数值型:整型->byte、short、int、long 浮点型->float、double
    字符型:char
    布尔类型:boolean
    引用数据类型:类(class)、接口(interface)、数组([ ])

  6. 为什么会出现4.0-3.6=0.40000001这种现象?
    二进制小数无法精确的表达十进制小数。在进行十进制小数的计算中需要酱十进制转化为二进制,这中间出现了错误。

  7. Java8的新特性,请简单介绍一下
    Lambda表达式、方法引用、默认方法、新工具、Stream API、Date Time API、Option类、Nashorn,JavaScript引擎

  8. 说明一下符号"==" 比较的是什么
    ==:在比较类型为数基本数据类型时,是比较值,引用数据类型==比较的是内存的地址

  9. Object若不重写hashCode()的话,hashCode()如何计算出来?
    hashCode的默认行为是对堆上的对象产生独特值。

  10. 为什么重写equals还要重写hashcode?
    因为如果不重写hashCode的话,是根据相应对象的JVM内存地址进行计算,如果没有重写那么无论如何都是不可能相等的。

  11. 若对一个类不重写,它的equals()方法是如何比较的
    类没有覆盖equals()方法。则通过equals()比较该类的两个对象时,等价于通过"=="比较这两个对象。

二、 关键字

  1. Java里面的final关键字怎么用的?
    用于修饰类、属性和方法:

    • 被final修饰的类不可被继承
    • 被final修饰的方法不可以被重写
    • 被final修饰的变量不可被改变,被final修饰不可变的是变量的引用,而不是引用指向的内容,引用指向的内容是可以改变的。
  2. 谈谈synchronized和lock

    • 首先synchronized是Java的内置关键字,在JVM层面lock是Java的一个类;
    • synchronized只能给类、方法、代码块加锁,而lock只能给代码块加锁;
    • synchronized不需要手动获取锁和释放锁使用简单,发生异常会自动释放锁,不会造成死锁;lock需要自己手动加锁,释放锁,如果操作不当没有unLock()去释放锁,那么就会造成死锁
    • 通过lock可以知道有没有成功获取锁,而synchronized无法办到。
  3. 请介绍一下volatile
    对于可见性,Java 提供了 volatile 关键字来保证可见性和禁止指令重排。 volatile 提供 happens-before 的保证,确保一个线程的修改能对其他线程是可见的。当一个共享变量被 volatile 修饰时,它会保证修改的值会立即被更新到主存,当有其他线程需要读取时,它会去内存中读取新值。

  4. 请介绍一下Synchronized锁,如果用这个关键字修饰一个静态方法,锁住了什么?如果修饰成员方法,锁住了什么?

    修饰静态方法: 也就是给当前类加锁,会作用于类的所有对象实例,因为静态成员不属于任何一个实例对象,是类成员( static 表明这是该类的一个静态资源,不管new了多少个对象,只有一份)。所以如果一个线程A调用一个实例对象的非静态 synchronized 方法,而线程B需要调用这个实例对象所属类的静态 synchronized 方法,是允许的,不会发生互斥现象,因为访问静态 synchronized 方法占用的锁是当前类的锁,而访问非静态 synchronized 方法占用的锁是当前实例对象锁。

    修饰成员方法:作用于当前对象实例加锁,进入同步代码前要获得当前对象实例的锁

三、面相对象

  1. Java中的方法重写(Override)和方法重载(Overload)是什么意思?
    方法重载(Overload):发生在同一个类,方法名相同,参数列表不同(参数类型不同、个数不同、顺序不同),与方法返回值和访问修饰符无关,即重载的方法不同根据返回类型来区分。
    方法重写(Override):发生在父子类中,方法名、参数列表、必须相同,返回值小于等于父类,抛出的异常小于等于父类,访问修饰符大于等于父类 (里氏替换原则);如果父类方法访问修饰符为private则子类中就不是重写。

  2. 如何通过反射获取和设置对象私有字段的值?
    可以通过类对象的getDeclaredField()方法字段(Field)对象,然后再通过字段对象的setAccessible(true)将其设置为可以访问,接下来就可以通过get/set方法来获取/设置字段的值了。

  3. 请说明内部类可以引用它包含类的成员吗,如果可以,有没有什么限制吗?
    完全可以,如果不是静态内部类,那没有什么限制! 如果你把静态嵌套类当作内部类的一种特例,那在这种情况下不可以访问外部类的普通 成员变 量,而只能访问外部类中的静态成员

  4. 当一个对象被当作参数传递给一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?
    是值传递,Java语言的方法调用只支持值传递。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用,对象的属性可以在被调用过程中被改变,但对对象引用的改变是不会影响到调用者的。

  5. 什么是泛型?

    泛型,即“参数化类型”。就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数类型

  6. 解释一下类加载机制,双亲委派模型,好处是什么?
    虚拟机把描述类的数据从class文件加载到内存,并对数据进行校验,解析和初始化最终形成可以被虚拟机直接使用的Java类型。
    双亲委派模型:首先如果一个类加载器收到了类加载请求,他首先不会自己去加载这个类,而是把这个请求委派给父类加载器去完成,每一层的类加载器都是如此,这样所有的请求都会被传送到顶层的启动类加载器中,只有当父加载无法完成加载请求的时候,子加载器才会去尝试去加载类。

  7. “static”关键字是什么意思?Java中是否可以重写(Override)一个private或者static方法
    主要意义是在于创建独立于具体对象的域变量或方法,也就是说,即使没有创建对象,也能使用属性和调用方法。
    Java中不可以Override一个private或者static方法

  8. 列举你知道的Object类的方法并简要说明。
    Clone():创建并返回对象的副本。
    getClass():返回一个运行时的类。
    toString():返回该对象的字符串表示。
    finalize():用于释放资源,该方法一般由垃圾回收器来调用。
    equals()
    hashCode()
    wait():wait是Object方法,而sleep是Thread的方法。
    notify():唤醒在该对象等待的某个线程。
    notifyAll():唤醒在该对象的全部线程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值