C++ 和java 关键字

C++ 关键字
1.引用 &  是伪装指针 引用只能初始化一次
void类型不能引用
数组不能引用
引用没有指针
NULL不能引用
类型不能引用
2.namespace #include <iostream>
using namespace std;
void main(void)
{ cout<<“hello,world!”<<endl; }
没写namespace,则要std::cout, std::endl
3.c++ 程序里必须要有一个main函数
4. 重载与覆盖(重写) 成员函数
被重载的特征: (1)相同的范围(在同一个类中);
(2)函数名字相同;
(3)参数不同;
(4)virtual关键字可有可无。
覆盖是指派生类函数覆盖基类函数,特征是: (1)不同的范围(分别位于派生类与基类);
(2)函数名字相同;
(3)参数相同;
(4)基类函数必须有virtual关键字。
令人迷惑的隐藏规则 (1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual 关键字,基类的函数将被隐藏(注意别与重载混淆)。
(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual 关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)
5.静态绑定- 编译时多态 动态绑定- 运行时多态
6.函数重载的关键是参数列表- 即function signature不同,在编译期时就可以确定该调用那个函数。 重载也是静态绑定- 编译时多态。
7.虚函数的引入:为了实现动态绑定。关键字virtual。虚函数有声明,也有定义。
8.在派生类里重新定义基类函数叫做覆盖。通常应该将基类方法声明为virtual(只在声明时写,定义不用)。 而且一旦基类里方法声明为虚拟virtual后,派生类里自动成为虚函数。
9.由于C++里函数覆盖的缘故,有2种方式确定调用函数该使用那个: 静态绑定:
指针类型在编译是确定的,
如果基类里被覆盖的函数没有virtual关键字, 则在编译期是就根据指针类型确定函数调用该使用那个函数, 即对非虚方法编译器使用静态绑定。
动态绑定:
如果基类里被覆盖的函数有virtual关键字, 则在运行期根据指针指向的对象类型确定函数调用该使用那个函数, 即对虚方法编译器使用动态绑定。
10.避免派生类对基类函数的隐藏
11.如果基类析构函数不是virtual的,则释放时调用指针对应类型的析构函数(可能派生类的某些析构操作被忽略)。 所以基类声明虚析构函数,是为了确保释放派生类对象时, 按正确顺序调用析构函数,因为是动态绑定会调用相应对象类型的析构函数。
纯虚析构函数:定义抽象类却没有其他方法时,可以把析构函数搞成纯虚的,但定义仍要写。 因为会先调用派生类的析构函数,再调用基类的析构函数。
12.纯虚函数和抽象类 纯虚函数(只有声明,没有定义): virtual void main(void) = 0; 抽象类是指不能被实例化的类,包含一个或多个纯虚函数的类叫抽象类。
13.动态绑定的额外处理开销和虚函数表vtbl。 给对象添加一个隐藏成员,保存一个指向虚函数表的指针。

Java 关键字:
1. super()与this()的区别?
This():当前类的对象,super父类对象。
Super():在子类访问父类的成员和行为,必须受类继承规则的约束
而this他代表当前对象,当然所有的资源都可以访问.
在构造函数中,如果第一行没有写super(),编译器会自动插入.但是如果父类没有不带参数的构造函数,或这个函数被私有化了(用private修饰).此时你必须加入对父类的实例化构造.而this就没有这个要求,因为它本身就进行实例化的构造.
而在方法中super和this使用的方法就差不多了.只不过super 要考虑是否能访问其父类的资源.

  1. 作用域public,protected,private,以及不写时的区别?
    ? Public:不同包、同一包、类内都可用
    ? Private:类内
    ? Protected: 不同包的子类、同一包、类内都可用
    ? 不写时:同一包内、类内
  2. JAVA的事件委托机制和垃圾回收机制
    java 事件委托机制的概念,一个源产生一个事件并将它送到一个或多个监听器那里。在这种方案中,监听器简单的等待,直到它收到一个事件。一旦事件被接受,监听器将处理这个事件,然后返回。
    垃圾回收机制 垃圾收集是将分配给对象但不再使用的内存回收或释放的过程。如果一个对象没有指向它的引用或者其赋值为null,则此对象适合进行垃圾回收。
  3. 在JAVA中,如何跳出当前的多重嵌套循环?
    用break; return 方法。
  4. 什么是java序列化,如何实现java序列化?(写一个实例)
    序列化:
    处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操作时所引发的问题。
    序列化的实现:
    将 需要被序列化的类实现Serializable接口,该接口没有需要实现的方法,implements Serializable只是为了标注该对象是可被序列化的,然后使用一个输出流(如:FileOutputStream)来构造一个 ObjectOutputStream(对象流)对象,接着,使用ObjectOutputStream对象的writeObject(Object obj)方法就可以将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。
  5. 一个”.java”源文件中是否可以包括多个类(不是内部类)?有什么限制?
    可以。如果这个类的修饰符是public,其类名与文件名必须相同。
  6. 重载(没有关键字)和重写(Override)的区别。重载的方法是否可以改变返回值的类型?
    方法的
    重写Override,子类覆盖父类的方法,将子类传与父类的引用调用的还是子类的方法。
    注意和C++里面的重写Override有点区别(动态绑定),见p.4
    重载是指一个类里面的多个方法,函数名称相同,参数个数类型不同,返回值的类型也可以不同。
    两者都是Java多态性的不同表现。
    重载的方法是可以改变返回值的类型。
  7. Final有什么特点?
    final 做为一个独立的存在,也表现的与众不同。一般情况都可以理解为 can’t be changed.
    1)final data: 实现constant语义。说明这个值:在编译时不会变;在运行时也不能被改变。
    在java中,提供了blank final:允许大家将初始化的动作延迟到constructor中。这是极限,有编译器保证。
    2)final parameter: 同上语义。
    3)final method:
    a)防止子类重写.(注:这个角度,private 隐含了final语义) b)代码效率: 允许编译器转换调用为inline call.
    4)final class: 拒绝继承
  8. 继承基类的子类的构造执行顺序一般都是什么?
    类的static 代码段,可以看作是类首次加载(被虚拟机加载)执行的代码,所以对于类的加载,执行顺序是基类的static代码段-》本身的static代码段-》基类的构造-》本身的构造。
  9. Static有什么特点?
    我们不能定义一个 public修饰的并且其类名和与文件名相同的类=top-level class 为static.
    public static class Outest { // 会出现编译错误,
    …;
    }
    但是可以修饰内部类,即嵌套类。
    1)static import (static import …)
    single-static-import declaration: import static TypeName.Identifier 静态引用包使得访问标识得以简化。(简单,无二义)
    J2SE 5.0新特性之static import,主要方便开发人员创建和使用全局的常量以及静态的方法。
    在《effective java》中作者曾经谈到在接口中定义常量是很糟糕的一种使用方法,我们应该始终使用接口来定义类型。但是在实际开发工作中还是有很多人这样使用接口,他们这样做的原因是这样定义常量使用起来很方便。
    如果你想在自己的类中使用这些接口中定义的常量的时候,那么你必须要实现这些接口。
    这样这些常量就变成你的类的一部分了,如果这个类不是final的话,其它的类继承了这个类又使得它继承了这些常量,但是这也许不是用户需要的结果。
    针对这样的情况,我们可以这样曲线救国,那就是在一个类中定义这些常量,使用的时候可以通过ClassName.variableName来访问他们。
    最后,现在J2SE 5.0提供了静态导入的功能,你只需要在import关键字后面写一个static关键字就可以直接使用类中定义的常量了,例如:import static staticEx.IrrationalConstants.SQRT_TWO;
    当然你也可以使用.*的格式,例如:import static staticEx.IrrationalConstants.*;的格式
    PS:注意对常量定义是如此,对静态方法的使用也适用。
    2) static initializer: (static {}):
    完成一段初始化操作.常见用法:类的static 代码段,可以看作是类首次加载(被虚拟机加载)执行的代码,所以对于类的加载,执行顺序是基类的static代码段-》本身的static代码段-》基类的构造-》本身的构造。
    3) static 变量或对象:
    4) static 方法:
    5)static 内部类.( member class & member interface:
    此处放在 nested class嵌套类 部分讲解)

