Ideally, you should have one mainstream programming language down very well, to use in interviews. Java is mine.
- An interrupt is an indication to a thread that it should stop what it is doing and do something else. It's up to the programmer to decide exactly how a thread responds to an interrupt, but it is very common for the thread to terminate.
- A thread sends an interrupt by invoking
Threadobject for the thread to be interrupted. For the interrupt mechanism to work correctly, the interrupted thread must support its own interruption.
joinmethod allows one thread to wait for the completion of another. If it is a Thread object that is currently executing, then
thread.join();causes the current thread to pause execution until its thread terminates.
- When a JVM starts up, there is usually a single non-daemon thread (which typically calls the method named
mainof some designated class). The JVM continues to execute threads until either of the following occurs:
- The exit method of class
Runtimehas been called and the security manager has permitted the exit operation to take place.
- All threads that are not daemon threads (
thread.setDaemon(true);wasn't called) have died, either by returning from the call to the
runmethod or by throwing an exception that propagates beyond the
- The exit method of class
|boolean||1 bit||1 Byte|
|byte||8 bit||1 Byte|
|short||16 bit||2 Byte|
|char||16 bit||2 Byte|
|int||32 bit||4 Byte|
|float||32 bit||4 Byte|
|long||64 bit||8 Byte|
|double||64 bit||8 Byte|
- Memory reference (pointer): 4 Bytes.
- Object header: a few Bytes (~8 Bytes) for housekeeping info (GC, class, id, etc.).
- Array header: 12 Bytes (4 Bytes for array length).
BitSet– a bit vector with growing size, each element is a boolean with 1-bit size (not 8-bit as regular booleans).
- Thread stacks are allocated outside the heap. The heap only stores objects.
- Thread stacks contain local variables (primitives, heap references) and calls to methods. Sometimes the JVM optimizes and allocates objects that never leave the stack scope on the stack (function-local objects).
- Arrays are like Objects, and are generally stored on the heap.
- Default stack size on 64-bit Linux is 256 KB for a single thread.
- Frame size for a simple method call is 32 Bytes.
- JVM Internals (read at least until Class File Structure.)
- In JDK8 8 PermGen is replaced with Metaspace, which is very similar. The main difference is that Metaspace can expand at runtime (less
- If you don't specify
MaxMetaspaceSizethe Metaspace will dynamically resize depending on the application demand at runtime.
- Metaspace allocations are out of native memory.
- Metaspace garbage collection of dead classes and classloaders is triggered once the class metadata usage reaches the
- Since JDK 6 interned strings are no longer allocated in the PermGen, but are instead allocated in the regular heap.
- Objects are created on the heap.
- Garbage collection is a mechanism provided by the JVM to reclaim heap space from objects eligible for GC.
- GC is done by the GC thread.
- Before removing an object from memory, GC thread invokes the
finalize()method of the object, allowing for cleanup operations (but don't use finalizers – Effective Java 2nd Ed. Item 7).
- As a developer you can't force GC, it will only be triggered if the JVM thinks it needs to based on the Java heap size.
- You can request GC (by
System.gc()) but it's not guaranteed to happen.
- If the JVM heap is full, and a new object can't be created, an
OutOfMemoryErrorexception is thrown.
- An object becomes eligible for GC if it's not reachable from any live thread of any static reference, meaning if all its references are null.
- Cyclic dependencies aren't references, and they will be GCed if no other objects have a reference to any of them.
- GC scenarios: all references to an object are set to null, object declared in a block and now out of scope, object is a member and the parent is eligible for GC, object in a
- Java memory leaks:
- Can be created by some hacks involving
ThreadLocal, see link
- Static final fields
myString.intern()– places string in memory pool that can't be removed
- Unclosed open streams (file, network, etc.) or connections
- Native hooks that aren't accessible to GC
- Misuse of JVM options (parameters)
Mapwhich uses incorrect
hashCode, so elements are always added
- Can be created by some hacks involving
- Available garbage collectors and how to select one.
Common JVM Options
-Xms1g– Initial heap size
-Xmx2g– Hax heap size
-XX:MaxMetaspaceSize=200m– Add a limit to Metaspace (not limited by default)
-Xmn500m– Initial and max young gen size
-XX:SurvivorRatio=4– Ratio of survivor size relatively to eden size (ratio = young/survivor - 2)
-Xss256k– Thread frame stack size
- More options recommendations and details
- Can use
java.util.BitSetto work with single bits.
- Positive integers are stored as simple binary numbers:
int a = 0b101; assertEquals(5, a); // true int zero = 0b0; int one = 0b1; int two = 0b10; int three = 0b11; int five = 0b101;
- Negative integers are stored as the two's complement of their absolute value. The two's complement of a positive number is, when using this notation, a negative number.
- To find the negative of a number (
x) in two's complement:
- Invert all the bits (
x + 1)
- Invert all the bits (
int x = 4; int minusX = ~x + 1; assertEquals(-4, minusX); // true int minusOne = 0b11111111111111111111111111111111; int minusTwo = 0b11111111111111111111111111111110; int minusThree = 0b11111111111111111111111111111101; int minusFour = 0b11111111111111111111111111111100; int minusFive = 0b11111111111111111111111111111011;
- Signed shift right.
- Uses the sign bit (left most bit) to fill the trailing positions after the shift.
- Unsigned (logical) shift right.
- Shift right while filling zeros
0, irrespective of the sign of the number.
intcasting drops any decimal, essentially rounding down.
- Backed by char array, can get it by calling
- Strings are always immutable, and the class is
- Strings concatenation with the
+operator translates to
StringBuilderoperations by the compiler, but creates a new instance of
StringBuilderfor every concatenation. Use
StringBuilderdirectly for repeated concatenation in multiple statements with intermediate strings (single statements are fine, e.g., for
String s = a + b + cuse
- String literals, i.e.
String s = "hello", are interned by the compiler.
- Interned strings are privately maintained in a pool, which is initially empty, by the class
public String intern()function on
Stringplaces that instance in the pool and returns the canonical representation for that string object.
- When the
internmethod is invoked, if the pool already contains a string equal to this
Stringobject as determined by the
equals(Object)method, then the string from the pool is returned.
- Otherwise, this
Stringobject is added to the pool and a reference to this
Stringobject is returned.
- All literal strings and string-valued constant expressions are interned.
==tests for reference equality (whether they are the same object).
.equals()tests for value equality (whether they are logically equal).
new String("test") == "test"is
new String("test") == new String("test")is
"test" == "test"is
- You almost always want to use
.equals(). In the rare situation where you know you're dealing with interned strings, you can use
ITC (Inter-Thread Communication)
- Java includes an inter-process communication mechanism via the
- These methods are implemented as final methods in
Object, so all classes have them.
- All three methods can be called only from within a
wait()tells the calling thread to give up the monitor and go to sleep until some other thread enters the same monitor and calls
- Additional forms of
wait()exist that allow you to specify a period of time to wait.
notify()wakes up the first thread that called
wait()on the same object.
notifyAll()wakes up all the threads that called
wait()on the same object. The highest priority thread will run first.
- You should probably not use
notifydirectly and use the
Lockclass and others from
- Having no modifier is also called package-private.
- When a class or interface is accessible to clients for each modifier:
- Autoboxing is the automatic conversion that the Java compiler makes between the primitive types and their corresponding object wrapper classes (e.g., converting an
- If the conversion is the other way around (object to primitive) it's unboxing.
- The Java compiler applies autoboxing/unboxing when a primitive/object is:
- Passed as a parameter to a method that expects an object/primitive of the corresponding wrapper/primitive type.
- Assigned to a variable of the corresponding wrapper/primitive type.
- The compiler uses
valueOfto autobox and
intValueto unbox (for
int, for example).
- Beware of unnecessary Object creation with autoboxing/unboxing.
- Object types don't support operators (
+for example), so using it on
Integerwill trigger unboxing and then autoboxing.
- For arithmetics always prefer primitives.
- Equality checks with
==don't unbox and so reference are compares, not values. So to compare two
.equals()or preferrable use primitive types.
- You can get
NullPointerExceptions when unboxing.