3年Java面试概要

1、基本语法

这包括static、final、transient等关键字的作用,foreach循环的原理等等。今天面试我问你static关键字有哪些作用,如果你答出static修饰变量、修饰方法我会认为你合格,答出静态块,我会认为你不错,答出静态内部类我会认为你很好,答出静态导包我会对你很满意,因为能看出你非常热衷研究技术。
让我印象深刻的一次面试经历,面试官直接问到了我volatile关键字的底层实现原理(顺便插一句,面试和被面试本身就是相对的,面试官能问这个问题同时也让面试者感觉到面试官也是一个喜爱研究技术的人,增加了面试者对公司的好感,我最终选择的就是问了这个问题的公司),不要觉得这太吹毛求疵了----越简单的问题越能看出一个人的水平,别人对你技术的考量绝大多数都是以深度优先、广度次之为标准的,切记。

java的8中基本类型数据

byte(位) 8 0 -2^7 - 2^7-1 byte b = 10;
short(短整数) 16 0 -2^15 - 2^15-1 short s = 10;
int(整数) 32 0 -2^31 - 2^31-1 int i = 10;
long(长整数) 64 0 -2^63 - 2^63-1 long l = 10l;
float(单精度) 32 0.0 -2^31 - 2^31-1 float f = 10.0f;
double(双精度)64 0.0 -2^63 - 2^63-1 double d = 10.0d;
char(字符) 16 空;0 - 2^16-1 char c = ‘c’;
boolean(布尔值)8 false;true false boolean b = true;

static

static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块
被static修饰后的成员,在编译时由内存分配一块内存空间,直到程序停止运行才会释放,那么就是说该类的所有对象都会共享这块内存空间。
在java类库当中有很多类成员都声明为static,可以让用户不需要实例化对象就可以引用成员。
静态导包就是Java包的静态导入,用import static代替import静态导入包是JDK1.5中的新特性。
一般我们导入一个类都用 import com……ClassName;而静态导入是这样:import static com……ClassName.;这里的多了个static,还有就是类名ClassName后面多了个. ,意思是导入这个类里的静态方法。当然,也可以只导入某个静态方法,只要把 .* 换成静态方法名就行了。然后在这个类中,就可以直接用方法名调用静态方法,而不必用ClassName.方法名 的方式来调用。
好处:这种方法的好处就是可以简化一些操作,例如打印操作System.out.println(…);就可以将其写入一个静态方法print(…),在使用时直接print(…)就可以了。但是这种方法建议在有很多重复调用的时候使用,如果仅有一到两次调用,不如直接写来的方便。

transient

Java的serialization提供了一种持久化对象实例的机制。当持久化对象时,可能有一个特殊的对象数据成员,我们不想用serialization机制来保存它。为了在一个特定对象的一个域上关闭serialization,可以在这个域前加上关键字transient。当一个对象被序列化的时候,transient型变量的值不包括在序列化的表示中,然而非transient型的变量是被包括进去的。

strictfp

想让你的浮点运算更加精确,而且不会因为不同的硬件平台所执行的结果不一致的话,可以用关键字strictfp.

volatile

volatile的作用是: 作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值.
一般说来,volatile用在如下的几个地方:
1、中断服务程序中修改的供其它程序检测的变量需要加volatile;
2、多任务环境下各任务间共享的标志应该加volatile;
3、存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能有不同意义;
另外,以上这几种情况经常还要同时考虑数据的完整性(相互关联的几个标志读了一半被打断了重写),在1中可以通过关中断来实现,2 中可以禁止任务调度,3中则只能依靠硬件的良好设计了。

面向对象的特征

面向对象编程有三大特性:封装、继承、多态。

封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据。对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法。
继承是为了重用父类代码。两个类若存在IS-A的关系就可以使用继承。同时继承也为实现多态做了铺垫。那么什么是多态呢?多态的实现机制又是什么?
所谓多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。

