java面试集锦整理

 

一.        面向对象的特性

1.      面向对象的特征

   继承:通过子类可以实现继承,子类继承父类的所有状态和行为,同时添加自身的状态和行为。

   封装:将代码及处理数据绑定在一起的一种编程机制,该机制保证程序和数据不受外部干扰。

   多态:包括重载和重写。重载为编译时多态,重写是运行时多态。重载必须是同类中名称相同参数不同(包括个数不同和类型不同),但返回类型不同不构成重载;重写发生于子类对父类的覆盖,子类继承父类方法名相同、参数列表相同、返回类型相同才构成重写。

2.      类、对象的概念:

   类:具有共同属性和行为的对象的抽象。类是创建对象的模板。

   对象:现实世界中的实体。在计算机中,是指可标识的存储区域。

   类是对象的抽象、对象是类的实例。

3.      接口与抽象类:

   抽象:是从特定的实例中抽取共同性质形成一般化概念的过程。

   接口和抽象类都用于抽象,接口是抽象类的抽象。

   接口中只有方法声明,没有实现(无方法体);在接口中声明的方法具有public和abstract属性,一个类可以实现多个接口(即多继承),接口以‘,’分隔;接口中的方法必须全部实现。

   抽象类可以有部分方法实现,抽象类必须通过继承才能使用。

4.      内部类(Inner Class)

   内部类是嵌套在另一个类中的类。

   内部类用于名称隐藏和程序代码的组织,另外内部类拥有直接访问其外部类所有成员(包括private的)的权限(无需任何关键字修饰)。

   内部类不可以在其他类或main方法里实例化,必须使用如下方法(非静态内部类)

   外部类.内部类 对象名=new 外部类().new 内部类();

   静态内部类调用方式:

   外部类.内部类 对象名=new 外部类.内部类();

   非静态内部类不可以声明静态成员;静态内部类的非静态成员可以访问其外部类的静态成员,声明为静态的成员不可以访问外部的非静态成员。

5.      访问修饰符限制

   Private protected friendly(default) public

   同类 Y Y Y Y

   同包不同类 N Y Y Y

   同包子类 N Y Y Y

   不同包不同类 N N N Y

   不同包子类 N Y N Y

6.      Static关键字的使用

   类成员,直接使用 类名.成员 调用。

   静态方法只能访问静态成员。

   静态方法不能使用this、super关键字。

   静态方法不能被非静态方法重写或重载。

7.      final关键字:

   被final修饰的变量为常量不能改变。

   被final修饰的方法不可以重写。

   被final修饰的类不能被继承。

8.      abstract关键字

   被abstract修饰的类不能实例化。

   被abstract修饰的方法只能在子类中实现。

9.      native关键字

   非Java语言的编写,例如JNI技术。

10.   synchronized关键字

   多线程的同步访问控制。

11.   简述UML中类的关系

   当一个类是“一种”另一个类时:is-a关系

   当两个类之间有关联时:

   一个类“包含”另一个类:has-a关系

   一个类“使用”另一个类

   还可以细分有聚合和组合(UML宝典)或聚集和组成(包括国内某些知名学术团体都这么说)。

   聚集(aggregation)表示整体与各部分之间的关系。例如汽车与轮胎,没有了汽车轮胎依然是一个整体。(用空心菱形表示)

   组成是一种整体和部分所属更强的聚集关系,每个部分只能属于一个整体,没有整体部分也就没有存在的价值。比如桌子和桌腿,没有桌子也就没有桌腿的价值了。(用实心菱形表示)

12.   设计模式

  一个设计模式描述了一个被证实可行的方案。这些方案非常普遍,是具有完整定义的最常用的模式。一般模式有4个基本要素:模式名称(pattern name)、问题(problem)、解决方案(solution)、效果(consequences)。常见23种模式概述:

   抽象工厂模式(Abstract Factory):提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

   适配器模式(Adapter):将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的类可以一起工作。

   桥梁模式(Bridge):将抽象部分与它的实现部分分离,使它们都可以独立地变化。

   建造模式(Builder):将一个复杂对象的构建与它的表示分离,使同样的构建过程可以创建不同的表示。

   责任链模式(Chain of Responsibility):为解除请求的发送者和接收者之间耦合,而使多个对象都有机会处理这个请求。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它。

   命令模式(Command):将一个请求封装为一个对象,从而可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可取消的操作。

   合成模式(Composite):将对象组合成树形结构以表示“部分-整体”的层次结构。它使得客户对单个对象和复合对象的使用具有一致性。

   装饰模式(Decorator):动态地给一个对象添加一些额外的职责。就扩展功能而言,它能生成子类的方式更为灵活。

   门面模式(Facade):为子系统中的一组接口提供一个一致的界面,门面模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

   工厂方法(Factory Method):定义一个用于创建对象的接口,让子类决定将哪一个类实例化。Factory Method 使一个类的实例化延迟到其子类。

   享元模式(Flyweight):运用共享技术以有效地支持大量细粒度的对象。

   解释器模式(Interpreter):给定一个语言,定义它的语法的一种表示,并定义一个解释器,该解释器使用该表示解释语言中的句子。

   迭代子模式(Iterator):提供一种方法顺序访问一个聚合对象中的各个元素,而又不需暴露该对象的内部表示。

   调停者模式(Mediator):用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式的内部表示。

   备忘录模式(Memento):在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到保存的状态。

   观察者模式(Observer):定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动刷新。

   原始模型模式(Prototype):用原型实例指定创建对象的种类,并且通过拷贝这个原型创建新的对象。

   代理模式(Proxy):为其他对象提供一个代理以控制对这个对象的访问。

   单例模式(Singleton):保证一个类仅有一个实例,并提供一个访问它的全局访问点。

   状态模式(State):允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它所属的类。

   策略模式(Strategy):定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法的变化可独立于使用它的客户。

   模板模式(Template Method):定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

   访问者模式(Visitor):表示一个作用于某对象结构中的各元素的操作。该模式可以实现在不改变各元素的类的前提下定义作用于这些元素的新操作。

