[关闭]
@lovesosoi 2020-08-21T12:55:49.000000Z 字数 35633 阅读 1009

Java面试常见问题

面试


1、面向对象的特征有哪些方面

(1)抽象:
抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节。抽象包括两个方面,一是过程抽象,二是数据抽象。
(2)继承:
继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承。新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类)。派生类可以从它的基类那里继承方法和实例变量,并且类可以修改或增加新的方法使之更适合特殊的需要。
(3)封装:
封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。
(4) 多态性:
多态性是指允许不同类的对象对同一消息作出响应。多态性包括参数化多态性和包含多态性。多态性语言具有灵活、抽象、行为共享 、代码共享的优势,很好的解决了应用程序函数同名问题。

2、String是最基本的数据类型吗?

基本数据类型包括byte、int、char、long、float、double、boolean和short。
java.lang.String类是final类型的,因此不可以继承这个类、不能修改这个类。为了提高效率节省空间,我们应该用StringBuffer类

3、int 和 Integer 有什么区别

Java 提供两种不同的类型:引用类型和原始类型(或内置类型)。Int是java的原始数据类型,Integer是java为int提供的封类。
Java为每个原始类型提供了封装类。
原始类型封装类
booleanBoolean
charCharacter
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
引用类型和原始类型的行为完全不同,并且它们具有不同的语义。引用类型和原始类型具有不同的特征和用法,它们包括:大小和速度问题,这种类型以哪种类型的数据结构存储,当引用类型和原始类型用作某个类的实例数据时所指定的缺省值。对象引用实例变量的缺省值为 null,而原始类型实例变量的缺省值与它们的类型有关。

4、String 和StringBuffer的区别

JAVA 平台提供了两个类:String和StringBuffer,它们可以储存和操作字符串,即包含多个字符的字符数据。这个String类提供了 数值不可改变的字符串。而这个StringBuffer类提供的字符串可以进行修改。当你知道字符数据要改变的时候你就可以使StringBuffer。典型地,你可以使用StringBuffers来动态构造字符数据

5、运行时异常与一般异常有何异同?

异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误。java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。

6、说出Servlet的生命周期,并说出Servlet和CGI的区别。

Servlet被服务器实例化后,容器运行其init方法,请求到达时运行其service方法,service方法自动派遣运行与请求对应的doXXX方法(doGet,doPost)等,当服务器决定将实例销毁的时候调用其destroy方法。
与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。

7、说出ArrayList,Vector, LinkedList的存储性能和特性

ArrayList 和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector由于使用了synchronized方法(线程安全),通常性能上较ArrayList差,而LinkedList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。

8、EJB是基于哪些技术实现的?并说出SessionBean和EntityBean的区别,StatefulBean和StatelessBean的区别。

EJB包括Session Bean、Entity Bean、Message Driven Bean,基于JNDI、RMI、JAT等技术实现。
SessionBean在J2EE应用程序中被用来完成一些服务器端的业务操作,例如访问数据库、调用其他EJB组件。EntityBean被用来代表应用系统中用到的数据。
对于客户机,SessionBean是一种非持久性对象,它实现某些在服务器上运行的业务逻辑。
对于客户机,EntityBean是一种持久性对象,它代表一个存储在持久性存储器中的实体的对象视图,或是一个由现有企业应用程序实现的实体。
Session Bean 还可以再细分为 Stateful Session Bean 与 Stateless Session Bean ,这两种的 Session Bean都可以将系统逻辑 放在 method之中执行,不同的是 Stateful Session Bean 可以记录呼叫者的状态,因此通常来说,一个使用者会有一个相对应的 Stateful Session Bean 的实体。Stateless Session Bean 虽然也是逻辑组件,但是他却不负责记录使用者状态,也就是说当使用 者呼叫 Stateless Session Bean 的时候,EJB Container 并不会找寻特定的 Stateless Session Bean 的实体来执行这个 method 。换言之,很可能数个使用者在执行某个 Stateless Session Bean 的 methods 时,会是同一个 Bean 的 Instance 在执行。从内 存方面来看, Stateful Session Bean 与 Stateless Session Bean 比较, Stateful Session Bean 会消耗 J2EE Server 较多的 内存,然而 Stateful Session Bean 的优势却在于他可以维持使用者的状态。

9、Collection 和 Collections的区别。

Collection是集合类的上级接口,继承与他的接口主要有Set 和List.Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。

10、&和&&的区别。

&是位运算符,表示按位与运算,&&是逻辑运算符,表示逻辑与(and)。

11、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算法都大概一样,所以性能不会有很大的差异。

12、final, finally, finalize的区别。

final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
finally是异常处理语句结构的一部分,表示总是执行。
finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。

13、sleep() 和 wait() 有什么区别?

sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,把执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。
wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。

14、Overload(重载)和Override(重写)的区别。Overloaded的方法是否可以改变返回值的类型?