final ,finally,finalize 的区别

final

如果一个类被final修饰,意味着该类不能派生出新的子类,不能作为父类被继承。因此一个类不能被声明为abstract,又被声明为final。将变量或方法声明为final。可以保证他们在使用的时候不被改变。其初始化可以在两个地方:一是其定义的地方,也就是在final变量在定义的时候就对其赋值;二是在构造函数中。这两个地方只能选其中的一个,要么在定义的时候给值,要么在构造函数中给值。被声明为final的方法也只能使用,不能重写。

finally

在异常处理的时候,提供finally块来执行任何的清除操作。如果抛出一个异常,那么相匹配的catch字句就会执行,然后控制就会进入finally块,前提是有finally块。

finalize

finalize是方法名,java技术允许使用finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是在垃圾收集器确认一个对象没有被引用时对这个对象调用的。它是在Object类中定义的,因此,所有的类都继承了它。子类覆盖finalize()方法已整理系统资源或者执行其他清理工作。finalize()方法是在垃圾收集器删除对象之前对这个对象调用的。

int和Integer的区别

1、Integer是int的包装类,int则是java的一种基本数据类型
2、Integer变量必须实例化后才能使用,而int变量不需要
3、Integer实际是对象的引用,当new一个Integer时,实际上是生成一个指针指向此对象;而int则是直接存储数据值
4、Integer的默认值是null,int的默认值是0

重载和重写的区别

重写
1、方法名、参数、返回值相同。
2、子类方法不能缩小父类方法的访问权限。
3、子类方法不能抛出比父类方法更多的异常(但子类方法可以不抛出异常)。
4、存在于父类和子类之间。
5、方法被定义为final不能被重写。 
重载
1、参数类型、个数、顺序至少有一个不相同。
2、不能重载只有返回值不同的方法名。
3、存在于父类和子类、同类中。

抽象类和接口有什么区别

接口是抽象类的变体,接口中所有的方法都是抽象的。而抽象类是声明方法的存在而不去实现它的类。
接口可以多继承,抽象类不行
接口定义方法,不能实现,而抽象类可以实现部分方法。
接口中基本数据类型为static 而抽类象不是的。
接口中不能含有静态代码块以及静态方法,而抽象类可以含有静态方法和静态代码块。

说说反射的用途及实现

1、反射最重要的用途就是开发各种通用框架。

基本反射功能的实现(反射相关的类一般都在java.lang.relfect包里):

1、获得Class对象

使用Class类的forName静态方法
直接获取某一个对象的class
调用某个对象的getClass()方法

2、判断是否为某个类的实例

用instanceof关键字来判断是否为某个类的实例

3、创建实例

使用Class对象的newInstance()方法来创建Class对象对应类的实例。
先通过Class对象获取指定的Constructor对象,再调用Constructor对象的newInstance()方法来创建实例。

4、获取方法

getDeclaredMethods()

5、获取构造器信息

getDeclaredMethods()
getMethods()
getMethod()

6、获取类的成员变量(字段)信息

getFiled: 访问公有的成员变量
getDeclaredField:所有已声明的成员变量。但不能得到其父类的成员变量
getFileds和getDeclaredFields用法

7、调用方法

invoke()

8、利用反射创建数组

Array.newInstance()

注意:

由于反射会额外消耗一定的系统资源,因此如果不需要动态地创建一个对象,那么就不需要用反射。
另外,反射调用方法时可以忽略权限检查,因此可能会破坏封装性而导致安全问题。

说说自定义注解的场景及实现

登陆、权限拦截、日志处理,以及各种 Java 框架,如 Spring,Hibernate,JUnit 提到注解就不能不说反射,Java 自定义注解是通过运行时靠反射获取注解。实际开发中,例如我们要获取某个方法的调用日志,可以通过 AOP(动态代理机制)给方法添加切面,通过反射来获取方法包含的注解,如果包含日志注解,就进行日志记录。反射的实现在 Java 应用层面上讲,是通过对 Class 对象的操作实现的,Class 对象为我们提供了一系列方法对类进行操作。在 JVM 这个角度来说,Class 文件是一组以 8 位字节为基础单位的二进制流,各个数据项目按严格的顺序紧凑的排列在 Class 文件中,里面包含了类、方法、字段等等相关数据。通过对 Class 数据流的处理我们即可得到字段、方法等数据。

HTTP 请求的 get和post区别

1.get是从服务器上获取数据,post是向服务器传送数据。
2. get是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看到。
3. post是通过HTTP post机制,将表单内各个字段与其内容放置在HTML HEADER内一起传送到ACTION属性所指的URL地址,用户看不到这个过程。
3.对于get方式,服务器端用Request.QueryString获取变量的值,对于post方式,服务器端用Request.Form获取提交的数据。
4.get传送的数据量较小,不能大于2KB。post传送的数据量较大,一般被默认为不受限制。
5.get安全性非常低,post安全性较高。但是执行效率却比Post方法好。

cookie和session的区别

session 在服务器端,cookie 在客户端(浏览器)
session 默认被存在在服务器的一个文件里(不是内存)
session 的运行依赖 session id,而 session id 是存在 cookie 中的,也就是说,如果浏览器禁用了 cookie ,
同时 session 也会失效(但是可以通过其它方式实现,比如在 url 中传递 session_id)
session 可以放在 文件、数据库、或内存中都可以。

Session实现原理

1、创建Session的时候,服务器将生成一个唯一的sessionid然后用它生成一个关闭浏览器就会失效的cookie。
2、然后再将一个与这个sessionid关联的数据项加入散列表。
3、当浏览器端提交到服务器时,会通过sessionid去散列表中寻找属于该用户的Session信息。

JDBC 流程

1.加载驱动
2.通过drivermanager获取连接
3.通过连接获取会话
4.通过对会话的增删改查获取结果集
5.处理结果集
6.关闭资源

mybaits和jdbc相比较?

1.mybaits给我们维护连接池
2.对结果集的处理更友好,给我们封装成对象
3.把sql语句放在配置文件中,便于维护,而不用修改代码

statement和 prestatement比较

1.后者的安全性较高,可以防止sql注入。
2.后者先经过编译,效率较高

equals 与 == 的区别

“ = = ” 比较的是两个引用在内存中指向的是不是同一对象(即同一内存空间),也就是说在内存空间中的存储位置是否一致。
如果两个对象的引用相同时(指向同一对象时),“ = = ”操作符返回true,否则返回flase。
equals用来比较的是两个对象的内容是否相等

MyBatis中#和$的区别

#{}:占位符号,好处防止sql注入
${}:sql拼接符号

MVC设计思想

视图(View)-对应组件:JSP或者HTML文件
控制器(Controller)-对应组件:Servlet(controller)
模型(Model) -对应组件:JavaBean
优点:完美的系统架构 = 松耦合 + 高重用性 + 高扩展性
缺点:原理复杂增加了系统结构和实现的复杂性视图对模型数据的低效率访

谈谈分布式Session的几种实现方式

  1. Session Replication 方式管理 (即session复制)
    简介:将一台机器上的Session数据广播复制到集群中其余机器上
    使用场景:机器较少,网络流量较小
    优点:实现简单、配置较少、当网络中有机器Down掉时不影响用户访问
    缺点:广播式复制到其余机器有一定廷时,带来一定网络开销
  2. Session Sticky 方式管理
    简介:即粘性Session、当用户访问集群中某台机器后,强制指定后续所有请求均落到此机器上
    使用场景:机器数适中、对稳定性要求不是非常苛刻
    优点:实现简单、配置方便、没有额外网络开销
    缺点:网络中有机器Down掉时、用户Session会丢失、容易造成单点故障
  3. 缓存集中式管理
    简介:将Session存入分布式缓存集群中的某台机器上,当用户访问不同节点时先从缓存中拿Session信息
    使用场景:集群中机器数多、网络环境复杂
    优点:可靠性好
    缺点:实现复杂、稳定性依赖于缓存的稳定性、Session信息放入缓存时要有合理的策略写入

