阿里历年经典Java面试题汇总

Volatile的特征:html

A、禁止指令重排(有例外) 
B、可见性java

Volatile的内存语义:算法

当写一个volatile变量时,JMM会把线程对应的本地内存中的共享变量值刷新到主内存。sql


当读一个volatile变量时,JMM会把线程对应的本地内存置为无效,线程接下来将从主内存中读取共享变量。编程


Volatile的重排序数组

一、当第二个操做为volatile写操作时,无论第一个操做是什么(普通读写或者volatile读写),都不能进行重排序。这个规则确保volatile写以前的全部操做都不会被重排序到volatile以后;安全

二、当第一个操做为volatile读操做时,无论第二个操做是什么,都不能进行重排序。这个规则确保volatile读以后的全部操做都不会被重排序到volatile以前;微信

三、当第一个操做是volatile写操做时,第二个操做是volatile读操做,不能进行重排序。并发

这个规则和前面两个规则一块儿构成了:两个volatile变量操做不可以进行重排序;app

除以上三种状况之外能够进行重排序。

好比:

一、第一个操做是普通变量读/写,第二个是volatile变量的读; 
二、第一个操做是volatile变量的写,第二个是普通变量的读/写;


内存屏障/内存栅栏

内存屏障(Memory Barrier,或有时叫作内存栅栏,Memory Fence)是一种CPU指令,用于控制特定条件下的重排序和内存可见性问题。Java编译器也会根据内存屏障的规则禁止重排序。(也就是让一个CPU处理单元中的内存状态对其它处理单元可见的一项技术。)

内存屏障能够被分为如下几种类型:

LoadLoad屏障:对于这样的语句Load1; LoadLoad; Load2,在Load2及后续读取操做要读取的数据被访问前,保证Load1要读取的数据被读取完毕。

StoreStore屏障:对于这样的语句Store1; StoreStore; Store2,在Store2及后续写入操做执行前,保证Store1的写入操做对其它处理器可见。

LoadStore屏障:对于这样的语句Load1; LoadStore; Store2,在Store2及后续写入操做被刷出前,保证Load1要读取的数据被读取完毕。

StoreLoad屏障:对于这样的语句Store1; StoreLoad; Load2,在Load2及后续全部读取操做执行前,保证Store1的写入对全部处理器可见。它的开销是四种屏障中最大的。

在大多数处理器的实现中,这个屏障是个万能屏障,兼具其它三种内存屏障的功能。

内存屏障阻碍了CPU采用优化技术来下降内存操做延迟,必须考虑所以带来的性能损失。为了达到最佳性能,最好是把要解决的问题模块化,这样处理器能够按单元执行任务,而后在任务单元的边界放上全部须要的内存屏障。采用这个方法可让处理器不受限的执行一个任务单元。合理的内存屏障组合还有一个好处是:缓冲区在第一次被刷后开销会减小,由于再填充改缓冲区不须要额外工做了。


happens-before原则


Java是如何实现跨平台的?

跨平台是怎样实现的呢?这就要谈及Java虚拟机(Java Virtual Machine,简称 JVM)。

JVM也是一个软件,不一样的平台有不一样的版本。咱们编写的Java源码,编译后会生成一种 .class 文件,称为字节码文件。Java虚拟机就是负责将字节码文件翻译成特定平台下的机器码而后运行。也就是说,只要在不一样平台上安装对应的JVM,就能够运行字节码文件,运行咱们编写的Java程序。

而这个过程当中,咱们编写的Java程序没有作任何改变,仅仅是经过JVM这一”中间层“,就能在不一样平台上运行,真正实现了”一次编译,处处运行“的目的。

JVM是一个”桥梁“,是一个”中间件“,是实现跨平台的关键,Java代码首先被编译成字节码文件,再由JVM将字节码文件翻译成机器语言,从而达到运行Java程序的目的。

注意:编译的结果不是生成机器码,而是生成字节码,字节码不能直接运行,必须经过JVM翻译成机器码才能运行。不一样平台下编译生成的字节码是同样的,可是由JVM翻译成的机器码却不同。

因此,运行Java程序必须有JVM的支持,由于编译的结果不是机器码,必需要通过JVM的再次翻译才能执行。即便你将Java程序打包成可执行文件(例如 .exe),仍然须要JVM的支持。

注意:跨平台的是Java程序,不是JVM。JVM是用C/C++开发的,是编译后的机器码,不能跨平台,不一样平台下须要安装不一样版本的JVM。


手机扫二维码登陆是怎么实现的?

参考:http://www.jianshu.com/p/7f072ac61763


