Ask HN: How do you get better at coding?
The survey below contains just 6 simple questions to answer. Or just answer here. THANK YOU!
https://goo.gl/forms/emc16fdMC8UkTYYh1
The survey below contains just 6 simple questions to answer. Or just answer here. THANK YOU!
https://goo.gl/forms/emc16fdMC8UkTYYh1
No, really. You can read all the books, blog posts, open source code samples you want, but nothing will substitute writing code.
I maintain a handful of side projects as well as write code daily for my job. Plus, I love it. Also, my side projects usually encompass something I have no idea how to do, which quickly elevates my skill level. I love learning, so it works for me.
I started actually coding seriously and properly the past 1-2 years. Easily learned a hundred-fold more by doing it, literally.
I think too often I told myself I'm "not good enough to make something serious". And you know -- it was probably true. But that doesn't matter. Just start, things will fall into place, sometimes you'll fail, sometimes you won't. It's just the only way really.
it's not true, most "serious" things aren't that difficult or complex
Generally speaking, when I discover some interesting technology, I attempt to implement it in whatever language I am currently trying to improve my skills with, regardless if it's not the best environment. A good example of this was implementing the Ethereum VM in PHP. After just a few weeks of tinkering, some takeaways were learning the best and fastest ways to interact with binary data in PHP, improving my mental model of state machines, improving my debugging skills, learning how JIT compilation works, handling "big numbers" properly and caveats between several available libraries, etc...
A few important rules that have proven successful for me:
1. If available, your first iteration should be built purely following a specification (e.g.: RFC, whitepaper, yellowpaper), otherwise, if you have enough domain knowledge and understanding of what the program should actually do, build it without any reference, but allow an exception for researching (when required) very specific problems such as determining the best sorting algorithm for some function. Performing either of these will challenge and improve your ability to carry out the SDLC.
2. Hand-in-hand with #1: Don't start testing against (or even looking at) other reference implementations until at least iteration two. Whichever iteration this lands on, it'll likely be your first major refactor and will be the most time consuming, but most satisfying step. You will discover things you've (supposedly) done right (awesome++), things you've done wrong (learning++), and maybe even novel solutions to problems that end up being noteworthy contributions to the community (really awesome++++).
3. For lack of better phrasing: Focus on the specific task of the program or library. For example if your project is multiplayer netcode, you will of course need a game engine of some sort to capture a realistic state from, feed the data to, display it, etc. Sure, go ahead and write a simple game engine, but as cool as it is, don't focus on that...just get it to do what you need for your netcode! Game engines are cool and so are other subsystems of multiplayer games, but don't get distracted. This example is being used because multiplayer games are complex and meticulous and spending too much time on each subsystem may lead to burn-out or disinterest for what should be a far smaller project.
4. Don't worry (too much) about the language or environment being used. Unless you're planning on the project materializing in to a product, the sole intent should be becoming a better programmer, which requires only one language and a fresh project. Learning a new language isn't going to immediately make you better at programming, although there are plenty of benefits in learning new syntaxes and paradigms. Plus, you may always use your newfound domain knowledge as motivation to pick up the appropriate language and/or platform.
5. Never be intimidated.
1. If I'm learning a new language, I pick a topic I know well and try to apply it in the language. Typically the first pass is nonidomatic, and I iterate as I learn more about the language. 2. If I'm learning a new algorithm, I use a language I know really well. 3. If I'm learning a new framework, I pick a smallish project and dive in.
Most of it is throw away, and I've found that takes a lot of pressure off.
Instead just learn how to solve your actual problems or entertain yourself using programming /today/. Making your friends websites, making games for / with your kids, making an app to water your plants, making spreadsheets to manage your finances, automating that annoying manual thing you do at work, making goofy software that converts images to pixel art, whatever floats your boat.
You have to make a lot of bad things to start making good things. So start making bad things, and enjoy it while you're at it - I've made my fair share.
Do a little bit of programming every day. Do it for now, and not for later. Set yourself a direction every so often, but not much more than that. Review your own work and see what was not great, and figure out what to learn next to make it better. Show your work to other people and ask them for help, or enjoy together. It's much more pleasant to look back later and continually be surprised how far you've come.
Edit: and to answer your question. At first I learned by reading other's people code and trying stuff. Adapting existing base bit by bit can go a long way. Back then I had no internet.
At university most of the curriculum was theoretical. We have done very little actual coding and most problems were too small. Often too specific and vague at the same time.
Nowadays I learn by coding. When you re-read your code from a few months back it should look bad, this is the sign that you have progressed. If there are no idiomatic ways of solving a particular problem, I try to find a better way to implement it each new time.
Finally, I try to talk to people smarter or more experienced than me.
If I would change one thing, it would be to do more projects in university and make them follow agile methodology with the teacher as product owner.
For example, if you want to write an SQL parser/analyzer, take a stab at how you'll structure it, then try extracting this piece from postgresql. Compare and contrast. You'll learn how a good modular code looks like and start learning how to apply such patterns to your code.
Delving into a code base without a goal isn't helpful imo. You need to have a main goal like fixing a bug, adding a feature, or extracting a piece to integrate it into your own code.
The best kind of practice is the one you dread most.
Last year I kept hitting the semicolon, curly brackets wrong and getting the capitalizations off. I deliberately practiced typing those for dozens of hours. These things really helped me stay in flow instead of stumbling.
I used to dread all the complicated architectures of modern Android. So I did a few app sprints trying to find simpler ways of building one from scratch and seeing which corners I can cut.
I felt that I was too slow in coding things that weren't copy paste. So now I've been doing some 'sprints' by doing Hackerrank or Project Euler as fast as possible and then taking a long break from them.
2. Use Anki for difficult memorization
3. Use mindmaps for difficult concepts
4. Practice Coding
5. Sleep and Exercise for mental health
I've also found a low carb high fat diet helps me focus a lot more ymmv .
However, working with other smart (ideally smarter) people really helps a lot. Code review of my own code is helpful. But also reviewing other people’s code. I find that reviewing other people’s code from projects I am familiar with is more valuable than just reviewing any code.
I’m also a musician, the same approach applies there too. I always try to play in bands where I’m the worst player (though hopefully good enough that my playing satisfies the others in the band). That way I’m always learning and pushing limits.
I would quantify a key difference between an effective intern and an ineffective intern as "has this person written 10KLoC". Writing software is a craft, and crafts require practice.
After initial competence is achieved, i.e., you can do your first coding language/tech and be comfortable, you need to choose another, different, one and repeat the process. It will break individual understandings of that one system and show you commonalities. Then, do it again. Even more different. Rinse, repeat. The breakthrough and toughness are required for getting better.
At a certain point, the problem of "learning how to code" or "getting better at coding" disappears and you need to understand how to work with others and building work products for them - open source or otherwise. On and on it goes.
2. Try to learn the underlying technologies thoroughly. For example, try writing a simple C compiler and linker. That will teach you about a lot of things that a lot of the programming world sits on top of.
Tinker a lot and don't be afraid to make your own mistakes (and learn from them once you've recognized them).
Reading, esp. code (including learning new languages and reading in them), shows me new paradigms, new idioms, new ideas, sometimes parts of new ideas which may click together later. Sometimes the patterns may however be subtle and not easy to notice by pure code reading; in such cases reading free-form prose (blogs/etc.) can help notice them. Also reading code invariably provides examples of bad code, to be remembered as a warning and something to try to avoid.
Writing code introduces need for actually choosing some of the learned approaches, excercises the learned theory, ingrains it, shows the shortcomings and costs of particular patterns/approaches, their nuances, where they fit and where they don't, allows to experiment with them.
"Exchange with coworkers" is usually also reading in my case, i.e. code reviews.
And I just realized that also doing code reviews helps me improve coding in one more way: I sometimes discover stuff when I'm trying to express in words why I find some peer's code jarring, troublesome, or confusing.
By active I mean actually coding. I usually have a side project or two that I'm working on (although sometimes barely at all) and I try to pick projects that involve working with a tool, platform or skillset I haven't tried yet. That's how I've gotten into things like deep learning, computer vision and 3D graphics that I wouldn't normally get to use at work.
By passive I generally mean podcasts. As a front end developer, I recommend Shop Talk Show, DevChat.tv's podcasts, Toolsday and Codepen Radio (and for people who are new to CS entirely, Base.cs is an awesome podcast). I'll put one of these on while driving or playing a zone-outable video game and just absorb.
I suppose I should also recommend things like Pluralsight and Lynda.com for getting an introduction to a topic I'm completely unfamiliar with. These are invaluable, but only if combined with actual experience in the thing you are learning. If I take a course on there and don't apply it soon after, I'll generally forget most of what I learned.
I'll add one extra on top of that: it's important to practice on real, complete, non-trivial programs that actually do something. Ideally it'll be a large project because that will give you practice in working with other people, API design, refactoring, testing, debugging, and reverse-engineering.
2. Fix tons of bugs. You will get exposure to all kinds of issues and shortcomings that people before you made. Those who do not know history's mistakes are doomed to repeat them (or any variation of this quote)
3. Talk and work with others. Software engineering is a team sport. Surround your self with smarter than yourself, that often works best.
4. Teach others, share your knowledge. No matter if they are more junior or senior, it does not matter. That will make you understand problem even better.
5. Build simple things. KISS and done. Simplicity is the ultimate sophistication. Do not try to impress others with how complicated your software is, try to do that other way around if you have to.
Years of accumulating minor improvements based on real projects I actually worked on have compounded.
If you spent most of a day on something, nobody is going to notice an extra twenty minutes to fix it up a bit more. Especially if it means fewer production issues with that code. On a sane project the interesting problems are given to the most reliable people, not the fastest. So look at th code one more time than you deem necessary.
Try to look at it the way someone else will or the way you will in six months when you touch it again. Do the commit comments match the code? Can you tweak the code a bit to make it mean what you said? Then do it.
+1 for reading other people's code. I'll build on that by adding:
- by learning to make your own code readable
- by working with people who want to make code reviews a priority
... and then suffering through withering dismissals of my urgent questions on stackoverflow and also facing condescension, ridicule or getting ignored by people who can help me at work. Seriously.
Challenge yourself, to try the hard task once in a while (prove to yourself, those "I could do that much better" thoughts), attempt "proof of concepts" (at least) of your wild ideas. You will be surprised how far you can get.
Exchange ideas and accept bitter pills of criticism, yeah sometimes you will have to admit you got something wrong and now you have to rethink how to do something. Once you get over that you will find new opportunities and also have a new story about "back in the day I was so bad at this, I..."
On #2, for example, if you are working on a todo list backend in python, try to find existing solutions for todo list backend in python. Then you can see what others using in their solutions and try to bring them into yours.
I understand, this approach is not applicable for everything but I have found lots of gems this way.
Only when you get stuck and cant figure something out with your current knowledge set, should you venture to look at others solutions.
Or after you have completed your solution and are curious about what others have done. You might find a library that makes your life way easier, but had you started out using that library, you wouldn't have the best understanding of the nitty gritty details.
I will admit sometimes I get a little ambitious with what I want to do and end up looking at other solutions to see just how complex we have to go.
- Eric Raymond, "How to Become a Hacker"
2. Rewriting, rewriting, rewriting
3. Trying new languages for fun (I ported a LAMP website to Node to learn about node+express)
You have to be exposed to code written by other people in order to see better ways to do things.
2. Dive in head first knowing a ton of research will need to happen
3.
4. Profit
Bouncing off ideas, war stories, snippets, learning and sharing alternative ways to solve problems. Priceless.
That worked for me.