【大白话说Java面试题 第164题】【06_Spring篇】第24题:如何理解 SpringBoot 的 Starter?

📌 PDF :大白话说Java面试题 --- 06_Spring篇

第24题:如何理解 SpringBoot 的 Starter?

📚 回答:

  • 核心考点Starter 是 SpringBoot "约定优于配置" 哲学的核心载体。大厂面试中,面试官不会满足于"Starter 是一组依赖打包"这种表面理解,而是期望你深入理解 Starter 的工程结构pom.xml 依赖管理 + autoconfigure 模块 + starter 空壳模块)、官方 Starter 与第三方 Starter 的命名规范差异spring-boot-starter-xxx vs xxx-spring-boot-starter)、Starter 与自动配置的协同关系 (Starter 负责依赖聚合,自动配置负责条件装配)、Starter 的依赖传递与版本仲裁机制spring-boot-dependencies BOM 管理)、以及 自定义 Starter 的完整工程实践(多模块结构、条件注解设计、配置属性绑定、发布到 Maven 仓库)。面试官真正想判断的是:你是否能从工程架构和源码级理解 Starter 的设计哲学,以及能否在生产环境中设计和维护企业级 Starter。

1. Starter 的本质:依赖聚合 + 自动配置的模块化单元

Starter 不是简单的"依赖打包",而是 SpringBoot 生态的标准化功能模块单元,遵循"引入即用"(Out-of-the-Box)的设计哲学:

维度 传统 Spring 项目 SpringBoot + Starter
依赖管理 手动引入多个依赖,版本冲突频繁 引入一个 Starter,传递依赖自动管理
配置方式 大量 XML/Java 配置 自动配置 + application.yml 少量属性覆盖
集成成本 高(需理解各组件的初始化顺序) 低(Starter 内部已处理初始化顺序)
可维护性 低(版本升级需手动调整所有依赖) 高(升级 SpringBoot 版本即可统一升级)

核心设计原则

  1. 单一职责:每个 Starter 只负责一个功能领域(如 Web、JDBC、Redis);
  2. 依赖传递 :Starter 通过 pom.xml<dependencies> 引入所有必需依赖;
  3. 版本仲裁 :通过 spring-boot-dependencies BOM 统一管理版本,避免冲突;
  4. 条件装配 :通过自动配置类 + @Conditional 注解实现"按需加载"。citation:0

2. Starter 的工程结构:官方 Starter 的双模块设计

官方 Starter 通常采用 双模块结构 (以 spring-boot-starter-web 为例):

复制代码
spring-boot-starter-web/          ← 空壳 Starter(仅依赖管理)
├── pom.xml                       ← 引入 spring-boot-starter + spring-web + spring-webmvc + tomcat-embed 等
└── src/                          ← 无代码,纯依赖声明

spring-boot-autoconfigure/        ← 自动配置模块(核心逻辑)
├── src/main/java/
│   └── org/springframework/boot/autoconfigure/web/servlet/
│       ├── WebMvcAutoConfiguration.java      ← @ConditionalOnClass + @EnableConfigurationProperties
│       ├── WebMvcProperties.java             ← @ConfigurationProperties("spring.mvc")
│       └── DispatcherServletAutoConfiguration.java
└── src/main/resources/
    └── META-INF/
        ├── spring.factories                    ← Spring Boot 2.x 自动配置注册
        └── spring/
            └── org.springframework.boot.autoconfigure.AutoConfiguration.imports  ← Spring Boot 3.x 注册

为什么分离为两个模块?

模块 职责 被谁依赖 是否包含代码
Starter(空壳) 依赖聚合,声明该功能需要的所有 jar 包 用户项目直接引入 无代码
AutoConfigure(核心) 自动配置逻辑,条件装配、属性绑定 被 Starter 传递依赖 包含配置类

设计优势

  • 解耦:用户只关心"引入哪些依赖"(Starter),不关心"如何自动配置"(AutoConfigure);
  • 可选性 :如果用户不需要自动配置,可以只引入 spring-boot-autoconfigure 依赖而不引入 Starter;
  • 版本隔离:Starter 版本与 SpringBoot 版本绑定,AutoConfigure 版本独立演进。

citation:1


