Archive for the ‘General Agile’ Category

Error 51: Unable to communicate with the VPN subsystem

Tuesday, October 6th, 2009

I upgraded Mac OS X to 10.5.8. I did the upgrade after my hard drive died and imported my profile from an old backup. When I tried to run my Cisco VPN client that I use for work, I was given this error:

Error 51: Unable to communicate with the VPN subsystem

First, I read that I could do this in the terminal:

$ sudo /System/Library/StartupItems/CiscoVPN/CiscoVPN restart

Since I don’t have a CiscoVPN directory under startup items, that didn’t help me. Then I read that you need to to repair disk permissions using disk utility. I did that and it found several inconsistencies. Good stuff, though, it also did not solve my problem.

Then, I read that I could do this:

$ sudo SystemStarter restart CiscoVPN

The command didn’t produce any output, nor did it fix my problem.

Finally, I came across a site that told me to do this:

$ sudo kextunload /System/Library/Extensions/CiscoVPN.kext
$ sudo kextload /System/Library/Extensions/CiscoVPN.kext

This finally fixed my problem. Here is the sequence of commands that I ran and the output:

$ sudo kextunload /System/Library/Extensions/CiscoVPN.kext
kextunload: unload kext /System/Library/Extensions/CiscoVPN.kext failed
$ sudo kextload /System/Library/Extensions/CiscoVPN.kext
kextload: /System/Library/Extensions/CiscoVPN.kext loaded successfully
$ sudo kextunload /System/Library/Extensions/CiscoVPN.kext
kextunload: unload kext /System/Library/Extensions/CiscoVPN.kext succeeded
$ sudo kextload /System/Library/Extensions/CiscoVPN.kext
kextload: /System/Library/Extensions/CiscoVPN.kext loaded successfully

Hopefully, this will save someone some time.

The Lego Game at Agile Atlanta Users Group

Wednesday, April 15th, 2009

When I joined Thoughtworks, I went to India for training and played the Lego game as a way to experience a form of Agile product development. It was a lot of fun and a great experience.

Almost 3 years later, I got to help facilitate the game for the Agile Atlanta Users Group. Only this time, I got to be one of the customers. It was a blast.

In case you aren’t familiar with the Lego game, the objective is to form a team of people and have them go through 3 agile iterations developing a lego creature via story cards.

Tim Kaddon was one of the people subjected to to our lego demands and wrote a great blog entry about his experience in the game.

Thanks to Conrad Bentham for organizing and facilitating the session, and Adrian Wible, Lefak Fakiyesi, and Brian Gunthrie for participating and making it fun.

Top Highlights:

Seeing how seriously people take building anything, including a lego animal.

Seeing the big Aha! moments, like where they realized they forgot to ask the customer what they wanted, or what the priorities were in the first iteration.

Me trying to find a balance between getting the lego animal I’m satisfied with, and torturing the team in order to make the game more interesting

Being reminded of how great a forum the game is for communicating a wide variety of Agile concepts.

Finding tests related to code you are changing

Sunday, December 7th, 2008

Often, when working on a well tested codebase, you find that you want to know what tests may exist that test the code you are going to modify.

Often a quick search on usages of a method or class is sufficient. You look at the tests briefly to see what is going on, and then you make a new test to assert the new behavior that is going to be added.

Sometimes, when there are a lot of tests, I just prefer to remove the code I’m going to modify, and see what tests fail.

This technique provides some quick and useful information. For instance:

  1. What tests were written that test the code? Are there any applicable tests?
  2. Are there other tests that implicitly test the code and should not?
  3. Are the current tests testing all the conditions?
  4. Is there a test that no longer applies?
  5. Is there a test who’s expectation are changing? That test can be modified instead of writing a new test.

This approach tends to be practical in the case of unit tests, and perhaps a few integration tests that you may know are related. Otherwise, it becomes too expensive to run a long running suite.

An additional benefit is that if you already know of some tests that should be testing some code, you may find a test that meant to test the logic, but for some reason was always passing.

Winning the Game

Sunday, November 16th, 2008

I was talking to a fellow Thoughtworker about the challenges of consulting, and I thought that one of his points was interesting. What he basically said is that you have to try to understand the motivations behind all the stakeholders in a project; not everyones primary goal is delivering software, there are many motivating factors that drive people. A good consultant will try to understand what their motivations are and then try to unify their goals with successful software delivery.

