Android校招复习全书(1)-j2se

来源:互联网 发布:维启网络 编辑:程序博客网 时间:2024/06/04 22:36

一、九种基本数据类型的大小,以及他们的封装类

关于JAVA基本数据类型

名称 解释 长度(位) 默认值 封装类 byte 字节 8 0 Byte shot 短整型 16 0 Short int 整型 32 0 Integer long 长整型 64 0 Long float 浮点型 32 0.0f Float double 双精度 64 0.0d Double char 字符型 16 ‘\u0000’ Character boolean 布尔型 1 false Boolean void

操作系统16位的时候,int 2字节,操作系统32位的时候,int 4字节,由于32位系统之前占主流地位,实际现在就算是64位系统,出于兼容性考虑,int也是4字节的。
Java的类型分成两种,一种是基本类型,一种是引用类型。两种的本质区别就是:基本类型是在堆栈处分配空间存“值”。但是引用类型,是在堆里面分配空间存“值”。Void是不能new出来,也就是不能在堆里面分配空间存对应的值。那就是一开始在堆栈处分配好空间了。所以,有些人将Void归成基本类型,也有道理。

二、Switch能否用string做参数?

  • JDK1.7之前不能用,JDK1.7后可以用。
  • switch后面的括号里面只能放int类型的值,但由于byte,short,char类型,它们会 自动 转换为int类型(精精度小的向大的转化),所以它们也支持。
  • 我们也可以用枚举类型实现switch可传入string参数。

三、equals与==的区别

前者比较值,后者比较在内存中地址的位置。
String比较特殊重写了equals方法

public boolean equals(Object anObject) {        if (this == anObject) {            return true;        }        if (anObject instanceof String) {            String anotherString = (String)anObject;            int n = value.length;            if (n == anotherString.value.length) {                char v1[] = value;                char v2[] = anotherString.value;                int i = 0;                while (n-- != 0) {                    if (v1[i] != v2[i])                        return false;                    i++;                }                return true;            }        }        return false;    }

如果自定义的类重写了equals值,用于比较值相同,一定要重写hashcode方法,因为在HashSet/HashMap/HashTable进行查重比较的时候,用于hashcode

四、Object有哪些公用方法?

1.protected Object clone()创建并返回此对象的一个副本。

1)浅复制和深复制的概念
 浅复制:被复制的对象的所有变量都与原来的对象有相同的值,但是指向的引用的对象相同,即地址相同,操作一个对象,另一个也会改变。 深复制:被复制的对象的所有变量都与原来的对象有相同的值,但是复制了引用的对象不相同,即地址不同,操作一个对象,另一个不会改变。
