I've spent most of this year wallowing through a huge amount of old bad code. Diving into this mess got me thinking about Prof. Samuel Holtzman's "Intelligent Design Systems", a book I read about twenty years ago (here's his TED talk). It changed how I approach the unknown: rather than seeing it as a big blob of nothing, I apply Holtzman s "Taxonomy of Ignorance" and dive in. The idea is to look at what you don't know and categorize it; understanding your ignorance makes it manageable.
Here's my programmer-biased view of Holtzman's taxonomy...
Combinatorial ('Computational' in the TED video)
You know there is a solution and you know how to get it, but the calculation costs prevent you from getting the answer; the foundation of encryption.
You have a complete model of the problem but lack an effective solution method, like Dr. Watson and Sherlock Holmes. Or the uber programmer that can see a solution that no one else sees, even though everyone has the same data.
Gordian (interesting that in the TED talk this comes after Ptolemaic; this is order in the book)
What do you do when you no longer have a complete model of the problem? Whatever solution method you have will not work; you need to restate the problem. Alexander the Great could not untie the knot that Gordius, king of Phrygia, tied for the future ruler of Asia. Instead, he reframed the problem of untying it and simply cut the knot.
Our team is dealing with code we find incomprehensible. It was written over a dozen years with little regard for maintainability and is the worse example of technical debt I've ever seen. Instead of trying to unravel it, we've decided to bypass it: figure out the API methods, isolate parts, replace them, and discard the old code. The job changed from 'make the old code work' to 'make the application work'; cutting was more effective than fixing.
In this case you have a solution to the problem that is based on an inadequate model, like the Ptolemaic earth-centric model of the solar system, vs. the more elegant Copernican model. Or, to put it another way, if all you have is hammer, everything looks like a nail.
Computer programming is in that state: schools teach Java almost exclusively and students see "programming" through a procedural C syntax filter. It's sad that they are not exposed to Prolog, Lisp, Smalltalk, assembler, SNOBOL ... anything that would shake up their mental model, and maybe even provide a more elegant one.
You know something works, but it contains essential elements for which you have no effective formalization. Your car works, you rely on it, but when it breaks you suddenly realize that you do not know how it works. And that's a fair deal: we can't know everything. We do rely on the knowledge of others.
I'm happy to program without knowing all the details of how my keystrokes translate into electrical impulses that eventually render images on a screen, but I sure do notice when it breaks.
When it comes to code that I'm responsible for, magical ignorance is not an option. Our project schedule has slipped because of this: we'd rather delay deploying than rely on code that we don't understand.
When we lack a model we have not way to approach a solution. "What is life? Why are we here?" ... not a comfortable question, so some find refuge in religion and faith. Guess it's better to believe something than to admit that you just don't know.
Finally, what about cases where we don't even know the question exists? We don't have a model because we don't know to look for one. Like the innocence of youth; no three year old worries about politics.
Apply this list, and add the understanding that you will know more tomorrow than you do today, you can start eating that elephant, one bit at a time.
Simple things should be simple. Complex things should be possible.