BackendBench
Coffee
Archive

All Java bug puzzles

132 short Java snippets, each with one real bug, the explanation and the fix. Grouped by the kind of mistake. Want to play without spoilers? Try today's puzzle.

Off-by-one errors (6)

Loop bounds, indexes and lengths are the oldest source of bugs in programming. Java arrays and lists are zero-based, so the last valid index is length minus one, and ranges such as substring use an inclusive start and an exclusive end.

Equality and identity (6)

In Java == compares primitive values but only compares references for objects. Strings, boxed numbers and enums behave differently, and a class that overrides equals without hashCode quietly breaks every hash-based collection.

Numeric overflow and precision (6)

Java integers wrap around silently when they exceed their range, with no exception. int and long arithmetic, integer division and implicit narrowing casts all produce wrong numbers that look plausible.

Modifying while iterating (6)

Collections detect structural changes made during iteration and throw ConcurrentModificationException, but only some of the time, and not at all for certain patterns. Removing in a loop is a classic way to skip elements or crash.

Resource leaks (6)

Files, streams, sockets, connections and statements hold operating system handles that the garbage collector will not release promptly. A leak often shows up only in production after hours of load as too many open files or an exhausted connection pool.

Shared and static mutable state (6)

Static fields and singleton beans are shared by every request and thread. Mutable state kept there leaks data between users, makes tests order-dependent and creates race conditions that appear only under load.

Exception handling mistakes (6)

Swallowed exceptions, lost causes and returns in finally blocks hide failures until the data is already wrong. The program keeps running and nobody knows why the result is missing.

Scheduling and cron mistakes (6)

Cron dialects differ in field count and meaning. Spring has six fields starting with seconds, Unix has five, Quartz needs a question mark in one day field, and time zones decide when midnight actually is.

SQL and JDBC mistakes (6)

Building SQL by string concatenation invites injection, and a handful of subtle JDBC habits leak connections, load too much data or commit half a change.

Threading and race conditions (6)

Without synchronization, threads can see stale values and interleave read-modify-write sequences. A volatile field gives visibility but not atomicity, and check-then-act sequences are never atomic by themselves.

Null handling (6)

NullPointerException is still the most common production exception. Chained calls, auto-unboxing, maps that return null for missing keys and Optional used the wrong way all hide a null until the worst moment.

Floating point and money (6)

Binary floating point cannot represent most decimal fractions exactly, so equality checks and money calculations with double drift. BigDecimal needs its own care: construct it from strings and always give a scale and rounding mode.

Dates, time zones and DST (6)

Local dates and times hide the zone they belong to. Daylight saving changes the length of a day, a month has varying lengths and the week-year differs from the calendar year around New Year.

Streams and lambdas (6)

Streams are single-use and lazy, and lambdas can only capture effectively final variables. Side effects inside stream pipelines and parallel streams over shared state are frequent sources of surprise.

JPA and Hibernate pitfalls (6)

The persistence context, lazy loading and entity equality rules create bugs that look fine in a unit test and break once there is a real session, a real transaction or real data volume.

Spring pitfalls (6)

Spring features such as @Transactional, @Async and @Cacheable work through proxies. Calls that bypass the proxy, wrong bean scopes and misplaced annotations make behavior silently disappear.

Collections contracts (6)

Collection classes come with contracts about ordering, mutability and key behavior. Fixed-size lists, views of other collections and mutable map keys break those contracts without compile errors.

String handling (6)

Strings are immutable, split and replaceAll take regular expressions, and character encodings default to whatever the platform says. Small misunderstandings produce wrong output rather than errors.

Boxing and generics (6)

Autoboxing, overload resolution and generics erasure change what a line of code means. The Integer cache, List.remove(int) versus remove(Object) and raw types all behave in ways that surprise careful readers.

Security mistakes (6)

Predictable random numbers, secrets in source code, unvalidated file paths and weak hashes turn working features into vulnerabilities. They pass every functional test.

Messaging and Kafka mistakes (6)

Message handling combines retries, offsets and transactions, and the order of those steps decides whether a failure loses data or processes it twice.

Logic and control flow (6)

Operator precedence, missing break statements, short-circuit evaluation and loop conditions that never change are simple to write and tiring to spot after a long day of reviews.