50
votes

Everyone says the same thing: "a real programmer knows how to handle real problems." But they forget how they learned this ability or where: it's not taught in schools.

What can I do to improve my ability to tackle complex programming problems? What strategies have worked for you? Are there specific areas I should be focusing on, like algorithms or design patterns?

2
  • 3
    Two useful books mentioned in Code Complete are: Conceptual Blockbusting by James Adams, and Lateral Thinking by Edward De Bono.
    – mctylr
    Commented Jan 17, 2011 at 17:09
  • 1
    AH! I forgot to post in here back when it just had a few answers.
    – Mark C
    Commented Jan 19, 2011 at 5:33

26 Answers 26

25
votes

A few techiques that might or might not work:

  • Look at existing solutions to common problems, e.g. design patterns. Maybe you find something similar that at least partially resembles your problem. Search the web.
  • Act as if the problem has already been solved, and trace what follows back to the solution to make. For example, instead of designing the API for a class, just write the code that makes use of the class, with method calls as you would like them, and then implement that API.
  • Do something else, e.g. surf the net or play solitaire, and wait for inspiration to happen.
  • Think of the person you like most, and pretend you want to impress her with your problem solving skills. What would be an extremely impressive solution?
  • Check the problem for inherent contradictions or conflicting requirements, and state exactly what they are and what compromise could be made. Often, when such conflicts exist, but you are not aware of, you tend to discard one possible solution after another because you cannot perfectly satisfy all requirements.
  • If you already have a possible solution, but it feels "dirty" (copy-paste, global variables, spaghetti code etc.), use it anyway and make it better afterwards
10
  • The last point is excellent. Sometimes to solution to the problem is to just get it working for most cases and then see where it needs to be improved.
    – JeffO
    Commented Jan 11, 2011 at 13:20
  • 4
    However, be aware that the number of "I'll fix it later"s which turn in to "I've fixed it"s is (at least in my experience) fractionally small.
    – Gareth
    Commented Jan 11, 2011 at 16:09
  • 3
    Gareth: True, but the idea is not to make it better next week, next month or whenever, but immediately after getting it to work. It's meant as a method to crack hard nuts.
    – user281377
    Commented Jan 11, 2011 at 18:27
  • 3
    I don't surfing the net as a way of waiting for inspiration to happen. You need idle brain cycles to get inspiration to happen, and surfing the net is a way of wasting those idle brain cycles. Instead, go shopping, or take a walk, or take a bike ride, clean your apartment -- do something that doesn't take much brain power. Inspiration will come more quickly under those circumstances.
    – Ken Bloom
    Commented Jan 16, 2011 at 17:08
  • 1
    Geek: I know that #4 sounds a bit paradoxical, but sometimes, it really works for me; especially in situations where more than one approach seems possible and the problem is the selection of one of those approaches. #6 means not to be too restricted by the usual don'ts in our profession. Sometimes we have internalized rules like "avoid global variables" to the point that we unconsciously reject every solution that makes use of such deprecated technique.
    – user281377
    Commented Jan 17, 2011 at 7:15
20
votes

Use R-mode or L-mode thinking as required

R-mode is the creative, non-verbal approach we commonly associate with the subconcious. L-mode is the linear, logical, verbal approach associated with your "inner voice".

If a problem appears to be intractible it is probably because you are attempting to solve it using the incorrect thinking mode. For programmers, the default thinking mode tends to be L-mode so it may work for you to switch it off temporarily and access R-mode.

How to access R-mode thinking

There are many ways, but perhaps try the Poincare method (named after the famous mathematician).

Write down everything you know about the problem. Immediately solve all the easy aspects of it (if any). Pick a single item from the remain "hard problems" list and then go off for a walk where you won't be disturbed or distracted.

Don't try to analyse the problem during the walk, just let your mind wander and observe any interesting images or sensations that arise that could be related to the problem. Let them coalesce. If inspiration strikes immediately stop the walk and return to write down the insight that you have gained.

Rinse and repeat until all problems have insights. Then start exploring the insights.

Book recommendation

Also reading Pragmatic Thinking and Learning may help you become a better problem solver. (I seem to be referencing this book a lot recently...)

2
17
votes
+25

Ask someone else...

No seriously. You biggest resource can be the person sitting next to you. Don't even ask them for the answer to the problem, ask them to sit next to you and let you explain the problem.

Often you'll work it out as you verbalise it.

