- Pros and Cons: when I have too many answers, I try to make it objective by drawing up the pros and cons and seeing where that takes me.
- Simplify: like a lot of developers, I can be prone to over-analyse when I am stuck on an issue for a while. So I remind myself to try simplifying the problem. Often by dropping a layer of flexibility the problem is a lot easier to solve. If I really need the flexibility, I can add it later when I have greater understanding.
- Take a Break: sometimes I’m just trying too hard, and need to step back. I work from home, so a short walk outside is a welcome break. Actually getting away from the computer relaxes the grey matter. The vitamin D doesn’t hurt either.
- Explain the Problem: very often I find that while I’m explaining the problem, I see it in a different way. If not, the input of another person usually throws a different perspective on the issue. If there’s nobody to bother immediately, just writing down an explanation can help.
- Switch Gears: this works when I’m getting frustrated by a lack of progress. By switching to a small, unrelated task, I can Get Something Done and develop some new momentum. This also serves as a break from the original problem.
- Write Some Tests: I don’t practice TDD all the time, but when I’m stuck trying to understand how things work, writing some tests first can be very illuminating. Having tests in place also gives gratifying feedback as I finally start to crack the underlying problem. I find this works best for really tough technical issues, where good test coverage is even more important than normal.
- Write Some Code: if I have a partial solution, even if I know it is ugly or inadequate, sometimes I’ll just plow ahead anyway. Actually working through a throwaway implementation is better than standing still, as it turns up all the little details. I’m happy to throw that code away since I know the alternative was not getting anywhere.
Really tricky ones - write off a day to 'troubleshooting' and try out some radically different ideas including ones you may have rejected earlier, hacking or scribbling down the bare minimum to see if it makes sense. Often they won't, but every now and again your struggles will have led you in the meantime to some new insight which allows you to escape the 'local minimum'.
Still no luck? Decompose the problem into smaller pieces and put them under the microscope one at a time.
Abstractions like this can often give you a new perspective on a tricky problem. http://www.graphpad.com/curvefit/local_minimum.htm
Taking a break to clear one's head can help a lot. I also found that postponing the problem, and doing something completely unrelated allows my subconciousness to dream up an idea.
If the situation permits, seeking help from fellow team members (possibly combined with one or more of the above) should also be a routine.
There's also the sitting down, rephrasing the problem, the current status - preferably to someone who has no clue about it, but can listen well. A plush toy works wonders: by systematically going over the whole thing, to an audience who doesn't have a clue, one might just see the problem from a different angle, which in turn has a good chance of giving one a new good idea.
Another thing I have learnt to do and found to be very helpful - surround myself with a lot of good and relevant books.
Around 70% of my programming solutions, I get from the net, the other 30% from books. Quite often (at least for me), the books also help me to figure out what to ask on the net.
These, just in addition to the other very good suggestions in the comments.