java面试题目

Posted ityangshuai

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java面试题目相关的知识,希望对你有一定的参考价值。

  1. String s = new String("xyz"); 创建了几个StringObject?是否可以继承String类?
    String s=new String("xyz")究竟对象个数分为两种情况:
    1.如果String常理池中,已经创建"xyz",则不会继续创建,此时只创建了一个对象new String("xyz");
    2.如果String常理池中,没有创建"xyz",则会创建两个对象,一个对象的值是"xyz",一个对象new String("xyz")。
    
    不可以,因为String类有final修饰符,而final修饰的类是不能被继承的,实现细节不允许改变。
    

      

  2. StringBuffer 和 StringBuilder的区别
    当对字符串进行修改的时候,需要使用 StringBuffer 和 StringBuilder 类。
    和 String 类不同的是,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。
    StringBuilder 类在 Java 5 中被提出,它和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。
    由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。
    小结:(1)如果要操作少量的数据用 String;
         (2)多线程操作字符串缓冲区下操作大量数据 StringBuffer;
         (3)单线程操作字符串缓冲区下操作大量数据 StringBuilder。
    

      

  3. error 和exception有什么区别
    首先Exception和Error都是继承于Throwable 类,在 Java 中只有 Throwable 类型的实例才可以被抛出(throw)或者捕获(catch),它是异常处理机制的基本组成类型。
    
    Exception和Error体现了JAVA这门语言对于异常处理的两种方式。
    
    Exception是java程序运行中可预料的异常情况,咱们可以获取到这种异常,并且对这种异常进行业务外的处理。
    
    Error是java程序运行中不可预料的异常情况,这种异常发生以后,会直接导致JVM不可处理或者不可恢复的情况。所以这种异常不可能抓取到,比如OutOfMemoryError、NoClassDefFoundError等。
    
    其中的Exception又分为检查性异常和非检查性异常。两个根本的区别在于,检查性异常 必须在编写代码时,使用try catch捕获(比如:IOException异常)。非检查性异常 在代码编写使,可以忽略捕获操作(比如:ArrayIndexOutOfBoundsException),这种异常是在代码编写或者使用过程中通过规范可以避免发生的。
    

      

  4. 什么是java序列化,如何实现java序列化?或者解释Serializable接口的作用
    .序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化(将对象转换成二进制)。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间,序列化是为了解决在对对象流进行读写操作时所引发的问题。把对象转换为字节序列的过程称为对象的序列化,把字节序列恢复为对象的过程称为对象的反序列化。
    .序列化的实现:将需要被序列化的类实现Serializable接口,该接口没有需要实现的方法,implements Serializable只是为了标注该对象是可被序列化的,然后使用一个输出流(如:FileOutputStream)来构造一个ObjectOutputStream(对象流)对象,接着,使用ObjectOutputStream对象的writeObject(Object obj)方法就可以将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。
    .对象的序列化主要有两种用途:
     1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;
     2) 在网络上传送对象的字节序列。
           在很多应用中,需要对某些对象进行序列化,让它们离开内存空间,入住物理硬盘,以便长期保存。比如最常见的是Web服务器中的Session对象,当有10万用户并发访问,就有可能出现10万个Session对象,内存可能吃不消,于是Web容器就会把一些seesion先序列化到硬盘中,等要用了,再把保存在硬盘中的对象还原到内存中。
           当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个Java对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为Java对象。
    

     

  5. 描述一下JVM加载class文件的原理机制,反射机制是如何拿到对应的class对象?

    JVM将类加载过程分为三个步骤:装载(Load),链接(Link)和初始化(Initialize)链接又分为三个步骤,如下图所示:
    
    1) 装载:查找并加载类的二进制数据;
    2)链接:
      验证:确保被加载类的正确性;
      准备:为类的静态变量分配内存,并将其初始化为默认值;
      解析:把类中的符号引用转换为直接引用;
    3)初始化:为类的静态变量赋予正确的初始值;
              那为什么我要有验证这一步骤呢?首先如果由编译器生成的class文件,它肯定是符合JVM字节码格式的,但是万一有高手自己写一个class文件,让JVM加载并运行,用于恶意用途,就不妙了,因此这个class文件要先过验证这一关,不符合的话不会让它继续执行的,也是为了安全考虑吧。
            准备阶段和初始化阶段看似有点矛盾,其实是不矛盾的,如果类中有语句:private static int a = 10,它的执行过程是这样的,首先字节码文件被加载到内存后,先进行链接的验证这一步骤,验证通过后准备阶段,给a分配内存,因为变量a是static的,所以此时a等于int类型的默认初始值0,即a=0,然后到解析,到初始化这一步骤时,才把a的真正的值10赋给a,此时a=10。
    
    反射最大的好处是解耦。
    获取Class对象的三种方式:
      1):通过对象的getClass方法进行获取。这种方式需要具体的类和该类的对象,以及调用getClass方法。
      2):任何数据类型(包括基本数据类型)都具备着一个静态的属性class,通过它可直接获取到该类型对应的Class对象。这种方式要使用具体的类,然后调用类中的静态属性class完成,无需调用方法,性能更好。
      3):通过Class.forName()方法获取。这种方式仅需使用类名,就可以获取该类的Class对象,更有利于扩展。
    

      

  6. Servlet API 中 forward() 与 redirect()的区别?

    1、 forward是服务器端的转向也就是请求转发而redirect是客户端的跳转也就是重定向
    2、 使用forward浏览器的地址不会发生改变。而redirect会发生改变。
    3、 forward是一次请求中完成。而redirect是重新发起请求。
    4、 forward是在服务器端完成,而不用客户端重新发起请求,效率较高。
    

      

  7. request.getAttribute()  和 request.getParameter() 有何区别?

    getParameter 是用来接受用post和get方法传递过来的参数的.
    getAttribute 必须先setAttribute.
    
    (1)request.getParameter() 取得是通过容器的实现来取得通过类似post,get等方式传入的数据,request.setAttribute()和getAttribute()只是在web容器内部流转,仅仅是请求处理阶段。
    
    (2)request.getParameter() 方法传递的数据,会从Web客户端传到Web服务器端,代表HTTP请求数据。request.getParameter()方法返回String类型的数据。
    
    request.setAttribute() 和 getAttribute() 方法传递的数据只会存在于Web容器内部
    
    还有一点就是,HttpServletRequest 类有 setAttribute() 方法,而没有setParameter() 方法。
    

      

  8. 什么是Cookie? Session和cookie有什么区别?
    首先一种场景, 在一个网站上面, 我发起一次请求,那服务器怎么知道我是谁?是谁发起的这次请求呢,  HTTP协议是无状态的协议, 浏览器的每一次请求,服务器都当做一次新请求, 但是在实际应用中我们需要知道这个请求来自于谁,需要查找哪些信息返回给访问者,
    
    这个时候就引入了COOKIE机制, COOKIE机制是什么呢? 
    Cookie实际上是一小段的文本信息。其实就是服务器给客户端返回数据的时候,中间加了一个标识, 然后客户端再次请求数据的时候,数据中带上这个标识, 那么服务器接收到请求消息时就知道这个请求来自于谁了(相当于服务器接收到请求时,如果没有带识别码,生成一个识别码给客户端, 如果有识别码,就把这个识别码需要的对应内容返回给客户端)
    
    
    cookie保存在客户端,比较不安全;session保存在服务器端,比较安全。
    
    cookie目的可以跟踪会话,也可以保存用户喜好或者保存用户名密码,session用来跟踪会话。
    

      

  9. tomcat 容器是如何创建servlet 类实例? 用到了什么原理?
    当容器启动时,会读取在 webapps 目录下所有的 web 应用中的 web.xml 文 件,然后对 xml 文件进行解析,并读取 servlet 注册信息。然后,将每个应用中注册的 servlet 类都进行加载, 并通过反射的方式实例化。(有时候也是在第一次请求时实例化)在 servlet 注册时加上如果为正数,则在 一开始就实例化,如果不写或为负数,则第一次请求实例化。

     

  10. 数据库连接池的原理,为什么要使用连接池?
    数据库连接是一件费时的操作,连接池可以使多个操作共享一个连接。 
    数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。我们可以通过设定连接池最大连接数来防止系统无尽的与数据库连接。更为重要的是我们可以通过连接池的管理机制监视数据库的连接的数量、使用情况,为系统开发,测试及性能调整提供依据。 
    连接池的工作原理主要由三部分组成,分别为
      连接池的建立
      连接池中连接的使用管理
      连接池的关闭
            第一、连接池的建立。一般在系统初始化时,连接池会根据系统配置建立,并在池中创建了几个连接对象,以便使用时能从连接池中获取。连接池中的连接不能随意创建和关闭,这样避免了连接随意建立和关闭造成的系统开销。Java中提供了很多容器类可以方便的构建连接池,例如Vector、Stack等。
    
            第二、连接池的管理。连接池管理策略是连接池机制的核心,连接池内连接的分配和释放对系统的性能有很大的影响。其管理策略是:
    
            当客户请求数据库连接时,首先查看连接池中是否有空闲连接,如果存在空闲连接,则将连接分配给客户使用;如果没有空闲连接,则查看当前所开的连接数是否已经达到最大连接数,如果没达到就重新创建一个连接给请求的客户;如果达到就按设定的最大等待时间进行等待,如果超出最大等待时间,则抛出异常给客户。
    
            当客户释放数据库连接时,先判断该连接的引用次数是否超过了规定值,如果超过就从连接池中删除该连接,否则保留为其他客户服务。
    
            该策略保证了数据库连接的有效复用,避免频繁的建立、释放连接所带来的系统资源开销。
    
            第三、连接池的关闭。当应用程序退出时,关闭连接池中所有的连接,释放连接池相关的资源,该过程正好与创建相反。
    
    使用连接池是为了提高对数据库连接资源的管理

     

  11. 使用spring框架的好处是什么?
    1、轻量: Spring 是轻量的,基本的版本大约2MB。 
    2、控制反转: Spring通过控制反转实现了松散耦合,对象们给出它们的依赖,而不是创建或查找依赖的对象们。 
    3、面向切面的编程(AOP): Spring支持面向切面的编程,并且把应用业务逻辑和系统服务分开。 
    4、容器: Spring 包含并管理应用中对象的生命周期和配置。 
    5、MVC框架: Spring的WEB框架是个精心设计的框架,是Web框架的一个很好的替代品。 
    6、事务管理: Spring 提供一个持续的事务管理接口,可以扩展到上至本地事务下至全局事务(JTA)。 
    7、异常处理: Spring 提供方便的API把具体技术相关的异常(比如由JDBC,Hibernate or JDO抛出的)转化为一致的unchecked 异常。

     

  12. springMVC的开发模式,执行流程
    SpringMVC流程:
    
    01、用户发送出请求到前端控制器DispatcherServlet。
    
    02、DispatcherServlet收到请求调用HandlerMapping(处理器映射器)。
    
    03、HandlerMapping找到具体的处理器(可查找xml配置或注解配置),生成处理器对象及处理器拦截器(如果有),再一起返回给DispatcherServlet。
    
    04、DispatcherServlet调用HandlerAdapter(处理器适配器)。
    
    05、HandlerAdapter经过适配调用具体的处理器(Handler/Controller)。
    
    06、Controller执行完成返回ModelAndView对象。
    
    07、HandlerAdapter将Controller执行结果ModelAndView返回给DispatcherServlet。
    
    08、DispatcherServlet将ModelAndView传给ViewReslover(视图解析器)。
    
    09、ViewReslover解析后返回具体View(视图)。
    
    10、DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。
    
    11、DispatcherServlet响应用户。

     

  13. 简单的说一下MyBatis的一级缓存和二级缓存
    mybatis的有两种缓存,一级缓存和二级缓存。两个缓存的不同点和相同点总结如下
    
    不同点:
    
      一级缓存存在于一个SqlSession之内,二级缓存存在于不同的SqlSession之间
      一级缓存不需要手动开启,属于默认开启状态;二级缓存需要手动开启
    相同点: 在增删改SQL之后,缓存会自动清空 flushCache
    ="true"的查询语句查询内容不存放进缓存

    一级缓存是mybatis自带的缓存,mybatis每次在查询后,会将语句和参数相同的查询SQL的结果集存放进缓存,待下一次有相同的语句和参数时,mybatis直接将缓存内的结果集返回,而不再查询数据库。如果对于缓存的数据对应的表有增删改操作的话,缓存自动清空。
    相较于一级缓存的自动默认开启,二级缓存需要手动开启。一级缓存在同一个SqlSession内,以SqlSession为缓存单位;二级缓存在不同的SqlSession间,以mapper为单位,即不同的SqlSession间可以共享相同的mapper下接口查询的数据。

     

  14. redis和数据库的同步时如何实现的?
     1:读取数据的时候先从redis里面查,若没有,再去数据库查,同时写到redis里面,并且要设置失效时间。
     2:存数据的时候要具体情况具体分析,可以选择同时插到数据库和redis(要是存放到redis中,最好设置失效时间),也可以选择直接插到数据库里面,少考虑一些问题。

     

以上是关于java面试题目的主要内容,如果未能解决你的问题,请参考以下文章

Java工程师面试题,二级java刷题软件

片段(Java) | 机试题+算法思路+考点+代码解析 2023

面试常用的代码片段

面向面试编程代码片段之GC

经验总结:Java高级工程师面试题-字节跳动,成功跳槽阿里!

java常见面试题目