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.
- 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.
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.
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.
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.
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).
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.
* 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.
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!
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.
- 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.
0: I choose not to work anywhere that sells critical infrastructure, medicine, or anything else where imperfections could jeopardize someone's life.
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.
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.
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.
* 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.
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.
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.
- Leetcode, my DS & A courses in college weren't particularly rigorous. Only by doing 300 LC problems to prep for interviews did I begin to feel competent with DS & A, and I still have a lot more niche stuff to learn like Red Black trees and KD trees.
- Pay attention in college classes! Certain classes I took in college are core parts of my computer mental model that I think about every day. Especially operating systems, hardware + systems fundamentals, programming languages, and obviously DS & A.
- Generally most of the work that is done these days is in web dev, so be sure to do a bunch of web dev personal projects, ideally substantial apps. If going into another area then be sure to get good at that, like do some RPi stuff if you're trying to get into embedded.
But above all else, the number one thing that made getting good at programming easier was being genuinely interested in the subject matter. My classes and projects never really felt like work to me. If you hate computers then you're gonna have a bad time.
* studying algorithms
* experimenting with different solutions
* learning paradigms, methodologies and best practices
* striving for simplicity
* being curious about how things work
* systems thinking
Being really interested and motivated to write my own projects.
Learning everything I possibly could about every topic I found interesting relating to computing ans software.
Focusing my effort on a small selection of technologies.
Making the decision to be able to build an end to end application on my own.
1. Is it the fast promotion cadence in a non-faang job? 2. Fast promotion cadence in a faang job? 3. Confident that you can learn a new langauge/stack/tool/algorithm easily? 4. Confident that you can implement a language/stack/tool/algorithm (with enough time)? 5. Passion to actually do #3 and/or #4?
I have always sucked at #1 and #2 but have constantly been deep on #5 (id even say i "waste" enough time doing this that I neglected coding at work so ended up switching to management). I really envy the folks who can only code for a living and not be bothered about wanting to do side projects.
2. Reading, debugging, modifying source code. Reading is harder than writing, which means that it's good practice: "why is this hard to read? Is it necessarily hard, or is it something about the implementation?"
3. Taking less advice from random blog posts. When I started getting good in the 2000's, it was quite a thing for developers to self-promote by making cookie-cutter blogs about OO pattern du jour or "code katas" or something. Today YT content probably does the same kind of thing with new fads. When you cut through it, it mostly isn't technical knowledge, it's sophistry. You don't want to restrict yourself to "never view this stuff", especially not at the beginning where you're looking for a branch to cling to, but you do want to locate it in a place of pop culture and fashion relative to the actual problem-solving work.
4. Doing things two or three times in different ways. This is a way of testing whether advice is good. In work you may not get the chance to, but as a side project, you can try doing things with different styles of coding and seeing if one way is harder, substantially reduces your error rate or SLOC, etc.
5. Applying logic and philosophical thinking to coding. To do task 4 properly you have come up with success metrics. What makes code successful, and what makes it fail, and can you encode those things as a rule for yourself? If you can encode it as a rule for yourself, can you then automate that rule so that it is enforced by definition? The better your critical thinking is, the more you can work through these entanglements. Both math and philosophy can spark some ideas towards this end, as well as plain old life experience.
Programming can be both satisfying and frustrating: when you're able to apply the basic concepts well to solve something it almost always feels great. When you have to deal with things other people built, it's almost always frustrating.
1. Programming. Lots and lots and lots and lots of programming.
2. Having my code reviewed by people with strong opinions, some of which I agreed with and some I didn't.
3. Reading, and practising what I read (number 1 above).
i made toy apps and widgets. chrome extensions. took on a bit of client work.
read some books.
stay up all night and hack on projects for a few years while people are sleeping and youll get some where.
never had a sideporject or 'startup' that actually made money, but thye taught me the skills i have now that are paying the bills, and i pretty much have my pick of jobs at this point.
but also suffer from extreme impostor syndrome and try and use that to fill my (perceived) gaps
* read the source /framework code, if available
* tests and examples are not optional documentation. They will always tell you things that were forgotten in the docs
* reading docs without actually writing code won’t help until you’ve spent a long time with the code. You have to write your own examples while you were learning
http://robert-inman.com/blog/2016/2/11/how-do-you-get-to-car...
I've never deliberately practiced or anything like that, just built stuff that I wanted to build.
Taking time to read docs and "learning" to read docs (awkward output of various auto-docs tools) has helped me crack programming right from my early days of PIC microchip data sheets
Getting constant exposure to cutting edge tech so you have a delta between what is possible and what you can build.
Shrink the delta by building such a thing
well I wouldn't say that I'm good. I'm better than I was, sure but "good", man, I dunno. I've been told I'm good but those people were being nice to me so I can't trust what they say.
to get better: do more of it. come to your own conclusions about what works. read other's opinions, and ignore them mostly, because what sounds good when described is rarely actually good when implemented (see: object orientation).
put the hours in. there is no shortcut.
But at some point you won't be satisfied with just doing things that other people have already done before, or you'll want more control, or be unhappy with some aspect of the approach people before you have taken. Or maybe you'll just be curious: "I know this code let's me draw a circle... but how exactly does it do that?".
At first, this will be hard because the "how" is often quite complicated. You'll have to force yourself to understand a lot of things that previously you didn't, but you'll also see why certain things you've tried in the past didn't work. This is where you learn the difference between what is easy and what is hard. You'll start to properly plan a project out before just diving in.
Later, you'll get used to processing the complexity of "how" things actually work behind the scenes, and then a strange thing will happen. Instead of seeing complexity and thinking "that person must have been a genius to come up with that", you'll see something and think "wait a minute... what idiot wrote that".
You'll suddenly find that every codebase you dig into is a steaming pile of garbage under the surfacce, and you can't bear to build anything on top of it. Congratulations, you now have NIH syndrome! You'll try lots of different languages, technologies, etc. and although they'll all be a disappointment in one way or another, you'll learn a ton in the process.
After that, there are fewer dramatic step-changes. It will just be several gradual changes:
- Some (although definitely not all...) of those things you thought were garbage turn out to actually be well motivated.
- Your focus will shift from the code itself, to more abstract engineering ideas. The coding part will just be automatic at this point, but you'll be thinking about things like backwards compatibility, ease of use, scale, performance, etc. more and more.
- Motiviation will be a bigger problem. You'll have the mathematicians problem of knowing in so much detail how to do something that actually doing it is just... uninteresting.
The only way to progress through all of this is to keep programming, keep reading other people's code, and keep learning.
Being able to be choosy where I do so.
Follow your instinct, build things, read, write, repeat.
So, I become a better programmer when I'm actively working on something. I no longer contribute code on a regular basis at my day job so to stay sharp I've started creating little utility programs for personal use.
I've also started finding hobbies that incorporate some programming, generative art, robotics, etc.
tldr; find ways to incorporate programming into everyday life, practice by building things that are actually useful to you.
I love the community. There are so many people who are willing to help others learn, which is really inspiring. I think it’s because we get that everyone starts somewhere, and we all want to grow our skills and help others do the same. There are also tons of resources online for learning new things—a quick Google search is all you need to find a tutorial or a YouTube video that can give you the information you need to move forward.
Last but not least, my mentor has been an invaluable resource for me as I started learning about programming and software development. He has a lot of experience in the field and he’s been able to answer any questions I have about what it’s like working as a developer in the real world. He also gave me some great advice when I was starting out, like making sure to keep up with current events in tech and reading blogs written by developers with more experience than me.