《面试1v1》Spring基础

news2024/11/26 12:34:39

🍅 作者简介:王哥,CSDN2022博客总榜Top100🏆、博客专家💪
🍅 技术交流:定期更新Java硬核干货,不定期送书活动
🍅 王哥多年工作总结:Java学习路线总结, 点击 突击面试
🍅 数十万人的面试选择: 面试说人话系列《面试1v1》

我是 javapub,一名 Markdown 程序员从👨‍💻,八股文种子选手。


《面试1v1》 连载中…


我是 javapub,一名 Markdown 程序员从👨‍💻,八股文种子选手。

面试官: 想请你简单介绍一下 Spring 框架,它的核心特性是什么?

候选人: Spring 是一个开源框架,目的是简化 JavaEE 开发。它的核心特性有:

  1. IoC(Inverse of Control):通过 DI(Dependency Injection)实现将对象间的依赖关系交给 Spring 管理。
  2. AOP(Aspect Oriented Programming):面向切面编程,可以在程序运行期间动态的将某段代码切入到指定的方法、指定的位置进行运行。
  3. Portlet MVC:Spring 提供 MVC 框架可以快速开发 Web 应用。
  4. 事务管理:Spring 提供广泛的事务管理接口,支持 JDBC、Hibernate 等事务管理。
  5. Spring 统一一体化了其他框架和技术,如:Struts、Hibernate、Quartz 等。
    面试官(笑):你说的真是五花八门,让我有点晕,来聊点具体的吧。Spring 是如何工作的,它如何用于构建 Web 应用程序?

候选人: 好的,Spring 的工作原理主要是 IoC 容器。对 Web 应用来说,Spring MVC 是基于 JavaEE 的 Model-View-Controller 设计模式构建的,主要工作流程是:

  1. 浏览器发送请求到 DispatcherServlet。
  2. DispatcherServlet 接收请求后会转交给 HandlerMapping 得到请求对应的 Handler。
  3. HandlerMapping 将 Handler 映射到 HandlerAdapter。
  4. HandlerAdapter 调用 Handler 处理请求,Handler 会返回一个 ModelAndView。
  5. ViewResolver 解析 ModelAndView,找到正确的 View。
  6. DispatcherServlet 将 View 返回给浏览器。

通过这个流程,Spring MVC 应用了 MVC 模式,实现了业务逻辑、控制逻辑、表现逻辑的分离,使我们可以更加专注于业务开发。

面试官: 你说的很具体,我明白了。那么 Spring 可以在哪些实际场景中使用?开发人员在使用 Spring 时常犯哪些错误?

候选人: Spring 可以应用在很多实际场景中:

  1. Web 应用:Spring MVC 是 Spring 体系中最为成熟的框架,可以用来开发网站、BBS、博客等 Web 应用。
  2. 企业应用:Spring 提供事务管理、数据访问等功能,非常适用于开发企业级应用。
  3. 微服务:Spring Boot 提供了快速开发单个微服务的能力,配合 Spring Cloud 可以开发微服务架构的系统。
  4. Android 应用:Spring for Android 提供了在 Android 应用中使用 Spring 的能力。

开发人员在使用 Spring 时常犯的几个错误:

  1. 容器管理对象依赖关系错乱:未正确配置 bean 的依赖关系,导致依赖注入错误。
  2. 上下文目录 problemas:beans.xml 配置文件放在了非上下文目录,导致 Spring 无法识别。
  3. 事务管理错误:未正确配置事务属性,导致事务管理不生效。
  4. AOP 误用:滥用 AOP 或错误使用 AOP 导致 sistem 过于复杂或 AOP 不生效。
  5. 未考虑扩展性:在开发初期未考虑系统扩展性,导致系统难以演进。

面试官: 那么如何使基于 Spring 的应用程序更高效、更可扩展?

