1、Java
里的传引用和传值的区别是什么?
答案:传引用是指传递的是地址而不是值本身,传值则是传递值的一份拷贝。
2、为什么Java
里没有全局变量?
答案:全局变量是全局可见的,Java
不支持全局可见的变量,因为:全局变量破坏了引用透明性原则。全局变量导致了命名空间的冲突。
3、如何将String
类型转化成Number
类型?
答案:Integer
类的valueOf
方法可以将String
转成Number
。
4、面向对象编程的原则是什么?
答案:主要有三点,多态,继承和封装。
5、所有类的父类是什么?
答案:object
6、Java
的基本类型有哪些?
答案:byte,char, short, int, long, float, double, boolean
。
7、怎么判断数组是null
还是为空?
答案:输出array.length
的值,如果是0,说明数组为空。如果是null
的话,会抛出空指针异常。
8、JDK
和JRE
的区别是什么?
答案:Java
运行时环境(JRE
)是将要执行Java
程序的Java
虚拟机。它同时也包含了执行applet
需要的浏览器插件。Java
开发工具包(JDK
)是完整的Java
软件开发包,包含了JRE
,编译器和其他的工具(比如:JavaDoc
,Java
调试器),可以让开发者开发、编译、执行Java
应用程序。
9、Java
中的方法覆盖(Overriding
)和方法重载(Overloading
)是什么意思?
答案:Java
的方法重载,就是在类中可以创建多个方法,它们具有相同的名字,Java
中的方法重载发生在同一个类里面两个或者是多个方法的方法名相同但是参数不同的情况。与此相对,方法覆盖是说子类重新定义了父类的方法。方法覆盖必须有相同的方法名,参数列表和返回类型。覆盖者可能不会限制它所覆盖的方法的访问。
10、Java
支持多继承么?
答案:不支持,Java
不支持多继承。每个类都只能继承一个类,但是可以实现多个接口。
11、进程和线程的区别是什么?
答案:进程是执行着的应用程序,而线程是进程内部的一个执行序列。一个进程可以有多个线程。线程又叫做轻量级进程。
12、创建线程有几种不同的方式?你喜欢哪一种?为什么?
答案:有三种方式可以用来创建线程:
继承Thread
类
实现Runnable
接口
实现Callable
接口
应用程序可以使用Executor
框架来创建线程池
实现Runnable
接口这种方式更受欢迎,因为这不需要继承Thread
类。在应用设计中已经继承了别的对象的情况下,这需要多继承(而Java
不支持多继承),只能实现接口。同时,线程池也是非常高效的,很容易实现和使用。
13、什么是死锁(deadlock
)?
答案:两个进程都在等待对方执行完毕才能继续往下执行的时候就发生了死锁。结果就是两个进程都陷入了无限的等待中。
14、简单的说下HashMap
和TreeMap
的区别?
答案:HashMap
:适用于在Map
中插入、删除和定位元素。TreeMap
:适用于按自然顺序或自定义顺序遍历键(key
)。HashMap
通常比TreeMap
快一点(树和哈希表的数据结构使然),建议多使用HashMap
,在需要排序的Map
时候才用TreeMap
。
15、自定义标签要继承哪个类?
答案:这个类可以继承TagSupport
或者BodyTagSupport
,两者的差别是前者适用于没有主体的标签,而后者适用于有主体的标签。如果选择继承TagSupport
,可以实现doStartTag
和doEndTag
两个方法实现Tag
的功能,如果选择继承BodyTagSupport
,可以实现doAfterBody
这个方法。
16、jsp
页面是在服务器端运行还是在客户端运行?
答案:服务器端。JSP
与Java Servlet
一样
17、JSP
与SERVLET
的区别。
答案:JSP
先编译成SERVLET
然后再编译成CLASS
文件。JSP-----SERVLET-----JAVA文件---CLASS
,jsp
主要做视图层,servlet
主要做控制层
**18、try {}
里有一个return
语句,那么紧跟在这个try
后的finally {}
里的code
会不会被执行,什么时候被执行,在return
前还是后? **
答案:会执行,在return
前执行。
19、在JAVA
中,如何跳出当前的循环?
答案:用break; return
方法。
**20、在Java
中,如何跳出当前的多重嵌套循环? **
答案:在最外层循环前加一个标记如A
,然后用break A;
可以跳出多重循环。
21、在书写代码记录操作日志时,是先写日志 还是后写日志?哪个会好些?
答案:先写日志。 先写日志-->处理业务-->更新日志状态。
22、什么是ORM
框架?
答案:ORM(Object Relational Mapping)
框架采用元数据来描述对象一关系映射细节,元数据一般采用XML
格式,并且存放在专门的对象一映射文件中。通过某种关系来维持实体对象和数据库之间的关系,然后通过实体对象的操作来实现数据库的操作。也就是对象关系映射。
23、你了解哪几种orm
框架?
答案:Hibernate/myBatis
等。myBatis
不完全是orm
,需要手动写sql
。
24、你用过哪几个版本控制工具?
答案:GIT
等。
25、说出几种java中的修饰符?
答案:public、protect、default、private
26、MyEclipse
中java
文件中快速查找方法名的快捷键是?
答案:ctrl+o
27、当一个线程进入一个对象的一个synchronized
方法后,其它线程是否可进入此对象的其它方法?
答案:当一个线程访问“某对象”的“synchronized方法”
或者“synchronized代码块”
时,其他线程仍然可以访问“该对象”的非同步代码块;当一个线程访问“某对象”的“synchronized方法”
或者“synchronized代码块”
时,其他线程对“该对象”的其他的“synchronized方法”
或者“synchronized代码块”
的访问将被阻塞。
28、Collection
和 Collections
的区别?
答案:Collection
是集合类的上级接口,继承与他的接口主要有Set
和List
。Collections
是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。
29、在java
中一个类被声明为final
类型,表示了什么意思?
答案:表示该类不能被继承,是顶级类。
30、存在使i + 1 < i
的数吗?
答案:存在,解析:如果i
为int
型,那么当i
为int
能表示的最大整数时,i+1
就溢出变成负数了,此时不就<i
了吗。
31、Java接口的修饰符可以为(D)
A private B protected C final D abstract
32、不通过构造函数也能创建对象吗(A)
A 是 B 否
- (1)用
new
语句创建对象,这是最常见的创建对象的方法。 - (2) 运用反射手段,调用
java.lang.Class
或者java.lang.reflect.Constructor
类的newInstance()
实例方法。 - (3) 调用对象的
clone()
方法。 - (4) 运用反序列化手段,调用
java.io.ObjectInputStream
对象的readObject()
方法。
33、swtich
是否能作用在byte
上,是否能作用在long
上,是否能作用在String
上?
答:早期的JDK
中,switch(expr)
中,expr
可以是byte、short、char、int
。从1.5版开始,Java
中引入了枚举 类型(enum
),expr
也可以是枚举,从JDK 1.7
版开始,还可以是字符串(String
)。长整型(long
)是不可以的。
34、是否可以继承String
类?
答:String
类是final
类,不可以被继承。
35、当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?
答:是值传递。Java
编程语言只有值传递参数。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。对象的属性可以在被调用过程中被改变,但对象的引用是永远不会改变的。
36、String
和StringBuilder、StringBuffer
的区别?
答:Java
平台提供了两种类型的字符串:String
和StringBuffer / StringBuilder
,它们可以储存和操作字符串。其中String
是只读字符串,也就意味着String
引用的字符串内容是不能被改变的。而 StringBuffer
和StringBuilder
类表示的字符串对象可以直接进行修改。StringBuilder
是JDK 1.5
中引入的,它和StringBuffer
的方法完全相同,区别在于它是在单线程环境下使用的,因为它的所有方面都没有被synchronized
修饰,因此它的效率也比StringBuffer
略高。
37、char
型变量中能不能存贮一个中文汉字?为什么?
答:char
类型可以存储一个中文汉字,因为Java
中使用的编码是Unicode
(不选择任何特定的编码,直接使用字符在字符集中的编号,这是统一的唯一方法),一个char
类型占2
个字节(16bit
),所以放一个中文是没问题的。
补充:使用Unicode
意味着字符在JVM
内部和外部有不同的表现形式,在JVM
内部都是Unicode
,当这个字符被从JVM
内部转移到外部时 (例如存入文件系统中),需要进行编码转换。所以Java
中有字节流和字符流,以及在字符流和字节流之间进行转换的转换流,如 InputStreamReader
和OutputStreamReader
,这两个类是字节流和字符流之间的适配器类,承担了编码转换的任务;
38、抽象类(abstract class
)和接口(interface
)有什么异同?
答:抽象类和接口都不能够实例化,但可以定义抽象类和接口类型的引用。一个类如果继承了某个抽象类或者实现了某个接口都需要对其中的抽象方法全部进行实现,否则该类仍然需要被声明为抽象类。接口比抽象类更加抽象,因为抽象类中可以定义构造器,可以有抽象方法和具体方法,而接口中不能定义构造器而且其 中的方法全部都是抽象方法。抽象类中的成员可以是private、默认、protected、public
的,而接口中的成员全都是public
的。抽象 类中可以定义成员变量,而接口中定义的成员变量实际上都是常量。有抽象方法的类必须被声明为抽象类,而抽象类未必要有抽象方法。
39、静态变量和实例变量的区别?
答:静态变量是被static
修饰符修饰的变量,也称为类变量,它属于类,不属于类的任何一个对象,一个类不管创建多少个对象,静态变量在内存中有 且仅有一个拷贝;实例变量必须依存于某一实例,需要先创建对象然后通过对象才能访问到它。静态变量可以实现让多个对象共享内存。在Java
开发中,上下文 类和工具类中通常会有大量的静态成员。
40、是否可以从一个静态(static
)方法内部发出对非静态(non-static
)方法的调用?
答:不可以,静态方法只能访问静态成员,因为非静态方法的调用要先创建对象,因此在调用静态方法时可能对象并没有被初始化。
41、如何实现对象克隆?
答:有两种方式:
- 1.实现
Cloneable
接口并重写Object
类中的clone()
方法; - 2.实现
Serializable
接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆。
42、GC
是什么?为什么要有GC
?
答:GC
是垃圾收集的意思,内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java
提供的GC
功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java
语言没有提供释放已分配内存的显示操作方法。Java
程序员不用担心内存管理, 因为垃圾收集器会自动进行管理。要请求垃圾收集,可以调用下面的方法之一:System.gc()
或Runtime.getRuntime().gc()
,但JVM
可以屏蔽掉显示的垃圾回收调用。
43、String s=new String(“xyz”);
创建了几个字符串对象?
答:两个对象,一个是静态存储区的"xyz"
,一个是用new
创建在堆上的对象。
44、接口是否可继承(extends
)接口? 抽象类是否可实现(implements
)接口? 抽象类是否可继承具体类(concrete class
)?
答:接口可以继承接口。抽象类可以实现(implements
)接口,抽象类可继承具体类,但前提是具体类必须有明确的构造函数。
45、什么时候用assert
?
答:assertion
(断言)在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制。一般来说,assertion
用于保证程序最基本、关键的正确性。assertion
检查通常在开发和测试时开启。为了提高性能,在软件发布后,assertion
检查通常是关闭的。在实现中,断言是一个包含布尔表达式的语句,在执行这个语句时假定该表达式为true
;如果表达式计算为false
,那么系统会报告一个AssertionError
。
46、Error
和Exception
有什么区别?
答:Error
表示系统级的错误和程序不必处理的异常,是恢复不是不可能但很困难的情况下的一种严重问题;比如内存溢出,不可能指望程序能处理这样的情 况;Exception
表示需要捕捉或者需要程序进行处理的异常,是一种设计或实现问题;也就是说,它表示如果程序运行正常,从不会发生的情况。
47、sleep()
和wait()
有什么区别?
答:sleep()
方法是线程类(Thread
)的静态方法,导致此线程暂停执行指定时间,将执行机会给其他线程,但是监控状态依然保持,到时后会 自动恢复(线程回到就绪(ready
)状态),因为调用sleep
不会释放对象锁。wait()
是Object
类的方法,对此对象调用wait()
方法导致本线程放弃对象锁(线程暂停执行),进入等待此对象的等待锁定池,只有针对此对象发出notify
方法(或notifyAll
)后本线程才进入对象锁定池准备获得对象锁进入就绪状态。
48、sleep()
和yield()
有什么区别?
答:sleep()
方法给其他线程运行机会时不考虑线程的优先级,因此会给低优先级的线程以运行的机会;yield()
方法只会给相同优先级或更高优先级的线程以运行的机会;线程执行sleep()
方法后转入阻塞(blocked
)状态,而执行yield()
方法后转入就绪(ready
)状态;sleep()
方法声明抛出InterruptedException
,而yield()
方法没有声明任何异常;sleep()
方法比yield()
方法(跟操作系统相关)具有更好的可移植性。
49、请说出与线程同步相关的方法。
答:
- 1.
wait():
使一个线程处于等待(阻塞)状态,并且释放所持有的对象的锁; - 2.
sleep():
使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉InterruptedException
异常,不会释放锁; - 3.
notify():
唤醒一个处于等待状态的线程,当然在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM
确定唤醒哪个线程,而且与优先级无关; - 4.
notityAll():
唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争; - 5.
JDK 1.5
通过Lock
接口提供了显式(explicit
)的锁机制,增强了灵活性以及对线程的协调。Lock
接口中定义了加锁(lock()
)和解锁 (unlock()
)的方法,同时还提供了newCondition()
方法来产生用于线程之间通信的Condition
对象; - 6.
JDK 1.5
还提供了信号量(semaphore
)机制,信号量可以用来限制对某个共享资源进行访问的线程的数量。在对资源进行访问之前,线程必须得到信号量的 许可(调用Semaphore
对象的acquire()
方法);在完成对资源的访问后,线程必须向信号量归还许可(调用Semaphore
对象的release()
方法)。
50、什么是线程池(thread pool
)?
答:
- 在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源。在
Java
中更是如此,虚拟机将试图跟踪每 一个对象,以便能够在对象销毁后进行垃圾回收。所以提高服务程序效率的一个手段就是尽可能减少创建和销毁对象的次数,特别是一些很耗资源的对象创建和销 毁,这就是"池化资源"技术产生的原因。线程池顾名思义就是事先创建若干个可执行的线程放入一个池(容器)中,需要的时候从池中获取线程不用自行创建,使用完毕不需要销毁线程而是放回池中,从而减少创建和销毁线程对象的开销。 - 在
Java 5+
中的Executor
接口定义一个执行线程的工具。它的子类型即线程池接口是ExecutorService
。要配置一个线程池是比较复杂的,尤其是对于线程池的原理不是很清楚的情况下,因此在工具类Executors
面提供了一些静态工厂方法,生成一些常用的线程池,如下所示:
newSingleThreadExecutor
:创建一个单线程的线程池。这个线程池只有一个线程在工作,也就是相当于单线程串行执行所有任务。如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。
newFixedThreadPool
:创建固定大小的线程池。每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。
newCachedThreadPool
: 创建一个可缓存的线程池。如果线程池的大小超过了处理任务所需要的线程,那么就会回收部分空闲(60秒不执行任务)的线程,当任务数增加时,此线程池又可 以智能的添加新线程来处理任务。此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM
)能够创建的最大线程大小。
newScheduledThreadPool
:创建一个大小无限的线程池。此线程池支持定时以及周期性执行任务的需求。
newSingleThreadExecutor
:创建一个单线程的线程池。此线程池支持定时以及周期性执行任务的需求。
如果希望在服务器上使用线程池,强烈建议使用newFixedThreadPool
方法来创建线程池,这样能获得更好的性能。
82、简述synchronized
和java.util.concurrent.locks.Lock
的异同?
答:Lock
是Java 5
以后引入的新的API
,和关键字synchronized
相比主要相同点:Lock
能完成synchronized
所实现的所有功能;主要不同点:Lock
有比synchronized
更精确的线程语义和更好的性能。synchronized
会自动释放锁,而Lock
一定要求程序员手工释放,并且必须在finally
块中释放(这是释放外部资源的最好的地方)。
83、Java
中如何实现序列化,有什么意义?
答:序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决对象流读写操作时可能引发的问题(如果不进行序列化可能会存在数据乱序的问题)。要实现序列化,需要让一个类实现Serializable
接口,该接口是一个标识性接口,标注该类对象是可被序列化的,然后使用一个输出流来。构造一个对象输出流并通过writeObject(Object obj)
方法就可以将实现对象写出(即保存其状态);如果需要反序列化则可以用一个输入流建立对象输入流,然后通过readObject
方法从流中读取对 象。序列化除了能够实现对象的持久化之外,还能够用于对象的深度克隆。
84、heap
和stack
有什么区别。
答:java
的内存分为两类,一类是栈内存,一类是堆内存。栈内存是指程序进入一个方法时,会为这个方法单独分配一块私属存储空间,用于存储这个方法内部的局部变量,当这个方法结束时,分配给这个方法的栈会释放,这个栈中的变量也将随之释放。堆是与栈作用不同的内存,一般用于存放不放在当前方法栈中的那些数据,例如,使用new
创建的对象都放在堆里,所以,它不会随方法的结束而消失。方法中的局部变量使用final
修饰后,放在堆中,而不是栈中。