Java面试题更新帖(2020年04月19日更新)

一、Spring

1.谈一谈Spring中的IOC容器和DI依赖注入

答:Spring中的IOC容器,即inverse of control控制反转,举个例子,在使用Spring之前,我们在service层使用dao层的对象时,我们都习惯new一个dao层的对象使用,这是一种很强的依赖,不符合Java中低耦合高内聚的原则,为了解耦,我们就引入了工厂模式,原来我们获取对象的方式都是自己new出来,现在由工厂创建对象提供给我们,原来是我们主动的,现在是被动的,这就称之为控制反转,这个工厂其实是一个Map,我们称之为容器。

SpringIOC容器使用过程
//1.使用 ApplicationContext 接口,就是在获取 spring 容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
//2.根据 bean 的 id 获取对象
IAccountService aService = (IAccountService) ac.getBean("accountService");
System.out.println(aService);
IAccountDao aDao = (IAccountDao) ac.getBean("accountDao");
System.out.println(aDao);

BeanFactory和ApplicationContext的区别?

BeanFactory 才是 Spring 容器中的顶层接口。
ApplicationContext 是它的子接口。
创建对象的时间点不一样。
ApplicationContext:只要一读取配置文件,默认情况下就会创建对象。
BeanFactory:什么使用什么时候创建对象。

IOC中的bean标签?

用于配置对象让 spring 来创建的。
默认情况下它调用的是类中的无参构造函数。如果没有无参构造函数则不能创建成功。

id:给对象在容器中提供一个唯一标识。用于获取对象。
class:指定类的全限定类名。用于反射创建对象。默认情况下调用无参构造函数。
scope:指定对象的作用范围。
* singleton :默认值,单例的.
* prototype :多例的.
* request  :WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 request 域中.
* session  :WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 session 域中.
* global session  :WEB 项目中,应用在 Portlet 环境.如果没有 Portlet 环境那么
globalSession 相当于 session.
init-method:指定类中的初始化方法名称。
destroy-method:指定类中销毁方法名称。

bean的作用范围和生命周期?

单例对象:scope="singleton"
一个应用只有一个对象的实例。它的作用范围就是整个引用。
生命周期:
对象出生:当应用加载,创建容器时,对象就被创建了。
对象活着:只要容器在,对象一直活着。
对象死亡:当应用卸载,销毁容器时,对象就被销毁了。
多例对象:scope="prototype"
每次访问对象时,都会重新创建对象实例。
生命周期:
对象出生:当使用对象时,创建新的对象实例。
对象活着:只要对象在使用中,就一直活着。
对象死亡:当对象长时间不用时,被 java 的垃圾回收器回收了。

Spring中的依赖注入DI

DI,dependency injection。

构造函数注入

<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">
    <constructor-arg name="name" value=" 张三 "></constructor-arg>
    <constructor-arg name="age" value="18"></constructor-arg>
    <constructor-arg name="birthday" ref="now"></constructor-arg>
</bean>

Set方法注入,最常用

<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">
    <property name="name" value="test"></property>
    <property name="age" value="21"></property>
    <property name="birthday" ref="now"></property>
</bean>
<bean id="now" class="java.util.Date"></bean>

p命名空间注入,实际上还是调用set方法注入

2.Spring中的注解

@Component:相当于<bean id="" class="">;注解内只有一个属性value,用来指定bean的id值;衍生出了三种注解分别用于三层架构的不同层,@Controller,@Service,@Repository。

@Autowired:自动按照类型注入。当使用注解注入属性时,set方法可以省略。它只能注入其他 bean 类型。当有多个类型匹配时,使用要注入的对象变量名称作为 bean 的 id,在 spring 容器查找,找到了也可以注入成功。找不到就报错。

@Qualifier:在自动按照类型注入的基础之上,再按照 Bean 的 id 注入。它在给字段注入时不能独立使用,必须和@Autowire 一起使用;但是给方法参数注入时,可以独立使用。该注解有一个属性value:指定 bean 的 id。

@Resource:直接按照 Bean 的 id 注入。它也只能注入其他 bean 类型。该注解只有一个属性name:指定 bean 的 id。

@Value:注入基本数据类型和 String 类型数据的,该注解有一个属性value:用于指定值。

@Scope:相当于:<bean id="" class="" scope="">,指定 bean 的作用范围。该注解只有一个属性value:指定范围的值。取值:singleton prototype request session globalsession。

@Configuration:用于指定当前类是一个 spring 配置类,当创建容器时会从该类上加载注解。获取容器时需要使用AnnotationApplicationContext(有@Configuration 注解的类.class)。该注解有一个属性value:用于指定配置类的字节码。

@ComponentScan:用于指定 spring 在初始化容器时要扫描的包。作用和在 spring 的 xml 配置文件中的:
<context:component-scan base-package="com.itheima"/>是一样的。写在@Configuration下面一行,@ComponentScan("com.itheima")

@Bean:该注解只能写在方法上,表明使用此方法创建一个对象,并且放入 spring 容器。name:给当前@Bean 注解方法创建的对象指定一个名称(即 bean 的 id)。

