- java中有哪些基本类型?
- java为什么能够跨平台运行?
- String是基本数据类型吗?我可不可以写个类继承于String?
- 谈谈&和&&的区别?
- Switch语句里面的条件可不可以是byte、long、String?使用时候还应注意什么?
- short s1=1;s1=s1+1;有什么错?short s1 = 1;s1+=1 有什么错?
- char为什么能存贮一个汉字?
- 用最效率的办法算出2乘以8等于几?
- final修饰变量时,该变量是对象时,对象的值可不可以改变?
- 静态变量和实例变量的区别?
- 面向对象的基本特征是什么?请说详细
- 作用域public,private,protected,以及不写时的区别?
- Overload和Override的区别。
- 构造器可不可以被重载或重写?
- Java中有没有多继承?
- 抽象类和接口的区别?
- java中实现多态的机制是什么?
- int和integer的区别?
- String和StringBuffer的区别?StringBuffer和StringBuilder区别?
- String s=new String(“xyz”);创建了几个String Object?
- 数组中有没有length()方法,String中有没有length()方法?
- try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后?
- final, finally, finalize的区别。
- ‘==’和equals的区别?
- error和exception有什么区别?
- java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用?
- sleep() 和 wait() 有什么区别?
- 当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?
- 线程的基本概念、线程的基本状态以及状态之间的关系
- ArrayList和Vector的区别?
- List、Set和Map的区别?
- Collection 和 Collections的区别。
- Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()?它们有何区别?
- 什么是java序列化,如何实现java序列化?
- heap和stack有什么区别。
- GC是什么? 为什么要有GC?
- 编写一个程序,将d:\java目录下的所有.java文件复制到d:\jad目录下,并将原来文件的扩展名从.java改为.jad。
- 说明生活中遇到的二叉树,用java实现二叉树
- 第1个人10,第2个比第1个人大2岁,依次递推,请用递归方式计算出第8个人多大?
- 排序都有哪几种方法?请列举。用JAVA实现一个快速排序。
- 金额转换,阿拉伯数字的金额转换成中国传统的形式如:(¥1011)->(一千零一拾一元整)输出。
- 什么是内部类?分为哪几种?
- 为什么需要内部类?
- 内部类可以引用它的包含类的成员吗?有没有什么限制?
- Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)?
- java中有几种类型的流?JDK为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类?
- 字节流与字符流的区别
- 简述 static 和 和 final 的 用法?
- 写出冒泡排序的算法
- abstract class 和 interface 有什么区别?
- 类有哪三个基本特性?各特性的优点?
- Error和Exception有什么区别? 列出你见过的Exception并简要说明
- java中会存在内存泄露吗?请简单描述
- 多线程有几种实现方法,都是什么?同步有几种实现方法,都是什么?
- sleep()和wait()有什么区别?
- 谈谈java跟你所知道的其它的语言相比,有什么优点??
- 谈谈你对面向对象的理解??
- 简单讲一下java的跨平台原理
- 有了基本数据类型,为什么还需要包装类型?
- 说一下”==”和equals方法究竟有什么区别?
- 讲一下java中的集合
- ArrayList和LinkedList的区别?
- 讲一下HashMap和HashTable的区别?
- 请说出集合类中List、Map、Set的区别
- Collection 和 Collections的区别?
- String、StringBuffer和StringBuilder的区别?
- 讲一下线程的几种实现方式?
- 讲一下线程的几种启动方式?
- 有没有使用过线程并发库?
- 静态变量和实例变量的区别?
- try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后?
- 同步和异步有何异同,在什么情况下分别使用他们?举例说明。
- java 中有几种类型的流?JDK 为每种类型的流提供了一些抽象类以供继承, 请说出他们分别是哪些类?
- &和&&的区别?
- 数组有没有length()这个方法? String有没有length()这个方法?
- 构造器Constructor是否可被override?
- 构造器如何工作?
- super与this的区别?
- GC是什么? 为什么要有GC?
- 接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承实体类?
- 内部类可以引用他包含类的成员吗?有没有什么限制?
- Java有没有goto?
- 解释内存中的栈(stack)、堆(heap)和静态区(static area)的用法
- 用最有效率的方法计算2乘以8?
- 在Java中,如何跳出当前的多重嵌套循环?
- 两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对?
- char 型变量中能不能存贮一个中文汉字,为什么?
- Anonymous Inner Class(匿名内部类)是否可以继承其它类?是否可以实现接口?
- 内部类可以引用它的包含类(外部类)的成员吗?有没有什么限制?
- Java 中的final关键字有哪些用法?
- 写出常见的5个RuntimeException
- 阐述final、finally、finalize的区别。
- 阐述ArrayList、Vector、LinkedList的存储性能和特性。
- Collection和Collections的区别?
- List、Map、Set三个接口存取元素时,各有什么特点?
- 当一个线程进入一个对象的synchronized方法A之后,其它线程是否可进入此对象的synchronized方法B?
- 请说出与线程同步以及线程调度相关的方法。
- Java中如何实现序列化,有什么意义?
- 如何通过反射创建对象?
- 谈谈 JVM 的内存结构和内存分配?
- 什么是双亲委派机制
- Static 关键字有哪些作用?
- Instanceof 有什么作用?
- 什么是不可变类?
- 值传递与引用传递的区别?
- 强制类型转换的注意事项有哪些?
- ++i与 i++的区别?
- 字符串存储的机制是什么?
java中有哪些基本类型?
byte、short、int、long、float、double、char、boolean
java为什么能够跨平台运行?
因为Java程序编译之后的代码不是能被硬件系统直接运行的代码,而是一种“中间码”——字节码。然后不同的硬件平台上安装有不同的Java虚拟机(JVM),由JVM来把字节码再“翻译”成所对应的硬件平台能够执行的代码。因此对于Java编程者来说,不需要考虑硬件平台是什么。所以Java可以跨平台。
String是基本数据类型吗?我可不可以写个类继承于String?
不是,String是引用类型;String是final的类,是不可以被继承的。
谈谈&和&&的区别?
&和&&都可以用作逻辑与的运算符,表示逻辑与(and),当运算符两边的表达式的结果都为true时,整个运算结果才为true,否则,只要有一方为false,则结果为false。
&&还具有短路的功能,即如果第一个表达式为false,则不再计算第二个表达式。
&还可以用作位运算符,当&操作符两边的表达式不是boolean类型时,&表示按位与操作.。
Switch语句里面的条件可不可以是byte、long、String?使用时候还应注意什么?
switch里面的条件必须是能隐式的转化成为Int的故long和String不行,byte可以;使用Switch时候还应注意它的穿透,即每个case后要跟break;
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编译器会对它进行特殊处理,因此可以正确编译。
char为什么能存贮一个汉字?
char型变量是用来存储Unicode编码的字符的,unicode编码字符集中包含了全世界所有的字体。
用最效率的办法算出2乘以8等于几?
2<<3 位移运算是最底层的运算,他直接操作的是二进制,故效率最快。
final修饰变量时,该变量是对象时,对象的值可不可以改变?
final修饰的变量指的是引用不可变,对象的值是可以改变的。
静态变量和实例变量的区别?
静态变量也称为类变量,归全类共有,它不依赖于某个对象,可通过类名直接访问;而实例变量必须依存于某一实例,只能通过对象才能访问到它。
面向对象的基本特征是什么?请说详细
1)抽象:抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意 与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一 部分,暂时不用部分细节。抽象包括两个方面,一是过程抽象,二是数据抽象。<br /> 2)继承:子类拥有父类一切非私有的属性和方法。<br /> 3)封装:封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。面 向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装 的对象,这些对象通过一个受保护的接口访问其他对象。<br /> 4)多态性:同一种事物的不同种表现形式。<br />
作用域public,private,protected,以及不写时的区别?
| 作用域 | 当前类 | 同包 | 子孙类 | 其他 |
|---|---|---|---|---|
| public | √ | √ | √ | √ |
| protected | √ | √ | √ | × |
| default | √ | √ | × | × |
| private | √ | × | × | × |
| 不写时默认为default |
Overload和Override的区别。
(Overload)重载:发生在同一个类之中,方法名相同、参数列表不同,与返回值无关、与final无关、与修饰符无关、与异常无关。
(Override)重写:发生在子类和父类之间,方法名相同、参数列表相同、返回值相同、不能是final的方法、重写的方法不能有比父类方法更为严格的修饰符权限、重写的方法所抛出的异常不能比父类的更大。
如果父类私有的方法,子类拥有方法签名相同的方法,子类不属于重写父类的方法,该方法属于子类的新方法。
构造器可不可以被重载或重写?
Java中有没有多继承?
java中没有多继承,但是可以多实现,即一个类实现多个接口。
虽然没有多继承,但是java中接口可以近似的实现多继承,那就是接口;接口和接口之间可以进行多继承。
抽象类和接口的区别?
a.抽象类继承与object接口不继承object.
b.抽象类有构造器,接口中没有构造器。
c.抽象类中可以有普通成员变量和常量,接口中只能有常量,而且只能是public static final 不写默认。
d.抽象类中可以有抽象方法,也可以由普通的方法,接口中只能有抽象的方法而且修饰符只能是public abstract 不写默认。
e.抽象类中可以有final的方法,接口中不能有final的方法。
f.抽象类只能是单继承,多实现,接口是可以多继承其他接口,但是不能实现接口,和不能继承其他类。
g.抽象类中可以有静态的方法,接口中不可以。
java中实现多态的机制是什么?
int和integer的区别?
int是java的基本数据类型,integer是1.4版本后提供的基本类型包装类,当两者作为成员变量时,初始值分别为;int是0;integer是null;其中integer提供了一些对整数操作的方法,还定义了integer型数值的最值,其他基本类型也有对应的包装类,基本类型包装类的出现,使得java完全面向对象.
String和StringBuffer的区别?StringBuffer和StringBuilder区别?
String是不可变的,对String类的任何改变都会返回一个新的String对象。
StringBuffer是可变的,对StringBuffer中的内容修改都是当前这个对象。
String重写了equals方法和hashCode方法,StringBuffer没有重写equals方法。
String是final的类。StringBuffer不是。
String创建的字符串是在常量池中,创建的变量初始化一次,如果再对该字符串改变会产生新的字符串地址值,StringBuffer是在堆中创建对象,当对字符串改变时不会产生新的字符串地址值,如果对字符串进行频繁修改的话建议使用StringBuffer,以节省内存。
StringBuffer和StringBuilder,StringBuffer是线程安全的,StringBulider是线程不安全的。当不考虑并发问题时候,请使用StringBulider。
String s=new String(“xyz”);创建了几个String Object?
两个对象,一个是”xyx”,一个是指向”xyx”的引用对象s。
数组中有没有length()方法,String中有没有length()方法?
数组中没有length()方法,但是有length属性,String中有length()方法
try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后?
这道题很有争议,我是通过debug模式分为两种情况进行测试的.
a.finally中没有return时候:
会先执行try里面的,return会执行但是没有真正的return此时去执行了finally里面的,然后再返回来执行return.
b.finally中有return时候(其实这种情况不符合编程规范,会报黄线警告):
会先执行try里面的,return会执行但是没有真正的return此时去执行了finally里面的,然后执行finally里面的return,直接返回。
final, finally, finalize的区别。
final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
内部类要访问局部变量,局部变量必须定义成final类型。
finally是异常处理语句结构的一部分,表示总是执行。
finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。JVM不保证此方法总被调用
final 可以用来修饰类、方法、变量,分别有不同的意义,final 修饰的 class 代表不可以继承扩展,final 的变量是不可以修改的,而 final 的方法也是不可以重写的(override)。
finally 则是 Java 保证重点代码一定要被执行的一种机制。我们可以使用 try-finally 或者 try-catch-finally 来进行类似关闭 JDBC 连接、保证 unlock 锁等动作。
finalize 是基础类 java.lang.Object 的一个方法,它的设计目的是保证对象在被垃圾收集前完成特定资源的回收。finalize 机制现在已经不推荐使用,并且在 JDK 9 开始被标记为 deprecated。
‘==’和equals的区别?
‘==’比较的是两个变量的内容和在内存中的地址值是否全部相等,如果要比较两个基本数据类型那必须用’==’
equals如果没有重写,则和’==’的意义一样,如果重写了,则会会按照重写的内容进行比较,javaBean规定当重写equals时候必须重写hashCode,如果不重写会出现对象相同但是hashCode不同,这样会出现问题,eg:HashSet存储元素时候是按照hashCode,如果重写equals不重写hashCode会导致同一个对象,存储了两次。
error和exception有什么区别?
error表示恢复不是不可能但是很困难的情况下的一种严重问题,例如程序书写错误,虚拟机错误等,exception是一种设计和实现问题,如果程序运行正常,从不会发生的情况。error是可以避免的,exception是不可避免的。
(1)Error类和Exception类都是继承Throwable类
(2)Error(错误)是系统中的错误,程序员是不能改变的和处理的,是在程序编译时出现的错误,只能通过修改程序才能修正
(3)Exception(异常)表示程序可以处理的异常,可以捕获且可能恢复。
java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用?
实现线程有两种方式:1.继承Thread类,重写run方法,在调用start方法。
2.实现Runnable接口,重写run方法。在传给Thread构造器,调用时调用Thread的start方法。
用synchronized关键字修饰同步方法 。
不使用stop(),是因为它不安全。它会解除由线程获取的所有锁定,而且如果对象处于一种不连贯状态,那么其他线程能在那种状态下检查和修改它们。结果很难检查出真正的问题所在。suspend()方法容易发生死锁。调用suspend()的时候,目标线程会停下来,但却仍然持有在这之前获得的锁定。此时,其他任何线程都不能访问锁定的资源,除非被”挂起”的线程恢复运行。对任何线程来说,如果它们想恢复目标线程,同时又试图使用任何一个锁定的资源,就会造成死锁。所以不应该使用suspend(),而应在自己的Thread类中置入一个标志,指出线程应该活动还是挂起。若标志指出线程应该挂起,便用wait()命其进入等待状态。若标志指出线程应当恢复,则用一个notify()重新启动线程。
sleep() 和 wait() 有什么区别?
sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。 wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。
当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?
分几种情况:
1.其他方法前是否加了synchronized关键字,如果没加,则能。
2.如果这个方法内部调用了wait,则可以进入其他synchronized方法。
3.如果其他个方法都加了synchronized关键字,并且内部没有调用wait,则不能。
4.如果其他方法是static,它用的同步锁是当前类的字节码,与非静态的方法不能同步,因为非静态的方法用的是this。
线程的基本概念、线程的基本状态以及状态之间的关系
一个程序中可以有多条执行线索同时执行,一个线程就是程序中的一条执行线索,每个线程上都关联有要执行的代码,即可以有多段程序代码同时运行,每个程序至少都有一个线程,即main方法执行的那个线程。如果只是一个cpu,它怎么能够同时执行多段程序呢?这是从宏观上来看的,cpu一会执行a线索,一会执行b线索,切换时间很快,给人的感觉是a,b在同时执行,好比大家在同一个办公室上网,只有一条链接到外部网线,其实,这条网线一会为a传数据,一会为b传数据,由于切换时间很短暂,所以,大家感觉都在同时上网。
状态:就绪,运行,synchronize阻塞,wait和sleep挂起,结束。wait必须在synchronized内部调用。
调用线程的start方法后线程进入就绪状态,线程调度系统将就绪状态的线程转为运行状态,遇到synchronized语句时,由运行状态转为阻塞,当synchronized获得锁后,由阻塞转为运行,在这种情况可以调用wait方法转为挂起状态,当线程关联的代码执行完后,线程变为结束状态。
ArrayList和Vector的区别?
这两个类都实现了List接口(List接口继承了Collection接口),他们都是有序集合,即存储在这两个集合中的元素的位置都是有顺序的,相当于一种动态的数组,我们以后可以按位置索引号取出某个元素,,并且其中的数据是允许重复的,这是HashSet之类的集合的最大不同处,HashSet之类的集合不可以按索引号去检索其中的元素,也不允许有重复的元素(本来题目问的与hashset没有任何关系,但为了说清楚ArrayList与Vector的功能,我们使用对比方式,更有利于说明问题)。
接着才说ArrayList与Vector的区别,这主要包括两个方面:.
(1)同步性:
Vector是线程安全的,也就是说是它的方法之间是线程同步的,而ArrayList是线程序不安全的,它的方法之间是线程不同步的。如果只有一个线程会访问到集合,那最好是使用ArrayList,因为它不考虑线程安全,效率会高些;如果有多个线程会访问到集合,那最好是使用Vector,因为不需要我们自己再去考虑和编写线程安全的代码。
备注:对于Vector&ArrayList、Hashtable&HashMap,要记住线程安全的问题,记住Vector与Hashtable是旧的,是java一诞生就提供了的,它们是线程安全的,ArrayList与HashMap是java2时才提供的,它们是线程不安全的。所以,我们讲课时先讲老的。
(2)数据增长:
ArrayList与Vector都有一个初始的容量大小,当存储进它们里面的元素的个数超过了容量时,就需要增加ArrayList与Vector的存储空间,每次要增加存储空间时,不是只增加一个存储单元,而是增加多个存储单元,每次增加的存储单元的个数在内存空间利用与程序效率之间要取得一定的平衡。Vector默认增长为原来两倍,而ArrayList的增长策略在文档中没有明确规定(从源代码看到的是增长为原来的1.5倍)。ArrayList与Vector都可以设置初始的空间大小,Vector还可以设置增长的空间大小,而ArrayList没有提供设置增长空间的方法。
总结:即Vector增长原来的一倍,ArrayList增加原来的0.5倍。
List、Set和Map的区别?
a.List和Set是Collection的子接口,map不是。
b.List的底层是数组的方式实现,Set是散列表的方式实现,map是键值对的方式。
c.list是有序可重复的,Set是无序不可重复的,map是有序,key不重复,value可重复
d.list和Set可直接使用itertator来进行遍历,map只能通过先遍历Key在遍历value.
Collection 和 Collections的区别。
Collection是集合类的上级接口,继承与他的接口主要有Set 和List.
Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。
Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()?它们有何区别?
Set里的元素是不能重复的,元素重复与否是使用equals()方法进行判断的。
equals()和==方法决定引用值是否指向同一对象equals()在类中被覆盖,为的是当两个分离的对象的内容和类型相配的话,返回真值。
什么是java序列化,如何实现java序列化?
通俗的说,就是可以将内存中Java对象可以写在硬盘上(序列化到硬盘上),反序列化就是讲硬盘的内容读取到内存中去;java是通过实现Serializable接口,实现的序列化,Serializable接口里面没有任何的方法,只是个标示接口。
heap和stack有什么区别。
java的内存分为两类,一类是栈内存,一类是堆内存。栈内存是指程序进入一个方法时,会为这个方法单独分配一块私属存储空间,用于存储这个方法内部的局部变量,当这个方法结束时,分配给这个方法的栈会释放,这个栈中的变量也将随之释放。
堆是与栈作用不同的内存,一般用于存放不放在当前方法栈中的那些数据,例如,使用new创建的对象都放在堆里,所以,它不会随方法的结束而消失。方法中的局部变量使用final修饰后,放在堆中,而不是栈中。
GC是什么? 为什么要有GC?
GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的显示操作方法。<br />** **
编写一个程序,将d:\java目录下的所有.java文件复制到d:\jad目录下,并将原来文件的扩展名从.java改为.jad。
答:listFiles方法接受一个FileFilter对象,这个FileFilter对象就是过虑的策略对象,不同的人提供不同的FileFilter实现,即提供了不同的过滤策略。
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class Jad2Java {
public static void main(String[] args) throws Exception {
File srcDir = new File(“java”);
if(!(srcDir.exists() && srcDir.isDirectory()))
throw new Exception(“目录不存在”);
File[] files = srcDir.listFiles(
new FilenameFilter(){
public boolean accept(File dir, String name) {
return name.endsWith(“.java”);
}
}
);
System.out.println(files.length);
File destDir = new File(“jad”);
if(!destDir.exists()) destDir.mkdir();
for(File f :files){
FileInputStream fis = new FileInputStream(f);
String destFileName = f.getName().replaceAll(“\.java$”, “.jad”);
FileOutputStream fos = new FileOutputStream(new File(destDir,destFileName));
copy(fis,fos);
fis.close();
fos.close();
}
}
private static void copy(InputStream ips,OutputStream ops) throws Exception{
int len = 0;
byte[] buf = new byte[1024];
while((len = ips.read(buf)) != -1){
ops.write(buf,0,len);
}
}
}
由本题总结的思想及策略模式的解析:
1.
class jad2java{
1.得到某个目录下的所有的java文件集合
1.1得到目录 File srcDir = new File(“d:\java”);
1.2得到目录下的所有java文件:File[] files = srcDir.listFiles(new MyFileFilter());
1.3只想得到.java的文件: class MyFileFilter implememyts FileFilter{
public boolean accept(File pathname){
return pathname.getName().endsWith(“.java”)
}
}
2.将每个文件复制到另外一个目录,并改扩展名
2.1得到目标目录,如果目标目录不存在,则创建之
2.2根据源文件名得到目标文件名,注意要用正则表达式,注意.的转义。
2.3根据表示目录的File和目标文件名的字符串,得到表示目标文件的File。
//要在硬盘中准确地创建出一个文件,需要知道文件名和文件的目录。
2.4将源文件的流拷贝成目标文件流,拷贝方法独立成为一个方法,方法的参数采用抽象流的形式。
//方法接受的参数类型尽量面向父类,越抽象越好,这样适应面更宽广。
}
分析listFiles方法内部的策略模式实现原理
File[] listFiles(FileFilter filter){
File[] files = listFiles();
//Arraylist acceptedFilesList = new ArrayList();
File[] acceptedFiles = new File[files.length];
int pos = 0;
for(File file: files){
boolean accepted = filter.accept(file);
if(accepted){
//acceptedFilesList.add(file);
acceptedFiles[pos++] = file;
}
}
Arrays.copyOf(acceptedFiles,pos);
//return (File[])accpetedFilesList.toArray();
}
说明生活中遇到的二叉树,用java实现二叉树
这是组合设计模式。
我有很多个(假设10万个)数据要保存起来,以后还需要从保存的这些数据中检索是否存在某个数据,(我想说出二叉树的好处,该怎么说呢?那就是说别人的缺点),假如存在数组中,那么,碰巧要找的数字位于99999那个地方,那查找的速度将很慢,因为要从第1个依次往后取,取出来后进行比较。平衡二叉树(构建平衡二叉树需要先排序,我们这里就不作考虑了)可以很好地解决这个问题,但二叉树的遍历(前序,中序,后序)效率要比数组低很多,原理如下图:
代码如下:
package com.huawei.interview;
public class Node {
public int value;
public Node left;
public Node right;
public void store(int value)
{
if(value
if(left == null)
{
left = new Node();
left.value=value;
}
else
{
left.store(value);
}
}
else if(value>this.value)
{
if(right == null)
{
right = new Node();
right.value=value;
}
else
{
right.store(value);
}
}
}
public boolean find(int value)
{
System.out.println(“happen “ + this.value);
if(value == this.value)
{
return true;
}
else if(value>this.value)
{
if(right == null) return false;
return right.find(value);
}else
{
if(left == null) return false;
return left.find(value);
}
}
public void preList()
{
System.out.print(this.value + “,”);
if(left!=null) left.preList();
if(right!=null) right.preList();
}
public void middleList()
{
if(left!=null) left.preList();
System.out.print(this.value + “,”);
if(right!=null) right.preList();
}
public void afterList()
{
if(left!=null) left.preList();
if(right!=null) right.preList();
System.out.print(this.value + “,”);
}
public static void main(String [] args)
{
int [] data = new int[20];
for(int i=0;i
data[i] = (int)(Math.random()100) + 1;
System.out.print(data[i] + “,”);
}
System.out.println();
Node root = new Node();
root.value = data[0];
for(int i=1;i
root.store(data[i]);
}
root.find(data[19]);
root.preList();
System.out.println();
root.middleList();
System.out.println();
root.afterList();
}
}
————————-又一次临场写的代码—————————————-
import java.util.Arrays;
import java.util.Iterator;
public class Node {
private Node left;
private Node right;
private int value;
//private int num;
public Node(int value){
this.value = value;
}
public void add(int value){
if(value > this.value)
{
if(right != null)
right.add(value);
else
{
Node node = new Node(value);
right = node;
}
}
else{
if(left != null)
left.add(value);
else
{
Node node = new Node(value);
left = node;
}
}
}
public boolean find(int value){
if(value == this.value) return true;
else if(value > this.value){
if(right == null) return false;
else return right.find(value);
}else{
if(left == null) return false;
else return left.find(value);
}
}
public void display(){
System.out.println(value);
if(left != null) left.display();
if(right != null) right.display();
}
/
}/
public static void main(String[] args){
int[] values = new int[8];
for(int i=0;i<8;i++){
int num = (int)(Math.random() 15);
//System.out.println(num);
//if(Arrays.binarySearch(values, num)<0)
if(!contains(values,num))
values[i] = num;
else
i—;
}
System.out.println(Arrays.toString(values));
Node root = new Node(values[0]);
for(int i=1;i
}
System.out.println(root.find(13));
root.display();
}
public static boolean contains(int [] arr, int value){
int i = 0;
for(;i
}
return false;
}
}
第1个人10,第2个比第1个人大2岁,依次递推,请用递归方式计算出第8个人多大?
package cn.itcast;
import java.util.Date;
public class A1 {
public static void main(String [] args)
{
System.out.println(computeAge(8));
}
public static int computeAge(int n)
{
if(n==1) return 10;
return computeAge(n-1) + 2;
}
}
public static void toBinary(int n,StringBuffer result)
{
if(n/2 != 0)
toBinary(n/2,result);
result.append(n%2);
}
排序都有哪几种方法?请列举。用JAVA实现一个快速排序。
public class QuickSort {
/
快速排序
@param strDate
@param left
@param right
*/
public void quickSort(String[] strDate,int left,int right){
String middle,tempDate;
int i,j;
i=left;
j=right;
middle=strDate[(i+j)/2];
do{
while(strDate[i].compareTo(middle)<0&& i
while(strDate[j].compareTo(middle)>0&& j>left)
j—; //找出右边比中间值小的数
if(i<=j){ //将左边大的数和右边小的数进行替换
tempDate=strDate[i];
strDate[i]=strDate[j];
strDate[j]=tempDate;
i++;
j—;
}
}while(i<=j); //当两者交错时停止
if(i
}
if(j>left){
quickSort(strDate,left,j);
}
}
/
@param args
/
public static void main(String[] args){
String[] strVoid=new String[]{“11”,”66”,”22”,”0”,”55”,”22”,”0”,”32”};
QuickSort sort=new QuickSort();
sort.quickSort(strVoid,0,strVoid.length-1);
for(int i=0;i
}
}
}
金额转换,阿拉伯数字的金额转换成中国传统的形式如:(¥1011)->(一千零一拾一元整)输出。
去零的代码:
return sb.reverse().toString().replaceAll(“零[拾佰仟]”,”零”).replaceAll(“零+万”,”万”).replaceAll(“零+元”,”元”).replaceAll(“零+”,”零”);
public class RenMingBi {
/*
@param args add by zxx ,Nov 29, 2008
*/
private static final char[] data = new char[]{
‘零’,’壹’,’贰’,’叁’,’肆’,’伍’,’陆’,’柒’,’捌’,’玖’
};
private static final char[] units = new char[]{
‘元’,’拾’,’佰’,’仟’,’万’,’拾’,’佰’,’仟’,’亿’
};
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(
convert(135689123));
}
public static String convert(int money)
{
StringBuffer sbf = new StringBuffer();
int unit = 0;
while(money!=0)
{
sbf.insert(0,units[unit++]);
int number = money%10;
sbf.insert(0, data[number]);
money /= 10;
}
return sbf.toString();
}
}
什么是内部类?分为哪几种?
内部类是指在一个外部类的内部再定义一个类。内部类作为外部类的一个成员,并且依附于外部类而存在的。内部类可为静态,可用protected和private修饰(而外部类只能使用public和缺省的包访问权限)。
内部类主要有以下几类:成员内部类、局部内部类、静态内部类、匿名内部类。
为什么需要内部类?
典型的情况是,内部类继承自某个类或实现某个接口,内部类的代码操作创建其的外围类的对象。所以你可以认为内部类提供了某种进入其外围类的窗口。
使用内部类最吸引人的原因是:每个内部类都能独立地继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。如果没有内部类提供的可以继承多个具体的或抽象的类的能力,一些设计与编程问题就很难解决。从这个角度看,内部类使得多重继承的解决方案变得完整。接口解决了部分问题,而内部类有效地实现了“多重继承”。
内部类可以引用它的包含类的成员吗?有没有什么限制?
完全可以。如果不是静态内部类,那没有什么限制!
如果你把静态嵌套类当作内部类的一种特例,那在这种情况下不可以访问外部类的普通成员变量,而只能访问外部类中的静态成员,例如,下面的代码:
class Outer
{
static int x;
static class Inner
{
void test()
{
syso(x);
}
}
}
答题时,也要能察言观色,揣摩提问者的心思,显然人家希望你说的是静态内部类不能访问外部类的成员,但你一上来就顶牛,这不好,要先顺着人家,让人家满意,然后再说特殊情况,让人家吃惊。
Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)?
java中有几种类型的流?JDK为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类?
字节流,字符流。字节流继承于InputStream OutputStream,字符流继承于InputStreamReader OutputStreamWriter。在java.io包中还有许多其他的流,主要是为了提高性能和使用方便
字节流与字符流的区别
把一片二进制数据数据逐一输出到某个设备中,或者从某个设备中逐一读取一片二进制数据,不管输入输出设备是什么,我们要用统一的方式来完成这些操作,用一种抽象的方式进行描述,这个抽象描述方式起名为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);
}
简述 static 和 和 final 的 用法?
static:修饰属性,方法,代码块
(1)静态属性:也可叫类变量 类名.属性名 来访问
(共有的类变量与对象无关,只和类有关)
注意:类中的实例变量是在创建对象时被初始化的,被 static 修饰的属性,也就是类变量,是在类加载时被创建并进行初始化,类加载的过程是进行一次。也就是类变量只会被创建一次。
(2)静态方法:类名.方法名 直接访问
注意:static 修饰的方法,不能直接访问本类中的非静态(static)成员(包括方法和属性)
本类的非静态方法可以访问本类的静态成员(包括方法和属性),可以调用静态方法。
修饰变量,方法,类
final:修饰变量,类,方法
(1)修饰变量
被 fianl 修饰的成员变量就是常量(常量名大写),一旦赋值不能改变
修饰局部变量:修饰基本数据类型 -> 变量的值不能改变
修饰引用 -> 引用只能指向固定的对象
修饰实例变量:默认值不生效,可以再赋值
(2)修饰方法 :不能被子类覆盖
(3)修饰类:不能被继承
在一个 final 类中的所有方法,默认都是 final 的
注意:final,不能用来修饰构造方法。
写出冒泡排序的算法
for(int i=0;i<arr.length-1;i++){ //控制轮数for(int j=0;j<arr.length-1-i;j++){ //控制每一轮的次数if(arr[j]>arr[j+1]){ //每次都是和它下一个元素比int t=arr[j];arr[j]=arr[j+1];arr[j+1]=t;}}}
abstract class 和 interface 有什么区别?

1.相同点
A. 两者都是抽象类,都不能实例化。
B. interface 实现类及 abstrct class 的子类都必须要实现已经声明的抽象方法。
2. 不同点
A. interface 需要实现,要用 implements,而 abstract class 需要继承,要用 extends。
B. 一个类可以实现多个 interface,但一个类只能继承一个 abstract class。
C. interface 强调特定功能的实现,而 abstract class 强调所属关系。
D. 尽管 interface 实现类及 abstrct class 的子类都必须要实现相应的抽象方法,但实现的形式不同。interface 中的每一个方法都是抽象方法,都只是声明的 (declaration, 没有方法体),实现类必须要实现。而 abstract class 的子类可以有选择地实现。
类有哪三个基本特性?各特性的优点?
类具有封装性、继承性和多态性。
封装性:类的封装性为类的成员提供公有、缺省、保护和私有等访问权限,目的是隐藏类中的私有变量和类中方法的实现细节。
继承性:允许通过继承原有类的某些特性或全部特性而产生全新的类,原有的累称为父类,产生的新类称为子类。子类不仅可以直接继承父类的共性,而且也可以创建它特有的个性。
多态性:是指在基类中定义的属性和方法被子类继承之后,可以具有不同的数据类型或表现出不同行为,多态性有两种表现形式:重载和覆盖。
Error和Exception有什么区别? 列出你见过的Exception并简要说明
答:error表示系统级的错误和程序不必处理的异常,
是恢复不是不可能但很困难的情况下的一种严重问题;
比如内存溢出,不可能指望程序能处理这样的情况;
exception表示需要捕捉或者需要程序进行处理的异常,
是一种设计或实现问题;也就是说,它表示如果程序运行正常,
从不会发生的情况。 常见异常有: NullPointerException:
当操作一个空引用时会出现此错误。 NumberFormatException:
数据格式转换出现问题时出现此异常。 ClassCastException:
强制类型转换类型不匹配时出现此异常。 ArrayIndexOutOfBoundsException:
数组下标越界,当使用一个不存在的数组下标时出现此异常。
java中会存在内存泄露吗?请简单描述
答:内存泄露是指系统中存在无法回收的内存,
有时候会造成内存不足或系统崩溃。Java存在内存泄露。
Java中的内存泄露当然是指:存在无用但是垃圾回收器无法回收的对象。
而且即使有内存泄露问题存在,也不一定会表现出来。
自己实现堆栈的数据结构时有可能会出现内存泄露。
多线程有几种实现方法,都是什么?同步有几种实现方法,都是什么?
答:多线程有两种实现方法:继承Thread类或者实现Runnable接口。
实现同步也有两种方法:一种是同步方法,另一种是同步代码块。
同步方法是在方法返回类型前面加上synchronized关键字
同步代码块是synchronized (这里写需要同步的对象){…}
sleep()和wait()有什么区别?
答案:
不同点:
1. Thread类的方法:sleep(),yield()等
Object的方法:wait()和notify()等
2.每个对象都有一个锁来控制同步访问。Synchronized关键字可以和对象的锁交互,来实现线程的同步。
sleep方法没有释放锁,
wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。
3.wait、notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用
4.sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常
谈谈java跟你所知道的其它的语言相比,有什么优点??
Java是一种可以撰写跨平台应用程序的面向对象的程序设计语言。Java技术具有卓越的通用性、高效性、平台移植性和安全性,广泛应用于PC、数据中心、游戏控制台、科学超级计算机、移动电话和互联网,同时拥有全球最大的开发者专业社群。Java是功能完善的通用程序设计语言,可以用来开发可靠的、要求严格的应用程序。java是纯面向对象开发,功能强大,分支众多,没有java不能做的软件。C/S也好B/S也好。从功能上讲,没有语言可以和java相比。
C是面向过程编程的,这样往往会导致所谓的单一程序,既所有的功能只能包含在几个(通常是一个)代码模块中。当然,C语言也有自身的不足,比如:C语言的语法限制不太严格,对变量的类型约束不严格,影响程序的安全性,对数族下标越界不作检查等。从应用的角度,C语言比其他高级语言较难掌握。
谈谈你对面向对象的理解??
所谓的面向对象就是将我们的程序模块化,对象化,把具体事物的特性属性和通过这些属性来实现一些动作的具体方法放到一个类里面,这就是封装。封装是我们所说的面相对象编程的特征之一。除此之外还有继承和多态。继承有点类似与我们生物学上的遗传,就是子类的一些特征是来源于父类的,儿子遗传了父亲或母亲的一些性格,或者相貌,又或者是运动天赋。有点种瓜得瓜种豆得豆的意思。面向对象里的继承也就是父类的相关的属性,可以被子类重复使用,子类不必再在自己的类里面重新定义一回,父类里有点我们只要拿过来用就好了。而对于自己类里面需要用到的新的属性和方法,子类就可以自己来扩展了。当然,会出现一些特殊情况,就是我们在有一些方法在父类已经定义好了,但是子类我们自己再用的时候,发现,其实,我们的虽然都是计算工资的,但是普通员工的工资计算方法跟经理的计算方法是不一样的,所以这个时候,我们就不能直接调用父类的这个计算工资的方法了。这个时候我们就需要用到面向对象的另一个特性,多态。对,就是多态,我们要在子类里面把父类里面定义计算工资的方法在子类里面重新实现一遍。多态包含了重载和重写。重写很简单就是把子类从父亲类里继承下来的方法重新写一遍,这样,父类里相同的方法就被覆盖了,当然啦,你还是可以通过super.CaculSalary方法来调用父类的工资计算方法。而重载就是类里面相同方法名,不同形参的情况,可以是形参类型不同或者形参个数不同,或者形参顺序不同,但是不能使返回值类型不同。
简单讲一下java的跨平台原理
java源程序(.java文件)通过编译器编译成为Class文件(字节码文件),而它的class文件是基于字节码(以byte为单位存储的文件)的,而字节码文件是描述程序要运行的的虚指令的集合,这些虚指令的集合与任何的平台无关,Java虚拟机认识它(只要在不同的平台下部署相应的jre,运行jvm!就可以了)
有了基本数据类型,为什么还需要包装类型?
我们知道Java是一个面相对象的编程语言,基本类型并不具有对象的性质,为了让基本类型也具有对象的特征,就出现了包装类型(如我们在使用集合类型Collection时就一定要使用包装类型而非基本类型),它相当于将基本类型“包装起来”,使得它具有了对象的性质,并且为其添加了属性和方法,丰富了基本类型的操作。
另外,当需要往ArrayList,HashMap中放东西时,像int,double这种基本类型是放不进去的,因为容器都是装object的,这是就需要这些基本类型的包装器类了。
Java是一个面向对象的语言,然而基本数据类型不具备面向对象的属性。当我们把基本数据类型包装成包装类型后,基本数据类型就具备了面向对象的属性。
在ArrayList 、HashMap这些容器来传输数据是,,基本类型int和double是传输不进去的,因为容器都是装泛型(object类型)的,所以需要转为包装类型进行传输。
每一个基本类型都有对应的包装类型
说一下”==”和equals方法究竟有什么区别?
==操作符专门用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存储的数值是否相同,要比较两个基本类型的数据或两个引用变量是否相等,只能用==操作符。
equals 方法是用于比较两个独立对象的内容是否相同,就好比去比较两个人的长相是否相同,它比较的两个对象是独立的。
答案:对于比较基本数据类型来说,==比较的就是数值的大小,例如:
int m = 2;
int n = 3;
boolean b = m==n;
System.out.println(b);//结果为false,因为2和3不等吗.
但是对于引用类型数据来说,==和equals就有些不同了,在大多数类中的equals方法调用的依然是==,但比较的是两个引用变量的地址是否相同.
例如:
int[] arr1 = {1,2,3};
int[] arr2 = {1,2,3};
System.out.println(arr1==arr2);//结果是false,因为比较的是地址值.
System.out.println(arr1.equals(arr2));//结果还是false,因为比较的还是地址值.其实调用的方法还是”==”
但是在字符串String中就不一样了,因为String中的equals方法被重写了,它比较的是两个字符串对象中的内容是否相同.
例如:
String s1 = new String(“abc”);
String s2 = new String(“abc”);
System.out.println(s1==s2);//结果是false,因为比较的是地址值.
System.out.println(s1.equals(s2));//结果是true,因为比较的是对象中内容是否相同.
**
讲一下java中的集合
set(集)、list(列表)和map(映射)。
区别嘛 HASHMAP只有KEY和value值对应的。。set是可以自动清楚相同的元素
list是其对象以线性方式存储,没有特定顺序,只有一个开头和一个结尾,当然,它与根本没有顺序的集是不同的。
列表在数据结构中分别表现为:数组和向量、链表、堆栈、队列。
ArrayList和LinkedList的区别?
1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。 2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。 3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。
讲一下HashMap和HashTable的区别?
在Java 2以前,一般使用Hashtable来映射键值和元素。为了使用Java集合框架,Java对Hashtable进行了重新设计,但是,为了向后兼容保留了所有的方法。Hashtable实现了Map接口,除了Hashtable具有同步功能之外,它与HashMap的用法是一样的。·在使用时一般是用ArrayList代替Vector,LinkedList代替Stack,HashMap代替HashTable,即使在多线程中需要同步,也是用同步包装类。
请说出集合类中List、Map、Set的区别
答:List和Set继承了Collection接口,而map不是;
List中存放元素有顺序并且可以重复;
set中存放的元素是无序并且是不可能重复的;
Map中存放是键值对。
Collection 和 Collections的区别?
答:Collection是java.util下的接口,它是各种集合的父接口,
继承于它的接口主要有Set 和List;Collections是个java.util下的类,
是针对集合的帮助类,提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。
HashSet :内部封装了HashMap和TreeMap,数据保存在键这一列
LinkedHashMap(哈希表,存放数据以链表来连接,数组存放无序但链表连接有序,可看做一个有序的HashMap),既可快速定位,查找数据,又可以使数据存放有序
ConcurrentHashMap(分段加锁)Concurrent-同步
String、StringBuffer和StringBuilder的区别?
1、首先说运行速度,或者说是执行速度,在这方面运行速度快慢为:StringBuilder > StringBuffer > String
2、再来说线程安全
在线程安全上,StringBuilder是线程不安全的,而StringBuffer是线程安全的
String:适用于少量的字符串操作的情况
StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况
StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况
讲一下线程的几种实现方式?
extends Thread
implements Runnable
implements Callable
Runnable和Callable的区别是 :
(1)Callable规定的方法是call(),Runnable规定的方法是run()。
(2)Callable的任务执行后可返回值,而Runnable的任务是不能返回值得
(3)call方法可以抛出异常,run方法不可以
(4)运行Callable任务可以拿到一个Future对象,表示异步计算的结果。
讲一下线程的几种启动方式?
.第一种方法是将类声明为 Thread 的子类。该子类应重写 Thread 类的 run 方法,然后在run方法里填写相应的逻辑代码。
第二种方法是实现Runnable接口,并编写run方法,相比继承Thread类创建线程的好处是以实现接口的方式创建线程可以对类进行更好的扩展,该类可以继承其他类来扩展自身需求,相比第一种方式更加灵活,扩展性强。
实现Callable接口创建线程与Runnable接口的不同之处在于:如果你想要在线程执行完毕之后得到带有返回值的线程则实现Callable接口
有没有使用过线程并发库?
在java5之后,就有了线程池的功能了,在介绍线程池之前,先来简单看一下线程池的概念。假设我开了家咨询公司,那么每天会有很多人过来咨询问题,如果我一个个接待的话,必然有很多人要排队,这样效率就很差,我想解决这个问题,现在我雇几个客服,来了一个咨询的,我就分配一个客服去接待他,再来一个,我再分配个客服去接待……如果第一个客服接待完了,我就让她接待下一个咨询者,这样我雇的这些客服可以循环利用。这些客服就好比不同的线程,那么装这些线程的容器就称为线程池。
静态变量和实例变量的区别?
静态变量也叫类变量,这种变量前加了static修饰符。可以直接用类名调用,也可以用对象调用,而且所有对象的同一个类变量 都是共享同一块内存空间。
实例变量也叫对象变量,这种变量没有加static修饰符。只能通过对象调用, 而且所有对象的同一个实例变量是共享不同的内存空间的。
区别在于:
静态变量是所有对象共有的,某一个对象将它的值改变了,其他对象再去获取它的值,得到的是改变后的值;
实例变量则是每一个对象私有的,某一个对象将它的值改变了,不影响其他对象取值的结果,其他对象仍会得到实例变量一开始就被赋予的值。
try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后?
会执行 try{}中的return执行后在没有返回数据时先去执行finally{}中的代码,然后再返回。所以说finally{}在return中间执行
同步和异步有何异同,在什么情况下分别使用他们?举例说明。
如果数据将在线程间共享.例如正在写的数据以后可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那么这些数据就是共享数据,必须进行同步存取.
当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往往更有效率.
java 中有几种类型的流?JDK 为每种类型的流提供了一些抽象类以供继承, 请说出他们分别是哪些类?
Java中的流分为两种,一种是字节流,另一种是字符流,分别由四个抽象类来表示(每种流包括输入和输出两种所以一共四个):InputStream,OutputStream,Reader,Writer。Java中其他多种多样变化的流均是由它们派生出来的.
**
&和&&的区别?
&和&&都可以用作逻辑运算符,表示逻辑与。当运算符两边的表达式都为true时,结果才为true;否则,结果为false。
另外&&还具有短路功能,也就是说,当&&左边的表达式结果为false时,将不再运算&&右边的表达式,结果肯定为false。例如,对于if(str!=null&&!str.equals(“”)),当str为null时,不会对&&右边的表达式进行运算,否则会出现空指针异常。
&还可以用作位运算符,当&两边的表达式不是boolean类型时,&表示按位与。
数组有没有length()这个方法? String有没有length()这个方法?
数组中没有length()这个方法,但是数组中有length这个属性。用来表示数组的长度。
String中有length()这个方法。用来得到字符串的长度。
构造器Constructor是否可被override?
构造器Constructor不能被继承,因此不能重写Override,但可以被重载Overload。
Constructor不能被继承,所以Constructor也就不能被override。每一个类必须有自己的构造函数,负责构造自己这部分的构造。子类不会覆盖父类的构造函数,相反必须负责在一开始调用父类的构造函数。
构造器如何工作?
Java在构造实例时的顺序是这样的:
1、分配对象空间,并将对象中成员初始化为0或者空,java不允许用户操纵一个不定值的对象。
2、执行属性值的显式初始化
3、执行构造器
4 、将变量关联到堆中的对象上
super与this的区别?
不同点: 1、super()主要是对父类构造函数的调用,this()是对重载构造函数的调用
2、super()主要是在继承了父类的子类的构造函数中使用,是在不同类中的使用;
this()主要是在同一类的不同构造函数中的使用
相同点: 1、super()和this()都必须在构造函数的第一行进行调用,否则就是错误的
GC是什么? 为什么要有GC?
GC是垃圾收集的意思,内存处理是编程人员容易出现问题的地方,
忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,
Java语言没有提供释放已分配内存的显示操作方法。Java程序员不用担心内存管理,因为垃圾收集器会自动进行管理。要请求垃圾收集,可以调用下面的方法之一:System.gc()或Runtime.getRuntime().gc(),但JVM可以屏蔽掉显示的垃圾回收调用。
垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存。垃圾回收器通常是作为一个单独的低优先级的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清除和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收。
在Java诞生初期,垃圾回收是Java最大的亮点之一,因为服务器端的编程需要有效的防止内存泄露问题,然而时过境迁,如今Java的垃圾回收机制已经成为被诟病的东西。移动智能终端用户通常觉得iOS的系统比Android系统有更好的用户体验,其中一个深层次的原因就在于Android系统中垃圾回收的不可预知性。
接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承实体类?
接口可以继承接口。抽象类可以实现(implements)接口,抽象类可继承实体类,但前提是实体类必须有明确的构造函数
内部类可以引用他包含类的成员吗?有没有什么限制?
完全可以。如果不是静态内部类,那没有什么限制!
如果你把静态嵌套类当作内部类的一种特例,那在这种情况下不可以访问外部类的普通成员变量,而只能访问外部类中的静态成员
Java有没有goto?
答:
goto 是Java中的保留字,在目前版本的Java中没有使用。(根据James Gosling(Java之父)编写的《The Java Programming Language》一书的附录中给出了一个Java关键字列表,其中有goto和const,但是这两个是目前无法使用的关键字,因此有些地方将其称之为保留字,其实保留字这个词应该有更广泛的意义,因为熟悉C语言的程序员都知道,在系统类库中使用过的有特殊意义的单词或单词的组合都被视为保留字)
解释内存中的栈(stack)、堆(heap)和静态区(static area)的用法
答:通常我们定义一个基本数据类型的变量,一个对象的引用,还有就是函数调用的现场保存都使用内存中的栈空间;而通过new关键字和构造器创建的对象放在堆空间;程序中的字面量(literal)如直接书写的100、”hello”和常量都是放在静态区中。栈空间操作起来最快但是栈很小,通常大量的对象都是放在堆空间,理论上整个内存没有被其他进程使用的空间甚至硬盘上的虚拟内存都可以被当成堆空间来使用。
用最有效率的方法计算2乘以8?
答: 2 << 3(左移3位相当于乘以2的3次方,右移3位相当于除以2的3次方)。
在Java中,如何跳出当前的多重嵌套循环?
答:在最外层循环前加一个标记如A,然后用break A;可以跳出多重循环。(Java中支持带标签的break和continue语句,作用有点类似于C和C++中的goto语句,但是就像要避免使用goto一样,应该避免使用带标签的break和continue,因为它不会让你的程序变得更优雅,很多时候甚至有相反的作用,所以这种语法其实不知道更好)
两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对?
答:不对,如果两个对象x和y满足x.equals(y) == true,它们的哈希码(hash code)应当相同。Java对于eqauls方法和hashCode方法是这样规定的:
(1)如果两个对象相同(equals方法返回true),那么它们的hashCode值一定要相同;
(2)如果两个对象的hashCode相同,它们并不一定相同。当然,你未必要按照要求去做,但是如果你违背了上述原则就会发现在使用容器时,相同的对象可以出现在Set集合中,同时增加新元素的效率会大大下降(对于使用哈希存储的系统,如果哈希码频繁的冲突将会造成存取性能急剧下降)。
char 型变量中能不能存贮一个中文汉字,为什么?
答:char类型可以存储一个中文汉字,因为Java中使用的编码是Unicode(不选择任何特定的编码,直接使用字符在字符集中的编号,这是统一的唯一方法),一个char类型占2个字节(16比特),所以放一个中文是没问题的。
Anonymous Inner Class(匿名内部类)是否可以继承其它类?是否可以实现接口?
答:可以继承其他类或实现其他接口,在Swing编程和Android开发中常用此方式来实现事件监听和回调。
内部类可以引用它的包含类(外部类)的成员吗?有没有什么限制?
答:一个内部类对象可以访问创建它的外部类对象的成员,包括私有成员。
Java 中的final关键字有哪些用法?
答:(1)修饰类:表示该类不能被继承;(2)修饰方法:表示方法不能被重写;(3)修饰变量:表示变量只能一次赋值以后值不能被修改(常量)。
写出常见的5个RuntimeException
(1)java.lang.NullPointerException空指针异常,出现原因:调用了未经初始化的对性爱那个或者不存在的对象。<br /> (2)ClassNoFoundException 指定类找不到,出现原因:类的名称和路径加载错误,通常是试图通过字符串来加载某个类时可能引发异常。<br /> (3)NumberFormatException字符串转换为数字异常,出现原因:字符串数据中包含非数字型字符。<br /> (4)IndexOutOfBoundsException数组下标越界异常<br /> (5)IllegalArgumentException 方法传递参数错误<br /> (6)ClassCastException数据类型转换异常<br /> (7)NoClassDefFoundExcetion 未找到类定义错误<br /> (8)SQLException SQL异常<br /> (9)InstantiationException实例化异常<br /> (10)NoSuchMethodExceptioin 方法不存在异常
阐述final、finally、finalize的区别。
答:- final:修饰符(关键字)有三种用法:如果一个类被声明为final,意味着它不能再派生出新的子类,即不能被继承,因此它和abstract是反义词。将变量声明为final,可以保证它们在使用中不被改变,被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取不可修改。被声明为final的方法也同样只能使用,不能在子类中被重写。- finally:通常放在try…catch…的后面构造总是执行代码块,这就意味着程序无论正常执行还是发生异常,这里的代码只要JVM不关闭都能执行,可以将释放外部资源的代码写在finally块中。- finalize:Object类中定义的方法,Java中允许使用finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在销毁对象时调用的,通过重写finalize()方法可以整理系统资源或者执行其他清理工作。
阐述ArrayList、Vector、LinkedList的存储性能和特性。
答:ArrayList 和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector中的方法由于添加了synchronized修饰,因此Vector是线程安全的容器,但性能上较ArrayList差,因此已经是Java中的遗留容器。LinkedList使用双向链表实现存储(将内存中零散的内存单元通过附加的引用关联起来,形成一个可以按序号索引的线性结构,这种链式存储方式与数组的连续存储方式相比,内存的利用率更高),按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。Vector属于遗留容器(Java早期的版本中提供的容器,除此之外,Hashtable、Dictionary、BitSet、Stack、Properties都是遗留容器),已经不推荐使用,但是由于ArrayList和LinkedListed都是非线程安全的,如果遇到多个线程操作同一个容器的场景,则可以通过工具类Collections中的synchronizedList方法将其转换成线程安全的容器后再使用(这是对装潢模式的应用,将已有对象传入另一个类的构造器中创建新的对象来增强实现)。
Collection和Collections的区别?
答:Collection是一个接口,它是Set、List等容器的父接口;Collections是个一个工具类,提供了一系列的静态方法来辅助容器操作,这些方法包括对容器的搜索、排序、线程安全化等等。
List、Map、Set三个接口存取元素时,各有什么特点?
答:List以特定索引来存取元素,可以有重复元素。Set不能存放重复元素(用对象的equals()方法来区分元素是否重复)。Map保存键值对(key-value pair)映射,映射关系可以是一对一或多对一。Set和Map容器都有基于哈希存储和排序树的两种实现版本,基于哈希存储的版本理论存取时间复杂度为O(1),而基于排序树版本的实现在插入或删除元素时会按照元素或元素的键(key)构成排序树从而达到排序和去重的效果。
当一个线程进入一个对象的synchronized方法A之后,其它线程是否可进入此对象的synchronized方法B?
答:不能。其它线程只能访问该对象的非同步方法,同步方法则不能进入。因为非静态方法上的synchronized修饰符要求执行方法时要获得对象的锁,如果已经进入A方法说明对象锁已经被取走,那么试图进入B方法的线程就只能在等锁池(注意不是等待池哦)中等待对象的锁。
请说出与线程同步以及线程调度相关的方法。
答:- wait():使一个线程处于等待(阻塞)状态,并且释放所持有的对象的锁;- sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要处理InterruptedException异常;- notify():唤醒一个处于等待状态的线程,当然在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且与优先级无关;- notityAll():唤醒所有处于等待状态的线程,该方法并不是将对象的锁给所有线程,而是让它们竞争,只有获得锁的线程才能进入就绪状态;
Java中如何实现序列化,有什么意义?
答:序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决对象流读写操作时可能引发的问题(如果不进行序列化可能会存在数据乱序的问题)。
要实现序列化,需要让一个类实现Serializable接口,该接口是一个标识性接口,标注该类对象是可被序列化的,然后使用一个输出流来构造一个对象输出流并通过writeObject(Object)方法就可以将实现对象写出(即保存其状态);如果需要反序列化则可以用一个输入流建立对象输入流,然后通过readObject方法从流中读取对象。序列化除了能够实现对象的持久化之外,还能够用于对象的深度克隆.
如何通过反射创建对象?
答:- 方法1:通过类对象调用newInstance()方法,例如:String.class.newInstance()- 方法2:通过类对象的getConstructor()或getDeclaredConstructor()方法获得构造器(Constructor)对象并调用其newInstance()方法创建对象,例如:String.class.getConstructor(String.class).newInstance(“Hello”);
谈谈 JVM 的内存结构和内存分配?
Java内存模型
Java 虚拟机将其管辖的内存大致分三个逻辑部分:方法区(Method Area)、 Java 栈和 Java 堆。
1、方法区是静态分配的,编译器将变量绑定在某个存储位置上,而且这些绑定不会在运行时改变。常数池,源代码中的命名常量、 String 常量和 static 变量保存在方法区。
2、 Java Stack 是一个逻辑概念,特点是后进先出。一个栈的空间可能是连续的,也可能是不连续的。最典型的 Stack 应用是方法的调用, Java 虚拟机每调用一次方法就创建一个方法帧(frame),退出该
方法则对应的 方法帧被弹出(pop)。栈中存储的数据也是运行时确定的。
3、 Java 堆分配(heap allocation)意味着以随意的顺序,在运行时进行存储空间分配和收回的内存管理模型。堆中存储的数据常常是大小、数量和生命期在编译时无法确定的。 Java 对象的内存总是在 heap 中分配。
b) java 内存分配
1、基础数据类型直接在栈空间分配;
2、方法的形式参数,直接在栈空间分配,当方法调用完成后从栈空间回收;
3、引用数据类型,需要用 new 来创建,既在栈空间分配一个地址空间,又在堆空间分配对象的类变量;
4、方法的引用参数,在栈空间分配一个地址空间,并指向堆空间的对象区,当方法调用完后从栈空间回收;
5、局部变量 new 出来时,在栈空间和堆空间中分配空间,当局部变量生命周期结束后,栈空间立刻被回收,堆空间区域等待 GC 回收;
6、方法调用时传入的实际参数,先在栈空间分配,在方法调用完成后从栈空间释放;
7、字符串常量在 DATA 区域分配 , this 在堆空间分配;
8、数组既在栈空间分配数组名称, 又在堆空间分配数组实际的大小。
什么是双亲委派机制
双亲委派模式的工作原理的是;如果一个类加载器收到了类加载请求,它并不会自己先去加载,而是把这个请求委托给父类的加载器去执行,如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归,请求最终将到达顶层的启动类加载器,如果父类加载器可以完成类加载任务,就成功返回,倘若父类加载器无法完成此加载任务,子加载器才会尝试自己去加载,这就是双亲委派模式,即每个儿子都不愿意干活,每次有活就丢给父亲去干,直到父亲说这件事我也干不了时,儿子自己想办法去完成,这不就是传说中的双亲委派模式.那么这种模式有什么作用呢?
Static 关键字有哪些作用?
Static 有两种作用:第一, 为某特定数据类型或对象分配单一的存储空间,而与创建对象的个数无关。第二, 实现某个方法或属性与类而不是对象关联在一起。 Static 主要是有 4 种使用情况: Static 修饰成员变量:用 static 修饰的变量称之为静态变量或者也叫类变量/全局变量。静态变量是随着类的加载而加载到方法区中的静态区,并且在静态区中赋予了初始值。静态变量是在对象之前产生,所以可以不通过对象来调用,而是通过类来调用,所以可以通过类名.静态变量的 方式调用静态变量。由于每个对象在堆内存中存储的是静态变量在静态区中的地址,所以所有 的对象本质上共用一个静态变量。 Static 修饰成员方法:用static 修饰的方法就称之为静态方法,也叫类方法。静态方法在类加载 的时候加载到了方法区中的静态区,在调用的时候到栈内存中执行。—-静态方法是先于对象而存在的。静态方法可以通过类名.方法名的方式来调用执行。 静态代码块:静态代码块在类中是独立于成员变量和成员方法的代码块。它不在任何一个方法体内,jvm 在加载类时会执行静态代码块,静态代码块是先于构造代码块执行。静态代码块在 类加载的时候执行,只执行一次。 静态内部类:静态内部类是指被声明为静态内部类,它可以不依赖与外部类实例对象而被实例化,而通常的内部类需要在外部类实例化后才能实例化。静态内部类不能与外部类有相同的名字,不能访问外部类的普通成员变量,只能访问外部类中的静态成员和静态方法
Instanceof 有什么作用?
Instanceof 的作用是判断一个引用类型的变量所指向的对象是否是一个类的实例。
什么是不可变类?
不可变类是指当创建了这个类的实例后,就不允许修改它的值了,也就是说,一个对象一旦被 创建出来,在其整个生命周期中,它的成员变量就不能被修改了。
值传递与引用传递的区别?
值传递:在方法调用中,实参会把它的值传递给形参,形参只是用实参的值初始化一个临时的存储单元(方法内的局部变量),因此性参与实参虽然有着相同的值,但是却有着不用的存储单元,因此对形参的改变不会影响实参的值。 引用传递:在方法的调用中,传递的是对象(也可以看做是对象的地址),这时形参与实参指向 同一块存储单元(对象),因此对形参的修改就会影响实参的值。
强制类型转换的注意事项有哪些?
Java在涉及 byte、short 和 char 类型的运算时,首先会把这些类型的变量值强制转换为 int 类型, 然后对 int 类型的值进行计算,最后得到的值也是 int 类型。因此,如果把两个 short 类型的值相 加,最后得到的结果是 int 型;如果把两个 byte 类型的值相加,最后也会得到一个 int 类型的值。 如果需要得到 short 类型的结果,就必须显示地把运算结果转换为 short 类型。
++i与 i++的区别?
++i 先运算后赋值,i++先赋值后运算。
字符串存储的机制是什么?
字符串会存储在常量池中。在给字符串赋值的时候,JVM 会检查常量池中是否已经存在该字符 串,如果存在则直接引用该地址,否则会在常量池中创建该字符串然后引用该地址