This made me think about a general organizational “smell” in software development. For lack of a better label, I’ll call it fragmentation of goals. A manager might be juggling multiple projects, of which yours is not the highest priority. QA’s may be measured based on how many bugs they find, or how many test cases the document. A developer might see a better chance at promotion by going to all the meetings he or she is invited to, moreso than the delivery of features. Entire teams within a project may even be motivated by goals that are not complimentary to the success of the project.

When I was in college, I liked to compare the team projects I was on to games. My goal was making sure that we were winning the game (in that situation, getting an “A”). Later in my education, I read Agile Software Development by Alistair Cockburn, and he made the analogy that software development is like a cooperative game that we are trying to win. I’ve always loved that analogy, and I think that it’s a useful tool in conceptualizing an effective team or project. Much like a team game, software projects must be a coordinated and unified effort amongst individuals to achieve a common goal.

There are three important factors that are core to a team being able to deliver software successfully, and each easily becomes fragmented (I’m generally using team and project synonimously).

  1. Knowing how to win the game
  2. Being motivated to win the game
  3. Having the ability to win the game

I’ll discuss each inline below.

Knowing how to win the game

A team or project must know how to “win the game” - there has to be acceptance criteria on the results of the teams efforts. Not having this clearly established makes it impossible for people to unite towards winning (I am not implying having all the “requirements” - I am talking about a clear understanding of how to accomplish the business goal). Without a clear goal, a team can only work towards something that they hope is right, and everyone may not agree on what that is.

An important aspect of this strategy is to have a single dedicated product owner - someone who can provide a vision of the end goal, and be the final decision maker for what aspects of the product will achieve that goal. This will help not only knowing what to build, but have the ability to prioritize when to build something.

Being motivated to win the game

The second part is ensuring that the team is motivated to win the game. The team as a whole will suffer if the individuals are engaging in activities meant to promote their own goals over the goals of the team. There are many, many parts to this. My basic opinion is that measuring an individuals success should be based on their contribution to the team, and the teams success.

It is difficult to make sure that everyone has the incentives to be motivated. It is not enough to hire people and then put them to work on something. You must make sure that they are happy, and personally interested in succeeding. It’s especially important to make sure that the personal goals and desires of the individuals aligned with the success of the team.

This doesn’t just apply to individuals. Often large projects involves dividing the project into smaller teams. It’s not beneficial to set up teams with goals that allows them to succeed while the project fails. The concept that this works is often an attempt to suboptimize a system - the idea that if the individual components are succeeding then the whole will succeed. This approach is flawed and often leads to a team achieving it’s goals, even at the expense of the project.

Having the ability to win the game

The team must have the ability to be effective and able to win the game. Further, the team must be empowered to make changes to increase their ability to win the game. The easy example of a team not being able to win is that when the team is formed with people who’s skill-sets are not suited to success. For example, building a team of people that have never done web development, and asking them to build a sophisticated web application. Another easy example is creating unachievable goals for the team, such as having the scope be too great for the team to ever achieve.

More complicated scenarios involve putting a restriction on a team that they must use a certain language or technology, or to disallow some tools and technologies, without consideration as to whether it actually helps the team succeed. It could even be as simple as the developers not being able to get licenses for software that they need, or computers to support the development efforts.

This point is part of the reason that it is critical for teams to be responsive, continually improving, and honest about what will make them more effective and better able to succeed. It could be that 1 month into a project, the team already knows that it’s failing and it’s likely that nothing can be done to help. It could be that the team is producing features, but is losing a lot of time trying to communicate to disparate groups that they rely upon.

Designing the game

A final point here is that all of these factors are part of setting up the game in the first place. Often the decisions that are made early on in a projects life sets it up to succeed or to fail. In my experience, the structure of a software project tends to be an extension of the organizational behavior of the company. That structure may not be an ideal structure for a software project.

Regardless of how the project begins, it’s important to change how the game is played if it is necessary to win the game.

Saving lost developer time with better hardware

Saturday, October 4th, 2008

A common problem that I see on projects is that the computers available to the teams are mediocre. The obvious example of this is when the computers given to developers are mediocre, but I also think that there is a compelling point to be made around solving performance on build machines with hardware instead of software.

Developer Machines

I was once on a project where the local update and build process became an hour long. I won’t get into the details, but it was largely an IO bound delay, with portions with the processor as the bottleneck. We were using Dell 610 laptops. When some developers started gettting Dell 620’s (dual core laptops), we discovered that it reduced the local build time on the machines by 33% to 50%. Whoa.

