Oracle Java Lead - DSA & System Design
1. LRU Cache (O(1) Operations)
class LRUCache {
class Node {
int key, value;
Node prev, next;
Node(int k, int v) { key = k; value = v; }
}
private final int capacity;
private final Map<Integer, Node> map;
private final Node head, tail;
public LRUCache(int capacity) {
this.capacity = capacity;
map = new HashMap<>();
head = new Node(0, 0); tail = new Node(0, 0);
head.next = tail; tail.prev = head;
}
public int get(int key) {
if (!map.containsKey(key)) return -1;
Node node = map.get(key);
remove(node); insertToHead(node);
return node.value;
}
public void put(int key, int value) {
if (map.containsKey(key)) remove(map.get(key));
if (map.size() == capacity) remove(tail.prev);
Node node = new Node(key, value);
insertToHead(node); map.put(key, node);
}
private void remove(Node node) {
map.remove(node.key);
node.prev.next = node.next;
node.next.prev = node.prev;
}
private void insertToHead(Node node) {
node.next = head.next;
node.prev = head;
head.next.prev = node;
head.next = node;
}
}
Oracle Java Lead - DSA & System Design
2. Producer-Consumer (wait/notify)
class SharedBuffer {
private final Queue<Integer> buffer = new LinkedList<>();
private final int capacity = 5;
public synchronized void produce(int value) throws InterruptedException {
while (buffer.size() == capacity)
wait();
buffer.add(value);
System.out.println("Produced: " + value);
notifyAll();
}
public synchronized void consume() throws InterruptedException {
while (buffer.isEmpty())
wait();
int val = buffer.poll();
System.out.println("Consumed: " + val);
notifyAll();
}
}
3. Top K Frequent Elements
public int[] topKFrequent(int[] nums, int k) {
Map<Integer, Integer> freqMap = new HashMap<>();
for (int num : nums)
freqMap.put(num, freqMap.getOrDefault(num, 0) + 1);
PriorityQueue<Integer> heap = new PriorityQueue<>(
Comparator.comparingInt(freqMap::get)
);
for (int num : freqMap.keySet()) {
heap.add(num);
if (heap.size() > k) heap.poll();
}
int[] result = new int[k];
for (int i = k - 1; i >= 0; i--)
result[i] = heap.poll();
return result;
}
4. File Tree Fetch in Java
Oracle Java Lead - DSA & System Design
class FileNode {
String name;
boolean isDirectory;
List<FileNode> children;
public FileNode(String name, boolean isDirectory) {
this.name = name;
this.isDirectory = isDirectory;
if (isDirectory) {
children = new ArrayList<>();
}
}
public void addChild(FileNode child) {
if (isDirectory) {
children.add(child);
}
}
}
public class FileTreeBuilder {
public static FileNode buildTree(File file) {
FileNode node = new FileNode(file.getName(), file.isDirectory());
if (file.isDirectory()) {
File[] files = file.listFiles();
if (files != null) {
for (File f : files) {
node.addChild(buildTree(f));
}
}
}
return node;
}
public static void printTree(FileNode node, String indent) {
System.out.println(indent + (node.isDirectory ? "[D] " : "[F] ") + node.name);
if (node.isDirectory) {
for (FileNode child : node.children) {
printTree(child, indent + " ");
}
}
}
public static void main(String[] args) {
File root = new File("path/to/your/folder");
FileNode rootNode = buildTree(root);
printTree(rootNode, "");
}
}
Oracle Java Lead - DSA & System Design
5. System Design: URL Shortener
Requirements:
- Input: Long URL, Output: Short URL
- Redirect short URL to original
- Analytics on usage
Components:
- API Gateway
- URL Encoding Service
- Database (NoSQL like Cassandra or Redis)
- Cache Layer for fast redirects
- Analytics Queue (Kafka) -> Analytics Processor
Tech Stack:
- Java Spring Boot, Redis, Cassandra, Kafka, Nginx
Design Considerations:
- Use base62 encoding for shortening
- Rate limiting for API
- Consistent hashing or Snowflake ID for unique IDs
6. Java Microservice Architecture Patterns
Common Patterns:
1. API Gateway Pattern
- Handles routing, authentication, rate limiting
- Tech: Spring Cloud Gateway or Zuul
2. Circuit Breaker Pattern
- Prevents cascading failures
- Tech: Resilience4j, Hystrix
3. Saga Pattern
- Distributed transaction management
- Tech: Orchestration (Camunda) or Choreography (events)
4. Strangler Fig Pattern
- Gradual migration of monolith to microservices
Best Practices:
- Use DTOs to isolate layers
- Version your APIs
- Centralized config management (Spring Cloud Config)