Java面试准备资料七

171 阅读5分钟

这是我参与更文挑战的第7天,活动详情查看: 更文挑战

十七、Java中Wait、Sleep、Yield和join的区别

总体区别

  • sleep()和yield()方法定义在Thread类中,而wait()方法定义在Object类中,join由线程对象调用

Wait vs Sleep

  • 当一个线程调用wait()方法时,会释放持有对象的管程和锁;但调用sleep()不会释放持有的管程(wait释放cpu资源,也释放锁资源;sleep释放cpu资源,不释放锁资源
  • wait()方法需要在同步代码块中,而sleep方法不需要
  • 进入wait状态的线程能够被notify和notifyAll线程唤醒,但是进入sleeping状态的线程不能被notify方法唤醒。
  • wait通常有条件地执行,线程会一直处于wait状态,直到某个条件变为真。但是sleep仅仅让你的线程进入睡眠状态。
  • wait方法是针对一个被同步代码块加锁的对象,而sleep是针对一个线程。

yield vs sleep

  • yield方法会临时暂停当前执行的线程,来让有同样优先级的正在等待的线程有机会执行。如果没有正在等待的线程,或者所有正在等待的线程的优先级都比较低,那么该线程会继续运行。
  • yield方法不保证当前的线程会暂停或者停止,但是可以保证当前线程在调用yield方法时会放弃CPU。(让出cpu调度)

join

  • 一种特殊的wait,当前运行线程调用另一个线程的join方法,当前线程进入阻塞状态直到另一个线程运行结束等待该线程终止。
  • 该方法也需要捕捉异常。
  • 等待调用join方法的线程结束,再继续执行。如:t.join();//主要用于等待t线程运行结束,若无此句,main则会执行完毕,导致结果不可预测。

十八、SpringBoot和SpringCloud关系

  • SpringBoot专注于快速方便的开发单个个体微服务
  • SpringCloud是关注全局的微服务协调整理治理框架,它将SpringBoot开发的一个个单体微服务整合并管理起来,为各个微服务之间提供:配置管理、服务发现、断路器、路由、微代理、事件总线、全局所、决策竞选、分布式会话等等集成服务。
  • SpringBoot可以离开SpringCloud独立使用,但是SpringCloud离不开SpringBoot,属于依赖关系
  • SpringBoot专注于快速、方便开发单个个体微服务,SpringCloud关注全局的服务治理框架

十九、Dubbo和SpringCloud

  • 解决的问题域不一样:Dubbo的定位是一款RPC框架,SpringCloud的目标是微服务架构下的一站式解决方案
  • SpringCloud:http通信,Dubbo:RPC通信

二十、Spring bean

1. Spring bean的生命周期

  • 实例化

AbstractAutowireCapableBeanFactory.doCreateBean中会调用createBeanInstance()方法,从beanDefinitionMap循环读取bean,获取它的属性。然后利用反射,读取对象的构造方法,然后再去创建实例

  • 初始化

    1. 属性赋值

      这里可能发生循环依赖的问题

      Spring解决这个问题主要靠巧妙的三层缓存,所谓的缓存主要是指这三个map,singletonObjects主要存放的是单例对象,属于第一级缓存;singletonFactories属于单例工厂对象,属于第三级缓存;earlySingletonObjects属于第二级缓存,如何理解early这个标识呢?它表示只是经过了实例化尚未初始化的对象。Spring首先从singletonObjects(一级缓存)中尝试获取,如果获取不到并且对象在创建中,则尝试从earlySingletonObjects(二级缓存)中获取,如果还是获取不到并且允许从singletonFactories通过getObject获取,则通过singletonFactory.getObject()(三级缓存)获取。如果获取到了则移除对应的singletonFactory,将singletonObject放入到earlySingletonObjects,其实就是将三级缓存提升到二级缓存,这个就是缓存升级。spring在进行对象创建的时候,会依次从一级、二级、三级缓存中寻找对象,如果找到直接返回。由于是初次创建,只能从第三级缓存中找到(实例化阶段放入进去的),创建完实例,然后将缓存放到第一级缓存中。下次循环依赖的再直接从一级缓存中就可以拿到实例对象了。

      img

    2. 初始化

      初始化的过程包括将初始化好的bean放入到spring的缓存中、填充我们预设的属性进一步做后置处理等

    实例化和初始化区别:

    • 实例化是在jvm堆中创建了这个对象实例,此时它只是空的对象,所有的属性为null
    • 初始化过程是将对象依赖的一些属性进行赋值之后,调用某些方法来开启一些默认加载
  • 使用和销毁

【21】 hashCode()和equals()

  • hashCode()只有在散列表才有用,在其他条件下没用
  • hashCode()equals()都定义在Objecet.java中,所以所有对象都有这两个函数
  • 如果两个对象相同,则hashcode一定也是相同的,反之两个对象的hashcode值相同,并不能证明他们相同
  • equals方法被覆盖,则hashCode()方法也必须被覆盖
  • hashCode() 的默认行为是对堆上的对象产生独特值。如果没有重写 hashCode(),则该 class 的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)

【22】equals()和==

  • ==:判断两个对象是否相等,即:判断两个对象是不是同一个对象

  • equals()如果不被重写则是判断两个对象地址是否相同;如果被重写则根本重写的函数指定它的功能