Monthly Archives: July 2012

Order Matters: Java statics

Being a C# refugee, I haven’t quite picked up all the little nuances of Java. I’ve written a fair share of Java in my day but today I uncovered something new. Many of you may already know this, but in Java the order of statics matter.

To illustrate what I mean, let’s take a look at a snippet of C# code:

private static final IDictionary<string, object> foo = new Dictionary<string, object>() {{ "foo", bar }};
private static final object bar = new object();

In this example, after the class is initialized the contents of the ‘foo’ key’s value is bar.

Ok. Let’s take a look at a similar snippet in Java:

private static final Map<String, Object> foo = new HashMap<String, Object>() {{ put("foo", bar); }};
private static final Object bar = new Object();

Unlike C#, in Java the contents of ‘foo’ here is null.

The reason is that in Java, the order of initialization of static finals is the order in which they appear.

Bizarre.

How To Hire Great Developers

In a previous set of posts I talked about how the difference between an average developer and a great developer is enormous, how bad developers can effectively cancel-out your good developers, and why you therefor need to hire just the very best.

So how do you tell if someone is good? or bad? What are the core competencies and key indicators of an ‘A’ player developer? And how do you interview for them?

Great Developer Key Indicators

The following is a list I’ve accumulated over time. It’s never complete, and certainly up for discussion, but in my experience is a pretty good set of indicators for whether a developer is an ‘A’ player or not.

Great developers:

  • Can deal with many levels of abstraction simultaneously.
  • Are masters at managing complexity.
  • Know space and time trade-offs of the major data structures.
  • Understands multi-threading, resource locking, and how it’s implemented.
  • Understands that simple is better than complicated, every time.
  • Has used a DVCS (git, mercurial, etc).
  • Are masters at managing expectations.
  • Plays with new technologies and languages and stays aware of upcoming developments.
  • Understands what TDD is and why it’s a valuable practice.
  • Is likely to develop iteratively and incrementally, adding value with each release.
  • Understands how to accomplish loose-coupling and encapsulation, especially in things that are likely to change.
  • Is not a lone-coder who goes dark for long periods of time.
  • Knows how to communicate well, not just with developers, but all levels of management and stakeholders, and can adjust communication vocabulary/style per context.
  • Knows SOLID principles and practices them effectively.
  • Recognizes that code reviews are excellent ways to improve yourself, both as an author or reviewer.
  • Can grasp the bigger picture.
  • Doesn’t just accept work items and marching orders, but also proposes alternatives and improvements.
  • Knows 1 procedural language, 1 object-oriented language, 1 functional language, 1 scripting language, 1 statically typed language, and 1 dynamically typed language. (There is much overlap between these categorizations)
  • Fluent in major design patterns and how/when to implement them.
  • Knows most of these books:  Code Complete, Pragmatic Programmer, Clean Code, Mythical Man Month, Design Patterns by the Gang of Four, Programming Perls, Code: The Hidden Language of Computer Hardware and Software, C by K&R.
  • Keeps up with development blogs/twitter/podcasts.
  • Is highly passionate about software development.

Bad Developer Red Flags

There are some simple things you can do to immediately weed out the really bad developers in an interview scenario.

  • Have them write FizzBuzz; believe it or not most developers do poorly on this, and it’s a great way to identify them early on in the process.
  • Ask them what the last new language or development environment they learned was. If it’s been a long time since they’ve learned a new one, that’s a red flag.
  • Ask them what they think a great developer’s best attributes are. If the answer isn’t in the list above, it’s probably a red flag.
  • Have them explain dependency injection to you, and a simple example. If you get a deer-in-headlights response, it’s a red flag.
  • Ask them to solve problems that involve in-place manipulation of a linked list or string. If they don’t understand pointers or space/time complexities of a problem, that’s a concern. ‘Reverse a linked list’ is a good one to ask.
  • Find out if they have a GitHub/BitBucket/Codeplex/SourceForge.  Look for evidence of development both inside and outside of work.