11.抽象类和接口的区别?
抽象类关键字abstract,接口关键字interface。
c++的概念是抽象类里面有一个或多个函数只有声明,没有第一。接口里面所有函数都只有声明,没有定义。

但是java里面只要有一个或一个以上抽象方法的类,必须用abstract声明为抽象类; 但是抽象类里面也可以没有任何抽象方法,就是说明这个类不可以被显式实例化 ,可以没有抽象方法! 那样的抽象类通常只是一个模板。通常我们看到抽象类中的有些方法是 protected 类型。如果你需要实现子类,一般都要重写这些 protected  方法,根据“抽象类中的抽象方法必须被其子类全部实现”这一规则,可知:假如一个抽象类中没有抽象方法,那继承该抽象类的子类就不用全部override 此抽象类里的方法,也可以直接使用其中的方法。
我想,之所以把一个类声明为abstract,是因为想通过这个简单的声明方式使这个被声明的类不能被实例化,也就是说使任何人都不能在这个抽象类上使用new来实例化对象。我觉得这个是abstract作用在类上的一个非常基本的效果。

(1)接口可以被多重implements,抽象类只能被单一extends
(2)接口只有定义,抽象类可以有定义和实现
(3)接口的字段定义默认为:public static final, 抽象类字段默认是”friendly”(本包可见)
当功能需要累积时用抽象类,不需要累积时用接口。

12.什么是类的返射机制?
1)通过类(Class对象),可以得出当前类的fields、method、construtor、 interface、superClass、modified等,同时可以通过类实例化一个实例、设置属性、唤醒方法。Spring中一切都是返射、 struts、hibernate都是通过类的返射进行开发的。
2)类的返射机制中的包及核心类有:
? java.lang.Class
? java.lang.refrection.Method
? java.lang.refrection.Field
? java.lang.refrection.Constructor
? java.lang.refrection.Modifier
? java.lang.refrection.Interface
3)得到Class的三个过程是什么:
对象.getClass()
类.class或Integer.type(int)  Integer.class(java.lang.Integer)
Class.forName();
4)如何唤起类中的一个方法:
产生一个Class数组,说明方法的参数
通过Class对象及方法参数得到Method
通过method.invoke(实例,参数值数组)唤醒方法

13.java中实现多态的机制是什么?
静态的多态:在同一个类中方法名相同,参数个数或类型不相同。(这叫做重载Override)
动态的多态:
子类覆盖父类的方法,将子类的实例传与父类的引用,该引用调用的实际是子类的方法。
子类是实现接口,将子类的实例传与接口的引用,该引用调用的子类的方法。

14、垃圾回收器的基本原理是什么?垃圾回收器可以马上回收内存吗?有什么办法主动通知虚拟机进行垃圾回收?
1)动态内存里面存放类实例,静态内存里面存放类本身。
2)垃圾收集主要针对的是动态内存,一般当内存不够用时会进行垃圾收集。
3)通过System.gc()手动收集,但不保证一定执行。

15.写clone()方法时,通常都有一行代码,是什么?
Clone 有缺省行为,super.clone();他负责产生正确大小的空间,并逐位复制。

16.JAVA语言如何进行异常处理,关键字:throws,throw,try,catch,finally分别代表什么意义?在try块中可以抛出异常吗?
Try:执行部分,产生异常
Catch:捕捉异常
Finally:不管有没有异常都执行
Throws:在方法声明处声明要抛出的异常,调用者必须对其进行处理。
Throw:抛出一个异常比如 Throw new Exception(“This is test to throw exception”);
在try中可以抛出异常,一般与声明的异常相同。
自定义异常要继承于Exception或Exception的子类。

17.String and StringBuffer的区别?
String:长度给定不可变,当多个字符串联合时要先转为StringBuffer,再联合,速度慢。
StringBuffer:长度可变,可以将多个字符串值直接联合,效率高.

18.集合是什么?
Map没有继承于Collection,其相对是独立的。
Collection 和 Collections的区别。
Collection.java是所有集合的根类,她是一个Interface接口。
Collections是集合的算法和工具函数集。比如对一个集合排序Collections.sort(List<T> list)。
Collection是集合的根接口,其下面的子类(依然是接口Interface)有Set及List。

常用可以生产对象的集合类有:
ArrayList是List的子类。
Vector是List的子类。
LinkedList是List的子类。
SortedSet是Set的子类。
SortedMap是Map的子类。
HashMap是Map的子类。
Hashtable是Map的子类。

集合里面元素能不能重复??????????????????????

有序否(指能否用index访问) 允许元素重复否
Collection
List
Set AbstractSet
HashSet
TreeSet 是(用二叉树排序)
Map

(键/值对数组)

AbstractMap 使用key-value来映射和存储数据,Key必须惟一,value可以重复
HashMap
TreeMap 是(用二叉树排序)

http://hi.baidu.com/linkage121/blog/item/5093f5d10fd8e487a1ec9cfe.html
1)集合用于数据的传送 增加、删除、修改、查讯、判断包含constainsAll(?)和constains(?),可以存放不同类型的对象。
2)集合的通用方法有那些?(操作)
a).最基础的根接口Collection 的通用方法有:
(1).获取该Collection的迭代器:mCollection.iterator();

比如

private static List hashMapKey2SortedList(Map map){
List list = new ArrayList();
Iterator iterator=map.keySet().iterator();
while(iterator.hasNext()){                         //如果Collection里面至少有一个元素就返回true
String key=(String)iterator.next();        //返回Collection里面下个元素
Object obj=map.get(key);
if(obj instanceof Map){
list.add(key);
} else {

iterator.remove();//删除上次iterator.next()对应的元素,必须只能在iterator.next()之后调用。

}
}
}

