Java

  1.  final 关键字的作用

  2.  HashMap的安全性问题?

  3. ConcurrentHashMap 的机制,如何保证线程安全和高并发?

  4. finally 的作用是什么?

  5. 什么情况下不执行 finally 中的代码块?

  6. 如果 try 中有 return,先执行 return 还是 finally?

  7. 重载和重写?

  8. 为什么重写 equals() 需要重写 hashCode()?

  9. 如何避免 sql 慢查询?


【Q1】final 关键字的作用

  • 修饰类:该类不可被继承。

  • 修饰变量:

  • 局部变量:作为常量使用,一旦赋值,不可修改。

  • 成员变量:必须在构造器或代码块中显示赋值,之后不可修改。

  • 引用类型变量:其引用地址不可变,但对象内部成员的值可变。

【Q2】HashMap 的安全性问题?

由于 HashMap 不是线程安全的,因此在多线程的场景下,对 HashMap 进行并发写操作时,会出现两种问题:

  1. 数据丢失:并发 put 操作可能导致一个线程的写入被另外一个线程覆盖。(JDK1.7 和 JDK1.8 均有此问题)

  2. 死循环:在 JDK7 及之前的版本中,并发扩容时,由于头插法可能导致链表形成环,从而在 get 操作时引发死循环,导致 CPU 飙升到 100%。(仅 JDK1.7)

【Q3】ConcurrentHashMap 的机制,如何保证线程安全和高并发? 

JDK 1.7
ConcurrentHashMap 由 Segment 和 HashEntry 组成。
Segment 是一个数组,数组中的元素也是个 HashEntry 数组。
Segment 继承了 ReentrantLock,所以 Segment 也是一种可重入锁,以此来保证线程安全。
HashEntry 用于存储键值对。
JDK 1.8
ConcurrentHashMap 数据结构采用 Node 数组 + 链表 + 红黑树,然后采用 CAS + synchronized 来保证线程安全。并且 synchronized 锁的是细粒度的,实现了更加精妙的控制,因此并发性能会更好。

【Q4】finally 的作用是什么?

finally 通常配合 try-catch 使用,无论异常是否被捕获,finally 语句块都会被执行。
finally 通常作为任务的后续处理工作,如释放资源。

【Q5】什么情况下不执行 finally 中的代码块?

  1. 调用 System.exit() 方法

  2. JVM 崩溃:如 OutOfMemoryError 。

  3. 守护线程突然终止:当所有非守护线程结束时,JVM 会直接退出,守护线程中的 finally 代码块可能会来不及执行。

  4. 死循环和死锁:try 代码块陷入死循环或死锁。

  5. 操作系统强制终止进程:kill -9

【Q6】如果 try 中有 return,先执行 return 还是 finally?

  1. 首先执行 try 语句块中的 return 语句

  2. 跳转到 finally 中,如果此时 finally 也存在 return 语句,那么 finally 中的 return 会覆盖 try 中的 return。

public static int test1() { // return 1
    int x = 1;
    try {
        return x;
    } finally {
        x = 2;
        System.out.printf("tset1 x: %d\n", x);
    }
}

public static int test2() { // return 2
    int x = 1;
    try {
        return x;
    } finally {
        x = 2;
        return x; // 覆盖 try 的 return 1
    }
}

【Q7】重载和重写?

  • 重载:在一个类中,允许存在同名的方法,但是方法的参数类型、个数、顺序不能一样。方法的返回值不作为区分重载方法的标准。

  • 重写:子类允许重写父类的方法,并且方法的签名,即方法名、参数列表、返回值必须相同。但是方法的访问修饰符可以不同。

【Q8】为什么重写 equals() 需要重写 hashCode()?

因为在 Map 中,需要依赖 hashCode 来决定元素存储的位置,而如果发生了哈希冲突,则需要依靠 equals() 方法来进一步判断元素是否相同。因此,equals 和 hashCode 通常都是一起重写的。

【Q9】如何避免 sql 慢查询?

首先,慢 SQL 对数据库的影响,是一个量变到质变的过程,所以对“量”的把握就很重要。
影响 MySQL 处理能力的因素有很多:

  • 服务器的配置

  •  数据库中数据量的大小

  • MySQL 的一些参数配置

  • 数据库的繁忙程度

这些对“量”的把握也很重要。
另外一个定量指标:到底多慢的 SQL 才算是慢 SQL。这个“慢”的度量单位是多少?
可以使用每秒查询多少行数来衡量 SQL 的好坏。

  • 如果遍历行数在百万以内:可以认为比较安全。

  • 如果遍历行数在百万到千万以内:需要评估是否合理以及是否需要优化。

  • 如果遍历行数在千万以上:比较危险,为了减少慢 SQL 的可能性,每个数据表的行数应该最好控制在千万以内。

解决方案

  • 使用索引避免全表扫描:使用索引可以有效地减少执行查询时遍历数据的行数,提高查询性能。

  • 合理的运用 EXPLAIN 来分析 SQL 的查询计划。

  • 篇幅有限,完整资料点击下方小卡片,免费领取后端资料https://mp.weixin.qq.com/s/iBmSycbmeTCSRNKJQ10EuA

更多推荐