java基础

1、java的基本数据类型?
     8个:byte、short、int、long、float、double、char、boolean。

2、 short s1 = 1; s1 = s1 + 1;有错吗?short s1 = 1; s1 += 1;有错吗?
     答:对于short s1 = 1; s1 = s1 + 1;由于1是int类型,因此s1+1运算结果也是int 型,需要强制转换类型才能赋值给short型。而short s1 = 1; s1 += 1;可以正确编译,因为s1+=1;相当于s1 = (short)(s1 + 1);其中有隐含的强制类型转换。
     +=有隐含的强制类型转换功能。

3、int和integer的区别?
     java为每一种基本数据类型都引入了对应的包装类型(wrapper class),int的包装类型是Integer。从java5开始引入自动装箱/拆箱机制,二者可以相互转换。
     原始类型:byte、short、int、long、float、double、char、boolean
     包装类型:Byte、Short、Integer、Long、Float、Double、Character、Boolean

4、&和&&区别?
     &运算符有两种用法:(1)按位与;(2)逻辑与。
     作为逻辑与时,&&具有短路功能。

5、内存中的栈(stack)、堆(heap)和静态区(static area)的用法?
     通常定义一个基本数据类型的变量,一个对象的引用,还有就是函数调用的现场保存都使用内存中的栈空间;
     而通过new关键字和构造器创建的对象放在堆空间;
     程序中的字面量(literal),比如直接书写的100,“hello”和常量都是放在静态区中。
     栈空间操作起来最快但是栈很小,通常大量的对象都是放在堆空间,理论上整个内存没有被其他进程使用的空间甚至硬盘上的虚拟内存都可以被当成堆空间来使用。
      String str = new String("hello");
   上面语句中变量str放在栈上,用new创建出来的字符串对象放在堆上,而“hello”这个字面量放在静态区。

6、String类是否可以被继承?
     String类是final类,不可以被继承。

7、String和StringBuilder、StringBuffer的区别?
     java提供了两种类型的字符串:String和StringBuffer/StringBuilder,它们可以存储和操作字符串。
     其中,String是只读字符串,也就意味着String引用的字符串内容是不能被改变的。
     而StringBuilder/StringBuffer类表示的字符串对象可以直接进行修改。StringBuilder是java5中引入的,它和StringBuffer的方法完全相同。
     两者的区别在于StringBuilder是在单线程环境下使用的,因为它的所有方面都没有被synchronized修饰,因此它的效率也比StringBuffer高。

a:在执行速度方面的比较:StringBuilder > StringBuffer
b:StringBuffer与StringBuilder,它们是字符串变量,是可改变的对象,每当我们用它们对字符串做操作时,实际上是在一个对象上操作的,不像String一样创建一些对象       进行操作,所以速度就快了。
c:StringBuilder:线程非安全
      StringBuffer:线程安全
当我们在字符串缓冲区被多个线程使用时,JVM不能保证StringBuilder的操作是安全的虽然它的速度最快,但是可以保证StringBuffer是可以正确操作的。当然大多数情况下就是我们是在单线程下进行的操作,多以大多数情况下是建议用StringBuilder而不是StringBuffer,就是速度的原因。
对于三者使用的总结:
1、如果要操作少量的数据用  String
2、单线程操作字符串缓冲区下操作大量数据用 StringBuilder
3、多线程操作字符串缓冲区下操作大量数据用 StringBuffer

8、使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?
     使用final关键字修饰一个变量时,是指引用变量不能变,引用变量所指向的对象中的内容是可以改变的。
     例如:final StringBuffer a = new StringBuffer("immutable");
               执行如下语句将报告编译器错误:
               a = new StringBuffer("");
               但是,执行如下语句则可以通过编译:
               a.append("broken!");
     有人在定义方法的参数时,可能想采用如下形式来阻止方法内部修改传进来的参数对象:
     public void method(final StringBuffer param){}
     实际上,这是办不到的,在该方法内部仍然可以增加如下代码来修改参数对象:
     param.append("a");