(2).判断该Collection是否包含某个元素:mCollection.contails(Object o);
(3).判断该Collection是否包含另一个Collection里面所有元素:mCollection.contailsAll(Collection<?> o);
(4).判断和另一个Collection是否相等:mCollection1.equals(Object mCollection2);
(5).返回该Collection的hashCode:mCollection.hashCode();
(6).获取该Collection的里面元素的数量:mCollection.size();
(7).判断该Collection是否为空:mCollection.isEmpty();
(8).清除Collection里面的元素:mCollection.clear();
(9).以数组形式返回该Collection里面所有元素:mCollection.toArray();
(10).给定数组地址,以数组形式返回该Collection里面所有元素:mCollection.toArray(T[] array);
如果给定数组不足装下所有元素,则行为和toArray()一样自动创建一个数组,此时给定数组地址不会使用到。
(11).从该Collection里面删除一个元素:mCollection.remove(Object o);
(12).从该Collection里面删除所有和另一个Collection里面相同的元素:mCollection.removeAll(Collection<?> o);
(13).从该Collection里面删除所有和另一个Collection里面不相同的元素:mCollection.retainAll(Collection<?> o);
(14).向该Collection里面添加一个元素:mCollection.add(Object o);
(15).向该Collection里面添加另一个Collection里面所有的元素:mCollection.addAll(Collection<?> o);

b).次一级接口集合List 的通用方法有:
(1).向该List里面指定位置添加一个元素:mList.add(int i, Object o);
原来指定位置的元素及后面所有元素都向后移一位。
(2).获取指定位置的元素:mList.get(int i);
(3).搜索指定元素在List集合里面第一次出现的位置:mList.indexOf(Object o);
(4).搜索指定元素在List集合里面最后一次出现的位置:mList.lastIndexOf(Object o);
(5).返回双向迭代器:mList.listIterator();
比如
ListIterator<TYPE> li = mList.listIterator();
while (li.hasNext()) {//如果List里面有下一个元素就返回true
TYPE i = li.next();//返回List里面下个元素
}
while (li.hasPrevious()){//如果List里面有上一个元素就返回true
TYPE i = li.previous();//返回List里面上个元素
}
li.add(Object o); //向List的next()和previous()之间插入一个元素,插入的元素位置在新的previous()
li.nextIndex();  //返回下一个元素位置
li.previousIndex(); //返回上一个元素位置
li.remove();  //删除上次next()或previous()对应的元素。
li.set(Object o); //替换上次next()或previous()对应的元素。
(6).返回双向迭代器:mList.listIterator(int i);
迭代器位置在int i上。
(7).从该List指定位置删除一个元素:mList.remove(int i);
(8).从该List指定位置替换一个元素:mList.set(int i,Object o);
(9).从原List指定范围创建一个新的List集合:mList.subList(int start, int end);
c).次一级接口集合Set 的通用方法有:
。。。。。
d).最基础的根接口Map 的方法有:
(1).Map集合里面的键值对的数据结构:Map.Entry<K, V>
(2).判断包含某个键:mMap1.containsKey(Object key);
(3).判断包含某个值:mMap1.containsKey(Object value);
(4).判断和另一个Map是否相等:mMap1.equals(Object o);
(5).返回该Map的hashCode:mMap.hashCode();
(6).获取该Map的里面键值对的数量:mMap.size();
(7).判断该Map是否为空:mMap.isEmpty();
(8).以Set集合形式返回,获取该Map的键的集合:mMap.keySet();
(9).以Collection集合形式返回,获取该Map的值的集合:mMap.values();
(10).向该Map里面复制另一个Map的所有元素:mMap1.putAll(mMap2);
(11).从该Map里面删除一对键值:mMap.remove(Object key);
(12).向该Map里面添加一对键值:mMap.put(K key, V value);
(13).返回Map里面对应某个键的值:mMap.get(Object key);
(14).清除Map里面的元素:mMap.clear();
e).次一级实际集合HashMap 的方法有:
(1).创建HashMap<Integer, String> testHashMap = new HashMap<Integer, String>();
(2).往HashMap里面添加一对键值:
Integer i = new Integer(1);
String s = “hello”;
testHashMap.put(i, s);
(3).获取HashMap的大小:int length = testHashMap.size();
(4).获取HashMap里面的键值对:以Set<Entry<K, V>>集合形式返回,该HashMap里面的所有键值对。
for(Map.Entry<Integer, String> ent : testHashMap.entrySet()) {//以Set<Entry<K, V>>集合形式返回,该HashMap里面的所有键值对。
Integer i = ent.getKey();
String s = ent.getValue();
}
f).次一级实际集合HashMap 的方法有:
。。。。。。

3)说出ArrayList,Vector, LinkedList的存储性能和特性HashMap和Hashtable的区别
ArrayList Vector:以数组的方式存储,增、删慢,查、改快
ArrayList:线程不安全,速度快
Vector:线程安全,速度慢(synchoronized)
LikedList: 以单链表的方式存储,增、删快,查、改慢
HashMap与Hashtable都实现的Map接口,
HashTable线程安全,
HashMap线程不安全。

HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable。
HashMap允许将null作为一个entry的key或者value,而Hashtable不允许。
HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因为contains方法容易让人引起误解。
Hashtable继承自Dictionary类,而HashMap是Java1.2引进的Map interface的一个实现。
最 大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多个线程访问Hashtable时,不需要自己为它的方法实 现同步,而HashMap 就必须为之提供外同步(如果是ArrayList:List lst = Collections.synchronizedList(new ArrayList());如果是HashMap:Map map = Collections.synchronizedMap(new HashMap());)。
Hashtable和HashMap采用的hash/rehash算法都大概一样,所以性能不会有很大的差异。
4)Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别?用contains来区分是否有重复的对象。
在比较时先调用hashCode方法,如果不相同,证明不相等。
如果相同,再调用equals方法,如果equals方法相同,证明相等,不相同,证明不相等。
==:主要用在基本数据类型及引用,不能比较对象。
Equals:主要是对象或对象引用的比较。
集合中是否包含某一个元素用contains来判断,不能比较对象。
5)List, Set, Map是否继承自Collection接口?
List,set继承于Collection。
属于Collection接口的子类的对象,可以通过构造函数将一个集合构造成另外一个集合。
Map没有继承于Collection,其相对是独立的。
19.String是最基本的数据类型吗?
基本数据类型包括byte、int、char、long、float、double、boolean和short。
java.lang.String类是final类型的,因此不可以继承这个类、不能修改这个类。为了提高效率节省空间,我们应该用StringBuffer类

20.int 和 Integer 有什么区别?
Int是基本数据类型,不是对象,占一个内存空间,没有方法。与其同类的有long,char,doble
Integer是封装类,具有方法及属性。与其同类的有Long,Double.Float

21.运行时异常与一般异常有何异同?
运行时异常:java JVM抛出的异常,代码中不用处理。
一般异常:用户抛出的异常,如果用throws 声明了,调用这个方法的代码必须对其处理。

