面经(一)

面经(一)

讲一下 SpringMVC 和 SpringBoot 的区别?

先讲讲概念吧

1、Spring

Spring是一个开源容器框架,可以接管web层,业务层,dao层,持久层的组件,并且可以配置各种bean,和维护bean与bean之间的关系。其核心就是控制反转(IOC),和面向切面(AOP),简单的说就是一个分层的轻量级开源框架。

2、SpringMVC

Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。SpringMVC是一种web层mvc框架,用于替代servlet(处理|响应请求,获取表单参数,表单校验等。SpringMVC是一个MVC的开源框架,SpringMVC=struts2+spring,springMVC就相当于是Struts2加上Spring的整合。

3、SpringBoot

Springboot是一个微服务框架,延续了spring框架的核心思想IOC和AOP,简化了应用的开发和部署。Spring Boot是为了简化Spring应用的创建、运行、调试、部署等而出现的,使用它可以做到专注于Spring应用的开发,而无需过多关注XML的配置。提供了一堆依赖打包,并已经按照使用习惯解决了依赖问题—>习惯大于约定。

区别:

1.简单理解为:Spring包含了SpringMVC,而SpringBoot又包含了Spring或者说是在Spring的基础上做得一个扩展。

2、关系大概就是这样:

spring mvc < spring < springboot

3、Spring Boot 对比Spring的一些优点包括:

  1. 提供嵌入式容器支持
  2. 使用命令java -jar独立运行jar
  3. 在外部容器中部署时,可以选择排除依赖关系以避免潜在的jar冲突
  4. 部署时灵活指定配置文件的选项
  5. 用于集成测试的随机端口生成

4、结论

Spring Boot只是Spring本身的扩展,使开发,测试和部署更加方便。

Spring MVC 是基于 Servlet 的一个 MVC框架 主要解决 WEB 开发的问题 但关于Spring 的配置比较复杂 。

Spring 最初利用“工厂模式”( DI )和“代理模式”( AOP )解耦应用组件。按照这种模式搞了一个 MVC 框架(一些用 Spring 解耦的组件),用开发 web 应用( SpringMVC )。后来发现每次开发都要搞很多依赖,写很多样板代码,使代码臃肿而麻烦,于是聪明的前人整理了一些懒人整合包( starter ),这套就是 Spring Boot 。Spring boot 的原则是:约定优于配置 ,可以极大地简化 spring 的配置流程


讲一下 MyBatis 和 MyBatis-plus 的区别,谈一谈你的理解?

区别一 如果Mybatis Plus是扳手,那Mybatis Generator就是生产扳手的工厂。

通俗来讲—— MyBatis:一种操作数据库的框架,提供一种Mapper类,支持让你用java代码进行增删改查的数据库操作,省去了每次都要手写sql语句的麻烦。但是!有一个前提,你得先在xml中写好sql语句,是不是很麻烦?于是有下面的↓ Mybatis Plus:国人团队苞米豆在Mybatis的基础上开发的框架,在Mybatis基础上扩展了许多功能,自动为Mybatis生成简单的增删改查sql语句的工具 Mybatis Plus Generator:同样为苞米豆开发,比Mybatis Generator更加强大,支持功能更多,自动生成Entity、Mapper、Service、Controller等 总结: 数据库框架:Mybatis Plus > Mybatis 代码生成器:Mybatis Plus Generator > Mybatis Generator

区别二 Mybatis-Plus是一个Mybatis的增强工具,它在Mybatis的基础上做了增强,却不做改变。我们在使用Mybatis-Plus之后既可以使用Mybatis-Plus的特有功能,又能够正常使用Mybatis的原生功能。Mybatis-Plus(以下简称MP)是为简化开发、提高开发效率而生,但它也提供了一些很有意思的插件,比如SQL性能监控、乐观锁、执行分析等。

Mybatis虽然已经给我们提供了很大的方便,但它还是有不足之处,实际上没有什么东西是完美的,MP的存在就是为了稍稍弥补Mybatis的不足。在我们使用Mybatis时会发现,每当要写一个业务逻辑的时候都要在DAO层写一个方法,再对应一个SQL,即使是简单的条件查询、即使仅仅改变了一个条件都要在DAO层新增一个方法,针对这个问题,MP就提供了一个很好的解决方案,他已经为我们写好了一些简单的SQL语句供我们直接使用,只需要我们继承一个BaseMapper!


Java8 的新特性是什么?

  1. Lambda 表达式

  2. 函数式接口

  3. 方法引用与构造器引用

  4. Stream API

  5. 接口中的默认方法与静态方法

  6. 新时间日期 API

  7. 其他新特性

特点

  • 速度更快
  • 代码更少(增加了新的语法 Lambda 表达式 )
  • 强大的 Stream API
  • 便于并行
  • 最大化减少空指针异常 Optional

其中最为核心的为 Lambda 表达式与Stream API

Lambda 表达式

Lambda 是一个 匿名函数 ,我们可以把 L**ambda表达式理解为是 一段可以传递的代码 (将代码像数据一样进行传递)。**可以写出更简洁、更灵活的代码。作为一种更紧凑的代码风格,使Java 的语言表达能力得到了提升。

Lambda 表达式语法

Lambda 表达式在Java 语言中引入了一个新的语法元素和操作符。这个操作符为 “ -> ” , 该操作符被称为 Lambda 操作符或剪头操作符。它将 Lambda 分为两个部分:

左侧: 指定了 Lambda 表达式需要的所有参数

右侧: 指定了 Lambda 体,即 Lambda 表达式要执行的功能。

Lambda 表达式语法

语法格式一:无参,无返回值, Lambda 体只需一条语句

语法格式二: Lambda 需要一个参数

语法格式三: Lambda 只需要一个参数时,参数的小括号可以省略

语法格式四: Lambda 需要两个参数,并且有返回值

语法格式五:当 Lambda 体只有 一条 语句时, return 与大括号 可以省略

**语法格式六:**数据类型可以省略,因为可由编译器推断得出,称为“类型推断

类型推断 上述 Lambda 表达式中的参数类型都是由编译器推断得出的。Lambda 表达式中无需指定类型,程序依然可以编译,这是因为 javac 根据程序的上下文,在后台推断出了参数的类型。Lambda 表达式的类型依赖于上下文环境,是由编译器推断出来的。这就是所谓的“类型推断"

函数式接口

  • 只包含一个抽象方法的接口,称为 函数式接口
  • 你可以通过 Lambda 表达式来创建该接口的对象。(若 Lambda表达式抛出一个受检异常,那么该异常需要在目标接口的抽象方法上进行声明)。
  • 我们可以在任意函数式接口上使用 @FunctionalInterface 注解,这样做可以检查它是否是一个函数式接口,同时 javadoc 也会包含一条声明,说明这个接口是一个函数式接口。

作为参数传递 Lambda 表达式:为了将 Lambda 表达式作为参数传递,接收Lambda 表达式的参数类型必须是与该 Lambda 表达式兼容的函数式接口的类型。

方法引用与构造器引用

方法引用 当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用!( 实现抽象方法的参数列表,必须与方法引用方法的参数列表保持一致! )方法引用:使用操作符 “ :: ” 将方法名和对象或类的名字分隔开来。 如下三种主要使用情况 :

对象::实例方法

类::静态方法

类::实例方法

Stream

了解 Stream

Java8中有两大最为重要的改变。第一个是 Lambda 表达式;另外一

个则是 Stream API(java.util.stream.*)

Stream 是 Java8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数据库查询。也可以使用 Stream API 来并行执行操作。简而言之,Stream API 提供了一种高效且易于使用的处理数据的方式。

流(Stream) 到底是什么呢?

是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。

“集合讲的是数据,流讲的是计算!”

注意:

①Stream 自己不会存储元素。

②Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream。

③Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。

Fork/Join 框架与传统线程池的区别

采用 **“工作窃取”**模式(work-stealing)

当执行新的任务时它可以将其拆分分成更小的任务执行,并将小任务加到线程队列中,然后再从一个随机线程的队列中偷一个并把它放在自己的队列中。相对于一般的线程池实现,fork/join框架的优势体现在对其中包含的任务的处理方式上.在一般的线程池中,如果一个线程正在执行的任务由于某些原因无法继续运行,那么该线程会处于等待状态.而在fork/join框架实现中,如果某个子问题由于等待另外一个子问题的完成而无法继续运行.那么处理该子问题的线程会主动寻找其他尚未运行的子问题来执行.这种方式减少了线程的等待时间,提高了性能

新时间日期 API

使用 LocalDate LocalTime LocalDateTime

LocalDate 、 LocalTime 、 LocalDateTime 类的实例是 不可变的对象 ,分别表示使用 ISO-8601 日历系统的日期时间日期和时间。它们提供了简单的日期或时间,并不包含当前的时间信息。也不包含与时区相关的信息。

接口中的默认方法

Java 8中允许接口中包含具有具体实现的方法,该方法称为“默认方法”,默认方法使用 default 关键字修饰。

接口中的静态方法

Java8 中,接口中允许添加静态方法。

其他新特性

Optional

Optional 类(java.util.Optional) 是一个容器类,代表一个值存在或不存在,原来用 null 表示一个值不存在,现在 Optional 可以更好的表达这个概念。并且可以避免空指针异常。

重复注解与类型注解

Java 8对注解处理提供了两点改进:可重复的注解及可用于类型的注解

Java 中接口和抽象类的区别?

  • 1.接口是抽象类的变体,接口中所有的方法都是抽象的。而抽象类是声明方法的存在而不去实现它的类。
  • 2.接口可以多继承,抽象类不行。
  • 3.接口定义方法,不能实现,默认是 public abstract,而抽象类可以实现部分方法。
  • 4.接口中基本数据类型为 public static final 并且需要给出初始值,而抽类象不是的。

谈谈对 Java 泛型的理解?

泛型: 把类型明确的工作推迟到创建对象或调用方法的时候才去明确的特殊的类型

泛型擦除: 因为泛型其实只是在编译器中实现的而虚拟机并不认识泛型类项,所以要在虚拟机中将泛型类型进行擦除。也就是说,在编译阶段使用泛型,运行阶段取消泛型,即擦除。擦除是将泛型类型以其父类代替,如String 变成了Object等。其实在使用的时候还是进行带强制类型的转化,只不过这是比较安全的转换,因为在编译阶段已经确保了数据的一致性。

MySQL 中 group by 的用法?

group by的常规用法是配合聚合函数,利用分组信息进行统计,常见的是配合max等聚合函数筛选数据后分析,以及配合having进行筛选后过滤。

  • 当group by 与聚合函数配合使用时,功能为分组后计算
  • 当group by 与having配合使用时,功能为分组后过滤
  • 当group by 与聚合函数,同时非聚合字段同时使用时,非聚合字段的取值是第一个匹配到的字段内容,即id小的条目对应的字段内容。

MySQL 中插入一个字段的 SQL 语句怎么写?

Insert into 表名 (col1,col2....coln)values(value1,value2.....valuen);

对微服务的理解?

1.微服务是什么?

单个应用程序被划分成各种小的、互相连接的微服务,一个微服务完成一个比较单一的功能,相互之间保持独立和解耦合,这就是微服务架构。

2.单体服务存在的问题

某个业务模块负载过高,需要扩展的时候,必须扩展整个应用程序,这可能导致额外的资源浪费**。单体式应用程序由于服务之间的紧密度、相依性过高,这将导致测试、升级有所困难,且开发曲线有可能会在后期大幅度地上升,令开发不易。**相较之下「微服务架构」能够解决这个问题。

3.微服务的特点

想各个模块业务拆分,一个微服务完成一个比较单一的功能,相互之间保持独立和解耦合,这就是微服务架构。

优点:技术异构性,隔离性,可扩展性,易优化,简单部署

缺点:难管理

解决办法:服务注册与发现,服务监控,日志监控,调用追踪;服务容错(需要引入「熔断、隔离、限流和降级、超时机制」等「服务容错」机制来保证服务持续可用性。);服务安全

微服务框架一般都包含了RPC的实现和一系列「服务治理」能力,基于这个框架之上实现自己的微服务

end
  • 作者:AWhiteElephant(联系作者)
  • 发表时间:2022-03-17 20:35
  • 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)
  • 转载声明:如果是转载栈主转载的文章,请附上原文链接
  • 评论