面试的曲折

面试了一个地方做银行支付系统的,对方的技术人员最后问我“能不能加载一个自己重写的java.lang.String”。我想到的第一个回答是“有什么可能需要重写java.lang.String”,想了想还是没说。

不可能啊,类加载器的安全模型不同意。

加载是可以的,只需要自己重写一个classloader,但是被系统应用又是另外的事情了,看看下面的程序。我说这些的目的不是在讨论写一个自己的Integer或者String,其实是思考角度的问题。

站在应用Java做业务过程角度上其实不需要过分的关注Java是怎么实现安全管理的,因为在应用中根本就不应该考虑这种替换核心类的实现方式。

public class SimpleClassLoader extends ClassLoader {
private Hashtable classes = new Hashtable();

public SimpleClassLoader() {
}

/**
* This sample function for reading class implementations reads
* them from the local file system
*/
private byte getClassImplFromDataBase(String className)[] {
System.out.println(" >>>>>> Fetching the implementation of "+className);
byte result[];
try {
String path = null;
if(!className.equalsIgnoreCase("java/lang/Integer"))
{
path = "bin/ClassLoader/" + className+".class";
}
else
{
path = "bin/" + className+".class";
}

FileInputStream fi = new FileInputStream(path);
result = new byte[fi.available()];
fi.read(result);
return result;
} catch (Exception e) {

/*
* If we caught an exception, either the class wasnt found or it
* was unreadable by our process.
*/
return null;
}
}

/**
* This is a simple version for external clients since they
* will always want the class resolved before it is returned
* to them.
*/
public Class loadClass(String className) throws ClassNotFoundException {
return (loadClass(className, true));
}

/**
* This is the required version of loadClass which is called
* both from loadClass above and from the internal function
* FindClassFromClass.
*/
public synchronized Class loadClass(String className, boolean resolveIt)
throws ClassNotFoundException {
Class result;
byte classData[];

System.out.println(" >>>>>> Load class : "+className);

/* Check our local cache of classes */
result = (Class)classes.get(className);
if (result != null) {
System.out.println(" >>>>>> returning cached result.");
return result;
}

/* Check with the primordial class loader */
try {
if(!className.equalsIgnoreCase("java/lang/Integer"))
{
result = super.findSystemClass(className);
System.out.println(" >>>>>> returning system class (in CLASSPATH).");
return result;
}
} catch (ClassNotFoundException e) {
System.out.println(" >>>>>> Not a system class.");
}

/* Try to load it from our repository */
classData = getClassImplFromDataBase(className);
if (classData == null) {
throw new ClassNotFoundException();
}

/* Define it (parse the class file) */
result = defineClass(classData, 0, classData.length);
if (result == null) {
throw new ClassFormatError();
}

if (resolveIt) {
resolveClass(result);
}

classes.put(className, result);
System.out.println(" >>>>>> Returning newly loaded class.");
return result;
}
=============================================================================
package java.lang;

public class Integer
{
public String toString()
{
return "mine";
}
}
===============================================================================
public class TestClass{
public static void main(String[] args) throws Exception
{
SimpleClassLoader sc = new SimpleClassLoader();
Object o;
o = (sc.loadClass("java/lang/Integer")).newInstance();
o.toString();
}
}

呵呵,LS的classLoader可以说不是一个完整的classLoader,真的classLoader是有委托模型的,是要指定父子关系,只要指定了父子关系,那么就不可能通过自己写的classLoader来加载与类库同名的类了,因为加载顺序是先父加载器后子加载器。

没错的,这个方式下class被加载起来了,但是还不可能被真正的用起来,我这么写一个也仅仅是为了娱乐。

我发这个帖子也不是为了讨论技术,算是放水发个牢骚吧,这不是杂类么。

不需要重写一个ClassLoader吧?直接用URLClassloader指定路径,将String放在指定路径下不可以么?

很多年轻人对面试题耿耿于怀。
其实,面试出题,和考试出题,完全是两码事。
后者,你答对了,就给分,答错了,没分。
面试题,仅仅是一个话题。面试人随便找个话题,与你随便漫谈,从中了解你对技术的感悟程度。

ls说的是,面试更多的是互相了解的过程。
应该是思考方式不同吧,我遇到的面试人员几乎都是专注于某个技术细节的深入考察。但是我做过的项目都没有需要那么多对于某一个细节的太深入计较,反而更多的是对于应用过程的理解和程序结构上的考虑,很多细节在遇到的时候即时去学习就可以了。

也许我本来没想过做技术专家吧,呵呵。

很多年轻人对面试题耿耿于怀。
其实,面试出题,和考试出题,完全是两码事。
后者,你答对了,就给分,答错了,没分。
面试题,仅仅是一个话题。面试人随便找个话题,与你随便漫谈,从中了解你对技术的感悟程度。
------------------------------------
面试的时候,出任何题目的目的都是为了了解应聘者,更多是从其回答交流看这个人对技术理解的程度。像我们公司技术面试出题什么都有,但并不是要求应聘者答出标准答案,而是希望应聘者通过题目展开话题,最好是能延伸到其他方面,更好展现自己好让公司更好了解应聘者。
[该贴被BinnyJ于2009-11-02 18:26修改过]