二.        JAVA概念

1.      什么是 J2EE

   J2EE是Sun公司提出的多层(multi-diered),分布式(distributed),基于组件(component-base)的企业级应用模型(enterpriese application model).在这样的一个应用系统中,可按照功能划分为不同的组件,这些组件又可在不同计算机上,并且处于相应的层次(tier)中。所属层次包括客户层(clietn tier)组件,web层和组件,Business层和组件,企业信息系统(EIS)层。

2.      分类列举服务器和组件技术

   服务器端技术:Jsp、Servlet;

   组件技术:JavaBean、EJB。

3.      Anonymous Inner Class (匿名内部类) 

   匿名的内部类是没有名字的内部类。不能继承其它类,但可作为一个接口,由另一个内部类实现。

4.      Static Nested Class 和 Inner Class的不同。

   Nested Class (一般是C++的说法),Inner Class (一般是JAVA的说法)。Java内部类与C++嵌套类最大的不同就在于是否有指向外部的引用上。

   注:静态内部类(Inner Class)意味着:

l   创建一个static内部类的对象

l   不能从一个static内部类的一个对象访问一个外部类对象

5.      Http与Https

   Https即多了安全的Http,s(Security Socket Layer)指加密套接字协议层(简写SSL)。

6.      OSI(Open System Interconnection)网络抽象模型

   由国际标准化组织(ISO)提出。

   将互联网分为七层,从下至上分别为:物理层(physical)、数据链路层(data link)、网络层(network)、传送层(transport)、会话层(session)、表示层(presentation)、应用层(application)。底层通过提供接口支持上层功能。各层详解:

   物理层:LAN/ATM,为硬件层。

   数据链路层:LAN/ATM

   网络层:IP协议,IOS

   传输层:TCP/UDP协议,支持Java Socket。

   会话层:

   表示层:HTML、XML

   应用层:HTTP协议,使用Java Servlet/JSP

   <第八层(Web服务层):SOAP/UDDI>

7.      J2EE的容器与服务器

   容器负责EJB组件中生命周期的控制;

   服务器包含在容器外,提供系统级操作底层服务,包括事务、事件、多线程……。

8.      继承限制

   父类对象不可以赋给子类对象,因为子类可能具有更多的成员,反之可以。

9.      列举常见集合框架类型

   List、Set、Map。由这三个接口实现出ArrayList、LinkedList、HashSet、TreeSet、HashMap、TreeMap等常用集合框架。

   Vector属于重量级组件不推荐使用。

   Map类型维护键/值对,Hashtable与HashMap相近但效率略低于HashMap、高于TreeMap,TreeMap优点是可以排序。

   Set类型可装入唯一值,HashSet效率高于TreeSet但TreeSet可以维护内部元素的排序状态。

   List类型可按某种特定顺序维护元素。ArrayList允许快速随机访问,但如果添加或删除位于中间的元素时效率很低;LikedList提供最佳循序访问及快速的中间位置添加删除元素,并有addFirst、addLast、getFirst、getLast、removeFirst、 removeLast方法。

10.    ArrayList与Vector区别

   同步性:Vector是线程安全的,也就是说是同步的,而ArrayList是线程序不安全的,不是同步的 

   数据增长:当需要增长时,Vector默认增长为原来一培,而ArrayList却是原来的一半 

11.   HashMap与HashTable区别 

   都属于Map接口的类,实现了将惟一键映射到特定的值上。

   历史原因:Hashtable是基于陈旧的Dictionary类的,HashMap是Java 1.2引进的Map接口的一个实现。

   同步性:Hashtable是线程安全的,也就是说是同步的,它也比 HashMap 慢,而HashMap是线程序不安全的,不是同步的。

   HashMap 类允许一个 null 键和多个 null 值。

   Hashtable 类不允许 null 键和 null 值。

12.   String与StringBuffer以及StringBuilder的区别

   String类型和StringBuffer、StringBuilder类型的主要性能区别其实在于 String是不可变的对象,而后俩者都是可变的。 

   StringBuffer和StringBuilder的Append实现都是调用父类实现的。唯一不同的是 StringBuffer是线程安全的,方法中多了synchronized,而StringBuilder 是非线程安全的。

13.   Collection 和 Collections的区别

   Collections是个java.util下的类,它包含有各种有关集合操作的静态方法。

   Collection是个java.util下的接口,它是各种集合结构的父接口。

14.   char型变量中能否存储中文汉字

   能,因为java中以unicode编码,一个char占16个字节,因此,存放一个中文是没有问题的。

15.   String s = new String("xyz"); 创建了几个String Object?

   两个对象,一个是String类型的“xyx”,一个是指向“xyx”的引用对象s。

16.  是否可以继承String类?

   String类是final类故不可以继承。

17.   当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?

   不能,一个对象的一个synchronized方法只能由一个线程访问。

18.   Math.round(11.5)=? ,  Math.round(-11.5)=?

   Math.round(11.5)返回(long)12

   Math.round(-11.5)返回(long)-11;

19.   abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized?

   都不能

