(一) Java 部分java
一、 列举出 JAVA 中 6 个比较经常使用的包【天威诚信面试题】mysql
【参考答案】c++
java.lang;java.util;java.io;java.sql;java.awt;java.net;javax.swing程序员
二、 JDK 中哪些类是不能继承的? 【信雅达面试题】web
【参考答案】面试
不能继承的是类是那些用final关键字修饰的类。通常比较基本的类型或防止扩展类无心间破坏原来方法的实现的类型都应该是final的。ajax
三、 String 是最基本的数据类型吗 ? 【天能智健面试题】算法
【参考答案】spring
基本数据类型包括byte、int、char、long、float、double、boolean和short。sql
因此String不属于基本数据类型范畴内,但String属于最多见一种引用类型。
四、 short s1 = 1; s1 = s1 + 1; 有什么错 ? short s1 = 1; s1 += 1; 有什么错 ? 【博炎科技面试题】
【参考答案】
对于short s1 = 1; s1 = s1 + 1;因为s1+1运算时会自动提高表达式的类型,因此结果是int型,再赋值给short类型s1时,编译器会提示错误,须要强制转换类型。
对于short s1 = 1; s1 += 1;因为+=是java语言规定的运算符,Java编译器会对它进行特殊处理,所以能够正确编译。
【分析】
主要考查几种基本数据类型在运算时的,由低到高会自动转换,而由高到低时会强制转换。
五、 Java 对象初始化顺序?【腾鹏科技面试题】
【参考答案】
分为两种,一种是本类的初始化,一种是含有父类的初始化顺序。这里分开来讲,
本类的初始化顺序是:静态变量、静态初始化块、变量、初始化块、构造函数
继承类的初始化顺序是:父类静态变量、父类静态初始化块、子类静态变量、子类静态初始块、父类变量、父类初始化块、父类构造函数、子类变量、子类初始化块、子类构造函数。
【分析】
static{
System.out.println("静态块");
}
{
System.out.println("初始化模块"); }
public ClassName() {
System.out.println("构造方法");
}
说明:
原则上回答全面的话,应该是完整的说出带有继承的这种类的初始化过程,下面有个步骤能够参考:
1.装载程序的时候首先找到的是它的基(父)类,若是有多层基(父)类则会一级一级的往上找最后找到根基(父)类。
2.执行根基础(父)类中的static初始化,再执行下一个衍生类中的static,依此类推,一直保持这个顺序。
3.此时类已经装载完毕,开始建立对象,全部的基本数据类型都会设成它们的默认值,对象句柄设为null
4.调用基础(父)类的构造方法,基础(父)类的构建采用与衍生类构造方法彻底相同的处理过程。
5.构造方法初始完以后,进行变量的初始化。
6.执行构造方法中剩余的部分。
六、 写几个线程安全类,不安全的,支持排序的类名?【软通动力面试题】
【参考答案】
Ø线程安全类:Vector、Hashtable、Stack。
Ø线程不安全的类:ArrayList、Linkedlist、HashSet、TreeSet、HashMap、TreeMap等。
Ø支持排序的类有HashSet、LinkedHashSet、TreeSet等(Set接口下的实现都支持排序)
【分析】
此题主要考查集合框架的知识。在集合框架中Collection接口为集合的根类型,提供集合操做的经常使用API方法,该接口下派生出两个子接口,一个是不支持排序的List接口,一个是有自身排序的Set接口,因此回答排序与不排序分别从两接口的实现中在做答。线程安全上来讲,Vector类比同属于List接口的ArrayList要早,是一个线程安全的类,在JDK1.2之后才推出一个异步的ArrayList类,比Vector类效率高。同理Stack继承自Vector也线程安全的类,另外在在Map接口的实如今Hashtable也是个线程安全的类。
七、 哪几个方法能够实现一个线程?【上海华信面试题】
【参考答案】
一是继承Thread,重写Thread类的方法run方法;另种是实现runnable接口并实现run方法。
【分析】
考查线程的基本实现,不少公司喜欢考查这方面知识,另外补充一下关于线程的run方法,在多线程API中启动一个线程是调用start()方法,线程进入就绪状态。
八、 STOP() 和 SUSPEND() 不推荐使用的缘由?
【参考答案】
stop()是由于它不安全。它会解除由线程获取的全部锁定,当在一个线程对象上调用stop()方法时,这个线程对象所运行的线程就会当即中止,假如一个线程正在执行:synchronized void { x = 3; y = 4;}因为方法是同步的,多个线程访问时总能保证x,y被同时赋值,而若是一个线程正在执行到x = 3;时,被调用了stop()方法,即便在同步块中,它也干脆地stop了,这样就产生了不完整的残废数据。而多线程编程中最最基础的条件要保证数据的完整性,因此请忘记线程的stop方法,之后咱们不再要说“中止线程”了。并且若是对象处于一种不连贯状态,那么其余线程能在那种状态下检查和修改它们。
suspend()方法容易发生死锁。调用suspend()的时候,目标线程会停下来,但却仍然持有在这以前得到的锁定。此时,其余任何线程都不能访问锁定的资源,除非被"挂起"的线程恢复运行。对任何线程来讲,若是它们想恢复目标线程,同时又试图使用任何一个锁定的资源,就会形成死锁。因此不该该使用suspend(),而应在本身的Thread类中置入一个标志,指出线程应该活动仍是挂起。若标志指出线程应该挂起,便用wait()命其进入等待状态。若标志指出线程应当恢复,则用一个notify()从新启动线程。
【分析】
九、 "==" 和 equals 方法有什么区别? 【中科软】
【参考答案】
==操做符专门用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存储的数值是否相同,要比较两个基本类型的数据或两个引用变量是否相等,只能用==操做符。
若是一个变量指向的数据是对象类型的,那么,这时候涉及了两块内存,对象自己占用一块内存(堆内存),变量也占用一块内存,例如Objet 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方法,那么它将继承Object类的equals方法,Object类的equals方法的实现代码以下:
boolean equals(Object o){
return this==o;
}
这说明,若是一个类没有本身定义equals方法,它默认的equals方法(从Object类继承的)就是使用==操做符,也是在比较两个变量指向的对象是不是同一对象,这时候使用equals和使用==会获得一样的结果,若是比较的是两个独立的对象则总返回false。若是你编写的类但愿可以比较该类建立的两个实例对象的内容是否相同,那么你必须覆盖equals方法,由你本身写代码来决定在什么状况便可认为两个对象的内容是相同的。
十、 静态变量和实例变量的区别?
【参考答案】
在语法定义上的区别:静态变量前要加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);
}
}
备注:这个解答除了说清楚二者的区别外,最后还用一个具体的应用例子来讲明二者的差别,体现了本身有很好的解说问题和设计案例的能力,思惟敏捷,超过通常程序员,有写做能力!
十一、 构造器的名能不能和类的名字相同?
【参考答案】
构造器的名称必须与类名相同。
【分析】
构造器或构造函数(有些书这样叫)主要用来对类的成员变量进行初始化,当类建立实例时调用。
十二、 在一个主方法类可不能够调用一个非静态的方法?
【参考答案】
能够调用。由于Java的主方法(main)方法自己也是static类型方法,一个static类型方法,发起对另外一个static方法的调用没有问题。
【分析】
静态方法能够调用其它的静态方法,可是不能调用非静态方法,这个比如Java中的类变量与实例变量的关系。类变量是被全部类成员共享,而实例变量只被该实例共享,
1三、 一个类中可不能够有 2 个公共的方法?
【参考答案】
能够。Java中对公共方法的个数没有约束,可是对公共的类有约束,一个Java源文件中只能定义一个public类型的类。
1四、 GC 是什么,为何要使用它?【阿斯拓】
【参考答案】
GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会致使程序或系统的不稳定甚至崩溃,Java提供的GC功能能够自动监测对象是否超过做用域,从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的显示操做方法。
【分析】
1五、 说一下垃圾回收的原理,能够直接从内存中回收吗 ?
【参考答案】
Java语言中一个显著的特色就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候再也不须要考虑内存管理。垃圾回收能够有效的防止内存泄露,有效的使用能够使用的内存。垃圾回收器一般是做为一个单独的低级别的线程运行,不可预知的状况下对内存堆中已经死亡的或者长时间没有使用的对象进行清除和回收,程序员不能实时的调用垃圾回收器对某个对象或全部对象进行垃圾回收,由于Java语言规范并不保证GC必定会执行。回收机制有分代复制垃圾回收和标记垃圾回收,增量垃圾回收。
【分析】
1六、 Java 的异常有哪几种,有什么区别?
【参考答案】
两大类,通常异常和运行时异常。通常异常,这些异常是在定义方法时声明抛出的,这些异常必需用try catch抛出,或throws处理,若是不处理,程序将编译失败。好比:IOException、FileNotFoundException、SQLException等。
运行时异常是程序运行时可能报出的异常。能够用try catch抓取,也能够不作任何处理。例如:NullPointerException异常就是一种比较常见的运行时异常。
【分析】
1七、 switch 语句可否做用在 byte 上,可否做用在 long 上,可否做用在 String 上 ?
【参考答案】
在switch(表达式)中,括号表达式只能是一个整数表达式或者枚举常量(更大字体),整数表达式能够是int基本类型或Integer包装类型,因为,byte,short,char均可以隐含转换为int,因此,这些类型以及这些类型的包装类型也是能够的。显然,long和String类型都不符合switch的语法规定,而且不能被隐式转换成int类型,因此,它们不能做用于swtich语句中。
1八、 Integer 与 int 的区别?
【参考答案】
int是java提供的8种原始数据类型之一,另外Java为每一个原始类型提供了封装类,Integer是java为int提供的封装类。int的默认值为0,而Integer的默认值为null,即Integer能够区分出未赋值和值为0的区别,int则没法表达出未赋值的状况。
1九、 Java Reflection 是什么 ? 【】
【参考答案】
JAVA反射,Reflection是Java程序开发语言的特征之一,它容许运行中的Java程序对自身进行检查,或者说"自审",并能直接操做程序的内部属性。
【分析】
20、 写几个 java.lang.Object 类中的方法名称。
【参考答案】
主要有equals()、toString()、getClass()、hashCode()、clone()、notify()、wait()、notify()方法。
【分析】
这种题能记多少个就说多少个,不必定要求你全部的都记住,可是要理解其中部分重要方法的含义和做用。
2一、 & 和 && 的区别?
【参考答案】
&和&&均可以用做逻辑与的运算符,表示逻辑与(and),当运算符两边的表达式的结果都为true时,整个运算结果才为true,不然,只要有一方为false,则结果为false。
&&还具备短路的功能,即若是第一个表达式为false,则再也不计算第二个表达式。
&还能够用做位运算符,当&操做符两边的表达式不是boolean类型时,&表示按位与操做,咱们一般使用0x0f来与一个整数进行&运算,来获取该整数的最低4个bit位。
【分析】
先说分别说二者的做用,再说出&&和&各自的不一样之处。
2二、 数组有没有 length() 这个方法, String 有没有 length() 这个方法。
【参考答案】
数组没有length()方法,但有length属性
String有length()方法。
【分析】
考查平时使用数组和字符串的一些细节,通常在使用
2三、 String s=new String( “ xyz ” ) 建立了几个对象
【参考答案】
2个string对象,一个是=null的s,一个是=“xyz”的string
两个或一个”xyz”对应一个对象,这个对象放在字符串常量缓冲区,常量”xyz”无论出现多少遍,都是缓冲区中的那一个。New String每写一遍,就建立一个新的对象,它一句那个常量”xyz”对象的内容来建立出一个新String对象。若是之前就用过’xyz’,这句表明就不会建立”xyz”本身了,直接从缓冲区拿。
【分析】
2四、 能不能本身写个类,也叫 java.lang.String ?
能够,但在应用的时候,须要用本身的类加载器去加载,不然,系统的类加载器永远只是去加载jre.jar包中的那个java.lang.String。因为在tomcat的web应用程序中,都是由webapp本身的类加载器先本身加载WEB-INF/classess目录中的类,而后才委托上级的类加载器加载,若是咱们在tomcat的web应用程序中写一个java.lang.String,这时候Servlet程序加载的就是咱们本身写的java.lang.String,可是这么干就会出不少潜在的问题,原来全部用了java.lang.String类的都将出现问题。
虽然java提供了endorsed技术,能够覆盖jdk中的某些类,具体作法是….。可是,可以被覆盖的类是有限制范围,反正不包括java.lang这样的包中的类。
例如,运行下面的程序:
package java.lang;
public class String {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("string");
}
}
报告的错误以下:
java.lang.NoSuchMethodError: main
Exception in thread "main"
这是由于加载了jre自带的java.lang.String,而该类中没有main方法。
2五、 你对面向对象思想的理解?
【参考答案】
面向对象编程(Object-Oriented Programming)简称OOP技术,是开发计算机应用程序的一种新方法、新思想。过去的面向过程编程中经常会致使全部的代码都包含在几个模块中,使程序难以阅读和维护,在作一些修改时经常牵一动百,使之后的开发和维护难觉得继。而使用OOP技术,使用许多代码模块,每一个模块都只提供特定的功能,它们是彼此独立的,能够增长代码重用的概率,更加有利于软件的开发、维护和升级。另外OOP的三大核心特性:继承、封装、多态的特性,使得在面对象编上可以设计出高内聚、低耦合的系统结构,使得系统更灵活、更容易扩展,并且成本较低,因此这一编程思想是目前一种应用最为广泛的软件设计思想。
【分析】
2六、 最多见的 runtime exception 运行时异常?
【参考答案】
ClassCastException(类型转换异常)、NumberFormatException(格式化异常)、
ArrayIndexOutOfBoundsException(数组越界异常)、ArithmeticException(算术异常)、NullPointerException(空指针异常)等等
【分析】
这道题主要考查你们平时在项目开发过程当中常常遇到的一些异常类型信息,经过这些异常来考查你们的项目经验与项目排错能力。
2七、 用 JDBC 来实现访问数据库记录能够采用下面的几个步骤:
【参考答案】
一、经过驱动器管理器获取链接接口(Connection)。
二、得到Statement或它的子类。
三、指定Statement中的参数。
四、经过Statement发送SQL语句。
五、检查并处理返回的结果。
六、关闭Statement。
七、关闭链接接
【分析】
2八、 Error 和 exception 的区别与联系?
【参考答案】
error表示恢复不是不可能,但很困难的状况下的一种严重问题。好比说内存溢,网络故障等,不可能期望程序能处理的一类错误。
Exception表示一种由程序设计或实现问题,像咱们常说的异常处理,就是属于这类,通常程序能够捕获和处理这些异常。
【分析】
这道题的难点在Error不少时候因为咱们没法重现这种Error致使不少同窗甚至不知道Error究竟是什么,因此很容易把题目中的两种错误划上等号。
2九、 String s = "Hello";s = s + " world!"; 这两行代码执行后,原始的 String 对象中的内容到底变了没有?
【参考答案】
没有。由于String被设计成不可变(immutable)类,因此它的全部对象都是不可变对象。在这段代码中,s原先指向一个String对象,内容是"Hello",而后咱们对s进行了+操做,那么s所指向的那个对象是否发生了改变呢?答案是没有。这时,s不指向原来那个对象了,而指向了另外一个String对象,内容为"Hello world!",原来那个对象还存在于内存之中,只是s这个引用变量再也不指向它了。
经过上面的说明,咱们很容易导出另外一个结论,若是常常对字符串进行各类各样的修改,或者说,不可预见的修改,那么使用String来表明字符串的话会引发很大的内存开销。由于String对象创建以后不能再改变,因此对于每个不一样的字符串,都须要一个String对象来表示。这时,应该考虑使用StringBuffer类,它容许修改,而不是每一个不一样的字符串都要生成一个新的对象。而且,这两种类的对象转换十分容易。
同时,咱们还能够知道,若是要使用内容相同的字符串,没必要每次都new一个String。例如咱们要在构造器中对一个名叫s的String引用变量进行初始化,把它设置为初始值,应当这样作:
public class Demo {
private String s;
...
public Demo {
s = "Initial Value";
}
...
}
而非
s = new String("Initial Value");
后者每次都会调用构造器,生成新对象,性能低下且内存开销大,而且没有意义,由于String对象不可改变,因此对于内容相同的字符串,只要一个String对象来表示就能够了。也就说,屡次调用上面的构造器建立多个对象,他们的String类型属性s都指向同一个对象。
上面的结论还基于这样一个事实:对于字符串常量,若是内容相同,Java认为它们表明同一个String对象。而用关键字new调用构造器,老是会建立一个新的对象,不管内容是否相同。
至于为何要把String类设计成不可变类,是它的用途决定的。其实不仅String,不少Java标准类库中的类都是不可变的。在开发一个系统的时候,咱们有时候也须要设计不可变类,来传递一组相关的值,这也是面向对象思想的体现。不可变类有一些优势,好比由于它的对象是只读的,因此多线程并发访问也不会有任何问题。固然也有一些缺点,好比每一个不一样的状态都要一个对象来表明,可能会形成性能上的问题。因此Java标准类库还提供了一个可变版本,即StringBuffer。
30、 Jdk 1.5 的新特性?
【参考答案】
JDK1.5的一个重要主题就是经过新增一些特性来简化开发,这些特性主要包括:泛型、ForEach循环、自动装包/拆包、枚举、可变参数、静态导入这些。
【分析】
3一、 面向对象的特征有哪些方面?
【参考答案】
面向对象的编程语言有封装、继承、多态等3个主要的特征。
u封装
封装是保证软件部件具备优良的模块性的基础,封装的目标就是要实现软件部件的“高内聚、低耦合”,防止程序相互依赖性而带来的变更影响。面向对象的封装就是把描述一个对象的属性和行为的代码封装在一个“模块”中,也就是一个类中,属性用变量定义,行为用方法进行定义,方法能够直接访问同一个对象中的属性。
u继承
在定义和实现一个类的时候,能够在一个已经存在的类的基础之上来进行,把这个已经存在的类所定义的内容做为本身的内容,并能够加入若干新的内容,或修改原来的方法使之更适合特殊的须要,这就是继承。继承是子类自动共享父类数据和方法的机制,这是类之间的一种关系,提升了软件的可重用性和可扩展性。
u多态
多态是指程序中定义的引用变量所指向的具体类型和经过该引用变量发出的方法调用在编程时并不肯定,而是在程序运行期间才肯定,即一个引用变量倒底会指向哪一个类的实例对象,该引用变量发出的方法调用究竟是哪一个类中实现的方法,必须在由程序运行期间才能决定。由于在程序运行时才肯定具体的类,这样,不用修改源程序代码,就可让引用变量绑定到各类不一样的类实现上,从而致使该引用调用的具体方法随之改变,即不修改程序代码就能够改变程序运行时所绑定的具体代码,让程序能够选择多个运行状态,这就是多态性。多态性加强了软件的灵活性和扩展性。
3二、 JVM 工做原理?
运行jvm字符码的工做是由解释器来完成的。解释执行过程分三步进行:
代码的装入、代码的校验、和代码的执行。
装入代码的工做由“类装载器class loader”完成。类装载器负责装入运行一个程序须要的全部代码,这也包括程序代码中的类所继承的类和被调用的类。当类装载器装入一个类时,该类被放在本身的名字空间中。除了经过符号引用本身名字空间之外的类,类之间没有其余办法能够影响其余类。在本台计算机的全部类都在同一地址空间中,而全部从外部引进的类,都有一个本身独立的名字空间。这使得本地类经过共享相同的名字空间得到较高的运行效率,同时又保证它们与从外部引进的类不会相互影响。当装入了运行程序须要的全部类后,解释器即可肯定整个可执行程序的内存布局。解释器为符号引用与特定的地址空间创建对应关系及查询表。经过在这一阶段肯定代码的内布局,java很好地解决了由超类改变而使子类
崩溃的问题,同时也防止了代码的非法访问。随后,被装入的代码由字节码校验器进行检查。校验器能够发现操做数栈益处、非法数据类型转化等多种错误。经过校验后,代码便开始执行了。
Java字节码的执行有两种方式:
1)即时编译方式:解释器先将字节编译成机器码,而后再执行该机器码。
2)解释执行方式:解释器经过每次解释并执行一小段代码来完成java字节。
码程序的全部操做。
3三、 说说 Java 中的内存分配 ?
Java把内存分红两种,一种叫作栈内存,一种叫作堆内存
在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配。当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的做用域后,java会自动释放掉为该变量分配的内存空间,该内存空间能够马上被另做它用。
堆内存用于存放由new建立的对象和数组。在堆中分配的内存,由java虚拟机自动垃圾回收器来管理。在堆中产生了一个数组或者对象后,还能够在栈中定义一个特殊的变量,这个变量的取值等于数组或者对象在堆内存中的首地址,在栈中的这个特殊的变量就变成了数组或者对象的引用变量,之后就能够在程序中使用栈内存中的引用变量来访问堆中的数组或者对象,引用变量至关于为数组或者对象起的一个别名,或者代号。
引用变量是普通变量,定义时在栈中分配内存,引用变量在程序运行到做用域外释放。而数组&对象自己在堆中分配,即便程序运行到使用new产生数组和对象的语句所在地代码块以外,数组和对象自己占用的堆内存也不会被释放,数组和对象在没有引用变量指向它的时候,才变成垃圾,不能再被使用,可是仍然占着内存,在随后的一个不肯定的时间被垃圾回收器释放掉。这个也是java比较占内存的主要缘由。可是在写程序的时候,能够人为的控制。
3四、 final, finally, finalize 的区别。
【参考答案】
final用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
内部类要访问局部变量,局部变量必须定义成final类型,例如,一段代码……
finally是异常处理语句结构的一部分,表示老是执行。
finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,能够覆盖此方法提供垃圾收集时的其余资源回收,例如关闭文件等。JVM不保证此方法总被调用
3五、 E xtends 和 I mplement 的不一样?
【参考答案】
extends是继承父类,只要那个类不是声明为final或者那个类定义为abstract的就能继承,JAVA中不支持多重继承,可是能够用接口来实现,这样就要用到implements,继承只能继承一个类,但implements能够实现多个接口,用逗号分开就好了
好比class A extends B implements C,D,E
3六、 抽象类是否能够没有抽象方法?为何?
【参考答案】
能够在java中用abstract关键字来修饰一个类时,这个类叫作抽象类。
抽象类中不必定要包含abstract方法,但一个类中包含了abstract方法,则这个类必须声明为abstract类。
3七、 静态的多态和动态的多态的区别?
【参考答案】
静态的多态:即为重载;方法名相同,参数个数或类型不相同。(overloading)
动态的多态:即为重写;子类覆盖父类的方法,将子类的实例传与父类的引用调用的是子类的方法实现接口的实例传与接口的引用调用的实现类的方法。
3八、 说出一些经常使用的类,包,接口,请各举 5 个 ?
【参考答案】
经常使用的类:String、StringBuffer、Integer、Vector、ArrayList、Hashtable等
经常使用的包:java.lang java.io java.util、java.sql。
经常使用的接口:集合中的List、Set、Map接口;与Servlet API相关的Servlet接口、HttpServletRequest,HttpServletResponse,HttpSession接口等。
3九、 Collections 和 C ollection 的区别【天晟科技】
【参考答案】
Collection是个java.util下的接口,它是各类集合结构的父接口,定义了集合对象的基本操做方法。Collections是个java.util下的工具类,它包含有各类有关集合操做的静态方法,主要是针对集合类的一个帮助类或者叫包装类,它提供一系列对各类集合的搜索,排序,线程安全化等操做方法。
40、 Class.forName 的做用 ? 为何要用 ?
【参考答案】
按参数中指定的字符串形式的类名去搜索并加载相应的类,若是该类字节码已经被加载过,则返回表明该字节码的Class实例对象,不然,按类加载器的委托机制去搜索和加载该类,若是全部的类加载器都没法加载到该类,则抛出ClassNotFoundException。加载完这个Class字节码后,接着就能够使用Class字节码的newInstance方法去建立该类的实例对象了。有时候,咱们程序中全部使用的具体类名在设计时(即开发时)没法肯定,只有程序运行时才能肯定,这时候就须要使用Class.forName去动态加载该类,这个类名一般是在配置文件中配置的,例如,spring的ioc中每次依赖注入的具体类就是这样配置的,jdbc的驱动类名一般也是经过配置文件来配置的,以便在产品交付使用后不用修改源程序就能够更换驱动类名。
4一、 Socket 如何获取本地 ip 地址?
【参考答案】
InetAddress类提供的API来访问。InetAddress.getLocalAddress()
【分析】
4二、 接口是否可继承接口 ? 抽象类是否可实现 (implements) 接口 ? 抽象类是否可继承具体类【天威诚信面试题】
【参考答案】
接口能够继承接口。抽象类能够实现(implements)接口,抽象类是否可继承具体类。抽象类中能够有静态的main方法。
备注:只要明白了接口和抽象类的本质和做用,这些问题都很好回答,你想一想,若是你是java语言的设计者,你是否会提供这样的支持,若是不提供的话,有什么理由吗?若是你没有道理不提供,那答案就是确定的了。
只有记住抽象类与普通类的惟一区别就是不能建立实例对象和容许有abstract方法。
4三、 用最有效率的方法算出 2 乘以 8 等於几 ?
【参考答案】
2 << 3
【分析】
由于将一个数左移n位,就至关于乘以了2的n次方,那么,一个数乘以8只要将其左移3位便可,而位运算cpu直接支持的,效率最高,因此2乘以8等於几的最效率的方法是2 << 3。
4四、 char 型变量中能不能存贮一个中文汉字 ? 为何 ?
【参考答案】
char型变量是用来存储Unicode编码的字符的,unicode编码字符集中包含了汉字,因此,char型变量中固然能够存储汉字啦。不过,若是某个特殊的汉字没有被包含在unicode编码字符集中,那么,这个char型变量中就不能存储这个特殊汉字。补充说明:unicode编码占用两个字节,因此,char类型的变量也是占用两个字节。
4五、 写 clone() 方法时,一般都有一行代码,是什么?
【参考答案】
clone有缺省行为,super.clone();由于首先要把父类中的成员复制到位,而后才是复制本身的成员。
4六、 说说经常使用集合类有哪些?有哪些方法?
【参考答案】
一般咱们使用的集合类都大可能是由List、Set、Map这三类接口派生出来的类,例如:
ArrayList、Vector、LinkedList、Stack、TreeSet、Hashtable、HashMap等
集合类的大部分方法都是由Collection接口定义的,主要包括有:
add(Ee)、remove(Object e)、addAll(),remove()、 contains(Object obj) 、clear()等
4七、 请说出做用域 public , private , protected ,以及不写时的区别 ? 【天威诚信面试题】
【参考答案】
这四个做用域的可见范围以下表所示。
说明:若是在修饰的元素上面没有写任何访问修饰符,则表示friendly。
做用域同一类同一package子孙类其余package
public√√√√
protected√√√×
friendly√√××
private√×××
备注:只要记住了有4种访问权限,4个访问范围,而后将全选和范围在水平和垂直方向上分别按排从小到大或从大到小的顺序排列,就很容易画出上面的图了。
4八、 构造器 Constructor 是否可被 override? 【亿阳通信面试题】
【参考答案】
构造器Constructor不能被继承,所以不能重写Override,但能够被重载Overload。
4九、 是否能够从一个 static 方法内部发出对非 static 方法的调用? 【世承软件面试题】
【参考答案】
不能够。由于非static方法是要与对象关联在一块儿的,必须建立一个对象后,才能够在该对象上进行方法调用,而static方法调用时不须要建立对象,能够直接调用。
50、 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。
5一、 abstract class (抽象类)和 interface (接口)有什么区别 ? 【百度应用中心面试题】
【参考答案】
含有abstract修饰符的class即为抽象类,abstract类不能建立的实例对象。含有abstract方法的类必须定义为abstract class,abstract class类中的方法没必要是抽象的。abstract class类中定义抽象方法必须在具体(Concrete)子类中实现,因此,不能有抽象构造方法或抽象静态方法。若是的子类没有实现抽象父类中的全部抽象方法,那么子类也必须定义为abstract类型。
接口(interface)能够说成是抽象类的一种特例,接口中的全部方法都必须是抽象的。接口中的方法定义默认为public abstract类型,接口中的成员变量类型默认为public static final。
下面比较一下二者的语法区别:
1.抽象类能够有构造方法,接口中不能有构造方法。
2.抽象类中能够有普通成员变量,接口中没有普通成员变量
3.抽象类中能够包含非抽象的普通方法,接口中的全部方法必须都是抽象的,不能有非抽象的普通方法。
4.抽象类中的抽象方法的访问类型能够是public,protected和(默认类型,虽然
eclipse下不报错,但应该也不行),但接口中的抽象方法只能是public类型的,而且默认即为public abstract类型。
5.抽象类中能够包含静态方法,接口中不能包含静态方法
6.抽象类和接口中均可以包含静态成员变量,抽象类中的静态成员变量的访问类型能够任意,但接口中定义的变量只能是public static final类型,而且默认即为public static final类型。
7.一个类能够实现多个接口,但只能继承一个抽象类。
下面接着再说说二者在应用上的区别:
【分析】
这道题的思路是先从整体解释抽象类和接口的基本概念,而后再比较二者的语法细节,最后再说二者的应用区别。比较二者语法细节区别的条理是:先从一个类中的构造方法、普通成员变量和方法(包括抽象方法),静态变量和方法,继承性等方面来回答。
5二、 Collection 框架中实现比较要实现什么接口 ?
【参考答案】
Comparable、Comparator接口
5三、 是否能够继承 String 类 ?
【参考答案】
String类是final类故不能够继承。
5四、 String 和 StringBuffer 的区别
【参考答案】
JAVA平台提供了两个类:String和StringBuffer,它们能够储存和操做字符串,即包含多个字符的字符数据。String类表示内容不可改变的字符串。而StringBuffer类表示内容能够被修改的字符串。当你知道字符数据要改变的时候你就能够使用StringBuffer。典型地,你能够使用StringBuffers来动态构造字符数据。另外,String实现了equals方法,new String(“abc”).equals(new String(“abc”)的结果为true,而StringBuffer没有实现equals方法,因此,new StringBuffer(“abc”).equals(new StringBuffer(“abc”)的结果为false。
String覆盖了equals方法和hashCode方法,而StringBuffer没有覆盖equals方法和hashCode方法,因此,将StringBuffer对象存储进Java集合类中时会出现问题。
5五、 StringBuffer 与 StringBuilder 的区别
【参考答案】
StringBuffer和StringBuilder类都表示内容能够被修改的字符串,StringBuilder是线程不安全的,运行效率高,若是一个字符串变量是在方法里面定义,这种状况只可能有一个线程访问它,不存在不安全的因素了,则用StringBuilder。若是要在类里面定义成员变量,而且这个类的实例对象会在多线程环境下使用,那么最好用StringBuffer。
5六、 try {} 里有一个 return 语句,那么紧跟在这个 try 后的 finally {} 里的 code 会不会被执行,何时被执行,在 return 前仍是后 ? 【杭州天眼科技】
【参考答案】
答案是在return以前。
【分析】
程序代码的运行结果:
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(new Test().test());;
}
static int test()
{
int x = 1;
try
{
return x;
}
finally
{
++x;
}
}
}
---------执行结果---------
1
运行结果是1,为何呢?主函数调用子函数并获得结果的过程,比如主函数准备一个空罐子,当子函数要返回结果时,先把结果放在罐子里,而后再将程序逻辑返回到主函数。所谓返回,就是子函数说,我不运行了,你主函数继续运行吧,这没什么结果可言,结果是在说这话以前放进罐子里的。
下面的程序代码输出的结果是多少?
public class smallT
{
public static void main(String args[])
{
smallT t = new smallT();
int b = t.get();
System.out.println(b);
}
public int get()
{
try
{
return 1 ;
}
finally
{
return 2 ;
}
}
}
返回的结果是2。
我能够经过下面一个例子程序来帮助我解释这个答案,从下面例子的运行结果中能够发现,try中的return语句调用的函数先于finally中调用的函数执行,也就是说return语句先执行,finally语句后执行,因此,返回的结果是2。Return并非让函数立刻返回,而是return语句执行后,将把返回结果放置进函数栈中,此时函数并非立刻返回,它要执行finally语句后才真正开始返回。
在讲解答案时能够用下面的程序来帮助分析:
public class Test {
/**
* @param args add by zxx ,Dec 9, 2008
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(new Test().test());;
}
int test()
{
try
{
return func1();
}
finally
{
return func2();
}
}
int func1()
{
System.out.println("func1");
return 1;
}
int func2()
{
System.out.println("func2");
return 2;
}
}
-----------执行结果-----------------
func1
func2
2
结论:finally中的代码比return和break语句后执行。
5七、 Java 中的异常处理机制的简单原理和应用。
【参考答案】
异常是指java程序运行时(非编译)所发生的非正常状况或错误,与现实生活中的事件很类似,现实生活中的事件能够包含事件发生的时间、地点、人物、情节等信息,能够用一个对象来表示,Java使用面向对象的方式来处理异常,它把程序中发生的每一个异常也都分别封装到一个对象来表示的,该对象中包含有异常的信息。
Java对异常进行了分类,不一样类型的异常分别用不一样的Java类表示,全部异常的根类为java.lang.Throwable,Throwable下面又派生了两个子类:Error和Exception,Error表示应用程序自己没法克服和恢复的一种严重问题,程序只有死的份了,例如,说内存溢出和线程死锁等系统问题。Exception表示程序还可以克服和恢复的问题,其中又分为系统异常和普通异常,系统异常是软件自己缺陷所致使的问题,也就是软件开发人员考虑不周所致使的问题,软件使用者没法克服和恢复这种问题,但在这种问题下还可让软件系统继续运行或者让软件死掉,例如,数组脚本越界(ArrayIndexOutOfBoundsException),空指针异常(NullPointerException)、类转换异常(ClassCastException);普通异常是运行环境的变化或异常所致使的问题,是用户可以克服的问题,例如,网络断线,硬盘空间不够,发生这样的异常后,程序不该该死掉。
java为系统异常和普通异常提供了不一样的解决方案,编译器强制普通异常必须try..catch处理或用throws声明继续抛给上层调用方法处理,因此普通异常也称为checked异常,而系统异常能够处理也能够不处理,因此,编译器不强制用try..catch处理或用throws声明,因此系统异常也称为unchecked异常。
5八、 多线程有几种实现方法 ? 同步有几种实现方法 ?
【参考答案】
多线程有两种实现方法,分别是继承Thread类与实现Runnable接口。
同步的实现方面有两种,分别是synchronized,wait与notify。
a.wait():使一个线程处于等待状态,而且释放所持有的对象的lock。
b.sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉InterruptedException异常。
c.notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM肯定唤醒哪一个线程,并且不是按优先级。
d.allnotity():唤醒全部处入等待状态的线程,注意并非给全部唤醒线程一个对象的锁,而是让它们竞争。
5九、 启动一个线程是用 run() 仍是 start()?
【参考答案】
启动一个线程是调用start()方法,使线程就绪状态,之后能够被调度为运行状态,一个线程必须关联一些具体的执行代码,run()方法是该线程所关联的执行代码。
60、 内部类能够引用外部类的成员吗?有没有什么限制?
【参考答案】
彻底能够。若是不是静态内部类,那没有什么限制!
若是你把静态嵌套类看成内部类的一种特例,那在这种状况下不能够访问外部类的普通成员变量,而只能访问外部类中的静态成员。
6一、 List 和 Map 区别 ? 【软通动力】
【参考答案】
一个是存储单列数据的集合,另外一个是存储键和值这样的双列数据的集合,List中存储的数据是有顺序,而且容许重复;Map中存储的数据是没有顺序的,其键是不能重复的,它的值是能够有重复的。
6二、 ArrayList 和 Vector 的区别【博炎科技】
【参考答案】
这两个类都实现了List接口(List接口继承了Collection接口),他们都是有序集合,即存储在这两个集合中的元素的位置都是有顺序的,至关于一种动态的数组,咱们之后能够按位置索引号取出某个元素,而且其中的数据是容许重复的。
接着说ArrayList与Vector的区别,这主要包括两个方面:
一、同步性:
Vector是线程安全的,也就是说是它的方法之间是线程同步的,而ArrayList是线程序不安全的,它的方法之间是线程不一样步的。若是只有一个线程会访问到集合,那最好是使用ArrayList,由于它不考虑线程安全,效率会高些;若是有多个线程会访问到集合,那最好是使用Vector,由于不须要咱们本身再去考虑和编写线程安全的代码。
备注:对于Vector&ArrayList、Hashtable&HashMap,要记住线程安全的问题,记住Vector与Hashtable是旧的,是java一诞生就提供了的,它们是线程安全的,ArrayList与HashMap是java2时才提供的,它们是线程不安全的。
二、数据增加:
ArrayList与Vector都有一个初始的容量大小,当存储进它们里面的元素的个数超过了容量时,就须要增长ArrayList与Vector的存储空间,每次要增长存储空间时,不是只增长一个存储单元,而是增长多个存储单元,每次增长的存储单元的个数在内存空间利用与程序效率之间要取得必定的平衡。Vector默认增加为原来两倍,而ArrayList的增加为原来的1.5倍。ArrayList与Vector均可以设置初始的空间大小,Vector还能够设置增加的空间大小,而ArrayList没有提供设置增加空间的方法。
6三、 heap 和 stack 有什么区别。
【参考答案】
Java的内存分为两类,一类是栈内存,一类是堆内存。栈内存是指程序进入一个方法时,会为这个方法单独分配一块私属存储空间,用于存储这个方法内部的局部变量,当这个方法结束时,分配给这个方法的栈会释放,这个栈中的变量也将随之释放。
堆是与栈做用不一样的内存,通常用于存放不放在当前方法栈中的那些数据,例如,使用
new建立的对象都放在堆里,因此,它不会随方法的结束而消失。方法中的局部变量使
用final修饰后,放在堆中,而不是栈中。
6四、 J ava 类实现序列化的方法(二种)?如在 collection 框架中实现排序,要实现什么样的接口
【参考答案】
java.io.Serializable接口或实现Externalizable接口。
Collection框架中实现比较要实现Comparable接口或Comparator接口,并实现比较方法
6五、 JAVA 实现向数据库添加一列。
【参考答案】
Connection con = null;
ResultSet rs = null;
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
String url="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=db_name";
Connection con = DriverManager.getConnection(url,"","");
StateManager sm =con.createStateMent();
String sql = " alter table student add age int; ";
rs = sm.excute(sql);
6六、 什么是 J ava 序列化,如何实现 java 序列化?或者请解释 Serializable 接口的做用。【东软国际】
【参考答案】
序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。能够对流化后的对象进行读写操做,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操做时所引起的问题。
序列化的实现:将须要被序列化的类实现Serializable接口,该接口没有须要实现的方法,implements Serializable只是为了标注该对象是可被序列化的,而后使用一个输出流(如:FileOutputStream)来构造一个ObjectOutputStream(对象流)对象,使用ObjectOutputStream对象的writeObject(Object obj)方法就能够将参数为obj的对象写出,那么在另外一端,经过ObjectInputStream对象的readObject(Object obj)获取到字节流数据后,要将字节流转换成原对象,这叫反序列化,以便将数据存储在文件中或在网络传输。
Serializable接口描述启用其序列化功能,未实现此接口的类将没法使其任何状态序列化或反序列化。Serializable接口没有方法或字段,仅用于标识可序列化的语义,标识实现了该接口的对象属性可被序列化。
6七、 J ava 中有几种类型的流? JDK 为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类?
【参考答案】
字节流,字符流两种类型流。字节流继承于InputStream、OutputStream;字符流继承于Reader 、 Writer。其它与IO操做相关的类都是派生至上述4个抽象类,如字节相关的:FileInputStream、FileOutputStream类;字符相关的:BufferedReader、BufferedWriter类
6八、 用 JDBC 如何调用存储过程
【参考答案】
经过JDBC组件中的CallableStatement接口实现调用存储过程。
核心代码以下:
Class.forName("com.mysql.jdbc.Driver");
Connection conn=
DriverManager.getConnection("jdbc:mysql:///test","root","root");
CallableStatement cstmt = cn.prepareCall("{call insert_Student(?,?,?)}");
cstmt.registerOutParameter(3,Types.INTEGER);
cstmt.setString(1, "wangwu");
cstmt.setInt(2, 25);
cstmt.execute();
6九、 JAVA 事件有哪些模式?
【参考答案】
一、事件直接驱动模式。它的特色是直接并且快,是必须常用的,主要适合于迅速处理前台的命令,一般就是咱们说的command(命令)模式。。2.监控式事件模式。主要借助第三者来监控和触发事件,就是一般咱们说的观察者模式。特色是:有一个观察者置身事外在按期独立运行着,咱们将咱们要监听的事件向这个观察者注册,这样观察者就代替咱们来监听这个事件,应用客户端经过观察者来得到事件情况。
【分析】
70、 JVM 加载 class 文件原理?
【参考答案】
所谓装载就是寻找一个类或是一个接口的二进制形式并用该二进制形式来构造表明这个类或是这个接口的class对象的过程.
在Java中,类装载器把一个类装入Java虚拟机中,要通过三个步骤来完成:装载、连接和初始化,其中连接又能够分红校验、准备、解析
装载:查找和导入类或接口的二进制数据;
连接:执行下面的校验、准备和解析步骤,其中解析步骤是能够选择的;
校验:检查导入类或接口的二进制数据的正确性;
准备:给类的静态变量分配并初始化存储空间;
解析:将符号引用转成直接引用;
初始化:激活类的静态变量的初始化Java代码和静态Java代码块
JVM中类的装载是由ClassLoader和它的子类来实现的,Java ClassLoader是一个重要的Java运行时系统组件。它负责在运行时查找和装入类文件的类
一个Java应用程序使用两种类型的类装载器:根装载器(bootstrap)和用户定义的装载器(user-defined)。
根装载器以某种默认的方式将类装入,包括那些Java API的类。在运行期间一个Java程序能安装用户本身定义的类装载器。根装载器是虚拟机固有的一部分,而用户定义的类装载器则不是,它是用Java语言写的,被编译成class文件以后而后再被装入到虚拟机,并像其它的任何对象同样能够被实例化。Java类装载器的体系结构以下所示:
Bootstrap(根装载器)
|
Extension (扩展装载器)
|
System
|
UserDefine1
/
UserDefine2 UserDefine3
|
UserDefine4
Java的类装载模型是一种代理(delegation)模型。当JVM要求类装载器CL(ClassLoader)装载一个类时,CL首先将这个类装载请求转发给他的父装载器。只有当父装载器没有装载并没有法装载这个类时,CL才得到装载这个类的机会。这样,全部类装载器的代理关系构成了一种树状的关系。树的根是类的根装载器(bootstrap ClassLoader) ,在JVM中它以"null"表示。除根装载器之外的类装载器有且仅有一个父装载器。在建立一个装载器时,若是没有显式地给出父装载器,那么JVM将默认系统装载器为其父装载器
下面针对各类类装载器分别进行详细的说明:
根(Bootstrap)装载器:该装载器没有父装载器,它是JVM实现的一部分,从sun.boot.class.path装载运行时库的核心代码。
扩展(Extension)装载器:继承的父装载器为根装载器,不像根装载器可能与运行时的操做系统有关,这个类装载器是用纯Java代码实现的,它从java.ext.dirs (扩展目录)中装载代码。
系统(System or Application)装载器:装载器为扩展装载器,咱们都知道在安装JDK的时候要设置环境变量(CLASSPATH ),这个类装载器就是从java.class.path(CLASSPATH环境变量)中装载代码的,它也是用纯Java代码实现的,同时仍是用户自定义类装载器的缺省父装载器。
小应用程序(Applet)装载器:装载器为系统装载器,它从用户指定的网络上的特定目录装载小应用程序代码。
7一、 SOCKET 中有几中链接方式,各有什么区别?
【参考答案】
Sockets有两种主要的操做方式:面向链接(TCP/IP)的和无链接(UDP)的。无链接的操做使用数据报协议,无链接的操做是快速的和高效的,可是数据安全性不佳.面向链接的操做使用TCP协议.面向链接的操做比无链接的操做效率更低,可是数据的安全性更高
【分析】
7二、 抽象类可否被实例化 ?抽象类的做用是什么?
【参考答案】
抽象类通常不能被实例化;抽象类一般不是由程序员定义的,而是由项目经理或模块设计人设计抽象类的缘由一般是为了规范方法名抽象类必需要继承,否则无法用,做为模块设计者,能够把让底层程序员直接用得方法直接调用,而一些须要让程序员覆盖后本身作得方法则定义称抽象方法
【分析】
7三、 Linkedlist 、 A rraylist 内部是如何实现的(更深刻的问了 LinkedList 与 ArrayList 的区别) 【天威诚信面试题】
【参考答案】
ArrayList的内部实现是基于内部数组Object[],它更像是对数组实现的一种封装,因此在向ArrayList的前面或中间插入数据时,必须将其后的全部数据相应的后移,这样必然要花费较多时间。
而LinkedList的内部实现是基于一组双向链表实现的存储特性,因此提供了链表同样访问的API接口,它们在性能上有很大的差异。当你访问Linkedlist链表中的某个元素时,就必须从链表的一端开始沿着链接方向一个一个元素地去查找,直到找到所需的元素为止,因此,当你的操做是在一列数据的前面或中间添加或删除数据,而且按照顺序访问其中的元素时,就应该使用LinkedList了。
而当你的操做是在一列数据的后面添加数据而不是在前面或中间,而且须要随机地访问其中的元素时,使用ArrayList会提供比较好的性能。
【分析】
7四、 H a s htable 的原理【北辰网络】
【参考答案】
经过节点的关键码肯定节点的存储位置,即给定节点的关键码k,经过必定的函数关系H(散列函数),获得函数值H(k),将此值解释为该节点的存储地址
7五、 JDBC 中的 PreparedStatement 相比 Statement 的好处?
【参考答案】
预编译语句 java .sql.PreparedStatement ,扩展自Statement,不但具备Statement的全部能力并且具备更强大的功能。不一样的是,PreparedStatement是在建立语句对象的同时给出要执行的sql语句。这样,sql语句就会被系统进行预编译,执行的速度会有所增长,尤为是在执行大语句的时候,效果更加理想
7六、 sleep() 和 wait() 区别
【参考答案】
sleep()方法:线程主动放弃CPU,使得线程在指定的时间内进入阻塞状态,不能获得CPU时间,指定的时间一过,线程从新进入可执行状态。典型地,sleep()被用在等待某个资源就绪的情形:测试发现条件不知足后,让线程阻塞一段时间后从新测试,直到条件知足为止。
wait( ):与notify()配套使用,wait()使得线程进入阻塞状态,它有两种形式,一种容许指定以毫秒为单位的一段时间做为参数,另外一种没有参数,当指定时间参数时对应的notify()被调用或者超出指定时间时线程从新进入可执行状态,后者则必须对应的notify()被调用
( 网上的答案 :sleep是线程类(Thread)的方法,致使此线程暂停执行指定时间,给执行机会给其余线程,可是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。wait是Object类的方法,对此对象调用wait方法致使本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备得到对象锁进入运行状态。)
sleep就是正在执行的线程主动让出cpu,cpu去执行其余线程,在sleep指定的时间事后,cpu才会回到这个线程上继续往下执行,若是当前线程进入了同步锁,sleep方法并不会释放锁,即便当前线程使用sleep方法让出了cpu,但其余被同步锁挡住了的线程也没法获得执行。wait是指在一个已经进入了同步锁的线程内,让本身暂时让出同步锁,以便其余正在等待此锁的线程能够获得同步锁并运行,只有其余线程调用了notify方法(notify并不释放锁,只是告诉调用过wait方法的线程能够去参与得到锁的竞争了,但不是立刻获得锁,由于锁还在别人手里,别人还没释放。若是notify方法后面的代码还有不少,须要这些代码执行完后才会释放锁,能够在notfiy方法后增长一个等待和一些代码,看看效果),调用wait方法的线程就会解除wait状态和程序能够再次获得锁后继续向下运行。对于wait的讲解必定要配合例子代码来讲明,才显得本身真明白。
package com.huawei.interview;
public class MultiThread {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new Thread(new Thread1()).start();
try {
Thread.sleep(10);
}catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
new Thread(new Thread2()).start();
}
private static class Thread1 implements Runnable
{
@Override
public void run() {
// TODO Auto-generated method stub
//因为这里的Thread1和下面的Thread2内部run方法要用同一对象做为监视器,咱们这里不能用this,由于在Thread2里面的this和这个Thread1的this不是同一个对象。咱们用MultiThread.class这个字节码对象,当前虚拟机里引用这个变量时,指向的都是同一个对象。
synchronized (MultiThread.class) {
System.out.println("enter thread1...");
System.out.println("thread1 is waiting");
try {
//释放锁有两种方式,第一种方式是程序天然离开监视器的范围,也就是离开了synchronized关键字管辖的代码范围,另外一种方式就是在synchronized关键字管辖的代码内部调用监视器对象的wait方法。这里,使用wait方法释放锁。
MultiThread.class.wait();
}catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("thread1 is going on...");
System.out.println("thread1 is being over!");
}
}
}
private static class Thread2 implements Runnable
{
@Override
public void run() {
// TODO Auto-generated method stub
synchronized (MultiThread.class) {
System.out.println("enter thread2...");
System.out.println("thread2 notify other thread can release wait status..");
//因为notify方法并不释放锁,即便thread2调用下面的sleep方法休息了10毫秒,但thread1仍然不会执行,由于thread2没有释放锁,因此Thread1没法得不到锁。
MultiThread.class.notify();
System.out.println("thread2 is sleeping ten millisecond...");
try {
Thread.sleep(10);
}catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("thread2 is going on...");
System.out.println("thread2 is being over!");
}
}
}
})
7七、 概述反射和序列化
【参考答案】
Reflection :是Java被视为动态语言的一个关键性质。这个机制容许程序在运行时透过Reflection APIs取得任何一个已知名称的class的内部信息,包括其modifiers(诸如public, static等等)、superclass(例如Object)、实现之interfaces(例如Cloneable),也包括fields和methods的全部信息,并可于运行时改变fields内容或唤起methods。
序列化 : 就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。能够对流化后的对象进行读写操做,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操做时的问题。
7八、 J ava 中实现多态的机制是什么 ?
【参考答案】
重写,重载
方法的重写Overriding和重载Overloading是Java多态性的不一样表现。
重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。若是在子类中定义某方法与其父类有相同的名称和参数,咱们说该方法被重写(Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被“屏蔽”了。
果在一个类中定义了多个同名的方法,它们或有不一样的参数个数或有不一样的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是能够改变返回值的类型。
7九、 Overload 和 Override 的区别? Overloaded 的方法是否能够改变返回值的类型 ? 【软通动力】
【参考答案】
Overload是重载的意思,Override是覆盖的意思,也就是重写。
重载Overload表示同一个类中能够有多个名称相同的方法,但这些方法的参数列表各不相同(即参数个数或类型不一样)。
重写Override表示子类中的方法能够与父类中的某个方法的名称和参数彻底相同,经过子类建立的实例对象调用这个方法时,将调用子类中的定义方法,这至关于把父类中定义的那个彻底相同的方法给覆盖了,这也是面向对象编程的多态性的一种表现。子类覆盖父类的方法时,只能比父类抛出更少的异常,或者是抛出父类抛出的异常的子异常,由于子类能够解决父类的一些问题,不能比父类有更多的问题。子类方法的访问权限只能比父类的更大,不能更小。若是父类的方法是private类型,那么,子类则不存在覆盖的限制,至关于子类中增长了一个全新的方法。
是否能够改变返回值类型,在重载的定义中,与方法是什么类型返回值无关。
【分析】
override能够翻译为覆盖,从字面就能够知道,它是覆盖了一个方法而且对其重写,以求达到不一样的做用。对咱们来讲最熟悉的覆盖就是对接口方法的实现,在接口中通常只是对方法进行了声明,而咱们在实现时,就须要实现接口声明的全部方法。除了这个典型的用法之外,咱们在继承中也可能会在子类覆盖父类中的方法。在覆盖要注意如下的几点:
一、覆盖的方法的标志必需要和被覆盖的方法的标志彻底匹配,才能达到覆盖的效果;
二、覆盖的方法的返回值必须和被覆盖的方法的返回一致;
三、覆盖的方法所抛出的异常必须和被覆盖方法的所抛出的异常一致,或者是其子类;
四、被覆盖的方法不能为private,不然在其子类中只是新定义了一个方法,并无对其进行覆盖。
overload对咱们来讲可能比较熟悉,能够翻译为重载,它是指咱们能够定义一些名称相同的方法,经过定义不一样的输入参数来区分这些方法,而后再调用时,VM就会根据不一样的参数样式,来选择合适的方法执行。在使用重载要注意如下的几点:
一、在使用重载时只能经过不一样的参数样式。例如,不一样的参数类型,不一样的参数个数,不一样的参数顺序(固然,同一方法内的几个参数类型必须不同,例如能够是fun(int,float),可是不能为fun(int,int));
二、不能经过访问权限、返回类型、抛出的异常进行重载;
三、方法的异常类型和数目不会对重载形成影响;
四、对于继承来讲,若是某一方法在父类中是访问权限是priavte,那么就不能在子类对其进行重载,若是定义的话,也只是定义了一个新方法,而不会达到重载的效果。
80、 ClassLoader 如何加载 class 。
【参考答案】
jvm里有多个类加载,每一个类加载能够负责加载特定位置的类,例如,bootstrap类加载负责加载jre/lib/rt.jar中的类,咱们平时用的jdk中的类都位于rt.jar中。extclassloader负责加载jar/lib/ext/*.jar中的类,appclassloader负责classpath指定的目录或jar中的类。除了bootstrap以外,其余的类加载器自己也都是java类,它们的父类是ClassLoader。
8一、 ArrayList 如何实现插入的数据按自定义的方式有序存放
【参考答案】
实现Comparable比较接口,并实现compareTo方法。排序的方法,取决于compareTo方法中的比较定义的返回值,通常有3个返回值:一、-一、0表示不一样的比较结果。
程序示例:
class MyBean implements Comparable {
public int compareTo (Object obj){
if(! obj instanceof MyBean)
throw new ClassCastException();
MyBean other = (MyBean) obj;
return age > other.age?1:age== other.age?0:-1;
}
}
class MyTreeSet {
private ArrayList datas = new ArrayList();
public void add(Object obj){
for(int i=0;i
if(obj.compareTo(datas.get(i) != 1){
datas.add(i,obj);
}
}
}
}
8二、 hashCode 方法的做用?
【参考答案】
hashcode这个方法是用来鉴定2个对象是否相等的。hashcode方法通常用户不会去调用,好比在hashmap中,因为key是不能够重复的,他在判断key是否是重复的时候就判断了hashcode这个方法,并且也用到了equals方法。这里不能够重复是说equals和hashcode只要有一个不等就能够了!因此简单来说,hashcode至关因而一个对象的编码。咱们通常在覆盖equals的同时也要覆盖hashcode,让他们的逻辑一致。
8三、 abstract 的 method 是否可同时是 static, 是否可同时是 native ,是否可同时是 synchronized?
【参考答案】
abstract的method不能够是static的,由于抽象的方法是要被子类实现的,而static与子类扯不上关系!
native方法表示该方法要用另一种依赖平台的编程语言实现的,不存在着被子类实现的问题,因此,它也不能是抽象的,不能与abstract混用。例如,FileOutputSteam类要硬件打交道,底层的实现用的是操做系统相关的api实现,例如,在windows用c语言实现的,因此,查看jdk的源代码,能够发现FileOutputStream的open方法的定义以下:
private native void open(String name) throws FileNotFoundException;
若是咱们要用java调用别人写的c语言函数,咱们是没法直接调用的,咱们须要按照java的要求写一个c语言的函数,又咱们的这个c语言函数去调用别人的c语言函数。因为咱们的c语言函数是按java的要求来写的,咱们这个c语言函数就能够与java对接上,java那边的对接方式就是定义出与咱们这个c函数相对应的方法,java中对应的方法不须要写具体的代码,但须要在前面声明native。
关于synchronized与abstract合用的问题,我以为也不行,由于在我几年的学习和开发中,历来没见到过这种状况,而且我以为synchronized应该是做用在一个具体的方法上才有意义。并且,方法上的synchronized同步所使用的同步锁对象是this,而抽象方法上没法肯定this是什么。
8四、 Anonymous Inner Class ( 匿名内部类 ) 是否能够 extends( 继承 ) 其它类,是否能够 implements( 实现 )interface( 接口 )?
【参考答案】
能够继承其余类或实现其余接口。不只是能够,而是必须!
8五、 JAVA 语言如何进行异常处理,关键字: throws,throw,try,catch,finally 分别表明什么意义?在 try 块中能够抛出异常吗?
【参考答案】
Java使用面向对象的方式来处理异常,它把程序中发生的每一个异常也都分别封装到一个对象来表示的,该对象中包含有异常的信息。而throws hrow ry、catch、finally就是Java中用来对异常进行处理的几个关键字,在Java编程中规容Java编译器强制普通异常必须try..catch处理或用throws声明继续抛给上层调用方法处理,通常异常必需要求被捕获和处理,而系统异常能够处理也能够不处理,因此编译器不强制用try..catch处理或用throws、throw声明异常。而finally通常与try或trycatch一块儿使用作为异常的最后处理出口。
8六、 同步和异步有何异同,在什么状况下分别使用他们?举例说明。
【参考答案】
若是数据将在线程间共享。例如正在写的数据之后可能被另外一个线程读到,或者正在读的数据可能已经被另外一个线程写过了,那么这些数据就是共享数据,必须进行同步存取。
当应用程序在对象上调用了一个须要花费很长时间来执行的方法,而且不但愿让程序等待方法的返回时,就应该使用异步编程,在不少状况下采用异步途径每每更有效率。
8七、 当一个线程进入一个对象的一个 synchronized 方法后,其它线程是否可进入此对象的其它方法 ?
【参考答案】
分几种状况:
1.其余方法前是否加了synchronized关键字,若是没加,则能。
2.若是这个方法内部调用了wait,则能够进入其余synchronized方法。
3.若是其余个方法都加了synchronized关键字,而且内部没有调用wait,则不能。
4.若是其余方法是static,它用的同步锁是当前类的字节码,与非静态的方法不能同步,由于非静态的方法用的是this。
8八、 线程的基本概念、线程的基本状态以及状态之间的关系
【参考答案】
一个程序中能够有多条执行线索同时执行,一个线程就是程序中的一条执行线索,每一个线程上都关联有要执行的代码,便可以有多段程序代码同时运行,每一个程序至少都有一个线程,即main方法执行的那个线程。若是只是一个cpu,它怎么可以同时执行多段程序呢?这是从宏观上来看的,cpu一会执行a线索,一会执行b线索,切换时间很快,给人的感受是a,b在同时执行,比如你们在同一个办公室上网,只有一条连接到外部网线,其实,这条网线一会为a传数据,一会为b传数据,因为切换时间很短暂,因此,你们感受都在同时上网。
状态:就绪,运行,synchronize阻塞,wait和sleep挂起,结束。wait必须在synchronized内部调用。
调用线程的start方法后线程进入就绪状态,线程调度系统将就绪状态的线程转为运行状态,遇到synchronized语句时,由运行状态转为阻塞,当synchronized得到锁后,由阻塞转为运行,在这种状况能够调用wait方法转为挂起状态,当线程关联的代码执行完后,线程变为结束状态。
8九、 简述 synchronized 和 java.util.concurrent.locks.Lock 的异同 ?
【参考答案】
主要相同点:Lock能完成synchronized所实现的全部功能
主要不一样点:Lock有比synchronized更精确的线程语义和更好的性能。synchronized会自动释放锁,而Lock必定要求程序员手工释放,而且必须在finally从句中释放。Lock还有更强大的功能,例如,它的tryLock方法能够非阻塞方式去拿锁。
90、 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的方法是synchronized的,而HashMap不是,在多个线程访问Hashtable时,不须要本身为它的方法实现同步,而HashMap就必须为之提供外同步。
Hashtable和HashMap采用的hash/rehash算法都大概同样,因此性能不会有很大的差别。
9一、 List 、 Set 、 Map 是否继承自 Collection 接口 ?
【参考答案】
List、Set是,Map不是;Map接口定义的是Key-Value存储的特性,与List和Set不一样,Map在存储对象时,先要定义这个对象的key的值,再存入与这个key相对应的Object,Map集合的取值时根据存入的key(关键字)来获取与这个关键字对应的对象。
9二、 List 、 Map 、 Set 三个接口,存取元素时,各有什么特色?
【参考答案】
首先,List与Set具备类似性,它们都是单列元素的集合,因此,它们有一个功共同的父接口Collection接口。Set里面不容许有重复的元素,即不能有两个相等的对象。
List表示有前后顺序的集合,当咱们屡次调用add(Obj e)方法时,每次加入的对象就像火车站买票有排队顺序同样,按先来后到的顺序排序。
Map与List和Set不一样,它是双列的集合每次存储时,要存储一对key/value,不能存储重复的key,这个重复的规则也是按equals比较相等。取则能够根据key得到相应的value,即get(Object key)返回值为key所对应的value。另外,也能够得到全部的key的结合。
【分析】
总结:List以特定次序来持有元素,可有重复元素。Set没法拥有重复元素,内部排序。Map保存key-value值,value可多值。上面是大体不一样,另外上述3个只是接口,而具体实现类中,用法大同小异,只是实现的数据结构不一样,例如List接口下的LinkedList主要实现了双链表的存储特色,Vector是线程安全的集合类。
9三、 说出 ArrayList,Vector, LinkedList 的存储性能和特性。【 大唐动力面试题 】
【参考答案】
ArrayList和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增长和插入元素,它们都容许直接按序号索引元素,可是插入元素要涉及数组元素移动等内存操做,因此索引数据快而插入数据慢,Vector因为使用了synchronized方法(线程安全),一般性能上较ArrayList差,而LinkedList使用双向链表实现存储,按序号索引数据须要进行前向或后向遍历,可是插入数据时只须要记录本项的先后项便可,因此插入速度较快。
LinkedList也是线程不安全的,LinkedList提供了一些方法,使得LinkedList能够被看成堆栈和队列来使用。
9四、 如何去掉一个 Vector 集合中重复的元素
【参考答案】
Vector newVector = new Vector();
for (int i=0;i
{
Object obj = vector.get(i);
if(!newVector.contains(obj);
newVector.add(obj);
}
还有一种简单的方式,HashSet set = new HashSet(vector);
9五、 Set 里的元素是不能重复的,那么用什么方法来区分重复与否呢 ? 是用 == 仍是 equals()? 它们有何区别 ?
【参考答案】
Set里的元素是不能重复的,元素重复与否是使用equals()方法进行判断的。
9六、 两个对象值相同 (x.equals(y) == true) ,但却可有不一样的 hash code ,这句话对不对 ?
【参考答案】
对。
若是对象要保存在HashSet或HashMap中,它们的equals相等,那么,它们的hashcode值就必须相等。
若是不是要保存在HashSet或HashMap,则与hashcode没有什么关系了,这时候hashcode不等是能够的,例如arrayList存储的对象就不用实现hashcode方法。
9七、 字节流与字符流的区别
【参考答案】
要把一片二进制数据数据逐一输出到某个设备中,或者从某个设备中逐一读取一片二进制数据,无论输入输出设备是什么,咱们要用统一的方式来完成这些操做,用一种抽象的方式进行描述,这个抽象描述方式起名为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);
}
}
9八、 java 里面的 io 跟 nio 有什么区别
【参考答案】
一、Java NIO和IO之间第一个最大的区别是,IO是面向流的,NIO是面向缓冲区的。
二、Java IO的各类流是阻塞的。而Java NIO的非阻塞模式,使一个线程从某通道发送请求读取数据,可是它仅能获得目前可用的数据,若是目前没有数据可用时,就什么都不会获取。而不是保持线程阻塞,因此直至数据变的能够读取以前,该线程能够继续作其余的事情。
三、选择器上,Java IO无选择器,而NIO有选择器,Java NIO的选择器容许一个单独的线程来监视多个输入通道,你能够注册多个通道使用一个选择器,而后使用一个单独的线程来“选择”通道:这些通道里已经有能够处理的输入,或者选择已准备写入的通道。
9九、 J ava 中会存在内存泄漏吗,请简单描述。
【参考答案】
所谓内存泄露就是指一个再也不被程序使用的对象或变量一直被占据在内存中。java中有垃圾回收机制,它能够保证一对象再也不被引用的时候,即对象变成了孤儿的时候,对象将自动被垃圾回收器从内存中清除掉。因为Java使用有向图的方式进行垃圾回收管理,能够消除引用循环的问题,例若有两个对象,相互引用,只要它们和根进程不可达的,那么GC也是能够回收它们的,例以下面的代码能够看到这种状况的内存回收:
package com.huawei.interview;
import java.io.IOException;
public class GarbageTest {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
try {
gcTest();
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("has exited gcTest!");
System.in.read();
System.in.read();
System.out.println("out begin gc!");
for(int i=0;i<100;i++)
{
System.gc();
System.in.read();
System.in.read();
}
}
private static void gcTest() throws IOException {
System.in.read();
System.in.read();
Person p1 = new Person();
System.in.read();
System.in.read();
Person p2 = new Person();
p1.setMate(p2);
p2.setMate(p1);
System.out.println("before exit gctest!");
System.in.read();
System.in.read();
System.gc();
System.out.println("exit gctest!");
}
private static class Person
{
byte[] data = new byte[20000000];
Person mate = null;
public void setMate(Person other)
{
mate = other;
}
}
}
java中的内存泄露的状况:长生命周期的对象持有短生命周期对象的引用就极可能发生内存泄露,尽管短生命周期对象已经再也不须要,可是由于长生命周期对象持有它的引用而致使不能被回收,这就是java中内存泄露的发生场景,通俗地说,就是程序员可能建立了一个对象,之后一直再也不使用这个对象,这个对象却一直被引用,即这个对象无用可是却没法被垃圾回收器回收的,这就是java中可能出现内存泄露的状况,例如,缓存系统,咱们加载了一个对象放在缓存中(例如放在一个全局map对象中),而后一直再也不使用它,这个对象一直被缓存引用,但却再也不被使用。
检查java中的内存泄露,必定要让程序将各类分支状况都完整执行到程序结束,而后看某个对象是否被使用过,若是没有,则才能断定这个对象属于内存泄露。
若是一个外部类的实例对象的方法返回了一个内部类的实例对象,这个内部类对象被长期引用了,即便那个外部类实例对象再也不被使用,但因为内部类持久外部类的实例对象,这个外部类对象将不会被垃圾回收,这也会形成内存泄露。
[]是对象已不可到达,而内存又没有回收,真正的内存黑洞。
而Java的泄漏,则是由于各类缘由,对象对应用已经无用,但一直被持有,一直可到达。
总结缘由无外乎几方面:
1.被生命周期极长的集合类不当持有,号称是Java内存泄漏的首因。
这些集合类的生命周期一般极长,并且是一个辅助管理性质的对象,在一个业务事务运行完后,若是没有将某个业务对象主动的从中清除的话,这个集合就会吃愈来愈多内存,能够用WeakReference,如WeakHashMap,使得它持有的对象不增长对象的引用数。
2.Scope定义不对,这个很简单了,方法的局部变量定义成类的变量,类的静态变量等。
3.异常时没有加finally{}来释放某些资源,JDBC时代也是很广泛的事情。
4.另一些我了解不深的缘由,如:Swing里的Listener没有显式remove;内部类持有外部对象的隐式引用;Finalizers形成关联对象没有被及时清空等。
内存泄漏的检测
有很多工具辅助作这个事情的,若是手上一个工具也没有,能够用JDK自带的小工具:
·看看谁占满了Heap?
用JDK6的jmap能够显示运行程序中对象的类型,个数与所占的大小
先用jps找到进程号,而后jmap -histo pid显示或jmap -dump:file=heap_file_name pid导出heap文件
·为何这些对象仍然能够到达?
用jhat(Java Heap Analysis Tool)分析刚才导出的heap文件。
先jhat heap_file_name,而后打开浏览器http://localhost:7000/浏览。
100、 Hashcode 和 Equals 的联系
【参考答案】
首先equals()和hashcode()这两个方法都是从object类中继承过来的,主要用来比较对象时进行调用。在object类中定义以下:
a)、若是两个对象相同,那么它们的hashCode值必定要相同;
b)、若是两个对象的hashCode相同,它们并不必定相同上面说的对象相同指的是用eqauls方法比较。
10一、 Tread 和 T hreadlocal 的做用及区别?
【参考答案】
答:threadlocal是线程局部变量(thread local variable),为每个使用该线程的线程都提供一个变量值的副本,使每个线程均可以独立地改变本身的副本,而不会和其余线程的副本产生冲突。
10二、 TCP 和 UDP 的区别?
【参考答案】
TCP/IP的运输层有两个不一样的协议:①用户数据报协议UDP②传输控制协议TCP
两者最大区别:TCP是面向链接的,而UDP是无链接的.区别大体以下:
1)UDP传送的数据单位协议是UDP报文或用户数据报,TCP传送的数据单位协议是TCP报文段。
2)UDP发送数据以前不须要创建链接,所以减小了开销和发送以前的时延。TCP提供面向链接的服务,不提供广播或多播服务。
3)对方的运输层在收到UDP报文后,不须要给出任何确认。TCP则须要确认。
4)UDP没有拥塞控制,所以网络出现的拥塞不会使源主机的发送速率下降,也不保证可靠交付,所以主机不须要维持具备许多参数的、复杂的链接状态表。TCP要提供可靠的、面向链接的运输服务,所以不可避免地增长了许多的开销,这不只使协议数据单元的首部增大不少,还要占用许多的处理机资源。
5)UDP用户数据报只有8个字节的首部开销,比TCP的20个字节的首部要短。
10三、 启动一个线程用什么方法?【北京永中软件面试题】
【参考】
使用Thread类的start()方法来启动一个线程,使线程进入就绪状态。若是自定义的类是Thread类的子类的话,能够直接使用Start()来启,若是是实现的Runnable接口的话,还要将该类的实例做为参数传入到Thread对象中来启动。
10四、 做用域 public 等写不写的区别?【北京永中软件面试题】
【参考】
做用域不写将采用默认的做用域,默认做用域的访问权限是包的权限,也就是除本包中的全部类能访问,不一样包只有子类能访问。
10五、 同步和异步有何异同
【参考答案】
同步(synchronized)和异步(asynchronized)是对于多线程(multi-threading)而言的
同步可防止并发主要出于数据安全的考虑
若是数据将在线程间共享。例如正在写的数据之后可能被另外一个线程读到,或者正在读的数据可能已经被另外一个线程写过了,那么这些数据就是共享数据,必须进行同步存取。
异步容许并发
ajax技术一般都是异步实现的,异步主要使用在当应用程序在对象上调用了一个须要花费很长时间来执行的方法,而且不但愿让程序等待方法的返回时,就应该使用异步编程,在不少状况下采用异步途径每每更有效率。
10六、 Static 方法和 static 字段有什么用处?能够被重载吗?
【参考答案】
用static修饰的方法叫类方法,被全部实例共享;static修饰的字段为类变量,被全部实例共享,在使用类变量时,通常会结合final一块儿使用定义类常量,不容许被其它的类实例修改。
能够被重载,重载只是参数类型、顺序和个数不一样。