Think about that. A 60 minute build cut down to 30 minutes. Let’s assume that developers only build once per day and that each developer has an average cost of $100 per hour (total cost to the organization, not just wages). With those savings, getting every developer a Dell 620 instead of a Dell 610 pays for itself in couple weeks. This is just considered cutting a long build in half. There are many other situations where having a slow machine causes lost developer time.

We lobbied for getting the developers better machines, and were mostly denied. I discovered that organizations measure the cost of people separate from the cost of hardware. In fact, they may be accounted for by different departments entirely, where an arbitrary budget is given to the department that issues employee computers.

I’ve seen this on every project I’ve been on. We are given slow machines, and time is lost. It may be lost because I’m running grep over a lot of files, it may be because when I have my all my development tools open and the machine slows down.

I think that it’s fine that organizations begin developers with cheap machines, but they should be quick to spend money at the first sign that it is needed by the developers. I believe that it is an aspect of agility that many organizations fall short on, where the ability to respond to constraints in the software development system is hindered by the structure and policies of the organization.

In fact, I think that IT organizations should do a few tests against their technology stack and see what kind of performance difference exist, and use those numbers to decide what kind of machines that developers can use that will result in the best performance while being reasonable on cost. This is especially true of Java J2EE projects, as most of the tools and applications are intensive, and the time it takes to build an entire application can be intensive.

Build Machines

If your project has any kind of continuous integration (and it should!) then you have probably felt the pain of long builds at some point. I’ve seen this on every project I’ve been on. There are two areas in particular that I’ve found to be painful: Long running regression or acceptance tests, and long compilation and deployment cycles due to heavyweight tools.

Often builds and tests are segmented into builds that are run locally on developer machines, and builds that are run by the build server. A typical approach is to have developers run unit tests and fast running integration tests locally while developing, but to have long running integration tests and acceptance tests run by a build server, where failures will be fixed later by developers when the build completes.

Many projects will find over time that the time it takes to run these large integration tests and acceptance tests becomes so long that the value is reduced. The time it takes to get feedback might be hours or even days. Often, these tests are failing, as by the time they complete, multiple developers or teams may made changes that break a portion of the test suite.

I’ve seen or read of different approaches to this problem, from using in-memory databases, to manually splitting the regression suites into separate builds or “pipelines”, to distributed computing, to transparent parallelization of tests.

An example of a new tool for transparently running tests in parallel is the Selenium Grid which attempts to run selenium tests in parallel. While I think there is merit in exploring these tools, they are non-trivial to setup and maintain, and while it may result in the build/test time being cut down to a fraction of it’s original time, it increases the complexity of the infrastructure that developers will have to maintain. There tends to be surprise issues with parallization as well. You have to make sure that you can have tests that are writing to the filesystem, querying a database, or calling other services in parrallel.

One day, I hope to try a different approach. I would rather spend the money trying to use hardware to solve the problem instead of using some complicated tool. From a previous experience of dealing with an incredibly IO bound build, I’ve long dreamt of building a hard drive out of RAM. I’m not talking about using flash memory; I’m talking about using DDR RAM instead of a traditional hard drive.

I recently looked into this concept, and I found that there are a few manufacturers out there that provide devices to do this very thing, such as the Hyper Drive 4. There are a few other devices out there that can achieve this, but I liked the information/propaganda on the Hyper Drive page the best.

The stats claimed by using a RAM based hard disk are nothing short of sexy.

I won’t reiterate the numbers here, but depending on the usage, it ranges from an order of magnitude to several orders of magnitude in increased performance. Even in builds and test suites that are not predominately IO bound, I am willing to bet that the performance boost to the operating system will translate into large gains for the performance of the tests. My favorite statistic was that Windows XP booted in 2 seconds with their test configuration, and that was only because of device polling.

I don’t think that the cost of such as system is unreasonable. One 16 gigabyte drive using the Hyper Drive system would probably cost around $5000. Assuming an average developer cost of $100 dollars an hour, it pays for itself if one week of 1 developers time is saved, let alone considering the benefits to an entire team. Come to think of it, I would argue that developers should have similar setups for their local machines. For instance, grep would probably be instantaneous with a DDR based drive.

There more to consider than whether to return null

Tuesday, August 19th, 2008

