面试经验题目
Linux 查看线程的指令
- ps 指令:可以使用
ps -Lf <pid>
来查看指定进程 ID(pid)下的线程信息,L
选项用于显示线程相关信息,f
选项以完整格式显示。 - top 指令:在
top
命令执行过程中,按下H
键可以切换显示线程信息,它会显示系统中各个线程的资源占用等情况。 - pstack 指令:
pstack <pid>
可以打印出指定进程中所有线程的栈跟踪信息,有助于分析线程的执行状态和函数调用关系。
Spring 的特点及使用 Spring 的原因
- 特点
- 轻量级:Spring 框架本身相对轻量级,对系统资源的占用较少,不会给项目带来过多的负担。
- 控制反转(IoC):将对象的创建和依赖关系的管理交给 Spring 容器,降低了组件之间的耦合度,提高了代码的可维护性和可测试性。
- 面向切面编程(AOP):允许将横切关注点(如日志记录、事务管理等)与业务逻辑分离,以更优雅的方式实现这些功能,提高了代码的复用性和可扩展性。
- 丰富的框架集成:能与各种持久层框架(如 Hibernate、MyBatis)、Web 框架(如 SpringMVC)等很好地集成,方便构建各种类型的应用。
- 事务管理:提供了统一的事务管理接口,支持编程式事务管理和声明式事务管理,方便进行事务处理。
- 使用原因
- 提高开发效率:提供了大量的工具类和模板代码,减少了开发人员的重复劳动,加快了项目的开发进度。
- 便于维护和扩展:低耦合和模块化的设计,使得在项目后期进行功能扩展和维护时更加容易,降低了维护成本。
- 增强代码的可测试性:通过 IoC 和 AOP 等特性,使得代码更加容易进行单元测试和集成测试,提高了软件的质量。
Java 深拷贝与浅拷贝
- 浅拷贝:创建一个新对象,新对象的属性值与原对象相同,但对于引用类型的属性,只是复制了引用地址,新对象和原对象的引用属性指向同一个对象。
- 深拷贝:创建一个新对象,新对象的属性值与原对象相同,对于引用类型的属性,会递归地复制其引用的对象,使得新对象和原对象的所有属性都相互独立,互不影响。
Spring 依赖的类型
- 构造函数注入:通过类的构造函数来传递依赖关系,在创建对象时,将依赖的对象作为参数传入构造函数。
- Setter 方法注入:通过类的 Setter 方法来设置依赖关系,先创建对象,然后通过调用 Setter 方法将依赖的对象注入到目标对象中。
- 接口注入:不太常用,定义一个注入接口,让需要注入的类实现该接口,通过接口方法来注入依赖。
事务的隔离
- 读未提交(Read Uncommitted):允许事务读取其他事务尚未提交的数据,可能会出现脏读、不可重复读和幻读问题。
- 读已提交(Read Committed):只能读取已经提交的数据,避免了脏读,但可能会出现不可重复读和幻读。
- 可重复读(Repeatable Read):在一个事务内多次读取同一数据时,读取到的数据是一致的,解决了脏读和不可重复读问题,但可能会出现幻读。MySQL 默认的隔离级别是可重复读。
- 串行化(Serializable):事务完全串行执行,避免了所有的并发问题,但性能较低,一般很少使用。
多线程的实现种类
- 继承 Thread 类:创建一个类继承 Thread 类,重写 run 方法,在 run 方法中定义线程要执行的任务。
- 实现 Runnable 接口:创建一个类实现 Runnable 接口,实现 run 方法,将该类的实例作为参数传递给 Thread 类的构造函数来创建线程。
- 实现 Callable 接口:创建一个类实现 Callable 接口,实现 call 方法,该方法可以有返回值,通过 FutureTask 来获取线程执行的结果。
方法重写与方法重载的区别
- 定义
- 方法重写:发生在子类与父类之间,子类重写父类中已有的方法,方法名、参数列表、返回类型必须与父类中的方法一致(返回类型可以是父类方法返回类型的子类)。
- 方法重载:发生在同一个类中,方法名相同,但参数列表不同(参数个数、类型或顺序不同),与返回类型无关。
- 作用
- 方法重写:用于子类根据自身需求对父类方法的具体实现进行修改和扩展,体现了多态性。
- 方法重载:方便在同一个类中以相同的方法名实现不同的功能,提高了代码的可读性和可维护性。
HashMap 和其他集合类的区别及安全性
以 HashMap 和 Hashtable 为例:
- 区别
- 线程安全性:HashMap 是非线程安全的,在多线程环境下可能会出现数据不一致等问题;Hashtable 是线程安全的,它的方法都被
synchronized
关键字修饰。 - 键值是否允许为 null:HashMap 的键和值都可以为 null;Hashtable 的键和值都不允许为 null。
- 迭代器的一致性:HashMap 的迭代器在迭代过程中如果集合结构发生变化(除了通过迭代器自身的 remove 方法),会抛出 ConcurrentModificationException 异常;Hashtable 的迭代器相对更稳定,但效率可能会稍低。
- 线程安全性:HashMap 是非线程安全的,在多线程环境下可能会出现数据不一致等问题;Hashtable 是线程安全的,它的方法都被
- 安全性:在多线程环境下,Hashtable 更安全,但如果不需要考虑线程安全问题,HashMap 的性能通常更好,因为它没有线程安全的开销。
双等号(==)和 equals 的不同
- 双等号(==):对于基本数据类型,比较的是值是否相等;对于引用数据类型,比较的是对象的引用地址是否相等,即是否指向同一个对象。
- equals 方法:在 Object 类中,equals 方法与双等号的作用相同,也是比较对象的引用地址。但在很多类中,如 String、Integer 等,都重写了 equals 方法,用于比较对象的内容是否相等。
Java 中抽象类和接口的区别
- 抽象类:可以包含普通方法和抽象方法,有构造函数,子类只能单继承抽象类。
- 接口:只能包含抽象方法(Java 8 开始可以有默认方法和静态方法),没有构造函数,类可以实现多个接口。
HTTP 和 HTTPS 的区别
- 安全性:HTTP 数据以明文传输,容易被窃取和篡改;HTTPS 通过 SSL/TLS 协议对数据进行加密,安全性更高。
- 端口:HTTP 默认使用 80 端口,HTTPS 默认使用 443 端口。
- 证书:HTTPS 需要 CA 证书来验证服务器的身份,HTTP 不需要。
数据库索引的作用及原理
- 作用:提高数据的查询效率,减少数据库的 I/O 操作,加速表与表之间的连接等。
- 原理:索引是一种数据结构,常见的有 B 树、B + 树等。以 B + 树为例,它将数据按照一定的规则组织成树状结构,通过对索引列的值进行比较和查找,可以快速定位到数据所在的位置。