候选人: 这里有几点建议:

  1. 采用模块化设计,遵循高内聚低耦合原则,每个模块保持高内聚,模块之间低耦合。
  2. 使用设计模式,如工厂模式、单例模式、代理模式等,提高系统扩展性。
  3. 应用 AOP,通过预置切点在不修改源代码的情况下增加新功能。
  4. 使用 Spring 的事件机制,通过事件监听器监听事件,当事件触发时执行相应逻辑。
  5. 应用 Spring 的 Profile 功能,可以根据环境部署不同的 bean,提高系统灵活性。
  6. 使用 Spring Boot 依赖管理和自动配置的能力,简化构建过程,提高开发效率。
  7. 应用微服务架构,将单体应用拆分成职责单一、松耦合的服务,更容易扩展和升级。
  8. 使用缓存技术,如 Redis 缓存数据库查询结果,降低数据库压力,提高系统吞吐量。

面试官: 很棒,你对 Spring 和高可扩展系统的理解很透彻!最后一个问题,Spring 的源码中 IoC 容器的实现你可以大致描述一下吗?

候选人: 可以的,IoC 容器的实现主要在 AbstractApplicationContext 及其子类 ClassPathXmlApplicationContext 和FileSystemXmlApplicationContext 中。主要流程是:

  1. 容器启动时会调用 refresh() 方法,其中会调用 obtainFreshBeanFactory() 方法初始化 DefaultListableBeanFactory,此为 IoC 容器的核心。
// AbstractApplicationContext.java
public void refresh() throws BeansException, IllegalStateException {
   // 初始化 BeanFactory
   DefaultListableBeanFactory beanFactory = obtainFreshBeanFactory();
}

  1. 然后会调用 loadBeanDefinitions(beanFactory) 方法加载 bean 定义,主要通过 XmlBeanDefinitionReader 解析 bean 定义文件。
// AbstractXmlApplicationContext.java  
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
    // Create a new XmlBeanDefinitionReader for the given BeanFactory.
    XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
  
    // Configure the bean definition reader with this context's
    // resource loading environment.
    beanDefinitionReader.setEnvironment(this.getEnvironment());
    beanDefinitionReader.setResourceLoader(this);
    beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
  
    // Allow a subclass to provide custom initialization of the reader,
    // then proceed with actually loading the bean definitions.
    initBeanDefinitionReader(beanDefinitionReader);
    loadBeanDefinitions(beanDefinitionReader);
}
  1. bean 实例化阶段会调用 getBean() 方法,通过工厂方法或构造器实例化 bean。
  2. 实例化 bean 后,会对 bean 进行属性注入、初始化以及其他Aware接口回调。
  3. bean 的生命周期至此结束,容器会对 bean 进行管理,直至容器关闭。
    这就是 IoC 容器实现的大致流程,关键是 bean 定义资源的加载和解析,以及 bean 的实例化及生命周期管理。IoC 容器屏蔽了 bean 之间的依赖关系,使 bean 的使用者可以零配置使用 bean。

面试官: 你的解释很到位,IoC 容器的源码分析确实需要对它的原理有深入了解。最后一个问题,在你的项目中是如何设计一个高并发的系统的?

候选人: 设计一个高并发系统,有以下几点建议:

  1. 选择高性能技术栈:选择支持高并发的语言(Java、Go 等)和框架(Spring、Vert.x 等)。
  2. 采用分布式和微服务架构:将系统拆分为多个单一职责的服务,部署在不同服务器上,可以实现高可用和负载均衡。
  3. 选择高性能存储:使用能支撑高并发读写的数据库,如 Redis、Kafka 等。对关系型数据库进行分库分表、添加缓存等优化。
  4. 限流与降级:使用限流手段控制流量,避免被高流量打垮;使用降级策略保证核心服务可用。
  5. 缓存与异步:对频繁读取数据的接口使用缓存;对非关键性计算使用异步处理,避免线程阻塞。
  6. 服务治理:使用服务注册与发现、熔断器、网关等手段管理各服务。
  7. 线程模型优化:根据业务选择恰当的线程模型。如对大量短连接使用线程池;对长连接使用主从 Reactor 线程模型等。
  8. 利用好硬件资源:合理分配 CPU 和内存资源给应用;利用好多核 CPU 进行并行计算等。
  9. 测试与监控:进行压力测试,监控系统的负载、吞吐量和延迟指标,并进行优化。
  10. 容错和自动恢复:设计稳定的容错方案,当系统发生故障时可以自动检测并恢复。
    这些方面搭配得当,可以设计一个高性能、高并发的系统。但需要权衡系统复杂性,在满足需求前提下保持最简实现。

面试官: 很棒,你在高并发系统设计方面有很强的理解力和丰富经验。

最近我在更新《面试1v1》系列文章,主要以场景化的方式,讲解我们在面试中遇到的问题,致力于让每一位工程师拿到自己心仪的offer,感兴趣可以关注JavaPub追更!


《面试1v1》 连载中…


🎁目录合集:

Gitee:https://gitee.com/rodert/JavaPub

GitHub:https://github.com/Rodert/JavaPub

http://javapub.net.cn

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/651427.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

浅谈微前端

本文呢是我梳理的一个扫盲文,由于最近团队准备使用微前端对项目进行改造,所以我呢就先浅了解一下: 微前端到底是什么? 为什么要使用微前端? 都有哪些微前端方案? 微前端有什么不好的地方吗? 通过…

48 最佳实践-性能最佳实践-Guest-Idle-Haltpoll

文章目录 48 最佳实践-性能最佳实践-Guest-Idle-Haltpoll48.1 概述48.2 操作指导 48 最佳实践-性能最佳实践-Guest-Idle-Haltpoll 48.1 概述 为了保证公平性及降低功耗,当虚拟机vCPU空闲时,虚拟机将执行WFx/HLT指令退出到宿主机中,并触发上…

计算机视觉 - 基于黄金模板比较技术的缺陷检测

一、黄金模板比较概述 基于黄金模板比对的检测是一种常见的视觉应用。当进行缺陷检查而其他缺陷检测方法是不可行的时候,使用金模板比较。另外当物体的表面或物体的形状非常复杂时,此技术特别有用。 虽然说黄金模板比较的技术的思路很简单,但是真正落地实施确不是一件十分容…

广告数仓:数仓搭建(二)

系列文章目录 广告数仓:采集通道创建 广告数仓:数仓搭建 广告数仓:数仓搭建(二) 文章目录 系列文章目录前言DWD层创建1.建表广告事件事实表 2.数据装载初步解析日志解析IP和UA标注无效流量编写脚本 总结 前言 这次我们完成数仓剩下的内容 D…

Web服务器群集:Web基础与HTTP协议

目录 一、理论 1.Web基础 2.HTTP协议 二、实验 1.浏览本地HTML页面 三、总结 一、理论 1.Web基础 (1)域名和DNS ① 域名 网络是基于TCP/IP 协议进行通信和连接的,每一台主机都有一个唯一的标识(固定的IP地 址&#xff0…

【Java面试】什么是SpringMVC?它的工作流程是什么样子的?

文章目录 什么是MVC?MVC组件组件前端控制器DispatcherServlet处理器映射器HandlerMapping处理器适配器HandlAdapter视图解析器ViewResolver处理器Handler视图View 工作原理具体执行流程 什么是MVC? M:model,模型层,包…

搅拌机打蒜机不转维修

打蒜机不转维修:打蒜机用的18650电池,霍尔传感器,Dp0206场效应管。故障为按一下开关显示红灯:电池电压低!按下启动按钮电机动一下就再不动了。如果给电池两边加一个5伏电源,打蒜机电机运行正常。那么我把充…

【028】C++ 类和对象的 构造函数、析构函数、拷贝构造、初始化列表 详解(最全讲解)

C类和对象的构造函数、析构函数、拷贝构造、初始化列表详解 引言一、构造函数1.1、数据初始化和清理1.2、构造函数概述1.3、构造函数的定义1.4、提供构造函数的影响 二、析构函数三、拷贝构造函数3.1、拷贝构造的定义3.2、拷贝构造、无参构造、有参构造 三者的关系3.3、拷贝构造…

【群智能算法改进】一种改进的浣熊优化算法 改进长鼻浣熊优化算法 改进后的ICOA[1]算法【Matlab代码#41】

文章目录 【获取资源请见文章第5节:资源获取】1. 原始COA算法1.1 开发阶段1.2 探索阶段 2. 改进后的ICOA算法2.1 Circle映射种群初始化2.2 Levy飞行策略2.3 透镜成像折射反向学习策略 3. 部分代码展示4. 仿真结果展示5. 资源获取 【获取资源请见文章第5节&#xff1…

05-DataFrame的数据清洗

数据清洗 import pandas as pd df pd.read_excel("学生成绩.xlsx") df删除重复列 df.drop_duplicates(inplaceTrue) df删除数学成绩 df.drop([数学成绩],axis1, inplaceTrue) df重命名列名字 df.rename(columns{"生活":"自然"},inplaceTrue…

什么是Redis的BigKey,如何处理BigKey?

一、什么是BigKey BigKey通常以Key的大小和Key中成员的数量来综合判定,例如: Key本身的数据量过大:一个String类型的Key,它的值为5 MB。Key中的成员数过多:一个ZSET类型的Key,它的成员数量为10,000个。Ke…

Linux之多线程(下)——线程控制

文章目录 前言一、POSIX线程库1.概念2.pthread线程库是应用层的原生线程库3.错误的检查 二、线程控制1.创建线程——pthread_createpthread_create函数例子创建一个新线程主线程创建一批新线程 2.获取线程ID——pthread_self3.线程等待——pthread_join4.线程终止——return、p…

SSH服务器详解

文章目录 文字接口连接服务器:SSH服务器连接加密技术简介启动SSH服务SSH客户端连接程序SSH:直接登录远程主机的指令使用案例 服务器公钥记录文件:~/.ssh/known_hosts报错解决 模拟FTP的文件传输方式:SFTP使用案例 文件异地直接复制…

Python主要应用的10大领域你是否感兴趣

原文: Python主要应用的10大领域你是否感兴趣 Python 是一门快速发展的编程语言,其在各个领域的应用也在不断增加。根据 TIOBE 编程语言排行榜,Python 在 2021 年排名第 3,仅次于 Java 和 C。根据 Stack Overflow 的开发者调查报…

圆的基本性质

如何确定一个圆? 两个点: 无法确定一个圆,因为只要到这两个点距离相等的点都可以作为圆心(在两个点连线的垂直平分线上),因此可以确定无数个圆 三个点(且这三个点不能在同一个直线上&#xf…

【MySQL数据库】事务

事务 一、事务1.1事务的概念 二 、事务的ACID特点2.1原子性2.2一致性(Consistency)2.3隔离性2.4持久性 三、脏读、不可重复读、幻读、丢失更新3.1脏读3.2不可重复读3.3幻读3.4丢失更新 四、事务的隔离级别 一、事务 1.1事务的概念 事务是一种机制、一个…

二叉堆(大顶堆、小顶堆)学习(使用java手写)

二叉堆 我们现在有一个需求,用来存放整数,要求需要提供三个接口 添加元素获取最大值删除最大值 我们可以用我们熟悉的数据结构去解决这些问题 获取最大值删除最大值添加元素描述动态数组/双向链表O(n)O(n)O(1)O(n) 复杂度太高了(有序&#x…

redis -- 持久化存储方案

前言 一般情况下,我们存储到redis的数据,是存储到内存中,再存储到硬盘中(这是基于reb方案来实现)因此一旦强制关机,就直接over了。 硬存和内存的区别和联系: 我们用文本编辑器,里面写入一段话,未保存&am…

检测PPG信号的心跳

基于大佬的代码。 PPG信号靠心率 (HR) 进行估计,主要取决于收缩压峰值检测的准确性。与 ECG 不同,PPG 信号形式简单和特定点 少。低振幅 PPG 信号更容易受到噪声污染和其他不良影响的影响,例如baseline drift和wandering。这是由于信号强度与…

从零开始理解Linux中断架构(3)--Armv8体系架构

首先让我们带着问题进入到armv8架构的学习中。linux中断代码分为两部分entry.S @arch\arm64\kernel\entry.S汇编部分和C代码后续处理。汇编代码中处理最为低级的部分,设置硬件中断向量表,保持当前上下文,切换中断堆栈等任务,这是就如我们嵌入式系统看到那样。 @arch\arm64…