1. There is no substitute for the hours spent coding. Sure, you can waste a lot of time, but there's a high correlation between hours spent and skill attained.
2. You can do almost anything with almost any tool. The energy spent debating tools would probably be better spent building something.
3. One of the biggest differentiators between a good coder and a poser is the willingness and ability to go several levels down. Deep understanding comes from deep diving.
4. One of the best ways to deep dive is to benchmark. The milliseconds gained will be a byproduct. The real benefit is your understanding of what goes on under the hood.
5. Write a framework. You may never use it, but you'll never be the same programmer either.
6. Almost everything you do will take longer than you expect, no matter how experienced you get or how good you get at estimating. If it doesn't, then you're not taking on challenging enough work.
7. Once you regularly deliver great value to others, you will often feel like an imposter. The compliments will exceed what you think you deserve based upon how hard it was for you to build. That's OK. Accept it and enjoy it. It's payback for all those hours you slaved away and no one knew what you were doing.
8. If you maintain a sense of wonder and delight every time you get something new working, you will probably never get burnt out. Don't let anyone tell you otherwise.
9. When you look at your old code, most of it will suck. That means you're always getting better. But some of it will still amaze you. Embrace and harness that energy. Try to recreate the conditions under which you wrote it.
10. Name your variables properly. That will always be half the battle.
Even the time wasted is valuable, and not just for racking up hours. Wasted time includes making mistakes, and once you've made a mistake then you've seen that mistake. This means that when you later see the results of that mistake, made by you or a colleague, you can quickly consider if it's that same mistake; often it is.
We've all asked someone for help about something weird, and that someone gives us an immediate suggestion. Chances are it's because they've made and seen that mistake in the past.
Cherish your bugs, and cherish your mistakes.
That's a byproduct of learning any craft. It is not the act of writing 20 lines of a script in 10 minutes to process that file that makes you amazing. It is the fact that you know what 20 lines to write.
11. Learn to read, navigate and understand code! Unless you are working alone (but even then) you will spend a lot of time "uploading" code to your brain. Code is read more than written.
12. Algorithms are not nearly as important as some people make it look like. I can't really remember if I ever wrote a sorting routine that is used in production and I am still waiting for the moment A* will be useful. And when that moment comes, I will just need to _read_ it on wikipedia.
Not even knowing it exists to google for, is a bit of a problem.
Knowing of 100 algos is more worthwhile than knowing everything about 1 algo.
If you struggle, bash your head against the problem, put in a lot of hours, and eventually produce something that works you may feel like you don't really understand what you're doing, that you only managed to produce something by brute force and luck (which may sometimes actually be true).
On the other hand, if you breeze through something and knock out a solution with little effort it may seem like you're not actually doing anything at all.
It's easy to undervalue knowledge and the difficulty of acquiring it. Just as it's easy to undervalue merely putting in the time and effort even when skills are underdeveloped. What ultimately matters is whether or not you were able to build something worthwhile that wouldn't have existed without your effort.
Re: #10, also use good commit messages. I find this harder with smaller commit increments such as with using git. Lately I've tried to avoid using "change" or "fix" as the first words in my commit messages.
I see users of a simple file parsing utility that took me an hour to write gushing over the amount of time it saves them every day and it just makes me feel good to be able to help someone with such little effort.
I'm reminded of the scene in Office Space where people are brought in an asked to describe what they do. That sort of thing is harder than one may think, it can be difficult to fully sum up how one works and in what ways one's skillset and expertise is valuable. For several years I had a job that was very difficult for me to describe to others succinctly. Mostly because it was hard to explain what I did if you didn't know many other details of the development process within the organization, some of them highly technical.
To use an analogy, it's a bit like asking why Beethoven is good music (without falling back on popularity). To express such things succinctly can be quite difficult, more so if you're put on the spot. Most people don't spend hours and hours thinking about how to justify the value of their own work, because that sort of thing can seem egotistical, more so if they already suffer from imposter syndrome. And without doing that when they put themselves on the spot they'll fall into the same trap of not having a good answer.
By the way, nice to see a post from you. It seems like it's been awhile.
(All that follows is my humble opinion, apply grain of salt and critique as needed)
Writing a framework for the first time is hard. You said you don't really know what happens server-side and this may get in your way. A framework is often designed to address specific problems/needs in a specific context.
These problems/needs don't have to be shared by anyone else, it could just be you thinking "It's hard to build RESTful urls, I should build something to do it for me" and have a CLI util or a script handler that would register them for you in your app server. And some can be everyday problems: "F*ckin' databases, how do they work?".
However, you need to know these problems to address them. Which is a part of my long-term feud with frameworks: "If you always use a framework, you will never have (too much) problems and will never learn how to solve them" (writing my own active-record-like ORM for node.js is a lot of fun actually).
Which is why my advice to you is: Don't write a framework.
Instead, write an app, get stuck a lot of times and find a way. Identify your problems. Then write a different app. This time, look at what you are doing the same way, what problems you are solving another way and what you'd like your framework to automate. There, for this second app, you can start writing your framework because you'll have a better idea of what you need to address.
You don't really need to make a framework that caters to everyone's needs, but one that caters to your needs and expand from there.
Next (optional) step is rewriting the first app with the second app's framework and iterate new functionalities.
When you start building bigger stuff, and your routes and controllers start looking crufty and ugly, and you start wishing you had more tools to keep everything organized, then pick up Rails.
I suppose you could try to hack together your own framework to give you a sense of what's involved. In Ruby this is done with Rack, it handles the HTTP requests and you can focus on the mid-level framework-y stuff. But seriously, Sinatra's what you'd eventually come up with, and it's already out there, so why not use it?
#8 is why I've been coding for years. There is always something new and interesting to do.
"8." is probably the hardest thing to explain to someone who hasn't been there.
There are a million resources for specifics, like doing a server redirect or creating a jump list for Windows Phone, but precious little on the end-to-end implementation semantics of, say, a smartphone app that syncs content to a server that scales out and up. Also, adding security, monitoring hooks, and exception and configuration management. The realisation that open standards are far, far more important than open source.
Similarly, the web is full of people telling you to use Mongo, but again hardly anything about being able to reference indexes in a document, or that partition tolerance and availability come at the expense of consistency.
Get these things right and suddenly even using GOTOs, or the differences between closed and open source, become non-issues because if your solution works, and is successful, any ciritics of such semantics can go to hell.
This made me chuckle. I recently designed an entirely new way of doing just that (to me, at least), and it's probably the 20th or more end-to-end approach I've developed over the last seven years on that specific problem.
I don't know why scalable sync interests me, but it does. :)
It's rare that you'll need to use pointers that much in C++ (compared to C where they're definitive and essential), and type casting is stricter in C++.
I also laughed a little at the Joel Spolsky bit. But overall, sound advice. It beats most of the empty fluff that the "learn to code" movement is producing.
"Braces should go on the next line. Braces should go on the same line. Use tabs to indent. But tabs are evil. You should use stored procedures, but actually you shouldn’t use them. You should always comment your code. But good code doesn’t need comments."
Work on an over-commented code base and come back and tell me commenting everything is good.
Work on a large crud app where it's 'SPs only' and come back and tell me SPs are good. Worse still that particular debate is dead. The parametrized queries not only won, they blew SPs out of the park with ORMs. Hence the articles linked are 7-8 years old. And yet I still come across the occasional programmer who uses SPs (who will generally think ORMs are evil rather than massive time savers).
As for commenting, new coders need to comment because they forget what they did. New programmers can't read code properly, they need help from comments. So it's good general advice to tell newbies to comment while they're learning. But not in production code.
New coders also tend to get a revelation when they go back to some of the first code they wrote and can't understand it. The revelation is 'I should have commented it all!'. But the revelation is false, there are two reasons they can't understand it. Firstly, it's crap code because it's their first code. Secondly, they can't read code properly. But they can't admit it to themselves because they think that now they're good coders.
I've seen this time and time again, programmers with less than 2 or 3 years experience often won't try to read the code and figure out the logic when something goes wrong. Be it their own code or a bug in someone else's they've been asked to fix. They start changing random variables or commenting out lines. And yet they honestly think they are good coders.
Many time I have sat down with them to help, read the code and then pointed at a line and said 'Hmmm, that looks wrong'. And that will be the bug. 5 min fix, if you can read code. It's just part of the learning process and now I'm older I can see the Dunning–Kruger effect as stupefyingly obvious in programmers. I don't begrudge it, I don't think they're stupid or unskilled, it's just a stage every programmer seems to need to go through. The stage where they still haven't realized they can actually read the code to figure out what it does.
What's funny is that I can see I suffered from it constantly in my early years and was a right arrogant idiot.
This is and always has been my problem. I like to look at what other people do, and I like coding in theory. But the little I need for myself isn't enough to keep pushing myself. I don't work anywhere near programming, and I don't particularly want to, either. Because of that, though, I haven't progressed very far into SICP, my finished Scheme programs can be counted on one hand, and most of my shell scripts are simple <1h (including looking things up) hack jobs.
I only really script for personal use, and my personal usage patterns are either not terribly demanding or too complex for me to satisfy.
I'm guessing you probably work in Windows because most people do at work; their shells are either too simplistic and awkward (cmd) or nuclear-capable (psh). Install cygwin and use the bash shell. Or do everything in Scheme/Racket and don't worry about a shell.
Automate something today, something almost too simple to automate. Repeat.
The thing is, I do have a script for example to push the current git project to various remote repositories or to create a new empty remote repository on those servers, set it up locally etc. But there are few other things that need to be scripted. I'm sure some of my things violate all kinds of sensible programming standards, but they do work (e.g. looping through shell arguments and then using case "$1" instead of using getopts, because it only allows long arguments in a hackish way).
The problem, essentially, is that of the plateau. If I wanted to do something that pushes things further, I'd need a real project, not the odd, occasional shell script. But for that, I lack the motivation, since, after all, it's not really what I should be doing. It's a bit of a circular problem.
edit: My "job" is studying literature.
I thought someone in your position might use regex fairly frequently.
When I came to start learning iOS development, I had a range of transferable skills and knowledge that I could call upon, for example I was comfortable with loops, declaring variables and manipulating/defining objects.
So I think while these courses won't take you from beginner to employable or experienced, they do serve their own purpose.
Determining when you're employable can be difficult (entry-level at Google vs. some LAMP web shop) and I'm sure that some portion of people trying these programs are looking to switch careers. I found it easy to get the notion that "If I learn through a bunch of courses and books and maybe do a few projects, I can put these languages on my resume and get hired". That, unfortunately, turned out to not be the case.
They also make the initial stages of learning to code 'fun' (I'm aware that's a highly subjective term however) when learning syntax, often without having grander goal in mind e.g. an app, can be a dry subject at best.
On your second point, are you referring specifically to people who complete these courses or people who teach themselves to code and build a few projects?
Someone will always tell you you’re doing it wrong
In my case, it wasn't that people were telling me I was doing it wrong, it's that I saw all these people asserting the Right Way to do things and I was so worried about doing it wrong that I would get bogged down worrying about tiny irrelevant problems. But in the end what people cared about most was getting things done, and usually didn't care as much about the methods as one would believe reading the web.
The most common traits of all the best code I've worked with is consistency and thoroughness.
First thing in any lang: learn the tools available for debugging and quickly opening library code to trace execution. Set breakpoints; dive into stack traces.
The point being, I think, that drawing this bright line at Turing completeness doesn't hold up when you give it any thought, and so it's not very useful. Aside from that, you've utterly missed the point of the OP.
>Implements a Turing machine in Java without using control structures, variable declarations, method definitions, or anonymous classes. The main2 method shows the code before I removed variables. Control structures are too controlling for this day and age. Us youth yearn for the unstructured hippie days of our parents' generations."
I like this guy's sense of humor :)