20.   接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承实体类(concrete class)?

   接口可以继承接口。抽象类可以实现(implements)接口,抽象类可以继承实体类,但前提是实体类必须有明确的构造函数。

21.   &和&&的区别

   &是位运算符。

   &&是布尔逻辑运算符。

22.   Java缓存两种方式

   文件缓存,是指把数据存储在磁盘上,可以XML格式,也可以序列化文件DAT格式还是其它文件格式。 

   内存缓存,也就是实现一个类中静态Map,对这个Map进行常规的增删查。

23.   Java对象的强、软、弱和虚引用

   在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象。也就是说,只有对象处于可触及(reachable)状态,程序才能使用它。从JDK 1.2版本开始,把对象的引用分为4种级别,从而使程序能更加灵活地控制对象的生命周期。这4种级别由高到低依次为:强引用、软引用、弱引用和虚引用。

   强引用(StrongReference):是使用最普遍的引用。如果一个对象具有强引用,那垃圾回收器绝不会回收它。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。

   软引用(SoftReference):如果一个对象只具有软引用,则内存空间足够,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存。软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收器回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。

   弱引用(WeakReference):弱引用与软引用的区别在于:只具有弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。不过,由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象。弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。

   虚引用(PhantomReference):顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。虚引用主要用来跟踪对象被垃圾回收器回收的活动。虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列(ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之 关联的引用队列中。程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。如果程序发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。

24.   什么时候用assert

   断言是一个包含布尔表达式的语句,在执行这个语句时假定该表达式为 true。如果表达式计算为 false,那么系统会报告一个 AssertionError。示例:

   assert(a > 0); // throws an AssertionError if a <= 0

   断言可以有两种形式:

   assert Expression1 ;

   assert Expression1 : Expression2 ;

   Expression1 应该总是产生一个布尔值。

   Expression2 可以是得出一个值的任意表达式。这个值用于生成显示更多调试信息的 String 消息。

   断言在默认情况下是禁用的。要在编译时启用断言,需要使用 source 1.4 标记:

   javac -source 1.4 Test.java

   要在运行时启用断言,可使用 -enableassertions 或者 -ea 标记。

   要在运行时选择禁用断言,可使用 -da 或者 -disableassertions 标记。

   要系统类中启用断言,可使用 -esa 或者 -dsa 标记。还可以在包的基础上启用或者禁用断言。

   可以在预计正常情况下不会到达的任何位置上放置断言。断言可以用于验证传递给私有方法的参数。不过,断言不应该用于验证传递给公有方法的参数,因为不管是否启用了断言,公有方法都必须检查其参数。不过,既可以在公有方法中,也可以在非公有方法中利用断言测试后置条件。另外,断言不应该以任何方式改变程序的状态。

25.   多线程以及同步的实现

   多线程有两种实现方法,分别是继承Thread类与实现Runnable接口 

   同步的实现方面有两种,分别是synchronized,wait与notify

26.   Java垃圾回收机制

   Java的垃圾回收机制是Java虚拟机提供的能力,用于在空闲时间以不定时的方式动态回收无任何引用的对象占据的内存空间。

   需要注意的是:垃圾回收的是无任何引用的对象占据的内存空间而不是对象本身。

   显示通知JVM进行垃圾回收:

System.gc()

Runtime.getRuntime().gc() 

    上面的方法调用时用于显式通知JVM可以进行一次垃圾回收,但真正垃圾回收机制具体在什么时间点开始发生动作这同样是不可预料的,这和抢占式的线程在发生作用时的原理一样。

27.   Java中判断int, float的值是否相等

   int:a == b;

   float:a – b < 0.000001f;

28.   编程题: 用最有效率的方法算出2乘以8等於几?

   位运算符计算:2《3 = 8

29.   当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?

   Java 编程语言只有值传递。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。对象的内容可以在被调用的方法中改变,但对象的引用是永远不会改变的。

   这里的内存模型涉及到两种类型的内存:栈内存(stack)和堆内存(heap)。传递的是栈内存中的数据。

30.   swtich是否能作用在byte上,是否能作用在long上,是否能作用在String上?

   switch(expr1)中,expr1是一个整数表达式,因此传递给 switch 和 case 语句的参数应该是 int、 short、 char 或者byte。

   long,string 都不能作用于swtich。

31.   final, finally, finalize的区别

   final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。如果一个类被声明为final,意味着它不能再派生出新的子类,因此一个类不能既被声明为 abstract的,又被声明为final的。将变量或方法声明为final,可以保证它们在使用中不被改变。被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改。被声明为final的方法也同样只能使用,不能重载。内部类要访问局部变量,局部变量必须定义成final类型,例如,一段代码……

   finally是异常处理语句结构的一部分,表示总是执行。

   finalize是Object类的一个方法,因此所有的类都继承了它,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。JVM不保证此方法总被调用

32.   运行时异常与一般异常异同

   运行异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误。

   java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。

33.   error和exception的区别

   error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。

   exception 表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。

34.   Java中的异常处理机制的简单原理和应用

   异常是指java程序运行时(非编译)所发生的非正常情况或错误,与现实生活中的事件很相似,现实生活中的事件可以包含事件发生的时间、地点、人物、情节等信息,可以用一个对象来表示,Java使用面向对象的方式来处理异常,它把程序中发生的每个异常也都分别封装到一个对象来表示的,该对象中包含有异常的信息。

   Java对异常进行了分类,不同类型的异常分别用不同的Java类表示,所有异常的根类为java.lang.Throwable,Throwable下面又派生了两个子类:Error和Exception,Error 表示应用程序本身无法克服和恢复的一种严重问题,程序只有死的份了,例如,说内存溢出和线程死锁等系统问题。Exception表示程序还能够克服和恢复的问题,其中又分为系统异常和普通异常,系统异常是软件本身缺陷所导致的问题,也就是软件开发人员考虑不周所导致的问题,软件使用者无法克服和恢复这种问题,但在这种问题下还可以让软件系统继续运行或者让软件死掉,例如,数组脚本越界(ArrayIndexOutOfBoundsException),空指针异常(NullPointerException)、类转换异常(ClassCastException);普通异常是运行环境的变化或异常所导致的问题,是用户能够克服的问题,例如,网络断线,硬盘空间不够,发生这样的异常后,程序不应该死掉。

   java为系统异常和普通异常提供了不同的解决方案,编译器强制普通异常必须try..catch处理或用throws声明继续抛给上层调用方法处理,所以普通异常也称为checked异常,而系统异常可以处理也可以不处理,所以,编译器不强制用try..catch处理或用throws声明,所以系统异常也称为unchecked异常。

    提示答题者:就按照三个级别去思考:虚拟机必须宕机的错误,程序可以死掉也可以不死掉的错误,程序不应该死掉的错误;

35.   写出你最常见到的5个runtime exception

   这道题主要考你的代码量到底多大,如果你长期写代码的,应该经常都看到过一些系统方面的异常,你不一定真要回答出5个具体的系统异常,但你要能够说出什么是系统异常,以及几个系统异常就可以了,当然,这些异常完全用其英文名称来写是最好的,如果实在写不出,那就用中文吧,有总比没有强!

   所谓系统异常,就是…..,它们都是RuntimeException的子类,在jdk doc中查RuntimeException类,就可以看到其所有的子类列表,也就是看到了所有的系统异常。我比较有印象的系统异常有:NullPointerException、ArrayIndexOutOfBoundsException、ClassCastException。

36.   JAVA语言如何进行异常处理

   Java 通过面向对象的方法进行异常处理,把各种不同的异常进行分类,并提供了良好的接口。在 Java 中,每个异常都是一个对象,它是 Throwable 类或其它子类的实例。当一个方法出现异常后便抛出一个异常对象,该对象中包含有异常信息,调用这个对象的方法可以捕获到这个异常并进行处理。Java 的异常处理是通过 5 个关键词来实现的:try、catch、throw、throws 和 finally。一

   般情况下是用 try 来执行一段程序,如果出现异常,系统会抛出(throws)一个异常,这时候你可以通过它的类型来捕捉(catch)它,或最后(finally)由缺省处理器来处理;

    try 用来指定一块预防所有“异常”的程序;

    catch 子句紧跟在 try 块后面,用来指定你想要捕捉的“异常”的类型;

    throw 语句用来明确地抛出一个“异常”;

    throws 用来标明一个成员函数可能抛出的各种“异常”;

    Finally 为确保一段代码不管发生什么“异常”都被执行一段代码;

    可以在一个成员函数调用的外面写一个 try 语句,    在这个成员函数内部写另一个 try 语句保护其他代码。每当遇到一个 try 语句,“异常”的框架就放到堆栈上面,直到所有的 try 语句都完成。如果下一级的 try 语句没有对某种“异常”进行处理,堆栈就会展开,直到遇到有处理这种“异常”的 try 语句。

37.   Web Service名词解释

   Web Service描述语言WSDL SOAP即简单对象访问协议(Simple Object Access Protocol),它是用于交换XML编码信息的轻量级协议。 

   UDDI 的目的是为电子商务建立标准;UDDI是一套基于Web的、分布式的、为Web Service提供的、信息注册中心的实现标准规范,同时也包含一组使企业能将自身提供的Web Service注册,以使别的企业能够发现的访问协议的实现标准。

38.   Java命名规范

   必须以英文字母、下划线(’_’)或’$’开始,其余可以有数字但不允许 包含空格,且组合后的名称不能是Java关键字或保留字。

   匈牙利命名法:以m开始为类成员变量,以g开始为全局变量,以v开始为本地局部变量,常量命名一般不以下划线、美元符开始。

   驼峰命名:一般称由多个单词或缩写组成的变量名,并且该变量名每个单词首字母均为大写(一般类名全部首字母大写,方法或属性名第一个字母小写)的称为驼峰命名。

39.   线程中的Run和Start方法

    用start方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码。通过调用Thread类的start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦得到spu时间片,就开始执行run()方法,这里方法run()称为线程体,它包含了要执行的这个线程的内容,Run方法运行结束,此线程随即终止。

   run()方法只是类的一个普通方法而已,如果直接调用Run方法,程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码,这样就没有达到写线程的目的。

40.   Java创建多线程程序的方法

   通过创建Thread类的子类来实现

l   设计Thread的子类

l   根据工作需要重新设计线程的run方法

l   线程类Thread中提供的run是一个空方法。为此,我们可以继承Thread,然后覆盖(override)其中的run,使得该线程能够完成特定的工作。

l   使用start方法启动线程,将执行权转交到run。

   通过实现Runable接口的类来实现(推荐)

l   创建某个类实现Runnable接口,实现run()方法。

l   创建Thread对象,用实现Runnable接口的对象作为参数实例化该Thread对象。

l   调用Thread的start方法。

41.   try{}中有return语句,那么紧跟在这个try后的finally {}里的code何时执行

   会执行,在return前执行。

 1 public  class Test {
 2 
 3          public static void main(String[] args) {
 4 
 5                    System.out.println(new Test().test());
 6 
 7          }
 8 
 9          static int test(){
10 
11                    int x = 1;
12 
13                    Try{
14 
15                             return x;
16 
17                   }Finally{
18 
19                             ++x;
20 
21                    }
22 
23          }
24 
25 }
View Code

输出结果 1

 1 public class  smallT{
 2 
 3      public static void main(String args[]){
 4 
 5                    smallT t  = new  smallT();
 6 
 7                    int  b  =  t.get();
 8 
 9                    System.out.println(b);
10 
11          }
12 
13          Public  int  get(){
14 
15                    Try{
16 
17                             return 1 ;
18 
19                    }Finally{
20 
21                             return 2 ;
22 
23                    }
24 
25          }
26 
27 }
View Code

输出结果 2

42.   Singleton实现对比              

  

三.        框架的理解与运用

1.      Hibernate框架相关

Ø  Hibernate总览

    SessionFactory (net.sf.hibernate.SessionFactory):对编译过的映射文件的一个线程安全的,不可变的缓存快照。它是Session的工厂。是ConnectionProvider的客户。

   可能持有事务之间重用的数据的缓存。

l   会话,Session (net.sf.hibernate.Session) 单线程,生命期短促的对象,代表应用程序和持久化层之间的一次对话。封装了一个JDBC连接。也是Transaction的工厂。

   持有持久化对象的缓存。

l   持久化对象(Persistent Object)及其集合(Collection):生命期短促的单线程的对象,包含了持久化状态和商业功能。它们可能是普通的JavaBeans,唯一特别的是他们现在从属于且仅从属于一个Session。

l   临时对象(Transient Object)及其集合(Collection) :目前没有从属于一个Session的持久化类的实例。他们可能是刚刚被程序实例化,还没有来得及被持久化,或者是被一个已经关闭的Session所实例化的。

l   事务,Transaction (net.sf.hibernate.Transaction):(可选) 单线程,生命期短促的对象,应用程序用它来表示一批工作的原子操作。是底层的JDBC,JTA或者CORBA事务的抽象。一个Session可能跨越多个Transaction 事务。

l   ConnectionProvider (net.sf.hibernate.connection.ConnectionProvider):(可选)JDBC连接的工厂和池。从底层的Datasource或者 DriverManager抽象而来。对应用程序不可见。

l   TransactionFactory (net.sf.hibernate.TransactionFactory):(可选)事务实例的工厂。对应用程序不可见。

   在上面的轻型结构中,程序没有使用Transaction / TransactionFactory 或者ConnectionProvider API,直接和JTA/JDBC对话了。

Ø  Hibernate持久化对象标识(Persistent Object Identity )

   应用程序可能同时在两个不同的session中存取同一个持久化对象。然而,两个Session实例是不可能共享一个持久化类的实例的。有两种不同的用来辨别对象是否相同的方法。

   Persistent Identity,持久化辨别

   foo.getId().equals( bar.getId() )

   JVM Identity, JVM辨别

   foo==bar

   对于同一个特定的Session返回的对象来说,这二者是等价的。然而,当程序并行在两个不同的session中访问含义上“相同”(持久化辨别)的商业对象时,两个对象实例从JVM的角度上来看却是“不同”的(JVM辨别)

   这种方式把并行访问(应用程序不需要对任何商业对象进行同步,只要求遵循每个Session一个线程的原则)和对象辨别(在应用程序的一个session之中,可以安全的用==来比较对象)的难题留给了Hibernate和数据库。

Ø  Hibernate工作原理

   读取并解析配置文件

   读取并解析映射信息,创建SessionFactory

   打开Session

   创建事务Transation

   持久化操作

   提交事务

   关闭Session

   关闭SesstionFactory

Ø  Hibernate优点

   对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码。

   Hibernate是一个基于JDBC的主流持久化框架,是一个优秀的ORM实现。他很大程度的简化DAO层的编码工作。

   大多数 EJB CMP CMR 解决方案使用代码生成实现持久性代码,而 JDO 使用字节码修饰。与之相反,Hibernate 使用反射和运行时字节码生成,使它对于最终用户几乎是透明的 hibernate使用Java反射机制,而不是字节码增强程序来实现透明性。

   Hibernate的性能非常好,因为它是个轻量级框架。映射的灵活性很出色。它支持各种关系数据库,从一对一到多对多的各种复杂关系。

Ø  Hibernate如何延迟加载

   Hibernate2延迟加载实现:a)实体对象 b)集合(Collection)

   Hibernate3 提供了属性的延迟加载功能 当Hibernate在查询数据的时候,数据并没有存在与内存中,当程序真正对数据的操作时,对象才存在与内存中,就实现了延迟加载,他节省了服务器的内存开销,从而提高了服务器的性能。 

