Feeds:
Posts
Comments

Archive for the ‘Software development’ Category

Pair programming is a great way to share knowledge. But every developer is different, does pairing work for everyone?

Pairing helps a team normalise its knowledge – what one person knows, everyone else learns through pairing: keyboard shortcuts, techniques, practices, third party libraries as well as the details of the source code you’re working in. This pushes up the average level of the team and stops knowledge becoming siloed.

Pairing also helps with discipline: it’s a lot harder to argue that you don’t need a unit test when there’s someone sitting next to you, literally acting as your conscience. It’s also a lot harder to just do the quick and dirty hack to get on to the next task, when the person sitting next to you has taken control of the keyboard to stop you committing war crimes against the source code.

The biggest problem most teams face is basically one of communication: coordinating, in detail, the activities of a team of developers is difficult. Ideally, every developer would know everything that is going on across the team – but this clearly isn’t practical. Instead, we have to draw boundaries to make it easier to reason about the system as a whole, without knowing the whole system to the same level of detail. I’ll create an API, some boundary layer, and we each work to our own side of it. I’ll create the service, you sort out the user interface. I’ll sort out the network protocol, you sort out the application layer. You have to introduce an architectural boundary to simplify the communication and coordination. Your architecture immediately reflects the relationships of the developers building it.

Whereas on teams that pair, these boundaries can be softer. They still happen, but the boundary becomes softer because as pairs rotate you see both sides of any boundary so it doesn’t become a black box you don’t know about and can’t change. One day I’m writing the user interface code, the next I’m writing the service layer that feeds it. This is how you spot inconsistencies and opportunities to fix the architecture and take advantage of implementation details on both sides. Otherwise this communication is hard. Continuous pair rotation means you can get close to the ideal that each developer knows, broadly, what is happening everywhere.

However, let’s be honest: pairing isn’t for everyone. I’ve worked with some people who were great at pairing, who were a pleasure to work with. People who had no problem explaining their thought process and no ego to get bruised when you point out the fatal flaw in their idea. People who spot when you’ve lost the train of thought and pick up where you drifted off from.

A good pairing session becomes very social. A team that is pairing can sound very noisy. It can be one of the hardest things to get used to when you start pairing: I seem to spend my entire day arguing and talking. When are we gonna get on and write some damned code? But that just highlights how little of the job is actually typing in source code. Most of the day is figuring out which change to make and where. A single line of code can take hours of arguing to get right and in the right place.

But programming tends to attract people who are less sociable than others – and let’s face it, we’re a pretty anti-social bunch: I spend my entire day negotiating with a machine that works in 1s and 0s. Not for me the subtle nuances of human communication, it either compiles or it doesn’t. I don’t have to negotiate or try and out politick the compiler. I don’t have to deal with the compiler having “one of those days” (well, I say that, sometimes I swear…). I don’t have to take the compiler to one side and offer comforting words because its cat died. I don’t have to worry about hurting the compiler’s feelings because I made the same mistake for the hundredth time: “yes of course I’m listening to you, no I’m not just ignoring you. Of course I value your opinions, dear. But seriously, this is definitely an IList of TFoo!”

So it’s no surprise that among the great variety of programmers you meet, some are extrovert characters who relish the social, human side of working in a team of people, building software. As well as the introvert characters who relish the quiet, private, intellectual challenge of crafting an elegant solution to a fiendish problem.

And so to pairing: any team will end up with a mixture of characters. The extroverts will tend to enjoy pairing, while the introverts will tend to find it harder and seek to avoid it. This isn’t necessarily a question of education or persuasion, the benefits are relatively intangible and more introverted developers may find the whole process less enjoyable than working solo. It sounds trite: but happy developers are productive developers. There’s no point doing anything that makes some of your peers unhappy. All teams need to agree rules. For example, some people like eating really smelly food in an open plan office. Good teams tend to agree rules about this kind of behaviour; everyone agrees that small sacrifices for an individual make a big difference for team harmony.

However, how do you resolve a difference of opinion with pairing? As a team decision, pairing is a bit all or nothing. Either we agree to pair on everything, so there’s no code ownership, regular rotation and we learn from each other. Or we don’t, and we each become responsible for our own dominion. We can’t agree that those that want to pair will go into the pairing room so as not to upset everyone else.

One option is to simply require that everyone on your team has to love pairing. I don’t know about you: hiring good people is hard. The last thing I want to do is start excluding people who could otherwise be productive. Isn’t it better to at least have somebody doing something, even if they’re not pairing?

Another option is to force developers to pair, even if they find it difficult or uncomfortable. But is that really going to be productive? Building resentment and unhappiness is not going to create a high performance team. Of course, the other extreme is just as likely to cause upset: if you stop all pairing, then those that want to will feel resentful and unhappy.

And what about the middle ground? Can you have a team where some people pair while others work on their own? It seems inevitable that Conway’s law will come into play: the structure of the software will reflect the structure of the team. It’s very difficult for there to be overlap between developers working on their own and developers that are pairing. For exactly the same reason it’s difficult for a group of individual developers to overlap on the same area of code at the same time: you’ll necessarily introduce some architectural boundary to ease coordination.

This means you still end up with a collection of silos, some owned by individual developers, some owned by a group of developers. Does this give you the best compromise? Or the worst of both worlds?

What’s your experience? What have you tried? What worked, what didn’t?

Read Full Post »

Whether or not you write integration tests can be a religious argument: either you believe in them or you don’t. What we even mean by integration tests can lead to an endless semantic argument.

What do you mean?

Unit tests are easy to define they test a single unit: a single class, a single method, make a single assertion on the behaviour of that method. You probably need mocks (again, depending on your religious views on mocking).

Integration tests, as fas as I’m concerned, mean they test a deployed (or at least deployable) version of your code, outside in, as close to what your “user” will do as possible. If you’re building a website, use Selenium WebDriver. If you’re writing a web service, write a test client and make requests to a running instance of your service. Get as far outside your code as you reasonably can to mimic what your user will do, and do that. Test that your code, when integrated, actually works.

In between these two extremes exist varying degrees of mess, which some people call integration testing. E.g. testing a web service by instantiating your request handler class and passing a request to it programmatically, letting it run through to the database. This is definitely not unit testing, as it’s hitting the database. But, it’s not a complete integration test, as it misses a layer: what if HTTP requests to your service never get routed to your handler, how would you know?

What’s the problem then?

Integration tests are slow. By definition, you’re interacting with a running application which you have to spin up, setup, interact with, tear down and clean up afterwards. You’re never going to get the speed you do with unit tests. I’ve just started playing with NCrunch, a background test runner for Visual Studio – which is great, but you can’t get it running your slow, expensive integration tests all the time. If your unit tests take 30 seconds to run, I’ll bet you run them before every checkin. If your integration tests take 20 minutes to run, I bet you don’t run them.

You can end up duplicating lower level tests. If you’re following a typical two level approach of writing a failing integration test, then writing unit tests that fail then pass until eventually your integration test passes – there is an inevitable overlap between the integration test and what the unit tests cover. This is expected and by design, but can seem like repetition. When your functionality changes, you’ll have at least two tests to change.

They aren’t always easy to write. If you have a specific case to test, you’ll need to setup the environment exactly right. If your application interacts with other services / systems you’ll have to stub them so you can provide canned data. This may be non-trivial. The biggest cost, in most environments I’ve worked in, with setting up good integration tests is doing all the necessary evil of setting up test infrastructure: faking out web services, third parties, messaging systems, databases blah blah. It all takes time and maintenance and slows down your development process.

Finally integration tests can end up covering uninteresting parts of the application repeatedly, meaning some changes are spectacularly expensive in terms of updating the tests. For example, if your application has a central menu system and you change it, how many test cases need to change? If your website has a login form and you massively change the process, how many test cases require a logged in user?