9、"=="和equals有什么区别?
==专门用来比较两个变量的值是否相等。
也就是用于比较变量所对应的内存中所存储的数值是否相同,要比较两个基本类型的数据或两个引用变量是否相等,只能用==操作符。
如果一个变量指向的数据是对象类型的,那么,这时候涉及了两块内存,对象本身占用一块内存(堆内存),变量也占用一块内存。
例如:Object obj = new Object(); 变量obj是一个内存,new Object()是另一个内存,此时,变量obj所对应的内存中存储的数值就是对象占用的那块内存的首地址。
    对于指向对象类型的变量,如果要比较两个变量是否指向同一个对象,即要看这两个变量所对应的内存中的数值是否相等,这时候就需要用==操作符进行比较。
equals方法是用于比较两个独立对象的内容是否相同,就好比去比较两个人的长相是否相同,它比较的两个对象是独立的。
例如: String a = new String("foo");
     String b = new String("foo");
两条new语句创建了两个对象,然后用a,b这两个变量分别指向了其中一个对象,这是两个不同的对象,他们的首地址是不同的,即a和b中存储的数值是不相同的,所以表达式a==b将返回false,而这两个对象中的内容是相同的,所以,表达式a.equals(b)将返回true。
在实际开发中,我们经常要比较传递进来的字符串内容是否相等,例如:String input = ...; input.equals("quit");如果稍不注意使用==进行比较久错误了。
☆记住:字符串的比较基本上都是使用equals方法。
如果一个类没有自己定义equals方法,那么它将继承Object类的equals方法,Object类的equals方法的实现代码如下:
boolean equals(Object o){
return this == o;
}
这说明,如果一个类没有自己定义equals方法,它默认的equals方法就是使用==操作符,也是在比较两个变量指向的对象是否是同一个对象,这时候使用equals和使用==会得到同样的结果。如果比较的是两个独立的对象,则总返回false;如果你编写的类希望能够比较该类创建的两个实例对象的内容是否相同,那么你必须覆盖equals方法,由你自己写代码来决定在什么情况即可认为两个对象的内容是相同的。

10、静态变量和实例变量的区别?
语法上的区别:静态变量前要加static关键字,实例变量不需要。
在程序运行时的区别:实例变量属于某个对象的属性,必须创建了实例对象,其中的实例变量才会被分配空间,才能使用这个实例变量。静态变量不属于某个实例对象,而是属于类,所以也称为类变量,只要程序加载了累的字节码,不用创建任何实例对象,静态变量就会被分配空间,静态变量就可以被使用了。总之,实例变量必须创建对象后才可以通过这个对象来调用,静态变量则可以直接使用类名来引用。

例如:对于下面的程序,无论创建多少个实例对象,永远都只分配了一个staticVar变量,并且每创建一个实例对象,这个staticvar就会加1;但是每创建一个实例对象就会分配一个instanceVar,即可能分配多个instanceVar,并且每个instanceVar的值都只自加了1次。
public class VariantTest{
public static int staticVar = 0;
public int instanceVar = 0;
public VariantTest(){
staticVar ++;
instanceVar++;
System.out.println("staticVar=" + staticVar + ",instanceVar=" + instanceVar);
}
}

11、是否可以从一个static方法内部发出对非static方法的调用?
不可以。
因为非static方法是要与对象关联在一起的,必须创建一个对象后,才可以在该对象上进行方法调用,而static方法调用时不需要创建对象,可以直接调用。
也就是说,当一个static方法被调用时,可能还没有创建任何实例对象,如果从一个static方法中发出对非static方法的调用,那个非static方法是关联到哪个对象上的呢?
这个逻辑无法成立,所以,一个static方法内部发出对非static方法的调用。

12、Math.round(11.5)等于多少?Math.round(-11.5)等于多少?
Math类中提供了三个与取整有关的方法:ceil、floor、round。
这些方法的作用与它们的英文名称的含义相对应。
例如:ceil的英文意义是天花板,该方法就表示向上取整。Math.ceil(11.3)结果为12,Math.ceil(-11.3)的结果是-11;
    floor的英文意义是地板,该方法就表示向下取整。Math.floor(11.6)的结果为11,Math.floor(-11.6)的结果是-12;
    round表示“四舍五入”,算法为Math.floor(x+0.5),即将原来的数字加上0.5后再向下取整,所以,Math.round(11.5)的结果为12,Math.round(-11.5)的结果是-11.