方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载
Overloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写
(Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被”屏蔽”了。如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。

15、error和exception有什么区别?

error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。
exception 表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。

16、同步和异步有何异同,在什么情况下分别使用他们?举例说明。

如果数据将在线程间共享。例如正在写的数据以后可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那么这些数据就是共享数据,必须进行同步存取。
当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往往更有效率。

17、abstract class和interface有什么区别?

声明方法的存在而不去实现它的类被叫做抽象类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。不能创建abstract 类的实例。然而可以创建一个变量,其类型是一个抽象类,并让它指向具体子类的一个实例。不能有抽象构造函数或抽象静态方法。Abstract 类的子类为它们父类中的所有抽象方法提供实现,否则它们也是抽象类为。取而代之,在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法。
接口(interface)是抽象类的变体。在接口中,所有方法都是抽象的。多继承性可通过实现这样的接口而获得。接口中的所有方法都是抽象的,没有一个有程序体。接口只可以定义static final成员变量。接口的实现与子类相似,除了该实现类不能从接口定义中继承行为。当类实现特殊接口时,它定义(即将程序体给予)所有这种接口的方法。然后,它可以在实现了该接口的类的任何对象上调用接口的方法。由于有抽象类,它允许使用接口名作为引用变量的类型。通常的动态联编将生效。引用可以转换到接口类型或从接口类型转换,instanceof 运算符可以用来决定某对象的类是否实现了接口。

18、short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错?

short s1 = 1; s1 = s1 + 1; (s1+1运算结果是int型,需要强制转换类型)
short s1 = 1; s1 += 1;(可以正确编译)

19、Math.round(11.5)等於多少? Math.round(-11.5)等於多少?

Math.round(11.5)==12
Math.round(-11.5)==-11
round方法返回与参数最接近的长整数,参数加1/2后求其floor.

20、String s = new String(“xyz”);创建了几个String Object?

两个(一个是“xyx”,一个是指向“xyx”的引用对象s)

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

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

22、List, Set, Map是否继承自Collection接口?

List,Set是,Map不是

23、说出数据连接池的工作机制是什么?

J2EE 服务器启动时会建立一定数量的池连接,并一直维持不少于此数目的池连接。客户端程序需要连接时,池驱动程序会返回一个未使用的池连接并将其表记为忙。如果当前没有空闲连接,池驱动程序就新建一定数量的连接,新建连接的数量由配置参数决定。当使用的池连接调用完成后,池驱动程序将此连接表记为空闲,其他调用就可以使用这个连接。

24、abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized?

都不能

25、数组有没有length()这个方法? String有没有length()这个方法?

数组没有length()这个方法,有length的属性。String有有length()这个方法。

26、Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别?

Set里的元素是不能重复的,那么用iterator()方法来区分重复与否。equals()是判读两个Set是否相等。
equals()和==方法决定引用值是否指向同一对象equals()在类中被覆盖,为的是当两个分离的对象的内容和类型相配的话,返回真值 。

27、构造器Constructor是否可被override?

构造器Constructor不能被继承,因此不能重写Overriding,但可以被重载Overloading。

28、是否可以继承String类?

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

29、swtich是否能作用在byte上,是否能作用在long上,是否能作用在String上?

switch(expr1)中,expr1是一个整数表达式。因此传递给 switch 和 case 语句的参数应该是 int、 short、 char 或者 byte。
long,string 都不能作用于swtich。

30、try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后?

会执行,在return前执行。

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

2 << 3 (有C背景的程序员特别喜欢问这种问题)

32、两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对?

不对,有相同的hash code。

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

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

34、Java的接口和C++的虚类的相同和不同处。

由于Java不支持多继承,而有可能某个类或对象要使用分别在几个类或对象里面的方法或属性,现有的单继承机制就不能满足要求。与继承相比,接口有更高的灵活性,因为接口中没有任何实现代码。当一个类实现了接口以后,该类要实现接口里面所有的方法和属性,并且接口里面的属性在默认状态下面都是public static,所有方法默认情况下是public.一个类可以实现多个接口。

35、Java中的异常处理机制的简单原理和应用。

当JAVA 程序违反了JAVA的语义规则时,JAVA虚拟机就会将发生的错误表示为一个异常。违反语义规则包括2种情况。一种是JAVA类库内置的语义检查。例如数组下标越界,会引发IndexOutOfBoundsException;访问null的对象时会引发NullPointerException。另一种情况就是JAVA允许程序员扩展这种语义检查,程序员可以创建自己的异常,并自由选择在何时用throw关键字引发异常。所有的异常都是 java.lang.Thowable的子类。

36、你所知道的集合类都有哪些?主要方法?

最常用的集合类是 List 和 Map。 List 的具体实现包括 ArrayList 和 Vector,它们是可变大小的列表,比较适合构建、存储和操
作任何类型对象的元素列表。 List 适用于按数值索引访问元素的情形。
Map 提供了一个更通用的元素存储方法。 Map 集合类用于存储元素对(称作"键"和"值"),其中每个键映射到一个值。

37、描述一下JVM加载class文件的原理机制?

JVM中类的装载是由ClassLoader和它的子类来实现的,Java ClassLoader 是一个重要的Java运行时系统组件。它负责在运行时查找和装入类文件的类。

38、char型变量中能不能存贮一个中文汉字?为什么?

能够定义成为一个中文的,因为java中以unicode编码,一个char占2个字节(Byte)共16位(bit),所以放一个中文是没问题的

39、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实例

40、什么情况下调用doGet()和doPost()?

Jsp页面中的form标签里的method属性为get时调用doGet(),为post时调用doPost()。

41、JSP和Servlet有哪些相同点和不同点,他们之间的联系是什么?

JSP 是Servlet技术的扩展,本质上是Servlet的简易方式,更强调应用的外表表达。JSP编译后是”类servlet”。Servlet和JSP最主要的不同点在于,Servlet的应用逻辑是在Java文件中,并且完全从表示层中的HTML里分离开来。而JSP的情况是Java和HTML可以组合成一个扩展名为.jsp的文件。JSP侧重于视图,Servlet主要用于控制逻辑。

42、四种会话跟踪技术

会话作用域ServletsJSP 页面描述
page否是代表与一个页面相关的对象和属性。一个页面由一个编译好的 Java servlet 类(可以带有任何的 include 指令,但是没
有 include 动作)表示。这既包括 servlet 又包括被编译成 servlet 的 JSP 页面
request是是代表与 Web 客户机发出的一个请求相关的对象和属性。一个请求可能跨越多个页面,涉及多个 Web 组件(由于
forward 指令和 include 动作的关系)
session是是代表与用于某个 Web 客户机的一个用户体验相关的对象和属性。一个 Web 会话可以也经常会跨越多个客户机请求
application是是代表与整个 Web 应用程序相关的对象和属性。这实质上是跨越整个 Web 应用程序,包括多个页面、请求和会话的 一个全局作用域

43、Servlet执行时一般实现哪几个方法?

public void init(ServletConfig config)
public ServletConfig getServletConfig()
public String getServletInfo()
public void service(ServletRequest request,ServletResponse response)
public void destroy()
init ()方法在servlet的生命周期中仅执行一次,在服务器装载servlet时执行。缺省的init()方法通常是符合要求的,不过也可以
根据需要进行 override,比如管理服务器端资源,一次性装入GIF图像,初始化数据库连接等,缺省的inti()方法设置了servlet的
初始化参数,并用它的ServeltConfig对象参数来启动配置,所以覆盖init()方法时,应调用super.init()以确保仍然执行这些任务

service ()方法是servlet的核心,在调用service()方法之前,应确保已完成init()方法。对于HttpServlet,每当客户请求一个
HttpServlet对象,该对象的service()方法就要被调用,HttpServlet缺省的service()方法的服务功能就是调用与 HTTP请求的方法
相应的do功能,doPost()和doGet(),所以对于HttpServlet,一般都是重写doPost()和doGet() 方法。
destroy()方法在servlet的生命周期中也仅执行一次,即在服务器停止卸载servlet时执行,把servlet作为服务器进程的一部分关闭
。缺省的destroy()方法通常是符合要求的,但也可以override,比如在卸载servlet时将统计数字保存在文件中,或是关闭数据库连接。
getServletConfig()方法返回一个servletConfig对象,该对象用来返回初始化参数和servletContext。servletContext接口提供有
关servlet的环境信息。
getServletInfo()方法提供有关servlet的信息,如作者,版本,版权。

44、j2ee常用的设计模式?说明工厂模式。

Java中的23种设计模式:
Factory(工厂模式), Builder(建造模式), Factory Method(工厂方法模式),
Prototype(原始模型模式),Singleton(单例模式), Facade(门面模式),
Adapter(适配器模式), Bridge(桥梁模式), Composite(合成模式),
Decorator(装饰模式), Flyweight(享元模式), Proxy(代理模式),
Command(命令模式), Interpreter(解释器模式), Visitor(访问者模式),
Iterator(迭代子模式), Mediator(调停者模式), Memento(备忘录模式),
Observer(观察者模式), State(状态模式), Strategy(策略模式),
Template Method(模板方法模式), Chain Of Responsibleity(责任链模式)
工厂模式:工厂模式是一种经常被使用到的模式,根据工厂模式实现的类可以根据提供的数据生成一组类中某一个类的实例,通常这一组类有一个公共的抽象父类并且实现了相同的方法,但是这些方法针对不同的数据进行了不同的操作。首先需要定义一个基类,该类的子类通过不同的方法实现了基类中的方法。然后需要定义一个工厂类,工厂类可以根据条件生成不同的子类实例。当得到子类的实例后,开发人员可以调用基类中的方法而不必考虑到底返回的是哪一个子类的实例。

45、JAVA语言如何进行异常处理,关键字:throws,throw,try,catch,finally分别代表什么意义?在try块中可以抛出异常吗?

Java 通过面向对象的方法进行异常处理,把各种不同的异常进行分类,并提供了良好的接口。在Java中,每个异常都是一个对象,它是Throwable类或其它子类的实例。当一个方法出现异常后便抛出一个异常对象,该对象中包含有异常信息,调用这个对象的方法可以捕获到这个异常并进行处理。Java的异常处理是通过5个关键词来实现的:try、catch、throw、throws和finally。一般情况下是用try来执行一段程序,如果出现异常,系统会抛出(throws)一个异常,这时候你可以通过它的类型来捕(catch)它,或最后(finally)由缺省处理器来处理。
用try来指定一块预防所有”异常”的程序。紧跟在try程序后面,应包含一个catch子句来指定你想要捕捉的”异常”的类型。
throw语句用来明确地抛出一个”异常”。
throws用来标明一个成员函数可能抛出的各种”异常”。
Finally为确保一段代码不管发生什么”异常”都被执行一段代码。
可以在一个成员函数调用的外面写一个try语句,在这个成员函数内部写另一个try语句保护其他代码。每当遇到一个try语句,”异常“的框架就放到堆栈上面,直到所有的try语句都完成。如果下一级的try语句没有对某种”异常”进行处理,堆栈就会展开,直到遇到有处理这种”异常”的try语句。

46、MVC的各个部分都有那些技术来实现?如何实现?

MVC 是Model-View-Controller的简写。”Model” 代表的是应用的业务逻辑(通过JavaBean,EJB组件实现), “View” 是应用的表示面,用于与用户的交互(由JSP页面产生),”Controller” 是提供应用的处理过程控制(一般是一个Servlet),通过这种设计模型把应用逻辑,处理过程和显示逻辑分成不同的组件实现。这些组件可以进行交互和重用。
model层实现系统中的业务逻辑,view层用于与用户的交互,controller层是model与view之间沟通的桥梁,可以分派用户的请求并选择恰当的视图以用于显示,同时它也可以解释用户的输入并将它们映射为模型层可执行的操作。

47、java中有几种类型的流?JDK为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类?

字节流,字符流。字节流继承于InputStream OutputStream,字符流继承于InputStreamReader OutputStreamWriter。在java.io包中还有许多其他的流,主要是为了提高性能和使用方便。

48、java中实现多态的机制是什么?

方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载
Overloading是一个类中多态性的一种表现。

49、静态变量和实例变量的区别?

static i = 10; //常量
class A a; a.i =10;//可变

50、在JAVA中,如何跳出当前的多重嵌套循环?

用break; return 方法。

51、List、Map、Set三个接口,存取元素时,各有什么特点?

List 以特定次序来持有元素,可有重复元素。Set 无法拥有重复元素,内部排序。Map 保存key-value值,value可多值。

52、数据库事务的四大特性(ACID)

原子性:整个事务中所有操作,要么全部完成,要么全部不完成,不可能停留在中间的某个环节。如果事务在执行的过程中遇到错误,会被回滚(Rollback)到事务的开始前的状态。

一致性:在事务开始之前和结束之后,数据库的完整约束性不会被破坏。

隔离性:如果有两个事务,运行在相同的时间内,执行相同的功能,事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统。这种属性有时称为串行化,为了防止事务操作时间的混淆,必须串行化或序列化请求,使得在同一时间仅有一个请求用于同一数据。

持久性:在事务完成以后,该事务对数据库所作的更改便持久的保存在数据库之中。

Java基础:

1. 九种基本数据类型的大小,以及他们的封装类。

byte(Byte) 1 ,short(Short) 2 ,int(Integer) 4 ,long(Long) 8 ,float(Float) 4 ,double(Double) 8,boolean(Boolean),char(Character)2

2. Switch能否用string做参数?

switch语句中的变量类型可以使byte,short,int,char。从jdk1.7后可以使用String类型,是通过switch中的String.hashcode将String转换成int进行判断的。

3. equals与==的区别。

==操作符是用来比较两个变量的值是否相等,即就是比较变量在内存中的存储地址是否相同,equals()方法时String类从Object类中继承的,被用来检测两个对象的内容是否相同。

4、String s=new String(‘xyz’);创建了几个object对象?

会创建一个String类型的变量s。在类加载到此处之前没有出现“xyz”字面量的话,加载此处会创建一个对应“xyz”的String常量对象。在符合规范的JVM上,执行到此处new关键字会创建

一个String对象。

5. Object有哪些公用方法?

1、clone()创建斌返回此对象的副本

2、equals()判断

3、getclass()返回object的运行类

4、hashcode()返回对象的哈希码值

5、notify()唤醒正在等待对象监听器的单个进程

6、notifyAll()唤醒正在等待对象监听器的所有进程

7、wait()导致当前线程等待,直到另一个线程调用该对象的 notify()方法或 notifyAll()方法。

8、toString()返回此对象的字符串表示形式

9、finalize()当垃圾收集确定不需要该对象时,垃圾回收器调用该方法

6. Java的四种引用,强弱软虚,用到的场景。

强引用:垃圾回收器不会回收

软引用:如果内存空间足够,垃圾回收器就不会进行回收,如果内存空间不足,垃圾回收器就会进行回收

弱引用:一旦发现了只有弱引用的对象,垃圾回收器就会进行回收。

虚引用:如果发现该对象还具有虚引用,就会在回收该对象之前,吧这个虚引用加入到与之关联的引用队列中。

7. 静态变量和实例变量的区别

静态变量前要加上关键字static,实例变量则不会。

实例变量是属于某个对象的属性,必须创建了实例对象,其中的实例变量才会分配空间,才能使用这个实例变量。静态变量不属于任何的实例对象,而是属于类,也称为类变量,只

要程序加载了类的字节码,不用创建任何实例对象,就会被分配空间。总之就是,静态变量不需要创建任何的对象就可以直接使用,而实例变量需要先创建实例对象才能被使用。

8. Overload和Override的区别:

重载Overload表示的是同一个类中可以有多个相同名称的方法,但这些方法的参数列表不同,即就是参数参数或参数类型不同。重载时返回值当然可以不一样,但是如果参数列表

完全一致时,不能通过返回类型不一致而实现重载,这是不可以的。

重写Override表示子类中的方法可以与父类中的方法名称和参数完全相同,通过子类创建的对象来调用这个方法时,将调用子类中定义的方法,即就是子类中的该方法将父类的该方

法覆盖了。子类覆盖父类方法时只能抛比父类更少或者更小的异常。重写的方法其返回必须和被覆盖的方法返回一致。

9. 抽象类和接口的区别

抽象类可以有默认的方法进行实现,可以有构造器,可以有main方法进行运行,可以直接在该类中添加实现的方法

接口没有默认的方法进行实现,没有构造器,不可以使用main方法进行运行,在接口中添加方法时需要在具体实现的类中添加方法。

10. String、StringBuffer与StringBuilder的区别。

String表示内容不可修改的字符串,StringBuffer表示内容可以修改的字符串,

String覆盖了equals()方法和hashcode()方法,而StringBuffer没有覆盖两个方法,,所以StringBuffer对象存储到java集合类中时会出现问题。

StringBulider也表示内容可以修改的字符串,但是其线程是不安全的,运行效率高

11. Java面向对象的特征与含义。

封装、继承、抽象、多态

1、封装:封装的目的在于实现程序的“高内聚,低耦合”,防止程序相互依赖而带来的变动影响。封装是保证是把对同一事物进行操作的方法和相关的方法放在同一个类中,把方法

和他操作的数据放在同一个类中。

2、抽象:抽象就是找出事物的相似和共性,然后将这些事物归为同一类,这个类只考虑这些事物的相似和共性,忽略和当前主题不相关的因素。

3、继承:子类继承父类的内容作为自己的内容,可以加入新的内容或者是修改父类的内容而更加适合特殊的需要。提高了额程序的可重用性和可扩张性。

4、多态:多态是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类

的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。

12. java多态的实现

接口实现,

继承父类进行方法重写,

同一个类中进行方法重载。

异常:

14. error和exception区别

error表示有可能恢复但比较困难的的一种严重问题,程序是不能进行处理的

exception表示一种设计或者实现问题。

15. 运行时异常和一般异常的区别

异常表示程序运行过程中可能出现的非正常状态。运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见的运行错误。java编译器要求方法必须声明抛出可能出现的非

运行时异常,但是并不要求必须声明抛出未被捕获的异常

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

JAVA程序违反了JAVA的语义规则时,JAVA虚拟机就会将发生的错误表示为一个异常。违反语义规则包括2种情况。一种是JAVA类库内置的语义检查。例如数组下标越界,

会引发IndexOutOfBoundsException;访问null的对象时会引发 NullPointerException。另一种情况就是JAVA允许程序员扩展这种语义检查,程序员可以创建自己的异常,并自由选

择在何时用 throw关键字引发异常。所有的异常都是java.lang.Thowable的子类。

17. Java语言如何进行异常处理,throws,throw,try catch finally代表什么意义,try块中可以抛出异常吗?

Java通过面向对象的方法进行异常处理,把各种不同的异常进行分类,并提供了良好的接口。在Java中,每个异常都是一个对象,它是Throwable类或其它子类的实例。当一个

方法出现异常后便抛出一个异常对象,该对象中包含有异常信息,调用这个对象的方法可以捕获到这个异常并进行处理。Java的异常处理是通过5个关键词来实现的:try、catch、

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

由缺省处理器来处理。

用try来指定一块预防所有”异常”的程序。紧跟在try程序后面,应包含一个catch子句来指定你想要捕捉的”异常”的类型。

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

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

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

可以在一个成员函数调用的外面写一个try语句,在这个成员函数内部写另一个try语句保护其他代码。每当遇到一个try语句,”异常”的框架就放到堆栈上面,直到所有的try语句都完成。

如果下一级的try语句没有对某种”异常”进行处理,堆栈就会展开,直到遇到有处理这种”异常”的try语句。

18. try catch finally,try里有return,finally还执行么?

1、finally语句总会执行

2、如果try、catch中有return语句,finally中没有return,那么在finally中修改除包装类型和静态变量、全局变量以外的数据都不会对try、catch中返回的变量有任何的影响(包装类型、静态变量会改变、全局变量)

3、尽量不要在finally中使用return语句,如果使用的话,会忽略try、catch中的返回语句,也会忽略try、catch中的异常,屏蔽了错误的发生

4、finally中避免再次抛出异常,一旦finally中发生异常,代码执行将会抛出finally中的异常信息,try、catch中的异常将被忽略

19. Java中final、finally和finalize的区别、

final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。

内部类要访问局部变量,局部变量必须定义成final类型,例如,一段代码……

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

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

20. 常见的运行时异常

系统异常是RuntimeException的子类,常见的系统异常有:

ArrayIndexOutOfBoundsException - 数组越界访问

ClassCastException - 类型转换异常

NullPointerException - 试图访问一空对象的变量、方法或空数组的元素

IllegalArgumentException - 方法的参数无效

NoClassDefFoundException - JAVA运行时系统找不到所引用的类

集合:

21. Collection框架的结构

集合框架(Collection Framework)泛指java.util包的若干个类和接口.如Collection,List,ArrayList,LinkedList,Vector(自动增长数组),HashSet,HashMap等.

集合框架中的类主要封装的是典型的数据结构,如动态数组,链表,堆栈,集合,哈希表等.

集合框架类似编程中经常用到的工具类,使得编码这专注于业务层的实现,不需要从底层实现相关细节—“数据结构的封装”和”典型算法的实现”.

22. Collection包结构

Collection是集合类的上级接口,是单列集合。继承他的接口主要有Set 和List.

Set接口的子接口有:HashSet,TreeSet

List接口的子接口有:Arraylist,LinkedList,Vector

23. Collection与Collections的区别。

Collection是集合类的上级接口,继承他的接口有Set和List

Collections是针对集合类的一个帮助类,它提供一系列的静态方法实现集合的搜索,排序,线程安全等操作。

24. Colection框架中实现比较要实现什么接口?

comparable:只包含compareTo()方法

comparator:compare()和equals()

25. Map、Set、List、Queue、Stack的特点与用法。

1、Map是以键值对的形式进行存储的,其中key是唯一不可重复的,value的可以重复,当插入的值是key相同,后加入的会将已有的覆盖。他有几个具体的实现类,包括Treemap

和HashMap,TreeMap是有序的,HashMap是无序的。

2、List 有序,可重复

|--ArrayList

底层数据结构是数组,查询快,增删慢,线程不安全,效率高

|--Vector

底层数据结构是数组,查询快,增删慢,线程不安全,效率高

|--LinkedList

底层数据结构是链表,查询慢,增删块,线程安全,效率低

3、Set 无序,唯一

|--HashSet

底层数据结构是哈希表

如何保证元素的唯一性:

依赖两个方法,hashCode()和equals()

|--LinkedHashSet

底层数据结构是链表和哈希表,由链表保证元素有序,由哈希表保证元素唯一

|--TreeSet

底层数据结构是红黑树,

如何保证元素的排序:

自然排序:让元素所属的类实现Comparable接口

比较器排序:让集合接收一个Comparator的实现类对象

如何保证元素的唯一性:

根据比较的返回值是否是0来决定的

4、Query队列遵循先进先出的原则,不允许插入null值,其中提供了相应的进队和出队的方法,建议使用offer()方法来添加元素,使用poll()方法删除元素

5、Stack遵从后进先出的原则,继承自Vector。他通过5个操作对Vector类进行扩展,它提供了push和pop操作,以及去堆栈顶点的peek()方法,测试堆栈是否为空的empty方法

6、使用方法:

如果涉及到堆栈,队列等操作,建议使用List

对于快速插入和删除元素建议使用LinkedList

需要快速随机访问元素建议使用ArrayList

26. Set里面的元素不能重复,用什么方法区分重复与否。?

Set里的元素是唯一不能重复的,元素是否重复使用equals()方法进行判断。

equals()方法和==方法决定引用值是否指向同一对象equals()在类中被覆盖,为的是两个分离的对象的内容和类型相匹配的话,返回真值。

27. HashMap和Hashtable的区别。

1、Hashtable是基于Dictionary类的,HashMap是Map接口的一个实现类

2、Hashtable是线程安全的,即是同步的;HashMap线程不是安全的,不是同步的。

3、HashMap可以将空值作为key或value

28. HashMap、LinkedHashMap、TreeMap的区别。

1、HashMap是根据键的hashcode值存储数据,根据键可以直接获取它的值,具有很快的访问速度,取得的数据完全是随机的

2、LinkedHashMap保存了记录的插入顺序,在使用Iterator进行遍历的时候,先得到的肯定是先插入的数据,可以在构造时带参数,按照应用次数来进行排序

3、TreeMap实现SortMap接口,能够把它保存的记录根据键排序。默认的是升序排序,也可以指定排序的比较器,进行遍历的时候得到的是排序过的记录。

29. HashMap、LinkedHashMap、ConcurrentHashMap、ArrayList、LinkedList的底层实现。

1、HashMap是java数据结构中两大结构数组和链表的组合。HashMap底层数组,数组中的每一项又是一个链表。程序会先根据key的hashcode()方法返回值决定该Entry在数组中的

存储位置,如果该位置上没有元素,就会将元素放置在此位置上,如果两个Entry的key相同,会调用equals,返回值是true则覆盖原来的value值,返回false则会形成Entry链,位于

头部

2、ArrrayList的底层实现是数组,在执行add操作时,会先检查数组 大小是否可以容纳新的元素,如果不够就会进行扩容。然后会将原来的数据拷贝到新的数组中

3、LinkedList底层是一个链表,其实现增删改查和数据结构中的操作完全相同,而且插入是有序的

4、LinkedHashMap的底层结构式是双链表,其他的逻辑处理与HashMap一致,同样没有锁保护,多线程使用时存在风险

5、ConcurrentHashMap是segment数组结构和HashEntry数组结构组成的,segment在ConcurrentHashMap中充当锁的角色,HashEntry用于存储键值对数据。segment的结构是数组

和链表,一个segment中有一个HashEntry,每个HashEntry是一个链表结构的元素。对HashEntry中的数据进行修改时,需要先获得它所对应的segment锁。每个ConcurrentHashMap

默认有16个segment。

30. 迭代器Iterator

Iterator提供了统一遍历操作集合元素的统一接口,Collection接口实现Iterator接口。每个集合都通过实现Iterator接口中的iterator()方法返回实例,然后对元素进行迭代操作,,但是

在迭代元素的时候不能使用集合的方法删除元素,否则会抛出异常,可以使用Iterator接口中的remove()方法进行删除

31. 快速失败(fail-fast)和安全失败(fail-safe)的区别

Iterator的安全失败是基于对底层集合做拷贝,因此它不受源集合修改的影响。util包下的所有集合类都是快速失败的,util.concurren包下面的所有类都是安全失败的。

IO流:

32. 什么是java序列化?如何实现java序列化

序列化就是一种用来处理对象流的 机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可以将流化后的对象在网络间进行传递。

序列化的实现:将需要被序列化的类实现Serializable接口,该接口没有需要实现的方法,implements Serializable 只是为了标注 该对象时可被序列化的。

线程、反射、枚举、泛型:

33. 什么是线程安全

线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类时进行保护,其他线程不能访问直到该线程访问结束,其他的线程才可以使用。一般使用synchronized关键字加锁同步

控制来解决线程不安全的问题。

34. 创建线程的3种方式。

1、继承Thread类

2、实现Runnable接口

3、应用程序可以使用Executor框架来创建线程池。

实现Runnable接口的这种方式是更好的,因为不需要继承Thread类,在应用设计中已经继承了别的对象的情况下,需要多继承,但是java不支持多继承,同时线程池也是非常高效的,

很容易实现和使用。

35. 线程从创建到死亡的几种状态

1、新建new:新创建一个线程对象

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

3、运行running:可运行状态的线程获取了cpu的时间片,执行程序代码

4、阻塞block:线程因为某种原因放弃了cpu的使用权,暂时停止运行,知道线程进入可运行状态才会再次有机会进入运行状态。

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

36. 什么是ThreadLocal。

在面向对象编程中,创建和销毁对象是很耗费时间的,因为创建一个对象要获取内存资源或者其他的资源。在java中更是如此,所以提高服务程序效率的一个手段就是尽可能减少创建和

销毁对象。线程池,顾名思义就是事先创建若干个可执行的线程放如到一个池(容器)中,需要的时候从池中获取线程不用自行创建,使用完毕后不需要销毁线程而是放回到池中,从而

减少创建和销毁线程对象的开销。

37. 创建线程池的4种方式。

java5中的Executor接口定义一个执行线程的工具。它的子类型即线程池接口是ExecutorService。要配置一个线程池是非常复杂的,因此工具类Executors里面提供了一些静态的工厂方法

来生成线程池:

1、newSingleThreadExecutor:创建一个单线程的线程池。这个线程池只有一个线程在工作。如果这个唯一的线程因为异常结束,就会有一个新的线程来代替它

2、newFixedThreadPool:创建一个固定大小的线程池。

3、newCacheThreadPool:创建一个可缓存的线程池。

4、newScheduledThreadPool:创建一个大小不限的线程池

38. 线程同步的方法:sychronized、lock、reentrantLock等

1、sychrnized关键字主要有两种用法:sychrnized方法和sychrnized块。

sychrnized方法,在方法声明前加入了sychrnized关键字,把需要同步的资源放入到该方法中,就能保证这个方法在同一时刻只能被一个线程调用,从而实现了多线程访问的安全性

sychrnized块,既可以把任意的代码段声明为sychrnized,也可以指定上锁的对象,非常具有灵活性,如果一个对象既有同步方法又有同步块,那额当前中的一个同步方法或者同步块被

线程执行时,这个对象就被锁定了,其他线程无法在此时访问这个对象的同步方法和同步块

2、Lock:jdk5新增了Lock接口以及他的一个实现类ReentrantLock(重入锁)。Lock(),以阻塞的方式来获取锁,如果获取到锁,就立即返回,如果别的线程持有锁,则当前线程等待

直到获取到锁返回

3、ReentranLock

39. Runnable接口和Callable接口的区别。

1、Runnable的方法时run()方法,Callable的方法是call()

2、Callable的任务执行后可以返回值,Runnable的任务是不能返回值

3、call方法可以抛出异常,但是run方法不能抛出异常

40. wait方法和sleep方法的区别。

sleep是线程类Thread的方法,导致此线程暂停执行时间,把执行机会给其他的线程,但是监控状态依然保持,到时会自动恢复,调用sleep不会释放对象锁

wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待锁定池,只有针对此对象发出notify方法后本线程才进入对象锁定池准备获取对象锁进入运行状态。

41. 锁的等级:方法锁、对象锁、类锁。

42. 分布式环境下,怎么保证线程安全。

1、时间戳:分布式环境下是无法保证时序的,无论是通过远程接口同步调用或者一部消息,很容易造成某些对时序性有要求的业务在高并发时产生错误。对于这问问题,常用的方法是

采用时间戳的方式。系统A给系统B发送变更时需要带上一个时间戳,B通过与已经存在的时间戳进行变更,这样的方式比较简单,关键在于调用的一方要有保证时间戳的时序有效性

2、串行化:有时候可以牺牲性能和扩张性来使用串行化,满足对数据一致性的需求。

3、数据库:分布式的环境中共享资源不能 通过Java里同步方法或者加锁来保证线程安全,但是数据库是分布式各服务器的共享点,可以通过数据库的高可靠一致性来满足需求

4、行锁:

5、统一触发途径:当一个数据可能被多个触发点或多个业务涉及到,就有并发问题产生的隐患,因此 可以通过前期架构和业务世界尽量统一触发途径,触发途径少一是减少了并发的

可能性也有利于并发问题的分析和判断

43. 介绍下CAS(无锁技术)。

CAS(compare and swap),即比较并替换,实现并发算法时常用到的一种技术,CAS是通过unsafe类的compareAndSwap方法实现的

CAS的思想:三个参数,一个当前内存值V,旧的预期值A,即将更新的值B,当且仅当预期值和内存值相同时将内存值修改为即将更新的值并返回,否则什么都不做,返回false。

缺点:即就是ABA问题,也就是如果变量A初次读取的是A,并且在准备赋值的时候检查到它还是A,那能证明它没有被修改过吗?很显然是不能的,如果这段时间它被修改为B然后又被

修改为A,那么CAS就会认为它没有被修改过,针对这种情况,java并发包提供了一个带有标记的原子引用类,AtomicStampedReference,它可以通过看着呢会变量值的版本来

保证CAS的正确性。

44. 反射的作用于原理。

简单的说,反射机制其实就是指程序在运行的时候可以获取自身的信息,。如果知道一个 类的名称或者它的一个实例对象,就能把这个类的所有方法和变量的信息找出来,如果明确知道

这个类里的某个方法名和参数个数及类型,还能通过传递参数来运行那个类的方法,这就是反射。在java中,class类与java.lang.reflect类库一起对反射的概念提供了支持,该类库包含了

了Field、Method以及Construcctor类。

43. 泛型常用特点,List能否转为List。

泛型实现了参数化类型的概念,使得我们的代码可以在更多的场景使用。泛型的好处在于在编译时进行类型的安全检查,并且在运行的时候所有的转换都是强制的,隐式的,大大的提高

了代码的重用率。

先来回答List能否转为List的问题,答案是不行的,因为String的list不是Object的list,String的list持有String类和其子类型,Object的list持有任何类型的Object,String

的list在类型上不等价于Object的list。

44. Java1.5、1.7与1.8新特性。

JDK1.5:

自动装箱与拆箱:基本类型与包装类型自动互换
枚举类型的引入
静态导入:import static,可直接使用静态变量与方法
可变参数类型
泛型
for-each循环
JDK1.7:

switch允许传入字符串
泛型实例化类型自动推断:List tempList = new ArrayList<>()
对集合的支持,创建List / Set / Map 时写法更简单了,如:List< String> list = ["item"],String item = list[0],Set< String > set = {"item"}等
允许在数字中使用下划线
二进制符号加入,可用作二进制字符前加上 0b 来创建一个二进制类型:int binary = 0b1001_1001
一个catch里捕捉多个异常类型,‘|’分隔
JDK1.8:

允许为接口添加默认方法,又称为拓展方法,使用关键字default实现
Lambda 表达式
Date API
多重注解

45. JNI的使用

JNI即Java Native Interface的缩写,中文译为“Java本地调用”。通俗的说,JNI是一种实现Java层与Native层(C/C++)交互的技术。有时为了追求效率问题,

或者是使用用native代码编写的函数库,我们就不得不使用JNI接口。

设计模式:

46. 设计模式有哪些?

1、设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案,这些方案是众多的软件开发人员经过相当长的一段时间的实验和错误实践总结出来的

2、设计模式可以分为三大类:创建型模式、结构型模式、行为型模式

3、设计模式的6大原则:

开闭原则:对扩展开放,对修改关闭

里氏代换原则:

依赖倒转原则:

接口隔离原则

迪米特法则

合成复用原则:

47. 设计模式:单例、工厂、适配器、责任链、观察者等等。

  1. 1、单例模式
  2. 1、懒汉模式
  3. public class SingletonDemo {
  4. private static SingletonDemo instance;
  5. private SingletonDemo(){}
  6. public static SingletonDemo getInstance(){
  7. if(instance==null){
  8. instance=new SingletonDemo();
  9. }
  10. return instance;
  11. }
  12. }
  13. 2、懒汉模式(线程安全)
  14. public class Singleton {
  15. private static Singleton instance;
  16. private Singleton (){}
  17. public static synchronized Singleton getInstance() {
  18. if (instance == null) {
  19. instance = new Singleton();
  20. }
  21.    return instance;
  22. }
  23. }
  24. 3、饿汉模式
  25. public class Singleton {
  26. private static Singleton instance = new Singleton();
  27. private Singleton (){}
  28. public static Singleton getInstance() {
  29.    return instance;
  30. }
  31. }
  32. 4、双重校验锁
  33. public class Singleton {
  34. private volatile static Singleton singleton;
  35. private Singleton (){}
  36. public static Singleton getSingleton() {
  37.    if (singleton == null) {
  38.     synchronized (Singleton.class) {
  39.   if (singleton == null) {
  40. singleton = new Singleton();
  41.   }
  42. }
  43. }
  44.   return singleton;
  45. }
  46. }

5、饿汉模式和懒汉模式的区别:

饿汉模式在类加载时就将自己实例化,有点在于无序考虑多线程访问的问题,从资源和利用效率来看,饿汉模式不及懒汉模式

懒汉模式在第一次使用时创建,无须一直占用资源,实现了延迟加载,需要处理好多个线程同时访问的问题,从资源和利用效率来看,实例化必然涉及资源初始化,而资源初

化很有可能耗费大量的时间,这就意味着多线程同时首次引用此类的纪律变得较大。需要通过双重检查锁定机制进行控制,这样的后果就是导致性能受到一定的影响。

2、工厂模式

工厂模式属于创建型模式,提供了一种创建对象的最佳方式。会定义一个创建对象的接口,让其子类决定实例化哪一个工厂类,,工厂模式使其创建过程延迟到子类进行

3、适配器模式

将一个类的接口转换成客户希望的另外的一个接口,适配器模式可以让那些接口不兼容的类可以一起工作。它包含3个角色:

1、Target(目标抽象类):目标抽象类定义客户所需要的接口,可以是抽象类、接口或者是具体类

2、Adapter(适配器类):它可以调用另外的一个接口,作为一个转换器,是适配器的核心

3、Adaptee(适配者类):适配者即被适配的角色,它定义了一个已经存在的接口,这个接口需要适配,适配者类包好了客户希望的业务方法

4、责任链模式

使多个对象都有机会处理请求,从而避免了请求者和接受者的耦合关系,将这个对象形成一条链,并沿着这条链传递该请求,知道有一个对象处理它为止。主要在三个框架中使用:

1、servlet中的filter

2、dubbo中的filter

3、mybatis中的plugin

5、观察者模式

观察者模式属于行为型模式的一种,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有的观察者对象,使他们可以自动的

更新自己

1、Subject:抽象主题(抽象被观察者),抽象主题角色把所有观察者对象保存在一个集合里,每个主题都可以有任意数量的观察者,抽象主题提供一个接口,可以增加和删除观察者对象。

2、ConcreteSubject:具体主题(具体被观察者),该角色将有关状态存入具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知。

3、Observer:抽象观察者,是观察者者的抽象类,它定义了一个更新接口,使得在得到主题更改通知时更新自己。

4、ConcrereObserver:具体观察者,实现抽象观察者定义的更新接口,以便在得到主题更改通知时更新自身的状态。

48. 写出生产者消费者模式。

生产者消费者模式,就是在一个系统中,存在生产者和消费者两种角色。他们通过内存缓冲区进行通信,生产者生产消费者所需要的资料,消费者把资料做成产品。

实现:生产者是一堆线程,消费者是另外的一堆线程,内存缓冲区可以使用List数组队列,数据类型只需要定义一个简单的类就好。在这个模型中,最关键的就是内存缓冲区为空的时候消费者必须等待,而内存

缓冲区满的时候生产者需要等待。值得注意的是多线程对临界资源操作的时候必须保证在读写的时候只能存在一个线程,这就需要设计锁的策略。

JVM

49. heap和stack区别

java中对象都是分配在heap(堆)中,从heap中分配内存所消耗的时间远远大于stack产生存储空间所需的时间

区别:

1、栈和堆都是java用来在Ram中存放数据的地方,java自动管理栈和堆,程序员不能直接设置栈和堆

2、栈的优势在于存取速度比堆快,仅次于直接位于cpu中的寄存器,但是缺点就是存在栈中的数据大小与生存期必须是确定的。堆的优势在于可以动态的分配内存的大小,java的垃圾收集器会自动回收这些

不能再使用的数据,但 缺点是运行时动态分配内存,存取速度较慢。

50. 描述一下JVM加载Class文件的原理和机制

1、JVM中类的加载是由ClassLoader和它的子类来实现的,Java ClassLoader是一个很重要的java运行时系统组件,他负责在运行时查找和装入类文件的类。java中的所有类,都需要装载到JVM中才能运行,

类加载器本省就是一个类,它的工作就是将class文件从硬盘读取到内存中。

2、类装载的方式有两种:

隐式转载:程序在运行过程中碰道通过new等方式生成对象时,隐式调用类加载器加载对应的类到jvm中

显示装载:通过class.forname()等方法,显示加载需要的类

51. 类加载的五个过程:加载、验证、准备、解析、初始化。

1、加载:加载是类加载过程中的一个阶段,这个阶段会在内存中生成一个代表这个类的java.lang.class对象,作为方法区这个类的各种数据的接口。

2、验证:这一阶段的主要目的是为了确保Class文件中的字节流中包含的信息是否符合当前虚拟机的要求,并且不会危害虚拟机自身的安全

3、准备:准备阶段是正式为类变量分配内存并设置类变量的初始阶段,即在方法区中分配这些变量所需要的内存空间

4、解析:解析阶段是虚拟机将常量池中的符号引用替换为直接引用的过程

5、初始化:初始化阶段是执行类构造器方法的过程,方法是由编辑器自动收集类中的类变量的赋值操作和静态语句块中的语句合并而成的。虚拟机会保证方法执行之前,父类的

方法已经执行完毕

52. JVM的分区:程序计数器、本地方法栈、方法区、栈和堆

GC

53. GC的基本原理

当程序员在创建对象时,GC就开始监控这个对象的地址、大小以及使用情况,GC采用有向图的方式记录和管理堆中的所有对象。通过这种方法来确定哪些对象是“可达的”,哪些是“不可达”的,当确定为“不可达”

时,GC就有责任回收这些内存空间。垃圾回收器可以马上回收内存,程序员可以手动指定system.gc()方法,通知GC进行回收,但是java语言规范并不保证GC一定会执行

54. GC的三种收集方法:标记清除、标记整理、复制算法的原理与特点,分别用在什么地方,如果让你优化收集方法,有什么思路?

1.标记清除算法:首先标记处所有需要回收的对象,在标记完成后统一进行回收。

缺点:标记的过程效率不高、标记清除之后产生大量不连续的内存碎片,当需要申请大块连续内存空间时,无法找到。

2.复制算法:将内存按容量费为大小相等的两块区域,每次只使用其中的一块,当一块内存用完了,就将还存活的对象复制到另一块内存上面,然后吧使用过的那块内存统一清理掉。

缺点:每次只能使用总内存容量的一半。在对象存活较多的情况下会进行大量复制操作,效率底下。

3.标记整理算法:和标记清除算法一样,先对死亡对象进行标记,然后将存活对象向一端移动,然后直接清理掉边界以外的内存。

55. GC收集器有哪些?CMS收集器与G1收集器的特点

1.Serial:一个单线程的收集器,在进行垃圾收集时候,必须暂停其他所有的工作线程直到它收集结束。

特点:CPU利用率最高,停顿时间即用户等待时间比较长。

2.Parallel:采用多线程来通过扫描并压缩

特点:停顿时间短,回收效率高,对吞吐量要求高。

3.CMS收集器:采用“标记-清除”算法实现,使用多线程的算法去扫描堆,对发现未使用的对象进行回收。

4:G1:堆被划分成 许多个连续的区域(region)。采用G1算法进行回收,吸收了CMS收集器特点。

特点:支持很大的堆,高吞吐量、支持多CPU和垃圾回收线程、在主线程暂停的情况下,使用并行收集、在主线程运行的情况下,使用并发收集

56. java中的内存泄漏

java中的内存泄漏广义通俗的说就是:不会再被使用的对象不能被回收。如果长生命周期的对象持有短生命周期的引用,就有可能会出现内存泄漏。

二、Java web部分

1. Cookie与Session的作用与原理

1、cookie是流浪器保存在用户电脑上的一小段文本,用来保存用户在网站上的必要信息。web页面或者服务器告诉浏览器按照一定的规范存储这些信息,并且在以后的所有请求中,这些信息就会自动加在http

请求头中发送给服务器,服务器根据这些信息判断不同的用户,并且cookie本身是安全的

2、session的作用和cookie差不多,但是session是存储在服务器端的,不会在网络中进行传输,所以比cookie更加安全一些。但是session是依赖cookie的,当用户访问某个站点的时候,服务器会为这个用户产生

唯一的session_id,并把这个session_id以cookie的形式,发送到客户端,以后的客户端请求都会自动携带则cookie。

2. 什么时候使用断言(assertion)?

assertion是软件开发中一种常用的调试方式,在现实中,assertion就是程序中的一条语句,他对一个boolean表达式进行检查,一个正确的程序必须保证这个Boolean表达式的值为true,如果返回false,则说明

程序已经处于不正确的状态下,系统会给出警告或者退出。一般来说,assertion用于保护程序最基本、关键的正确性。断言检查通常在开发和测试的过程中开始,在软件发布后是关闭的。

3. jsp的内置对象和作用

JSP有9个内置对象:

request:封装客户端的请求,其中包含来自GET或POST请求的参数;

response:封装服务器对客户端的响应;

pageContext:通过该对象可以获取其他对象;

session:封装用户会话的对象;

application:封装服务器运行环境的对象;

out:输出服务器响应的输出流对象;

config:Web应用的配置对象;

page:JSP页面本身(相当于Java程序中的this);

exception:封装页面抛出异常的对象。

4. jsp有哪些动作,作用是什么?

JSP 共有以下6种基本动作:

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

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

jsp:setProperty:设置JavaBean的属性。

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

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

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

5. Request对象的主要方法

setAttribute(String name,Object):设置名字为name的request的参数值

getAttribute(String name):返回由name指定的属性值

getAttributeNames():返回request对象所有属性的名字集合,结果是一个枚举的实例

getCookies():返回客户端的所有Cookie对象,结果是一个Cookie数组

getCharacterEncoding():返回请求中的字符编码方式

getContentLength():返回请求的Body的长度

getHeader(String name):获得HTTP协议定义的文件头信息

getHeaders(String name):返回指定名字的request Header的所有值,结果是一个枚举的实例

getHeaderNames():返回所以request Header的名字,结果是一个枚举的实例

getInputStream():返回请求的输入流,用于获得请求中的数据

getMethod():获得客户端向服务器端传送数据的方法

getParameter(String name):获得客户端传送给服务器端的有name指定的参数值

getParameterNames():获得客户端传送给服务器端的所有参数的名字,结果是一个枚举的实例

getParameterValues(String name):获得有name指定的参数的所有值

getProtocol():获取客户端向服务器端传送数据所依据的协议名称

getQueryString():获得查询字符串

getRequestURI():获取发出请求字符串的客户端地址

getRemoteAddr():获取客户端的IP地址

getRemoteHost():获取客户端的名字

getSession([Boolean create]):返回和请求相关Session

getServerName():获取服务器的名字

getServletPath():获取客户端所请求的脚本文件的路径

getServerPort():获取服务器的端口号

removeAttribute(String name):删除请求中的一个属性

6. 对于监听器的理解

Java Web开发中的监听器(listener)就是application、session、request三个对象创建、销毁或者往其中添加修改删除属性时自动执行代码的功能组件,如下所示:

①ServletContextListener:对Servlet上下文的创建和销毁进行监听。

②ServletContextAttributeListener:监听Servlet上下文属性的添加、删除和替换。

③HttpSessionListener:对Session的创建和销毁进行监听。

session的销毁有两种情况:1). session超时(可以在web.xml中通过/标签配置超时时间);2). 通过调用session对象的invalidate()方法使session失效。

④HttpSessionAttributeListener:对Session对象中属性的添加、删除和替换进行监听。

⑤ServletRequestListener:对请求对象的初始化和销毁进行监听。

⑥ServletRequestAttributeListener:对请求对象属性的添加、删除和替换进行监听。

7.过滤器的作用以及用法

1、对Web应用来说,过滤器是一个驻留在服务器端的Web组件,它可以截取客户端和服务器之间的请求与响应信息,并对这些信息进行过滤。当Web容器接受到一个对资源的请求时,它将判断是否有过滤器与这个

资源相关联。如果有,那么容器将把请求交给过滤器进行处理。在过滤器中,你可以改变请求的内容,或者重新设置请求的报头信息,然后再将请求发送给目标资源。当目标资源对请求作出响应时候,容器同

样会将响应先转发给过滤器,在过滤器中你可以对响应的内容进行转换,然后再将响应发送到客户端。

2、常见的过滤器用途主要包括:对用户请求进行统一认证、对用户的访问请求进行记录和审核、对用户发送的数据进行过滤或替换、转换图象格式、对响应内容进行压缩以减少传输量、对请求或响应进行加解密

处理、触发资源访问事件、对XML的输出应用XSLT等。

3、和过滤器相关的接口主要有:Filter、FilterConfig和FilterChain。

8. Servlet如何获取用户提交的查询参数以及表单数据

可以通过请求对象(HttpServletRequest)的getParameter()方法通过参数名获得参数值。如果有包含多个值的参数(例如复选框),可以通过请求对象的getParameterValues()方法获得。当然也可以通过请求

对象的getParameterMap()获得一个参数名和参数值的映射(Map)。

9. Servlet的生命周期是什么?是否是单例?

Servlet 生命周期可被定义为从创建直到毁灭的整个过程。以下是 Servlet 遵循的过程:

Servlet 通过调用 init () 方法进行初始化。

Servlet 调用 service() 方法来处理客户端的请求。

Servlet 通过调用 destroy() 方法终止(结束)。

最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。

Servlet单实例,减少了产生servlet的开销

10. MVC各个部分都有哪些技术来实现

MVC 是Model-View-Controller的简写。”Model” 代表的是应用的业务逻辑(通过JavaBean,EJB组件实现), “View” 是应用的表示面,用于与用户的交互(由JSP页面产生),”Controller” 是提供应用的处

理过程控制(一般是一个Servlet),通过这种设计模型把应用逻辑,处理过程和显示逻辑分成不同的组件实现。这些组件可以进行交互和重用。model层实现系统中的业务逻辑,view层用于与用户的交互,

controller层是model与view之间沟通的桥梁,可以分派用户的请求并选择恰当的视图以用于显示,同时它也可以解释用户的输入并将它们映射为模型层可执行的操作。

三、数据库部分

1、sql语句的书写、执行顺序

书写顺序:

select--from--where--group by--having--order by

其中select和from是必须的,其他关键词是可选的

执行顺序

from--where--group by--having--select--order by,

from:需要从哪个数据表检索数据

where:过滤表中数据的条件

group by:如何将上面过滤出的数据分组

having:对上面已经分组的数据进行过滤的条件

select:查看结果集中的哪个列,或列的计算结果

order by :按照什么样的顺序来查看返回的数据

2、数据库事务的四个特性及含义

原子性(Atomic):事务中各项操作,要么全做要么全不做,任何一项操作的失败都会导致整个事务的失败;

一致性(Consistent):事务结束后系统状态是一致的;

隔离性(Isolated):并发执行的事务彼此无法看到对方的中间状态;

持久性(Durable):事务完成后所做的改动都会被持久化,即使发生灾难性的失败。通过日志和同步备份可以在故障发生后重建数据。

3、数据库优化

1、选取最实用的字段属性:字段的大小设计较为严谨的话,一方面可以减小资源空间的浪费,另一方面可以加快查询的速度

