面经总结2022/10/9 day1

一. java基础

1. JVM,用户自己写一个String类,会发生什么?

假设用户自己写了一个String类,就会加载不进内存。
原因:
基于JVM的双亲委派机制,类加载器收到了加载类的请求,会把这个请求委派给他的父类加载器。
而只有父类加载器自己无法完成加载请求时,子类才会自己加载。
这样用户自定义的String类的加载请求就会最终达到顶层的BootStrap ClassLoader启动类加载器,
启动类加载器加载的是系统中的String对象,而用户编写的java.lang.String不会被加载。

2.sleep()和wait()的区别

区别1:使用限制

使用 sleep 方法可以让让当前线程休眠,时间一到当前线程继续往下执行,在任何地方都能使用,但需要捕获 InterruptedException 异常。

try {
    Thread.sleep(3000L);
} catch (InterruptedException e) {
    e.printStackTrace();
}

而使用 wait 方法则必须放在 synchronized 块里面,同样需要捕获 InterruptedException 异常,并且需要获取对象的锁。

synchronized (lock){
    try {
        lock.wait();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

而且 wait 还需要额外的方法 notify/ notifyAll 进行唤醒,它们同样需要放在 synchronized 块里面,且获取对象的锁。

synchronized (lock) {
    // 随机唤醒
    lock.notify();

    // 唤醒全部
    lock.notifyAll();
}

当然也可以使用带时间的 wait(long millis) 方法,时间一到,无需其他线程唤醒,也会重新竞争获取对象的锁继续执行。

区别2:使用场景

sleep 一般用于当前线程休眠,或者轮循暂停操作,wait 则多用于多线程之间的通信。

区别3:所属类

sleep 是 Thread 类的静态本地方法,wait 则是 Object 类的本地方法。

java.lang.Thread#sleep
public static native void sleep(long millis) throws InterruptedException;
java.lang.Object#wait
public final native void wait(long timeout) throws InterruptedException;

为什么要这样设计呢?
因为 sleep 是让当前线程休眠,不涉及到对象类,也不需要获得对象的锁,所以是线程类的方法。wait 是让获得对象锁的线程实现等待,前提是要获得对象的锁,所以是类的方法。

区别4:释放锁

Object lock = new Object();
synchronized (lock) {
    try {
        lock.wait(3000L);
        Thread.sleep(2000L);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

如上代码所示,wait 可以释放当前线程对 lock 对象锁的持有,而 sleep 则不会。

区别5:线程切换

sleep 会让出 CPU 执行时间且强制上下文切换,而 wait 则不一定,wait 后可能还是有机会重新竞争到锁继续执行的。

3.object类有哪些方法

Object类,属于java.lang包,位于类层次结构树的顶部。每个类都是Object类的直接或间接的后代。使用或编写的每个类都继承Object的实例方法。Object类总共13个方法。

3.1 clone方法

保护方法,实现对象的浅复制,只有实现了Cloneable接口才可以调用该方法,否则抛出CloneNotSupportedException异常。
主要是JAVA里除了8种基本类型传参数是值传递,其他的类对象传参数都是引用传递,我们有时候不希望在方法里将参数改变,这是就需要在类中复写clone方法。

3.2 getClass方法

final方法,获得运行时类型。

3.3 toString方法

该方法用得比较多,一般子类都有覆盖。

3.4 finalize方法

该方法用于释放资源。因为无法确定该方法什么时候被调用,很少使用。

3.5 equals方法

该方法是非常重要的一个方法。一般equals和==是不一样的,但是在Object中两者是一样的。子类一般都要重写这个方法。

3.6 hashCode方法

该方法用于哈希查找,可以减少在查找中使用equals的次数,重写了equals方法一般都要重写hashCode方法。这个方法在一些具有哈希功能的Collection中用到。

一般必须满足obj1.equals(obj2)==true。可以推出obj1.hash- Code()==obj2.hashCode(),但是hashCode相等不一定就满足equals。不过为了提高效率,应该尽量使上面两个条件接近等价。

如果不重写hashcode(),在HashSet中添加两个equals的对象,会将两个对象都加入进去。

3.7 wait方法

wait方法就是使当前线程等待该对象的锁,当前线程必须是该对象的拥有者,也就是具有该对象的锁。wait()方法一直等待,直到获得锁或者被中断。wait(long timeout)设定一个超时间隔,如果在规定时间内没有获得锁就返回。

调用该方法后当前线程进入睡眠状态,直到以下事件发生。

(1)其他线程调用了该对象的notify方法。

(2)其他线程调用了该对象的notifyAll方法。

(3)其他线程调用了interrupt中断该线程。

(4)时间间隔到了。

此时该线程就可以被调度了,如果是被中断的话就抛出一个InterruptedException异常。

3.8 notify方法

该方法唤醒在该对象上等待的某个线程。

3.9 notifyAll方法

该方法唤醒在该对象上等待的所有线程。

Object的notify、notifyAll和wait方法都在同步程序中独立运行线程的活动中起着作用

3.10 finalize 方法

Java允许在类中定义一个名为finalize()的方法。它的工作原理是:一旦垃圾回收器准备好释放对象占用的存储空间,将首先调用其finalize()方法。并且在下一次垃圾回收动作发生时,才会真正回收对象占用的内存。

关于垃圾回收,有三点需要记住:

1、对象可能不被垃圾回收。只要程序没有濒临存储空间用完的那一刻,对象占用的空间就总也得不到释放。

2、垃圾回收并不等于“析构”。

3、垃圾回收只与内存有关。使用垃圾回收的唯一原因是为了回收程序不再使用的内存。

finalize()的用途:

无论对象是如何创建的,垃圾回收器都会负责释放对象占据的所有内存。这就将对finalize()的需求限制到一种特殊情况,即通过某种创建对象方式以外的方式为对象分配了存储空间。不过这种情况一般发生在使用“本地方法”的情况下,本地方法是一种在Java中调用非Java代码的方式。

为什么不能显示直接调用finalize方法?

如前文所述,finalize方法在垃圾回收时一定会被执行,而如果在此之前显示执行的话,也就是说finalize会被执行两次以上,而在第一次资源已经被释放,那么在第二次释放资源时系统一定会报错,因此一般finalize方法的访问权限和父类保持一致,为protected。

4.讲一下equals()与hashcode(),什么时候重写,为什么重写,怎么重写?

如果你需要要在 HashMap 的“键”部分存放自定义的对象,一定要重写 equals 和 hashCode 方法。

总结下就是自定义对象作为key时要重写hashcode和equals方法,因为要比较两个对象,是先比较hashcode,再比较equals方法,从object继承的hashcode和equals方法都是比较的内存地址,由于自定义的两个对象,内存地址肯定不一致,但是我们可能创建的入参是一样的,所以我们希望它们是相等的。

hashCode()与equals()相关规定

1.如果两个对象相等,则hashcode必须相等。

2.如果两个对象相等,对其中的一个对象调用equals()必须返回true,也就是说a .equals(b),则 b.equals(a).

3.如果两个对象有相同的hashCode值,他们也不一定相等。但若两个对象相等,则hashcode值一定相等。

4.因此若equals()被覆盖过,则hashcode()也必须被覆盖。

5.hashCode()的默认行为实在对heap上的对象产生独特的值。如果没有override过hashCode(),则该class的两个对象怎么都不会被认为是相同的。

6.equals()的默认行为是执行==的比较。也就是说会去测试两个引用是否对上heap上同一个对象。如果equals()没有被覆盖过,两个对象永远都不会被视为相同的。因此不同的对象有不同的字节组合。
a.equals(b)必须与a.hashCode()==b.hashCode()等值。
但a.hashCode()==b.hashCode不一定要与a.equals()等值。

5.java多态,如何实现?动态绑定

多态,顾名思义,表示一个对象具有多种的状态,具体表现为父类的引用指向子类的实例。

多态的特点:

1.对象类型和引用类型之间具有继承(类)/实现(接口)的关系;
2.引用类型变量发出的方法调用的到底是哪个类中的方法,必须在程序运行期间才能确定;
3.多态不能调用“只在子类存在但在父类不存在”的方法;
4.如果子类重写了父类的方法,真正执行的是子类覆盖的方法,如果子类没有覆盖父类的方法,执行的是父类的方法。

https://blog.csdn.net/guanshengg/article/details/126380197?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_baidulandingword~default-0-126380197-blog-52191321.pc_relevant_aa_2&spm=1001.2101.3001.4242.1&utm_relevant_index=3

6. java如何保证多线程安全

https://blog.csdn.net/qq_46546793/article/details/120195232?spm=1001.2101.3001.6650.3&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-3-120195232-blog-90018414.pc_relevant_multi_platform_whitelistv4&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-3-120195232-blog-90018414.pc_relevant_multi_platform_whitelistv4&utm_relevant_index=4

7.I/O多路复用讲一下,epoll优势在哪里,为什么,epoll水平与边缘触发

https://blog.csdn.net/qq_35423154/article/details/107709322

8. == 和equals的区别?

8.1 对象类型不同

1、equals():是超类Object中的方法。
2、==:是操作符。

8.2 比较的对象不同

1、equals():用来检测两个对象是否相等,即两个对象的内容是否相等。
2、==:用于比较引用和比较基本数据类型时具有不同的功能,具体如下:
(1)、基础数据类型:比较的是他们的值是否相等,比如两个int类型的变量,比较的是变量的值是否一样。
(2)、引用数据类型:比较的是引用的地址是否相同,比如说新建了两个User对象,比较的是两个User的地址是否一样。

8.3 运行速度不同

1、equals():没有运行速度快。
2、:运行速度比equals()快,因为
只是比较引用。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值