Using patterns like the page object pattern you can code your tests to minimize this, but it’s not always easy to avoid this class of failure entirely. I’ve worked in too many companies where, even with the best of intentions, the integration tests end up locking in a certain way of working that you either stick with or declare bankruptcy and just delete the failing tests.

What are the advantages then?

Integration tests give you confidence that your application actually works from your user’s perspective. I’d never recommend covering every possible edge case with integration tests – but a happy-path test for a piece of functionality and a failure-case gives you good confidence that the most basic aspects of any given feature work. The complex edge cases you can unit test, but an overall integration test helps you ensure that the feature is basically integrated and you haven’t missed something obvious that unit tests wouldn’t cover.

Your integration tests can be pretty close to acceptance tests. If you’re using a BDD type approach, you should end up with quite readable test definitions that sufficiently technical users could understand. This helps you validate that the basic functionality is as the user expects, not just that it works to what you expected.

What goes wrong?

The trouble is if integration tests are hard to write you won’t write them. You’ll find another piece of test infrastructure you need to invest in, decide it isn’t worth it this time and skip it. If your approach relies on integration tests to get decent coverage of parts of your application – especially true for the UI layer – then skipping them means you can end up with a lot less coverage than you’d like.

Some time ago I was working on a WPF desktop application – I wanted to write integration tests for it. The different libraries for testing WPF applications are basically all crap. Each one of them failed to meet my needs in some annoying, critical way. What I wanted was WebDriver for WPF. So I started writing one. The trouble is, the vagaries of the Windows UI eventing system mean this is hard. After a lot of time spent investing in test infrastructure instead of writing integration tests, I still had a barely usable testing framework that left all sorts of common cases untestable.

Because I couldn’t write integration tests and unit testing WPF UI code can be hard, I’d only unit test the most core internal functionality – this left vast sections of the WPF UI layer untested. Eventually, it became clear this wasn’t acceptable and we returned to the old-school approach of writing unit tests (and unit tests alone) to get as close to 100% coverage as is practical when some of your source code is written in XML.

This brings us back full circle: we have good unit test coverage for a feature, but no integration tests to verify that all the different units are hanging together correctly and work in a deployed application. But, where the trade-off is little test coverage or decent test coverage with systematic blindspots what’s the best alternative?

Conclusion

Should you write integration tests? If you can, easily: yes! If you’re writing a web service, it’s much easier to write integration tests for than almost every other type of application. If you’re writing a relatively traditional, not too-javascript-heavy website, WebDriver is awesome (and the only practical way to get some decent cross-browser confidence). If you’re writing very complex UI code (WPF or JavaScript) it might be very hard to write decent integration tests.

This is where your test approach blurs with architecture: as much as possible, your architecture needs to make testing easy. Subtle changes to how you structure your application might make it easier to get decent test coverage: you can design the application to make it easy to test different elements in isolation (e.g. separate UI layer from a business logic service); you don’t get quite fully integrated tests, but you minimize the opportunity for bugs to slip through the cracks.

Whether or not you write integration tests is fundamentally a question of what tests your architectural choices require you to write to get confidence in your code.

Read Full Post »

A colleague asked me recently:

Why aren’t developers writing comments any more?

He’d been looking through some code his team had written, and couldn’t understand it – he was looking for comments to make sense of the mess, but there were none. Before he challenged the team, he asked my opinion: should developers be writing comments?

Excessive Comments

When I started programming some years ago, I would comment everything, and I mean everything.

    // Add four to x
    x += 4;

My logic at the time was that it was impossible to tell the difference between uncommented clear code and gnarly code you just hadn’t spotted the gnarliness in yet. So I would comment everything, where the absence of a comment meant I’d forgotten – not that it was so trivial as to not warrant mentioning.

No Comments

Eventually I started working with peers who knocked some sense into me, and I immediately halved the number of lines of code I produced. At first it was a shock, but soon I realised that clear code is easier to read if there’s just less noise. And this is all (most) comments become: noise. Sometimes they’re accurate, sometimes they’re not. But you can’t rely on them, you always have to assume they might be wrong. So if the code and the comment seem at odds, you assume it’s the comment that’s wrong and not your understanding of the code (naturally you’re infallible!)

