Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Core Java and Android Interview Concepts for Senior Developers

Tech 1

Data Types and Access Control

Java distinguishes between primitive and reference data types. Primitives include byte (8-bit), short (16-bit), int (32-bit), long (64-bit), float (32-bit), double (64-bit), char (16-bit), and boolean. Reference types encompass classes, interfaces, arrays, enumerations, and annotations.

Access control modifiers dictate visibility scope. Ranked from most restrictive to least, they are private (class level), default (package level), protected (subclass level), and public (universal access).

String comparison requires distinguishing between object reference equality and content equality. The == operator checks if two references point to the same memory address. The equals() method compares the actual character sequence content. For instance:

String s1 = new String("text");
String s2 = "text";
// s1 == s2 is false (different objects)
// s1.equals(s2) is true (same content)

Static methods belong to the class definition rather than an instance. While a subclass can inherit a static method from a parent, it cannot override it in the polymorphic sense; defining a method with the same signature in the subclass merely hides the parent's version.

Abstraction and Interfaces

An abstract class serves as a blueprint when a complete implementation cannot be defined. It may contain abstract methods (declared without a body) and concrete methods. Abstract classes cannot be instantiated directly and must be subclassed, with all abstract methods implemented by the child. They cannot be final, private, or static.

Interfaces define a contract of behavior. All fields in an interface are implicitly public, static, and final, while methods are public and abstract by default. Like abstract classes, interfaces cannot be instantiated.

The key differences between abstract classes and interfaces are:

  1. State: Abstract classes can maintain state (member variables); interfaces can only hold constants.
  2. Inheritance: A class can extend only one abstract class but implement multiple interfaces.
  3. Implementation: Abstract classes provide a partial implementation that subclasses can use; interfaces require the implementing class to provide the full logic.

Polymorphism

Polymorphism manifests primarily through method overloading and overriding. Overriding occurs when a subclass provides a specific implementation for a method already defined in its superclass. This determines runtime behavior based on the actual object type. Overloading happens within a single class, defining multiple methods with the same name but different parameter lists.

class Parent {
    void show() { System.out.println("Parent"); }
}
class Child extends Parent {
    @Override
    void show() { System.out.println("Child"); }
}

Object Initialization

The execution Person p = new Person(); triggers the following sequence:

  1. The Person class bytecode is loaded into the method area.
  2. Memory is allocated in the stack for the reference variable p.
  3. Memory is allocated in the heap for the Person object.
  4. Instance variables are initialized to default values, then explicit initializers and constructors run.
  5. The memory address of the heap object is assigned to the stack variable p.

String Handling

The String class is immutable; operations that appear to modify a string actually return a new object. In contrast, StringBuilder and StringBuffer represent mutable sequences of characters.

  • StringBuffer: Synchronized, thread-safe, but slightly slower due to locking overhead.
  • StringBuilder: Not synchronized, faster, and preferred for single-threaded scenarios.

Collections: Lists

ArrayList, Vector, and LinkedList serve different purposes.

  • ArrayList: Implements a resizable array. Offers fast random access ($O(1)$) but slower insertions/deletions ($O(n)$) due to shifting elements. It is not thread-safe. When capacity is reached, it grows by approximately 50%.
  • Vector: Similar to ArrayList but synchronized (thread-safe) and thus slower. It doubles in size when resizing. Generally, ArrayList is preferred over Vector.
  • LinkedList: Implements a doubly-linked list. Offers fast insertions and deletions ($O(1)$ at ends) but slower random access ($O(n)$) as it must traverse nodes. It is not thread-safe.

SparseArray and ArrayMap

In Android, HashMap can be inefficient due to object overhead. Alternatives include:

  • SparseArray: A map optimized for int keys. It avoids auto-boxing of integers, saving memory and garbage collection overhead. It stores keys and values in parallel arrays and uses binary search for lookups ($O(\log n)$). It is best for collections with fewer than 1,000 items.
  • ArrayMap: A general-purpose map implementation designed for memory efficiency. It manages two arrays (one for hash codes, one for keys/values) and keeps them sorted. Like SparseArray, it uses binary search and is suitable for smaller datasets.

Map Implementations

HashMap vs HashTable:

  • Thread Safety: HashMap is unsynchronized; HashTable is synchronized.
  • Nulls: HashMap permits one null key and multiple null values; HashTable does not.
  • Performance: HashMap is generally faster due to the lack of synchronization.
  • Iteration: HashMap iterators are fail-fast; HashTable enumerators are not.

LinkedHashMap extends HashMap, maintaining a doubly-linked list running through all entries. This preserves insertion order (or access order if configured), unlike the unordered HashMap.

HashMap Internal Mechanics (JDK 8+)

  1. Structure: Uses an array of buckets (Node<K,V>), where each bucket is a linked list. If a list exceeds 8 elements (and the table size is >= 64), it transforms into a Red-Black tree for $O(\log n)$ lookup performance.
  2. Collision Resolution: Uses separate chaining with treeification for performence.
  3. Resizing: When the load factor (default 0.75) is exceeded, the capacity doubles. Unlike JDK 7, JDK 8 uses tail insertion during resize to prevent infinite loops in multi-threaded environments.
  4. Power of Two Size: Capacity is always a power of two. This allows the use of bitwise AND (hash & (n-1)) instead of modulo operation for index calculation, which is computationally efficient.