2)Java的clone()方法
package com.li;public class Test4{    public static void main(String[] args)    {        // TODO Auto-generated method stub        Student s1 = new Student("zhangsan", 12);        Student s2 = (Student) s1.clone();        s2.name="lisi";            s2.age=20;           System.out.println("name="+s1.name+","+"age="+s1.age);//   name=zhangsan,age=12    }}class Student implements Cloneable{    String name;        int age;        Student(String name,int age)        {           this.name=name;           this.age=age;        }        @Override    protected Object clone()    {        Object o = null;        try        {            o = (Student)super.clone();            return o;        }        catch(Exception e)        {            e.printStackTrace();        }        return o;    }}

①为什么我们在派生类中覆盖Object的clone()方法时,一定要调用super.clone()呢?在运行时刻,Object中的clone()识别出你要复制的是哪一个对象,然后为此对象分配空间,并进行对象的复制,将原始对象的内容一一复制到新对象的存储空间中。
②继承自java.lang.Object类的clone()方法是浅复制。以下代码可以证明之。

package com.li;public class Test4{    public static void main(String[] args)    {        // TODO Auto-generated method stub        Professor p = new Professor("jiaoshou",50);        Student s1 = new Student("li", 20, p);        Student s2 = (Student) s1.clone();        s2.p.name = "jiaoshou2";        s2.p.age = 55;        //如果加了注释输出:name=jiaoshou2,age=55        System.out.println("name="+s1.p.name+","+"age="+s1.p.age);        //如果不加注释输出:name=jiaoshou,age=50    }}class Professor implements Cloneable{    String name;    int age;    public Professor(String name, int age)    {        this.name = name;        this.age = age;    }    /*    @Override    protected Object clone()    {        Professor o = null;        try        {            o = (Professor) super.clone();        }        catch (Exception e)        {            e.printStackTrace();        }        return o;    }*/}class Student implements Cloneable{    String name;    int age;    Professor p;    public Student(String name, int age, Professor p)    {        this.name=name;            this.age=age;            this.p=p;     }    @Override    protected Object clone()    {        Student o = null;        try        {            o = (Student) super.clone();        }        catch (Exception e)        {            e.printStackTrace();        }        /*o.p = (Professor) p.clone();*/        return o;    }}

2. boolean equals(Object obj)指示其他某个对象是否与此对象“相等”。

3. protected void finalize()当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。

C++析构函数和Java的finalize()方法不一样。前者是在对象消亡时运行,如果是自己new,即在堆中申请的内存,需要自己手动delete,所以析构函数中经常做一些文件保存之类的收尾工作;后者在Java中很不幸,如果内存总是充足的,那么垃圾回收可能永远不会进行,也就是说filalize()可能永远不被执行,显然指望它做收尾工作是靠不住的,它最主要的用途是回收特殊渠道申请的内存。Java程序有垃圾回收器,所以一般情况下内存问题不用程序员操心。但有一种JNI(Java Native Interface)调用non-Java程序(C或C++),finalize()的工作就是回收这部分的内存。

4. Class getClass() 返回此 Object 的运行时类。

5. int hashCode() 返回该对象的哈希码值。

6. void notify() 唤醒在此对象监视器上等待的单个线程。

7. void notifyAll() 唤醒在此对象监视器上等待的所有线程。

8. String toString() 返回该对象的字符串表示。

public String toString() {        return getClass().getName() + "@" + Integer.toHexString(hashCode());    }

9. void wait() 在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。

10. void wait(long timeout) 在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量前,导致当前线程等待。

11. void wait(long timeout, int nanos) 在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量前,导致当前线程等待。

//以纳秒为单位进行精确控制public final void wait(long timeout, int nanos) throws InterruptedException {        if (timeout < 0) {            throw new IllegalArgumentException("timeout value is negative");        }        if (nanos < 0 || nanos > 999999) {            throw new IllegalArgumentException(                                "nanosecond timeout value out of range");        }        if (nanos > 0) {            timeout++;        }        wait(timeout);    }

五、Java的四种引用,强软弱虚,用到的场景。

1.强引用

以前我们使用的大部分引用实际上都是强引用,这是使用最普遍的引用。如果一个对象具有强应用,那就类似必不可少的生活用品,垃圾回收器绝不会回收它。当内存空间不足,jvm宁愿跑出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。

2.软引用(SoftReference)

如果一个对象具有软引用,类似与生活可有可无的生活用品。如果内存足,GC就不会回收,如果不足,GC就会回收。软引用可以用来实现内存敏感的高速缓存。软引用可以和一个引用队列联合使用,如果软引用所引用的对象被GC回收,JVM就会把这个软引用加入到与之关联的引用队列中。

3.弱引用(WeakReference)

如果一个对象具有软引用,类似与生活可有可无的生活用品。与软引用的区别在于:只具有弱引用的对象拥有更短暂的生命周期。在GC线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存足够与否,都会回收它的内存。不过,由于GC是个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象。弱引用可以和一个引用队列联合使用,如果弱引用所引用的对象被GC回收,JVM就会把这个弱引用加入到与之关联的引用队列中。

4.虚引用(PhantomReference)

如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收。虚引用主要用来跟踪对象被垃圾回收的活动。虚引用与软引用以及弱引用的区别在于:虚引用必须和引用队列联合使用。当GC准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。程序可以通过判断引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。

package com.li;import java.lang.ref.SoftReference;//软引用实例代码public class Test4{    public static void main(String[] args)    {        A a = new A();        SoftReference<A> sr = new SoftReference<A>(a);        a = null;        if(sr != null)        {                a = sr.get();        }        else        {            a = new A();            sr = new SoftReference<A>(a);        }    }}class A{    int[] a ;    public A(){        a = new int[100000000];    }}

六、Hashcode的作用。

  • hashCode的存在主要是用于查找的快捷性,如Hashtable,HashMap等,hashCode是用来在散列存储结构中确定对象的存储地址的;
  • 如果两个对象相同,就是适用于equals(java.lang.Object) 方法,那么这两个对象的hashCode一定要相同;
  • 如果对象的equals方法被重写,那么对象的hashCode也尽量重写,并且产生hashCode使用的对象,一定要和equals方法中使用的一致,否则就会违反上面提到的第2点;
  • 两个对象的hashCode相同,并不一定表示两个对象就相同,也就是不一定适用于equals(java.lang.Object) 方法,只能够说明这两个对象在散列存储结构中,如Hashtable,他们“存放在同一个篮子里”。
  • 以下代码证明,先比较hash,如果hash相同比较equals。自己敲一遍,事半功倍。
package com.li;import java.util.HashMap;import java.util.HashSet;import java.util.Set;public class Test6{    public static void main(String[] args)    {        Test6 a = new Test6();        a.SetI(1);        Test6 b = new Test6();        b.SetI(1);        Set<Test6> set = new HashSet<Test6>();        set.add(a);        System.out.println("----------");        set.add(b);        System.out.println("----------");        System.out.println(set.toString());//默认调用toString方法,toString()源码调用了hashCode()        /*输出        hashcode        ----------        hashcode        equlas        ----------        hashcode        [com.li.Test6@1]        */    }    public int i;    public int getI()    {        return i;    }     public void SetI(int i)    {        this.i = i;    }    public int hashCode()    {        System.out.println("hashcode");        return i%10;       }    public boolean equals(Object object) {          System.out.println("equlas");        if (object == null) {              return false;          }          if (object == this) {              return true;          }          if (!(object instanceof Test6)) {              return false;          }          Test6 other = (Test6) object;          if (other.getI() == this.getI()) {              return true;          }          return false;      }}

七、ArrayList、LinkedList、Vector的区别。

1.ArrayList

以下代码来自1.8Jdk的ArrayList.java源码

    /**     * Default initial capacity.     * 默认数组初始容量大小为10     */    private static final int DEFAULT_CAPACITY = 10;    /**     * The size of the ArrayList (the number of elements it contains).     * 数组里面实际元素的个数     * @serial     */    private int size;    /**     * 最大容量     * The maximum size of array to allocate.     * Some VMs reserve some header words in an array.     * Attempts to allocate larger arrays may result in     * OutOfMemoryError: Requested array size exceeds VM limit     */    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;    /**    * 记录操作次数,快速失败机制,在迭代器中使用,remove抛出异常    */    protected transient int modCount = 0;    public boolean add(E e) {        ensureCapacityInternal(size + 1);  // Increments modCount!!增加一个        elementData[size++] = e;        return true;    }    private void ensureCapacityInternal(int minCapacity) {        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);        }        ensureExplicitCapacity(minCapacity);    }    private void ensureExplicitCapacity(int minCapacity) {        modCount++;        // overflow-conscious code        if (minCapacity - elementData.length > 0)            grow(minCapacity);    }    /**    * 实现自增的核心代码,1.5倍递增    */    private void grow(int minCapacity) {        // overflow-conscious code        int oldCapacity = elementData.length;        int newCapacity = oldCapacity + (oldCapacity >> 1);        if (newCapacity - minCapacity < 0)            newCapacity = minCapacity;        if (newCapacity - MAX_ARRAY_SIZE > 0)            newCapacity = hugeCapacity(minCapacity);        // minCapacity is usually close to size, so this is a win:        elementData = Arrays.copyOf(elementData, newCapacity);    }

2.Vector

以下代码来自1.8Jdk的Vector.java源码

    /**    * 实现自增的核心代码,2.0倍递增    */    private void grow(int minCapacity) {        // overflow-conscious code        int oldCapacity = elementData.length;        int newCapacity = oldCapacity + ((capacityIncrement > 0) ?                                         capacityIncrement : oldCapacity);        if (newCapacity - minCapacity < 0)            newCapacity = minCapacity;        if (newCapacity - MAX_ARRAY_SIZE > 0)            newCapacity = hugeCapacity(minCapacity);        elementData = Arrays.copyOf(elementData, newCapacity);    }    /**    * 主要区别,使用了synchronized修饰,线程安全    */    public synchronized boolean add(E e) {        modCount++;        ensureCapacityHelper(elementCount + 1);        elementData[elementCount++] = e;        return true;    }

3.LinkedList

以下代码来自1.8Jdk的LinkedList.java源码

    /**    * 私有内部类。用于链表操作    */    private static class Node<E> {        E item;        Node<E> next;        Node<E> prev;        Node(Node<E> prev, E element, Node<E> next) {            this.item = element;            this.next = next;            this.prev = prev;        }    }

总:
时间复杂度:ArrayList、Vector都为动态数组,LinkedList为链表。前者适合查找,后者适合修改删除。
空间复杂度:ArrayList开辟1.5倍、Vector开辟2.0倍,LinkedList每增加一个多一个内部类对象。前两者可以使用trimToSize()方法将多余的空间删除。
线程安全性:ArrayList、LinkedList不安全,但是可以自己实现线程安全。Vector线程安全。

八、String、StringBuffer与StringBuilder的区别。

String使用+""会创建一个新的对象,StringBuffer是线程安全的,使用append在一个对象进行修改,StringBuilder是1.5之后出现的,和StringBuffer基本一样,只是它不是线程安全的。

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

十、HashMap和HashTable的区别。

  • 前者是线程非安全的,并能传递null作为键值对。内部维护了一个链表,通过数组和链表进行存储
  • 后者是线程安全的,不能传递null作为键值对。
  • 参考:http://www.importnew.com/7099.html

十一、HashMap和ConcurrentHashMap的区别,HashMap的底层源码。

以下是Jdk1.8的HashMap.java源码

    /**默认大小16     * The default initial capacity - MUST be a power of two.     */    static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16    /**最大容量 <= 1<<30     * The maximum capacity, used if a higher value is implicitly specified     * by either of the constructors with arguments.     * MUST be a power of two <= 1<<30.     */    static final int MAXIMUM_CAPACITY = 1 << 30;    /**默认装载因子     * The load factor used when none specified in constructor.     */    static final float DEFAULT_LOAD_FACTOR = 0.75f;

十二、 TreeMap、HashMap、LindedHashMap的区别。

十三、Collection包结构,与Collections的区别。

十四、try catch finally,try里有return,finally还执行么?

public class HelloJ {    public static void  main(String[] args)    {        int i = g();        System.out.println(i);        /*输出          ---          1        */    }    static int g(){        int i = 0;        try{            return i++;        }catch (Exception e){            e.printStackTrace();        }finally {            System.out.println("---");            return i++;        }    }}

十五、Excption与Error包结构。OOM你遇到过哪些情况,SOF你遇到过哪些情况。

参考:http://www.mamicode.com/info-detail-1091344.html
这里写图片描述

十六、Java面向对象的三个特征与含义。

0 0
原创粉丝点击