3. 命名规范:官方 vs 第三方
类型 命名格式 示例 归属
官方 Starter spring-boot-starter-xxx spring-boot-starter-web Spring 官方团队维护
官方技术 Starter spring-boot-starter-xxx spring-boot-starter-data-redis Spring Data 团队维护
第三方 Starter xxx-spring-boot-starter mybatis-spring-boot-starter 社区/企业维护
自定义 Starter xxx-spring-boot-starter company-oss-spring-boot-starter 企业内部维护

命名规范的意义

  • spring-boot-starter- 前缀表示 Spring 官方出品,用户可放心使用;
  • xxx-spring-boot-starter 表示 第三方/社区出品,需评估维护活跃度;
  • 避免命名冲突,方便 Maven Central 搜索和依赖管理。

常见官方 Starter 速查

Starter 功能 核心自动配置类
spring-boot-starter-web Web 应用(MVC + Tomcat) WebMvcAutoConfiguration
spring-boot-starter-data-jpa JPA 数据访问 HibernateJpaAutoConfiguration
spring-boot-starter-data-redis Redis 缓存 RedisAutoConfiguration
spring-boot-starter-jdbc JDBC 数据源 DataSourceAutoConfiguration
spring-boot-starter-security 安全认证 SecurityAutoConfiguration
spring-boot-starter-test 测试支持 TestAutoConfiguration
spring-boot-starter-actuator 监控端点 EndpointAutoConfiguration

citation:2


4. Starter 的依赖传递与版本仲裁机制
  • 4.1 依赖传递 Starter 通过 pom.xml 引入所有必需依赖,用户只需引入 Starter 即可获得完整功能:

    xml 复制代码
    <!-- spring-boot-starter-web 的 pom.xml(简化) -->
    <dependencies>
        <!-- 基础 Starter -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <!-- Web 核心 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-json</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
        </dependency>
    </dependencies>
  • 4.2 版本仲裁(BOM 管理) SpringBoot 通过 spring-boot-dependencies BOM(Bill of Materials)统一管理所有 Starter 及其传递依赖的版本:

    xml 复制代码
    <!-- 用户项目的 pom.xml -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.18</version>
    </parent>
    
    <dependencies>
        <!-- 无需指定版本,由 parent 的 BOM 统一管理 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
    </dependencies>

    spring-boot-dependencies BOM 中定义了数百个依赖的版本属性:

    xml 复制代码
    <!-- spring-boot-dependencies 中的版本管理(简化) -->
    <properties>
        <spring-framework.version>5.3.31</spring-framework.version>
        <tomcat.version>9.0.83</tomcat.version>
        <jackson.version>2.15.3</jackson.version>
        <mysql.version>8.0.33</mysql.version>
    </properties>

    版本覆盖机制 :如果用户需要覆盖某个依赖版本,可以在自己项目的 pom.xml 中定义同名属性:

    xml 复制代码
    <properties>
        <mysql.version>8.0.35</mysql.version>  <!-- 覆盖 BOM 中的版本 -->
    </properties>

    citation:3


5. Starter 与自动配置的协同关系

Starter 和自动配置是 "依赖聚合"与"条件装配" 的协同关系,缺一不可:

复制代码
用户引入 Starter
    ↓
Starter 传递依赖(引入 autoconfigure + 功能 jar)
    ↓
SpringBoot 启动 → @EnableAutoConfiguration
    ↓
AutoConfigurationImportSelector 加载 META-INF/spring.factories
    ↓
读取自动配置类(如 WebMvcAutoConfiguration)
    ↓
@ConditionalOnClass(Servlet.class) 判断类路径是否存在 Servlet API
    ↓
存在 → 自动配置生效,注册 Bean(DispatcherServlet、Tomcat 等)
不存在 → 自动配置跳过,不报错

关键认知

  • Starter 不负责自动配置:它只负责引入依赖;
  • 自动配置不依赖 Starter :如果用户手动引入 spring-webmvc + spring-boot-autoconfigure,自动配置同样生效;
  • Starter 是"入口",自动配置是"引擎"

citation:4


