Java
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Object-Oriented Java
-
Section 4: Collections Framework
-
Section 5: Exception Handling
-
Section 6: Generics
-
Section 7: Functional Java
-
Section 8: Concurrency
-
Section 9: I/O and NIO
-
Section 10: JVM Internals
-
Section 11: Modern Java Features
-
Section 12: Build Tools and Project Structure
-
Section 13: Testing
-
Section 14: Databases and Persistence
-
Section 15: Networking
-
Section 16: Design and Best Practices
-
Section 17: Reflection and Annotations
-
Section 18: Logging and Diagnostics
-
Section 19: Date, Time, and Internationalization
-
Section 20: Java Platform Module System
-
Section 21: Security in Java
-
Section 22: Advanced Collections and Data Structures
-
Section 23: More Concurrency Patterns
-
Section 24: Compression, Files, and System Integration
-
Section 25: GUI Programming
-
Section 26: Practical Projects
-
Section 27: Data Structures and Algorithms
-
Section 28: Interview and Algorithm Practice
-
Section 29: JSON and Data Interchange
-
Section 30: More Concurrency Utilities
-
Section 31: More Collections and Streams Practice
-
Section 32: More File and System Programming
-
Section 33: Standard Library Deep Dive
-
Section 34: More Practice and Drills
-
Section 35: More Testing and Quality
-
Section 36: More Design Patterns and Architecture
-
Section 37: Career and Ecosystem
-
Section 38: More OOP and Architecture Practice
-
Section 39: More Enterprise Concepts
-
Section 40: Advanced JavaFX
-
Section 41: More Interview Practice
252: Mock Coding Interview Walkthrough in Java
When I conduct mock interviews, the most common mistake I see isn't a lack of knowledge—it's "coding in a vacuum." A candidate will dive straight into the IDE, write a solution that works for the basic test case, and then completely freeze when the interviewer asks, "What happens if the input is an empty string?" or "Why did you choose a HashMap over an array here?"
Let's look at a piece of code a student of mine wrote recently. We were tackling the "Longest Substring Without Repeating Characters" problem. On the surface, it looks solid, but it has a subtle bug that would likely get them flagged in a real interview.
public int lengthOfLongestSubstring(String s) {
int n = s.length();
int maxLength = 0;
Map<Character, Integer> map = new HashMap<>();
for (int right = 0, left = 0; right < n; right++) {
char current = s.charAt(right);
if (map.containsKey(current)) {
// The bug is right here
left = map.get(current);
}
map.put(current, right);
maxLength = Math.max(maxLength, right - left + 1);
}
return maxLength;
}
The "Backwards Jump" Bug
If you run this with the string "abcabcbb", it actually works. But try it with "abba". When the loop hits the second 'a' at index 3, it looks at the map and sees the first 'a' was at index 0. It sets left = 0. However, the left pointer had already moved to index 2 because of the double 'b'.
By jumping left back to 0, the code suddenly thinks the substring is "abba", which is obviously wrong. You've essentially allowed your sliding window to expand backward, capturing characters that were already supposed to be excluded. I always tell my students: your window boundaries should only ever move in one direction. If you're moving a "left" pointer, it should only ever go right.
Stabilizing the Sliding Window
To fix this, we need to ensure that left never moves backward. We also need to move left to the position after the last occurrence of the duplicate character, not exactly onto it. Here is how we clean that up:
public int lengthOfLongestSubstring(String s) {
int n = s.length();
int maxLength = 0;
Map<Character, Integer> map = new HashMap<>();
for (int right = 0, left = 0; right < n; right++) {
char current = s.charAt(right);
if (map.containsKey(current)) {
// Fix: Use Math.max to prevent jumping backward
// and add 1 to skip the duplicate character.
left = Math.max(left, map.get(current) + 1);
}
map.put(current, right);
maxLength = Math.max(maxLength, right - left + 1);
}
return maxLength;
}
Now, when we hit that second 'a' in "abba", map.get('a') + 1 is 1, but left is already 2. Math.max(2, 1) keeps us at 2. The logic holds, and the window remains valid.
Communicating Your Trade-offs
In a real interview, writing the code is only 50% of the grade. The other 50% is the dialogue. If I were interviewing you, I'd be looking for you to mention the space-time complexity without me prompting you. For this solution, you'd say: "The time complexity is O(n) because we traverse the string once, and the space complexity is O(min(m, n)) where m is the size of the alphabet."
I'd also be impressed if you questioned the constraints. Ask, "Is the input limited to ASCII characters?" If the answer is yes, you can replace the HashMap with a simple int[128] array. An array is significantly faster and uses less memory than a HashMap in Java because it avoids the overhead of object wrapping (Integer) and hashing collisions. Mentioning that optimization shows you aren't just memorizing LeetCode patterns—you actually understand how Java manages memory.
📋 Practical Task
Implement a Group Anagrams Logic with Array-Based Keys
You are asked to implement a method that takes an array of strings and groups anagrams together. To avoid the overhead of sorting every string (which would be O(n * k log k)), you should use a frequency array to generate a unique key for each group.
Your task: Complete the groupAnagrams method. Instead of sorting the string, create a key by counting the occurrences of each character (a-z) and formatting it as a string (e.g., "1#0#2#..." meaning one 'a', zero 'b's, two 'c's). Use a HashMap<String, List<String>> to collect the groups.
import java.util.*;
public class AnagramGrouper {
public List<List<String>> groupAnagrams(String[] strs) {
if (strs == null || strs.length == 0) return new ArrayList<>();
Map<String, List<String>> map = new HashMap<>();
for (String s : strs) {
// TODO: Create a frequency array for 'a'-'z'
// TODO: Convert that array into a unique String key
// TODO: Add the string to the corresponding list in the map
}
return new ArrayList<(map.values());
}
public static void main(String[] args) {
AnagramGrouper grouper = new AnagramGrouper();
String[] input = {"eat", "tea", "tan", "ate", "nat", "bat"};
System.out.println(grouper.groupAnagrams(input));
// Expected output: [[eat, tea, ate], [tan, nat], [bat]]
}
}There are no comments for now.