top | item 31240927

Ask HN: What helped you get good at programming?

76 points| robalni | 3 years ago

What are the most important things that have helped you get as good at programming as you are today?

82 comments

order
[+] rektide|3 years ago|reply
Dive deeper. A huge amount of programmers bounce out, throw up their hands when something isnt working as expected. Go look at the souce of the libraries you are using. Learn tools like strace or dtrace. For god sake get good at your debugger.

In programming, everything is about mindfulness, perspective, awareness. The willingness & ability to go deeper, to dig for truth is the ultimate superpower. The docs dont help, your mentors dont help: Seymore Papert was correct. You have to mine your own truth, develop your own internal models for what is going on, how things are happening, and you need endless boundless ability to dive further in, to chase real genuine truth yourself. The ability to develop your own mental model of how you think things work, and your ability to probe & validate & make inquisitions into each little step: that scientific minded exploration makes all the magic happen.

Also, get good at promises & async. How things happen over time has gotten more complex in modernity. You need to understand & be able to internalize/visualize the timeline of execution, in a way we didnt used to demand.of programmers. Learn the tools, think about causality.

[+] ltbarcly3|3 years ago|reply
Came to say basically this.

Whenever something doesn't work the way you believe it should have, whenever you see something that does not make sense, that is your understanding at odds with reality. Something doesn't work the way you think it does! Every time you don't get to the bottom of why it doesn't work the way you think it should work you are continuing to be a little worse than you might have been.

Accumulating moments like this over time adds up to the difference between being a great programmer and being complete crap. It's the difference between someone who overhears two people talking about a problem and says "Did you check that the locale is not set to iso8859?" and blows their minds that you could debug the problem they have spent 2 days working on in 5 seconds and the person who tells people "oh, yea, sometimes our app just crashes, it's something about text encoding but if you just open the file and save it as utf8 then you can manually fix the broken characters after you import it".

[+] viraptor|3 years ago|reply
Similar answer here. Some activities I got most new skills from: reverse engineering feature phone firmware (no previous experience with re, tiny bit of assembly), contributing to all an OS which included an AOT C# compiler (no previous experience), writing a low latency telephony proxy (no previous experience), etc.

Someone learned how to do those things, so you can too. The information is out there, and if not, you can go one layer deeper and figure out how/why things work.

[+] omegalulw|3 years ago|reply
> to chase real genuine truth yourself. The ability to develop your own mental model of how you think things work, and your ability to probe & validate & make inquisitions into each little step: that scientific minded exploration makes all the magic happen.

Wonderfully put; this cannot be overstated! And I think you can apply this to most of math, physics, electric engineering, etc too.

[+] beefjerkins|3 years ago|reply
- A LOT of practice. One of that parts of becoming a good programmer is learning about potential pitfalls and bad practices; what better way is there of avoiding these than by making these mistakes yourself and learning from it.

- Studying and researching best practices for not just your current language or paradigm, but others as well. If you've got experience with Java, look into other paradigms than OOP such as Haskell / Elm that focus on Functional Programming. This can lead to learning about new ideas of programming in general, which is a good thing as it exposes you to more tools that you can use.

- Making your own things. Find areas in your life that could use some automation, or perhaps use programming as a creative outlet; the more tools you make, the more practice and experience you'll get which leads to the first point I made.

- Cringe at your old code. If it's really that bad, it's likely you've come a long way as a developer, which is good! Reflect from time to time about why you originally wrote code a certain way, and think about how you would approach the same problem now with more experience.

[+] efortis|3 years ago|reply
I was able to code much larger projects after watching this Uncle Bob's Live Refactoring video:

https://web.archive.org/web/20150905163826/https://www.youtu...

BTW, I think sometimes is ok to have inline code with a comment of what the extracted function name would have been.

---

Also, by coding using his TPP helped me gain confidence on figuring out complex algorithms. For example, he explains how writing a sort algorithm went from bubble sort to quick sort (I think) by following the TPP. https://en.wikipedia.org/wiki/Transformation_Priority_Premis...

---

Lastly, as I have a few projects that I can't even run dev on them, because their deps are too outdated, I try to keep deps at a minimum. e.g. I have a custom minifyCSS that minifies ~85% compared to other minifiers, but it's super simple in comparison.

https://github.com/uxtely/js-utils/blob/main/minifyCSS.js

[+] PaulDavisThe1st|3 years ago|reply
A mentor who wouldn't give me answers.

When I needed to make SunOS give me tty key stroke input 1 character at a time, he refused to tell me what he already knew and just pointed me at some "areas to look into". Knowing about kernel tty drivers and terminals and line buffering didn't make me a better programmer, but it didn't hurt. Knowing my way around a variety of different documentation at many different levels of the systems I was working on helped make me a better programmer, and my mentor refusing to just answer my questions was a major factor in that. It also forced me to understand much more of the systems I was working on, rather than just how to use some piece of convenient API.

