面试题及答案

来源:互联网 发布:java thread import 编辑:程序博客网 时间:2024/04/29 21:00

1.作用域public,private,protected以及不写时的区别:

作用域 当前类 同一package 子孙类 其他package

public √ √ √ √

protected √ √ √ ×

friendly √ √ × ×

private √ × × ×

2.说明一下java的collections中List,Set和Map的联系和区别

首先list与set都继承于Collection,list序列的形式存储元素。所以取出来的顺序可能和放入顺序不同。set的特点是无法存放重复的元素。map一个映射不能包含重复的键;每个键最多只能映射一个值。以键值对存放数据以上三个都是接口且不能被实例化。

3.String,StringBuilder,StringBuffer的区别

1.三者在执行速度方面的比较:StringBuilder > StringBuffer > String
2.String <(StringBuffer,StringBuilder)的原因

    String:字符创常量

    StringBuffer:字符串变量

    StringBuilder:字符串变量

    从上面的名字可以看到,String是“字符创常量”,也就是不可改变的对象。对于这句话的理解你可能会产生这样一个疑问 ,比如这段代码:

1 String s = "abcd";2 s = s+1;3 System.out.print(s);// result : abcd1

我们明明就是改变了String型的变量s的,为什么说是没有改变呢? 其实这是一种欺骗,JVM是这样解析这段代码的:首先创建对象s,赋予一个abcd,然后再创建一个新的对象s用来执行第二行代码,也就是说我们之前对象s并没有变化,所以我们说String类型是不可改变的对象了,由于这种机制,每当用String操作字符串时,实际上是在不断的创建新的对象,而原来的对象就会变为垃圾被GC回收掉,可想而知这样执行效率会有多低。

    而StringBuffer与StringBuilder就不一样了,他们是字符串变量,是可改变的对象,每当我们用它们对字符串做操作时,实际上是在一个对象上操作的,这样就不会像String一样创建一些而外的对象进行操作了,当然速度就快了。
3.一个特殊的例子:

1 String str = “This is only a” + “ simple” + “ test”;3 StringBuffer builder = new StringBuilder(“This is only a”).append(“ simple”).append(“ test”);

你会很惊讶的发现,生成str对象的速度简直太快了,而这个时候StringBuffer居然速度上根本一点都不占优势。其实这是JVM的一个把戏,实际上:

    String str = “This is only a” + “ simple” + “test”;

    其实就是:

    String str = “This is only a simple test”;

    所以不需要太多的时间了。但大家这里要注意的是,如果你的字符串是来自另外的String对象的话,速度就没那么快了,譬如:

    String str2 = “This is only a”;

    String str3 = “ simple”;

    String str4 = “ test”;

    String str1 = str2 +str3 + str4;

    这时候JVM会规规矩矩的按照原来的方式去做。
4.StringBuilder与 StringBuffer

    StringBuilder:线程非安全的

    StringBuffer:线程安全的

    当我们在字符串缓冲区被多个线程使用时,JVM不能保证StringBuilder的操作是安全的,虽然他的速度最快,但是可以保证StringBuffer是可以正确操作的。当然大多数情况下就是我们是在单线程下进行的操作,所以大多数情况下是建议用StringBuilder而不用StringBuffer的,就是速度的原因。

对于三者使用的总结:
1.如果要操作少量的数据用 = String

2.单线程操作字符串缓冲区 下操作大量数据 = StringBuilder

3.多线程操作字符串缓冲区 下操作大量数据 = StringBuffer