With the previous discussions about whether or not we should return null from a method, I think that there is a few important points that were missed. I wanted to weigh in one last time, before I personally declare this topic beaten to death.

In the example that was given, it was asked what to do have something like:

  1. VendingMachine vendingMachine = new VendingMachine();
  2. vendingMachine.addMoney(Money.ONE_DOLLAR); // not enough money, drinks cost $1.50
  3. Drink drink = vendingMachine.getDrink();

// What now? Oh Crap, we can’t have a drink at this point. We didn’t put enough money in the machine.

In the case that there isn’t enough money, we could have the getDrink() method could return null, return a Drink.NULL. In any case, we are defining an invariant for the use of getDrink(). We are promising that, in the event that getDrink() is called and not enough money was given, we are going to do one of those two things. Alternatively, we are saying that if and only if there is enough money added, will it return a valid drink object.

Also, with this example, the assumption is that we are going to check the post-condition of the operation in order to detect failure:

  1. Drink drink = vendingMachine.getDrink();
  2. if (drink == null)  // Oh Crap!
  3.  
  4. or with a null object
  5.  
  6. Drink drink = vendingMachine.getDrink();
  7. if (drink.isNull()) // Oh Crap!
  8.  

Ideally, I don’t ever want my code to veer from the happy path. I don’t want to ever have my code reach an invalid situation where it cannot return a drink. I also don’t want to expend much effort as a developer handling the scenario. I would rather write tests that asserts that it can’t happen in relation to the client object.

One such option, is to provide a different invariant scenario - One where we check a pre-condition:

  1. VendingMachine vendingMachine = new VendingMachine();
  2. while (vendingMachine.needsMoreMoneyForADrink()) {
  3.     vendingMachine.addMoney(Money.ONE_DOLLAR);
  4. }
  5. Drink drink = vendingMachine.getDrink(); // we know for sure that we have enough money for a drink here
  6.  

or

  1. if (!vendingMachine.needsMoreMoneyForADrink()) {
  2.     Drink drink = vendingMachine.getDrink();
  3. }

The invariant is now that if needsMoreMoneyForADrink() returns false, we will always get a drink.

Personally, I like the precondition approach (in this particular example). It reads well, and it adheres to the principle of Command-Query separation. Also, in the post-condition example, null (or a wrapper) is being used to communicate that not enough money has been given to the vending machine, and that more should be added. Personally, I’d like to ask the vending machine if I’m supposed to give more money. Note that situation is similar to an iterator pattern.

Along the way, Andy referred to using exceptions because they follow the Principle of “Tell, Don’t Ask.” I don’t believe that it qualifies as a good representation of that principle, but I have an example a little later that I believe is better.

Andy’s example of throwing an exception when getDrink() is called under conditions when it shouldn’t have been raises an important question for me. Should we have a method that fails, and then communicates failure back to the client object (such as with throwing an exception)? Perhaps we should not have a method that is expected to return a drink at all.

In the world of object to object communication, there are only a few ways for an object to respond to the communication of another object, with each having strengths and weaknesses.

1.) You can return a value, or an object reference. Null is the equivalent of reponding with “No, I can’t or won’t give that to you.”

2.) You can return some kind of communication object or value, one that perhaps allows you to communicate a number of message types. I consider a Null object a variation of this. You could also return an enum, where each enum value represents a different type of message.

3.) You could set some kind of global variable to hold a message - something that can be read by the client object. This is generally considered terrible OO, but I see it from time to time in the form of Singletons.

4.) In languages like Java, you can throw an exception. Exceptions generally signify an exceptional error situation. Exceptions can be handled, but if not, will continue to bubble throughout the code, interrupting every called frame, finally interrupting the flow of execution if not handled.

5.) You can respond with a method call. This is the standard “Proper” way of having objects communicate. Of the different message/communication types available to object, this one is the richest and most intentional (most explicit). You can send a message (a method call) and send parameters as details with the message.

I generally avoid using exceptions to communicate between objects. I try to reserve them for really exceptional situations. I will spend time looking at important code and deciding on how to do it well, but many, many time before, I have written methods or functions that just return null, and I also wrote the code that used it. It’s simple, and people who look at that kind of logic will be familiar with it, so it’s not going to be a surprise.