2、集合

LinkedList与ArrayList的区别

LinkedList底层是双向链表 ;ArrayList底层是可变数组
LinkedList不允许随机访问,即查询效率低 ;ArrayList允许随机访问,即查询效率高
LinkedList插入和删除效率快 ;ArrayList插入和删除效率低

List 和 Map 区别

List是存储单列数据的集合,Map是存储键和值这样的双列数据的集合,
List中存储的数据是有顺序,并且允许重复;
Map中存储的数据是没有顺序的,键不能重复,值是可以有重复的。

List 和 Set 区别

1、List,Set都是继承自Collection接口
2、List特点:元素有放入顺序,元素可重复 ,Set特点:元素无放入顺序,元素不可重复,重复元素会覆盖掉,
(元素虽然无放入顺序,但是元素在set中的位置是有该元素的HashCode决定的,其位置其实是固定的,
加入Set 的Object必须定义equals()方法 ,另外list支持for循环,也就是通过下标来遍历,也可以用迭代器,
但是set只能用迭代,因为他无序,无法用下标来取得想要的值。)
3.Set和List对比:
Set:检索元素效率低下,删除和插入效率高,插入和删除不会引起元素位置改变。
List:和数组类似,List可以动态增长,查找元素效率高,插入删除元素效率低,因为会引起其他元素位置改变。

Arraylist 与 LinkedList 区别

1、ArrayList和LinkedList可想从名字分析,它们一个是Array(动态数组)的数据结构,一个是Link(链表)的数据结构,此外,它们两个都是对List接口的实现。前者是数组队列,相当于动态数组;后者为双向链表结构,也可当作堆栈、队列、双端队列
2、当随机访问List时(get和set操作),ArrayList比LinkedList的效率更高,因为LinkedList是线性的数据存储方式,所以需要移动指针从前往后依次查找。
3、当对数据进行增加和删除的操作时(add和remove操作),LinkedList比ArrayList的效率更高,因为ArrayList是数组,所以在其中进行增删操作时,会对操作点之后所有数据的下标索引造成影响,需要进行数据的移动。
4、从利用效率来看,ArrayList自由性较低,因为它需要手动的设置固定大小的容量,但是它的使用比较方便,只需要创建,然后添加数据,通过调用下标进行使用;而LinkedList自由性较高,能够动态的随数据量的变化而变化,但是它不便于使用。
5、ArrayList主要控件开销在于需要在lList列表预留一定空间;而LinkList主要控件开销在于需要存储结点信息以及结点指针信息。

ArrayList 与 Vector 区别

Vector的方法都是同步的(Synchronized),是线程安全的(thread-safe),而ArrayList的方法不是,由于线程的同步必然要影响性能,因此,ArrayList的性能比Vector好。 当Vector或ArrayList中的元素超过它的初始大小时,Vector会将它的容量翻倍,而ArrayList只增加50%的大小,这样,ArrayList就有利于节约内存空间。

2.HashTable与HashMap的区别

Hashtable方法是同步的 ; HashMap方法是非同步的
Hashtable基于Dictionary类 ; HashMap基于AbstractMap,而AbstractMap基于Map接口的实现
Hashtable中key和value都不允许为null,遇到null,直接返回 NullPointerException
HashMap中key和value都允许为null,遇到key为null的时候,调用putForNullKey方法进行处理,而对value没有处理
Hashtable中hash数组默认大小是11,扩充方式是old*2+1
HashMap中hash数组的默认大小是16,而且一定是2的指数

问:HashSet与HashMap区别