[+] don-code|3 years ago|reply
I'm curious if you've ultimately found your mentor's behavior to be a net positive, or net negative, in your career.

One of the engineers under me often expresses his discontent that I won't give him answers, either. I think he's more than able to get to those answers on his own, and that the value he'll derive from learning how to learn is vastly greater than the value of being able to complete his work faster. On the other hand, he's given me the feedback that the method is excessively socratic at best, and flat-out frustrating at worst.

[+] gilbetron|3 years ago|reply
My first boss out of college (a long time ago) was like this. I'd ask him, "how do I do X?" and he'd reply "man <some-command-useful-to-do-X>". I thought it was annoying, but got it a few years later :) I find myself being the same way these days when it comes to mentoring. Others will help a struggling person, but as long as they aren't crazy frustrated it is destroying their motivation too much, and as long as biz needs aren't being too disrupted, I generally have no desire to help. Why would I deprive them of deeper learning by helping them? ;)
[+] ncmncm|3 years ago|reply
The single most important concept separating a good from a bad programmer is the concept of the invariant. Good code maintains (or anyway restores) invariants, bad code doesn't.

It is very easy to miss this because invariants are often not written down, and you have to discover them.

Related are preconditions and postconditions. Function A establishes postconditions that satisfy the following function B's preconditions.

Your goal maximizing merit of code is to ensure invariants, preconditions, and postconditions may be stated as simply as possible; and keep them satisfied.

[+] mikewarot|3 years ago|reply
What do you mean by invariant? Clearly, the word has special meaning for you, but it is defined as never changing. That definition is not consistent with your emphasis.
[+] jacknews|3 years ago|reply
This is from formal methods, and while it is one way to specify your code, and contain unexpected behaviour, I wouldn't say it's the main thing in being a good programmer. Managing complexity in general is perhaps the main thing, so that you can do more complex things without getting completely overwhelmed by details.
[+] omega3|3 years ago|reply

[deleted]

[+] rg111|3 years ago|reply
I am not sure that I am good at programming. I am certainly not as good as the HN-type second generation SV kids who started programming at four.

Given that, I do work at a lucrative position doing cutting-edge work.

What made me get programming was- _getting hired_. I was so-so before.

When I got hired, the work was so challenging and the situation was so unforogiving, I had to grow. I had no other way. I learned new stuff, wrote code that inspired me, and was really "impossible" by me a few months ago. Sometimes, a few weeks ago.

What made me and and keep making me better than before is Hacker News and peers.

I want to get as good (from the first paragraph); grow as a programmer, grow as an overall problem-solver and thinker.

I keep learning new paradigms, new applications, gaining new knowledge, and growing as a person.

So the most important thing would be community. Before HN, Reddit. Now, Twitter and Discord, too.

I get to know so many new perspective, so many new resources to follow, books to read, stuff to generally know. I barely have time to breathe.

I also made some genuine, long-term friends through this process.

So, community would be the utmost important things.

I was born in a middle-of-nowhere small town, and community and internet are the ones that made me who I am today.

I am not much, but definitely levels above what I was a decade ago.

Edit: It would be incomplete if I did not mention high-quality teachers teaching for free through MOOCs, YT playlists, etc. And internet pirates, too. Having quick access to any book you might want is very important. (I do spend a lot on books, but piracy is what makes me spend that money so that authors get what they deserve).

[+] betwixthewires|3 years ago|reply
I wouldn't say I'm a top notch programmer by any means, but one thing ironically that made be better is to take a step back for a while and stop programming and try to learn, read and understand things better. This doesn't work unless you've been programming for a bit and have some hands on the basics, but it does help to break bad habits.

Stick with standards and conventions, even if they seem stupid. Just do them. Four spaces in python, that sort of thing. Pretend they're rules of the language, pretend that not following them will break your program.

Try to understand data types and structures, they're vastly more important than programming. Knowing how to write code, syntax, libraries only helps you if you understand the data you're manipulating, what you want to do with it, and how it is best structured for your purpose. You're better off knowing about data structures and not knowing a single programming language than the opposite.

Finally, build things, solve problems. If you want to do something, do it. Don't worry about if you're good enough.

[+] jcranmer|3 years ago|reply
I don't believe I can prioritize these between more or less important things, but this is the set of things that I usually credit:

* Programming competitions. The main utility I got out of this wasn't learning obscure data structures or algorithms (which tend to often not be very relevant), but rather the experience in coming up with corner cases that might break my own code, and how to write and debug code without sitting in front of the computer. I guess in short it's the ability to separate the algorithm from the implementation and track down failures to one or the other.