13、overload和override的区别?
overload:重载。override:是覆盖的意思,也就是重写。
重载overload表示同一个类中可以有多个名称相同的方法,但这些方法的参数列表各不相同(参数个数或者类型不同)。
重写override表示子类中的方法可以与父类中的某个方法的名称和参数完全相同,通过子类创建的实例对象调用这个方法时,将调用子类中定义的方法,这相当于把父类中定义的那个完全相同的方法给覆盖了,这也是面向对象变成的多态性的一种表现。
重载要注意以下的几点:
1、在使用重载时只能通过不同的参数样式;
2、不能通过访问权限、返回类型、抛出的异常进行重载;
3、方法的异常类型和数目不会对重载造成影响;
4、对于继承来说,如果某一方法在父类中访问权限是private,那么就不能在子类对其进行重载,如果定义的话,也只是定义了一个新方法,而不能达到重载的效果。

重写(覆盖)要注意以下几点:
1、覆盖的方法的标志必须要和被覆盖的方法的标志完全匹配,才能达到覆盖的效果。
2、覆盖的方法的返回值必须和被覆盖的方法的返回值一致。
3、覆盖的方法所抛出的异常必须和被覆盖的方法所抛出的异常一致,或者时期子类。
4、被覆盖的方法不能为private,否则在其子类中只是新定义了一个方法,并没有对其进行覆盖。

