<i>"A knowledge of algorithms doesn't teach you to pick the right problems to solve."</i><p>That is true. To create a application, one needs a Use Case. A Use Case will provide the most abstract solution to what the app will be doing. Then you can take the top down design approach, by dividing the Use Case into a several abstract sub problems. That is known as code architecture and belongs to System Engineering. The System Engineer needs a domain-expert help to identify what problems that needs to be solved.<p>Then..<p>Programming is carrying out those abstract sub-problems (interfaces) to become a concrete solution using a specific programming language. To complete such a task, one needs a person that knows his/hers algorithms design techniques, sorting, searching, string processing, graph problems, combinatorial problems, geometric problems and numerical problems. And lastly, the analysis of the respective algorithms.<p>Once you know what to solve, its just a matter of being able to carry out the task.<p>I think you might have confused the programmers job with the job of actually creating the entire software - which in general terms is non-sense. To sum up:<p>The software engineer (the project lead) takes care of identifying the sub-problems, after creating the Use Case with the domain expert (often the customer).<p>The programmer solves those sub-problems bottoms up, by focusing on creating the atomic parts as efficient as possible.