Clean Code

Uncle Bob and the notion of clean code have taken “no comments” to an almost fanatical zeal. But every time I get into an argument with someone about how maybe this time a comment might be justified: Ctrl-Alt-M, enter your comment as the method name and it makes the code more obvious. Every. Damned. Time.

However, the trouble with a zealous argument like this is it gets taken up by asshats and lazy people. It’s too easy to say “if you’d read Clean Coder you’d know you don’t need comments. Quit living in the past, grandpa!”. Uh huh. But your code is still a muddled pile of indecipherable crap. At least with comments there’d be some signposts while I wade through your steaming mess.

Some Comments

The truth is: sometimes comments do help (squeal clean code weenies, squeal!) There are some cases where extracting a method name isn’t sufficient. Sometimes having 20 one line methods in my class does not make it easier to read. The end goal is to produce understandable code. Generally, naming things properly helps. Adding comments that get stale does not. But that doesn’t mean that writing crap code and not commenting is the answer. Don’t use “no comments” as an excuse to leave your code indecipherable by human beings.

For example, sometimes you need to document why you didn’t do something. Maybe there’s a standard way of converting between currencies in your application – which this one time you’ve deliberately not used. A comment here might help future people not refactor away your deliberate choice (even better is baking your decision into a design – some class structure that makes it really obvious). Sometimes a method name really doesn’t do a line of code justice, it’s better to be seen in the context of the lines before and after it – but it really needs some explanation of what you’re doing. This is particularly true when dealing with complex algorithms or mathematical formulae.

Getting the Balance Right

How do you get the balance right? Well, your goal is to make code that other people can understand. The best way to get feedback on that is to ask someone. Either have explicit code reviews or pair program. If another human being has read your code and they could understand it – there’s a better than average chance that most other capable people will be able to read it too.

Read Full Post »

Newcomers to TDD ask some interesting questions, here’s one I was asked recently: testing private methods is bad, but why?

How did we get here?

If you’re trying to test private methods, you’re doing something wrong. You can’t get to TDD nirvana from here, you’re gonna have to go back.

It all started with an innocuous little class with an innocuous little method. It did one little job, had a nice little unit test to verify it did its thing correctly. All was right with the world. Then, I had to add an extra little piece of logic. I wrote a test for it, changed the class until the test passed. Happy place. Then I started refactoring. I realised my little method, with its handful of test cases was getting quite complicated, so I used the extract method refactoring and boom! I have a private method.

While simple when I extracted it, another couple of corner cases and this private method evolves into quite a complicated piece of code – which now I’m testing one level removed: I’m testing the overall functionality of my outer method, which indirectly tests the behaviour of the private method. At some point I’m going to hit a corner case that’s quite awkward to test from the outside, it’d be so much easier if I could just test the private method directly.

What not to do

Don’t use a test framework that let’s you test private methods. Good God, no. For the love of all that is right with the world step away from the keyboard.

What to do instead

This is a prime example of your tests speaking to you. They’re basically shouting at you. But what are they saying?

Your design stinks!

If you need to test a private method – what you’re doing wrong is design. Almost certainly, what you’ve identified in your private method is a whole new responsibility. If you think about it carefully, it probably isn’t anything to do with what your original class is. Although your original class might need renaming to make that obvious. That’s ok, too. That’s incremental design at work.

An example would help about now

Say I started off with a Portfolio class – it has a bunch of Assets in it, each of which has a Value. So I can implement a Portfolio.GetValue() to tell me how much it’s all worth. But then I start dealing with weird corner cases like opening or closing prices. And what do I mean by value, what I could sell it for, right now? Or perhaps there’s some foreign currency conversion to do, or penalty clauses for early exit, how does all that get factored in?

Before too long, GetValue() has a fairly large piece of logic, which I extract into GetSpotSalePrice(Asset). This method is then hairy enough to need testing, so it’s pretty clear that my design stinks. The deafening din of my tests, finally persuades me to extract GetSpotSalePrice(Asset) into another class, but here’s the million dollar question: which?