* Going to school and getting a CS degree. Learning in general is useful, but I believe that the structure of a full CS degree is generally better than picking things up ad-hoc, especially in guiding you towards areas you wouldn't otherwise think to learn about (e.g., I wouldn't have picked up information visualization on my own).

* Seek out and learn as much as you can in general. You never know when randomly learning some topic in some distaff field might come in useful; one time, I happened to discover (while looking up information on ptrace in a debugger-like side-project I was working on at the time) that Linux supported hardware watchpoints via perf... and a few days later, we had to resort to that to track down a bug that wouldn't reproduce in gdb.

* Peruse other projects for how they do stuff. Part of the above, but you'll pick up on "huh, that's an interesting thing to do" as you learn about how they work. If you're curious about how something works, just open up the source code to see how it works. At the very least, doing so frequently will give you a good sense of how to quickly find stuff in large, unfamiliar projects, which is apparently not as common a skill as I take it to be.

[+] timoteostewart|3 years ago|reply
1. Having a passion project that made it easy for me to sustain lots of hours of coding as I strove to complete the project.

2. Reading widely in the coding literature, from personal blogs to engineering blogs to O'Reilly (etc.) books, to "philosophy" stuff like Bentley's Programming Pearls

3. Regular LeetCode. Not grinding exactly, but disciplined practice of solving specific, short challenges.

