Lessons in Software from Mike de Libero


Editor’s note: This is a guest post from Mike de Libero.  Mike has been doing software development for more than 9 years in a variety of settings.  He’s worked as a freelance developer.  He’s also worked on a small team of developers maintaining 30+ programs at one time.  He’s even worked as a security tester on the Microsoft Office team.

I first met Mike through Mark Curphey.  Software security is a small world.  The funny thing about many of the people I meet in software security is that they 1) tend to break things to make things better, 2) like to help, and 3) focus on improvement.  The great thing about Mike is that he’s got a passion for development, and he’s more focused on principles, patterns, and practices, than on a particular technology.  Here are Mike’s top lessons learned in software development …

Top 10 Lessons in Software Development

Here is a summary of my top lessons in software development:

  • Lesson 1. All software is flawed.
  • Lesson 2. Check-in often.
  • Lesson 3. Tests, gotta love them.
  • Lesson 4. Refactor, check-in and repeat.
  • Lesson 5. Coding is easy, humans are tough.
  • Lesson 6. The more eyes on your code the better.
  • Lesson 7. Keep learning and improving.
  • Lesson 8. Simple is beautiful.
  • Lesson 9. Learn software development not coding.
  • Lesson 10. Think about your audience.

Lesson 1. All software is flawed.
Anyone who has written a software program larger than “hello world” knows that there will be bugs.  That is just a fact of software development.  These flaws occur because the way a piece of software is written is a reflection of what the developer’s though processes are and what challenges he or she is trying to solve.  Because human thoughts are not logically perfect all of the time, errors will occur.  Also, software development is always a trade-off between time/money and features leading to items left partially coded or rushed through.  Which leads us to the next lesson…

Lesson 2. Check-in often.
Everyone is using source control, right?  If you are not, start now!  When developing software or doing heavy refactoring, source control is your friend.  The more often you check-in a usable piece of code the easier it is to rollback if you completely screw something up.  On teams that require a code review before check-in or they freeze check-ins setup a private source control server it is so quick and easy.  I always think of source control as an undo button and it partially frees the developer from the fear of screwing up publicly.  If you use source control and unit-tests almost all fear just goes away.

Lesson 3. Tests, gotta love them.
Ahh unit tests… Everyone says you have to use them and they are the best thing since sliced bread.  I happen to agree for the most part.  When doing greenfield development I make sure unit tests are always written and used.  However the idea of unit tests as a part of the normal development cycle has only become semi-common in the last five years and good software was built long before then.  Keeping a list of common tests that should be ran outside of an IDE is also a great thing to have.  I think the greatest advantage of unit tests is that as long as they are quick to run it allows for a quick sanity check for the developer.  If source control is the development undo button then unit-tests are the babysitter that yells at you for doing something you wouldn’t do if your parents were around.

Lesson 4. Refactor, check-in and repeat.
No piece of code is perfect but it can hopefully become better (and yes it could get worse) by going back over and asking the questions “what can I do to make this shorter, easier to understand, etc…”  People do this all the time when writing papers but it doesn’t happen often when writing code.  After each interval, check-in the code in case you go too far and removed some needed piece of code.  Depending on the size of code being refactored there might be many iterations.

Lesson 5. Coding is easy, humans are tough.
Don’t get me wrong, there are some hard problems in coding but they are not as hard as figuring out what our fellow beings want out of a piece of software.  Humans tend to be fickle and contradict what they say.  On top of that it is very hard to communicate clearly and a barrier exists between “geek-speak” and normal vocabulary.  It becomes extremely difficult to figure out what users are asking for.

Lesson 6. The more eyes on your code the better.
Whenever I go into a new code base or one I haven’t been into for a few weeks I always spend a few minutes browsing around looking for things to improve.  When I spot something that was a bad implementation or just a bug I shoot an email over to the developer and let them know how it could be improved (I also change the implementation to make it better).  I ask for and expect the same thing out of any developer I work with.  Why?  Because it keeps us honest and teaches us ways to make our programs better.  Sure, this might not be a sit-down code review but I find this to work fairly well at least for smaller teams.  The more formal code reviews are nice to and have similar goals: higher quality code, bugs found before QA gets it and information transfer.  I think it all depends on the environment you are in.

Lesson 7. Keep learning and improving.
This lesson is pretty obvious but it has to be said.  If you don’t learn and/or keep improving you risk becoming a fez which I doubt anyone wants.  My usual metric is:

  • 1)    What new language / technology / technique did I learn in the past month?
  • 2)    When looking at my old code can I easily find better ways to do things?

I think the second metric is very important.  If you can’t think of ways to improve the code – even if it is not feasible in the current code base – then you should be concerned as that is one sign you are not growing.

Lesson 8. Simple is beautiful.
The acronym KISS is awesome and I try to follow that when developing software since I also believe in the idea that as software grows it becomes more complex.  Whenever I have to fix an issue or write code I always ask myself “can it be any simpler?”  Simplicity has many benefits and not just from a development perspective some of them are:

  • Code is easier to understand
  • Maintenance tends to be easier
  • Simple UIs tend to make programs easier to use

Lesson 9. Learn software development not coding.
Personally I make a distinction between coding and actual software development.  I think there are far too many people who focus on just the coding portion and not the bigger picture.  Many people can write code but it seems fewer people can design a system, test a system, write the code, document the architecture, talk to users to figure out requirements, create semi-accurate estimates, help other team members and when designing a user interface know the basics of user interaction.  There are things all developers should know about coding as well but I feel improving your coding chops is pretty easy and is done as you develop software.  Learning and improving in regards to software development is not necessary for one to hold done a job as a programmer.

