面试官:双亲委派模型你了解吗?

面试官要不你今天来详细讲讲双亲委派机制?

候选者:嗯,好的。

候选者:上次提到了:class文件是通过「类加载器」装载至JVM中的

候选者:为了防止内存中存在多份同样的字节码,使用了双亲委派机制(它不会自己去尝试加载类,而是把请求委托给父加载器去完成,依次向上)

候选者:JDK 中的本地方法类一般由根加载器(Bootstrp loader)装载,JDK 中内部实现的扩展类一般由扩展加载器(ExtClassLoader )实现装载,而程序中的类文件则由系统加载器(AppClassLoader )实现装载。

面试官:双亲委派模型你了解吗?

候选者:这应该很好理解吧?

面试官:雀食(确实)!

面试官顺着话题,我想问问,打破双亲委派机制是什么意思?

候选者:很好理解啊,意思就是:只要我加载类的时候,不是从APPClassLoader->Ext ClassLoader->BootStrap ClassLoader 这个顺序找,那就算是打破了啊

候选者:因为加载class核心的方法在LoaderClass类的loadClass方法上(双亲委派机制的核心实现)

候选者:那只要我自定义个ClassLoader,重写loadClass方法(不依照往上开始寻找类加载器),那就算是打破双亲委派机制了。

面试官:这么简单?

候选者:嗯,就是这么简单

面试官那你知道有哪个场景破坏了双亲委派机制吗?

候选者:最明显的就Tomcat啊

面试官:详细说说?

候选者:在初学时部署项目,我们是把war包放到tomcat的webapp下,这意味着一个tomcat可以运行多个Web应用程序(:

候选者:是吧?

面试官:嗯..

候选者:那假设我现在有两个Web应用程序,它们都有一个类,叫做User,并且它们的类全限定名都一样,比如都是com.yyy.User。但是他们的具体实现是不一样的

候选者:那么Tomcat是如何保证它们是不会冲突的呢?

候选者:答案就是,Tomcat给每个 Web 应用创建一个类加载器实例(WebAppClassLoader),该加载器重写了loadClass方法,优先加载当前应用目录下的类,如果当前找不到了,才一层一层往上找(:

候选者:那这样就做到了Web应用层级的隔离

面试官:双亲委派模型你了解吗?

面试官嗯,那你还知道Tomcat还有别的类加载器吗?

候选者:嗯,知道的

候选者:并不是Web应用程序下的所有依赖都需要隔离的,比如Redis就可以Web应用程序之间共享(如果有需要的话),因为如果版本相同,没必要每个Web应用程序都独自加载一份啊。

候选者:做法也很简单,Tomcat就在WebAppClassLoader上加了个父类加载器(SharedClassLoader),如果WebAppClassLoader自身没有加载到某个类,那就委托SharedClassLoader去加载。

候选者:(无非就是把需要应用程序之间需要共享的类放到一个共享目录下嘛)

面试官:嗯..

候选者:为了隔绝Web应用程序与Tomcat本身的类,又有类加载器(CatalinaClassLoader)来装载Tomcat本身的依赖

候选者:如果Tomcat本身的依赖和Web应用还需要共享,那么还有类加载器(CommonClassLoader)来装载进而达到共享

候选者:各个类加载器的加载目录可以到tomcat的catalina.properties配置文件上查看

候选者:我稍微画下Tomcat的类加载结构图吧,不然有点抽象

面试官:双亲委派模型你了解吗?

面试官:嗯,还可以,我听懂了,有点意思。

面试官顺便,我想问下,JDBC你不是知道吗,听说它也是破坏了双亲委派模型的,你怎么理解的。

候选者:Eumm,这个有没有破坏,见仁见智吧。

候选者:JDBC定义了接口,具体实现类由各个厂商进行实现嘛(比如MySQL)

候选者:类加载有个规则:如果一个类由类加载器A加载,那么这个类的依赖类也是由「相同的类加载器」加载。

候选者:我们用JDBC的时候,是使用DriverManager进而获取Connection,DriverManager在java.sql包下,显然是由BootStrap类加载器进行装载

候选者:当我们使用DriverManager.getConnection()时,得到的一定是厂商实现的类。

候选者:但BootStrap ClassLoader会能加载到各个厂商实现的类吗?

候选者:显然不可以啊,这些实现类又没在java包中,怎么可能加载得到呢

面试官:嗯..

候选者:DriverManager的解决方案就是,在DriverManager初始化的时候,得到「线程上下文加载器」

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zgyyfg.html