Java的基本知识

来源:互联网 发布:云计算基础设施建设 编辑:程序博客网 时间:2024/06/06 14:15



Java的HashMap和HashTable

1. HashMap

1)  hashmap的数据结构 

     Hashmap是一个数组和链表的结合体(在数据结构称“链表散列“),如下图示:

        当我们往hashmap中put元素的时候,先根据key的hash值得到这个元素在数组中的位置(即下标),然后就可以把这个元素放到对应的位置中了。如果这个元素所在的位子上已经存放有其他元素了,那么在同一个位子上的元素将以链表的形式存放,新加入的放在链头,最先加入的放在链尾。

2)使用

复制代码
Map map = new HashMap();map.put("Rajib Sarma","100");map.put("Rajib Sarma","200");//The value "100" is replaced by "200".map.put("Sazid Ahmed","200");Iterator iter = map.entrySet().iterator();while (iter.hasNext()) {    Map.Entry entry = (Map.Entry) iter.next();    Object key = entry.getKey();    Object val = entry.getValue();}
复制代码

2. HashTable和HashMap区别

第一,继承不同。

public class Hashtable extends Dictionary implements Mappublic class HashMap  extends AbstractMap implements Map

第二

Hashtable 中的方法是同步的,而HashMap中的方法在缺省情况下是非同步的。在多线程并发的环境下,可以直接使用Hashtable,但是要使用HashMap的话就要自己增加同步处理了。

第三

Hashtable中,key和value都不允许出现null值。

在HashMap中,null可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为null。当get()方法返回null值时,即可以表示 HashMap中没有该键,也可以表示该键所对应的值为null。因此,在HashMap中不能由get()方法来判断HashMap中是否存在某个键, 而应该用containsKey()方法来判断。

第四,两个遍历方式的内部实现上不同。

Hashtable、HashMap都使用了 Iterator。而由于历史原因,Hashtable还使用了Enumeration的方式 。

第五

哈希值的使用不同,HashTable直接使用对象的hashCode。而HashMap重新计算hash值。

第六

Hashtable和HashMap它们两个内部实现方式的数组的初始大小和扩容的方式。HashTable中hash数组默认大小是11,增加的方式是 old*2+1。HashMap中hash数组的默认大小是16,而且一定是2的指数。





overload和override


说实话,这两个没有什么可比较的,概念相差那么大,但是很多笔试题之类的还喜欢考。只是长的像了一点而已。

overload是重载,对方法而言,同名不同参数,可以发生在当前类,也可以发生在父类和子类的身上。

override是覆盖,主要是发生在父类和子类的身上,子类继承了父类,然后写一个和父类同名,同参数的方法,那么父类的方法就被子类覆盖掉了。

但是,我总结了最重要的两点:

1.子类的方法的返回类型,参数,方法名称,要和父类方法的返回类型,参数,方法名完全一样,否则编译出错。

2.子类方法不能缩小父类方法的访问权限。(体现在修饰符上面,比如父类是public 的,子类变为了protected就不行了),但是反过来可以,就是说子类可以放大父类的方法的访问权限。





 

java中,什么是GC?GC的基本原理。



1.什么是GC
 GC(GarbageCollection)是垃圾回收机制,在Java中开发人员无法使用指针来自由的管理内存,GC是JVM对内存(实际上就是对象)进行管理的方式。GC使得Java开发人员摆脱了繁琐的内存管理工作,让程序的开发更有效率。

2. GC基本原理

Java的内存管理实际上就是对象的管理,其中包括对象的分配和释放。

  对于程序员来说,分配对象使用new关键字;释放对象时,只要将对象所有引用赋值为null,让程序不能够再访问到这个对象,我们称该对象为"不可达的"。GC将负责回收所有"不可达"对象的内存空间。

  对于GC来说,当程序员创建对象时,GC就开始监控这个对象的地址、大小以及使用情况。通常,GC采用有向图的方式记录和管理堆(heap)中的所有对象。通过这种方式确定哪些对象是"可达的",哪些对象是"不可达的"。当GC确定一些对象为"不可达"时,GC就有责任回收这些内存空间。但是,为了保证GC能够在不同平台实现的问题,Java规范对GC的很多行为都没有进行严格的规定。例如,对于采用什么类型的回收算法、什么时候进行回收等重要问题都没有明确的规定。因此,不同的JVM的实现者往往有不同的实现算法。这也给Java程序员的开发带来行多不确定性。本文研究了几个与GC工作相关的问题,努力减少这种不确定性给Java程序带来的负面影响。

  增量式GC( Incremental GC )

  GC在JVM中通常是由一个或一组进程来实现的,它本身也和用户程序一样占用heap空间,运行时也占用CPU。当GC进程运行时,应用程序停止运行。因此,当GC运行时间较长时,用户能够感到Java程序的停顿,另外一方面,如果GC运行时间太短,则可能对象回收率太低,这意味着还有很多应该回收的对象没有被回收,仍然占用大量内存。因此,在设计GC的时候,就必须在停顿时间和回收率之间进行权衡。一个好的GC实现允许用户定义自己所需要的设置,例如有些内存有限有设备,对内存的使用量非常敏感,希望GC能够准确的回收内存,它并不在意程序速度的放慢。另外一些实时网络游戏,就不能够允许程序有长时间的中断。增量式GC就是通过一定的回收算法,把一个长时间的中断,划分为很多个小的中断,通过这种方式减少GC对用户程序的影响。虽然,增量式GC在整体性能上可能不如普通GC的效率高,但是它能够减少程序的最长停顿时间。