What NOT To Do

  • Don’t ask questions that are just quick facts. A programmer that knows what port IMAP runs on isn’t going to be a better programmer than one who doesn’t. Knowing little C compiler optimizations doesn’t make you a better programmer.
  • Don’t just ask questions with verbal answers, or open-ended answers. Actually have them write code on the whiteboard. A lot.
  • Don’t use questions that are common enough to where they could be googled before hand or memorized.
  • Don’t just be satisfied that someone answered something correctly. Talk to them about their solution. Ask them to modify it. Ask them to test it. Challenge their thinking.

This is an organic post, and I suspect I’ll add many suggestions from readers.

 

Reduce Your Nesting

A key aspect of software development is making the code base maintainable. If the code is hard to read or understand, it corresponds to an increase in the time to wrap your head around what it’s doing. And since time is money, we can conclude that if code is hard to read/understand, there is a very real increase in cost required to maintain that software.

Nesting Is Your Enemy

Nesting occurs when you open up a new code block. This comes in various forms depending on the language, but is typically your branching, looping, and function definitions. For example, here’s a LOT of nesting:

public String getNameFromDatabase(string id) {

	if(id != null) {
		if(id.trim() != "") {
			Person person = this.database.load(id);
			if(person != null) {
				if(person.Name != null) {
					return person.Name;
				} else {
					return "";
				}
			}
		}
	}

	return "";

}

That’s awful. The human brain can only keep so many things in mind at a time, and usually the more contexts that you need to keep in your head at once, the more likely it is that you’ll get lost or make mistakes. Each level of nesting is another context that you’ve got to keep in your head.

What do you do? The solution is often to use early exits.

public String getNameFromDatabase(string id) {

	if(id == null) {
		return "";
	}

	if(id.trim() == "") {
		return "";
	}

	var person = this.database.load(id);
	if(person == null) {
		return "";
	}

	if(person.Name == null) {
		return "";
	}

	return person.Name;

}

Doing this improves readability and maintainability. You only have to keep at most 1 context in your head at a time. Once you’ve moved beyond that possibility, you can safely forget it and move on to the next one.

Another common (but less severe than the above), and one that junior developers make often is a scenario like this:

public boolean getFoo() {

	if(thingX == true && thingY == true) {
		return true;
	}

	return false;
}

Here’s how we can make it a little better:

public boolean getFoo() {

	if(thingX && thingY) {
		return true;
	}

	return false;
}

But it can still be even better. Here’s how:

public boolean getFoo() {
	return thingX && thingY;
}

It’s a contrived example of course, but illustrates the point. Now there’s no nesting, no unnecessary comparisons, and it’s faster to read and understand. As with all practices and approaches this needs to be considered on a case by case basis because there are certainly cases where a single line return statements actually hurts readability, especially as the branch clause grows larger.

Happy coding.

Work Smarter, Not Harder

During the industrial age it was common to hear people romantically refer to their work ethic by the incredible number of hours they worked. The calculation many people had in their minds was that working a ton of hours correlated to long term success. This actually made a fair amount of sense, given that if you put in N hours, you might be able to make N widgets, wheras if you put in N+5 hours, you could make N+5 widgets.

This Isn’t Manual Labor

Software development doesn’t work like that. It’s been a long time since there was a strong case made for equating more hours input with more success output. In fact, working with software is much more about working smarter, not harder. You can put in quite a small amount of hours done intelligently and get out a spectacular output of success. In terms of overall success, it’s usually a combination of elegant technical solutions married with great opportunities.

How It Relates to Agile

Many software shops that have historically been using a waterfall approach find it challenging to accept that 100% resource utilization isn’t valuable. It’s much more important to prioritize work, limit work in progress, and deliver working software early/often. Just because someone is freed up does not mean that we should stick them on a new project, because what you’ll end up with is just a divergence in the number of things you’re trying to accomplish. Ultimately this leads to a lack of focus, and a dilution of talent across too many objectives.