6. 自定义 Starter 的完整工程实践
  • 6.1 多模块工程结构 企业级自定义 Starter 应遵循官方的双模块结构:

    复制代码
    company-oss-spring-boot-starter/     ← 根项目(POM 聚合)
    ├── company-oss-spring-boot-autoconfigure/   ← 自动配置模块(含代码)
    │   ├── pom.xml
    │   └── src/main/
    │       ├── java/com/company/oss/autoconfigure/
    │       │   ├── OssAutoConfiguration.java        ← @AutoConfiguration + @ConditionalOnClass
    │       │   ├── OssProperties.java               ← @ConfigurationProperties("company.oss")
    │       │   └── OssService.java                  ← 核心服务类
    │       └── resources/
    │           └── META-INF/
    │               └── spring/
    │                   └── org.springframework.boot.autoconfigure.AutoConfiguration.imports
    ├── company-oss-spring-boot-starter/         ← 空壳 Starter(仅依赖)
    │   ├── pom.xml                                ← 引入 autoconfigure + sdk 依赖
    │   └── src/                                   ← 无代码
    └── pom.xml                                    ← 聚合 POM,定义版本和依赖管理
  • 6.2 自动配置类设计 遵循"条件装配 + 属性绑定 + 默认兜底"三原则:

    java 复制代码
    @AutoConfiguration  // Spring Boot 2.7+ 推荐,替代 @Configuration
    @ConditionalOnClass(OssClient.class)  // 类路径存在 OssClient 才生效
    @EnableConfigurationProperties(OssProperties.class)  // 启用属性绑定
    @ConditionalOnProperty(prefix = "company.oss", name = "enabled", havingValue = "true", matchIfMissing = true)
    public class OssAutoConfiguration {
    
        @Bean
        @ConditionalOnMissingBean  // 用户未自定义时才创建
        public OssClient ossClient(OssProperties properties) {
            return OssClient.builder()
                .endpoint(properties.getEndpoint())
                .accessKey(properties.getAccessKey())
                .secretKey(properties.getSecretKey())
                .bucket(properties.getBucket())
                .build();
        }
    
        @Bean
        @ConditionalOnMissingBean
        public OssService ossService(OssClient ossClient) {
            return new OssService(ossClient);
        }
    }
  • 6.3 属性配置类设计 提供完整的 IDE 自动提示支持:

    java 复制代码
    @ConfigurationProperties(prefix = "company.oss")
    @Data
    public class OssProperties {
        /** 是否启用 OSS 自动配置,默认 true */
        private boolean enabled = true;
        /** OSS 服务端点,必填 */
        private String endpoint;
        /** AccessKey ID,必填 */
        private String accessKey;
        /** AccessKey Secret,必填 */
        private String secretKey;
        /** 默认 Bucket */
        private String bucket;
        /** 连接超时时间(毫秒),默认 3000 */
        private int connectionTimeout = 3000;
        /** 读取超时时间(毫秒),默认 10000 */
        private int readTimeout = 10000;
    }

    IDE 自动提示支持 :在 autoconfigure 模块的 resources/META-INF 下添加 additional-spring-configuration-metadata.json

    json 复制代码
    {
      "properties": [
        {
          "name": "company.oss.endpoint",
          "type": "java.lang.String",
          "description": "OSS 服务端点,如 https://oss-cn-hangzhou.aliyuncs.com",
          "sourceType": "com.company.oss.autoconfigure.OssProperties"
        }
      ],
      "hints": [
        {
          "name": "company.oss.endpoint",
          "values": [
            {"value": "https://oss-cn-hangzhou.aliyuncs.com", "description": "杭州节点"},
            {"value": "https://oss-cn-beijing.aliyuncs.com", "description": "北京节点"}
          ]
        }
      ]
    }
  • 6.4 注册自动配置类 Spring Boot 3.x 在 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 中注册:

    复制代码
    com.company.oss.autoconfigure.OssAutoConfiguration
  • 6.5 空壳 Starter 的 pom.xml 只负责依赖聚合,无代码:

    xml 复制代码
    <project>
        <parent>
            <groupId>com.company</groupId>
            <artifactId>company-oss-spring-boot-starter-parent</artifactId>
            <version>1.0.0</version>
        </parent>
        <artifactId>company-oss-spring-boot-starter</artifactId>
        <dependencies>
            <!-- 引入自动配置模块 -->
            <dependency>
                <groupId>com.company</groupId>
                <artifactId>company-oss-spring-boot-autoconfigure</artifactId>
                <version>${project.version}</version>
            </dependency>
            <!-- 引入 OSS SDK -->
            <dependency>
                <groupId>com.aliyun.oss</groupId>
                <artifactId>aliyun-sdk-oss</artifactId>
            </dependency>
        </dependencies>
    </project>

    citation:5


7. 自定义 Starter 的最佳实践与避坑指南
原则 说明 反例
必须加 @ConditionalOnMissingBean 保护用户自定义 Bean,避免冲突 不加则用户无法覆盖默认配置
必须提供 enabled 开关 允许用户通过配置关闭自动配置 无法关闭,强制生效
属性类必须提供默认值 降低用户配置成本 所有属性必填,使用门槛高
必须处理依赖不存在的情况 @ConditionalOnClass 避免 ClassNotFoundException 直接引用类,类路径不存在时启动失败
版本与 SpringBoot 兼容 测试多个 SpringBoot 版本的兼容性 只测试最新版本,旧版本兼容性问题
提供配置元数据 additional-spring-configuration-metadata.json 支持 IDE 提示 无元数据,用户配置时无提示
Starter 无代码,AutoConfigure 有代码 严格分离职责 把配置类直接放在 Starter 中

常见陷阱

  1. 循环依赖:AutoConfigure 模块依赖 Starter 模块,导致循环;
  2. 版本冲突:Starter 引入的依赖版本与项目已有依赖冲突;
  3. 自动配置未生效 :忘记在 importsspring.factories 中注册;
  4. 条件注解写反@ConditionalOnMissingBean 写成 @ConditionalOnBean,导致配置永远不生效。