22.&和&&的区别?
&:与: 左边若为false右边还执行。
&&:短路与,左边若为false右边不执行。

23.final, finally, finalize的区别?
final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
finally是异常处理语句结构的一部分,表示总是执行。
finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。

24、堆(heap)和堆栈(stack)有什么区别
一、)预备知识—程序的内存分配
一个由c/C++编译的程序占用的内存分为以下几个部分
1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。
3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 – 程序结束后有系统释放
4、文字常量区 —常量字符串就是放在这里的。 程序结束后由系统释放
5、程序代码区—存放函数体的二进制代码。
例子程序 :
这是一个前辈写的,非常详细
//main.cpp
int a = 0; 全局初始化区
char *p1; 全局未初始化区
main()
{
int b; 栈
char s[] = “abc”; 栈
char *p2; 栈
char *p3 = “123456”; 123456\0在常量区,p3在栈上。
static int c =0; 全局(静态)初始化区
p1 = (char *)malloc(10);
p2 = (char *)malloc(20);
分配得来得10和20字节的区域就在堆区。
strcpy(p1, “123456”); 123456\0放在常量区,编译器可能会将它与p3所指向的”123456″优化成一个地方。
}
二、)堆和栈的理论知识
2.1)申请方式
stack:
由系统自动分配。 例如,声明在函数中一个局部变量 int b; 系统自动在栈中为b开辟空间
heap:
需要程序员自己申请,并指明大小,在c中malloc函数
如p1 = (char *)malloc(10);
在C++中用new运算符
如p2 = (char *)new char[10];
但是注意p1、p2本身是在栈中的。
2.2)
申请后系统的响应
栈:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。
堆:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,
会 遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内 存空间中的首地址处记录本次分配的大小,这样,代码中的delete语句才能正确的释放本内存空间。另外,由于找到的堆结点的大小不一定正好等于申请的大 小,系统会自动的将多余的那部分重新放入空闲链表中。
2.3)申请大小的限制
栈:在Windows下,栈是向低地址扩展的数据结构, 是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在 WINDOWS下,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因 此,能从栈获得的空间较小。
堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。
2.4)申请效率的比较:
栈由系统自动分配,速度较快。但程序员是无法控制的。
堆是由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便.
另外,在WINDOWS下,最好的方式是用VirtualAlloc分配内存,他不是在堆,也不是在栈是直接在进程的地址空间中保留一快内存,虽然用起来最不方便。但是速度快,也最灵活
2.5)堆和栈中的存储内容
栈: 在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量。注意静态变量是不入栈的。
当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。
堆:一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容有程序员安排。

2.6)堆和栈的区别主要分:
操作系统方面的堆和栈,如上面说的那些,不多说了。
还有就是数据结构方面的堆和栈,这些都是不同的概念。这里的堆实际上指的就是(满足堆性质的)优先队列的一种数据结构,第1个元素有最高的优先权;栈实际上就是满足先进后出的性质的数学或数据结构。
虽然堆栈,堆栈的说法是连起来叫,但是他们还是有很大区别的,连着叫只是由于历史的原因。

25.描述一下JVM加载class文件的原理机制?
JVM中类的装载是由ClassLoader和它的子类来实现的,Java ClassLoader 是一个重要的Java运行时系统组件。它负责在运行时查找和装入类文件的类。类的static 代码段,可以看作是类首次加载(被虚拟机加载)执行的代码,所以对于类的加载,执行顺序是基类的static代码段-》本身的static代码段-》基类 的构造-》本身的构造。

 

26.接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承实体类(concrete class)?
接口可以继承接口。抽象类可以实现(implements)接口,抽象类可以继承实体类,但前提是实体类必须有明确的构造函数。任何抽象类都是实际类Object.java(java所有对象的根类)的子类。
一个类,有方法,有属性,而且表示一个实体(比如:动物,植物,人等世界万物) 这就是实体类。 区别与工具类等。

27.abstract的method(抽象函数)是否可同时是static,是否可同时是native,是否可同时是synchronized?
都不能。

28.java里面的关键字,抽象abstract,接口Interface,静态static,常量final
1).抽象类:abstract
1,只要有一个或一个以上抽象方法的类,必须用abstract声明为抽象类; 但是抽象类里面也可以没有任何抽象方法。就是说明这个类不可以被显式实例化 ,可以没有抽象方法! 那样的抽象类通常只是一个模板。通常我们看到抽象类中的有些方法是 protected 类型。如果你需要实现子类,一般都要重写这些 protected  方法,根据“抽象类中的抽象方法必须被其子类全部实现”这一规则,可知:假如一个抽象类中没有抽象方法,那继承该抽象类的子类就不用全部override 此抽象类里的方法,也可以直接使用其中的方法。
我想,之所以把一个类声明为abstract,是因为想通过这个简单的声明方式使这个被声明的类不能被实例化,也就是说使任何人都不能在这个抽象类上使用new来实例化对象。我觉得这个是abstract作用在类上的一个非常基本的效果。
2,抽象类中可以有具体的实现方法;
3,抽象类中可以没有抽象方法;
4,抽象类中的抽象方法必须被它的子类实现,如果子类没有实现,则该子类继续为抽象类
5,抽象类不能被实例化,但可以由抽象父类指向的子类实例来调用抽象父类中的具体实现方法;通常作为一种默认行为;
6,要使用抽象类中的方法,必须有一个子类继承于这个抽象类,并实现抽象类中的抽象方法,通过子类的实例去调用;
2).接口:interface
1,接口中可以有成员变量,且接口中的成员变量必须定义初始化;
2,接口中的成员方法只能是方法原型,不能有方法主体;
3,接口的成员变量和成员方法只能public(或缺省不写),效果一样,都是public
4,实现接口的类必须全部实现接口中的方法(父类的实现也算,一般有通过基类实现接口中个异性不大的方法来做为适配器的做法)
3).关键字:final
1,可用于修饰:成员变量,非抽象类(不能与abstract同时出现),非抽象的成员方法,以及方法参数
2,final方法:不能被子类的方法重写,但可以被继承;
3,final类:表示该类不能被继承,没有子类;final类中的方法也无法被继承.
4,final变量:表示常量,只能赋值一次,赋值后不能被修改.final变量必须定义初始化;
5,final不能用于修饰构造方法;
6,final参数:只能使用该参数,不能修改该参数的值;
4).关键字:static
1,可以修饰成员变量和成员方法,但不能修饰类以及构造方法;
2,被static修饰的成员变量和成员方法独立于该类的任何对象。也就是说,它不依赖类特定的实例,被类的所有实例共享
3,static变量和static方法一般是通过类名直接访问,但也可以通过类的实例来访问(不推荐这种访问方式)
4,static变量和static方法同样适应java访问修饰符.用public修饰的static变量和static方法,在任何地方都可以通过类 名直接来访问,但用private修饰的static变量和static方法,只能在声明的本类方法及静态块中访问,但不能用this访问,因为this 属于非静态变量.