Java 线程有哪些状态,这些状态之间是如何转化的?

  1. 新建(new):新建立了一个线程对象。

  2. 可运行(runnable):线程对象建立后,其余线程(好比main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取cpu 的使用权 。

  3. 运行(running):可运行状态(runnable)的线程得到了cpu 时间片(timeslice) ,执行程序代码。

  4. 阻塞(block):阻塞状态是指线程由于某种缘由放弃了cpu 使用权,也即让出了cpu timeslice,暂时中止运行。直到线程进入可运行(runnable)状态,才有机会再次得到cpu timeslice 转到运行(running)状态。阻塞的状况分三种:

(一). 等待阻塞:运行(running)的线程执行o.wait()方法,JVM会把该线程放入等待队列(waitting queue)中。

(二). 同步阻塞:运行(running)的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池(lock pool)中。

(三). 其余阻塞:运行(running)的线程执行Thread.sleep(long ms)或t.join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程从新转入可运行(runnable)状态。

  1. 死亡(dead):线程run()、main() 方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期。死亡的线程不可再次复生。


List接口、Set接口和Map接口的区别

参考:http://blog.csdn.net/zcg_java/article/details/43232251


Cookie和Session的区别?

参考:http://blog.csdn.net/axin66ok/article/details/6175522


Java中的equals和hashCode方法详解

参考:http://www.cnblogs.com/Qian123/p/5703507.html


Java中CAS算法

参考:http://www.kancloud.cn/seaboat/java-concurrent/117870


TimSort原理

参考:http://suo.im/532OHc


comparable与comparator的区别?

参考:http://www.cnblogs.com/szlbm/p/5504634.html


手写单例模式(线程安全)

参考:http://www.cnblogs.com/hupp/p/4487521.html


Java线程间的通讯方式?

参考1:http://www.cnblogs.com/mengdd/archive/2013/02/20/2917956.html

参考2:http://www.jb51.net/article/84213.htm


Java8的内存分代改进

参考:http://blog.csdn.net/chlu113/article/details/51890469


对Java内存模型的理解以及其在并发当中的做用?

参考:http://www.cnblogs.com/_popc/p/6096517.html


Arrays和Collections 对于sort的不一样实现原理?

一、Arrays.sort() 
该算法是一个通过调优的快速排序,此算法在不少数据集上提供N*log(N)的性能,这致使其余快速排序会下降二次型性能。

二、Collections.sort() 
该算法是一个通过修改的合并排序算法(其中,若是低子列表中的最高元素效益高子列表中的最低元素,则忽略合并)。此算法可提供保证的N*log(N)的性能,此实现将指定列表转储到一个数组中,而后再对数组进行排序,在重置数组中相应位置处每一个元素的列表上进行迭代。


Java中object经常使用方法

一、clone() 
二、equals() 
三、finalize() 
四、getclass() 
五、hashcode() 
六、notify() 
七、notifyAll() 
八、toString()


对于Java中多态的理解

所谓多态就是指程序中定义的引用变量所指向的具体类型和经过该引用变量发出的方法调用在编程时并不肯定,而是在程序运行期间才肯定,即一个引用变量到底会指向哪一个类的实例对象,该引用变量发出的方法调用究竟是哪一个类中实现的方法,必须在由程序运行期间才能决定。由于在程序运行时才肯定具体的类,这样,不用修改源程序代码,就可让引用变量绑定到各类不一样的类实现上,从而致使该引用调用的具体方法随之改变,即不修改程序代码就能够改变程序运行时所绑定的具体代码,让程序能够选择多个运行状态,这就是多态性。

多态的定义:指容许不一样类的对象对同一消息作出响应。即同一消息能够根据发送对象的不一样而采用多种不一样的行为方式。(发送消息就是函数调用)

Java实现多态有三个必要条件:继承、重写、父类引用指向子类对象。

继承:在多态中必须存在有继承关系的子类和父类。

重写:子类对父类中某些方法进行从新定义,在调用这些方法时就会调用子类的方法。

父类引用指向子类对象:在多态中须要将子类的引用赋给父类对象,只有这样该引用才可以具有技能调用父类的方法和子类的方法。

实现多态的技术称为:动态绑定(dynamic binding),是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。

多态的做用:消除类型之间的耦合关系。


Session机制?

参考 :http://justsee.iteye.com/blog/1570652


Java序列化与反序列化是什么?为何须要序列化与反序列化?如何实现Java序列化与反序列化?

参考 : http://blog.csdn.net/wangloveall/article/details/7992448/


Spring AOP 实现原理?

参考 :http://blog.csdn.net/moreevan/article/details/11977115/


Servlet 工做原理?

参考:http://www.ibm.com/developerworks/cn/java/j-lo-servlet/


Java NIO和IO的区别?

参考:http://www.jb51.net/article/50621.htm


Java中堆内存和栈内存区别?

参考:http://www.cnblogs.com/whgw/archive/2011/09/29/2194997.html


反射讲一讲,主要是概念,都在哪须要反射机制,反射的性能,如何优化?

反射机制的定义:

是在运行状态中,对于任意的一个类,都可以知道这个类的全部属性和方法,对任意一个对象都可以经过反射机制调用一个类的任意方法,这种动态获取类信息及动态调用类对象方法的功能称为java的反射机制。

反射的做用:

一、动态地建立类的实例,将类绑定到现有的对象中,或从现有的对象中获取类型。

二、应用程序须要在运行时从某个特定的程序集中载入一个特定的类。


如何保证RESTful API安全性 ?

参考: http://blog.csdn.net/ywk253100/article/details/25654101


如何预防Mysql注入?

参考:http://www.jb51.net/article/87948.htm

我有一个微信公众号,常常会分享一些Java技术相关的干货;若是你喜欢个人分享,能够用微信搜索“Java团长”或者“javatuanzhang”关注。

相关文章
相关标签/搜索