你对Java的集合框架了解吗? 能否说说常用的类?
Java集合框架类图:
我常用的类:
HashMap,Hashtable,HashSet,ArrayList,Vector,LinkedList,Collections,Arrays;
说说Hashtable与HashMap的区别(源代码级别)
最明显的区别在于Hashtable 是同步的(每个方法都是synchronized),而HashMap则不是.
HashMap继承至AbstractMap,Hashtable继承至Dictionary ,前者为Map的骨干, 其内部已经实现了Map所需要做的大部分工作, 它的子类只需要实现它的少量方法即可具有Map的多项特性。而后者内部都为抽象方法,需要它的实现类一一作自己的实现,且该类已过时
两者检测是否含有key时,hash算法不一致,HashMap内部需要将key的hash
码重新计算一边再检测,而Hashtable则直接利用key本身的hash码来做验证。
两者初始化容量大小不一致,HashMap内部为 16*0.75 , Hashtable 为 11*0.75
后续的区别应该还有很多, 这里先列出4点。
平时除了ArrayList和LinkedList外,还用过的List有哪些?ArrayList和LinkedList的区别?
事实上,我用过的List主要就是这2个, 另外用过Vector.
ArrayList和LinkedList的区别:
1. 毫无疑问,第一点就是两者的内部数据结构不同, ArrayList内部元素容器是一个Object的数组, 而LinkedList内部实际上一个链表的数据结构,其有一个内部类
来表示链表.
2. 两者的父类不同,也就决定了两者的存储形式不同。 ArrayList继承于 AbstractList,
而LinkedList继承于AbstractSequentialList. 两者都实现了List的骨干结构,只是前者的访问形式趋向于 “随机访问”数据存储(如数组),后者趋向于 “连续访问”数据存储(如链接列表)
3. 再有就是两者的效率问题, ArrayList基于数组实现,所以毫无疑问可以直接用下标来
索引,其索引数据快,插入元素设计到数组元素移动,或者数组扩充,所以插入元素要慢。LinkedList基于链表结构,插入元素只需要改变插入元素的前后项的指向即可,故插入数据要快,而索引元素需要向前向后遍历,所以索引元素要慢。
ArrayList的特点,内部容器是如何扩充的?
Properties类的特点? 线程安全?
Properties 继承于Hashtable,,所以它是线程安全的.
其特点是:
它表示的是一个持久的属性集,它可以保存在流中或者从流中加载,属性列表的每一个键和它所对应的值都是一个“字符串”
这里特别的是,实际上,Properties从流中加载属性集合,是通过将流中的字符或者字节分成一行行来处理的。
请说一下Struts2的初始化?和类的创建?(从源代码角度出发) 由于这个问题研究起来可以另外写一篇专门的模块,这里只列出相对简单的流程,后续会希望有时间整理出具体的细节:
首先,Struts2是基于Xwork框架的,如果你有仔细看过Xwork的文档,你会发现,它的初始化过程基于以下几个类:
Configuring XWork2 centers around the following classes:-
• ConfigurationManager
• ConfigurationProvider
• Configuration
而在ConfigurationProvider的实现类XmlConfigurationProvider 的内部,你可以看到下面的代码:
同样的,Struts2的初始化也是这样的一个类,只不过它继承于Xwork原有的类,并针对Struts2做了一些特别的定制。
OK, 整体来说,这个问题说清楚很难,因为你无法记住你追踪到的所有的类,但是有一点是肯定的,那就是流程: 基本上我的理解就是 通过一系列配置文件的初始化,将文件转换成对象,加载进内存中,再在处理请求时候(注意,只有当FilterDispatcher的doFilter第一次被调用时,才会去初始化Action类),加载Action类来进行业务处理。
第二部分:
据你了解,除了反射还有什么方式可以动态的创建对象?
请说一下Struts2 是如何把Action
交给Spring托管的?
它是单例的还是多例? 你们页面的表单对象是多例还是单例?
首先,来看看如何让Spring 来管理Action.
2. 有两种整合方式:
a) 将Struts的业务逻辑控制器类配置在Spring的配置文件中,业务逻辑控制器中引用的业务类一并注入。 (这样的处理,必须将action类的scope配置成property)
的class属性为Spring配置文件中相应bean的id或者name值。示例如下:
b) 第2种方式:
业务类在Spring配置文件中配置,业务逻辑控制器类不需要配置,Struts2的Action
像没有整合Spring之前一样配置,的class属性指定业务逻辑控制器类的全限定名。 Action中引用的业务类不需要自己去初始化,Struts2的Spring插件会使用bean的自动装配将业务类注入进来,其实Action也不是Struts2创建的,而是Struts2的Spring插件创建的。默认情况下,插件使用by name的方式装配,可以通过增加Struts2常量来修改匹配方式:设置方式为:struts.objectFactory.spring.autoWire = typeName,可选的装配参数如下:
name:相当于spring配置的autowrie="byName"(默认)
type:相当于spring配置的autowrie="byType"
auto:相当于spring 配置的autowrie="autodetect"
constructor: 相当于spring配置的autowrie="constructor"
OK,这里说了配置部分,但是,这里有一个问题, 就是
Spring管理Action,如果按照第一方式,那么只要通过scope="property"来配置为每个请求创建一个Action实例。 那么第二种方式,我们并没有指定Action的作用域(好似也没有地方可配„„),那么,这样的整合方式,Action的创建到底是单例还是多例的呢?
答案也是没个请求一个实例,我这里通过一个很笨的办法,来证明它:
我会写一个Action的构造函数, 并在里面打上一句话,加入断点,如果说,每次请求都会进入断点,那么就意味着,每个请求都有一个新的实例是正确的。
第一次进入的时候,是在容器启动的时候:
我们请求
Action,
再次进入断点,说明,每个请求都有一个Action实例来处理。
对于这点的原因,我还是没有弄清楚,为什么按照第2种方式配置,不用指定scope,就会自动的为每个action创建一个实例?(希望懂的朋友,可以指点指点)
对于我们项目中的页面表单对象, 毫无疑问,它也是多例的.
请说一下你们业务层对象是单例还是多例的?
业务层对象是单例的。
请说一下Struts2源代码中有哪些设计模式?
简单罗列一下: 单例模式-- 典型应用: 类:
org.apache.struts2.config.ServletContextSingleton
模版方法模式:
在org.apache.struts2.components包中大量运用
责任连模式:
在拦截器部分使用.
请说一下线程安全出现的原因?
我们都知道线程安全是指什么,我的理解是, 当一个类的“状态”(实例变量)被多个线程所修改时,那么这个类的状态的“正确”性得不到保证,我们就可以理解成线程安全出现。 当然,如果一个没有状态的类,那么它永远都是线程安全的。
再深入一点来看, 我们从Java虚拟机的层面来看这个问题,答案就很明朗了:
Java程序在运行时创建的所有类实例或数组,都存放在同一个堆中,而一个JVM实例中只存在一个堆空间,因此,它被所有的线程共享着,这样的情况下,就可能出现,多个线程访问对象(堆数据)的同步问题了。
请说一下线程池的中断策略(4个)? 各有什么特点?
这里所指的线程池是concurrent包中的ThreadPoolExecutor,而中断策略实际上是指饱和策略(concurent包中的RejectedExecutionHandler接口),
这里需要先解释一下,什么叫饱和策略, 实际就是说, 线程池中的线程容器已经放不下先的任务了,饱和了,必须要有一个相应的策略来处理。
ThreadPoolExecutor内部,已经定义了4种饱和策略:
默认的饱和策略是: (中止), 既如果放不下了,既中止新加入的任务。
源代码中调用如下
如果需要设置饱和策略,可以调用ThreadPoolExecutor的setRejectExecutionHandler方法,JDK提供了4种不同策略的实现(4种实现都定义在ThreadPoolExecutor类中,有兴趣可以查看一下源代码):
下面介绍一下4种实现的特点:
AbortPolicy: (中止)它是默认的策略。
CallerRunsPolicy: (调用者运行), 它既不会丢弃任务,也不会抛出任何异常,它会把任务推回到调用者那里去,以此缓解任务流
DiscardPolicy: (遗弃)策略,它默认会放弃这个任务
DiscardOldestPolicy:(遗弃最旧的),它选择的丢弃的任务,是它本来要执行的(可怜的娃,就这样被新加入的给排挤了),
下面发出这4种策略的源代码:
你对Java的集合框架了解吗? 能否说说常用的类?
Java集合框架类图:
我常用的类:
HashMap,Hashtable,HashSet,ArrayList,Vector,LinkedList,Collections,Arrays;
说说Hashtable与HashMap的区别(源代码级别)
最明显的区别在于Hashtable 是同步的(每个方法都是synchronized),而HashMap则不是.
HashMap继承至AbstractMap,Hashtable继承至Dictionary ,前者为Map的骨干, 其内部已经实现了Map所需要做的大部分工作, 它的子类只需要实现它的少量方法即可具有Map的多项特性。而后者内部都为抽象方法,需要它的实现类一一作自己的实现,且该类已过时
两者检测是否含有key时,hash算法不一致,HashMap内部需要将key的hash
码重新计算一边再检测,而Hashtable则直接利用key本身的hash码来做验证。
两者初始化容量大小不一致,HashMap内部为 16*0.75 , Hashtable 为 11*0.75
后续的区别应该还有很多, 这里先列出4点。
平时除了ArrayList和LinkedList外,还用过的List有哪些?ArrayList和LinkedList的区别?
事实上,我用过的List主要就是这2个, 另外用过Vector.
ArrayList和LinkedList的区别:
1. 毫无疑问,第一点就是两者的内部数据结构不同, ArrayList内部元素容器是一个Object的数组, 而LinkedList内部实际上一个链表的数据结构,其有一个内部类
来表示链表.
2. 两者的父类不同,也就决定了两者的存储形式不同。 ArrayList继承于 AbstractList,
而LinkedList继承于AbstractSequentialList. 两者都实现了List的骨干结构,只是前者的访问形式趋向于 “随机访问”数据存储(如数组),后者趋向于 “连续访问”数据存储(如链接列表)
3. 再有就是两者的效率问题, ArrayList基于数组实现,所以毫无疑问可以直接用下标来
索引,其索引数据快,插入元素设计到数组元素移动,或者数组扩充,所以插入元素要慢。LinkedList基于链表结构,插入元素只需要改变插入元素的前后项的指向即可,故插入数据要快,而索引元素需要向前向后遍历,所以索引元素要慢。
ArrayList的特点,内部容器是如何扩充的?
Properties类的特点? 线程安全?
Properties 继承于Hashtable,,所以它是线程安全的.
其特点是:
它表示的是一个持久的属性集,它可以保存在流中或者从流中加载,属性列表的每一个键和它所对应的值都是一个“字符串”
这里特别的是,实际上,Properties从流中加载属性集合,是通过将流中的字符或者字节分成一行行来处理的。
请说一下Struts2的初始化?和类的创建?(从源代码角度出发) 由于这个问题研究起来可以另外写一篇专门的模块,这里只列出相对简单的流程,后续会希望有时间整理出具体的细节:
首先,Struts2是基于Xwork框架的,如果你有仔细看过Xwork的文档,你会发现,它的初始化过程基于以下几个类:
Configuring XWork2 centers around the following classes:-
• ConfigurationManager
• ConfigurationProvider
• Configuration
而在ConfigurationProvider的实现类XmlConfigurationProvider 的内部,你可以看到下面的代码:
同样的,Struts2的初始化也是这样的一个类,只不过它继承于Xwork原有的类,并针对Struts2做了一些特别的定制。
OK, 整体来说,这个问题说清楚很难,因为你无法记住你追踪到的所有的类,但是有一点是肯定的,那就是流程: 基本上我的理解就是 通过一系列配置文件的初始化,将文件转换成对象,加载进内存中,再在处理请求时候(注意,只有当FilterDispatcher的doFilter第一次被调用时,才会去初始化Action类),加载Action类来进行业务处理。
第二部分:
据你了解,除了反射还有什么方式可以动态的创建对象?
请说一下Struts2 是如何把Action
交给Spring托管的?
它是单例的还是多例? 你们页面的表单对象是多例还是单例?
首先,来看看如何让Spring 来管理Action.
2. 有两种整合方式:
a) 将Struts的业务逻辑控制器类配置在Spring的配置文件中,业务逻辑控制器中引用的业务类一并注入。 (这样的处理,必须将action类的scope配置成property)
的class属性为Spring配置文件中相应bean的id或者name值。示例如下:
b) 第2种方式:
业务类在Spring配置文件中配置,业务逻辑控制器类不需要配置,Struts2的Action
像没有整合Spring之前一样配置,的class属性指定业务逻辑控制器类的全限定名。 Action中引用的业务类不需要自己去初始化,Struts2的Spring插件会使用bean的自动装配将业务类注入进来,其实Action也不是Struts2创建的,而是Struts2的Spring插件创建的。默认情况下,插件使用by name的方式装配,可以通过增加Struts2常量来修改匹配方式:设置方式为:struts.objectFactory.spring.autoWire = typeName,可选的装配参数如下:
name:相当于spring配置的autowrie="byName"(默认)
type:相当于spring配置的autowrie="byType"
auto:相当于spring 配置的autowrie="autodetect"
constructor: 相当于spring配置的autowrie="constructor"
OK,这里说了配置部分,但是,这里有一个问题, 就是
Spring管理Action,如果按照第一方式,那么只要通过scope="property"来配置为每个请求创建一个Action实例。 那么第二种方式,我们并没有指定Action的作用域(好似也没有地方可配„„),那么,这样的整合方式,Action的创建到底是单例还是多例的呢?
答案也是没个请求一个实例,我这里通过一个很笨的办法,来证明它:
我会写一个Action的构造函数, 并在里面打上一句话,加入断点,如果说,每次请求都会进入断点,那么就意味着,每个请求都有一个新的实例是正确的。
第一次进入的时候,是在容器启动的时候:
我们请求
Action,
再次进入断点,说明,每个请求都有一个Action实例来处理。
对于这点的原因,我还是没有弄清楚,为什么按照第2种方式配置,不用指定scope,就会自动的为每个action创建一个实例?(希望懂的朋友,可以指点指点)
对于我们项目中的页面表单对象, 毫无疑问,它也是多例的.
请说一下你们业务层对象是单例还是多例的?
业务层对象是单例的。
请说一下Struts2源代码中有哪些设计模式?
简单罗列一下: 单例模式-- 典型应用: 类:
org.apache.struts2.config.ServletContextSingleton
模版方法模式:
在org.apache.struts2.components包中大量运用
责任连模式:
在拦截器部分使用.
请说一下线程安全出现的原因?
我们都知道线程安全是指什么,我的理解是, 当一个类的“状态”(实例变量)被多个线程所修改时,那么这个类的状态的“正确”性得不到保证,我们就可以理解成线程安全出现。 当然,如果一个没有状态的类,那么它永远都是线程安全的。
再深入一点来看, 我们从Java虚拟机的层面来看这个问题,答案就很明朗了:
Java程序在运行时创建的所有类实例或数组,都存放在同一个堆中,而一个JVM实例中只存在一个堆空间,因此,它被所有的线程共享着,这样的情况下,就可能出现,多个线程访问对象(堆数据)的同步问题了。
请说一下线程池的中断策略(4个)? 各有什么特点?
这里所指的线程池是concurrent包中的ThreadPoolExecutor,而中断策略实际上是指饱和策略(concurent包中的RejectedExecutionHandler接口),
这里需要先解释一下,什么叫饱和策略, 实际就是说, 线程池中的线程容器已经放不下先的任务了,饱和了,必须要有一个相应的策略来处理。
ThreadPoolExecutor内部,已经定义了4种饱和策略:
默认的饱和策略是: (中止), 既如果放不下了,既中止新加入的任务。
源代码中调用如下
如果需要设置饱和策略,可以调用ThreadPoolExecutor的setRejectExecutionHandler方法,JDK提供了4种不同策略的实现(4种实现都定义在ThreadPoolExecutor类中,有兴趣可以查看一下源代码):
下面介绍一下4种实现的特点:
AbortPolicy: (中止)它是默认的策略。
CallerRunsPolicy: (调用者运行), 它既不会丢弃任务,也不会抛出任何异常,它会把任务推回到调用者那里去,以此缓解任务流
DiscardPolicy: (遗弃)策略,它默认会放弃这个任务
DiscardOldestPolicy:(遗弃最旧的),它选择的丢弃的任务,是它本来要执行的(可怜的娃,就这样被新加入的给排挤了),
下面发出这4种策略的源代码: