Ask HN: How to learn best practices when you have no one to teach you?

440 points by bradhoffman ↗ HN
I am currently working for a startup and am one of 3 developers. Most of my work revolves around building the API in Node + Express as well as some small projects with MongoDB. The other developers don't really assist me since they have their own projects to work on, and, honestly, they have less experience and knowledge than I do.

So my question is: What is the best way for me to go about learning best practices in API development, or using MongoDB, or even just being a better software developer in general?

208 comments

[ 5.7 ms ] story [ 248 ms ] thread
Read and if possible contribute to an Open Source project you are using everyday.
1. Make lots of mistakes.

2. Experience pain in the form of late, buggy software and angry clients.

3. Read books and work on side projects. (Martin Fowler’s were my favorite).

4. Repeat for 5-10 years with hopefully ever-decreasing amounts of 1 and 2.

You probably think I'm kidding...

There's no substitute for direct experience.

You can rattle off quotes and documents all day, but this doesn't teach 1% as much as the direct pain of dealing with st on the job.

5. Ideally, make _unique_ mistakes.
I had a boss once who called them "errors of enthusiasm," as long as they only happened once.

If you made the same mistake twice, then you were in trouble.

> ...as they only happened once. If you made the same mistake twice, then you were in trouble.

I guess I’d be worried about classifying. “Play” part of discovery might have multiple cases of (nearly) identical “mistakes”.

In one sentence (by C.S. Lewis ):

“Experience: that most brutal of teachers. But you learn, my God do you learn.”

Hopefully. A friend of mine once said "So do you have ten years of experience, or do you have one year of experience ten times?"
I've heard this old saw a million times, or maybe once a year for a million years, but what does it really mean? Nobody seems to be able to describe to me a developer with one year of experience ten times. What does this look like in practice?
someone who despite having been in the industry many years, has only learned more and more jargon, but not technical skills. So they sound almost like the experience they have counts, except when you put them next to someone with the same level of experience and stronger understanding, the difference is obvious.
Sometimes there is a mismatch between seniority and experience.
One definition: A developer who joins a team, builds out a product, and then leaves for a new job after a couple years. They don't stick around long enough to see their code become legacy, and then get replaced.
“One year of experience ten times” is shorthand for repeating the same banal tasks over and over and never increasing your skillset. Versus “ten years of experience”, indicatig 10 years of varied tasks, increased responsibility, increasing your skillset etc...
What does this look like in practice?

My interpretation of that has always been something like "repeating the same actions over and over again, but never importing any new knowledge from outside" where "outside knowledge" means books, classes, blog posts, videos, meetups, etc. So you can "learn" to just keep doing the same thing incrementally better by just doing it the way way for 10 years, but to make significant changes, you need whole new models, thoughts, and ways of seeing things.

Now sometimes you may make a big leap purely off introspection, applying logic, empirical experimentation, etc., but that would - IMO - be an exception for most people.

This is the dirty secret of tech. We're almost all self-learning all the time. By the time it becomes more of a formula than an art, it'll be automated.
repeat for new languages
This I think makes the difference between people who follow "best practices" and people who understand why they apply certain practices or not dependent on the situation.
This. I have been looking for a company to be mentored at for the past 8 years. They don't exist (well they do, but they are few and far in between - and it varies from team to team even in a company)

The way I've learned is through books/talks, common sense (often things are clearly terrible for obvious reasons), people willing to take risks on giving me projects, and sweat/mistakes/learning how to focus on the right things through experience

They do but they're extremely rare. Before I started for myself I spent a lot of time mentoring my team. Most if it was building their confidence up so they could think critically themselves whilst reading the right books.

I myself have never had a technical mentor. Never needed one. What I did need and have were mentors for the other 90% of being a successful professional (and people who built my self confidence up).

I think this is because "mentorship" is very hard to plan at the company level. My best mentors have been specific senior devs who were willing to share what they knew.
++ to this. Experience is the best teacher, though I think it widely depends on the person learning. Some individuals will learn well from others' whereas others really need to feel the fire to know why it's hot.

This, of course, coming from a person with burn marks :)

That really doesn’t help. How do you know that what you are doing is a “mistake” if it works?

10K line UserManager classes “work”.

That’s how you get the “expert beginner”.

https://daedtech.com/how-developers-stop-learning-rise-of-th...

The only feedback you get as a sole developer are your compiler and errors in production. You would never know that it isn’t a good idea to write your own AcmeDatabaseManager or AcmeLogManager.

How do you know that what you are doing is a “mistake” if it works?

Reading. Plenty of books, blog posts, and forum posts point out that you shouldn't have "10 KLOC UserManager classes".

The thing is, one has to figure out how to integrate "book learning" AND real world experience, so that they're constantly synthesizing a newer, better understanding.

Yes. I would also include reading other more-experienced developers' code in bullet point #3. Pick a well-respected project from a language you're looking to get better at, and dive in.
Funny thing is, if you look at codebases of some opensource projects [1] doing complex and ambitious stuff, written by some real experienced engineers, you’ll see the common „dogmas” (don’t have long classes, don’t have long methods etc. etc.) are not obeyed. And yet, they shipped very complex and successful software. It’s almost as if these rules are mostly arbitrary and don’t really matter.

[1] I’ve noticed that in codebases of Apache Spark, Apache Oozie, Apache Cassandra, and Firefox.

It’s almost as if these rules are mostly arbitrary and don’t really matter.

Definitely. I mean, some of them probably have some objective basis. But clearly some of them are indeed subjective and arbitrary. Take "long method names" for example... I believe method names should state what they do, and should be however long it takes to do that. To my way of thinking, making a method name shorter just for the sake of being shorter, and eliding semantic information, is an anti-pattern, not a best-practice. shrug

Reminds me of other comments on this subject: one person's best practice is another person's bad practice.
I wrote some really long functions in C back in the day just to avoid the overhead of function calls. Yes, this was after running a profiler and we had massive amounts of data (for the time) to crunch within a short window.
That really doesn’t help. How do you know that what you are doing is a “mistake” if it works?

Keep looking at it and ask if you are doing something redundantly.

The only feedback you get as a sole developer are your compiler and errors in production.

False. There's plenty of resources online. There's plenty of code to read online. There's plenty of potential critics online.

You would never know that it isn’t a good idea to write your own AcmeDatabaseManager or AcmeLogManager.

Unless you've read the Internet. There are plenty of database and log utilities out there.

> How do you know that what you are doing is a “mistake” if it works?

Because it hurts.

So even if you see that your 10K line UserManager class is hurting your velocity and you are spending more and more time maintaining your AcmeDatabaseManager and AcmeLogManager, you still don't why it's taking longer or what to do about it.
Neither did the first person to encounter it, but they figured it out anyway. There is no magic one-size-fits-all process for this.
What are the chances that you are as smart as the people who figured it out decades ago?
Problem solving doesn't work like that. Many comparable issues have been found and solved by different people at different times, in parallel, unknown to each other.

With as many people as we have on Earth it is unlikely that one special unique problem can only be solved by one special unique person. While it might happen, it's unlikely to happen to a software developer at a small company. The problems and solutions you find there are often relatively comparable or even generic, and are found and solved by many people in parallel at the same time. While working together might be faster, it has nothing to do with the feasibility of detecting and repairing issues.

> How do you know that what you are doing is a “mistake” if it works?

It's a good question, one that's a good nod towards the principle that you will inevitably learn more slowly if your own mind is the only one you have to work with (and lately I've been thinking about how I can get in a professional position where I'm near the bottom end of the intelligence and/or domain knowledge range in the room for this very reason).

But one answer might be: you'll know. "Works" is shorthand for satisfying a certain set of expected conditions. There's a core of reliable behavior in the software that's the minimal working definition of "works" ... but there's also the question of relative ease when it comes to reading, understanding, and changing/augmenting the code you have, or how the code "works" as an expression of the system for the purpose of presenting an interface to the developer.