Anyway, I wanted to weigh in on a different way of “handling nulls.” I created a sample solution to the VendingMachine::getDrink() dilemma; one that doesn’t assume that there is a getDrink() method at all. It’s an example of the VendingMachine responding to the client object (a Person) with a richer object communication (and a better example of “Tell, don’t ask” than using exceptions). Imagine that the interaction begins with someone calling Person::getARefreshingDrink() and passing in a VendingMachine.

  1. public class Person {
  2.     VendingMachine vendingMachine;
  3.    
  4.     void mustAddMoreMoney() {
  5.         vendingMachine.addMoney(Money.ONE_DOLLAR, this);
  6.     }
  7.  
  8.     public void getARefreshingDrink(VendingMachine machine) {
  9.         this.vendingMachine = machine;
  10.         vendingMachine.addMoney(Money.ONE_DOLLAR, this);
  11.     }
  12.    
  13.     void enoughMoneyGiven() {
  14.         vendingMachine.enterDrinkSelection(DrinkType.COKE, this);
  15.     }
  16.    
  17.     void givePersonChangeAndADrink(Money change, Drink drink) {
  18.         // let’s guzzle that drink and pocket the change
  19.     }
  20. }
  21.  
  22.  
  23. public class VendingMachine {
  24.     private static final Money COST_PER_DRINK = Money.valueOf(“$1.50″);
  25.     private Money totalMoney = Money.ZERO;
  26.  
  27.     public void addMoney(Money money, Person person) {
  28.         totalMoney = totalMoney.add(money);
  29.         if (notEnoughMoney()) {
  30.             person.mustAddMoreMoney();
  31.         } else {
  32.             person.enoughMoneyGiven();
  33.         }
  34.     }
  35.    
  36.     public void enterDrinkSelection(DrinkType type, Person person) {
  37.         if (notEnoughMoney()) {
  38.             person.mustAddMoreMoney();
  39.         } else {
  40.             person.givePersonChangeAndADrink(getChange(), getDrinkFromType(type));
  41.             totalMoney = Money.ZERO;
  42.         }
  43.     }
  44.  
  45.     private Drink getDrinkFromType(DrinkType type) {
  46.         return new Drink(type);
  47.     }
  48.  
  49.     private boolean notEnoughMoney() {
  50.         return COST_PER_DRINK.greaterThan(totalMoney);
  51.     }
  52.  
  53.     private Money getChange() {
  54.         return totalMoney.minus(COST_PER_DRINK);
  55.     }
  56.    
  57. }

I’m not arguing that this is optimal either, but I got other blog posts to write, and stuff to do. It’s meant to represent a way of having objects interact in a rich manner. I’m sure you can imagine other ways to make this better, such as moving the Person method definition into a “Drinker” interface.

Java Swing memory leak: JDialog, JDateChooser, and the evil of Singleton’s

Saturday, August 16th, 2008

I recently solved a mysterious memory leak puzzle in a java swing application that I’m working on. The source of the memory leak was proving elusive, even with people on the team using JProbe in order to find the source of the leak.

At the root of the problem, the Dialog was too complex and with too much logic to easily pinpoint the problem. Circularly referential object graphs were everywhere. I had to rip out most of the dialog in large chunks until I reduced it down to a simple JDialog, and then considered each possible factor.

I was a little tripped up along the way. Apparently, calling Runtime.getRuntime().gc() doesn’t necessarily collect memory, but if push push the JVM to the point of an OutOfMemoryError, it’ll do everything in it’s power to get all the available memory back. Pushing it the edge was a sure way to get an honest answer.

Normally, when Java memory leaks happen in Swing, the culprit is a listener of some kind. It’s easy to register a listener and forget about it, while it continues to point to other objects with a strong reference. It’s further complicated by the fact that it’s not always obvious when a reference is created, like in the case of defining an anonymous inner class.

In my case I discovered that the culprit of the memory leak was a JDateChooser object that we are using. That object is defined as part of the JCalendar api. Specifically, inside the dialog, a PropertyChangeListener was anonymously created and registered to the JDateChooser, creating a circular reference from the JDateChooser and the dialog.

So, what was JDateChooser doing? Sure enough, in the constructor, it was registering a listener with a Swing singleton called MenuSelectionManager. That singleton never dies, and does not releasing the reference so that the garbage collector can do it’s magic.