hashmap实现了Map接口 ; hashSet实现了Set接口
HashMap储存键值对 ; HashSet仅仅存储对象
HashMap使用put()方法将元素放入map中 ; HashSet使用add()方法将元素放入set中
HashMap中使用键对象来计算hashcode值 ; HashSet使用成员对象来计算hashcode值
HashMap比较快,因为是使用唯一的键来获取对象 ; HashSet较HashMap来说比较慢

HashMap 的工作原理及代码实现

这里有点长,还是自己跳转连接去看吧
https://blog.csdn.net/abcdad/article/details/64123291

ConcurrentHashMap的锁分段技术

ConcurrentHashMap所使用的锁分段技术,首先将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问。

ConcurrentHashMap的读是否要加锁,为什么

1、public V get(Object key)不涉及到锁,也就是说获得对象时没有使用锁;
2、put、remove方法要使用锁,但并不一定有锁争用,原因在于ConcurrentHashMap将缓存的变量分到多个Segment,
每个Segment上有一个锁,只要多个线程访问的不是一个Segment就没有锁争用,就没有堵塞,各线程用各自的锁,
ConcurrentHashMap缺省情况下生成16个Segment,也就是允许16个线程并发的更新而尽量没有锁争用;
3、Iterator对象的使用,不一定是和其它更新线程同步,获得的对象可能是更新前的对象,ConcurrentHashMap允许一边更新、
一边遍历,也就是说在Iterator对象遍历的时候,ConcurrentHashMap也可以进行remove,put操作,且遍历的数据会随着remove,
put操作产出变化,所以希望遍历到当前全部数据的话,要么以ConcurrentHashMap变量为锁进行同步(synchronized该变量),
要么使用CopiedIterator包装iterator,使其拷贝当前集合的全部数据,但是这样生成的iterator不可以进行remove操作。

Hashtable和ConcurrentHashMap的不同点:

1、Hashtable对get,put,remove都使用了同步操作,它的同步级别是正对Hashtable来进行同步的,也就是说如果有线程正在遍历集合,其他的线程就暂时不能使用该集合了,这样无疑就很容易对性能和吞吐量造成影响,从而形成单点。而ConcurrentHashMap则不同,它只对put,remove操作使用了同步操作,get操作并不影响,详情请看以上第1,2点,当前ConcurrentHashMap这样的做法对一些线程要求很严格的程序来说,还是有所欠缺的,对应这样的程序来说,如果不考虑性能和吞吐量问题的话,个人觉得使用Hashtable还是比较合适的;
2、Hashtable在使用iterator遍历的时候,如果其他线程,包括本线程对Hashtable进行了put,remove等更新操作的话,
就会抛出ConcurrentModificationException异常,但如果使用ConcurrentHashMap的话,就不用考虑这方面的问题了。

线程

创建线程的方式及实现

。。。待更新

3、设计模式

本来以为蛮重要的一块内容,结果只在阿里巴巴B2B事业部面试的时候被问了一次,当时问的是装饰器模式。
当然咱们不能这么功利,为了面试而学习,设计模式在工作中还是非常重要、非常有用的,23种设计模式中重点研究常用的十来种就可以了,面试中关于设计模式的问答主要是三个方向:
  你的项目中用到了哪些设计模式,如何使用

知道常用设计模式的优缺点

