In the beginning it was exciting because I was learning so much that was new and was able to apply it and see tangible results. Now Im at the peak of my programming abilities so far with my current knowledge in programming and ability to understand and apply concepts, though I no longer feel like Im getting better each day.
Im just wondering if others have had a similar experience and what concept, idea or project was able to get you past this wall?
To become great, look what's underneath each abstraction and see how many layers down you can go and still understand stuff. Try to build your own abstractions from the ground up, e.g. write an ORM, write an interpreter, a network protocol, a graphics toolkit, a Javascript framework.
That will already propel you into the 95-99 % quantile in terms of technical understanding. I see e.g. so many frontend people that only have a superficial understanding of how Javascript or a browser works, or how to write good CSS from scratch.
But... I dunno. It's possible I am just getting lazier as I get older, but I've found that improving my communication skills, helping stakeholders understand the costs of what they're asking, verifying the value that expected cost is expected to generate, and getting alignment on delivering 80% of the solution with 50% of the effort is what others truly value and reward.
That said, it likely depends on your domain, too. The technical difficulty of engineering jobs likely varies wildly between fields.
Anyway, to answer the question more directly, I became a better developer when I became passionate about a project I had a vested interest in seeing succeed. Only then did I find the motivation to research problems to the depth necessary to have "ah hah!" moments. I found myself in this position by working on a personal project until it became popular. The popularity then fueled my desire for increased status, I poured myself deeply into the project, and levelled up my technical abilities significantly as a result. Once I had that experience, though, it seemed like there was diminishing returns on difficulty/knowledge acquisition, as you seem to be noting, so I focused on becoming a more well-rounded technical person rather than pursuing depth.
I recently commented about that here:
> For me, leaving a plateau usually requires a paradigm shift. Here's a few rabbit-holes for you:
> • Learn memory management from Rust
> • Study Postgres internals: https://www.interdb.jp/pg/
> • Learn architecture and design from Elm: https://taylor.town/elm-2023
> • Try building things "from scratch" with zero dependencies
> • Watch online lectures from Joe Armstrong, Alan Kay, Gerald Sussman, Bret Victor, Casey Muratori, Greg Young, Richard Feldman
> • Build a robot
> • Learn a semi-esoteric language like Forth, APL/J/K/BQN, Lisp/Scheme, Wolfram Language, etc.
> But research isn't enough. I never really understood the value of new paradigms until I tried to use them in a personal (or professional) project.
That repeats over and over, it just becomes more nuanced and specific in some ways and more general in others. You have "good days" and bad ones, and you're often exposed to the really different ideas simply by being "in the room" to engage with them properly on a project instead of skimming over someone's half-assed summary.
The two interesting areas of programming, to me, are at the very bottom of the stack near the hardware, and the very top where there's intensive abstraction and algorithm design. The parts in the middle are quicksand; it's pragmatically useful and productive for a job to know some little corner of C++ or a certain Unix tool or a longstanding bug in a Javascript framework. But that's not "programming" in the broad sense either. Shuffling around stacks of dependencies that have been vendored out for your consumption isn't the good part, and ultimately leads towards becoming what James Hague calls the "recovering programmer":
https://prog21.dadgum.com/56.html
Part of the bitterness he speaks of comes from the feeling of perpetual consumption: if you're always learning a next "new thing" you never feel like you've built much of your own. So you have to decide for yourself a cut-off line where you will start to DIY more of it, where you won't do things the "standard" way or aim to have a large, publicly visible project or other such demons in your head. At that point you can just program.
I think I have a set of talents that make me good at methodically solving problems. I have natural curiosity. I like learning on my own and from other people. I self-taught, read everything I could find (back in the '70s and early '80s), practiced a lot, started at age 14. I got lucky with some good mentors early on, that made a big difference. My grandparents bought a terminal and modem for me when I was 16 so I could spend more time programming. I had some great jobs that let me work with people with more and different experience.
I think a lot of luck and circumstance goes into success, but you also need hard work and probably an innate inclination to put in the extra work. Everyone I have ever known who succeeded, in any field, put in a lot of work, but they also had talents and traits that made success easier or more likely.
I don't think in terms of getting "great" at programming. I think in terms of solving business problems and adding value for my employer or customer. What does it even mean to call someone a "great" programmer?
If I have to give advice I'll say read a lot of code, learn from your peers, especially those more experienced than you. A good mentor or two can make a huge difference.
2. Realising that complexity is the enemy. Smart people avoid complexity, dumb people who think they're smart introduce complexity.
3. Realising that in order to ship anything worthwhile you need good specifications, a clear line in the sand, and the time to be left alone to do it.
Edit:
4. Shipping something small is good. You don't know what is needed, but once you've ran something in production for a few days you probably will. YAGNI and MVP all the way!
Don't avoid annoying things - try to be the one who can solve anything
Learn how to automate repetitive tasks quickly (e.g. shell scripting + tools)
Understand deployment and devops
Write documentation together with the users for better requirements understanding
Keep up with modern tech (e.g. ChatGPT, Phind, CoPilot, etc.)
Learn concepts, not Frameworks[1]
1: https://pilabor.com/blog/2021/05/learn-concepts-not-framewor...
Programmers often get to design AND assemble simultaneously, because you can't put together something that hasn't yet been conceived -- and design is where most of the perceived value lies to the non-programmer. The final product looks nice, it feels nice, it does something amazing that I want or need it to do. WHOEVER MADE THIS IS A GENIUS! STEVE JOBS INVENTED THE IPOD! HE WAS A GREAT PROGRAMMER! etc etc. The perception of greatness overshadows the many half-truths and un-truths in the myth.
Beware lionizing "greatness" as the ultimate goal -- society tends to designate it as a shallow summary of a big thing (big number, big building, big company, big media coverage, etc). Sometimes greatness is also bestowed upon things in hindsight, after the grimy details surrounding the thing have been long forgotten or eroded into a tidy, bite-sized story.
If you're bored / hit a wall learning and applying things other people have invented, you'll need to invent some things of your own to recapture that dopamine rush that was there at the beginning. If you have nothing to invent, as others have mentioned in the comments, the next fulfilling challenge will be learning to provide quality service to others as a programmer -- to businesses, as part of a team, etc. Get paid to help them achieve their goals. Guide them through the bog that is modern technology. Provide value in quality implementation and insightful counsel, help them win their biggest wins and you'll become invaluable. In their eyes you will be great, and your reputation will start to precede you.
Just like no amount of weightlifting will turn me into Eddie Hall and no amount of studying will turn me into Albert Einstein, no amount of programming will turn me into John Carmack. I've learned to make peace with that.
Write a (mini)C compiler in OCaml. A distributed reliable key-value value store using the Raft protocol in Go. Work on some toy OS in C. A Gameboy emulator in Rust. A doom-like game in C++. Do 500 leetcode problems. It's endless!
I personally like to pick up some programming projects from MIT or similar institutions. Considering you're self taught, you may benefit from more academic material. Just pick something that corresponds to your level.
Challenge yourself with a project that pushes your boundaries: Look for open-source projects you can contribute to, or brainstorm a personal project that requires you to learn new skills. This will expose you to different coding styles and approaches, accelerating your growth.
There are tools that can help with both approaches, but that's a topic for another day ;)
It's not magic. Take yourself seriously as a tradesperson, continually read about the field, and work for companies that provide you with high quality experiences.
I don't know that I'd call myself a 'great' programmer, but I am quite a bit better than I was ten years ago. And the reason for that largely comes from using that ten years of experience to improve my understanding of the field.
There isn't a silver bullet beyond putting the work in.
Knowing more that what's needed. You work with SQL? Learn other types of storage. Your main language is OOP? Learn other styles of languages. Be knowledgeable in other domains such as networking, OS, game dev, storage, how memory works, etc.
[0] https://www.yieldcode.blog/post/why-engineers-should-write/
It's not just about knowing the framework, but where it breaks, where it shines, how it's meant to be used. Which part is being held together with duct tape? How is it processing a certain graphics type?
Few really amazing developers I've met in my life were either humble or too busy to brag about the size of their genitals...
Just saying.
Good programmers treat programming as an art. Great programmers treat it as food and water.
I eventually started internalizing good practices instead of having to consciously work at it.
I needed people keeping me honest to get to that point.
e.g. writing code without consulting any docs or writing code that meets business requirements?
To feel like you’re taking big leaps each day after reaching a level of maturity you’d likely need to be learning new things, which you’d likely pick up quickly and feel like you’re making a lot of progress, but you’d be sacrificing depth for breadth, if you’re way of finding new things is picking up a new language each week or making the same type of projects which don’t introduce new concepts.
At some point you just need to start making things. Let people use those things and get feedback, they’ll let you know what your blind spots are. Even something as simple and thinking about designing for an end user instead of just yourself will make you think a lot differently about your program. The first thing I really did on my own was a collection of scripts to help me at work. They helped me, but couldn’t really help anyone else. Eventually I started thinking about others and it got a lot better. I made a GUI front end so people could consume it easier, made settings so it could be customized, figured out how to compile it to distribute it to them without dependencies, started actually handling errors, testing edge cases, and fixing little bugs that I would simply avoid running into when it was just me. The whole thing became much more robust. That project, and a couple others, led me out of the sys admin space and over to being a software engineer.
If know one can use, or wants to use, what you’re writing… what’s the point? Thinking about building for people really helped me out when I was getting started.