Ø  Hibernate中怎样实现类之间的关系(如:一对多、多对多的关系)

   类与类之间的关系主要体现在表与表之间的关系进行操作,它们都市对对象进行操作,我们程序中把所有的表与类都映射在一起,它们通过配置文件中的many-to-one、one-to-many、many-to-many

2.      Spring框架相关

Ø  Spring总览

    Core包是框架的最基础部分, 并提供依赖注入(Dependency Injection)特性来使你可管理Bean容器功能。 这里的基础概念是BeanFactory,它提供Factory模式来消除对程序性单例的需要, 并允许你从程序逻辑中分离出依赖关系的配置和描述。

   构建于Beans包上Context包,提供了一种框架式的Bean访问方式, 有些象JNDI注册。Context包的特性得自Beans包,并添加了文本消息的发送,通过比如资源串, 事件传播,资源装载的方式和Context的透明创建,如通过Servlet容器。

   DAO包提供了JDBC的抽象层,它可消除冗长的JDBC编码和解析数据库厂商特有的错误代码。 该包也提供了一种方法实现编程性和声明性事务管理,不仅仅是针对实现特定接口的类, 而且对所有的POJO。

   ORM包为流行的关系-对象映射APIs提供了集成层,包括JDO,Hibernate和iBatis。 通过ORM包,你可与所有Spring提供的其他特性相结合来使用这些对象/关系映射, 如前边提到的简单声明性事务管理。

   Spring的AOP包提供与AOP联盟兼容的面向方面编程实现,允许你定义, 如方法拦截器和切点,来干净地给从逻辑上说应该被分离的功能实现代码解耦。 使用源码级的元数据

   功能,你可将各种行为信息合并到你的代码中,有点象.Net的attribute。

   Spring的Web包提供了基本的面向Web的综合特性,如Multipart功能, 使用Servlet监听器的Context的初始化和面向Web的Applicatin Context。 当与WebWork或Struts一起使用Spring时,这个包使Spring可与其他框架结合。

   Spring的Web MVC包提供了面向Web应用的Model-View-Controller实现。 Spring的MVC实现不仅仅是一种实现,它提供了一种domain model代码和web form的清晰分离, 这使你可使用Spring框架的所有其他特性,如校验.

Ø  Spring概念

   Spring是一个集成了许多第三方框架的大杂烩,其核心技术是IOC(控制反转,也称依赖注入)和AOP(面向切面编程)。

   简单地说,AOP 让开发人员可以创建非行为性的关注点,称为横切关注点,并将它们插入到应用程序代码中。使用 AOP 后,公共服务(比如日志、持久性、事务等)就可以分解成方面并应用到域对象上,同时不会增加域对象的对象模型的复杂性。

   IOC 允许创建一个可以构造对象的应用环境,然后向这些对象传递它们的协作对象。正如单词“倒置”所表明的,IOC 就像反过来的JNDI。没有使用一堆抽象工厂、服务定位器、单元素(singleton)和直接构造(straight construction),每一个对象都是用其协作对象构造的。因此是由容器管理协作对象(collaborator)。

   Spring既是一个AOP框架,也是一个IOC容器。 Spring 最好的地方是它有助于您替换对象。有了Spring,只要用 JavaBean 属性和配置文件加入依赖性(协作对象)。然后可以很容易地在需要时替换具有类似接口的协作对象。

   Spring中I0C的三种实现机制:通过setter方法注入、通过构造方法注入和接口注入。

3.      Spring IOC与Hibernate配置

  

四.        JSP运用

1.      JSP的内置对象及作用

   JSP共有以下9种基本内置组件(可与ASP的6种内部组件相对应): 

   request 用户端请求,此请求会包含来自GET/POST请求的参数 

   response 网页传回用户端的回应 

   pageContext 网页的属性是在这里管理 

   session 与请求有关的会话期 

   application servlet 正在执行的内容 

   out 用来传送回应的输出 

   config servlet的构架部件 

   page JSP网页本身 

   exception 针对错误网页,未捕捉的例外

