• Java基础面试题总结二


     1,什么是字符串常量池?

      字符串的分配,和其他的对象分配一样,耗费高昂的时间与空间代价。JVM为了提高性能和减少内存开销,在实例化字符串常量的时候进行了一些优化。为 了减少在JVM中创建的字符串的数量,字符串类维护了一个字符串池,每当代码创建字符串常量时,JVM会首先检查字符串常量池。如果字符串已经存在池中, 就返回池中的实例引用。如果字符串不在池中,就会实例化一个字符串并放到池中。Java能够进行这样的优化是因为字符串是不可变的,可以不用担心数据冲突 进行共享。

    2,重载和重写的区别?

    ①重写:

      表示子类中的方法可以与父类中的某个方法的名称和参数完全相同,通过子类创建的实例对象调用这个方法时,将调用子类中的定义方法,这相当于把父类中定义的那个完全相同的方法给覆盖了,这也是面向对象编程的多态性的一种表现。子类覆盖父类的方法时,只能比父类抛出更少的异常,或者是抛出父类抛出的异常的子异常,因为子类可以解决父类的一些问题,不能比父类有更多的问题。子类方法的访问权限只能比父类的更大,不能更小。如果父类的方法是private类型,那么,子类则不存在覆盖的限制,相当于子类中增加了一个全新的方法。

    ②重载:

      在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同甚至是参数顺序不同)则视为重载。同时,重载对返回类型没有要求,可以相同也可以不同,但不能通过返回类型是否相同来判断重载。

    总结:

      方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。重载发生在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同或者二者都不同)则视为重载;重写发生在子类与父类之间,重写要求子类被重写方法与父类被重写方法有相同的参数列表,有兼容的返回类型,比父类被重写方法更好访问,不能比父类被重写方法声明更多的异常(里氏代换原则)。重载对返回类型没有特殊的要求,不能根据返回类型进行区分。
    ————————————————

    https://blog.csdn.net/wintershii/article/details/80558739

    3,throw和throws的区别?

      throws是用来声明一个方法可能抛出的所有异常信息,throws是将异常声明但是不处理,而是将异常往上传,谁调用我就交给谁处理。而throw则是指抛出的一个具体的异常类型。throw代表动作,表示抛出一个异常的动作;throws代表一种状态,代表方法可能有异常抛出;throw用在方法实现中,而throws用在方法声明中;throw只能用于抛出一种异常,而throws可以抛出多个异常。

    4,hashmap实现原理?

      HashMap采用了(数组 + 链表 + 红黑树)的实现结构,数组的一个元素称作位桶。

      HashMap基于hashing原理,我们通过put()和get()方法储存和获取对象。当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算hashcode,让后找到bucket位置来储存值对象。当获取对象时,通过键对象的equals()方法找到正确的键值对,然后返回值对象。如果该位置中没有元素,则直接把元素存储在此位置,如果该位置有元素了,则把元素以链表的形式存放在链表的尾部。HashMap使用链表来解决碰撞问题,当发生碰撞了,对象将会储存在链表的下一个节点中。 HashMap在每个链表节点中储存键值对对象。

      当两个不同的键对象的hashcode相同时会发生什么? 它们会储存在同一个bucket位置的链表中。键对象的equals()方法用来找到键值对。

    hashmap和hashtable的区别:

      ①HashMap可以接受为null的键值(key)和值(value),而Hashtable则不行。

      ②HashMap是非synchronized,而Hashtable是synchronized,这意味着Hashtable是线程安全的,多个线程可以共享一个Hashtable;而如果没有正确的同步的话,多个线程是不能共享HashMap的。Java 5提供了ConcurrentHashMap,它是HashTable的替代,比HashTable的扩展性更好。

      ③HashMap的迭代器(Iterator)是fail-fast迭代器,而Hashtable的enumerator迭代器不是fail-fast的。

      ④由于Hashtable是线程安全的也是synchronized,所以在单线程环境下它比HashMap要慢。如果你不需要同步,只需要单一线程,那么使用HashMap性能要好过Hashtable

      ⑤Hashtable每次扩容,容量都为原来的2倍加1,而HashMap为原来的2倍。

    5,什么是Servlet,Servlet生命周期方法?

      Servlet是一个基于Java技术的动态网页技术,运行在服务器端,由Servlet容器管理,用于生产动态的内容。是jsp的前身。

      Servlet是平台独立的符合特定规范的java类,编写一个Servlet实际上就是按照Servlet规范编写一个java类。

      Servlet不是由用户或程序直接调用,而是由容器管理,没有main方法。

    生命周期方法:

      init()

      service()

      destory()

    Servlet运行过程:

      ①类加载

      ②Web服务器首先检查是否已经装载并创建了该Servlet的实例对象。如果是,则直接执行第⑤步,否则,执行第③步。

      ③装载并创建该Servlet的一个实例对象。 

      ④调用Servlet实例对象的init()方法。

      ⑤创建一个用于封装HTTP请求消息的HttpServletRequest对象和一个代表HTTP响应消息的HttpServletResponse对象,然后调用Servlet的service()方法,根据提交方式选择执行doGet()方法或者doPost()方法,并将请求和响应对象作为参数传递进去。

      ⑥WEB应用程序被停止或重新启动之前,Servlet引擎将卸载Servlet,并在卸载之前调用Servlet的destroy()方法。 

    6,JSP的隐式对象有哪些?

      request,response,out,session,application,pageContext,page,config,exception

    7,JSP的四个域对象的作用范围?

      pageContext:作用范围:当前jsp页面。

      request:一次请求范围内,转发有效重定向失效。

      session:存活时间内(默认30分钟),一次会话内有效,转发和重定向都有效。浏览器打开到关闭就是一次会话。

      application:最大作用范围,范围限于当前web应用,只要在一处设置了,当前web应用下的其他servlet和jsp都可以访问。

    8,转发和重定向的区别?

      ①重定向访问服务器两次,转发只访问服务器一次。

      ②重定向可以看见目标页面的URL,转发只能看见第一次访问的页面URL,以后的工作都是有服务器来做的。

      ③重定向跳转后必须加上return,要不然页面虽然跳转了,但是还会执行跳转后面的语句,转发是执行了跳转页面,下面的代码就不会在执行了。      

      ④在request级别使用信息共享,使用重定向必然出错。

      ⑤还有一个大的区别就是,重定向可以访问自己web应用以外的资源。

      详情:https://blog.csdn.net/xybelieve1990/article/details/49486751

      第一范式(1NF)所谓第一范式(1NF)是指数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的属性。如果出现重复的属性,就可能需要定义一个新的实体,新的实体由重复的属性构成,新实体与原实体之间为一对多关系。在第一范式(1NF)中表的每一行只包含一个实例的信息。在任何一个关系数据库中,第一范式(1NF)是对关系模式的基本要求,不满足第一范式(1NF)的数据库就不是关系数据库。理解注释:列不可分。

      第二范式(2NF)第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。第二范式(2NF)要求数据库表中的每个实例或行必须可以被惟一的区分。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。要求实体的属性完全依赖于主关键字。理解注释:不能部分依赖。即:一张表存在组合主键时,其他非主键字段不能部分依赖。

      第三范式(3NF)满足第三范式(3NF)必须先满足第二范式(2NF)。简而言之,第三范式(3NF)要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。在第二范式的基础上,数据表中如果不存在非关键字段对任一候选关键字段的传递函数依赖则符合第三范式。理解注释:不能存在传递依赖。即:除主键外,其他字段必须依赖主键。

    还是这个容易理解

     https://www.cnblogs.com/knowledgesea/p/3667395.html

    10数据库连接池原理?

      对于一个复杂的数据库应用,频繁的建立、关闭连接,会极大的减低系统的性能,因为对于连接的使用成了系统性能的瓶颈。连接复用,通过建立一个数据库连接池以及一套连接使用管理策略,使得一个数据库连接可以得到高效、安全的复用,避免了数据库连接频繁建立、关闭的开销。

      对于共享资源,有一个很著名的设计模式:资源池。该模式正是为了解决资源频繁分配、释放所造成的问题的。把该模式应用到数据库连接管理领域,就是建立一个数据库连接池。

      数据库连接池是负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个。

      数据库连接池的基本原理是在内部对象池中维护一定数量的数据库连接,就是预先在池中放入一定数量的数据库连接管道,需要时,从池子中取出管道进行使用,操作完毕后,在将管道放入池子中,从而避免了频繁的向数据库申请资源,释放资源带来的性能损耗。并对外暴露数据库连接获取和返回方法。如:

      外部使用者可通过getConnection 方法获取连接,使用完毕后再通过releaseConnection 方法将连接返回,注意此时连接并没有关闭,而是由连接池管理器回收,并为下一次使用做好准备。

    11,Spring的IOC和AOP机制?

    ①IOC

      在使用Spring框架之后,对象的实例不在由调用者来创建,而是由Spring容器来创建,Spring容器会负责控制程序之间的关系,而不是由调用者的程序代码直接控制。这样,控制权由应用代码转移到Spring容器,控制权发生了反转,这就是Spring的控制反转。

    ②AOP

      在传统的业务处理代码中,通常都会进行事务处理,日志记录等操作。虽然使用OOP可以通过组合或者继承的方式来达到代码的重用,但如果要实现某个功能(如日志记录),同样的代码任然会分散到各个方法中。这样,如果想关闭某个功能,或者对其进行修改,就必须要修改多有的相关方法。这不但增加了开发人员的工作量,而且提高了代码的出错率。

      为了解决这一问题,AOP思想随之产生。AOP采取横向抽取机制,将分散在各个方法中的重复代码提取出来,然后在程序编译运行时,再将这些提取出来的代码应用到需要执行的地方。

    12,Spring中Autowired和Resource关键字的区别?

      @Autowired::用于对bean的属性变量,属性的setter方法及构造方法进行标注,配合对应的注解处理器完成bean的自动配置工作。默认按照bean的类型进行装配。

      @Resource:作用与@Autowired一样。两个重要属性:name和type。Spring将name属性解析为Bean实例名称,type属性解析为Bean实例类型。如果指定name属性,则按照实例名称进行装配,如果是type属性,则按照Bean类型进行装配;如果都不指定,则先按Bean实例名称装配,如果不能匹配,再按照Bean类型进行装配;如果都无法匹配,则抛出NoSuchBeanDefinitionException 异常。

       区别在于@Autowired默认按照Bean类型装配,而@Resource默认按照Bean实例名称进行装配。

    13,依赖注入的方式有几种,各是什么?

      属性setter方法注入:通过调用无参构造器或者无参静态工厂方法实例化Bean后,调用Bean的setter方法,即可实现基于setter方法的依赖注入。

      构造方法注入:通过调用带参数的构造方法来实现,每个参数代表着一个依赖。

    14,Spring容器对bean组件是如何管理的?

    Bean对象创建

    默认是随着容器创建

    可以使用 lazy-init=true:在调用 getBean 延迟创建

    也可以用 <beans default-lazy-init="true"/> 批量延迟创建

    Bean对象的创建模式

    默认是单例,可以使用scope属性改变。

    singleton:单例,每次调用getBean返回同一个对象

    prototype:原型,每次调用getBean返回一个新的对象

    Bean对象初始化和销毁

    init-method 属性用于指定初始化方法

    spring 容器创建完对象后,将会执行 xml 文件中指定的初始化方法,单例模式中初始化方法只会执行一次

    destroy-method 属性用于指定销毁方法,仅适用于 singleton 模式,

    在调用 AbstractApplicationContext 对象的 close() 方法时触发

    三种实例化bean的方式

    1.使用类构造器实例化

    1 <bean id=“userService" class="service.UserService"/>

    2.使用静态工厂方法实例化

    <bean id="userService" class="service.UserFactory" factory-method="createUser"/>
    
        public class UserFactory {
            public static UserService createUser(){
                return new UserService();
            }
        }

    3.使用实例工厂方法实例化:

    <bean id="userServiceFactory" class="service.UserFactory"/>
        <bean id="userService" factory-bean="userServiceFactory" factory-method="createUser"/>
    
        public class UserFactory {
            public UserService createUser(){
                return new UserService();
            }
        }

    https://www.cnblogs.com/loveer/p/11576408.html

    15,Spring容器是如何创建的?

      ①BeanFactory

      ②ApplicationContext

        1,通过ClassPathXmlApplicationContext创建

        2,通过FileSystemXmlApplicationContext创建

    16,SpringMVC如何处理JSON数据?

      @RequestBody注解用于读取http请求的内容(字符串),通过springmvc提供的HttpMessageConverter接口将读到的内容(json数据)转换为java对象并绑定到Controller方法的形参上。

      @ResponseBody注解用于将Controller的方法返回的对象,通过springmvc提供的HttpMessageConverter接口转换为指定格式的数据如:json,xml等,通过Response响应给客户端。

    17,SpringMVC拦截器原理,如何自定义拦截器?

     浏览器请求

    DispatcherServlet 执行调用 doService(request, response) 作为 Servlet 主要执行者,

    doService(request, response) 通过调用 doDispatch(request, response) 来真正执行请求处理

    doDispatch(request, response) 中完成拦截器的添加和拦截器拦截处理

    通过 getHandler(HttpServletRequest request) 获取到 HandlerExecutionChain 处理器执行链,

    将拦截器注入到 HandlerExecutionChain 的属性中。

    分别调用 HandlerExecutionChain 的三个方法,applyPreHandle、applyPostHandle、triggerAfterCompletion,

    实现前置拦截/请求提交拦截和请求完成后拦截。

    使用责任链的设计模式,实际调用的是HandleInterceptor的三个接口,分别对应

    • preHandle
      在访问到达Controller之前执行,如果需要对请求做预处理,可以选择在该方法中完成
      返回值为true:继续执行后面的拦截器或者Controller
      返回值为false:不再执行后面的拦截器和Controller,并调用返回true的拦截器的afterCompletion方法
    • postHandle

      在执行完Controller方法之后,渲染视图之前执行,如果需要对响应相关的数据进行处理,可以选择在该方法中完成

    • afterCompletion

      调用完Controller接口,渲染View页面后调用。返回true的拦截器都会调用该拦截器的afterCompletion方法,顺序相反。

    自定义拦截器:

    自定义拦截器一般继承自HandlerInterceptorAdapter 或者实现 HandlerInterceptor 接口。 实现接口需要实现对应的3中方法,继承父类只需要实现需要的方法即可。

    详细源码分析:https://www.cnblogs.com/loveer/p/11577949.html#766671773

    https://www.jianshu.com/p/61eae2ad7320

    18,SpringMVC常见注解有哪些?

     Controller  RequestMapping  

    组合注解:GetMapping  PostMapping  PutMapping  DeleteMapping  PatchMapping

    19,MyBatis中#和$的区别?

     #传入的参数在SQL中显示为字符串,#方式能够很大程度防止sql注入;$传入的参数在SqL中直接显示为传入的值,$方式无法防止Sql注入。

    https://www.php.cn/faq/416843.html

  • 相关阅读:
    React Native 四:图片
    hadoop集群ambari搭建(1)之ambari-server安装
    OpenGL核心之视差映射
    大数据分析:结合 Hadoop或 Elastic MapReduce使用 Hunk
    在Android实现client授权
    HDU 5072 Coprime (单色三角形+容斥原理)
    mmtests使用简介
    win7 以管理员身份运行cmd, windows services 的创建和删除
    php使用curl设置超时的重要性
    window下查看端口命令
  • 原文地址:https://www.cnblogs.com/YancyL/p/11440015.html
Copyright © 2020-2023  润新知