Working With a Really Terrible Developer
If you’ve never had this experience you have my envy. You’re on a development team and one of the developers does sloppy work and there is nothing you can do about it.
Time was when everyone in software from the first-day QA trainee to the executives had some experience at coding. That is long gone and now we have layers of methodology “masters” and managers who have never written a line, and who regard any and all complaints about others’ work as insubordinate and as personal conflicts, never considering the criticisms on their technical merits.
If I say that one of the other members of the group is doing shoddy work, even if I explain politely and in technical detail, managers hear “unpleasantness” and focus all their attention on team cohesion, which means I’m the one who gets in trouble.
I was working until a few weeks ago on a distributed team for a company in England. One team member, whom I will refer to as L, not only did terrible work (more on this below) but on the daily Zoom status update was three times louder than anyone else in a voice that could etch diamond, made little effort to pronounce English clearly, and insisted on hijacking others’ computers with a compulsive screen-share that illuminated nothing, just so the rest of us could watch him wiggle his mouse.
He was mechanical. His reaction to any transition was always the same. His turn to talk? “Let me share my screen.” Get an error message? Take a full-desktop BMP screen shot with a huge rectangle within which the error message was almost invisible.. Explain a keyword? Another screen shot. Thanks, L, I didn’t know how to spell “foreign key.”
I came to dread the call because his abrasive and loud voice gave me a headache. While everyone else on the team had mastered English well enough to be understood, L moved the accented syllables of words (“Chrome conSOLE”) in a way that reminded of why so many companies that outsourced tech support to his country are now moving it to the Philippines.
Late edit: a lot of people respond to this mention by calling me a bigot for bringing up L’s “accent.” I guess not many of you have seen real bigotry because this doesn’t qualify.
L’s pronunciation was like his work; just barely good enough and no better. He was very loud and he had a voice like rocks being pulverized. I was the only native English speaker in the development group; all of the others managed to keep their voices at a modest volume and pronounce in a way that was not a strain to understand.
It had nothing to do with his accent. I’m used to foreign accents. It was just another instance of his mediocrity.
He was unresponsive to communication and made changes to interfaces and API behavior without informing anyone of them. Since we did not have code reviews, which I tried hard to spearhead, we only discovered these wanton changes when things broke.
Worst of all L appeared to get cognitively rebooted every few minutes. This company had its Git branches set up all wrong, two “master” branches in the same repo, one for the front end and one for the back. My cryptography work was in a branch off the front end “master.” We had been talking about the branches by name for about ten minutes, and it was clear as could be that I was doing my work in “frontend-crypto,” which we had both mentioned many times.
He suddenly asked me, apropos of nothing, “Chris, which branch are you working in?”
This sort of thing happened many times and managers would patiently explain to him what any eight year old could have followed. They could see he wasn’t tracking but for some reason it was only a problem when I expressed my frustration at having to explain simple matters over and over.
He did a lot of work, all of it very low quality. In addition to industry standard illegibility he did the absolute bare minimum in rigor that he could get away with.
I Write an Endpoint
I needed a new API, one that would return two or more rows for recipients who may or may not already be in the database. I didn’t know Django well enough to do it perfectly, not knowing where Python ends and Django begins (I really dislike Django, it shows no coherence or idiom), but I wrote out all the logic and status codes.
Suppose I called this API seeking the encryption keys for ten people. Here are the number found and the HTTP status codes in my original bad Django:
Number returned HTTP code
10 200 (full success)
1-9 206 (partial content)
0 204 (data not found)
server exception 500 (exception)
If the response had fewer rows than the number requested I returned an array of their not-found identifiers.
I turned it over to L to fix up the Django syntax, not to rewrite it, but this is what he did:
Number returned HTTP code
10 200 (full success)
1-9 200 (wrong)
0 200 (wrong)
server exception 400 (wrong)
So even if not a single row was returned, he called it a complete success, and he removed my array of the rows not found, so the client had to enumerate the returned data, compare to the request and determine which ones didn’t come back. And a server exception returned 400, Bad Request, which was completely wrong.
This guy was supposed to be their back end expert. I expected him to know these codes; I don’t know every single one of them but I know the dozen or so most common ones. And even with the logic and intended status codes right in front of him he threw it all away and did it “his way.”
To be fair there are multiple schools of thought on how to handle intermediate levels of API success. I almost never see any 2XX status code other than 200; that and 500 are the only codes most developers ever return. Most developers only know three or four status codes. L knew two and one of them was wrong.
It would be charitable to allow that L had his own approach that was different from mine; in my view we have more than four status codes for a reason, and I use them. I knew however from months of working with him that he had just copied and pasted in the same line for all of them, probably taken from StackOverflow. He left my sieving logic for the cases above (0, 1–9, 10) but pasted the same line for all of them.
In any case an API is a transaction and if he changed the behavior it was incumbent on him to inform the rest of us of his changes, as we were expecting these more detailed status codes. Not only did he fail to do so, he never answered me when I asked him about it. This isn’t teamwork. This was a pattern in working with him. Since this project had no QA it would likely have been customers who first saw the holes in the logic.
I was furious. I had done it all correctly except for the Django syntax which he could have fixed in under a minute, but instead he rewrote the whole thing with significantly altered logic. And of course his code looked like a pair of cats had fought on the keyboard.
I tried asking L why he had made these changes but when he ignored me as usual I asked the managers for a conference call. I showed them what I’ve written above. They tut-tutted and said they would talk to L about it. I don’t think they did, because two weeks later it was still unchanged.
And they paid this guy.
So if they didn’t talk to L then they probably decided I was bringing conflict to the team, though they never told me so. This was my last item in the work, all my stuff worked except this mangled API. I was done. With three new languages under my belt and experience in a really cool cryptographic implementation.
I didn’t bother talking to L again. What would be the point? He had done a bare minimum lousy job and in his work ethic that was just fine. In previous debates on design he had contributed nothing. I could have mentored him but I knew from months of working with him that he would have ignored me and gone on doing things the way he was accustomed: sloppy, shoddy, and illegible.
Managers Who Don’t Know Code
As with so many who say that “people skills” are more important than “coding skills,” the managers on this project were more interested in keeping things nicey-nicey in the team than in doing a solid product. Since this was a very security-centric application it was more vital than usual to do the most rigorous job possible, but they allowed L’s sloppy rewrite to remain.
Their attitude toward my report was probably that there was some “friction” between me and L; I got along fine with everyone and managed to mask my frustration with L and his mysterious context-loss episodes and godawful code, and my part was about done so not much came of this.
This is what comes of regarding software development as a social activity. It sure as hell isn’t engineering yet.
But had I been the development lead, L would have been looking for another job.
There is a continuum in the software development work ethic; the two poles are
- Do it as perfectly as possible and to hell with the deadlines
- Do as little as you can get away with and make clearing your task list your only priority. Take up the slack by writing unit tests (which we didn’t do).
L and I were at opposite poles of this continuum. Stir in his disinterest in communication and we had a mess.