本文介绍一些有关Java基础其它面试常问的问题。
问题1:迭代器Iterrator?
- Iterator 主要是用来遍历集合用的
- 特点是更加安全,因为它可以确保,在当前遍历的集合元素被更改的时候,就会抛出 ConcurrentModificationException 异常。
问题2:comparable 和 comparator的区别?
- comparable 接口实际上是出自java.lang包 它有一个 compareTo(Object obj)方法用来排序
- comparator接口实际上是出自 java.util 包它有一个compare(Object obj1, Object obj2)方法用来排序
- 一般我们需要对一个集合使用自定义排序时,我们就要重写compareTo()方法或compare()方法,当我们需要对某一个集合实现两种排序方式,比如一个 song 对象中的歌名和歌手名分别采用一种排序方法的话,我们可以重写compareTo()方法和使用自制的Comparator方法或者以两个 Comparator 来实现歌名排序和歌星名排序,第二种代表我们只能使用两个参数版的 Collections.sort().
问题3:HashSet是如何保证不重复的?
- 判断两个对象是不是重复的,主要依靠的是hashCode方法和equals方法,所以,一个对象如果想通过HashSet方法判断是不是重复的,需要重写hashCode方法和equals方法
- 如果hashCode不同,说明是新元素,存
- 如果hashCode相同,且equals也相同,就说明元素存在,就不存
- 如果hashCode相同,但equals不同,说明元素不存在,存
问题4:final finally finalize的区别?
- final用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
- finally是异常处理语句结构的一部分,try...catch...finally表示总是执行。
- finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,供垃圾收集时的其他资源回收,例如关闭文件等。
问题5:强引用、软引用、弱引用、虚引用
- 强引用: 如果一个对象具有强引用,那就类似于必不可少的物品,不会被垃圾回收器回收。
- 软引用: 软引用是用来描述一些有用但并不是必需的对象,在Java中用java.lang.ref.SoftReference类来表示。对于软引用关联着的对象,只有在内存不足的时候JVM才会回收该对象。因此,这一点可以很好地用来解决OOM的问题,并且这个特性很适合用来实现缓存:比如网页缓存、图片缓存等。
- 弱引用: 弱引用也是用来描述非必需对象的,当JVM进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象。
- 虚引用: 如果一个对象与虚引用关联,则跟没有引用与之关联一样,在任何时候都可能被垃圾回收器回收。虚引用主要用来跟踪对象被垃圾回收的活动。
问题6:Arrays.sort实现原理 和 Collection.sort实现原理?
- 不论是Collections.sort方法或者是Arrays.sort方法,底层实现都是TimSort实现的,这是jdk1.7新增的,以前是归并排序。TimSort算法就是找到已经排好序数据的子序列,然后对剩余部分排序,然后合并起来.
问题7:异常分类以及处理机制
- 异常:是指程序运行过程中发生的一些不正常事件(如除0溢出,数组下标越界,所要读取的文件不存在)
- 抛出异常:Java程序的执行过程中如果出现异常事件,可以生成一个异常类对象,该对象封装了异常事件的信息,并将其提交给Java运行系统,这个过程称为抛出异常,不处理的话会直接导致程序中断
- Error:Error是无法处理的异常,比如OutOfMemoryError,一般发生这种异常,JVM会选择终止程序。因此我们编写程序时不需要关心这类异常。
- Exception: 就是我们经常见到的一些异常情况,这些异常是我们可以处理的异常,是所有异常类的父类。
- unchecked exception(非受查异常):包括Error和RuntimeException,比如常见的NullPointerException、IndexOutOfBoundsException。对于RuntimeException,java编译器不要求必须进行异常捕获处理或者抛出声明,由程序员自行决定。
- checked exception(受查异常):也称非运行时异常(运行时异常以外的异常就是非运行时异常),由代码能力之外的因素导致的运行时错误。java编译器强制程序员必须进行捕获处理,比如常见的有IOExeption和SQLException。如果不进行捕获或者抛出声明处理,编译都不会通过。
问题8:wait和sleep的区别?
- sleep来自Thread类,和wait来自Object类
- sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法
- 使用范围:wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用
- sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常
问题9:String、StringBuilder、StringBuffer的区别?
- 操作少量的数据: 适用 String
- 单线程操作字符串缓冲区下操作大量数据: 适用 StringBuilder
- 多线程操作字符串缓冲区下操作大量数据: 适用 StringBuffer
- String 中的对象是不可变的,也就可以理解为常量,线程安全。
- StringBuffer 对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。
- StringBuilder 并没有对方法进行加同步锁,所以是非线程安全的。
- String 类中使用 final 关键字修饰字符数组来保存字符串,String对象不可变; StringBuilder 与 StringBuffer的对象是可变的。
问题10:== 和 equles的区别?
(1) == : 它的作用是判断两个对象的地址是不是相等。即,判断两个对象是不是同一个对象(基本数据类型==比较的是值,引用数据类型==比较的是内存地址)。
(2) equals() : 它的作用也是判断两个对象是否相等。但它一般有两种使用情况:
- 情况 1:类没有覆盖 equals() 方法。则通过 equals() 比较该类的两个对象时,等价于通过“==”比较这两个对象。
- 情况 2:类覆盖了 equals() 方法。一般,我们都覆盖 equals() 方法来比较两个对象的内容是否相等;若它们的内容相等,则返回 true (即,认为这两个对象相等)。
问题11:文件和I/O流?
- 按照流的流向分,可以分为输入流和输出流;
- 按照操作单元划分,可以划分为字节流和字符流;
- 按照流的角色划分为节点流和处理流。
- InputStream/Reader: 所有的输入流的基类,前者是字节输入流,后者是字符输入流。
- OutputStream/Writer: 所有输出流的基类,前者是字节输出流,后者是字符输出流。
文章会持续更新,后续还会更新一些本人或者同学在实际秋招中遇到各个公司的笔试或面试题。请大家多多关注!!!谢谢大家!!!
若文中有不准确的地方,或者有其他任何问题,欢迎留言+评论。
上一篇文章:面试之Java基础问题(2)