Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I just finished reading this recent article. It's a very interesting read, and it makes some great points. The point that specifically jumped out at me was this:

The difference was in how they spent this [equal] time. The elite players were spending almost three times more hours than the average players on deliberate practice — the uncomfortable, methodical work of stretching your ability.

This article (if you care not to read it) is discussing violin players. Of course, being a software engineer, my mind turned towards software ability. Granted, there are some very naturally talented individuals out there, but time and time again, it is those folks who stretch their abilities through deliberate practice that really become exceptional at their craft.

My question is - how would one go about practicing the "scales" of software engineering and computer science? When I practice the piano, I will spend more of my time on scales and less on a fun song. How can I do the same in developing software?

To head off early answers, I don't feel that "work on an open source project," and similar answers, is really right. Sure...that can improve your skills, but you could just as easily get stuck focusing on something that is unimportant to your craft as a whole. It can become the equivalent of learning "Twinkle Twinkle Little Star" and never being able to play Chopin.

So, again, I ask - how would you suggest that someone deliberately practice software engineering?

share|improve this question

marked as duplicate by gnat, Martijn Pieters, Dan Pichelman, haylem, Dynamic Mar 2 at 18:24

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

5  
Take a look here and, for something related, here. –  Jordão Nov 12 '11 at 23:19
    
I'm guessing that studying algorithm math and reading programming books all alone in a silent room for 5 hours a day has some role. –  raindrop Aug 2 '13 at 3:21
    
@Jordão thanks for the links! They have some very interesting insights. –  Ashutosh Jindal Nov 10 '13 at 8:56
    
You're welcome @Ashutosh. –  Jordão Nov 10 '13 at 10:50
1  
possible duplicate of I'm graduating with a Computer Science degree but I don't feel like I know how to program. Title isn't really a dup, but the answers are pretty much the same. Also this and this. –  haylem Feb 26 at 12:42

6 Answers 6

There's a difference between what we do as software engineers and what a violinist (or anything else that requires physical practice would do). A violinist spends hours practicing methodically because they are teaching their brain very specific patterns of how to interact with an instrument.