Chances are pretty good you know the feeling of writing something that you either (a) are uncertain is really adequate as far as the developer experience goes or (b) you know is probably not adequate but seems to get you to the minimal definition of "works" fastest.

Listen to that feeling. Interrogate it. Try something different. Observe the tradeoffs.

I'd argue it's not a mistake if there are no visible consequences.

If you get a production bug that takes a week to fix because the code is a mess you feel it. If adding simple new features is a pain, you feel it.

Now, of course, you might want to skip that, by learning from others, but OP is suggesting that you make your own mistakes.

It is a "mistake" as soon as the work gets to be too much for one developer and the company brings in some more developers.

By this time, that one inexperienced developer gets promoted to "Architect" because he knows where all of the bodies are buried. Now one of two things happens. He brings in more inexperienced developers because he doesn't know what a good developer is and they keep adding on to the UserManager class and to organize it better, they add section breaks. The class grows.

If they are lucky, they get an experienced developer who tries to tell the "Architect" about proper coding techniques, management and the architect dismisses the critique as "if it ain't broke don't fix it"/"this is the way we've always done it". All of the good developers leave and you are left with only bad developers.

Then you end up with the "Dead Sea Effect"....

http://brucefwebster.com/2008/04/11/the-wetware-crisis-the-d...

You've triggered my PTSD with the phrase "UserManager class". Seriously, OOP can be such a foot-gun sometimes. Dozens of wrapper classes and manager classes might be the sign of a cluttered mind.
You're going to want to follow the best practice, that no file should be longer than 2 lines of code. One line for imports/requires. One line for a massive one liner.
If you have a 10k line UserManager class and you are happy with that, than that is fine.

If the 10k line UserManager class has you pulling your hair out, you know you have a problem.

1. Make lots of mistakes.

It's all about hundreds of cost/benefit trade-offs in a particular context. There will be trade-offs between short, medium, and long term goals and issues. There will be trade-offs between the developers, management, sales, and the users. Try to find as many compromises as possible which are synergistic.

When it comes to hiring and otherwise interacting with other coders, you will even make compromises with the developer community!

4. Repeat for 5-10 years

At least. Always be learning from your mistakes. Be skeptical of yourself and your own model of reality. You should be actively looking for your biases and misunderstandings. Try to understand where the contrarians are coming from. If they have a point, it just might be valuable.

Be wary of dogmatism.

Actually this it's a good advice. For me 5 years worked.
It's curious that for my first software enterprise I'm already doing those things. It's a lot of A. just starting, B. pushing through pain, C. keep pushing.

Strangely, there have been very few customers who have been unhappy. Many have even written long glowing reviews that have had a great positive impact in profits.

Those who give negative feedback seem to always have a problem or a pain. Being kind of a bloodhound to discover what that pain is and where did it come from seems very valuable.

Two most difficult things for me seem to be: A. drawing borders and limits on my time and what to do and when to say no, B. pricing

They say just surviving long enough mean you win, but turning a business to make profit seems really a herculean task, even as a solo dev.

I'll just add that good, maintainable software is as much about communication with other devs, in the form of code that they can read without being too distracted, as it is about getting the immediate job done. That requires socialization with other software developers on some level. That kind of socialization is going to be harder for a lone developer to obtain. But I imagine working on an open source project where there are other people will do the trick.
Experience is what you get when you don't get what you want.
There are a lot of famous books on the subject of best practices: "Code Complete" and "Clean Code" are the first to come to mind, but I'm sure the folks here can recommend others.
(comment deleted)
You can always find people to help you. I'm not a node + express specialist but I do a fair share of JS, you can contact me at localhostdotdev@protonmail.com if you want.
Blog posts other developers make detailing the way they've built a particular project have helped me gain some perspective when looking to understand how people are working in a particular stack. Learning from other projects is good for understanding how people are using contemporary tools. Github is also a great source for this, you can search with those tags to find relevant projects. As for software engineering in general, there is more academic materials which cover various methodologies ( you can just search software engineering and find many resources ). There are so many resources out there; I don't personally have a systematic way of navigating it. Once I find a good resource, I tend to look at what else the author has done and who else is connected to that author and then I walk around what that social circle's body of work, picking up various things. Finding the sages in a particular area, finding out who really knows about the area I'm studying at the moment, then learning from them... all starting from Google searches and some sleuthing.
Blog posts other developers make detailing the way they've built a particular project

