Hacker News new | past | comments | ask | show | jobs | submit login
A bunch of programming advice I'd give to myself 15 years ago (mbuffett.com)
544 points by marcusbuffett 3 months ago | hide | past | favorite | 318 comments



I'll add one point. You are not your job. Don't take things personally at work. And never be afraid to leave if you're not fitting in with your company .

I've left jobs over a few reasons, primarily bad managers, increased compensation, and bad code .

If people are writing bad code at your company, to the point where you know it's going to come back to haunt you later, it's okay to just walk away .

Don't embarrass anybody, don't escalate to a manager and explain how horrible the code is. I was in a situation where someone our team was effectively writing code that pretended to do things it really didn't. I got into a really nasty argument with half my team about this. I ended up putting in my two weeks, and then my manager was like oh you were right the entire time .

Life is too short to deal with incompetent people.


It’s funny, this comment went in a totally different direction from what I expected based on the start.

When you wrote ‘don’t take things personally at work’, I was expecting you to say things things about various kinds of humility – trying to make requested changes in code review instead of pushing back, not feeling wronged if someone rewrites something you wrote, etc – and seeing the bigger picture – the code exists to serve business purposes and sometimes priorities there don’t align with your more narrowly focused desires for the direction the code should be changed in.

I would say that the rest of you comment gives examples of taking things quite personally – feeling such strong ownership over the code that you’ll quit when you can’t control it as well as you’d like. To be clear, I’m arguing that the beginning does not match the rest of the comment, but not really about the overall message, which to me feels to be more something like ‘you are not required to be loyal’ than ‘don’t take it personally’.


I explain more in other comments, but in this situation I was dealing with people who fundamentally could not program .

It wasn't a matter of, oh I would have done this differently, it was more like this company is full of people who have no idea what they're doing and I'd rather not be here .

I will say you should absolutely never talk about code issues at a current employer when interviewing. Who's ever interviewing you is going to interpret this as you being some weirdo who argues over tabs and spaces. There's not enough nuance communicated.

Maybe I'm trying to say you shouldn't take it personally when a company isn't a good fit.


I agree so much with your arguments.

There's a huge difference between "I don't like your variable name" and "this code is so messed up that any change will have to be manually checked against 20 major features under 20 different cases".


A lot of my progression as a software engineer has come from decoupling my ego from the things I produce. That’s hard to do because the code you produce is a very strong reflection of your mental models and it’s justified to feel some connection to it.

Tactfully navigating this kind of thing in code review takes practice.

In my experience, the best teams of programmers work through problems with their egos held to the side.


100% agree with you. The best teams I've been on have had complete harmony whether things were running smoothy or not. Everybody just banded together and got it done. Every once and awhile we'd encounter some bad code someone wrote and have a good laugh with each other and fix it up. Each and every person had one another's backs.


Unless you have a lot of flexibility in terms of where you work, this type of advice is becoming less relevant in an IT job market that's in free fall.

Much fewer devs can just jump ship at will than between 2003 - 2022.


In my situation it would have been much easier to just keep my head down until I was able to get another job. I ended up causing a lot of tension at work, the engineer who had wrote this code openly resented me .

Usually when people are putting broken code into the code base it's a wider cultural problem, that you're not realistically going to solve.


> Unless you have a lot of flexibility in terms of where you work, this type of advice is becoming less relevant in an IT job market that's in free fall. > Much fewer devs can just jump ship at will than between 2003 - 2022.

Citation needed. Good developers are just as in demand now as they have ever been.


The demand might be there, but if you have a proven way to get recognized as a "good developer" during the hiring process I'd love to hear it.


References. Ask the good devs you have for someone good they know.


Anecdata incoming: a company I worked for had such a referral. They bombed the interview. The referring employee was incredulous. I was asked to re-interview them. They did seem good, they got an offer. The experience delayed things, put a bad taste in the candidates mouth, they took a different offer.

My point, the result of interviewing a good developer is potentially random. There is perhaps less probability of a bad developer having a random outcome as well, but certainly can happen.

Though.. define "good". Some people are incredible only when in the right team and environment.


I have seen a few situations like this:

Company says "looking for an expert on X"

Expert on X walks into the room.

Interviewer: "How good are you at Y?"

Expert on X: "I know a little about Y, but not too much. I mostly use X for my work; I could show you how to solve the problem using X."

Interviewer: "Thank you for your time; goodbye."

When I tried to figure out why this happens, the answers are usually something stupid like: "HR posted the job announcement, they have no idea what we really need", or "yeah, we are still looking for an expert on X, but we need an expert on Y more urgently". (The latter still does not explain why they rejected the expert on X without asking him anything about X, but to the person who said this it seemed to make perfect sense.)


I think the parent commenter was asking from the point of view of a person looking to be employed, not a business or hiring manager looking for devs.


None of the FAANGs or even tier 2 companies work on references, unless you invented the internet or something.

And even then, there is a famous story of the dev of the popular MacOS FOSS package manager, Homebrew, failing his interview at Apple.


I don't get the point why a maintainer of a popular package failed his interview. Having a popular package has nothing to do with coding ability and much more to do with writing the right thing at the right time.


He wasn't the "maintainer of a popular package".

He was the creator/designer and main dev of Homebrew, the OSS <<package manager>> almost every dev on MacOS uses.

He took an idea to completion, made it production ready and used by probably millions of users.

I don't care about raw coding ability (Carmack style), if building such a large project doesn't prove at least development abilities, nothing does.


It's supply and demand. Demand is lower (less jobs.) Supply is higher (more layoffs, people looking for work.) Even if you are "good", there's a lot of other "good" people looking, too. Some even may be better than you! Or at least better at marketing themselves.


Marketing yourself is more important now than ever. The advent of AI has created a noise problem at the hiring level on both sides: applicants are leveraging tools to generate necessary documents (targeted resumes, cover letters, social profiles), recruiters are using scanning tools to weed out anything that doesn't contain the magical keywords or phrases.


Hard to compare the time period. I'm still coming to grips what it means when 95% of jobs I apply to are remote.

There are other data points to consider:

- higher interest rates and less VC money equates to less startups and less hiring

- large tech layoffs

To your point of demand for 'good' developers - I suspect that is likely true. I don't know how to decouple that from the problem of interviews not able to identify good developers. A 'good' developer is a function of the individual, what is happening in their life, the team, the codebase, leadership, process, tech debt, etc..


"Good developers are just as in demand now as they have ever been."

Citation needed.


The market is not in a free fall. Or rather, it's only a free fall for junior fresh-out-of-college developers. If you are skilled and senior, don't believe this nonsense and have confidence in yourself. This is just an extension of the imposter syndrome that I see often in many people.


If you are skilled and senior about 2 years back you'd compete with 5-10 other qualified candidates. Now it's 100+.


This is exactly it.

The entry level market is getting more and more over saturated. It is bleeding upwards to mid level slowly. But if you are a skilled senior you are still in high demand. If not your resume probably sucks or you are not as skilled as most seniors.


Don't just jump ship. But do actively look for better opportunities if you are not satisfied where you are.


Define “free fall”, please. There seem to be plenty of interesting openings as far as I can tell. Less hysterical hiring, but plenty of work (and more interesting than the endless CRUD of 15 years ago).


