什么是面向对象编程(OOP)?
面向对象编程(OOP)是一种通过考虑程序中的对象来组织代码的方法。这些对象表示现实世界的实体,用于将数据和行为封装在一起。OOP 的基本原则包括封装、继承、多态性和抽象,这有助于创建模块化和可重用的代码。
什么是依赖关系注入(DI)?
依赖关系注入(DI)是一种软件设计模式,其中组件的依赖关系是从外部注入的,而不是在组件本身内部创建的。这意味着组件不是创建自己的依赖项,而是从外部源提供给它。DI 的主要优点包括更高的模块化、更轻松的测试和更好的关注点分离。
依赖注入的优势:
减少组件之间的耦合。
增强代码的可维护性和可测试性。
促进更简洁的代码和设计。
实现依赖注入的常见方法:
构造函数注入:依赖项通过类构造函数提供。
Setter 注入:依赖项通过 Setter 方法提供。
方法注入:依赖项通过方法提供。
什么是死锁?
当两个或多个进程由于每个进程都在等待另一个进程释放资源而无法继续时,将发生死锁。这会产生一个循环等待条件,从而导致停顿。
如何避免死锁:
Banker's Algorithm:进程声明它们将使用的最大资源,如果请求的资源少于可用资源,则允许执行。
信号量:通过一次只允许关键部分中的一个进程来确保互斥。
互斥:此条件表示必须至少有一个资源处于不可共享模式。并非总是能够消除这种情况,因为某些资源(如打印机或磁带驱动器)本质上是不可共享的。
什么是容错能力(Fault Tolerance)?
容错能力是指系统即使在某些组件发生故障时也能继续正常运行的能力。它通过优雅地处理故障来确保系统的可靠性和可用性。
什么是断路器(Circuit Breaker)?
断路器就像一个安全开关,如果电流过大,它会自动关闭电源,防止电气火灾并保护电器。在软件中,断路器模式会停止对失败服务的请求流,从而允许系统恢复。
SQL 与 NoSQL 的区别
何时使用 SQL:
结构化数据:当数据具有明确定义的结构和清晰的关系时。
复杂事务:当需要 ACID 事务以确保数据完整性时。
何时使用 NoSQL:
水平可扩展性:当可扩展性是优先事项时,NoSQL 更加灵活。
半结构化/非结构化数据:适用于不适合关系模型的数据,如 JSON 或 XML。
身份验证和授权的区别
身份验证:验证用户的身份,通常通过密码、生物识别或安全令牌等凭证。
授权:确定经过身份验证的用户是否有权访问特定资源或执行某些操作。
什么是 REST?
REST(Representational State Transfer)是一种系统设计,它使用 HTTP 协议通过 HTTP 方法在分布式系统之间进行通信。
抽象类和接口的区别
抽象类:无法实例化的部分定义的类。它可以有抽象和具体方法,以及实例变量。
接口:一个完全抽象的结构,仅包含方法签名和常量字段。
Java 中 equals() 和 hashCode() 的区别
equals():确定两个对象在逻辑上是否等效。
hashCode():提供对象的哈希值。两者必须一起覆盖,以确保在基于 Hash 的集合(如 HashMap 和 HashSet)中的行为正确。
ArrayList 和 LinkedList 的区别
ArrayList:基于数组的实现,具有快速随机访问但插入/删除速度较慢。
LinkedList:基于节点的实现,具有缓慢的随机访问,但在任何位置都可以快速插入/删除。
已检查异常和未检查异常的区别
已检查异常(Checked Exceptions):在编译时检查,需要显式处理或声明。
未检查异常(Unchecked Exceptions, RuntimeExceptions):在运行时发生,允许程序在不进行显式处理的情况下进行编译。
如何在 Java 中处理并发?
Java 中的并发可以通过 Thread 类或 Runnable 接口的多线程来处理,并使用同步机制(如同步块、易失性变量或 java.util.concurrent 包中的类)控制对共享资源的访问。
如何监控生产中的 Bug?
日志记录:例如,使用 Log4J。
日志管理:使用 Logstash 或 Datadog 等工具。
应用程序运行状况检查:例如使用 Spring Actuator。
Kubernetes:使用运行情况和就绪情况探测。
Java 中的垃圾收集器是如何工作的?
垃圾回收器通过识别和释放不再使用的对象来自动管理内存,从而释放内存并防止内存泄漏。
如何保持代码的质量?
代码审查:定期检查代码,确保清晰易懂。
自动化测试:使用单元测试和集成测试确保代码按预期工作。
重构:定期重构代码,改善其结构和可读性。
编码标准:遵循一致的编码标准,确保代码易于阅读和维护。
文档:为代码编写文档,方便其他开发者理解。
IDE 插件和工具:使用如 SonarLint 和 CheckStyle 的工具帮助编写简洁、干净的代码。
什么是 SOLID 原则?
单一责任原则(SRP):一个类应该只有一个更改的理由。
开放/封闭原则(OCP):软件实体应开放以供扩展,但应关闭以供修改。
里氏替换原则(LSP):超类的对象应该可以被子类的对象替换,而不会影响程序的正确性。
接口隔离原则(ISP):不应强迫客户端依赖它们不使用的接口。
依赖反转原则(DIP):高级模块不应依赖低级模块;两者都应该依赖于抽象。