The hard part is finding the right blog. There are a ton of blogs out there from developers with little experience who are convinced that their way of doing things is the best/only/right way. The blogs are often nothing more than SEO for their resumes.

For that reason, I'd lean heavier on books. At least with books there is some filter. Yes, it can be incomplete and sporadic, but it's often better than the wild west of bad information out there, especially in web dev blogs.

Yes, good point. Usually you can filter blogs by reading the comments and seeing the reception it got as well as the popularity. If it is an open source project, you can see the stars on GH and read through the issues on the repo to further filter. Books get outdated very quickly for modern tech stacks. I would recommend them for the fundamentals, but not contemporary stuff. You obviously have to do your due diligence here. Researching the author is also important obviously if you are going to truly heed their advice.
You have a lot of people to teach you! It's just that they use books and GitHub repos to communicate :)

Emphasis on GitHub repos: you can learn a lot of good practices and efficient solutions in open source projects somewhat related to your problem domain.

It's hard to get "better" at something because it can mean so many things. Describing the attributes that makes you better with MongoDB, APIs, or software development gets you a lot of the way towards learning how to do it.

Take Mongo for example: is the issue that your database keeps going down? If you frame it that way, it doesn't take long to discover clustering, replicasets, and monitoring. Is the issue that your queries are hammering the server? If so, googling that leads you down a months-long rabbit hole that ends in indexing, caching, and denormalizing strategies. Are you frustrated with the amount of boilerplate needed to get mongo data to the frontend? That's a good hint that you're in the market for a library/framework that might help with that.

Much in the same way that one of the hardest parts of solving a bug is knowing what to Google, specifically defining what "better" looks like is the first step towards getting there.

you're already doing the right thing by thinking about best practises. your question is pretty vague though, which is probably what invites so many comments about "experience" being the best teacher. just saying to "learn the hard way" is doing you a bit of a disservice though, because there is a ton of material out there!! read it. oreilly my friend. and be sure to share it with your team
(comment deleted)
1. Reading and learning from other people's work is certainly a good way to learn new approaches. 2. Learning to measure how your code/application performs will let you test various approaches so you can decide for yourself.
See if you can find someone external to your company to mentor you. Easier said than done, it's true, but most people who are currently employed can find someone in their social graph within one or two degrees of separation that's able and willing.

In most cases, the leverage you'll get from this, compared to trying to learn everything yourself, tends to be overwhelmingly greater than the cost of searching.

Self learning is one thing and being completely on your own without a way to ask specific questions on the daily basis is totally another.

If there is no one to answer your questions in your company - try and find some buddies on the internets or even change company, as in my experience, ability to ask stupid questions and get answers quick is crucial in learning programming. StackOverflow is good, but not quick enough.

——-

Ouch, sorry, misunderstood your question. I am not sure there is a book on best practices on APIs, but it’s definitly possible to have someone experienced help you as a company. There are good developers with experience doing this type of contractor work.

Go to GitHub and start contributing to open source projects that use the same stack.
Read engineering blogs, most big companies have it. Follow HN topics Read books Go to conferences
I learned a lot by working on open source projects in my younger days. People were always around on IRC to answer questions, especially when answering my questions got them closer to their own goals for the project.
I was asking myself this in 2013 and in 2014 I quit my job because of it. I thought https://www.codementor.io/ was going after this problem.

