八股相关
一、具体问题
(Java 语言)1. Object 类知道多少方法?
(Java 语言)2. 普通的集合类是线程安全的吗?
(数据库)3. Mybatis 是怎么做到防止 SQL 注入的?
(数据库)4. 说说 MySQL 数据库回滚的过程?
(数据库)5. 说说 MySQL 数据库事务提交的过程?
(数据库)6. MySQL 有几种日志,有什么区别?
(Java 语言)7. JDK1.6 / 1.7 / 1.8 中 HashMap 的区别?
(数据库)8. MySQL 的 MVCC(多版本并发控制)是如何实现的?
(Java 语言)9. Java 自动装箱和拆箱是什么?有什么优势?底部是如何缓存的?
二、参考答案
(Java 语言)1. Object 类知道多少方法?
Object 类的方法包括:
- clone(): 用于拷贝对象的副本,是通过浅拷贝形式进行拷贝的。
- equals(): 用于判断两个对象的内存地址是否相等。
- getClass(): 用于返回运行时的 Class 对象。
- hashCode(): 用于返回对象的哈希值。
- wait(): 导致调用 wait 方法的线程等待。
- notify(): 唤醒当前等待的线程,一般与 wait 方法搭配使用。
- toString(): 用于输出对象名称加上哈希 code 的十六进制。
(Java 语言)2. 普通的集合类是线程安全的吗?
普通的集合类,无论是列表 ArrayList,还是常用的 HashSet、 HashMap,它们都不是线程安全的。
这是因为这些集合类的实现在并发环境下没有加锁,可能导致线程出现读写不一致等问题。
要解决普通集合类的线程不安全问题,常用的解决方法是使用 JUC 包里的安全集合类。例如:
- 列表可以使用 CopyOnWriteArrayList 类。
- 集合可以使用 CopyOnWriteArraySet 类。
- 哈希表可以使用 ConcurrentHashMap 类。
(数据库)3. Mybatis 是怎么做到防止 SQL 注入的?
Mybatis 防止 SQL 注入是通过 #{}
来实现的。
由于 Mybatis 是半自动化的 ORM,需要我们编写 SQL 语句,当我们需要表示参数的时候,可以使用 #{}
符号。
- 首先,它会将传入的参数进行自动类型转换,并使用通配符
?
替换。 - 然后,它会使用 PrepareStatement 编译编写好的 SQL 语句,通过编译检查的 SQL 语句将参数传入执行。
- 如果,在编译过程中发现,不正确的 SQL 语句,则会报错,这样就可以避免 SQL 注入的攻击。
(数据库)4. 说说 MySQL 数据库回滚的过程?
MySQL 数据库回滚依赖于 MySQL 事务的原子性。
具体来说:当事务对数据库进行修改时,MySQL 默认的存储引擎 InnoDB 会生成相应的回滚日志(undo log)。
这个回滚日志是物理层面的日志,记录的是事务修改前的数据。
当事务提交失败或主动调用 ROLLBACK 进行事务回滚时,InnoDB 会根据回滚日志的内容恢复事务之前的数据。
(数据库)5. 说说 MySQL 数据库事务提交的过程?
MySQl 数据库事务的提交过程是一个两阶段的过程,分别是:准备阶段和提交阶段。
准备阶段的工作是:
将事务 ID 写入到重做日志(redo log),同时设置事务的状态为准备(prepare),然后将重写日志刷回磁盘。
提交阶段的工作是:
将事务 ID 写入到归档日志(bin log),同时设置事务的状态为提交(commit),然后将归档日志刷回磁盘。
(数据库)6. MySQL 有几种日志,有什么区别?
MySQL 有三种日志,分别是:回滚日志(undo log)、重做日志(redo log)和归档日志(bin log)。其中:
- 回滚日志:记录了事务开始前的状态,也就是更新前的值,用于事务回滚和 MVCC。
- 重做日志:记录了事务提交后的状态,也就是更新后的值,用于掉电后的数据恢复。
- 归档日志:记录了所有数据库表结构的变更和数据修改的日志,用于数据备份和主从复制。
(Java 语言)7. JDK1.6 / 1.7 / 1.8 中 HashMap 的区别?
JDK 1.6 HashMap 和 JDK 1.7 HashMap 区别主要在于两点:
- 在 JDK 1.6 中,HashMap 通过 new 创建后会开启内存;在 JDK 1.7 中,使用懒汉初始化,意味着添加元素时才开辟内存空间。
- 在 JDK 1.6 中,扩容的负载阈值固定为 0.75;在 JDK 1.7 中,这个值可以自主设置。
JDK 1.7 HashMap 和 JDK 1.8 HashMap 区别主要在于:
- 在 JDK 1.8 中,如果出现哈希碰撞后,解决冲突的链表长度超过 8 后,会将链表转换为红黑树,加快查找效率。
- 在 JDK 1.8 中,修改了扩容算法和 hash 算法,扩容算法使用移位操作和 hash 算法均使用到位运算,加快效率。
(数据库)8. MySQL 的 MVCC(多版本并发控制)是如何实现的?
MySQL 的 MVCC 是通过可见域(Read View)和回滚日志(undo log)实现的。
具体来说,当事务开启后会生成相应的可见域,这个可见域对应着事务能够看到的数据版本范围。
当使用查询操作时,MySQL 会顺着回滚日志的版本链找到满足其可见域的数据。
从而控制并发事务访问同一条记录。
(Java 语言)9. Java 自动装箱和拆箱是什么?有什么优势?底部是如何缓存的?
Java 自动装箱:指的是将 Java 基本数据类型转换为包装类型。例如:int 类型转换为 Integer 类型。
Java 自动拆箱:就是装箱的逆过程,将 Java 包装类型转换为基本数据类型。
Java 自动装箱和拆箱机制优势在于:
- 使得 Java 的变量赋值或者是方法调用等情况下,使用原始类型或者对象类型更加简单。
- 基本类型对应的包装类,底层进行了数据缓存机制。
对于整数类型对应的包装类,底层会缓存 [-128, 127] 之间的数据,因为这个范围内的数据使用比较频繁。
所以相应的,在这个范围内的 Integer 对象,可以使用 == 号来比较大小。
但是超过这个范围内的 Integer 对象,需要使用 equals 方法来比较大小。
参考:
4, 5, 6, 8 - 小林Coding - https://www.cnblogs.com/xiaolincoding/p/16396502.html
7 - 风沙第一 - https://www.jianshu.com/p/b98010c22975
9 - 小白写程序 - https://blog.youkuaiyun.com/qq_41030039/article/details/101903107