Lesson 10. Think about your audience.
When reading this point did you immediately jump to the users of the program for which it is being created?  If you did you forgot a few other audiences :).  Whenever you code I find that there are at least 4 audiences: the compiler, other programmers / your future self, attackers/malicious users and then the users of the program.  All of these audiences require different things and the easiest audience to please is the compiler.  The other audiences take a bit more work while creating software.  For example the attacker audience we really want to piss off instead of please and pissing off an attacker is fairly easy by just not trusting input and properly encoding output (note: this won’t protect you from everything in the attacker arsenal but it will take care of a huge amount).  The developer audience is fairly tough as we tend to think all other code is stupid or at least have an opinion about it, this stems from the differences in how each person thinks (at least that is my opinion on it).  Commenting business logic, writing clean and clear code and keeping it simple usually helps the development audience.  For the actual users of the program they are an interesting group.  There are many books on usability and design so I am just going to suggest you pick-up a few good books on that matter (if you need any suggestions feel free to get in touch with me).


  1. Nice one.
    With regards to check-in, I’m a very strong believer that each and every project must be source controlled no matter how small or large the size of the project. The point on which I differ is – no check-in with incomplete code or code with known bugs – in other words half baked code. This ensures that the code base is as consistent as possible.
    I have this philosophy of 1, 3 and 5 day check-ins. Plan for what you can achieve in this time frame and work accordingly. But at the end of the day, if you check in it has to be complete.
    I’m also a lesson 6 follower. However, being the one man army I am right now, I have found that changing hats (learnt from JD) helps donning different roles. I believe that when a developer writes code, it is the optimal variant of one of the many variants that run in the developer’s mind albeit might not be the one. This is where reviewing your own code helps. I always tell my folks that never run through it with the same thought process. It is pointless. There is always another way of doing things. It is not mandatory that it has to be adopted. However it allows you to compare and decide on your pros and cons.
    KISS coding is awesome. According to me what makes it tick is a documentation that supports it. Even the simplest of code without documentation is hard to understand. (Let me say I have had prior experience – with my own code :D)

    However, I had one question with the audience part. Why would you pick compiler as an audience? As far I’m concerned, the technology and App Type dictate the framework, and the compiler of course.

  2. Hi Mike,

    This is really good and precise, I myself has followed almost all of this lessons in my professional life, but putting them together in such a precise and un-ambiguous way makes the difference.

    Now I know a good article to be shared with my colleagues 🙂

    Thanks Mike for such a good article.


  3. Thanks for the feedback!

    @Praveen – I usually try to make my longest code change last a day so for me checking in every few hours does check-in fully baked and tested code. There are exceptions of course but that is my usual goal. But maybe that is just a limitation of my brain :). Yes, documentation does help with code clarity, I tend to put comment headers specifying the high-level logic of the method (or class) along with the pre and post-conditions for any method.

    As far as why I chose the compiler as part of my audience. Mainly for the reason that no matter what language you choose you still have to write code that is understandable by the compiler or interpreter, it basically consumes your code (not technically accurate but you get the idea). It is not something we normally think about but no matter what we always have to write code the compiler understands it is kind of like the lowest level of Maslow’s hierarchy of needs :). I agree with you I never pick my language or technology until I find out the business needs there is no single tool that fits all of the issues.

    @Prashant – Thanks, I am glad the article was good!


  4. #5 is a bull eye.
    #9 took me to #8 which is all times winner. Man, i am tired seeing FOA (fashion oriented architectures). One case was when a customer required to build a SOA based system when simple plain vanilla web site would work perfectly. loved #10 too a lot. It is too often considered that end users are the only users of the system forgetting IT folks, architects that should integrate the system with other systems, and developers that would build vNext of the system, in fact everyone who touches the system is its audience, its users.

  5. Mike, there are many parallels in your post to performance testing.

    My current customer failed to engineer for security & perf from the ground up. Today, they are paying a big price. All the time “saved” in their project plan has been for nought.

    Thanks for sharing. Nicely done.

  6. @Alik – Yea I love it when people want overly complex solutions. Granted the flip side can be just as bad. I have seen systems that tried to be too simple and it ended up they wrote so much duplicated code it became complex :).

    @Jimmy – Yea I love it when people are penny-wise and pound foolish. Sadly that appears to be fairly common since “it is just code” and it will “be pretty easy to change, right?” 🙂 It seems this is changing though, thankfully.

    Thanks for all of the feedback guys!

  7. I liked lesson 8 the best, simple is indeed beautiful. Your thoughts on this reminded me of a solution to detecting rootkits that I heard about once that was so simple that it was inspiring. Everyone else was trying to use graph trees, Fourier transforms, genetic algorithms yada yada. Then someone suggests this algorithm: inventory the files on a system while the OS is running and call it set A. Inventory the files on the same system while the OS is not running and call it set B. The delta between A and B are the files that are trying to hide themselves (i.e., rootkits).

    Simple and beautiful. All code should be this way in my honest opinion. Great post Mike!


  8. Mike – this is a brilliant list!

    I particularly liked “Learn software development, not coding” simply because it is so true. I think the difference between a programmer and a software developer is that a developer knows how to understand needs, write code, test and document the architecture. In a longer run, success as a software professional really depends on your ability to understand the business of software business.

Comments are closed.