设计模式:模式是一种问题的解决思路,它已经适用于一个实践环境。并且可以适用于其他环境。
设计模式的分类:分布式编程模式,用户界面模式,数据模型模式三大类。
设计模式的作用:设计的重用;
为设计提供共同的词汇,每个模式名就是一个设计词汇,其概念使得程序员的交流变得方便;
在开发文档中采用模式词汇可以让其他人更容易理解你的想法。
GoF设计模式的分类:
根据目的准则分类:
1. 创建型:creational 与对象的创建有关。
2. 结构型:Structural 处理类或对象之间的组合。
3. 行为型:behavioral 描述类或对象如何交互及如何分配职责。
创建型模式
1.抽象工厂模式 AbstractFactory
2.建造者模式 Builder
3.工厂方法模式 Factory Method
4.原型模式 Prototype
5.单例模式 Singleton
结构型模式
1.适配器模式 Adapter
2.桥接模式 Bridge
3.组合模式 Composite
4.装饰模式 Decorator
5.外观模式 Facade
6.享元模式 Flyweight
7.代理模式 Proxy
行为模式
1.职责链模式 Chain of Responsibility
2.命令模式 Command
3.解释器模式 Interpreter
4.迭代器模式 Iterator
5.中介者模式 Mediator
6.备忘录模式 Memento
7.观察者模式 Observer
8.状态模式 State
9.策略模式 Strategy
10.模板方法模式 Template Method
11.访问者模式 Visitor

1 简单工厂模式(Static Factory Method)

适用场景

工厂类负责创建的对象比较少。
客户只知道传入工厂类的参数,对于如何创建对象(逻辑)不关心。
由于简单工厂很容易违反高内聚责任分配原则,因此一般只在很简单的情况下应用。

优点

工厂类是整个模式的关键。包含了必要的逻辑判断,根据外界给定的信息,决定究竟应该创建哪个具体类的对象。
通过使用工厂类,外界可以从直接创建具体产品对象的尴尬局面摆脱出来,仅仅需要负责“消费”对象就可以了。而不必管这些对象究竟如何创建及如何组织的。明确了各自的职责和权利,有利于整个软件体系结构的优化。

缺点

由于工厂类集中了所有实例的创建逻辑,违反了高内聚责任分配原则,将全部创建逻辑集中到了一个工厂类中,它所能创建的类只能是事先考虑到的,如果需要添加新的类,则就需要改变工厂类了。
当系统中的具体产品类不断增多时候,可能会出现要求工厂类根据不同条件创建不同实例的需求。这种对条件的判断和对具体产品类型的判断交错在一起,很难避免模块功能的蔓延,对系统的维护和扩展非常不利。
这些缺点在工厂方法模式中得到了一定的克服。
2 策略模式(Strategy)

适用场景

多个类有不同的表现形式,每种表现形式可以独立成单独的算法。
需要再不同情况下使用不同的算法,以后算法可能还会增加。
对用户隐藏算法逻辑。

优点

每个算法单独封装,减少了算法和算法调用者的耦合。
合理使用继承有助于提取出算法中的公共部分。
简化了单元测试。

缺点

策略模式只适用于客户端知道所有的算法或行为的情况。
策略模式造成很多的策略类,每个具体策略类都会产生一个新类。不过可以使用享元模式来减少对象的数量。
3 装饰模式(Decorator)

适用场景

需要扩展一个类的功能,或给一个类添加附加职责。
需要动态的给一个对象添加功能,这些功能可以再动态的撤销。
需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变的不现实。
当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。

优点

Decorator模式与继承关系的目的都是要扩展对象的功能,但是Decorator可以提供比继承更多的灵活性。
通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。

缺点

这种比继承更加灵活机动的特性,也同时意味着更加多的复杂性。
装饰模式会导致设计中出现许多小类,如果过度使用,会使程序变得很复杂。
装饰模式是针对抽象组件(Component)类型编程。但是,如果你要针对具体组件编程时,就应该重新思考你的应用架构,以及装饰者是否合适。当然也可以改变Component接口,增加新的公开的行为,实现“半透明”的装饰者模式。在实际项目中要做出最佳选择。
4 代理模式(Proxy)

适用场景

远程代理,为一个对象在不同的地址空间提供局部代表,这样就可以隐藏一个对象存在于不同地址空间的事实。
虚拟代理,是根据需要创建开销很大的对象。通过它来存放实例化需要很长时间的真是对象。
安全代理,用来控制真实对象访问时的权限。
智能指引,是指当调用真是的对象时,代理处理另外的一些事情。