What not to do – part 2

For the love of SOLID, don’t put it in a AssetSalePriceCalculator, or a SalePriceManager. This is the number one easy mistake to make – you can follow TDD and ignore decent OO design and still end up with a steaming turd pile of horribleness.

NounVerber class is always a design smell. Just stop doing it. Now. I mean it. I’m watching you. I will hunt you down and feed you to the ogre of AbstractSingletonProxyFactoryBean.

What should I do then?

The answer might seem obvious, but to too many people starting out doing TDD and half-decent design – it isn’t at all obvious. The method needs to move to a class where that responsibility makes sense. In our example, it’s crushingly obvious this is really a method on Asset – it even passes one in. If your method has one class parameter and uses a bunch of data from that class, you can bet your bottom dollar you’re suffering feature envy. Sort your life out, apply the method move refactoring. Go live happily ever after.

Summary

Why shouldn’t you test private methods? Because the fact you’re asking the question means the method shouldn’t be private – it’s a piece of independent behaviour that warrants testing. The hard choice, the design decision, is where you stick it.

 

 

Read Full Post »

What makes you a “senior developer”? Everyone and their dog calls themselves a senior developer these days. From fresh graduates to the CTO, everyone is a senior developer. But what the hell does it even mean?

Technologists

Some developers are avid technologists. They got into programming really because they like tinkering. If it hadn’t been 7 languages in 7 weeks, it would have been a box of meccano or they’d be in their shed busy inventing the battery operated self-tieing tie. These people are great to have on your team, they’ll be the ones continually bombarding you with the latest and greatest shiny. If you ever want to know if there’s an off the shelf solution to your problem, they’ll know the options, have tried two of them, and currently have a modified version of a third running on their raspberry pi.

The trouble with technologists is more technology is always the answer. Why have a HTTP listener when you can have a full stack application server? Why use plain old TCP when you can introduce an asynchronous messaging backbone? Why bother trying to deliver software when there’s all these toys to play with!

Toolsmiths

Some developers naturally gravitate towards providing tools for the rest of the developers on the team. Not for them the humdrum world of building some boring commercial website, instead they’ll build a massively flexible website creation framework that through the magic of code generation will immediately fill source control with a gazillion lines of unmaintainable garbage. Of course, that’s assuming it works, or that they even finish it – which is never guaranteed.

There’s a certain kudos to being the tools guy on the team: you don’t want the most junior member of the team creating tools that everyone else uses. If he screws up, his screw up will be amplified by the size of the team. Instead one of the smart developers will see a problem and start sharpening his tools; the trouble is you can spend an awful long time creating really sharp shears and somehow never get round to shaving the yak.

Backend Boys (and Girls)

Another common pull for a lot of developers is to get further down the stack, away from those messy, annoying users and nearer to the data. Here you can make problems more pure, really express your true artistry as a developer and an architect. It’s true: as you move down the stack you tend to find the real architectural meat of a system, where you want the developers who can see the big picture of how everything interacts. The seasoned professionals that understand scalability, availability and job-security.

It’s pretty easy to put off outsiders (project managers, customers, sniveling little front end developers) – you start drawing diagrams with lots of boxes and talk of enterprise grade messaging middleware and HATEOAS service infrastructure, before you know it their eyes have glazed over and they’ve forgotten what they were going to ask you: like perhaps why this has taken six months to build instead of six days?

GTD

Some developers just Get Things Done. Sure their methods might be a little… slapdash. But when you’re in a crunch (when aren’t you?) and you need something done yesterday, these are the people you want on your team. They won’t waste time designing a big complex architecture; they won’t even waste time writing automated tests. They’ll just hammer out some code and boom! problem solved.

Sometimes they can come across as heroes: they love nothing better than wading into a tough battle to show how fast they can turn things around. Of course, that also lets them quickly move from battlefield to battlefield, leaving others to clean up the dead and wounded they’ve left behind.

Front End Developers

For some reason Front End developers never seem to be considered the most senior. As though hacking WPF or HTML/CSS was somehow less worthy. In fact, I think the front end is the most important part – it’s where all your wonderful n-tier architecture and multiple redundant geegaws finally meets users. And without users, everything else is just intellectual masturbation.

The front end developers are responsible for the user experience. If they make a mess, the product looks like crap, works like crap: it’s crap. But if the front end developers create a compelling, easy to use application – it’s the great, scalable architecture underneath that made it all possible. Obviously.

Team Lead

Your team lead probably isn’t a senior developer. Sorry, bro: if you’re not coding you can’t call yourself anything developer. Go easy on your team lead though: the poor sod probably wrote code once. He probably enjoyed it, too. Then some suit decided that because he was good at one job, he should stop doing that and instead spend his life in meetings, explaining to people in suits why the product he’s not writing code for is late.

Architect

Your architect probably isn’t a senior developer either. Unless he’s actually writing code. In which case, why does he need the label “architect”? Architecture is a team responsibility. Sure, the most senior guy on the team is likely to have loads of experience and opinions to share with the team – but it doesn’t mean his pronouncements should be followed like scripture. But if instead of writing code you spend your time drawing pretty pictures of your scalable messaging middleware one more time, I will shove it up your enterprise service bus.

Conclusion

There are lots of different types of senior developer. That’s probably why the term has got so devalued. Once you’ve been in the industry for a few years, you’ll have found yourself in at least one of these roles and can immediately call yourself senior. The truth is you spend your whole life learning, only in an industry this young and naive could someone with 3 years experience be called “senior”. I’ve been programming professionally for 13 years and I’m only just starting to think I’m getting my head around it. I’m sure next year I’ll realise I’m an idiot and there’s a whole new level to learn.

So, go ahead, call yourself senior developer. Just make sure you keep on learning. Change jobs, wear a different hat. Be the tools guy. Meet like-minded developers. Play with different technologies. Become a middle tier developer. Then switch to work on user experience.

Senior developer: it’s just a job title, after all.

Read Full Post »

Where I work we have an unusual split: although the developers use C#, we also work with engineers who use Matlab. This allows the engineers to work in a simple, mathematics friendly environment where working with volumes of data in matrices is normal. Whereas the developers work with real computer code in a proper language. We get to look after all the data lifting, creating a compelling user interface and all the requisite plumbing. Overall it creates a good split. Algorithms are better developed in a language that makes it easy to prototype and express complex algorithms; while dealing with databases, networks and users is best done in a proper object oriented language with support for a compile time checked type system.

As part of a recent project for the first time we had a lot of data flowing through Matlab. This led to us have to verify that our matlab code, and our integration with it from C#, was going to perform in a reasonable time. Once we had a basic working integrated system, we began performance testing. The initial results weren’t great: we were feeding the system with data at something approximating a realistic rate (call it 100 blocks/second). But the code wasn’t executing fast enough, we were falling behind at a rate of about 3 blocks/second. This was all getting buffered in memory, so it was manageable but creates a memory impact over time.

So we began scaling back the load: we tried putting 10 blocks/second through. But the strangest thing: now we were only averaging 9.5 blocks/second being processed. WTF? So we scaled back further, 1 block/second. Now we were only processing 0.9 blocks / second. What in the hell was going on?

MatlabPerf

Let’s plot time to process batches of each of the three sizes we tried (blue line), and a “typical” estimate based on linear scaling (orange line). I.e. normally you expect twice the data to take twice as long to process. But what we were seeing was nearly constant time processing. As we increased the amount of data, the time to process it didn’t seem to change?!

We checked and double checked. This was a hand-rolled performance test framework (always a bad idea, but due to some technical limitations it was a necessary compromise). We unpicked everything. It had to be a problem in our code. It had to be a problem in our measurements. There was no way this could be realistic – you can’t put 1% of the load through a piece of code and it perform at, basically, 1% of the speed. What were we missing?

Then the engineers spotted a performance tweak to optimise how memory is allocated in Matlab, which massively speeded things up. Suddenly it all started to become clear: what we were seeing was genuine, the more data we passed into Matlab, the faster it processed each item. The elapsed time to process one block of data was nearly the same as the elapsed time to process 100 blocks of data.

Partly this is because the cost of the transition into Matlab from C# isn’t cheap, these “fixed costs” don’t change depending whether you have a batch size of 1 or 100. We reckon that accounted for no more than 300ms of every 1 second of processing. But what about the rest? It seems that because of the way Matlab is designed to work on matrices of data: the elapsed time to process one matrix is roughly the same, regardless of size. No doubt this is due to Matlab’s ability to use multiple cores to process in parallel and other such jiggery pokery. But the conclusion, for me, was incredibly counter intuitive: the runtime performance of matlab code does not appreciably vary based on the size of the data set!

Then the really counter intuitive conclusion: if we can process 100 blocks of data in 500ms (twice as fast as we expect them to arrive), we could instead buffer and wait and process 1000 blocks of data in 550ms. To maximize our throughput, it actually makes sense to buffer more data so that each call processes more data. I’ve never worked with code where you could increase throughput by waiting.

Matlab: it’s weird stuff.

Read Full Post »

How do you choose the right language to use for your next project? Use the right tool for the job? Sure, but what does that mean? And how do I know what the right tool is? How do I get enough experience in a new language to know whether or not it is the right tool for the job?

Your choice of language will have several impacts on your project:

  • Finding & hiring new developers to join your team
  • Whether there is a thriving community: both for providing Q&A support and the maturity of libraries & frameworks to help you get more done
  • Training your existing team; discovering and learning new tools; as well as the possible motivation impact of using new technologies
  • Finally your choice of “the right tool for the job” will make the development effort easier or harder, both in the short-term and for long-term maintenance

This is the first article in a series on choosing the right language – we will start by addressing recruitment.

Recruitment

For many teams, recruiting new staff is the hardest problem they face. While choice of programming language has many obvious technical impacts on the development process, it also has a huge impact on your recruitment efforts. If your choice of language has the ability to make your hardest problem easier then it has to be considered.

Filtering

The truth is that most developers will naturally filter themselves by language, first and foremost. Most Java developers, when looking for jobs, will probably start by asking their Java developer friends and searching job sites for Java developer jobs. Recruiters naturally further this – they need a simple, keyword friendly way to try and match candidates to jobs, and filtering by language is an easy way to start.

Of course, this is completely unnecessary – most developers, if the right opportunity arose, would happily switch language. Most companies, given the right candidate, would be more than happy to hire someone without the requisite language background.

Yet almost every time I’ve been involved in recruitment we’ve always filtered candidates by language. No matter how much we say “we just want the best candidates”, we don’t want to take a risk hiring someone that needs a couple of months to get up to speed with our language.

My last job switch involved a change of language, the first time in 10 years I’ve changed language. Sure, it took me a month to become even competent in C#; and arguably three or four months to become productive. But of course it is possible, and yet it doesn’t seem to be that common.

This is purely anecdotal: I’d love to find a way to try and measure how often developers switch languages – just how common is it for companies to take on developers with zero commercial experience in their primary language? How could we measure this? Could we gather statistics from lots of companies on their recruitment process? Email me or post a comment below with your ideas.

Size of Talent Pool

Ultimately your choice of language has one main impact on recruitment: which language would make it easiest to find good developers? I think we can break this down into three factors:

  1. Overall number of developers using that language
  2. Competition for these developers from other companies
  3. The density of “good” developers within that pool

Total Number of Developers

Some languages have many more developers using them than others. For example, there are many times more Java developers than there are Smalltalk developers. At a simple level, by looking for Java developers I will be looking for developers from a much larger pool than if I search for Smalltalk developers. But how we can we quantify this?

We can estimate the number of developers skilled in or actively using a particular language by approximating the size of the community around that language. Languages with large communities indicate more developers using and discussing them. But how can we measure the size of the community?