4. Browsing OOP (other people's programs) on github and such.

I'm curious to see what others post!

[+] LeftHandPath|3 years ago|reply
My first real experience programming was when I was 19, before ever having a class, teaching myself PHP/JS on the job to write custom wordpress themes. I started writing inefficient spaghetti code and progressed into writing object-oriented, then started looking at performance. The performance aspect was definitely the deepest rabbit hole.

I would say that I learned more doing that than I have getting a CS degree at my state school (aside from writing performant code, which classes have helped with). But it is mostly because I viewed getting good as a way to escape from some bad circumstances at the time - every word I didn't know was a low-hanging fruit waiting to be picked. I did a lot of reading, and I practiced at home in my spare time as well.

I got really good at front-end stuff and learned how to use the terminal so that I could host and manage our company's websites on a digital ocean droplet (running centos). I learned a lot on the linux terminal - writing bash / shell scripts, managing configurations, etc. Improved speed a lot by configuring apache... then again by redoing things in Nginx on the next site, which I've preferred since.

Since I've gone back to school, going overboard on programming labs has also helped a lot.

[+] mediocregopher|3 years ago|reply
- A lot of practice, which stemmed from a lot of fooling around and abandoned side-projects. I would deliberately start projects which were way over my head, with no intention of even getting something working, just to see how far I could get before getting bored.

- Learning new languages which had vastly different paradigms than the ones I was used to. Java to Perl to Javascript to PHP to Erlang to Clojure to Go to... Over time you learn patterns from one place you can bring to another, and learn patterns which exist in most places which you'd rather didn't.

- Lots of experience in the actual workforce, building things people (supposedly) wanted. There are aspects of programming which people spin their wheels on which really don't matter in the long run, and conversely there are aspects which go ignored but are very important. Working on real, rubber-to-the-road projects gives you perspective on what actually matters.

- Being a daily archlinux user (I don't use any non-archlinux OS on any machine I own). Yes, it's hard. Yes, it's an incredibly good use of your time to figure out. Once you're comfortable in arch, every other Unix-like OS (ie, most of them that you'll ever probably work with) will feel familiar.

[+] notreallyserio|3 years ago|reply
I've been at it for a bit over 20 years and I haven't figured out how to get good at it. I do OK, though, because I learned it's often more important to ship than perfect[0], and rewriting isn't so bad because the second time is usually better than the first.

0: I choose not to work anywhere that sells critical infrastructure, medicine, or anything else where imperfections could jeopardize someone's life.

[+] jokab|3 years ago|reply
18 yrs doing this and I feel exactly the same way. I just love building things on my free time even if i know some of them won't make it out of my dev environment simply because i work too slow. I guess to me, the discovery process (in building something new) is so much fun than say, playing video games.
[+] mmcgaha|3 years ago|reply
I have no clue who you are but from reading your answer, I bet your coworkers love working with you and I bet you write nice maintainable code. You are probably better than you think.
[+] leecommamichael|3 years ago|reply
Make something from nothing. Trying skipping out on a project starter-template. Try compiling it without your IDE. Try writing the SQL. Not with the intent of saying "this way is better" but with the intent of feeling what is done for you, so that you might control it when the time comes.
[+] mdp2021|3 years ago|reply
I presume, a large number of problems to solve through coding and a passion to solve them...
[+] frantzmiccoli|3 years ago|reply
Not sure I am good at programming, but I would list the following:

Programming, a lot. And I would add, staying on the same project for long enough to get the pain from your mistakes.

Working alone, because it prevents "easy help" and forced me to dig hard on some problem that needed solving.

At the opposite side of the spectrum, having super rigorous colleagues that did not mince their words and explained and asked me to redo work multiple time if needed (I only had that for a few months but I think it was a turning point).

Practicing multiple languages and shipping something with them.

Building a mental model, I consider that software engineering is 90% a communication exercise towards colleagues or your future self.

[+] MrFishy|3 years ago|reply
I had a really good mentor for many years. He was my manager starting back when I was in high school, and he was always working with us to improve our code. He recommended good books and articles, put in place systems of formal code reviews that emphasized egoless programming, so we could review, learn about, and improve our code without feeling threatened. He helped me think about the code development process and how to be constantly improving it.

He helped me establish many good habits that helped me to grow throughout the years. More than 3 decades later we are still good friends.

[+] mikewarot|3 years ago|reply
Access to a programming environment with good discoverability, and reasonable examples of working code that I could tweak. Back when I learned, examples abounded in print material, and print documentation tended towards complete. (Especially Turbo Pascal's manual)

This made it possible to experiment, and get started. Since then it's a matter of repetition, deliberate practice, and raw experience over time.

Everything has scaled towards good thanks to Moore's law, the Internet, and GIT. You can't overstate how much better git makes things.

[+] tastysandwich|3 years ago|reply
* I read a lot of technical books. Designing Data-Intensive Applications was a favourite. I dove deeply into technical books on the language I was using at the time - C/C++. That knowledge carried over to other languages I later learnt.

* I read a lot of non-technical books. Don't underestimate how beneficial it is to expand your general knowledge. Be open to new ideas. Engage in discussions with people, but don't be arrogant. It can be tempting to think you know everything, especially when you read a lot. Books can teach you a lot about the human condition, helping you connect and collaborate better with others. Ultimately to be a good programmer you need to be able to work with others.

* I was genuinely curious and played around with Linux a lot at home. I got pretty good at writing bash scripts. When shit hits the fan, being able to bang out a bash script to quickly fix some data issue can literally save the day. Also knowing where things live on Linux can be super helpful when debugging services, or just getting your dev environment set up.

* My first graduate role was doing mostly C, as well as C++ on fairly barebones Linux devices. Knowing C, understanding memory allocation, concurrency (mutexes, semaphores), man I can't overestimate how useful that has been. Having this understanding means you're just way ahead when you need to learn another language. It all carries over.

* Don't neglect the human/social aspect. Be the kind of developer people love having on their team. Be generous, be kind, be humble. A smile can go a long way in this world. You'll be paid back many times over.

[+] matthewmacleod|3 years ago|reply
The top one for me has been to try working with as many technologies as possible. Do something in every environment you can – write some C, some Ruby, Python, Java, Swift, Typescript, C++, Haskell, Rust, Objective C… whatever you can get your hands on. Every language and framework you use—even if just for a minor project—will expose you to a set of new ideas, idioms, and APIs. After a while you start to recognise all of the different patterns, and understand how and why they work in the way they do. I think this is effective if you're the sort of person who learns more effectively from practice than from research.

The other one is to always be thinking about that well-known Torvalds quote:

"Bad programmers worry about the code. Good programmers worry about data structures and their relationships."

We often think of "programming" as "writing code" - but that's really just a tool to an end, and the best code is the code you didn't have to write. Approaching problems by thinking about the shape of the data you have, what you want it to look like, and the relationship between these things sometimes feels like a superpower. The code is just the annoying bit in the middle that helps you do all that stuff.

[+] karmakaze|3 years ago|reply
Probably starting with my Atari 400 back in the 80s. There was no internet and any low-level documentation was hard to come by and readily shared with the few others with the same system and interest. All this is to say that I learned to dig, learn, and figure out stuff on my own, trying, failing, and keep going until I got something I was satisfied with. The other interesting thing is that the computer was over my budget so my parents only bought me the BASIC cart and Asteroids, but no storage of any kind. That meant that I would code for a couple days, never turning the computer off and when my program was done and I'd played with it long enough, I'd get bored and want to play Asteroids. That taught me not to get too attached to versions of programs I wrote. The next version was of course better, and I got faster writing them.

After going through this process, anything after like school courses, university, co-op terms, learning C, using compilers, doing low-level firmware development all seemed like natural continuations. I'm also always seeking novelty and new ways of doing old things.