Sometimes the other person will ask a question or point out a detail which will unlock the mental floodgate.

Eventually you will learn to verbalise things in your head without the use of a puppet, and spot the key details in the problem quicker.

And if all else fails at least they might be able to show you a technique which you wouldn't have thought of using.

3
9
votes

Actually my short answer is "solving more problems". But the point is: Really concentrate on the problems and don't give up. Don't ask for help on StackOverflow or whatever. (Reading StackOverflow is ok of course!) Try hard until you get a nearly working solution, then you nearly reached your goal. And continue until you have a satisfying solution.

For me problem solving is two things:

  • problem solving strategy
  • persistence and frustration tolerance

Point 2 is really crucial in my opinion because it forces you to change your thinking the longer you are stuck with a problem. It also allows you to spend more time with problem solving allowing you to even more improve your skills. ;-)

By the way, I recommend you to read Edward de Bono. Though I aquired my problem solving skills mainly by studying Physics, his writing is really interesting.

Well and my problem solving toolkit is this:

  • randomly try something
  • read random articles/blogs/posts about the topic I am concerned with (or a closely connected topic)
  • making a nice drawing
  • split the problem into multiple but simpler problems
  • do something else
  • Google something that is related in some way to the problem
  • talk to others about the problem
  • make a TODO list
  • write down stuff you know about the problem's effect so you can more easily find patterns

Please note that most of these tools can be applied recursively.

And my algorithm is this:

  1. Which tool of my problem solving toolkit makes most sense at the moment?
  2. Problem not solved? Continue with 1. ;-)

Step 1. is a tough decision, but you make better decisions the more you practice.

Oh and I nearly forget the most important ingredient:

Think positive about the whole process. Don't think "I hope XYZ will now solve the problem." Rather think: "If XYZ doesn't work then I know that YZX can't be the problem source and I will check if ZYX works." Problem solving can be fun sometimes in particular if your process of finding a problem ends up to be elegant and informative.

3
  • I searched this page for the word "Physics" to see if someone already wrote about it. Mathematics is the other one.
    – Mark C
    Commented Jan 19, 2011 at 5:34
  • The value of studying physics with regard to your problem solving ability is hard to overstate, I think.
    – Mark C
    Commented Jan 19, 2011 at 5:35
  • +1 for thinking positive. If you find yourself getting worked up then your problem solving ability is impaired. Look at the problem as it giving you knowledge.
    – Gary
    Commented Jan 19, 2011 at 7:49
7
votes

Start working on the skill of identifying problems as well. Sometimes you have to recognize there is a problem before you can solve it. In school they require too many answers and not enough questions out of students.

Find people around you that solve problems and ask them how they go about it.

Be prepared to be wrong. You won't improve if you keep them all to yourself and you won't be of any use.

1
  • +1 for "In school they require too many answers and not enough questions out of students." this is soo true and take time to learn to ask the right questions... check everywhere there are so many examples of bad question
    – Rémi
    Commented Apr 3, 2014 at 15:32
4
votes

The main benefit of a computer science education for software engineers is the ability to create and understand abstractions. Abstractions are used to encapsulate common functionality, such as String class methods, into tight, reusable packages that allow us to focus on the bigger problem.

Learn to recognize and create Abstractions:

But most importantly, abstractions teach us how to break a problem down into smaller, more manageable chunks. When combined with a science background, the combination of those skills can create an engineer capable of cutting through the noise and getting to the heart of the problem.

Learn to solve problems using the Scientific Method:

When troubleshooting a production application where a hard-to-find problem exists, sometimes it helps to actually break the application further (in a non-production environment) in order to eliminate several variables in order to isolate and eliminate one.

In summary, the scientific method, learned from taking all of the Physics electives and other science electives required for a computer science degree, helps solve these problems as if we were trying out a placebo and a new drug trial on a series of volunteers. Like scientists who sometimes have to make something worse in order to make it better, sometimes we as engineers must do the same.

Scientifically thinking in this manner can -- in general -- only come from having experience in a science background. Sometimes solving a problem can't be perceived as a linear path from A to B.

In short, study computer science, study other scientific fields, learn functional programming. These will help you think like a scientist and to think outside the box.

1
  • Exactly. Break big problems into smaller problems. Commented Apr 3, 2014 at 13:12
3
votes

It is all dependent on what type of problems you are aiming to solve, but learning to think logically if you already don't is a good thing.

