# 常见的Java问题

 

## 什么是Java虚拟机?为什么Java被称作是“平台无关的编程语言”?

 

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。 - Java虚拟机是一个可以执行Java字节码文件的虚拟机进程。Java源文件被编译成能够被Java虚拟机执行的字节码文件。 - Java是被设计为允许应用程序在任意平台都可以允许,不需要我们为每一个平台单独重写或者重新编译,Java虚拟机使其变成可能,因为它直到底层硬件平台的指令长度和其他特性。

 

## JDK和JRE的区别是什么?

 

- JRE是将要执行Java程序的Java虚拟机,它同时包含了执行applet需要的浏览器插件。 - JDK是完整的Java程序开发包,包含了JRE、编译器和其他工具。 所以,我们通常情况下,只需要下载JDK、配置好开发环境就可以了

 

## "static"关键字是什么意思?Java能否覆盖(override)一个private或则static的方法

 

- “static”关键字表名一个成员变量或者一个成员方法可以在没有所属类的实例变量的情况下被访问,也就是我们不用使用new关键字构建一个对象,使用**类名.成员变量**或者**类名.成员方法**就可以。 - Java中的static方法不能被覆盖,因为方法覆盖是基于动态绑定的,而static方法使编译时静态绑定的。(换句话说,一个static方法,或者static属性,static代码块实在这个类加载时就被注册,而方法覆盖是动态的)

 

## 是否可以在static环境下访问非static变量

 

static变量在Java中是属于类的,它在所有的实例中的值是一样的。当类被Java虚拟机载入的时候,会对static变量进行初始化。如果我们尝试不用实例来访问一个非static的变量,那么编译器就会报错,因为这些变量还未被创建出来,还没有跟任何实例关联上

 

## Java支持的数据类型有哪些?什么时候自动装箱?

 

Java语言支持的8种基本数据类型:

 

名称 | 字节数 -------|--------- byte | 1 short | 2 int | 4 long | 8 float | 4 double | 8 boolean | 1 char | 2

 

**自动装箱**是Java编译器在基本数据类型和对象的包装类型之间做的一个相互转换。

 

## Java中方法覆盖(override)和重载(overload)是什么意思?

 

- Java的方法覆盖通常是一个子类重新定义了其父类的方法,它们必须具有相同的方法名,参数列表和返回类型,父类的方法访问通常是public。 - Java的方法重载发生同一个类中,两个或则多个方法具有相同的方法名但是他的参数不同(参数个数不同或则参数类型不同或则参数顺序不同)

 

## java中,什么是构造函数?什么是构造函数重载?什么是复制构造函数?   - 当一个新对象被创建的时候,构造函数就会被调用。每一个类都有它的构造函数。当程序员没有给一个类提供构造函数的时候,Java编译器会自动给这个类创建一个默认的构造函数。 - Java中的构造函数重载和方法的重载很相似。可以为一个类创建多个构造函数,而每一个构造函数都必须有它自己唯一的参数列表。 - Java不支持复制构造函数。

 

## Java支持多继承吗?

 

不支持,Java支持单继承,每一个类都只能继承一个类,但可以实现多个接口。

 

## 接口和抽象类的区别是什么?

 

- 接口中所有的方法隐含的都是抽象的,而抽象类可以同时包含抽象和非抽象的方法。 - 一个类可以实现多个接口,但一个类只能继承一个抽象类 - 一个类要实现一个接口,就必须实现它里面的所有方法。但一个类继承一个抽象类,就不必实现其所有的方法。 - 接口里声明的变量默认都是final,而抽象类可以包含非final的变量 - 接口中的成员函数默认都是public的,而抽象类的成员变量可以说private、protected或则public - 接口是绝对抽象的、不可以被实例化。抽象类也不可以被实例化,但当它包含一个main方法的时候还是可以被调用的。   ## 什么是值传递和引用传递

 

- 对象被值传递,意味着传递的是对象的一个副本。因此,就算改变了对象的副本,也不会影响源对象的值 - 对象被引用传递,意味着传递的并不是实际的对象,而是对象的引用。因此,外部对引用对象所做的改变会反映到所有的对象上。

 

# Java线程

 

## 进程和线程的区别是什么?

 

进程是执行着的应用程序,而线程是进程内部的一个执行序列。一个进程可以有多个线程。线程又被称为轻量级进程。

 

## 创建线程有几种不同的方式?

 

- 继承Thread类 - 实现Runnable接口 - 应用程序可以使用Executor框架来创建线程池

 

