网站支付宝接口代码,深圳网络推广运营企业,网站开发用到哪些技术,注册公司上什么网站声明#xff1a; 背景#xff1a;本人为24届双非硕校招生#xff0c;已经完整经历了一次秋招#xff0c;拿到了三个offer。本专题旨在分享自己的一些Java开发岗面试经验#xff08;主要是校招#xff09;#xff0c;包括我自己总结的八股文、算法、项目介绍、HR面和面试… 声明 背景本人为24届双非硕校招生已经完整经历了一次秋招拿到了三个offer。本专题旨在分享自己的一些Java开发岗面试经验主要是校招包括我自己总结的八股文、算法、项目介绍、HR面和面试技巧等等如有建议可以友好指出感谢我也会不断完善。想了解我个人情况的可以关注我的B站账号东瓜Lee 面试题 Spring框架中的bean是单例的吗 是单例的IOC容器里面的bean对象默认就是单例singleton的也可以使用Scope注解设置为prototype原型的Scope可以设置五种类型 Spring框架中的bean是线程安全的吗? 如果使用默认的单例作用域Singleton不一定是线程安全的要分两种情况考虑 如果bean没有可变的状态此如Controller、Service、DAO类在某种程度上来说这种bean是线程安全的。如果在bean中定义了可修改的成员变量同时被多个线程访问就会导致数据的不一致性就不是线程安全的可以使用多例或者加锁来解决 如果使用原型作用域Prototype线程不会共享同一个bean就不会有线程安全问题 定义bean的方式怎么把对象交给IOC容器管理 XML配置文件注解JavaConfig很少用 什么是IOC IOC就是控制反转不同于正转手动new对象自己去处理对象之间的依赖关系IOC就相当于是一个容器可以管理的所有的java对象也就是bean然后也可以让它去处理对象依赖关系它的目的就是为了降低代码耦合度而且可以使得对象被统一管理。DI就是依赖注入它是实现了控制反转建立了bean对象之间的依赖关系 什么是AOP AOP称为面向切面编程可以将那些与业务无关但却对多个对象产生影响的公共行为抽取并封装为一个可重用的模块这个模块就是为切面(Aspect) 简单来说AOP就是在不惊动原始设计的基础上 为代码进行功能增强。作用减少系统中的重复代码、降低了模块间的耦合度、提高了系统的可维护性。AOP的底层用的就是动态代理模式 使用场景 记录操作日志Spring事务处理的底层实现就是用的AOP Spring AOP底层是代理模式实现的具体是怎么实现的 用到了两种代理机制 JDK的动态代理针对实现接口的类的产生代理Cglib的动态代理针对没有实现接口的类的产生代理 AOP的实现中涉及到哪些注解项目中怎么使用的AOP【待完善】 Aspect定义当前类为 切面Pointcut定义当前方法为 切入点Before标注当前方法为 前置通知After标注当前方法为 后置通知Around标注当前方法为 环绕通知 Spring中的事务是如何实现的 事务这个概念其实是数据库层面的Spring框架只是基于数据库中的事务进行了扩展而且方便程序操作事务。 Spring支持编程式事务管理和声明式事务管理两种方式 编程式事务需使用TransactionTemplate来进行实现对业务代码有侵入性也就是要手动写代码来实现开启、提交、回滚事务项目中很少使用。声明式事务声明式事务管理是建立在AOP之上的本质是通过AOP功能对方法前后进行拦截在目标方法开始之前加入一个事务在执行完目标方法之后根据执行情况提交或者回滚事务。在方法上加个Transactional注解 为什么有的公司禁止使用声明式事务Transactional注解反而使用编程式事务 如果方法存在嵌套调用而被嵌套调用的方法也声明了事务就会出现事物的嵌套调用也就是事务传播行为来决定事务如何执行这样容易引起事物的混乱。声明式事务是将事物控制逻辑放在注解中如果项目的复杂度增加事务的控制可能会变得更加复杂导致代码可读性和维护性下降。 Spring中事务的隔离级别 Spring事务的隔离级别其实也就是数据库的隔离级别 ru读未提交rc读已提交rr可重复读serializable串行化 mysql默认的隔离级别是可重复读rroracle是读已提交rc如果Spring中配置的隔离级别和数据库不一样以Spring配置的为准 Spring中事务失效的场景有哪些 指的是声明式事务在方法操作多张表上加上Transactional注解 异常捕获处理 如果的正常的话出现了异常运行时异常那么事务就会进行回滚那么事务就是正常的如果代码主动对异常进行了try catch捕获处理就会导致事务失效。 如果非要自己处理异常还要保证事务不会失效可以在catch块添加throw new RuntimeException(e)再把运行时异常主动抛出去。 抛出编译时检查异常 因为Spring的声明式事务 默认只会在出现运行时异常的时候进行回滚编译时异常是不会回滚的。 可以在Transactional注解中加上一个rollbackFor属性指定所有的异常都可以进行回滚 非public的方法 因为 Spring 为方法添加事务通知的前提条件是 该方法是 public的所以只有public的方法才能使用声明式事务 Spring 中事务的传播行为有哪些 它解决的核心问题是多个声明了事务的方法 在相互调用的时候 会存在事务的嵌套问题那么这个事务的行为应该如何进行传递呢 比如说A B两个方法都开启了事务方法A 调用 方法B那么 方法B 是开启一个新的事务还是继续在 方法A 的事务中执行就取决于事务的传播行为。 一共有7种事务传播行为 1. REQUIRED默认的事物传播级别如果当前存在事务则加入这个事务如果不存在事务就新建一个事务。
2. REQUIRE_NEW不管是否存在事务都会新开一个事务新老事务相互独立。外部事务抛出异常回滚不会影响内部事务的正常提交。
3. NESTED如果当前存在事务则嵌套在当前事务中执行。如果当前没有事务则新建一个事务类似于 REQUIRE_NEW
4. SUPPORTS表示支持当前事务如果当前不存在事务以非事务的方式执行。
5. NOT_SUPPORTED表示以非事务的方式来运行如果当前存在事务则把当前事务挂起。
6. MANDATORY强制事务执行若当前不存在事务则抛出异常。
7. NEVER以非事务的方式执行如果当前存在事务则抛出异常。Spring的bean的生命周期 通过BeanDefinition获取bean的定义信息xml里面定义的bean or 注解调用构造方法 实例化bean对bean进行依赖注入set注入实现几个Aware接口BeanNameAware、BeanFactoryAware重写里面的方法Bean的前置后置处理器BeanPostProcessor-before初始化方法(InitializingBean、init- method)Bean的后置处理器BeanPostProcessor-after关闭ioc容器销毁bean对象 Spring中的循环引用依赖 比如的几种情况 在创建A对象的时候要用到B对象在创建B的时候又要用到A A依赖于BB依赖于CC又依赖于A A依赖于自己 Spring解决循环依赖是通过三级缓存 一级缓存单例池缓存的是 已经初始化完成的bean对象已经经历了完整的生命周期的bean 二级缓存缓存的是 早期的还没初始化完成的bean对象生命周期还在进行中的bean对象 三级缓存缓存的是ObjectFactory对象工厂对象工厂就是用来创建某个对象的 使用一级缓存和二级缓存可以解决一般的循环依赖问题但是如果有代理对象的话就要使用三级缓存了三级缓存可以解决大部分的循环依赖问题 谈谈你对SpringMVC的理解 SpringMVC是一种基于Spring的 Web框架采用了 MVC 的架构模式。 把复杂的 Web 应用分成逻辑清晰的几个组件在 Spring MVC 中有 9 大重要的组件。 1. HandlerMapping 处理器映射器在 SpringMVC 中会有很多请求每个请求都需要一个 Handler 来处理HandlerMapping 的作用就是找到 每个请求 对应的处理器 Handler。
2. HandlerAdapter 处理器适配器它就是一个适配器它主要就是如何让固定的 Servlet 处理方法 灵活的调用 Handler 来进行处理
3. ViewResolvers 视图解析器将 String 类型的 视图名 和 Locale 解析为 View 类型的视图。
4. RequestToViewNameTranslator 视图名称翻译器有的 Handler 处理完后并没有设置 View 也没有设置 ViewName这时就需要从request 中获取而 RequestToViewNameTranslator 就是为 request 提供获取 ViewName 的实现。
5. HandlerExceptionResolver 异常处理器用于处理其他组件产生的异常情况
6. MultipartResolver 文件处理器用于处理上传请求
7. ThemeResolver 主题处理器用于解析主题
8. LocaleResolver 当前环境处理器在 ViewResolver 进行视图解析的时候会用到
9. FlashMapManager 参数传递管理器用于请求重定向场景中的参数传递SpringMVC的执行流程知道吗 前后端不分离阶段视图阶段直接说这个版本的前后端分离阶段的就是少了个视图的解析 用户发出请求 到前端控制器DispatcherServlet调度中心DispatcherServlet收到请求 调用处理器映射器HandlerMappingHandlerMapping找到具体的处理器生成 含有处理器对象和处理器拦截器 的执行链再重新返回给DispatcherServletDispatcherServlet再去 调用处理器适配器HandlerAdapterHandlerAdapter经过适配 调用具体的处理器controller中的方法执行完成后返回一个ModelAndView对象HandlerAdapter再将ModelAndView返回给DispatcherServletDispatcherServlet将ModelAndView 传给视图解析器ViewReslover视图解析器ViewReslover返回 具体的试图View给DispatcherServletDispatcherServlet根据View进行试图的渲染最后将试图响应给用户 用户发送请求给前端控制器前端控制器去找控制器映射器控制器映射器返回给前端控制器一个执行链前端控制器请求处理器适配器处理器适配器去找执行器执行处理处理器执行完处理返回给处理器适配器一个ModelAndView处理器适配器再将ModelAndView返回给前端控制器前端控制器请求视图解析器视图解析器返回给前端控制器View对象前端控制器再对视图进行渲染最后响应给用户。 SpringMVC拦截器、Servlet过滤器的区别 归属不同过滤器属于Servlet、拦截器属于SpringMVC、 拦截内容不同过滤器对所有访问进行增强、拦截器仅针对SpringMVC的访问对Controller的请求进行增强 实现原理不同过滤器是基于函数的回调、拦截器是基于Java的反射动态代理 实现方式不同 过滤器Filter主要重写三个方法init()、destory()、doFilter()拦截器Interceptor主要重写三个方法preHandle()、postHandle()、aftetCompletion() 使用范围不同 过滤器Filter依赖于Tomcat等容器只能在web程序中使用拦截器Interceptor本质上属于Spring的组件不依赖于Tomcat等容器可以在web程序、Application等等程序中使用。 执行顺序不同先执行过滤器再执行拦截器 SpringBoot自动配置装配原理 主要依赖于SpringBootApplication注解包含了三个注解 SpringBootConfiguration:该注解与Configuration注解作用相同用来声明当前也是一个配置类。ComponentScan:组件扫描默认扫描当前引导类所在包及其子包。EnableAutoConfiguration: SpringBoot实现自动化配置的核心注解。 其中EnableAutoConfiguration是实现自动化配置的核心注解。 该注解通过Import注解导入对应的配置选择器内部读取了spring.factories文件中的所有配置类在这些配置类中Bean会根据条件注解来决定是否需要将其导入到Spring容器中会判断是否有对应的class文件如果有则加载该类。 SpringBoot框架的好处是什么 我们以前可能使用的比较常见的后端框架是SSH后来又是SSM再到现在主要使用的就是SpringBootSpringBoot的核心就是采用了 约定大于配置 这样的思想省去了一些繁琐的配置项使得我们可以专注于业务代码的编写。 具体来说使用传统的Spring框架来开发web应用需要做很多和业务无关的配置比如一些.xml文件的维护、管理依赖jar包、将应用手动部署到服务器。 而在SpringBoot种不需要再去做这些繁琐的配置Spring Boot 已经自动帮我们完成了这就是约定大于配置思想 的体现它配置了很多东西比如说 SpringBoot Starter也就是启动依赖它能帮我们管理所有的 jar 包在SpringBoot 自动装配机制的实现中通过扫描约定路径下的 spring.factories 文件来识别配置类实现 Bean 的自动装配。SpringBoot还内嵌了几种服务器比如Tomcat、Jetty不再需要手动部署应用到服务器 总的来说SpringBoot正因为有约定大于配置 的思想使得它可以更高效 也更便捷的 实现软件系统的开发和维护。 Spring框架常见注解 Configuration指定当前类是一个Spring配置类 Component放在类上 用于实例化bean对象的对应的还有Controller、Service、Mapper ComponentScan用于指定Spring在初始化容器时要扫描的包 Autowired使用在字段上 用于根据类型依赖注入 Scope用于标注bean的作用范围单例、原型bean SpringMVC常见的注解 RequestMapping用于映射请求路径可以定义在类上和方法上用于类上则表示类中的所有的方法都是以该地址作为父路径RequestBody实现前台传过来的的是json字符串将json转换为Java对象RequestParam指定请求参数的名称PathViriable从请求路径下中获取请求参数(/user/id)传递给方法的形式参数ResponseBody实现将controller方法返回的Java对象 转化为json字符串响应给前台 Springboot常见注解 SpringBootApplication启动类上的注解包含了三个注解 SpringBootConfiguration用来声明当前也是一个配置类。ComponentScan组件扫描默认扫描当前引导类所在包及其子包。EnableAutoConfigurationSpringBoot实现自动化配置的核心注解。 MyBatis执行流程 读取MyBatis的配置文件mybatis-config.xml里面有数据库的连接信息、映射文件和代理方式等等信息构造会话工厂SqlSessionFactory再通过会话工厂创建SqISession对象包含了执行所有sql语句的方法SqISession有个操作数据库的接口 Executor执行器同时它还负责了查询缓存的维护Executor的执行方法中 有一个MappedStatement类型的参数封装了映射信息输入参数映射就可以执行数据库的操作了执行完后数据库操作后就可以输出结果映射 MyBatis-Plus selectOne的时候查询出多条数据怎么办 查询出多条数据会报异常临时解决方案可以加个limit 1但是可能得不到想要的数据 正确的话可以通过AOP来解决设置切面 MyBatis延迟加载 MyBatis默认是立即加载延迟记载需要配置一下 延迟加载的意思 需要用到数据的时候就进行加载到数据库中去查找暂时还没有用到的话就不提前加载比如有两个表用户表和订单表一个用户可以对应多个订单在用户属性里面就有一个字段叫做订单项使用mybatis执行对用户的查询的时候默认也会去查找订单信息这就是立即加载所谓延迟加载就是如果只查询用户的信息底层就不执行查询订单的逻辑需要用到订单项的时候再去查询要实现延迟加载需要配置一下延迟加载也可以叫做懒加载类似于单例模式成的懒汉式单例 MyBatis的一级、二级缓存 MyBatis中的一级二级缓存都是基于本地缓存本质上就是一个hashmap的结构给一个key在缓存中得到一个value 一级二级缓存其实就是作用域不同默认开启的就是一级缓存 一级缓存作用域是session级别的 比如使用sqlSessionFactory也就是会话工厂来创建一个session会话使用这个session来get到两个mapper对象来操作数据库两个mapper对象执行同一条sql查询数据那其实就只会去数据库查询一次查询一次后就把数据放到了一级缓存中第二次查询直接从缓存中命中。 二级缓存作用域是namespace和mapper的作用域不依赖于session 就比如当前使用的是默认的一级缓存如果sqlSessionFactory创建了两个session使用这两个session来分别get到两个mapper对象去执行同一条sql查询语句那么其实就会去查询两次数据库因为是用的两个session。 然后可以去配置文件中开启一下二级缓存开启之后使用不同的session对象得到的mapper再去执行同一条查询操作第一次查询就会将数据保存到二级缓存中第二次查询就不会查询数据库了。 Mybatis 动态SQL是什么有哪些动态SQL 动态SQL是一种可以根据不同条件生成不同SQL语句的技术可以在xml映射文件中编写灵活的SQL语句能根据设定参数的不同情况来动态生成SQL语句。Mybatis 常用的动态 SQL 标签 where生成动态的WHERE子句只有满足条件时才包含WHERE子句避免不必要的WHERE关键字。set生成动态的SET子句只有满足条件时才包含SET子句用于动态更新表中的字段。choose根据不同的条件选择执行不同的SQL片段实现类似于switch-case语句的功能。foreach对集合进行循环并在SQL语句中使用循环的结果trim对SQL语句进行修剪和重组去掉多余的AND或OR等以便根据不同的条件动态生成合适的SQL语句。 MyBatis和Hibernate的区别 在国内MyBatis是主流的持久层框架但是其实在欧美国家Hibernate用的更多主要的原因就是欧美国家对于java的态度更加把它当成一门面向对象的语言。因为Hibernate是全自动ORM框架ORM也就是对象关系映射它将java中的对象和数据库中的表直接关联起来通过对象就可以实现对数据库的操作而MyBatis是半自动ORM框架它的重点在于java对象和SQL语句之间的映射关系操作数据表还是要通过SQL语句。 SpringBoot除了集成了Tomcat它还集成了哪些容器Servlet容器 Tomcat是SpringBoot默认使用的web容器除此之外还有Jetty、Undertow、Netty容器因为默认是使用Tomcat所以如果要使用其他的容器就需要先排除exclusionTomcat容器再导入其他容器。 SpringBoot有bootstrap.yml和application.yml两个配置文件这两个文件有什么区别 SpringBoot项目一般具有两个配置文件bootstrap.yml、application.yml 也可以用.propertiesproperties yml yaml 具体区别 加载顺序不同bootstrap比application配置文件先加载因为bootstrap是由spring父上下文加载而application是由子上下文加载。优先级不同bootstrap加载的配置信息是不能被application的相同配置覆盖的也就是说如果两个配置文件同时存在以bootstrap为主。应用场景不同bootstrap常用于配置一些固定的、系统级别的参数application常用于配置一些springboot项目的自动化配置。 大部分情况下都是使用application.yml Spring的BeanFactory和ApplicationContext是什么有什么区别 BeanFactory就是一个bean工厂用到了工厂设计模式负责读取bean的配置文件、管理bean的加载、实例化还能维护bean之间的依赖关系也就是依赖注入DI它负责了bean的整个生命周期。ApplicationContext其实是属于BeanFactory的子接口除了实现了BeanFactory接口的功能之外还做了功能增强比如国际化访问、资源访问、事件传递之类的。还一个区别就是他俩加载bean的时机不同 BeanFactory不会在初始化的时候就加载所有的bean执行getBean的时候才会加载也就是采用的惰性加载类似于懒汉式单例好处就是节省了资源而且初始化速度比较快因为有的bean不一定会被使用坏处就是要用的时候要等一个加载的时间ApplicationContext会在初始化的时候加载所有的bean也就是饿汉式加载类似于饿汉式单例好处就是要用的时候可以直接用坏处就是可能会浪费资源而且初始化速度慢。 Spring的 BeanFactory和FactoryBean的区别是什么 BeanFactory就是一个bean工厂用到了工厂设计模式负责读取bean的配置文件、管理bean的加载、实例化还能维护bean之间的依赖关系也就是依赖注入DI它负责了bean的整个生命周期。FactoryBean 是一个工厂 Bean它是一个接口主要的功能是 动态地生成某一个类型 的Bean 的实例也就是说我们可以自定义一个 Bean 然后加载到 IOC 容器里面它里面有一个重要的方法叫 getObject()这个方法里面就是用来实现动态构建 Bean的过程。
【后续继续补充敬请期待】