Tag Archives: Tips

10 Ways to Learn New Things in Development

Expanding upon one of the topics in my post about 5 Attributes of Highly Effective Developers, I’ve been thinking of various ways to kick-start learning opportunities in my career and hobbies.

1. Read books. There are tons of books about programming–probably most of them are useless, but there are many, many gems that can greatly influence your abilities.

I still find that it’s easier and faster to find information about many topics in familiar books than to find similarly valuable information online. Read all your books to get to this point.

Books are also valuable from theory, architecture, design point of view. There just aren’t that many places on the web to get high-quality, authoritative instruction in this.

Like this? Please check out my latest book, Writing High-Performance .NET Code.

2. Read Code. This is something I was late to. I didn’t start reading a lot of significant code until after I had a few years of professional programming experience. I would be a better programmer if I had started earlier. I try to read some source code every week (not related to work, not my own, etc.) from an open source project. Start with programs that you use and are interested in. I started with Paint.Net and it solidified a lot of .Net program design technique for me.

Reading other people’s code shows you different ways of doing things than you might have thought of on your own.

3. Write Code – Lots of it. Fundamentally, the best way to learn something is to do it. You can’t fully internalize something until you’ve written it. This starts with something as simple as copying the code examples from tutorials and books. That’s copying by hand, not cut&paste. There’s a difference. The idea is internalize and think, not blindly copy. Look up new API calls as you go. Tweak things.

Most importantly, develop your own projects–whether they’re simple games, participation in an open source project, or a simple plug-in to a program you use.

Try to use new technologies, new techniques, new designs–do things differently. Do things better in this project than in previous ones.

This is really the core point–if you want to be a better developer than develop.

4. Talk to other developers – about specific problems you have, as well as the latest tech news from [Apple|Microsoft|Google|Other]. This not only helps you feel part of a team or a community, but exposes you to a wide variety of different ideas.

Different types of projects require different designs, coding techniques, processes and thinking.

If you work in a small team (like I do) and you don’t have access to many other people, go find some at a local user group meeting. If nothing else, participate in online forums (you’ll have to look harder for an intelligent discussion).

5. Teach others. Similar to just reading code versus writing it, teaching other people can do wonders for forcing you to learn a topic in depth.

The very idea that you’re going to have to teach a topic to someone else should force you to learn something with a far better understanding than you might otherwise. You can face questions.

If you can’t explain a concept to a 6 year-old, you don’t fully understand it. – Albert Einstein

Teaching situations are myriad: one-on-one with your office-mate, water-cooler meetings, informal weekly gatherings, learning lunches, classrooms, seminars, and more.

How about setting up a once-a-week 30 minute informal discussion among like-minded developers? Each week, someone picks a topic they want to know more about and teaches it to the others, instigating a conversation. If you knew were going to teach the group about synchronization objects, don’t you think you’d want to understand the ins and outs of critical section implementation?

6. Listen to podcasts

If you’ve got time where your brain isn’t otherwise occupied, subscribe to podcasts. My current favorite programming-related one is .Net Rocks. They also do a video screen cast called dnrTV.

These will help you keep up on the latest and greatest technologies. You can’t learn everything and podcasts are a good way to get shallow, broad knowledge about a variety of topics, from which you can do your own deep investigations.

If there are other, high-quality developer podcasts, I’d love to hear about them.

7. Read blogs

There are more blogs than people to read them, but some are extremely well-done. I’m not even going to post links to any–there are plenty of other resources out there for that. This is one of the best ways to connect to people who actually develop the software you love and use.

8. Learn a new language