Sun JDK提供的HotSpot JVM就能支持增量式GC。HotSpot JVM缺省GC方式为不使用增量GC,为了启动增量GC,我们必须在运行Java程序时增加-Xincgc的参数。HotSpot JVM增量式GC的实现是采用Train GC算法。它的基本想法就是,将堆中的所有对象按照创建和使用情况进行分组(分层),将使用频繁高和具有相关性的对象放在一队中,随着程序的运行,不断对组进行调整。当GC运行时,它总是先回收最老的(最近很少访问的)的对象,如果整组都为可回收对象,GC将整组回收。这样,每次GC运行只回收一定比例的不可达对象,保证程序的顺畅运行。

3.Java coding suggestion

(1)最基本的建议就是尽早释放无用对象的引用。大多数程序员在使用临时变量的时候,都是让引用变量在退出活动域(scope)后,自动设置为null。我们在使用这种方式时候,必须特别注意一些复杂的对象图,例如数组,队列,树,图等,这些对象之间有相互引用关系较为复杂。对于这类对象,GC回收它们一般效率较低。如果程序允许,尽早将不用的引用对象赋为null。这样可以加速GC的工作。


  (2)尽量少用finalize函数。finalize函数是Java提供给程序员一个释放对象或资源的机会。但是,它会加大GC的工作量,因此尽量少采用finalize方式回收资源。


  (3)如果需要使用经常使用的图片,可以使用soft(softReference)应用类型。它可以尽可能将图片保存在内存中,供程序调用,而不引起OutOfMemory。


  (4)注意集合数据类型,包括数组,树,图,链表等数据结构,这些数据结构对GC来说,回收更为复杂。另外,注意一些全局的变量,以及一些静态变量。这些变量往往容易引起悬挂对象(dangling reference),造成内存浪费。


  (5)当程序有一定的等待时间,程序员可以手动执行System.gc(),通知GC运行,但是Java语言规范并不保证GC一定会执行。使用增量式GC可以缩短Java程序的暂停时间。





常用的类,包,接口,各5个


类:

Java.lang.Object;

java.lang.String;

java.lang.Runtime;

java.io.file;

java.io.BufferdReader;  等。。。。

包:

java.lang;

java.io;

java.swt;

java.util;

java.sql;

javax.servlet;   and so on....

接口:

java.util.list;

java.util.map;

java.util.Iterator;

java.lang.comparable;

java.sql.Statement;



 

java 强引用、弱引用、软引用、虚引用 浅析



强引用(StrongReference):

强引用最常见, StringBuffer buffer=new StringBuffer();这条语句创建了一个stringBuffer类的对象,并用一个变量buffer存储对这个对象的引用,这就是一个强引用。变量持有的是这个对象的引用。通常,引用是一个对象的存储地址,如果一个对象具有强引用,GC绝不回收,哪怕内存不足,JVM抛出outofmemoryError使程序终止,也不会回收StrongReference。

Java不像c或者c++一样,java没有取地址符号,也米有解引用符号*或者-->,引用不同于指针,引用不能与整型进行相互转换,也不能进行增减操作。强引用是垃圾回收机制相关的。一般的,如果一个对象可以通过一些列的强引用引用到,那么就说明,它是不会被垃圾回收机制回收的。因为GC不会收回你正在使用的对象,如果一个对象,没有引用指向他,那么它就被认为是一个垃圾。


弱引用(WeakReference):

                      简单的说就是将对象留在内存的能力不是那么强的引用,不保证不被GC回收的对象,生命周期短,GC一旦发现只有弱引用的对象,就回收它的内存,但GC线程优先级比较低,不会很快发现只有弱引用的对象。

弱引用可以实现WeakHashMap类,和HashMap几乎一样,唯一的区别就是WeakHashMap的键使用WeakReference引用。当WeakHashMap的键被标记为垃圾的时候,这个键对应的条目也会被自动移除。WeakHashMap也可以方便的转为HahMap或者Map。如果没有任何强引用引用弱引用的对象的话,使用get()方法时候,很可能会返回null(除非GC还未发现)弱引用是和引用队列(ReferenceQueue)相关联的,一旦弱引用开始返回null,该弱引用指向的对象被标记成了垃圾,而这个弱引用就没有什么用了。引用队列是跟踪不需要的引用,像上面这种情况的弱引用,JVM就把它加入到ReferenceQueue,然后,在固定的周期,便可以处理这个引用队列。


