JAVA初级工程师面试36问(二)

第七问:    请简单描述你对Ioc(控制反转)的理解?

         一个类需要用到某个接口的方法,需要将类A和接口B的实现关联起来,最简单的方法是在类A中创建一个对于接口B的实现类C的实例,但是用这种方法显然两者的依赖太大.稍微好一点的方式是使用工程模式,实例类通过工厂类创建,减少了类A与接口B的实现类C的依赖,但是创建工厂类也不是很方便.而IOC相当于一个大的bean工厂,使用IOC后,只在类A中定义好用于关联接口B的实现方法,将类A,接口B和接口B的实现放在IOC容器中,通过一定的配置由容器来实现类A与接口B的实现C的关联.

第八问:    java接口为什么不能实例化?

             首先,我们需要明白实例化的含义。实例化实际意义是在jvm的堆中开辟出一块内存空间,比如Student s = new Student();此处声明Student对象s,并且实例化一个Student对象,实则是在堆中开辟出一块空间来存放Student对象,s则是指向这块空间,也就是内存中的一块地址。这块地址中所存放的值就是我们这个Student对象的一些属性。

    而接口中允许有什么:静态的属性以及方法声明。 接口中所有的东西的具体值都是存放在代码去和静态数据区的,所以接口的这块地址上并没有任何实际的值需要存储,那么为什么要给他一块地址来浪费空间呢。其实用底层代码在内存中开辟出一块空间很容易,那么为什么java设定不允许接口实例化呢,以我的理解而言,那就是接口的实例化没有任何实际意义,只会占用一块内存空间,却不会在这块空间中放任何实际的值,所以java主动去规避掉了这个问题.

第九问:    谈谈你对异常的理解?

      此处放一张图便于理解

一  什么是编译时异常,什么是运行时异常? 

运行时异常可以通过改变程序避免这种情况发生,比如,除数为0异常,可以先判断除数是否是0,如果是0,则结束此程序。从继承上来看,只要是继承RunTimeException类的,都是运行时异常,其它为编译时异常。

二编译时异常和运行时异常的区别

使用抛出处理方式处理异常时,对于编译时异常,当函数内部有异常抛出,该函数必须声明,调用者也必须处理,运行时异常则不一定要声明,调用者也不必处理;编译时异常必须在函数中声明,调用者也必须在函数中处理.

三、常见的编译时异常

1.FileNotFoundException

2.ClassNotFoundException

3.SQLException

4.NoSuchFieldException

5.NoSuchMethodException

6.ParseException

四、常见的运行时异常

1.NullPointerException

2.ArithmeticException

3.ClassCastException

4.ArrayIndexOutOfBoundsException

5.StringIndexOutOfBoundsException

第十问:    为什么springboot一个main方法就可以让服务启动起来?

       此处问题考的是springboot的一些注解以及springboot的启动流程,大致总结为以下步骤:

  启动时候 :

  1.会创建一个springApplication对象实列,调用springApplication的实列方法,在springApplication实列初始化的时候会做三件事情

第一件:判断classpath下查找并判断与之对应的ApplicationContext类型,并且创建出来这个ApplicationContext

第二件:springFactionLaoder在classpath下找出并加载所有可用的applicationContextInitializer

第三件:springFactionLaoder在classpath下找出并加载所有可用的applicationListener ,找出main方法的定义类

2.springApplication实例初始完成后,开始执行run方法逻辑,首先会遍历所有的springFactions查到的springApplicationRunListener,接着调用started方法,告诉springApplicationRunListener执行

3 创建并配置当前springboot应用要使用的环境(environment)

4.遍历所有的environment,并调用prepered方法,告诉springboot环境已经准备好了

5.根据设置springContext的class类型以及初始化阶段的推断结果,来决定当前spingboot应用创建什么类型的applicationContext,并且把我们的的环境设置进去,然后创建出这个applicationContext

6.再次执行springFactionLaoder在classpath下找出并加载所有可用的applicationContextInitializer

7.springFactionLaoder在classpath下找出并加载所有可用的applicationListener

8,.通过@enableAutoconfiguration获取所有的配置以及IOC容器配置加载到我们准备好的applicationContext

9.遍历所有的applicationListener ,调用contextLoader的方法

10.调用applicationContext的refresh()方法,对我们的IOC容器初始化完成

11.在applicationContext中查找是否有注册的commandeLineRuner,有就遍历

12.最后一步就是遍历springApplicationRunListener调用finished()方法,有异常会抛出来,整个过程结束。

第十一问:  说说你知道的springBoot常用的注解?

   @PathVaribale 获取url中的数据 

   @RequestParam 获取请求参数的值 

   @GetMapping 组合注解,是@RequestMapping(method = RequestMethod.GET)的缩写

   @RestController是@ResponseBody和@Controller的组合注解。

   @SpringBootApplication:包含了@ComponentScan、@Configuration和@EnableAutoConfiguration注解

      其中 @ComponentScan让spring Boot扫描到Configuration类并把它加入到程序上下文。 

  @EnableAutoConfiguration 自动配置。

  @ComponentScan 组件扫描,可自动发现和装配一些Bean。

  @Component可配合CommandLineRunner使用,在程序启动后执行一些基础任务。

  @RestController注解是@Controller和@ResponseBody的合集,表示这是个控制器bean,并且是将函数的返回值直 接填入HTTP响应体中,是REST风格的控制器。

   @Configuration:相当于传统的xml配置文件,如果有些第三方库需要用到xml文件,建议仍然通过@Configuration类作为项目的配置主类——可以使用@ImportResource注解加载xml配置文件。

   @Autowired:自动导入依赖的bean

   @Service:一般用于修饰service层的组件

   @Repository:使用@Repository注解可以确保DAO或者repositories提供异常转译,这个注解修饰的DAO或者repositories类会被ComponetScan发现并配置,同时也不需要为它们提供XML配置项。

  @Bean:用@Bean标注方法等价于XML中配置的bean。

  @Value:注入Spring boot application.properties配置的属性的值

第十二问:  说说springMVC实现原理?

   1.当客户端(浏览器)发送请求,直接请求到DispatcherServlet。

   2.DispatcherServlet会根据请求信息来调用HandlerMapping,解析请求对应的Handler。

   3.解析到对应的Handler后,开始由HandlerAdapter适配器处理。

   4.HandlerAdapter会根据Handler来调用真正的处理器开处理请求,并处理相应的业务逻辑。

   5.处理器处理完业务后,会返回一个ModelAndView对象,Model是返回的数据对象,View是个逻辑上的View。

   6.ViewResolver会根据逻辑View查找实际的View。

   7.DispaterServlet把返回的Model传给View。

   8.通过View返回给请求者(浏览器).

  

未完待续.....

猜你喜欢

转载自blog.csdn.net/FindHuni/article/details/106617241