欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java面试准备(1)

程序员文章站 2022-05-05 22:49:20
...

J2SE基础

1. 八种基本数据类型的大小,以及他们的封装类。

类型 大小 封装类
int 32位=>4字节 Integer
byte 8位 Byte
short 16位 Short
long 64位 Long
char 16位 Character
boolean 1位 Boolean
double 64位 Double
float 32位 Float

2. Switch能否用string做参数?

在jdk 7 之前,switch 只能支持 byte、short、char、int 这几个基本数据类型和其对应的封装类型。

switch后面的括号里面只能放int类型的值,但由于byte,short,char类型,它们会 自动 转换为int类型(精精度小的向大的转化),所以它们也支持。
注意,对于精度比int大的类型,比如long、float,doulble,不会自动转换为int,如果想使用,就必须强转为int,如(int)float;

为什么jdk1.7后又可以用string类型作为switch参数呢?

其实,jdk1.7并没有新的指令来处理switch string,而是通过调用switch中string.hashCode,将string转换为int从而进行判断。

3. equals与==的区别。

equals用于覆写equals方法自己判断

==判断引用所指的对象是否是同一个(地址是否相同)

例如String,==判断是否是同一对象,equals判断是否值相等。Object默认equals方法和==一样的。

4. Object有哪些公用方法?

clone

保护方法,实现对象的浅复制,只有实现了Cloneable接口才可以调用该方法,否则抛出CloneNotSupportedException异常

equals

在Object中与==是一样的,子类一般需要重写该方法

hashCode

该方法用于哈希查找,重写了equals方法一般都要重写hashCode方法。这个方法在一些具有哈希功能的Collection中用到

getClass

final方法,获得运行时类型

wait

使当前线程等待该对象的锁,当前线程必须是该对象的拥有者,也就是具有该对象的锁。wait()方法一直等待,直到获得锁或者被中断。wait(long timeout)设定一个超时间隔,如果在规定时间内没有获得锁就返回。
调用该方法后当前线程进入睡眠状态,直到以下事件发生:
1. 其他线程调用了该对象的notify方法
2. 其他线程调用了该对象的notifyAll方法
3. 其他线程调用了interrupt中断该线程
4. 时间间隔到了

notify

唤醒在该对象上等待的某个线程
此时该线程就可以被调度了,如果是被中断的话就抛出一个InterruptedException异常

notifyAll

唤醒在该对象上等待的所有线程

toString

转换成字符串,一般子类都有重写,否则打印句柄

5. Java的四种引用,强弱软虚,用到的场景。

强引用(StrongReference)

强引用是使用最普遍的引用。如果一个对象具有强引用,那垃圾回收器绝不会回收它。如下:

    Object o=new Object();  //  强引用

强引用在实际中有非常重要的用处,举个ArrayList的实现源代码:

    private transient Object[] elementData;
    public void clear() {

            modCount++;

            // Let gc do its work

            for (int i = 0; i < size; i++)

                elementData[i] = null;

            size = 0;

    }

在ArrayList类中定义了一个私有的变量elementData数组,在调用方法清空数组时可以看到为每个数组内容赋值为null。
不同于elementData=null,强引用仍然存在,避免在后续调用 add()等方法添加元素时进行重新的内存分配。
使用如clear()方法中释放内存的方法对数组中存放的引用类型特别适用,这样就可以及时释放内存。

软引用(SoftReference)

如果一个对象只具有软引用,则内存空间足够,垃圾回收器就不会回收它;
如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,
该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存。

    String str=new String("abc");   // 强引用
    SoftReference<String> softRef=new SoftReference<String>(str);    // 软引用
    当内存不足时,等价于:
    If(JVM.内存不足()) {
       str = null;  // 转换为软引用
       System.gc(); // 垃圾回收器进行回收
    }

虚引用在实际中有重要的应用.
例如浏览器的后退按钮。按后退时,这个后退时显示的网页内容是重新进行请求还是从缓存中取出呢?
这就要看具体的实现策略了。
(1)如果一个网页在浏览结束时就进行内容的回收,则按后退查看前面浏览过的页面时,需要重新构建
(2)如果将浏览过的网页存储到内存中会造成内存的大量浪费,甚至会造成内存溢出
这时候就可以使用软引用

    Browser prev = new Browser();               // 获取页面进行浏览
    SoftReference sr = new SoftReference(prev); // 浏览完毕后置为软引用    
    if(sr.get()!=null){ 
        rev = (Browser) sr.get();           // 还没有被回收器回收,直接获取
    }else{
        prev = new Browser();               // 由于内存吃紧,所以对软引用的对象回收了
        sr = new SoftReference(prev);       // 重新构建
    }

弱引用(WeakReference)

弱引用与软引用的区别在于:只具有弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。
不过,由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象。

    String str=new String("abc");    
    WeakReference<String> abcWeakRef = new WeakReference<String>(str);
    str=null;

你想引用一个对象,但是这个对象有自己的生命周期,你不想介入这个对象的生命周期,这时候你就是用弱引用

虚引用(PhantomReference)

“虚引用”顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。
如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。

虚引用主要用来跟踪对象被垃圾回收器回收的活动。
虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列 (ReferenceQueue)联合使用。
当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之 关联的引用队列中。

在垃圾回收时区别

java面试准备(1)
java面试准备(1)
参考:https://my.oschina.net/ydsakyclguozi/blog/404389

6. Hashcode的作用。