优点

职责清晰,真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一件完成事务,附带的结果就是编程简洁清晰。
代理对象可以在客户端和目标对象之间起到中介的作用,这样起到了中介的作用和保护了目标对象的作用。
高扩展性

缺点

在客户端和目标对象增加一个代理对象,会造成请求处理速度变慢。
增加了系统的复杂度。
5 工厂方法模式(Factory Method)

适用场景

工厂方法模式是new一个对象的替代品,所以在所有需要生成对象的地方都可以使用,但是需要慎重地考虑是否要增加一个工厂类进行管理,增加代码的复杂度。
需要灵活的、可扩展的框架时,可以考虑采用工厂方法模式。
工厂方法模式可以用在异构项目中,例如通过WebService与一个非Java的项目交互,虽然WebService号称是可以做到异构系统的同构化,但是在实际的开发中,还是会碰到很多问题,如类型问题、WSDL文件的支持问题,等等,从WSDL中产生的对象都认为是一个产品,然后由一个具体的工厂类进行管理,减少与外围系统的耦合。
可以使用在测试驱动开发的框架下,例如,测试一个类A,就需要把与类A有关联关系的类B也同时产生出来,我们可以使用工厂方法模式把类B虚拟出来,避免类A与类B的耦合。目前由于JMock和EasyMock的诞生,该使用场景已经弱化了,读者可以在遇到此种情况时直接考虑使用JMock或EasyMock。

优点

良好的封装性,代码结构清晰,减少模块间的耦合。
工厂方法模式的扩展性非常优秀。
屏蔽产品类。
工厂方法模式是典型的解耦框架。

缺点

使用者必须知道相应工厂的存在。
每次增加一个产品时,都需要增加一个具体类和对象实现工厂,是的系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。
6 原型模式(Prototype)

适用场景

某些结构复杂的对象的创建工作;由于需求的变化,这些对象经常面临着剧烈的变化,但是他们却拥有比较稳定一致的接口。
一般在初始化的信息不发生变化的情况下,克隆是最好的方法。

优点

隐藏了对象创建的细节。
提高了性能。
不用重新初始化,动态获得对象运行时的状态。

缺点

适用性不是很广。
每一个类必须配备一个克隆方法。
配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类不是很难,但对于已有的类不一定很容易,特别当一个类引用不支持串行化的间接对象,或者引用含有循环结构的时候。
7 模板方法模式(Template Method)

适用场景

适用于子类中有重复的代码,可以把重复代码提取出来,放到父类中。

优点

提高代码复用性。
帮助子类摆脱重复的不变行为。

缺点

考虑不全面统一出现问题。

4、多线程

这也是必问的一块了。因为三年工作经验,所以基本上不会再问你怎么实现多线程了,会问得深入一些比如说Thread和Runnable的区别和联系、多次start一个线程会怎么样、线程有哪些状态。当然这只是最基本的,出乎意料地,几次面试几乎都被同时问到了一个问题,问法不尽相同,总结起来是这么一个意思:

假如有Thread1、Thread2、Thread3、Thread4四条线程分别统计C、D、E、F四个盘的大小,所有线程都统计完毕交给Thread5线程去做汇总,应当如何实现?

你对这个问题是否有答案呢?不难,java.util.concurrent下就有现成的类可以使用。

另外,线程池也是比较常问的一块,常用的线程池有几种?这几种线程池之间有什么区别和联系?线程池的实现原理是怎么样的?实际一些的,会给你一些具体的场景,让你回答这种场景该使用什么样的线程池比较合适。

最后,虽然这次面试问得不多,但是多线程同步、锁这块也是重点。synchronized和ReentrantLock的区别、synchronized锁普通方法和锁静态方法、死锁的原理及排查方法等等…

。。。待更新
直接来这里看也可以
http://blog.720ui.com/2018/java_interview_final/#简历篇

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值