If all you’ve ever done is C(++,#)/Java there are a LOT of other ways to think about computer problems. Learning a new language will change the way you think. It’s not just a different syntax–it’s fundamentally rewiring the brain. Sure, all languages get compiled down to assembler in the end, but that doesn’t mean a high level abstraction isn’t valuable.

Functional, query, and aspect-oriented languages are starting to merge with C-based languages–are you ready?

9. Learn the anti-patterns

Aside from knowing what to do, learn what not to do. Read Dailywtf.com often and take the lessons to heart if you don’t already know.

It’s all well and good to understand proper OO design, coding style, and what you should be writing, but it’s easy to get into bad habits if you’re not careful. Learning to recognize bad ideas is vital when taking charge of a project.

Wikipedia has a thorough breakdown of many common anti-patterns,

10. Be Humble

Learning means:

  • Replacing faulty knowledge with better knowledge
  • Adding knowledge that you do not already have

There’s no way to learn until you admit you have some deficiencies. It all comes back to humility, doesn’t it? If you ever start thinking you know everything you need to, you’re in trouble. True learning is about hungrily seeking after knowledge and internalizing it. It takes lots effort. We all know this in theory, but we have to be constantly reminded.

How to file good bug reports (from Frank Kelly)

This is an issue I run into constantly at my job.

Frank Kelly wrote up a good summary of some items. They’re simple, easy to understand, easy to follow, even for non-programmers. 😉

In fact, I’m sending this link out to everyone in my group here at work.

Technorati Tags: ,,

Never make assumptions about performance

The importance of measuring performance changes is a topic that has been covered by others smarter and more experienced than me, but I have a recent simple tale.

I’ve simplified the code quite a bit in order to demonstrate the issue. Suppose I have a wrapper around an image (it has many more attributes):

   1: class Picture
   2: {
   3:     Image _image;
   4:     string _path;
   5: 
   6:     public Image Photo
   7:     {
   8:         get
   9:         {
  10:             if (_image==null && !string.IsNullOrEmpty(_path))
  11:             {
  12:                 _image = Bitmap.FromFile(_path);
  13:             }
  14:             return _image;
  15:         }
  16:     }
  17: 
  18: }

I had this and a view that loading about 2,700 of these into a customized ListView control at program startup. On a cold start (where none of the pictures were in the disk’s cache), it would take 27 seconds. Unacceptable.

What to do?

My first thought was to load the pictures asynchronously. I wrapped Bitmap.FromFile() into a function and called it asynchronously. When it was done, it fired an event that percolated up to the top.

Well, I spent about 30 minutes implementing that and ran it–horrible. The list showed up immediately, but it was unusable. The problem? Dumping 2,700 items into the ThreadPool queue is a problem. It doesn’t create 2,700 threads, but it causes enough problems to not be a viable option.

Asynchronicity is still the answer, though. But it’s at a different level. Instead of loading the individual images asynchronously, I skipped loading the images when creating the list control and instead launched a thread to load all the images and update them when done. The list loads in under a second, and the pictures show up little by little after that.

Measure, measure, measure. And pay attention.

Technorati Tags: ,,

6 Ways to Increase Your Confidence As You Code

One of the key requirements for being able to reliably update software is the confidence that the changes you are making are safe. The amount of confidence required increases with the complexity of the system.

In my day job I work on a real-time messaging system that can have very, very little downtime. As the service grows and sees more traffic, the amount of downtime shrinks. We start to worry now if upgrades take longer than 5 minutes. (It’s almost to the point where we’ll need redundant systems in order to do maintenance).

To upgrade this software, I have to have an awful lot of confidence in the code changes made. Sometimes that confidence varies.

What to do to gain confidence:

1. Consistent process

Having a set of rules to follow is a fundamental requirement of good software engineering. I’m not going to discuss what the process should be, but you should have one that works well.

Why is this important?

Programmers like order. We like well-defined problems where we can see the end from the beginning. We don’t like haziness, indeterminism, or too many choices.

A process nails down the unknowns–it tells you very specifically what the next thing to do is. A good process leaves no room for doubt.

A good development, testing, and deployment process is the first step to building confidence in what you’re doing.

For my messaging system example, here’s a short summary of what our upgrade process is. We didn’t just come up with it–it evolved as our business grew and the requirements grew with it.

  1. All unit and integration tests pass (we have about 2200 automated tests for this that can run in about 4 minutes)
  2. We’ve run it on staging server for a few weeks with no issues.
  3. All new features have been tested on the staging server
  4. Formal change document has been submitted and approved.
  5. Formal test results documented.
  6. Previous version backed up.
  7. Perform upgrade
  8. Monitor system (including custom automated monitoring tools)

At any point, I know where we are in the process and what needs to be done next. Sure, there may be details within these steps that require thought and creativity, but the process guides it all and makes us more confident that we’re not performing ad-hoc operations.

2. Unit Testing

There are other types of testing, but it all starts at the unit level, with simple tests that exercise your code line by line, function by function, feature by feature. I recently wrote a few thoughts about unit testing. Unit testing is where you can see the overall wellness of your code–you want that green bar!

Without unit testing, how do you know the code you’re writing is doing what it should? do you just run it and push it through its paces? This is highly inefficient for most types of code. You’ll run out of steam before you start getting close to edge cases.

The fact is that automated unit tests are a baseline for confidence in your code. You need to be able demonstrate time and again that your code performs well.

This all presupposes that you are writing good unit tests. If you’re not sure, start studying. I don’t buy the arguments about lulling developers into a false sense of security–sure, that can happen, but having good developers who understand this is a prerequisite.

If you’re not unit testing–what is your basis for confidence in your code?

3. Code Coverage

Code coverage goes hand-in-hand with unit testing as a good way to automatically discover what areas of your program are in need of more testing. I’ve found that one of the biggest barriers to unit testing a large C++ application we have is that we have no way of easily measuring test coverage. If we had time, we could definitely to the analysis ourselves, or we could spend a lot of money to get a C++ instrumentation profiler, but these are slow and very tedious to use in my experience.

In .Net, use the tools to your advantage.

The psychological benefits of seeing 75-, 90-, 95-, even 100-percent coverage are immense. You know that every line of the program has at least been touched.

Of course, most code coverage tools analyze line coverage, not path coverage. Combine  complexity analysis with code coverage to determine which functionality should probably have better testing. There are plenty of free and commercial tools that will give you cyclomatic complexity, among other metrics.

Use other analysis tools like FxCop to make sure your other ducks are in a row. It can find easy-to-overlook problems like not validating arguments of public methods, which can then lead to more unit tests and more coverage to achieve.

4. Automation

Take yourself out of the equation as much as possible. The point of a process is to be repeatable–it’s like automating yourself. Not only should unit testing be automated (thankfully, most testing frameworks handle this easily), but so should coverage and quality analyses.

What about deployment? Automate it. Documentation generation? CD master creation? Web upload? E-mail notification? Automate them all. Production builds should be invoked with a single command.

Working on boring, repeatable code? Automate it with code-gen.

The bottom line is: Don’t waste your brain cells on stuff that is highly repeatable, especially when it is prone to mistakes.

5. Code Review

Last week, a rather serious bug was discovered in some of our software (not released yet, thankfully, but close). The bug was mine, and I knew exactly what the problem was, but instead of designing a solution by myself, I brought a co-worker into the discussion just to bounce ideas off of. He had great suggestions, and made me think of things I might not necessarily have thought of on my own. We both went over the code and came to a solution that was simple and acceptable to both of us. The confidence level was much higher with this than it would have been otherwise.

This story is repeated daily by programmers throughout the world. Code review is a practice based on the simple notion that there is no one person smart enough to get it correct the first time.

Even if you’re working alone, which I often do, it pays huge dividends to regularly review your code with an eye for finding trouble. If you see any weakness at all, don’t ignore it–fix it. If you’re reviewing your own code, it’s a good idea to wait a bit after the time you wrote it. This gives your brain a chance to forget a little bit about it. Then, if you find you can’t understand it anymore, it’s either too complicated, or (if it fundamentally really is complicated) you need better comments.

Reviewing with other people has more benefit, however. Not everybody thinks the same way about problems. People have different experience, different expertise and focus, and you can’t take advantage of that if you don’t let them teach you. Even if the other people have less expertise than you, it is still beneficial (assuming they have some basic competency that they can bring to the discussion).

Once you let other people tear into your code (nicely, I hope), your confidence can be higher because you can add the confidence other people have in it (once your problems are corrected, of course!)

6. Repeatable Experiences

In the end, one of the best ways to increase your confidence in yourself, your code, and your practices is to have the evidence of repeated experiences behind you. You’re always learning, and that learning contributes to improvements in processes, testing, and your personal coding practices. Once you learn what works, especially during tricky upgrades, you can go into the next trial with increased confidence that you’re doing something right.

Have any other ideas on increasing confidence? Leave them in the comments!

Technorati Tags: ,,

Tip: Easily Automating use of WaitCursor

This is really simple and probably common, but it’s a useful tip anyway.

Say you need to set a form’s cursor to the wait cursor while you accomplish something.

You would do something like this:

this.Cursor = Cursors.WaitCursor;
 
//do something
 
this.Cursor = Cursors.Default;

Of course, what if “do something” throws an exception? Then your cursor won’t be set back to the default.

So let’s wrap it in try-finally.

try
{
    this.Cursor = Cursors.WaitCursor;
    //do something
}
finally
{
    this.Cursor = Cursors.Default;
}

Better, but that’s a lot of wrapping around a simple operation. Notice, that the try-finally is exactly the pattern that using is. Why not wrap this functionality into a simple to use class that handles the cursor reset automatically?

internal class WaitCursor : IDisposable
{
    private Control _control = null;
    public WaitCursor(Control control)
    {
        _control = control;
        _control.Cursor = Cursors.WaitCursor;
    }
    public void Dispose()
    {
        _control.Cursor = Cursors.Default;
    }
}

And to use it in a form is simple:

using (new WaitCursor(this))
{
    //do work
}

Of course, you could easily add functionality like restoring the previous cursor instead of always the default, handling exceptions, make it thread-aware so it uses Invoke if necessary, better error-handling, etc.

Technorati Tags: ,,,

.Net Reflector

Lutz Roeder’s .Net Reflector has been discussed on many blogs before, but I want to give it an additional plug. I recently had to emulate some C# serial-port code in our C++ app. The .Net SerialPort class is great, easy-to-use, and works well. Unfortunately, we’re using a C++ serial port library that does not support all the possible features. Fortunately, we have the source code and can easily extend it. Unfortunately, I’m not too familiar with serial port programming, and the .Net functionality does not all obviously map to the Win32 API in every respect.

Enter Reflector. It was trivial to poke into the .Net assemblies and see what the SerialPort class was doing under the covers and then use the correct Win32 functionality in our app.

There are also a ton of plugins available.

Technorati Tags: ,,,

Top 5 Attributes of Highly Effective Programmers

What attributes can contribute to a highly successful software developer versus the ordinary run-of-the-mill kind? I don’t believe the attributes listed here are the end-all, be-all list, nor do I believe you have to be born with them. Nearly all things in life can be learned, and these attributes are no exception.

Like this article? Check out my new book, Writing High-Performance .NET Code.

Humility

Humility is first because it implies all the other attributes, or at least enables them. There are a lot of misunderstandings of what humility is and sometimes it’s easier to explain it by describing what humility isn’t:

  • humility isn’t letting people walk all over you
  • humility isn’t suppressing your opinions
  • humility isn’t thinking you’re a crappy programmer

C.S. Lewis said it best, in the literary guise of a devil trying to subvert humanity:

Let him think of [humility] not as self-forgetfulness but as a certain kind of opinion (namely, a low opinion) of his own talents and character. . . Fix in his mind the idea that humility consists in trying to believe those talents to be less valuable than he believes them to be. . . By this method thousands of humans have been brought to think that humility means pretty women trying to believe they are ugly and clever men trying to believe they are fools.*

Ok, so we realize humility isn’t pretending to be worse than you are and it’s not timidity. So what is it?

Simply put, humility is an understanding that the world doesn’t begin and end with you. It’s accepting that you don’t know everything there is to know about WPF, or Perl, or Linux. It’s an acknowledgment of the fact that, even if you’re an expert in some particular area, there is still much to learn. In fact, there is far more to learn than you could possibly do in a lifetime, and that’s ok.

Once you start assuming you’re the expert and final word on something, you’ve stopped growing, stopped learning, and stopped progressing. Pride can make you obsolete faster than you can say “Java”.

The fact is that even if you’re humble, you’re probably pretty smart. If you work in a small organization with few programmers (or any organization with few good programmers), chances are you’re more intelligent than the majority of them when it comes to computers. (If you are smarter than all of them about everything, then either you failed the humility test or you need to get out of that company fast). Since you happen to know more about computers and how software works than most people, and since everybody’s life increasingly revolves around using computers, this will give you the illusion that you are smarter than others about everything. This is usually a mistake.

Take Sales and Marketing for example. I have about 50 Dilbert strips hung in my office. I would guess half of them make fun of Sales or Marketing in some way. It’s easy, it’s fun, and it’s often richly deserved!

But if they didn’t sell your software, you wouldn’t get paid. You need them as much as they need you. If someone asked you to go sell your software, how would you do it? Do you even like talking to people? As clueless as they are about the realities of software development, they have skills you don’t.

There are some industries where extreme ego will get you places. I do not believe this to be the usual case in software, at least in companies run by people who understand software. Ego is not enough–results matter. If you have a big ego, you’d better be able to back it up. Unfortunately, the problem with egos is that they grow–eventually you won’t be able to keep up with it, and people will see through you.

The competent programmer is fully aware of the strictly limited size of his own skull; therefore he approaches the programming task in full humility, and among other things he avoids clever tricks like the plague. – Dijkstra

Without humility, you will make mistakes. Actually, even with humility you’ll make mistakes, but you’ll realize it sooner. By assuming that you know how to solve a problem immediately, you may take steps to short-circuit the development process. You may think you understand the software so well that you can easily fix a bug with just a few tweaks…and yet, you didn’t realize that this other function over here is now broken. A humble programmer will first say “I don’t know the right way to solve this yet” and take the time to do the analysis.

Finally, humble people are a lot more pleasant to work with. They don’t make their superiority an issue. They don’t always have the “right answer” (meaning everybody else is wrong, of course). You can do pair programming with a humble person, you can do code reviews with a humble person, you can instruct a humble person.

Leave your ego out of programming.

It’s not at all important to get it right the first time. It’s vitally important to get it right the last time. – Andrew Hunt and David Thomas

Perhaps most importantly, a humble programmer can instruct him/herself…

Love of Learning

If you’re new to this whole programming thing, I hate to break it to you: school has just begun. Whatever you thought of your BS/MS in Computer Science you worked so hard at–it was just the beginning. It will get you your first job or two, but that’s it. If you can’t learn as you go, from now until you retire, you’re dead weight. Sure, you’ll be able to find a job working somewhere with your pet language for the rest of your life–COBOL and Fortran are still out there after all, but if you really want to progress you’re going to have to learn.

Learning is not compulsory. Neither is survival. – W. Edwards Deming

This means reading. A lot. If you don’t like reading, I suggest you start–get into Harry Potter, fantasy, science fiction, historical fiction, whatever. Something. Just read. Then get some technical books. Start with my list of essential developer books. They’re not as exciting as Harry Potter, but they’re not bad either.

A lot material is online, but for high quality, authoritative prose on fundamental subjects, a good book beats all.

Reading isn’t enough, though. You have to practice. You have to write your own test projects. You have to force yourself to push your boundaries. You can start by typing in code sample, but then you need to change them in ways unique to you. You should have personal projects and hobbies that expand your skills. Be writing your own tools, or “fun” programs. Write a game. Do what it takes to learn new things!

The type of programs you write have a big bearing on how well you learn new material. It has to be something that interests you, or you won’t keep it up. In my case, I’m developing software related to my LEGO hobby. In the past, I’ve written tools for word puzzles, system utilities, multimedia plug-ins, and more. They all started out of a need I had, or a desire to learn something new and useful to me personally.

Another aspect of this love of learning is related to debugging software. An effective developer is not satisfied with a problem until they understand how it works, why it happens, and the details of how to fix it. The details matter–understanding why a bug occurs is just as important as knowing what to do to fix it.

Learn from mistakes. I have seen programmers who make a mistake, have the correct solution pointed out to them, say, “huh, wonder why it didn’t work for me”, and go on their merry way, none-the-wiser. Once their code is working “the way it should” they’re done. They don’t care why or how–it works and that’s enough. It’s not enough! Understand the mistake,what fixed it, and why.

Good judgement comes from experience, and experience comes from bad judgement. – Fred Brooks

Obviously, some balance has to be struck here. You cannot learn everything–it simply isn’t possible. Our profession is becoming increasingly specialized because there is simply too much out there. I also think that in some respects, you need to love learning just for the sake of learning.

Detail-orientedness

Developing software with today’s technologies is all about the details. Maybe in 100 years, software will progress to the point where it can write itself, be fully component-pluggable, self-documenting, self-testing, and then…there won’t be any programmers. But until that comes along (if ever), get used to paying attention to a lot of details.

To illustrate: pick a feature of any software product, and try to think of all the work that would have to be done to change it in some way. For anything non-trivial, you could probably come up with a list of a hundred discrete tasks: modifying the UI (which includes graphics, text, localization, events, customization, etc.), unit tests, algorithms, interaction with related components, and on and on, each discrete step being broken into sub-steps.

I have always found that plans are useless, but planning is indispensable. – Dwight Eisenhower

Here’s a problem, though: few humans can keep every single task in their head, especially over time. Thankfully, detail-orientedness does not necessarily mean being able to mentally track each and every detail. It means that you develop a mental pattern to deal with them. For example, the steps of changing a piece of software could be:

  1. Thoroughly understand what the code is doing and why
  2. Look for any and all dependencies and interactions with this code
  3. Have a well-thought-out mental picture of how it fits together.
  4. Examine the consequences of changing the feature.
  5. Update all related code that needs to (and repeat this cycle for those components)
  6. Update auxiliary pieces that might depend on this code (build system, installer, tests, documentation, etc.)
  7. Test and repeat.

An example: I find that as I’m working on a chunk of code, I realize there are several things I need to do after I’m finished with my immediate task. If I don’t do them, the software will break. If I try to remember all of them, one will surely slip by the wayside. I have a few choices here:

  1. Defer until later, while trying to remember them all
  2. Do them immediately
  3. Defer until later, after writing  them down

Each of these might be useful in different circumstances. Well…maybe not #1. I think that’s doomed to failure from the start and creates bad habits. If the secondary tasks  are short, easy, and well-understood, just do them immediately and get back to your primary task.

However, if you know they’ll require a lot of work, write them down. I prefer a sturdy engineering notebookin nearly all cases, but text files, Outlook tasks, notes, OneNote, bug tracking systems, and other methods can all work together to enable this.

The more experience you have, the easier you’ll be able to track the details you need to worry about. You’ll also analyze them quicker, but you will always need some way of keeping track of what you need to do next. There are simply too many details. Effective organization is a key ability of any good software engineer.

Another aspect of paying attention to details is critical thinking. Critical thinking implies a healthy skepticism about everything you do. It is particularly important as you examine the details of your implementation, designs, or plans. It’s the ability to pull out of those details what is important, what is correct, or on the other hand, what is garbage and should be thrown out. It also guides when you should use well-known methods of development, and when you need to come up with a novel solution to a hard problem.

Adaptability

“Enjoying success requires the ability to adapt. Only by being open to change will you have a true opportunity to get the most from your talent.” – Nolan Ryan

Change happens. Get used to it. This is a hard one for me, to tell the truth. I really, really like having a plan and following it, adapting it to my needs, not those of others.

The fact is, in software development, the project you end up writing will not be the one you started. This can be frustrating if you don’t know how to handle it.

To become adaptive first requires a change in mind set. This mind set says that change is inevitable, it’s ok, and you’re ready for it. How do you become ready for it? This is a whole other topic in itself, and I will probably devote a separate essay for it.

Other than the shift in mind set, start using techniques and technologies that enable easy change. Things like unit testing, code coverage, and refactoring all enable easier modification of code.

In war as in life, it is often necessary when some cherished scheme has failed, to take up the best alternative open, and if so, it is folly not to work for it with all your might. – Winston Churchill

For me, the first step in changing my mind set is to not get frustrated every time things change (“But you specifically said we were NOT going to implement the feature to work this way!”).

Passion

I think passion is up there with humility in importance. It’s so fundamental, that without it, the others don’t matter.

Anyone can dabble, but once you’ve made that commitment, your blood has that particular thing in it, and it’s very hard for people to stop you. – Bill Cosby

It’s also the hardest to develop. I’m not sure if it’s innate or not. In my own case, I think my passion developed at a very early age. It’s been there as long as I remember, even if I had periods of not doing much with it.

I’ve interviewed dozens of prospective developers at my current job, and this is the one thing I see consistently lacking. So many of them are in it just for another job. If that’s all you want, just a job to pay the bills, so be it. (Of course, I have to ask, if that’s the case, why are you reading this article?)

One person with passion is better than forty people merely interested. – E. M. Forster

There’s a world of difference between someone who just programs and someone who loves to program. Someone who just programs will probably not be familiar with the latest tools, practices, techniques, or technologies making their way down the pipeline. They won’t think about programming outside of business hours. On the weekends, they do their best to forget about computers. They have no personal projects, no favorite technologies, no blogs they like to read, and no drive to excel. They have a hard time learning new things and can be a large burden on an effective development team.

Ok, that’s maybe a bit of exaggeration, but by listing the counterpoints, it’s easier to see symptoms of someone who does have passion:

  • Thinks and breaths technology
  • Reads blogs about programming
  • Reads books about programming
  • Writes a blog about programming
  • Has personal projects
  • These personal projects are more important than the boring stuff at work
  • Keeps up with latest technologies for their interests
  • Pushes for implementation of the latest technologies (not blindly, of course)
  • Goes deep in technical problems.
  • Not content with merely coding to spec.
  • Needs an outlet of creativity, whether it be professional (software design) or personal (music, model building, LEGO building, art, etc.)
  • Thinks of the world in terms of Star Trek

Just kidding on the last one…

…(maybe)

That’s my list. It’s taken a few months to write this, and I hope it’s genuinely useful to someone, especially new, young software engineers just getting started. This is a hard industry, but it should also be fun. Learning these attributes, changing your mind set, and consciously deciding to become the engineer and programmer you want to be are the first steps. And also part of every step thereafter.

Nobody is born with any of these–they are developed, practiced, and honed to perfection over a lifetime. There is no better time to start than now.

* The Screwtape Letters, C.S. Lewis

Easily Unit Testing Event Handlers

In C#, If you need to unit test a class that fires an event in certain circumstances (perhaps even asynchronously), you need to handle a little more than just running some code and doing the assertion. You have to make sure your unit test waits for the event to be fired. Here’s one naive way of doing it, a WRONG way:

   1: private bool statsUpdated = false;
   2: private ManualResetEvent statsUpdatedEvent = new ManualResetEvent(false);
   3:
   4: [Test]
   5: public void CheckStats()
   6: {
   7:     BrickDatabase db = new BrickDatabase(tempFolder, maxCacheAge);
   8:
   9:     statsUpdated = false;
  10:     statsUpdatedEvent.Reset();
  11:
  12:     db.InventoryStatsUpdated += new EventHandler(db_InventoryStatsUpdated);
  13:     db.DoSomethingThatFiresEvent();
  14:
  15:     statsUpdatedEvent.WaitOne();
  16:
  17:     Assert.IsTrue(statsUpdated);
  18: }
  19:
  20: void db_InventoryStatsUpdated(object sender, EventArgs e)
  21: {
  22:     statsUpdated = true;
  23:     statsUpdatedEvent.Set();
  24: }

There are a number of things wrong with this:

  1. The class variables. More complex unit test class. Have to coordinate these variables across multiple functions.
  2. Since they are class variables, you will want to reuse them, but you’d better remember to reset the event and the boolean every time!
  3. Have to have two functions to do something really, really simple.
  4. The WaitOne() does not have a timeout, so if the wait is ever satisfied then statsUpdated is guaranteed to be true.

Here’s a better way of doing it, using anonymous methods in C# 2.0:

   1: [Test]
   2: public void CheckStats()
   3: {
   4:     BrickDatabase db = new BrickDatabase(tempFolder, maxCacheAge);
   5:     bool statsUpdated = false;
   6:     ManualResetEvent statsUpdatedEvent = new ManualResetEvent(false);
   7:
   8:     db.InventoryStatsUpdated += delegate
   9:     {
  10:         statsUpdated = true;
  11:         statsUpdatedEvent.Set();
  12:     };
  13:
  14:     db.DoSomethingThatFiresEvent();
  15:
  16:     statsUpdatedEvent.WaitOne(5000,false);
  17:
  18:     Assert.IsTrue(statsUpdated);
  19: }

Improvements?

  1. The event is just part of the method. Since the event handler is an anonymous delegate, it can access the enclosing method’s local variables.
  2. Added 5,000ms timeout to the WaitOne() function to prevent hanging of unit tests.

20 Things to do when the Internet goes down

Even if the Internet connection goes out, your computer does not become a dumb brick. There were days these last few days where I didn’t bother turning it on. Then I realized all the things I could still do.

(My home Internet connection finally came back this morning. I’m bit upset that they didn’t figure it out earlier. It turned out that the first technician grossly misdiagnosed the problem. He put in an order for a new drop to be put in. Turned out it was just a broken modem. Why didn’t they try that earlier? Worse, why didn’t I think of it earlier. To be honest, I did think of it, but didn’t push it. Now I just need to get my money back from Comcast.)

Without further ado, here’s my suggestions for what to do when the Internet goes out:

On the computer:

  1. Organize photos in Picasa – I have nearly 6,000 photos on my computer. Many of them need to be deleted, organized, tagged, labeled, e-mailed, etc. (Yes, e-mailed–I can queue them in Outlook until the connection comes back).
  2. Organize My Documents – I’ve let My Documents folder get very messy. Lots of files that don’t need to be there anymore. Others need to be filed, or re-filed.
  3. Organize e-mail – I’ve got hundreds of folders in Outlook. I’ve tried to keep my Inbox empty and put things into @Action, @Someday, or @WaitingFor folders before they find a permanent home, but sometimes it still gets out of hand.
  4. Organize and fill in information in Windows Media Player. I still have music tagged with the wrong genre…
  5. Program. I’ve got two major programming projects I’m working on. They don’t depend on the Internet. The Internet is NICE if you need to learn something, but there’s always plenty of stuff to do that doesn’t require it. Write unit tests, run code coverage, design graphics, do all the other stuff if you must.
  6. Write e-mails to family. Long ones. Your mom will thank you.
  7. Catch up on podcasts. I got through ten episodes of Ask a Ninja, and nearly all backlogged podcasts. Now I’ll have a flood when I sync tonight.
  8. Write blog entries. I use Windows Live Writer. I should have done more of this.
  9. Play a game.
  10. Better, write a game.
  11. Setup appointments and events in Outlook for the next year.
  12. Read some classic programming texts.
  13. General computer maintenance. Defrag your disk, delete temp files, delete old installation files you haven’t used in 5 years (yes, I have some of those…). Use DiskSlicer to find where your space is going.
  14. Do long-avoided projects. I have approximately 20 hours of audio I need to edit and split into tracks. I’ve been putting it off for a very long time.

Off the Computer:

  1. Practice the piano.
  2. Read books. I’ve just started Cryptonomicon by Neal Stephenson. Very good, so far. Go buy it. If you’re a geek, you’ll like it. How can you not love a 2 page diversion into the mathematics of when a bike chain will interfere with a broken spoke and fall off? Other than the geekiness, it’s a good story.
  3. Learn to cook a new dish.
  4. Do crosswords.
  5. Exercise.
  6. Relax.

Or just go to the library and use the Internet. I only did this a few times, despite it being within walking distance from where I live.

Technorati Tags: ,,,,,,

Don’t delay your merging

Another one of those lessons learned posts. I know I’m supposed to merge changes across branches often to minimize the pain, but I didn’t do it.

Here’s the scenario: We’ve got 3 development branches: 6.3, 6.4, and 7.0 (the trunk). 6.3 and 6.4 are technically maintenance branches because we didn’t anticipate needing to them, but we are. Here’s where it gets funny. 6.4 is actually a branch off of 7.0 with some new features removed. 6.4 is the code base converted to handle unicode. 6.3 is the current development version, and it’s features need to be merged into 6.4 These two branches are rather divergent in places. It’s been months since the branches were synchronized. In addition to 20 conflicted files, the 13 localized resource DLLs can’t automatically be merged because their location changed. Yeesh…

So now I’m spending all day using DiffMerge to do these files. Not a fun day…

Lesson learned. Do frequent merges.

At least it’s Friday. Tomorrow, my wife and I are heading down to North Carolina to visit my grandmother before she heads to California for Christmas.

By the way, still no Internet at home. Comcast says it could be 28 days before the local construction company gets around to installing the new drop to our home. I’ve been getting a lot of piano practice and reading in.