阿里云面试查缺补漏(线程、Java基础、Spring Boot、Bean)
阿里云面试查缺补漏
== 和equals的区别?类的hashcode是什么?如果两个对象的hash码相同,equals一定为true吗?
- == 比较的是引用指向的内存地址,比较基本类型会用到
- equals比较方法是类继承于Object后自己重写的,如果直接用==(或者没重写equals)去比较,不同的对象在堆中的内存地址以及存的值一定是不一样的,重写后可以按照自己定义的规则去比较。
类的hashCode,有时候不同的对象生成的hashCode也可能相同,且equals相同的两个对象,hashcode也不一定相等
- 只有在HashSet,HashTable,HashMap等散列表结构数据中,hashcode才派上用场,这时equals相同的两个类,hashcode一定相等
抽象类和普通类的区别?抽象类和接口的区别?抽象类中一定会有抽象方法吗?
- 抽象类不能被实例化,普通类可以
- 抽象类不可为private
- 子类必须实现抽象父类的抽象方法,否则只能定义为抽象子类
抽象类和接口
- 抽象类可以有具体方法和属性,接口只能有抽象方法和不可变变量
- 抽象类中不一定有抽象方法
线程和进程的区别?有几种创建线程的方法?
创建线程的方法
- 结成Thread类实现多线程
- 覆写Runnable接口实现多线程
- 覆写Callable接口实现多线程
使用线程池启动
submit和execute都可以添加线程任务,但submit有返回值,execute没有
- submit返回的是一个future ,可以通过这个future取到线程执行的结果或者异常信息
- 使用submit提交子任务,一定要获取返回值Future,通过get方法获取可能出现的异常,并且可以进行捕获(推荐)
- 使用execute执行子任务,异常可以被抛出,但是主线程不能捕获子任务线程中的异常
- 使用submit提交子任务,只是提交,不获取返回值future,异常会被封装在子线程内部,不会抛出,主线程也无法捕获
- shutdown 已提交的任务继续执行,不接受新任务提交
- 通过ThreadPoolExecutor方式,这一方面是由于jdk中Executor框架虽然提供了如newFixedThreadPool()、newSingleThreadExecutor()、newCachedThreadPool()等创建线程池的方法,但都有其局限性,不够灵活;另外由于前面几种方法内部也是通过ThreadPoolExecutor方式实现,使用ThreadPoolExecutor有助于大家明确线程池的运行规则,创建符合自己的业务场景需要的线程池,避免资源耗尽的风险
参考 https://www.cnblogs.com/dafanjoy/p/9729358.html
为什么要用IoC这种方式?
- 控制反转可以把创建对象的主动权由用户交还给容器
- 通过配置文件而不是修改程序块代码来控制程序的流程和细节
- 让程序单元更加易于修改和维护,因为配置文件不参与编译
HashMap和Hashtable的区别?
- 继承的父类不同(前者继承自AbstractMap,后者继承自Dictionary)
- 线程安全和线程不安全
- HashMap是没有contains方法的,而包括containsValue和containsKey方法;hashtable则保留了contains方法,效果同containsValue,还包括containsValue和containsKey方法
- Hashmap是允许key和value为null值的,用containsValue和containsKey方法判断是否包含对应键值对;HashTable键值对都不能为空
- HashMap的hash冲突可以有红黑树和链表两种方法解决,Hashtable只有链表
Spring Boot的Bean是什么?
- 在 Spring 中,构成应用程序主干并由Spring IoC容器管理的对象称为bean。bean是一个由Spring IoC容器实例化、组装和管理的对象
bean规范如下:
- 所有属性为private
- 提供默认构造方法
- 提供getter和setter
- 实现serializable接口
Bean有哪些种类?Bean的生命周期?
种类
普通Bean
- Spring直接创建实例,并返回
- FactoryBean,工厂生成对象能力
类别 说明 singleton IOC容器中仅存在一个bean实例,以单例方式存在,默认值 prototype 每次从容器中调用bean时,都返回一个新实例,即getBean()=new xxxBean() request 每次HTTP请求都会创建一个新的bean,仅适用于WebApplicationContext环境 session 同一个http session共享一个bean,不同session不同bean,仅适用于WebApplicationContext环境 globalSession 一般用于portlet应用环境,该作用域仅适用于WebApplicationContext环境
参考 https://blog.csdn.net/pcwl1206/article/details/80647877
生命周期
1)根据配置情况调用 Bean 构造方法或工厂方法实例化 Bean。
2)利用依赖注入完成 Bean 中所有属性值的配置注入。
3)如果 Bean 实现了 BeanNameAware 接口,则 Spring 调用 Bean 的 setBeanName() 方法传入当前 Bean 的 id 值。
4)如果 Bean 实现了 BeanFactoryAware 接口,则 Spring 调用 setBeanFactory() 方法传入当前工厂实例的引用。
5)如果 Bean 实现了 ApplicationContextAware 接口,则 Spring 调用 setApplicationContext() 方法传入当前 ApplicationContext 实例的引用。
6)如果 BeanPostProcessor 和 Bean 关联,则 Spring 将调用该接口的预初始化方法 postProcessBeforeInitialzation() 对 Bean 进行加工操作,此处非常重要,Spring 的 AOP 就是利用它实现的。
7)如果 Bean 实现了 InitializingBean 接口,则 Spring 将调用 afterPropertiesSet() 方法。
8)如果在配置文件中通过 init-method 属性指定了初始化方法,则调用该初始化方法。
9)如果 BeanPostProcessor 和 Bean 关联,则 Spring 将调用该接口的初始化方法 postProcessAfterInitialization()。此时,Bean 已经可以被应用系统使用了。
10)如果在 中指定了该 Bean 的作用范围为 scope=“singleton”,则将该 Bean 放入 Spring IoC 的缓存池中,将触发 Spring 对该 Bean 的生命周期管理;如果在 中指定了该 Bean 的作用范围为 scope=“prototype”,则将该 Bean 交给调用者,调用者管理该 Bean 的生命周期,Spring 不再管理该 Bean。
11)如果 Bean 实现了 DisposableBean 接口,则 Spring 会调用 destory() 方法将 Spring 中的 Bean 销毁;如果在配置文件中通过 destory-method 属性指定了 Bean 的销毁方法,则 Spring 将调用该方法对 Bean 进行销毁
Spring Boot的过滤器,拦截器?哪个在先哪个在后?
- 拦截器是基于Java的反射机制的,而过滤器是基于函数回调。
- 拦截器不依赖与servlet容器,过滤器依赖与servlet容器。
- 拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
- 拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
- 在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
- 拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。
- 过滤器在请求进入servlet之前预处理,在servlet处理完后再处理,过滤器包裹着servlet,servlet包裹着拦截器
参考 https://www.cnblogs.com/panxuejun/p/7715917.html
还没有评论,来说两句吧...