A Million Lines of Bad Code
varianceexplained.org
varianceexplained.org
But this blog reminded me of some of the concepts from the book, its far more productive to give positive encouragement than to give negative feedback, and just adding a complement isn't enough if you follow it with a "but".
"Hey pretty cool program! Its a great start. I bet we can make it run faster if we changed the way files are imported to something like this... nice work"
will get better results then this
"Hey pretty cool program, but you're reading in files wrong"
which even that is better than this
"You're reading in files completely wrong, try googling for a better solution" which unfortunately among engineers seems to be the most common reply.
I usually hear this referred to as a "criticism sandwich": Criticism surrounded on either side with compliments.
By being polite you're ensuring that the message you're sending gets incorporated into their strategy for tackling that problem and making them feel comfortable discussing other issues with you.
As programmers, we have to learn that 'programming' people is very different from programming computers.
That's great! To make it read files faster, next time let's try xyz.
At some point in my career, I stopped taking criticism personally. I just realized I was wrong so often that upholding the pretense that I knew it all was too hard. For that reason, I prefer direct suggestions.
If I was teaching a child or a new beginner, I would start with a lot of praise that they're even trying. I want to get them some early wins to help boost their confidence.
Recently though, I've been assigned a guy to help me with one of my tasks, managing the build pipeline. This requires a wide range of knowledge about unix and scripting (Bash, Perl AND Python. Yup. On top of Makefiles, of course).
The guy doesn't know how to use a command-line.
I'm surprised to find myself to be very unhelpful and curt with this guy. He's the unlucky recipient of my resentment at the amount of effort I will have to put in before he can actually become remotely helpful. Of course, it doesn't help that he's in far off timezone where I'd have to stay up late to help him, and that I have trouble getting direct answers from him about his knowledge level. The communication and experience gap is too large.
Anyhow, this is just my two cents relating an experience to show how a seemingly normal and friendly human being can revert to angry "RTFM"s.
FWIW, I suspect that you're much more experienced in this stuff than me, so it's a bit arrogant for me to offer a suggestion. But still, I'm going to offer one. Is the guy quite self-motivated? If so, one thing that might help you is to spend some time curating good learning resources for him, and then linking him to them. It's essentially the ethical version of RTFM. You help him figure out what the useful "M" actually is, and he'll get himself up to scratch from there.
Just a suggestion, anyway. :)
http://www.amazon.com/Practical-Guide-Commands-Editors-Progr...
I've also found "Unix for the Impatient" very helpful but the 1995 copyright is a little scary.
Parts of it are a bit dated (no longer typically used features), but it's a pretty good overview of how Linux works for end users.
Sure. We're all human, and I know I've been there many times. Just also remember how the seemingly normal and ready to learn human will react to a lesson put that way.
The guy is not just a human being, he's also a professional whose job it is to know what he's doing. Shouldn't there be some sense of "duty to do a job well", not just "duty to care about someone's feelings"? If he's not pulling his weight and is failing at his job, then the poor responses are his fault also.
The "interesting" thing here is the cultural gap, where these folks have had all initiative beaten out of them throughout their education, where the cost of failure is higher than that of not trying. It's really disheartening.
My point is, it's heard to blame the person when you know how flawed is the system they come from.
Then the powers that be decided I needed a manager, and hired some old wreck retired from IBM. I have no idea why. Old? Male? Wore a suit and would be more presentable to the board than me (not hard)? It was certainly not for his knowledge. He couldn't fix a PC, diagnose Windows problems, or use a Unix command line, and actually added to my workload because he would break his computer and need me to fix it. A co-worker quietly told me he spent his day playing Solitaire and taking messages because he was unable to solve problems.
He didn't seem to want to learn, either. That was the kicker. I would usually spend an hour a day teaching my previous assistant about networks or software, but this guy, his ignorance was just too big and he just didn't express any curiosity. I'm pretty sure his job was to collect a paycheck.
I quit. There wasn't really much choice. I was overworked and insulted. And within 2 weeks he resigned as well.
Did the assigner spend enough time with the remote worker to understand the skill level?
In your organisation, is it OK to report a skill mismatch like this up the chain?
Summary: this is a management issue I think
As for myself, I tend to not call out the positive parts of something, because that's sort of implicit. I would not bother to point out that the file reading code is wrong if the whole thing was broken.
I admit I'm probably incorrect here, but I notice people try this "say something positive" and it really comes off wrong. Or maybe I don't notice when they do it well.
"Sweet! Uh...that run time is pretty terrible though. Don't worry, let's see what's up with that. (Twenty seconds later:) Ohhhhhhhhh, ha, ok, check this out."
The novice coder knows they suck. They're not really worried about that because, well, they're still here. What they are worried about is that you'll write them off. So don't.
Remember: knowing a bias exists doesn't make it go away, at all.
In my experience, the sort of person who professes a love of unvarnished communication is someone heavily into sending it - the same people reliably hit the roof whenever they receive it.
Public relations is 50% of the job, even if you're bad at public relations. There are no quick hacks to make that go away, 'cos if there were then everyone would already be using them.
I have to admit though, it took many years and a few courses in psychology until I finally could admit to myself and my surroundings that I actually need positive reinforcement, that negative reinforcement, even if true and relevant, could even be detrimental to my performance.
I do agree on the importance of not just "say something positive", it has to be real, most people have probably filled their quota of obviously false/exaggerated complements in preschool. I myself struggle with finding the right balance between sounding patronizing and being overly critical.
And it's not really self confidence[1]. It's more of an extension of principles of coding. Anyone can write a system that does X. But doing X when things go well, and doing it in the face of errors, edge cases, and other faults - that's what it's all about. For me, anyways, when I'm writing code "as an engineer". So I don't find it particularly notable that something works. Of course it " works ", or you wouldn't be telling or showing me in the first place! Likewise if I ask for a review and your only comment is " file buffer is too small " I'm gonna guess the rest is alright else you wouldn't bother pointing out smaller things. If I'm unsure about something, I'll ask about it explicitly.
Outside of a feedback system like a code review, it is important to let people know you appreciate their work. And it's to my detriment that I don't let people know, honestly, when I appreciate them. But that's separate from mixing it in with criticism.
1: I've low confidence in my self confidence. On one hand I know I have a fairly good error rate and I'm objectively better than a lot of other developers. Yet, especially here on HN, I can plainly see I'm nothing special. But this doesn't really assure me that any particular piece of my work is good.
> I gotta wonder, do you actually have such confidence yourself that you assume that everything other people _does not_ comment was good? If so congratulations! A suggestion though, on how you could improve the confidence in people like me - who aren't sure everything not mentioned is good - would be to actually point out the positive parts even if you don't feel that it is necessary.
If you learn another language (a human language), and try to practice it with native speakers, you'll quickly notice that they never comment on your correct grammar. (It's not exactly common for people to comment on incorrect grammar either, but it can happen.) The only way to learn that your phrasing was correct is to ask outright, or observe someone producing an exact analogue of your sentence. This is a source of great aggravation to me, but things couldn't reasonably be any other way -- most of the correct stuff people say is stuff that they already knew was correct.
"The other thing about it is: Comedy comes from a good or a bad place. And I think that the funniest people always comes from a good place. Two people can say the same thing, and one person can be so nasty and vitriolic -- and therefore not funny. And the other can be, you know, a celebration. You know, you can be in on the joke."
--Ricky Gervais
http://www.howardschatz.com/film.php?ID=3814
Corny as it might sound -- I think brutal honesty is more constructive when it comes from a place of love. I'm not sure what the practical take-away from that is. Maybe build trust first, and then be direct? Or be honest, but avoid being mean?
OTOH I think everyone deserves/needs a good bit of BOFH bootcamp to slap them into reality before they are let lose writing code that talks to the Internet... ;-)
I can empathize with this because I feel like saying this all too often. I guess it's a mentality of "teach a man how to fish". I guess I could use a reading of "How to Win Friends & Influence People".
But (yes, I buted), I think a lot of people go overboard. I've seen people get so bent up around coming off as nice and encouraging, that it becomes difficult to even understand what they want from you. Or worse, it comes off passive aggressive.
I'm not sure there's a better fix for that than practice.
You've offered a compliment, then suggestion, then a platitude, while telling someone that being rude is acceptable if it's technically correct and seemingly disagreeing with the previous poster.
It's sound advice, to have thick skin, but you've just shown how easy it is to give corrective feedback in a tactful way. Still good advice to not let people offend you though.
You did this on purpose, didn't you. ;)
When I ask "why should I do this rather than that?", I either get a muddy explanation, or none at all.
Worse still is inconsistency. Just recently I was working on a project, went through several reviews without comment on the approach, was told "almost done just fix these tests". After waiting a week for review of those last tweaks, the review was "this is fundamentally flawed and shouldn't be done this way at all."
Now I'm not saying that's wrong, but it would have been better to hear that three weeks ago. Nor is the explanation of _why_ it's flawed the slightest bit clear.
Further, the new approach does _not_ support the business need motivating these changes in the first place. I am figuring out how to support that need within the directed approach, but it is harder than the first design would have been. Again, that doesn't mean I was right -- sometimes there are choices where you put the ugly stuff. These changes are pretty deep in our architecture, and so touch a lot of code. If being clean there means that some top-level stuff is more complicated, that is probably the right trade-off. But it would be nice to have a "sorry, I didn't think this through soon enough." And no, I am not the idiot I'm made out to be because I didn't, as a junior dev, immediately and fully understand how all the pieces should fit together.
Nor is this a two-way street. I've had moments where I've pointed out what seems like problems, been told I'm wrong, or ignored . . . and then find that the issue is quietly fixed a few days later. We do some stuff that is just flat wrong because that's how he likes it.
I'm not the only one, the others with more experience than I have similar problems.
I'm learning. The guy has good instincts, so his critiques usually lead in the right direction, so I roll with it and figure out the principles for myself. But it is absolutely zero fun working with this guy. I've become averse to submitting code for review, because I never know when the process will take 180 and stuff that was fine becomes crap. And while I think I'm getting better, I have to figure out how to build confidence in those skills, because I'm not going to get it from this feedback loop. Probably that will be working on my own projects, taking what I'm learning and using that to make them better. And at some point I'll move on.
Tough feedback, even insulting feedback, is ok with me. I'll work with it. But if you're going to be tough, then you have to be fair, you have to be clear, and you have to be right.
If a senior person won't explain something if you ask politely, usually either they don't understand it themselves, or they are simply not very good at explaining things. Not all senior people are good teachers. It sounds like your team lead is one of the latter.
If you want to avoid this, you're going to have to make it your job to point out potential flaws and hurdles in your work as you come across them, to ask only for essential and broad-strokes guidance up front, and to find/fix smaller issues yourself as you go along without bothering the higher ups. Your senior probably genuinely wasn't aware of the deeper issues with your work because they just didn't have time to do anything but scan your code and hope for the best, because their senior is hassling them about a,b,c, which are far more important.
Now that was flawed on their part, and they're doing their job wrong, but you can help them fix that process, if you want to, and it is a good skill to learn. You absolutely should not be avoiding code review, you should be guiding that process in a direction that is in everyone's interest. The world of work is not remotely fair, clear or right - it is very rarely even one of those, but you can make it better yourself by managing upwards and making your requirements and concerns clear at a very early stage.
In my opinion the dichotomy of tough but fair/nice but inaccurate feedback is a false one. Most feedback is rushed, muddled, partly correct, partly irrelevant, partly insightful and still useful if you know how to mine it.
General advice is easy to give. There are millions of tiny details which tend to guide you away.
One reason engineers can be unintentionally critical is that their job is often "find what's wrong with this thing and make it better". It's rarely "find what's right with this thing and congratulate someone". It takes me quite a bit of mental effort to switch from nitpick mode to encouragement mode. I've tried to consciously balance my criticisms by leaving a few honest encouraging comments in code reviews like: "thanks for improving test coverage here", or "glad you handled timeouts and retrys, this api has given us grief before".
https://people.gnome.org/~michael/data/2011-10-13-new-develo... (5 page presentation)
Compare pages 3 and 4.
We aren't selling cars nor running for office where "win friends" is particularly useful. I'm also not saying we should be deliberately nasty or personally demeaning. But we shouldn't let shit pass just to be nice either. There is far too much of that nonsense in the world, and the net effect of it is a theft from everyone.
We should try to be our best. We should ask others to be their best. We should always be positive and helpful and teach others what we can. But we should also be direct when something is wrong and we know better. This in the best interest of the person, the project and the organization. The ability to give and to accept honest criticism with the goal of improvement is unfortunately strikingly rare.
When we don't know better we should keep our mouths shut rather than bluffing and blustering our way along. If I had 10 bucks for every loudmouth know-nothing trying to impress everyone or score political points I have met in life I'd be rich. The tech scene is particularly full of these kind of blowhards in my experience. Some people have a hard time telling the difference between positive honest criticism and ego driving showing off. And some people just plain don't know what they are talking about but talk anyway. This kind particularly needs to be called out in the most direct manner possible for the best interest of everyone involved.
I can only imagine sending an invoice today to my three top clients with "5 Hours Refactoring Bad Code That is Working But Could Be Better Looking....$400".
There is just no way I would get paid.
Unfortunately, I have interests outside of working on code that mostly preclude me from sitting for hours happily breaking-and-then-refixing code that is currently working ok and that I cannot bill on.
Hell, just keeping up to date with the unreal pace of change that is occurring in software right now is almost a full-time job in itself, much less fixing old stuff that is going to go away soon anyway.
You: "Err..."
Solution B is to refactor some fraction of the code you interface with when adding a new feature.
So it's "X+2 hours adding new feature" when you spent 2 hours refactoring code that feature X needed to deal with.
As far as the ethics of Solution B, then if your refactoring is actually improving your net productivity, then you truely are doing necessary work towards adding the feature (just as you would bill tests or build scripts needed for the feature along with it). If it isn't improving your net productivity, then why are you doing it?
When I first started (in Python), I didn't understand what a function was, but I wanted my program to react differently depending on user input, and had some conception that I should be breaking my program up into files by purpose. So what I did to get it working was this: I named each file "$cmd.py", then I concatted the user's input with ".py", opened & read the file with the associated name, and ran the resulting string through exec() !!
I came to this result incrementally by googling different aspects of the problem that I didn't know how to describe properly. If someone had been a jerk to me about it then, I probably would've been really self-conscious about it. But no one was a jerk, so I'm not ashamed: what I did is ridiculous and funny & I'm glad to be able to laugh about it now.
However, I have to disagree with the notion of having to write a lot of shitty code to learn to write good code. Granted, that is one way to learn, but not nearly the most effective way to learn.
For years, when I started my career, I wrote lots of shitty code. I feel badly about having done this because I unwittingly caused quite a bit of havoc in the products I was working on, and even pissed off a few customers along the way. Writing shitty code can have really bad effects on a team and on a product.
Fortunately for me, I eventually ended up working in an extremely talented team. They were not only talented at programming, but also highly skilled at teaching others good programming. Their method was simple- they accepted nothing that failed to meet their high (and documented) standards of readability and testing, but were extremely thorough in spending time showing you what you did wrong. They were never demeaning and always constructive- they always had a high level optimism in every new-comer's potential. Given enough time, it was clear that some new team members weren't going to work out, but those who had it in them to patiently improve their skills flourished and enjoyed very successful stints with this team.
After a rough first few days on the team, I heeded their warnings and agreed to check my misplaced ego at the door. Then, and after a couple of months of embarrassing ineffectiveness, I gradually became a better programmer and went on to become a great team member. I'm really grateful for the patience these guys had with me and the other noobs. They really made a difference in my career and in the career of my peers!
I personally don't get any feedback on my code and I don't really have time to police myself on it. I end up blending in with the conventions I see in whatever current document I'm working on (e.g. presence of type prefixes, casing style, underscore usage). I always thought this was bad practice in the general population but I guess I get paid for it.
We aren't going to raise the industry-wide skill level if we let people figure it out on their own the hard way. That's valuable up until a point but eventually they should start wanting to know what the effective way of doing X is (if it exists). Individuals take a long time to arrive at an optimal point with that stuff, and may never even reach it.
I'm fairly sure NASA doesn't let staff (astronauts especially) in training learn everything the hard way. Imagine if your workplace maintained something like this: http://llis.nasa.gov/
I've been writing code since 1976.
Are you sure it's better? Are you keenly aware that there are no, say, cycles in your coding approach?
I know this year I look back at last year's code and go, "oh boy, why'd I do it that way?" And I feel like it's better, but I'm always a little afraid I'm just chasing novelty. Not sure how to objectively know if it's better.
Perhaps look at code from 2 years ago and 3 years ago, and if possible blind yourself as to which is older, and rate each one.
I've had that sneaking suspicion that maybe I'm not really getting any better, yes. But I have independent corroboration - I've worked with another guy for most of that time, and we've got one anothers' code to look at. What one of us learns, the other learns too. He's not cycling, or just writing bad code. And he says the same about me.
I'd say about half my bad code is due to inexperience, what the post is referring to. As time goes on it DOES get better, especially since -- like most of you -- I'm constantly reading and trying to improve my skills.
The other half of my bad code is due to time constraint. This is either because a quick hack is needed, or the proper planning time is not allocated to do a proper job.
This leads me back to my initial statement. Sometimes you just need to get the job done. If you're not good enough to do it right, but you hack it and it works, that's good enough for now.
This is how systems get built poorly and bloat up, but there are deadlines and requirements that need to be met, and if you never ship, you'll never get the budget to rebuild that old system you allowed to get unwieldy. It's a constant struggle to balance quality, functionality, and deadlines.
(Sorry for commenting in a form of a meme, but it really was asking for it)
To the extent that the aphorism about writing bad code is true, I think it's just another way of saying that people's code improves with their coding experience. I really don't think you need to write bad code _in order_ to learn to write good code. It's hard to know for sure, but I think the most positive influence on my code quality was _reading_ lots of very good code, not having written bad code. (It's the same with my writing, too.)
[Edited for clarity, ironically.]
If that can't be done, if you can't spend your free time honing your abilities, then accept helpful feedback from other more experienced developers. Don't just accept feedback--assume your code is garbage, and ask how you can make it better. If the answer eventually becomes "it's good enough for business purposes", then find out why that is, and learn from that.
Communication is hard, and explaining why a codebase is just wrong can be as difficult as explaining to somebody why you find them abrasive.
At the same time, it's the job of senior engineers to make the effort and try.
Sadly, in a startup environment, it's usually smarter business-wise in the short-term just to sack the inexperienced developers or railroad them into simpler work that they can't screw up, and kick the can down the line.
I find that viewing (and discussing) code this way has a lot of benefits:
* It is really hard for a single global negative value judgement made about code to not be taken personally by the person who wrote it (e.g., "your code sucks" == "you suck"). This is much easier to avoid when talking about attributes of a thing, since (a) it comes across as more objective than subjective, (b) gives plenty of opportunities for acknowledging aspects of the code that _don't_ suck, and (c) lends itself to much more of a "give and take" discussion.
* It gives you the opportunity to talk about "figures of merit" and trade-offs that are the reality of engineering, but rarely taught in schools (e.g., readability/development cost/flexibility vs. performance, etc.)
* It gives you a framework for explaining why things like idiomatic style, "principle of least astonishment", and general elegance actually contribute to code quality (and aren't just excuses for subjective attacks).1: https://www.yahoo.com/movies/bp/steven-spielberg-finally-adm...
That said, this XKCD comic is one of Randall's rare misses. It's about mocking something which I -- as a developer -- would actually like to promote: People taking initiative and teaching themselves to code. Even people who are shitty at it.
In fact, I'm almost always very impressed with people who are not professional coders but who have taught themselves a few coding skills in order to solve some problem or to actualize some idea -- even if the code itself is horrific from a professional standpoint. That's awesome! And if they want help, I won't mock -- I'll help! It's a rare opportunity to really show someone why I find the act of programming to be so fascinating and satisfying.
Not sure what you're trying to say here? Its a cartoon about a stick figure who can't code. Funniest part was "it's like someone took a transcript of a couple arguing at ikea and made random edits until it compiled without errors" lol
> That said, this XKCD comic is one of Randall's rare misses. It's about mocking something which I -- as a developer -- would actually like to promote: People taking initiative and teaching themselves to code. Even people who are shitty at it.
I understand that you feel passionately about this, and I agree wholeheartedly that non professionals should not be mocked. That said, I dont think that's what's going on here. What we have here, is a cartoon that's poking fun at an exaggerated circumstance. No individual or group is being (sincerely) called out or told they shouln't try to learn to code. It's all just a joke, for amusement.
Its like saying Peanuts is mean spirited for mocking people with poor hygiene with the character Pig Pen: It discourages those people from leaving their homes and interacting with people. I should instead encourage those with poor hygiene to pick up that bar of soap and go outside!
... But that's silly, right?
I'm just poking a little fun at your earlier reductionism. You're right, it's just a stick figure. A real human has not been hurt.
My main issue with the comic is that it's not particularly funny. To me. The zingers don't really zing. It's just someone whaling on someone else for three panels. And since I'm not catching onto the humor, all I'm left with is the weird feeling that the comic is condoning that kind of behavior.
There's nothing sinister in this cartoon, no matter what you feel. You might as well accuse all cartoonists of condoning their characters' outlandish behaviors. (e.g. "The writers of the Simpsons must condone child abuse because I didn't find the humor in Homer choking his son" ... Give me a break.)
Here's a hard-earned lesson for any newly-minted developers out there: Yeah, you're smart. But not as smart as you think you are. And regardless, it doesn't give you license to treat anyone poorly.
But the main point is that it worked in production for years. I would have written it much better today, and it will probably work faster and be easier to maintain. But it would also probably take longer to develop (though less time to debug and stabilize) - and ultimately, it would do the same work in production.
I'm not saying that improving your coding style and skills is not important. Just that we need to keep our eye on the ball - which is delivering working software, not code.
I would say 10k is enough that you can put it on your resume... But, even that is probably way less than the average comp-sci graduate writes. So, I would still consider it a starting point. Especially, since reading other peoples code is just as important a skill, and that isn't something generally picked up in school, or on little weekend projects using a new language.
But again, it depends on the breadth of the problems being solved. We hired a web developer a couple years ago, who in the space of about a year wrote ~150k lines of PHP and javascript, and got a _LOT_ better at it, but he solved most of the problems the same way and there was a metric ton of duplicate code, and imprecise problem solving (AKA problems solved in the most roundabout way). Over the last 2 years I've probably only written about 50k lines of PHP/Javascript but I've added about 20x the functionality he added. So, I would say that i'm better now than he was when he left, but i'm still not really that good.
I think I write better code now because I spent so much time just writing stuff early on, and learning from my mistakes. That, along with some good mentors helped me so much more than the people that merely criticize you because of your code. I definitely agree with this article.
[1] http://findbugs.sourceforge.net/ [2] http://softwarerecs.stackexchange.com/questions/2902/static-... [3] https://github.com/LMAX-Exchange/freud [4] http://spoon.gforge.inria.fr/
Seems to me if someone writes bad code when they SHOULD be writing good code, code-shaming might be in order.
I'm all for being nice and understanding. Everyone programs at a different level and I may not write code that is as good as I think, but some code is just obviously bad...and constructive criticism (if willing to be accepted) might help
Just think, if everything is pretty good and isn't that bad and doesn't need that much improvement, why should anything ever get any better, ever?
I certainly had jobs in the past where I got angry over bad code when, in fact, I should have been bad at the businessmen making me use the bad code (instead of putting time on the calendar to write things properly) and setting the deadlines that caused the bad code.
For sure, there are some sloppy, borderline-unethical engineers who write shitty fast code to get promoted away from the maintenance messes they generate... and there are definitely some incompetent engineers. For the most part, though, bad code is a symptom of bad leadership rather than bad programmers. Under a tight enough deadline, everyone's code will be shit.
And, of course, it goes without saying that the proper response to bad code isn't to flip out on the person, but to teach him how to do it better. One of the reasons why I like using high-productivity languages like Haskell rather than Java is that it selects for people who genuinely want to improve.
No. Not in Java since 1999 or so.
Concat code: http://pastebin.com/CcezmJbf
Builder code: http://pastebin.com/Dd6kzcKa
Results, using JRE 7:
> time java concat data.blk Finished. java foo data.blk 170.08s user 1.52s system 102% cpu 2:48.12 total
> time java builder data.blk Finished. java builder data.blk 0.30s user 0.05s system 151% cpu 0.230 total
builder: http://hastebin.com/qadusoriqa.cs