2.      JSP常用的方法及作用

   JSP共有以下6种基本动作 

   jsp:include:在页面被请求的时候引入一个文件。 

   jsp:useBean:寻找或者实例化一个JavaBean。 

   jsp:setProperty:设置JavaBean的属性。 

   jsp:getProperty:输出某个JavaBean的属性。 

   jsp:forward:把请求转到一个新的页面。 

   jsp:plugin:根据浏览器类型为Java插件生成OBJECT或EMBED标记

3.      JSP中动态INCLUDE与静态INCLUDE的区别

   动态INCLUDE用jsp:include动作实现 

   它总是会检查所含文件中的变化,适合用于包含动态页面,并且可以带参数 

   静态INCLUDE用include伪码实现,定不会检查所含文件的变化,适用于包含静态页面 

   <%@ include file="included.htm" %>

4.      JSP两种跳转方式

   有两种,分别为: 

    

    

   前者页面不会转向include所指的页面,只是显示该页的结果,主页面还是原来的页面。执行完后还会回来,相当于函数调用。并且可以带参数.后者完全转向新页面,不会再回来。相当于go to 语句。

五.        Servlet相关

1.      Servlet的生命周期?

   servlet有良好的生存期的定义,包括加载和实例化、初始化、处理请求以及服务结束。

   这个生存期由javax.servlet.Servlet接口的init,service和destroy方法表达。

2.      JAVA Servlet API中forward()与redirect()的区别

   前者仅是容器中控制权的转向,在客户端浏览器地址栏中不会显示出转向后的地址;

   后者则是完全的跳转,浏览器将会得到跳转的地址,并重新发送请求链接。

   这样,从浏览器的地址栏中可以看到跳转后的链接地址。所以,前者更加高效,在前者可以满足需要时,尽量使用forward()方法,并且,这样也有助于隐藏实际的链接。在有些情况下,比如,需要跳转到一个其它服务器上的资源,则必须使用sendRedirect()方法。

3.      Servlet的基本架构 

 1 public class ServletName extends HttpServlet { 
 2 
 3 public void doPost(HttpServletRequest request, HttpServletResponse response) throws 
 4 
 5 ServletException, IOException { 
 6 
 7 } 
 8 
 9 public void doGet(HttpServletRequest request, HttpServletResponse response) throws 
10 
11 ServletException, IOException { 
12 
13 } 
14 
15 }
View Code

 

六.        数据库