2、使用连接代替子查询

3、临时表的使用

临时表的使用有好有坏,但对于大量的数据操作来说,还是利大于弊的。

好处:减少阻塞,提高并发性

弊端:频繁建立和删除临时表,浪费系统的资源

4、使用事物。保持事物的一致性和完整性是较为重要的

4. sql语句的优化

1、避免全表查询,考虑建立索引

查询的过程中查询所需要的关键字段,全表查询会浪费大量的时间

合理的建立索引会大大的提高sql的效率,但索引并不是越多越好,数据的插入和删除会重新建立索引和修改索引,会消耗大量的时间。

2、避免在where子句中进行如下的操作,这都将导致引擎放弃使用索引而进行全表扫描

进行null值判断(最好不要给数据库留null)、

使用!=或<>操作符、

使用模糊查询like、

对字段进行表达式操作或函数操作

3、尽量避免在where子句中使用or来连接查询条件,如果一个字段有索引,一个字段没有索引,将导致引擎放弃使用索引而进行全表扫描;可以使用union all来代替or;

4、慎用in和not in,这也会导致全表扫描;对于连续的数值,可以用between代替in;

5、很多时候可以用exists代替in;

6、存储过程

四、手写代码

1. 常用的排序算法

2. 二分查找

2. 递归读取文件夹中的文件

