What I Wish I Knew When Starting Out as a Software Developer: Slow the Fuck Down(blog.salsitasoft.com)
blog.salsitasoft.com
What I Wish I Knew When Starting Out as a Software Developer: Slow the Fuck Down
http://blog.salsitasoft.com/what-i-wish-i-knew-when-starting-out-as-a-software-developer-slow-the-fuck-down/
15 comments
> I'm not sure if there are CS programs out that start with a small project and then force the students to make massive changes to that project throughout the course of the year
I studied Software Engineering at Swinburne University in Melbourne Australia, and we did exactly that.
One subject was "Software Maintenance Project" where we took an existing code-base we didn't write (a front-end for laTex for our year, the CVS code base for the next year students) and continually made changes to it. Halfway through the course we had to deal with changing requirements. We were graded on the quality of our code and how well it fit the existing style etc., not how fast we did it.
We also did a full-year final year project with 16 of us where we created a BIG code base from scratch. We decided to use an iterative approach (our choice) and so over the year we ran 6 iterations continually building on what we'd already done.
We also did awesome courses like "Personal Software Process" to teach us discipline in how we personally approach writing code.
EDIT: Sometimes I post to HN "hire/resume" threads about my hire-ability and how I personally think I'm "better" than the average person who studied CS because of things like the above. Normally everyone disagrees and says as long as I can code, it doesn't matter that I studied Software Engineering and am a certified Engineer. It's for reasons like the above I still personally feel I'm stronger than the average CS grad.
I studied Software Engineering at Swinburne University in Melbourne Australia, and we did exactly that.
One subject was "Software Maintenance Project" where we took an existing code-base we didn't write (a front-end for laTex for our year, the CVS code base for the next year students) and continually made changes to it. Halfway through the course we had to deal with changing requirements. We were graded on the quality of our code and how well it fit the existing style etc., not how fast we did it.
We also did a full-year final year project with 16 of us where we created a BIG code base from scratch. We decided to use an iterative approach (our choice) and so over the year we ran 6 iterations continually building on what we'd already done.
We also did awesome courses like "Personal Software Process" to teach us discipline in how we personally approach writing code.
EDIT: Sometimes I post to HN "hire/resume" threads about my hire-ability and how I personally think I'm "better" than the average person who studied CS because of things like the above. Normally everyone disagrees and says as long as I can code, it doesn't matter that I studied Software Engineering and am a certified Engineer. It's for reasons like the above I still personally feel I'm stronger than the average CS grad.
FYI, you are stronger than the average grad. People get pretty defensive when it comes to skills; nobody wants to believe they're below average if they're frequenting this site.
My one piece of advice: keep studying and practicing making beautiful software, in and out. Be careful who you take technical advice from; the industry right now is flush with cash, and thus there is a huge incentive to talk more than produce. Projects are often killed as quickly as they're started, causing people not to practice program design.
My one piece of advice: keep studying and practicing making beautiful software, in and out. Be careful who you take technical advice from; the industry right now is flush with cash, and thus there is a huge incentive to talk more than produce. Projects are often killed as quickly as they're started, causing people not to practice program design.
That sounds like a seriously awesome course. I wish my school would do that...
Even more challenging would be to maintain somebody else's code. Say, at the start of an assignment, each student is randomly assigned a code base from the previous project (we could restrict this set to only include code bases that met the grade). New requirements that weren't a part of the previous project are introduced every time this happens.
If the students are being graded on a curve so they're competing against one another, this would be downright diabolical.
If the students are being graded on a curve so they're competing against one another, this would be downright diabolical.
I'm embarrassed to say that I went 15 years before I really learned to work with "other people's code". That's partly because I came to programming as a math/industrial engineering student, where I was really writing code to solve problems and get answers rather than a sustainable, usable product. Even once I started writing code for users, it was generally pretty experimental and research-y, so I usually got a green field project.
In the past few years, I've worked repeatedly with existing code bases to extend or modify functionality (or just fix problems), and it has been an amazing learning experience. Not all of the code has been good, much of it has been questionable. But the process of understanding someone else's code, figuring out how to change it, balancing the harm of forking vs the benefit of improving, dealing with pull requests and merges… there are a number of skills you will only learn from years in this kind of environment.
One huge challenge here is when you don't work in an organization that understands software. People aren't knowledgeable about software are often impressed with green field programmers "jim wrote the whole thing". Truth is, understanding a different code base and getting to the point where you can improve it and contribute back to it is (at least in my experience) far more challenging than just writing something from scratch. It seems that most people who write software are already well aware of this, but it can be a hard sell outside (in fact, you may even find that people seriously question your progress - a green field app there's something nifty and new to demo even day, with existing code bases, there's a lot of confusion and investigation - and it can be very dispiriting to spend days stubbornly trying to understand and diagnose a feature, finally solve it, and realize that the team is disappointed with your progress).
However, the good software teams appear to be well aware of the challenges, and it's an essential learning experience.
In the past few years, I've worked repeatedly with existing code bases to extend or modify functionality (or just fix problems), and it has been an amazing learning experience. Not all of the code has been good, much of it has been questionable. But the process of understanding someone else's code, figuring out how to change it, balancing the harm of forking vs the benefit of improving, dealing with pull requests and merges… there are a number of skills you will only learn from years in this kind of environment.
One huge challenge here is when you don't work in an organization that understands software. People aren't knowledgeable about software are often impressed with green field programmers "jim wrote the whole thing". Truth is, understanding a different code base and getting to the point where you can improve it and contribute back to it is (at least in my experience) far more challenging than just writing something from scratch. It seems that most people who write software are already well aware of this, but it can be a hard sell outside (in fact, you may even find that people seriously question your progress - a green field app there's something nifty and new to demo even day, with existing code bases, there's a lot of confusion and investigation - and it can be very dispiriting to spend days stubbornly trying to understand and diagnose a feature, finally solve it, and realize that the team is disappointed with your progress).
However, the good software teams appear to be well aware of the challenges, and it's an essential learning experience.
I find that a lot of what is taught as the "right way" to make maintainable code isn't actually that effective in practice. Particularly when I need to read someone else's code.
For example, the conventional wisdom that functions should be less than a page of text and that they should do one thing and as abstracted as possible actually makes it quite hard to understand what a program does when you aren't familiar with it.
Instead, I'd propose first writing straight line code, and then abstracting out the common functionality into separate functions as necessary. Casey Muratori (the guy behind Handmade Hero) calls this compression oriented programming [1].
[1]: http://mollyrocket.com/casey/stream_0019.html
For example, the conventional wisdom that functions should be less than a page of text and that they should do one thing and as abstracted as possible actually makes it quite hard to understand what a program does when you aren't familiar with it.
Instead, I'd propose first writing straight line code, and then abstracting out the common functionality into separate functions as necessary. Casey Muratori (the guy behind Handmade Hero) calls this compression oriented programming [1].
[1]: http://mollyrocket.com/casey/stream_0019.html
> For example, the conventional wisdom that functions should be less than a page of text and that they should do one thing and as abstracted as possible actually makes it quite hard to understand what a program does when you aren't familiar with it.
It does? Maybe you mean something more extreme when you say "as abstracted as possible" but for /reading code/, I generally find it easier to get the high-level picture and avoid getting bogged down in minute from code that looks like this:
For /writing code/, I do agree the reverse is often best: start by doing the simplest thing that works, and then refactor it into something cleaner.
It does? Maybe you mean something more extreme when you say "as abstracted as possible" but for /reading code/, I generally find it easier to get the high-level picture and avoid getting bogged down in minute from code that looks like this:
function sendReport(params) {
var dataSource = findDataSource(params);
var data = dataSource.generateData();
var report = reportBuilder.build(params);
sendReportEmail(report, param.recipients, this.template);
}
... versus a flatter one-page implementation with 15 lines of data loading, 20 lines of report, 5 lines of email templating and 15 lines of communicating with the mail server... all sprinkled with variously scoped try..catch blocks. It also helps me focus in on the part of the task I'm really interested in without trying to load the entire system in my head.For /writing code/, I do agree the reverse is often best: start by doing the simplest thing that works, and then refactor it into something cleaner.
I think that if functionality is repeated it makes sense to abstract it into a function. However, I've recently been reading through a codebase in which every function is about 10 lines long, and there are numerous functions that are only used once. This makes it hard for me to follow the code since I frequently need to chase down the 10 line function that is only called once to see what it is doing and then return to wherever I was in the code.
A function that is only used once is not necessarily a bad thing.
Shouldn't that 10 line function be pretty much self documenting?
Done right this should really help get a good grasp of code base quickly.
Now, if the function has bunch of side effects and you HAVE to read it to make sense of what's going on one abstraction higher, then it is done wrong.
Shouldn't that 10 line function be pretty much self documenting?
Done right this should really help get a good grasp of code base quickly.
Now, if the function has bunch of side effects and you HAVE to read it to make sense of what's going on one abstraction higher, then it is done wrong.
With good naming and comments this shouldn't really be an issue. At my most recent software internship I got to see very abstracted code with many short functions, and realized quickly how much more clear to read and maintainable it was.
Yeah, there's ways to screw up every method of coding, but I find favoring more and shorter functions tends to better outcomes. Obviously you could reductio ad absurdum any code into something like:
function do_task() {
do_step1();
do_step2();
do_step3();
}
function do_step {
step1();
}
function do_step2 {
step2();
}
function do_step3 {
step3();
}
But I've rarely seen that be the problem. It's been far, far more common to see giant functions that are much more understandable when broken up.I don't think I agree with that suggestion. That's like saying a table of contents is not useful if don't read a book multiple times. Certainly the DRY principle provides a good prompt of when to abstract code but it's not the only reason to do it.
Usually I am only interested in specific parts at any given time, either because I only have a particular task to accomplish (e.g. update the email template) or because trying to understand everyone at once would overload my little monkey brain.
If I'm trying to just update the email template then I don't care about the part the loads the data and I'd be wasting my time reading it. Sometimes you can't even tell if an chunk of inline code is relevant without spending a decent bit of energy figuring out what it's doing. Having everything in a single function also makes it easier for lines of unrelated code to become entangled together and thus harder to understand.
Well-structured code gives me a choice; I dive in and see the details if I'm interested, or I can leave it for another day and focus my attention elsewhere.
Certainly though, good tools like IDE are vitally helpful in reducing the friction in peeling back the abstractions when necessary. The nature of some languages though means that the level of tool support available can vary widely, which probably has an effect on different prefered coding styles. In Java, for instance, it's pretty easy to find all the pieces of code that call a particular method, while in Python, it's often not really possible without running the code.
Usually I am only interested in specific parts at any given time, either because I only have a particular task to accomplish (e.g. update the email template) or because trying to understand everyone at once would overload my little monkey brain.
If I'm trying to just update the email template then I don't care about the part the loads the data and I'd be wasting my time reading it. Sometimes you can't even tell if an chunk of inline code is relevant without spending a decent bit of energy figuring out what it's doing. Having everything in a single function also makes it easier for lines of unrelated code to become entangled together and thus harder to understand.
Well-structured code gives me a choice; I dive in and see the details if I'm interested, or I can leave it for another day and focus my attention elsewhere.
Certainly though, good tools like IDE are vitally helpful in reducing the friction in peeling back the abstractions when necessary. The nature of some languages though means that the level of tool support available can vary widely, which probably has an effect on different prefered coding styles. In Java, for instance, it's pretty easy to find all the pieces of code that call a particular method, while in Python, it's often not really possible without running the code.
That sounds more like a navigation problem than a problem with the code (unless the function names are misleading).
I agree somewhat, but context switching has non-zero overhead since it requires that I keep in my short term memory what the previous code was doing as well.
Also, I probably should have been clearer above. Sometimes a short function is the right approach, particularly for something that is going to be done over and over again, but the overall goal is clarity, not short functions.
Anyways, it's not worth getting too hung up on I don't think, it seems my opinion is the minority one.
Also, I probably should have been clearer above. Sometimes a short function is the right approach, particularly for something that is going to be done over and over again, but the overall goal is clarity, not short functions.
Anyways, it's not worth getting too hung up on I don't think, it seems my opinion is the minority one.
>"but the overall goal is clarity, not short functions."
I've never seen this discussion play out where the "short function" side is saying that the only goal of short functions is...short functions.
Obviously "clarity" vs "short-functions" is a no-brainer discussion. But fails to acknowledge the complexities and nuances being discussed.
I've never seen this discussion play out where the "short function" side is saying that the only goal of short functions is...short functions.
Obviously "clarity" vs "short-functions" is a no-brainer discussion. But fails to acknowledge the complexities and nuances being discussed.
> For example, the conventional wisdom that functions should be less than a page of text and that they should do one thing and as abstracted as possible actually makes it quite hard to understand what a program does when you aren't familiar with it.
This hasn't been my experience at all. Functions as small as 100 lines can absolutely destroy my comprehension to the point where I need to refactor it into smaller functions to be able to understand it. I'm dealing with one such function (at 200 lines) right now at work.
Well, let me rephrase. I can see what it's doing easily enough. I just have no idea what it's supposed to be doing, on a chunk by chunk basis, because it's all hand rolled search loops and array manipulation.
I also know the final result is incorrect.
I'm sure I'll slap my forehead and wonder why I couldn't see the problem before after I'm done refactoring it.
This hasn't been my experience at all. Functions as small as 100 lines can absolutely destroy my comprehension to the point where I need to refactor it into smaller functions to be able to understand it. I'm dealing with one such function (at 200 lines) right now at work.
Well, let me rephrase. I can see what it's doing easily enough. I just have no idea what it's supposed to be doing, on a chunk by chunk basis, because it's all hand rolled search loops and array manipulation.
I also know the final result is incorrect.
I'm sure I'll slap my forehead and wonder why I couldn't see the problem before after I'm done refactoring it.
That's one way of doing it.
I, however, do it differently. I start from a high-level of abstraction, and work my way down. At the top level I might have a function called "ImportData". I write that call down, then move to the next line where I write "RunDataAnalysis". At that point, if I decide to move down and implement the second function, I forget about what ImportData does, how it does it, or whether or not I've implemented it.
All I know is that the data structures are populated with the "Imported" data, and proceed to code along with that assumption. Obviously if I test, it won't work, but that's for unit-tests. You do unit-tests, right? Can't do that meaningfully with giant functions, but I digress.
To me, functions are a form of "interface". It delineates responsibility and expectations between different bits of code. I'm not a chaotic and/or artistic programmer and I'm definitely not a genius wunder-programmer that can hold the entire functioning of the program I'm writing in my head at any time. What I can do is systematically break-down a problem into component pieces, negotiate their interaction, and make it solve a problem.
I, however, do it differently. I start from a high-level of abstraction, and work my way down. At the top level I might have a function called "ImportData". I write that call down, then move to the next line where I write "RunDataAnalysis". At that point, if I decide to move down and implement the second function, I forget about what ImportData does, how it does it, or whether or not I've implemented it.
All I know is that the data structures are populated with the "Imported" data, and proceed to code along with that assumption. Obviously if I test, it won't work, but that's for unit-tests. You do unit-tests, right? Can't do that meaningfully with giant functions, but I digress.
To me, functions are a form of "interface". It delineates responsibility and expectations between different bits of code. I'm not a chaotic and/or artistic programmer and I'm definitely not a genius wunder-programmer that can hold the entire functioning of the program I'm writing in my head at any time. What I can do is systematically break-down a problem into component pieces, negotiate their interaction, and make it solve a problem.
I had a couple classes like that, usually it was more at the semester boundary. E.g. my intro to compilers classes involved writing a compiler for a c-subset. The advanced compilers class built on that compiler by adding optimizations and such. My intro to systems class had a project that was to write a shell. My operating systems class had a project to add job management and pipes to the shell from the systems class. I really liked those projects you felt like you had something pretty substantial when you were done.
A really great addition to any CS curriculum would be a long-running projects course that runs the full four years so that you get experience in managing architecture, growth, and maintenance, instead of just building. Lots of students do that by attaching themselves to open source projects or working internships, which is great, but it's not (as far as I know) an official major part of any curriculum I've heard about.
For Prof. Larry Peterson's networking class, we had to build up a web server over the course of a semester. You built IP, and used that library to build TCP, and then served files over your TCP connection.
It was the first time I realized that bugs in earlier assignments don't magically disappear, and changed my thinking dramatically.
It was the first time I realized that bugs in earlier assignments don't magically disappear, and changed my thinking dramatically.
I had the same experience in my compilers class at USF. Each assignment added layers on top of old assignments (lexer -> parser -> type checker -> codegen). I think it's an excellent strategy for helping students understand the importance of maintainability. Also, forcing you to revisit past assignments will help implant the concepts.
[deleted]
A single four year project would be a little harsh... once you realize what you've done wrong, you'd be to too deep in it to amend your ways anymore. Give them a chance to start from scratch a few times...
Realizing what you've done wrong and feeling the pain of figuring out how to amend it is the whole point of the exercise. Maybe the right way to amend it is to rewrite the whole thing, but that may or may not be the best choice, depending on what else you want to get done. Just like the real world!
A rewrite could always be an option, if it's finished on time.
Setting a reasonable pace with the project could be tricky, but I think it would be very beneficial.
Setting a reasonable pace with the project could be tricky, but I think it would be very beneficial.
Most of the time, you should be building an initial version and throwing it away anyway.
Internet time does not justify poor program design.
Internet time does not justify poor program design.
It occurs to me, reading your comment, that an interesting exercise for a software development school program would be to assign a project for first-year students; then, in second year, assign the students to take the same project from the previous year and modify it.
One problem with that is that you tend to penalize students who didn't do well the first time, and you also make it more difficult to grade because it's not an independent measurement of their progress in a particular class.
Agreed. I feel like the biggest problem with these sorts of assignments for students is that most students are still learning to program - so by the time you "add on" to your first assignment, a lot of them will want/need to re-write it.
That's kind of the point: the assignment is to take an existing codebase (probably a crappy one), figure it out (who remembers what they were thinking a year ago?), and add to it without breaking it.
So then you give every student the same existing codebase (along with the same set of requirements), and as a bonus this helps them learn and adapt something written by a different person.
Saying: "Use the same thing you worked on last quarter" dooms everyone who made wrong foundational choices with their old project to spend most of their time "fighting the last war".
Saying: "Use the same thing you worked on last quarter" dooms everyone who made wrong foundational choices with their old project to spend most of their time "fighting the last war".
"Saying: "Use the same thing you worked on last quarter" dooms everyone who made wrong foundational choices with their old project to spend most of their time "fighting the last war"."
Not unless you told them before they started the previous year's project that it'll be used further along the line.
I'd just make it one really long subject that spans 3/4 years.
Not unless you told them before they started the previous year's project that it'll be used further along the line.
I'd just make it one really long subject that spans 3/4 years.
I actually discussed this idea with professors at my university, but the general consensus was that it was too ambitious/complicated to work into the current system.
My undergraduate program at Georgia Tech attempted to do this in CS2335 (Software Practicum). That I recall, our first project was an IM client/server, our second was a client/sever game involving programmable automatons, and our third project was a hybrid of Space War-Asteroids-Trader-Lander-Pirates.
You had the option of building them all completely separately, but you were strongly encouraged to re-use code form earlier revisions, particular for the client-server bits. The class also included labs on Subversion, although nothing on the notion of things like code review. I could imagine teaching the course today with Github and requiring (or at least awarding some credit for) good use of Pull Requests, meaningful code review, etc.
Sadly it looks like the course no longer exists; I have no idea what replaced it.
You had the option of building them all completely separately, but you were strongly encouraged to re-use code form earlier revisions, particular for the client-server bits. The class also included labs on Subversion, although nothing on the notion of things like code review. I could imagine teaching the course today with Github and requiring (or at least awarding some credit for) good use of Pull Requests, meaningful code review, etc.
Sadly it looks like the course no longer exists; I have no idea what replaced it.
CS2340 replaced it. It is a java project course, working in groups of 4-5 people. In my opinion, and that of many others, it is very useless.
6.170 at MIT attempted to be a 'real-life' coding lab class, while teaching OO concepts. First you're given an assignment; eg, write a simple physics engine that simulates a pool table, and you're graded on your implementation of this. Next a curve-ball is thrown that you're not supposed to know before hand. Eg. Add gravity and turn it into pinball. (Apparently, it's no longer taught in Java, but a quick glance says the curriculum hasn't fundamentally changed - it's a 'real-world' coding lab - now with git!)
I was lucky enough to start my career at a place which appreciated stable working software and the principle of slowing the fuck down. Then I had the unfortunate experience of changing jobs and ending up at a place where speed was king. Developers were worshiped by their ability to blast through projects. I would call this the "Get Shit Done" principle.
What I have found is that you need a balance. "Slow the Fuck Down" gets you working software, but if that takes you twelve months to a year, you lose the sense of progress and accomplishment that having a live product gives you. There has to be a healthy balance between "Slow the Fuck Down" and "Get Shit Done" which usually involves cutting features, prioritizing and temporary fixes. Most projects using MOSCOW is a good place to start with this.
What I have found is that you need a balance. "Slow the Fuck Down" gets you working software, but if that takes you twelve months to a year, you lose the sense of progress and accomplishment that having a live product gives you. There has to be a healthy balance between "Slow the Fuck Down" and "Get Shit Done" which usually involves cutting features, prioritizing and temporary fixes. Most projects using MOSCOW is a good place to start with this.
I think it's unfortunately common to have "Get Shit Done" people that work on making greenfield stuff quickly and "Slow the Fuck Down" that make that stuff work and keep working, which is both technically and politically.
Also, what is MOSCOW?
Also, what is MOSCOW?
Maybe I've had it pretty hard but from my personal experience, often what happens is that the reason why I can't write unit tests, documentation, or spend enough time in a code review so that the code is maintainable is because either the project manager or the client is always screaming at the top of his lungs that he needs everything done by yesterday.
If you hire an electrician to wire your house, he doesn't say “This costs $3,500 (or whatever) and another $700 to ground everything properly." He says "That will cost $4,200", because he is a professional, and he is going to do the job correctly, or not at all.
Part of our jobs as professional developers is to understand the potential business impact on a feature and not invest time on documentation or unit tests for code that will probably be dropped next week. That said, and not to be harsh—but if you want to be treated like a professional, act like one, and set expectations for how much a feature costs to deliver, rather than breaking your work down into separate tasks and inviting your supervisor to discard the tasks he doesn't understand.
Part of our jobs as professional developers is to understand the potential business impact on a feature and not invest time on documentation or unit tests for code that will probably be dropped next week. That said, and not to be harsh—but if you want to be treated like a professional, act like one, and set expectations for how much a feature costs to deliver, rather than breaking your work down into separate tasks and inviting your supervisor to discard the tasks he doesn't understand.
I was going to reply, but you said exactly what I would have. As an electrical engineer, it's been beaten into me from a very early age that my job is not to get shit done quickly, but get it done right. The client always wants things done double quick, and the project manager always wants to meet his crazy deadlines.
The best thing you can do in this situation, is hold your ground and slow the fuck down. Not because you're a recalcitrant bastard, but because you are the one responsible for quality. Once you learn this, and really internalise it, a lot of things fall into place. Projects are a tug of war over the time / cost / quality triangle. Make sure you're pulling your corner.
The best thing you can do in this situation, is hold your ground and slow the fuck down. Not because you're a recalcitrant bastard, but because you are the one responsible for quality. Once you learn this, and really internalise it, a lot of things fall into place. Projects are a tug of war over the time / cost / quality triangle. Make sure you're pulling your corner.
This. Thousand times this.
To fix the corporate world is to say "No" more often.
To fix the corporate world is to say "No" more often.
Listen to me. This is very, very important. Just do the tests anyway. Don't put them in the same repo, do them through the API, and don't go overboard, but for people that scream about needing things yesterday are obviously poor planners, poor planners change their minds frequently and this requires a test suite to keep up with.
You make tests for your own stuff, but 15 other engineers don't make tests. You have partial test coverage and it just becomes overwhelming because 15 people can write more code lines than you can.
You can't do everyone's job. Trying to write tests for the whole team (in addition to your own work) will just exhaust you. But doing tests on your just own code is still better than no one doing it. Better yet, see if you can use it as a tool to convince others and recruit them to your side.
"Better yet, see if you can use it as a tool to convince others and recruit them to your side."
Been there, tried that. I make it as easy as "run this bat file to test everything" in this specific sub-project. And then I watch them make some silly little "test-program" to debug the thing. Not only that, but we discuss a feature in said sub-project that they're implement and I hear disturbing comments such as "I hope it works" or "I hope it all still works after I'm done".
Been there, tried that. I make it as easy as "run this bat file to test everything" in this specific sub-project. And then I watch them make some silly little "test-program" to debug the thing. Not only that, but we discuss a feature in said sub-project that they're implement and I hear disturbing comments such as "I hope it works" or "I hope it all still works after I'm done".
That's the point where you need to ask yourself if you're doing yourself any favors working on a project with 15 other engineers who don't even write unit tests. Go find a better project and/or company.
The poor planners are in charge. Usually if you're going to build tests, you'll be doing it on your own time. That's where the 60+ hour work weeks come from.
If you're not going to build tests, you'll spend 4x in debug sessions and also get "fear of change".
I worked in a project where we had 80%+ branches coverage in unit tests and awesome automated regression package for end-to-end. When you have that, you have a luxury to be lazy in predictions what would break if I fix this. 90% of defect were business-related, not stability or functionality issues.
It entirely depends on the culture. In my career I've worked in test centric environments, and I've worked in places were testing was nearly forbidden. You can guess which ones generally run smoother. Some places just really care about cranking code out the door, and the people in charge don't realize how badly they're shooting themselves in the feet. It's more common than you'd think.
But I agree with everything you're saying, which is why I try to get into more test centric cultures when job hunting.
But I agree with everything you're saying, which is why I try to get into more test centric cultures when job hunting.
Spend the time to do all that stuff anyway. It's part of your job as a developer and they don't need to know the breakdown of how long it took you to finish the work or what you did with every minute of every day.
What's really lovely is when you take the electrician's attitude (professionalism), and always do the tests and documentation anyway, and then find that you are avoided for new jobs because of your "perfectionist" attitude and longer job estimates.
Eventually some of the management may learn how unwise this is, but it can take a long time, especially when many projects don't end up being successful/used by intended users anyway (which is its own drag on morale). I don't work in this environment anymore, thankfully.
Eventually some of the management may learn how unwise this is, but it can take a long time, especially when many projects don't end up being successful/used by intended users anyway (which is its own drag on morale). I don't work in this environment anymore, thankfully.
I'm ambivalent about this. The idea of professionalism is innately appealing, but in many cases I think programmers are too unwilling to put themselves in the project manager's or customer's shoes and try to understand why they believe they need things yesterday. Most of the time they aren't just meanies, but rather have very real constraints they are attempting to work within, things like "will I even be able to pay all these salaries if this doesn't get to market in the next two weeks?" or "will I have to lay people off because our budget for next year is cut if we don't meet our goals?", which they are insulating people from.
What? No, 99% of the time it's just "if I ask for it faster the guy will work harder"
Maybe it's because I've worked in smaller teams but there was no real pressure to deliver a month earlier. When we presented to other people in the company they don't really care if we covered 38% of cases this month or 42%, they simply don't know what those numbers mean.
Maybe it's because I've worked in smaller teams but there was no real pressure to deliver a month earlier. When we presented to other people in the company they don't really care if we covered 38% of cases this month or 42%, they simply don't know what those numbers mean.
I guess your mileage may vary? I have yet to come across people who are pointlessly cruel, but have come across a few who were thought to be, but actually had understandable motivations that very few people bothered to wonder about.
Just say how long you will think it will take realistically. Project managers don't usually understand the code. Be as honest as you can be.
Somebody somewhere said that:
"Estimate the time it takes to finish the project. Then multiply that by 8"
Surprisingly, this usually lands in the correct estimate. Best advice ever.
Somebody somewhere said that:
"Estimate the time it takes to finish the project. Then multiply that by 8"
Surprisingly, this usually lands in the correct estimate. Best advice ever.
Depends on the culture of the workplace if this will work. If they have many developers, who really underestimate but always end up over the deadline all the time. Then you give an estimate thats double, your gonna look bad even if your dead on. And they're going to try to push that estimate down.
80% of workplaces are like that.
I think its the incentives of billable hours that does this. They want low estimates, so they can win the work at all costs. They have to do it because other companies also underestimate. That or they think pressure motivates developers, but it really results in terrible code.
I personally advocate using accurate estimates, then applying a discount if you have to.
80% of workplaces are like that.
I think its the incentives of billable hours that does this. They want low estimates, so they can win the work at all costs. They have to do it because other companies also underestimate. That or they think pressure motivates developers, but it really results in terrible code.
I personally advocate using accurate estimates, then applying a discount if you have to.
Did you know you can change that culture?
Underestimating is very common with programmers, yeah, because they think they can do it in the given time, but in reality that almost never happens, at least to my experience.
What is an accurate estimate ? It changes all the time when new pitfalls and problems are discovered during the development cycle. So accurate estimate is something that almost all the time more than the original estimate, if you think logically. So better to just multiply by some factor that is realistic.
Underestimating is very common with programmers, yeah, because they think they can do it in the given time, but in reality that almost never happens, at least to my experience.
What is an accurate estimate ? It changes all the time when new pitfalls and problems are discovered during the development cycle. So accurate estimate is something that almost all the time more than the original estimate, if you think logically. So better to just multiply by some factor that is realistic.
I usually multiply how long I think it would take to do a task by three - it has not failed me.
Three is a nice multiplier too. Just after I posted this I started to think about it, 8 might be too much, but on complex projects with many developers, it's not even so far fetched, there's always things that we cannot see before we start to work on those, a task that takes on our mind 1-2 days might take up to 2 weeks easily if there is some problem that is not solvable right away.
"we don't have time for that. You're a rockstar. Make it happen".
That's the most bullshit line you hear in companies.
Sometimes we can make it happen, and ship code, but then most of the time somebody has to go in and fix it later to actually be extendable and work in other places than the original use-case..
It doesn't make sense in the long run to do this "fix, patch, fix, patch" non-sense .. but still companies need to ship shit to some deadline, so we do it.
It doesn't make sense in the long run to do this "fix, patch, fix, patch" non-sense .. but still companies need to ship shit to some deadline, so we do it.
"You don't have time for me not to do it. I'm a rockstar. Listen to me."
Yeah, I know that it's not likely to work...
Yeah, I know that it's not likely to work...
Sometimes it does. It's the battle that every developer, especially leads, will face quite often in this career.
You need a new job (as do I probably). There are companies that are not like this, and clients that value developers with exactly these skill sets.
This has been my experience and that of my peers the last 15 years or so. The easy is answer is "Tell them no" but the problem lies in the fact that those project managers and clients have all the power.
Devil's advocate:
> Peter asked Zawinski, “Overengineering seems to be a pet peeve of yours.”
> “Yeah,” he says, “At the end of the day, ship the fucking thing! It’s great to rewrite your code and make it cleaner and by the third time it’ll actually be pretty. But that’s not the point—you’re not here to write code; you’re here to ship products.”
> My hero.
http://www.joelonsoftware.com/items/2009/09/23.html
> Peter asked Zawinski, “Overengineering seems to be a pet peeve of yours.”
> “Yeah,” he says, “At the end of the day, ship the fucking thing! It’s great to rewrite your code and make it cleaner and by the third time it’ll actually be pretty. But that’s not the point—you’re not here to write code; you’re here to ship products.”
> My hero.
http://www.joelonsoftware.com/items/2009/09/23.html
Anyone who used Netscape knows how that approach turned out.
"Slow the 'f down" is the wrong thing to say. Younger-me is totally capable of finishing in 3-hours and then lying about it for 2 more days. That results in a slow down without any improvement to the code.
The more important lesson I would impart upon my younger self is that the code isn't done until it's been committed, there's been a README written, and some testing has been done. Who cares if it works? Pft, that's the easy part!
If your commit messages after the first few aren't more specific than 'updated' or 'new stuff', you fail. If the README is 1 line long and just says 'I made a thing', you fail more.
And then there's this:
You dig up old code, and it really sucks. The idiot that wrote it should not be allowed behind a keyboard! Y'all know the end to this story - the 'blame' command points the finger... at yourself.
There's nothing more humbling than that.
Proper software engineering isn't about writing code, it's about maintaining developer sanity, especially in the face of fast-moving business requirements. Don't push back hard enough and the sale's guy's unrealistic schedules start to dominate. Push back too far and you start writing a frameworks on top of frameworks instead of deliverable code. Push back too far and you end up with lazy engineers who drop features because they're "too hard" to test (Hello Google, so glad you decided not to drop ext4 support in ChromeOS's Files app.)
But in today's fast-moving world? Run. Run as fast as you can. Keep running.
The more important lesson I would impart upon my younger self is that the code isn't done until it's been committed, there's been a README written, and some testing has been done. Who cares if it works? Pft, that's the easy part!
If your commit messages after the first few aren't more specific than 'updated' or 'new stuff', you fail. If the README is 1 line long and just says 'I made a thing', you fail more.
And then there's this:
You dig up old code, and it really sucks. The idiot that wrote it should not be allowed behind a keyboard! Y'all know the end to this story - the 'blame' command points the finger... at yourself.
There's nothing more humbling than that.
Proper software engineering isn't about writing code, it's about maintaining developer sanity, especially in the face of fast-moving business requirements. Don't push back hard enough and the sale's guy's unrealistic schedules start to dominate. Push back too far and you start writing a frameworks on top of frameworks instead of deliverable code. Push back too far and you end up with lazy engineers who drop features because they're "too hard" to test (Hello Google, so glad you decided not to drop ext4 support in ChromeOS's Files app.)
But in today's fast-moving world? Run. Run as fast as you can. Keep running.
> (The dreaded Windows 3.1 "General Protection Fault" error made such frequent appearances that my boss, the company's CEO, took to saluting me with a sardonic "Salut, mon Général !" when he passed me in the hallway.)
Ouch!!
Ouch!!
Going slow is often a good idea, but part of the wisdom that comes from 20 years writing software is knowing when you should choose between slowing down, coding like hell, slapping something half-working together, etc.
I generally agree with this post. What I have found to be ironic, personally, is that good automated testing often takes a long time to implement and it feels like it takes forever sometimes. However it usually shortens the overall development time and increases quality because you can add new features, re-factor others, etc and then just run the tests to make sure you didn't break something. And if you did break something, you know immediately what it is wrong and can fix it.
Lots of people seem to think that an automated test suite is a guarantee that you know when you've broken something. I have never found that to be true. Sometimes I have even found it to be a dangerous idea, leading to complacency in reasoning about the potential impacts of a change and actively verifying its behavior. It's great to have a good automated test suite, but it's much greater to also have people using and verifying software.
That is why I used the adjective "good". Like you said, just having an automated test suite is not necessarily useful. Let me define what I mean by "good".
A good automated test suite has a very high (>90%) coverage of all cases that an actual user may encounter in the real world. It is extremely difficult to achieve this in the initial version of the test suite. The goal initially should be to build a test suite that can be quickly and easily updated so that >90% test coverage can be achieved over time.
When people are "using and verifying software" or when there is a bug found in production, the bug fix should be accompanied by an update to the test suite. This way this particular bug will never happen again in production. In addition, you never let your guard down and continue this process for as long as the product exists. Over time this process will yield a test suite so good that you can assume that a particular change hasn't broken existing functionality even though there isn't a 100% guarantee.
The cool thing now is that build tools are so good that you can codify some of this process into the build to ensure commits are tested before merged. And commits are reviewed to verify relevant tests were added or updated before merged.
A good automated test suite has a very high (>90%) coverage of all cases that an actual user may encounter in the real world. It is extremely difficult to achieve this in the initial version of the test suite. The goal initially should be to build a test suite that can be quickly and easily updated so that >90% test coverage can be achieved over time.
When people are "using and verifying software" or when there is a bug found in production, the bug fix should be accompanied by an update to the test suite. This way this particular bug will never happen again in production. In addition, you never let your guard down and continue this process for as long as the product exists. Over time this process will yield a test suite so good that you can assume that a particular change hasn't broken existing functionality even though there isn't a 100% guarantee.
The cool thing now is that build tools are so good that you can codify some of this process into the build to ensure commits are tested before merged. And commits are reviewed to verify relevant tests were added or updated before merged.
I'd be curious how many people feel like they have automated test suites that achieve greater than 90% coverage of user actions (presumably this means the tests are at the integration level). Really good integration test suites are definitely great for catching regressions and being confident in making changes, but in my experience they are also difficult to build, slow to run, and expensive to maintain. Which is why, I think, people often focus more on getting high coverage of unit tests, which are much lower cost, but not nearly as useful for catching regressions.
Slowing down was one of the hardest and best things I have ever done.
It can be hard in environments where even hours longer on a piece of work can make the difference between happy customers and sad ones but it pays off quite quickly.
You write better code which is easier to maintain and has more tests. In doing so you are able to improve your craft which is hard to do when you are rushing yourself.
Once you get better you will be more productive and can get work done faster but with acceptable quality.
It can be hard in environments where even hours longer on a piece of work can make the difference between happy customers and sad ones but it pays off quite quickly.
You write better code which is easier to maintain and has more tests. In doing so you are able to improve your craft which is hard to do when you are rushing yourself.
Once you get better you will be more productive and can get work done faster but with acceptable quality.
Writing software and Selling software need different and distinct skills.
Nice article. "I'll quickly rewrite the engine", said no wise developer ever.
In addition to the negative impacts on code and the actual product of going too fast, there is the additional problem of working at an unsustainable pace. That then becomes the norm and is expected even when it can no longer be kept up. This isn't a problem specific to programming. It shows up in almost any job.
Over-performance will never be rewarded. One might get a slightly higher bonus if one is lucky, but generally it'll be forgotten. All those long days, nights, and weekends spent working non-stop will be immediately erased from the company's recollection once the product ships. They will be especially forgotten once the developer can no longer sustain that pace which now has become the norm and needs to be reprimanded (despite still being objectively productive).
In the end, it's only the developer who suffers, and it'll be great suffering up to and including mental and physical disability from not slowing down. Excellent advice.
Over-performance will never be rewarded. One might get a slightly higher bonus if one is lucky, but generally it'll be forgotten. All those long days, nights, and weekends spent working non-stop will be immediately erased from the company's recollection once the product ships. They will be especially forgotten once the developer can no longer sustain that pace which now has become the norm and needs to be reprimanded (despite still being objectively productive).
In the end, it's only the developer who suffers, and it'll be great suffering up to and including mental and physical disability from not slowing down. Excellent advice.
You hit the nail on the head here. The harder you work, the more that becomes the "norm." Now, if you decide to slow down, you start to look "less productive."
Absolutely true. We need a culture where management is done by engineers.
This means we need to step up as engineers and start becoming managers.
But we also need to refuse to work for managers who are incompetent.
IF you're a programmer and you're reporting to someone who is not the CEO and is not an engineer, then you need to find another job and tell them why.
Time to stop working for startups run by CEOs who have nothing more than a business degree. IF the CTO is a competent engineer and the CEO has some domain expertise that's fine.
At amazon my boss, literally, had wanted to be a prison guard and gone to school for that. He was a terrible manager. They didn't even hire engineers to be managers, they just got these random incompetents. His boss was right out of the DMV. It was that way all the way up the chain of command to bezos. When nobody between you and the CEO, including the CEO, is a competent engineer, you're not going to be managed well. (and Amazon's software quality reflects that, despite the constant hype the site is a tragedy of bad design.)
This means we need to step up as engineers and start becoming managers.
But we also need to refuse to work for managers who are incompetent.
IF you're a programmer and you're reporting to someone who is not the CEO and is not an engineer, then you need to find another job and tell them why.
Time to stop working for startups run by CEOs who have nothing more than a business degree. IF the CTO is a competent engineer and the CEO has some domain expertise that's fine.
At amazon my boss, literally, had wanted to be a prison guard and gone to school for that. He was a terrible manager. They didn't even hire engineers to be managers, they just got these random incompetents. His boss was right out of the DMV. It was that way all the way up the chain of command to bezos. When nobody between you and the CEO, including the CEO, is a competent engineer, you're not going to be managed well. (and Amazon's software quality reflects that, despite the constant hype the site is a tragedy of bad design.)
Absolutely agree on this. Managers should have an engineering background. Managers and Technical Leads should be chosen from those who are bored with the engineering aspect (eg programming, designing, implementing) and want to focus on bigger challenges like leading a technical project.
Managers who only manage people have no clue about what it takes to think technically, so they tend just to apply their human management techniques to a technical AND human problem. Engineers can become managers, but manager only people cannot become engineers during the course of leading a project.
Managers who only manage people have no clue about what it takes to think technically, so they tend just to apply their human management techniques to a technical AND human problem. Engineers can become managers, but manager only people cannot become engineers during the course of leading a project.
> Absolutely true. We need a culture where management is done by engineers.
I'm not so sure, you want engineers to be engineering. You want good managers to be managing. The skillsets don't have much overlap and people who are good at one might be lousy at the other.
I'm not so sure, you want engineers to be engineering. You want good managers to be managing. The skillsets don't have much overlap and people who are good at one might be lousy at the other.
Someone who does not understand how software is produced cannot manage the process of producing software.
It's easy to learn to manage programmers, I've done it, and I did it by dealign with a lot of bad managers.
In 25 years I've yet to meet a manager who was good at managing software development who did not have an engineering background. At best, the best managers sat by and let the programmers run the show and they themselves just helped with interpersonal problems and hr, and spend their time doing some project management type efforts.
The idea that managers possess something magical that engineers don't have is false.
Or maybe over decades I've just randomly never seen it. And I've worked at places like Amazon and Microsoft-- at amazon the managers were not engineers and it really sucked. At microsoft the mangers were engineers and at least in that regard it was much better.... except at the higher levels where it became political and the mangers stopped being engineers, and thus projects got behind.
It's easy to learn to manage programmers, I've done it, and I did it by dealign with a lot of bad managers.
In 25 years I've yet to meet a manager who was good at managing software development who did not have an engineering background. At best, the best managers sat by and let the programmers run the show and they themselves just helped with interpersonal problems and hr, and spend their time doing some project management type efforts.
The idea that managers possess something magical that engineers don't have is false.
Or maybe over decades I've just randomly never seen it. And I've worked at places like Amazon and Microsoft-- at amazon the managers were not engineers and it really sucked. At microsoft the mangers were engineers and at least in that regard it was much better.... except at the higher levels where it became political and the mangers stopped being engineers, and thus projects got behind.
At AWS, engineering management is technical all the way up to and including Charlie Bell. It's not really different from any other top tech company in that respect.
Pardon me for this, but I'm a bit irked by being taken out of context.
Most obviously, Michael urges young programmers deciding how much effort to put into their work to "ebb towards underperformance".
That's not what I said. From the source (on Quora, here: http://www.quora.com/What-do-software-developers-age-30-and-...):
3. Recognize underperformance and overperformance and avoid them. There are a lot of low-effort players who stay employed for years. This isn't a bad strategy if you're settled, but I wouldn't fall too low. That said, the only people who typically get fired for underperformance are the people who fail so badly that they generate work for others. People who hide and do little tend not to make any enemies. At the same time, be cautious of overperformance. This isn't like college where challenging your professor's ideas could earn you an 'A' if you argued your point well. Overperformers often also generate extra work for their superiors and colleagues and draw unwanted attention (see: McNulty in The Wire) and are more likely to be culled for "performance" (98 percent of "performance management" in companies is politics) than underperformers. I'm not saying that you shouldn't work hard and do a good job and learn as much as you can. That's not necessarily overperformance. In my experience, though, overperformance is much more dangerous than underperformance. It can get you just as fired and it will happen a lot faster. If you end up stuck between the two, prefer underperformance.
I'm not saying that people shouldn't work hard or do a good job. On the contrary, I think young people should bust their asses at growing the skills and contacts that will serve them well for the rest of their lives. I'm saying "avoid overperformance", and overperformance isn't the same thing as "doing a great job". I'm saying, "don't become like McNulty on The Wire" (or a certain person at Google who tried to prevent a product failure and got burned for it). McNulty is a textbook overperformer: he loves the job, it doesn't love him back, and he puts so much into it that it destroys his life and career.
Sorry, but I'm pretty fucking pissed out this being out there like that. That was way the fuck out of context. I wasn't happy with the Lifehacker edit either but I didn't speak up about that because I didn't see it as a big deal. But I am definitely not telling a generation of people to slack off at their jobs.
Most obviously, Michael urges young programmers deciding how much effort to put into their work to "ebb towards underperformance".
That's not what I said. From the source (on Quora, here: http://www.quora.com/What-do-software-developers-age-30-and-...):
3. Recognize underperformance and overperformance and avoid them. There are a lot of low-effort players who stay employed for years. This isn't a bad strategy if you're settled, but I wouldn't fall too low. That said, the only people who typically get fired for underperformance are the people who fail so badly that they generate work for others. People who hide and do little tend not to make any enemies. At the same time, be cautious of overperformance. This isn't like college where challenging your professor's ideas could earn you an 'A' if you argued your point well. Overperformers often also generate extra work for their superiors and colleagues and draw unwanted attention (see: McNulty in The Wire) and are more likely to be culled for "performance" (98 percent of "performance management" in companies is politics) than underperformers. I'm not saying that you shouldn't work hard and do a good job and learn as much as you can. That's not necessarily overperformance. In my experience, though, overperformance is much more dangerous than underperformance. It can get you just as fired and it will happen a lot faster. If you end up stuck between the two, prefer underperformance.
I'm not saying that people shouldn't work hard or do a good job. On the contrary, I think young people should bust their asses at growing the skills and contacts that will serve them well for the rest of their lives. I'm saying "avoid overperformance", and overperformance isn't the same thing as "doing a great job". I'm saying, "don't become like McNulty on The Wire" (or a certain person at Google who tried to prevent a product failure and got burned for it). McNulty is a textbook overperformer: he loves the job, it doesn't love him back, and he puts so much into it that it destroys his life and career.
Sorry, but I'm pretty fucking pissed out this being out there like that. That was way the fuck out of context. I wasn't happy with the Lifehacker edit either but I didn't speak up about that because I didn't see it as a big deal. But I am definitely not telling a generation of people to slack off at their jobs.
Your article can be reinforced by the Ribbon Farm analysis of "The Office" [1]. What you have stated about over-performance seems to line up nicely with the "clueless" in that hierarchy.
To quote from Ribbon Farm article: "The simple reason is that if you over-perform at the Loser level, it is clear that you are an idiot. You’ve already made a bad bargain, and now you’re delivering more value than you need to, making your bargain even worse. Unless you very quickly demonstrate that you know your own value by successfully negotiating more money and/or power, you are marked out as an exploitable clueless Loser. "
[1] http://www.ribbonfarm.com/2009/10/07/the-gervais-principle-o...
To quote from Ribbon Farm article: "The simple reason is that if you over-perform at the Loser level, it is clear that you are an idiot. You’ve already made a bad bargain, and now you’re delivering more value than you need to, making your bargain even worse. Unless you very quickly demonstrate that you know your own value by successfully negotiating more money and/or power, you are marked out as an exploitable clueless Loser. "
[1] http://www.ribbonfarm.com/2009/10/07/the-gervais-principle-o...
Michael has written nearly 30 essays on the Gervais Principle - check out his blog.
I will have to check them out and possibly emotionally prepare myself since living through seeing this in a large company is hilarious and sad at the same time.
>>I'm saying "avoid overperformance", and overperformance isn't the same thing as "doing a great job"
Can someone explain this formulation of 'performance' without referencing "the Wire"? Ie is it simply long hours? Or is it long hours coupled with getting a lot done, in a good way? Or is it getting a lot done, and breaking things for everyone else? Or ...?
Can someone explain this formulation of 'performance' without referencing "the Wire"? Ie is it simply long hours? Or is it long hours coupled with getting a lot done, in a good way? Or is it getting a lot done, and breaking things for everyone else? Or ...?
Basically going outside of the, often implicit, boundaries of your role.
For example if you are a developer and realise your project needs to engage another team NOW for a critical deliverable due in 3 months and you spend your time on this task then you run the serious risk of pissing off both your manager and the project manager.
Or for example putting together a prototype that shows how another teams work could be automated.
Or pointing out flaws/discrepancies of a high profile product. Or telling a senior manager how a project is really doing, etc.
The bottom line doesn't matter as much in terms of respect and career progress as it should. There is a misconception that you can get away from politics if you work for startups or smaller firms but that's just not the case.
For example if you are a developer and realise your project needs to engage another team NOW for a critical deliverable due in 3 months and you spend your time on this task then you run the serious risk of pissing off both your manager and the project manager.
Or for example putting together a prototype that shows how another teams work could be automated.
Or pointing out flaws/discrepancies of a high profile product. Or telling a senior manager how a project is really doing, etc.
The bottom line doesn't matter as much in terms of respect and career progress as it should. There is a misconception that you can get away from politics if you work for startups or smaller firms but that's just not the case.
You nailed it. My upvote is not enough, and you will probably get fewer than you deserve for this post.
It's more like getting a lot done and breaking things for everyone else. Imagine your boss has a terribly, horrendously stupid way he wants things done. Overperformance would be going over his head to his boss to try to change the awful policy. It might be the right thing to do, but you're only going to piss off your boss in the process. Michael is saying it's better to do what the boss asks in that case, but only do the minimal amount of work necessary, instead of going off on a crusade that will only cause trouble for yourself and provides no benefit.
At my first job, I used to grind out work, staying hours past when most people went home. For me, this was the best time to actually get work done without the distractions. But I remember my project manager, who was twice my age, getting pissed off at me and telling me to go home. When I was completing tasks and sending off emails, I was just giving her more work to do that night. So that would be overperforming I think.
Don't worry, only someone purposefully attempting to misunderstand you would take their interpretation as the context.
As a previous overperfomer(who got burned for it) I find overperforming is often a product of misunderstanding what the company wants you to do, and in the end it doesn't help you, your peers, or anyone except your personal idea of what you think is right, without regard to reality.
As a previous overperfomer(who got burned for it) I find overperforming is often a product of misunderstanding what the company wants you to do, and in the end it doesn't help you, your peers, or anyone except your personal idea of what you think is right, without regard to reality.
Author here. I linked to your post and there are comments on the blog (which you took advantage of). No need to be pissed off. I still disagree with this particular point (and I'm not sure why you say I took that quote out of context), despite your clarification. But overall I think you provide a lot of good and valuable advice that might be counterintuitive to younger devs entering the corporate world.
I find it amazing that people swear in the title. Surely the author must have the self-awareness to realise that few will be impressed and many will be turned off.
It's a puerile attempt to be edgy or authentic. Not that it shocks me, judiciously used swear words can be effective -- most often in spoken English, but occasionally in written as well. It just adds nothing to this title.
This case from yesterday: http://fuckinggodateformat.com/ is slightly better. It tells the reader that the author of the page doesn't like the go date format in a succinct fashion. Though, on the other hand, it primes you for a rant rather than a cheat-sheet.
This case from yesterday: http://fuckinggodateformat.com/ is slightly better. It tells the reader that the author of the page doesn't like the go date format in a succinct fashion. Though, on the other hand, it primes you for a rant rather than a cheat-sheet.
Of course, that guy did a PG version, too:
http://flippinggodateformat.com/
http://flippinggodateformat.com/
I suspect that you are conflating "I'm turned off" and "many will be turned off". I seriously doubt it will make any difference either way to the hacker news demographic.
Personally it doesn't bother me a bit. But I would be less likely to tweet it or share it publicly for fear of offending certain people who may be overly sensitive, but I have respect for.
This is one reason I don't use swear words in my blog posts. Also I don't my site blocked by any filters. My personal policy, but I really don't care if other people do it.
This is one reason I don't use swear words in my blog posts. Also I don't my site blocked by any filters. My personal policy, but I really don't care if other people do it.
Sounds to me like a good filter for your audience. Kinda like the color scheme of jwz's website.
It's certainly a filter, I'm not sure I would say it's good though.
Especially since the content is relatively tame. It's not like a Cracked article or anything. It's just a regular blog post...
Personally I didn't even notice. To me "curse" words are just words that evoke a stronger meaning in the rest of title. Potatoes are horrible vs Potatoes are shit. It just seems like the curse word gets the meaning across better, at least to me.
I used to have the same reaction, and your post made me realize that I don't even notice it anymore.
EDIT: That said, I do agree with the post, as someone who is also twenty years in.
EDIT: That said, I do agree with the post, as someone who is also twenty years in.
20 years ago, colleges taught you to program slowly, with good architecture and with maintainability. When I was taking CS courses we were taught to flowchart our programs, write them all out, and really create the software on paper before even touching a computer.
I've observed that programmers from successive generations become more and more likely to just sit down and start writing before they've even had proper time to think.
I think there's a spectrum, with one extreme example being the person who writes 1,000 lines in 2 hours of code that is buggy and unmaintainable but that the boss is really impressed because it does %70 of what is needed. These guys really impress PHBs.
At the other end of the spectrum is the guy who gets the same assignment, does nothing but sit in his cubicle thinking for a week. And then over the course of a day writes 100-200 lines that does %90 of the assignment, and with no bugs.
Current culture seems to favor the former guy-- which is why we have unit tests (to catch all his bugs) and the assumption that code is crap. There isn't much cultural support for the latter guy... but those guys, in my experience are the better programmers.
For trivial programs speed is king, but trivial programs can be done by either guy with a difference of a few hours in time to completion.
For programs of significance... the slower guy can save you months or years and even cut your required engineering headcount.
But that guy doesn't seem to be recognized for what he does-- in fact, he's often perceived as not working as hard, and is many times interrupted for no good reason, but because they think he needs more work.
I've observed that programmers from successive generations become more and more likely to just sit down and start writing before they've even had proper time to think.
I think there's a spectrum, with one extreme example being the person who writes 1,000 lines in 2 hours of code that is buggy and unmaintainable but that the boss is really impressed because it does %70 of what is needed. These guys really impress PHBs.
At the other end of the spectrum is the guy who gets the same assignment, does nothing but sit in his cubicle thinking for a week. And then over the course of a day writes 100-200 lines that does %90 of the assignment, and with no bugs.
Current culture seems to favor the former guy-- which is why we have unit tests (to catch all his bugs) and the assumption that code is crap. There isn't much cultural support for the latter guy... but those guys, in my experience are the better programmers.
For trivial programs speed is king, but trivial programs can be done by either guy with a difference of a few hours in time to completion.
For programs of significance... the slower guy can save you months or years and even cut your required engineering headcount.
But that guy doesn't seem to be recognized for what he does-- in fact, he's often perceived as not working as hard, and is many times interrupted for no good reason, but because they think he needs more work.
> the person who writes 1,000 lines in 2 hours of code that is buggy and unmaintainable
> the person who gets the same assignment, does nothing but sit in his cubicle thinking for a week. And then over the course of a day writes 100-200 lines that does %90 of the assignment, and with no bugs.
I think you're leaving out the person who writes the buggy and unmaintainable version in 2 hours, in order to discover any pitfalls they failed to imagine before starting the project, then spends the remaining 38 hours of the week thinking about the proper solution to both the foreseen and unforeseen problems.
> the person who gets the same assignment, does nothing but sit in his cubicle thinking for a week. And then over the course of a day writes 100-200 lines that does %90 of the assignment, and with no bugs.
I think you're leaving out the person who writes the buggy and unmaintainable version in 2 hours, in order to discover any pitfalls they failed to imagine before starting the project, then spends the remaining 38 hours of the week thinking about the proper solution to both the foreseen and unforeseen problems.
What you don't learn in school is how to write maintainable code. This is a much different style of writing code, and much more valuable once you go out in the "Real World". I'm not sure if there are CS programs out that start with a small project and then force the students to make massive changes to that project throughout the course of the year, but to me there is immense value to that. Even better would be if they had CS101, CS201, CS301 and the students taking CS201 would be forced to dig up their project from CS101 and work on that, CS301 would work on the code from CS201, etc. It's eye-opening how much you forget about your code after a few weeks, so it would drive home the notion of commenting, writing easily readable code, etc.