在互联网大厂的面试间里,气氛紧张而严肃。面试官正襟危坐,面前放着王铁牛的简历,王铁牛则有些紧张地坐在对面,双手不自觉地捏着衣角。
第一轮提问 面试官:首先,我们来聊聊 Java 核心知识。Java 中基本数据类型有哪些? 王铁牛:嗯,有 byte、short、int、long、float、double、char、boolean。 面试官:不错,回答得很准确。那你说说 String 类为什么是不可变的? 王铁牛:因为 String 类被 final 修饰,它的成员变量也是 final 的,所以不能被修改。 面试官:非常好。那在 Java 中,== 和 equals 方法有什么区别? 王铁牛:== 比较的是两个对象的内存地址,而 equals 方法在 Object 类中也是比较内存地址,但很多类重写了 equals 方法,用来比较对象的内容。 面试官:回答得很清晰,看来你对 Java 核心知识掌握得不错。
第二轮提问 面试官:接下来我们谈谈 JUC 和多线程。什么是线程安全? 王铁牛:就是在多线程环境下,对共享资源的操作不会出现数据不一致等问题。 面试官:很好。那 Java 中实现线程安全的方式有哪些? 王铁牛:可以用 synchronized 关键字,还有 JUC 包下的 Lock 接口实现类。 面试官:那你说说 synchronized 和 Lock 的区别。 王铁牛:synchronized 是 Java 的关键字,是隐式锁,会自动释放;Lock 是一个接口,是显式锁,需要手动释放。 面试官:你对多线程和 JUC 相关知识理解得挺到位的。
第三轮提问 面试官:现在我们来看看框架相关的。Spring 框架中 IOC 和 AOP 是什么? 王铁牛:IOC 是控制反转,把对象的创建和依赖关系的管理交给 Spring 容器;AOP 是面向切面编程,可以在不修改原有代码的基础上增加额外功能。 面试官:那 Spring Boot 相比 Spring 有什么优势? 王铁牛:Spring Boot 简化了 Spring 的配置,有自动配置功能,能快速搭建项目。 面试官:MyBatis 中 #{} 和 ${} 的区别是什么? 王铁牛:这个……嗯……好像一个是预编译,一个不是,但具体我有点说不太清楚。 面试官:那 Dubbo 框架的核心功能有哪些? 王铁牛:嗯……好像有服务注册与发现,还有远程调用,但细节我不太确定了。 面试官:看来你对一些框架的基础概念有了解,但部分细节还需要加强。
面试接近尾声,面试官放下手中的笔,看着王铁牛说:“今天的面试就到这里。你在 Java 核心知识、多线程和 JUC 方面表现得不错,回答清晰准确,说明你有一定的基础。不过在框架的一些细节问题上,回答得不是很完善,还需要进一步深入学习。我们会综合考虑这次面试的情况,你先回家等通知吧。”
以下是问题的详细答案:
- Java 中基本数据类型有哪些?
- Java 中有 8 种基本数据类型,分别是:
- 整数类型:byte(1 字节)、short(2 字节)、int(4 字节)、long(8 字节)。
- 浮点类型:float(4 字节)、double(8 字节)。
- 字符类型:char(2 字节)。
- 布尔类型:boolean(理论上 1 位,但实际实现中通常为 1 字节)。
- Java 中有 8 种基本数据类型,分别是:
- String 类为什么是不可变的?
- String 类被声明为 final,这意味着它不能被继承。
- String 类内部使用一个 final 的 char 数组来存储字符串内容,一旦数组被初始化,就不能再指向其他数组,并且数组的内容也不能被修改。
- 不可变的好处包括:线程安全、可以作为 HashMap 的键、提高字符串常量池的效率等。
- 在 Java 中,== 和 equals 方法有什么区别?
- ==:对于基本数据类型,比较的是值是否相等;对于引用数据类型,比较的是两个引用是否指向同一个对象的内存地址。
- equals 方法:在 Object 类中,equals 方法的实现就是使用 == 来比较对象的内存地址。但很多类(如 String、Integer 等)重写了 equals 方法,用来比较对象的内容是否相等。
- 什么是线程安全?
- 线程安全是指在多线程环境下,对共享资源的访问和操作不会导致数据不一致、数据损坏等问题。也就是说,多个线程同时访问和操作共享资源时,程序的行为和单线程环境下的行为是一致的。
- Java 中实现线程安全的方式有哪些?
- synchronized 关键字:可以修饰方法或代码块,保证同一时刻只有一个线程可以执行被修饰的方法或代码块,从而实现线程同步。
- Lock 接口及其实现类:如 ReentrantLock,通过显式地加锁和解锁来控制线程的访问,比 synchronized 更加灵活。
- 原子类:JUC 包下的原子类,如 AtomicInteger、AtomicLong 等,使用 CAS(Compare-And-Swap)算法实现原子操作,保证线程安全。
- 线程安全的集合类:如 ConcurrentHashMap、CopyOnWriteArrayList 等,这些集合类在设计上考虑了多线程并发访问的情况,提供了线程安全的操作。
- synchronized 和 Lock 的区别
- 语法层面:synchronized 是 Java 的关键字,是隐式锁,会自动释放锁;Lock 是一个接口,需要手动调用 lock() 方法加锁和 unlock() 方法解锁。
- 锁的获取和释放:synchronized 在发生异常时会自动释放锁,不会出现死锁的情况;而 Lock 需要在 finally 块中手动释放锁,否则可能会出现死锁。
- 锁的特性:Lock 可以实现公平锁和非公平锁,还可以尝试获取锁(tryLock())、定时获取锁等,比 synchronized 更加灵活。
- Spring 框架中 IOC 和 AOP 是什么?
- IOC(控制反转):也称为依赖注入(DI),是一种设计模式,将对象的创建和依赖关系的管理从代码中转移到 Spring 容器中。通过 Spring 容器来创建和管理对象,对象之间的依赖关系由容器来注入,降低了代码的耦合度。
- AOP(面向切面编程):是一种编程范式,它允许在不修改原有代码的基础上,对程序的功能进行增强。AOP 通过将横切关注点(如日志记录、事务管理等)从业务逻辑中分离出来,形成独立的切面,在程序运行时将切面织入到目标对象中。
- Spring Boot 相比 Spring 有什么优势?
- 简化配置:Spring Boot 提供了自动配置功能,通过约定大于配置的原则,减少了大量的 XML 配置文件,开发人员只需要添加相应的依赖,Spring Boot 会自动进行配置。
- 快速搭建项目:Spring Boot 提供了 Spring Initializr 工具,可以快速生成项目骨架,集成了常用的依赖,让开发人员可以快速开始项目开发。
- 内嵌服务器:Spring Boot 内嵌了 Tomcat、Jetty 等服务器,不需要单独部署服务器,直接运行项目即可。
- 监控和管理:Spring Boot Actuator 提供了丰富的监控和管理功能,如健康检查、性能监控等,方便开发人员对项目进行监控和管理。
- MyBatis 中 #{} 和 ${} 的区别是什么?
- #{}:是预编译处理,MyBatis 会将 #{} 解析为一个占位符(?),在执行 SQL 语句时会使用 PreparedStatement 进行预编译,能有效防止 SQL 注入攻击。
- **{} 直接替换为传入的值,不会进行预编译,可能会导致 SQL 注入攻击。一般用于动态表名、动态列名等场景。
- Dubbo 框架的核心功能有哪些?
- 服务注册与发现:Dubbo 提供了服务注册中心(如 ZooKeeper、Nacos 等),服务提供者将自己提供的服务注册到注册中心,服务消费者从注册中心获取服务提供者的地址信息,实现服务的自动发现。
- 远程调用:Dubbo 支持多种远程调用协议(如 Dubbo 协议、HTTP 协议等),可以实现不同服务之间的远程调用,屏蔽了网络通信的细节。
- 集群容错:Dubbo 提供了多种集群容错策略(如失败重试、快速失败等),当服务调用失败时,可以根据不同的策略进行处理,提高系统的可用性。
- 负载均衡:Dubbo 支持多种负载均衡算法(如随机、轮询等),可以根据服务提供者的性能和负载情况,将请求分发到不同的服务提供者上,提高系统的性能和吞吐量。