面试笔记Spring

微服务架构

微服务架构就是将单体的应用程序分成多个应用程序,这多个应用程序就是微服务,而且各个服务可以使用不同的编程语言、不同的数据库可以极大的降低耦合性。

SpringCloud使用得意义

利用SpringBoot开发的便利性,简化了分布式系统基础设施的开发,服务发现、配置中心、负载均衡、断路器、数据监控等。

SpringCloud的优缺点

优点:

  • 1.耦合度比较低。不会影响其他模块的开发。
  • 2.减轻团队的成本,可以并行开发,不用关注其他人怎么开发,先关注自己的开发。
  • 3.配置比较简单,基本用注解就能实现,不用使用过多的配置文件。
  • 4.微服务跨平台的,可以用任何一种语言开发。
  • 5.每个微服务可以有自己的独立的数据库也有用公共的数据库。
  • 6.直接写后端的代码,不用关注前端怎么开发,直接写自己的后端代码即可,然后暴露接口,通过组件进行服务通信。
缺点:
  1. 部署比较麻烦,给运维工程师带来一定的麻烦。
  2. 针对数据的管理比麻烦,因为微服务可以每个微服务使用一个数据库。
  3. 系统集成测试比较麻烦
  4. 性能的监控比较麻烦。【最好开发一个大屏监控系统】
SpringBoot与SpringCloud
SpringBoot专注于单个服务的开发,而SpringCloud则是为了多个服务之间的协调调用,关注全局的微服务治理,将SpringBoot开发的许多服务整合并管理起来
SpringBoot可以离开SpringCloud独立使用的开发项目,但是SpringCloud需要SpringBoot作为微服务被cloud统一管理。
SpringBoot专注于快速、方便的开发单个微服务个体,SpringCloud关注全局的服务治理框架。

SpringCloud由什么组成

  • Spring Cloud Eureka:服务注册与发现
  • Spring Cloud Zuul:服务网关
  • Spring Cloud Ribbon:客户端负载均衡
  • Spring Cloud Feign:声明性的Web服务客户端
  • Spring Cloud Hystrix:断路器
  • Spring Cloud Config:分布式统一配置管理

依赖注入控制反转

ioc

“控制反转”,并不是一种技术,而是一种设计思想。在开发过程中,Ioc意味着将设计好的对象交给容器控制,而不是像传统的在对象内部直接控制。

传统的模式下:在对象内部通过new进行创建对象,是程序主动去创建依赖对象;

在Ioc模式下:存在一个专门的容器来创建你这些对象,由Ioc容器来控制对像的创建。

IoC容器控制二楼对象;主要是控制外部资源的获取(不止对象包括文件等)

因为容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象所以是反转,反转的的是依赖对象的获取被反转了。(传统模式下,我们的对象是主动控制去直接获取依赖对象)

IoC的用途

IoC只是一种思想,在这种理念下,从传统的以程序为主,需要获取什么资源都是主动出击但是再IoC下,程序变为被动接受,被动的等待IoC容器来创建并注入。实现了对象与对象之间是松耦合、方便测试、利于功能的服用。

IoC与DI

DI就是依赖注入:组件之间依赖关系由容器决定,即由容器动态的将某个依赖关系注入到组件之中。依赖注入的目的并非为软件系统带来更多功能,而是提高了组件的冲用的频率,并微系统搭建一个灵活、可扩展的平台。通过依赖注入,我么你可以通过简单的配置,不需要任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不需要关心具体的资源来自何处。

谁依赖于谁:引用程序依赖IoC容器

为什么要依赖:应用程序需要IoC容器来提供对象需要的外部资源

谁注入谁:明显IoC容器注入应用该程序某个对象,应用程序以来的的对象;

注入了什么:注入某个对象所需要的外部资源

IoC(控制反转)的理解

所有的类都会在spring容器中等级,告诉Spring你是个什么东西,然后spring会在系统运行到适当的时候,把你要的东西主动给你,同时也把你交给其他需要你的东西。所有类的创建。销毁都有spring来控制,也就是说控制对象生存周期的不再是引用它的的对象,而是spring。对于某个具体的独享而言,以前是他控制其他对象,现在是所有的UI系那个被spring控制,所以叫控制反转。

 sleep与wait的区别