4.Java中线程的四种状态分别是什么?sleep()和wait()有什么区别?

  1. 新建状态(New):新创建了一个线程对象。
  2. 就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权。
  3. 运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。
  4. 阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:
    (一)、等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。
    (二)、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池中。
    (三)、其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
  5. 死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。
  6. 区别:sleep()使线程停止段间sleep 间间隔期满线程定立即恢复执行刻其线程能运行且没调度放弃执行除非(a)”醒”线程具更高优先级 (b)运行线程其原阻塞wait()线程交互线程同步象x 发wait()调用该线程暂停执行调象进入等待状态直唤醒或等待间。
    sleep指线程被调用时,占着CPU不工作,形象地说明为“占着CPU睡觉”,此时,系统的CPU部分资源被占用,其他线程无法进入,会增加时间限制。
    wait指线程处于进入等待状态,形象地说明为“等待使用CPU”,此时线程不占用任何资源,不增加时间限制。
    所以
    sleep(100L)意思为:占用CPU,线程休眠100毫秒
    wait(100L)意思为:不占用CPU,线程等待100毫秒

5.多线程有几种实现方法,都是什么?

多线程有两种实现方法:
      方法一:继承Thread类,重写方法run();
      方法二:实现Runnable接口,实现方法run();
  实现同步有几种方法:例如:synchronized,wait,notify都可以实现同步。

6.怎样建立socket连接?建立连接时,客户端和服务端有什么区别?

//创建Socket 客户端对象
Socket s = new Socket(“127.0.0.1”,6666);

//创建ServerSocket 服务器端对象。。
ServerSocket ss = new ServerSocket(6666);
//监听服务器连接
s = ss.accept();
(客户端和服务端的区别没总结!!!!!!!)

7.servlet和Jsp之间的关系是什么?servlet API中forward()和redirect()的区别?

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

2request.getRequestDispatcher(“apage.jsp”).forward(request, response);//转发到apage.jsp

response.sendRedirect(“apage.jsp”);//重定向到apage.jsp
1.从地址栏显示来说
forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服务器发送的内容从哪里来的,所以它的地址栏还是原来的地址.
redirect是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址.所以地址栏显示的是新的URL.
2.从数据共享来说
forward:转发页面和转发到的页面可以共享request里面的数据.
redirect:不能共享数据.
3.从运用地方来说
forward:一般用于用户登陆的时候,根据角色转发到相应的模块.
redirect:一般用于用户注销登陆时返回主页面和跳转到其它的网站等.
4.从效率来说
forward:高.
redirect:低.

用重定向和转发不是一个习惯问题。而是什么情况下必须用什么的问题。

不要仅仅为了把变量传到下一个页面而使用session作用域,那会无故增大变量的作用域,转发也许可以帮助你解决这个问题。

重定向:以前的request中存放的变量全部失效,并进入一个新的request作用域。

转发:以前的request中存放的变量不会失效,就像把两个页面拼到了一起。

forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器,浏览器根本不知道服务器发送的内容是从哪儿来的,所以它的地址栏中还是原来的地址。

redirect就是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址, web应用程序会要求客户端浏览器重新发出请求地址,客户端会重新连接至所指定的地址,因此浏览器的地址会出现重新导向的信息,重新导向后的请求由浏览器发出。

forward与include共享Request范围内的对象,而redirect则不行,

forward与include基本上都是转发到context内部的资源,而redirect可以重定向到外部的资源

8.JPA Annotation中常用的类有哪些,都有什么作用?

(未整理)

9.说下Struts的设计模式,Struts的validate 框架是如何验证的?

1.装饰模式(Decorator ):对象的一种结构模式,能够动态的为一个对象添加一些额外的行为职责。解决过度依赖使用继承来进行对象的功能扩展
HttpServletRequestWrapper和HttpServletResponseWrapper对HttpServletRequest对象和HttpServletResponse对象装饰,在Filter中可以使用继承wrapper的类来修改请求或响应对象。
2.策略模式:针对一组算法货行为特性,将它们抽象到具有共同接口函数的独立抽象类或接口中,从而使得他们可以相互替换。当一个业务场景可能具备多种行为,且多种行为之间可以进行替换时,可讲它们的行为特性的公共部分进行抽象,并最终形成一个统一接口的过程。
3.验证方式:
方法一:Action类继承ActionSupport类,其中ActionSupport实现了Validateable接口,并定义了validation方法,只要在用户自定义的Action类中重写该方法就可以实现该功能。

其中错误信息可以通过addFieldError方法将错误信息保存起来。

方法二:在Action类的文件的路径下,添加一个校验文件ActionName-validation.xml,并配置校验器

10.说说AOP和IOC的概念以及在spring中是如何应用的。介绍一下spring的事务管理。

1.依赖注入(Dependecy Injection)和控制反转(Inversion of Control)是同一个概念

具体的讲:当某个角色需要另外一个角色协助的时候,在传统的程序设计过程中,通常由调用者来创建被调用者的实例。但在spring中创建被调用者的工作不再由调用者来完成,因此称为控制反转。创建被调用者的工作由spring来完成,然后注入调用者
因此也称为依赖注入。
spring以动态灵活的方式来管理对象 , 注入的两种方式,设值注入和构造注入。
设值注入的优点:直观,自然
构造注入的优点:可以在构造器中决定依赖关系的顺序

2.Spring的事务管理机制实现的原理

就是通过这样一个动态代理对所有需要事务管理的Bean进行加载,并根据配置在invoke方法中对当前调用的 方法名进行判定,并在method.invoke方法前后为其加上合适的事务管理代码,这样就实现了Spring式的事务管理。Spring中的AOP实 现更为复杂和灵活,不过基本原理是一致的。

11.Hibernate工作原理 以及为什么要用?说说你对hibernate缓存的理解。

1.hibernate工作原理:

1.通过Configuration config = new Configuration().configure();//读取并解析hibernate.cfg.xml配置文件
2.由hibernate.cfg.xml中的读取并解析映射信息
3.通过SessionFactory sf = config.buildSessionFactory();//创建SessionFactory
4.Session session = sf.openSession();//打开Sesssion
5.Transaction tx = session.beginTransaction();//创建并启动事务Transation
6.persistent operate操作数据,持久化操作
7.tx.commit();//提交事务
8.关闭Session
9.关闭SesstionFactory

2.说下Hibernate的缓存机制:

Hibernate缓存的作用:
Hibernate是一个持久层框架,经常访问物理数据库,为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能。缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据,在特定的时刻或事件会同步缓存和物理数据源的数据
Hibernate缓存分类:
Hibernate缓存包括两大类:Hibernate一级缓存和Hibernate二级缓存
Hibernate一级缓存又称为“Session的缓存”,它是内置的,意思就是说,只要你使用hibernate就必须使用session缓存。由于Session对象的生命周期通常对应一个数据库事务或者一个应用事务,因此它的缓存是事务范围的缓存。在第一级缓存中,持久化类的每个实例都具有唯一的OID。
Hibernate二级缓存又称为“SessionFactory的缓存”,由于SessionFactory对象的生命周期和应用程序的整个过程对应,因此Hibernate二级缓存是进程范围或者集群范围的缓存,有可能出现并发问题,因此需要采用适当的并发访问策略,该策略为被缓存的数据提供了事务隔离级别。第二级缓存是可选的,是一个可配置的插件,在默认情况下,SessionFactory不会启用这个插件。

什么样的数据适合存放到第二级缓存中?   
1 很少被修改的数据   
2 不是很重要的数据,允许出现偶尔并发的数据   
3 不会被并发访问的数据   
4 常量数据   
不适合存放到第二级缓存的数据?   
1经常被修改的数据   
2 .绝对不允许出现并发访问的数据,如财务数据,绝对不允许出现并发   
3 与其他应用共享的数据。

Hibernate查找对象如何应用缓存?
当Hibernate根据ID访问数据对象的时候,首先从Session一级缓存中查;查不到,如果配置了二级缓存,那么从二级缓存中查;如果都查不到,再查询数据库,把结果按照ID放入到缓存
删除、更新、增加数据的时候,同时更新缓存

