一. java语言基础:
1、合法标识符:
答:以字母,“—”,“$“符号开头,可以包含字母“—”,“$“和数字;
2、八大类型以及各种整数类型的取值范围:
答:byte(-27至27-1)、short(-215至215-1)、int(-231至231-1)、long(-263至263-1)、
float、double、boolean、char等;
3、&(位运算符)与&&(关系运算符)区别:
答:&比较两个二进制是否为1;而&&比较两边是否为true,只有两边都为true时才为true;
4、if与else语句:
答:一个判断中可以有多个if、if else语句,但是只能有一个else;else可以没有;
5、switch里面数据类型包括:
答:整型(byte,short,int),char,枚举(重点);
6、while循环:
答:当while内条件为true时,循环继续执行,当while内条件为false时才退出循环;若一开始就为false时程序只执行do范围内语句一次;
Given:
10.int x=0;
11.int y=10;
12. do {
l3. y--;
14. ++x;
15. } while (x < 5);
16. System.out.print(x + "," + y);
Answer:5,5
7、break与continue区别:
答:continue是退出本次循环,继续下一次循环,而break是退出整个循环体;
8、关于可变长参数:
答:a、参数列表中最多只能出现一次可变长参数;
b、如果参数中包含多个参数的话,那么可变长参数只能出现在最后面的位置;
c、可变长参数可实现方法的重载(重点);
9、静态常量初始化两种方式:
答:静态常量必须显示的初始化;a、通过构造器进行初始化,b、只能用静态代码块初始化;
10、不同访问修饰符对类成员的访问范围:
可见性 public protected 默认(default) private
从同一个类 是 是 是 是
从同一个包中的任何类 是 是 是 否
从同一个包外的子类 是 是 否 否
从包外的任何非子类 是 否 否 否
11、String 和stringBuffer的区别:
答:String创建的字符串不能修改;而stringBuffer定义的字符串可以修改;
12、GC是什么? 为什么要有GC? GC全称?
答:GC是垃圾回收机制的意思,GC是用来自动回收超过作用域的对象;
GC全称:garbage collection
13、final, finally, finalize的区别。
final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
finally是异常处理语句结构的一部分,表示总是执行。
finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。
14、int 和 Integer 有什么区别?
答:a、Integer是对象类型,而int是基本数据类型;
b、类可以是null,但基本数据类型不能为空;
15、default可以放在中间吗?多个case可以共用一条语句;
答:可以,一般放在后面;
16、String s = new String("xyz");创建了几个String Object?
答:两个对象,一个是“xyx”,一个是指向“xyx”的引用对象s.
17、Math.round(11.5)等于多少? Math.round(-11.5)等于多少?
Math.round(11.5)返回(long)12,Math.round(-11.5)返回(long)-11;
18、怎样将浮点数(float)相加 ? Float 好像没有办法?
答:请注意 float 和 Float 是不同的,前者是 Java 基本类型之一, 而后者却是class。您应该将源代码改为:
float One;
float Two;
float Hard = One + Two;
或
Float One = new Float(1.0);
Float Two = new Float(2.0);
Float Hard = new Float(One.floatvalue() + Two.floatvalue());
19、如何将字串String转换成整数int?
答:1)int i = Integer.parseInt(“String”);
20、如何将整数 int 转换成字串 String?
有三种方法:
1)String s = String.valueOf(i);
2)String s = Integer.toString(i);
3)String s = "" + i;
21、什么是J2EE,J2SE,J2ME?
答:J2SE主要用于开发界面平台软件的;
J2ME主要用于开发嵌入式程序,如:手机软件程序等;
J2EE主要是基于WEB服务器的开发B/S结构企业级程序;
22、Java中的属性和字段有什么区别?
答:Java中的属性,通常可以理解为get和set方法。而字段通常叫做“类中定义的成员变量”。
23、值类型与引用类型变量的区别?
答:值类型变量是基本数据类型的一个变量;而引用类型变量是一个对象类型引用的变量;
24、隐式参数与显示参数?
答:显示参数是明显地列在方法声明中的显示参数,隐式参数没有出现在方法声明中的参数;
在每一个方法中,关键字this表示隐式参数。
25、什么是实例域、实例、实例变量?
答:实例域就是指定义类时的最外层的那两个大括号那个范围。
实例就是你new出来的类的对象引用。
实例变量:private(访问修饰符) int(数据类型) a(实例变量)=0;
实例变量不能标识为 abstract、synchronized 、native 或 strictfp。
26、什么是标识符、修饰符、访问修饰符?
(1)标识符:“_”、“$”
(2)修饰符:final、synchronized、abstract、
(3)访问修饰符:public、protected、default、private
27、一个类在new后,其静态代码块会执行吗?
答:一个类在new的时候即执行其静态代码块;执行完毕之后不会再执行;
二.类/接口/枚举/封装类:
1、一个类为什么要做成抽象类?接口?
答:a、减少代码的重复;b、解耦合;
接口与抽象类:一个类实现接口必须实现接口所有方法,而继承抽象类只需实现抽象方法,非抽象方法可不实现,这样就减少了这个类不需要的代码的重写性;
答:匿名内部类必须扩展一个基类或实现一个接口,但是不能有显式的extends和implements子句;
3、静态内部类与普通内部类区别:
4、为什么需要使用内部类呢?其主要原因有以下三点:
答:a、内部类方法可以访问该类定义所在的作用域中的数据,包括私有的数据。
b、内部类可以对同一个包中的其他类隐藏起来。
c、当想要定义一个回调函数且不想编写大量代码时,使用匿名内部类比较便捷。
三.面向对象编程:
1、请问java的三大特性是什么?它们各有什么特点?
答:a、封装:将一个类的成员属性设置成私有的,再提供get和set方法供外部访问;即这样的封装类不会被外界所改变,只能给外界使用;
b、继承:一个子类继承一个父类,继承父类中所有方法,不能继承父类中成员变量;子类本身又可以有另外的方法,即子类具有可扩展性特性;
c、多态:两种:
一种是重写,重写就是子类重写父类中方法(方法名、返回类型(子类的返回类型必须相同或是父类返回类型的子类)和参数类型必须一致);
另外一种是重载,重载是在一个类中的方法名相同,参数类型必须不同(或它们有不同的参数个数),返回类型可以相同,可以不同;
2、类与对象之间的关系:
答:a、关联:一个类受另外一个类影响,一个Driver类里面只跟一个Car类变量,即在Driver类中的方法内传一个car属性对象,强耦合关系;
b、依赖:一种使用关系,很弱的一种耦合。driver开几种类型的车,即重载,drive(plane);drive(car);这个时候drive与plane的关系即为依赖关系;
c、聚合:聚合关联 Aggregation:弱'拥有'关系,A对象可以包含B对象,但B不是A的一部分;
d、组合:是一种强的‘拥有’关系,体现严格的部分和整体的关系,
e、泛化:继承
f、实现:接口
3、类与对象间的结构关系:
纵向关系:泛化(包括类继承、接口继承、实现)
横向关系:关联(包括一般关联、聚合、组合)
4、面向对象的7大基本设计原则:
答:LSP里氏替换原则:子类与父类对象间替换;
OCP开闭原则:扩展开放,更改封闭;
SRP单一职责原则:依赖不同的具体类,不要将不相关的方法放到一个具体类中,然后具体类再关联。
ISP接口隔离原则:具体类不要实现无关接口中的方法,应使用具体类实现多个接口。
DIP依赖倒置原则:针对接口编程,不是针对实现编程
CARP组合/聚合复用原则:尽量使用组合/聚合,而不是使用继承来达到复用目的
LoD迪米特法则:类间最少通信原则,采用中间类。
5、23种经典设计模式:
单例模式:当多个对象需要共享同一个对象时;
原型模式:对扩展开发,对修改关闭;
工厂模式:客户需要某个产品,能够根据客户要求取得产品给客户;
状态模式:当需要对某个对象内部状态改变时,使用;
装饰模式:当需要对某个对象动态添加新功能时,可以用;
适配器模式:只需要对接口中的一小部分方法重新定义,又不希望将接口中的所有方法实现,
这时可以使用;
观察者模式:当主题对象改变时,需要通知所有的观察者,这时可以使用;
命令模式:将用户发出命令以对象形式传递,通过参数可改变命令对象的状态;
6、UML图分几类?
答:常用的UML图:
A、用例图:帮助开发团队以一种可视化的方式了解系统功能需求,比如:角色与用例之间关系;
B、 类图:三部分描述,上面是类名、中间是属性、下面是方法;完整的类图,应该具有指向其父类关系,并且具有与之关联的部分;
C、 序列图:显示不同对象之间的调用关系;
D、状态图:某个类所处的不同状态或者是该类的状态转换信息:
E、 活动图:表示在处理某个活动时,两个或者更多类对象之间的过程控制流。
F、 组件图:显示系统中软件与其他软件的依赖关系:
G、部署图表示该软件系统如何部署到硬件环境中。
静态(系统结构):用例图、类图、对象图、组件图、部署图
动态(系统行为):时序图、协作图、状态图、活动图
四.异常和断言:
1、error和exception有什么区别?
答:error和exception为接口Throwable下面的两个类; error是在程序执行过程中可能发生的严重问题,比如内存溢出等,error错误不需要程序明确的捕捉;而exception是在程序正常允许的状态下可能发生或可能不会发生的异常;exception分两类:一是运行时异常,即RuntimeException,此类异常可在程序中明确抛出,也可不抛出;二是非运行时异常,即IOException,此类异常必须在程序中明确抛出;
以上都是类;
2、throw和throws区别:
答:throw是在程序中抛出异常,而throws是在方法的声明中声明抛出异常;
3、同步和异步有何异同?
答:同步就是两个方法不能同时对一个共享数据进行更新处理;而异步就是说一个方法要执行很久的时候可以利用多线程方式同时执行另外一个方法;
4、子类异常抛出与父类异常抛出限制:
答:子类异常抛出不能比父类更加宽泛,即如果父类中方法抛出IOException,则子类抛出的异常可以是IOException或者其子类(FileNotFoundException)等;
5、你在代码中,都是怎样对待异常情况的?
答:在绝大多数情况下,我都知道哪些代码可能会抛出异常以及会抛出什么样的异常。所以我也会针对不同类型方面的异常区分对待。我一般会分成三类情况:一类是服务器崩溃等情况,是最严重的异常了,没有什么可以挽救的余地,返回给用户“服务器维护中,暂时无法使用”;一类是数据库操作失败等情况,比如JDBC连接数据库失败、Hibernate正常删除数据失败等,是属于意外情况,严重程度稍微低一些,返回给用户“刚才由于网路不畅,导致操作失败,请重新操作”,同时,需要回滚的及时回滚;再一类在实现有所准备的、业务操作异常的情况,比如登录密码错误、新用户注册重名现象等等,这些异常都是在意料之中、有所准备的。此时可以返回相关的提示,严重程度相对比较的低。
7、try{}里有一个return 语句,那么紧跟在这个try后的finally{}里的code会不会执行?
答:会执行,先执行完finally语句块后再执行return语句;finally是一定会执行的,只有代码中有system.exit() 这一种情况才不会执行finally,因为终止了虚拟机进程;
五.I/O流:
1、在Java语言中,如何列出PC机文件系统中的所有驱动器名?
答:在Java 2版本中,java.io包中的File类新增加了方法listRoots()可以实现这一功能;
2、IO流的三种分类方式:
a.按流的方向分为:输入流和输出流;
b.按流的数据单位不同分为:字节流和字符流;
c.按流的功能不同分为:节点流和过滤流;
3、IO流的四大抽象类:
(1)字节流:
InputStream(读数据):所有字节输入流的祖先;(从外部读取文件数据到程序中)
OutputStream(写数据):所有字节输出流的祖先;(将程序中的数据输出到外部文件中)
(2)字符流:Reader:所有读取字符输入流的祖先;
Writer :所有写入字符串的祖先;
4、文件读写的基本类:
(1)、读取字节流:
文件àFileInputStreamàBufferedInputStreamàDataInputStreamà数据;
(2)、写入字节流:
数据à DataOutputStream à BufferedOutputStream à FileOutputStream à文件;
(3)、该程序接受键盘输入(从键盘读取数据):
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String str=in.readLine();
(4)、写入字符流:
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("C:\\test.txt")));
out.write(“dagdagd”);
六.集合和泛型
1、说出ArrayList,Vector, LinkedList的存储性能和特性
答:ArrayList,Vector, 查询数据快,插入慢,Vector是线程安全的,LinkedList查询数据慢,插入速度快;list有序可重复;set不可重复且无序;
2、Collection 和 Collections的区别
答:Collection是集合类的上级接口,继承与他的接口主要有Set 和List.
Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。
3、HashMap和Hashtable的区别。
答:HashMap是线程不安全的,允许有null的key值或者value值;
Hashtable是线程安全的,不允许空key和value值;
4、Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别?
Set里的元素是不能重复的,那么用iterator()方法来区分重复与否。equals()是判读两个Set是否相等。而==是判断两个值是否相等的;
5、遍历一个list
for(int i=0;i <list.size();i++)
for(Object o:list)
Iterator it=list.iterator()
for(;it.hasNext();)
Object os[]=list.toArray();
for(int i=0;i <os.length;i++)
for(Object o:os)
for(Object o:list)
{ System.out.println(o.toString()); }
for(int i=0;i <list.size();i++)
{ System.out.println(list.get(i).toString()); }
Set set = new HashSet(list);
for(Iterator it=set.iterator();it.hasNext();)
{ Object o = it.next; System.out.println(o.toString());}
List<Object> list
for(Object foo : list){
String className = foo.getClass().getClassName;
System.out.println(foo);
}
6、你所知道的集合类都有哪些?主要方法?
七.线程
1、java线程的生命周期可分为4个部分:
(1)创建(new)状态:
Thread t = new Thread();
t.start();
new一个线程,并调用其start()方法启动一个线程;
(2)可运行状态:
在可运行状态下有很多操作,
A、睡眠操作,通过调用sleep方法来实现;经过睡眠时间后,线程从不可运行状态自动恢复为可运行状态;
B、挂起操作,通过调用suspend方法来实现;必须调用恢复(resume)方法才可将线程从不可运行状态恢复为可运行状态;
C、等待操作,通过调用wait方法来实现;必须调用notify或notifyAll方法才可将线程从不可运行状态恢复为可运行状态;
退让操作,通过调用yield方法来实现;
终止操作,通过调用stop方法来实现。
前三种方法调用即可将线程从可运行状态转变为不可运行状态;
(3)不可运行状态:
恢复为可运行状态的三种形式:
A、自动恢复,调用sleep()方法进入的不可运行状态;
B、用resume方法进行恢复,对应可运行状态方法为suspend();
C、通知方法(notify或notifyAll)进行恢复,对应可运行状态方法为wait();
(4)消亡状态:
调用(stop)方法终止线程;
2、Java线程的两种创建途径或者说java多线程的实现的两种方式:
第一种方法:extends Thread并重写run()方法;
class Mango exteds Thread {
public void run() { ……..}}
第二种方法:implements Runnable并重写run()方法;
class Mango implements Runnable {
public void run() { ……..}}
3、sleep() 和 wait() 有什么区别?
sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。
wait是Object类的方法,导致此线程进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。调用wait方法导致本线程放弃对象锁;
4、启动一个线程是用run()还是start()?
答:启动一个线程用start()方法,start()方法将线程进入可运行状态;
而启动run ()方法不会产生线程,而是把它当作普通的方法调用,马上执行;
5、请说出你所知道的线程同步的方法。
wait():使一个线程处于等待状态,并且释放所持有的对象的lock.
sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉InterruptedException异常。
notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。
notifyAll():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争。
synchronized关键字:
第一点:synchronized用来标识一个普通方法时,表示一个线程要执行该方法,必须取得该方法所在的对象的锁。
第二点:synchronized用来标识一个静态方法时,表示一个线程要执行该方法,必须获得该方法所在的类的类锁。
第三点:synchronized修饰一个代码块。类似这样:synchronized(obj) { //code.... }。表示一个线程要执行该代码块,必须获得obj的锁。这样做的目的是减小锁的粒度,保证当不同块所需的锁不冲突时不用对整个对象加锁。利用零长度的byte数组对象做obj非常经济。
6、多个服务器相连,每个服务器安装有一个独立的JDK;共用一个session,如何实现线程安全?
(1)分布式处理方法:设置一个管理服务器,一个负载服务器专门接收请求,一个服务器专门管理共用session处理请求;这个session再将请求分配至其他服务器进行处理;
7、Web服务器开发环境下的线程安全问题?
(1)在Java的Web服务器环境下开发,要注意线程安全的问题。最简单的实现方式就是在Servlet和Struts Action里不要使用类变量、实例变量,但可以使用类常量和实例常量。
如果有这些变量,可以将它们转换为方法的参数传入,以消除它们。
如果你在每次方法调用时
新建一个对象,再调用它们的方法,则不存在同步问题---因为它们不是多个线程共享的资源,只有共享的资源才需要同步---而Servlet和Action的实例对于多个线程是共享的。
(2)最简单的同步是将一个方法标记为synchronized,对同一个实例来说,任一时刻只能有一个synchronized方法在执行。当一个方法正在执行某个synchronized方法时,其他线程如果想要执行这个实例的任意一个synchronized方法,都必须等待当前执行 synchronized方法的线程退出此方法后,才能依次执行。
多线程同步的实现最终依赖锁机制。我们可以想象某一共享资源是一间屋子,每个人都是一个线程。当A希望进入房间时,他必须获得门锁,一旦A获得门锁,他进去后就立刻将门锁上,于是B,C,D...就不得不在门外等待,直到A释放锁出来后,B,C,D...中的某一人抢到了该锁(具体抢法依赖于 JVM的实现,可以先到先得,也可以随机挑选),然后进屋又将门锁上。这样,任一时刻最多有一人在屋内(使用共享资源)。
7、避免死锁的方法有哪些?
A、全部程序禁用,然后重启自己需要的程序;
8、JAVA中的Wait() 和notify()方法使用时应注意些什么?
答:应注意线程之间的优先级,防止死锁发生;(自我总结)
其他
1、 异常考点:一个接口或者父类中方法抛出Exception异常,其实现类或者子类中此方法可不抛出异常,或抛出更窄或相同异常,即:NullPointerException、Exception等;
2、 修饰符考点:一个接口或者父类中方法为default时,其实现类或者子类中此方法可以是default或者是protect,public,即实现类或者子类的修饰符范围必须更加广;
3、 每次构造父类都会初始化一次父类的数据.父类子类初始化顺序应该是:
父静态变量-->子静态变量-->父非静态变量-->父静态代码块-->父构造函数-->子非静变量-->子静态代码块-->子构造函数.
实例化的顺序是先实例化父类,再实例化子类,这应该也是子类为什么可以调用父类的方法的原因.
4、 String传值,
public class Test {
public static void change(String str){
str="123";
}
public static void main(String args[]) {
String abc = new String("abc");
Test.change(abc);
System.out.println(abc); }
输出:abc