Related book: The Mythical Man Month

Succeed By Failing

How do you define success? Is it by counting the number of successful software projects you’ve completed, how many people downloaded/used them, or what kind of job title you have? It’s actually lot easier to define success that way, but it’s not the truth (at least from my perspective). I define success as having learned from past failure.

Let’s take a look at a quote from Carl Sagan:

“In science it often happens that scientists say, ‘You know that’s a really good argument; my position is mistaken,’ and then they would actually change their minds and you never hear that old view from them again. They really do it. It doesn’t happen as often as it should, because scientists are human and change is sometimes painful. But it happens every day. I cannot recall the last time something like that happened in politics or religion.”
― Carl Sagan

Not Everyone Can Be 1st Place

Fearing failure is something that can lead to “everyone is a winner” syndrome. It’s often unpopular for people and organizations to own a failure, so often what you’ll see is everything being treated as a success (at least when viewed from a manufactured perspective). What’s even worse is if you have a situation in which the person or organization is unable to measure success against a stated goal. If you don’t know there’s a failure, you can’t correct against it. Being able to measure against your stated goals is also a great way to get rid of guesswork or politics associated with what people ‘feel’ is the best thing to do. Facts and numbers tell the true story.

Cycle Time

So let’s say that we understand failing is a good thing, because it allows us to not fail at that particular thing again, and hopefully we gain some validated learning from it. But isn’t failing expensive? Either monetarily or emotionally? Not if you fail early. And the point isn’t to fail; it’s to understand why the previous attempt failed and be able to analyze and correct it. If you learn to shorten the cycle time, you won’t have invested a lot in it, and you’ll be able to pivot to the success path faster. The cycle time looks like this:

  1. State a goal.
  2. Identify a way to measure against that goal.
  3. Try it, and validate your attempted method of attack with your measurement method.
  4. Failed? Go to 1. Success? Huzzah.

Failing early is failing cheaply. Eric Ries wrote a book “Lean Startup” which discusses this, and he refers to it as being almost like an automobile engine, with the increasing revolutions of the cycle causing the engine to crank over, and at some point the engine really gets going and becomes a sustainable way of operating.

“I have not failed. I’ve just found 10,000 ways that won’t work.” -Thomas Edison

“Success is 99% failure” – Soichiro Honda

Why You Need To Hire Great Developers, Part 2

In my last post I talked about why you need to hire great developers, and how the difference between average and great developers is easily 20x.

Recently, Robert X. Cringely found and restored an hour long interview with Steve Jobs from his days at NeXT. He’s put it up on the web as Steve Jobs The Lost Interview. In this video, you really get to see first hand a lot of Steve Jobs thinking. What I found interesting, in a deja-vu sort of way, is the following remarks from Steve Jobs about teams and the dynamic range of software developers:

“I observed something fairly early on at Apple, which I didn’t know how to explain then, but have thought a lot about it since. Most things in life have a dynamic range in which average to best is at most 2:1. For example if you go to New York City and get an average taxi cab driver versus the best taxi cab driver, you’ll probably get to your destination with the best taxi driver 30% faster. And an automobile; What’s the difference between the average car and the best? Maybe 20% ?  The best CD player versus the average CD player? Maybe 20% ? So 2:1 is a big dynamic range for most things in life. Now, in software, and it used ot be the case in hardware, the difference between the average software developer and the best is 50:1; Maybe even 100:1. Very few things in life are like this, but what I was lucky enough to spend my life doing, which is software, is like this. So I’ve built a lot of my success on finding these truly gifted people, and not settling for ‘B’ and ‘C’ players, but really going for the ‘A’ players. And I found something… I found that when you get enough ‘A’ players together; when you go through the incredible work to find these ‘A’ players, they really like working with eachother. Because most have never had the chance to do that before. And they dont work with ‘B’ and ‘C’ players, so its self policing. They only want to hire ‘A’ players. So you build these pockets of ‘A’ players and it just propogates.”