• 【深圳五兴科技】Java后端面经


    写在前面

    关于这个专栏:
    本专栏记录一些互联网大厂、小厂的面试实录!包含校招、社招!
    内容主要来源:博主面试总结以及博主从牛客网等平台摘录
    专栏地址:2023Java面试实录

    试题总览

    在这里插入图片描述

    1、java集合

    Java集合框架提供了一组用于存储和操作数据的接口和类。以下是Java集合框架中最常用的一些集合类型:
    List(列表):有序、可重复的集合,常用的实现类有ArrayList和LinkedList。
    Set(集合):无序、不可重复的集合,常用的实现类有HashSet和TreeSet。
    Map(映射):键值对的集合,每个键唯一,常用的实现类有HashMap和TreeMap。
    Queue(队列):先进先出(FIFO)的集合,常用的实现类有LinkedList和PriorityQueue。
    Stack(栈):后进先出(LIFO)的集合,常用的实现类是Stack。
    Deque(双端队列):既可以作为队列使用,也可以作为栈使用的集合,常用的实现类是ArrayDeque。
    除了以上常用的集合类型,Java还提供了一些其他的集合类,如BitSet、Vector等,以满足不同的需求

    2、创建线程的方式

    在 Java 中,创建线程的方式主要有以下几种:

    1、继承 Thread 类:定义一个类继承自 Thread 类,并重写其 run() 方法来定义线程执行的任务。然后创建该类的实例并调用 start() 方法启动线程

    class MyThread extends Thread {
        public void run() {
            // 线程执行的任务
        }
    }
    MyThread thread = new MyThread();
    thread.start();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2、实现 Runnable 接口:定义一个实现了 Runnable 接口的类,实现接口中的 run() 方法来定义线程执行的任务。然后将该实现类的实例传递给 Thread 类的构造函数,并调用 start() 方法启动线程。

    class MyRunnable implements Runnable {
        public void run() {
            // 线程执行的任务
        }
    }
    
    MyRunnable myRunnable = new MyRunnable();
    Thread thread = new Thread(myRunnable);
    thread.start();
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    3、使用匿名内部类:可以通过匿名内部类的方式实现 Runnable 接口,简化代码编写。

    Runnable myRunnable = new Runnable() {
        public void run() {
            // 线程执行的任务
        }
    };
    
    Thread thread = new Thread(myRunnable);
    thread.start();
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    4、使用 Lambda 表达式:Java 8 引入的 Lambda 表达式可以进一步简化线程创建的代码。

    Runnable myRunnable = () -> {
        // 线程执行的任务
    };
    
    Thread thread = new Thread(myRunnable);
    thread.start();
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3、对spring的理解

    Spring 是一个开源的轻量级框架,它为构建企业级应用程序提供了全面的基础设施支持。以下是对 Spring 框架的一些理解:
    IoC(控制反转):Spring 提供了 IoC 容器,通过依赖注入的方式管理组件之间的依赖关系,降低了组件之间的耦合度,使得代码更加灵活、可维护、可测试。
    AOP(面向切面编程):Spring 支持 AOP 编程,通过切面(Aspect)将横切逻辑(如日志记录、事务管理等)与核心业务逻辑分离,提高了代码的模块化和可重用性。
    声明式事务管理:Spring 提供了声明式事务管理的支持,简化了事务管理的配置,使开发者能够专注于业务逻辑的实现,而不必过多关注事务管理的细节。
    模块化设计:Spring 框架被设计成由多个独立的模块组成,开发者可以根据需要选择合适的模块来使用,例如 Spring Core、Spring MVC、Spring Data 等,使得开发更加灵活和轻量级。
    简化开发:Spring 提供了大量的现成解决方案和模板,并且支持各种技术整合,如与 ORM 框架(如 Hibernate、MyBatis)的集成、与消息队列(如 ActiveMQ、RabbitMQ)的集成等,可以大大简化企业应用的开发过程。
    总的来说,Spring 框架通过提供一套全面的功能和良好的设计思想,帮助开发者快速构建可扩展、高效、易维护的企业级应用程序。

    4、Spring Boot 和传统 Spring 框架的一些区别

    Spring Boot 是基于 Spring 框架的一个开发框架,它旨在简化基于 Spring 的应用程序的配置和部署。下面是 Spring Boot 和传统 Spring 框架的一些区别:
    自动配置: Spring Boot 通过使用自动配置(auto-configuration)的机制,根据应用程序的依赖和配置,自动配置 Spring 相关的组件和功能。而传统的 Spring 框架需要手动配置大量的 XML 或 Java 配置文件。
    起步依赖: Spring Boot 引入了起步依赖(Starter Dependencies)的概念,它是一种预配置的依赖项集合,可以简化项目的依赖管理。通过引入相关的起步依赖,开发者无需手动添加和管理每个单独的依赖项。
    嵌入式服务器: Spring Boot 默认内嵌了常用的 Web 服务器,如 Tomcat、Jetty 或 Undertow,开发者无需手动配置或部署额外的服务器。
    简化的配置: Spring Boot 使用约定优于配置的原则,提供了默认的配置,使得开发者能够快速启动应用程序。同时,Spring Boot 支持外部化配置,可以通过属性文件、环境变量等方式灵活配置应用程序。
    健康检查和监控: Spring Boot 提供了健康检查和监控的功能,通过访问特定的端点(如/actuator/health)可以获取应用程序的运行状态、性能指标等信息。
    总的来说,Spring Boot 提供了一种更简化、更快速的开发方式,使得基于 Spring 的应用程序的开发、配置和部署更加高效和便捷。它适用于构建独立的、可扩展的、自包含的应用程序,而传统的 Spring 框架则更适用于需要更精细控制和配置的复杂应用程序。

    5、springboot如何解决循环依赖

    在 Spring Boot 中,处理循环依赖(circular dependency)的方式与传统的 Spring 框架是一致的。Spring 框架本身提供了解决循环依赖的机制,而 Spring Boot 作为基于 Spring 的快速开发框架,并未改变这一机制。
    通常情况下,Spring 解决循环依赖的方式是利用三级缓存(three-level cache):

    第一级缓存:Spring 在创建 bean 实例时,将正在创建的 bean 放入一个缓存中,以便后续引用。
    第二级缓存:如果在创建 bean 的过程中遇到循环依赖,Spring 将创建一个包装过的代理对象作为占位符,同时将未完成创建的 bean 放入第二级缓存中。
    第三级缓存:当出现循环依赖时,Spring 会尝试从第二级缓存中获取代理对象,然后通过调用代理对象的方法来完成对另一个 bean 的注入。

    通过这种方式,Spring 能够在遇到循环依赖时,仍然能够正常创建和管理 bean 实例。

    6、对mybatis的理解

    MyBatis 是一个优秀的持久层框架,它将 SQL 语句和 Java 代码进行分离,通过 XML 文件或注解来配置 SQL 映射关系,从而简化了数据库操作的编写和维护。以下是对 MyBatis 的一些理解:
    SQL 与 Java 之间的分离:MyBatis 采用了将 SQL 语句与 Java 代码进行分离的方式,通过编写 XML 文件或使用注解来定义 SQL 映射关系,使得开发者能够更清晰地管理 SQL 语句,减少了 Java 代码中硬编码 SQL 的情况。
    灵活的映射配置:MyBatis 支持灵活的映射配置,可以通过 XML 文件或注解来定义对象与数据库表之间的映射关系,包括字段映射、关联关系、结果集映射等,同时还支持动态 SQL,可以根据条件动态生成 SQL 语句。
    高度可定制化:MyBatis 提供了丰富的配置选项和插件机制,可以对其行为进行高度定制,例如配置缓存、执行器、日志输出等,同时还可以编写自定义插件来扩展 MyBatis 的功能。
    优秀的性能:MyBatis 使用 JDBC 进行底层数据库操作,性能较高,同时提供了缓存机制和延迟加载等功能,可以有效提升查询效率,并且避免了 ORM 框架的性能问题。
    轻量级框架:相比于其他 ORM 框架,MyBatis 是一个轻量级的框架,学习曲线较低,使用简单,适合对 SQL 有较好掌握的开发者使用,同时也支持与 Spring 等主流框架集成。
    总的来说,MyBatis 是一个功能强大、灵活可定制、性能优秀的持久层框架,适用于需要灵活控制 SQL 语句和数据库操作的项目,能够帮助开发者提高开发效率,同时保持良好的性能表现。

    7、缓存三兄弟

    "缓存三兄弟"通常指的是缓存击穿、缓存雪崩和缓存穿透,它们是在使用缓存时可能会遇到的一些常见问题。
    缓存击穿
    问题描述:指的是在某个时间点,某个热点数据突然失效,此时大量请求并发访问这个热点数据,导致所有请求都直接访问数据库,造成数据库压力剧增。
    解决方法:可以在缓存中设置热点数据的过期时间,或者使用互斥锁(如分布式锁)来避免多个线程同时访问数据库。
    缓存雪崩:
    问题描述:指的是缓存中大量数据同时失效,导致大量请求直接访问数据库,类似于缓存击穿,但是影响范围更广,可能涉及多个缓存键值对。
    解决方法:可以给缓存数据设置不同的过期时间,采用多级缓存策略,或者使用熔断机制来保护数据库。
    缓存穿透:
    问题描述:指的是恶意请求访问不存在的数据,由于缓存没有命中,请求直接访问数据库,这种请求可能是攻击性的,也可能是由于程序错误导致的。
    解决方法:可以在缓存中设置空对象占位,或者使用布隆过滤器等技术来拦截无效请求,另外也可以对请求参数进行校验来过滤无效请求。
    解决缓存问题需要综合考虑缓存的设计、失效策略、并发控制等多个方面,通常需要结合具体的业务场景和系统架构来进行调整和优化。

    8、接口响应慢的处理思路

    理接口响应慢的问题需要综合考虑系统性能、网络延迟、数据库查询等多个方面,以下是一些处理思路:
    性能监控和日志分析:
    首先,需要对系统进行性能监控和日志分析,通过监控工具和日志记录系统的响应时间、CPU 使用率、内存占用情况等,定位慢响应问题所在。
    优化数据库查询:
    如果接口涉及数据库查询,可以通过索引优化、SQL 优化、分库分表等方式来提升数据库查询效率。
    并发处理和线程池:
    对于需要大量并发处理的接口,可以采用线程池来管理并发请求,避免因为线程创建和销毁带来的性能损耗。
    缓存优化:
    对于需要频繁访问的数据,可以考虑增加缓存层,减少对数据库的访问,提高数据读取速度。
    网络优化:
    如果接口涉及跨网络通讯,可以通过优化网络拓扑结构、使用 CDN 等方式来提高网络传输效率。
    降级和限流:
    当接口响应慢时,可以考虑实施降级策略,返回默认数据或者提示信息,避免影响整个系统的稳定性;另外也可以考虑实施限流策略,控制并发访问量,避免系统过载。
    技术选型优化:
    对于某些核心接口,可以考虑优化底层技术选型,例如更高效的框架、更适合的数据库等。
    代码优化:
    在代码层面,可以通过优化算法、减少不必要的计算、减少内存使用等方式来提高接口响应速度。

    9、http的状态码

    HTTP 协议定义了多种状态码,用于表示客户端请求的处理结果。以下是一些常见的 HTTP 状态码及其含义:

    1xx 信息性状态码:

    100 Continue:服务器已经收到请求头,并且客户端应该继续发送请求体。
    101 Switching Protocols:服务器正在切换协议,例如切换到 WebSocket。
    
    • 1
    • 2

    2xx 成功状态码:

    200 OK:请求成功。
    201 Created:请求已创建新资源。
    204 No Content:服务器成功处理请求,但不返回任何内容。
    
    • 1
    • 2
    • 3

    3xx 重定向状态码:

    301 Moved Permanently:永久重定向。
    302 Found:临时重定向。
    304 Not Modified:资源未修改,可使用缓存的版本。
    
    • 1
    • 2
    • 3

    4xx 客户端错误状态码:

    400 Bad Request:请求无效。
    401 Unauthorized:未授权。
    403 Forbidden:禁止访问。
    404 Not Found:资源未找到。
    
    • 1
    • 2
    • 3
    • 4

    5xx 服务器错误状态码:

    500 Internal Server Error:服务器内部错误。
    502 Bad Gateway:网关错误。
    503 Service Unavailable:服务不可用。
    504 Gateway Timeout:网关超时。
    
    • 1
    • 2
    • 3
    • 4
  • 相关阅读:
    matplotlib的默认字体
    Datawhale 202208 GitModel |线性规划 整数规划 多目标规划 灵敏度分析
    Java版企业电子招标采购系统源代码Spring Boot + 二次开发 + 前后端分离 构建企业电子招采平台之立项流程图
    面试:Fragment懒加载
    如何设计开发一对一交友App吸引更多活跃用户
    一、爬虫-爬取豆瓣电影案例
    SpringCloud-12-Eureka:自我保护机制
    ExpressLRS开源代码之工程结构
    Mysql——》BufferPool相关信息
    Android 13中的 Open Mobile API
  • 原文地址:https://blog.csdn.net/qq_54796785/article/details/136474828