Java基础知识面试常见问题

1.Java语言有哪些特点

面向对象、分布性、安全性、支持多线程。

2.面向对象和面向过程的区别

面向过程:根据解决问题的步骤,使用函数一步步实现。优点是性能好,一般用于单片机、嵌入式
面向对象:将构成问题的事务分解为各个对象,建立对象的目的是为了描述某事物在解决整个问题过程中发生的行为。面向对象有封装、继承、多态的特性,易维护、易复用、易扩展,性能低于面向过程。

3.instanceof 关键字的作用

instanceof 是Java中的一个双目运算符,用来测试一个对象是否为一个类的实例

boolean result = obj instanceof Class

其中 obj 为一个对象,Class 表示一个类或者一个接口,当 obj 为 Class 的对象,或者是其直接或间接子类,或者是其接口的实现类,结果result 都返回 true,否则返回false。

注意:编译器会检查 obj 是否能转换成右边的class类型,如果不能转换则直接报错,如果不能确定类型,则通过编译,具体看运行时定。
  还有obj不能是基本数据类型,即八个分别是 byte,short,int,long,float,double,char,boolean以及一个特殊类型null

3.Java自动装箱与拆箱

装箱就是自动将基本数据类型转换为包装器类型(int–>Integer)通过调用Integer的valueOf(int) 方法
拆箱就是自动将包装器类型转换为基本数据类型(Integer–>int)通过调用Integer的intValue方法

从Java SE5开始提供了自动装箱的特性,如生成一个数值为10的Integer对象

Integer i = 10;

注意:(仅仅适用于int,而float不适用)通过valueOf方法创建Integer对象的时候,数值在[-128,127]之间,返回指向IntegerCache.cache中已经存在的对象的引用;否则创建一个新的Integer对象

4. 重写Override和重载Overload的区别

重写 :

public class Father {
  public static void main(String[] args) {
    // TODO Auto-generated method stub
    Son s = new Son();
    s.sayHello();
 }
  public void sayHello() {
    System.out.println("Hello");
 }
}
class Son extends Father{
  @Override
  public void sayHello() {
    // TODO Auto-generated method stub
    System.out.println("hello by ");
 }
}

1.发生在父类与子类之间
2.方法名,参数列表,返回类型(除过子类中方法的返回类型是父类中返回类型的子类)必须相同
3.访问修饰符的限制一定要大于被重写方法的访问修饰符(public>protected>default>private)
4.重写方法一定不能抛出新的检查异常或者比被重写方法申明更加宽泛的检查型异常
重载 :

public class Father {
  public static void main(String[] args) {
    // TODO Auto-generated method stub
    Father s = new Father();
    s.sayHello();
    s.sayHello("wintershii");
 }
  public void sayHello() {
    System.out.println("Hello");
 }
  public void sayHello(String name) {
    System.out.println("Hello" + " " + name);
 }
}

1.重载Overload是一个类中多态性的一种表现
2.重载要求同名方法的参数列表不同(参数类型,参数个数甚至是参数顺序)
3.重载的时候,返回值类型可以相同也可以不相同。无法以返回型别作为重载函数的区分标准

5. equals与==的区别

==: 比较的是变量(栈)内存中存放的对象的(堆)内存地址,用来判断两个对象的地址是否相同,即是否是指相同一个对象。比较的是真正意义上的指针操作。

equals用来比较的是两个对象的内容是否相等,由于所有的类都是继承自java.lang.Object类的,所以适用于所有对象,如果没有对该方法进行覆盖的话,调用的仍然是Object类中的方法,而Object中的equals方法返回的却是==的判断。

6.String、StringBuffer 和 StringBuilder 的区别是什么?

运行速度StringBuilder > StringBuffer > String,因为String为字符串常量,一旦创建不可修改,只能new,而StringBuffer 和 StringBuilder可以在原基础上修改,此外StringBuffer由于加了synchronized锁,因此运行速度慢于不加锁的StringBuilder,但是StringBuffer是线程安全的,总结下来就是需要并发用StringBuffer,单线程StringBuilder。

从方法上来说,String实现了三个接口:Serializable、Comparable、CarSequence;StringBuffer 和 StringBuilder只实现了两个接口Serializable、CharSequence,相比之下String的实例可以通过compareTo方法进行比较,其他两个不可以。

7.ArrayList和linkedList的区别

Array是基于索引(index)的数据结构,它使用索引在数组中搜索和读取数据是很快,但是要删除数据开销很大;
ArrayList的toArray方法返回一个数组
ArrayList的asList方法返回一个列表
在这里插入图片描述
LinkList是一个双链表,在添加和删除元素时具有比ArrayList更好的性能.但在get与set方面弱于ArrayList

8.HashMap和HashTable的区别

HashMap和HashTable都是哈希表,两者结构基本相同,但还是有区别的
(1)父类不同
HashMap是继承自AbstractMap类,而Hashtable是继承自Dictionary类,不过它们都实现了同时实现了map、Cloneable(可复制)、Serializable(可序列化)这三个接口

(2)Hashtable比HashMap多提供了elments()(源于Dictionary类) 和contains() 两个方法

(3)对null的支持不同
Hashtable:key和value都不能为null
HashMap:key可以为null,但是这样的key只能有一个,因为必须保证key的唯一性;可以有多个key
值对应的value为null
(4)安全性不同
HashMap是线程不安全的,Hashtable是线程安全的,因此HashMap效率更高

9.Collection与Collections的区别

Collection是集合类的上级接口,子接口有 Set、List、LinkedList、ArrayList、Vector、Stack、Set;
Collections是集合类的一个帮助类, 它包含有各种有关集合操作的静态多态方法。

10.Java的四种引用,强弱软虚

强引用:
强引用是平常中使用最多的引用,强引用在程序内存不足(OOM)的时候也不会被回收,使用方式:

String str = new String("str");

软引用:
可有可无的对象,如果内存空间足够,GC就不会去回收这个对象,如果内存不足,就会回收,使用方式:

SoftReference<String> wrf = new SoftReference<String>(new String("str"));

弱引用:
也是描述可有可无的对象,和软引用不同的是,它的生命周期更短,在GC的过程中,一旦发现有弱引用的对象,不管当前内存空间是否足够,都会回收它的内存,使用方式:

WeakReference<String> wrf = new WeakReference<String>(str);

虚引用
虚引用的回收机制跟弱引用差不多,但是它被回收之前,会被放入 ReferenceQueue 中。其它引用是被JVM回收后才被传入 ReferenceQueue 中的。由于这个机制,所以虚引用大多被用于引用销毁前的处理工作。还有就是,虚引用创建的时候,必须带有 ReferenceQueue :

PhantomReference<String> prf = new PhantomReference<String>(new
String("str"), new ReferenceQueue<>());

11.使用泛型的好处?

类型安全、消除强制类型转换、潜在性能优化

12.Java创建对象有几种方式?

(省略了异常处理代码,部分代码无法正常运行)
1.使用new创建对象:最常见,但是会增加代码耦合度

package com.test;
public class Hello
{
    public void sayWorld()
    {
        System.out.println("Hello world!");
    }

}
public class NewClass
{
    public static void main(String[] args)
    {
        Hello h = new Hello();
        h.sayWorld();
    }
}

2.使用反射的机制创建对象
(1)使用Class类的newInstance方法

package com.test;
public class NewClass
{
    public static void main(String[] args)
    {
           Class heroClass = Class.forName("yunche.test.Hello");//根路径
           Hello h =(Hello) heroClass.newInstance();
           h.sayWorld();
        
    }
}

(2)使用Constructor类的newInstance方法

public class NewClass
{
    public static void main(String[] args)
    {
            //获取类对象
           Class heroClass = Class.forName("yunche.test.Hello");
           //获取构造器
           Constructor constructor = heroClass.getConstructor();
           Hello h =(Hello) constructor.newInstance();
           h.sayWorld();
    }
}

3.采用clone
要调用clone方法需要实现Cloneable接口

public class Hello implements Cloneable
{
    public void sayWorld()
    {
        System.out.println("Hello world!");

    }

    public static void main(String[] args)
    {
        Hello h1 = new Hello();
        Hello h2 = (Hello)h1.clone();
        h2.sayWorld();
    }
}

4.采用序列化机制
当我们序列化和反序列化一个对象,JVM会给我们创建一个单独的对象,在反序列化时,JVM创建对象并不会调用任何构造函数。为了反序列化一个对象,我们需要让我们的类实现Serializable接口。

public class Serialize
{
    public static void main(String[] args)
    {
        Hello h = new Hello();

        //准备一个文件用于存储该对象的信息
        File f = new File("hello.obj");

        FileOutputStream fos = new FileOutputStream(f);
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        FileInputStream fis = new FileInputStream(f);
        ObjectInputStream ois = new ObjectInputStream(fis)
            //序列化对象,写入到磁盘中
        oos.writeObject(h);
            //反序列化对象
        Hello newHello = (Hello)ois.readObject();
            //测试方法
        newHello.sayWorld();
    }
}

13.两个不相等的对象有相同的hashcode如何处理

拉链法:每个哈希表节点都有一个next指针,多个哈希表节点可以用next指针构成一个单向链表,被分配到同一个索引上的多个节点可以用这个单向链表进行存储,Java中的HashMap在存储数据的时候就是用的拉链法来实现的

开放定址法:一旦发生了冲突,就去寻找下一个空的散列地址,只要散列表足够大,空的散列地址总能找到,并将记录存入

再哈希:又叫双哈希法,有多个不同的Hash函数.当发生冲突时,使用第二个,第三个….等哈希函数计算地址,直到无冲突.

14.深拷贝和浅拷贝的区别是什么

浅拷贝(shallowCopy)只是增加了一个指针指向已存在的内存地址
深拷贝(deepCopy)是增加了一个指针并且申请了一个新的内存,使这个增加的指针指向这个新的内存

15.被final修饰后会发生什么

:被final修饰的类不可以被继承

方法:被final修饰的方法不可以被重写,且JVM会尝试将其内联,以提高运行效率

常量:被final修饰的常量,在编译阶段会存入调用类的常量池中

变量:如果final修饰的是一个基本数据类型的变量,那么这个变量的值就定了,不能变了,而如果修饰的是一个引用变量如StringBuffer,那么该变量存的是一个内存地址,该地址就不能变了,但是该内存地址所指向的那个对象还是可以变的

16.3*0.1==0.3返回值是什么

false,浮点数不能完全精确地表示出来

17.a=a+b与a+=b有什么区别吗?

(1)性能方面:a=a+b是加法运算 需要两次寻找地址而a+=b是增量运算有寄存器优先时 只有一次地址查找
(2)数据类型方面
+= 操作符会进行隐式自动类型转换,此处a+=b隐式的将加操作的结果类型强制转换为持有结果的类型,而a=a+b则不会自动进行类型转换

short s1= 1;
s1 = s1 + 1;

short类型在进行运算时会自动提升为int类型,也就是说 s1+1 的运算结果是int类型,而s1是short
类型,此时编译器会报错
正确写法:

short s1= 1;
s1 += 1;

19.Excption与Error结构

Java可抛出(Throwable)的结构分为三种类型:被检查的异常(CheckedException),运行时异常
(RuntimeException),错误(Error)
在这里插入图片描述

1、运行时异常
定义:RuntimeException及其子类都被称为运行时异常
注意:Java编译器不会检查它

常见的五种运行时异常:
ClassCastException(类转换异常)
IndexOutOfBoundsException(数组越界)
NullPointerException(空指针异常)
ArrayStoreException(数据存储异常,操作数组是类型不一致)
BufferOverflowException(写入的长度超出了允许的长度)

2、被检查异常
定义:Exception类本身,以及Exception的子类中除了"运行时异常"之外的其它子类都属于被检查异常。
特点 : Java编译器会检查它,此类异常,要么通过throws进行声明抛出,要么通过try-catch进行捕获处理,否则不能通过编译。
如IOException,FileNotFoundException,SQLException,NullPointerException,CloneNotSupportedException

3、错误
定义 : Error类及其子类。
特点 : 和运行时异常一样,编译器也不会对错误进行检查。

20.线程、程序、进程的基本概念及关系

进程是程序的一次执行过程,是系统运行程序的基本单位。系统运行一个程序即是一个进程从创建,运行到消亡的过程。

程序是含有指令和数据的文件,被存储在磁盘或其他的数据存储设备中,程序是静态的代码

线程是一个比进程更小的执行单位,进程在其执行的过程中可以产生多个线程,同类的多个线程共享同一块内存空间和一组系统资源

21.线程有哪些基本状态?

在这里插入图片描述
共有六种状态:
new:初始状态,线程被调用但是没有调用start方法
runnable:运行状态,Java线程将操作系统的就绪和运行两种状态称为运行中
Blocked:阻塞状态,表示线程阻塞于锁
Waiting:等待状态,表示线程进入等待状态,进入该状态标识当前线程做出一些特定动作
Time_Waiting:超时等待状态,不同于waiting,可以在指定时间后返回
Terminated:终止状态,表示线程已经执行完毕

22.Java 序列化中如果有些字段不想进行序列化怎么办?

对于不想进行序列化的变量,使用 transient 关键字修饰。transient 关键字的作用是:阻止实例中那些用此关键字修饰的的变量序列化;当对象被反序列化时,被 transient 修饰的变量值不会被持久化和恢复。transient 只能修饰变量,不能修饰类和方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值