All in all, and you are gonna hate me for saying it, but practice makes perfect. I didn't get pulled out of my mother's womb knowing how to be a good problem solver and no one else did. You need to practice and learn how to do things on your own. If you are still in school and don't have programming/computer science type classes, math and science are also quite good for fostering development of these skills.

3
votes

I think what you are looking for is computer science heuristics.

When it comes down to what 99% of us do in the trenches, there really isn't anything new under the sun. So you might see a problem and recognize it as a DP problem, or another one as a problem that could benefit from memoization, etc...

How do you gain this knowledge? A proper CS degree is a good place to start... Not Software Engineering or Information Systems, but that stuff that most undergrads complain about "not being practical".

You can do this on your own, but it'll probably be harder. I'd start with these two courses:

Intro to Algorithms

Great Ideas in Theoretical CS

2
votes

My answers relate specifically to coding but can be applied to anything.

  1. Step away from the keyboard. Talk a walk, go for a run, talk it over with a colleague over a coffee
  2. Become 10 years older! My experience has helped me enormously.
  3. Use Binary chop. Split the problem into two and narrow the problem: repeat.
  4. Remember Sherlock Holmes: When you have eliminated the possible, whatever remains (no matter how strange) is the answer
  5. Check your test data. Well over half of my really tricky problems have been caused by faulty data and not faulty code or algorithms.
1
vote

In terms of practice, I can tell you what I do. I'm more interested in applied math, than programming, but applied math as applied to computing is programming of sorts. I see problems and solutions around. Before (or sometimes after, if say my job requires a timely solution), linking to a known solution -or existing code library, I like to ask myself: "If this were a virgin problem -i.e. you won't be able to find a canned solution, how would you proceed?" If the answer is somewhat straightforward consider writing a solution (analytic, or a computer program to solve it). Ignore complicating end cases,-you are interested in exloring approaches, and algorithms, not reinventing an existing library. If the solution will require too much effort, don't program the full solution, but at least think about the sorts of data structures and methods that you would want to use. Also think about alternative methods.

1
vote

There's a great SO question on this.

My answer was:

The best way to improve is to practice!

Subscribe to the RSS feed at: http://www.mensa.org.uk/puzzles/ and take time to complete them as they come out.

A puzzle-a-day desk calendar (e.g. http://www.calendars.com/product.asp?PID=1&MGID=-1&IID=46387&cm_mmc=Affiliate_Program--performics--k137666-_-DDI%20Link) is a good idea too as it will give you regular, bite-sized, and varied problems to solve.

While these will invariably be off topic from the problems you will find yourself facing, the variety is important as it will force you think in ways you haven't before, which is really what problem solving is all about.

Edit: Also check: http://www.mindtools.com/pages/main/newMN_TMC.htm for good problem solving tips.

1
vote

Play Chess

Playing chess is an excellent trainer for solving programming problems. The layers of problems and the logic trees relate very nicely. It also helps you to think ahead and plan before going down a suboptimal path and wasting time.

Chess also requires a balance between the left and right “thinking modes.” If you become too analytical, you can get bogged down in trying to calculate everything, which is impossible. However, every creative inspiration needs to be checked with a calculation to make sure it fits with the concrete reality of the situation. Hard problems are just like this.

Chess demonstrates how study and practice lead to solid improvement in a very linear fashion. This is true with program problem solving as well.

Playing chess can also help you get a good grasp on how much there is to learn. Even though you have been programming (or playing chess) for 10 years, you aren't a grandmaster yet.

1
  • I have found my mind sharpened with regularly playing chess. Commented Jan 18, 2011 at 17:41
1
vote

I have recently been solving the problems at Project Euler. The problems are of varying difficulty. The solutions don't usually require large amounts of code, but you do have to consider many factors like run-time of your algorithm. You can use any language you like, as you just enter an answer. There is a good write-up of an optimal solution for many problems, and lots of discussion about each problem. Try to solve one problem every day and you will be amazed how much your problem solving and analysis improve. For extra credit, try solving the same problem in many languages, such as a procedural language (maybe C++), a scripting language (like python) and a functional language (like F#).

1
vote

I come from a science background, so when I look at a problem, I tend to use tactics from the Scientific Method. I especially like to set up "experiments" based on hypotheses and use "controls", so I'll build something and then change/add only 1 thing about it and see what the result is of that one change/addition and if I'm not getting the result I need, I'll switch it back and change something else. This works well for troubleshooting/debugging code. Sometimes you get the answer you seek, but you always learn something new doing that even when you fail. I also like to learn through reductionism-- taking something that already exists (always good to start with something you may not understand, but you know works) and looks complex to me and seeing if I can break it down into its component parts and learn how they work first. It's sometimes easier for my brain to handle learning like this instead of approaching a problem holistically and I can use that knowledge to build other similar complex things myself. I also recommend reading books on logic and reasoning choosing works from both classical and modern thinkers (start with Aristotle and work your way up). They can give you some of the foundations of basic logic which you can use to help in problem solving in computers. And, of course, if you can't solve a problem and you've been working on it for awhile, take a brain break. Ruminating on a particular aspect of an issue is sometimes detrimental. Everyone needs breaks :)