——

If not, it pains me to know that there still isn’t an answer besides, “quit and be skilled enough at determining that a company is good at teaching best practices.”

> books

Are a way to absorb information that the author thought a broad audience would want to know and be able to digest. They don’t replace being able to get detailed individual feedback on your work and your particular questions.

> make mistakes

In my experience, mistakes have one big flaw: They don’t teach you a way to do something correctly. It is possible to go into a situation thinking, “I don’t know what to do here and I need help.” And to come out of the situation saying, “Yep, I did my best and I failed in pretty much the way I thought I would. New information learned: none.” Ideally, you would be able to shop for or come up with a workable solution yourself. In reality, humans benefit greatly by learning from the past solutions of others and from getting personal recommendations.

I recommend participating, daily, in communities, particularly ##programming or #python (if that's the language you're learning) on Freenode.

It's less that you'll learn best practices, but you will expose yourself to the zeitgeist, which I feel is important to being a good dev. Again, not to blindly follow it or even agree with it, but to understand it and why it's pushing in one direction or another.

I haven't seen this advice yet but follow thought leaders on Twitter. They'll post blogs and offer advice to keep you up-to-date on what the zeitgeist of your lingua franca is.
See if you can work with them to plan your code before you guys write it. And afterwards, if you can do a code review for each other. This is hard in startups but it can avoid a lot of bugs downstream; cuz I'm guessing you don't really have any QA either.
Personally I actually think you will gain a better understanding because you have nobody to teach you.

If you work with people who are already experts, they will always prevent you from making mistakes. Being able to actually make those mistakes gives you a much better understanding of why people do things though.

I wouldn't say that... I'll often put in "for next time, look at..." type advice in Pull Requests from more junior coworkers. Sometimes working is more important than ideal.

It's when a Junior-Mid dev has to add a feature that's made difficult by their own choices and then rethink to make things better they tend to learn. That said, plenty of Jr-Mid devs don't advance with more practice, they stay jr-mid.

"Best practices" are not the best way to think about your output nor your (personal) development.

The term is flawed to start with in the sense that it invites you to think of practices as fixed or objective rather than contextual.

You should think of your development as striving to amass the experience/wisdom to recognize the practices that are likely to work better in each situation on the fly. And that just comes with hours and hours and hours of trying different stuff and seeing for yourself (consciously) what you like best and what works best and when. It's slower, but finding that stuff out through experience is really the only true way to learn. Knowledge is a commodity, wisdom is what matters.

And there's a lot more subjectivity to it than we normally treat it as. A given practice can be better along dimension X. But two (great) developers can disagree about whether X is the dimension to optimize vs. Y.

If what you need is a specific practice that is working for people in one specific context at one specific time, you can search the web. But even then, it's not a black and white "best" thing and without your own instinct to judge what you're reading or being told by someone, you're making at some level a guess.

I think you're somewhat taking down a strawman here. Some practices (e.g. using source control, being super extra careful about state changes) are indeed almost always best, and it's rather likely that you'll also learn when to use them for the best practices you do learn. We're - so I hope - not talking about some nonsense like learning design patterns by heart or some such.
Using source control is basic and vague, the specific practices around it you might be tempted to call an education are just as subject to getting lost in dogma vs. developing personal wisdom as anything else.
Just my two cents: learning by "experience" works, but is extremely inefficient, and you don't always get the feedback of your work. You always learn by experience, but you do as much as you can to learn to avoid making mistakes in practice. Compare it to learning to drive: Yes, you learn driving by experience, but you still need driving lessons to avoid getting in accidents.

You can try to learn on your own by reading, but if you want to make serious progeaa, you need a teacher, it's as simple as that.

There are a lot of articles here on HN explaining problems other people ran into, solutions and best practices. Just keep reading. I read for 30 min every day on new tech and ideas even if I don't use them regularly. Keeps me in the loop and a lot of the ideas and principles are portable to other projects.