面试基础
1.自我介绍。(第一印象超级超级重要)
1. 介绍个人信息,说明本次应聘岗位。
2. 项目经验,实习经验。
3. 个人特点,爱好。
4. 对贵公司的价值观认可。
5. 谢谢。
2. 面试圣经
人品第一, 技术第二! 细节处体现人品,面试态度一定要和善。把不懂的知识点往你懂的知识点处引导。始终有答案,不要被问住。
3. 你在项目中遇到的一个困难,你是怎么解决的?(解决问题的逻辑过程 思路 总结性的结论)
技术方面的,还是团队配合方面的。最好结合自己的工作经验,先把困难和问题描述清楚,然后介绍,你如何去查找问题的原因,任何问题,只要原因查到了,基本就已经接近了百分之八十了。(自己能搞定的,就自己上网找资料;但如果比如在2个小时之内还没有头绪,就考虑问公司技术水平比较高的同事之类的,然后还要及时和项目经理沟通)。这个问题如果回答的好,可以把项目中的知识点导向你擅长的知识点处。
4. 你是如何与项目团队之间进行沟通和合作的?
Java基础篇(50问)
1. 你觉得Java语言怎么样?
java是面向对象的语言;跨平台可移植;解释性语言;封装、继承、多态;Java中无指针,对象的引用实现链表;GC自动垃圾回收,不用担心内存泄露;单继承,实现多接口;java中有异常处理(C++没有)。
2. 说说你常使用的集合类,然后针对一个往死里问。
接口List和Set继承自接口Collection,Map接口则不是。实现List的类有ArrayList、LinkedList、Vector;实现Set的类有HashSet、TreeSet;实现Map的类有HashMap、LinkedHashMap。
Hashtable和HashMap的区别:
1.Hashtable是Dictionary的子类,HashMap是Map接口的一个实现类;
2.Hashtable中的方法是同步的,而HashMap中的方法是非同步的。在多线程应用程序中可以安全地可以使用Hashtable;而对于HashMap,则需要额外的同步机制。但HashMap的同步问题可通过Collections的一个静态方法得到解决:Map Collections.synchronizedMap(Map m)。这个方法返回一个同步的Map,这个Map封装了底层的HashMap的所有方法,使得底层的HashMap即使是在多线程的环境中也是安全的。
3.在HashMap中,允许key=null&&value=null,但是HashTable不允许。
// HashMap和ConcurrentHashMap的区别。
1. HashMap线程不安全。ConcurrentHashMap线程安全。
2. ConcurrentHashMap实现线程安全不是通过synchronized来实现的。而是采用了一个分段锁的概念。
3. ConcurrentHashMap的工作机制,通过把整个Map分为N个Segment, 当put和get的时候,通过使用key.hashCode()方法来算出放到哪个setment中。
// HashMap和HashSet的区 map存键值对; Collections存对象。HashSet是用HashMap来实现的。
Map集合,就是有一对属性值的集合,属性包含key,和value。关键字key是唯一不重复的。Map是一个有序的集合,所以查询起来速度很快。而HashSet就像是把HashMap中value去掉,说白了就是只有一个key的HashMap集合。
Set是数学中定义的集合,所以元素无序, 且不能重复添加。java程序中Set集合用的不多,Map集合中的HashMap集合,List集合用的倒是不少。
1. HashSet存储的元素不能重复。HashSet中有equals()和hasCode()方法,确保存入集合的元素不重复。add方法存入元素的时候,首先判断要放入对象的hashcode值与集合中的任意一个元素的hashcode值是否相等,如果不相等直接将该对象放入集合中。如果hashcode值相等,然后再通过equals方法判断要放入对象与集合中的任意一个对象是否相等,如果equals判断不相等,直接将该元素放入到集合中,否则不放入。
2. HashSet中add元素的源码如下:
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
public V put(K key, V value) {
if (key == null)
return putForNullKey(value);
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(hash, key, value, i);
return null;
}
3. HashMap保存了对象存入时候的顺序,但是HashSet再输出的时候,顺序是跟存入时候的顺序不一样的。因为其内部是使用hashCode()方法来实现的。map用put()方法; set用add()方法。
// HashSet是如何遍历的?遍历hashSet有两种方案:
1. clone出一个新的hashSet, 再用iterator迭代。(源码中采用这种 推荐)
2. toArray创建一个新数组, 再用for each循环遍历。(不推荐 效率不高)
3. length()和size()?
size用于集合类,length用于字符串和数组,字符串是函数,数组是属性。
4. Java集合类中的排序:
// ArrayList中有sort() 方法, 对 Java Arrays.sort()源代码解析:
1. sort()方法的源码中对基本数据类型使用快速排序; 对引用数据类型使用归并排序。理由:对象排序,稳定性更重要,对象移动开销大。具体的快速排序方法是有一定优化的,根据数组大小的不同,有不同的分割位置。
//ArrayList 默认初始容量是10,扩容1.5倍。LinkedList不需要,那么Vector是扩容2倍。Vector线程安全。
//HashTable怎么实现线程安全的,调用了Hashtable.Synchronized方法后才变成线程安全,内部使用一个静态字段实现锁定。
5. equals( )方法和 = = 比较。 equals( )方法和hasCode( )方法比较。
// 首先equals 和 == 比较。
1. 一个是运算符,一个是方法
2. 比较无非就是在比较基本数据类型和引用数据类型。当比较基本数据类型的时候,equals和==都可以比较两个值是否相等,相等为true,否则为false。
当比较的是引用数据类型的时候,==和equals都是比较对象在内存中的地址是否相等,相等为true,否则为false。
3.特别注意的就是String了。object中的equals方法是==,string重写了==方法,所以,在String在比较的是对象的时候,equals同,==不同。比较字符串的时候是相同的。
public class Test{
public static void main(String args[]){
String s1 = "abc";
String s2 = "abc";
System.out.println(s1==s2?Boolean.TRUE:Boolean.FALSE);
System.out.println(s1.equals(s2)?Boolean.TRUE:Boolean.FALSE);
}
}
// 其次, equals()和hasCode()方法比较
1. 先掌握两个知识点:HashMap中put元素的实现; HashSet中add元素时候, 如何判断元素是否相同。
2. Object中默认的equals是比较内存地址的; 一般对象重写equals方法是为了比较内容。Object类的对象的hashCode是每new一个都不一样。 但是如果你new两个相同的String,那么他们的hashCode是一样的。hashcode大部分情况下映射到内存地址。
6. Java抽象类和接口的区别。
抽象类可以有构造方法,构造方法不可以继承。但是可以供子类使用super来调用。
接口中的方法和变量是共有的,因为要供别人使用。抽象类中的方法和变量则是可以私有的。
可以继承一个类,但是可以实现多个接口。
接口定义方法,不能实现。抽象类可以实现部分方法。抽象类动物。接口是抽出公有的行为。动作。
概念不一样:实现接口的一定要实现接口里定义的所有方法,而实现抽象类可以有选择地重写需要用到的方法,一般的应用里,最顶级的是接口,然后是抽象类实现接口,最后才到具体类实现。public class ArrayList<E> extends AbstractList<E> implements List<E>
7. Java多态的实现机制。
重载和重写。
子类重写父类方法。
参数不同,重载。
8. Java类加载的原理。
每个java开发人员对java.lang.ClassNotFoundExcetpion这个异常肯定都不陌生,这背后就涉及到了java技术体系中的类加载。Java的类加载机制是java技术体系中比较核心的部分,虽然和大部分开发人员直接打交道不多,但是对其背后的机理有一定理解有助于排查程序中出现的类加载失败等技术问题,对理解java虚拟机的连接模型和java语言的动态性都有很大帮助。(跟异常结合来问) 最佳答案
9. Object类有几个方法?
1. clone( )方法, 创建并返回对象的一个副本。
2. getClass()方法,返回运行时类。
3. hashCode()方法,返回对象的哈希码。
4. toString()方法,返回对象的字符串表示。
5. wait()方法,使当前线程等待,知道被唤醒
// 我们知道万事万物都是联系的,java对象世界也是如此; 所以要有一个超类Object,对象之间要发生关系,要并发、要同步,必须要使用wait()方法,学了JavaScript的继承机制,你就知道了为什么要有一个超类。
10. try-catch-finally中,如果在try或catch中有return过,是否还执行 。
// 执行顺序总结:一句话描述“finally 永远执行”
1. 在try中没有异常的情况下try、catch、finally的执行顺序 try --- finally
2. 如果try中有异常,执行顺序是try --- catch --- finally
3. 如果try中没有异常并且try中有return这时候正常执行顺序是try ---- finally --- return
4. 如果try中有异常并且try中有return这时候正常执行顺序是try----catch---finally--- return
try-catch-finally里都没有return ,finally 之后有个return ,如果try中有异常,finally执行完后,还能执行return吗?那是不可能执行的了,try中有异常以后,根据java的异常机制先执行catch后执行finally,此时错误异常已经抛出,程序因异常而终止,所以你的return是不会执行的
//catch中同时有父异常和子异常,那么子异常优先来捕获异常。
11. JVM布局,JVM内部内存的划分。
首先知道,内存中被划分成这么几块儿:堆、栈、程序计数器、本地方法栈、方法区。
1.方法区是线程共享的,跟堆一样; 本地方法栈,类似于栈,是用于执行本地方法的。
12. Java中序列化
第一点,要阐述的是当JVM处于运行时,java对象才可能存在。即Java对象的生命周期不会比JVM的生命周期更长。但在现实应用中,就可能要求在JVM停止运行之后能够保存(持久化)指定的对象,并在将来重新读取被保存的对象。Java对象序列化就能够帮助我们实现该功能。使用Java对象序列化,在保存对象时,会把其状态保存为一组字节,在未来,再将这些字节组装成对象。必须注意地是,对象序列化保存的是对象的"状态",即它的成员变量。由此可知,对象序列化不会关注类中的静态变量。除了在持久化对象时会用到对象序列化之外,当使用RMI(远程方法调用),或在网络中传递对象时,都会用到对象序列化。
第二点,在Java中,只要一个类实现了java.io.Serializable接口,那么它就可以被序列化。
13. Java中反射机制
一句话说Java反射机制就是,运行状态时动态获取信息。很多开源框架实现都是使用了java的反射机制。为什么要使用java反射呢?有一句经典的话,叫做:父类引用指向子类对象。能发挥这种能力,需要配合在动态运行时确定。体现了Java的灵活性,体现了多态,降低了类之间的耦合性。
1. 对于任意一个类,都能够知道这个类的所有属性和方法;
2. 对于任意一个对象,都能够调用它的任意一个方法;
Java反射机制能干什么?如果不使用反射机制。一个对象,增删改查,分别要创建四个Dao类来,有了Dao类,只需要写一个Dao类,四个方法,其余的交给java反射机制来解决。
14. Java中多线程
1. 继承Thread类,或者实现Runnable接口。
2. 重写Runnable中的run方法,启动线程用start方法。
3. java中有两种线程,用户线程和守护线程。 守护线程:优先级最低,setDaemon方法设置为守护线程。GC垃圾回收就是一个守护线程。
4. 当JVM的线程都是守护线程的时候,JVM就可以退出了。守护线程是用来服务用户线程的。
5. Java线程池,如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间。那么有没有一种办法使得线程可以复用,就是执行完一个任务,并不被销毁,而是可以继续执行其他的任务。在Java中可以通过线程池来达到这样的效果。
6. Java中线程安全问题, 线程安全问题主要出现在访问临界资源的时候,就是访问同一个对象的时候,可能会出现无法挽回的损失,特别是在关于资金安全方面的时候,当然还有数据库事务方面的问题。他们很类似,都是要保证数据的原子性。对与共同使用的对象进行加锁,意思是我使用的时候,那么你就必须等待,等我用完之后你再用,反之依然。加锁使用关键字synchronized。将当前线程锁定,让别的线程等待。
7. HashMap为何线程不安全,同时又读又写的时候,不能保证结果的唯一。就是线程不安全。
8. 线程有几种状态:就绪、运行、阻塞、挂起。
21. Java中哈希实现原理。
哈希的出现时因为传统数据结构如线性表(数组,链表等),树中,关键字与其它的存放位置不存在对应的关系。因此在查找关键字的时候需要逐个比对,虽然出现了二分查找等各种提高效率的的查找算法。但是这些并不足够,希望在查询关键字的时候不经过任何比较,一次存取便能得到所查记录。因此,我们必须在关键字和其对应的存储位置间建立对应的关系f。这种对应的关系f被称为哈希函数,按此思想建立的表为哈希表。关键在于哈希函数如何构造。
http://www.linuxidc.com/Linux/2014-04/100598.htm
HashMap里面实现一个静态内部类Entry,
静态定义,其实主要作用就是把初始化交给JVM,而且不需要人工初始化。 Entry就是用的LinkedList<E>里面的E, javaAPI的设计者们把Entry设计成静态内部类应该是为了方便使用吧。
22. 说说Java静态内部类。
需要了解2个概念:内部类和静态修饰符static
1)首先,用内部类是因为内部类与所在外部类有一定的关系,往往只有该外部类调用此内部类。所以没有必要专门用一个Java文件存放这个类。
2)静态都是用来修饰类的内部成员的。比如静态方法,静态成员变量,静态常量。它唯一的作用就是随着类的加载(而不是随着对象的产生)而产生,以致可以用类名+静态成员名直接获得。
这样静态内部类就可以理解了,因为这个类没有必要单独存放一个文件,它一般来说只被所在外部类使用。并且它可以直接被用 外部类名+内部类名 获得。
以下举例说明怎么使用:
Student类有个叫School的内部类(非静态)
Student stu = new Student();
stu.School sch = new stu.School();
sch就是School的一个对象。
假如School是内部静态类:
Student.School sch = new Student.School();
首先你要明白静态内部类和一般内部类的区别。
1、静态内部类也叫嵌套类,用这个名字给他定义是更加形象的。意思是说内部类和外部类的关系只是层次嵌套关系,所以只是在创建类文件的时候类文件名是如下形式:outer$inner.java,在使用方面完全和两个普通类一样。
2、一般内部类在我看来才是真正的内部类,他们不仅有着嵌套关系,更重要的是内部类可以获得外部类的引用从而实现回调。而且通过创建内部类还可已让java实现真正的多继承!(interface名叫接口,顾名思义,他就是实现接口的,让一个类继承多个接口实现多继承是不合适的)。关于内部类里面的东西比较多,也是java比较特色之一,不要指望在网上看就能学会,买本书再多多练习才能掌握。
Java语言允许在类中再定义类,这种在其它类内部定义的类就叫内部类。内部类又分为:常规内部类、局部内部类、匿名内部类和静态嵌套类四种。
1、静态内部类定义
静态内部类,定义在类中,任何方法外,用static定义;静态内部类只能访问外部类的静态成员。
生成(new)一个静态内部类不需要外部类成员:这是静态内部类和成员内部类的区别。静态内部类的对象可以直接生成:Outer.Inner in=new Outer.Inner();而不需要通过生成外部类对象来生成。这样实际上使静态内部类成为了一个顶级类。可以定义私有静态内部类。
2、java实现静态内部类注意事项
将某个内部类定义为静态类,跟将其他类定义为静态类的方法基本相同,引用规则也基本一致。不过其细节方面仍然有很大的不同。具体来说,主要有如下几个地方要引起注意。
1)一般情况下,如果一个内部类不是被定义成静态内部类,那么在定义成员变量或者成员方法的时候,是不能够被定义成静态成员变量与静态成员方法的。也就是说,在非静态内部类中不可以声明静态成员。
2)一般非静态外部类可以随意访问其外部类的成员变量以及方法(包括声明为private的方法),但是如果一个内部类被声明为static,则其在访问包括自身的外部类会有诸多的限制。静态内部类不能访问其外部类的非静态成员变量和方法
3)在一个类中创建非静态成员内部类的时候,有一个强制性的规定,即内部类的实例一定要绑定在外部类的实例中。然后要在一个外部类中定义一个静态的内部类,不需要利用关键字new来创建内部类的实例。即在创建静态类内部对象时,不需要其外部类的对象。
23. 说说Java内部类。
内部类的优点是:内部类可以访问外部类的私有成员变量,而不需要new外部类的对象。
内部类又分为:静态内部类、匿名内部类、局部内部类、成员内部类。
静态内部类的应用场景是:只可以访问外部类的静态成员变量和静态成员方法。
成员内部类的应用场景是:它可以访问它的外部类的所有成员变量和方法,不管是静态的还是非静态的都可以。
局部内部类:像局部变量一样,不能被public, protected, private和static修饰。只能访问方法中定义的final类型的局部变量。
匿名内部类:匿名内部类就是没有名字的局部内部类,不使用关键字class, extends, implements, 没有构造方法。匿名内部类隐式地继承了一个父类或者实现了一个接口。匿名内部类使用得比较多,通常是作为一个方法参数。
内部类不是很好理解,但说白了其实也就是一个类中还包含着另外一个类。 如同一个人是由大脑、肢体、器官等身体结果组成,而内部类相当于其中的某个器官之一,例如心脏:它也有自己的属性和行为(血液、跳动)。
显然,此处不能单方面用属性或者方法表示一个心脏,而需要一个类。而心脏又在人体当中,正如同是内部类在外部内当中
从上面的例子不难看出,内部类其实严重破坏了良好的代码结构,但为什么还要使用内部类呢? 因为内部类可以随意使用外部类的成员变量(包括私有)而不用生成外部类的对象,这也是内部类的唯一优点 如同心脏可以直接访问身体的血液,而不是通过医生来抽血
程序编译过后会产生两个.class文件,分别是Out.class和Out$In.class。其中$代表了上面程序中Out.In中的那个。Out.In in = new Out().new In()可以用来生成内部类的对象,这种方法存在两个小知识点需要注意:1.开头的Out是为了标明需要生成的内部类对象在哪个外部类当中。2.必须先有外部类的对象才能生成内部类的对象,因为内部类的作用就是为了访问外部类中的成员变量。
24. Java中final和static区别。
Java中的String类就是一个final类。当用final修饰一个类时,表明这个类不能被继承。要注意final类中的所有成员方法都会被隐式地指定为final方法。对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。被final修饰的引用变量一旦初始化赋值之后就不能再指向其他的对象,那么该引用变量指向的对象的内容是可变的。
在static方法内部不能调用非静态方法,反过来是可以的。static目的是,方便在没有创建对象的情况下来进行调用(方法/变量)。被static关键字修饰的方法或者变量不需要依赖于对象来进行访问,只要类被加载了,就可以通过类名去进行访问。对于静态方法来说,是没有this的,因为它不依附于任何对象,既然都没有对象,就谈不上this了。在静态方法中不能访问类的非静态成员变量和非静态成员方法,因为非静态成员方法/变量都是必须依赖具体的对象才能够被调用。在静态方法中不能访问非静态成员方法和非静态成员变量,但是在非静态成员方法中是可以访问静态成员方法/变量的。
附:经常翻java API么?最新的JDK是哪个版本?有什么新特性。
当前JDK 1.8版本。新特性如下:
1.Java 8允许我们给接口添加一个非抽象的方法实现,只需要使用 default关键字即可,这个特征又叫做扩展方法。
2.Lambda 表达式 和 Functional 接口。Lambda表达式(也称为闭包)是整个Java 8发行版中最受期待的在Java语言层面上的改变,Lambda允许把函数作为一个方法的参数(函数作为参数传递进方法中),或者把代码看成数据:函数式程序员对这一概念非常熟悉。在JVM平台上的很多语言(Groovy,Scala,……)从一开始就有Lambda,但是Java程序员不得不使用毫无新意的匿名类来代替lambda。关于Lambda设计的讨论占用了大量的时间与社区的努力。可喜的是,最终找到了一个平衡点,使得可以使用一种即简洁又紧凑的新方式来构造Lambdas。在最简单的形式中,一个lambda可以由用逗号分隔的参数列表、–>符号与函数体三部分表示。
例如:
在看实例之前,先看一个函数的使用Arrays.asList()方法的使用:
Arrays首先是一个工具类,它提供了Arrays.sort()方法.
25 。 Collection 和 Collections的区别。
Collection是集合类的上级接口,继承与他的接口主要有Set 和List.
Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。
26. HashMap和Hashtable的区别。
HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable。
HashMap允许将null作为一个entry的key或者value,而Hashtable不允许。
HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因为contains方法容易让人引起误解。
Hashtable继承自Dictionary类,而HashMap是Java1.2引进的Map interface的一个实现。
最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多个线程访问Hashtable时,不需要自己为它的方法实现同步,而HashMap 就必须为之提供外同步。
Hashtable和HashMap采用的hash/rehash算法都大概一样,所以性能不会有很大的差异。
27. sleep() 和 wait() 有什么区别?
sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。
wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。
28. Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型?
方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被"屏蔽"了。如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。
29. error和exception有什么区别?
error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。
exception 表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。
30. 同步和异步有何异同,在什么情况下分别使用他们?举例说明。
如果数据将在线程间共享。例如正在写的数据以后可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那么这些数据就是共享数据,必须进行同步存取。
当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往往更有效率。
31。 forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器,浏览器根本不知道服务器发送的内容是从哪儿来的,所以它的地址栏中还是原来的地址。
redirect就是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址,一般来说浏览器会用刚才请求的所有参数重新请求,所以session,request参数都可以获取。
23. EJB与JAVA BEAN的区别?
Java Bean 是可复用的组件,对Java Bean并没有严格的规范,理论上讲,任何一个Java类都可以是一个Bean。但通常情况下,由于Java Bean是被容器所创建(如Tomcat)的,所以Java Bean应具有一个无参的构造器,另外,通常Java Bean还要实现Serializable接口用于实现Bean的持久性。Java Bean实际上相当于微软COM模型中的本地进程内COM组件,它是不能被跨进程访问的。Enterprise Java Bean 相当于DCOM,即分布式组件。它是基于Java的远程方法调用(RMI)技术的,所以EJB可以被远程访问(跨进程、跨计算机)。但EJB必须被布署在诸如Webspere、WebLogic这样的容器中,EJB客户从不直接访问真正的EJB组件,而是通过其容器访问。EJB容器是EJB组件的代理, EJB组件由容器所创建和管理。客户通过容器来访问真正的EJB组件。
24. 说出数据连接池的工作机制是什么?
J2EE 服务器启动时会建立一定数量的池连接,并一直维持不少于此数目的池连接。客户端程序需要连接时,池驱动程序会返回一个未使用的池连接并将其表记为忙。如果当前没有空闲连接,池驱动程序就新建一定数量的连接,新建连接的数量有配置参数决定。当使用的池连接调用完成后,池驱动程序将此连接表记为空闲,其他调用就可以使用这个连接。
25.当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?
不能,一个对象的一个synchronized方法只能由一个线程访问。
26. Java中的异常处理机制的简单原理和应用。
当JAVA 程序违反了JAVA的语义规则时,JAVA虚拟机就会将发生的错误表示为一个异常。违反语义规则包括2种情况。一种是JAVA类库内置的语义检查。例如数组下标越界,会引发IndexOutOfBoundsException;访问null的对象时会引发NullPointerException。另一种情况就是JAVA允许程序员扩展这种语义检查,程序员可以创建自己的异常,并自由选择在何时用throw关键字引发异常。所有的异常都是 java.lang.Thowable的子类。
27. 垃圾回收的优点和原理。并考虑2种回收机制。
Java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再需要考虑内存管理。由于有个垃圾回收机制, Java中的对象不再有"作用域"的概念,只有对象的引用才有"作用域"。垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存。垃圾回收器通常是作为一个单独的低级别的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清楚和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收。回收机制有分代复制垃圾回收和标记垃圾回收,增量垃圾回收。
28. 请说出你所知道的线程同步的方法。
wait():使一个线程处于等待状态,并且释放所持有的对象的lock。
sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉InterruptedException异常。
notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。
Allnotity():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争。
29. 你所知道的集合类都有哪些?主要方法?
最常用的集合类是 List 和 Map。 List 的具体实现包括 ArrayList 和 Vector,它们是可变大小的列表,比较适合构建、存储和操作任何类型对象的元素列表。 List 适用于按数值索引访问元素的情形。
Map 提供了一个更通用的元素存储方法。 Map 集合类用于存储元素对(称作"键"和"值"),其中每个键映射到一个值。
30. 描述一下JVM加载class文件的原理机制?
JVM中类的装载是由ClassLoader和它的子类来实现的,Java ClassLoader 是一个重要的Java运行时系统组件。它负责在运行时查找和装入类文件的类。
31. JSP的内置对象及方法。
request表示HttpServletRequest对象。它包含了有关浏览器请求的信息,并且提供了几个用于获取cookie, header, 和session数据的有用的方法。
response表示HttpServletResponse对象,并提供了几个用于设置送回浏览器的响应的方法(如cookies,头信息等)
out对象是javax.jsp.JspWriter的一个实例,并提供了几个方法使你能用于向浏览器回送输出结果。
pageContext表示一个javax.servlet.jsp.PageContext对象。它是用于方便存取各种范围的名字空间、servlet相关的对象的API,并且包装了通用的servlet相关功能的方法。
session表示一个请求的javax.servlet.http.HttpSession对象。Session可以存贮用户的状态信息
applicaton 表示一个javax.servle.ServletContext对象。这有助于查找有关servlet引擎和servlet环境的信息
config表示一个javax.servlet.ServletConfig对象。该对象用于存取servlet实例的初始化参数。
page表示从该页面产生的一个servlet实例
31. 线程的基本概念、线程的基本状态以及状态之间的关系
线程指在程序执行过程中,能够执行程序代码的一个执行单位,每个程序至少都有一个线程,也就是程序本身。
Java中的线程有四种状态分别是:运行、就绪、挂起、结束。
32. servlet的生命周期
web容器加载servlet,生命周期开始。通过调用servlet的init()方法进行servlet的初始化。通过调用service()方法实现,根据请求的不同调用不同的do***()方法。结束服务,web容器调用servlet的destroy()方法。
http://www.aliyun.com/zixun/content/3_12_523694.html
http://wenku.baidu.com/link?url=tpivQbMVCwLtk8r24ggl7hcF-gXQ5-bTKrnYcMnYenvu-b7ylUBodmuZ0H52xVeN1KHNk0ciHygy0sshINcAxqCb4T19laxjUZ_npHZ6SSK
http://blog.csdn.net/sunshinesir/article/details/8221509
Java框架篇
1. Ajax实现机制。
Ajax是异步通讯,所谓的异步是指再不刷新页面的情况下与后台进行的一次通信。它的技术实现原理通过内置的XmlHttpRequest发送请求,相当于有一个小浏览器在你不知情的情况下发送了一个小请求,从服务器获取数据,通过javascript处理返回值来更新页面上的东西。
2. Servlet线程安全么?周期呢?
Servlet容器默认采用单实例多线程的方式来处理请求,默认是非线程安全的。Servlet容器如何同时来处理多个请求,Servlet采用多线程来处理多个请求同时访问。servlet依赖于一个线程池来服务请求。线程池实际上是一系列的工作者线程集合。Servlet使用一个调度线程来管理工作者线程. 当容器收到一个Servlet请求,调度线程从线程池中选出一个工作者线程,将请求传递给该工作者线程,然后由该线程来执行Servlet的 service方法。当这个线程正在执行的时候,容器收到另外一个请求,调度线程同样从线程池中选出另一个工作者线程来服务新的请求,容器并不关心这个请求是否访问的是同一个Servlet.当容器同时收到对同一个Servlet的多个请求的时候,那么这个Servlet的service()方法将在多线程中并发执行。 Servlet容器默认采用单实例多线程的方式来处理请求,这样减少产生Servlet实例的开销,提升了对请求的响应时间,对于Tomcat可以在server.xml中通过<Connector>元素设置线程池中线程的数目。 就实现来说: 调度者线程类所担负的责任如其名字,该类的责任是调度线程,只需要利用自己的属性完成自己的责任。所以该类是承担了责任的,并且该类的责任又集中到唯一的单体对象中。而其他对象又依赖于该特定对象所承担的责任,我们就需要得到该特定对象。那该类就是一个单例模式的实现了。
3.
Hibernate为什么优于JDBC。
Hibernate一级缓存和二级缓存。
Servlet生命周期。
session是怎么实现的?存储在哪里? http://blog.csdn.net/zhq426/article/details/2992488
说说你认识的设计模式。及常见的应用场景。
http://zhidao.baidu.com/link?url=wTRk2ft-_lOZCHKiGp8_Wu2pi1pqUJC5GFwFVzpy1qmqZsGS5UkyllRaE0G-wlrKTMl4CYJ5rvOwINFqULoA_q
+杂题
6. SpringMVC常常用的注解
// 常用注解总结
1. @Controller , 标注在控制层。@Service 常标注在业务层,用于标志业务逻辑。@Repository 标注在持久层,即dao。用于标注数据访问。
2. @RequestMapping , 同上标注在类定义出,将Controller和特定请求关联起来。
3. @PathVariable , 该注解绑定它传过来的值到方法的参数上。
4. @Autowired, Java web的实体类属性中使用注解@Autowired之后, 不需要再写getter和setter方法,spring会自动注入。
数据结构篇
6.
设计模式篇
1. 静态代理模式,及其应用场景。
2. Spring中用到的设计模式。
http://www.360doc.com/content/13/0116/13/11261516_260506834.shtml
3.
SQL常用命令研究
1. 先来一个基础复习,SQL语句基础
// 先来几组约定:
1. sql语句不区分大小写,但涉及到表名 字段名的时候要对应起来。
2. 数据库名约定为DBName 表名约定为tableName 列名约定为columnName
1. create database DBName;
2. drop database DBName;
3. creat table tableName (id varchar(20) primary key, idCard varchar(18), address varchar(100))
4. drop table tableName
5. Alter table tableName add column columnName varchar(10)
6. select * from tableName where
7. insert into tableName(id,age) values(11,28)
8. delete from table where
9. update tableName set id=12 where
10. select * from tableName where name like '%李%'
11. select * from tableName order by id, age[des]
12. select count as totalCount from tableName //总数
2.数据库中group by和having区别
having 和where 都是用来筛选用的 having 是筛选组 而where是筛选记录; 当分组筛选的时候用having, 其他的情况用where。
使用having,就一定要与group by连用. 用group by不一定要用having,它只是当需要在组内筛选的时候用的.
项目篇
1.