5).static和final同时使用
1,static final用来修饰成员变量和成员方法,可简单理解为“全局常量”!
2,对于变量,表示一旦给值就不可修改,并且通过类名可以访问。
3,对于方法,表示不可覆盖,并且可以通过类名直接访问。

29.数组有没有length()这个方法? String有没有length()这个方法?
String有length()这个方法.
数组没有length()这个方法,但是有length这个属性,可以直接获取。
声明数组时不能指定其长度(数组中元素的个数),Java中使用关键字new创建数组对象,格式为: 数组元素的类型[] 数组名 = new 数组元素的类型 [数组元素的个数];
例程:
int[] s = new int[10];
int l = s.length;//得到l==10
String[] ps = new String[]{“tom”,”luck”,”bruce”};
int j = ps.length;//得到j==3

30.构造器Constructor是否可被继承重写?
构造器Constructor不能被继承,因此不能重写,但可以被重载Override。

31.是否可以继承String类?
String类是final类故不可以继承。

32.swtich是否能作用在byte上,是否能作用在long上,是否能作用在String上?
switch(expr1)中,expr1是一个整数表达式。因此传递给 switch 和 case 语句的参数应该是 int、 short、 char 或者 byte。long,string 都不能作用于swtich。

33.try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后?
会执行,在return前执行。

34.编程题: 用最有效率的方法算出2乘以8等於几?
2 << 3

35.两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对?
不对,有相同的hash code。

36.当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?
是引用传递
基本数据类型:值传递
对象: 引用传递

37.编程题: 写一个Singleton出来。
Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。
一般Singleton模式通常有几种种形式:
第一种形式: 定义一个类,它的构造函数为private的,它有一个static的private的该类变量,在类初始化时实例话,通过一个public的getInstance方法获取对它的引用,继而调用其中的方法。
public class Singleton {
private Singleton(){}
//在自己内部定义自己一个实例,是不是很奇怪?
//注意这是private 只供内部调用
private static Singleton instance = new Singleton();//每次都进行生成对象?????????????????????
//这里提供了一个供外部访问本class的静态方法,可以直接访问
public static Singleton getInstance() {
return instance;   //每次都进行生成对象????????????
}
}
第二种形式:
public class Singleton {
private static Singleton instance = null;
public static synchronized Singleton getInstance() {
//这个方法比上面有所改进,不用每次都进行生成对象,只是第一次
//使用时生成实例,提高了效率!
if (instance==null)
instance=new Singleton();
return instance;   }
}
其他形式:
定义一个类,它的构造函数为private的,所有方法为static的。
一般认为第一种形式要更加安全些

38.Java中的异常处理机制的简单原理和应用。
原理: 有错直接转到异常处理部分或向上抛出。
应用: JAVA的异常就是错误,有两种,一种是运行时,编码可以不用捕捉。一种是一般异常,如果throws声明了,必须进行处理。

当JAVA程序违反了JAVA的语义规则时,JAVA虚拟机就会将发生的错误表示为一个异常。违反语义规则包括2种情况。一种是JAVA类库内 置的语义检查。例如数组下标越界,会引发IndexOutOfBoundsException;访问null的对象时会引发 NullPointerException。另一种情况就是JAVA允许程序员扩展这种语义检查,程序员可以创建自己的异常,并自由选择在何时用 throw关键字引发异常。所有的异常都是java.lang.Thowable的子类。

39.描述一下JVM加载class文件的原理机制?
JVM中类的装载是由ClassLoader和它的子类来实现的,Java ClassLoader 是一个重要的Java运行时系统组件。它负责在运行时查找和装入类文件的类。

40.char型变量中能不能存贮一个中文汉字?为什么?
能够定义成为一个中文的,因为java中以unicode编码,一个char占16个字节,所以放一个中文是没问题的

41.如何格式化日期?
Import java.text.SimpleDateFormat;
SimpleDateFormat sdf = new SimpleDateFormat(“yyyy-MM-dd hh:mm:ss”);//2011-06-24 14:10:29
“yyyy/mm/dd hh:mm:ss”//2011/06/24 14:10:29
Date dat = new Date();//获取当前时间
//把日期转化为字符串
String str = sdf.format(dat);
System.out.println(str);//2011-06-24 14:10:29
//将字符串转化为日期
SimpleDateFormat sdf = new SimpleDateFormat(“yyyy-MM-dd hh:mm:ss”);
Java.util.Date d1 = sdf.parse(“1970-1-1 0:0:35”);//格式要和前面的一致
System.out.println(dl);//dl==35000毫秒
42.编码转换,怎样实现将GB2312编码的字符串转换为ISO-8859-1编码的字符串。
写法一:
String a=new String(“中”.getBytes(“gb2312″),”iso-8859-1”);
写法二:
String.getBytes(String encoding)//把一个字符串按照指定的编码格式转换为字节流
String a=new String(“中”.getBytes(“iso-8859-1”));//接着上面的,按照指定的编码格式创建新的字符串

43.String s = new String(“xyz”);创建了几个String Object?
New了一个,”XYZ”本来又是一个
两个

44.float型float f = 3.4是否正确?
报错,应当是float f = 3.4f;
或者float f = (float)3.4;
如果是float f=3(整数)正确.

45.介绍JAVA中的Collection FrameWork(包括如何写自己的数据结构)?
答:Collection FrameWork如下:
Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set
Map
├Hashtable
├HashMap
└WeakHashMap
Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素(Elements)
Map提供key到value的映射

46、启动一个线程是用run()还是start()?
启动一个线程是调用start()方法,启动线程并调用run方法。

47、线程的基本概念、线程的基本状态以及状态之间的关系
线程是进程内的并发,没有自已内存空间,共享进程的,线程间的通信成本较低。
在Java 1.4及以下的版本中,每个线程都具有新建、可运行、阻塞、死亡四种状态,但是在
Java 5.0及以上版本中,线程的状态被扩充为新建、可运行、阻塞、等待、定时等待、死亡
六种。线程的状态完全包含了一个线程从新建到运行,最后到结束的整个生命周期。线程状
态的具体信息如下:
1). NEW(新建状态、初始化状态):线程对象已经被创建,但是还没有被启动时的状态。
这段时间就是在我们调用new命令之后,调用start()方法之前。
2). RUNNABLE(可运行状态、就绪状态):在我们调用了线程的start()方法之后线程所
处的状态。处于RUNNABLE状态的线程在JAVA虚拟机(JVM)上是运行着的,但是它可
能还正在等待操作系统分配给它相应的运行资源以得以运行。
3). BLOCKED(阻塞状态、被中断运行):线程正在等待其它的线程释放同步锁,以进
入一个同步块或者同步方法继续运行;或者它已经进入了某个同步块或同步方法,在运行的
过程中它调用了某个对象继承自java.lang.Object的wait()方法,正在等待重新返回这个同步
块或同步方法。
4). WAITING(等待状态):当前线程调用了java.lang.Object.wait()、
java.lang.Thread.join()或者java.util.concurrent.locks.LockSupport.park()三个中的任意一个方法,
正在等待另外一个线程执行某个操作。比如一个线程调用了某个对象的wait()方法,正在等
待其它线程调用这个对象的notify() 或者notifyAll()(这两个方法同样是继承自Object类)方
法来唤醒它;或者一个线程调用了另一个线程的join()(这个方法属于 Thread类)方法,正
在等待这个方法运行结束。
5). TIMED_WAITING(定时等待状态):当前线程调用了 java.lang.Object.wait(long
timeout)、java.lang.Thread.join(long
millis)、java.util.concurrent.locks.LockSupport.packNanos(long
nanos)、java.util.concurrent.locks.LockSupport.packUntil(long deadline)四个方法中的任意一个,
进入等待状态,但是与WAITING状态不同的是,它有一个最大等待时间,即使等待的条件
仍然没有满足,只要到了这个时间它就会自动醒来。
6). TERMINATED(死亡状态、终止状态):线程完成执行后的状态。线程执行完run()方
法中的全部代码,从该方法中退出,进入TERMINATED状态。还有一种情况是run()在运行
过程中抛出了一个异常,而这个异常没有被程序捕获,导致这个线程异常终止进入
TERMINATED状态。
在Java5.0及以上版本中,线程的全部六种状态都以枚举类型的形式定义在java.lang.Thread
类中了,代码如下:
Java代码
public enum State {
NEW,
RUNNABLE,
BLOCKED,
WAITING,
TIMED_WAITING,
TERMINATED;
}

48、多线程有几种实现方法,都是什么?同步有几种实现方法,都是什么? 用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用?
用synchoronized修饰同步方法。
答:多线程有两种实现方法,分别是继承Thread类与实现Runnable接口
线程实现方法一:Extends Thread
线程实现方法二:Implements Runnable

同步的实现方面有两种,分别是synchronized,wait与notify

wait():使一个线程处于等待状态,并且释放所持有的对象的lock。
sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉InterruptedException异常。调用sleep不会释放对象锁。
notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。
Allnotity():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争。
Public synchronized func()//func()同一时间只能被一个线程调用,其它线程需要等待。
{
。。。。。。
}

Public void func(object aa)
{
synchronized(aa)//这段代码同一时间只能被一个线程进入,其它线程需要等待。
{

}
}
反对使用stop(),是因为它不安全。它会解除由线程获取的所有锁定,而且如果对象处于一种不连贯状态,那么其 他线程能在那种状态下检查和修改它们。结果很难检查出真正的问题所在。suspend()方法容易发生死锁。调用suspend()的时候,目标线程会停 下来,但却仍然持有在这之前获得的锁定。此时,其他任何线程都不能访问锁定的资源,除非被”挂起”的线程恢复运行。对任何线程来说,如果它们想恢复目标线 程,同时又试图使用任何一个锁定的资源,就会造成死锁。所以不应该使用suspend(),而应在自己的Thread类中置入一个标志,指出线程应该活动 还是挂起。若标志指出线程应该挂起,便用wait()命其进入等待状态。若标志指出线程应当恢复,则用一个notify()重新启动线程。

49.集合框架有什么?
一).Collection
1).List
a).ArrayList
b).linkedList
2).set
a).HashSet
b).TreeSet
二).Map
1).HashMap
2).TreeMap
3).HashTable

50.设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少1。写出程序
class Inc implements Runnable//实现Runnable接口
{
private TestThread obj;
public Inc(TestThread obj)
{
this.obj=obj;
}
public void run()
{
//   for (int i = 0; i < 100; i++)
//   {
this.obj.inc();
//   }
}
}
class Dec implements Runnable//实现Runnable接口
{
private TestThread obj;
public Dec(TestThread obj)
{
this.obj=obj;
}
public void run()
{
//   for (int i = 0; i < 100; i++)
//   {
this.obj.dec();
//   }
}
}

public class TestThread
{
private int j;
public synchronized void inc()
{
j++;
System.out.println(Thread.currentThread().getName() + “-inc:” + j);
}
public synchronized void dec()
{
j–;
System.out.println(Thread.currentThread().getName() + “-dec:” + j);
}
public static void main(String[] args)
{
TestThread t=new TestThread();
for (int i = 0; i < 2; i++)
{
Thread inc=new Thread(new Inc(t));//实现Runnable接口
Thread dec=new Thread(new Dec(t));//实现Runnable接口
inc.start();
dec.start();
}
}
}

51.同步和异步有和异同,在什么情况下分别使用他们?举例说明。
同步:上一段代码没的完成,下一段必须等到上一段代码完成后才可以执行。如买票排队
异步:上一段代码没的完成,下一段不必等到上一段代码完成就可以执行。如手机发送短信。

52.sleep() 和 wait() 有什么区别?
Sleep是指休眠给定的时间,当这个时间达到之后,线程会再次醒来。
Wait是等待状态,多长时间不清楚,由另一个线程将其唤醒。
sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。
wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。

53.当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?
如过要进的其它方法是也是同步方法,不可以进入。如果不是则可以进入。

54.java中有几种类型的流?JDK为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类?
字节流,字符流。
字节流继承于InputStream, OutputStream。
字符流继承于Reader Writer。
在java.io包中还有许多其他的流,低层流与调层流,高层流主要是为了提高性能和使用方便。

55.输入输出流的理解:
在java使用流的机制进行数据的传送,从文件到内存是输入流,从内存到文件是输出流,输入流可以通过 read读取,输出流以write或print写入,对于流可以是分为高层流和低层流,低层以一个字节或字符为单位进行处理,高层流以一批数据为单位进行处理。
FileInputStream(System.in)至InputSteamReader至BufferReader
OutputSteam(System.out)至printStream
FileReader至BufferedReader
FileWriter 至 PrintWriter或bufferWriter
分类:
字节(二进制)
FileInputStream(低层输入流)
FileOutputStream(低层输出流)
PrintStream(高层流)  System.out.println()
字符(一个char)
FileReader
FileWriter

56.请写一个程序的读写,要求用两种方式一种是低层流另一种是高层流。
import java.io.FileWriter;
import java.io.InputStream;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.FileReader;

public class Untitled1 {
public static void writeFileChar() throws Exception {
FileWriter f = new FileWriter(“c:\\aa.txt”);
InputStream is = System.in;
int c = is.read();
while (((char) c) != ‘x’) {
f.write(c);
c = is.read();
}
f.close();
is.close();
}
public static void writeFileString() throws Exception {
FileWriter f = new FileWriter(“c:\\aa.txt”);
BufferedWriter bwr=new BufferedWriter(f);
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
String c = bf.readLine();
while (!c.equals(“stop”)) {
bwr.write(c+”\r\n”);
c = bf.readLine();
}
bwr.close();
f.close();
bf.close();
}

public static void readFileChar() throws Exception {
FileReader f = new FileReader(“c:\\aa.txt”);
int c = f.read();
while (c!=-1) {
System.out.print((char)c);
c=f.read();
}
f.close();
}
public static void readFileString() throws Exception {
BufferedReader bf = new BufferedReader(new FileReader(“c:\\aa.txt”));
String c = bf.readLine();
while (c!=null)
{
System.out.println(c);
c=bf.readLine();
}
bf.close();
}

public static void main(String[] args) throws Exception {
readFileString();
}
}

