views:

408

answers:

7

I was reading a J2EE interview question thread and saw these. I realize that i cant answer these. If anyone wants to stab at this, i will generously reward points =)

  1. What is the flaw with the Stack class?
  2. Explain the Java Class loader mechanism. How would you prevent someone from overriding the java.lang.Object class?
  3. Can interfaces contain inner classes?
  4. Explain how you would get a Thread Deadlock with a code example?
  5. What happens when you try to serialize a class whose base class does not implement serializable?
  6. How can you prevent flow of control to a finally { } clause?
  7. I write two classes : I write a static method in the base class and override that static method in the child class. Will this code compile?
  8. What happens if you try to start a thread thats already been started?
+2  A: 

#5 http://java.sun.com/javase/6/docs/api/java/io/Serializable.html

To allow subtypes of non-serializable classes to be serialized, the subtype may assume responsibility for saving and restoring the state of the supertype's public, protected, and (if accessible) package fields. The subtype may assume this responsibility only if the class it extends has an accessible no-arg constructor to initialize the class's state. It is an error to declare a class Serializable if this is not the case. The error will be detected at runtime.

During deserialization, the fields of non-serializable classes will be initialized using the public or protected no-arg constructor of the class. A no-arg constructor must be accessible to the subclass that is serializable. The fields of serializable subclasses will be restored from the stream.

When traversing a graph, an object may be encountered that does not support the Serializable interface. In this case the NotSerializableException will be thrown and will identify the class of the non-serializable object.

#6 Call System.exit before the finally block.

#7 It will compile. It's okay to have a subclass "redefine" a static method in the parent class. However, this method is not "overridden" so polymorphism doesn't apply. This method is invoked by ClassName.method or by class instance variable. If invoked by class instance variable, it's the static method in this class that gets called.

#8 IllegalThreadStateException - Thread.start docs

marklai
#5 Question is about non-serialisable base classes. Which is all serialisable objects, because of `java.lang.Object`. (Assuming question is about serialising an instance of a class, not a `Class`.)
Tom Hawtin - tackline
Thanks. Updated answer with more javadoc. I think it usually ends in NotSerializableException in practice, for anything useful.
marklai
+1. Nice explanation
Bragboy
+2  A: 

#1: I'm unsure if it's the flaw that was intended, but Stack extending Vector (rather than being composed of one) always seemed like a flaw to me.

Jeff Walden
+3  A: 

#1. java.util.Stack extends java.util.Vector. Instead of an is-a, it should've been a has-a. The way it currently is, you can insert elements at any arbitrary index and do other Vector-like but not Stack-like behavior on a Stack.

#6. Two ways: (i) shutdown the JVM with System.exit(n), or (ii) infinite loop or other such non-sense.

#7. Absolutely the code will compile. There is no trick to that question at all. Maybe if you ask which gets invoked when you do Base b = new Child(); b.method();, then we have something to discuss. But not really, because static method invocation is always bound at compile time, and there's no polymorphism what so ever. That code will always call Base.method(). In fact, you should invoke a static method on the type, not on an instance of that type, just to make that point clear (although it really should be quite obvious).


On further thought, maybe what is meant is that the @Override annotation was used. In this case, then no, it wouldn't compile, since really it's not a proper override (for reasons already mentioned).

polygenelubricants
Why is why the @Override annotation is so awesome. And since Java6 it also works on methods implementing interfaces.
Mark Renouf
#7 Won't compile if the method in the base class is final.
Tom Hawtin - tackline
+2  A: 

#2

The Java ClassLoader system, and protecting sensitive classes.

The ClassLoader mechanism is responsible for loading and verifying java bytecode and using it to instantiate Class instances within the JVM. The ClassLoader is asked to retreive a class the first time it is referenced. There is one system ClassLoader which is used by default, and additional ClassLoaders can be set as the default per-thread. Any mechanism can be used to retrieve the given code, up to and including dynamically generating it on the fly (this is how scripting languages are implemented atop the JVM).

By first delegating requests up to the parent ClassLoader, and only handling them in the cases where the parent (system) ClassLoader does not locate the class, you are protected from loading overriding sensitive system classes which may have not been loaded yet. You could even just implement your own strategy in your ClassLoader to white-list a particular package, or only handle classes implementing a specific set of interfaces.

Finally a security policy can be used to restrict which code is even allowed to change the ClassLoaders in use.

#3

Can an interface define inner classes?

Absolutely!

It comes in handy if you want to provide an Enum in the definition of your interface. Though I don't know any real cases where this provides a clear benefit, since there's no special access to a class instance that you'd normally get with inner classes within classes.

You can also define fields (must be final, but can non static!). Anyone know why you would ever use this? And does the implementing class inherit them as expected?

#4

Causes of deadlocks

There are two common situations.

  1. Two threads which attempt to acquire a series of locks in different orders can end up each holding a lock which the other is waiting for.

  2. Code which attempts to acquire a lock it already holds (usually due to recursion). For this you should consider switching using java.util.concurrent.Lock. the ReentrantLock implementation solves this problem elegantly.

Mark Renouf
A: 

#1: java.util.Stack does not strictly follow the Stack ADT. You can insert or delete elements inbetween. I dont know why Stack still extends Vector. If you ask me it should be made an interface as it is done with Queue. Queue and Stack go hand in hand and should be treated as a family. java.util.LinkedList implements Queue. Infact you can do exactly the same with Stack as well.

However, in that case too stack will still have the properties of a List interface. At least it wont be as bad as it is extending the obsolete Vector class which we should not use anymore due to synchronized methods within.

#3

public interface InterfaceInnerClass {
    class example{
        //Yes, you can have a inner class
    }
}
Bragboy
Re: Stack... it won't ever get changed that this point. Instead you should use the Queue and Deque interfaces. There are several implementations in the JDK, and also don't forget that Vector (as well as Hashtable) is completely synchronized which leads to unnecessary overhead when not shared by multiple threads.
Mark Renouf
@Mark: Yes I completely agree. But why was that designed that way? Enqueue, dequeue for Queues are similar to Push/Pop for a stack. why Queue was made an interface while stack hasnt. I've also stressed to the point that usage of Vector has to be avoided at all costs.
Bragboy
A: 
  1. Stack uses inheritance instead of composition and because all methods in vector are synchronized so are the ones in stack.
  2. Wyh would someone do class loading itself?
  3. Static inner classes, yes.
  4. Pfff...
  5. Nothing. Object does not implement Serializable but sub classes can.
  6. Pull the power cord.
  7. Yes. But redefining != overriding. You can't override static methods.
  8. A useful exception? See javadocs.
Willi