Practicing software engineering also involves learning patterns. The more projects you do, the more you will learn (hopefully) about what works and what doesn't. There's no standard recipe for writing great software (that's why some people compare our profession to a "craft" rather than pure science). So my advice #1, write code, then write more code. And don't think that if what you are working on is fun, it isn't teaching you as much. I say pick something that IS fun; it'll keep your interest longer and you'll enjoy yourself that much more.

You don't have to join an open source project if you don't want to. Just set a goal for yourself, something would interest you, and just start coding. You don't even need to finish it, so don't get disappointed if half way through the project you decide to drop it and go to something else. Most importantly as you walk away from that project, you need to be walking away with better skills and more knowledge of the technology you used.

Advice #2, read Pragmatic Programmer. Main take away from that book is that just as you think about how to write a piece of software, once in a while you need to step back and review your process for thinking about writing a piece of software. Any time you do work, don't just put it on a shelve and move on, but take another glance at it and think of ways you could've done it better. You don't have to go and actually redo it, but by thinking about it, you will exercise your brain to recognize the patterns I mentioned in the intro.

Advice #3, talk to other people who are passionate about writing code. Listen to what they've done and how they approached things. And explain to them what you are doing. I have few friends at work and periodically I'd just walk into their cube and quickly sketch out the design of software I'm working on. Sometimes they'll just nod, but other times, they might say, well if you move this box over here and get rid of this class, you could save yourself 2 days of work and gain advantages A, B and C.

Advice #4, after you've done few projects and found some patterns. Go back and read books like the famous GoF book. If you've already done work, you'll a) recognize some of the things authors are talking about and b) you'll discover different ways you could've approached your projects.

Advice #5, always keep reading and challenging yourself. Don't ever get into the mode that now I know technology X, therefore I'm an expert. No matter how much you think you've learned, just remember, there's infinitely more out there for you to absort, so in grand scheme of things, you still don't know that much. Keep reading blogs; learn a new language. For example I've been reading about F# and functional programming although I mainly program in C++ and I've started applying functional concepts to my object oriented code. In some places this greatly simplified the use of multiple threads and data synchronization.

share|improve this answer

Two things that come to mind are Project Euler and Google's AI Challenge. Especially if you do it in a language other than your day job language, these sorts of problems are constrained enough to stretch your abilities, but also simple enough to have clear approaches.

I've been doing the AI challenge this year, and what I find most fascinating about it is that the problem is simple enough to be solved with basic algorithms, but you'll hit the time limit per turn if you do it the naive way. You have to understand not just the rote part of the basics, but also the underlying reasons behind them in order to make it work within the time constraints.

share|improve this answer

After you write a block of code that works and passes a test, ask yourself "can this code be better?". In this context, better doesn't necessarily mean faster or more efficient, though that's part of it. Clarity of the code is also important -- can someone look at it and understand what it is doing. Ask yourself if you would submit that code to a potential employer as being representative of your best work.

Don't just do this for your own personal code. Come to sites like this and answer questions that require you to provide a working example. Writing code that may someday be copied and used by people who are just learning can be a powerful motivator. Make sure you do this with your real name so you have no choice but to claim it as your own.

Another way to do this -- and I see that you are -- is to write a blog that requires you to provide code. Again, this forces you to write code that will in the public eye, open to criticism.

When you write code that will be read and scrutinized by others, I think that's the equivalent of practicing scales.

share|improve this answer

None of the above is software engineering. It is all only programming in a haphazard manner.

Software Engineering (SE) is an engineering discipline concerned with a systematic, rigorous, disciplined approach to the design, development, operation, and maintenance of software, and the study of these approaches; that is, the application of engineering to software.

In particular, software can be engineered when you apply engineering techniques. To learn such techniques, the best is to study a relevant SE Master's Degree. When you teach yourself, you may learn about programming, but I cannot imagine you learning engineering on your own.

Example: Programmer comes and starts writing code, optimizing code, etc. (everything that matters to a programmer is code and nothing but code). Complex projects are often late, the budget is exceeded up to a few orders of magnitude, and the software does not solve requirements well. This is known as software crisis. The answer to that is the SE discipline.

SE comes and wants to understand the problem domain as the first thing. An engineering approach is applied, in particular Requirements Engineering (RE) (requirements elicitation -> requirements analysis -> requirements specification -> requirements validation).

The result of RE is typically a set of models such as contextual model, behavioral model, and business process model. From these models, SE understands the business problem and designs a software solution.

The design typically means SE translates requirement models into component-based system architecture and then engineers component design for each component individually. This results in a certain specification of component boundaries, component interfaces, and classes to compose components from.

Next step is someone who comes to these (usually auto-generated) interfaces and creates their implementation. That person may be a programmer. Finally, SE follows with software validation where everything is tested against original design and requirements.

In SE, projects typically have a project plan which allows engineers to plan, control, and monitor projects. In particular, software is engineered on time, on budget, to specification.

During the implementation phase of software, documentation is produced for every artifact and many Configuration Items (CIs) are generated. These need to be managed somehow. Usually, in SE, there is a Software Configuration Management (SCM) repository and Change Management. Another part of SE is Software Process (SP), i.e. RUP, Scrum, DSDM, Crystal, Waterfall, ...

SP must be documented and rigorously followed as in the documentation, without any exception, so that results are always reproducible. (ISO 9000). This refers to Software Quality.

Another SE topic is Software Measurement and Estimation which allows you to measure the efficiency of your SP, team performance, estimated project size (LOC - Lines of Code) i.e. COCOMO, estimated project delivery (man days), and similar.

There is still much more to SE than this short answer describes. Applying SE approaches instead of only writing code is how you practice SE.

Because SE is still an emerging field, it happens that non-engineers call themselves engineers. Unless they are applying engineering approaches, they are merely programmers.

For further reading, see Software Engineering by Ian Sommerville and www.ieee.org / www.computer.org. In these resources, SE is the engineering discipline. On Stack Overflow and in many companies, unfortunately, they borrow the term SE and use it as another name for programming.

share|improve this answer
    
I think this should have been the selected answer. It is spot on and totally true. Most people here are programmers/developers not software engineers. –  AlanChavez Jan 24 at 15:23

How does a writer practice writing books?

OK, what I meant to say is that writing code is not like mastering a musical instrument. The role of a programmer is more of a writer or a composer trying to find the right chord. So you should ask yourself how these professionals practice their craft instead. Actually, I think our profession has more in common with those than with other engineering disciplines.

A writer practices writing by writing books and a composer practices composing by composing music, so a programmer should practice programming by programming.

share|improve this answer

One approach might be to take a relatively non-trivial project (say, over 1000 lines), and port it to other languages. You will find that this highlights many assumptions made for you by your language.

Another approach might be to determine a larger project - at least 10KLoC by your estimate - and start writing it, writing it fast. Keep writing it, and then after it's accomplished its goal, maintain it. This will teach you about managing codebases mutating over time.

Just some thoughts.

share|improve this answer

Not the answer you're looking for? Browse other questions tagged or ask your own question.