The code in the JDateChooser constructor:

  1. // Corrects a problem that occured when the JMonthChooser’s combobox is
  2. // displayed, and a click outside the popup does not close it.
  3.  
  4. // The following idea was originally provided by forum user
  5. // podiatanapraia:
  6. changeListener = new ChangeListener() {
  7.  public void stateChanged(ChangeEvent e) {
  8.     // do stuff that creates a reference back to the JDateChooser
  9.  }
  10. };
  11. MenuSelectionManager.defaultManager().addChangeListener(changeListener);

I love the comment. It’s just too bad that the forum user didn’t recommend constructor injection of that manager, which would have allowed me an elegant means of preventing the memory leak without modifying the library.

For instance, I could make a WeakReferenceMenuSelectionManager that stores the listeners using WeakReferences - thus allowing the garbage collector to reclaim the objects in the event that there are no other objects with a strong reference to the listener.

Unfortunately, when the maker of JDateChooser realized they were causing memory leaks, they came up with this solution:

  1. /**
  2. * Should only be invoked if the JDateChooser is not used anymore. Due to popup
  3. * handling it had to register a change listener to the default menu
  4. * selection manager which will be unregistered here. Use this method to
  5. * cleanup possible memory leaks.
  6. */
  7. public void cleanup() {
  8.   MenuSelectionManager.defaultManager().removeChangeListener(changeListener);
  9.   changeListener = null;
  10. }

This is better than nothing, but is still far inferior to a WeakReference approach. This is an excellent example of why we shouldn’t write code that reaches out and calls a Singleton. statically referencing an object does not allow me to reconfigure the object without changing the source code - something I would prefer not to do in a library. Luckily, the JCalendar api is covered under the LGPL, so at least changing the library was an option.

The better fix was this. First, I create a weak change listener as a proxy around the original change listener.

  1. public class WeakChangeListenerProxy implements ChangeListener {
  2.  
  3.     public WeakReference reference;
  4.  
  5.     public WeakChangeListenerProxy(ChangeListener listener) {
  6.         this.reference = new WeakReference(listener);
  7.     }
  8.  
  9.     public void stateChanged(ChangeEvent e) {
  10.         ChangeListener actualListener = (ChangeListener)reference.get();
  11.         if (actualListener != null) {
  12.             actualListener.stateChanged(e);
  13.         }
  14.     }
  15. }

Then, In JDateChooser, I changed the constructor like so:

  1. // The following idea was originally provided by forum user
  2. // podiatanapraia:
  3. ChangeListener changeListener2 = new ChangeListener() {
  4.     // Change listener body
  5. };
  6.      
  7. changeListener = new WeakChangeListenerProxy(changeListener2);
  8. MenuSelectionManager.defaultManager().addChangeListener(changeListener);

Finally, I wanted to clean up the remaining WeakReference object. Now that the JDateChooser will get garbage collected, I can do that by creating a finalize method.

  1. protected void finalize() throws Throwable {
  2.     super.finalize();
  3.     MenuSelectionManager.defaultManager().removeChangeListener(changeListener);
  4. }

I posted this solution to the JCalendar forum, hopefully, it’ll get added to the next release. The cleanup() method is not an obvious solution. As a user of a widget api (especially in Java), I wouldn’t expect that I need to free up any resources, and indeed, a lot of time and money was wasted with developers looking into this issue.

Oh well, at least I got to have some fun with Weak References.

Use a Java Decompiler with your IDE

Wednesday, August 13th, 2008

If you work in Java, and you don’t use a decompiler, you haven’t lived.

Well, maybe that’s a bit excessive. Still, I’m shocked by the number of developers that don’t use a decompiler like Jad combined with their IDE, like with Jadclipse and Eclipse.

In eclipse, you can download the Java api source code and attach it that so you can always look at the actual code - original comments and all.

However, you want to be able to look at the source code for any jars that your application depends on as well. I didn’t even realize how useful and freeing it is to be able to do that until I started. I would say that less than 30% of all developers that I’ve met use a decompiler, but it’s definitely one of the top plugins you have to have.

The Power of Culture

Sunday, August 10th, 2008

I recently blogged about preventing the NNPP through better hiring practices. Though I feel that a strict hiring practice is key to ensuring consistently higher quality developers, I wanted to talk a little bit about what comes after an employee is hired.

Companies should have a serious view of employees as an asset. One that should be about individuals being nurtured and grown into something and someone greater. This is a large part of why I advocate pair programming, because there is no better way to raise the skill level of developers than have them constantly working hands-on with other skilled members of their profession.