ConcurrentHashMap

JDK 7: Uses "segmants" (ReentrantLock locks) where each segment covers a portion of the hash table, allowing concurrent reads.

JDK 8: Abandons segments. Uses CAS (Compare-And-Swap) operations for insertion and synchronized blocks only on the specific bucket head (node) during updates. The data structure is similar to HashMap (Array + Linked List + Red-Black Tree). This reduces lock contention and improves performance.

Reflection

Reflection allows runtime inspection of classes, interfaces, fields, and methods.

Obtaining Class Objects:

  1. obj.getClass()
  2. ClassName.class
  3. Class.forName("com.example.MyClass")

Creating Objects:

Class<?> clazz = Class.forName("com.example.Person");
// Using no-arg constructor
Object instance = clazz.getDeclaredConstructor().newInstance();

Threading and Concurrency

Thread Creation

  1. Extending Thread: class MyThread extends Thread { public void run() { ... } }
  2. Implementing Runnable: class MyTask implements Runnable { public void run() { ... } }

Wait vs Sleep

  • wait(): Releases the object lock. Belongs to Object. Must be called within a synchronized context.
  • sleep(): Does not release the lock. Belongs to Thread. Can be called anywhere.

Concurrency Concepts

  • Atomicity: Operations appear indivisible.
  • Visibility: Changes to variables are seen by other threads.
  • Ordering: Instructions execute in the order expected by the code.

volatile ensures visibility and ordering but not atomicity. synchronized ensures all three.

Network Programming

HTTP Versions

  • HTTP/1.0: Short-lived connections; a new TCP connection is needed for each resource.
  • HTTP/1.1: Persistent connections (Keep-Alive) by default; pipelining allows sending multiple requests without waiting for responses; chunked transfer encoding.
  • HTTP/2.0: Multiplexing (multiple requests over a single TCP connection), header compression (HPACK), and server push.

HTTPS

HTTPS (HTTP Secure) uses TLS/SSL for encryption. It combines HTTP with cryptography to ensure data integrity and confidentiality. It typically runs on port 443 (vs 80 for HTTP).

Handshake Process:

  1. Client sends ClientHello.
  2. Server responds with ServerHello and its digital certificate (containing the public key).
  3. Client verifies the certificate.
  4. Client generates a pre-master secret, encrypts it with the server's public key, and sends it.
  5. Server decrypts the pre-master secret with its private key.
  6. Both parties generate the session key (symmetric key) from the pre-master secret.
  7. Subsequent data is encrypted using this symmetric key for performance.

Android Specifics

Data Storage

  1. Internal Storage: Private to the app.
  2. External Storage: Public or private media/files.
  3. SharedPreferences: Stores key-value pairs in XML files.
    • commit(): Synchronous, returns boolean.
    • apply(): Asynchronous, no return value (preferred for UI thread).
  4. SQLite: Relational database.
  5. ContentProvider: Manages access to a structured set of data, enabling inter-app data sharing.

Reference Types

  • Strong Reference: Default, prevents garbage collection.
  • SoftReference: Cleared when memory is low.
  • WeakReference: Cleared aggressively on GC cycles.
  • PhantomReference: Cleared after finalization.

Activity Lifecycle

Launch Modes:

  • standard: Default. New instance created for every launch.
  • singleTop: Reuses instance if it's at the top of the stack.
  • singleTask: Reuses instance; clears other activities on top of it in the stack.
  • singleInstance: Runs in its own unique task stack.

View Rendering

The rendering pipeline involves three steps:

  1. Measure: onMeasure() determines dimensions.
  2. Layout: onLayout() positions children.
  3. Draw: onDraw() renders content.

requestLayout() triggers measure and layout. invalidate() triggers draw.

Animation

  • View Animation: Tweens (alpha, scale, translate, rotate). Only alters visual drawing, not properties. View location doesn't actually change.
  • Property Animation: Changes actual object properties (e.g., translationX). Works on any object (not just Views).

View Event Handling

Events flow in the order: dispatchTouchEvent -> onInterceptTouchEvent (ViewGroup only) -> onTouchEvent. requestDisallowInterceptTouchEvent(true) prevents parent ViewGroup from intercepting events.

IPC (Inter-Process Communication)

  1. AIDL (Android Interface Definition Language): Defines interfaces for clients and services to communicate using Binder IPC. Supports complex data types.
  2. Messenger: Handles messages via a Handler. Simpler than AIDL but supports one-way requests (mostly). Good for low-concurrency commands.
  3. ContentProvider: Exposes data across processes using a URI-based model.
  4. Binder: The underlying kernel driver for IPC. It is efficient (one memory copy), secure (UID-based checking), and stable.

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.