The recurring patterns that separate developers who guess from developers who reason. Learn them once, spot them everywhere.
When scanning arrays or strings for pairs, sums, or palindromes, move two pointers from opposite ends instead of nesting loops. Turns O(n²) brute force into O(n).
For 'longest/shortest subarray matching X' problems, expand a window forward and shrink it from behind instead of recalculating from scratch every time.
Before writing the recursive call, write down exactly when the function should stop. If you can't state the base case in one line, you're not ready to write the recursion yet.
Instead of a pile of booleans (isLoading, isError, isSuccess all fighting each other), model your component as one 'state' variable with defined transitions. Bugs disappear.
If a function returns the same output for the same input, store the result. Applies to recursive algorithms, API calls, and even expensive frontend re-renders.
Before optimizing anything, ask: is this loop inside another loop? Is this running per-request or once at startup? Most 'slow code' is just an accidental nested loop.