First, Break All the Rules is a fantastic book about management and companies and I highly recommend it for managers and non-managers alike. Toward the end it makes the case that good managers lead to engaged employees.
I was totally enthralled by that term engaged employees. It's a perfect description of one of the characteristics that can make one person so much better at their job than another. I'm sure you've seen examples of this too. One person can be ridiculously smart, and yet do bad work. Or they might be amazingly talented, and still they don't do good work. You see examples of this every day in the grocery store checkout clerk, or the person at the front desk of your hotel, or the cleaning staff at your office, or the police officer directing traffic.
Sometimes when a person isn't performing well in their work, the failure is attributed to them being lazy, or immature, or even that they're just not challenged enough and so are bored. That may all be true, but the problem is really that they are simply not engaged in their work, for reason or another.
It turns out this concept of employee engagement has a rich history dating back to at least 1993 when it was described as "an employee's involvement with, commitment to, and satisfaction with work."
This really goes to the heart of what Peopleware was all about. Every manager wants their employees to be involved and committed to their work, but they all too often forget that they also need to be satisfied with it. Peopleware talks about this all over the place. And probably the two best real world examples are Google and Fog Creek.
Companies with disengaged employees are simply bleeding money. Its like the difference between people who drive the speed limit and coast into all their stops and people who are constantly speeding up to the bumper of the car in front of them and hitting the brakes... The second dude is just throwing gas away and killing his mileage. Every time he pulls around someone and floors it he feels good, but then he has to slam on the brakes again. And when he fills up at the pump and calculates his mileage, he'll blame his car or traffic conditions for the low mileage, anything but himself. This same short sightedness is the reason why companies want to skimp on amenities for their staff or the quality of their product. But its costing them engaged employees.
So engaged employees are important, the challenge is in getting them. Some people need someone around to keep them actively engaged, but others don't. The people that don't need help are your "self-motivated" people. The kind who need to be engaged to be happy. I would argue that most people in the world fall into this category, they just might be engaged in things other than their work. Look at sports. I'm not into sports. At all. I enjoy watching a game, but I just can't get into the stats and the history and memorizing years and events and people and on and on and on... I'm simply amazed by people who can learn all that stuff and talk and argue about it endlessly. The amount of energy and dedication required for that is phenomenal and it takes some serious smarts. Imagine if you could harness just a little bit of that energy and apply it towards something slightly more productive.
And therein lies the rub. How do you get people to be engaged, and more importantly how do you get them engaged in the right things?
I've had the fortune of knowing and working with a lot of smart people. Most have been naturally engaged. But it's interesting to see what that results in. If there is a project at work that excites them, they're all in. But when it doesn't, or when some other factor is causing them to dislike it, they'll find other things to get into: side projects at home, or frameworks or "minor" bugs or related "enhancements" at work. Expending energy on these things is extremely valuable experience to the individual but maybe not so much to the company.
But on the other hand, the greatest breakthroughs can frequently come from people messing with unrelated stuff. Just look at Google's 20% time and the making of ad sense. Ad sense practically single-handedly funds Google, and it was invented by someone in their 20% time. So having some leeway is equally important.
There is a line to walk here. If you have a lot of people who are very engaged, but always in things that don't help you achieve your business goals, you're screwed. And if most of your people are not engaged at all, you're screwed.
Walking this line is going to be difficult, but I would guess that most companies aren't even aware of it. Maybe their employees are engaged anyway, because of good managers or just because of luck. But that doesn't seem too likely.
So how do you get people to be engaged? Peopleware, and First, Break All the Rules, and Joel Spolsky, and 37 Signals can answer that question better than I can, so I'll refer you there.
In the mean time I'm curious, does your company engage you?
Monday, August 31, 2009
Monday, August 24, 2009
Optimize for Success
Lets pretend you are writing some code. This code does something. Occasionally, it may fail for some reason, but we intend it to succeed, and it will succeed more often than it fails.
As an example, lets say we're going to update a record in a database, but before we do we need to a do a get so we can see if any of the values changed. If some values have changed, we'll do some stuff after the update. Maybe we'll send an email or something. We're going to do a concurrency check by optimistic concurrency (see if it changed in any way using a last update timestamp column) before we do our save.
Now, this is just an example so I can make a larger point, so bear with me here. Lets go ahead and pretend we're using LINQ-to-sql to do the update, so LINQ will also do the concurrency check for us.
Our psuedo code looks kind of like this:
Now, if the update fails due to the concurrency check, this will just bomb out.
But notice that when the concurrency check fails, we still did the Get operation. This kind of sucks because we didn't need to do it. And we can't do the Update before we do the Get, that would defeat the purpose. So we're going to have to do the concurrency check manually.
Wait. What? Why am I getting all upset about this? WHO CARES if I do a Get I don't need to do in a failure scenario. Unless there is something unusual about this failure, like it's going to happen all the time, or it has some record locking implications, none of which apply here. I'm optimizing for the wrong thing. I should be optimizing for success, not for failure (While avoiding premature optimization, of course).
If I could remove the Get completely, so the method would Succeed and not need it, that might be something worth talking about. But it is totally not worth adding any code complexity just to optimize this method for a failure case.
Thus: Optimize for Success, and don't get too worked up over failure.
As an example, lets say we're going to update a record in a database, but before we do we need to a do a get so we can see if any of the values changed. If some values have changed, we'll do some stuff after the update. Maybe we'll send an email or something. We're going to do a concurrency check by optimistic concurrency (see if it changed in any way using a last update timestamp column) before we do our save.
Now, this is just an example so I can make a larger point, so bear with me here. Lets go ahead and pretend we're using LINQ-to-sql to do the update, so LINQ will also do the concurrency check for us.
Our psuedo code looks kind of like this:
Get record
Update record
if record.prop changed:
send email
Update record
if record.prop changed:
send email
Now, if the update fails due to the concurrency check, this will just bomb out.
But notice that when the concurrency check fails, we still did the Get operation. This kind of sucks because we didn't need to do it. And we can't do the Update before we do the Get, that would defeat the purpose. So we're going to have to do the concurrency check manually.
Wait. What? Why am I getting all upset about this? WHO CARES if I do a Get I don't need to do in a failure scenario. Unless there is something unusual about this failure, like it's going to happen all the time, or it has some record locking implications, none of which apply here. I'm optimizing for the wrong thing. I should be optimizing for success, not for failure (While avoiding premature optimization, of course).
If I could remove the Get completely, so the method would Succeed and not need it, that might be something worth talking about. But it is totally not worth adding any code complexity just to optimize this method for a failure case.
Thus: Optimize for Success, and don't get too worked up over failure.
Monday, August 17, 2009
Another C# Fluke
Here's some code:
You would expect those two Adds to be equivalent and that after executing them l.Count would be equal to 2.
Instead you get an ArgumentException on the second Add. Turns out System.Collections.Generic.List implements both Add(...) and System.Collections.IList.Add(...) and the interface specific one does some input validation not done by the other Add. This validation doesn't understand Nullable types, so you get an exception.
I guess its a probably a bug, due to the fact that Nullable<> behaves kind of strangely through reflection.
var l = new List<int?>();
l.Add( null );
( ( System.Collections.IList)l ).Add( null );
l.Add( null );
( ( System.Collections.IList)l ).Add( null );
You would expect those two Adds to be equivalent and that after executing them l.Count would be equal to 2.
Instead you get an ArgumentException on the second Add. Turns out System.Collections.Generic.List implements both Add(...) and System.Collections.IList.Add(...) and the interface specific one does some input validation not done by the other Add. This validation doesn't understand Nullable types, so you get an exception.
I guess its a probably a bug, due to the fact that Nullable<> behaves kind of strangely through reflection.
Subscribe to:
Posts (Atom)