3.谈一谈你对Spring中的AOP的理解

AOP:全称是 Aspect Oriented Programming 即:面向切面编程。简单的说它就是把我们程序重复的代码抽取出来,在需要执行的时候,使用动态代理的技术,在不修改源码的基础上,对我们的已有方法进行增强。

连接点(JointPoint):指的是项目中的所有方法,我们可以为每一个方法都加上写日志的代码,所以每一个候选者都是连接点

切入点(pointcut):那我们肯定不是每个方法都要加日志,那些需要处理的连接点我们称作切入点

通知(Advice):写日志的代码就叫做通知,意思就是具体增强的那部分代码

切面(Aspect)切入点+通知=切面

<bean id="log" class="com.wanglei.utils.Logger"></bean>
<!--配置AOP-->
<aop:config>
        <!--配置切入点-->
        <aop:pointcut id="accountServicePoint" expression="execution(* com.wanglei.service.impl.*.*(..))"></aop:pointcut>
        <!--配置切面=通知+切入点-->
        <aop:aspect id="logAdvice" ref="log">
            <!--前置通知-->
            <aop:before method="printLog1" pointcut-ref="accountServicePoint"></aop:before>
            <!--后置通知-->
            <aop:after-returning method="printLog2" pointcut-ref="accountServicePoint"></aop:after-returning>
            <!--异常通知-->
            <aop:after-throwing method="printLog3" pointcut-ref="accountServicePoint"></aop:after-throwing>
            <!--最终通知-->
            <aop:after method="printLog4" pointcut-ref="accountServicePoint"></aop:after>

        </aop:aspect>
</aop:config>

二、SpringMVC

1.SpringMVC的处理流程

(1)客户端发送请求至前端控制器DispatcherServlet;
(2) DispatcherServlet收到请求后,调用HandlerMapping处理器映射器,请求获取Handle;
(3)处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet;
(4)DispatcherServlet 调用 HandlerAdapter处理器适配器
(5)HandlerAdapter 经过适配调用 具体处理器(Handler,也叫后端控制器);
(6)Handler执行完成返回ModelAndView;
(7)HandlerAdapter将Handler执行结果ModelAndView返回给DispatcherServlet;
(8)DispatcherServlet将ModelAndView传给ViewResolver视图解析器进行解析;
(9)ViewResolver解析后返回具体View;
(10)DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)
(11)DispatcherServlet响应用户。

2.请求参数的绑定

基本数据类型和String,要求请求路径中必须是key=value格式

    <a href="param?info=wanglei">向后台传递wanglei</a>

    @RequestMapping(path = "/param")
    public String paramMethod(String info){
        System.out.println(info);
        return "success";
    }

POJO对象,要求表单中的name属性和user实体类中的属性必须相同才可以通过set方法注入

    <form action="beanparam" method="post">
        用户名:<input name="username" type="text"><br>
        年&nbsp龄:<input name="userage" type="text"><br>
        账户名:<input name="account.accountname" type="text"><br>
        账户密码:<input name="account.accountpass" type="text"><br>
        <input type="submit" name="提交">
    </form>

    @RequestMapping(path = "/beanparam")
    public String parambeanMethod(User user){
        System.out.println(user);
        return "success";
    }

请求路径占位符绑定参数:要求请求路径必须是/delProducts.do/3格式

    //使用占位符,保证占位符和@PathVariable("ids")一样
    @RequestMapping("/delProducts.do/{ids}")
    @ResponseBody
    public String delProducts(@PathVariable("ids") String ids){
        if (ids.contains(",")){
            String[] split = ids.split(",");
            Integer id = Integer.valueOf(split[0]);
            productService.delProducts(id);
            System.out.println("================id"+id);
        }else {

        }

        return "删除ok";
    }

3.请求参数中文乱码

<filter>
    <filter-name>characterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>characterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

4.Cookie和Session

Cookie和Session都是属于javaweb中的会话技术,会话:一次会话类似于生活中的一次谈话,会话技术的作用是在一次会话中共享数据,分为客户端会话技术(cookie)和服务器端会话技术(session)。

HTTP协议是无状态的协议。一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接。这就意味着服务器无法从连接上跟踪会话。

区别:Cookie保存在客户端浏览器中,而Session保存在服务器上。Cookie机制是通过检查客户身上的“通行证”来确定客户身份的话,那么Session机制就是通过检查服务器上的“客户明细表”来确认客户身份。Session相当于程序在服务器上建立的一份客户档案,客户来访的时候只需要查询客户档案表就可以了。
 

5.转发和重定向

转发:是在服务器内部控制权的转移,是由服务器区请求,客户端并不知道是怎样转移的,因此客户端浏览器的地址不会显示出转向的地址。地址栏不会发生变化。
重定向:是服务器告诉了客户端要转向哪个地址,客户端再自己去请求转向的地址,因此会显示转向后的地址,也可以理解浏览器至少进行了两次的访问请求。地址栏会变化。

发布了111 篇原创文章 · 获赞 60 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/Haidaiya/article/details/105611801