Mike J / Retrospective 2019: Coding Interviews

Created Sat, 16 May 2026 12:00:00 -0400 Modified Sat, 06 Jun 2026 08:27:36 -0400

I’ve interviewed with Google, Apple, Amazon, MongoDB, Capital One, and countless others. Every one of them put me through a coding interview, with wildly varying degrees of difficulty. I could say a lot more about that — but it’s the kind of topic that almost demands feedback and pushback, so you can leave your opinion or ask for mine in the comments below.

The languages varied as much as the difficulty did. I once had an interview where every line had to be delivered in Python — and another where I was offered the choice of literally any language, except Python.

A Little History

I’m genuinely happy to be working in an era where remote work for software engineers is normalized. Mind you, this isn’t new to me. I worked remotely, full-time, as far back as 2004–2005 — for Sun Microsystems. Sun was a company ahead of its time in some ways, and out of time in others (LOL). It was eventually acquired by Oracle, and a lot of what made it special got absorbed and rearranged.

There’s no shortage of interview prep material online these days. In my time, I leaned on Cracking the Coding Interview by Gayle Laakmann McDowell — the book this whole repository is named after. Its companion site, HackerRank, is a lot of fun. I’m not a competitive-coding person, but I enjoy taking a swing at the challenges there now and then.

Back in 2019 I was job hunting, and I wanted to be prepared. The exercises below are some of the practice problems I worked through, collected in my Cracking-the-Coding-Interview-in-Java repository. They contain a combination of puzzles, like what you might see in a job interview, and deep dives into complex algorithms using source material - just to get my brain working on following detailed instructions.

One heads-up if you click into the code: the variable names are short and the style is deliberately terse. I wrote these in a whiteboard-coding frame of mind, where spelling out long, descriptive names costs you time you don’t have. It’s not how I write production code — it’s how you write code with a marker in your hand and an interviewer watching the clock.

The Puzzles

Add Without Arithmetic — Add two integers without using + or any arithmetic operator at all — only bitwise logic, propagating the carry one bit at a time across all 32 bits. A classic test of whether you really understand two’s complement.

Unique Characters — Determine whether every character in a string is unique, with the twist that you’re not allowed any additional data structures. The repo solves it recursively in O(n²) to honor that constraint, then adds a bonus O(n) version for when a lookup table is allowed.

Compound Words — Decide whether a word can be assembled entirely from a dictionary of smaller words — “houseboat” from “house” plus “boat”. There are two implementations: a straightforward slow recursion, and a faster one backed by a sorted set.

Word Ladder — Given two equal-length words and a dictionary, transform one into the other one letter at a time, where every intermediate step is itself a real word: DAMP → LAMP → LIMP → LIME → LIKE. It’s a word ladder puzzle, and under the hood it’s a breadth-first search.

Rabin–Karp String Search — Find a pattern inside a larger string using a rolling hash, so most non-matching positions can be rejected with a single cheap comparison instead of a full character-by-character scan. (Rabin–Karp)

Remove Duplicates from a Linked List — Walk an unsorted singly-linked list and splice out repeated values, using a hash set to remember what’s already been seen.

Reverse a Tree’s Siblings — Take a tree stored in child/sibling representation and reverse every sibling list, from the root all the way down. Easy to describe, and genuinely fiddly to get right with pointers.

Select Random — Pick m integers at random from an array of n, with no repeats — a partial Fisher–Yates that does just enough shuffling to fill the result.

Shuffle — Shuffle a deck in place with the full Fisher–Yates algorithm — every ordering equally likely, no bias.

Bomberman — On a 2D grid of walls, badguys, and empty space, find the single spot where dropping a bomb takes out the most badguys. The blast travels down its row and column until a wall stops it. The whole grid is solved in one O(N) sweep.

Minimum Spanning Trees: Kruskal & Prim — Two classic graph algorithms aimed at the same target — finding the minimum spanning tree of a weighted graph. Kruskal’s sorts the edges and leans on a disjoint-set (“union-find”) structure to avoid cycles; Prim’s grows the tree outward from a starting node. The union-find itself is implemented here as weighted quick-union with path compression — an intereting data structure that’s a complex piece of engineering in its own right.

Closing

If any of these bring back your own interview war stories or classroom nostalgia — triumphant or traumatic — let us know in the comments below!