For me, I think absolutely. Sometimes to the point where I don't consider myself a 'real' programmer and feel like a faker any time I'm talking with someone more skilled than myself. I've always been much better at just getting things done than learning an entire catalog. Maybe it's because I spend half my time in the design space, where I also have no training and also feel like a 'faker'.
I've looked in various apprenticeships like thoughtbot's and others, but at my age (30) I am not their usual target demo.
It's why I'm so grateful for hackernews. i learn a lot of great stuff here from the 'real' developers that I can then apply in my day-to-day.
>Sometimes to the point where I don't consider myself a 'real' programmer and feel like a faker any time I'm talking with someone more skilled than myself.
interesting! As one of the top performers in my major as a senior, I think I self-inflict this a little bit to keep myself sharp / hungry. Kids call me crazy and say I've had all kinds of success, but I don't compare myself to the apathy I see around me and putting a chip on my shoulder compared to 'elite' devs has worked for me.
Privately I think most people have this but don't want to admit it because they think someone would call them out on it. From what I see/experience it seems like the world mostly runs on people trying to impress other people because that's the only validation for our own skills we get.
I sometimes feel the exact same way. I graduated with CS degree but have never used any of that knowledge until I got my current contracting gig - almost 11 years later.
During the first 10 years of my career, I used a language where I didn't have to "worry" about all of the kind of things I have to concern myself with now (using Java/MyBatis/Oracle).
I've always wondered what it was like using a "real" programming language and now I know - it can be tough but it's not terribly difficult. I love using the tools I've been reading so much about on various blogs and whatnot.
I just have to say that this post spoke to me. I've found things on this forum that have helped me tremendously at work. I have a minor in CS and I now work as a developer. I have been able to perform well at work, but I still feel inadequate for the job. I know some of the other developers do things better than I do, and I struggle to see how "I" am a Hacker. I really deem that a term for the elite in our field, and I don't think I'm there.
But I'm learning and I love learning and that's what I think is really important as a programmer. Some of the things in this post I knew about others, I'm going to have to research but at least it's easy to find useful help nowadays. Thank you Hacker News.
I consider myself a self-taught developer even though I hold a CS degree. The reason is, what is taught in college is not always up the standard required by the industry.
The only thing I learnt from college was the list of topics that needed to be studied. I spent time learning those things practically on my own.
That was the thing that helped me land a job immediately after college.
So I would say that a college CS degree is really a subjective, It depends on the person and the college.
Any self-taught developer who has the interest to improve him/her self can and will learn the foundations eventually.
My university's CS department had just enough "time" to skim over the big topics (one database class, really??) while we ran around trying to please non-CS profs in classes that weren't really necessary for me (two chem classes and physics).
I'm all for general knowledge, but if I need to know anything about chemistry (which I haven't yet in my role as a web dev), then I can go learn it, or change my major and focus on it.
The goal of a college education is to learn how to learn, so you can stop paying people to teach you. Becoming an independent learners isn't in spite of college, it is the goal.
If you are careful enough to learn the basics good and practice what you have learned, there is not really anything that can get in your way. So it depends on the person, but definitely working with more advanced developer can improve your learning curve. ;)
Software developers are concerned with making things "the right way" - eg. in the article the writer speaks about choosing the right data structure, algorithms etc.
Users couldn't care less about a perfect domain model, dependency injection or asynchronous yada yada.
They care if it works and Product Developers know this.
"Drivers don't care about different ways of reinforcing concrete or finite element modelling or yada yada, they just care if the bridge works."
If the users don't care, it's because they don't really understand why the software they pay for and put up with over the years becomes an unmaintainable nightmare...
No, but just because the users don't care (right now) doesn't mean it's not important. As a driver, I don't particularly care about bridge engineering, but I certainly want the people who build my bridges to care about it.
Imagine you have a web startup and as soon as people visiting your website start coming with reasonably large data sets, your website becomes noticeably sluggish.
And then a competitor pops up and they are dealing with the same sized data blazingly fast, instantly from the user's perspective.
And you look into it and they are using the same technology stack you are using.
It's at that point that you might start to care about the difference between a linked list and a hash table.
And at exactly that point (but rarely before), a good "product developer" puts on his "software developer" hat, and executes his finely-tuned JIT learning subroutine. He Googles "[framework] profiling", spends a week collecting information, tracks down the bottleneck, makes a fix, tests it, evaluates the new output, then calls it a day or repeats from step 1 until the issue is resolved.
Or a if you already know the difference you take a minute to look at the APIs you are using and switch to the one which is implemented with a hash table instead of a linked list. One minute vs. a week. A week here and a week there adds up.
Of course users care about page load time - scalability should be built in to an application from day one (I never said otherwise). Modern Paas services allow for this more or less out of the box so there's no excuse not to have scalability built in.
I've built apps that scale well (over 100 concurrent users) but have still never had to worry about whether to use a linked list or a hash table.
So in your vision a software developer is someone who creates "very correct" applications, while a product developer is someone who hacks an application that somehow works, with no clear model, no standards and patterns.
I would call your product developer a cowboy programmer. Been there, done that, after the cowboy leaves the result is a maintenance nightmare.
I didn't say that (good) product developers should employ bad practice in order to get something out the door.
I meant that product developers know when something is good enough (or "will do for now") whilst IMO software developers want to iterate and iterate to a perfect, elegant solution.
Don't get me wrong, the latter may be the correct choice to take but only when its for a feature that people are actually using.
From a business perspective, a software developer who is sitting on functionality thats "not quite right yet" is the cowboy programmer. But I guess thats just perspectives for ya :-)
I've been programming professionally for about 8 years, and I'm self-taught.
To be honest, I've found that my degree carrying co-workers fall way short in the basics. Perhaps it's just me, but my background in languages went something like this: GW-BASIC -> QBASIC -> ASM -> C -> C++ -> PHP -> JS --> Python -> Erlang -> Ruby -> C# -> Clojure. So for me, programming in C meant that I had to understand linked lists and sort algorithms.
I've sat in in interviews before and asked candidates (with degrees and experience) the difference between a dictionary, a hash-set and a list, and I just get blank stares.
So no, I think it's more about the desire to learn. If you have a true interest in Software Engineering, you'll teach these basics to yourself. If not, then not even college will help you.
I think most folks who truly master this stuff are self-taught, whether they went to University or not. I got all the degrees, but I can honestly say that I learned a lot more exploring on my own than I did sitting in class.
You're right. You probably won't need to take any courses to learn all this stuff - this stuff can be easily accessed online. It's definitely crucial for all software developers to have this sort of CS background.
Self-taught developer here, I think the foundation is incredibly important if you desire to advance in your career as a developer.
That being said, you don't need to know all that to get started. I probably would have hated a CS program if I had tried it in college. Now, however, I am completely fascinated by things that would have terrified me before.
There is a lot to be said for Just in Time learning as opposed to front-loading your knowledge Just in case you need it down the road.
Just In Time learning is perfectly fine, but there is a minimum of foundation for you to even realize there's something you need to learn. I think this article covers that pretty well.
You know, in years and years and years of programming, of applications and web and back-end and front-end etc etc, I have never had a real-life use case for Big-O notation, except in interviews. Nor had a real-life use case for caring about sort algorithms. I mean, not once.
I'd say the true foundation needed is entirely different. Avoiding spaghetti code, good refactoring practices, understanding when more architecture is needed, avoiding premature optimization or over-architecture, concepts like technical debt, writing code designed to be readable, how to establish practices and standards and make sure they're communicated properly... These are the kinds of things that actually matter in most projects.
(Obviously, if you're writing video codecs or kernel code, it's a whole different story...)
Okay, why do you use a hash table instead of a linked list when quick retrieval is more important than in-order traversals?
Now, it's pretty obvious when we're discussing something as simple as this, but this is the fundamental essence of Big O. Certainly, we don't need to calculate it on a daily basis, especially past the general case, but it also doesn't hurt to have common terminology when speaking about an edge case of an algorithm.
And just having a general feel of a graph of how quickly an O(n^2) algorithm can spiral out of control versus an O(log n) algorithm is useful. (That is, if you have a small amount of elements, it's not going to matter, but it will matter quickly as the number of elements grow.)
Eh, as a web programmer those certainly aren't a concern for me (and I hope this convo won't devolve into "web programmers aren't real programmers").
For both PHP and JS, there really isn't a difference; you're just given some basic data structures that handle pretty much everything under the sun, and you go from there. You can have an array with numeric keys (list), or you can have an array with string keys (dictionary), and it's only in your implementation that will determine if you use it as an iterative structure or as a kind of hash-lookup structure.
While PHP does have some advanced data structures provided by SPL, and some JS implementations offer typed arrays and such, they're rarely used in the wild for various reasons. I think the main reason, though, is probably that they're not really needed for 99.9% of web apps.
Well, I wouldn't phrase it that way, but it's not a fallacious argument.
If I were to rephrase, I would say, application developers aren't full stack developers.
Modern languages and frameworks hide a lot of complexity, allowing application developers to focus on business problems, which is a good thing.
But if you want to continue to grow as a programmer, and understand the tools you use, or use them to maximum efficiency, understanding things like Big-O analysis are crucial.
I don't often do complex "math" or analysis using Big-O... but understanding the core tenants are crucial, especially as you move from building apps to building frameworks themselves.
> you're just given some basic data structures that handle pretty much everything under the sun, and you go from there
This only works because the size of your n is small, possibly a few hundred, so it doesn't matter. When you start dealing with millions or billions of records this stuff matters. Quite a lot.
So really, it's not the language, it's the size of your data - or the size of n that matters.
Exactly, and how many web apps deal with millions of data points? Not many, as far as the view layer is concerned. Perhaps you'll have millions of rows in your DB, but you typically won't process all of those, at once, within PHP or JS. At least in my experience, most data processing on that scale happens in your OLAP layer (and thus is fully removed from the jurisdiction of PHP and JS).
Especially given single-page apps, you should never be dealing with millions of objects; with pagination and such, it's usually under a 1000 at a time, more typically 100 or so.
Perhaps the reason you have never had to think about it is because you developed a good foundation for reasoning about algorithm time complexity?
I will say that I have never personally had to concern myself with a sorting algorithm (though I can definitely think of areas where one would), but pretty much everything else I have learned about algorithms has been extremely useful both as "tools for thinking about problems" and actually making correct and practical choices.
Sorting algorithms are taught because they are such a fundamental operation AND they provide some good "easy" examples for how different approaches can give you dramatically different performance. Some lessons can only be learned by actually seeing it for yourself.
I completely agree. I very rarely catch myself saying "I wish the developer had understood the Big-O implications of this algorithm". I very often catch myself saying "I wish the developer would have realized that these 10 lines of code don't DO anything, and that this variable name is actively misleading." I find a very weak correlation between issues like the above and education levels. But maybe I'm biased. :)
Big-O is a foundation for all of those things you mentioned as a true foundation. Don't know the former, you are likely to get tripped up by the later.
I get the feeling from your post that you get this though. Because at some point you have to transcend your knowledge of Big-O, pattern languages, and go through those stages of being an Architecture Astronaut, second-syndrome, failing, failing better, and then maybe even succeeding in what you do.
Just an anecdotal experience, but yes, I did happen to say things like "this lookup is O(n^2), you should use some other structure here". It's useful when that conversation ends with an "OK", rather than a wide eyes stare...
It just takes less time when you can explain something using common terms, rather than starting with what complexity is.
However most unreasonable cases are much less subtle than that - I run into "filter in the database, not in the app" more often than more complicated issues.
> I did happen to say things like "this lookup is O(n^2), you should use some other structure here". It's useful when that conversation ends with an "OK", rather than a wide eyes stare...
If you'd have said "this lookup is very inefficient and slow" you wouldn't have had a wide eyed stare, and it would have had the same effect.
When was the last time you counted over 1000 objects by hand? You were taught this skill because understanding how to count arbitrarily high ingrains certain concepts. Even if you don't count high every day, that understanding was the foundation of more interesting skills.
I use the concept of Big-O notation, informally, almost every day. Almost every time I'm writing a new non-trivial method I ask myself, how will this scale to large values of n. Sure I don't sit down and formally prove anything and I rarely even spend a long time thinking about it. But knowing whether the function I'm about to write is O(n), O(n^2) or O(2^n) and understanding the implications of each is something I'd consider very fundamentally important.
I think this is just it though. You don't necessarily need to be able to sit down and formally write out the exact amortized big O complexity, (or little O, [O|o]mega or theta) but equally it's good to have some idea of how something would scale.
I feel like self taught developers who are serious just learn this by intuition because, frankly, if you're writing software where it matters then very quickly it becomes an obvious concern. If your self taught and it doesn't matter then it doesn't matter!
With a formal background you may or may not use it, but I'd say the only difference is knowing the formal notation makes talking about it with other programmers who also know that notation easier, but even then it's not like algorithmic complexity is (at it's heart) at particularly difficult concept when directly applied to a project. I always found it much harder as an abstract idea rather than when working with a specific algorithm.
You don't necessarily need to be able to sit down and formally write out the exact amortized big O complexity, (or little O, [O|o]mega or theta) but equally it's good to have some idea of how something would scale.
If you have a good idea of how things scale, being able to express exactly how they scale with succinct and clear notation is useful. Quite useful in fact.
That's why formal notation exists, because it is handy. Not because there is an eternal, global conspiracy among academics to keep up useless habits just to show off.
You're confusing wisdom and knowledge. Data structures and Big-O are mostly knowledge. It's stuff that can be transmitted from one person to another in form of cold, hard facts.
Avoiding spaghetti code, good refactoring practices, understanding when more architecture is needed -- all that stuff involves knowledge a lot less than wisdom. Sure, you can teach someone the basic principles, but until they've been bitten by some of the problems those principles try to solve, they won't truly know how to apply them.
The same can be said for algorithms and data structures: until you actually find yourself in a situation where you need finger trees because no other data structure fits your usage, you won't really know why finger trees are necessary and when to apply them. But the rules are a lot more clear-cut than when it comes to best practices.
Bottom line: both "computer sciencey stuff" (e.g. algorithms and data structures) and "best practices" (e.g. writing readable code and understanding when you need more architecture) can be learned and both require a degree of "wisdom" to apply, but the latter is a lot less clear-cut and has a lot more "maybes" in it.
Oh, and writing web stuff is not the only kind of work outside video codecs or kernel code. You could also be processing huge amounts of data, writing your own programming language or developing a game, for example.
The distinction between wisdom and knowledge is good. Personally, I don't even see the point of SW engineering in college; it's too much wisdom & experience based.
Also - I use the computer science conceptual framework every day. I lacked it - and badly - when I was a self-taught teenager soaking up as much online as I could.
I have... a method using contains() on a list vs a HashSet(). In one instance the O(n) caused the method to run in 20-30 seconds. The O(1) ran in milliseconds. Just simple stuff like that can kill you if you don't have a basic foundation of knowledge.
I have never had a real-life use case for Big-O notation, except in interviews. Nor had a real-life use case for caring about sort algorithms. I mean, not once.
That is frightening. I can't think of any function I write without taking a second to think about what the Big-O would be.
And I don't even know how I could do things like parse input without knowing how to structure it so that look-ups never take more than log N time. And I don't know how I could do that without knowing sorting algorithms intimately.
And I am not writing codecs or kernel code, mostly it has been high performance and some soft real time, but I've also worked in back end web development.
Everything in your second paragraph I fully endorse, but your first paragraph is terrifying. I'm terrified I'll run into someone like you some day, clearly smart, clearly experienced and without a clue as to why I'm concerned about the Big-O of his implementation of something.
>someone like you ... without a clue as to why I'm concerned about the Big-O
Except that's not what he said. He clearly does have a clue, he just hasn't actually needed it. And for application development, where most of the work is wiring together libraries, that's sounds about right.
Everyone writing code for a living has internalized when to use a map vs a vector. If that is the bar for "fundamental", then this whole discussion is pointless.
Some people know the computational complexity of something they write without knowing it in terms of Big O. Before my CS degree, I understood that looping through a list and for each item, looping through the same list again was not optimal. And someone only needs to write an O(n^3) algorithm once to realize that it's a very bad idea for any but the smallest amounts of data. Knowing about Big O is nice though, if only to understand documentation (realizing that O(nlogn) is better than O(n^2)).
I don't think he formally uses big-O but understands if something he is writing is linear (iterating over an array), exponential or O(1).
People have to get rid of their big hard on for Big-O, a useful concept that takes a couple hours to learn. It isn't a difficult thing that only the true macho programmers can know. I'd wish it was traditionally in starting programming books in the 'optimization & profiling' chapter and we wouldn't be having big fights about it.
The 'foundation' as you use it changes greatly depending on what you use programs to do. If you are working on a user interface over a very simple problem, then design principles and maintanable code are critical.
If you are working on data analysis, than Big-O type basics become more important.
The point of having 'foundations', is that when you go to do almost a type of problem that you normally do not, such as CPU intensive data crunching, you know where to look for the information.
As a self-taught programmer who started in the '80s, I definitely missed a lot of foundation I had to pick up over the years. However, this was mostly on the architectural level. As far as the more technical stuff is concerned, I was lucky enough to start with C at a time where we still had to code a lot of stuff by hand which is now taken for granted.
But realistically, this knowledge is rarely needed in most modern day application-level programming. Many decent developers can not only get by, but produce great applications without it. It's mostly a matter of the right skills for the right job. And as always, just getting stuff done is the #1 skill.
Agree. A lot of us self taught developers get started because there may be something simple we want to do that requires a program, and can hack or reverse engineer our way through it. But if/when we progress past hacks to actually building applications, it becomes obvious (to the ones who care) where a good understanding of the foundation is crucial.
The part about dismissing boolean logic really rang true.
I'm a (mostly) self taught developer but I have taken some software related courses (assembly, C, data structures), so I have some semblance of a foundation. Still, I constantly feel 'behind' in my foundational knowledge compared to my peers because I majored in something other than CS/SWE.
That's why the rise of edtech startups have been of interest to me: online courses like Algorithms: Design and Analysis from Coursera have been a godsend, at least when I have the time and energy to do it. It's not easy playing catchup with a full-time job, but there's even less time (and money) for me to go back and get a degree in CS.
"but there's even less time (and money) for me to go back and get a degree in CS."
It seems like many don't understand that not having pursued a CS degree is often a pragmatic one dealing with money, not because self-taught people are too lazy or unwilling to learn at a university level.
They have already obtained their degree and invested a lot of time and money. Or they're far enough along in life where they're giving up a lot more than a teenager or person in their early 20s if they take 4 years off to pursue a degree full-time.
I think these are articles are useful for people who are learning on their own, or who come from that direction. But if you're starting out at a self-taught person, from my experience, no one seems to care if you understand algorithms. You're better off building real things, and it doesn't seem close.
no we don't, when I started programming in high school in my late i had a copy of the dragon book that a RE friend told me about.
ops question would be better addressed if it addressed it's audience correctly:
"Self-Taught Web-Developers: Are You Missing Your Foundation" - and again the answer would be no. Since it's essentially a form of text processing we're talking about. Entirely different audience/target/whatever.
There's also many many many algorithms books around these days. The average web developer doesn't read them, and why would he?
Long story short:
Any headline which ends in a question mark can be answered by the word 'no'".
What stops a self taught developer from also 'self teaching' the fundamentals?
Books and lectures (from OCW etc) have been available for years now. These days you can go one step further by taking online courses with assignments, exams etc from Coursera. All you need is motivation, and self taught devs often have that in spades.
The real problem is that in most enterprise swshops/codebases, knowing (say) algorithmic complexity is not very valued in terms of reward structure (though it should be - I've fixed my share of O(k^n) horrors) and lots of people choose to go through life writing simple apps and stitching APIs together (which is perfectly ok as a career choice if that's what floats your boat).
(Due Disclosure: I worked as an enterprise dev for a decade before I shifted fields. I work on fairly large machine learning systems these days and let me assure you that knowing algorithmic complexity analysis - and other things like statistics and linear algebra - is a basic required skill in this world. Fwiw I am entirely self taught. My degree is in Industrial Engineering)
I think what stops them is motivation and a realization that the information can be really valuable when reasoning about software.
Certainly I am making up for a deficiency of math during my early years now. I always dismissed all category theory as useless but increasingly I realize how important statistics, category theory, and a solid understanding of how to analyze algorithms is. Even if you never prove the time complexity of an algorithm, being able to approach new literature and come out with new insights for your engineering efforts is invaluable.
Which is what any civil or mechanical engineer could have told you about their career, I guess.
> What stops a self taught developer from also 'self teaching' the fundamentals?
I think that the main problem, especially for maintaining the student's motivation, is that a lot of the fundamentals don't seem to be all that useful to a programmer... until you finally understand them and it "clicks".
The more serious topics(set theory, algorithm design, and processor design) are almost entirely theoretical at the basic level, with very little information that can be directly applied to the real world. But once you start digging deeper, the usefulness becomes readily apparent.
Algorithms is an especially problematic topic, for a couple of reasons. The first is that the entire topic is built on top of a good foundation of discrete math, big-O, set and graph theory, and with a sprinkling of data structures on the side. So it's no a topic that you can just jump into immediately. There's a lot of background study needed before you can really start working on it.
The second is that to really understand an algorithm, you really need to be able to make(or understand) the proof of correctness and proof of efficiency. The goal of the student looking into algorithms shouldn't be just to get a laundry list of potential things to use(though they will get that as well), but to have the skills to be able to show that their algorithm will work correctly for all valid inputs, and that it's capable of doing so at a certain efficiency. That's the mindset of a good programmer, and it definitely comes with experience, but I think having the theoretical background helps a lot as well.
Self teaching fundamentals is boring and not sexy. I'm self taught and I'll admit it took me a year of doing the fun stuff before I forced myself to go back and start to really understand the fundamentals of what I was doing. Turns out I now enjoy what I used to think was boring.
For me, I've learned what I've needed to learn to solve immediate problems that I was facing -- more like JIT learning. As such, there's many concepts that I simply haven't had a pressing need to learn and personal curiosities aside, they won't get learned.
> Why would I care about the difference between a list and a hash table.
> A lot of people tend to assume hostile bias against knowledge simply because they've been successful without it for a while.
I don't necessarily see it like that. My opinion is more along these lines:
> Why would I care TO STORE IN LONG TERM MEMORY the difference between a list and a hash table.
There are plenty of things I know I know, things I know I don't know and things I don't know I don't know. The vast majority of my programming knowledge resides in short-term memory; in six months ask me about Linked Lists vs Array Lists and I will have forgotten the primary differences (fast iterate vs fast insert or something like that)... I only vaguely know that today because I was researching something.
The biggest challenge I see as a self-taught developer is I see everything on equal footing. That means the basics (map, set, list) and the trivial (apache config settings, tomcat's web.xml) tend to reside in the same heap and if I don't think about one element for awhile it tends to get GC'ed. Since all of my knowledge came from 14 years of on-the-job-training nothing was given particular precedence, everything was important to the task at hand.
I believe that's really what frustrates self-taught developers. It isn't that I don't know the answer, or that I'm hostile to learning new things (far from it) it is simply that I never burned these fundamentals into my permament memory. I've tried, but I tend to miss bits and pieces, for example, I needed to refresh myself on autoboxing just a few weeks ago because I just haven't _thought_ about it.
I'm about 90% self-taught, including the foundation. To be honest, university is a waste of time for me. When I learn by myself, it's about 10x faster and more effective. What is most important is experience and practical knowledge. The good thing about university is that 1) I have lots of time 2) I find out about stuff like boolean function minimization or state machines.
At first I found the article kind of condescending. I was expecting something I didn't know, instead:
>hey self-taught developers, here's all this totally elementary stuff that you probably don't know.
I'm self taught, but I have a very solid computer science foundation because I found that stuff interesting when I was learning. Looking at the other comments here, I guess that's not the default...
We're in the same happy boat. I think there are probably more in it, too, but a lot of us have stopped thinking of ourselves as self-taught, because we've been working at a higher level for a while. I'd bet that those who are less interested in fundamental topics have shorter lifespans in the profession.
In this context self-taught obviously means: didn't pursue computers in secondary education. I've learned way more about development post college, but I wouldn't call myself "self taught."
Having a "formal" CS education, the only thing that keeps me current, relevant, is being perpetually self-taught and self-directed.
Having and building this discipline is the single master skill that unlocks everything else.
As soon as we think we're done, arrived, or have a "foundation", we're dead. What we know today will be relevant in a different way tomorrow.
It's true there are intangible skills like design, usability and architecture, but it only comes from building lots of small and larger software projects, not in the classroom, textbooks, projects, or theories.
Algorithms are important, but I contest that the majority of web/mobile apps don't even come close to needing premature optimization.
I wouldn't think twice at hiring someone who's self-taught and self-directed over someone with a CS degree.
Why? Self-taught people seem to have more of a track record of things they've built, instead of school projects on a resume. Self-taught programmers also tend to like to build things customers like and focus on the customer a lot more instead of optimizing their own world and tools.
I would definitely argue that the only thing that gets in the way of my learning is my "education"
One handicap my CS education gave me until I realized it was the "start fresh" syndrome. In CS you start pretty much everything from scratch, and think that's normal. Get into the post-graduate world and scrapping existing codebases isn't exactly normal, nor is always starting from scratch.
I don't see your example as a trap a self-taught developer would fall into. The non-usage of enumerate just indicates that it is a code from some one who has started with python and any self taught developer who groks pydocs would eventually discover enumerate.
I think most developers are self-taught. Those college classes were okay for comp sci theory perhaps. But for accomplishing real world tasks, I think I got more from books and the internet and actual knowledge, than paying for a course.
I'm somewhat "self-taught". I majored in straightforward "pure" math, with emphasis on real analysis and abstract algebra, but I did take graph theory, numerical analysis, and so forth - and the professors did include a lab component that involved writing substantial amounts of code... so I'm not completely self-taught.
That said, I feel that there is a gap because I didn't major in CS.
Although I had to read a textbook on Data Structures and Algorithms on my own, I don't feel like this is a particularly glaring gap. Interestingly, my math coursework did cover a lot of the stuff at the end of the algorithms book, since I'd taken graph theory, linear and non-linear optimization, numerical analysis. But I had to learn the basic data structures (trees, hashes, lists) on my own. While it took some work to learn this, it came naturally enough, because I consider data structures and algorithms to be very similar to math. You could study this stuff without a computer and get a decent understanding of it.
The big gap in my knowledge is more around compilers, operating systems, and that elusive border between software and hardware. I never took compiler design, and I think that languages are still a dark art to me because of it. I think I also would have benefitted from doing some very low level programming (when I was in college, "C" was still considered a "high level" language, but at least I had to struggle with memory management). Also, a lot of data structures that are optimized to interact with memory or hardware are still pretty much a mystery to me. Obviously, without this knowledge, my understanding of operating systems is going to be pretty limited.
Right on the same page with you. Mathematician by training, programmer by youthful joy of building games and ELIZAs in QBasic, with some MATLAB/Python in college. Lucky both things caught my interest when they did, it's made breaking into Machine Learning awfully accessible as a post-university career.
A CS degree can differentiate you from someone who cargo-cults their way through a software project. Sure cargo-culting can make the plane land once in a while, but wouldn't you some day want to know why?
I started programming for a living before I got a CS degree. After I got the degree, the biggest difference I found (aside from the really cool knowledge I gained) was that I had a common language to use to talk to other people with CS degrees and an understanding of common methods that I used to take for granted.
Also, I appreciate the rigor behind a lot of CS fundamentals, and I believe I'm able to teach myself new CS-y things more easily and do my job better as a result. I don't think the CS degree is necessary, but I really really really believe it helps you in ways you may not realize until you get one.
Its a great question. I believe IMHO that ultimately it boils down to the application; does it require computer science, some deep scientific understanding, or does it require basic knowledge of a language? Are you writing real-time Bayesian Learning algorithms for use on big data feeds for example or a sign-up form for a web site? Do you need to have fine control over where data is placed in memory so you can optimize performance (C/C++...assembly even?) or do you not need to know anything at all about memory management - and don't want to? There is a raft of questions like this.
Self taught programmers can write well but may be missing some of the nuance for why things are done one way over another or maybe be missing some tricks that save a lot of time. These limitations can be overcome by somebody committed to writing good quality code.
109 comments
[ 4.1 ms ] story [ 164 ms ] threadI've looked in various apprenticeships like thoughtbot's and others, but at my age (30) I am not their usual target demo.
It's why I'm so grateful for hackernews. i learn a lot of great stuff here from the 'real' developers that I can then apply in my day-to-day.
http://en.wikipedia.org/wiki/Impostor_syndrome
http://www.inc.com/magazine/20060901/handson-leadership.html
During the first 10 years of my career, I used a language where I didn't have to "worry" about all of the kind of things I have to concern myself with now (using Java/MyBatis/Oracle).
I've always wondered what it was like using a "real" programming language and now I know - it can be tough but it's not terribly difficult. I love using the tools I've been reading so much about on various blogs and whatnot.
But I'm learning and I love learning and that's what I think is really important as a programmer. Some of the things in this post I knew about others, I'm going to have to research but at least it's easy to find useful help nowadays. Thank you Hacker News.
The only thing I learnt from college was the list of topics that needed to be studied. I spent time learning those things practically on my own.
That was the thing that helped me land a job immediately after college.
So I would say that a college CS degree is really a subjective, It depends on the person and the college.
Any self-taught developer who has the interest to improve him/her self can and will learn the foundations eventually.
My university's CS department had just enough "time" to skim over the big topics (one database class, really??) while we ran around trying to please non-CS profs in classes that weren't really necessary for me (two chem classes and physics).
I'm all for general knowledge, but if I need to know anything about chemistry (which I haven't yet in my role as a web dev), then I can go learn it, or change my major and focus on it.
Users couldn't care less about a perfect domain model, dependency injection or asynchronous yada yada.
They care if it works and Product Developers know this.
"Drivers don't care about different ways of reinforcing concrete or finite element modelling or yada yada, they just care if the bridge works."
If the users don't care, it's because they don't really understand why the software they pay for and put up with over the years becomes an unmaintainable nightmare...
And then a competitor pops up and they are dealing with the same sized data blazingly fast, instantly from the user's perspective.
And you look into it and they are using the same technology stack you are using.
It's at that point that you might start to care about the difference between a linked list and a hash table.
Of course users care about page load time - scalability should be built in to an application from day one (I never said otherwise). Modern Paas services allow for this more or less out of the box so there's no excuse not to have scalability built in.
I've built apps that scale well (over 100 concurrent users) but have still never had to worry about whether to use a linked list or a hash table.
I would call your product developer a cowboy programmer. Been there, done that, after the cowboy leaves the result is a maintenance nightmare.
I meant that product developers know when something is good enough (or "will do for now") whilst IMO software developers want to iterate and iterate to a perfect, elegant solution.
Don't get me wrong, the latter may be the correct choice to take but only when its for a feature that people are actually using.
From a business perspective, a software developer who is sitting on functionality thats "not quite right yet" is the cowboy programmer. But I guess thats just perspectives for ya :-)
To be honest, I've found that my degree carrying co-workers fall way short in the basics. Perhaps it's just me, but my background in languages went something like this: GW-BASIC -> QBASIC -> ASM -> C -> C++ -> PHP -> JS --> Python -> Erlang -> Ruby -> C# -> Clojure. So for me, programming in C meant that I had to understand linked lists and sort algorithms.
I've sat in in interviews before and asked candidates (with degrees and experience) the difference between a dictionary, a hash-set and a list, and I just get blank stares.
So no, I think it's more about the desire to learn. If you have a true interest in Software Engineering, you'll teach these basics to yourself. If not, then not even college will help you.
I think most folks who truly master this stuff are self-taught, whether they went to University or not. I got all the degrees, but I can honestly say that I learned a lot more exploring on my own than I did sitting in class.
That being said, you don't need to know all that to get started. I probably would have hated a CS program if I had tried it in college. Now, however, I am completely fascinated by things that would have terrified me before.
There is a lot to be said for Just in Time learning as opposed to front-loading your knowledge Just in case you need it down the road.
I'd say the true foundation needed is entirely different. Avoiding spaghetti code, good refactoring practices, understanding when more architecture is needed, avoiding premature optimization or over-architecture, concepts like technical debt, writing code designed to be readable, how to establish practices and standards and make sure they're communicated properly... These are the kinds of things that actually matter in most projects.
(Obviously, if you're writing video codecs or kernel code, it's a whole different story...)
Now, it's pretty obvious when we're discussing something as simple as this, but this is the fundamental essence of Big O. Certainly, we don't need to calculate it on a daily basis, especially past the general case, but it also doesn't hurt to have common terminology when speaking about an edge case of an algorithm.
And just having a general feel of a graph of how quickly an O(n^2) algorithm can spiral out of control versus an O(log n) algorithm is useful. (That is, if you have a small amount of elements, it's not going to matter, but it will matter quickly as the number of elements grow.)
For both PHP and JS, there really isn't a difference; you're just given some basic data structures that handle pretty much everything under the sun, and you go from there. You can have an array with numeric keys (list), or you can have an array with string keys (dictionary), and it's only in your implementation that will determine if you use it as an iterative structure or as a kind of hash-lookup structure.
While PHP does have some advanced data structures provided by SPL, and some JS implementations offer typed arrays and such, they're rarely used in the wild for various reasons. I think the main reason, though, is probably that they're not really needed for 99.9% of web apps.
If I were to rephrase, I would say, application developers aren't full stack developers.
Modern languages and frameworks hide a lot of complexity, allowing application developers to focus on business problems, which is a good thing.
But if you want to continue to grow as a programmer, and understand the tools you use, or use them to maximum efficiency, understanding things like Big-O analysis are crucial.
I don't often do complex "math" or analysis using Big-O... but understanding the core tenants are crucial, especially as you move from building apps to building frameworks themselves.
This only works because the size of your n is small, possibly a few hundred, so it doesn't matter. When you start dealing with millions or billions of records this stuff matters. Quite a lot.
So really, it's not the language, it's the size of your data - or the size of n that matters.
Especially given single-page apps, you should never be dealing with millions of objects; with pagination and such, it's usually under a 1000 at a time, more typically 100 or so.
I will say that I have never personally had to concern myself with a sorting algorithm (though I can definitely think of areas where one would), but pretty much everything else I have learned about algorithms has been extremely useful both as "tools for thinking about problems" and actually making correct and practical choices.
Sorting algorithms are taught because they are such a fundamental operation AND they provide some good "easy" examples for how different approaches can give you dramatically different performance. Some lessons can only be learned by actually seeing it for yourself.
I get the feeling from your post that you get this though. Because at some point you have to transcend your knowledge of Big-O, pattern languages, and go through those stages of being an Architecture Astronaut, second-syndrome, failing, failing better, and then maybe even succeeding in what you do.
Then things begin to get interesting.
It just takes less time when you can explain something using common terms, rather than starting with what complexity is.
However most unreasonable cases are much less subtle than that - I run into "filter in the database, not in the app" more often than more complicated issues.
If you'd have said "this lookup is very inefficient and slow" you wouldn't have had a wide eyed stare, and it would have had the same effect.
I feel like self taught developers who are serious just learn this by intuition because, frankly, if you're writing software where it matters then very quickly it becomes an obvious concern. If your self taught and it doesn't matter then it doesn't matter!
With a formal background you may or may not use it, but I'd say the only difference is knowing the formal notation makes talking about it with other programmers who also know that notation easier, but even then it's not like algorithmic complexity is (at it's heart) at particularly difficult concept when directly applied to a project. I always found it much harder as an abstract idea rather than when working with a specific algorithm.
If you have a good idea of how things scale, being able to express exactly how they scale with succinct and clear notation is useful. Quite useful in fact.
That's why formal notation exists, because it is handy. Not because there is an eternal, global conspiracy among academics to keep up useless habits just to show off.
Avoiding spaghetti code, good refactoring practices, understanding when more architecture is needed -- all that stuff involves knowledge a lot less than wisdom. Sure, you can teach someone the basic principles, but until they've been bitten by some of the problems those principles try to solve, they won't truly know how to apply them.
The same can be said for algorithms and data structures: until you actually find yourself in a situation where you need finger trees because no other data structure fits your usage, you won't really know why finger trees are necessary and when to apply them. But the rules are a lot more clear-cut than when it comes to best practices.
Bottom line: both "computer sciencey stuff" (e.g. algorithms and data structures) and "best practices" (e.g. writing readable code and understanding when you need more architecture) can be learned and both require a degree of "wisdom" to apply, but the latter is a lot less clear-cut and has a lot more "maybes" in it.
Oh, and writing web stuff is not the only kind of work outside video codecs or kernel code. You could also be processing huge amounts of data, writing your own programming language or developing a game, for example.
Also - I use the computer science conceptual framework every day. I lacked it - and badly - when I was a self-taught teenager soaking up as much online as I could.
That is frightening. I can't think of any function I write without taking a second to think about what the Big-O would be.
And I don't even know how I could do things like parse input without knowing how to structure it so that look-ups never take more than log N time. And I don't know how I could do that without knowing sorting algorithms intimately.
And I am not writing codecs or kernel code, mostly it has been high performance and some soft real time, but I've also worked in back end web development.
Everything in your second paragraph I fully endorse, but your first paragraph is terrifying. I'm terrified I'll run into someone like you some day, clearly smart, clearly experienced and without a clue as to why I'm concerned about the Big-O of his implementation of something.
Except that's not what he said. He clearly does have a clue, he just hasn't actually needed it. And for application development, where most of the work is wiring together libraries, that's sounds about right.
Everyone writing code for a living has internalized when to use a map vs a vector. If that is the bar for "fundamental", then this whole discussion is pointless.
People have to get rid of their big hard on for Big-O, a useful concept that takes a couple hours to learn. It isn't a difficult thing that only the true macho programmers can know. I'd wish it was traditionally in starting programming books in the 'optimization & profiling' chapter and we wouldn't be having big fights about it.
If you are working on data analysis, than Big-O type basics become more important.
The point of having 'foundations', is that when you go to do almost a type of problem that you normally do not, such as CPU intensive data crunching, you know where to look for the information.
But realistically, this knowledge is rarely needed in most modern day application-level programming. Many decent developers can not only get by, but produce great applications without it. It's mostly a matter of the right skills for the right job. And as always, just getting stuff done is the #1 skill.
The part about dismissing boolean logic really rang true.
That's why the rise of edtech startups have been of interest to me: online courses like Algorithms: Design and Analysis from Coursera have been a godsend, at least when I have the time and energy to do it. It's not easy playing catchup with a full-time job, but there's even less time (and money) for me to go back and get a degree in CS.
It seems like many don't understand that not having pursued a CS degree is often a pragmatic one dealing with money, not because self-taught people are too lazy or unwilling to learn at a university level.
They have already obtained their degree and invested a lot of time and money. Or they're far enough along in life where they're giving up a lot more than a teenager or person in their early 20s if they take 4 years off to pursue a degree full-time.
I think these are articles are useful for people who are learning on their own, or who come from that direction. But if you're starting out at a self-taught person, from my experience, no one seems to care if you understand algorithms. You're better off building real things, and it doesn't seem close.
ops question would be better addressed if it addressed it's audience correctly:
"Self-Taught Web-Developers: Are You Missing Your Foundation" - and again the answer would be no. Since it's essentially a form of text processing we're talking about. Entirely different audience/target/whatever.
There's also many many many algorithms books around these days. The average web developer doesn't read them, and why would he?
Long story short:
Any headline which ends in a question mark can be answered by the word 'no'".
http://en.wikipedia.org/wiki/Betteridge%27s_Law_of_Headlines
Books and lectures (from OCW etc) have been available for years now. These days you can go one step further by taking online courses with assignments, exams etc from Coursera. All you need is motivation, and self taught devs often have that in spades.
The real problem is that in most enterprise swshops/codebases, knowing (say) algorithmic complexity is not very valued in terms of reward structure (though it should be - I've fixed my share of O(k^n) horrors) and lots of people choose to go through life writing simple apps and stitching APIs together (which is perfectly ok as a career choice if that's what floats your boat).
(Due Disclosure: I worked as an enterprise dev for a decade before I shifted fields. I work on fairly large machine learning systems these days and let me assure you that knowing algorithmic complexity analysis - and other things like statistics and linear algebra - is a basic required skill in this world. Fwiw I am entirely self taught. My degree is in Industrial Engineering)
Certainly I am making up for a deficiency of math during my early years now. I always dismissed all category theory as useless but increasingly I realize how important statistics, category theory, and a solid understanding of how to analyze algorithms is. Even if you never prove the time complexity of an algorithm, being able to approach new literature and come out with new insights for your engineering efforts is invaluable.
Which is what any civil or mechanical engineer could have told you about their career, I guess.
I think that the main problem, especially for maintaining the student's motivation, is that a lot of the fundamentals don't seem to be all that useful to a programmer... until you finally understand them and it "clicks".
The more serious topics(set theory, algorithm design, and processor design) are almost entirely theoretical at the basic level, with very little information that can be directly applied to the real world. But once you start digging deeper, the usefulness becomes readily apparent.
Algorithms is an especially problematic topic, for a couple of reasons. The first is that the entire topic is built on top of a good foundation of discrete math, big-O, set and graph theory, and with a sprinkling of data structures on the side. So it's no a topic that you can just jump into immediately. There's a lot of background study needed before you can really start working on it.
The second is that to really understand an algorithm, you really need to be able to make(or understand) the proof of correctness and proof of efficiency. The goal of the student looking into algorithms shouldn't be just to get a laundry list of potential things to use(though they will get that as well), but to have the skills to be able to show that their algorithm will work correctly for all valid inputs, and that it's capable of doing so at a certain efficiency. That's the mindset of a good programmer, and it definitely comes with experience, but I think having the theoretical background helps a lot as well.
I think this is a fairly common experience.
Just read through the many comments here the gist of which is: Why would I care about the difference between a list and a hash table.
A lot of people tend to assume hostile bias against knowledge simply because they've been successful without it for a while.
> A lot of people tend to assume hostile bias against knowledge simply because they've been successful without it for a while.
I don't necessarily see it like that. My opinion is more along these lines:
> Why would I care TO STORE IN LONG TERM MEMORY the difference between a list and a hash table.
There are plenty of things I know I know, things I know I don't know and things I don't know I don't know. The vast majority of my programming knowledge resides in short-term memory; in six months ask me about Linked Lists vs Array Lists and I will have forgotten the primary differences (fast iterate vs fast insert or something like that)... I only vaguely know that today because I was researching something.
The biggest challenge I see as a self-taught developer is I see everything on equal footing. That means the basics (map, set, list) and the trivial (apache config settings, tomcat's web.xml) tend to reside in the same heap and if I don't think about one element for awhile it tends to get GC'ed. Since all of my knowledge came from 14 years of on-the-job-training nothing was given particular precedence, everything was important to the task at hand.
I believe that's really what frustrates self-taught developers. It isn't that I don't know the answer, or that I'm hostile to learning new things (far from it) it is simply that I never burned these fundamentals into my permament memory. I've tried, but I tend to miss bits and pieces, for example, I needed to refresh myself on autoboxing just a few weeks ago because I just haven't _thought_ about it.
>hey self-taught developers, here's all this totally elementary stuff that you probably don't know.
I'm self taught, but I have a very solid computer science foundation because I found that stuff interesting when I was learning. Looking at the other comments here, I guess that's not the default...
You don't get taught anything (especially programming) you get out there and you fucking LEARN it!
Having and building this discipline is the single master skill that unlocks everything else.
As soon as we think we're done, arrived, or have a "foundation", we're dead. What we know today will be relevant in a different way tomorrow.
It's true there are intangible skills like design, usability and architecture, but it only comes from building lots of small and larger software projects, not in the classroom, textbooks, projects, or theories.
Algorithms are important, but I contest that the majority of web/mobile apps don't even come close to needing premature optimization.
I wouldn't think twice at hiring someone who's self-taught and self-directed over someone with a CS degree.
Why? Self-taught people seem to have more of a track record of things they've built, instead of school projects on a resume. Self-taught programmers also tend to like to build things customers like and focus on the customer a lot more instead of optimizing their own world and tools.
I would definitely argue that the only thing that gets in the way of my learning is my "education"
One handicap my CS education gave me until I realized it was the "start fresh" syndrome. In CS you start pretty much everything from scratch, and think that's normal. Get into the post-graduate world and scrapping existing codebases isn't exactly normal, nor is always starting from scratch.
Developers should know security
Developers should know testing
Developers should know the business
Developers should understand marketing and SEO
Developers should should should. Everybody's different. Do what you need to do. No one is going to be perfect at everything.
Here's my 'should advise': Developers should stop listening and executing everyone else's ideas and execute their own.
A simple example in Python:
vs.That said, I feel that there is a gap because I didn't major in CS.
Although I had to read a textbook on Data Structures and Algorithms on my own, I don't feel like this is a particularly glaring gap. Interestingly, my math coursework did cover a lot of the stuff at the end of the algorithms book, since I'd taken graph theory, linear and non-linear optimization, numerical analysis. But I had to learn the basic data structures (trees, hashes, lists) on my own. While it took some work to learn this, it came naturally enough, because I consider data structures and algorithms to be very similar to math. You could study this stuff without a computer and get a decent understanding of it.
The big gap in my knowledge is more around compilers, operating systems, and that elusive border between software and hardware. I never took compiler design, and I think that languages are still a dark art to me because of it. I think I also would have benefitted from doing some very low level programming (when I was in college, "C" was still considered a "high level" language, but at least I had to struggle with memory management). Also, a lot of data structures that are optimized to interact with memory or hardware are still pretty much a mystery to me. Obviously, without this knowledge, my understanding of operating systems is going to be pretty limited.
(I still think there are dragons inside the CPU.)
I started programming for a living before I got a CS degree. After I got the degree, the biggest difference I found (aside from the really cool knowledge I gained) was that I had a common language to use to talk to other people with CS degrees and an understanding of common methods that I used to take for granted.
Also, I appreciate the rigor behind a lot of CS fundamentals, and I believe I'm able to teach myself new CS-y things more easily and do my job better as a result. I don't think the CS degree is necessary, but I really really really believe it helps you in ways you may not realize until you get one.
Self taught programmers can write well but may be missing some of the nuance for why things are done one way over another or maybe be missing some tricks that save a lot of time. These limitations can be overcome by somebody committed to writing good quality code.