面试题02

1. 常见的持久层框架有哪些?

主要持久层框架:

  • MyBatis - 半自动ORM框架
  • Hibernate - 全自动ORM框架
  • Spring Data JPA - 基于JPA规范的框架
  • JdbcTemplate - Spring提供的JDBC模板
  • JOOQ - 面向对象的SQL查询框架
  • MyBatis-Plus - MyBatis的增强工具

2. 什么是半自动?什么是全自动?

半自动(MyBatis):

  • 开发者需要手动编写SQL语句
  • 框架负责SQL执行和结果映射
  • 更灵活,可以优化复杂SQL
  • 学习成本相对较低

全自动(Hibernate):

  • 框架自动生成SQL语句
  • 通过对象关系映射(ORM)自动操作数据库
  • 开发效率高,但复杂查询性能可能不佳
  • 学习曲线较陡峭

3. Mybatis和Hibernate有什么区别?

特性 MyBatis Hibernate
SQL控制 手动编写SQL 自动生成SQL
性能 可优化复杂SQL 复杂查询性能较差
学习曲线 平缓 陡峭
灵活性 高,可编写任意SQL 相对较低
缓存 一级、二级缓存 更完善的缓存机制
适用场景 复杂查询、需要SQL优化 简单CRUD、快速开发

4. 泛型和Object有什么区别?

泛型的优势:

java 复制代码
// 泛型 - 类型安全
List<String> list1 = new ArrayList<>();
list1.add("hello");
String str = list1.get(0); // 不需要强制类型转换

// Object - 需要类型转换
List list2 = new ArrayList();
list2.add("hello");
String str = (String) list2.get(0); // 需要强制类型转换,可能ClassCastException

主要区别:

  • 类型安全:泛型在编译期进行类型检查,Object在运行期可能抛出ClassCastException
  • 代码简洁性:泛型不需要强制类型转换
  • 可读性:泛型代码意图更明确
  • 重用性:泛型可以编写更通用的类型安全代码

5. 6. 项目中使用泛型的例子

例子1:统一响应结果封装

java 复制代码
// 使用泛型封装统一响应格式
public class Result<T> {
    private boolean success;
    private String message;
    private T data;  // 泛型数据
    
    public static <T> Result<T> success(T data) {
        Result<T> result = new Result<>();
        result.setSuccess(true);
        result.setData(data);
        return result;
    }
}

// 使用
Result<User> userResult = Result.success(user);
Result<List<User>> listResult = Result.success(userList);

例子2:分页查询结果

java 复制代码
// 泛型分页结果
public class PageResult<T> {
    private long total;
    private List<T> list;  // 泛型列表
    
    // 构造方法
    public static <T> PageResult<T> of(List<T> list, long total) {
        PageResult<T> result = new PageResult<>();
        result.setList(list);
        result.setTotal(total);
        return result;
    }
}

// 使用
PageResult<User> userPage = userService.getUsers(pageRequest);

例子3:工具类中的泛型方法

java 复制代码
// 类似你提供的CopyUtil
public class BeanUtil {
    public static <T> T copyProperties(Object source, Class<T> targetClass) {
        // 实现拷贝逻辑
        return target;
    }
    
    public static <T> List<T> copyList(List<?> sourceList, Class<T> targetClass) {
        return sourceList.stream()
            .map(source -> copyProperties(source, targetClass))
            .collect(Collectors.toList());
    }
}

例子4:Service层泛型使用

java 复制代码
// 基础Service接口
public interface BaseService<T, ID> {
    T findById(ID id);
    List<T> findAll();
    T save(T entity);
    void deleteById(ID id);
}

// 具体实现
@Service
public class UserService implements BaseService<User, Long> {
    @Override
    public User findById(Long id) {
        // 实现
    }
    
    @Override
    public List<User> findAll() {
        // 实现
    }
}

CopyUtil`中使用的泛型就是很好的实践,让工具类可以处理任意类型的对象拷贝。

相关推荐
鬼火儿1 天前
SpringBoot】Spring Boot 项目的打包配置
java·后端
cr7xin1 天前
缓存三大问题及解决方案
redis·后端·缓存
间彧1 天前
Kubernetes的Pod与Docker Compose中的服务在概念上有何异同?
后端
间彧1 天前
从开发到生产,如何将Docker Compose项目平滑迁移到Kubernetes?
后端
间彧1 天前
如何结合CI/CD流水线自动选择正确的Docker Compose配置?
后端
间彧1 天前
在多环境(开发、测试、生产)下,如何管理不同的Docker Compose配置?
后端
间彧1 天前
如何为Docker Compose中的服务配置健康检查,确保服务真正可用?
后端
间彧1 天前
Docker Compose和Kubernetes在编排服务时有哪些核心区别?
后端
间彧1 天前
如何在实际项目中集成Arthas Tunnel Server实现Kubernetes集群的远程诊断?
后端
brzhang1 天前
读懂 MiniMax Agent 的设计逻辑,然后我复刻了一个MiniMax Agent
前端·后端·架构