3. 给定txt文件,如何得到某字符串出现的次数

4. 写出单例模式和工厂模式

5. 用 wait-notify 写一段代码来解决生产者-消费者问题?

6. 用 1,2 , 2 ,3, 4 ,5 这 6个数字, 用 Java 写一个 main 函数, 打印出所有不同的排列

7. 一个数如果恰好等于它的因子之和, 这个数就称为” ” 完数” ”. 例如 6 = 1+2+3 。 编程找出0 1000 以内的所有完数

五、J2SE部分

Hibernate和Mybatis的区别。

Spring MVC和Struts2的区别。

Spring用了哪些设计模式。

Spring中AOP主要用来做什么。

Spring注入bean的方式。

什么是IOC,什么是依赖注入。

Spring是单例还是多例,怎么修改。

Spring事务隔离级别和传播性。

介绍下Mybatis/Hibernate的缓存机制。

Mybatis的mapper文件中#和$的区别。

Mybatis的mapper文件中resultType和resultMap的区别。

Mybatis中DAO层接口没有写实现类,Mapper中的方法和DAO接口方法是怎么绑定到一起的,其内部是怎么实现的。

(注:手写代码部分和J2SE部分没有给出详细的解答,答案都可以在其他的网络资源上找到,核心重点在于前面的基础部分。)

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注