快来看看啊,可靠的Java面经

Posted 韶光不负

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了快来看看啊,可靠的Java面经相关的知识,希望对你有一定的参考价值。

         相思(唐·王维)

红豆生南国,春来发几枝?

愿君多采撷,此物最相思。

目录

一,双亲委派模型(双亲委托)

优点

二,Java中的异常体系

Error

Exception:

三,Gc如何判断对象可以被回收的

引用计数法(Java中并没有用,python中有使用):

可达性分析法(Java中垃圾回收方法)

GC Roots对象 

四,线程的生命周期与状态

线程的生命周期

线程的状态

五,sleep() ,wait() ,join(),yield()的区别

锁池

等待池

sleep() ,wait()的区别(!!!)

yield ()

join ()

六,谈谈你对对线程安全的理解

线程安全描述:当多个线程访问一个对象时,如果不用进行额外的同步控制或其他的协调操作,调用这个对象的行为都可以获得正确的结果,我们就说这个对象是线程安全的

七,Thread与Runable的区别

八,谈谈你对并发,并行,串行的理解

串行

并行

并发

九,并发的三大特征(作用:保证线程的安全)

原子性

可见性

有序性

虚拟机在进行代码编译时,对于那些改变顺序之后不会对最终结果造成影响的代码,虚拟机不一定会按照我们写的代码的顺序来执行,有可能将他们重排序。实际上,对于有些代码进行重排序之后,虽然对变量的值没有造成影响,但有可能会出现线程安全问题。


一,双亲委派模型(双亲委托)

一个程序的启动从main函开始,appClassLoader加载器就会开始向上委派(查找appClassLoader到顶级加载器BootStrapClassLoader查找缓存) ,当缓存找到就返回如果在顶级加载器都没有找到就会向下查找(从顶级加载器到发起加载器进行路径查找)。找到就返回,没有找到就返回找不到

优点

1,为了安全性,避免程序员自己编写类替换了Java中的核心类,如:String

2,避免了类的重复加载,因为jvm中区分不同的类,不仅仅根据类名称,相同的.class文件被不同的加载器加载就是二个不同的文件

二,Java中的异常体系

Java中的所有异常都来自顶级父类Throwable。

Throwable下有两个子类Exception和Error。

Error


Error是程序无法处理的错误,一旦出现这个错误,则程序将被迫停止运行。如 oom(栈溢出)

Exception:

Exception不会导致程序停止,又分为两个部分RunTimeException运行时异常CheckedException检查异常

RunTimeException常常发生在程序运行过程中,会导致程序当前线程执行失败。如:空指针,下标越界(程序员自定义异常一般继承RunTimeException

CheckedException常常发生在程序编译过程中,会导致程序编译不通过,如:int类型写为字符串类型
 

三,Gc如何判断对象可以被回收的

引用计数法(Java中并没有用,python中有使用):

每一个对象都有一个引用计数的属性,新增一个引用计数加1,引用释放时计数减1,当引用计数为0时,就可以回收该对象

优点:效率高

缺点:当A引用B,B引用A时,二个对象计数都为1,当不需要使用A与B,因为引用计数法该对象A与B没有办法被回收

可达性分析法(Java中垃圾回收方法)

从GC Roots开始向下搜索,搜索所有的路径称为引用链,当一个对象到GC Roots没有引用链时,就证明该对象是不看用的,虚拟机(jvm)判断该对象是可以回收的对象

 

GC Roots对象 

1,虚拟机栈中的引用对象

2,方法区中静态属性的引用对象

3,方法区中常量的引用对象

4,本地方法栈中JNI/(一般说是Native方法)引用对象

四,线程的生命周期与状态

线程状态的详细了解https://blog.csdn.net/weixin_47514459/article/details/121684582

线程的生命周期

从线程的创建到线程死亡时的过程称为一个周期。

线程的状态

线程分为五种状态:创建,就绪,运行,阻塞与死亡。

五,sleep() ,wait() ,join(),yield()的区别

线程方法了解https://blog.csdn.net/weixin_47514459/article/details/121385539

锁池


所有需要竞争同步锁的线程都会放在锁池当中,比如当前对象的锁已经被其中一个线程得到,则其他线程需要在这个锁池进行等待,当前面的线程释放同步锁后锁池中的线程去竞争同步锁,当某个线程得到后会进入就绪队列进行等待cpu资源分配。

等待池


当我们调用wait ()方法后,线程会放到等待池当中,等待池的线程是不会去竞争同步锁。只有调用了notify ()或notifyAlI)后等待池的线程才会开始去竞争锁,notify ()是随机从等待池选出一个线程放到锁池,而notifyAllo)是将等待池的所有线程放到锁池当中
 

相同点:

这四个方法都是线程当中使用的方法

sleep() ,wait()的区别(!!!)

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

2、sleep方法不会释放lock,但是wait会释放,而且会加入到等待队列中。

3、sleep方法不依赖于同步器synchronized,但是wait需要依赖synchronized关键字。
4、sleep不需要被唤醒(休眠之后推出阻塞),但是wait需要(不指定时间需要被别人中断)。

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

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

yield ()

执行后线程直接进入就绪状态,马上释放了cpu的执行权,但是依然保留了cpu的执行资格,所以有可能cpu下次进行线程调度还会让这个线程获取到执行权继续执行


join ()

执行后线程进入阻塞状态,例如在线程B中调用线程A的join (),那线程B会进入到阻塞队列,直到线程A结束或中断线程
 

六,谈谈你对对线程安全的理解

不是线程安全、应该是内存安全,堆是共享内存,可以被所有线程访问

线程安全描述:
当多个线程访问一个对象时,如果不用进行额外的同步控制或其他的协调操作,调用这个对象的行为都可以获得正确的结果,我们就说这个对象是线程安全的


七,Thread与Runable的区别

Thread和Runnable的实质是继承关系,没有可比性。无论使用Runnable还是Thread,都会new Thread(创建一个新线程),然后执行run方法。用法上,如果有复杂的线程操作需求,那就选择继承Thread,如果只是简单的执行一个任务,那就实现runnable.
 

八,谈谈你对并发,并行,串行的理解

串行

时间上不可能发生重叠前一个任务没搞定,下一个任务就只能等着

并行

在时间上是重叠的,两个任务在同一时刻互不千扰的同时执行。


并发

允许两个任务彼此干扰统一时间点、只有一个任务运行,交替执行(对于cpu来说也是串行执行的)
 

九,并发的三大特征(作用:保证线程的安全)

原子性

是指在一个操作中cpu不可以在中途暂停然后再调度,即不被中断操作,要不全部执行完成,要不都不执行。

可见性

当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。

有序性

虚拟机在进行代码编译时,对于那些改变顺序之后不会对最终结果造成影响的代码,虚拟机不一定会按照我们写的代码的顺序来执行,有可能将他们重排序。实际上,对于有些代码进行重排序之后,虽然对变量的值没有造成影响,但有可能会出现线程安全问题。
 


 

以上是关于快来看看啊,可靠的Java面经的主要内容,如果未能解决你的问题,请参考以下文章

快来看看啊,可靠的Java面经

快来看看啊,可靠的Java面经

快来看看啊,可靠的Java面经

快来看看啊,可靠的Java面经

单例模式你会几种写法?

单例模式你会几种写法?(转)