java面试填坑解惑篇
感谢原文出处:https://www.cnblogs.com/javazhiyin/
NO1.请简单描述JDK和JRE的区别?
NO1.回答JDK和JRE的区别这道题,首先要回答两个名次的概念,JDK就是Java Developement Kit的缩写,java最核心的东西,包括了java的运行环境(JRE),一些基本类库方便开发人员开发程序和源码压缩等。主要由bin(可执行命令如javac,java等)、include(和java虚拟机交互的头文件)、lib(java类库)、 jre(运行环境)组成。
而JRE(Java Runtime Environment)是java的运行环境,包含java虚拟机和一些基本运行类库,但不包括调试和开发工具,一个项目被编译为.class后缀后即可在JRE上运行。
顺便补一下上面提到的JVM(Java Virtual Machine)知识,JVM是 java运行时所需要的环境,JVM是一种用于计算设备的规范,它是一个虚构出来的微小计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。针对java用户,也就是拥有可运行的.class文件包(jar或者war)的用户。
里面主要包含了jvm和java运行时基本类库(rt.jar)。rt.jar可以理解为java源码编译后的jar包。Java虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令执行,比如windows或者linux。这就是Java所宣称的“一次编译,到处运行”的原因。
NO2.告诉我JVM的类加载过程?对不起各位这里直接提升了面试的难度,但是工作三年以上的中级程序员还是需要了解的,看图说话还差哪些过程么。
NO2.第二题考察大家对JVM加载class的理解程度,题目的图中缺少的步骤为应用和卸载两步,因为当JVM完成前面三步以后就等系统调用,当实例完成线程任务后即被JVM进行GC,当Class不被引用后就会被卸载。
NO3.哦,工作快三年了,了解多JVM的双亲委派模式么,为什么需要由父类加载类再传递给最下面的类加载器?
NO3.java中可以加载类的加载器由高到低顺序为BootstrapClassLoader,ExtensionClassLoader,AppClassLoader三类,JVM加载类时都是由AppClassLoader请求他的父类ExtensionClassLoader进行加载,如果父类可以加载类到虚拟机则子类不能再加载类,依次类推,只有那些一二级类加载器都没发现的类才被AppClassLoader加载,这类class可以理解为自定义类。这样设置的初衷主要是出于安全考虑,免得被不怀好意的人破篡改API类库。
NO4. 哦,对了如何如何控制多个子线程任务执行完成,再执行主线程程序?除了thread.join(2000),还有其他方法么?
NO4.在主线程中启动子线程,为了保证子线程统一执行完成再执行主线程代码除了上面提到的join(),join(2000)外,其实还可以使用countDownLatch方法,主要实现原理是通过在主程序中设置子线程数量,同时在子线程中调用countDownLatch.countDown()方法计数达到统计线程的目的,顺便提到一下CyclicBarrier目的是让子线程同时完成的,感兴趣的同学可以多去了解下。
NO5. 下面的代码执行以后S1,S2分别等于多少?还是说会出现什么问题?
NO5.此题主要考察越界和转化的问题,S1的值是-128,S2的值是2。第一行代码因为byte最大值是127在计算机中表示为01111111加1后变为10000000此时是补码,计算机只存储补码,此时计算机都是通过补码来表示数值的11111111的补码是符号位不变其他位取反为10000000(源码)就是-128,S2的时候其实是Integer类型强制转换的结果。
NO6.年轻人,请回答一下servlet的生命周期,这个对于了解配置加载和预加载参数有重要意义?
N06.主要考察对容器生命周期的理解,无论后面出现怎样的框架,底层始终都没有变化,答案基本回答到点上了,说一句目前的大多框架都是默认单例类实例的,因此使用完成后不会被destroy掉。
NO7.想必你知道一些关于threadLocal的知识,我不问你怎么使用,也不问你使用场景。我想说的是线程池提供给用户的线程会存在数据混淆么?(这个可能有点高端,有些高级开发都不知道,呵呵)
NO7.关于threadLocal知识,目前来说使用的不是很多,大家可以了解他的使用场景是为了隔离数据,就是说希望线程各自访问各自的数据互不干涉。题目中的坑其实就是线程池公用出现的问题,当上一个线程不是新创建的而是来自线程池时存在threadLocal中止没被清空的情况,造成数据篡写。正确的做法就是每次使用完成后都立马置为null,这样伴随着线程销毁,变量也被销毁。
NO8.知道序列化吧,什么情况下需要序列化?RPC服务中的参数为啥都需要序列化呢?参数中的日期类型到底用sql.Date还是util.Date?
NO8.这道题其实是考察序列化的场景的,序列化的目的依赖为了进行网络传输,确保传过去的字节流还能被反编译找到对应的类,二来为了方便本地硬盘存储。RPC(Remote Protocal Call)服务为异步服务都是通过网络传输数据,当然需要序列化数据。Java.sql.Date类继承java.util.Date类,但是并未实现序列化因此作为参数不能在RPC服务中传输。
NO9.请问各位大侠,这个诡异的代码能运行么?
NO9.这道题已经有小伙伴给出了答案,其实这道题大家都会想着null转换对象肯定还是null,然后就空指针了,结果是被狠狠打脸了。其实我之前也不知道这个东西,还好查了资料及时补起来了,一句话:null不属于任何类型,可以被转换成任何类型,但是用instanceof永远返回false.
NO10.做下小调查,大家平时工作用到的代码管理器有哪些?是CVS还是SVN亦或GIT或者VSS,能给出使用的理由么?作者目前用的是SVN,因为这个工具当前比较通用受众多因此在使用。
NO10.听大鼻说Github被微软收购了,后面还不知道要怎么进行运营呢。说又出来一个新的代码版本管理工具GitLab,可我连github还没用熟练呢,简直不得不感叹技术更新的速度。