Java Interview Questions
The "What is..." question. Usually about the reserved keywords or concepts.
Field/method not tied to any object instance but the class.
- static field: Class variable. Accessed by class name and has only one copy.
- static method: Class method. Called by class name(
Foo.baz()) instead of by instance(
- not part of the persistent state of an object
- will not be serialized. Used for fields you do not want to serialize in a
- will be
- Abstract Class: Contains abstract methods, cannot be instantiated.
- Abstract Interface: Interfaces are implicitly abstract. Optional modifier.
- Abstract Method: Method without a body. The class containing this abstract method must also be abstract.
- The class could not be instantiated from outside. A static public method must be provided for creating instances. (Factory Method Pattern)
- The class could not be inherited.
- protect data from unwanted access.
- a new class extends an existing one.
- different implementations for the same interface.
- Compile-time polymorphism: method/operator overload(method with different parameters)
- Run-time polymorphism: override(re-define functionality, same signature)
- interface with no field or methods. (i.e. empty interface)
- a.k.a. tag interface
- used to indicate something to compiler or JVM.
Annotationis a better alternative after Java 5.
- indicates that a variable's value will be modified by different threads.
- The value of this variable will never be cached thread-locally: all reads and writes will go straight to "main memory";
- Access to the variable acts as though it is enclosed in a synchronized block, synchronized on itself.
In Java, each thread has a separate memory space known as working memory; this holds the values of different variables used for performing operations. After performing an operation, thread copies the updated value of the variable to the main memory, and from there other threads can read the latest value. Simply put, the volatile keyword marks a variable to always go to main memory, for both reads and writes, in the case of multiple threads accessing it.
- object state cannot change after it is created.
- simple to use test and construct.
- thread-safe, useful in concurrent applications
- do not require a copy constructor.
- do not require an implementation of clone.
- allow hashCode to use lazy initialization, and to cache its return value.
- do not need to be copied defensively when used as a field.
- are good Map keys and Set elements (these objects must not change state while stored in the collection).
- have their class invariant established once upon construction, and it never needs to be checked again.
- always have "failure atomicity" (a term used by Joshua Bloch) : if an immutable object throws an exception, it's never left in an undesirable or indeterminate state.
To make an object immutable:
- make the class
- all its member
final, or non-final but
privateand not modified except in constructors.
- Class: cannot be sub-classed.
- Method: cannot be overridden.
- Primitive Variable: value cannot be changed.
- Reference Variable: cannot point to another object.
- Note that in final
Map, items/entries are still modifiable
- optional block after try-catch block. Used for clean up.
- finally block will be executed even if exit, return, continue, break or exceptions are found in try block.
- finally block will not be executed if VM exits in between try-catch block, or the thread is killed. Or an exception is thrown in finally block and not handled then remaining code in finally block may not be executed.
- the method called before the object is garbage collected; to release the resources, e.g. if an object is holding some non-java resources like file handle.
- deprecated after Java 9
- Interface: only declare constants and methods, no implementation before Java 8, but after that interface can have default methods and static methods. Abstract class: may have implementations.
- Interface: all public members. Abstract class: public/private/protected, must have abstract method.
- abstract class could not be used for multiple inheritance, interface could.
- syn block place locks for shorter period.
- JVM call finalize before running the garbage collector.
sleep()could not wake up.
wait()could stop when receiving
sleep()is defined in class Thread,
wait()is in class Object.
wait()releases the lock or monitor while
wait()is used for inter-thread communication while
sleep()is used to introduce pause on execution.
- Callable returns a value
- Runnable does not return a result and cannot throw a checked exception.
Executors.newCachedThreadPool(): an executor with an expandable thread pool. This executor is suitable for applications that launch many short-lived tasks.
start()creates new Thread and execute code declared in run(); directly calling
run()method doesn’t create any new thread and execute code on same calling thread
- can reuse CyclicBarrier once barrier is broken but you can not reuse CountdownLatch.
- If two Threads, t1/t2, are accessing the same object and updating a variable which is declared as static then it means t1 and t2 can make their own local copy of the same object(including static variables) in their respective cache, so update made by t1 to the static variable in its local cache wont reflect in the static variable for t2 cache .
- used in the Object context where update made by one object would reflect in all the other objects of the same class but not in the Thread context where update of one thread to the static variable will reflect the changes immediately to all the threads (in their local cache).
- If two Threads, t1/t2, are accessing the same object and updating a variable which is declared as volatile then it means t1 and t2 can make their own local cache of the Object except the variable which is declared as a volatile. So the volatile variable will have only one main copy which will be updated by different threads and update made by one thread to the volatile variable will immediately reflect to the other Thread.
- used in the Thread context.
- a primitive variable may be declared volatile however you can't synchronize on a primitive with synchronized;
- an access to a volatile variable never has the potential to block: we're only ever doing a simple read or write, so unlike a synchronized block we will never hold on to any lock;
- because accessing a volatile variable never holds a lock, it is not suitable for cases where we want to read-update-write as an atomic operation (unless we're prepared to "miss an update");
- a volatile variable that is an object reference may be null (because you're effectively synchronizing on the reference, not the actual object).
Attempting to synchronize on a null object will throw a NullPointerException.
- String: immutable
- StringBuffer: mutable, synchronized. Use it if the object can be modified by multiple threads.
- StringBuilder: mutable, not synchronized. Use it if the object will not be modified by multiple threads.
It is very useful to have strings implemented as final or immutable objects. Below are some advantages of String Immutability in Java
- Immutable objects are thread-safe. Two threads can both work on an immutable object at the same time without any possibility of conflict.
- Security: the system can pass on sensitive bits of read-only information without worrying that it will be altered
- You can share duplicates by pointing them to a single instance.
- You can create substrings without copying. You just create a pointer into an existing base String guaranteed never to change. Immutability is the secret behind Java’s very fast substring implementation.
- Immutable objects are much better suited to be Hashtable keys. If you change the value of an object that is used as a hash table key without removing it and re-adding it you lose the mapping.
- Since String is immutable, inside each String is a char exactly the correct length. Unlike a StringBuilder there is no need for padding to allow for growth.
- If String were not final, you could create a subclass and have two strings that look alike when "seen as Strings", but that are actually different.
Everything in Java is pass-by-value. There is no such thing as "pass-by-reference" in Java. In case of objects, think of it as passing the value of the "address" of the object.
- JVM is out of memory, and no more memory could be made available by the garbage collector.
- to solve
java.lang.OutOfMemoryError: Java heap space: add
-Xms1024m -Xmx1024mwhen starting the program.
Why main() in java is declared as public static void main? What if the main method is declared as private?
- Public - main method is called by JVM to run the method which is outside the scope of project therefore the access specifier has to be public to permit call from anywhere outside the application
- static - When the JVM makes are call to the main method there is not object existing for the class being called therefore it has to have static method to allow invocation from class.
- void - Java is platform independent language therefore if it will return some value then the value may mean different to different platforms so unlike C it can not assume a behavior of returning value to the operating system.
If main method is declared as private then - Program will compile properly but at runtime it will give "Main method not public." error.
- blocked on IO: no way to interrupt
- blocked by
join(): interrupt the thread and it will awake by throwing InterruptedException.