14、☆ClassLoader如何加载class?
jvm里有多个类加载,每个类加载可以负责加载特定位置的类。
例如:bootstrap类加载负责加载jre/lib/rt.jar中的类,我们平时用的jdk中的类都位于rt.jar中。
    extclassloader负责加载jar/lib/ext/*.jar中的类,appclassloader负责classpath指定的目录或jar中的类。
    除了bootstrap之外,其他的类加载器本身也都是java类,他们的父类是ClassLoader。

15、分层设计的好处?
把各个功能按照调用流程进行了模块化,模块化带来的好处就是可以随意组合。
举例说明:如果要注册一个用户,流程为显示界面并通过界面接收用户的输入,接着进行业务逻辑处理,在处理业务逻辑又访问数据库。如果我们将这些步骤全部按照流水账的方式放在一个方法中编写也是可以的,但是这其中的坏处就是,当界面需要修改时,由于代码全在一个方法内,可能会影响到业务逻辑和数据库访问的代码。同样,当修改业务逻辑或数据库访问的代码是,也会影响到其他部分的代码。分层就是要把界面部分、业务逻辑部分、数据库访问部分的代码放在各自独立的方法或类中编写,这样就不会出现牵一发而动全身的问题。
分层的好处:
1、实现了软件之间的解耦;
2、便于进行分工;
3、便于维护;
4、提高软件组件的重用;
5、便于替换某种产品,比如持久层用的是Hibernate,需要更换产品用toplink,就不用修改其他业务代码,直接把配置修改就可以了。

16、写clone()方法时,通常都有一行代码,是什么?
clone有缺省行为,super.clone();因为首先要把父类中的成员复制到位,然后才是复制自己的成员。

17、abstract class 和interface有什么区别?
含有abstract修饰符的class即为抽象类,abstract类不能创建实例对象。含有abstract方法的类必须定义为abstract class,abstract class类中的方法不必是抽象的。
abstract class中定义的抽象方法必须在具体子类中实现,所以,不能有抽象构造方法或者抽象静态方法。如果子类没有实现抽象父类中的所有抽象方法,那么子类也必须定义为abstract类型。
interface可以说成是抽象类的一种特例,接口中的所有方法都必须是抽象的。接口中的方法定义默认为public abstract类型,接口中的成员变量类型默认为public static final

两者语法区别:
1、抽象类可以有构造方法,接口中不能有构造方法
2、抽象类中可以有普通成员变量,接口中没有普通成员变量
3、抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法
4、抽象类中的抽象方法的访问类型可以是public,protected,但接口中的抽象方法只能是public类型的,并且默认为public abstract类型。
5、抽象类中可以包含静态方法,接口中不能包含静态方法
6、抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static final类型,并且默认即为publicstatic final类型。
7、一个类可以实现多个接口,但只能继承一个抽象类

两者在应用上的区别:
接口更多的是在系统架构设计方法发挥作用,主要用于定义模块之间的通信契约。而抽象类在代码实现方面发挥作用,可以实现代码的重用。

18、什么是内部类?内部类可以引用它的包含类的成员吗?
内部类就是在一个类的内部定义的类,内部类中不能定义静态成员,内部类可以直接访问外部类中的成员变量,内部类可以定义在外部类的方法外面,也可以定义在外部类的方法中。

19、下面这条语句一共创建了多少个对象?
String s  = "a" + "b" + "c" + "d";
答:对于如下代码:
String s1 = "a";
String s2 = s1 + "b";
String s3 = "a" + "b";
System.out.println(s2 == "ab");
System.out.println(s3 == "ab");
第一条语句打印的结果为false,第二条语句打印的结果为true,这说明javac编译可以对字符串常量直接相加的表达式进行优化,不必要等到运行期进行加法运算处理,而是在编译时去掉其中的加号,直接将其编译成一个这些常量相连的结果。
题目中的第一行代码被编译器在编译时优化后,相当于直接定义了一个“abcd"的字符串,所以,上面的代码应该只创建了一个String对象。
写如下两行代码:
String s = "a" + "b" + "c" + "d";
System.out.println(s == "abcd");
最终打印的结果应该为true

20、final、finally、finalize的区别?
final用于声明属性、方法和类,分别表示属性不可变、方法不可覆盖,类不可继承。内部类要访问局部变量,局部变量必须定义成final类型。
finally是异常处理语句结构的一部分,表示总是执行。
finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。JVM不保证此方法总被调用。

21、error和exception有什么区别?
error表示恢复不是不可能,但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。
exception表示一种设计或实现问题,也就是说,它表示如果程序运行正常,从不会发生的情况。

22、运行时异常和一般异常有何异同?
异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误。java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。

23、java中的异常处理机制的简单原理和应用?
   异常是指java程序运行时(非编译)所发生的非正常情况或错误。与现实生活中的事件很相似,现实生活中的事件可以包含事件发生的时间、地点、人物、情节等信息,可以用一个对象来表示,java使用面向对象的方式来处理异常,它把程序中发生的每个异常也都分别封装到一个对象来表示的,该对象中包含有异常的信息。
java对异常进行了分类,不同类型的异常分别使用不同的Java类表示,所有异常的根类为java.lang.Throwable,Throwable下面又派生了两个子类:Error和Exception。
   Error表示应用程序本身无法克服和恢复的一种严重问题,程序只有死的份了,例如:内存溢出和线程死锁等系统问题。      Exception表示程序还能够克服和恢复的问题,其中又分为系统异常和普通异常,系统异常是软件本身缺陷所导致的问题,也就是软件开发人员考虑不周所导致的问题,软件使用者无法克服和恢复这种问题,但在这种问题下还可以让软件系统继续运行或者让软件死掉,例如:数组角标越界,空指针异常、类转换异常;普通异常是运行环境的变化或异常所导致的问题,是用户能够克服的问题,例如:网络断线、硬盘空间不够,发生这样的异常后,程序不应该死掉。
   java为系统 异常和普通异常提供了不同的解决方案,编译器强制普通异常必须try……catch处理或者用throws声明继续抛给上层调用方法处理,所以普通异常也称为checked异常,而系统异常可以处理也可以不处理,所以,编译器不强制用try……catch处理或用throws声明,所以系统异常也称为unchecked异常。
   提示:可以按照三个级别去思考:
   虚拟机必须宕机的错误、程序可以撕掉也可以不死掉的错误、程序不应该死掉的错误。

24、请写出你最常见的5个runtime exception?
  NullPointerException、ArrayIndexOutOfBoundsException、ClassCastException

25、java中有几种方法可以实现一个线程?用什么关键字修饰同步方法?stop()和suspend()方法为何不推荐使用?
有两种实现方法,分别使用new Thread()和new Thread(runnable)形式。
第一种直接调用thread的run方法,所以,我们往往使用Thread子类,即new SubThread()。
第二种调用runnable的run方法。

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

26、sleep()和wait()有什么区别?
sleep就是正在执行的线程主动让出CPU,CPU去执行其他线程,在sleep指定的时间过后,CPU才会回到这个线程上继续往下执行,如果当前线程进入了同步锁,sleep方法并不会释放锁,即使当前线程使用sleep方法让出了CPU,但其他同步锁挡住了的线程也无法得到执行。
wait是指在一个已经进入了同步锁的线程内,让自己暂时让出同步锁,以便其他正在等待此锁的线程可以得到同步锁并运行,只有其他线程调用了notify方法(notify并不释放锁,只是告诉调用过wait方法的线程可以去参与获得锁的竞争了,但不是马上得到锁,因为锁还在别人手里,别人还没释放。如果notify方法后边的代码还有很多,需要这些代码执行完后才会释放锁,可以在notify方法后增加一个等待和一些代码,看看效果),调用wait方法的线程就会解除wait状态和程序可以再次得到锁后继续向下运行。
sleep就是睡自己的觉,让别人吵吵去(睡到定点醒)
wait就是等电话,电话来了立刻接,其它时间也在睡(睡到有人叫)

27、启动一个线程使用run()方法还是start()方法?
启动一个线程调用start()方法,使线程成为就绪状态,以后可以被调度为运行状态,一个线程必须关联一些具体的执行代码,run()方法是该线程所关联的执行代码。

28、当一个线程进入一个对象的一个synchronized方法后,其他线程是否可以进入此对象的其他方法?
分几种情况:
1、其它方法前是否加了synchronized关键字,如果没加,则能。
2、如果这个方法内部调用了wait,则可以进入其他synchronized方法。
3、如果其它方法都加了synchronized关键字,并且内部没有调用wait,则不能。
4、如果其它方法是static,它用的同步锁是当前类的字节码,与非静态的方法不能同步,因为非静态的方法用的是this。

29、线程的基本概念、线程的基本状态以及各状态之间的关系?
一个程序中可以有多条执行线索同时执行,一个线程就是程序中的一条执行线索,每个线程上都关联有要执行的代码,即可以有多段程序代码同时运行,每个程序至少都有一个线程,即main方法执行的那个线程。如果只是一个CPU,它怎么能够同时执行多段程序呢?这是从宏观上来看的,CPU一会儿执行a线索,一会儿执行b线索,切换时间很快,给人的感觉是a,b在同时执行,好比大家在同一个办公室上网,只有一条连接到外部的网线,其实,这条网线一会儿为a传数据,一会儿为b传数据,由于切换时间很短暂,所以,大家感觉都在同时上网。
状态:
就绪、运行、synchronize 阻塞、wait和sleep 挂起、结束。 wait必须在synchronized内部调用。

调用线程的start方法后线程进入就绪状态,线程调度系统将就绪状态的线程转为运行状态,遇到synchronized语句时,由运行状态转为阻塞,当synchronized获得锁后,由阻塞转为运行,在这种情况下可以调用wait方法转为挂起状态,当线程关联的代码执行完后,线程变为结束状态。

30、Collection框架中实现比较要实现什么接口?
Comparable/comparator

31、ArrayList和Vector的区别?
这两个类都实现了List接口,List接口继承了Collection接口,它们都是有序集合。即存储在这两个集合中的元素的位置都是有顺序的,相当于一种动态的数组,我们以后可以按位置索引号来取出某个元素,并且其中的数据是允许重复的。
区别:
1、同步性:Vector是线程安全的,也就是说它的方法之间线程同步,而ArrayList是线程不安全的,它的方法之间的线程是不同步的,如果只有一个线程会访问到集合,那么最好用ArrayList,因为它不考虑线程安全,效率高。如果多个线程会访问到集合 ,那么就使用Vector,因为不需要我们自己去考虑和编写线程安全代码。
备注:
对于Vector和ArrayList,Hashtable和HashMap,线程安全是前2个,记住Vector和Hashtable是旧的,是java一诞生就提供了的,它们是线程安全的。而ArrayList和HashMap是java2才提供的,它们是线程不安全的。
2、数据增长:
ArrayList和Vector都有一个初始的容量大小,但存储进它们里面的元素的个数超过了容量时,就需要增加ArrayList和Vector的存储空间,每次要增加时,不是只增加一个存储单元,而是增加多个存储单元,每次增加的存储单元的个数在内存空间里和程序效率之间要取得一定的平衡。Vector增长为原来的一倍,ArrayList增加原来的0.5倍。

32、HashMap和Hashtable的区别?
HashMap是Hashtable的轻量级实现(非线程安全的实现),它们都实现了map接口,主要区别在于HashMap允许空(null)键值(key),由于非线程安全,在只有一个线程访问的情况下,效率要高于Hashtable。

HashMap允许将null作为一个entry的key或者value,而Hashtable不允许。
总结以下三点:
1、历史原因:Hashtable是基于陈旧的Dictionary类的,HashMap是java1.2引进的Map接口的一个实现。
2、同步性:Hashtable是线程安全的,也就是说是同步的,而HashMap是线程不安全的,不是同步的。
3、值:只有HashMap可以让你将空值作为一个表的条目的key或value。

33、List和Map的区别?
一个是存储单列数据的集合,另一个是存储键和值这样的双列数据的集合。
List中存储的数据是有序的,并且允许重复;
Map中存储的数据是没有顺序的,其键是不能重复的,它的值可以重复。

34、List、set、Map是否继承自Collection接口?
List、set是,Map不是

35、List、Map、Set三个接口,存取元素时,各有什么特点?
List以特定次序来持有元素,可有重复元素。
Set无法拥有重复元素,内部排序。
Map保存key-value值,value可多值。

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

37、去掉一个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);

38、Collection和Collections的区别?
Collection是集合类的上级接口,继承于它的接口主要有Set和List。
Collections是针对集合类的一个帮助类,它提供了一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。

39、Set里的元素是不能重复的,那么用什么方法来区分重复与否呢?使用==还是equals()?它们有何区别?
Set里的元素是不能重复的元素重复与否是使用equals()方法进行判断的。
equals()和==方法决定引用值是否指向同一对象equals()在类中被覆盖,为的是当两个分离的对象的内容和类型相配的话,返回真值。
 
40、你所知道的集合类都有哪些?主要方法?
最常用的集合类是List和Map。
List的具体实现包括ArrayList和Vector,它们是可变大小的列表,比较适合构建、存储和操作任何类型对象的元素列表。List适用于按数值索引访问元素的情形。
Map提供了一个更通用的元素存储方法。Map集合类用于存储元素对(称作“键”和“值”),其中每个键映射到一个值。
41、两个对象值相同(x.equals(y)==true),但却可有不同的hashcode,这句话对不对?
对。
如果对象要保存在HashSet或HashMap中,它们的equals相等,那么,它们的hashcode值就必须相等。
如果不是保存在HashSet或HashMap中,则与hashcode没有什么关系了,这时候hashcode不等是可以的,例如:ArrayList存储的对象就不用实现hashcode,当然,我们没有理由不实现,通常都会去实现的。

42、说出一些常用的类、包、接口?
常用的类:
String、java.util.Date、System、BufferedReader、BufferedWriter、FileReader、FileWriter
常用的包:
java.lang、java.io、java.util、java.sql、javax.servlet、org.apache.struts.action、org.hibernate
常用接口:
List、Map、Document、Servlet、HttpServletRequest、Transaction、Session(Hibernate)

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

44、字节流与字符流的区别?
要把一片二进制数据逐一输出到某个设备中,或者从某个设备中逐一读取一片二进制数据,不管输入输出设备是什么,我们要用统一的方式来完成这些操作,用一种抽象的方式进行描述,这个抽象描述方式起名为IO流,对应的抽象类为OutputStream和InputStream,不同的实现类就代表不同的输入和输出设备,它们都是针对字节进行操作的。
在应用中,经常要完全是字符的一段文本输出去或读进来,用字节流可以吗?在计算机中的一切最终都是二进制的字节形式存在。对于“中国”这些字符,首先要得到其对应的字节,然后将字节写入到输出流。读取时,首先读到的是字节,可是我们要把它显示为字符,我们需要将字节转换成字符。由于这样的需求很广泛,人家专门提供了字符流的包装类。
底层设备永远只接受字节数据,有时候要写字符串到底层设备,需要将字符串转成字节在进行写入。字符流是字节流的包装,字符流则是直接接受字符串,它内部将串转换成字节,再写入底层设备,这为我们想IO设备写入或读取字符串提供了一点点方便。
字符向字节转换时,要注意编码的问题,因为字符串转成字节数组,其实是转成该字符的某种编码的字节形式,读取也是反之的道理。

讲解字节流与字符流关系的代码案例:

import java.io.BufferedReader;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.FileReader;

import java.io.FileWriter;

import java.io.InputStreamReader;

import java.io.PrintWriter;

 

public class IOTest {

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

String str = "中国人";

/*FileOutputStream fos  = new FileOutputStream("1.txt");

fos.write(str.getBytes("UTF-8"));

fos.close();*/

/*FileWriter fw = new FileWriter("1.txt");

fw.write(str);

fw.close();*/

PrintWriter pw = new PrintWriter("1.txt","utf-8");

pw.write(str);

pw.close();

/*FileReader fr = new FileReader("1.txt");

char[] buf = new char[1024];

int len = fr.read(buf);

String myStr = new String(buf,0,len);

System.out.println(myStr);*/

/*FileInputStream fr = new FileInputStream("1.txt");

byte[] buf = new byte[1024];

int len = fr.read(buf);

String myStr = new String(buf,0,len,"UTF-8");

System.out.println(myStr);*/

BufferedReader br = new BufferedReader(

new InputStreamReader(

new FileInputStream("1.txt"),"UTF-8"

)

);

String myStr = br.readLine();

br.close();

System.out.println(myStr);

}

 

}


45、什么是java序列化?如何实现java序列化?解释Serializable接口的作用?
我们有时候将一个java对象变成字节流的形式传出去或者从一个字节流中恢复成一个java对象。例如:要将java对象存储到硬盘或者传送给网络上的其它计算机,这个过程我们可以自己写代码去把一个java对象变成某个格式的字节流再传输,但是jre本身就提供了这种支持,我们可以调用OutputStream的writeObject方法来做,如果要让java帮我们做,要被传输的对象必须实现serializable接口,这样,javac编译时就会进行特殊处理,编译的类才可以被writeObject方法操作,这就是所谓的序列化。需要被序列化的类必须实现Serializable接口,该接口是一个mini接口,其中没有需要实现的方法,implements Serializable只是为了标注该对象是可被序列化的。
例如,在web开发中,如果对象被保存在了Session中,tomcat在重启时要把Session对象序列化到硬盘,这个对象就必须实现Serializable接口。如果对象要经过分布式系统进行网络传输或通过rmi等远程调用,这就需要在网络上传输对象,被传输的对象就必须实现Serializable接口。

46、heap和stack有什么区别?
java的内存分为两类,一类是栈内存,一类是堆内存。栈内存是指程序进入一个方法时,会为这个方法单独分配一块私属存储空间,用于存储这个方法内部的局部变量,当这个方法结束时,分配给这个方法的栈会释放,这个栈中的变量也将随之释放。
堆是与栈作用不同的内存,一般用于存放不放在当前方法栈中的那些数据,例如:使用new创建的对象都放在堆里,所以,它不会随方法的结束而消失。方法中的局部变量使用final修饰后,放在堆中,而不是栈中。

47、GC是什么?为什么要有GC?
GC是垃圾收集的意思,内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,java提供的GC功能可以自动检测对象是否超过作用域从而达到自动回收内存的目的,java语言没有提供释放已分配内存的显示操作方法。

48、垃圾回收的优点和原理?考虑2中回收机制?
Java语言中一个显著的特点就是引入了垃圾回收机制,是c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再考虑内存管理。由于有个垃圾回收机制,Java中的对象不再有“作用域”的概念,只有对象的引用才有“作用域”。垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存。垃圾回收器通常是作为一个单独的低级别的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清除和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收。回收机制又分代复制垃圾回收和标记垃圾回收,增量垃圾回收。

49、垃圾回收器的基本原理是什么?垃圾回收器可以马上回收内存吗?有什么方法主动通知虚拟机进行垃圾回收?
对于GC来说,当程序员创建对象时,GC就开始监控这个对象的地址、大小以及使用情况。通常,GC采用有向图的方式记录和管理堆(heap)中的所有对象。通过这种方式确定哪些对象是“可达的”,哪些对象是“不可达的”。当GC确定一些对象是“不可达”时,GC就有责任回收这些内存空间。
可以。
程序员可以手动执行System.gc(),通知GC运行,但是Java语言规范并不保证GC一定会执行。

50、


关联的执行代码。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值