面试的曲折

面试了一个地方做银行支付系统的,对方的技术人员最后问我“能不能加载一个自己重写的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修改过]