- 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.
- 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.
- Use array for fast access or fixed-size collections.
- Use linked list for dynamic collections or frequent insertions/deletions.
A data structure that maps keys to values using a hash function.
- Chaining: Use linked lists to store multiple values at the same index.
- 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;
}
}
- LIFO: Last In, First Out.
- Operations:
push(),pop(),peek().
- FIFO: First In, First Out.
- Operations:
enqueue(),dequeue().
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];
}
}
- 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.
- A collection of nodes (vertices) and edges.
- DFS: Depth-First Search.
- BFS: Breadth-First Search.
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);
}
}
}
void dfs(Node root) {
if (root == null) return;
System.out.print(root.value + " ");
dfs(root.left);
dfs(root.right);
}
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);
}
}
- 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.
- 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 |
- Connection-Oriented: Establishes a connection before data transfer.
- Reliable: Ensures data delivery and retransmits lost packets.
- Slower: Due to overhead from error checking and acknowledgment.
- Use Case: Email (SMTP), File Transfer (FTP), Web Browsing (HTTP/HTTPS).
- Connectionless: No handshake or connection establishment.
- Unreliable: No guarantee of data delivery or order.
- Faster: Minimal overhead.
- Use Case: Video Streaming, Online Gaming, Voice Calls.
The Open Systems Interconnection (OSI) model standardizes network communication into seven layers.
- Physical Layer: Transmits raw binary data over physical mediums.
- Data Link Layer: Manages error detection/correction and frames.
- Network Layer: Handles routing and addressing (IP addresses).
- Transport Layer: Ensures reliable data transfer (TCP/UDP).
- Session Layer: Manages sessions and connections.
- Presentation Layer: Ensures data translation, encryption, and compression.
- Application Layer: Provides network services to applications (HTTP, FTP).
DNS translates human-readable domain names (e.g., www.google.com) into IP addresses.
- Query Initiation: User types a domain in the browser.
- Recursive Query: DNS resolver contacts other DNS servers.
- Name Resolution: DNS root, TLD, and authoritative name servers work together to return the IP address.
- Response: Browser uses the IP to establish a connection with the server.
- Insecure: Data is transferred in plain text.
- No Encryption: Susceptible to interception.
- Use Case: General information transfer where security is not critical.
- Secure: Encrypts data using SSL/TLS.
- Authentication: Ensures server identity with certificates.
- Use Case: E-commerce, banking, and any sensitive data transfer.
A firewall is a security system that monitors and controls incoming and outgoing network traffic based on predefined security rules.
- Packet Filtering: Inspects packets and allows or blocks based on rules.
- Stateful Inspection: Tracks active connections and determines packet validity.
- Proxy Firewall: Intercepts traffic and validates requests before forwarding.
- Hardware Firewall: Dedicated devices (e.g., routers with built-in firewalls).
- Software Firewall: Installed on individual systems (e.g., Windows Firewall).
- Cloud Firewall: Protects cloud infrastructure.
- Allowing HTTP/HTTPS traffic: Rules to allow only web traffic on ports 80 (HTTP) and 443 (HTTPS).
- Blocking unauthorized access: Deny all incoming requests except those explicitly allowed.
- 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.
- 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.
- Use array for fast access or fixed-size collections.
- Use linked list for dynamic collections or frequent insertions/deletions.
A data structure that maps keys to values using a hash function.
- Chaining: Use linked lists to store multiple values at the same index.
- 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;
}
}
- LIFO: Last In, First Out.
- Operations:
push(),pop(),peek().
- FIFO: First In, First Out.
- Operations:
enqueue(),dequeue().
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];
}
}
- 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.
- A collection of nodes (vertices) and edges.
- DFS: Depth-First Search.
- BFS: Breadth-First Search.
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);
}
}
}
void dfs(Node root) {
if (root == null) return;
System.out.print(root.value + " ");
dfs(root.left);
dfs(root.right);
}
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);
}
}
- 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.
- 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 |