概述题
本人对网上的一些面试题作了一些整理,但愿对你们面试有帮助
JAVA 基础
1.如何在JVM虚拟机挂掉的时候,作一些操做,例如发邮件通知?我的总结
可使用Runtime里面的addShutdownHook(Thread hook)方法,把JVM挂掉的时候所须要启动的线程注册到runtime中,就能够帮你完成这个动做
2.HashSet 和HashMap的关系(深刻源码) 我的总结
-
经过如下HashSet源码能够得知,HashSet 内部其实就是一个HashMap,但HashSet只是用到HashMap的key,而没有用倒HashMap的value
-
-
-
-
-
-
-
3.String类为何是final的。
-
String是全部语言中最经常使用的一个类。咱们知道在Java中,String是不可变的、final的。Java在运行时也保存了一个字符串池(String pool),这使得String成为了一个特别的类。
-
-
-
-
只有当字符串是不可变的,字符串池才有可能实现。字符串池的实现能够在运行时节约不少heap空间,由于不一样的字符串变量都指向池中的同一个字符串。但若是字符串是可变的,那么
String interning将不能实现(译者注:String interning是指对不一样的字符串仅仅只保存一个,即不会保存多个相同的字符串。),由于这样的话,若是变量改变了它的值,那么其它指向这个值的变量的值也会一块儿改变。
-
若是字符串是可变的,那么会引发很严重的安全问题。譬如,数据库的用户名、密码都是以字符串的形式传入来得到数据库的链接,或者在socket编程中,主机名和端口都是以字符串的形式传入。由于字符串是不可变的,因此它的值是不可改变的,不然黑客们能够钻到空子,改变字符串指向的对象的值,形成安全漏洞。
-
由于字符串是不可变的,因此是多线程安全的,同一个字符串实例能够被多个线程共享。这样便不用由于线程安全问题而使用同步。字符串本身即是线程安全的。
-
类加载器要用到字符串,不可变性提供了安全性,以便正确的类被加载。譬如你想加载java.sql.Connection类,而这个值被改为了myhacked.Connection,那么会对你的数据库形成不可知的破坏。
-
由于字符串是不可变的,因此在它建立的时候hashcode就被缓存了,不须要从新计算。这就使得字符串很适合做为
Map中的键,字符串的处理速度要快过其它的键对象。这就是HashMap中的键每每都使用字符串。
4.HashMap的源码,实现原理,底层结构
参考:http://blog.csdn.net/vking_wang/article/details/14166593
http:
5.反射中,Class.forName和classloader的区别
转自:http://www.linuxidc.com/Linux/2014-01/94895.htmhtml
-
Java中
class.forName和classLoader均可用来对类进行加载。前者除了将类的.class文件加载到jvm中以外,还会对类进行解释,执行类中的static块。而classLoader只干一件事情,就是将.class文件加载到jvm中,不会执行static中的内容,只有在newInstance才会去执行static块。Class.forName(name, initialize, loader)带参函数也可控制是否加载static块。而且只有调用了newInstance()方法采用调用构造函数,建立类的对象 示例代码以下:
-
-
package com.blueray.java.test;
-
-
public class ClassLoaderTest {
-
-
-
-
-
public static void main(String[] args) {
-
ClassLoader classLoader=StaticSample.class.getClassLoader();
-
-
System.out.println(
"Before load class");
-
Class clazz=classLoader.loadClass(StaticSample.class.getName());
-
System.out.println(
"After load class.");
-
System.out.println(
"executing newInstance");
-
-
}
catch (ClassNotFoundException e) {
-
-
}
catch (InstantiationException e) {
-
-
-
}
catch (IllegalAccessException e) {
-
-
-
-
-
-
-
-
-
-
package com.blueray.java.test;
-
-
public class StaticSample {
-
-
System.out.println(StaticSample.class.getName()+
" is loading the static block");
-
-
-
System.out.println(
"StaticSample Constructor is executing.");
-
-
-
-
-
-
-
-
-
-
-
com.blueray.java.test.StaticSample is loading the static block
-
StaticSample Constructor is executing.
6.说说你知道的几个Java集合类:list、set、queue、map实现类
参考:http://www.cnblogs.com/LittleHann/p/3690187.html?utm_source=tuicool&utm_medium=referral
7.描述一下ArrayList和LinkedList各自实现和区别
转自:http://www.importnew.com/6629.html
-
LinkedeList和ArrayList都实现了List接口,可是它们的工做原理却不同。它们之间最主要的区别在于ArrayList是可改变大小的数组,而LinkedList是双向连接串列(doubly LinkedList)。ArrayList更受欢迎,不少场景下ArrayList比LinkedList更为适用。这篇文章中咱们将会看看LinkedeList和ArrayList的不一样,并且咱们试图来看看什么场景下更适宜使用LinkedList,而不用ArrayList。
-
-
-
-
LinkedList和ArrayList的差异主要来自于
Array和LinkedList数据结构的不一样。若是你很熟悉Array和LinkedList,你很容易得出下面的结论:
-
-
1) 由于Array是基于索引(index)的数据结构,它使用索引在数组中搜索和读取数据是很快的。Array获取数据的时间复杂度是O(1),可是要删除数据倒是开销很大的,由于这须要重排数组中的全部数据。
-
-
2) 相对于ArrayList,LinkedList插入是更快的。由于LinkedList不像ArrayList同样,不须要改变数组的大小,也不须要在数组装满的时候要将全部的数据从新装入一个新的数组,这是ArrayList最坏的一种状况,时间复杂度是O(n),而LinkedList中插入或删除的时间复杂度仅为O(1)。ArrayList在插入数据时还须要更新索引(除了插入数组的尾部)。
-
-
3) 相似于插入数据,删除数据时,LinkedList也优于ArrayList。
-
-
4) LinkedList须要更多的内存,由于ArrayList的每一个索引的位置是实际的数据,而LinkedList中的每一个节点中存储的是实际的数据和先后节点的位置。
-
-
什么场景下更适宜使用LinkedList,而不用ArrayList
-
-
我前面已经提到,不少场景下ArrayList更受欢迎,可是还有些状况下LinkedList更为合适。譬如:
-
-
1) 你的应用不会随机访问数据。由于若是你须要LinkedList中的第n个元素的时候,你须要从第一个元素顺序数到第n个数据,而后读取数据。
-
-
2) 你的应用更多的插入和删除元素,更少的读取数据。由于插入和删除元素不涉及重排数据,因此它要比ArrayList要快。
-
-
以上就是关于ArrayList和LinkedList的差异。你须要一个不一样步的基于索引的数据访问时,请尽可能使用ArrayList。ArrayList很快,也很容易使用。可是要记得要给定一个合适的初始大小,尽量的减小更改数组的大小。
8.Java中的队列都有哪些,有什么区别
转自:http://blog.itpub.net/143526/viewspace-1060365/
9.Java七、Java8的新特性
转自:http://blog.csdn.net/zhongweijian/article/details/9258997
10.Java数组和链表两种结构的操做效率,在哪些状况下(从开头开始,从结尾开始,从中间开始),哪些操做(插入,查找,删除)的效率高
参考:http://blog.csdn.net/a19881029/article/details/22695289
11.Java内存泄露的问题调查定位:jmap,jstack的使用等等
参考:http:
12.string、stringbuilder、stringbuffer区别
参考:http:
13.hashtable和hashmap的区别
参考:http://www.cnblogs.com/carbs/archive/2012/07/04/2576995.html
14.异常的结构,运行时异常和非运行时异常,各举个例子
参考:http:
15.String 类的经常使用方法
转自:http:
16.Java 的引用类型有哪几种
参考:http://blog.csdn.net/coding_or_coded/article/details/6603549
17.抽象类和接口的区别
参考:http:
18.java的基础类型和字节大小
参考:http://www.cnblogs.com/doit8791/archive/2012/05/25/2517448.html
-
Java基本类型共有八种,基本类型能够分为三类,字符类型
char,布尔类型boolean以及数值类型byte、short、int、long、float、double。数值类型又能够分为整数类型byte、short、int、long和浮点数类型float、double。JAVA中的数值类型不存在无符号的,它们的取值范围是固定的,不会随着机器硬件环境或者操做系统的改变而改变。实际上,JAVA中还存在另一种基本类型void,它也有对应的包装类 java.lang.Void,不过咱们没法直接对它们进行操做。8 中类型表示范围以下:
-
-
byte:8位,最大存储数据量是255,存放的数据范围是-128~127之间。
-
-
short:16位,最大数据存储量是65536,数据范围是-32768~32767之间。
-
-
int:32位,最大数据存储容量是2的32次方减1,数据范围是负的2的31次方到正的2的31次方减1。
-
-
long:64位,最大数据存储容量是2的64次方减1,数据范围为负的2的63次方到正的2的63次方减1。
-
-
float:32位,数据范围在3.4e-45~1.4e38,直接赋值时必须在数字后加上f或F。
-
-
double:64位,数据范围在4.9e-324~1.8e308,赋值时能够加d或D也能够不加。
-
-
boolean:只有true和false两个取值。
-
-
char:16位,存储Unicode码,用单引号赋值。
19.Hashtable,HashMap,ConcurrentHashMap底层实现原理与线程安全问题
参考:http:
20.若是不让你用Java Jdk提供的工具,你本身实现一个Map,你怎么作。
http://www.cnblogs.com/xwdreamer/archive/2012/05/14/2499339.html
21.Hash冲突怎么办?哪些解决散列冲突的方法?
参考:http:
22.HashMap冲突很厉害,最差性能,你会怎么解决?从O(n)提高到log(n)
参考:http://www.2cto.com/kf/201505/399352.html
理解了hashmap的实现,聪明的人确定已经知道怎么更加高性能的使用hashmap。不过在此以前仍是先说明下初始容量和负载因子的含义。
Hashmap的设想是在O(1)的时间复杂度存取数据,根据咱们的分析,在最坏状况下,时间复杂度极可能是o(n),但这确定极少出现。可是某个链表中存在多个元素仍是有至关大的可能的。当hashmap中的元素数量越接近数组长度,这个概率就越大。为了保证hashmap的性能,咱们对元素数量/数组长度的值作了上限,此值就是负载因子。当比值大于负载因子时,就须要对内置数组进行扩容,从而提升读写性能。但这也正是问题的所在,对数组扩容,代价较大,时间复杂度时O(n)。
故咱们在hashmap须要存放的元素数量能够预估的状况下,预先设定一个初始容量,来避免自动扩容的操做来提升性能。
23.何时ReHash
参考:http://www.tuicool.com/articles/qqyENz
24.hashCode() 与 equals() 生成算法、方法怎么重写
1.hibernate和ibatis的区别
转自:http://blog.csdn.net/cdh1213/article/details/5967405
-
-
-
-
hibernate 是当前最流行的o/r mapping框架,它出身于sf.net,如今已经成为jboss的一部分了。
-
ibatis 是另一种优秀的o/r mapping框架,目前属于apache的一个子项目了。
-
相对hibernate“o/r”而言,ibatis是一种“sql mapping”的orm实现。
-
hibernate对数据库结构提供了较为完整的封装,hibernate的o/r mapping实现了pojo 和数据库表之间的映射,以及sql 的自动生成和执行。程序员每每只需定义好了pojo 到数据库表的映射关系,便可经过hibernate 提供的方法完成持久层操做。程序员甚至不须要对sql 的熟练掌握, hibernate/ojb 会根据制定的存储逻辑,自动生成对应的sql 并调用jdbc 接口加以执行。
-
而ibatis 的着力点,则在于pojo 与sql之间的映射关系。也就是说,ibatis并不会为程序员在运行期自动生成sql 执行。具体的sql 须要程序员编写,而后经过映射配置文件,将sql所需的参数,以及返回的结果字段映射到指定pojo。
-
使用ibatis 提供的orm机制,对业务逻辑实现人员而言,面对的是纯粹的java对象。
-
这一层与经过hibernate 实现orm 而言基本一致,而对于具体的数据操做,hibernate会自动生成sql 语句,而ibatis 则要求开发者编写具体的sql 语句。相对hibernate而言,ibatis 以sql开发的工做量和数据库移植性上的让步,为系统设计提供了更大的自由空间。
-
-
1.ibatis很是简单易学,hibernate相对较复杂,门槛较高。
-
-
3.当系统属于二次开发,没法对数据库结构作到控制和修改,那ibatis的灵活性将比hibernate更适合
-
4.系统数据处理量巨大,性能要求极为苛刻,这每每意味着咱们必须经过通过高度优化的sql语句(或存储过程)才能达到系统性能设计指标。在这种状况下ibatis会有更好的可控性和表现。
-
5.ibatis须要手写sql语句,也能够生成一部分,hibernate则基本上能够自动生成,偶尔会写一些hql。一样的需求,ibatis的工做量比hibernate要大不少。相似的,若是涉及到数据库字段的修改,hibernate修改的地方不多,而ibatis要把那些sql mapping的地方一一修改。
-
6.以数据库字段一一对应映射获得的po和hibernte这种对象化映射获得的po是大相径庭的,本质区别在于这种po是扁平化的,不像hibernate映射的po是能够表达立体的对象继承,聚合等等关系的,这将会直接影响到你的整个软件系统的设计思路。
-
7.hibernate如今已是主流o/r mapping框架,从文档的丰富性,产品的完善性,版本的开发速度都要强于ibatis。
2.讲讲mybatis的链接池
参考:http:
3.spring框架中须要引用哪些jar包,以及这些jar包的用途
参考:http:
4.springMVC的原理
参考:http:
5.springMVC注解的意思
参考:http:
6. spring中beanFactory和ApplicationContext的联系和区别
-
-
-
1. BeanFactory负责读取bean配置文档,管理bean的加载,实例化,维护bean之间的依赖关系,负责bean的声明周期。
-
2. ApplicationContext除了提供上述BeanFactory所能提供的功能以外,还提供了更完整的框架功能:
-
-
-
b. 资源访问:Resource rs = ctx. getResource(“classpath:config.properties”), “file:c:/config.properties”
-
c. 事件传递:经过实现ApplicationContextAware接口
-
3. 经常使用的获取ApplicationContext的方法:
-
FileSystemXmlApplicationContext:从文件系统或者url指定的xml配置文件建立,参数为配置文件名或文件名数组
-
ClassPathXmlApplicationContext:从classpath的xml配置文件建立,能够从jar包中读取配置文件
-
WebApplicationContextUtils:从web应用的根目录读取配置文件,须要先在web.xml中配置,能够配置监听器或者servlet来实现
-
-
<listener-
class>org.springframework.web.context.ContextLoaderListener</listener-class>
-
-
-
<servlet-name>context</servlet-name>
-
<servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
-
<load-on-startup>1</load-on-startup>
-
-
这两种方式都默认配置文件为web-inf/applicationContext.xml,也可以使用context-param指定配置文件
-
-
<param-name>contextConfigLocation</param-name>
-
<param-value>/WEB-INF/myApplicationContext.xml</param-value>
-
7.spring注入的几种方式
参考:http://developer.51cto.com/art/201207/348019.htm
8.spring如何实现事物管理的
参考:http:
9.springIOC
参考:http:
10.hibernate中的1级和2级缓存的使用方式以及区别原理(Lazy-Load的理解)
参考:http:
11.Hibernate的原理体系架构,五大核心接口,Hibernate对象的三种状态转换,事务管理
参考:http://www.cnblogs.com/shysunlove/archive/2012/11/21/2780240.html
多线程
1.Java建立线程以后,直接调用start()方法和run()的区别
参考:http:
2.经常使用的线程池模式以及不一样线程池的使用场景
参考:http:
3.newFixedThreadPool此种线程池若是线程数达到最大值后会怎么办,底层原理
参考:http:
4.多线程之间通讯的同步问题,synchronized锁的是对象,衍伸出和synchronized相关不少的具体问题,例如同一个类不一样方法都有synchronized锁,一个对象是否能够同时访问。或者一个类的static构造方法加上synchronized以后的锁的影响。
参考:http://www.cnblogs.com/shipengzhi/articles/2223100.html
5.了解可重入锁的含义,以及ReentrantLock 和synchronized的区别
http://outofmemory.cn/java/java.util.concurrent/synchronized-locks-Lock-ReentrantLock
6.同步的数据结构,例如concurrentHashMap的源码理解以及内部实现原理,为何他是同步的且效率高
参考:http:
7.atomicinteger和Volatile等线程安全操做的关键字的理解和使用
参考:http://www.cnblogs.com/dolphin0520/p/3920373.html
8.线程间通讯,wait和notify
参考:http://www.2cto.com/kf/201502/376021.html
10.场景:在一个主线程中,要求有大量(不少不少)子线程执行完以后,主线程才执行完成。多种方式,考虑效率
参考:http:
11.进程和线程的区别
参考:http:
12.什么叫线程安全
线程安全:若是你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。若是每次运行结果和单线程运行的结果是同样的,并且其余的变量的值也和预期的是同样的,就是线程安全的。或者说:一个类或者程序所提供的接口对于线程来讲是原子操做或者多个线程之间的切换不会致使该接口的执行结果存在二义性,也就是说咱们不用考虑同步的问题
13.线程的几种状态
参考:http:
14.并发、同步的接口或方法
转自:http://blog.csdn.net/woshisap/article/details/43119569
-
-
-
与每次须要时都建立线程相比,线程池能够下降建立线程的开销,这也是由于线程池在线程执行结束后进行的是回收操做,而不是真正的
-
-
-
-
-
-
ReentrantLock提供了tryLock方法,tryLock调用的时候,若是锁被其余线程持有,那么tryLock会当即返回,返回结果为
false,若是锁没有被
-
-
其余线程持有,那么当前调用线程会持有锁,而且tryLock返回的结果是
true,
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
保证了同一个变量在多线程中的可见性,因此它更可能是用于修饰做为开关状态的变量,由于
volatile保证了只有一份主存中的数据。
-
-
-
-
-
-
private AtomicInteger counter = new AtomicInteger();
-
-
-
-
return counter.incrementAndGet();
-
-
-
-
-
-
return counter.decrementAndGet();
-
-
-
-
-
-
AtomicInteger内部经过JNI的方式使用了硬件支持的CAS指令。
-
-
-
-
它是java.util.concurrent包中的一个类,它主要提供的机制是当多个(具体数量等于初始化CountDown时的count参数的值)线程都到达了预期状态
-
-
或完成预期工做时触发事件,其余线程能够等待这个事件来出发本身后续的工做,等待的线程能够是多个,即CountDownLatch是能够唤醒多个等待
-
-
的线程的,到达本身预期状态的线程会调用CountDownLatch的countDown方法,而等待的线程会调用CountDownLatch的await方法
-
-
-
-
循环屏障,CyclicBarrier能够协同多个线程,让多个线程在这个屏障前等待,直到全部线程都到达了这个屏障时,再一块儿继续执行后面的动做。
-
-
CyclicBarrier和CountDownLatch都是用于多个线程间的协调的,两者的一个很大的差异是,CountDownLatch是在多个线程都进行了latch.countDown
-
-
后才会触发事件,唤醒await在latch上的线程,而执行countDown的线程,执行完countDown后,会继续本身线程的工做;
-
-
CyclicBarrier是一个栅栏,用于同步全部调用await方法的线程,而且等全部线程都到了await方法,这些线程才一块儿返回继续各自的工做,由于使用CyclicBarrier的线程都会阻塞在await方法上,因此在线程池中使用CyclicBarrier时要特别当心,若是线程池的线程 数过少,那么就会发生死锁了,
-
-
CyclicBarrier能够循环使用,CountDownLatch不能循环使用。
-
-
-
-
是用于管理信号量的,构造的时候传入可供管理的信号量的数值,信号量对量管理的信号就像令牌,构造时传入个数,总数就是控制并发的数量。
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Exchanger,从名字上讲就是交换,它用于在两个线程之间进行数据交换,线程会阻塞在Exchanger的exchange方法上,直到另外一个线程也到了
-
-
同一个Exchanger的exchange方法时,两者进行交换,而后两个线程会继续执行自身相关的代码。
-
-
-
-
-
-
Future<HashMap> future = getDataFromRemote2();
-
-
-
-
HashMap data = (HashMap)future.get();
-
-
-
-
private Future<HashMap> getDateFromRemote2() {
-
-
return threadPool.submit(new Callable<HashMap>() {
-
-
-
-
return getDataFromRemote();
-
-
-
-
-
-
-
-
思路:调用函数后立刻返回,而后继续向下执行,急须要数据时再来用,或者说再来等待这个数据,具体实现方式有两种,一个是用Future,另外一个
-
-
15.HashMap 是否线程安全,为什么不安全。 ConcurrentHashMap,线程安全,为什么安全。底层实现是怎么样的。
参考:http:
16.J.U.C下的常见类的使用。 ThreadPool的深刻考察; BlockingQueue的使用。(take,poll的区别,put,offer的区别);原子类的实现
http:
参考:http:
17.简单介绍下多线程的状况,从创建一个线程开始。而后怎么控制同步过程,多线程经常使用的方法和结构
参考:http://www.infoq.com/cn/articles/java-memory-model-4/
19.实现多线程有几种方式,多线程同步怎么作,说说几个线程里经常使用的方法
参考:http:
http://www.cnblogs.com/psjay/archive/2010/04/01/1702465.html
http:
20.进程间的通信
网络通讯
1. http是无状态通讯,http的请求方式有哪些,能够本身定义新的请求方式么
参考:http:
2. socket通讯,以及长链接,分包,链接异常断开的处理
参考:http://developer.51cto.com/art/201202/318163.htm