0
votes

The hardest part of problem-solving is "Perceptual Narrowing".

You pick something that appears to be the problem and doggedly go after that until you're exhausted and making no progress.

The way to do this is to be sure -- absolutely sure -- you really understand the problem. "Solving the Right Problem" is the most important part of problem-solving.

Sometimes they call this "thinking outside the box". "The box" is a narrow viewpoint that may not include the real, fundamental problem. Thinking outside the box is to look for the right problem to solve.

There are numerous books on strategies for avoiding the narrowing that goes with premature focus on the wrong problem.

Mostly the trick is to identify what the real outcome is supposed to be. Then figure out what blocks that desirable outcome.

0
votes

Honestly I think everybody is different, so everyones road map to becoming a better problem solver is different. You can learn from other people's experience, but in the end you have to forge your own path. This is essentially learning something the "hard way", but it's effective in this case.

Here is how I started to improve my problem solving, though I am not a great problem solver yet, just a better one than I was last year. I was given a new project at work that involved extending a piece of open source time tracking software, by adding three new reports for management. This software was written in a language I had never used and it was poorly documented and highly obfuscated. I dug in and did a ton of research and then I just worked on the reports in baby steps, once I had basic functionality I improved upon them and then finally I added more features.

So, in other words, I recommend you find some sort of sink or swim real world project to work on. If you are currently employed as a programmer, find a project or ask your boss for one. If this scenario isn't possible find one outside of work, maybe contract/freelance work or something. I solve problems very well and very quickly when I have to and I retain that knowledge because of the intensity of the project. If this won't work for you then just do what everyone else on this thread suggests :).

0
votes

The answer is itself in the Question by coming out with different solutions. There are always more than one solutions (e.g. Sorting can be done in different ways viz. Bubble Sort, Selections sort etc.) you just need to choose a way you can do it (Sorting) efficiently. Try with different next time and so on..... And books for Problem solving..... None You can not learn Problem solving skills from books, more code you will execute more knowledge you will gain. Good Luck

0
votes

It's easy for a programmer to mentally attack a problem by visualizing how to solve the problem with their favourite programming language. Just like the classic carpenter who sees all problems as nails when his favourite tool is the hammer.

I think the best problem solving exercises comes when you get above the practical level and just think in terms of "this is what I would need in order to solve it in an optimal way". In some cases you may have to learn (a lot of) new stuff to apply the solution at all, but the key point is that your ability to work out a solution shouldn't be limited to your historical and existing techniques.

An old practical example for me is that I learned how to implement efficient cooperative multitasking when I realized that my problem didn't actually need preemptive threads, even though I usually would have gone right ahead to my comfort zone banging up all those mutexes (that eventually always seem to stop being comfortable at some point..).

0
votes

In application development, many of the problems we face are either our own invention or the invention of the idiot we inherited that screwed up code base from. Resolving a problem most often comes down to finding the source . Often, once we find where it's happening, mere competence is what is needed to solve it.

To that end:

  1. Learn your platform.
  2. Learn your tools.
  3. Learn what tools are available for your platform that you haven't encountered yet.

All the brain training in the world is useless without information for the brain to use. In order to solve a problem, you must know what the possibilities are first! Even then, it's a lot quicker to work with good information rather than just a description of the problem.

I might speculate til the cows come home on why something is taking too long to execute. But if I say "lets get some data first", I might see that a whole lot of exceptions are being thrown and realize I could change this to an if statement instead. Without knowing how to collect the information, knowing that on my platform exceptions take quite a bit of overhead, and that there's a way to check before try that is faster, I'd never solve the problem.

0
votes

There's two parts to your answer:

a) Technique's for the actual problem solving

b) Making your brain inherently "better" at thinking and problem solving

There's always been some great answers on technique (assume you know the problem etc) so I'm not going to cover that as much. As for training your brain, there's a couple of things you can do to cross those synapses and build more interconnections

1) Learn a new language, a real language (like french, or chinese might be a good bet these days)

2) Learn to play a new instrument

3) Do something artistic like paint, draw or sculpture

4) Play scrabble or do crosswords

5) Dance like you mean it. No, I'm not kidding. Dancing has been shown to have an impact on your brain and thinking

6) Broaden your experiences, innovative solutions came come from applying a theory in one field in another so study different fields and areas you find interesting

7) Exercise, exercise is crucially important to improving the thinking process

Finally, I'm going to offer my best tip for solving hard problems: take a long walk. I've found that it works miracles for clearing out your head and letting one contemplate problems


0
votes

My advice would be to throw out the book!

Not literally of course. What I mean is, enter a topic area you have little experience in, and solve hard problems there, without learning about existing solutions. Rely on nothing but your creativity and critical thinking and perhaps a reference manual.

You might design an image format. Or a web server. Or a compression scheme. File system. Kernel. Artificial intelligence. Programming language. Computer vision system.

Something you find interesting, that is reasonably complex, and which you never learned about. Don't read about it: just jump straight in. Experiment. Make mistakes. Reinvent the wheel.

Don't ask for help. Stay away from tutorials. Stay away from the theory. Don't pull a solution off the shelf.

Why?

  • We learn best from mistakes.
  • It gives you an opportunity to practise coming up with solutions creatively, rather than regurgitating and adapting old solutions.
  • You are forced to evaluate your ideas. You can't evaluate them without developing a good understanding of your tools, of the problem you're solving, and of the idea you wish to evaluate. This leads to a deeper understanding of the topic than you would otherwise develop. (Feel free to read about the tools you are using, just don't read about the problem you're trying to solve.)

Make a few attempts, and once you feel happy with what you've achieved, leave it for a few months. Then come back fresh and see if you can find a new perspective. After that, it's time to start reading about the problem and how others have solved it (or talking with people). At this point, instead of saying to yourself "yes, that makes sense" while you read, you'll say "yes, exactly", or "well, to some extent", or "wow, that's clever".

In other words, you'll think much more critically about what you read, and you'll find it much easier to understand and remember because you already have a large "mental framework" to attach it to. You'll feel good about those things which you discovered independently, and you'll walk away with a heap of new knowledge.

Don't try to make your solution perfect. Just prove to yourself that you can solve the problem. Adopt a "can-do" attitude, and if you feel daunted by the problem, remember that the person who first solved it probably knew about as much as you do (in fact, they didn't know it had a solution!).

0
votes

Problem solving isn't something that can be taught or even learned by reading. The only way to get better at solving problems is to solve problems.

There are different techniques and methodologies to problem solving that you can read about, and you can read about tools and technologies that you can use to solve problems in a particular domain. Unless you continually think about problems, try to come up with solutions (come up with multiple solutions for every problem and evaluate them against each other), and then evaluate your solutions against the solutions developed by others, you won't get better at problem solving.

I recommend picking up a copy of Pragmatic Thinking and Learning: Refactor Your Wetware by Andy Hunt. It's a book about understanding how you think, react, and learn. It brings in relevant theories from behavioral theory and other cognitive sciences. It's specifically geared toward software developers, but applicable to any knowledge worker.

0
votes

For newbies in programming like myself I recommend the book "Think Like a Programmer". In the first chapter it covers such problem solving techniques as restating and dividing the problem, starting with what you know, reducing, analogies and experimenting.

Then there are more advanced techniques with examples in C++: solving problems with arrays, pointers and dynamic memory, classes, recursion, code reuse. I cannot comment on this part because it's too hard for me yet.

-1
votes

I solve as many problems as possible. I also like some puzzle books like this one. I also tinker with problem solving games, like math games involving prime numbers or something, sudoku, the Tower of Hanoi, etc. Just find things to solve. Also, code it out when possible.

-1
votes

Bye solving a LOT of problems!

you start with easy problems and you move up to more harder problems once the easy ones become a routine instead of problems.

-4
votes

Don't keep yourself to theory, do more practice. With practice comes experience.