大家好呀,小编今天给大家分享一些 Java 常见的基础知识面试题,为即将要面临春招,以及正在寻找工作的小伙伴们提前支支招。
推荐好课:Java基础入门到框架实践、深入解析Java面向对象
一、八种基本数据类型的大小,以及他们的封装类
数据类型 | 封装类 | 大小 |
---|---|---|
byte | Byte | 1 字节 |
short | Short | 2 字节 |
int | Integer | 4 字节 |
long | Long | 8 字节 |
float | Float | 4 字节 |
double | Double | 8 字节 |
boolean | Boolean | / |
char | Character | 2 字节 |
二、switch 能否用 string 做参数?
switch 语句中的变量类型可以使 byte,short,int,char。从 jdk1.7 后可以使用 String 类型,是通过 switch 中的 String.hashcode 将 String 转换成 int 进行判断。
三、equals 与 == 的区别
== 操作符是用来比较两个变量的值是否相等,即就是比较变量在内存中的存储地址是否相同,equals()方法时 String 类从 Object 类中继承的,被用来检测两个对象的内容是否相同。
四、String s = new String(‘abc’);创建了几个 object 对象?
会创建一个 String 类型的变量 s。在类加载到此处之前没有出现“abc”字面量的话,加载此处会创建一个对应“abc”的 String 常量对象。在符合规范的 JVM 上,执行到此处 new 关键字会创建一个 String 对象。
五、 Object有哪些公用方法?
- clone() 创建斌返回此对象的副本
- equals() 判断
- getclass() 返回 object 的运行类
- hashcode() 返回对象的哈希码值
- notify() 唤醒正在等待对象监听器的单个进程
- notifyAll() 唤醒正在等待对象监听器的所有进程
- wait() 导致当前线程等待,直到另一个线程调用该对象的 notify() 方法或 notifyAll() 方法
- toString() 返回此对象的字符串表示形式
- finalize() 当垃圾收集确定不需要该对象时,垃圾回收器调用该方法
六、Java的四种引用,用到的场景
- 强引用:垃圾回收器不会回收
- 软引用:如果内存空间足够,垃圾回收器就不会进行回收,如果内存空间不足,垃圾回收器就会进行回收
- 弱引用:一旦发现了只有弱引用的对象,垃圾回收器就会进行回收。
- 虚引用:如果发现该对象还具有虚引用,就会在回收该对象之前,吧这个虚引用加入到与之关联的引用队列中。
七、静态变量和实例变量的区别
静态变量前要加上关键字 static,实例变量则不会。
实例变量是属于某个对象的属性,必须创建了实例对象,其中的实例变量才会分配空间,才能使用这个实例变量。静态变量不属于任何的实例对象,而是属于类,也称为类变量,只要程序加载了类的字节码,不用创建任何实例对象,就会被分配空间。总之就是,静态变量不需要创建任何的对象就可以直接使用,而实例变量需要先创建实例对象才能被使用。
八、 Overload 和 Override 的区别
重载 Overload 表示的是同一个类中可以有多个相同名称的方法,但这些方法的参数列表不同,即就是参数参数或参数类型不同。重载时返回值当然可以不一样,但是如果参数列表完全一致时,不能通过返回类型不一致而实现重载,这是不可以的。
重写 Override 表示子类中的方法可以与父类中的方法名称和参数完全相同,通过子类创建的对象来调用这个方法时,将调用子类中定义的方法,即就是子类中的该方法将父类的该方法覆盖了。子类覆盖父类方法时只能抛比父类更少或者更小的异常。重写的方法其返回必须和被覆盖的方法返回一致。
九、抽象类和接口的区别
抽象类可以有默认的方法进行实现,可以有构造器,可以有 main 方法进行运行,可以直接在该类中添加实现的方法接口没有默认的方法进行实现,没有构造器,不可以使用 main 方法进行运行,在接口中添加方法时需要在具体实现的类中添加方法。
十、 Java面向对象的特征与含义
- 封装:封装的目的在于实现程序的“高内聚,低耦合”,防止程序相互依赖而带来的变动影响。封装是保证是把对同一事物进行操作的方法和相关的方法放在同一个类中,把方法和他操作的数据放在同一个类中;
- 抽象:抽象就是找出事物的相似和共性,然后将这些事物归为同一类,这个类只考虑这些事物的相似和共性,忽略和当前主题不相关的因素;
- 继承:子类继承父类的内容作为自己的内容,可以加入新的内容或者是修改父类的内容而更加适合特殊的需要。提高了额程序的可重用性和可扩张性;
- 多态:多态是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。
十一、java多态的实现
接口实现,继承父类进行方法重写,
同一个类中进行方法重载。
十二、运行时异常和一般异常的区别
异常表示程序运行过程中可能出现的非正常状态。运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见的运行错误。java 编译器要求方法必须声明抛出可能出现的非运行时异常,但是并不要求必须声明抛出未被捕获的异常。
十三、Java语言如何进行异常处理,throws,throw,try catch finally 代表什么意义,try 块中可以抛出异常吗?
Java 通过面向对象的方法进行异常处理,把各种不同的异常进行分类,并提供了良好的接口。在 Java 中,每个异常都是一个对象,它是 Throwable 类或其它子类的实例。当一个
方法出现异常后便抛出一个异常对象,该对象中包含有异常信息,调用这个对象的方法可以捕获到这个异常并进行处理。Java 的异常处理是通过 5 个关键词来实现的:try、catch、throw、throws 和 finally。一般情况下是用 try 来执行一段程序,如果出现异常,系统会抛出(throws)一个异常,这时候你可以通过它的类型来捕捉(catch)它,或最后(finally)由缺省处理器来处理。
用try来指定一块预防所有”异常”的程序。紧跟在 try 程序后面,应包含一个 catch 子句来指定你想要捕捉的”异常”的类型。
throw 语句用来明确地抛出一个”异常”;
throws 用来标明一个成员函数可能抛出的各种”异常”;
Finally 为确保一段代码不管发生什么”异常”都被执行一段代码;
可以在一个成员函数调用的外面写一个 try 语句,在这个成员函数内部写另一个 try 语句保护其他代码。每当遇到一个 try 语句,”异常”的框架就放到堆栈上面,直到所有的 try 语句都完成;
如果下一级的 try 语句没有对某种”异常”进行处理,堆栈就会展开,直到遇到有处理这种”异常”的 try 语句。
十四、 try catch finally,try里有return,finally还执行么?
- finally 语句总会执行;
- 如果 try、catch 中有 return 语句,finally 中没有 return,那么在 finally 中修改除包装类型和静态变量、全局变量以外的数据都不会对 try、catch 中返回的变量有任何的影响(包装类型、静态变量会改变、全局变量);
- 尽量不要在 finally 中使用 return 语句,如果使用的话,会忽略 try、catch 中的返回语句,也会忽略 try、catch 中的异常,屏蔽了错误的发生;
- finally 中避免再次抛出异常,一旦 finally 中发生异常,代码执行将会抛出 finally 中的异常信息,try、catch 中的异常将被忽略。
十五、 Java 中 final、finally 和 finalize 的区别
- final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承;内部类要访问局部变量,局部变量必须定义成final类型,例如,一段代码……
- finally 是异常处理语句结构的一部分,表示总是执行;
- finalize 是 Object 类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。JVM 不保证此方法总被调用。
十六、String、StringBuffer与StringBuilder的区别
- String 表示内容不可修改的字符串,StringBuffer 表示内容可以修改的字符串;
- String 覆盖了 equals()方法和 hashcode()方法,而 StringBuffer 没有覆盖两个方法,,所以 StringBuffer 对象存储到 java 集合类中时会出现问题;
- StringBulider 也表示内容可以修改的字符串,但是其线程是不安全的,运行效率高。
十七、error和exception区别
- error 表示有可能恢复但比较困难的的一种严重问题,程序是不能进行处理的;
- exception 表示一种设计或者实现问题。
十八、Java 中的异常处理机制和简单原理和应用
JAVA 程序违反了 JAVA 的语义规则时,JAVA虚拟机就会将发生的错误表示为一个异常。违反语义规则包括 2 种情况:
一种是JAVA类库内置的语义检查。例如数组下标越界,会引发 IndexOutOfBoundsException; 访问 null 的对象时会引发 NullPointerException。
另一种情况就是 JAVA 允许程序员扩展这种语义检查,程序员可以创建自己的异常,并自由选择在何时用 throw 关键字引发异常。所有的异常都是 java.lang.Thowable 的子类。
十九、 常见的运行时异常
系统异常是 RuntimeException 的子类,常见的系统异常有:
- ArrayIndexOutOfBoundsException - 数组越界访问
- ClassCastException - 类型转换异常
- NullPointerException - 试图访问一空对象的变量、方法或空数组的元素
- IllegalArgumentException - 方法的参数无效
- NoClassDefFoundException - JAVA运行时系统找不到所引用的类
二十、 Set 里面的元素不能重复,用什么方法区分重复与否?
- Set里的元素是唯一不能重复的,元素是否重复使用 equals() 方法进行判断。
- equals() 方法和 == 方法决定引用值是否指向同一对象 equals() 在类中被覆盖,为的是两个分离的对象的内容和类型相匹配的话,返回真值。
二十一、HashMap 和 Hashtable 的区别
- Hashtable 是基于 Dictionary 类的,HashMap 是 Map 接口的一个实现类;
- Hashtable 是线程安全的,即是同步的;HashMap 线程不是安全的,不是同步的;
- HashMap 可以将空值作为 key 或 value。
二十二、 HashMap、LinkedHashMap、TreeMap的区别
- HashMap 是根据键的 hashcode 值存储数据,根据键可以直接获取它的值,具有很快的访问速度,取得的数据完全是随机的;
- LinkedHashMap 保存了记录的插入顺序,在使用 Iterator 进行遍历的时候,先得到的肯定是先插入的数据,可以在构造时带参数,按照应用次数来进行排序;
- TreeMap 实现 SortMap 接口,能够把它保存的记录根据键排序。默认的是升序排序,也可以指定排序的比较器,进行遍历的时候得到的是排序过的记录。
二十三、HashMap、LinkedHashMap、ConcurrentHashMap、ArrayList、LinkedList的底层实现。
- HashMap 是 java 数据结构中两大结构数组和链表的组合。HashMap 底层数组,数组中的每一项又是一个链表。程序会先根据key的hashcode()方法返回值决定该 Entry 在数组中的存储位置,如果该位置上没有元素,就会将元素放置在此位置上,如果两个 Entry 的 key 相同,会调用 equals,返回值是 true 则覆盖原来的value值,返回 false 则会形成 Entry 链,位于头部。
- ArrrayList 的底层实现是数组,在执行 add 操作时,会先检查数组大小是否可以容纳新的元素,如果不够就会进行扩容。然后会将原来的数据拷贝到新的数组中。
- LinkedList 底层是一个链表,其实现增删改查和数据结构中的操作完全相同,而且插入是有序的。
- LinkedHashMap 的底层结构式是双链表,其他的逻辑处理与 HashMap 一致,同样没有锁保护,多线程使用时存在风险。
- ConcurrentHashMap 是 segment 数组结构和 HashEntry 数组结构组成的,segment 在 ConcurrentHashMap 中充当锁的角色,HashEntry 用于存储键值对数据。segment 的结构是数组和链表,一个segment中有一个 HashEntry,每个 HashEntry 是一个链表结构的元素。对 HashEntry 中的数据进行修改时,需要先获得它所对应的 segment 锁。每个 ConcurrentHashMap 默认有 16 个 segment。
二十四、迭代器Iterator
Iterator 提供了统一遍历操作集合元素的统一接口,Collection 接口实现 Iterator 接口。每个集合都通过实现 Iterator 接口中的iterator() 方法返回实例,然后对元素进行迭代操作,但是在迭代元素的时候不能使用集合的方法删除元素,否则会抛出异常,可以使用 Iterator 接口中的 remove() 方法进行删除。
二十五、Map、Set、List、Queue、Stack的特点与用法。
1、Map 是以键值对的形式进行存储的,其中 key 是唯一不可重复的,value 的可以重复,当插入的值是 key 相同,后加入的会将已有的覆盖。他有几个具体的实现类,包括 Treemap 和 HashMap,TreeMap 是有序的,HashMap 是无序的。
2、List 有序,可重复
|–ArrayList
底层数据结构是数组,查询快,增删慢,线程不安全,效率高
|–Vector
底层数据结构是数组,查询快,增删慢,线程不安全,效率高
|–LinkedList
底层数据结构是链表,查询慢,增删块,线程安全,效率低
3、Set 无序,唯一
|–HashSet
底层数据结构是哈希表
如何保证元素的唯一性:
依赖两个方法,hashCode() 和 equals()
|–LinkedHashSet
底层数据结构是链表和哈希表,由链表保证元素有序,由哈希表保证元素唯一
|–TreeSet 底层数据结构是红黑树,
如何保证元素的排序:
自然排序:让元素所属的类实现 Comparable 接口
比较器排序:让集合接收一个 Comparator 的实现类对象
如何保证元素的唯一性:
根据比较的返回值是否是 0 来决定的
4、Query 队列遵循先进先出的原则,不允许插入null值,其中提供了相应的进队和出队的方法,建议使用offer() 方法来添加元素,使用poll() 方法删除元素
5、Stack遵从后进先出的原则,继承自 Vector。他通过 5 个操作对 Vector 类进行扩展,它提供了 push 和 pop 操作,以及去堆栈顶点的peek() 方法,测试堆栈是否为空的 empty 方法
6、使用方法:
如果涉及到堆栈,队列等操作,建议使用 List
对于快速插入和删除元素建议使 用LinkedList
需要快速随机访问元素建议使用 ArrayList
二十六、Collection 包结构
Collection 是集合类的上级接口,是单列集合。继承他的接口主要有 Set 和 List.
Set接口的子接口有:HashSet,TreeSet
List接口的子接口有:Arraylist,LinkedList,Vector
二十七、Collection 与 Collections 的区别。
Collection 是集合类的上级接口,继承他的接口有 Set 和 List;
Collections 是针对集合类的一个帮助类,它提供一系列的静态方法实现集合的搜索,排序,线程安全等操作。
二十八、 Colection 框架中实现比较要实现什么接口?
comparable:只包含 compareTo() 方法
comparator:compare() 和 equals()
二十九、Collection框架的结构
集合框架(Collection Framework)泛指 java.util 包的若干个类和接口。如 Collection, List, ArrayList, LinkedList, Vector( 自动增长数组), HashSet, HashMap 等;
集合框架中的类主要封装的是典型的数据结构,如动态数组,链表,堆栈,集合,哈希表等;
集合框架类似编程中经常用到的工具类,使得编码这专注于业务层的实现,不需要从底层实现相关细节—“数据结构的封装”和”典型算法的实现”。
三十、 快速失败(fail-fast)和安全失败(fail-safe)的区别。
Iterator 的安全失败是基于对底层集合做拷贝,因此它不受源集合修改的影响。util 包下的所有集合类都是快速失败的,util.concurren包下面的所有类都是安全失败的。
推荐好课:Java开发实例:坦克大战游戏、Java零基础之io流详解