101 Steps to Build an Effective Coding Team
There are plenty of great blogs on general management skills, and I’m not going to regurgitate their combined wisdom here. Instead, I’m going to focus on the 1%: those pressures, priorities, and problems that uniquely affect software developers, and how you can use knowledge of them to build a happy, effective team.
Coders are, first and foremost, people, and 99% of the triumphs and challenges of managing a team of them will be those same triumphs and challenges of managing any team.
We’re going to start at the very beginning, so in this blog, we’ll be looking at the recruitment process, and how to go about hiring software developers and build an effective coding team. This blog also explains the 101+ New Team Hacks in 2019.
Do you actually need a coder?
Imagine the situation: your organization needs a piece of software, and there’s not the capacity in-house to write it. The software is important enough that, for once, money is made available by the brooding guardians of the company coffers to solve the problem, and you are tasked with spending it appropriately. What’s your next move?
If your gut instinct is to spin up a job spec and start calling recruiters, then hold your horses. Hiring software developers are hard. There’s a perennial shortage of tech talent.
Furthermore, a new permanent employee carries financial and organizational overhead, and are you sure you’ll know what to do with them once the current project is complete?
It might very well be that the best thing to do is to go ahead and start hiring, but before you jump to it, always make sure to run through the list of alternative approaches, just in case there’s a better way of doing things in this particular case.
If you’ve decided that to get what you need you’re going to have to build it, your next decision is whether you’re going to grow your in-house team, or whether you’ll pay someone else to build your software for you.
This isn’t an entirely binary decision: depending on the sort of “someone else” you work with, the line between in-house and outsourced can be a little bit blurry.
At one end of the spectrum, you could work with a software consultancy or development agency. This will be an organization that takes on projects building bespoke software for other companies.
They may do fixed-price-per-project work, or they may offer a quote at a daily rate for a particular specification, or they may suggest, if they’re a more Agile-leaning organization, a weekly rate for X hours of work per week and say, “We’ll work with you until you don’t need any more work done.”
You would expect such an agency to do their own project management, and they won’t normally do their work on your premises by default, but will normally offer on-site work if that’s a requirement.
At the other end of the spectrum, you could hire a contractor. This will be someone who joins your company for a fixed period of time, normally paid on a daily or even hourly rate, whom you can set to work on anything you choose. Typically the terms of the contract will not specify a particular deliverable that they must produce, just a duration of the engagement.
Generally, contractors are lone wolves—you can hire several of them, but you’ll still have to do the work of project managing them—although you could hire a manager on contract to do that as well. The default assumption is normally that contractors will work on-site, but there are plenty of exceptions.
In the middle are all sorts of alternatives. Freelancers tend to be individuals who behave more like agencies, quoting for and taking on complete projects by themselves.
Contractor teams are more like a multi-buy promotion on contractors, with the added benefit that they often know each other, have worked together before, and include their own manager.
Then there are agencies that are really just account managers, who outsource all their development work to contractors and freelancers they find themselves, and so on.
How do you choose between these options? One factor is the extent to which you know what you’re doing.
If you only know vaguely what you want, and have no idea how such a thing would work technically, agencies can offer significant value: part of what they do is working with you to build specs. Some will offer to do the UX and graphic design as part of their service.
Normally they will design and propose a technical architecture to suit the requirements of the project.
Contrast that to a contractor, who will often have a very particular set of technical skills, but will only know how to employ them as directed—you will need to provide them with the spec and the design, and in some cases, it’s best if you can have the architectural requirements predefined too.
If you have an in-house team of coders and strong opinions as to how new software should be built and integrated, a contractor will be better suited to work closely with the in-house team to ensure that what is produced is up to scratch.
Because there is normally better visibility on what contractors are working on as they do it, whereas agencies tend to prefer to work separately until the project is finished and ready to hand over.
Agencies also tend to reduce the amount of time you spend on hiring, and they have more resource flexibility to cope with change.
This is because they already have a pool of developers whom they can divert to your project as needed, whereas each contractor needs to be hired one by one by you unless you’re lucky enough to find a pre-packaged team that matches your requirements.
This resource flexibility comes at a premium, however: agency rates tend to be higher per developer-day than contractor rates.
But if you’re thinking about money, be aware that both agencies and contractors can be significantly more expensive than permanent, in-house employees, even taking into account the overheads incurred for permanent staff.
Money isn’t the only reason you might prefer not to use an external developer. For one thing, contractors and agencies get to leave at the end of a project— they’re not going to be the ones who have to deal with the clean-up.
This causes an occasional tendency towards shortsightedness, and a willingness to accumulate technical debt for the sake of hitting upcoming deadlines.
Sometimes this means taking decisions that add less value in the long term. For another, particularly when working with agencies, the quality of the code can be questionable simply because the agency can assign whichever developers it chooses to any given project—including the most junior, inexperienced, and bad decision-prone.
Finally, the process of working on a piece of software involves building up a complex mental model of what’s going on as well as a nuanced understanding of what everything does and why it all is the way it is.
This knowledge is invaluable when making changes down the line. If you outsource your development, that knowledge will build up in the heads of people who won’t necessarily be the ones who come to make those changes.
If you do decide to go down the route of outsourcing there’s one other decision to consider. It’s pretty common for businesses to outsource development to offshore agencies—that is, companies based in other countries where living costs, and hence wages, are much lower, leading to pretty cheap quotes for work.
This can be a very attractive notion since there’s no obvious need for an outsourced software team to be located in the same country or even the same time zone as their clients.
Offshore development agencies, however, have a pretty poor reputation in developer circles, at least in the USA and UK.
A large part of this, make no mistake, is because local software developers have plenty to gain from giving remote developers a poor reputation: if it were universally acknowledged that offshore teams did just as good a job as domestic ones, the price difference would put local developers out of work.
Nevertheless, there are pitfalls and problems when working with a team based in another country.
First, if an organization is largely based abroad, it’s much harder to assess the quality of the team and the standard of their work—you can’t pop by and ask to chat to some of the developers to get a sense of whether they know what they’re talking about or not.
Second, since their key selling point is their cheapness, foreign firms will try to optimize towards that selling point: there’s always going to be a self-perpetuating stigma when it comes to quality compared to domestic teams, so it’s in their interest to keep the focus of their pitch squarely on their more attractive pricing.
If the conversation is about quality they will always be at a disadvantage, so they need to make the conversation be about price. So they are actually more likely to hire cheap substandard devs to keep their costs rock-bottom.
Most importantly, though, the thing that has project managers tearing their hair out the world over when it comes to working with remote teams is communication.
You don’t appreciate it until you go without, but face-to-face communication really helps avoid misunderstandings—facial expressions and body language provide subtle emphasis and nuance that can help correct people’s natural sloppiness in speech. Take those away and people quickly stray off the same page.
If the client’s first language is not one of the developers are fluent in, the potential for misunderstanding doubles.
Put the development team in a different time zone so that there are large periods of the day where one party can’t contact the other to deal with queries and clarifications, and you’ve got the potential for things to get messy.
I don’t mean to put you off working with offshore teams. I’ve had very successful results with them in the past, and there’s no denying the cost savings. However, it’s important to realize that if you work with them, establishing effective communication should be treated as a challenge to address early.
How to look for a coder
If you take the decision that you do indeed need to hire a permanent member of staff, it’s time to start hunting for one. Make no mistake, finding a software developer can be hard.
Almost every industry moans about the shortage of technical talent. According to some estimates, 30% of enterprise software projects fail simply because they can’t be resourced.
The problem is a straightforward supply/demand imbalance. Software development has become an essential function in any business of any significant size—to the extent that some claim that software development is the blue-collar job of the future.
And yet this demand and the ensuing remuneration and career security benefits it entails hasn’t yet had a chance to drive sufficient numbers of the workforce towards learning the relevant skills.
As a result, many developers can command salaries far higher than seems reasonable, simply because of the scarcity, and employers often find themselves in bidding wars to attract talent.
This means that in many cases you’ll need to put some care into how you go about advertising a vacancy because it’s not always a case of sitting back and waiting for a flood of great candidates to come to you. The first thing to look at is what your role requirements are.
The thing about hiring coders is that normally you won’t actually have many requirements, and a very common mistake is to fabricate requirements to make the job spec look more “professional.”
I believe that this is partially the fault of internal job spec templates, which normally have a very long section of empty bullet points under the “Skills and experience required” heading, the implication being that you need to come up with content for every bullet.
This causes people hiring coders to put together a list of every tool, framework, and the process they use and describe the experience with each of them as a requirement, simply to put together content to put on the list.
The truth is, however, that the right candidate might never have worked with any of those tools, frameworks, or processes before, and if they see those things required on a job spec they might never even send in their resume.
Joel Spolsky recommends that the only two qualities a prospective technical hire needs to have are: (a) being smart, and (b) getting stuff done. If they have those, they can pick up any other specific knowledge along the way.
I would argue that while in the long term this is generally true, most of the time when you’re hiring you to have a specific task or project that needs to be undertaken urgently, and you’re looking for someone who will be able to make a big contribution in the short term.
To do this, they are going to have to have some prior knowledge of, and experience in, the technology involved. But, I would strongly argue, what really matters is just familiarity with the particular programming language(s) involved.
Everything else—frameworks, tools, third-party services, processes, industries—is the knowledge that can be picked up quickly enough by a good coder who knows the language, and you’re severely limiting yourself if you make the prior experience of it a requirement.
Once you have your job spec, you’ll need to advertise it, and you may find that simply sticking the role on your company’s website isn’t enough, even if your company is known to be cool and trendy and everyone wants to work for you.
The reason is this: if I were to look for a project manager job, I might make a list of companies I was wanted to work for and browse their careers pages to see if they were hiring for PMs. This could be a relatively efficient strategy because if any happened to be hiring PMs there’s a decent chance that I’d be a good fit for what they needed.
However, if I were to look for a coding job, it would be a terribly inefficient strategy, the reason being that if any of the companies I was interested in were hiring coders, they probably would be looking for experience with a specific language, and it probably wouldn’t be one of the ones I’m proficient in.
For a coder, the most effective way to job search is first to filter available jobs according to whether they require one’s skill set, and only then to narrow down to companies that seem interesting.
Coders, therefore, make heavy use of tech job boards. Which of these are the most popular is constantly changing, and different ones are better for different types of technology and industry, but any site that lets you put in a particular programming language as a keyword is going to make the job-seeking developer’s life easier.
Equally, you may find it fruitful to try to wheedle your way into an appropriate developer community.
If you’re based in Iowa and you need to hire a Java developer, have a look to see if there’s an Iowa Java users’ mailing list that is amenable to job postings, or if there are local meetups for Java developers where you could send an ambassador to try to attract candidates.
If you can get an “in” to a community of developers who have the right sort of skills to suit your needs, direct contact with the community can throw up viable candidates.
Finally, you may, of course, want to engage with a recruiter. A word of caution on this: a good recruiter will not only post your ad onto the most appropriate job boards, but they will also be continually reaching out to developers via multiple avenues to establish a pool of talent, such that at any one time some of their contacts will be actively looking for work.
They will have the technical knowledge to be able to distinguish a suitable candidate from an unsuitable one, and they will work with you to define exactly what you need so that each candidate they send you is a better fit than the last.
However, a bad recruiter will take your requirements verbatim and post them on the same job boards that you would use yourself and do no more work than that;
They will push every candidate that applies to them on to you and dress up each one as a perfect fit whether they are or not; they may even alienate good coders with pushy sales tactics to pressure the candidate in ways they find repellant.
I have yet to find a reliable way of distinguishing a good recruiter from a bad one short of working with them and finding out firsthand, sometimes at my cost.
I would recommend at the very least that you try to get recommendations for recruiters from people you trust who have had successful relationships with them in the past.
[Note: You can free download the complete Office 365 and Office 2019 com setup Guide for here]
How to interview a coder
You put together a job spec, you publicize it through appropriate channels, and some developers decide to apply. Next, you have to figure out how to evaluate your applicants to work out which (if any) to offer the job too.
You have to establish who is the best fit to suit your needs and whether the best-fit candidate is, according to some absolute criteria, good enough.
The first filter you will apply is via the initial application itself. To gather the data you need you could simply ask candidates to submit a resume and covering note;
You could require them to fill in an online form asking them for all the details of their resume but forcing them to write it out again, field by field, in the format dictated by the form;
You could even require them to write several short essays on everything from “Why are you passionate about working for our company?” to “If you were a type of sandwich what sort of sandwich would you be and why?”
I would strongly advise against either of the latter two approaches, on the grounds that anything that makes it harder for a coder to apply might put them off applying at all, and you might just lose out on an ideal candidate. You might respond that you only want to hire people who are passionate about working for you, and anyone who’s too lazy to fill out your carefully crafted form clearly lacks that passion.
However, remember that coders tend to look for jobs by seeking out vacancies that fit their skill set rather than finding companies they want to work for and checking for their vacancies. This means that most of the time, coder candidates don’t know very much about the company at the time they apply for the job.
It might be an organization that they can and will become enthused and even, indeed, passionate about, but if that happens it’ll come as they get to know the company, which should happen through the interview process.
Assuming, then, that you keep the application process as simple and easy as possible, soon you’ll find yourself with some resumes to evaluate.
As quickly as possible you want to establish whether each candidate has sufficient experience with the right technologies, and for this, you may need the help of an existing in-house developer to interpret each career history.
If this is your first hire, you may need to “borrow” a developer to help you do this screening, either from another company you’re friendly with or through any technically-minded contact or friend whom you can coerce into helping you out.
Once you’ve weeded out the candidates who very obviously don’t have what you need, there are really only two questions you need to answer for the remaining contenders.
Do they have the technical smarts to get done at a reasonable speed the things you need doing, and do they have the social smarts to do it in a way that contributes to the harmonious running of the company?
Of the two questions, the first will again require the help of a developer: if you don’t code yourself, you can’t be expected to assess someone else’s ability. There are a few different approaches to technical evaluation, each with their strengths and pitfalls, and we’ll look now at the most common ones.
First of all, you could ask each candidate to provide a portfolio of prior work for you to review. In some respects this is the lowest-friction approach, as it requires no additional work from the candidate: all you want to see is things they have already done in the past. However, it’s hard to get a really clear sense of a developer’s ability via this approach.
For one thing, any code written in a professional environment will have been written collaboratively in some sense, whether multiple people have worked on the same file at different times, or the candidate was pairing with someone else when writing something, or whether someone else reviewed the code and provided feedback that caused the candidate to change their original contribution.
If the code is good, you won’t know if that’s thanks to the candidate or despite them. (If the code is bad, and the candidate had any hand in it, that is, however, a red flag.)
For another thing, if they have worked on a large code base, the whole thing will probably be slightly bigger than your assessor has time to assess, but an extract from it will be hard to assess without context.
Finally, and most crucially, most developers spend most of their time writing code that is private and proprietary to their employers, and it would be a betrayal of trust for them to share it with other companies. Therefore any remotely ethical developer probably won’t be able to let you see the best and most recent code they have written.
Another approach is to set a coding challenge in an interview. This will be some small, normally somewhat contrived, problem to be solved by writing code. This allows your technical assessor to see not only what sort of code a candidate writes when working by themselves, but also how they go about solving a problem.
The first difficulty with this approach is that by setting someone a time-constrained challenge under observation you’re creating an artificial, high-pressure situation, and some great coders respond very badly to that sort of pressure.
Equally, it can be very hard to design a sufficiently small, self-contained challenge that requires the sorts of skills that you want day-to-day from a coder:
often, technical challenges end up falling back on the sorts of questions about algorithms that give an unfair advantage to people who’ve studied algorithms in a computer science degree in college (which, by the way, will probably not be a majority of your candidates).
Or more real-world problems that unfairly advantage people who’ve happened to deal with that particular problem in their previous positions.
To set a more realistic task, sometimes the challenge is to do a piece of work that your business actually needs doing.
As a candidate will normally be being exposed to your company’s code base for the first time, they will often need a lot of help getting up to speed with how the existing code works, the nuances of the requirement and the general context of the task they’ve been assigned.
For this reason, real-world tasks are often set as pairing challenges, where the candidate works with a member of the existing development team to complete the task.
This can be a great way to get a sense of how easy the candidate is to work with, and how well they’re likely to get on with the current team.
Unfortunately, it does create a disruptive time commitment for the in-house half of the pair, and even if they are working on genuinely valuable tasks in the interview, they’ll still be moving slowly.
It’s also hard to find a series of tasks that need doing just when a candidate comes in, that is small and self-contained enough to be suitable for an interview challenge.
Also, it does mean giving a candidate access to your code, which, depending on how you handle IP and trade secrets, may be problematic.
Finally, there is the take-home challenge. By giving a candidate a technical challenge and asking them to complete it in their own time you remove the artificial exam conditions and you can set a longer, more in-depth (and therefore less contrived) challenge than an in-person one without requiring more time from your in-house devs.
That being said, you mustn’t set too long a challenge, because there’s only so much of their free time that a candidate will give up to try to impress you.
You also cannot guarantee that the candidate won’t get help, or try to find someone else’s solution to the same challenge online.
You can counter this to a certain extent by asking some additional questions about the challenge in person after the take-home test has been completed, to see whether the candidate understands what they’ve written sufficiently to extend or improve on it.
The take-home approach also won’t give you as much insight into how a candidate works (although you can ask them to use version control to enable you to view in what order their code was built, which gives you some idea of their process).
There is no perfect approach to a technical assessment; however, that doesn’t mean there’s any excuse not to bother.
I’ve seen seemingly perfect resumes which turned out to belong to candidates who had literally no idea what they were doing—either they had grossly misrepresented their previous roles, or they had clearly been terrible at their past jobs. I wouldn’t have found out had it not been for a technical test.
The other part of your assessment process is to find out whether the candidate is someone who could be an effective member of your team, quite apart from their technical abilities. Really, what it comes down to is whether they can communicate clearly and whether they can play nicely with others.
On the communication front, you’re going to be particularly interested in how well they can translate from computer-speak to people-speak. To see how good a candidate is at this, all you have to do is ask them about their previous experience.
You don’t need to understand what it was they worked on at their last company based on what they put on their resume. In fact, it’s best if you start off not understanding.
If a candidate has written on their resume something abstruse about their last role like, “converted a monolithic API into a functional SOA using AWS Lambdas”, a legitimate and healthy question to ask is something like: “Can you explain to me what a functional SOA is, and why is it preferable to a monolithic API?”
You could also follow up with: “So what are AWS Lambdas, and why did you use them?” You’ll gain absolutely nothing by pretending to understand something deeply technical; conversely, the challenge you can set the candidate is to make you understand something deeply technical via their explanation.
If they can do all manner of marvelous things but they don’t know how to talk about them, that’s a red flag.
In a similar vein, be very wary of any candidate who comes across as a genius. We, humans, tend to err towards ascribing intellectual prowess to anyone who uses big words and talks about things we find hard to understand.
However, when it comes to coders, the ability to throw around big words and to wow non-technical people with complex-seeming things signifies neither intelligence nor skill.
Whereas the ability to take the real-world technical problems one has worked on in a professional capacity and explain them in terms so simple a five-year-old could grasp them, that can mostly only be done by someone who is very smart and has a great understanding of their subject matter.
When you interview a coder, be more impressed by the use of small words than big ones.
Finally, when it comes to whether a candidate can play nicely with others, you’re looking for exactly the same evidence of being personable and self-aware that you’d be looking for in any role. You just need to be slightly more on the lookout when interviewing a coder.
The reason for this is that, unlike in other career paths, you don’t have to have people skills to have amassed an impressive coder career history. But people skills nevertheless are very important in a coder.
Therefore there’s a slightly elevated likelihood that a coder candidate will be a sociopath. The normal checks still apply: Do they seem to have a sense of humor? How do they respond to being challenged?
To being disagreed with? Do they display contextual awareness? For example, if your standard interview questions include the “What’s your greatest weakness?” chestnut, what you’re really doing is inviting the candidate to play a game whereby they have to come up with something that at first sounds like a weakness but actually is a strength.
If they try to bluster and just give you strength, or deny they have weaknesses, they’ve misunderstood the game, because they haven’t appreciated what the question is actually asking, given the context is a job interview.
Likewise, if they’re too honest and tell you an actual weakness, they’ve not picked up that, given this is a job interview, when asked for a weakness the correct answer is not actually going to be a weakness.
Equally, if they do produce a weakness-that-is-a-strength, think of that as a point in their favor, whether or not you actually believe they really have that strength. It shows they’ve understood the rules of the game.
One more general piece of interview advice that a very wise person pointed out to me: most of us tend to form first impressions very quickly, and we find it very hard to shake them.
Therefore if you’re trying to assess someone’s general character, there’s no point interviewing them for more than five minutes (enough time to form a first impression) unless you’re going to continue to interview them for at least an hour (enough time for the first impression to be supplanted by the weight of actual empirical evidence).
Unless you genuinely believe that your first impressions are always reliable, don’t rush the interview.
How to get a coder to say yes
It’s all very well finding the perfect candidate who meets all your requirements and whom you would love to have on board. Unless you are fortunate enough to be in an area with only a few employers working with your particular tech stack.
There’s a very good chance that whoever is applying to you is also applying to several other companies, and they may well end up in a position to choose between working for you or picking another organization—possibly even a competitor firm.
You would do well, then, to ensure that your company is attractive enough to make you the no-brainer option. I’m not going to lecture you with my own opinions on what makes an organization a good one to work.
What I will briefly cover here, however, is what benefits and qualities you can advertise that will likely be at the forefront of a developer’s mind when choosing a new position.
The first thing and this one is criminally overlooked by far too many technical departments, are the people. Writing software is an intensively collaborative process, and when you’re part of a software team you spend the vast majority of your time only interacting with that team. If you don’t get on with the people, you won’t get on with the role.
It’s really important, whenever you want to offer a coder a position, that you make sure they have had a chance to meet any existing team members, and by meet I mean more than an in-passing introduction during a quick office tour.
You have to convince a potential hire that they will like your team, and if that means bullying your team into being on artificially good behavior when they meet candidates then so be it.
Similarly, for goodness sake, show your candidates where they’ll be working. Let them build up as clear a picture of what their life will be like so that they don’t have to worry about risks and surprises.
If your office is a horrible mouse-infested dingy basement and you’re not proud of it, then stop trying to recruit right now. Spend all your HR budget on improving working conditions; otherwise, you’ll never retain any developers you hire for long anyway.
Next, ask about what caused a developer to leave their last role, and aim to reassure them that whatever they didn’t like in the last place, you don’t have here. Developers often hop from job to job every few years.
There’s no stigma attached to switching from place to place as a coder in the way that there is in other job functions. Therefore, it’s common for developers who have adverse working conditions to try to better their lot by switching company rather than sticking it out and hoping for change.
It is often the case that job-hunting devs think not only about what they’re looking for but also about what it is they’re aiming to get away from. They’ll often tell you what’s on their mind if you ask, and if you can offer an environment that doesn’t have whatever particular peeve put them off the last place, highlight that fact.
Finally, be aware that coding is the lifetime pursuit of technical expertise, and coders will very often be aiming to use their next job to expand not only their depth of knowledge but also their breadth.
This can create a slight tension between your goals in hiring someone and their goals in being hired. You’re looking for coders who already know the technologies they’ll be working with. They might instead be looking for opportunities to work with technologies that they don’t know.
It’s therefore wise to dangle the carrot of opportunities to work with new things, even if the primary need you have right now is for them to do more of the same.
Build vs. buy
Here’s the thing: most software isn’t unique. Most businesses have similar needs in their internal, B2B, and B2C functions, and there are normally many different software products designed to meet each of those needs.
Even “disruptive” tech startups that are proposing business models that no one has ever tried before in their particular industry tend to offer pretty similar functionality: an online shop, a profile-creation app, a marketplace.
The very few “deep tech” companies that are genuinely doing certain technical things for the first time aside, it’s normally the case that whatever it is that a business wants software for, there’s already at least one piece of existing software that does something pretty similar.
So why not use one of them? For internal software this is pretty straightforward—either the pre-existing thing is free and you can just set it up and use it, or it’s pay-for, in which case you need to compare its cost to the cost of building it yourself.
Either it’s something you run on your own computers and servers, or there’s a component that runs on an external party’s servers.
For external-facing software, it’s more complex, because you may want your customers and clients to interact with something with your brand on it—in which case you’ll only be able to use pre-existing software if it’s appropriately customizable, i.e., if it’s what’s called “white label” software.
That, of course, is a very broad generalization, and we’ll dig into it more in the next section, but as a rule of thumb, expect the hiring process to be difficult unless you’ve direct evidence that your particular needs are easy to recruit for.
The biggest advantage of using something off-the-shelf is that it can save a fair amount of money and a fantastic amount of time. You can often get yourself 90% of the functionality required for only a fraction of the effort.
Equally, the off-the-shelf software will normally already have been used for thousands of hours by other companies, meaning that all the major bugs in it should have already been spotted and eliminated, so that you should get reliable software from the get-go.
The first problem, though, is that last 10% of the required functionality. If you start by making a list of what you want and then go looking for a piece of software that matches it, you’ll almost never find something that entirely matches your list.
If the missing items are all more like requests than requirements then you may be onto a winner; however, if there’s a gap between what you get and what you genuinely need, then things will start to get painful because you’ll have to figure out customization.
Can you bend the software to match what you need? Are there options within the software itself to let you set it up the way you want?
Or is there a way that you can write your own code, either by modifying the source code or by adding some sort of custom-written plug-in, to achieve the desired effect? Will the software provider customize their software to meet your requirements?
Let’s say that you solve the customization issue. The next problem you’re going to have to face is integration. Most software systems don’t work in isolation. Internal tools should talk to each other, otherwise, employees end up manually (and therefore painstakingly and time-consumingly) moving data from one tool to another.
For example, customer-facing services need to wire up to the systems that govern analytics, accounting, sales, customer support, and so on. It’s very rare to be able to integrate off-the-shelf software seamlessly with an existing system.
Even when they offer “full integration” with another tool that you use, that normally means that some data in some situations pass in a certain direction between the software and the tool, and it’s often not quite the data flow you need.
At that point, you’ll have to start looking at whether you can build in ways of getting the information you need in and out, via an API, a set of “webhooks,” or a batch import/export system.
You may have to write some software “glue” to convert information into the right format and push it into the right places between the third-party piece and the rest of the system.
Even if you can customize and integrate a piece of third-party software, and even if once all the effort to do that is taken into account it still works out quicker and cheaper than building your own, you still might not want to go down the third-party route, particularly if you have no control of the source code.
If the data you need to work with is particularly sensitive, you might worry that the third party’s security isn’t up to scratch.
Or their T&Cs may give them the right to view and access your data. Equally, you might worry that they might suddenly raise their prices, once you’ve migrated to their system and are now dependent on them.
Or worse, what if they just go bust? What if they suffer a systems failure and go offline for extended periods of time? Depending on third-party software means trusting a third party, and, while that’s in many cases a reasonable thing to do, it’s not a decision to be taken lightly.
Hiring coders are hiring people, and hiring people is hard, but you probably already know that. Technical evaluation is tricky, and there are no perfect solutions.
The best you can hope for is to come up with a process that will probably weed out the no-hopers, with a minimum of stress and time commitment for your existing team, and without scaring too many good candidates off in the process.
Things That Coders Care About
People who write software for a living spend their professional lives thinking about things that people with other jobs don’t think about, and thinking about them in a way that’s different to how people with other jobs think.
The subject matter and the type of reasoning required to make for a mentality that is distinctive, if not unique.
This is important to recognize if you deal with software developers. Understanding how they work and how they think means you can make decisions that make their lives easier, respond more intelligently to their needs and concerns, and avoid getting in their way.
This blog is all about some specific things that preoccupy software developers, and how you can use knowledge of those things to work more effectively with a team. I should stress again here, as I have done before, that I’m not talking about generalizations about the personalities of software developers.
I have no interest in clumsy stereotyping. Rather, I’m talking about the sorts of things that come to be on your mind as a software developer as an almost inevitable result of the activity that is software development, whatever you’re like as a person.
The forum phenomenon
I’ve said before that most software used by businesses conforms to similar patterns in its functionality. Most of the time it’s about putting data in at one end, and getting those data, or aggregates derived from them, out at the other end, with some effort to make both ends look pretty.
What I want to draw attention to here is that this holds true at the microscopic level of lines of code as well as the macroscopic level of user-facing functionality.
If you take any small chunk of code that performs a particular function in a particular piece of software, you can more or less guarantee that there will be hundreds, thousands, possibly hundreds of thousands, of other software applications in the world that have a similar chunk in them that performs almost exactly the same function.
Those other applications may have completely dissimilar over-all purposes, and be written in totally different languages, but they will have a shared need for a component that works in a particular way—in the same way that a cog in an 18th-century grandfather clock may be exactly the same shape and size as a cog in a 21st-century orange juicer.
Software development is therefore really about the aggregation and integration of lots and lots of little pieces, where each piece in itself is neither particularly unique nor, usually, particularly ingenious. It is in the manner of combination of these bits that the distinctive character of a piece of software lies.
Sometimes the little bits don’t have to be written anew each time. Software libraries are simply collections of reusable bits. Equally, sometimes the need to join the bits up to other specific bits means that the bits have to be shaped in such a way that they can’t be pulled in from a generic library and have to be crafted afresh.
Either way, what this means is that, for the most part, any time you’re stuck trying to solve a particular problem with a particular little piece of functionality, you can rest assured that someone, somewhere has experienced this problem before.
And more than that, you can be pretty sure that someone, somewhere has solved this problem before. At which point, it would be pretty handy if you could contact that person and ask them how they did it.
Enter the Internet
It turns out that if you ask in the right places online, there’s a good chance you’ll get the attention of someone who has experienced exactly the same problem as you and solved it, and who is only too happy to point you in the right direction. Indeed, you might well find you get a response from such a person in less than 24 hours.
Even better, if you know how to look for it there’s a good chance you’ll find online a place where someone in the past has asked for help with the exact same problem you currently have, and someone else has already answered them, meaning you can see the answer immediately.
It is genuinely generally the case that for most things you have to do as a software developer, there is somewhere online a page where someone has asked how to do that thing and someone else has given a clear answer.
Likewise, it is often the case that there is a page where someone has, unprompted, described their own encounter with a problem or requirement and written up how they tackled it, for the edification of any who tread the same path in the future.
Such a prevalence of online information is, to be frank, marvelous, and for a large number of developers, regular consultation with this ‘hive mind’ forms part of the basic workflow of getting code written.
But while it’s easy to blindly and unquestioningly accept this digital bounty, you do have to wonder: why is all this information online?
Why do coders take the time to document their knowledge publicly, either spontaneously or in response to a request for help from another anonymous coder somewhere out there on the Web?
Part of the reason is that there is a popular platform available to facilitate such exchanges. Stack Overflow is a forum specifically designed to make it easy to ask and answer questions about code, and it boasts seven million users. Google a coding question and there’s a good chance that a Stack Overflow page will be the top hit.
Because it’s already established as a source for answers, a good number of developers spend a lot of time on the site, and contributing answers form a logical next step from asking questions.
But there’s more to it than that. Stack Overflow gamifies the process, and how it does that is quite revealing: the more you contribute to the site, and the better other users judge your contributions to be, the more points you gain.
These points, in turn, allow you to contribute in more and more ways, slowly changing from a mere user to something more akin to a moderator or editor. But, and this is the key thing, Stack Overflow points aren’t called “points.”
They’re called “reputation.” And this is what it’s really all about: answering questions on Stack Overflow is about publicly proving one’s knowledge and ability.
Every Stack Overflow user has a public profile that shows off their numerical reputation, as well as the most popular information they have contributed and the particular achievements they have unlocked.
Even though Stack Overflow is the only place that has a formal calculus for defining one’s reputation, the concept of public contributions of information as a way of enhancing status extends far beyond that one site.
Huge numbers of developers have or contribute to a blog—which may be entirely personal or may be run by their employer—which comprises nothing but posts about technologies used and related problems solved.
These sometimes take the form of a review or narrative (“These are my experiences of using technology X”), and sometimes an explicit tutorial (“This is how to do particular thing Y using technology X”).
Such content is almost never monetized and exists purely as a way for the author to demonstrate publicly their expertise. Sometimes this is motivated by a desire to make oneself more employable, but for the most part, it is about boosting one’s reputation for its own sake, so as to be respected and taken seriously by the coder community at large.
It seems to me that there’s also one further reason why coders are likely to share their knowledge so freely with other strangers online. Being a coder can be isolating in a company where most of the other employees aren’t coders.
Your problems are nothing like your colleagues’ problems, even the language you’d use to describe those problems may be incomprehensible to them.
You’re living in a separate world to your non-technical peers, and even if you spend all day around them, you can end up feeling quite lonely.
Connection to and interaction with an online community of people who understand the sort of thing you’re working on day to day can be comforting and can scratch an itch that is missed by interaction with non-technical people. Contributing answers and tips is a way into this community.
So: that is what the forum phenomenon is. Knowing this, what can you do to make your team more effective? I think there are three practical conclusions to draw.
Most immediately, give your devs free access to the Internet. I’ve worked in places where the IT policy included a blanket ban on all online forums, enforced by automated content filtering on the company internet connection. This makes life needlessly hard for developers.
Equally, as mentioned in the previous blog, accept that not only is Googling things a necessary part of software development, it is also an important skill— if you’re bad at searching for information online you’ll be a worse coder than someone who is otherwise similar but has better “Google-fu.”
Therefore not only is it important to allow developer candidates access to the Internet if you do on-site coding challenges as part of your interview process, it’s also potentially valuable to set a challenge that requires some searching, so you can see how good they are at that.
Finally, think about whether you want your developers to be parasites or not. Parasites leech off the global developer community, taking advantage of the pool of information online but never contributing to it.
Technically they get the most reward for the minimum effort (compared to their opposite, someone who answers other people’s questions online all the time but never looks online for solutions to their own problems).
But as we have seen, developers’ inclinations to contribute to a pool of knowledge online is a sign that such contributions are very positive, and can contribute to developer well-being and satisfaction. It’s up to you to consider how much you want to encourage your developers to contribute to the pool.
That encouragement could take the form of setting up a company tech blog, signing your team up to relevant tech email discussion groups, or simply letting them post answers on Stack Overflow on company time. I believe that encouraging a level of active participation in the global online community is good for developers.
The Hype Cycle
If I were, to sum up this section in a single sentence it’d be: people get disproportionately excited by new things, so be wary. So far, so “duh,” but in the context of technologies used by software developers there are three different things to be wary of, and I want to help you identify all of them.
The thrill of the new
Let’s start with Gartner. Gartner is an American research firm who specializes in analyzing the potential of current and forthcoming technologies. They make predictions about which technologies will achieve broad adoption and when. To aid them in this they have a standard model they employ, which they call the Hype Cycle.
I love everything about the Hype Cycle except the name, which is hugely inaccurate because it isn’t a cycle, and what it models isn’t hype but visibility, which isn’t quite the same thing.
Quibbles aside, the Hype Cycle is a graph of visibility over time, with a curved line on it. The line starts at zero visibility, then shoots up sharply, in a phase called the “Technology Trigger.”
This represents the appearance of new potential technology, and the subsequent media interest it garners. (Think about those exciting articles you read that start something like: “Scientists at the Delft University of Technology have found a way of storing 3D video data in micro-carvings on the epidermis of a dung beetle…”).
The line rises to something called the “Peak of Inflated Expectations,” which is where the whole world is talking about this new technology and thinks it will solve all their problems, despite the fact that the technology is massively immature and very few people have actually successfully used it. Inevitably, the technology fails to live up to the hype.
It doesn’t cure a common cold or magically makes everyone’s jobs exponentially more enjoyable. After a few public failures and snippy editorials, people stop talking about the technology altogether and move on to the next big thing, and the graph of visibility drops way back down into the “Trough of Disillusionment.”
The tech doesn’t disappear, though. In the background, away from the media spotlight, technologists continue to work on the technology, ironing out the problems with it, discovering the most practical uses and adapting it to best suit those uses. Over time, more and more people start using it, and start talking about it more.
The visibility curve slowly rises, in a phase called the “Slope of Enlightenment.” Finally, the technology reaches maturity and starts being used and discussed in proportion with its actual merits, and the curve flattens off in the “Plateau of Productivity,” which is where it reaches stable mainstream adoption.
Gartner believes this model can be applied to the emergence of any technology. What varies is the absolute height of the peaks and troughs, and, more importantly for them, the timescale over which the technology will pass through the five different phases.
In their research reports they can paint a quick picture of the technology landscape by placing new technologies on the curve according to their current state, and for each one giving an estimate of the time, in years, to mainstream adoption.
For example, in their 2017 summary of emerging technologies, they placed machine learning at the very apex of the Peak of Inflated Expectations, estimating 2 to 5 years until mainstream adoption, while augmented reality wallows in the Trough of Disillusionment, with 5 to 10 years before it reaches the end of the cycle.
To me what is most lovely about this model is not the specific predictions that can be made about particular technologies.
Instead, I like the fact that, in very general terms, the broad shape of the model holds true for pretty much all technologies that end up being widely used (the ones that don’t achieve wide use disappear before they’ve had a chance to reach the end of the curve).
It’s what the cycle tells us about the enduring properties of people, rather than the transient properties of technology, that I find fascinating.
In particular, it tells us to be wary of our tendency to fill in the blanks of a positive-seeming picture in an overly positive way.
If something seems like it has potential, but we haven’t seen it in action yet, we lean towards imagining that when we do see it in action it will actually surpass its initial potential. We infer an incredible finish from a good start, and we continue to do so despite always being wrong.
What this teaches us is to be chary of a strong desire to use a technology despite never having used it before, especially if it’s a new technology.
Even if the technology is a great one, the instincts of the desirer may be being driven by these ubiquitous inflated expectations, in which case care must be taken when evaluating the merits of adopting that technology to counteract the bias of attraction.
Several times in my career I’ve seen a developer make the case passionately and insistently for using a particular technology, and through the strength of their own convictions, convince their colleagues and superiors to adopt that technology, only to discover in hindsight that that adoption was a bad call.
Sometimes it’s been because the technology has turned out to be fundamentally flawed, sometimes because it was immature and missing certain key features, sometimes because it was simply the wrong tool for the job, and occasionally because is was absolutely fine.
It’s just that in the final analysis the pain of changing everything to accommodate the new technology wasn’t quite offset by the benefits the new technology brought.
So, the first wariness is this: Be wary of the new, because it might not be as good as you think it is. The newness may be blinding you. Whenever possible, wait for the hype to die down.
Wait for the technology to become boring, old news. If it reaches the point where it’s boring, and it still seems like it’s useful to you, that’s a much more reliable indicator that if you find yourself convincing yourself that it’s useful when it’s the new hotness.
The second thing to be wary of is community starvation. The technologies that software developers use only thrive when there is a community around them. Think about the forum phenomenon described in the previous section.
It only works if there are sufficient numbers of people trying to use the same technologies as you to solve the same problems as you. If you’re using a technology that no one else uses, you’ve got no one else to ask about how to make it work.
Similarly, for open source technologies, the maintenance and improvement of the technologies rely on contributions from lots of people all over the world, and people won’t contribute to something they’re not using.
Finally, if you’re using a particular technology and you need to hire someone to work with you, if it’s not a popular technology you might not find anyone who knows much about it, or worse, you might not be able to find someone good who’s prepared to work with it.
Without a community supporting them, technologies die out, and it can happen pretty quickly. This is because one of the main things that cause a community to abandon a technology is the perception that the technology is being abandoned by its community, and this vicious cycle powers a snowball.
When you adopt new technology, you need to be on the lookout for signs that it could disappear without a trace.
Is it a technology with many up-and-coming competitors? Is it the type of technology area where change happens fast? Is it the first attempt to solve a particular problem, and how likely is it that someone else will come up with a better way of solving that problem?
If you want reassurance that a piece of technology has a stable community, be on the lookout for two things. First, has the community reached critical mass?
A good way of checking this is by looking on forums like Stack Overflow and checking how many discussions are tagged with that technology. Equally, the annual Stack Overflow developer survey tracks trends in technology adoption, and you can look to see whether a particular piece of tech has stabilized over the past few years.
The second thing to look out for is adoption by large companies. Big organizations move slowly, and if they commit to a piece of tech they will probably stick with it for years.
They will hire lots of developers who have to work with that tech, forming the seeds of a community right there, and they probably have the resources to artificially buoy the community, through hiring “evangelists,” sponsoring meetups and conferences dedicated to the technology, or even open-sourcing some of their own tools that complement that technology.
The last thing to be wary of is what’s sometimes called the bleeding edge. This is the edge that’s at the very edge of the cutting edge, the so-new-the-ink-hasn’t-even-dried-on-the-packaging edge.
When a new technology is released, or when a major update is released to an existing piece of technology, the creators will have done everything they can to minimize the number of bugs, security flaws, documentation inaccuracies, and so on.
However, as you’ll probably have discovered if you’ve ever released a piece of software, it’s impossible to catch everything. There will be errata, and the severity of those errata could be tiny or it could be immense. At the point of initial release, while adoption of something new is at its most exciting, it’s also at it’s most dangerous.
A good rule of thumb is to keep an eye on the version number of any piece of technology. number, a minor version number, and a patch number (although the latter two are often omitted for simplicity).
In general, try to hold off on using anything where the minor version number is zero. If you think there’s a strong case for using the newly released Virtual Widget System, if version 1.0.3 is out right now, wait until version 1.1.0 appears.
If TechnoGubbins Framework 5 just got released, stick with tried and tested version 4.6 until 5.1 appears.
Normally when the minor version gets bumped from 0 to 1, that means all the initial bugs have been fixed (as each bug is fixed the patch number will have been bumped up by one), and enough feedback has been gathered about what’s missing to enable a new bunch of features to be decided on, tested, and released, which is what will have bumped the minor version number.
If you wait for X.1, hopefully, you’ll be able to skip all the teething problems that came with X.0.
The last section was about love; this section is about hate.
Software developers have a tendency—not universal, but common enough to be noticeable and deserve mention—to form very strong aversions to particular tools and technologies.
There are several instances where there are multiple options available to do a particular thing, and devs will take an absolutist stance about which is the right option powered not so much by a love of their preferred option but rather by an utterly unrestrained loathing of the alternative(s).
Examples of this include the choice between using the “tab” character versus spaces for indenting text and the editor wars that have been running for decades between proponents of rival text editors Vi and Emacs.
I don’t mean to be dismissive of this sort of debate. There are always sensible arguments to be made on both sides, and the fact that such debates have been running for years demonstrates that there is no shortage of people making ingenious contributions to the discussion.
However, it is interesting to note that these are the sorts of topics that coders very seldom change their minds about: much like modern partisan politics, people first choose which camp they’re in and then seek out arguments to reinforce their position.
For the most part, this sort of debate doesn’t matter very much. The choice of whether to use Vi or Emacs as a text editor is a personal one, and if a coder wants to indulge in some blaring evangelism about their preference they’re not going to do too much damage.
However, sometimes this tribalism expands beyond the trivial, and it can turn into a bit of a force for nastiness.
In particular, one area where developers have a tendency to be mean about choices other than the ones they have made is in the choice of languages, particularly where there are multiple languages that tend to be used to do similar things.
So, for example, C# developers, in particular, tend to be pretty mean about PHP. Java developers say nasty things about Ruby.
This is bad because it’s a small step from being dismissive of a language to be dismissive of people who work in that language. And this sort of nastiness is easily reinforced: people who work in one language tend to work mostly alongside other people who work in the same language.
If they have coworkers who work in a different language, it’ll tend to be a language that’s used to do something completely different, and therefore isn’t a “competitor.”
It’s seldom that a company has expertise in multiple languages that are specialized towards doing the same thing. This means that there’s no one around to defend the language being picked on, to provide coherent arguments in its favor.
Partisan narrow-mindedness is a bad thing anywhere: it’s an unpleasant human habit, and the more you do it the easier it becomes to do. I suspect that coders who make a habit of trash-talking other coders’ languages have a harder time forming balanced, informed opinions about the stuff that actually does matter.
But more pressingly, narrow-mindedness narrows options. While it’s true that anything you can build in PHP you can build in C# and vice versa, sometimes depending on the specific circumstances PHP may be a better choice, and sometimes C# may be a better choice. If your team won’t even consider one of the two options, you will sometimes be forced into the wrong choice.
All of this is enough to make you wonder: why do coders do this, and what can we do to prevent it?
One of the causes for this tendency towards nastiness is a desire to bond. As stated above, developers normally work in teams that all use the same language or languages.
One thing they have in common is not using particular other languages. It’s a short step to setting up an “us vs. them” mentality, which reinforces the similarity of “us” in contrast to “them,” making it easier to bond. It’s just a shame that this is such a toxic way of doing things.
A second cause is the fact that certain languages are more accessible to beginners, because for whatever reason they’re easier to get started with for building simple apps, sites, and tools.
Those languages become associated with beginners, and sometimes that translates to the thought that those languages are only for beginners, while “real” programmers move onto more serious things—even if in fact there are lots of “real” programmers who spend their careers working with “beginner” languages.
This isn’t helped by the fact that beginners write bad code, and if some languages are more accessible to beginners, there will be proportionately more bad code in the world written in those languages than ones that are so arcane and specialized that only industry veterans ever bother to even try them.
It’s another short (but also shortsighted) step from seeing bad code written in a language to dismissing the whole language as bad.
Finally, I believe that a major motivation behind denigrating other languages is fear, specifically fear of obsolescence. Most of the time when coders start hating on a piece of technology, it’s when they’ve invested a large amount of time developing proficiency in a particular another piece of technology, and that hated piece is something that would do the same job just as well.
Text editors like Vi and Emacs do exactly the same thing, and both take a long time to learn to use, but your skills in Vi do not translate to Emacs or vice versa.
Similarly, any website you build in C# you could equally well build in PHP, or Java, or Ruby, but knowing how to code in one doesn’t mean knowing how to code in any of the others.
If you’ve spent a long time learning how to write C# code in Vi, and the rest of the world decides that PHP and Emacs are superior, all your hard-earned ability is massively devalued.
It’s therefore in your interest to undermine the credibility of PHP and Emacs, to ensure that your skills remain relevant given the prevailing zeitgeist.
You’d do well to try to stamp out this sort of tribal chest-beating in your team, but that’s easier said than done. It’s a mindset, and mindsets are hard to change. One thing you can do is be on the lookout for signs of disproportion-ate disparagement, and challenge it where possible. Challenge the denigrators to explore a new perspective.
One question that you can almost always pose whenever someone starts slagging off a piece of tech is: “Why do all the smart people in the world who do use Vi/tabs/Ruby/etc. consider it to be better than Emacs/spaces/Java for their particular situation?”
You won’t instantaneously spur your interlocutor into abandoning their prejudices, of course, but you might just sow the seeds of doubt in their mind that there’s more to the world than their own narrow perspective.
Equally, if you have the luxury of choice when hiring a team member, prefer candidates who have a breadth of experience, and are more likely to have used both Vi and Emacs, or C# and PHP.
The breadth of experience makes for more informed technology choices anyway, but it can also lead to a more open-minded attitude towards the novel and the unknown.
Beauty in code
Think about the last time you saw some lines of code. Would you consider it to be beautiful? Probably not. In fact, would you consider it even possible to apply the concept of beauty to something as dry as computer code?
If your answer is no then you’re in for a surprise, because there is an entire world of aesthetics bubbling away in the process of software development, and in this last section I want to explore the concept of beauty in code.
In previous blogs, we have talked about lots of ways in which code can be bad. We've talked about conceptual models that map badly onto the subject matter of the software, about code “smells,” that are common ways in which code is badly structured and shaped, and about formatting and syntax inconsistencies that make code harder to read.
There really are lots of ways in which code may be badly written, and many of these ways have an effect, direct or indirect, on what the code looks like on screen. For formatting problems, this is quite obvious, but equally poorly structured code at the macro level will affect what the code looks like on the micro level, and likewise uncomfortable conceptual models.
Given that coders spend a large amount of their time evaluating the quality of code—both their own and their colleagues’—they become particularly sensitive to indicators of badness, to the extent that over time they come to perceive the telltale visual signatures of badly written code as being in some sense ugly.
Conversely, code that is well written has a balance to it. There is a regularity to how it is structured, without leading to any unnecessary repetition. It is divided into smallish chunks which tend to hug the left-hand side of the screen,13 and there are a hundred other little shapes and symmetries that indicate that the code has been well written.
To many an experienced coder, the visual appearance of well-written code is so strongly associated with the appreciation of the quality of the code that it is experienced as beauty, and is genuinely pleasurable to behold.
This aesthetic sense can be a significant time-saver. It provides an intuitive, instinctive guide to the quality of a piece of code that can form a valuable heuristic when pushed for time.
Of course, it’s not always accurate. More than once I’ve heard a colleague say something along the lines of, “At first glance, it looked lovely, but it turns out when you get to grips with how it actually works it’s truly filthy.” What this means is that, when it matters, a quick skim of a piece of code is no substitute for a thorough exploration.
But an aesthetic judgment can be an invaluable way of confirming a judgment about quality. For example, when I am writing code, once I have something that works I start rewriting it to make it work well, and I only know that I’m done when what’s on screen in front of me looks pretty.
As long as there is ugliness, I know I need to keep looking for ways of improving what I’ve got.
Where the use of the aesthetic sense runs into difficulty is where different coders on the same team make different value judgments about the same piece of code.
If one person simply thinks a piece of code is well written and another person likewise thinks the code is poorly written, it’s easy for them to have a balanced discussion about what’s good and bad about the code.
However, if one person thinks the code is beautiful and another person thinks the code is ugly, their sense of quality is not just intellectual, it is also emotional, and that makes it much harder to have a reasoned conversation. Gut feel tends to trump empirical analysis.
Such different conceptions of what is beautiful are pretty common among coders. This may sound surprising since I’ve just said that the sense of code beauty isn’t innate but is derived from countless hours analyzing code quality.
The problem is that there is no universal agreement about what constitutes the good code. For one coder, a particular habit or pattern may seem like an effective, concise solution to a problem, and they may come to consider that habit or pattern to be beautiful.
To another coder who is less familiar with the problem, that particular habit or pattern may read as dense and obscure, and they may consider it to be ugly. Or equally, they may have seen how problematic that habit maybe when it is overused and may have been put off it entirely.
Every value judgment is nuanced by past experience, and particularly when a team of developers has all amassed a deal of experience working separately, their collective sense of what’s good, and therefore their sense of beauty, may have an alarming number of discrepancies.
This effect is emphasized by the fact that aesthetic judgments don’t translate well across languages. Some languages require one to use particular structures and formats that are anathema to those familiar with other languages—what is normal in Perl looks like an unbridled nightmare to someone whose sensitivities have been honed by Python, for example.
Equally, even beyond the hard constraints of a language, conventions develop, shaped by the community of users of a language, which can in time create a distinctive style that comes to be considered “best practice,” and therefore beautiful.
Even though according to the standards of a different community based around a different language, that style might be indicative of a highly problematic approach to coding, that therefore looks truly repulsive.
This disagreement over what is beautiful can genuinely slow down a project, because while a coder may be persuaded to write, reluctantly, code that has a structure of whose merits they are not convinced.
Simply because they were outvoted by the rest of the team, they will take an awful lot more persuading to write code that is, by their own standards, ugly.
I’ve seen coders point-blank refuse to take on a particular task because it included requirements about the structure that so flew in the face of their sense of beauty they couldn’t bear to write something that was, to them, so grotesque.
To avoid this sort of problem, it’s useful to encourage your team to develop a consistent coding style.
If they can start with a set of shared fundamentals, and they really pay attention to agreeing and refining the company style, over time they can achieve a closer shared understanding of what’s good and what’s beautiful, and this will lead to fewer squabbles and tantrums.
Where total accord is impossible, allow a little idiosyncrasy to cater to different people’s sense of what’s beautiful.
If one developer is going to own a particular section of code, and they want to do things in a certain way that appeals to their particular taste, then so long as it’s not unintelligible or vomit-inducing to the rest of the team, sometimes it’s best to let them have their way.
But really the most valuable thing is, where possible, to hire coders who have malleable value judgments. That is developers who have worked on enough diverse projects with enough different sets of styles and standards that they’ve got the hang of adapting their sense of beauty to fit their circumstances.
Often this means developers who’ve worked in multiple different languages, but equally, it applies to developers who’ve simply been in the game for a long time—standards shift over the years.
And someone who appreciates that what is considered beautiful code now is not what was considered beautiful code before may also appreciate that so too what is considered beautiful next may be different again.
Keeping Coders Happy
If you’re in charge of a team of software developers—and I hope this isn’t going to shock you—it’s important to keep them happy. Happy coders code faster. Happy coders act as evangelists for your company in their developer communities, making it easier to recruit.
Perhaps most importantly, happy coders are less likely to leave you for another firm, taking with them all of the years of accumulated know-how about your particular software and technology stack that makes them so much more valuable than a new hire.
Given that software developers tend to switch jobs faster than other engineers, business people, and managers anyway, finding ways of holding on to them for longer is particularly important.
In this section, we’ll be looking at ways of keeping software developers happy. As with more or less everything else in this blog, there are no silver bullets, largely because different people are different, and what makes one person happy will make another miserable.
Equally, the stuff that fundamentally makes many people happy—such as surrounding themselves with people whom they love and who love them in return. Getting plenty of sleep, fresh air, and exercise, or avoiding stressful situations and conflict—doesn’t fit very well with being paid to stare at a screen all day in the company of other people who are being paid to stare at a screen.
And lumbered with the responsibility of producing results that materially affect the success of a large organization.
You can’t make all software developers love their jobs, because for some people—even professional software developers—professional software development is an unlovable activity. But there’s plenty you can do to minimize unpleasantness and promote happiness, and that’s what this blog is all about.
A quiet room and a powerful computer
I’ve mentioned Joel Spolsky a few times before in this blog, and, not being one to buck a trend, I’m going to mention him again now. Specifically, several years ago Spolsky came up with a set of criteria for what makes a good software team, which he called the Joel Test.
It focuses on the practices and processes of the team, as well as their working conditions, and comprises 12 questions, each of which can be answered with a straightforward “yes” or “no.”
According to him, a “no” to any question represents a significant issue with the team, such that a team with a score of less than eleven has serious problems.
We’ve covered most of the working practices identified in the Joel Test. For example, hopefully by now if you were confronted with questions like “Do you have a spec?” and “Do you use source control?” you’d (a) know what the questions mean and (b) have some idea of why it’s a good thing to be able to answer “yes” to both questions.
A team that has the sorts of processes that are selected for by the Joel Test is likely to be more effective and more productive, and have fewer of the frustrations that make developers feel like their voices aren’t being heard and their talents and time are being wasted.
(It’s worth noting that, while being happy boosts productivity, being able to be productive boosts happiness, and a smooth process for software development enables that productivity boost.)
But I would also like to draw to your attention the two questions from the Joel Test that focus exclusively on working conditions because they are quite separate from how you work as a team, but their answers can have as significant an impact on job satisfaction and productivity.
The questions are, “Do programmers have quiet working conditions?” and “Do you use the best tools money can buy?”, and we’ll look at them in turn.
Software development requires focus. Intense, all-dominating focus. As we’ve seen, this is because software developers must be thinking about both the specifics of the syntax of each line of code they’re writing along with the overall structure of the conceptual model underlying the software as a whole.
They’re thinking about the visual elegance of a particular piece of code, and how it will interact with several other pieces of code. To write any given line, they need to have five or six different thoughts at the forefront of their consciousness ready to be consulted and cross-referenced.
This makes distractions extremely destructive because all those carefully placed thoughts hanging in the ether inside a coder’s mind are easily displaced. The easiest way to distract a coder is to make noise around them.
Unfortunately, the modern trend towards massive open-plan offices pretty much guarantees noise. Half the time a business’s coders sit on the same desk as people making sales calls all day, and every single “Hi there! Am I speaking to Lucinda Chao?” has the potential to make a coder lose their train of thought.
Let’s be clear: the primary motivating factor behind the open-plan office is financial. You can fit more people per square meter if you don’t put walls between them.
And I appreciate that giving the development team their own room (or, even better, an office for each developer!) is expensive, for some companies prohibitively so.
But there’s also a flawed ideology at work: it’s often assumed that since good communication between developers and their non-technical colleagues is a good thing, close proximity at all times must also be a good thing. (“Let’s build bridges, not walls!”) In fact, nothing could be further from the truth.
In a big open-plan office, some people don’t dare communicate, because they know that talking will disturb all the people around them. Some other people don’t worry about that sort of thing and talk away happily, generating resentment among the people who sit next to them, which closes down the potential for better communication.
And perhaps worst of all, noisy ambient chatter causes lots of developers to shove on some noise-canceling headphones and turn their music up, meaning it’s much harder to get their attention if there is genuinely something that needs saying.
There are so many ways in which a noisy open-plan office is bad for communication and bad for productivity. If you possibly can, give your coders a quiet, distraction-free place to work. They will be less stressed, more productive, and they will communicate better.
The other point from the Joel Test is about spending money on it. This one is a no-brainer.
All software developers rely on computers to do time-consuming things when they’re developing, be it compiling code, running tests, or scanning files for formatting inconsistencies. A more powerful laptop will take less time to do these things than a less powerful one.
Similarly, having two monitors rather than one will save a developer a few milliseconds every few seconds because they can have both the source code and the running software in their line of sight at once without having to switch windows.
That premium analysis tool will make it quicker for a developer to identify the problem than the free version.
In each case, spending money on the right hardware and software will save small increments of time—maybe an hour a week, maybe much more, maybe much less.
If you think about the total hours saved to the developer over a year, multiplied by their hourly rate, most purchases of this sort will justify themselves on purely financial grounds.
But more importantly, think about the frustration of a developer who is being constrained in their work by ineffective tools because their employer is scrimping.
Now think of the pleasure of a developer who is being lavished with the best tools on the market because their employer knows how much value that developer can add if they’re not impeded. Which developer sounds happier?
Time is money, and if you don’t keep track of how your coders spend it, and how much of it they spend, it could cost you dearly. It’s not enough to assume that your team should start work at 9 am and stop work at 5 pm, and leave it at that.
In this section we’ll look at a couple of different ways in which working hours can be warped, and what the ramifications are.
Some developers work best at 8 am. Some developers work best at 8 pm. Some developers work best at 2 am.
You may find that you have people on your team who really struggle to be effective if you force them to work standard office hours. It can be to your advantage to be flexible here.
I once worked for a company that asked for 40 hours of work per week, and for the sake of good communication asked that we all be in the office between 11 am and 4 pm every day, but beyond that was happy for us to work our own hours—some people did the early shift and left at 4 pm, and some did the late shift but only rolled in at 11 am. It was quite a civilized approach.
Equally, in some companies, the coders are allowed to work whenever, and indeed wherever they want. Going to Sydney for a few months? No problem! Log on via the hostel WiFi connection at whatever time you wake up, and be sure to check in on instant messenger regularly, and we’ll make it work.
This can be quite scary for traditional companies with traditional working environments. If you don’t have your team on-site for specified hours, how on earth can you ensure that they’re pulling their weight? Well, the good news is, if you’re being diligent with task estimation,6 this problem should solve itself.
If your team is ticking along completing 25 story points a week, and Luis is tending to contribute about 8 of those story points, and everything is going well, then you already have a measure of what constitutes Luis pulling his weight: 8 story points per week.
If Luis keeps up that pace, then it doesn’t have to matter to you whether he’s working all night and sleeping all day, or whether he’s working from a beach in Cambodia.
In fact, it doesn’t really matter whether he’s getting it all done in 4 hours per day or 10 hours per day. 8 story points per week is a tangible amount of value, and deserving of the same praise and financial compensation regardless of how it was delivered.
Now obviously, such extreme flexibility isn’t going to work for a lot of organizations. And to be fair, it won’t work for a lot of developers.
For example, I personally like the structure of a standard day, and I prefer working physically close to my colleagues, because of the potential for “kitchenette serendipity,” that wonderful thing that happens when colleagues take a break together and bounce problems and ideas off one another.
But by making you aware that such extremes are entirely possible, I hope to make you aware that if you have a developer who doesn’t like being on-site between 9 am and 6 pm every day, a little flexibility may make them happier and won’t bring the sky crashing down on your head.
Feeling the burn
Software projects have deadlines. The dirty little secret that the Agile community tries to conceal is that in the real world you can’t just keep iterating away, one manageable chunk at a time.
Sometimes there is a specific amount of work that has to be done by a specific date, otherwise something very bad will happen, usually money-related.
This means that there are crunches, times when the amount that has to be done won’t fit into the amount of time available in a normal working week, and no amount of careful planning and triage will prevent the need for some long hours.
This is ok. In fact, it can be a good thing. If a team is given a task to rally behind, it can actually be good for morale (so long as the task is achievable), good for team bonding, and generally quite fun.
But it really depends on who is on the team. Some people get exhausted quickly, and while a regular 8-hour day is sustainable for them, a 10- or 12-hour rhythm very quickly isn’t. Some people have inflexible commitments outside of work, particularly those with children.
And some people just have no interest in working long hours. This doesn’t mean that they’re not dedicated, motivated, and productive while they’re in the office. They may simply value their free time more highly than most, and I see no fault in that.
It can be frustrating as a manager not to have a team who’s prepared to work later in a pinch, and sometimes it can lead to hard conversations,7 but it is only naive and petulant managers who assume that it is an automatic response of their team to work radically longer hours just because a deadline looms.
But let’s say you do, in a crunch, manage to get your team to start giving up their evenings and weekends to keep on coding.
Let’s even assume they do it joyfully, delighted to be a part of whatever enterprise it is you’re leading them on. The output should increase, and you should have more to show at the end of each week. You might start enjoying this new state of affairs.
You might even think that, since no one is complaining, perhaps you could try to keep this pace up even outside of crunch time. It’d be great to be able to keep putting out new features that little bit faster, wouldn’t it?
You’re treading on dangerous ground if you don’t slacken off the pace soon. Best case scenario, after a certain amount of time, your team starts to feel like they’re getting tired, they complain, and things go back to how they were. Worst case, they experience burnout, giving rise to some really nasty consequences.
First of all, a coder who has lost that fire will be less productive. The drop in their speed of work will, at the very least, counteract the increased hours they’re working.
And if someone burns out, if they properly, utterly, horribly burn out, don’t assume that all it’ll take will be a week off for them to get back their mojo. A bad experience of being overworked for too long can permanently taint someone’s experience of a team and a company.
For as long as they’re in that team, in that company, they may continue to feel deep exhaustion that kills motivation and productivity.
At that point, if you’re lucky they’ll just leave, and you can replace them. If you’re unlucky they’ll stay, resentful and unproductive, sucking the joy out of the team around them, and dragging everyone’s output down.
Believe me, it’s not worth it. As soon as you get past crunch time, be sure to stop acting like it’s crunch time, and give your team their evenings back.
Old and new
Developers like new things. New challenges, new technologies to learn, new ideas to play with. They like to write new code, and conversely, they often don’t like working with old code.
This dislike rears its head in a couple of different circumstances, and I’d like to look into what they are and how to address them here.
If you have a team of coders who are assigned to a software product, and that product is already available to users, you can broadly categorize the responsibilities of the coders into two types of activity: writing new code and fixing bugs in the existing code.
Bug fixing is often referred to as supporting the product, but it’s worth being clear that it’s not part of the customer support process. Or, at least, it shouldn’t be.
The goal of customer support is to solve customers’ problems as cheaply as possible, and getting coders involved is not cheap. Coders should only really get directly involved in the customer support process if a customer has a problem that’s so obscure and so technical that only someone who actually wrote the software will understand it, which is a rare occurrence.
The rest of the time their interaction with customer support is hopefully more indirect: whoever is in contact with the customers has the job of working out whether their problem is caused by ignorance, idiocy, or a legitimate fault in the software.
If it really is a fault then someone (ideally still the customer support people, or a QA engineer) is tasked with investigating it, understanding it, finding reliable steps to reproduce it, documenting it, and adding it to the bug database. Only then, in a perfect world, does it then make it onto the radar of a coder.
Of course, this isn’t a perfect world. What actually happens is that coders end up in direct contact with users, trying to understand their problems and identify bugs.
Often they have to translate from Luddite-speak (“The website doesn’t work when I click the thingy”) into bug reports, and then end up back-and-frothing with the users to try to get to the bottom of why it doesn’t work for them when it does work for everyone else.
When a bug report is handed to them there’s almost never a reliable repro—instead, they simply learn that for some users, some of the time, a particular unwanted thing happens, and they spend hours trying to figure out how to make the bug appear on demand so they can study it.
Only then can they start actually digging into the code to try to find the cause of the problem. When they finally find it and fix it, they don’t get to bask in the joy of having made something new; all they’ve done is to make something old do what it was supposed to do in the first place.
Small wonder, then, that for many developers support work is despised and dreaded. This isn’t a universal feeling. Some people thrive on the detective work of working out what’s happened, treating the buggy software like a crime scene and the bug-reporting customers as witnesses to be questioned.
Some like the process of spelunking through the code on bug-hunting expeditions, setting up snares to capture and eliminate aberrant functionality. But I suspect that if you asked 100 developers, only a small percentage—perhaps even single figures—would claim to prefer support work to new feature development.
Unfortunately, though, bugs get found, and sometimes they have to be fixed. One approach to this is to hire dedicated support engineers, to protect the rest of the team from getting their hands dirty.
This is problematic for a few reasons. First, unless you have a very large software product, or it’s very, very bad, it’s unlikely that there will always be enough bugs to fix to sustain a full-time bug-fixing role.
Second, if support is seen as the boring stuff, having some people who just get to do the boring stuff, and some people who don’t do it at all, will likely breed resentment unless you happen to find support engineers who genuinely prefer support.
Most importantly, though, the people who will be best placed to fix a bug will be the people who know the most about the software, which will be the people who built it—getting other people to clean up their messes is just inefficient.
In my experience, the best thing you can do with support work is put limits on it, and prevent it from getting in the way of other work. Rather than have your engineers be pulled off what they’re working on every time a new bug is found, set up a bug database.
Make sure that whoever is discovering bugs, whether it be customer support staff or internal users of the product, is given away to report bugs that filter directly or indirectly into that database without going via the developers. Make sure that this database is prioritized in just the same way that you’d prioritize a product backlog.
Finally, allocate a set amount of time to each team member to spend bug fixing, ideally just a few hours per week, and have them only ever look at the bug database during that allocated time.
It could be at a set time (e.g., every Tuesday afternoon having a team-wide Bug Party), or you could simply ask your team to find a few hours each week, whenever they find themselves at a natural pause in their other tasks.
Knowing that each team member has a set amount of time hunting for bugs, you can adjust your expectations for how much new feature development they can get done in the rest of their time.
This way, bug fixing may be a chore, but it’ll be a manageable chore, which is probably the best you can hope for.
Coder’s sense of beauty is both important because it is a tool for sniffing out bad code, and highly idiosyncratic because it is shaped by personal preferences and past experiences.
This means that any coder who spends a lot of time with another coder’s code is likely to find fault with that code. This is particularly true if the code has been around for a long time and is part of a product with real users whose real requirements don’t fit nicely into neat, abstract patterns.
What this means is that coders will almost always be happier building a new product from scratch than making modifications to an existing product, because they want to minimize their exposure to other people’s code.
In fact, coders will often prefer building new things from scratch even to making modifications to an existing product that they themselves wrote, if they wrote it sufficiently long ago: their sense of what good code looks like will have changed since then, and they’ll regret the compromises they made to meet the needs of the business at the time.
The sad truth is that a universally pleasing code is an impossibility in real-world products made for real-world businesses because the aesthetics of code have no notion of time and money constraints.
The trade-offs, compromises, and workarounds that happen when the real world needs to be accommodated almost always result in code that jars against the sensibilities of an informed, experienced coder. We learn to live with such accommodations, but not to like them.
Coders have a habit of labeling code bases they don’t want to work on as “legacy” code, a term with derogatory connotations. Generally speaking, a piece of software stands a good chance of being dismissed as “legacy” if it meets any one of the following conditions: (a) it’s more than two years old,
(b) its chief architect is no longer actively working on it, or (c) it’s built using at least one technology that the person describing it doesn’t like.
You could keep a team of coders pretty happy if you could prevent them from ever having to work on the legacy code.
If every time a new feature was wanted, the entire product could be rebuilt from scratch using the latest technologies and most popular architectural paradigms, or the feature could be put into an entirely separate, self-contained new product, you’d create an environment free of one of the most common sorts of coder frustration. However, that’s pretty much impossible.
If you have just one software product, then it’s highly unlikely that rebuilding it from scratch will add more value than adding new things to it.
And for businesses that regularly build a series of new products, it’s almost never the case that it’s possible to completely stop work on a product once it is released. There is so often a demand for updates, bug fixes, new features, additional integrations, and so on.
The best advice I can offer, therefore, to stop legacy code from getting your coders down, is to advocate a modular structure to your product’s code.
I know that the architecture of your software will be outside your direct control, but know that a modular approach often takes more time in the short term to set up, and you can give your team the freedom and the time to do that set up if you recognize and emphasize the importance of modularity.
If your code base is partitioned into a series of independent units, this means that when new functionality needs to be added to an existing code base it can be done by creating a whole new unit, which limits exposure to the contents of the old, legacy bits.
If done right, when new code is added it can be added to a new file, rather than editing an existing file. This ensures that the ugly, unsightly stuff that puts coders off their dinners stays out of sight and out of mind.
In the previous blog, I talked a lot about the coder community, and how important interaction with it is to the day-to-day job of writing code.
Almost all tech teams will use open source software, and occasionally that usage generates some legal headaches because the license to use it occasionally has some unpalatable strings attached, such as the requirement to share the source for any software built in-house that derives from the open source original.
Here I’d like to go one step further and look at the decision to make some or all of one’s software open source voluntarily rather than due to a licensing requirement.
There are several reasons one might want to do this. Sometimes making certain bits of software freely available makes it easier for other people to interact with certain other software or services one provides, and commercial value is derived from that other stuff.
So, for example, an email marketing service might open source the libraries that enable other people’s software to interact with their APIs in order to facilitate automating the email marketing process, making it easier for those other people to spend money using the email marketing service.
Sometimes the company may have a commitment to transparency, and their IP may reside in their content rather than their technology, in which case open sourcing their software is a way of engendering trust and cultivating a particular type of engagement, For example, reddit.com has been open source since 2008 for this sort of reason.
However, in my experience by far the most powerful driver behind a company open sourcing something is pressure from their developers to do so. The open source movement is based on intellectual principles of community and collaboration that appeal strongly to many software developers.
This is partly because of the dependence on open source software to get one’s job done day-to-day, but also because, for many software developers, it is only thanks to the prevalence of open source software that they were provided with the tools to learn about software development in the first place: if it wasn’t for open source software, they wouldn’t be software developers at all.
This means that in many cases, coders are passionate about open source, and want to be creators of open source content. As a manager of coders, you may, therefore, be faced with a choice.
You can either decree that open source has no place in your organization, and ask your developers to limit their open source activities to personal projects and contributions to other people’s software. Or you can try to find ways of open sourcing some of what you do, with the goal of keeping your team happy.
This may seem scary and dangerous. Imagine if Google open sourced their search algorithm.
It would do untold damage to them, as it would surely allow a thousand competitors to spring up, using Google’s own technology to try to take their place! Or at the very least let companies from all over the world analyze the source code to try to find ways of unfairly boosting their search rankings.
It may surprise you to learn, then, that Google is a massive contributor to the open source world, and they are the source of nearly 1,000 open source software projects.
Now, to be fair, their main search algorithm is not something they open source, but that’s kind of the point: Google separates out the core tech IP that they want to keep secret from the stuff that they don’t need to, and in doing so place themselves and their developers at the heart of the tech community.
Beyond making the developers happy (and more indirectly, making it easier to recruit and retain developers), there are other benefits to open sourcing. The main one being: it encourages other people to make your code better without you having to pay them.
If you rely on a particular software tool you’ve created in-house, the price you pay by making that tool available to your competitors may be less than the benefits you get from having developers from all over the world try to take your tool and improve it, finding and fixing bugs, adding features, or building other tools that help integrate your tool with all manner of other products and services.
Of course, you’re banking on those other developers sharing their improvements with you, but here’s the thing: the past 20 years or so have shown that that’s what developers do, partially because it gains them reputation.
Partially because open source licenses often require such sharing, but mostly because that’s just how everyone knows it works— when you make an improvement, you make that improvement public.
The merits and disadvantages of open sourcing a piece of software are different in every case, and it’s never a decision to take lightly. I’m not recommending it as a panacea. You might indeed find that your developers don’t actually care about open sourcing in the slightest.
It’s not a universal desire. All I want to do is draw your attention to the fact that, if it would make your team happy to open source at least some of what they’re working on, that might in fact not be as dangerous, scary, or commercially naive as it may seem at first.
Continuing to learn
Lastly, a note about learning. Other industries talk about “Continuing Professional Development,” and though the term is a little old-fashioned and seldom used when talking about tech, it covers what I want to talk about quite well.
Coders are, as I’ve mentioned in previous blogs, often attracted by new technologies. This can lead to pain, because it can bias them towards rebuilding with new tech rather than continuing to work with old tech, in situations where in fact the latter choice makes more strategic sense.
However, in my experience, that’s not nearly so damaging as when a coder swings the other way and is biased towards not working with anything new.
The reason this is dangerous is that the tech landscape is perpetually changing. New technologies are constantly emerging to make certain things easier, and ignoring them means losing out on that increased ease.
New paradigms are perpetually being established, and ignoring them means building code that becomes less and less readable by the average coder who is used to keeping abreast of such modern ideas.
Old technologies are continually being abandoned by their communities, and code that continues to rely on those technologies becomes harder and harder to maintain and integrate with other technologies and tools because the community support for such activities dies away.
I’ve worked with coders who have lost their curiosity, who have decided to stop keeping abreast of what’s new. I’ve worked with the code bases that have been built and maintained by such coders, and reader, it has been horrible:
The obsolete tech that is kept alive on the digital equivalent of life-support, and horribly complex patterns that are replicated everywhere because the author neither knew nor cared about the better way of doing things.
It leads to software that is hard to change, hard to hire coders to work on, and more and more expensive to support.
On balance, therefore, I believe it’s preferable for your developers to err towards favoring the new than favoring the old. It’s easier to prevent an eager coder from using a piece of immature technology than to force a reluctant one to adopt something new and do it properly.
What this means is, if your developers have that spark of curiosity (and hopefully they do have it), be sure not to extinguish it. This means: encourage them to sign up to relevant mailing lists and spend time on tech forums. Organize trips to meetups and conferences—even consider sponsoring them or hosting them at your office.
The budget for learning: courses, blogs, events, you name it. And be open to the use of new technologies where appropriate. This is an area where, if you get it right, your developers’ interests will be very much aligned with your own. The proverbial cat aside, curiosity is good for everyone.
I absolutely don’t have a magic formula for developer happiness. I’ve highlighted a few things that, in my experience, are both good for morale and beneficial to an organization in other ways.
There will be other areas where you will find things that will make developers happy but will come at a cost, sometimes significant, to the business.
In such situations, you’ll have to weigh up the benefits of having happy coders against those costs. I believe that the boost to productivity and retention that happiness brings should be valued highly, but it’ll be up to you to make a judgment case by case.