什么是hashcode?

  1. HashCode的存在主要是为了查找的快捷性,HashCode是用来在散列存储结构中确定对象的存储地址的
  2. 如果两个对象equals相等,那么这两个对象的HashCode一定也相同
  3. 如果对象的equals方法被重写,那么对象的HashCode方法也尽量重写
  4. 如果两个对象的HashCode相同,不代表两个对象就相同,只能说明这两个对象在散列存储结构中,存放于同一个位置

HashCode有什么用?

  1. 假设内存中有0 1 2 3 4 5 6 7 8这8个位置,如果我有个字段叫做ID,那么我要把这个字段存放在以上8个位置之一,如果不用HashCode而任意存放,那么当查找时就需要到8个位置中去挨个查找。
  2. 使用HashCode则效率会快很多,把ID的HashCode%8,然后把ID存放在取得余数的那个位置,然后每次查找该类的时候都可以通过ID的HashCode%8求余数直接找到存放的位置了。
  3. 如果ID的 HashCode%8算出来的位置上本身已经有数据了怎么办?这就取决于算法的实现了,比如ThreadLocal中的做法就是从算出来的位置向后查找第 一个为空的位置,放置数据;HashMap的做法就是通过链式结构连起来。反正,只要保证放的时候和取的时候的算法一致就行了。
  4. 如果ID的 HashCode%8相等怎么办(这种对应的是第三点说的链式结构的场景)?这时候就需要定义equals了。先通过HashCode%8来判断类在哪一 个位置,再通过equals来在这个位置上寻找需要的类。对比两个类的时候也差不多,先通过HashCode比较,假如HashCode相等再判断 equals。如果两个类的HashCode都不相同,那么这两个类必定是不同的。

    举个实际的例子Set。我们知道Set里面的元素是不可以重复的,那么如何做到?Set是根据equals()方法来判断两个元素是否相等的。比方 说Set里面已经有1000个元素了,那么第1001个元素进来的时候,最多可能调用1000次equals方法,如果equals方法写得复杂,对比的 东西特别多,那么效率会大大降低。使用HashCode就不一样了,比方说HashSet,底层是基于HashMap实现的,先通过HashCode取一 个模,这样一下子就固定到某个位置了,如果这个位置上没有元素,那么就可以肯定HashSet中必定没有和新添加的元素equals的元素,就可以直接存 放了,都不需要比较;如果这个位置上有元素了,逐一比较,比较的时候先比较HashCode,HashCode都不同接下去都不用比了,肯定不一 样,HashCode相等,再equals比较,没有相同的元素就存,有相同的元素就不存。如果原来的Set里面有相同的元素,只要HashCode的生 成方式定义得好(不重复),不管Set里面原来有多少元素,只需要执行一次的equals就可以了。这样一来,实际调用equals方法的次数大大降低, 提高了效率。

为什么重写了equals方法就需要重写hashcode呢?

按照之前的说法,hashcode是用来判断对象是否相等,假设我们重写了equals方法,那么相等的条件就变了,我们需要改变hashcode方法使用equals的标准重新写一套返回独立数字的算法。

7. ArrayList、LinkedList、Vector的区别。

Arraylist和Vector是采用数组方式存储数据,此数组元素数大于实际存储的数据以便增加插入元素,都允许直接序号索引元素,但是插入数据要涉及到数组元素移动等内存操作,所以插入数据慢,查找有下标,所以查询数据快,

Vector由于使用了synchronized方法-线程安全,所以性能上比ArrayList要差

LinkedList使用双向链表实现存储,按序号索引数据需要进行向前或向后遍历,但是插入数据时只需要记录本项前后项即可,插入数据较快。

8. String、StringBuffer与StringBuilder的区别。

String 字符串常量
StringBuffer 字符串变量(线程安全)
StringBuilder 字符串变量(非线程安全)

9. Map、Set、List、Queue、Stack的特点与用法。

Map

Map是键值对,键Key是唯一不能重复的,一个键对应一个值,值可以重复。
TreeMap可以保证顺序,HashMap不保证顺序,即为无序的。
Map中可以将Key和Value单独抽取出来,其中KeySet()方法可以将所有的keys抽取正一个Set。而Values()方法可以将map中所有的values抽取成一个集合。

Set

不包含重复元素的集合,set中最多包含一个null元素
只能用Iterator实现单项遍历,Set中没有同步方法。
List
有序的可重复集合。
可以在任意位置增加删除元素。
用Iterator实现单向遍历,也可用ListIterator实现双向遍历

Queue

Queue遵从先进先出原则。
使用时尽量避免add()和remove()方法,而是使用offer()来添加元素,使用poll()来移除元素,它的优点是可以通过返回值来判断是否成功。
LinkedList实现了Queue接口。
Queue通常不允许插入null元素。

Stack

Stack遵从后进先出原则。
Stack继承自Vector。
它通过五个操作对类Vector进行扩展,允许将向量视为堆栈,它提供了通常的push和pop操作,以及取堆栈顶点的peek()方法、测试堆栈是否为空的empty方法等

用法

如果涉及堆栈,队列等操作,建议使用List中Queue,Stack
对于快速插入和删除元素的,建议使用LinkedList
如果需要快速随机访问元素的,建议使用ArrayList

10. HashMap和HashTable的区别。

hashmap 线程不安全 允许有null的键和值 效率高一点 方法不是Synchronize的要提供外同步 有containsvalue和containsKey方法 HashMap 是Java1.2 引进的Map interface 的一个实现 HashMap是Hashtable的轻量级实现
hashtable 线程安全 不允许有null的键和值 效率稍低 方法是是Synchronize的 有contains方法方法 Hashtable 继承于Dictionary 类 Hashtable 比HashMap 要重
相关标签: java 面试