The biggest test of what I've learned about learning was the day I had to learn embedded programming in twenty four hours.

A customer called me at 5 pm. They had a possible six figure hardware sale, but a key aspect of their hardware was too slow, their only embedded software/hardware guy was no longer working there, and they had to have the new code in 24 hours for a demo.

The software component to be sped up was three cores running handwritten assembly, and had been optimized by several people over four years.

The total of my embedded software experience was fooling around with an Arduino. I'd never written assembler before and never see this processor or its family before.

This was going to be good.

I wrote down the problem, and did the math to find out what the solution would have to look like.

It's hugely important to define the problem, and constrain the solution as much as possible. Nailing these down is probably the single most important "trick" problem solving.

With the problem defined, and the solution constrained, I printed the entire processor manual, and read/scanned it through in one sitting. I then went back over the memory and instruction timing sections, since that was going to be the hardest part.

I at least, learn much better by first scanning through a paper book on a subject. This lets you get the big picture all in your head at once, and see how things connect. Unlike just reading an overview, you also get to see the hard details that make up the way the system works. Then go back through later for the sections that matter for the problem you are working on.

I hooked up the customers hardware to the computer, flashed code the existing code to it, then changed the code to turn a status LED off. This was just to verify that I had the code to hardware toolchain working.

I've learned to bite off a small piece at a time, and then build up, rather than trying to solve everything at one go. The first code I ran on the processor just changed a status LED. This let me focus on as small of a chunk as possible, and deal with getting the new IDE configured, etc, without having to worry about the whole class of problems that would come from running my new algo.

I know I need X amount of sleep to solve problems. Even with a crazy deadline, knew I'd do still come out ahead. I went to bed at my usual time.

When I woke up, I knew how to solve the problem. The solution was similar to drawing a diagonal line on a computer screen - which is a really easy problem.

I've found that you can think in your sleep. Maybe this is just me again, but I've learned that as long as I clearly layout a problem, solution, and tools before I sleep, I wake up with the answer. I don't even wonder anymore if it's going to happen. Perhaps this is just the result of a lot of experience, but it never fails. If I'm stuck on something during the day, I just take a shower or a nap and know the answer afterwords.

Because the algorithm was going to be the most important part of this, I coded a JavaScript/HTML 5 canvas visualizer that gave me a live slider for the input variable and showed me a single view the output over many thousands of time steps. The JavaScript version of the algo worked great.

In optimization, the algorithm usually matters far more than anything else. It wasn't that I was the king of assembly language programmers, it was just that I was doing an entirely different thing than the previous programmers had been optimizing. I started with "what would the ideal solution to this problem be", and they started with "let's translate a hardware concept to software".

The second biggest trick to working with a new problem is visualization. I've learned that I can hugely increase my speed of understanding by building tools to visualize the problem and what my code is doing to solve it. For example in the recent, awesome, Halite programming competition, I built a tool that would let me output annotated html5 game maps and documents from within my code. Here's an example visualization output, straight from source code http://braino.org/thoughts/halite_the_simple_way.html
OODA loops really do matter, and really are constrained by how much you can see how fast.

After breakfast, I worked out the assembly instructions I'd need, tracking the timing and register values on graph paper. I read up carefully in the docs on each instruction I'd need.

By lunch time I had a paper version that should work, and by 3pm I had it running in the product and had learned how to use an oscilloscope. The customer picked up the hardware and got the sale. The new version used one core instead of three and was measurably, literally ten thousand times improved.

I was now a carded member of the Real Programmers Society.