Sometimes people dismiss certain companies. I remember my first boss dissing Google saying things like "how good can Google really be?". Now that I've experience it, I can say that career growth and learning between companies are not measure in percentage points or multiples, but orders of magnitude. The reason is simple: in some companies you might not learn anything or even pick up bad habits, while others will accelerate your growth.
I spent the first 7 years of my career in a low performing organization. A few year later I joined a Big Tech company, and in 1 year I grew more than those 7 years combined.
I'm in my 11th year as a developer and left a pure tech company 6 years ago where I was surrounded by other engineers for a small one where I've been 1 of a 2 until this past year (I now lead a team of 3 stateside and nominally 3 more overseas).
Note for traditional startup folks: the lack of team growth may seem like an obvious signal of low performance. Fwiw - we're entirely self-funded and our revenue has grown by nearly 5x and total staff by 3-4x during that time.
From a career/skill growth perspective, I often wonder how being on my little island nets out against joining a larger elite team.
I've no doubt developed idiosyncrasies but I've also directly or collaboratively coded, designed, deployed, and promoted every piece of software, including several web products from scratch, that have been foundational to our success since the first year the company existed.
I really have no idea how to compare that experience with being a cog in a massive machine but surrounded by brilliant work and brilliant people I could learn from.
Big Tech is more consistent and structured, while startups are sink or swim. I've seen people come in as Principal Engineers after building the entire product of a successful startup. But that happened because they joined a rocket ship as an early engineer, which is the programmer's equivalent of winning the lottery.
So if you can join a rocket ship by all means do it. Otherwise Big Tech is generally a safe bet.
Most "Big Tech companies" are already structured internally as small teams with wide responsibilities, which imclude owning multiple projects and with it everything required to develop and deploy them.
If anything, "Big Tech companies" have enough resources available to allow developers to work without bothering with distractions.
So then if you need to meet someone, you contact them and schedule that meeting. If the project requires custom designs, you write that design doc. And if they add more engineers to the project, it is your job to get them up to speed and assign parts of the project to them so they can be productive. Basically, your job is to ensure things gets done.
For example one of my previous companies was very top down, siloed and hierarchical. One time I went to talk with a PM from a different team about the prioritization of certain customer features, and my boss got really pissed off. He told me I should never talk directly with anyone and should always communicate via him. This was also the kind of place where new ideas were shut down and opposing the main point of view could get you in trouble.
What about the opposite, people who have the environment but not the mindset? Some might coast years in big tech actively refusing to learn, but it is rare. Most often they will be put in situations that make them uncomfortable and will choose to leave (reorgs are common). Other times their performance will simply suffer if they aren't able to keep up with the team.
ps: thanks for the nice suggestions folks :)
Another option is to use the LC problems as a test bed for your own exploration and "play" with solving problems. For example, I'm a nerd for optimizing algorithms and for practicing Java-style (not Smalltalk-style) object-oriented programming (OOP). So sometimes I'll find a way to optimize the LC problem in an interesting way. Or I'll deliberately use an OOP approach. Here are a few examples from the past week of me doing things like this on LC. Maybe it'll inspire you to hone your own particular interests in some way.
https://leetcode.com/problems/search-a-2d-matrix/discuss/197...
https://leetcode.com/problems/find-the-distance-value-betwee...
https://leetcode.com/problems/count-sub-islands/discuss/1974...
Then in his bio... Shopify / Royal Academy of Engineering Research Chair in Language Engineering.
I guess we have wildly differing opinions on what is considered rather limited talent.
But I don't want to downplay the blogpost by nitpicking here, his main point still stands.
But that second group can be ultimately more successful because they've learnt how to learn, the natural learner has no idea what they should do when it doesn't just click.
He also describes how it might look like some musicians can do magic effortlessly, but recognizes that it is based on training. And the same is true for software.
It is incredibly difficult to judge "natural" talent. The skill level can be judged, but the amount of prior experience cannot. It is always self-reported, or just estimated. Total time spent and the age at wich the first line of code was written is probably extremely high/low respectively for people considered talented.
The average SaaS engineering job is akin to recording a different concert for several hours every day, with no time to tune your instruments and little investment to fix or replace them.
Even if the orchestra is out of tune, the conductor won't necessarily notice or care because his job is not to actually conduct the orchestra. In fact, he doesn't understand music, he just knows how to request and deliver recordings. At times he pretends to understand music, which mostly involves flailing his arms spastically while musicians do their best at not minding him.
After 8 hours where only a couple were actually spent playing and the rest were spent arguing and debating how to play music with the conductor and the audience, musicians are left exhausted, with no energy to improve their skills.
I share your frustration on feature pressure with no official room for practice and refactoring however the metaphor about the role of a conductor is completely off. A conductor knows and understands music, deeply, a d they connect the dots and coordinate the orchestra and zoom into lots of little details while improving the big picture.
There's none of what I call "atomic time regions" where once you start, everything has to be right or the whole thing is considered a failure(Think of calligraphy and how one bad move can ruin a piece).
Instead there's just a small amount of base knowledge every coder needs, plus vague familiarity with frameworks, and a general sense of what will possibly screw you over later(Anyone can write most programs that don't involve novel math or algorithms, the challenge is in making them not screw you over somehow).
If a world champion level programmer makes a basic app in Vue, it will maybe be 20% better than mine, because... modern programming is all about providing obviously ways to do common things. There's not much variation possibly in something so completely technical.
If we both design 100kloc apps, his(hers?) will be a lot better. There design choices in that kind of thing that don't come up at all in a 1 day project.
Sports people say you play how you practice, right? So there's only one kind of technical practice I care about. The kind that is similar to production code. Either in scope and scale, or depth of crazy algorithmic math, or any other way, but if it doesn't replicate production... is it really practice?
Guitar plays have a concept called "Noodling", defined as playing guitar... but not really playing something. It might sound OK, but you can kind of feel that it's not really helping you towards being able to play that song you want to play, the way you actually want to play it.
It's widely considered not really practice. Almost like scrolling Facebook compared to reading a book, like I should be doing instead of scrolling Hacker News....
I don't make any effort to practice programming unless I want to learn a specific new technology.
I just do projects that I think are worth doing, and resemble the stuff I want to do in the future, and I try to do them well without hackery.
Generally outside of work hours I'll throw together a vague example and validate that the idea is something that works and get vaguely familiar with the libraries involved. That way when I go to build it at work I don't start from zero. If its for a personal project i just noodle in a repl or ide on a branch
Yes, I also think the experienced ones will have a 20% better code in every aspect that compounds with the development time.
> If we both design 100kloc apps, his(hers?) will be a lot better. There design choices in that kind of thing that don't come up at all in a 1 day project
Absolutely! What I believe is this design decision is the result of practice and experience.
> Instead there's just a small amount of base knowledge every coder needs, plus vague familiarity with frameworks, and a general sense of what will possibly screw you over later
Proposing that programmer needs only a small amount of base knowledge is a bit spicy proposal.
The reasons:
1. It undermines the actual result of having large knowledge base and familiarity with everything around computation. Sure, there may be limited concepts, but there are so many details behind these concepts. Think about it, there may be some historic reason to do certain ways of things. There may be fundamental concepts based on some rigorous proofs and maths. Or there may even be something so crucial that is yet to be discovered.
2. It's just that if we do something that doesn't involve these overall knowledge, doesn't mean the requirement is small. There is a lot of ways to do things and everything is dependent on problem at hand.
3. The rigidity and small base knowledge might have been the result to maintain a code base. But anyone who is careful enough, will definitely have large base knowledge at their disposal.
What are your thoughts on this? ;)
But I think the knowledge is "Distributed" differently, and it such a way that most of it is best learned by real world projects(Or toy ones that are similar to them) rather than the kind of practice musicians do.
Practice and experience is definitely valuable, but I'm not sure if the stuff programmers advocate(A constant flow of new small projects) is the best way.
The first thing programmers learn is the base concepts like variables, objects, and whatever other building blocks are considered atomic at the level you are working.
No real need to practice that much. It's deliberately kept small in most schools of thought, and many concepts can be learned in literally minutes.
I don't see much value in practice that only teaches this level, once you know what a class is. Plus, you use this stuff constantly. Sure, if you hear of a new base concept it's worth taking time to learn, but we don't need to take a class in "What a variable do" once we understand.
Slightly past that is just basic debugging in "regular code"(As opposed to the kind of code with algorithms you might consult a textbook about)
I don't know many who write things first try. So if you are coding wt all, you're probably getting your practice in for this.
Then there's algorithms. There's more of these than you have time to learn, so you'll need some kind of.... algorithm for choosing.
Working on any of these is going to help your general algorithmic ability, if you're doing something with novel algorithms. But the real hard part is often in the math, so if you want to focus on being really good at this, I would imagine that you also want to spend just as much time studying math and comp sci.
Plus, this is only one part of programming. Some toy weekend projects do seem like they'd teach this, others don't. Particularly automation stuff.
Then there's edge cases, one of my favorite subjects. I don't think anything random and throwaway shows you this. Automation projects might help a bit, but the real hard parts often only show up when something runs for two weeks and a server goes down at just the wrong time and some data gets out of sync.
The usual "Just find reasons to throw stuff together and make some ad hoc scripts every chance you get" doesn't really seem to help you practice thinking through obscure failure modes. SD card wear, unset system clocks, user error, etc don't come up a lot in 30 lines of Python always run manually. Your app works now... but if I run it without root, will it make half finished changes and lose data?
And then finally there's architecture. 100 line scripts don't have that much, and they certainly don't need things like plugins.
Nobody agrees on this. We fight over when to do microservices or monoliths. It involves making APIs that other programmers don't want to punch you for. As much art as science, unless someone figures out the One Final Best Practice.
I don't see how anything except projects big enough to need an architecture will teach this.
There's also low power, web scale, high security, and all kinds of other specific stuff.
In every other discipline, practice is supposed to push your limits, expose you to new things, resemble the "real thing", or just refresh your memory of fundamentals.
But the whole "10110100100 code program everyday" movement only focuses on the last one.
Coding for relaxation is fine, but I don't feel that I would learn all the things I want to learn particularly efficiently by fussing with some suckless app source code on a weekend.
Plus, there are only 24 hours a day, and people who code so much there's no room for anything else... are often insufferably boring and lack an appreciation for anything with no screen.
And of course the Digital Ankleweight effect. If you use a lot of DIY tools you have to maintain, it can... really take a lot of time on a constant basis. It's pretty freeing to use more standard tools and just... not have to worry about it. It's like what minimalists are trying to go for, but more effective, because you're directly going after stuff that actively hassles you not just the abstract "complexity" minimalists hate.
I'm all for continued education, it's the "Code noodling" without any real specific thought to what exactly it's meant to teach you, that I have doubts about.
I think practicing specific things you have considered and decided you want to learn, plus longer term projects and open source contribution, might be a lot more helpful than a lot of what people do.
A lot of great stuff happens in weekend projects, and also some mediocre stuff.
At my last job, I learned a lot more and could rely on more seasoned advice. It is something that I definitely miss, but we plan to hire soon, so I won't be alone forever :)
I liked this, but then they went on about automating their workflow (which is a great application of skills. They are correct).
It's just that I don't have a workflow that really benefits from automation. Whenever I introduce scripting and automation, I usually end up with concrete galoshes[0], and nothing is really gained. My automation is generally a run of SwiftLint, before compiling. I also automate Jazzy doc building. Other than that, I tend to be pretty manual, even for large projects, with repeated releases.
What I do, is ship often, and write Swift every day. I've been writing Swift every day for the last few years. I probably passed the "10,000 hours" mark, at least a couple of years ago. My GH ID Activity Graph[1] is solid green, and it's not "gamed," like so many people do with theirs.
I just write a lot of code; every single day.
I also like to ship stuff. That means actually doing what is necessary to move it out into the world. Push it out of the nest, so to speak. Lots of "boring" stuff, involved with that.
But I have found, that if you do it all the time, it basically becomes "muscle memory." When folks look at the code I write, they assume that I'm a slow, plodding programmer, because of all the structure and code docs.
Nothing could be farther from the truth. I write a lot of really high-Quality code; very quickly.
It's just habit.
[0] https://littlegreenviper.com/miscellany/concrete-galoshes/
Now that I'm full time at a start up, I've learned so much in the past year, not just about programming, but more about design, testing, tradeoffs, business, and DevOps.
The amount of skills a software engineer needs is much less of just programming than I thought. So many soft skills involved, so much design, so much practice and iteration.
It's absolutely amazing to see how much there is to learn. I can't see myself at that retail company again, just because everything was slow. They had very stable services and ops, no doubt, but since there was already a group of people to handle that task, I never learned it. At a start up, I need to do everything, and I love it so far.
That said, I can see it becoming overbearing at a certain point and wanting that slow down eventually, but I'll play it by ear.
It's a great industry to be a part of, and as a young developer, it's a very exciting future.