每日练手10道面试题(二)
1. 为什么需要pc寄存器,也就是程序计数器
首先它里面是没有垃圾和缓存的,它的主要功能是控制程序流程运转,还有最重要的是指明了下一条字节码指令指向的地方,主要是执行引擎中的解释器中需要通过改变程序计数器的值来决定下一次执行的指令,如果没有的话,线程切换就乱套了
2. pc寄存器为什么被设定为线程私有?
首先理解线程私有,每个线程各有一个计数器,如果没有区分开私有的话,就比如我们voliate一样不能保证原子性,线程不私有大家都可见了,但是在共享变量上修改就不能保证原子性了,那对于计数器来说,它就不能保证准确记录当前执行的字节码地址,所以最好每个线程各自带一个寄存器,独立计算互不影响
3. 并行和并发的区别
并行: 多个进程同时进行,互不干扰,同一个时间片上可以多个一起执行
并发:多个线程同时执行主要为了同一个任务,最后为了完成一个任务的完成,有时候快速的切换并发线程,容易看成并行,但是同一个时间片只能执行一个任务
4. 说说对递归的理解
递归实际上就是不停的调用本身,然后它有一个出口,到最后调用直到出口返回结果,其实可以看成结果是依赖前面的调用,它的实质是jvm中的java栈中栈的运行原理,每次调用,计数器的指令会指向当前栈帧,只有当前栈帧执行完然后弹出,才会执行下一个子栈帧并把结果带给他,递归就是自底向上返回结果,最后返回起初栈帧的结果
5. java真的能创建线程吗
答案是不能,你点进线程源码,它里面就是记录一下当前线程的状态started = true;,把当前线程加入线程组,然后并由一个native本地方法start0();创建的,native说明已经不是java能操纵的范围了,而我们平常的Thread,Runable,Callable等都只是利用了底层本地方法创建的,实质还是c++创建的
6.BIO,NIO和AIO的区别
BIO:同步阻塞,一个客户端一个连接,即使这个客户端什么事不干,也会占着连接不放浪费了线程资源,可以用线程池稍微改善、用于连接数目比较小且固定
NIO:同步非阻塞,它主要是一个请求一个连接,当一个请求发送的时候,会先创建一个Channel频道,也叫多路复用器,然后再把请求转发到Buffer缓冲区中,需要连接的时候会去找有连接但没处理请求的Buffer然后讲数据从刷新到缓冲区中,再从缓冲区取出,适用于连接数目多且连接比较短,它的buffer是双向的不需要再像BIO创建输入输出流
AIO:异步非阻塞,一个有效请求一个线程,有点类似ajax一样,当需要用到请求那个接口的时候,才会去执行,并且不会一直等待,系统会自动刷新出来,适用连接数目多且连接比较长
7. Synchronized和lock的区别
1、Synchronized 内置的Java关键字, Lock 是一个Java类
2、Synchronized 无法判断获取锁的状态,Lock 可以判断是否获取到了锁
3、Synchronized 会自动释放锁,lock 必须要手动释放锁!如果不释放锁,死锁
4、Synchronized 线程 1(获得锁,阻塞)、线程2(等待,傻傻的等);Lock锁就不一定会等待下
去;
5、Synchronized 可重入锁,不可以中断的,非公平;Lock ,可重入锁,可以 判断锁,非公平(可以
自己设置);
6、Syn chronized 适合锁少量的代码同步问题,Lock 适合锁大量的同步代码
8.什么是死锁?怎么解决
死锁,指的是多个线程由于争抢共同都需要的资源,然后互相都不让,导致了线程无法执行,从而一直阻塞的状态,称为死锁
如何避免?可以通过加锁顺序,加锁时限,还有死锁检测来调度
加锁顺序比如就是生产者消费者,消费者等待生产
加锁时限,如果双方获取锁,可以暂时休眠对方一会,然后以达到以一个锁的顺序执行
死锁检测出来,就直接抛异常等等,或者给线程设置优先级等等
9.简单说一下Aop
AOP是一种横切的思想,在对源代码无侵入式的加入一些功能,称之为Aop,比如织入事务,拦截器等等都可以随时添加进去,不会影响原来的代码,它实际上是利用了设计模式的代理模式,有两种,一种是动态代理,一种是静态代理,静态代理是固定死的之前就写好的方法,而且需要改动代理类的方法,相比之下还是动态代理好,利用jdk反射或者cglib反射来动态获取运行时的类的信息从来执行它的方法达到aop横切的思想,这里就可以谈谈对反射的理解
10. 简述一下http的长连接和短连接
http有1.0和1.1两个版本,前者是短连接,后者是长连接
短连接,每次浏览器和服务器进行一个http操作,就进行一次连接,然后处理完操作就断开
长连接,即使处理完任务之后任然会保持连接一会,等待是否后续还有没有同等操作
所以长连接跟频繁跟客户端有通信操作的连接更适宜,但也会更耗资源而短连接,则适用次数少的,如果多次频繁创建连接效率慢