Android校招复习全书(1)-j2se
来源:互联网 发布:维启网络 编辑:程序博客网 时间:2024/06/04 22:36
一、九种基本数据类型的大小,以及他们的封装类
关于JAVA基本数据类型
操作系统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面向对象的三个特征与含义。
- Android校招复习全书(1)-j2se
- Android校招复习全书(2)-Android
- Android校招准备复习干货
- J2SE复习
- Android校招笔试-1
- J2SE基础复习提纲
- J2SE复习笔记
- J2SE复习之接口
- J2SE复习之异常
- 校招算法复习之冒泡排序
- 校招复习之快速排序
- 校招面试知识点复习之计算机网络
- 校招面试知识点复习之计算机网络
- 校招面试知识点复习之计算机网络
- 校招面试知识点复习之计算机网络
- J2SE 上部分教程复习整理 NO.1
- J2SE习题(1)
- 续修四库全书1
- 使用regexpr()gregexpr()和函数读取字符串内的特定字符串
- 裸奔之MMU
- zoj1241
- Java语言基础1——基本数据类型
- 解决DreamWeaver代码视图中文不能精确选中的问题
- Android校招复习全书(1)-j2se
- [阿里笔试]有8只球队,采用抽签的方式随机配对,组成4场比赛。假设其中有4只强队,那么出现强强对话 (任意两只强队相遇)的概率是?
- 性能优化注意点
- uva1347 tour
- Mac 开机后黑屏
- python中的那些“神器”
- 北旅
- 微信语音
- C++调用c# dll