If the senior developers around you are worthy of that title, they've reached that point by making more mistakes than you have - and learning from them. Here are some techniques I use to learn from mistakes:<p>Double-checking. To take an example: say you take the integral of `sin x` and get `cos x` instead of `-cos x`. You can double-check this by differentiating `cos x`, which will give you `-sin x`. Not only does this tell you you're slightly off, it suggests exactly how to fix the problem. Many problems can be double-checked: you get a result, then run the steps backwards to see if you can get back to the starting point.<p>Incremental testing. I've recently been learning basic robotics / electronics as part of a side job. One thing I found enormously helpful was to build up progressively larger circuits on a breadboard - I'd even test the breadboard itself (e.g. do the two halves of each row connect? Well, there's an easy way to find out...) to make sure I had the correct mental model of how my components were working.<p>Isolation. When confronted with a problem, try to find the minimal example that reproduces the problem. I do this a lot when building out interfaces / applications, where I need to add some non-trivial piece into a larger application. I'll build a test page that contains just that piece, get it working, then figure out how to integrate that working example with the application as a whole. As a side benefit, I've broken my seemingly hard problem down into two smaller, easier problems.<p>Informed questioning. You will inevitably hit something beyond your level of expertise. Half of experience is learning when to identify that this has happened, and knowing how to coherently explain your mental model of the problem. Your mental model doesn't have to be right, but it should exist, and you should know how to describe it to someone who can pick it apart and improve it. Part of this is a sort of "egolessness" mindset: having the humility to admit you don't understand everything, and to seek expert help once you've tried what you can. (We're all bad at this last step, myself included; developing this mindset is itself a learning process.)<p>Finally, and IMHO most importantly: failure normalization. Failure is normal when learning a new tool, framework, language, skillset, etc. In this situation, one of the first things I do is to explore what failure looks like. I'll deliberately introduce syntax / logic errors: what sorts of errors does the compiler / toolchain spit out? How can I use the debugger to step into the problem, and what does that process look like? Do my tools give me any kind of visual / tactile / etc. feedback on my error? (If not: where can I find better tools?)