Top 50 Java Interview Questions and Answers for Freshers
Codevity Admin · 10/25/2026
Codevity Admin · 10/25/2026
These are the 50 questions freshers meet most often in Java interviews, grouped by topic. Each has a priority (High, Medium or Low, by how often it is asked) and a short answer you can say out loud. Answers assume modern Java (17 or 21). Start with the High priority questions, and follow the links when an answer feels thin.
High priority. The JVM runs bytecode. The JRE is the JVM plus the standard class libraries. The JDK is the JRE plus the development tools (javac, jar, jshell, jcmd). Since Java 11 no separate JRE download is provided, and you install a JDK. See JDK vs JRE vs JVM.
High priority. javac compiles source code to bytecode, not to machine code. Each operating system has its own JVM that interprets that bytecode and JIT-compiles the hot parts to native code. The same .class files run anywhere there is a JVM: "write once, run anywhere". The JVM itself is platform specific.
High priority. The eight primitives are byte, short, int, long, float, double, char and boolean. Each has a wrapper (Integer, Double...) so it can be used in collections and generics. Autoboxing converts automatically, and unboxing a null wrapper throws NullPointerException. See data types and autoboxing.
High priority. Always pass by value. For objects, the value that is copied is the reference, so a method can change the object's state through its copy, but it cannot make the caller's variable point somewhere else. A swap(a, b) method therefore cannot swap the caller's variables.
High priority. An immutable string is thread-safe, can be cached (its hash code is computed once), is safe as a HashMap key, and underpins security (file paths, class names). The pool is a cache of string literals on the heap, so identical literals share one object. new String("a") always creates a new object. See strings.
High priority. String is immutable. StringBuilder is a mutable, not thread-safe buffer and is fast. StringBuffer is the older mutable buffer whose methods are synchronized. Use StringBuilder unless several threads share the buffer, which is rare.
High priority. compares primitive values, or references for objects. compares logical content when a class overrides it (as , and records do). Without an override, behaves like .
High priority. marks a variable that cannot be reassigned, a method that cannot be overridden, or a class that cannot be extended. is a block that runs after and . was a cleanup hook called by the garbage collector; it is deprecated for removal, so use or .
Medium priority. A member belongs to the class, not to any instance: one copy shared by all. Static methods cannot use or access instance members directly. A block runs once when the class is loaded. Static nested classes do not hold a reference to an outer instance.
High priority. Encapsulation (hide the state behind methods), inheritance (reuse and specialize a parent), polymorphism (one call, different behaviour by object type) and abstraction (expose what, hide how). See OOP in Java.
High priority. Overloading: the same name with different parameters in one class, chosen at compile time. Overriding: a subclass supplies its own version of an inherited instance method with the same signature, chosen at run time by the object's real type. Always add .
High priority. An abstract class can have fields, constructors and implemented methods, and a class can extend only one. An interface defines a contract; since Java 8 it can also have and methods, and a class can implement many. Use an interface for a capability, an abstract class to share state and code.
Medium priority. No. Static methods are hidden, not overridden: the version called depends on the reference type. Private methods are not inherited at all, so a subclass method with the same name is a separate method. See the override vs hiding snippet.
Medium priority. A constructor initializes a new object and has the class name and no return type. calls another constructor of the same class, and calls the parent's. Either must be the first statement. Constructors are not inherited, but a subclass constructor always calls a parent constructor.
Medium priority. (the class), package-private (the default; the package), (the package plus subclasses) and (everywhere). Prefer the narrowest access that works.
Medium priority. Java 8 added them so interfaces could gain new methods (like and ) without breaking every existing implementation. If two interfaces supply the same default, the class must override it and choose, with .
Medium priority. Inheritance models "is-a", and it couples the subclass to the parent's implementation. Composition models "has-a": hold a field and delegate to it. It is more flexible, easier to test and avoids fragile hierarchies. "Favour composition over inheritance."
Medium priority. , , , , , (deprecated), and , and . Override the first three consistently.
High priority. Make the class , all fields , set them only in the constructor, provide no setters, and defensively copy any mutable object that goes in or comes out (for example ). Or use a . , and are immutable.
High priority. is a resizable array: O(1) random access and amortized O(1) append, slow insertion in the middle. is a doubly linked list: O(1) insertion at a known node, but O(n) access by index, and extra memory per node. In practice wins almost always; use for queues and stacks. See collections.
High priority. It stores entries in an array of buckets (16 by default). The key's is spread and masked to pick a bucket; finds the key inside it. Collisions form a linked list, which becomes a balanced tree when a bucket reaches 8 entries (and the table has at least 64 slots). When the size passes capacity times the load factor (0.75), the table doubles and entries are redistributed.
High priority. Equal objects must have equal hash codes. Unequal objects may share one (a collision). If you override , override from the same fields, or hash-based collections will miss the entry. See the contract.
High priority. is unsynchronized and allows one key. is legacy, with every method synchronized and no nulls. is thread-safe with fine-grained locking and fast reads, and forbids null keys and values. Use for shared maps.
Medium priority. It is backed by a : each element is a key, with a dummy value. returns if an equal element is already present, so and define uniqueness.
High priority. gives a class its natural order, with inside the class (one order only). is a separate object with , so there can be many orders and you can sort classes you do not own: .
Medium priority. An iterator on or throws if the collection is structurally modified during iteration (other than through the iterator itself). Use , , or a concurrent collection. It is a best-effort bug detector, not a thread-safety guarantee.
Medium priority. for fastest lookup with no order, to keep insertion (or access) order, and for keys kept sorted, at O(log n) per operation.
Medium priority. (Java 9) creates a truly immutable list that rejects . is a read-only view: changes to the original list still show through it.
Medium priority. Generics add compile-time type safety () and remove casts. The compiler erases the type arguments, so at run time a and a are both just . You therefore cannot write , or create a generic array. See generics.
High priority. Checked exceptions (, ) extend and must be caught or declared with . Unchecked ones extend (, ) and signal programming errors. s () are not meant to be caught.
High priority. A statement that declares resources and closes them automatically, in reverse order, even on an exception. If both the body and throw, the body's exception wins and the other is attached as a suppressed exception. See exceptions.
Medium priority. actually throws an exception object, as a statement. is part of a method signature and declares which checked exceptions it may throw.
High priority. Almost always: after a normal finish, after an exception, and after . It does not run if the JVM exits first () or the thread is killed. A inside overrides the earlier return value and can hide an exception, so avoid it.
Low priority. Extend for a checked exception or for an unchecked one, and provide constructors taking a message and a cause. Wrap lower-level exceptions as the cause so the stack trace is not lost.
High priority. A functional interface has exactly one abstract method (, , ). A lambda is a compact implementation of it: . Local variables a lambda captures must be effectively final. See modern Java.
High priority. Intermediate operations (, , ) return another stream and are lazy. A terminal operation (, , , ) starts the pipeline and produces the result. A stream can be consumed only once. See streams.
High priority. turns each element into exactly one element. turns each element into a stream and flattens them all into one stream, such as into .
Medium priority. A container that may or may not hold a value, used as a return type to say "there may be no result". Do not use it for fields or parameters, and do not call without checking; prefer , and .
Medium priority. Java 16 added them for immutable data carriers. The compiler generates the constructor, accessors, , and . A record cannot extend a class, but it can implement interfaces.
Medium priority. LTS releases are 8, 11, 17, 21 and 25. Java 8: lambdas, streams, . 11: in lambdas, the HTTP client. 16: records. 17: sealed classes. 21: virtual threads and pattern matching for . Many companies still run 8, 11 or 17.
Low priority. For large, CPU-bound, stateless operations on data that splits easily. It uses the shared common pool, so it is a poor choice for small data, I/O or shared mutable state. Measure before you use it.
High priority. Implement (or use a lambda) and pass it to , or submit it to an . creates a new thread that calls . Calling yourself just runs it on the current thread. See threads.
High priority. provides mutual exclusion and visibility, so it makes compound actions atomic. provides visibility and ordering for a single variable but not atomicity, so is still a race. Use for counters.
Medium priority. Two or more threads each hold a lock the other needs and wait forever. Prevent it by acquiring locks in a consistent global order, using with a timeout, and keeping critical sections small. Diagnose with a thread dump ().
Medium priority. Threads are expensive to create. A pool reuses a fixed set of them, bounds resource use and queues extra work. Use , and prefer a with a bounded queue in production. See executors and virtual threads.
High priority. Objects live on the heap, split into a young generation (Eden and survivor spaces) and an old generation. Local variables and call frames live in each thread's stack. The collector frees objects that are unreachable from the GC roots. G1 is the default collector. See memory and GC.
Medium priority. : a thread's call stack is full, usually from infinite or very deep recursion. : the heap (or Metaspace) cannot supply memory, from a leak or loading too much data.
High priority. DI means a class receives its collaborators instead of creating them, so it is loosely coupled and testable. Spring creates and injects beans. The default scope is singleton: one instance per container. Constructor injection is preferred. See SOLID, DI and Spring Boot.
High priority. runs a SQL string; if user input is concatenated into it, an attacker can change the query. sends the SQL with placeholders and the values separately, so input is always treated as data. See JDBC.
Medium priority. Depend on an interface (a repository), and in the test replace it with a fake or a Mockito mock so no real database is touched. Follow Arrange, Act, Assert and cover the happy path, edge cases and failures. Test the database mapping itself in a separate integration test. See JUnit 5 and Mockito.
Answer each question aloud in two or three sentences, then check yourself against the answer. For the High priority items, also write the code or the example. Then take the Java interview quizzes in this collection, and practise 35 coding problems.
==equals()StringIntegerObject.equals==finalfinallytrycatchfinalize()try-with-resourcesCleanerstaticthisstatic@Overridedefaultstaticthis(...)super(...)privateprotectedpublicList.sortCollection.streamA.super.method()toStringequalshashCodegetClassclonefinalizewaitnotifynotifyAllfinalprivate finalList.copyOf(items)recordStringIntegerLocalDateArrayListLinkedListArrayListArrayDequehashCode()equals()equalshashCodeHashMapnullHashtableConcurrentHashMapConcurrentHashMapHashMapaddfalseequalshashCodeComparablecompareToComparatorcompare(a, b)Comparator.comparing(Employee::salary).reversed()ArrayListHashMapConcurrentModificationExceptionIterator.remove()removeIfHashMapLinkedHashMapTreeMapList.ofnullCollections.unmodifiableListList<String>List<String>List<Integer>Listnew T()instanceof List<String>IOExceptionSQLExceptionExceptionthrowsRuntimeExceptionNullPointerExceptionIllegalArgumentExceptionErrorOutOfMemoryErrortryAutoCloseableclose()throwthrowsreturnSystem.exitreturnfinallyExceptionRuntimeExceptionRunnableComparatorFunction(a, b) -> a + bfiltermapsortedcollectforEachcountreducemapflatMapList<List<Integer>>List<Integer>get()maporElseorElseThrowequalshashCodetoStringOptionalvarswitchRunnablenew Thread(...)ExecutorServicestart()run()run()synchronizedvolatilevolatile int count; count++AtomicIntegertryLockjstackExecutorServiceThreadPoolExecutorStackOverflowErrorOutOfMemoryErrorStatementPreparedStatement?