I think though, that there is a more important point here that is difficult to define: a company has to have a culture of wanting the best people and facilitating the continued growth of those people. It’s so intangible because it doesn’t come from a CEO proclaiming a set of values that came out of a management book. It’s about what the individual people in company actually believe and embody.

Using Thoughtworks as an example again, I was initially very surprised at how ever present the culture of the company is. It’s telling that we call ourselves thoughtworkers. We identify as part of a group, not just as employees of a company. We want to be part of the group. I’ve met people that fit the culture and continue to refer to themselves as Thoughtworkers even after they’ve left the company to move on to some other career pursuit. In particular, an aspect of the culture is that of excellence.

How did this come to be? Well, I can’t say for sure - it’s an evolutionary process. However, I think that it happened for the same reason that many organizations develop a culture of excellence, whether it be great sports teams or great universities.

First, the organization has to try to select the best. There has to some amount of pride in getting in. Then, once you get in, and you meet many people that are more skilled than you (or perhaps, strongly skilled in different ways), and you see how you can improve. In fact, you want to improve - you want to live up to the standard of excellent that the organization has set. You don’t want to consider yourself below average in your group.

In teams and organizations with really strong and successful cultures, it’s not just the leadership that wants everyone on the team to be superlative, but it’s the team members as well. At Thoughtworks, I’ve met other thoughtworkers that give me suggestions on books that I should read, or technologies that I should learn. I’ve developed student/teacher relationships with some people, and I’ve developed teacher/student relationships with others. With many, it’s been peer to peer, but with us debating and sharing views and opinions.

I use Thoughtworks as an example of a strong culture, but I don’t want to make it sound like it’s perfect. It has it’s flaws too, but as an organization, it’s the best of what I’ve experienced. On the other side, I’ve worked with/at companies that have what I consider to be a poor or negative culture, but my ranting about that will have to wait for another day.

Preventing the Net Negative Producing Programmer

Thursday, August 7th, 2008

Jay Fields recently published a blog post where (amongst many other points) he mentioned the concept of the Net Negative Producing Programmer, referred to as NNPP.

I’d never heard that specific term before and I enjoyed the read. Almost every project that I have worked on had a healthy number of people who’s efforts were borderline negative to the teams productivity. I say borderline because I’ve never actually measured it - but I have worked with people that would take a week to do a days work, and it would be defect ridden when they claimed that it is done.

The part that struck me about the paper though was that it said that dismissal of an NNPP is a last resort. I do agree with the paper that it argues against measuring the person with absolute statistics in making this decision, but on collaborative/agile projects, it’s usually easy to spot the weak links. I can understand that it can be expensive and risky to fire someone, but software teams must have a way of weeding out these individuals, and removing them. I don’t just mean moving them to another team; I believe that they should be laid off. I wouldn’t even feel too bad about it, IT is still a high demand industry, and even the worst of the NNPP will find some giant company to disappear into.

There is a better way however, one that will prevent companies from getting into the position of having to worry about this in the first place. Improve the hiring standards. If you can keep the NNPP’s out of your company in the first place, you don’t have to worry about firing them.

At Thoughtworks, the interview process is pretty rigorous, there are phone interviews, a code submission, logic tests, and lengthy in-person interviews with people of varying roles. The highlight for me is the code submission. It’s pretty telling from looking at a code submission whether the candidate is worth pursuing in the first place. I don’t care how many languages and technologies someone claims to know - if they can’t create an elegant and working solution to a short problem when the expected outputs are provided, then they most likely aren’t top notch.

There is also a scale to the problems, from easy to hard. Personally, botching the easy problem is unacceptable, but I’m a slightly more forgiving with the hardest problem. In general, the reviewers are usually pretty harsh, so, it generally takes a good solution to even be considered acceptable. Oh, and experience level is factored in - junior candidates have to write pretty good code, but an experienced candidate needs to nail the code submission.

It’s a HUGE differentiator. Every company that is serious about staffing the best talent (or even just good talent) should require a code submission.

I’ve even heard of some offices doing pair-programming during the interview. This is also a great idea. Someone may know how to write great code, but still not be good at actually doing it. I’ve paired with (non-Thoughtworks) people that were supposed to have 5+ years of experience and watched them struggle to write a method with a single for-loop and get it to compile. Alternatively, I’ve paired with people that are like some freakish melding of man and machine, writing with blinding speed, and what they write is beautiful. If I owned a company or ran an IT team, I’d do my best to get the freakish cyborg artist types.