Junior Level Questions Level-1
1. Characteristics of Object-Oriented Programming (OOP) languages:
- Encapsulation: Bundling data (attributes) and methods (functions) that operate on the data into a single unit, usually a class.
- Abstraction: Hiding implementation details and showing only the essential features of an object.
- Inheritance: Allows a new class (subclass) to inherit properties and behaviors (methods) from an existing class (superclass).
- Polymorphism: The ability of an object to take many forms. Specifically, it allows one interface to be used for a general class of actions.
- Modularity: The code is organized into discrete units called classes and objects, improving code maintainability and readability.
2. Access Modifiers in Java:
- public: The member is accessible from anywhere.
- private: The member is only accessible within the same class.
- protected: The member is accessible within the same package or subclasses.
- default (package-private): If no access modifier is specified, the member is accessible only within the same package.
3. Overriding vs Overloading:
- Overriding: Changing the behavior of an existing method in a subclass. It requires the method signature (name, parameters) to be the same as in the parent class.
- Overloading: Defining multiple methods with the same name but different parameter lists (different number of parameters or parameter types) in the same class.
4. Interface vs Abstract Class:
- Interface: It defines a contract for what methods a class must implement. All methods in an interface are implicitly abstract (before Java 8), and an interface cannot contain any method implementation.
- Abstract Class: It is a class that cannot be instantiated directly. It can have both abstract methods (without implementation) and concrete methods (with implementation). An abstract class can also hold instance variables.
5. Can an Interface extend another Interface?
- Yes, an interface can extend another interface, and it can extend multiple interfaces (Java supports multiple inheritance of interfaces). The extending interface will inherit all the abstract methods of the parent interface(s).
6. Meaning of the static keyword in Java:
- The static keyword in Java is used to indicate that a member (variable, method) belongs to the class rather than instances of the class. This means the static member can be accessed without creating an object of the class.
7. Can a static method be overridden in Java?
- No, static methods cannot be overridden. They can be hidden in subclasses, but overriding applies only to instance methods.
8. Polymorphism and Inheritance:
- Polymorphism: The ability for different classes to be treated as instances of the same class through inheritance or interfaces. It typically refers to method overriding where a subclass can provide a specific implementation for a method defined in a superclass.
- Inheritance: A mechanism where one class (subclass) inherits the fields and methods of another class (superclass), promoting code reuse.
9. Can a constructor be inherited?
- No, constructors cannot be inherited. However, a subclass can call a constructor of its superclass using super().
10. Objects passed by reference or value in Java?
- In Java, all arguments are passed by value. However, if you pass an object, you are passing the value of the reference (memory address) to the object. This means that the reference to the object is copied, and changes made to the object affect the original, but if the reference itself is changed (e.g., pointing to another object), the original reference is not affected.
11. Difference between == and .equals() on a string:
- ==: Compares memory references (whether two objects point to the same memory location).
- .equals(): Compares the content (value) of two objects. In the case of strings, it compares the sequence of characters.
12. Usage of hashCode() and equals():
- hashCode(): Returns an integer hash code value that represents the object’s memory address or its state. It is used in hash-based collections like HashMap and HashSet.
- equals(): Determines whether two objects are considered equal based on their state (not their memory address).
13. Serializable vs Parcelable:
- Serializable: A standard Java interface that allows an object to be converted into a byte stream and saved or transmitted, so it can be restored later. It is a simple but slower method.
- Parcelable: A more efficient, Android-specific interface for serializing objects. It involves manual implementation and is faster than Serializable.
14. Array vs ArrayList:
- Array: A fixed-size collection that holds elements of the same type. It has a predefined length and cannot be resized.
- ArrayList: A dynamic array implementation in Java. It can grow or shrink in size dynamically, but it has an overhead because of its flexibility.
15. Difference between Integer and int:
- int: A primitive data type used to represent integer values (e.g., 5, -12).
- Integer: A wrapper class for the primitive int. It is used when you need to use an object-oriented approach (e.g., in collections like ArrayList).
16. What is a ThreadPool?
- A ThreadPool is a collection of reusable worker threads used to execute tasks concurrently. It improves performance by reusing threads, instead of creating new threads for every task. It is generally more efficient than creating separate threads for each task because it reduces thread creation overhead.
17. Difference between local, instance, and class variables:
- Local Variable: A variable declared inside a method or block, and it can only be accessed within that method or block.
- Instance Variable: A variable declared in a class, but outside any method. It is specific to each instance of the class.
- Class Variable: A variable declared as static in a class. It is shared among all instances of the class and can be accessed without creating an instance.
Junior Level Questions Level-2
1. What is Reflection in Java?
- Reflection is a feature in Java that allows the inspection and modification of classes, methods, fields, and other metadata during runtime. It enables you to access information about a class (like its methods, constructors, and fields) and modify it dynamically. It is commonly used in frameworks like Spring and Hibernate for operations like dependency injection, mapping, and more.
2. What is Dependency Injection? Can you name a few libraries?
- Dependency Injection (DI) is a design pattern where an object’s dependencies (i.e., objects it needs to function) are provided externally rather than being created inside the object. This promotes loose coupling and easier testing.
- Some popular libraries for Dependency Injection in Java include:
- Spring Framework
- Google Guice
- Dagger
- CDI (Contexts and Dependency Injection)
- Yes, I’ve worked with Spring Framework for DI.
3. What are strong, soft, and weak references in Java?
- Strong Reference: The standard reference type in Java. An object referenced by a strong reference will not be garbage collected.
- Soft Reference: Objects with soft references are collected only when the JVM needs memory. They are useful for implementing memory-sensitive caches.
- Weak Reference: Objects with weak references are collected as soon as they are no longer strongly reachable. They are used to implement data structures like WeakHashMap.
4. What does the synchronized keyword mean?
- The synchronized keyword in Java is used to ensure that a method or block of code is accessed by only one thread at a time. It provides thread safety by allowing only one thread to execute the synchronized block or method for a particular object or class.
5. Can you have “memory leaks” in Java?
- Yes, although Java has automatic garbage collection, memory leaks can still occur if references to unused objects are not properly released. This can happen when objects are unintentionally kept alive, preventing the garbage collector from reclaiming memory.
6. Do you need to set references to null in Java/Android?
- Java: It’s not mandatory to set references to null, but it can help in some cases, especially for large objects, to make sure they are eligible for garbage collection. However, relying too much on this can lead to unnecessary code complexity.
- Android: It’s recommended to set large objects, particularly those holding resources like bitmaps or context references, to null when they’re no longer needed to avoid memory leaks, especially in activities and fragments.
7. What does it mean to say that a String is immutable?
- A String in Java is immutable, meaning once a String object is created, its value cannot be changed. Any operation on a String (e.g., concatenation) creates a new String object rather than modifying the original one.
8. What are transient and volatile modifiers?
- transient: Used to indicate that a field should not be serialized. When an object is serialized, transient fields are ignored.
- volatile: Used to indicate that a field can be accessed and modified by multiple threads concurrently. It ensures visibility of changes made to the variable by one thread to other threads.
9. What is the finalize() method?
- The finalize() method in Java is invoked by the garbage collector before an object is garbage collected. It allows an object to clean up resources (like closing files or releasing connections) before it’s destroyed. However, its use is discouraged, and try-with-resources and explicit resource management are preferred.
10. How does the try { } finally { } work?
- The finally block is always executed, regardless of whether an exception is thrown in the try block or not. It’s typically used to release resources (like closing streams or connections) to ensure they are cleaned up properly.
11. What is the difference between instantiation and initialization of an object?
- Instantiation refers to the process of creating an object from a class using the new keyword. It allocates memory for the object.
- Initialization refers to the process of assigning values to the object’s fields after it has been instantiated. It may be done via constructors, setter methods, or directly at the point of creation.
12. When is a static block run?
- A static block is run when the class is first loaded into memory. It is executed only once, before any instances of the class are created or static methods are accessed.
13. Why are Generics used in Java?
- Generics in Java allow for type safety at compile-time. They allow you to write code that can work with different types while avoiding the need for type casting. For example, a List<T> can hold objects of any type, and the compiler ensures that only the specified type can be added to the list.
14. Can you mention the design patterns you know? Which of those do you normally use?
- Some common design patterns are:
- Singleton: Ensures a class has only one instance and provides a global point of access to it.
- Factory: Creates objects without specifying the exact class of object that will be created.
- Observer: Defines a one-to-many dependency between objects so that when one object changes state, all its dependents are notified.
- Strategy: Defines a family of algorithms, encapsulates each one, and makes them interchangeable.
- Decorator: Adds responsibilities to an object dynamically.
- Adapter: Converts the interface of a class into another interface that a client expects.
- Facade: Provides a simplified interface to a complex subsystem.
- I regularly use the Singleton, Factory, and Observer patterns, especially when working with frameworks like Spring, which leverages DI and other design patterns.
15. Can you mention some types of testing you know?
- Unit Testing: Testing individual units or components of the code in isolation.
- Integration Testing: Testing the interaction between different modules or systems.
- System Testing: Testing the complete system to ensure it meets the requirements.
- Acceptance Testing: Validating that the system meets the business requirements and is ready for deployment.
- Regression Testing: Ensuring that new changes or features don’t break existing functionality.
- Performance Testing: Testing the system for performance issues, like response time, scalability, and load capacity.
- Smoke Testing: A basic test to check if the most crucial functions of the system work as expected.
Junior Level Questions Level-3
1. How does Integer.parseInt() work?
- The Integer.parseInt() method converts a string representation of a number (e.g., “123”) into its corresponding integer value. It parses the string and checks if it’s a valid number. If the string is not a valid number, it throws a NumberFormatException.
- Example: int num = Integer.parseInt(“123”);
2. What is the “double check locking” problem?
- Double-check locking is a technique often used to reduce the overhead of acquiring a lock by first testing the condition without synchronization. However, it can lead to issues in multi-threaded environments because the memory visibility guarantees in Java are not always met. This happens because, after checking the condition once, the thread may proceed without locking, and the result might be inconsistent across threads. It is commonly used in singleton design patterns but can be problematic if not implemented correctly (e.g., not using volatile keyword).
3. What is the difference between StringBuffer and StringBuilder?
- Both StringBuffer and StringBuilder are classes used to manipulate strings, but their key difference lies in thread-safety:
- StringBuffer: Synchronized, which means it’s thread-safe. However, this comes with a performance overhead.
- StringBuilder: Not synchronized, so it is not thread-safe but is faster than StringBuffer when used in single-threaded scenarios.
4. How is a StringBuilder implemented to avoid the immutable string allocation problem?
- Unlike String (which is immutable), StringBuilder is mutable. It maintains an internal array of characters, and when characters are appended or modified, the array is resized or adjusted in place without creating a new object every time, unlike String. This allows more efficient string manipulation.
5. What does Class.forName() do?
- The Class.forName() method is used to load a class dynamically at runtime. It returns the Class object associated with the class name provided as a string. This is typically used in cases like JDBC (e.g., loading database drivers) or Reflection when you don’t know the class at compile time but need to load it at runtime.
Example: Class.forName(“com.example.MyClass”);
6. What is Autoboxing and Unboxing?
- Autoboxing: The automatic conversion between primitive types and their corresponding wrapper classes. For example, an int is automatically converted to an Integer when needed.
java
Copy
Integer num = 10; // Autoboxing from int to Integer
- Unboxing: The reverse of autoboxing, where an object of a wrapper class is automatically converted to its corresponding primitive type.
java
Copy
int num = new Integer(10); // Unboxing from Integer to int
7. What’s the difference between an Enumeration and an Iterator?
- Enumeration: It is an older interface for iterating over collections, primarily used with legacy classes like Vector and Hashtable. It has methods like hasMoreElements() and nextElement().
- Iterator: A more modern interface introduced in the Java Collections Framework. It is used to iterate over most collections. It has methods like hasNext(), next(), and remove(). It also allows you to remove elements during iteration, which Enumeration does not support.
8. What is the difference between fail-fast and fail-safe in Java?
- Fail-fast: A collection or iterator that immediately throws a ConcurrentModificationException if the collection is modified during iteration (e.g., in the case of ArrayList or HashMap iterators).
- Fail-safe: A collection or iterator that doesn’t throw an exception if the collection is modified during iteration. Instead, it operates on a copy of the collection. Examples include collections in java.util.concurrent (e.g., CopyOnWriteArrayList).
9. What is PermGen in Java?
- PermGen (Permanent Generation) was a part of the Java heap memory in earlier versions (Java 7 and before). It was used to store metadata like class definitions, method definitions, and static content. Since Java 8, PermGen has been replaced by Metaspace, which is not part of the heap and is managed separately by the native memory system.
10. What is a Java PriorityQueue?
- A PriorityQueue is a collection that stores elements in a sorted order, where the element with the highest or lowest priority is always at the front. Elements are ordered based on their natural ordering or by a custom comparator. It is often used when you need to process elements in order of priority (e.g., a scheduling system).
11. Is performance influenced by using the same number in different types: int, double, and float?
- Yes, the performance can be affected due to the differences in how each type is stored and processed:
- int: A 32-bit integer is processed faster than double or float because it uses less memory and is easier for the processor to handle.
- float: A 32-bit floating-point number, requiring more processing than an int but less than a double.
- double: A 64-bit floating-point number that requires more memory and more processing power than int and float.
- So, using the correct type for the required precision is essential for optimizing performance.
12. What is the Java Heap?
The heap in Java is a runtime memory area used for dynamic memory allocation. It is where all class instances (objects) and arrays are stored. Memory management in the heap is handled by the garbage collector, which automatically reclaims memory that is no longer in use.
13. What is a Daemon thread?
A daemon thread is a thread that runs in the background and is used for tasks like garbage collection or background processing. The JVM will exit when all non-daemon threads have finished, even if daemon threads are still running. Daemon threads can be created using Thread.setDaemon(true) before starting the thread.
14. Can a dead thread be restarted?
- No, once a thread has completed its execution (i.e., a “dead” thread), it cannot be restarted. You would need to create a new thread and start it again if you want to perform the same task.