GitHub and StackOverflow are two large community sites – representing open source code created by the community and questions asked by the community. Interestingly they seem to have a strong correlation – languages with lots of questions asked on StackOverflow have lots of code published on GitHub. I’m certainly not the first to spot this, I found a good post from Drew & John from a couple of years back looking at the correlation: http://www.dataists.com/2010/12/ranking-the-popularity-of-programming-langauges/

GitHub & StackOverflow probably give a good indication of the size of the community around each language. This means if we look for C# developers, there are many times more developers to choose from than if we choose Ada. However, sheer numbers isn’t the full story…

Competition for Developers

We’re not hiring in a vacuum – there is competition for developers from all the other companies hiring in our area (and those remote companies that don’t believe geography should be a barrier). This competition will have two impacts: first if there is more competition for developers using a certain language, that makes it harder to attract them to our company. Assuming market forces work, it also suggests that average salaries for developers with experience in an in-demand language will naturally be higher – as companies use salary to differentiate themselves from the competition. Just because there are more C# developers than Ada developers, the ease with which you can hire developers from either group is partly dependent on the amount of competition.

so-questions-adsI looked at the total number of questions tagged on StackOverflow.com and the number of UK job ads requiring the language on JobServe.com. Interestingly there is a very strong correlation (0.9) – this suggests, perhaps not surprisingly, that most developers primarily use the language they use in their day job: there are large communities around languages that lots of companies hire for; and only small communities around languages that few companies hire for. Of course – it’s not clear which comes first, do companies adopt a language because it has a large community, or does a large community emerge because lots of developers are using it in their job?

There are some interesting outliers: there seems to be greater job demand than there is developer supply for some languages such as Perl and VisualBasic. Does this suggest these are languages that have fallen out of favour, that companies still have investment in and now find it hard to recruit for? Similarly Scala and Node.js seem to have more demand than developers can supply. On the other side of the line, languages such as PHP and Ruby have much more active communities than there is job demand – suggesting they are more hobbyist languages, languages amateurs and professionals alike use in their spare-time. Then there is Haskell, another language with a lot of questions and not many jobs – perhaps this is purely its prevalence in academia that hasn’t (yet) translated to commercial success?

In general the more popular languages have more competition for developers. Perl & VisualBasic will be harder to find developers skilled in; whereas PHP, Ruby & Haskell should be easier to find developers. Besides these outliers, whichever language you hire for the overall size of the pool of developers (i.e. those within commuting distance or willing to relocate) is the only deciding factor. How many companies continue to use the mainstream languages (Java and C#) because its “easier” to hire developers? On the basis of this evidence, I don’t think its true. In fact, quite the opposite: to get the least competition for developers (lower salaries and less time spent interviewing) you should hire developers with Ruby or Haskell experience.

Density of Good Developers

One of the more contentious ideas is that filtering developers by language allows you to quickly filter out less capable developers. For example, by only looking at Python developers, maybe on average they are “better” than C# developers. My doubt with this is if it were found to be true, developers would quickly learn that language so as to increase their chances of getting a job: quickly eliminating any benefit of using language as a filter. It also starts to sound a bit “my language is better than your language”.

But it would be interesting if it were true, if we could use language as a quick filter to get higher quality candidates; it would be quite possible to gather data on this. For example, I use an online interview that could easily be used to provide an A/B test of developers self-selecting based on language. Given the same, standardized recruitment test – do developers using language A do better or worse than those using language B? Of course, the correlation between a recruitment test and on the job performance is very much debatable – but it could give us a good indication of whether there is correlation between language and (some measure of) technical ability. Would this work, is there a better way to measure it? Email me or post a comment below.

Conclusion

Popular languages have more developers to hire from but more companies trying to hire them. These two factors seem to cancel each other out – the ratio of developers:jobs is pretty much constant. As far as recruitment is concerned then, maybe for your next project break away from the norm and use a non-mainstream language? Is it time to hire you some Haskell?

Read Full Post »

Older Posts »

%d bloggers like this: