java基础面试题----最近在找工作,整理一些面试题~希望可以找到满意的工作~
一、面向对象的特征有哪些方面:
1、抽象:抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而是选择其中以部分,暂时不用部分细节。抽象包括两方面:过程抽象和数据抽象。
2、继承:继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表达共性的方法,对象的一个新类可以从现有的类中派生,这个过程成为类继承。新类继承了原始类的特性,新类称为原始类的派生类,而原始类称为新类的基类。派生类可以从它的基类哪里继承方法和实例变量,并且类可以修改或增加新的方法使之更适合特殊的需要。
3、封装:封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完成自治,封装的对象,这些对象通过一个受保护的接口访问其他对象。
4、多态:多态性是指允许不同类的对象对同一消息作出响应,多态性包括参数化多态和包含多态性。
二、String是最基本的数据类型吗?
不是。String类是final类型,因此不可以继承,不可以修改该类。为了提高效率节省空间我们应该用StringBuffer类。
基本数据类型有:byte,short,int,long,float,double,char,boolean。
引用类型有:数组,接口,类。
三、int 和 Integer 有什么区别
int是java提供的8种原始数据类型之一。java为每个原始数据类型提供了封装类,integer是int的封装类。int的默认值为0,Integer的默认值是null,即integer可以区分出为赋值和值为0的区别,int则无法表示出未赋值。另外,integer还提供了多个与整数相关的操作方法,还定义了表示整数的最大值和最小值的常量。
四、String ,StringBuilder和StringBuffer的区别
它们都可以存储和操作字符串。而string提供给的是数值不可改变的字符串,每当用String操作字符串时,实际上是在不断的创建新的对象;stringbuffer提供的是数值可改变的字符串,所以可以使用stringbuffer动态的构造字符数据。
1.三者在执行速度方面的比较:StringBuilder > StringBuffer > String
2.String <(StringBuffer,StringBuilder)的原因
String:字符串常量
StringBuffer:字符串变量
StringBuilder:字符串变量
从上面的名字可以看到,String是“字符串常量”,也就是不可改变的对象。
我们明明就是改变了String型的变量s的,为什么说是没有改变呢? 其实这是一种欺骗,JVM是这样解析这段代码的:首先创建对象s,赋予一个abcd,然后再创建一个新的对象s用来执行第二行代码,也就是说我们之前对象s并没有变化,所以我们说String类型是不可改变的对象了,由于这种机制,每当用String操作字符串时,实际上是在不断的创建新的对象,而原来的对象就会变为垃圾被GC回收掉,可想而知这样执行效率会有多底。
而StringBuffer与StringBuilder就不一样了,他们是字符串变量,是可改变的对象,每当我们用它们对字符串做操作时,实际上是在一个对象上操作的,这样就不会像String一样创建一些而外的对象进行操作了,当然速度就快了。
3.一个特殊的例子:
你会很惊讶的发现,生成str对象的速度简直太快了,而这个时候StringBuffer居然速度上根本一点都不占优势。其实这是JVM的一个把戏,实际上:
String str = “This is only a” + “ simple” + “test”;
其实就是:String str = “This is only a simple test”;
所以不需要太多的时间了。但大家这里要注意的是,如果你的字符串是来自另外的String对象的话,速度就没那么快了,譬如:
String str2 = “This is only a”;
String str3 = “ simple”;
String str4 = “ test”;
String str1 = str2 +str3 + str4;
这时候JVM会规规矩矩的按照原来的方式去做。
4.StringBuilder与 StringBuffer
StringBuilder:线程非安全的
StringBuffer:线程安全的
当我们在字符串缓冲去被多个线程使用是,JVM不能保证StringBuilder的操作是安全的,虽然他的速度最快,但是可以保证StringBuffer是可以正确操作的。当然大多数情况下就是我们是在单线程下进行的操作,所以大多数情况下是建议用StringBuilder而不用StringBuffer的,就是速度的原因。
string覆盖了equals方法和hashcode方法,而StringBuffer没有覆盖这两个方法,所以将StringBuffer对象存进集合类时会出现问题
对于三者使用的总结: 1.如果要操作少量的数据用 = String
2.单线程操作字符串缓冲区 下操作大量数据 = StringBuilder
3.多线程操作字符串缓冲区 下操作大量数据 = StringBuffer
五、一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制?
可以有多个类,但只能有一个public类,并且public的类名必须与文件名相同。
六、说出Servlet的生命周期,并说出Servlet和CGI的区别。
servlet被服务器实例化后,容器运行妻init()方法,请求到达时运行service方法,service自动派遣与请求对应doXXX方法,当服务器决定将实例销毁时,调用其destroy方法。
区别:servlet处于服务器进程中,它通过多线程方法运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会被销毁。而cgi对每个请求都产生一个新的进程,服务完后就销毁,所以效率低于servlet。
七、说出ArrayList,Vector, LinkedList的存储性能和特性
ArrayList和vector都使用数组方式存储数据此数据元素数大于实际存储的数据一边增加和插入数据,它们都允许直接序号索引元素,但插入元素要涉及数组移动等内存操作,所以索引数据快而插入数据慢;vector是线性安全的,所以性能上比ArrayList差。
LinkedList使用双向链表实现存储,按序号进行索引需要进行向后和向前遍历,但是插入数据时只需记录本项的前后项即可,所以插入数据速度较快。
八、Collection和 Collections的区别。
collection是集合的上级接口,继承于它的接口主要有set,list。
collections是针对集合的一个帮助类,它提供了一系列的静态方法实现对集合的搜索,排序,线程安全等操作
九、&和&&的区别。
&是位运算符,表示按位与运算。
&&是逻辑运算符,表示逻辑与。它具有短路功能,即如果第一个表达式为false则不再计算第二个表达式
十、HashMap和Hashtable的区别。
HashMap:允许空键值,非线性安全,效率高于Hashtable。
Hashtable:不允许空键值,线性安全的。
十一、final,finally, finalize的区别。
final:用于声明属性,方法,类。被其修饰的属性不可变,方法不可覆盖,类不可继承。
finally:异常处理语句的一部分,表示总是执行。
finalize:在垃圾回收时会调用被回收对象的此方法。
十二、sleep() 和 wait() 有什么区别?
sleep:是thread的方法,会导致线程暂停执行,给执行机会给其他线程,但不会释放对象锁,到时后会自动恢复。
wait:是object类的方法,调用此方法会导致本线程放弃对象锁,进入等待锁定池,只用针对此对象发出notify方法后本线程才会进入对象锁定池活得对象锁进入运行状态。
十三、Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型?
方法的重载和重写是java多态性的不同表现。
重载overload:表示同一个类中可以有多个名称相同的方法,但这些方法的参数列表各不相同(即参数个数或类型不同),重载的方法可以改变返回值的类型。
重写override:是父类和子类之间多态性的一种表现,如果子类中某方法与父类中有相同的名字和参数,则该方法被重写。
十四、switch语句能否作用在byte上,能否作用在long上,能否作用在String上?
只能是整数表达式(int基本类型或其包装类integer)和枚举常量。由于byte,short,char可以隐含转换为int,所以这些类型以及这些类型的包装类也是可以的。
十五、short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错?
s1+1的结果是int型,所以赋给short类型的s1会报错
+=是java语言规定的运算符,java编译器会对它进行特殊处理,所以可以正确编译。
十六、char型变量中能不能存贮一个中文汉字?为什么?
可以,char类型是16位的unicode编码。
十七、使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?
是引用变量不能变,引用的对象是可以改变的。
final StringBuffer a=new StringBuffer("immutable");
执行如下语句将报告编译期错误:
a=new StringBuffer("");
但是,执行如下语句则可以通过编译:
a.append(" broken!");
十八、"=="和equals方法究竟有什么区别?
==操作符专门用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存储的数值是否相同,要比较两个基本类型的数据或两个引用变量是否相等,只能用==操作符
equals方法是用于比较两个独立对象的内容是否相同,就好比去比较两个人的长相是否相同,它比较的两个对象是独立的。
String a=new String("foo");
String b=new String("foo");
表达式a==b将返回false,表达式a==b将返回false
十九、静态变量和实例变量的区别?
在语义定义上:静态变量前要加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);
}
}
二十、是否可以从一个static方法内部发出对非static方法的调用?
不可以,因为非static方法是要与对象关联在一起,必须创建对象后才可以在该对象进行方法的调用,而static方法调用时不需要创建对象可以直接调用,当一个static方法被调用时,可能没有创建对象,如果从一个static方法内部调用非static方法,那个非static方法调用那个对象呢?这个逻辑无法成立。
二十一、Math.round(11.5)等於多少? Math.round(-11.5)等於多少?
math提供了三个与取整有关的方法:ceil(向上取整),floor(上下取整),round(四舍五入),所以Math.round(11.5)=12;Math.round(-11.5)=-11
二十二、请说出四个作用域的区别。
作用域 当前类 同一package 子孙类 其他package
public √ √ √ √
protected √ √ √ ×
friendly √ √ × ×
private √ × × ×
二十三、构造器Constructor是否可被override?
构造器不能被继承,所以不能重写,但可以重载。
二十四、接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承具体类(concrete class)? 抽象类中是否可以有静态的main方法?
接口可以继承接口,抽象类可以实现接口,抽象类可以继承具体类,抽象类可以有静态的main方法。抽象类与普通类的区别是:不可以创建实例对象和允许有abstract方法。
二十五、写clone()方法时,通常都有一行代码,是什么?
super.clone();因为先把父类的成员复制到位,然后才是复制自己的成员。
二十六、java中实现多态的机制是什么?
靠的是父类或接口定义的引用变量可以指向子类或具体实现类的实例对象,而程序调用的方法在运行期才动态的绑定,就是引用变量所指向的具体实例对象方法,也就是内存正在运行的那个对象的方法,而不是引用变量的类型中定义的方法。
二十七、abstract class和interface有什么区别?
含有abstract修饰符的类为抽象方法,抽象类不可以实现实例对象。抽象类必须在具体子类中实现,如果子类没有实现抽象父类的所有方法,那么子类也必须定义为抽象类。
接口是抽象类的特例,接口中的所有方法都必须是抽象的。接口中的方法定义默认为 public abstract,成员变量默认为public static final。
区别:
1、抽象类中可以有构造方法,接口不能有。
2、抽象类可以有普通成员变量,接口中没有普通成员变量。
3、抽象类中可以有非抽象的普通方法,接口的所有方法必须是抽象的。
4、抽象类中的方法访问类型可以试public protected,但接口中的方法只能是public。
5、抽象类中可以有静态方法,接口中不能有静态方法。
6、一个类可以实现多个接口,但只能继承一个抽象类。
二十八、hashcode方法的作用
用来鉴别两个对象是否相等。与equals是有区别的:
它返回的是int型,比较不直观
二十九、abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized?
1、抽象方法不可以是静态的,因为抽象的方法要被子类实现的。
2、native表示该方法里面的方法不是用纯java编写的,所以它不能是抽象的。
3、方法上的synchronized同步所使用的同步锁对象是this,而抽象方法无法确定this是什么。
三十、String s = new String("xyz");创建了几个String Object? 二者之间有什么区别?
两个,一个是“xyz”,一个是s对“xyz”的引用。“xyz”放在字符串常量缓冲区,不管出现多少次都是缓冲区中的一个,而s是新创建出来的。
三十一、String s = "Hello";s = s + " world!";这两行代码执行后,原始的String对象中的内容到底变了没有?
没有,String是不可变对象。这时,s不指向原来的那个对象,而是指向另一个String对象,内容为“Hello world!”,原来的对象还存在于内存之中,只是s这个引用变量不再指向它了。
三十二、数组有没有length()这个方法? String有没有length()这个方法?
数组没有length()这个方法,只有length这个属性,String有length()这个方法。
三十三、下面这条语句一共创建了多少个对象:String s="a"+"b"+"c"+"d";
一个,javac编译可以对字符串常量直接相加的表达式进行优化,即在编译时去掉其中的加号,直接编译成一个常量相连的结果。而不必等到运行期去进行加法运算处理。
三十四、try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后?
会,在return之前。
三十五、运行时异常与一般异常有何异同?
异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见的运行时异常,java编译器要求方法必须声明抛出可能发生的非运行时异常,但并不要求必须声明抛出未被捕获的运行时异常。
三十六、error和exception有什么区别?
error表示可以恢复但很困难的一种严重问题,比如内存溢出,程序不可能处理这种情况。
exception表示一种设计或实现问题,即如果程序运行正常,从就不会发生的情况。
三十五、请写出你最常见到的5个runtime exception。
ArithmeticException, ArrayStoreException, BufferOverflowException, BufferUnderflowException, CannotRedoException, CannotUndoException, ClassCastException, CMMException, ConcurrentModificationException, DOMException, EmptyStackException, IllegalArgumentException, IllegalMonitorStateException, IllegalPathStateException, IllegalStateException, ImagingOpException, IndexOutOfBoundsException, MissingResourceException, NegativeArraySizeException, NoSuchElementException, NullPointerException, ProfileDataException, ProviderException, RasterFormatException, SecurityException, SystemException, UndeclaredThrowableException, UnmodifiableSetException, UnsupportedOperationException
三十六、JAVA语言如何进行异常处理,关键字:throws,throw,try,catch,finally分别代表什么意义?在try块中可以抛出异常吗?
java通过面向对象的方法进行异常处理,把各种不同的异常进行分类,并提供了良好的接口。在java中,每个异常都是一个对象,它是throwable类或其它子类的实例。当一个方法出现异常后便抛出一个异常对象,该对象包含异常信息。调用这个对象的方法可以捕获到这个异常并进行处理。
Java的异常处理是通过5个关键词来实现的:try、catch、throw、throws和finally。
一般情况下是用try来执行一段程序,如果出现异常,系统会抛出(throws)一个异常,这时候你可以通过它的类型来捕捉(catch)它,或最后(finally)由缺省处理器来处理。用try来指定一块预防所有“异常”的程序。紧跟在try程序后面,应包含一个catch子句来指定你想要捕捉的“异常”的类型。throw语句用来明确地抛出一个“异常”。throws用来标明一个成员函数可能抛出的各种“异常”Finally为确保一段代码不管发生什么“异常”都被执行一段代码。可以在一个成员函数调用的外面写一个try语句,在这个成员函数内部写另一个try语句保护其他代码。每当遇到一个try语句,“异常”的框架就放到堆栈上面,直到所有的try语句都完成。如果下一级的try语句没有对某种“异常”进行处理,堆栈就会展开,直到遇到有处理这种“异常”的try语句。