两个方法来自不同的类分别是Thread和Object

sleep方法没有释放对象锁,而wait方法释放了锁,使得其他线程可以使用同步控制快或者方法。

 wait的唤醒方式,notify(),notifyAll()

当sleep方法的休眠时间没结束,可以使用interrupt(),wait()也同样可以通过interrupt()打断线程的暂停状态,使线程立刻抛出InterruptedException,在catche(){}中直接return即可安全的结束线程,InterruptedException是线程自己从内部抛出,并不是因为interrupt()方法抛出,如果一个线程没有进入sleep或者wait并不会抛出InterruptedException而是正常执行。

Thread.Sleep(0)的作用,就是“触发操作系统立刻重新进行一次CPU竞争”

sleep与wait关于释放的所对象问题。

sleep锁住的对象:因为通过直接调用当前线程下的Thread对象的sleep(),其他线程是无法再次尝试使用当前这个线程的。

wait锁住的对象:wait是Object类的方法,当执行wait方法后线程挂起并且释放当前的对象锁,这个对象的其他线程仍然可以使用的。

 HashMap的时间复杂度

put时,先通过key.hashcode(),时间复杂度O(0)

找到桶以后,判断桶里是否有元素,如果没有直接new一个entry结点插入时间复杂度同样O(1)

开始遍历桶位置的链表,如果元素个数小于6则调用equals方法,比较key存在不插入,不存在new一个entry插入,时间:O(1)+O(n)=O(n)

若大于6转化为红黑树,则比较以及new一个entry后插入时间复杂度为O(1)+O(logn)

所以HashMap的时间复杂度可能的值为O(1)、O(logn)、O(n)

final

final修饰一个类时,表明这个类不能被继承。也就是说,如果一个类你永远不会让他被继承,就可以用final进行修饰。final类中的成员变量可以根据需要设为final,但是要注意final类中的所有成员方法都会被隐式地指定为final方法。

final修饰方法,该方法可重载不可重写

final修饰变量,对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。变量就是常亮。

 Servlet生命周期服务启动后,第一次请求servlet会初始化一个Servlet对象,执行初始化方法init(Servletconfig conf),执行客户端的请求service,最后服务器关闭时销毁servlet独享执行destroy().

@Resource与@Autowired

两个都是做bean的注入时使用,其实@Resource并不是Spring的注解,它的包是javax.annotation.Resource,需要导入,但是Spring支持该注解的注入。

相同点

两者都可以写在字段和setter方法上。如果写在字段上,就不需要再写setter方法.

@Autowired

为Spring提供的注解,需要导入org.springframework.bean.factory.annotation.Autowired;是按照byType注入

按照理性装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置required属性为false。如果希望按照名称(byName)来装配,可以结合@Qualifier注解一起使用

public class TestServiceImpl{
 @Autowired
  @Qualifier("userDao")
 private UserDao userDao;  
}

@Resource

默认按照ByName自动注入,有J2EE提供,需要导入包javax.annotaion.Resourcer。

@Resource有两个重要属性:name和type,而Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。

如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果两者都没制定,这时通过反射机制使用byName自动注入策略。

public class TestServiceImpl {
  // 下面两种@Resource只要使用一种即可
  @Resource(name="userDao")
  private UserDao userDao; // 用于字段上
   
  @Resource(name="userDao")
  public void setUserDao(UserDao userDao) { // 用于属性的setter方法上
    this.userDao = userDao;
  }
}

一般最好将注解放在setter方法上,这样更符合面向对象的思想,通过set、get去操作属性,而不是直接去操作属性。

@Resource装配顺序

①如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常。

②如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常。

③如果指定了type,则从上下文中找到类似匹配的唯一bean进行装配,找不到或是找到多个,都会抛出异常。

④如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配。

posted @ 2021-08-26 15:57  K峰  Views(47)  Comments(0)    收藏  举报