I've been into writing and running software for quite a while now, and as I see a bunch of articles and writings out here providing inspiring hints on what (not) to do to become a good or even better developer, thought I'd just chime in and share some of my insights on that subject. These are things I'd like to see in aspiring developers working in my team, too. Here we go:
No matter how good you are at mastering framework X or language Y: Learn to focus on problems you want to solve rather than solutions at hand. Otherwise you're in for the Golden Hammer: If you put your solution ideas first, you sooner or later will end up looking at your problem with the solution in mind, and you will always tend to judge whether you can solve a problem by how well your "familiar" solution works here. So, here: Try to talk to "business" people (those who want their problems solved) often, try to listen, try to understand what they need. Eventually help them get their requirements straight. Don't throw in solution ideas too quickly.
Successor to "problems first" and "Golden Hammer": Yes it is important to have solid skills in a bunch of tools in order to get work done quickly and in a high quality. But just the same way you should have a vague idea of a whole load of different architectural and technical approaches, frameworks, concepts, solution methods.
I had an interesting experience in that a few years ago when working on performance issues in our environment with a database consultant. That's when he looked all across the list of open connections on the system, wondered they all were coming from the same IP - until eventually ending like "ah ok, that's some sort of application server then." I both felt completely dumb and was greatly enlightened in course of the conversation that followed, mostly because in my world back then, hiding RDBMS and other means of persistency behind an application server facade was so incredibly common that the "obvious" thing at least for a local use cases (build a desktop application that connects to the database directly) was completely out of sight. It wouldn't have been absolutely "better" or "worse" - we didn't even think of evaluating this.
A similar thing I end up seeing these days with services using HTTP (and JSON) for communication excessively. That's when, sometimes in applications, I see dedicated routes or query params for downloading binary files if necessary. The "obvious" and HTTP'ish solution (using a different content-type and content-negotiaton) just rarely happens.
Some problems are likely to be solved easier with different solutions, different ways of thinking, different approaches to implementation. Try to search for good solutions from a conceptual point of view. Try to realize when you start putting your "comfortable" solution approach first, and try to question that in these situations.
So, to cut this short: In your learning efforts, you should spend some time on browsing what's going on in the tech and development world, maybe listen to some podcasts and hack your way through five-minute-tutorials to get an idea of things even without dedication to completely master them or to have to use them in your next project. Think of a toolbox: You should have a mostly familiar set of tools around, plus you should have an idea of what tools are available off-the-shelf and how they generally work, knowing you'd be able to quickly learn how to use them well if needed.
There's complexity inherent to the problem you're trying to solve, and there's complexity arising from the tools you use trying to solve this. You won't change much about the first one - the problem is as complex as it is. But you possibly can change the second one by carefully choosing how much frameworks, how much runtime dependencies, how many mandatory configuration options you add to your components. Sure they can ease your development and make it faster for your to get your solution up and running, but in the long run you will have to handle these things all along the way each and every time you touch that module.
Even though straightforward coding is fun: Some fundamental understanding about things behind the code makes life easier and your code better. Yes it's nice to be able to read and write code in a bunch of languages, but even more it's important to know some basic concepts - a bunch of fundamental algorithms, some essentials about data structures, abstraction, things such as polymorphism or inheritance, recursion, not to forget about some design patterns... . Knowing a QuickSort implementation or a Singleton once you stumble across it will help you understanding both written code and overall system behaviour faster and better.
This, too, is a field where you might want to spend a bit more time learning as this knowledge usually is more re-usable if moving between different stacks and languages (even though, in example, some design patterns make more sense in some languages than in others...).
I'm pretty much rooted in a Java world where people are used to using fully-fledged powerful IDEs such as Eclipse or NetBeans to do their work. Personally I like this pretty much as it makes things easier indeed. Be careful, however, to see that these tools are made to ease repetitive, boring routine tasks for people who know what's going on and want to be faster by not having to do all these things manually over and over again. The very moment you use an IDE or a similar tool without understanding (or worse: without wanting to understand) what happens under the hood, you might end up in trouble faster than you like. The same goes for some batteries-included frameworks such as jhipster which get a load of boilerplate code and setup hassle out of your way but are absolutely sure to make you stumble if you don't have an understanding of what's inside and how these things go together.
I had quite some experiences both in research projects and in corporate development where prototypes and early versions of modules of course used to run in an IDE on a local developers notebook. In some of these cases, moving the application out of the IDE and to some dedicated production server turned messy because all of a sudden we used to have a wholly new level of complexity. Suddenly packaging of applications and dependencies was necessary. Suddenly we had to cope with the fact that an application required dependencies in "newer" versions than those provided by the application server so we needed to question runtime and deployment strategy for those. In some cases it was only after first deployment to an "external" server that we experienced access to resources local to the development machine hard-coded somewhere in the application sources. Now, presenting applications on a dedicated testing system (not on a developers laptop) is part of the teams Definition Of Done. So generally, making yourself ready to ship artifacts of your applications early is a good idea. It helps gathering fast feedback, and it helps making dependencies and runtime requirements obvious. And it helps avoiding the dreaded "works on my device" situation which is a good chance to get you into trouble after going live and experiencing issues because production environment is in an unknown way different to your development system. That's something easily to be prepared for, and so you should be.
Finally: Never fall for the misconception of mastering things, of knowing all or even just "pretty much". You never do. You'll always be a learner in every possible way. No matter how many development jobs and projects you went through, no matter how many tech stacks you have seen or how many business problems you have solved - there's always way more. There's absolutely no reason to think you don't have to learn anything else. You'll always be learning... in development, in technology, in life in general.
From a developers perspective, this is especially interesting as you grow older: You're likely to see more and younger people in your team while possibly, at the same time, moving forth a bit into some sort of "senior engineer" role. You will see young colleagues coming up with new and unfamiliar ideas. You will see new tools and frameworks arise (and fall, in some cases). You'll see new methods and processes come, stay and go. You'll see people trying things and possibly making the same mistake. Challenge these guys, but be open to what they say. Let them inspire you. Grow all along with each other a bit more.
Comments and inspirations welcome. I'm but a learner too. ;)
- esr's "How To Become A Hacker" -- something that shouldn't be taken all too seriously either but you should still read it at least once, a few points in there are pretty valid.
- Neal Stephensons "In The Beginning There Was The Command Line" -- more fiction than fact, this is an extremely interesting read on technology, technological progress, user interfaces, disputable metaphors and a bunch of other things.
- Google "Site Reliability Engineering" book online -- in a traditional sense this is not of relevance for developers, but still and also for developers there are some valid insights to be found here.
- Essential vs. accidential complexity
- It Works On My Machine -- entertaining article with some neat pointers on one of the fundamental "issues" between dev and ops