8. 面试官追问与高分回答模板
  • 追问 1:"什么是 SpringBoot 的 Starter?它和自动配置是什么关系?"

    低分回答:"Starter 是一组依赖的打包,引入后自动配置相关功能。"(没有区分 Starter 和自动配置的职责)

    高分回答 : > "Starter 是 SpringBoot 的 模块化功能单元 ,遵循'引入即用'的设计哲学。它包含两个层面的职责: > 1. 依赖聚合 :Starter 的 pom.xml 引入该功能所需的所有依赖(如 spring-boot-starter-web 引入 spring-webmvctomcat-embed 等),通过 spring-boot-dependencies BOM 统一管理版本,避免冲突; > 2. 自动配置协同 :Starter 本身不直接包含自动配置代码,而是通过传递依赖引入 spring-boot-autoconfigure 模块中的自动配置类。自动配置类通过 @ConditionalOnClass@ConditionalOnMissingBean 等条件注解实现'按需加载'。 > 核心关系 :Starter 是'入口',负责依赖聚合;自动配置是'引擎',负责条件装配。两者协同实现'引入依赖即可用'。用户也可以只引入 spring-webmvc + spring-boot-autoconfigure 而不引入 Starter,自动配置同样生效。"

  • 追问 2:"官方 Starter 和第三方 Starter 的命名规范有什么区别?为什么这样设计?"

    高分回答 : > "命名规范是 '谁维护,谁前缀' 的原则: > - 官方 Starterspring-boot-starter-xxx,如 spring-boot-starter-webspring-boot-starter-data-redisspring-boot-starter- 前缀表示 Spring 官方团队维护,用户可放心使用,版本与 SpringBoot 绑定。 > - 第三方 Starterxxx-spring-boot-starter,如 mybatis-spring-boot-starterdruid-spring-boot-starter。第三方前缀表示社区或企业维护,需要评估维护活跃度。 > 这样设计的目的: > 1. 避免命名冲突 :Maven Central 上不会出现同名不同源的 Starter; > 2. 信任标识spring-boot-starter- 前缀是官方背书,降低用户选择成本; > 3. 搜索友好:IDE 和 Maven 仓库搜索时,前缀区分一目了然。"

  • 追问 3:"自定义 Starter 时,为什么要把 autoconfigure 和 starter 分成两个模块?"

    高分回答 : > "双模块设计是官方 Starter 的标准工程实践,核心目的是 职责分离和可选性 : > 1. Starter 模块(空壳) :只包含 pom.xml,负责聚合依赖。用户引入这个模块即可获得所有功能依赖。它无代码,只声明'需要什么'。 > 2. AutoConfigure 模块(核心) :包含自动配置类、属性类、条件注解逻辑。它负责'如何配置'。 > 分离的优势: > - 解耦 :用户只关心'引入哪些依赖'(Starter),不关心'如何自动配置'(AutoConfigure)。如果用户不需要自动配置(如已有自定义配置),可以只引入 AutoConfigure 模块的依赖而不引入 Starter; > - 版本隔离 :Starter 版本与 SpringBoot 版本绑定,AutoConfigure 可以独立演进; > - 测试隔离:AutoConfigure 可以独立测试,不依赖 Starter 的依赖传递。 > 反例:如果把配置类直接放在 Starter 中,用户无法单独使用自动配置逻辑,且 Starter 的依赖变化会直接影响配置类编译。"

  • 追问 4:"自定义 Starter 时,@ConditionalOnMissingBean 是必须的吗?不加会怎样?"

    高分回答 : > "是必须的 ,这是 Starter 设计的核心原则之一。 > 不加 @ConditionalOnMissingBean 的后果: > 1. Bean 冲突 :如果用户项目中也定义了同名同类型的 Bean(如自定义 DataSource),Spring 容器启动时会抛出 NoUniqueBeanDefinitionException 或后注册的 Bean 覆盖先注册的(取决于 allowBeanDefinitionOverriding 配置); > 2. 用户无法覆盖 :Starter 的默认配置强制生效,用户即使写了自定义配置也会被覆盖(如果 Starter 的 Bean 后注册); > 3. 灵活性丧失 :违背了 SpringBoot '约定优于配置,但配置可覆盖约定' 的设计哲学。 > 正确做法:所有自动配置类中的 @Bean 都应该加 @ConditionalOnMissingBean,确保用户自定义 Bean 优先级高于默认 Bean。同时配合 @ConditionalOnClass 确保类路径存在相关依赖时才加载,避免 ClassNotFoundException。"

  • 追问 5:"SpringBoot 的 BOM 机制是怎么管理 Starter 版本的?如果我想升级某个依赖版本怎么办?"

    高分回答 : > "SpringBoot 通过 spring-boot-dependencies BOM(Bill of Materials)统一管理所有 Starter 及其传递依赖的版本。用户项目继承 spring-boot-starter-parent 后,引入任何 Starter 都无需指定版本,由 parent 的 BOM 仲裁。 > BOM 的核心机制: > 1. 版本属性集中管理spring-boot-dependencies<properties> 中定义了 spring-framework.versiontomcat.versionjackson.version 等数百个版本属性; > 2. 依赖版本锁定<dependencyManagement> 中通过 ${xxx.version} 引用这些属性,锁定所有传递依赖的版本; > 3. 传递依赖仲裁 :当多个 Starter 引入同一依赖的不同版本时,BOM 中的版本作为最终仲裁。 > 升级单个依赖版本的方法: > 1. 覆盖属性 :在项目的 pom.xml 中定义同名属性,如 <mysql.version>8.0.35</mysql.version>,优先级高于 parent; > 2. 直接指定版本 :在 <dependency> 中显式写 <version>,但会失去 BOM 的统一管理; > 3. 升级 SpringBoot 版本:直接升级 parent 版本,所有依赖跟随升级,最简单但影响面最大。"

  • 追问 6:"如果自定义 Starter 的自动配置没有生效,你会怎么排查?"

    高分回答 : > "排查自动配置未生效,我通常按以下步骤: > 1. 检查注册文件 :确认 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports(Spring Boot 3.x)或 META-INF/spring.factories(Spring Boot 2.x)中是否正确注册了自动配置类的全限定名; > 2. 检查条件注解 :在自动配置类上加 @ConditionalOnClass(Xxx.class),确认类路径中确实存在 Xxx 类。可以用 spring-boot-autoconfigure-processor 生成配置元数据,在编译期检查条件; > 3. 检查属性开关 :确认 application.yml 中没有 company.oss.enabled=false 之类的关闭配置; > 4. 检查 Bean 覆盖 :确认没有用户自定义的同名 Bean 导致 @ConditionalOnMissingBean 判断为 false; > 5. 开启 DEBUG 日志 :配置 logging.level.org.springframework.boot.autoconfigure=DEBUG,SpringBoot 会输出 Positive matchesNegative matches 报告,明确显示哪些自动配置类生效、哪些被跳过及原因; > 6. 检查依赖传递 :确认 Starter 的 pom.xml 正确引入了 autoconfigure 模块,且用户项目正确引入了 Starter。 > 最有效的方法是开启 DEBUG 日志,直接看 Negative matches 中该配置类的跳过原因。"


9. 方案选型速查表
场景 推荐方案 说明
使用官方功能 引入官方 spring-boot-starter-xxx 版本由 SpringBoot 统一管理
使用第三方框架 引入第三方 xxx-spring-boot-starter 评估维护活跃度和兼容性
企业内部通用组件封装 自定义 Starter(双模块结构) 遵循 xxx-spring-boot-starter 命名
不需要自动配置,只需依赖 直接引入底层 jar + spring-boot-autoconfigure 手动配置
版本冲突解决 覆盖 BOM 属性或显式指定版本 优先覆盖属性,保持统一管理
自动配置未生效排查 开启 DEBUG 日志看 Positive/Negative matches 最快速的定位方法

💡 面试官想要的满分总结

SpringBoot Starter 的本质是 "约定优于配置" 哲学的工程化实现 ,它通过 依赖聚合 + 自动配置协同 实现"引入即用"。理解 Starter 必须抓住三个核心维度:

  1. 工程结构维度 :官方 Starter 采用 双模块结构(空壳 Starter 负责依赖聚合 + AutoConfigure 模块负责条件装配),职责分离、可选性强、版本可独立演进。自定义 Starter 必须遵循这一规范。
  2. 版本管理维度 :通过 spring-boot-dependencies BOM 统一管理数百个依赖版本,用户引入 Starter 无需指定版本。升级 SpringBoot 版本即可统一升级所有 Starter 依赖,大幅降低维护成本。
  3. 自动配置维度 :Starter 本身不直接配置,而是通过传递依赖引入 AutoConfigure 模块。自动配置类通过 @ConditionalOnClass(按需加载)、@ConditionalOnMissingBean(保护用户配置)、@ConditionalOnProperty(配置开关)实现精确的条件装配。

自定义 Starter 的最佳实践:

  • 必须加 @ConditionalOnMissingBean 保护用户自定义 Bean;
  • 必须提供 enabled 配置开关;
  • 属性类必须提供默认值降低使用门槛;
  • 必须提供 additional-spring-configuration-metadata.json 支持 IDE 自动提示;
  • 必须测试多个 SpringBoot 版本的兼容性。

最后记住:Starter 是"入口",自动配置是"引擎",BOM 是"版本管家"------三者协同构成了 SpringBoot 生态的模块化基石。


觉得对您有帮助,麻烦 点点关注啦 ,您的关注是我创作的最大动力~ 🎯

相关推荐
编程(变成)小辣鸡2 小时前
Spring事务失效场景
java·后端·spring
极客先躯3 小时前
高级java每日一道面试题-2026年03月30日-实战篇[Docker]-如何监控容器的网络流量?
java·运维·docker·容器·prometheus·高级面试
tachibana23 小时前
hot100 翻转二叉树(226)
java·数据结构·算法·leetcode
brave_zhao3 小时前
nginx的进程架构
java·学习·nginx
兰令水3 小时前
leecodecode【面试150】【2026.7.9打卡-java版本】
java·数据结构·leetcode·面试·职场和发展
禾高网络3 小时前
互联网医院|AI 互联网医院成品开发系统
java·大数据·人工智能·小程序
shepherd1113 小时前
一次把 Spring MVC 文件上传参数“查没了”的排查:multipart、Filter 与 request body 的连环坑
java·spring boot·后端
lbb 小魔仙3 小时前
MuMu 模拟器 6.0 硬核测评:这次升级确实不一样
java·开发语言·模拟器·mumu·硬核测评
前端炒粉3 小时前
手写promise
java·前端·javascript
H_HX1264 小时前
IDEA的下载和安装
java·intellij-idea·idea