Hibernate管理缓存实例
无论何时,我们在管理Hibernate缓存(Managing the caches)时,当你给save()、update()或saveOrUpdate()方法传递一个对象时,或使用load()、 get()、list()、iterate() 或scroll()方法获得一个对象时, 该对象都将被加入到Session的内部缓存中。
当随后flush()方法被调用时,对象的状态会和数据库取得同步。 如果你不希望此同步操作发生,或者你正处理大量对象、需要对有效管理内存时,你可以调用evict() 方法,从一级缓存中去掉这些对象及其集合。

11.WEB Service名词解释。JSWDL开发包的介绍SOAP,UDDI,WSDL介绍。

Web Service是基于网络的、分布式的模块化组件,它执行特定的任务,遵守具体的技术规范,这些规范使得Web Service能与其他兼容的组件进行互操作。
  JAXP(Java API for XML Parsing) 定义了在Java中使用DOM, SAX, XSLT的通用的接口。这样在你的程序中你只要使用这些通用的接口,当你需要改变具体的实现时候也不需要修改代码。
  JAXM(Java API for XML Messaging) 是为SOAP通信提供访问方法和传输机制的API。
  WSDL是一种 XML 格式,用于将网络服务描述为一组端点,这些端点对包含面向文档信息或面向过程信息的消息进行操作。这种格式首先对操作和消息进行抽象描述,然后将其绑定到具体的网络协议和消息格式上以定义端点。相关的具体端点即组合成为抽象端点(服务)。
  SOAP即简单对象访问协议(Simple Object Access Protocol),它是用于交换XML编码信息的轻量级协议。
  UDDI 的目的是为电子商务建立标准;UDDI是一套基于Web的、分布式的、为Web Service提供的、信息注册中心的实现标准规范,同时也包含一组使企业能将自身提供的Web Service注册,以使别的企业能够发现的访问协议的实现标准

12.XML有哪些解析技术,有什么区别?

有DOM,SAX,STAX等
DOM:处理大型文件是其性能下降的非常厉害,这个问题是由DOM的树结构造成的,这种结构占用的内存较多,而且DOM必须在解析文件之前把整个文档装入内存,适合对xml的随机访问,sax:不现于,DOM,SAX是事件驱动型的xml解析方式,他顺序的读取xml文件,不需要自已全部装载正文件,当遇到文档开头,文档结束,或者标签开都与标签结束时,他会触发一个事件,用于通过在其回调事件中写入处理代码来处理xml文件,适合对xml的顺序访问。Stax:StreamingAPIforxml(Stax)。

13.写出单例模式

1.懒汉式(线程不安全)

public class Singleton {    private static Singleton instance;    private Singleton (){}    public static Singleton getInstance() {    if (instance == null) {        instance = new Singleton();    }    return instance;    }}

懒汉式(线程安全)

public class Singleton {    private static Singleton instance;    private Singleton (){}    public static synchronized Singleton getInstance() {    if (instance == null) {        instance = new Singleton();    }    return instance;    }}

2.饿汉式

public class Singleton {    private static Singleton instance = new Singleton();    private Singleton (){}    public static Singleton getInstance() {    return instance;    }}

14.冒泡排序

/* * 冒泡排序 */public class BubbleSort {  public static void main(String[] args) {    int[] arr={6,3,8,2,9,1};    System.out.println("排序前数组为:");    for(int num:arr){      System.out.print(num+" ");    }    for(int i=0;i<arr.length-1;i++){//外层循环控制排序趟数      for(int j=0;j<arr.length-1-i;j++){//内层循环控制每一趟排序多少次        if(arr[j]>arr[j+1]){          int temp=arr[j];          arr[j]=arr[j+1];          arr[j+1]=temp;        }      }    }     System.out.println();    System.out.println("排序后的数组为:");     for(int num:arr){       System.out.print(num+" ");     }   } }
原创粉丝点击