57.如何列出某个目录下的所有文件
Import java.io.File;
File f=new File(“C:\\”);
File[] f1=f.listFiles();
for(int i=0;i<f1.length;i++)
{
if(f1[i].isDirectory())
{
System.out.println(“dirctory is”+f1[i].getName());
}
else
{
System.out.println(“file is”+f1[i].getName());
}
}
}
58.如何列出某个目录下的所有子目录
public static void main(String[] args) throws Exception
{
getFile(new File(“C:\\entityBean”),”\t”);
}
public static void getFile(File f,String sem) throws Exception
{
System.out.println(sem+f.getName());
File fl[]=f.listFiles();
if(fl.length>=1)
{
for(int i=0;i<fl.length;i++)
{
if(fl[i].isDirectory())
{
getFile(fl[i],sem+”\t”);
}
}
}
}

59。判断一个文件或目录是否存在
File f=new File(“C:\\entityBean”);
if(f.exists())
{
System.out.println(“exist”);
}
else
{
System.out.println(“not exist”);
}

60.用socket通讯写出客户端和服务器端的通讯,要求客户发送数据后能够回显相同的数据?
public class ServerSocket_1
{
public static void main(String[] args)
throws Exception
{
ServerSocket ss = new ServerSocket(4001);
Socket s = ss.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(s.
getInputStream()));
PrintStream ps=new PrintStream(s.getOutputStream());
String temp = br.readLine();
while (true)
{
System.out.println(“客户端:”+temp);
ps.println(temp);
if (temp.equals(“stop”))
{
break;
}
temp = br.readLine();
}
br.close();
ps.close();
ss.close();
}
}
public class ClientSocket
{
public static void main(String[] args) throws Exception
{
Socket s = new Socket(“localhost”, 4001);
PrintStream ps = new PrintStream(s.getOutputStream());
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedReader br_server = new BufferedReader(new InputStreamReader(s.
getInputStream()));
String temp = br.readLine();
while (true)
{
ps.println(temp);
temp = br_server.readLine();
System.out.println(“服务器的信息:” + temp);
if (temp.equals(“stop”))
{
break;
}
temp = br.readLine();
}
s.close();
br.close();
br_server.close();
}
}
61.Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)
答:匿名的内部类是没有名字的内部类。不能extends(继承) 其它类,但一个内部类可以作为一个接口,由另一个内部类实现。
62.ArrayList和Vector的区别,HashMap和Hashtable的区别

就ArrayList与Vector主要从二方面来说.
一).同步性:Vector是线程安全的,也就是说是同步的,而ArrayList是线程序不安全的,不是同步的
二).数据增长:当需要增长时,Vector默认增长为原来一培,而ArrayList却是原来的一半
就HashMap与HashTable主要从三方面来说。
一).历史原因:Hashtable是基于陈旧的Dictionary类的,HashMap是Java 1.2引进的Map接口的一个实现
二).同步性:Hashtable是线程安全的,也就是说是同步的,而HashMap是线程序不安全的,不是同步的
三).值:只有HashMap可以让你将空值作为一个表的条目的key或value
63.STRING与STRINGBUFFER的区别。
答:STRING的长度是不可变的,STRINGBUFFER的长度是可变的。如果你对字符串中的内容经常进行操作,特别是内容要修改时,那么使用StringBuffer,如果最后需要String,那么使用StringBuffer的toString()方法

64.ArrayList和Vector的区别
答:
这两个类都实现了List接口(List接口继承了Collection接 口),他们都是有序集合,即存储在这两个集合中的元素的位置都是有顺序的,相当于一种动态的数组,我们以后可以按位置索引号取出某个元素,,并且其中的数 据是允许重复的,这是HashSet之类的集合的最大不同处,HashSet之类的集合不可以按索引号去检索其中的元素,也不允许有重复的元素(本来题目 问的与hashset没有任何关系,但为了说清楚ArrayList与Vector的功能,我们使用对比方式,更有利于说明问题)。

接着才说ArrayList与Vector的区别,这主要包括两个方面:.
(1)同步性:
Vector是线程安全的,也就是 说是它的方法之间是线程同步的,而ArrayList是线程序不安全的,它的方法之间是线程不同步的。如果只有一个线程会访问到集合,那最好是使用 ArrayList,因为它不考虑线程安全,效率会高些;如果有多个线程会访问到集合,那最好是使用Vector,因为不需要我们自己再去考虑和编写线程 安全的代码。

备注:对于Vector&ArrayList、Hashtable&HashMap,要记住线程安全的问题,记住Vector 与Hashtable是旧的,是java一诞生就提供了的,它们是线程安全的,ArrayList与HashMap是java2时才提供的,它们是线程不 安全的。所以,我们讲课时先讲老的。
(2)数据增长:
ArrayList与Vector都有一个初始的容量大小,当存储进它们里面的元 素的个数超过了容量时,就需要增加ArrayList与Vector的存储空间,每次要增加存储空间时,不是只增加一个存储单元,而是增加多个存储单元, 每次增加的存储单元的个数在内存空间利用与程序效率之间要取得一定的平衡。Vector默认增长为原来两倍,而ArrayList的增长策略在文档中没有 明确规定(从源代码看到的是增长为原来的1.5倍)。ArrayList与Vector都可以设置初始的空间大小,Vector还可以设置增长的空间大 小,而ArrayList没有提供设置增长空间的方法。
总结:即Vector增长原来的一倍,ArrayList增加原来的0.5倍。
65.HashMap和Hashtable的区别
(条理上还需要整理,也是先说相同点,再说不同点)
HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key),由于非线程安全,在只有一个线程访问的情况下,效率要高于Hashtable。
HashMap允许将null作为一个entry的key或者value,而Hashtable不允许。
HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因为contains方法容易让人引起误解。
Hashtable继承自Dictionary类,而HashMap是Java1.2引进的Map interface的一个实现。
最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多个线程访问Hashtable时,不需要自己为它的方法实现同步,而HashMap 就必须为之提供外同步。
Hashtable和HashMap采用的hash/rehash算法都大概一样,所以性能不会有很大的差异。

就HashMap与HashTable主要从三方面来说。
一).历史原因:Hashtable是基于陈旧的Dictionary类的,HashMap是Java 1.2引进的Map接口的一个实现
二).同步性:Hashtable是线程安全的,也就是说是同步的,而HashMap是线程序不安全的,不是同步的
三).值:只有HashMap可以让你将空值作为一个表的条目的key或value
66.List 和 Map 区别?
一个是存储单列数据的集合,另一个是存储键和值这样的双列数据的集合,List中存储的数据是有顺序,并且允许重复;Map中存储的数据是没有顺序的,其键是不能重复的,它的值是可以有重复的。
67.List, Set, Map是否继承自Collection接口?
List,Set是,Map不是

68.List、Map、Set三个接口,存取元素时,各有什么特点?
这样的题属于随意发挥题:这样的题比较考水平,两个方面的水平:一是要真正明白这些内容,二是要有较强的总结和表述能力。如果你明白,但表述不清楚,在别人那里则等同于不明白。

首先,List与Set具有相似性,它们都是单列元素的集合,所以,它们有一个共同的父接口,叫Collection。Set里面不允许有重复 的元素,所谓重复,即不能有两个相等(注意,不是仅仅是相同)的对象 ,即假设Set集合中有了一个A对象,现在我要向Set集合再存入一个B对象,但B对象与A对象equals相等,则B对象存储不进去,所以,Set集合 的add方法有一个boolean的返回值,当集合中没有某个元素,此时add方法可成功加入该元素时,则返回true,当集合含有与某个元素 equals相等的元素时,此时add方法无法加入该元素,返回结果为false。Set取元素时,没法说取第几个,只能以Iterator接口取得所有 的元素,再逐一遍历各个元素。
List表示有先后顺序的集合, 注意,不是那种按年龄、按大小、按价格之类的排序。当我们多次调用add(Obj e)方法时,每次加入的对象就像火车站买票有排队顺序一样,按先来后到的顺序排序。有时候,也可以插队,即调用add(int index,Obj e)方法,就可以指定当前对象在集合中的存放位置。一个对象可以被反复存储进List中,每调用一次add方法,这个对象就被插入进集合中一次,其实,并 不是把这个对象本身存储进了集合中,而是在集合中用一个索引变量指向这个对象,当这个对象被add多次时,即相当于集合中有多个索引指向了这个对象,如图 x所示。List除了可以以Iterator接口取得所有的元素,再逐一遍历各个元素之外,还可以调用get(index i)来明确说明取第几个。
Map 与List和Set不同,它是双列的集合,其中有put方法,定义如下:put(obj key,obj value),每次存储时,要存储一对key/value,不能存储重复的key,这个重复的规则也是按equals比较相等。取则可以根据key获得相 应的value,即get(Object key)返回值为key 所对应的value。另外,也可以获得所有的key的结合,还可以获得所有的value的结合,还可以获得key和value组合成的Map.Entry 对象的集合。

List 以特定次序来持有元素,可有重复元素。Set 无法拥有重复元素,内部排序。Map 保存key-value值,value可有多个重复值。
HashSet按照hashcode值的某种运算方式进行存储,而不是直接按hashCode值的大小进行存储。例如,”abc” —> 78,”def” —> 62,”xyz” —> 65在hashSet中的存储顺序不是62,65,78,这些问题感谢以前一个叫崔健的学员提出,最后通过查看源代码给他解释清楚,看本次培训学员当中有 多少能看懂源码。LinkedHashSet按插入的顺序存储,那被存储对象的hashcode方法还有什么作用呢?学员想想!hashset集合比较两 个对象是否相等,首先看hashcode方法是否相等,然后看equals方法是否相等。new 两个Student插入到HashSet中,看HashSet的size,实现hashcode和equals方法后再看size。

同一个对象可以在Vector中加入多次。往集合里面加元素,相当于集合里用一根绳子连接到了目标对象。往HashSet中却加不了多次的。

69.说出ArrayList,Vector, LinkedList的存储性能和特性
ArrayList和Vector都是使用数组 方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引 数据快而插入数据慢,Vector由于使用了synchronized方法(线程安全),通常性能上较ArrayList差,而LinkedList使用 双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。

LinkedList也是线程不安全的,LinkedList提供了一些方法,使得LinkedList可以被当作堆栈和队列来使用。
70.去掉一个Vector集合中重复的元素
Vector newVector = new Vector();
For (int i=0;i<vector.size();i++)
{
Object obj = vector.get(i);
if(!newVector.contains(obj);
newVector.add(obj);
}
还有一种简单的方式,HashSet set = new HashSet(vector);
71.Collection 和 Collections的区别。
Collection是集合类的上级接口,继承与他的接口主要有Set 和List.
Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。
72.Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别?
Set里的元素是不能重复的,元素重复与否是使用equals()方法进行判断的。
equals()和==方法决定引用值是否指向同一对象equals()在类中被覆盖,为的是当两个分离的对象的内容和类型相配的话,返回真值。

73.你所知道的集合类都有哪些?主要方法?
最常用的集合类是 List 和 Map。 List 的具体实现包括 ArrayList 和 Vector,它们是可变大小的列表,比较适合构建、存储和操作任何类型对象的元素列表。 List 适用于按数值索引访问元素的情形。
Map 提供了一个更通用的元素存储方法。 Map 集合类用于存储元素对(称作”键”和”值”),其中每个键映射到一个值。

 

有序否(指能否用index访问) 允许元素重复否
Collection
List
Set AbstractSet
HashSet
TreeSet 是(用二叉树排序)
Map

(键/值对数组)

AbstractMap 使用key-value来映射和存储数据,Key必须惟一,value可以重复
HashMap
TreeMap 是(用二叉树排序)

http://hi.baidu.com/linkage121/blog/item/5093f5d10fd8e487a1ec9cfe.html

我记的不是方法名,而是思想,我知道它们都有增删改查的方法,但这些方法的具体名称,我记得不是很清楚,对于set,大概的方法是 add,remove, contains;对于map,大概的方法就是put,remove,contains等,因为,我只要在eclispe下按点操作符,很自然的这些方法 就出来了。我记住的一些思想就是List类会有get(int index)这样的方法,因为它可以按顺序取元素,而set类中没有get(int index)这样的方法。List和set都可以迭代出所有元素,迭代时先要得到一个iterator对象,所以,set和list类都有一个 iterator方法,用于返回那个iterator对象。map可以返回三个集合,一个是返回所有的key的集合,另外一个返回的是所有value的集 合,再一个返回的key和value组合成的EntrySet对象的集合,map也有get方法,参数是key,返回值是key对应的value。

74.两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对?
对。
如果对象要保存在HashSet或HashMap中,它们的equals相等,那么,它们的hashcode值就必须相等。
如果不是要保存在HashSet或HashMap,则与hashcode没有什么关系了,这时候hashcode不等是可以的,例如arrayList存储的对象就不用实现hashcode,当然,我们没有理由不实现,通常都会去实现的。
75.TreeSet里面放对象,如果同时放入了父类和子类的实例对象,那比较时使用的是父类的compareTo方法,还是使用的子类的compareTo方法,还是抛异常!
(应该是没有针对问题的确切的答案,当前的add方法放入的是哪个对象,就调用哪个对象的compareTo方法,至于这个compareTo方法怎么做,就看当前这个对象的类中是如何编写这个方法的)