Skip to content

Latest commit

 

History

History
359 lines (281 loc) · 8.61 KB

File metadata and controls

359 lines (281 loc) · 8.61 KB

36. Multithreading

What is Multithreading?

Multithreading is the ability of a CPU to execute multiple threads concurrently. Threads are lightweight processes that share the same memory space.

What are Threads?

Threads are the smallest unit of a process that can be scheduled for execution.

Implementing Threads in Java

class MyThread extends Thread {
    public void run() {
        System.out.println("Thread is running");
    }
}

public class Main {
    public static void main(String[] args) {
        MyThread thread = new MyThread();
        thread.start(); // Starts the thread
    }
}

37. What is a Deadlock?

Deadlock

A deadlock occurs when two or more threads are waiting for each other to release resources, leading to an infinite waiting state.

Deadlock Prevention

  1. Avoid nested locks.
  2. Use a timeout for locks.
  3. Use a deadlock detection mechanism.

Example of Deadlock in Java

class Resource {
    synchronized void methodA(Resource resource) {
        resource.methodB();
    }

    synchronized void methodB() {
        System.out.println("Locked");
    }
}

public class Main {
    public static void main(String[] args) {
        Resource r1 = new Resource();
        Resource r2 = new Resource();

        new Thread(() -> r1.methodA(r2)).start();
        new Thread(() -> r2.methodA(r1)).start();
    }
}

38. Process Synchronization

What is Process Synchronization?

Ensures that multiple processes or threads execute in a coordinated manner to avoid race conditions.

Example: Mutex Using synchronized

class Counter {
    private int count = 0;

    synchronized void increment() {
        count++;
    }

    synchronized int getCount() {
        return count;
    }
}

public class Main {
    public static void main(String[] args) {
        Counter counter = new Counter();
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) counter.increment();
        });
        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) counter.increment();
        });

        t1.start();
        t2.start();
    }
}

Example: Semaphore Using java.util.concurrent.Semaphore

import java.util.concurrent.Semaphore;

class Resource {
    private final Semaphore semaphore = new Semaphore(2);

    void accessResource() {
        try {
            semaphore.acquire();
            System.out.println(Thread.currentThread().getName() + " is accessing the resource.");
            Thread.sleep(1000);
            semaphore.release();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public class Main {
    public static void main(String[] args) {
        Resource resource = new Resource();

        for (int i = 0; i < 5; i++) {
            new Thread(resource::accessResource).start();
        }
    }
}

39. Virtual Memory

What is Virtual Memory?

Virtual memory is a memory management technique that uses disk space as an extension of RAM.

Paging

  • Divides memory into fixed-size blocks called pages.
  • Pages are stored in physical memory or on disk.

Segmentation

  • Divides memory into variable-sized segments based on logical divisions like functions or data structures.

40. System Calls

What are System Calls?

System calls are functions used by applications to interact with the operating system.

Examples in Java

Although Java abstracts system calls, actions like file I/O, threading, and process control internally invoke system calls.

Example of File I/O System Call in Java

import java.io.FileWriter;
import java.io.IOException;

public class Main {
    public static void main(String[] args) {
        try (FileWriter writer = new FileWriter("example.txt")) {
            writer.write("Hello, System Call in Java!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

31. Difference Between an Array and a Linked List

Array

  • Fixed Size: Size is predefined.
  • Contiguous Memory: Data stored in consecutive memory locations.
  • Access Time: O(1) for accessing elements.
  • Insertion/Deletion: O(n) as shifting elements is required.

Linked List

  • Dynamic Size: Grows or shrinks dynamically.
  • Non-Contiguous Memory: Nodes are linked using pointers.
  • Access Time: O(n) for accessing elements.
  • Insertion/Deletion: O(1) if pointer is known.

When to Use?

  • Use array for fast access or fixed-size collections.
  • Use linked list for dynamic collections or frequent insertions/deletions.

32. Hash Table

What is a Hash Table?

A data structure that maps keys to values using a hash function.

Collision Handling Techniques

  1. Chaining: Use linked lists to store multiple values at the same index.
  2. Open Addressing: Find the next available slot using techniques like linear probing.

Example: Chaining

class HashTable {
    private LinkedList[] table;

    public HashTable(int size) {
        table = new LinkedList[size];
    }

    void put(int key, String value) {
        int index = key % table.length;
        if (table[index] == null) table[index] = new LinkedList<>();
        table[index].add(new Entry(key, value));
    }
}

class Entry {
    int key;
    String value;

    Entry(int key, String value) {
        this.key = key;
        this.value = value;
    }
}

33. Difference Between a Stack and a Queue

Stack

  • LIFO: Last In, First Out.
  • Operations: push(), pop(), peek().

Queue

  • FIFO: First In, First Out.
  • Operations: enqueue(), dequeue().

Implement a Stack Using an Array

class Stack {
    private int[] stack;
    private int top;

    public Stack(int size) {
        stack = new int[size];
        top = -1;
    }

    void push(int value) {
        if (top == stack.length - 1) return;
        stack[++top] = value;
    }

    int pop() {
        if (top == -1) return -1;
        return stack[top--];
    }

    int peek() {
        return (top == -1) ? -1 : stack[top];
    }
}

34. Trees and Graphs

Trees

  • A hierarchical data structure.
  • Binary Search Tree (BST): A tree where the left subtree has values less than the root, and the right subtree has values greater.

Graphs

  • A collection of nodes (vertices) and edges.
  • DFS: Depth-First Search.
  • BFS: Breadth-First Search.

Implement a Binary Search Tree (BST)

class Node {
    int value;
    Node left, right;

    Node(int value) {
        this.value = value;
        left = right = null;
    }
}

class BST {
    Node root;

    void insert(int value) {
        root = insertRec(root, value);
    }

    private Node insertRec(Node root, int value) {
        if (root == null) return new Node(value);
        if (value < root.value) root.left = insertRec(root.left, value);
        else root.right = insertRec(root.right, value);
        return root;
    }

    void inorder(Node root) {
        if (root != null) {
            inorder(root.left);
            System.out.print(root.value + " ");
            inorder(root.right);
        }
    }
}

DFS Implementation

void dfs(Node root) {
    if (root == null) return;
    System.out.print(root.value + " ");
    dfs(root.left);
    dfs(root.right);
}

BFS Implementation

void bfs(Node root) {
    Queue queue = new LinkedList<>();
    queue.add(root);

    while (!queue.isEmpty()) {
        Node current = queue.poll();
        System.out.print(current.value + " ");
        if (current.left != null) queue.add(current.left);
        if (current.right != null) queue.add(current.right);
    }
}

35. Difference Between a Heap and a Stack in Memory

Heap

  • Purpose: Stores dynamically allocated objects.
  • Lifespan: Managed by the garbage collector.
  • Access: Slower due to non-contiguous memory and complex management.
  • Examples: Objects, instance variables.

Stack

  • Purpose: Stores method calls and local variables.
  • Lifespan: Automatically deallocated when the method exits.
  • Access: Faster due to LIFO structure.
  • Examples: Primitive types, references to objects.
Aspect Stack Heap
Allocation Static Dynamic
Management Automatically deallocated Managed by garbage collector
Speed Faster Slower
Use Case Method calls, local vars Objects, instance vars