软引用(SoftReference):如果一个对象只具有软引用,内存空间足够,GC不回收它,如果内存空间不足了,GC回收该对象的内存。

只要没回收,该对象就能被程序使用 。软引用可以用来实现内存敏感告诉缓存。(Soft references are for implementing memory-sensitive caches)


虚引用(PhantomReference):顾名思义,形同虚设,它决定不了对象的生命周期,如果一个对象仅仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被GC回收。

那么它的存在有什么意义呢?

用来跟踪对象被GC回收的活动,虚引用必须和引用队列联合使用。当GC准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。程序可以通过判断引用队列中是否已经加入了虚引用,来了解被以引用对象是否要被回收 。如果发现已经加入到引用队列中,那么就在所引用的对象被回收前采取必要的行动了。

PhantomReference的get()方法总是返回null,所以你得不到它的引用对象。


三种类型的引用定义了三种不同的层次可达性级别,由强到弱排列如下:

      StrongReference>softReferenc>WeakReference>PhantomReference





 

UML中类与类之间的关系



1.泛化(Generalization)

 表示类与类之间的继承关系,接口与接口之间的继承关系,或者对接口的实现关系。例如老虎类和小狗类继承了动物类。

2.依赖(Dependency)

依赖关系表现在局部变量,方法的参数,以及对静态方法的调用。

比如:

[java] view plain copy
  1. public class person{  
  2.     void screw(screwdrive sd){  
  3.                     sd.screw();  
  4.           }  
  5. }  
人要拧东西,但是要借助工具,所以依赖工具。这就是依赖。

3.关联(Association)

UML中,对于两个相互独立的对象,当一个类的实例与另一个类的实例存在固定的对应关系时,这两个对象之间为关联关系。 关联关系分为两种,一种是能独立存在的关联关系,一种是不能独立存在的。 关联关系是通过实例变量来表现的。

4.聚合(Aggregation)

对象A被加入到对象B中,成为对象B的组成部分时,对象B和对象A之间为聚合关系,是关联的一种,强调整体与部分的关系。属于强关联。这种情况下,部分不能独立于整体存在,整体消失,部分也消失。




 

浅析final finally finalize


1.final

final修饰类,说明这个类不能被继承,是个顶级类。

final修饰变量,说明这个变量是常量,初始化后不能再改。

fianl修饰方法,表示这个方法不能被重写,不过可以重载final修饰的方法。(常见的final方法是object类中的wait(),notify()方法)


2.finally

finally是关键字,在异常处理中,try字句中执行需要运行的内容,catch字句中用于捕获异常,finally字句表示不管是否发生异常,都会执行。finally可有可无。但是try....catch必须成对出现。


3.finalize()

finalize()方法,object类的方法,任何类都继承object类,所以任何对象都有这个方法。这个方法由GC在确定这个对象没有被引用时这个对象进行调用。


 

int 和 Integer 有什么区别?



Java 提供两种不同的类型:引用类型和原始类型(或内置类型);

int 是 java 的原始数据类型,Integer 是 java 为 int 提供的封装类。

Java 为每个原始类型提供了封装类:

原始类型: boolean,char,byte,short,int,long,float,double

封装类型:Boolean,Character,Byte,Short,Integer,Long,Float,Double

引用类型和原始类型的行为完全不同,并且它们具有不同的语义。引用类型和

原始类型具有不同的特征和用法,它们包括:大小和速度问题,这种类型以哪种

类型的数据结构存储,当引用类型和原始类型用作某个类的实例数据时所指定的

缺省值。对象引用实例变量的缺省值为 null,而原始类型实例变量的缺省值与

它们的类型有关。



用最有效率的方法算出 2 乘以 8 等於几?

2 << 3



 Swtich 是否能作用在 byte 上,是否能作用在 long 上,是否能作用在 String 上?

switch(expr1)中 ,expr1 是一个整数表达式。因此传递给 switch 和 case

语句的参数应该是 int、 short、 char 或者 byte。long,string 都不能作用

于 swtich。


我们在 web 应用开发过程中经常遇到输出某种编码的字符,如 iso8859-1 等,如何输出一个某种编码的字符串?


public String translate(String str){//对传入的str字符串进行转换

String tempStr = "";

try{

    tempStr = new String(str.getBytes("ISO-8859-1"), "GBK");//把"ISO-8859-1"转化为“GBK”编码

tempStr = tempStr.trim();

}catch (Exception e){

System.err.println(e.getMessage());

}

return tempStr;

}









原创粉丝点击