I disagree. If you have problems, you should try to escalate them. It's better for the company... it's better for your coworkers (they're probably also having these problems!) If you escalate them and nothing is changed, then it's time to go. If you're going to leave anyway, you may as well try to change things for the better first.


Yep. I’ve heard this talked about as Voice and Exit. They’re two strategies you almost always have available: essentially, speak up or leave.

If all the people who care about a problem leave, it becomes harder for the organisation to solve the problem. This is one form of organisational rot.

Most of us are good at one and bad at the other. Eg, my instinctive response has been to quit my job when I’m not enjoying it. And that’s fine, but some of the situations were almost certainly salvageable. And I could have helped. Some people try to fix a workplace indefinitely, even to their own detriment, and even when the situation is probably impossible to fix and they should just get out of there.

I think it’s really important to learn both skills. And remind myself when I’m stressed that they’re both options.


That model comes from Hirschman's treatise on Exit, Voice, and Loyalty. https://en.wikipedia.org/wiki/Exit,_Voice,_and_Loyalty


Feels a bit like a false dichotomy, in that there's at least one other option: wait it out. If you believe things will improve, the lapse is temporary, then doing nothing is a good move, and that's neither Voice nor Exit.


Totally right - it’s not a dichotomy. Those are just two strategies that happen to be broadly applicable. There are almost always other strategies available too, depending on the specific problem you’re facing. (Maybe you can fire the people involved. Maybe there’s a technical solution. Maybe you can ask for help. Etc etc.)


It really depends on the context.

The important thing to realize is that bad developers who are kept around tend to survive because they're well liked by people who make the decisions. If you raise concerns about their performance then you're picking a fight that you can very quickly lose. I've seen people get hung out to dry when they escalate concerns about people like that, and even if they were right it still leaves them in a much worse position for their next job hunt.

In most cases I'd tend to agree with OP that the right move for an employee in that situation is to lay low and start looking. If the situation isn't yet completely unbearable there's no need to just hand in your two weeks' notice, but it's worth looking for the exits.


I agree it is context dependent, but I was trying to show that it's not a binary choice between escalating or leaving. You can do both. If you lose the battle, at least you tried. I've left some jobs too early and regretted it. I could've done more and I should have done more. Probably, I would've failed anyway. Corporate politics and company culture is such a strong force.

The reality is many direct managers have little visibility into their reports day-to-day work because they are not hands-on enough. They should be checking the work product. Example: They should at least be looking at PRs and even participating in code reviews themselves. If you proposed this to some "engineering managers" I am familiar with, they would say this is not their job and you are crazy for even mentioning it. (I'd tell them I disagree about that, too.) This is why coworkers need to escalate performance problems: because many of the people making decisions do not know what is going on.


Or.

Hear me out.

You're going to then publicly embarrass another co worker. Not a good idea.

I need to clarify though, there's a difference between functional code that could have been written better, and code which does nothing at all .

I was at a company where three or four people literally were writing code that did nothing but was appearing to function correctly. Imagine an API that checks the status of another service, and you just code it to always return 200.

Instead of trying to save an organization from itself, you can just go somewhere else. I did so and I got like a $30,000 raise.


Not necessarily. You can escalate things to your boss. Or then their boss. They talk to the coworker about it. It doesn't have to (and shouldn't be) a public inquisition. Maybe you do some one-on-one sessions / mentoring to try to help them. Maybe you're not patient enough to try this. It's certainly easier to leave most of the time.

The code aspect is all shades of gray. I've seen code that "functions" but has such unacceptable levels of performance, quality, duplication, security problems, etc. that it would barely qualify as "working" and certainly not maintainable. You can't polish a turd.


I didn't have that experience, I was basically told that I should shut up and get used to working with code that doesn't functionally do anything .

Then when I complain later my manager was like, even though the code doesn't do anything it makes our metrics look better.

Imagine seeing

function1(){ ApiCall("1") }

function2(){ ApiCall("2) }

Over and over again.


I'd tell them I am not shutting up and this is a major problem affecting the quality of the product. I would then speak to the boss's boss about it and start complaining about the boss doing a poor job, encouraging fake, meaningless metrics to game the system. Maybe they'll get get fed up and tell you to GTFO. Probably not though. The thing about broken organizations is that they take forever to fire anyone, so use that to your advantage while you look for other jobs.


That seems like a whole lot of work, compared to just finding another job and walking out .

I'm not trying to change the world, I'm trying to make money so I can save and retire preferably before I turn 50.

If I've learned anything about life is that you need to pick what battles you want to fight.

If option A is argue with numerous people and openly expose multiple layers of incompetence, to the point where my manager and my coworkers are going to hate me .

Compared to, option B , keeping my head down until I can jump ship and then hoping the next place isn't as bad.

I'm picking B.

You gain nothing by going above and beyond your pay grade.


I mean, if you don't care about the company, product, or project, then yes, you are right. Lay low and move on. Some fights definitely aren't worth it. If you do care about more than your paycheck, maybe it is.

And do you really care if some incompetent hates you? I hate working with incompetent people, so some mutual feelings are perfectly fine. It may even improve the situation, at least temporarily: They'll reduce their interactions with you to avoid conflict, since most people are rather conflict avoidant.


Bad impressions can be contagious. Some "incompetents" have political capital.


IMHO labeling people “incompetent” is a bright orange flag. Sometimes it is true, but far more often it’s a genuine lack of respect.


>function1(){ ApiCall("1") }

>function2(){ ApiCall("2) }

Quoting from earlier in the thread, see this and tell me the person writing it is competent.

The polite way to put it is "there might be a skill mismatch".

Plenty of people get slowly drifted into programming roles they aren't qualified for.

At the end of the day, I'm not some super hero looking to drastically improve every company I work for.

It's fine to walk out if your not vibing with your co workers. Always say it's about money, you never know who you'll see again.


> Quoting from earlier in the thread, see this and tell me the person writing it is competent.

I can't, nor could I make any sprawling generality about them based on secondhand quips.

> The polite way to put it is "there might be a skill mismatch".

More than polite, it may be practical. Perhaps this person is vastly skilled in some other way and importantly valuable if applied to that work.

> Plenty of people get slowly drifted into programming roles they aren't qualified for.

Like me. I'm unqualified in many ways having no formal education in CS. Yet I've created around 1,000 jobs so far. I've taught CS and lectured on it in college programs. I'm pretty sure you'd consider me incompetent if we met, because we seem to see the world and this work very differently.

> At the end of the day, I'm not some super hero looking to drastically improve every company I work for.

I don't consider it super heroic to simply do your work in good faith, interact professionally with respect for other humans, and strive to leave the world (and every part of it you touch) no worse, if not better. That's just basics.

> It's fine to walk out if your not vibing with your co workers. Always say it's about money, you never know who you'll see again.

Yes, absolutely, change roles when it seems the right choice. That is freedom I wish everyone had, and felt safe in, and no guilt for. Pursue happiness. Even saying it's about money I can't argue with unless doing so obscures some other fact that harms other people.


For me, that's not enough. There could be reasons to write code like that. Maybe a function reference is needed for `function1` so it can be passed as a callback. Maybe it's given a meaningful name rather than "function1".


>I mean, if you don't care about the company, product, or project, then yes, you are right. Lay low and move on. Some fights definitely aren't worth it. If you do care about more than your paycheck, maybe it is.

Exactly!

I do not care about anything in regards to a job outside of my paycheck. I'm not trying to change the world. I have no expectation of anything I'm doing making a real difference.


Honestly your reaction is very understandable. You tried to legitimately improve things, go the extra mile and they treated you badly for it.

But ultimately that’s not how it goes in many places.

There are a lot of people who care more about their craft than their ego. And this can be enriching beyond compensation.


I'll second this. There are a lot of good managers that care more about the product than some team metrics. Same for coworkers that care about improving. Don't let one bad manager define how you'll do things in your next job.


Likewise, plenty of people who care about the customers and their coworkers as well. Collaboration with such a teams is where it’s at.

In my experience such situations are transitory though and a time comes to move on (gracefully and maintaining accountability for one’s own actions).


> The thing about broken organizations is that they take forever to fire anyone, so use that to your advantage while you look for other jobs.

My last place was horrendously broken in many aspects, and fired people at the drop of a hat.


Write a test case and file a bug.


That is a difficult escalation. When talking to your boss, it's almost always better to be discussing the solution to business problems, specifically those that are financially incentivized goals of your boss.

Talking about other problems, and suddenly you're 'that' guy. The boss might stop listening even and decide you are the problem, and not the fugly baby.


> Hear me out. You're going to then publicly embarrass another co worker. Not a good idea

We should all be working with each other under the assumption we are adults capable of receiving feedback. If a coworker is doing poorly, talk to them. If they wont listen escalate. If escalation doesn't work, its a bad fit.


> You're going to then publicly embarrass another co worker. Not a good idea.

Worth it if they really deserve it.


Related, the computer doesn’t care about you and isn’t judging you when it throws an error. Your code has the bug, not you. Stop feeling shitty about yourself and go fix it.


I find it helpful to blame all my bugs on the stupid computer not knowing how to listen, then comb through to code to find what the computer was too dumb to understand. When I find it, I realize that in my haste I had accidentally misspoken to the computer who was doing the best it could to please me, I correct it and promise to explain myself better next time, then apologize.

I find it therapeutic to externalize to inanimate objects.


Sounds like you’re ready for management!


Do what is asked and go home to your family


That is ok for some but others want to feel like there is some point to the 2/3 of their life that they spent working and preparing to work (i.e. school). For some, punching the clock and collecting a pay check isn't enough.


For me the paycheck isn’t enough so I decided to not to overextend myself at work so I can spend time with family, learning, cooking, etc.

I still have the urge to fight but I also have realized that fighting is more nuanced than pushing all the time. Maybe the best course of action is to push a bit and wait for the next opportunity. Find people you can trust in the org. Play the game. Or sometimes just do like the others, and chill, put in the minimal amount of work.


US-based individuals here are making 2-3x (or higher!) more cash than the median family (not to mention other comp that easily exceeds a year+ of income of other families)

If 4 years of school and sitting in an air conditioned home office for a few hours a day isn’t rewarding enough on its own, perhaps these folks should pursue perspectives of other people outside of their isolated tech bubble.

I’ll take “bad but meh coworker code” for a life on easy-mode.


There is nothing wrong with that at all. Some people (myself included) are just wired differently.


I scratch my itch with side projects


That is cool, but often feels potentially less impactful. I take a slightly different view - maybe I am lucky to be fortunate enough to be in a position to make an impact - even though it is unlikely that I will benefit financially.


Also in addition to not being your job. I left a place that had interesting work, great management, great coworkers and excellent pay/benefits/growth. A place I once considered a dream job.

Why did I leave? Because I grew a little bored of it and wanted to try something different. I wanted to try and build my own company. Which is going good so far. (It's been about 14 months since)

I am not my job and thus it gives me freedom to pursue things because I want too.


> If people are writing bad code at your company, to the point where you know it's going to come back to haunt you later, it's okay to just walk away .

IMO, one of the biggest reasons for this, is coders that know that they won't be around to have to clean up their messes.

Sort of a "chicken and egg" scenario.


> Try to solve bugs one layer deeper

This is one of the main things I try to impart to junior folks when I’m mentoring them or reviewing code.

It’s also one of the biggest red flags to me of someone who’s working above their level when I have to repeatedly press a more senior person to dig deeper and fix things at a deeper level.

You need to take the time to understand why the bug happened, or you’re just going to be patching wallpaper instead of fixing the plumbing leak.


> You need to take the time to understand why the bug happened, or you’re just going to be patching wallpaper instead of fixing the plumbing leak.

I think many would like to probe deeper but aren't afforded the time between sprint tasks. Management often pushes back for solutions that are good enough compared to exploration with an unknown duration until the solution is found.


Of course this can vary wildly, but I've never felt afraid to defy management on that one. Half the time, they don't even need to know. And the other half of the time... what are they going to do? Fire me? Fine, then their project will be filled with nothing but wallpaper-patchers and I'll be somewhere else doing good work.

(And of course, sometimes just patching the wallpaper is the right course of action, but it's rare to find management capable of accurately assessing this trade-off.)


Yeah, at a certain point I just stop caring what management thinks and just doing what I think is right. I usually don't get the recognition I think I deserve for preventing future issues but no one complains either.


Part of being senior is figuring out how to work in those constraints. In that situation I would push back my manager and tell them why root causing bugs will save us time in the long run and if they still don’t relent I would sandbag some of my time doing sprint tasks to root cause the bugs.


Which is why it's so important for teams to agree with management on a definition of "done" well in advance, to avoid this kind of argument later. Also why it's important for management to understand that velocity/estimation are Descriptive for long term planning, not Proscriptive and short term.


I recently encountered this in a hardware context. To “fix” a bug, instead of understanding the root cause, the designer’s patch just hid the first symptom. In a domain where bugs are remarkably expensive, this approach was terrifying to see.


Treat the disease, not the symptom. Always good advice.


I’m surprised by how many people cannot handle 5 Why’s. It’s substantially the same people who like wallpaper and putty.


Most of this advice has already clicked with me, but this part:

> If you can't easily explain why something is difficult, then it's incidental complexity, which is probably worth addressing

That's a real eye-opener. Hope I remember this next time I implement something complex. The thing is, I don't think this stuff would've helped me much when I was a junior dev. A lot of them are just too nuanced.


'Addressing' can be ambiguous. Writing comments to explain why it's right and needs to be this way? Or changing the code without considering if they have enough knowledge of the rest of the codebase.

There's also a chance it's not understood yet to easily explain it.

A key part of joining a team is remaining open to the fact that just because I don't understand something, doesn't mean there isn't understanding in it.


Sometimes there's understanding, sometimes the person who did understand has left the team. This is why it's worth writing good commit messages and going back to read them when there's a funny piece of code. A lot of my commit messages are to the effect of "I did it this way to be backwards compatible with how it always worked. It still looks funny to me though" Then at least future person knows I don't have a good reason for it and they can dig deeper or get PMs to sign off on something better if they want.


Definitely agree with this.

Reading code is harder than writing it, and too many people don't have the patience for it.

Instead, in cases like these they'd rather invest the time re-learning the lessons of the past because they thought it should be a certain way, and if they can't instantly see a reason why it's done a certain way, then they behave (unintentionally or otherwise) as if understanding is not possible.

Especially where it's tricky it's worth including a larger pre-amble in the code itself, as well as source code control.

Often one or the other are suffering, and it's sometimes worth giving a description of how the components work together in detail, or are relied up on by more than one use case (therefore not a simple change or solution).


Nobody could easily explain why early (1950s - 1970s) fusion reactors were so difficult. It must have been that everyone was stupid and creating their own problems.

No one can explain why the Collatz Conjecture is so hard to prove. It must be because everyone is so stupid and is adding incidental complexity to the problem. Why is everyone so stupid?

Or, maybe, possibly, that advice is utter bullshit nonsense and some problems are just hard for reasons that we don't fully understand. Go write a reliable reactive library that works how people expect. Oh, you can't? Better explain exactly why it's so hard then, or it's obviously all your fault.

That advice is so utterly at odds with actual reality that it makes it clear this author should be completely ignored.


A sign of a good educator is to - while it may take a lot of time and a lot of building up of base concepts - enlighten people through plain language the complexities of their topic.

Oftentimes, research papers and similar are written for an audience that is already deeply ingrained in their representative topic, such that those first principles aren't discussed anymore, so perhaps that's where you're coming from when you speak about how "no one can explain ..."; but I would argue that many people can, and have. It may just take a lot of speaking, paper, drawings and similar.

And even if / when there are obscenely difficult things to prove, the chances that the thing the proverbial "you" is working on is one of the incredibly difficult things is very unlikely.

There's a saying that a sign of actually understanding something is being able to describe it to a child. It's also why Thing Explainer and ELI5 exists.


"Good educators" are not solving difficult problems, they're teaching about long-standing solutions to long-understood problems. Long-standing solutions to long-understood problems in software engineering are called "packages" or "libraries" and it usually takes a single command to include them. We're talking about building software, not teaching.

The "explain it to a child" comes after decades of humanity's understanding something. Feynman might have been able to explain quantum mechanics to a child, but quantum mechanics was roughly 90 years old at the time. Nobody would have said Michelson and Morley were introducing "incidental complexity" into their experiment because they couldn't explain why the diffraction pattern looked so weird. What are the odds that they're working on an actual difficult problem!? They must be stupid.

You ignored my comment about fusion power and didn't give any examples of someone actually explaining why the Collatz Conjecture is hard. Nobody knows. The first person who deeply understands why the Collatz Conjecture is so hard is going to be the one who solves it. That's what life is like when you're near the edge of humanity's understanding.

> the chances that the thing the proverbial "you" is working on is one of the incredibly difficult things is very unlikely.

On the contrary. Being on the cutting edge of software engineering is incredibly easy. The discipline is (arguably) about 100 years old. The space of problems is unfathomably vast. Software engineering is applicable to literally any other discipline: pick any one and you should immediately find throngs of unsolved (hard) problems around how to apply software approaches to that problem.

And when anyone in the industry solves a specific problem, that specific problem is largely solved forever, for everyone, for free. So if you're not working on a difficult problem, what are you doing? Copy/pasting what someone else did?


Fusion: Turbulence, plus Naiver-Stokes was known to be hard, plus adding in EM fields, plus the exothermic state change of the nuclei fusing introduces discontinuous jumps in the free energy.

Collatz: if you replace 1 and 3 with arbitrary parameters, Conway showed that this class of problems is undecidable, so any particular instance could be arbitrarily hard.


Genuinely great responses. I'm not sure "it can be generalized to an undecidable problem" really explains why it's hard though, as the 5n + 1 problem is very easy (to prove false) and generalizes just the same. And all good points about Fusion, but my point was that it took some time (months, at the very least) for them to realize that's what was spoiling their machines. Remember that this is all a counterexample to the statement that "If you can't easily explain why something is difficult, then it's incidental complexity" -- meaning all the difficulty you are encountering is your fault (and therefore the actual problem must be easy, and you must be stupid.) That's literally what TFA says.


> I'm not sure "it can be generalized to an undecidable problem" really explains why it's hard....

Hah! I agree with this. :)


Not sure what 15 years means, but if that’s where I started:

(Blasphemies warning)

- Skip low level and go as high as you can. Ditch C, assembly, hardware. Take python, ruby, js. Never touched C++ cause it’s awful? Good.

- All the money is in the hands of a client. If you’re taking it from someone else, best case you’re taking less than a quarter for essentially the same job. Useless leeches everywhere who perceive you as a magic money generator. Go around them once you’re confident.

- Read sicp, htdp, taoup, but don’t take them to heart. Seriously, extensively test any idea you learn against reality, cause ideas may sound excellent out of context.

- Pragmatic is the only way. Don’t listen to industry peasants jumping through imaginary hoops, they are crazy. Religion in programming is worse than religion irl. There’s insane amount of it in programming. Don’t argue, let them be. It’s actually easy to test approaches by yourself and learn your own ways. Most of these are just habits making no difference once learned.

- Doing something together only turns out faster if you’re very good communicators. Good communicators are rare and you are not the one.


>Skip low level and go as high as you can. Ditch C, assembly, hardware. Take python, ruby, js. Never touched C++ cause it’s awful? Good.

In my personal experience, I think that having to work on different high AND more low level programming languages over time is what sets me apart from people/coworkers with low basic knowledge of computer foundations (the order in my case being Basic, Pascal, C, Perl, C/C++, PHP, JS, etc). Also it depends on the projects, but just my two cents.


I'd rephrase it as "know both high level and low level and use high level as much as possible".

Knowing the low level will prevent you from shooting yourself in the foot with the high level.


I think you’re right, I should have separated it in two parts. First is learning low-level “how it works, exactly” — that is useful. Second is writing actual low-level code — that I’d advise myself against.

So, I guess:

- Learn how sockets, filesystems and processes work, read apue, learn how jits/compilers work. But don’t write serious C, that’s a waste of time even if you’re smart enough.


This is the first time I’ve ever seen taoup ever recommended besides when I try to bring it up. It’s full of collective knowledge that’s foundational, along with Steven’s books, (if you want to work in Linux land), yet it’s never mentioned :(


> All the money is in the hands of a client. If you’re taking it from someone else, best case you’re taking less than a quarter for essentially the same job. Useless leeches everywhere who perceive you as a magic money generator. Go around them once you’re confident.

My better advice would be to avoid work that involves outside clients unless you own your own shop or freelance for yourself. They're always going to be price and deadline sensitive in a way that makes for shittier work conditions and lower pay. Working on well-funded internal projects that generate revenue is the way to go. Your work conditions are also going to be much nicer because a client being an asshole can't be used as an excuse for constant overtime or other BS.


Curious why you'd skip low level. Pay? Industry? Knowledge not helpful?


Because I ended up doing “business” things that are far from low-level, and I sort of like it, never wanted to return to C/asm.


I’m glad you’ve found a happy place in your work, but maybe take some of your own advice, drop this bit of your religion and change this to “use the right tool for the job”.

If you’re doing business logic in a micro service, C is probably the wrong choice. Python, Ruby, whatever probably makes more sense.

But if we are trying to build a (very) high-performance trading engine, or a device driver for a new piece of hardware we are building, and you are on my team and you show up with something in TypeScript because “it’s better”, we are going to need a conversation about whether you’re in the right place. I love high level languages but I also know the problem sets when not to use it.

I also know that if I am going to be writing something very low level, it’s a conscious choice and I’m going to invest in the tooling and the time to make sure my code is safe and secure.

The more generic advice might be that if you love a particular language or approach you might want to work on problems where that language is a good fit. Likewise, if you like particular problems, you should learn the language others think are a good fit in that problem space.


I like this a lot. While those commenters who say it is too advanced for novices have a point, I feel these are still issues worth thinking about - and coming back to - as they learn.

The one exception is “Bad code gives you feedback, perfect code doesn’t. Err on the side of writing bad code.” My experience with bad code is that it does not tell me much; instead, it presents inscrutable and baffling mysteries. From the caveats and examples, I think the author is trying to say something rather different; something like “don’t obsess over completeness” or other concepts of ideal software - especially, I might add, dogmatic concepts of this nature.


The Bad Code advice is for people who have the tendency for perfectionism (apparently like the author 15y ago).

My advice to me: write simple, dumb, repetitive code, but make an effort to be consistent.

Consistent, dumb code is really easy to visually parse. The repetitions slide into the background and the differences stick out. The more code there is, the easier to see what goes together (data aggregates/structures), what the overall flow should be (control, conditionals, order etc.). Then it's easier to factor things out or how to express more clearly what the code does.

But again, consistency is key. The code can be "bad", but it's very beneficial to do simple edits like renaming and reordering of things, grouping them under succinct comments so the structure stays clear.

Younger me would do the opposite: inconsistent code that is complex. I think its impatience that gets in the way, rushing to build abstractions and factoring out things way too early or trying out competing ways to express the same kinds of things (playing around with code).

Every programmer has their own tendencies and their own journey, so they need to hear different advice, in order to ignore it for now, but to have an AHA moment at some point when they realize why the advice was given.


I think this could have been phrased as, err on the side of shipping faster.

i.e. in most cases the cost of bugs is so low that the benefits of a faster feedback loop greatly outweigh the benefits of a more rigorous development process.

(On top of that, the number of defects asymptotically approaches zero with greater effort invested, i.e. diminishing returns.)


Agreed. "Perfect" code doesn't exist, but good code is written with the understanding that bugs happen, and exposes information at the right level for people to get the feedback they need, when they need it.


I think you got the wrong idea from that sentence; the author is talking more about the feedback you get from your end-users and/or customers, rather than development feedback a la debug info.


No I actually do mean the feedback you get as a developer when you realize which “bad” decisions actually end up being tech debt and which were totally fine and just saved time


The one thing I disagree is the thing about editors.

When I began coding I spent hours tweaking my vimrc file and learning all the essentially random shortcuts, and dealing with the absurdities of vimscript. (and debugging vim plugins that broke each other.) It felt like actual work while I was producing nothing.

Now I just open vscode with default settings and I am productive right away. Who cares about editors, vscode is good enough.

But maybe just vim sucks and I should have been playing with emacs all along, I don't know.


As with most things there's a balance. I've found if I try to learn one or two new features or shortcuts every couple weeks with the tools I use extensively, eventually I do get a sharp axe.

Typing speed is nice but not an important metric I don't think. It's like someone speeding past you on the road only for you to see them at the next red light. Other things will slow you down like code review or needing to wait until a set time to deploy. Also things like copilot and advanced auto-completion are making it less relevant.


Now I just open vscode with default settings and I am productive right away.

I am right away distracted by a huge rectangle around cursor line, current word highlighting and general jumpiness of everything. Coding in vscode feels like writing a book in the middle of brazilian festival. And then it cannot do random simple things like proper indents or humane snippets. The amount of work required to unfuck vscode is really comparable to creating .vimrc from scratch.


Same. I don't know why exactly, but VSCode feels like I'm programming inside an advertisement, and makes my skin crawl.


I'm a novice. I have only used vscode and sublime. Both have a problem when copying code from elsewhere, where the indent will be wrong every time somehow. If that's what you're talking about, is there an editor that will figure it out correctly somehow? Thanks


I was talking about nested indents, like this:

  f(a,
    b, g(c,
    d
    )
    )
Vscode cannot indent it properly due to how indent rules (simple regexes) work. Formatters like “prettier” exist but they can only format whole-file. Maybe try that (downside being you’re at its mercy completely).

I guess you are experiencing either auto-indent like that or the partially selected lines problem (when selection doesn’t touch \n at both ends). Vscode and sublime should also have a way to “paste raw” without reindenting. Try copying proper non-partial lines and/or pasting raw at column 0, removing automatic indent and adding yours afterwards. I know it’s tedious but I’ve seen enough people editing in ms-style editors and they all had this issue. Most just accept it as a fact of life.

As a vim user I’m afraid I can’t help much here. My copy-pasting is almost always line-oriented (V-mode copied lines always pasted after current line, regardless where the cursor is) and indent rules are very robust so it rarely indents things wrong. I also have gv> and gv= to re/indent just pasted text. I’d ask on stackoverflow (stackexchange) or on HN which popular editors have whole-line modes or maybe vscode/sublime plugins which can help with that.


In Sublime, there is a command to paste while matching the indentation as well. I think it’s Ctrl+Shift+V on most platforms by default. Maybe that’s what you’re looking for?


The author claims that a strong knowledge of development tools is a good indicator of general proficiency, but what if it's that learning how to use your editor makes you proficient? After all, nobody gets familiar with Emacs without inadvertently becoming a practitioner - if not an enthusiast - of Lisp!

That happened with me, and I'm now a big fan of functional programming, Clojure, Scheme etc., and that experience and exposure to a particular way of writing code has undoubtedly made me a better programmer. It sounds like you've had a similar experience with Vimscript :)


> nobody gets familiar with Emacs without inadvertently becoming a practitioner - if not an enthusiast - of Lisp

So you might think, until you meet a fervent Emacs advocate that doesn't know anything about "the underlying Lisp stuff".


I hate vimscript. vimscript is a horrible language.


Same here. I don't spend most of my time typing but rather thinking. So getting good at vim or getting faster at typing will not make me any better. That's not to say that I'm not in favor of being good at typing. I know my keyboard well enough to touch type also I know some keyboard short cuts specific to vscode but they are intuitive and have a GUI alternative if I don't feel like using them.


I think everyone's got a different threshold for where returns start diminishing sharply. While I'm squarely in the "don't waste time micro-tweaking your editor" camp, there are some little bits of shortcuts and tooling that made me much more fluent at code-editing with very little investment. One example that stands out is the multi-cursor support that Sublime Text popularized (and which I use all the time in vscode now). It eliminates a good 80% of repetitive typing, or symbol refactoring that would have involved clunking through menus in old IDEs, and makes experimentation that much quicker. Feels fundamental, like copy/paste shortcuts which everyone knows now.


Yes, I tend on the side of only tweaking things when I realise I'm repetitively using the same context menus. That's the only point I learn the keyboard shortcuts, or map one, these days. I really haven't had to learn too many shortcuts. The best ones are multi-cursor editing like you've mentioned.


more than multi-cursor, recordable keyboard macros save me a ton of time. I miss them sorely in vscode


For me it depends upon the task.

If I have to hunt down a bug or have something with a lot of touch points, yeah, there's probably less typing and more thinking.

But if it's a new mostly self contained feature usually I think for a bit, then get to the point where I know what I need to build and the next step is about shitting out a mountain of code. Being able to go from nothing -> mountain in a fast time is useful.


One of my colleagues was using dvorak and arguing that because he types faster with it, he's a better programmer.

i never thought typing speed is all that important when you code. But he DID write crazy fast.


Typing fast is an interesting metric.

Shipping the same code will happen sooner if you have tooling and typing setup to allow for quick iterations, and being quick in making those iterations. Selecting a language/framework that might take more work can slow you down too.

Typing faster does seem to look towards thinking faster, trouble shooting faster.

One place where it can get someone into trouble is typing too fast, faster than it might take to think through and not over look something which might invalidate what you're doing.

I have all hires do typeracer.com. Not for a high or a low score, but seeing the development of the score and understanding the importance of typing fast relating to thinking fast.

Typing code inherently is slower than writing sentences, so if you can type faster sentences in written communication, typing code will be faster, even if it's not at the full typing speed.


I'm grateful that I started learning vim and C at the same time in undergrad. Sure vscode is good enough, but a lot of value is gained tweaking your own tools beyond the tool itself.

Producing something doesn't always need to be the goal. Exploration has value.


I just open vi with default settings and am productive right away. I tried VS Code and couldn't get a "hello world" example to run out of the box after a half hour of trying.

Who cares about other editors, vi is good enough.


> I just open vi with default settings and am productive right away. I tried VS Code and couldn't get a "hello world" example to run out of the box after a half hour of trying.

I take it that you've learned vim (otherwise you wouldn't be "productive right away" - you wouldn't even know how to input text or save a file) whereas you had apparently never tried vscode before. How can that be a fair comparison?


And it's fine. Do what works for you. I just don't think playing with editor endlessly is a well spent time. It makes you feel like you do actual work when you don't. In my opinion.


You only play with the editor endlessly if you’re the type of person to play with the editor endlessly.

My vimrc was set up over the years a bit at a time based on my needs. After several years, I did an overhaul based on what I truly need and don’t need from experience. I rarely change anything in it these days. Maybe a few lines if I start using a new language.

With that stated, most of my vim use is still understanding buffers and motions, which takes no configuration.


These days you can write your neovim config in a real language -- lua. I used a pre-defined config called Lazy that does everything vscode can. Then I started tweaking shortcuts, removing and adding plugins, learning more lua.

Then, after I knew what I wanted, I wrote my config from scratch with only the plugins and settings and keybinds I wanted.

It was a very fun process for me. I enjoy simply using my editor. It makes me want to code. I don't get that same level of joy or customization from vscode -- which is phenomenal software btw.

e: replied to the wrong comment in the chain, but the point stands! Customization is how I got into programming. Crafting a status bar on linux, tweaking colorschemes, etc. Don't hate on the tinkerers just because it's not how you enjoy to work. It can be immensely valuable


The VS Code launch settings crap is a mess. But like as an editor, it's an editor. You can just use it like that. It works well and has good defaults, you can open a terminal with a hotkey, etc.


My productivity is rarely limited by the speed with which I can interface with a computer. Im in the same boat, I just use intellij for everything.


I've been using neovim pretty much since I began programming. I had some initial setup and have tweaked it once or twice, but it's by no means been a source of sunk time for me. I recently had to switch to VSCode and had a lot of issues learning all the out of the box key bindings and not having the telescope and fuzzy find windows I was used to was a huge productivity loss for me. When I able to jump back to neovim it was such a huge relief.


I'm reasonably familiar with both and use them for different cases than each other. vscode at least is my text editor in the gui... but consistently growing :)

The time getting up to speed on something new shouldn't be used against something else that is already familiar.

Now if the new tool (ie., vscode) could import your neovim setup and get you an equivalent, that would be neat.

Comparing the sunk cost time for neovim vs vscode might be a more interesting comparison. Neovim definitely is a little more polished than vim out of the box so it's entirely plausible it's pretty close.

If a vim user wanted to learn something like vscode, they could just install a vim extension in vscode to navigate most of vscode in vim keys. Lots on youtube.

It's hard to use a web browser without a vim extension installed.

It's true if you have sunk the time to super customize a setup for you in anything (currently I'm working through my Aerospace setup), the part that I get caught by sometimes is that something I had to customize in neovim, might already be built into vscode, or something else, or vice versa.

Repetitions is about creating the muscle memory, similar to building the same keys with vim.

I'm lucky I was able to get to a place of comfort with vim when I had lots of free time.

It's great when I don't have my setup with me, but my setup with neovim was a step forward, but vscode still sometimes just ends up where I am, and I figure out how to get it behaving a little better.


As a vim user, I think both worlds are crappy in their own way.

Vim has: a good editing model, good settings, programmability, arcane controls and language.

Ms-style usually has: extensive plugin systems, poor settings, poor editing model.

I wish there existed an editor/IDE which would consist of a good editing model, good settings, programmability and extensive plugin system, but without arcane controls and language.

Basically take vim, remap keys so it becomes ms++, replace vimscript with ts, add optional regular vscode around it. This editor would kill them all, imo.


I guess my point was that, often times people say some tool (or language, or anything) is easier when what they really mean is that they are used to it.

The fact is, you use something because it resonates with you (or its the only resource you have) and then you get good at it, and then everything else becomes a handicap


I don't think this point is about configuring your editor/environment as much as just knowing it. There's certain features that come up all the time: find file, find class, go to implementation, find references, rename var, etc.

It stuns me how many devs do this stuff manually, when virtually all editors/ides have ways of doing these things.


In some ecosystems, the tooling is just not that good. To use ruby on rails as an example: if you lean into the IDE's expectations for code layout it works ok, but there will always be generated methods and variables with nothing to show but the name—no documentation, no source, no googleable identifier, nothing. In these cases there's nothing to do but pull out the rails (or library) source to try and discern their intention.

In my experience, lisp also has this issue of being very difficult to tool in a general sense, as did aspects of writing c/c++ years ago (maybe recognizing stuff like macro-generated symbols has improved by now).


> lisp also has this issue of being very difficult to tool in a general sense

Most of the common lisp tooling is already present in the language itself. Things like inspect, trace, describe and apropos already gives you the equivalent of most IDEs. I agree with you for some dynamic language and magic methods. It can be hard to trace back the exact function that are being called. But you can always design some tooling for it as long as the code follows the ecosystem convention (Laravel plugin in PhpStorm).

The nice thing about Vim (and other configurable editors) is how easy to mesh existing tooling with the editor itself, without requiring for that extension to be a whole project unto itself.


This is a disadvantage of the more dynamic languages, I find. IDEs for languages like C++ and Java are relatively fast and accurate when jumping to definitions, showing references, performing automated refactorings and so on. I rarely see that same precision for any editor or IDE working with TypeScript, Python, and other very dynamic languages, even with the improvements recently thanks to LSP and generally better tools. When almost anything could theoretically have been patched at runtime — even if doing so would be a terrible idea and every style guide says don’t do it — it’s not safe for tools to make the same kind of assumptions with the more dynamic languages that they can with the more static ones.


100% agree about defaults. I do think it’s critical you actually learn the features of you IDE. Yes being able to type fast has nothing to with programming, but being able to jump to symbols, make refactors, use keyboard shortcuts etc. reduces the gap between hands and brain.


Possibly my all-time favourite XKCD, Is it worth the time?¹, demonstrates two important points. If you only do something very rarely anyway, spending time to automate it won’t have a great ROI. But for things you do moderately often that take a minute or even just a few seconds, you can afford to spend a surprisingly large amount of time optimising them and still get a big pay-off over a time frame measured in years.

I view time spent learning to use my tools efficiently and automating common tasks as a sound investment. Editors are a great example. Sure, I could fire up any of the usual suspects and write code somewhat productively. But in my fully customised editor of choice, I can insert and adapt common code patterns that would take me 10–30 seconds to type out fully in mere moments using templates and macros. I can jump to any position visible on-screen with around three keystrokes. I can see syntax highlighting for various file types that I use all the time, including some unusual ones that don’t have definitions readily available, and warnings for several different programming languages in real time as I work.

These save me a few seconds every time I use them, but how many times is that every day? The effort to set them up has probably repaid itself 100x over by now! And the lack of latency is also a qualitative improvement since it means once I’m ready to start writing, I can do so roughly as fast as I can think, instead of constantly being held back and interrupted for a moment.

¹ https://xkcd.com/1205/


> If you only do something very rarely anyway, spending time to automate it won’t have a great ROI

For code-editing, maybe. But in general software engineering, there are tasks that I have to do maybe once a year or less that are always way more painful than they need to be because I don't remember the details, and anytime I automate even part of them (or yes, just document a little better), it turns out to be well worth it. Stuff like bootstrapping new environments, some database-related work, etc.


Pasting all the commands in a doc that you keep around seems to give 90% of the benefit of automating it for 1-4 times per year tasks.

It's not typing the commands that takes time, it's remembering what commands to type.



Absolutely, I try to "automate" or at least have scripted almost everything I do.

I do this almost always for reproducibility and documentation purposes first.


It may not be worth the time to automate those, but I always take the time to document them, usually in Obsidian, where I can easily find them later.


I’m a big fan of writing things down for future reference. Keeping a journal with things like exactly which commands I used, or transferring that knowledge to something like a README or a wiki page for others to see, is a low effort but sometimes high reward habit. Even for something done only rarely, saving a lot of time next time can justify the documentation effort.

Similarly, if the automation effort is literally only copying those commands verbatim into a shell script or similar, that’s often time well spent. The trap, as the XKCD helpfully demonstrates, is when you then start spending significantly longer on making that script more “flexible”. Turning hard coded values into parameters. Looking context up from the environment. On multiple development platforms. In staging, UAT and production deployments too. With detailed help text to explain it all and say what the defaults for everything are if you don’t specify them explicitly. And then it turns out that you only actually run that script once every six months anyway and never use 95% of that extra flexibility anyway…


I have that XKCD printed out and posted on my cubicle wall. I refer to it quite frequently as justification as to why some requested feature/etc. should NOT be implemented.

I use it so much that many non-technical people at my company have started adopting it as well.


> Now I just open vscode with default settings and I am productive right away.

Is always so painful to watch how slow average developers are with the tool they use the most. Using mouse/touchpad to scroll/select word is unbelievably slow. Learning and configuring text editor that is customizable enough to not get in a way pays dividends really well.

Programming is mostly reading and navigating through the code with "go to definition" and similar code actions. Just being able to do this really fast would give a huge productivity boost right away.


I’m on the fence. When I obsessed more about Flow State, I really did see dividends from spending spare cycles reading the docs (especially release notes) and keyboard shortcut mappings to find faster ways to do things I did often.

Maybe I hit the point of diminishing returns. Maybe it’s because I don’t Code Like Hell much anymore, but it’s a habit I got out of. I keep resolving to getting back to it, but the fact I don’t maybe telling me something. Like maybe I’ve filled that spare time with other things that are more valuable.


> But maybe just vim sucks and I should have been playing with emacs all along, I don't know.

Honestly, yes, I think this is it. Ok, vim doesn't suck as a text editor, but it sucks if what you really wanted was VS Code. Emacs, however, doesn't suck. I spend very little time tweaking my Emacs config these days, but when I do it's to fix things VS Code users just have to put up with. I've watched over their shoulders. They put up with a lot.


Learning vim teaches you new ways to think about code editing and is useful if you ssh into machines. I think learning in itself has value, and I think even if you go back to vscode it might have taught you how to better navigate, maybe you realized for example that file trees aren’t so efficient and it’s best to navigate via the fuzzy search.

Then there is also the collective argument that letting Microsoft have editor monopoly can be really disastrous.


This.

i am much junior but from my experience, working with the toolchain of your team is better in the long run than against it.

if you become proficient quickly with whatever your team works with, it is much better overall than making everyone accommodate you. i have worked in teams where getting neovim installed would confuse the IT as they don't get those requests (or may not even know it exists!).


It’s a little bit like some productivity blogs obsessing over the notepad and pens and apps they use and spending a lot of time obsessing/procrastinating over things that don’t matter. I still learn the same shortcuts I’ve used for the last 15 years in whatever editor I use but most of my time is spent thinking and talking about problems rather than just typing things in the editor


When you began coding, was there vscode? These days there's lazyvim to let you skip all that fine tuning if you want to "just use vim".


I'm always slightly sad when software developers are confident that software can't possibly make them more productive.


VSCode can also be used more or less effectively though. There are quite a few shortcuts & tricks that can make you 10x more productive, even if maybe it's not as much as vim.


Multi-cursor on ten lines, sure. You get 10x for some seconds or maybe minutes. I'd expect practically zero people have gotten 3x more productive over a two week period for having advanced knowledge of tips and tricks in their editor. Saying 10x seems a wild exaggeration


The one piece of advice I would give myself 15 years ago:

In the corporate world be very good at administration. You only need to just be good enough at programming to not get fired. Everybody has opinions on software techniques and nobody measures anything, so it’s really just a popularity/tool game. The only goals are retain employment or promote out of software, being good at software is just a distraction from the goals.

If you want to be excellent at programming do it as a hobby and set your expectations right that it’s only a hobby.


I really hate that attitude. It's so self-defeating. The only way to ever advance your career is by becoming a worthless little middle-manager parasite? I'd rather quit. I know that's the common belief: just program long enough that you never have to do it again and then you get a cushy job telling other people what to do and spending hours in worthless meetings coming up with short-sighted "initiatives" to pump up your bullshit metrics so you can climb the ladder-of-shit even higher and play your ridiculous game over and over again while sucking the blood out of the work that real employees are doing. Unfortunately you might even be right that that's the optimal strategy for some kind of psycopathic narcissist who only cares about making as much money for as little work as possible. But some people want to do more with their professional life than to become a slimy little worm parasitizing the hard work of others.


Your attitude towards management is self-defeating too. Good managers make sure people aren’t working on the wrong problems, they clear barriers, and the defend the team from distractions from above.


It doesn’t match my experience. I developed features faster than the rest of my team and implemented a bunch of practices that are not known in the industry. As a result we delivered more and I got promoted.

Also be vary of someone saying that just because things aren’t measured it is just an opinion. Most important decisions you make won’t be measurable (a lot will though), that does not mean there aren’t good and bad decisions.


Could you expand a bit on what you mean by administration?


Not OP but I would say, generally non-engineering things that keep the business people happy. Project planning, delegating tasks, dashboards and metrics (customer feedback, if you can acquire it, is a big plus), setting and meeting deadlines, and knowing how to sell yourself.

There's that old (and very true) wisdom that if you solve a complex problem in two days, the business people won't think "wow, this guy is so smart and hard-working for solving that in 2 days." They will think "oh, this problem must not have been very hard to solve. Let's assign him extra work." Being a good engineer only gets you so far, career-wise.


Writing ample clear documentation, precision of communication, dutifully fulfilling all timesheets, logging of work performed, attending all requested meetings, and always delivering work on time.


[flagged]


All the "10x programmers" I've ever met have been taken advantage of way more and been used as company slaves more than the "clock watchers".

I'll "bend over" and be pleasant during a meeting. Then on Friday night I leave work, have a date night with my girlfriend and have to silence Slack because the 10x guy got suckered into working on some odd feature instead of living life. In the end, I get the same salary and the same equity. Who's the person actually being bent over by the industry here?


You don’t get the same salary and equity as a top performer. Very few companies give flat raises and bonuses without taking into account performance.

And if your manager cares about productivity, the 10x programmer is going to take the cake.


The correlation between performance and pay is really weak.

In my experience, probably negative too, since most work seem to be done by junior employees while the most seniors coast around fixing some bug every now and then on something they wrote some time ago.


Agreed. My primary motivation to be more productive is to free up work time for personal use. That's it. When I become a 10x developer and effectively work 1-2 hours a day I keep that to myself as a closely guarded secret. I know I will not receive 10x more pay for that increased productivity and I also know as I mention it the institution will find a way to take it from me for any number of unproductive reasons.


I’m telling you as a manager in a company that rewards productivity. We do refresher percentages and bonuses based on perf feedback from leads and peers.

Coasting senior clock punchers get base salary and little more. It’s easy for high performing people with lower titles to pass seniors in TC over a couple of years due to stacking perf bonus stock grants.


how do you measure productivity?


Absolutely. The problem with trying too hard to be a great craftsman is that you become emotionally invested. Most of your peers will not have this and will not understand it.

Someone else mentioned becoming a 10x developer and yet being surpassed in your career. That is absolutely very real.


> Your advice for being valuable is basically to slave away and follow your masters orders at daily scrum, not leave your box one minute outside of your allocated time , attend all bending over sessions and be pleasant as you take it , say what they want you to say with precision and always be whatever they want you to be i.e a massive people pleasing cuck with no principles that nobody can ever really trust or respect.

What the hell did I just read?


I think that it was the kind of screed that an incel might regurgitate


The paperwork matters far more than the actual work. Having your Jira tickets (or whatever) up to date and highly granular, and organized into all the taxonomies of sprints/epics/etc, and of course actually communicating status with teammates, tends to be significantly higher-valued than any actual code you're getting done, at least as far as winning brownie points and promotions are concerned.


This resonates well with my thinking. Programming I do for money is quite different from programming I do as a hobby.

If I wouldn't keep them separate, I would lose passion to it fairly quickly.


[flagged]


You’re right but OP is right too. If you can politic well, you can surpass a 10x programmer due to increased leverage. So, work on both I guess.


Those are way too abstract advice when you start programming.

You can only understand them because you lived those situations, which implies experience you don't have.

I would say (specifically to my young self):

- There is no substitute for doing. Less tutorials, more coding.

- Stop being obsessed with quality: you are not at the level where you can provide it yet. Do dirty. Do badly. But ship. Some people will be mad at you, and they are right. But do it anyway. Yes, reboot the servers with users on it. Yes, commit the spaghetti. You'll reach the level you want to avoid doing all this.

- The users don't care about the tech. They care about the result.

- Doing something for the hell of it is worth it. Just make it separate from the point above so they don't conflict.

- Programming is a battle against complexity. Again and again. Put that on a post-it. Make your decisions based on it. You will suck at it, but try.

- You have imposter syndrome because you are an imposter. You are really bad. It's ok, doctors hurt people for years while learning to save them. Don't sweat it. It will come.

- You need faith it will work out. On the long run, you'll get better at this. But in the short term also. You'll find the bug. You'll figure out the solution. It will happen if you keep at it even if it can be frustratingly long and unfair. Even if it doesn't feel like that right now.

- The right team is way more important than the right tech. If you are alone, get in touch with people who will lift you up from time to time.


"Those are way too abstract advice when you start programming."

I have come to the conclusion that the use of these sorts of posts is not that the reader, young or otherwise, will instantly and correctly apply all the lessons to their lives.

It's more about sensitizing people to problems they may not currently see, and solutions they may not currently be aware of. It's about shortening the learning curve, rather than eliminating it.

A 1-year programmer is not going to read themselves into a 20-year programmer, no matter what they read. But at the 5 year level I think you'll see a lot of difference between someone who never considers their craft and never pushes themselves, just keeps their heads down and doing the next bug, and the person who has even just occasionally read this sort of post, pondered how it may apply to their current situation, and taken out of it what they can... which may be something completely different than what they take out if they read the exact same post two years later.


Yes, countering "you don't know what you don't know"


These seem just as abstract as mine, if not more so, plus at least I provided examples where I could. Feels weird to criticize my post for general advice + examples, then come up with your own general advice without examples.

Also this was just an analogy I know, but doctors definitely don’t hurt people for years while trying to save them, very different profession from ours, if anything doctors earlier in their career have been shown to have better results.


I think you are trying to address different audiences. While your tips are mostly targeted at people who are already working as programmers, the parent comment's tips are mostly targeted at complete beginners.

E.g. this tip:

- There is no substitute for doing. Less tutorials, more coding.

is directly addressing a common mistake for absolute beginners. Many beginners will read (or worse yet, watch) loads of coding tutorials while doing little themsves. It is an issue a complete beginner encounters and understands.

Your tip on the other hand:

> If you (or your team) are shooting yourselves in the foot constantly, fix the gun

is addressing people working on medium to large projects with internal tooling. That is not a situation a complete beginner finds themselves in; it's a situation someone who already works in programming for a while finds themselves in.

I wouldn't necessarily say your tips are too abstract; they are simply too high level for a complete beginner.

That is not necessarily a bad thing; perhaps the you of 15 years ago already had the basic understanding necessary to be able to comprehend and make use of your tips.


I didn't read this as a criticism of your post, just as another point of view. Your post is more organized and probably thought through, this guy's is an opinion. No need to get defensive.

My experience with doctors, of which there has unfortunately been plenty, is that the older doctors are much better. If I need something delicate done I want a doctor who's 50-65ish. They know what they're doing, they don't screw around, and they've seen enough to know that yes, your case is the common thing they've seen 500 times before, and that this treatment works and that one doesn't.


I really liked “You should know all the major shortcuts in your editor. You should be a confident and fast typist. You should know your OS well. You should be proficient in the shell. You should know how to use the browser dev tools effectively.”

Typing skills are severely underrated in order to professions and roles adject to our professions like PM.


I think you both provide some kind of generational advice, like parent serving kid with life advice. Unfortunatelly, or fortunatelly, they will have to learn it by experiencing own failures first.


From 30+ years of dev work:

> - There is no substitute for doing. Less tutorials, more coding.

I'd rephrase that as "just write something!"

Many times I find myself being the classic example of 'perfect is the enemy of good' - I'll think about the perfect solution, rather than write something *now*, that works, and refactor towards perfect. TDD and all that.

Other things:

- Beware the beta and the boss. If it works, it will invariably get shipped if your manager sees it. Many managers cannot put a value on the future cost of maintaining something that's barely good enough.

- Classic Confucius: "I hear and I forget. I see and I remember. I do and I understand." If you're interested enough to read about some tech/language/framework, write something (again!).

- Learn at least one other language and ecosystem in addition to your main one. Even if it is syntactically similar (C++, Java, C#, for example).


> There is no substitute for doing. Less tutorials, more coding.

This may be good advice for yourself in the past, and for many people at lots of times, but I'd hesitate to give it as general advice. Reading code others have written should not be understated as way to learn valuable things from fundamental patterns and algorithms to language features and idioms. If you have a job in a team, this may happen anyway, but it's possible to write lots of code without realizing there's a better way.


Although, I should point out that reading code is not the same as reading tutorials. Reading code occurs with a kind of intent and focus that is missing when you don’t know much, and thus you may end up falling into the trap of studying multiple tutorials without really trying out much yourself.


Tutorials include some code which is intended to be exemplary and simple enough for a new programmer to make sense of, so I wouldn't discount it as a part of reading code. Practical code does not always have those properties, although you'd certainly be missing a lot if you only read code from tutorials.

I completely agree with the claim "There is no substitute for doing", and I might even say that code you read without running and tweaking it doesn't count.


Trying to learn to become a developer from tutorials is like trying to become a carpenter by reading instruction manuals for saws, nail guns, &c.

To learn how to implement computer programs, read books about it.


We might have different ideas about what constitutes a tutorial. Online tutorials vary massively in quality, but something like the official Python tutorial https://docs.python.org/3/tutorial/ is a fine resource. I would even say that the categories are not mutually exclusive - I would call "Structure and Interpretation of Computer Programs" both a book and a tutorial. Different people probably find different resources most helpful.

Also, "To learn how to implement computer programs, read books about it." contradicts the original comment's "There is no substitute for doing" more than I'm happy with.


I wouldn't call it a tutorial. It's the reference manual, but with more words and some stuff about pip and so on to make it more palatable to someone who isn't already initiated.

You need to start by reading somewhere, or you'll probably not get anywhere, as evidenced by pretty much zero office grunts using web browsers every day having figured out the JS console and application development on their own without reading about it. I recommend books over tutorial texts.

But yeah, as I alluded to, you need to build stuff and learn from other builders.


Indeed it's not general advice, it's to me specifically, who used to procrastinate a lot under the guise of learning.


Same. I would fall into the same trap. One more article, another tutorial, another chapter of a book… juuust to make sure I understood the concepts; and what actually helped? Just coding, getting it wrong, fixing it, getting it wrong, fixing it, etc.


I'd definitely agree that reading others' code can be a good way of learning, especially if you take the time to disassemble it line by line and look up things like what language features and functions they're using, how it's structured, etc.


I think reading code to understand because you forked a project and want to continue it is very different to following tutorials.


But you're not going to realize which way it's better unless you've written the bad code before.


Tangential, but I think that's the problem with trying to learn from design patterns.

I read about them and tried to apply them.

That's backward and didn't produce anything good.

I started to understand them by doing it the other way around:

- Coding, solving problems.

- Reading other people's sources.

- Then reinventing half a terrible design pattern.

- Later on, looking at a book: "ohhh, that's what I tried to do" or "ohhh, hence the snippet in that source".

- Now I can discuss with people about the pattern and name my code entities according to that.

Design patterns are a communication tool.


> You have imposter syndrome because you are an imposter. You are really bad. It's ok, doctors hurt people for years while learning to save them

What in the medical malpractice?


Making a mistake or a reasonable but ultimately incorrect call is not malpractice. Doctors are just people, just like the rest of us, and certainly you. It’s scary if you think that the medical system is more of a safety net than it actually is, but your gripe is with the precarious nature of life, not medicine.


Figuring out how to be a doctor by faking it til you make it most definitely is malpractice though, and ‘don’t worry, you’re an imposter but you only learn by screwing up’ is very much not how doctors learn their job.

The Hippocratic oath is not ‘first, do some harm, as long as you’re learning’.


A recent Johns Hopkins study claims more than 250,000 people in the U.S. die every year from medical errors.

It is ok to be an imposter.


Is it your impression that the medical profession thinks that’s ok?


Show me a hospital, and I'll show you overworked, under slept young doctors that have to deal with paper work, and are swimming in a field with heavy lobbying.

But even without this, the thing is, when you don't know, you will make mistakes.

And when your job is to take care of people, mistakes hurt them.

It's the nature of things.

Last year I had 3 medical errors, one that almost got me killed, by very well-meaning professionals.

Closing your eyes and pretending it doesn't happen is naive at best.

But people have to start somewhere. They can't stay in theory forever. And no amount of preparation will save you from making terrible mistakes.

Since we can't put an experienced doctor behind every intern 24/7, there is no real solution to this for now.

Same for programming.


The medical industrial complex clearly thinks it is, otherwise there would drastically lower patient loads, allow more spots for medical school, and provide better working conditions that would allow for fewer mistakes. None of this is happening and is an implicit acceptance of medical error deaths


They obviously do. Just look at the way they run residency programs. They work those poor kids to the bone under minimal supervision. Only the most disingenuous can pretend it's an accident when something goes wrong. The system is clearly designed to harm people.


Yes. Nothing is perfect. The remedy they've chosen is to rely on insurance. There is a reason we call doctor's offices 'practices'.


You think they're called practices because of the less common usage of the term to mean an amateur learning something, to imply they're inexperienced/without training?

Rather than it being the place where a practitioner works? ("someone whose regular work has involved a lot of training")


There is, but it's not what you're implying.


Yeah let's go build some shoddy bridges and crash some planes while we're at it.

Individuals can be new to a practice and feel like imposters but we shouldn't be pointing to statistics like this as an example of why it's ok.

I can't believe people think like this.


Planes and bridges are problems where the quality control can be centralized and you can therefore put a lot of redundancy.

Even then, the Boeing scandal shows it's not bulletproof.

It's not the same for medicine. There are way more doctors than you can put safety nets. Also, when a plane crashes, it's on the news, it costs money and PR. Much less so with doctors.

The plane industry is not inherently more moral, just more liable. Responsibility in the health industry is way more diluted.

It's not that we WANT to pay the price of people learning. I wish I would not have had the wrong meds given to me last year.

It's just that the system is not currently set up to do it otherwise.

So you can feel guilty and stop moving, and you will not learn. You will not grow. And you will actually hurt people for a longer period because you will still make mistakes.

Or you can own it and accept the inevitable: doing things means having actual consequences on the world.

If you want, you can dedicate your life to change the whole system and make it better. But I don't think anybody in this thread is doing that right now.

I did see a lot of people on their high horses, but doing nothing though, paralyzed because they were looking for a way to never break anything.

Me, for example. For years.


Sure, we're human. There is no argument there.

However, normalizing the loss of human life as part of the learning algorithm is psychopathic. There's a time and a place to make mistakes... In mission critical situations that's in training and everywhere else we should aspire for safeguards that prevent the loss of life due to mistakes.

In medicine a lot of these deaths can be prevented through greater care. It's not different than engineering in that respect. The greater problem is decision makers putting profits over life. And this kind of mentality in this thread is just fuel for that kind of behavior. It's gross.


I think you're misreading a singular opinion as occurring between two disparate points here.

The initial phrase was > doctors hurt people for years while learning to save them

It's then a separate reply from someone else about deaths from errors/malpractice.

So, nobody seems to be expressing the mentality you are, correctly, lambasting (at least so far as I've read in the comments). But, as it is relevant to the lessons we'd all want to pass back to ourselves (in my opinion, it's because we wish to hold ourselves accountable to said lessons for the future), let's address the elephant in the comment.

Normalising deaths, especially the preventable ones, is absolutely not something that anybody here is suggesting (so far as my read of the situation is).

Normalising responsibility, by recognising that we can cause harm and so do something about it, that seems far more in-line with the above comments.

As you say it yourself, there's a time and a place, which is undoubtedly what we hope to foster for those who are younger or at the start of learning any discipline, beyond programming, medicine, or engineering.

Nobody is saying that the death and loss is acceptable and normalised, but rather that in the real world we need a certain presence around the knowledge that they will occur, to a certain degree, regardless. So, we accept responsibility for what we can prevent, and strive to push the frontier of our capacity further with this in mind. For some, that comes from experience, unfortunately. For others, they can start to grapple with the notion in lieu of it through considering the consequences, and the scale of consequence; as the above comments would be evidence of, at least by implication.

These are not the only ways to develop a mindset of responsibility, fortunately, but that is what they can be, even if you find the literal wording to suggest otherwise. I cannot, of course, attest to the "true" feelings of others, but neither can anyone else... But in the spirit of the matter, consider: Your sense of responsibility, in turn, seems receptive to finding the areas by which such thinking can become justification for the very thing it would otherwise prevent, either as a shield purpose-built for the role or co-opted out of convenience. That too becomes integral, as we will always need to avoid complacency, and so must also promote this vigilance to become a healthy part of the whole for a responsible mindset -- lest we become that which we seek to prevent, and all that.

Exactly as you say, there's a greater problem, but this thinking is not necessarily justification for it, and can indeed become another tool to counter it. More responsibility, more mindfulness about our intents, actions, and consequences? That will prove indispensable for us to actually solve the greater problem, so we must appreciate that different paths will be needed to achieve it, after all, there are many different justifications for that problem which will all need to be robustly refuted and shown for what they are. Doing so won't solve the problem, but is rather one of many steps we will need to take.

Regardless, this mindfulness and vigilance about ourselves, as much as about each other, will be self-promoting through the mutual reinforcement of these qualities. If someone must attempt to visualise the staggering scale of consequence as part of developing this, then so be it. In turn, they will eventually grapple with this vigilance as well, as the responsibility behoves them to, else they may end up taking actions and having consequences that are equivalent to the exact mentality you fear, even if they do/did not actually "intend" to do so. The learning never ends, and the mistakes never will, so we must have awareness of the totality of this truth; even if only as best we can manage within our limited abilities.


> A recent Johns Hopkins study claims more than 250,000 people in the U.S. die every year from medical errors. It is ok to be an imposter.

Is what I was originally replying to, which, at least to me does seem to imply preventative deaths are some kind of training tax during ones 'imposter stage'. Perhaps not the intention of the poster.

Thanks for your thoughtful reply.


A bit snarky, but I would add

- don’t read opinions from a list and take it as gospel. Adapt to the jobs you’re in, and you’ll develop your own opinions, but now with experience to explain why. Opinions are formed by getting repeatedly hit with the consequences of your (and other’s) decisions, and everyone just has to take enough hits till the pattern seeking area of your brain takes over.


Maybe add to that: try to stay long enough in a role to really feel the consequences of your actions. Even better if you're on pager for a while too. I know it's not trendy to stay in a job for long these days, and conventional wisdom is it's not great for your salary either, but one thing it will do is allow you to understand whether decisions you made were actually good or not.

There are roles I've been in where it's only been years later that the true impact of decisions made was actually apparent. I'm glad I hung around long enough to experience that.


Skin in the game is important.

I have a terrible programmer friend.

He is better at creating actual products than most people I met because his livelihood is on the line: he makes money only from websites.

So he is not living in the abstract idea of best practices, he had to make it profitable for the last two decades, with little resources to go by on top of that.

And he does.

After 10 years, he is still asking me how to write git commands. And I'm still learning from him to shed a lot of BS from my practices.


Being directly chained to the financial outcome of your works will have you dropping Scrum for Scheme real quick...


I've been called back to code long after I left an org, and have had to review my own code 10-12-15 years after the fact. Seeing both the positive and negative aspects of decisions having played out in the real world was something it's hard to get from reading, and I'd argue somewhat harder to get even if you stay inside the same org for that length of time. Staying on the inside, you'll rationalize a lot of the changes to the code, the team and org over time, and it may be harder to be more objective about the impact the code has had.

I was quite proud of some decisions, but realized the negative long term impact of others. Trying to share that experience and whatever 'wisdom' or 'lessons learned' with others has been its own challenge in some situations, because you can easily come across as "the old person" who doesn't "get it" wrt to current trends. Some issues are evergreen and fundamental, but it's difficult for less experienced people to understand why some of these things are really core. I'm not sure there's much substitute for experience in many cases.


I wholeheartedly agree with this advice and have for over a decade now. I think there’s something in the fact that you know you caused that that helps the lesson stick. Potentially you will understand the assumptions you had then vs now that allows you to clearly see the underlying lesson to take.


I agree, form your opinions when you have enough information.

For example, if you can’t decide between two data structures or tech, pick one and add a comment:

// I’m not sure


I agree, and would say is equivalent to:

> - There is no substitute for doing. Less tutorials, more coding.


Yes true. Mostly just opining on the “list of everything you gotta’ know” is a bit TOO concrete IMO. (As opposed to too abstract)

I was quoting out of similar things years ago at the start of my career, “it should be done this way because X said it” didn’t help me at all.

It feels like insulation against being called too junior, since, you can just wholesale adopt someone else’s list of ideas and you’re good. But making mistakes because you’re new to the career is precisely what forms the base of those opinions in the first place.


Fine advice (better than OP). This works till you realize you're burned out, plus didn't get that promo, instead going to that bikeshedding worthless co-worker who's clearly less deserving.

Motivation, productivity go out the window. You don't give a sh*t about the work, team, code quality, made up deadlines or real issues.

Real maturity comes now. You learn to appreciate your limits, see what really matters despite what's being said and observe who make the calls and what their agenda is.

And finally, when you've picked a path and it seems like it works, you'll find equilibrium, somewhere between an idealistic comment on a PR and your next interview.

Till something else like health or kids rock the boat.

Take it easy, you matter more to you than your work. 15 years on, only ones who will remember the weekends you spent at work are your family and kids. Get out more, find solace in the varied arts. Enjoy you painless body till it lasts. Make the weekdays show up between weekends not the other way. Laugh more. Eat well. Feel your surroundings. Make friends, keep friends. Make memories. Don't throw your life away chasing menial pursuits. If a piece of work is really that substantial and meaningful, it will show itself as such. Don't go looking for it.


Stop being obsessed with quality: you are not at the level where you can provide it yet. Do dirty. Do badly. But ship.

You'll reach the level you want to avoid doing all this.

What if future you has reached that level and people on your team are shipping spaghetti?


I feel like this is bad advice, really, you need to be obsessed with quality and growth, but you can't let that stop you from shipping. Try for clean to the best of your ability in the time constraints you have, but accept that it will be dirty.


I think aiming for clean is good, but it’s really hard to pin down what clean means when you’re starting out.

I feel like just emulating what you see in your first few jobs is ideal. (As in, ask coworkers who know the thing you’re working on) It could be great code to be inspired from, or mediocre. Either way you get some input about what decisions result in what outcomes, and what the outcome “feels” like.

And if it comes time to change one or many of those decisions later on in this codebase, the person doing it gets a uniform codebase to work from! Unique abstractions and fixes in random places makes refactoring harder.


Obsession will stop you from shipping.

Or it's not an obsession.

It's caring.

Very few people can pull off a Steve Job level of nitpicking and actually finish a project.

I certainly couldn't, and that advice is for young me.


Then you find a new team, else you can do the classic 'making one trivial hill your Happy Path and be prepared to die on it' routine.


Most of these lists do not advise on "programming" the task but rather "programming" the job/position. There's no problem with that, I'd just wish it was labelled "software engineering advice" or "advice for programmers". Few of the points are about programming itself and the list is overall pretty good.

Consider this just a rant from an older programmer who hasn't fully recognized that 'programming' is now largely a social endeavor with online info for everything, language and library ecosystems, etc. I wonder how much of this information I would have internalized if it were all available in my time. Seems like the kind of thing I might read and nod in agreement and forget to apply when relevant without some hard earned run-ins (which is how I'd picked them up).

As for actual programming advice, the thing I'd highlight is to look at the data first and foremost. It goes from initial conditions to post conditions. The differences are what your program/function does, but both the pre/post conditions should be able to be fully described as a valid static state. Once you understand that, the problem, the code is largely plumbing with a small part that applies the functional transformation. There's so much focus on the form and style of "the code" that seems to consider it the main thing rather than an artifact of getting the main thing done: think any time there seems to be fancy abstractions that don't provide value to offset its complexity. To relate it to a point in the post, if you can't connect the difficulty you're having with the logical transformation that needs to be done (e.g. from database state to state), it's likely self-inflicted (or it could be due to a poor choice of database schema). Similarly for poor choices of request/response formats--basically bad plumbing between systems (and not intrinsically hard because of the information being handled).


> Doing something for the hell of it is worth it. Just make it separate from the point above so they don't conflict.

This is a great use for new, standalone open source modules: feel free to experiment with styles or techniques or goals that you wouldn't want to justify. (Or for experiments that you start and then abandon without ever showing anyone.)

For example, when I was making lots of packages to help build out the Racket ecosystem, I'd already made an HTML-writing package, but I felt a craving to do one that used syntax extension at compile time, rather than dynamic s-expressions. So I just did it, as a separate package: https://www.neilvandyke.org/racket/html-template/

I don't recall anyone saying they saw value in it, but I like it, and I scratched that itch, and added another skill to my programming mental bag of tricks.


> It's ok, doctors hurt people for years while learning to save them.

Modern medical education doesn't work this way.


Yeah, I'm surrounded with medical professionals.

It totally does.

They make grave mistakes all the time. And they hide them. They lie about them.

They have their ego and career on the line.

And they don't have enough resources at their disposal, not enough hours, too many patients, and they are exhausted.

In short, they are humans in a human system.


> Yeah, I'm surrounded with medical professionals

In fact you are. You're speaking to one.

Your original statement completely ignores the massive amount of barriers put up during your training. From my own experience I can tell you that students are usually quite self aware that they are learning and on a short leash. The most egregious mistakes I've seen were almost always a result of understaffing and gaps stemming from leadership issues coming from the top down. The small mistakes and cut corners are from tired overworked people.

Nobody accepts "hurting people" as a component of training. It's an absurd statement.


I like this but I think all advice suffers from the problem of the people needing it being incapable of using it and the people who are capable of using it already know it.

You learn by doing x time. There's also a place for study, reading, etc. to supplement this.

This is true in software development. It's true in martial arts. It's true in chess. (the 3 things I've invested some effort in progressing in). I've taught martial arts but there's no magic advice I can give people that will instantly take them to the next level, they need to experience and work through things to progress. Having a teacher helps (a lot).


* This * - The users don't care about the tech. They care about the result.


To the extent users do care about the tech, they care about performance not how "clean" the code is or whether you're using the newest framework. Users hate when software is slow or uses an exorbitant amount of memory.


Most users have no idea how much memory a piece of software uses. They care about user experience though which means they will care if the UI hangs or is unresponsive.


Bingo. I’d go further and say they don’t care about your application at all. They just want to do something, and your application’s quality is measured by how little it stands in the way of accomplishing that.

The sad fact is this encapsulates features (ease of development, a framework probably does help you ship faster), adaptability (clean abstractions that are easy to work with), and performance.

Finding that balance is always going to be hard but they’re all important!


And if the product is aimed at prousers/communities who extend the functionality themselves with their own commands, scripts and plugins.


Yeah, I totally agree. Those other factors are internal optimizations. What gets me is when a team wants to switch horses to new tech and do a forklift upgrade just to implement something using the new hotness.


This 100%. It's especially noticeable in the world of game development, where you see games that are ridiculously buggy and poorly made (on a coding basis) selling millions of copies and changing the industry. The original generation 1 Pokemon games are probably some of the best examples of this, though I'm pretty sure anyone who's reversed engineered any game from the Atari era onwards has probably been left wondering "what the hell were they thinking?"

But it doesn't matter. They were designed well, they were fun to play, and millions of people enjoyed them.


A way to rephrase your point about complexity is this wonderful quote "Developers are drawn to complexity like moths to a flame, often with the same outcome" (Neal Ford)


I've experienced this too, but I never understood why this phenomenon happens.

Is it because we start adding abstractions before we understand the problems?

Like, there's a certain threshold where keep things too simple makes them too complex, so people start introducing abstractions to reduce complexity. But often it's the wrong abstractions and then we accidentally end up with worse complexity that's harder to unravel.

There must be a term for this waves hand thing?

Edit: gosh typical on phones is hard


It’s because when you’re in the middle of things with a lot of context in your head, adding another little wrinkle feels like a negligible complication (in particular if the new wrinkle is ostensibly to reduce some complexity, or to ship more quickly), but those complications accumulate up to the limits of any developer’s comprehension (and beyond) rather sooner than later. Hence developers tend to work close to the limit of what they can handle in terms of complexity, which for anyone who hasn’t all the same context in their head (like the developers themselves some time later) is really more than they can handle in an effective manner.

From another perspective, this is a form of entropy: There are many more ways to increase complexity than to reduce it. This is also the reason why biological life has been getting more complex over time, the only criterion being if it’s fit to survive and reproduce.


The commonly used term, also mentioned by Fred Brooks, is accidental complexity. Accidental highlights the non intentional nature of devs introducing complexity.


Isn't accidental complexity just complexity that's not part of the problem domain? Say in the context of serving content/downloads, accidentally complexity would be caching, proxies, CDNs (etc). Basically stuff that we have to deal with to handle or optimise downloads, but isn't inherently part of the "just downloading files" problem?


I never really got the "it's ok to be an imposter", "it's ok to be bad" part... And the internet is full of people saying things like "I am a developer and I have no idea what I'm doing haha".

Seriously, you might be inexperienced or not know everything, but you should clearly not be an imposter and you should be confident in your ability to improve and understand what you don't understand yet.

Take responsabilities and ownership in what you do, don't get behind the easy excuse that it's too complicated. You are the professional and you are getting paid for this.


>Do dirty. Do badly. But ship. Some people will be mad at you, and they are right. But do it anyway. Yes, reboot the servers with users on it. Yes commit the spaghetti. You'll reach the level you want to avoid doing all this.

I think you're likely to reach that level a lot faster by trying and failing than by not trying at all.


I have a very severe case of impostor syndrome. :(


You probably are. But most of your colleagues as well :)

Most adults are kids in big meat suits, they fake it a lot.

I started to live like I was not completely worthless at 35.

Not saying that to be proud of it, just stating that if you think humanity should do better, the first person you'll judge is you.

It will be glaringly obvious you are not meeting your own standards.

The higher your standard, the longer it will take for you to reach them.

And the way to get there faster is to ignore the shame, and do it anyway. Because if you don't, your growth will be slower, and you will do more damage for longer.

Real life means real consequences.

It will make you more tolerant of others as well. Way more tolerant.


Don't worry, you're not a real imposter. You've just inadvertently ended up in a position where you're expected to be one. Just fake it until you actually become a true imposter.


In a world of imposters, the half decent imposter is king.


> - The users don't care about the tech. They care about the result.

Seasoned, grownup engineers and tech business leaders are forgetting this, even today. Users don't care that your product is made with AI, but techies just will not shut up about Generative AI, LLMs, Transformers and all this shit that should be implementation details. Users don't care about any of what goes into the sausage.


Investors care though, and for many startups the customer they need to appeal to is investors.


I don't understand why investors care, either. Product A is made with traditional algorithms, product B is made with AI and LLMs, product C is made with literal magic and wizardry. But they all do exactly the same thing. Why does an investor prefer to invest in product B?


This was great. I particularly enjoyed the "Bad code gives you feedback, perfect code doesn’t. Err on the side of writing bad code" section, I'd never thought about how spending time writing "perfect" code means you don't get to figure out which aspects of that code actually matter.


This is interesting. If I were to complement the list, these are some items I’d add that helped me:

- learn functional programming. Doing that was how I finally “grokked” programming and could solve problems more easily. Before I was ready to give up.

- learn CS history. I studied UX and what I learnt was mostly one side of how to think about computing where you spoon feed users and remove things. There are other ways to conceptualize software and design, which would have left me less disillusioned.

- learn fundamentals: data structures, networking, performance, operating systems, security, unix, math. These are so neglected in the industry, and we’re left with super complex systems we don’t actually understand as a result.


"learn fundamentals: data structures, networking, performance, operating systems, security, unix, math. These are so neglected in the industry, and we’re left with super complex systems we don’t actually understand as a result."

I sometimes hold a "command line fundamentals" course for my teams. Just being able to understand the basics puts them above any team that doesn't.

You have to know the ground you're building on. Otherwise even your foundation will be faulty.


> You have to know the ground you're building on. Otherwise even your foundation will be faulty

Exactly, well put. Knowing the fundamentals leads to a more solid, safer foundation as you understand better what you can do with what you have and avoid layers of abstraction.


Could you please share an itinerary for this? I’d also like to hold a similar course but don’t know where to start.


Sure thing! This assumes everyone has macOS, but isn't very mac-specific.

  * Introduction
    Quick history of Unix

  * When you log in
    Difference between login and interactive shells
    System shell files vs user shell files
    .zshenv for environment variables like PATH, EDITOR, and PAGER
    .zprofile for login shells, we don't use it
    .zshrc for interactive shells
    Your login files are scripts, and can have anything in them

  * Moving Around

  ** Where am I?
    pwd = "print working directory"
    stored in variable $PWD
    Confusingly, also called current working directory, so you may see CWD or cwd mentioned

  ** What is here?
    ls
    ls -al
    ls -alt
    . prefix to filenames makes them hidden
    . is also the current directory!
    .. means the parent directory

  ** Finding my way around
    cd
    cd -
    dirs | sed -e $'s/ /\\\n/g'

  ** Getting Help From The Man
    man 1 zshbuiltins
    manpage sections

  ** PATH
    echo $PATH | sed -e $'s/:/\\\n/g'
    zshenv PATH setting

  ** Environment Variables
    env | sort
    EDITOR variable

  ** History
    ctrl-r vs up arrow

  ** Permissions
    Making something executable

  ** Prompts
    zsh promptinit
    zsh prompt -l

  ** Pipes
    Iterate to show how pipes work
    cat ~/.zshrc | grep PATH

  ** Commands

  *** BSD vs GNU commands
    BSD are supplied by Apple, and Apple often uses old versions
    GNU are installed via homebrew, and match those commands available in Linux


I wish more articles talked about the usefulness of integration tests over unit tests. Personally, I feel that unit tests are overrated and rarely give the required confidence to inform the team whether something is ship ready, whereas integration tests on the common workflows means that even when a bug is introduced, very few users are affected.


So much this. I have been at a few shops now that feel their integration tests are ok and their unit tests are proving >90% coverage and yet they break the login or auth flow weekly. An absolute aversion to e2e tests. As soon as I can make a test log in and create and read one record, and bake that into the release process (preferably gating merge to main and after deployment artifact generation) then the site no longer breaks every week. Customer pain and hours of dev work saved.


It seems from my experience that when you're working on a core library or tool where the API is the product and it's going to be widely used by lots of other teams, or even companies in the case of open source, then unit tests are very important. If you're on a product team they probably are a waste of time.


> If you can’t easily explain why something is difficult, then it’s incidental complexity, which is probably worth addressing.

This one is good and has been following me since I've became a manager. Thanks to you, I know how to apply that objection to "press" people when I feel we're dealing with this kind of complexity.


Agree with sibling comment saying these are too abstract. Here are mine:

Fundamentals:

- Ecosystem beats language and syntax

- Use boring, battle tested technologies

- Use the relational database to do the heavy lifting

- Avoid caching unless you have a great reason

- Code cleanliness comes from simplicity, not elegance

- There's higher leverage from improved code reading ability over writing ability

Professional:

- You grow faster building in good industries over interesting codebases

- There's higher leverage from improving the business over improving the code

- There's higher leverage in finding mentorship over being an autodidact

- Make T-shaped buy vs build calls: build the secret sauce, try to buy the rest

Probably leaving a bunch out.


I rarely see advice with which I wholly agree. This is one of those rare times that I fully agree with everything g. Good seasoned advice from someone that has been doing this fo r a while.


Mostly pretty sound advice here, but oh, this rankles! --

"In situations where bugs aren’t mission critical (ex. 99% of web apps), you’re going to get further with shipping fast and fixing bugs fast, than taking the time to make sure you’re shipping pristine features on your first try."

In 99% of web apps, your end users have no possible way of telling you that you shipped a bug, and your bug will remain there forever, frustrating users and losing your client money as they abandon your site. Telemetry won't help you either becuase you'll misunderstand the observations it provides.


> Assess the trade-off you’re making between quality and pace

Very important! But also important to distinguish between kinds of quality. Using a sub-optimal algorithm or bad identifiers or copy-pasted code can always be fixed later. But some problems like a bad database schema is much harder to fix later.


I’d say be very skeptical of this advice if you’re a beginner. You almost certainly aren’t qualified to identify quality so don’t intentionally leave any on the table


The author’s comments about knowing your business context and the potential impact of bugs really hit home with me.

I have seen far too many teams using Facebook sized solutions for a few thousand users.

I’ve seen developers slowed to an absolute crawl, terrified of shipping code, for a completely secondary operational platform with low volumes and non-critical data. All because the product people were misguided in their mission.

And sadly, I’ve seen teams with almost non-existent security practices and knowledge happily banging out crap in financial services environments.

And I’ve been blessed with teams understanding their position and fully embracing it. Financial services products with quarterly releases that were rock solid and well architected. Batch document processing systems with just a few dozen end users who worked closely with us developers to tune algorithms where sometimes we would ship multiple times in a day and re run batches in production.

To be successful, teams gotta know if you’re at NASA level, or life threatening, or business critical, or somewhat critical, or just nice tooling, plus understand the cash flow / budget situation. As a dev you may not be privy to all that, but strive to know as much of this as you can.

And of course, understand who you users are, and who your customers are, and prioritize accordingly.


I am personally at the “nice tooling” level, but am currently building towards supporting other teams at the “business critical” level, so I try to apply the same rigour to everything that I do. It might make sense to also consider your dependents in similar scenarios.


My advices to new software engineers:

- Always think how to simplify the code you write, since simple code is easier to maintain and debug.

- Prefer writing dumb code than smart code. Smart code is good for programming contests. Smart code is very bad in production when it needs to be debugged or refactored.

- Always think about improving the usability of the software product you work on. Users don't care about code. They care about UX of your product.

- Fix small usability issues as soon as you notice them, since these issues are usually the most annoying for end users.

- Do not start writing code with some popular design patterns. Just write the most simple code, which resolves the given task. Later, the best design patterns will evolve organically from the code solving the particular task.

VictoriaMetrics development goals are based on these rules - https://docs.victoriametrics.com/goals/


I go a step further on "dumb code". Write code that is easy to reason about, understand, and grok the implications of.

I spent a ton of time doing support and engineering on a trading desk, where our SLA for an outage was somewhere in the range of 30 seconds to 5 minutes. Having super simple code that makes it easy to understand what the code problem is (if not necessarily the business problem) lets you move on with life and let the business keep moving.


For writing simple code, I often remind people that the first working code is not the one to commit. Just like a text draft is edited, once the code works, now is time to trim it and simplify it.


Or in short, KISS!

(Keep it simple stupid!)

And yes, users will notice the button that is only half visible quite a bit more, than a suboptimal sort algorithm.


I have one:

Learn to become comfortable implementing and working on state machines.

It might be one of the most useful abstractions out there that if implemented well leads to a great extensible design without compromising performance.


The point that resonated most with me, and that I repeat every time someone early in their career asks for advice (or one thing I wish I had been told when I first started out) is "When working on a team, you should usually ask the question".

Early in my career, I spent a lot of time reading unclear or obsolete documentation, poring over code, etc, when I could have asked the person sitting next to me and gotten an answer in 5 minutes. Sometimes, I didn't even know who the right person to ask was, but if I had just asked my tech lead, he would have been able to point me in the right direction.

Claiming that it reduces your overall time from several hours to < 5 minutes is maybe a bit exaggerated, since it also takes time to figure out what question you want to ask in the first place. But it's still worthwhile even if you end up investigating for 30 minutes instead of 3 hours.


On the other hand, though, I really wish people would take at least ten minutes to do that digging through the code or reading through the documentation before asking.

One, reading code in general is a good thing to do when you're new, and it's a skill that should be built up in general.

Two, you might actually find what you're looking for, and answer your own question! It's a nice little boost to realize you're getting self-sufficient.

Three, you'll have a lot more context for me, which will make it easier for me to give you the answer. "Hey, how come this function doesn't return what I expected" is a much harder question to answer than "This function says it returns a list of items a user has accessed in a given workspace, but it's returning an empty list; I've checked my local database and it has a good set of seed data I think, and from looking at the function there's nothing obviously filtering out users, so what's going on?"


At my first job, at a consulting company, they had a good rule, which was basically "show initiative when asking questions". What this boils down to is if you ask how to do X, you should first research and think about it, and then you can say "I think Y is how I do X, am I on the right track?"

A lot of the time, you'll answer your own question getting to Y. If not, it will save the person you're asking a bit of legwork, and show you are not trying to have them do your job for them and have respect for their time.


Or, even, "I see X Y Z is happening, that doesn't seem in line with the question, can we discuss it further ? "


Agreed, now that I'm the person getting these questions, it's hard to reconcile "it would have saved me a ton of time when I was new to this codebase" with "why can't you do even a basic amount of due diligence to even figure out what you're trying to do". (As I mentioned -- it's still important to figure out what the right question is!)

It's hard to find the right balance, and I agree with the author's framing of it as a spectrum, but I also agree that I at least (and most junior engineers, in my experience) leaned way too far on the side of being, um, self-motivated.

I certainly do notice myself getting frustrated by people asking questions when IMO they should know better, and I'm never sure whether I should be more lenient there or if I should tell them off for not putting in that tiny bit of effort.


It can go both ways. The most common one I've seen is definitely taking too long to ask about something. The other is asking too many trivial questions about things you can look up in minutes or ought to know given your job.

I think the problem is knowing when to ask is like many things a skill that gets better with experience. It isn't obvious especially to newer people. I also think if you're a senior you should be much more forgiving of juniors when it comes to this stuff. We were all there once.

I think asking too slowly tends to be caught more easily in things like standup before it snowballs. Asking too quickly tends to be habitual and seems to do more damage since it's harder to notice when managing projects, and often under the vague auspices of "pairing."


"Don’t underestimate the value of digging into history to investigate some bugs." Valuable advice, and it particularly highlights the risk of global state and the benefit of understanding your runtime. Browsers have popularized flamegraphs, stack traces show you the frames down to the moment of error, but global state survives multiple stack traces and the one you're looking at may not be (probably isn't) the cause of the problem. There is global state, the heap, external systems, etc that change over time and with successive calls. This is true even in single-threaded environments, and is far more complex in general multi-threaded environments. I often feel this isn't clear to beginners nor is it clear to them how you go about investigating bugs within this context.


The trick is not in having advice to offer. It’s in having advice they will hear.

Next month I’ll have been working in software for 30 years. Which means I would have a lot more common ground with me 15 years ago than most people will. that me with five years’ experience might not have understood at all.

Me with five years’ experience suspected many things that were true but missed some important one. I’d probably have to feed his ego by confirming some of those things before moving on to the difficult bits.

But who is to say that me with less Impostor Syndrome would be a better person? No, the main value in learning from the past is improving the future, not nostalgia or regrets or what ifs.


Sharing advice others will be able to hear is one part, having an audience who wants to get where they are a little faster and easier is another.

There was a while where too many jr devs wanted to learn it all and go through the phases of learning everything themselves without considering if others have maybe gone through something similar.

Thinking one's self not qualified might mean you share a good thoughtful approach towards learning something.

Thinking one's self is qualified and if it's too soon might mean otherwise.

No matter the better I have gotten, having a healthy mistrust of one's work helps it become better in a lot of cases haha.


"Bad code gives you feedback, perfect code doesn’t. Err on the side of writing bad code".

This is probably quite a cynical way of putting it (and it speaks to me, probably because I am quite cynical) though I don't know if a junior dev will really appreciate this.

The way I would put it is: don't seek satisfaction from trying to make perfect abstractions for business rules no one quite understands, rather seek satisfaction from making your user's lives easier as efficiently as possible.


One bit of programming advice I would give myself is, on large projects, ensuring that appropriate constraints are in place is more important than functionality. You want to be able to come back to an area of code after a few years (without looking at it) and everything that has been added should still make sense. Patterns that you don't want to see should be hard to do - the natural inertia will stop it from happening. Designing things that "allow people to do anything", while seemingly a benefit, end up causing a lot of problems in the long run.

A reasonable argument might be that it should be watched / policed but this is harder in practice than in might seem. A lot of orgs are fairly decentralized, meaning that no central entity can make the call (probably a good thing imo). If appropriate constraints are designed into the system this kind of energy sapping discussion will not even need to happen in the first place.

Essentially, adding constraints at t0 adds degrees of freedom in the future. Coding is a bit like a garden - you need to ensure that the garden makes sense as it grows.


A variant on that I say on one of these is "Do the dumb thing" thing to find the right abstraction. I've seen so mucb code that didn't need to be written if someone had just done the dumb thing. On the flip side, I've also seen so much code that could be so much simpler if after writing the dumb solution, they went back and figured out a better one. I guess the takeaway is: Prototype.


> Spending time sharpening the axe is almost always worth it

I hear this advice constantly. But I feel like it really need to be qualified. I have been in projects that never saw any real value produced because people constantly focused on DX, projects management, and other tools.

Sometimes one just needs to do with tools at hand, and not worry if there are better tools.


> "It’s really easy to write terrible code. But it’s also really easy to write code that follows absolutely every best practice, with 100% test coverage, and has been fuzz-tested and mutation-tested for good measure – your startup will just run out of money before you finish. So a lot of programming is figuring out the balance."

The situation appears to be changing rapidly. 15 years ago there were no advanced code-generating LLMs, and while relying on them for the core logic without having a good understanding of the language and system is still a bit iffy, it does seem that they're pretty good for generating tests and spotting deviations from whatever your group has decided are best practices.


What sort of tests does it seem good at generating? I was hoping it would give me a decent start writing tests with Jest and React Testing Library for an already existing but untested codebase. It seemed ok at small components that I can also quickly write tests for, but the larger, messier things would receive useless, failing tests.


> Our server models are exactly the same as the DTOs we would write, so I just serialized those, instead of writing all the boilerplate, we can write DTOs as needed later if needed

I worked on a system that used the protobuf types generated for communicating between services everywhere. There was absolutely nothing in any of the components of the system that didn't depend directly on the generated protobuf code. What made it even worse is that a backend system we called had multiple endpoints that used the same name for similar but slightly different things, so there wasn't, e.g. just a single Passenger type, but a bunch of different Passenger types across various packages.


> update our subscription layer to call subscribers on the main thread instead

I often do this, but have been doing it less frequently, lately, because I don't want to force a thread switch, unless I know that I'll be calling UIKit functions (not always things that affect UI. Many "background" UIKit functions also require main thread). Instead, I clearly mention the thread state, in the API headerdoc description ("- parameter handler: A simple, no-parameter, tail completion. May be called in any thread.").


I spent a ridiculous amount of hours tweaking my vim config over the last two decades. I've used vscode the last few years and rarely jump to vim to do some text manipulation (that I usually could do with a raw install)


Good post, I agree with most of it. One that goes hand-in-hand with "just ask the question" is learning to know when to pivot. If you've hit a blocker, whether it's something to do with waiting on a teammate, client, or answer to a hard question, consider pivoting to another task to knock out some easy wins.

Ideally the task you pivot to should require minimal context switching to get going. This way you won't lose productivity. Often if the blocker is a hard problem and you go back to it later, you might have a good idea after stepping away for a bit as a bonus.


I would have told myself that there's going to be a new frontend architecture called "SPA," and a new framework related to it called React.js. And that I should stay far away from both of them.


This is one of the better advice posts I’ve seen. Especially the parts about finding the balance between shipping fast and shipping bug-free code.

Too many engineers think their job is “great code writer” and not “value adder”


Really great advice! Few that I would add based on my experience:

- Engineers spend way more time reading code than writing it. So writing easy to read code is more important than writing fancy/complicated code just because it saves few lines of code.

- Extension to above point. Having coding standards in the company is important so that it's for anyone to make changes to different parts of the code. If one engineer ends up writing code using their own standards, it makes life harder for everyone else on the team every time anyone else has to debug that code.


Seems like some good advice here! The points about digging deeper into the cause of a bug and looking at the history of the codebase for more info are really good points to keep in mind for sure.

And remembering to ask questions hits home pretty well too. There's always the worry that you're bothering people too much, and the balancing act between thinking whether you need to be asking for help early enough to make sure you're not going down the wrong path and not asking about every little thing without attempting to fix it yourself...


not a good advice at all. it's hard to interpret right and will probably change in 5 years anyway when the author reaches another stage.

my advice would be much simpler: 1. Most of the time you'll be manipulating test. Learn options how to manipulate text professionally. That includes vim, bash, sed, awk, perl, and regexes in general, including lookbehinds etc. It's worth it. It takes a few years to learn but even the basic options give you the culture and approach how to do things faster. Most coders have trouble swapping two columns in a text file or finding unprintable character.

2. Learn hotkeys seriously. They're more consistent and uniform than UI, learn how change them, which tools are better designed for them, and organize some memorization scheme. It pays off a lot and gets into body memory, freeing up mental space.

3. Learn how to version your own code instead of creating multiple files and folders. Read git manual at least once. Learn how patches work, what is interactive rebase, and how to go back and forth, combining different changes from different branches. That gives you freedom to experiment with code on a larger scale.

4. Learn how to quickly test any framework/code. There will be countless situations where you have some piece of crap not producing the needed result, and you should be able to quickly prove it. For this p.1 is invaluable. I have my own json,xml,rest,kafka and text log parser and diff, and a few cloud, database and search clients which I tweak when switching jobs. It's all mostly written in standard unix tools, and can be literally retyped if needed (I worked on high security envs often). It's also isolates me from poor (non-)standard tooling different in every enterprise to which I only fallback when I already know the answer and need to prove it to a peer.

The rest is subjective and optional. You can love or hate your job, you can love tabs or spaces, weak or strong typing, but the above will definitely makes it faster. What to do with the rest of that time is your decision.


> If you can’t easily explain why something is difficult, then it’s incidental complexity, which is probably worth addressing

That’s how I feel about git.


It's a product of its time dealing with requirements and limitations that aren't much relevant anymore. As far as multiplayer save goes we have much more powerful tooling than we had back then.

But I think git became so ubiquitous that even new solutions unburdened by needing to mimic git's data model end up bringing that complexity forward because of familiarity.


> If you (or your team) are shooting yourselves in the foot constantly, fix the gun

This is a reasonable step to take if you're working in a reasonable company with reasonable "management". If you're unlucky enough to be working under a manager that refuses to recognize there is a problem, even with compelling data, prepare for pain. In that case nothing is allowed to be done because "well, that's how we've always done it and doing something about it might upset someone". It's really time to quit and find something new at that point because there is generally no hope of turning that around.

> If you can’t easily explain why something is difficult, then it’s incidental complexity, which is probably worth addressing

See above. "That's how we've always done it, and someone is used to that work flow, so we can't change it." Sometimes this will lead to a legitimate Chesterton's Fence situation, in which case you'd want to regroup and rethink it. Otherwise, the batshit insane is the default. Target the latter.

> Try to solve bugs one layer deeper

"There is no time to do that! We have so many other projects!" While being blind to the fact (or better yet, burying their head in the sand and trying to ignore) that it's all self-induced.

> Don’t underestimate the value of digging into history to investigate some bugs

"We can't change that because one of our people close to management made that decision and it might drive them away." Good, get them out, that's the only way to really fix it. Ideally if the management that hired them is pushed out too.

> When working on a team, you should usually ask the question

"Who are you to question our wisdom? Who are you to suggest something else, it's working in production."

These are great things to start conversations, but you have to start them in an organization that is willing to change and be willing to take your advice to heart. Don't waste your precious life trying to change what can't be change, no matter how much you want to see it change.


this is not on the content but on the website color choices for text and background: wonderfully well done, easy to read in dark mode. with this kind of sensible coloring i feel i don’t need eink devices for reading.


One more: Make developer velocity one of your top priorities.

You should be able to give anyone in your team the repo URL and have them running unit and local integration tests in five minutes without prior knowledge.


Funny how he casually mentions JIRA as a process that slows you down. I get that his team does the issue tracking somewhere else?

What does people use that is faster to process both for devs and the PM?


It always depends on the team. And by team, I mean the people working on a somewhat independent part of the project (they don’t need to care about the minutia of some other parts). Issue tracking is a tool, but project managers always wants the tool to become the process. And that’s when you got daily standups, story points, epics, and fixed sprints (aka fake deadlines).

Use the tool as a tool. As the devs, add issue and tasks that needs the attention of the team, comments on a ticket for knowledge retention. As the manager, schedule the ticket if its completion matters in a particular timeframe, use assignments and other fields to manage workload. Do all of these to help the team get things done. Anything else is a hindrance.


Correct, but JIRA is not SCRUM.

Why does the author mention JIRA as a process? Does he find it slow or convoluted compared to other tools? Or does he think that using JIRA means a PM is forcing the team to follow an unwanted process?


> Or does he think that using JIRA means a PM is forcing the team to follow an unwanted process?

Think that must be it. We use JIRA at work. We have very, very simple processes. We create issues, we assign them, we resolve them and they're closed when deployed ok. Minimal fuss.

I also have access to a customer's JIRA. They have like 6-7 steps between starting working on an issue and saying it's deployed in test environment. Another 5-6 to say it's delivered in prod. I saw the flow chart for the steps and it made my head spin.


That was more of a subtle joke than anything substantive. I think JIRA is probably fine as long as it’s not like a religion


I took it literally, sorry ^^

Thanks for your valuable advices!


> Keep doing the first sort of bug fix, and you end up with a mess.

To avoid the mess, design with the fail-fast principle in mind, which brings you closer to the spot where an error occurred.


I think this is great for the craft of coding and solving problems. I’d add one more, along the vein of career advice: you’re hired to solve problems for the business, not to solve technical problems. If you can’t explain how the thing you’re doing makes an actual difference for the business, you need to reflect on what you’re spending your time on. I’ve seen too many technical teams be far too fixated on technical problems and unable to understand why they can’t get more headcount, funding, or recognition. Nobody writing checks cares about code.


Advice I'd give myself:

Finish what you're doing.


Very reasonable, solving bugs one layer deeper can be very valuable, if you don't go too deep into the rabbit hole.


15 years ago? Just buy bitcoin


What about: buy Bitcoin?


> Don’t underestimate the value of digging into history to investigate some bugs

I'm one of about 2 people at my company who goes on archaeological expeditions to understand when and why a bug was introduced. A nonzero number of times, I have found that the behavior was introduced on purpose over a decade ago, and sometimes it's addressing an edge case I didn't think about. History is valuable!

(unfortunately the most common usage for me though is as a 'smell test' where I learn who wrote the code from the history and then decide based on my existing assessment of their skills, how suspicious I should be of that code)

e; oh yeah one more story that's kinda funny. Just this week I saw some behavior that I didn't like and went to look at the code's history. I was the one who wrote the code I didn't like. But I had left a good enough comment on it that I realized there actually was no issue at all and my expectations were incorrect.


programming is such a young field wirh many iterations that good advice is hard. I should have probaly made my own programming language!


I loved the author's point on "incidental complexity". I would point out though, that even if you CAN explain why something is complex doesn't mean it SHOULD be complex.

When the subject of "tech debt" comes up, I always tell the teams I work on to focus on tasks that improve our speed or agility in the future. I believe that many coding tasks actually have a negative dev cost over time, as they reduce the dev costs of future work more than they cost at the current moment to implement. (Of course the problem is that they have a positive dev cost in the current sprint, so good luck convincing decision makers...)


Codeisforhumans.com


> You’re going to be renaming things, going to type definitions, finding references, etc a lot; you should be fast at this. You should know all the major shortcuts in your editor.

Programmers love to think this matters. If you're doing anything more than the most rudimentary work, the time 'saved' by maximizing keyboard shortcuts is completely irrelevant. You're spending most of your time reading code, thinking about that code and thinking of what code you're going to write.

When any programmer emphasizes how fast they are at completing these rudimentary tasks, my assumption is they are less adapt at the actual work of programming and instead try to 'git gud' at the keyboard wizard bullshit.


> my assumption is they are less adapt at the actual work of programming and instead try to 'git gud' at the keyboard wizard bullshit.

Whatever lets you sleep at night.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: