java程序员面试必备的32个要点1.docx
- 文档编号:13803670
- 上传时间:2023-06-17
- 格式:DOCX
- 页数:32
- 大小:38.50KB
java程序员面试必备的32个要点1.docx
《java程序员面试必备的32个要点1.docx》由会员分享,可在线阅读,更多相关《java程序员面试必备的32个要点1.docx(32页珍藏版)》请在冰点文库上搜索。
java程序员面试必备的32个要点1
第一,谈谈final,finally,finalize的区别。
final修饰符(关键字),如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承。
因此一个类不能既被声明为abstract的,又被声明为final的。
将变量或方法声明为final,可以保证它们在使用中不被改变。
被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改。
被声明为final的方法也同样只能使用,不能重载
finally再异常处理时提供finally块来执行任何清除操作。
如果抛出一个异常,那么相匹配的catch子句就会执行,然后控制就会进入finally块(如果有的话)。
finalize方法名。
Java技术允许使用finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。
这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。
它是在Object类中定义的,因此所有的类都继承了它。
子类覆盖finalize()方法以整理系统资源或者执行其他清理工作。
finalize()方法是在垃圾收集器删除对象之前对这个对象调用的。
续:
final变量不能改变吗?
publicclassFirstClass{
finalStringBuildersb=newStringBuilder("initfinal......");
publicstaticvoidmain(String[]args){
FirstClassfc=newFirstClass();
;
"changed");
;
}
}
看看能不能改变?
不能改变的是这个"变量"的句柄(的值),也就是它不能再指向其它对象,而指向的对象本身你只要有方法就可以任意改变.
final方法不能重载吗?
publicclassFirstClass{
finalStringBuildersb=newStringBuilder("initfinal......");
finalvoida(){}
voida(Stringa){}
publicstaticvoidmain(String[]args)throwsException{
FirstClassfc=newFirstClass();
fc.a();
fc.a("");
}
}
只是不能被继承而已
finally从句除了在try{}catch(){}中调用了System.exit(x);
其它任何时候都会在离开该段之前执行,并不是只有抛出异常,即使return,breaklabel也一样.
第二,AnonymousInnerClass(匿名内部类)是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)?
答案:
可以继承其他类或完成其他接口,在swing编程中常用此方式。
第三,StaticNestedClass和InnerClass的不同,说得越多越好(面试题有的很笼统)。
1--NestedClass(一般是C++的说法),InnerClass(一般是JAVA的说法)。
Java内部类与C++嵌套类最大的不同就在于是否有指向外部的引用上。
注:
静态内部类(InnerClass)意味着1创建一个static内部类的对象,不需要一个外部类对象,2不能从一个static内部类的一个对象访问一个外部类对象
2--NestedClass一般是C++的说法,InnerClass一般是JAVA的说法。
Nestedclass分为静态Staticnestedclass的和非静态的innerclass,静态的Staticnestedclass是不可以直接调用它的外部类enclosingclass的,但是可以通过外部类的引用来调用,就像你在一个类中写了main方法一样。
非静态类innerclass可以自由的引用外部类的属性和方法,但是它与一个实例绑定在了以其,不可以定义静态的属性、方法
3--
1.nested(嵌套)class(一般是C++的说法)
nestedclass是合成型聚集关系(CompositeAggregation)的另一种表达方式,也就是说nestedclass也可以用Aggregation表达出来。
但是,nestedclass更加精确地表达了一种专用的、紧耦合的关系,尤其在代码生成时,nestedclass在Java中映射成inlineclass。
比如,计算机专用开关电源类可以作为计算机类的nestedclass,但是,电池组类就不一定适合作为计算机类的nestedclass,因为,电池组类表述的是一个过于通用的对象,可能还被包含(Aggregation)于模型中的其他设备对象。
classAnestedinclassB,则说明A是一个nestedclass,一般A是用来完成B中的某种重要功能的。
2.innerclass(一般是Java的说法)
Java内部类与C++嵌套类最大的不同就在于是否有指向外部的引用上。
静态内部类(innerclass)意味着:
创建一个static内部类的对象,不需要一个外部类对象;不能从一个static内部类的一个对象访问一个外部类对象。
关于下面类的定义,以下哪种说法是正确的?
[研华科技2005年11月面试题]
publicclassDroitwich{
classone{
privateclasstwo{
publicvoidmain(){
"two");
}
}
}
}
A.此代码不能编译成功,因为该类嵌套了不止一层
B.此代码不能编译通过,因为classtwo是私有的
C.此代码可以编译通过,并且在运行的时候输出字符串two
D.此代码编译没有错误
解析:
内部类或嵌套类在类层级上没有限制,所以选项A是错误的。
内部类可以是私有类,所以选项B也是错误的。
选项C的main方法不是publicstaticvoidmain的,并且假设命令行是javaDroitwich,它不能在任何地方被调用。
答案:
D
第四,&和&&的区别。
1.&是位运算符,&&是布尔逻辑运算符
2.&是非短路逻辑运算符,&&是短路逻辑运算符
3.我们老师的说法:
&既是逻辑运算符,又是位运算符,当&作为逻辑运算符时属于非短路型,而&&只是短路型逻辑运算符
问题补充:
//这是我们老师讲逻辑运算符时举的例子,结果b=13,c=4
publicclassTestLogic{
publicstaticvoidmain(String[]args){
inta=2,b=3,c=4;
if(a<2&(b=13)>10)
"不可能!
");
if(a<2&&(c=14)>10)
"不可能!
");
"b="+b);
"c="+c);
}
}
-----只有1对。
&是位运算符,&&是布尔逻辑运算符而且是短路与操作符。
注意:
&就根本不应该作为逻辑运算用的。
所谓的可以作为逻辑运算实际上是判断运算的结果是不是等于0,而由于要进行逻辑与操作,必须先要求出两边操作数的值(这个就好像是非短路了)。
不过这不是java语言所支持的,混淆了和C的区别。
绝对错误的概念。
------&和&&都可作为逻辑运算符“与”使用,但是&&是“短路与”,运算时先判断符号前面的表达式的值,如果能够确定整个表达式的值,则不进行符号后面的表达式的运算,如果是“&”则前后都必须进行判断。
另外,&也可作为位运算符使用。
eg:
publicclassTest
{
publicstaticvoidmain(Stringargs[])
{
Stringstr=null;
if(str!
=null&str.length()>0){
"hahha");
}
else{
"hehe");
}
}
}
A:
haha
B:
hehe
C:
编译错误
D:
运行时异常
str.length()会报空指针异常,如果用&&则会输出“hehe”
-----&单与
单与前后逻辑表达式都执行
if((a++>0)&(b--<0)){}
表达式1:
a++>0 与表达式2:
b--<0 -------------------------执行返回true或false之后,
按照同真则真,有假则假------------------------返回boolean值
&&双与-------双与先判断表达式1,若表达式1为false则表达式2不再执行----------------------直接返回false,若表达式2为true则再执行表达式2之后按照同真则真,有假则假----------------返回boolean值.
|与||的区别:
与上述正好相反(可以自己试一试)
单与&的特殊用法:
n1%n2==n1&(n2-1)
主要用在移位运算,求余数(大家可以试一试)
第五,HashMap和Hashtable的区别。
HashTable的应用非常广泛,HashMap是新框架中用来代替HashTable的类,也就是说建议使用HashMap,不要使用HashTable。
可能你觉得HashTable很好用,为什么不用呢?
这里简单分析他们的区别。
1.HashTable的方法是同步的,HashMap未经同步,所以在多线程场合要手动同步HashMap这个区别就像Vector和ArrayList一样。
2.HashTable不允许null值(key和value都不可以),HashMap允许null值(key和value都可以)。
3.HashTable有一个contains(Object value),功能和containsValue(Object value)功能一样。
4.HashTable使用Enumeration,HashMap使用Iterator。
以上只是表面的不同,它们的实现也有很大的不同。
5.HashTable中hash数组默认大小是11,增加的方式是 old*2+1。
HashMap中hash数组的默认大小是16,而且一定是2的指数。
6.哈希值的使用不同,HashTable直接使用对象的hashCode,代码是这样的:
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
而HashMap重新计算hash值,而且用与代替求模:
int hash = hash(k);
int i = indexFor(hash, table.length);
static int hash(Object x) {
int h = x.hashCode();
h += ~(h << 9);
h ^= (h >>> 14);
h += (h << 4);
h ^= (h >>> 10);
return h;
}
static int indexFor(int h, int length) {
return h & (length-1);
}
以上只是一些比较突出的区别,当然他们的实现上还是有很多不同的,比如
HashMap对null的操作
2--Hashtable和HashMap类有三个重要的不同之处。
第一个不同主要是历史原因。
Hashtable是基于陈旧的Dictionary类的,HashMap是Java1.2引进的Map接口的一个实现。
也许最重要的不同是Hashtable的方法是同步的,而HashMap的方法不是。
这就意味着,虽然你可以不用采取任何特殊的行为就可以在一个多线程的应用程序中用一个Hashtable,但你必须同样地为一个HashMap提供外同步。
一个方便的方法就是利用Collections类的静态的synchronizedMap()方法,它创建一个线程安全的Map对象,并把它作为一个封装的对象来返回。
这个对象的方法可以让你同步访问潜在的HashMap。
这么做的结果就是当你不需要同步时,你不能切断Hashtable中的同步(比如在一个单线程的应用程序中),而且同步增加了很多处理费用。
第三点不同是,只有HashMap可以让你将空值作为一个表的条目的key或value。
HashMap中只有一条记录可以是一个空的key,但任意数量的条目可以是空的value。
这就是说,如果在表中没有发现搜索键,或者如果发现了搜索键,但它是一个空的值,那么get()将返回null。
如果有必要,用containKey()方法来区别这两种情况。
一些资料建议,当需要同步时,用Hashtable,反之用HashMap。
但是,因为在需要时,HashMap可以被同步,HashMap的功能比Hashtable的功能更多,而且它不是基于一个陈旧的类的,所以有人认为,在各种情况下,HashMap都优先于Hashtable。
关于Properties
有时侯,你可能想用一个hashtable来映射key的字符串到value的字符串。
DOS、Windows和Unix中的环境字符串就有一些例子,如key的字符串PATH被映射到value的字符串C:
\WINDOWS;C:
\WINDOWS\SYSTEM。
Hashtables是表示这些的一个简单的方法,但Java提供了另外一种方法。
,设计用于Stringkeys和values。
Properties对象的用法同Hashtable的用法相象,但是类增加了两个节省时间的方法,你应该知道。
Store()方法把一个Properties对象的内容以一种可读的形式保存到一个文件中。
Load()方法正好相反,用来读取文件,并设定Properties对象来包含keys和values。
注意,因为Properties扩展了Hashtable,你可以用超类的put()方法来添加不是String对象的keys和values。
这是不可取的。
另外,如果你将store()用于一个不包含String对象的Properties对象,store()将失败。
作为put()和get()的替代,你应该用setProperty()和getProperty(),它们用String参数。
3--Hashtable和HashMap的区别:
1.Hashtable是Dictionary的子类,HashMap是Map接口的一个实现类;
2.Hashtable中的方法是同步的,而HashMap中的方法在缺省情况下是非同步的。
即是说,在多线程应用程序中,不用专门的操作就安全地可以使用Hashtable了;而对于HashMap,则需要额外的同步机制。
但HashMap的同步问题可通过Collections的一个静态方法得到解决:
MapCollections.synchronizedMap(Mapm)
这个方法返回一个同步的Map,这个Map封装了底层的HashMap的所有方法,使得底层的HashMap即使是在多线程的环境中也是安全的。
3.在HashMap中,null可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为null。
当get()方法返回null值时,即可以表示HashMap中没有该键,也可以表示该键所对应的值为null。
因此,在HashMap中不能由get()方法来判断HashMap中是否存在某个键,而应该用containsKey()方法来判断。
Vector、ArrayList和List的异同
线性表,链表,哈希表是常用的数据结构,在进行Java开发时,JDK已经为我们提供了一系列相应的类来实现基本的数据结构。
这些类均在java.util包中。
本文试图通过简单的描述,向读者阐述各个类的作用以及如何正确使用这些类。
Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set
Map
├Hashtable
├HashMap
└WeakHashMap
Collection接口
Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素(Elements)。
一些Collection允许相同的元素而另一些不行。
一些能排序而另一些不行。
JavaSDK不提供直接继承自Collection的类,JavaSDK提供的类都是继承自Collection的“子接口”如List和Set。
所有实现Collection接口的类都必须提供两个标准的构造函数:
无参数的构造函数用于创建一个空的Collection,有一个Collection参数的构造函数用于创建一个新的Collection,这个新的Collection与传入的Collection有相同的元素。
后一个构造函数允许用户复制一个Collection。
如何遍历Collection中的每一个元素?
不论Collection的实际类型如何,它都支持一个iterator()的方法,该方法返回一个迭代子,使用该迭代子即可逐一访问Collection中每一个元素。
典型的用法如下:
Iteratorit=collection.iterator();//获得一个迭代子
while(it.hasNext()){
Objectobj=it.next();//得到下一个元素
}
由Collection接口派生的两个接口是List和Set。
List接口
List是有序的Collection,使用此接口能够精确的控制每个元素插入的位置。
用户能够使用索引(元素在List中的位置,类似于数组下标)来访问List中的元素,这类似于Java的数组。
和下面要提到的Set不同,List允许有相同的元素。
除了具有Collection接口必备的iterator()方法外,List还提供一个listIterator()方法,返回一个ListIterator接口,和标准的Iterator接口相比,ListIterator多了一些add()之类的方法,允许添加,删除,设定元素,还能向前或向后遍历。
实现List接口的常用类有LinkedList,ArrayList,Vector和Stack。
LinkedList类
LinkedList实现了List接口,允许null元素。
此外LinkedList提供额外的get,remove,insert方法在LinkedList的首部或尾部。
这些操作使LinkedList可被用作堆栈(stack),队列(queue)或双向队列(deque)。
注意LinkedList没有同步方法。
如果多个线程同时访问一个List,则必须自己实现访问同步。
一种解决方法是在创建List时构造一个同步的List:
Listlist=Collections.synchronizedList(newLinkedList(...));
ArrayList类
ArrayList实现了可变大小的数组。
它允许所有元素,包括null。
ArrayList没有同步。
size,isEmpty,get,set方法运行时间为常数。
但是add方法开销为分摊的常数,添加n个元素需要O(n)的时间。
其他的方法运行时间为线性。
每个ArrayList实例都有一个容量(Capacity),即用于存储元素的数组的大小。
这个容量可随着不断添加新元素而自动增加,但是增长算法并没有定义。
当需要插入大量元素时,在插入前可以调用ensureCapacity方法来增加ArrayList的容量以提高插入效率。
和LinkedList一样,ArrayList也是非同步的(unsynchronized)。
Vector类
Vector非常类似ArrayList,但是Vector是同步的。
由Vector创建的Iterator,虽然和ArrayList创建的Iterator是同一接口,但是,因为Vector是同步的,当一个Iterator被创建而且正在被使用,另一个线程改变了Vector的状态(例如,添加或删除了一些元素),这时调用Iterator的方法时将抛出ConcurrentModificationException,因此必须捕获该异常。
Stack类
Stack继承自Vector,实现一个后进先出的堆栈。
Stack提供5个额外的方法使得Vector得以被当作堆栈使用。
基本的push和pop方法,还有peek方法得到栈顶的元素,empty方法测试堆栈是否为空,search方法检测一个元素在堆栈中的位置。
Stack刚创建后是空栈。
Set接口
Set是一种不包含重复的元素的Collection,即任意的两个元素e1和e2都有e1.equals(e2)=false,Set最多有一个null元素。
很明显,Set的构造函数有一个约束条件,传入的Collection参数不能包含重复的元素。
请注意:
必须小心操作可变对象(MutableObject)。
如果一个Set中的可变元素改变了自身状态导致Object.equals(Object)=true将导致一些问题。
Map接口
请注意,Map没有继承Collection接口,Map提供key到value的映射。
一个Map中不能包含相同的key,每个key只能映射一个value。
Map接口提供3种集合的视图,Map的内容可以被当作一组key集合,一组value集合,或者一组key-value映射。
Hashtable类
Hashtable继承Map接口,实现一个key-value映射的哈希表。
任何非空(non-null)的对象都可作为key或者value。
添加数据使用put(key,value),取出数据使用get(key),这两个基本操作的时间开销为常数。
Hashtable通过initialcapacity和loadfactor两个参数调整性能。
通常缺省的loadfactor0.75较好地实现了时间和空间的均衡。
增大loadfactor可以节省空间但相应的查找时间将增大,这会影响像get和put这样的操作。
使用Has
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- java 程序员 面试 必备 32 要点