英文自我介绍
一脸懵逼
Object类有什么方法
答了 hashCode, toString, wait, notify。
还有 equals,clone,getClass,notifyAll 方法。
hashCode()底层实现
java.lang.Object类的源码中,方法是native的,方法的计算依赖于对象实例的ID(内存地址),每个Object对象的hashCode都是唯一的,通过将该对象的内部地址转换成一个整数来实现的 。通常情况下,不同的对象产生的哈希码是不同的。toString方法也会用到这个hashCode。String的hashCode计算方式就是遍历字符数组,计算其加权和。
hashCode()在哪使用到
答了HashSet。
String a="abc" 和 String b="abc" 的hashCode()是否一样,地址呢
String :
public static int hashCode(byte[] value) {
int h = 0;
int length = value.length >> 1;
for (int i = 0; i < length; i++) {
h = 31 * h + getChar(value, i);
}
return h;
}
因为hashCode是类似于算哈希值的加权和,所以应当是一样的。
编译时,这两个"abc"被认为是同一个对象保存到了常量池中;运行时JVM则认为这两个变量赋的是同一个对象,所以地址是一样的。
wait()和notify()使用场景和作用
notify()
notify方法是一个native方法,并且也是final的,不允许子类重写。
唤醒一个在此对象监视器上等待的线程(监视器相当于就是锁的概念)。如果所有的线程都在此对象上等待,那么只会选择一个线程。选择是任意性的,并在对实现做出决定时发生。一个线程在对象监视器上等待可以调用wait方法。
直到当前线程放弃对象上的锁之后,被唤醒的线程才可以继续处理。被唤醒的线程将以常规方式与在该对象上主动同步的其他所有线程进行竞争。例如,唤醒的线程在作为锁定此对象的下一个线程方面没有可靠的特权或劣势。
notify方法只能被作为此对象监视器的所有者的线程来调用。一个线程要想成为对象监视器的所有者,可以使用以下3种方法:
- 执行对象的同步实例方法
- 使用synchronized内置锁
- 对于Class类型的对象,执行同步静态方法
一次只能有一个线程拥有对象的监视器。
wait()
wait方法会让当前线程(我们先叫做线程T)将其自身放置在对象的等待集中,并且放弃该对象上的所有同步要求。出于线程调度目的,线程T是不可用并处于休眠状态,直到发生以下四件事中的任意一件:
- 其他某个线程调用此对象的notify方法,并且线程T碰巧被任选为被唤醒的线程
- 其他某个线程调用此对象的notifyAll方法
- 其他某个线程调用Thread.interrupt方法中断线程T
- 时间到了参数设置的超时时间。如果timeout参数为0,则不会超时,会一直进行等待
所以可以理解wait方法相当于放弃了当前线程对对象监视器的所有者(也就是说释放了对象的锁)。
之后,线程T会被等待集中被移除,并且重新进行线程调度。然后,该线程以常规方式与其他线程竞争,以获得在该对象上同步的权利;一旦获得对该对象的控制权,该对象上的所有其同步声明都将被恢复到以前的状态,这就是调用wait方法时的情况。然后,线程T从wait方法的调用中返回。所以,从wait方法返回时,该对象和线程T的同步状态与调用wait方法时的情况完全相同。
锁Object和锁class的区别
HashMap冲突实现
链表+红黑树
Git划分的区域
image主要分为工作区,暂存区,本地仓库和远程仓库,分别对应add,commit,push操作。
用过reset吗
Maven冲突
- 依赖路径最短优先原则
- pom文件中申明顺序优先
- 覆写优先
最长公共子序列
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (s1[i] == s2[j]) dp[i][j] = dp[i-1][j-1] + 1;
else dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
}
}
网友评论