1.      MySQL相关

Ø  MYSQL支持事务吗? 

   在缺省模式下,MYSQL是autocommit模式的,所有的数据库更新操作都会即时提交,所以在缺省情况下,mysql是不支持事务的。 

但是如果你的MYSQL表类型是使用InnoDB Tables 或 BDB tables的话,你的MYSQL就可以使用事务处理,使用SET AUTOCOMMIT=0就可以使MYSQL允许在非autocommit模式, 在非autocommit模式下,你必须使用COMMIT来提交你的更改,或者用ROLLBACK来回滚你的更改。 示例如下: 

START TRANSACTION; 

SELECT @A:=SUM(salary) FROM table1 WHERE type=1; 

UPDATE table2 SET summmary=@A WHERE type=1; 

COMMIT;

Ø  MYSQL相比于其他数据库有哪些特点? 

   MySQL是一个小型关系型数据库管理系统,开发者为瑞典MySQL AB公司,现在已经 被Sun公司收购,支持FreeBSD、Linux、MAC、Windows等多种操作系统 与其他的大型数据库例如Oracle、DB2、SQL Server等相比功能稍弱一些 

l   可以处理拥有上千万条记录的大型数据 

l   支持常见的SQL语句规范 

l   可移植行高,安装简单小巧 

l   良好的运行效率,有丰富信息的网络支持 

l   调试、管理,优化简单(相对其他大型数据库)

Ø  如何提高MySql的安全性? 

   如果MYSQL客户端和服务器端的连接需要跨越并通过不可信任的网络,那么需要使用ssh隧道来加密该连接的通信。 

   使用set password语句来修改用户的密码,先“mysql -u root”登陆数据库系统,然后“mysql> update mysql.user set password=password(’newpwd’)”,最后执行“flush privileges”就可以了。 

   Mysql需要提防的攻击有,防偷听、篡改、回放、拒绝服务等,不涉及可用性和容错方面。对所有的连接、查询、其他操作使用基于acl即访问控制列表的安全措施来完成。也有一些对ssl连接的支持。 

   设置除了root用户外的其他任何用户不允许访问mysql主数据库中的user表; 加密后存放在user表中的加密后的用户密码一旦泄露,其他人可以随意用该用户名/密码相应的数据库; 

   使用grant和revoke语句来进行用户访问控制的工作; 

   不要使用明文密码,而是使用md5()和sha1()等单向的哈系函数来设置密码; 

   不要选用字典中的字来做密码; 

   采用防火墙可以去掉50%的外部危险,让数据库系统躲在防火墙后面工作,或放置在dmz区域中; 

   从因特网上用nmap来扫描3306端口,也可用telnet server_host 3306的方法测试,不允许从非信任网络中访问数据库服务器的3306号tcp端口,需要在防火墙或路由器上做设定; 10.为了防止被恶意传入非法参数,例如where id=234,别人却输入where id=234 or 1=1导致全部显示,所以在web的表单中使用”或”"来用字符串,在动态url中加入%22代表双引号、%23代表井号、%27代表单引号;传递未检查过的值给mysql数据库是非常危险的; 11.在传递数据给mysql时检查一下大小; 

   应用程序需要连接到数据库应该使用一般的用户帐号,开放少数必要的权限给该用户; $page_devide$ 

   在各编程接口(c c++ php perl java jdbc等)中使用特定‘逃脱字符’函数; 

   在因特网上使用mysql数据库时一定少用传输明文的数据,而用ssl和ssh的加密方式数据来传输; 

   学会使用tcpdump和strings工具来查看传输数据的安全性,例如tcpdump -l -i eth0 -w -src or dst port 3306 strings。以普通用户来启动mysql数据库服务; 15.不使用到表的联结符号,选用的参数 –skip-symbolic-links; 

   确信在mysql目录中只有启动数据库服务的用户才可以对文件有读和写的权限; 

   不许将process或super权限付给非管理用户,该mysqladmin processlist可以列举出当前执行的查询文本;super权限可用于切断客户端连接、改变服务器运行参数状态、控制拷贝复制数据库的服务器; 

   file权限不付给管理员以外的用户,防止出现load data ‘/etc/passwd’到表中再用select 显示出来的问题; 

   如果不相信dns服务公司的服务,可以在主机名称允许表中只设置ip数字地址; 20.使用max_user_connections变量来使mysqld服务进程,对一个指定帐户限定连接数; 21.grant语句也支持资源控制选项; 

   启动mysqld服务进程的安全选项开关,–local-infile=0或1 若是0则客户端程序就无法使用local load data了,赋权的一个例子grant insert(user) on mysql.user to ‘user_name’@'host_name’;若使用–skip-grant-tables系统将对任何用户的访问不做任何访问控制,但可以用 mysqladmin flush-privileges或mysqladmin reload来开启访问控制;默认情况是show databases语句对所有用户开放,可以用–skip-show-databases来关闭掉。 

   碰到error 1045(28000) access denied for user ‘root’@'localhost’ (using password:no)错误时,你需要重新设置密码,具体方法是:先用–skip-grant-tables参数启动mysqld,然后执行 mysql -u root mysql,mysql>update user set password=password(’newpassword’) where user=’root’;mysql>flush privileges;,最后重新启动mysql就可以了。

2.      NoSQL相关

Ø  NoSQL介绍

   NoSQL(NoSQL = Not Only SQL ),意即“不仅仅是SQL”,是一项全新的数据库革命性运动,早期就有人提出,发展至2009年趋势越发高涨。NoSQL的拥护者们提倡运用非关系型的数据存储,相对于铺天盖地的关系型数据库运用,这一概念无疑是一种全新的思维的注入。