通常情况下,实现Runnable接口比较受欢迎,因为不需要继承Thread类,在程序设计时,如果继承了其他的类,就无法继承多个类,这个时候就可以实现接口。同时,线程池也是非常高效的,比较容易实现和使用。

 

## 概述一下线程的几种可用状态

 

- 新建(new) - 就绪(线程对象调用了start方法) - 运行(Running):进程正在执行线程的代码 - 阻塞(Block):线程停止执行 - 死亡(Dead):线程完成执行

 

## 同步方法和同步代码块的区别是什么?

 

在Java中,每一个对象都有一把锁。线程可以使用synchronized关键字来获取对象上的锁。 synchronized关键字可以应用在方法级别(粗颗粒锁)或则代码块级别(细颗粒锁)。

 

## 在监视器(Monitor)内部,是如何做到线程同步的?程序应该做哪种级别的同步?

 

监视器和锁在Java虚拟机中是一块使用的。监视器监视一块同步代码块,确保一次只有一个线程执行同步代码块。每一个监视器和一个对象引用相关联。线程在获取锁之前不允许执行同步代码。

 

## 什么是死锁

 

两个进程都在等待对方执行完毕才能继续往下执行的时候就产生了死锁。结果就是两个进程都进入的无限的等待中

 

## 如何确保N个线程可以访问N个资源同时又不导致死锁

 

使用多线程的时候,一种简单避免死锁的方式就是:指定获取锁的顺序,并且强制线程安装指定的顺序去获取锁。因此,如果所有的线程都是按照同样的顺序来加锁和释放锁,就不会出现死锁了

 

# 集合类

 

## 集合类框架的基本接口有哪些?

 

- Collection:代表一组对象,每个对象都是它的子元素 - Set:不包含重复元素的Collection - List:有顺序的Collection,并且可以包含重复的元素 - Map:将键(key)映射到值(value)的对象,键不可以重复

 

## 为什么集合类没有实现Cloneable和Serializable接口

 

集合类接口指定了一组叫做元素的对象。集合类接口的每一种的具体实现类都可以选择以它自己的方式对元素进行保存和排序。 有的类允许重复的键,有的则不允许。

 

## 什么是迭代器(Iterator)

 

Iterator接口提供了许多对集合元素进行迭代的方法。每一个集合类都包含了可以返回迭代器的实例

 

## Java中的HashMap的工作原理是什么?

 

Java中的HashMap是以键值对(key-value)的形式来存储元素的。HashMap需要一个hash函数,它使用hashcode()和equals()方法来向集合中添加和检索元素。当调用put方法的时候,hashMap会计算key的hash值,然后将键值对存储在集合中是和的索引上。如果key已经存在,那么value就会被更新。HashMap的一些重要的特性就是他的容量(capacity),负载因子(load factor)和扩容极限(threshold resizing)。

 

## hashcode()和equals()方法的重要性体现在什么地方?

 

Java中的HashMap是使用hashCode()和equals()方法来确定键值对的索引,当根据键获取值得时候也会使用这两个方法。如果没有正确实现这两个方法,那么两个不同的键可能会有相同的hash值,可能会被集合认为是相等的。而且,这两个方法也用来发现重复的元素,所以这两个方法的实现对HashMap的精确性和正确性是很重要的

 

## HashMap和HashTable有什么区别

 

- HashMap允许键和值是null(键为null的只能又一个,值为null的可以有多个),HashTable不允许键或者值是null。 - HashMap不是同步的,而HashTable是同步的。所以HashMap比较适合单线程环境,HashTable适用于多线程环境 - HashTabl只是在HashMap的基础加了一个synchronized的锁

 

## 数组(Array)和(ArrayList)有什么区别,什么时候使用Array而不是ArrayList?

 

- Array可以包含基本数据类型和对象数据类型,而ArrayList只能包含对象类型。 - Array的大小是固定的,而ArrayList的大小是动态变化的 - ArrayList提供了多种方法和特性,比如:addAll(),removeAll()

 

## ArrayList和LinkList的区别?

 

- ArrayList是基于索引的数据接口,它的底层是数组,它可以以O(1)的时间复杂度对元素进行随机访问。LinkedList是以元素列表的形式存储它的数据,每一个元素都和它的前一个和后一个元素连接在一起,它的时间复杂度为O(n)。 - ArrayList的查询、遍历速度更快。LinkedList的插入,删除操作速度更快。 - LinkedList比ArrayList更占内存,因为LinkedList的每一个节点存储了两个引用。

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