Ø  NoSQL特点

   它们可以处理超大量的数据。

   它们运行在便宜的PC服务器集群上。

   PC集群扩充起来非常方便并且成本很低,避免了“sharding”操作的复杂性和成本。

   它们击碎了性能瓶颈。

   NoSQL的支持者称,通过NoSQL架构可以省去将Web或Java应用和数据转换成SQL友好格式的时间,执行速度变得更快。

   “SQL并非适用于所有的程序代码,” 对于那些繁重的重复操作的数据,SQL值得花钱。但是当数据库结构非常简单时,SQL可能没有太大用处。

   没有过多的操作。

   虽然NoSQL的支持者也承认关系数据库提供了无可比拟的功能集合,而且在数据完整性上也发挥绝对稳定,他们同时也表示,企业的具体需求可能没有那么多。

   Bootstrap支持

   因为NoSQL项目都是开源的,因此它们缺乏供应商提供的正式支持。这一点它们与大多数开源项目一样,不得不从社区中寻求支持。

Ø  NoSQL优点

   易扩展:NoSQL数据库种类繁多,但是一个共同的特点都是去掉关系数据库的关系型特性。数据之间无关系,这样就非常容易扩展。也无形之间,在架构的层面上带来了可扩展的能力。

   大数据量,高性能:NoSQL数据库都具有非常高的读写性能,尤其在大数据量下,同样表现优秀。这得益于它的无关系性,数据库的结构简单。一般MySQL使用 Query Cache,每次表的更新Cache就失效,是一种大粒度的Cache,在针对web2.0的交互频繁的应用,Cache性能不高。而NoSQL的 Cache是记录级的,是一种细粒度的Cache,所以NoSQL在这个层面上来说就要性能高很多了。

   灵活的数据模型:NoSQL无需事先为要存储的数据建立字段,随时可以存储自定义的数据格式。而在关系数据库里,增删字段是一件非常麻烦的事情。如果是非常大数据量的表,增加字段简直就是一个噩梦。这点在大数据量的web2.0时代尤其明显。

   高可用:NoSQL在不太影响性能的情况,就可以方便的实现高可用的架构。比如Cassandra,HBase模型,通过复制模型也能实现高可用。

Ø  NoSQL开源软件

   MongoDB

l   MongoDB更像一个关系型数据库。它的数据模型顶层是一个数据库(database),之下一个类似于MySql表结构的集合 (collection),然后collection内包含的是文档(document)就像MySql里的数据行。每个文档有一个域(field)和一 个值(value)类似于MySql里的列和值。field可以是简单的键/值(例如 { 'name': 'David Mytton' })也可以包含别的document(例如 { 'name': { 'first' : David, 'last' : 'Mytton' } })。

l   MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。它的特点是高性能、易部署、易使用,存储数据非常方便。主要功能特性有:

*面向集合存储,易存储对象类型的数据。

*模式自由。  

*支持动态查询。  

*支持完全索引,包含内部对象。  

*支持查询。  

*支持复制和故障恢复。  

*使用高效的二进制数据存储,包括大型对象(如视频等)。  

*自动处理碎片,以支持云计算层次的扩展性  

*支持RUBY,PYTHON,JAVA,C++,PHP等多种语言。  

*文件存储格式为BSON(一种JSON的扩展)  

*可通过网络访问

   Cassandra

l   在Cassandra里,document对应的是“column”,即一个键值对(例如{ 'key': 'name', 'value': 'David Mytton' }),还包括一个时间戳字段用于内部的复制和一致性。值可以是一个值也可以包含其它的“column”,这些column按照某个指定值的顺序保存在column family里,顶层是一个键空间(keyspace)类似于MongoDB的database。

七.        笔试题

1.      在数组{m, m+1, m+2, m+3, …, N, 1, 2, 3, 4, …, m-1}中获取某个值的索引。

   提示:二分法查找

2.    大数相乘,即输入两个较大的数,输出相乘的结果。

   提示:三个数组

3.      将一个句子按单词反序,比如“what is your name”反序后变为“name your is what”。

   提示:先整个反序,然后局部反序

4.      判断一个数是不是2的n次幂。

   提示:x &(x-1),结果为0则是

5.      小明家过桥。

   小明一家过一座桥,过桥时是黑夜,所以必须有灯。现在小明过桥要1秒,小明的弟弟要3秒,小明的爸爸要6秒,小明的妈妈要8秒,小明的爷爷要12秒。每次此桥最多可过两人,而过桥的速度依过桥最慢者而定,而且灯在点燃后30秒就会熄灭。问:小明一家如何过桥?

   答案:

小明与弟弟过去,小明回来,用4s;

妈妈与爷爷过去,弟弟回来,用15s;

小明与弟弟过去,小明回来,用4s;

小明与爸爸过去,用6s;

总共用29s。

6.      三只蚂蚁不相撞的概率

   在三角形的三个顶点上各有一只蚂蚁,它们向另一个顶点运动,目标随机(可能为另外两个顶点的任意一个)。问三只蚂蚁不相撞的概率是多少?

   答案:如果蚂蚁顺时针爬行记为0,逆时针爬行记为1。那么三只蚂蚁的状态可能为000,001,...,110,111中的任意一个,且为每种状态的概率相等。在这8种状态中,只有000和111可以避免相撞,所以蚂蚁不相撞的概率是1/4。

转载于:https://www.cnblogs.com/jiangxf/p/3471343.html

你可能感兴趣的:(java面试集锦整理)