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.
> 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.
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 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 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.
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.
>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.
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 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. :)
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 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.
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.
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.
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.
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'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.
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)
> 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.
> 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.
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.
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.
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.
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.
- learning many technologies, even the ones I'll never use
- learning 100% of the syntax (10x what I'll ever need)
- being able to solve the same problem 5 different ways
- learning slick stuff I'll never need
- being able to scale to levels I'll never encounter
- winning brogrammer arguments in on-line forums
then, yes, I'm missing my foundation.
If, OTOH, foundation means:
- seeking solutions for problems, not problems for solutions
- being able to learn whatever I need
- being able to solve most problems with few tools
- favoring action over status
- living in the real world, using academia as a resource
- having learned what really does and does not work
- having raving customers who don't care what's under the hood
- satisfying 100% of customers with 75% solutions
Another classic example of "what is good for the individual is not necessarily good for the group" (the exact name of the economic theory escapes me).
Sure, for you, the cost/benefit scenario might not work out. You seem to be doing quite fine. However what about the people that created the languages you use? Those who built the processors you work on?
A lot of people will never need the things they teach in a standard CS curriculum. I doubt most programmers even know how to spell "automata". But then again, most programmers aren't doing anything new or ground breaking. Most programmers are simply rehashing solutions to problems already solved somewhere, or simply making small iterative steps. I have found that my own work seemed very "small minded" before I began my formal studies.
Even beyond that, I am now equipped to do most anything I choose involving this discipline. I've always wanted to create my own language, and now the only barrier is simply the time and effort I need to put in. I have all the requisite knowledge and background, and my solid foundation will allow me to easily (comparatively) pick up any new concept I might encounter.
The average programmer might never desire to create their own language, but for this field to continue to grow we need people to push the limit and innovate beyond our current limitations. To do this you need to have a deep comprehension of what you are working with.
However even beyond all of that, I wasn't content with not knowing the intricacies of computation. Maybe I'm just a naturally curious person (and possibly biased), but in my opinion the world of Computer Science is one of the most fascinating fields to have ever studied.
One last point... why not? Knowledge is power.
Edit: After reading some of the replies posted while I was typing, I'll agree there are outliers. You will always have those people who are able to become masters of their field with no formal training, but then again, those are a select few.
What about being able to analyze efficiency (Big O), understanding compilers, full understanding of computer architecture, realizing how the CPU executes code, knowledge of advanced algorithms, knowledge of the OS workings, and AI fundamentals? That's generally what I see self-taught people lacking, i.e., deep understanding of anything outside of languages.
That's generally what I see self-taught people lacing, i.e., deep understanding of anything outside of languages.
What a shame. There are lots of very accomplished self-taught people who know much of this stuff and are busy changing the world. I sincerely hope you get a chance to meet many of them.
You realize these pet topics are only 5 university courses. It would be a intense 4 month semester, but it's workable.
1. full understanding of computer architecture, realizing how the CPU executes code
2. analyze efficiency (Big O) (a few hours), knowledge of advanced algorithms
3. understanding compilers
4. knowledge of the OS workings (often self taught out of necessity)
5. AI fundamentals (Admittedly a specialized topic)
I wholeheartedly disagree. First because I'm a self-taught developer (if such a thing is actually possibly), and second, because I often find myself studying deeply into things outside of the languages I use. A self-taught programmer isn't any less (or more) motivated to study Comp Sci topics than a CS student and most school's curriculum are wide open for anyone to inspect. Most self-taught developers I know are actually mostly the same, deeply passionate, driven, insightful, and knowledgable in a wide range of Comp Sci topics. But as the saying goes, birds of a feather flock together. I suppose I wouldn't necessarily engage with self-taught programmers who don't exhibit any kind of depth any more than I would a University CS graduate who lacked depth. Having said that, none of us are experts in all things Comp Sci related.
The difference between a self-taught programmer and a college CS education is that the self-taught studies what he wants to. If a self-taught person dives into the CS pool, they often learn much more than a B.S. CS person because they are learning what they want to.
However, some self-taught people have conditioned themselves to hate CS due to constantly needing to prove to companies that they are qualified for a job despite not having a CS degree. These people place little value in understanding CS and because of that they are worse off because they weren't forced to learn it.
It all depends on what kind of person the developer is, and I am glad that you are the first kind. I'm getting tired of HN bashing any article that suggests that perhaps a developer doesn't know everything.
I'm a self-taught engineer, and I first picked up Big-O when I was 16. (That was almost 20 years ago). I've written a linux kernel patch (rejected), toy compilers, and the two big no-nos of software development ( 1: Writing your own lock-free code, and 2: Writing a string library, both of which went successfully into production ). I've built my own microprocessor from NAND gates, and wrote the microcode instruction set to go with it. I've studied VLSI (ages ago), but I've never dug into AI topics.
There is one way in which I feel handicapped compared to my colleagues, which is that I find it generally hard to grab a book on a programming topic and read it cover-to-cover (The same goes for taking classes). I've got to get a development environment up, see how I can break the 'examples', and generally abandon the book to doing my own thing before I get more than a third of the way through.
On the other hand, every time I've worked with more classically trained developers on real projects (and all the cruft that goes with it), I always find that there are corners of the code base that none of them understand, and no one ventures in to find out what's wrong.
Myself, I need to understand how a system works in order to work on it, so I always dig, and tweak here, or tweak there, and so I tend to learn full systems much quicker than my colleagues.
In the end, it's a trade-off, but it's how I work, so I guess I'm stuck with it.
As someone who had started out as a self-taught programmer and only after a couple of years went back to school to get a degree, I can confirm that. I think the only thing from your list that I had been familiar with from my self-studies was the Big O notation and some algorithms and data structures. I first went back to get the degree mostly for the piece of paper with better job security and salary prospects in mind, but I actually enjoyed hearing about most of these things. I would add two things to your list which were great fun: automata/languages (I had known how to use regular expressions before, but I had no idea where they came from and how they fit a bigger picture) and heuristic algorithms (like simulated annealing and what not).
In all honesty, I can't say I know for a fact that knowing these things made me a better developer. It's hard to quantify. In your day-to-day life you don't generally use such knowledge. It's entirely possible that it didn't make any difference to my actual work. I certainly did use it during job interviews and lunch-time conversations with my coworkers.
It's remarkable how many of these are self-fulfilling prophecies. You'll never use technologies that you have no idea how to use. You'll never need slick stuff you don't know because you won't get into situations where you would end up using it. And so on.
Prioritization is fine, but always be careful about rationalizing your own continuing ignorance of things that a lot of people claim to find useful.
(I actually ran into a min-cut problem in the wild today. I'm glad I recognized it as such, because it was kind of important, and I wouldn't have been able to solve it if I hadn't heard of graph flows and cuts. Hell, I might even have congratulated myself for having avoided spending time learning something so useless....)
You seem to equate "foundation" with knowledge that's not immediately applicable. There's some truth to that, but I think it misses the forest for the trees. Knowledge is just the tip of the iceberg when it comes to excellence in software development.
Think of programming like writing an essay. Clearly some knowledge is required; you need to include some information in the essay or it's completely pointless. But the difference between a good essay, one that persuades the reader, and a poor essay isn't in the information it contains. It's in the flow of ideas, the juxtaposition of opposites, the emotional connotation of a well-chosen word, the ruthless elimination of extraneous words. The quality of a good essay comes from the skillful presentation of ideas as much as the ideas themselves.
Programming is similar. It's hard. Doing it well requires more than just knowledge of syntax or data structures or algorithms. It requires identifying the essential elements of the problem at hand, extracting their essence and crystallizing it as code. It means writing code that so simple that it seems so obvious and unremarkable that anyone could have done it. It means being able to move up and down the tower of abstraction, from bits flying around in memory to the concepts and language of the business domain, and from individual lines of code up to architecture and processes. It's a skill, like writing or pottery or motorcycle maintenance.
Now from your "I'm fine" list it sounds like maybe you're not interested in excellence in programming per se, just in the business value you can create by programming well enough to solve your customers' problems. That's a perfectly reasonable. That's how I approach design.
But if you want to be a good programmer, to really master the skill, then you need a bit more than a few tools that can solve most problems, and being able to learn new skills just in time. Which is not to say that an academic education is necessary. But it does mean you'll have to learn things that aren't immediately applicable.
Knowing how to solve a problem 5 different ways means you can choose the best way for the current situation, knowing that the other 4 solutions will probably be called-for another time. I've been in situations where "slick stuff" was absolutely appropriate. (For example, I once solved some tricky timing issues in multithreaded code by using continuations. Another time I used parser combinators to drastically reduce the size and complexity of a family of parsers, and eliminated a lot of bugs.)
I'm self-taught too, so I get it. But I wouldn't be so quick to dismiss the idea of building up a good foundation for your skills, if you're interested in developing them.
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.
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 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.
>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.
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.
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.
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.
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.
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.
Read the Hacker Ethic. As long as one is curious the information is there. Set theory? Probability? Algebraic lattices and convergent data structures? Monotonic functions? Cache registers and word alignment on some rare architecture you've never encountered before? Need to know how to write a compiler? I've learned some of this stuff and more on Usenet, web forums, IRC chats, books; from github, bitbucket, CPAN, PyPI, quicklisp; and by going to conferences, meetups, and even on the job. Academia is not the bastion of Computer Science fundamentals.
As long as one is curious and has the intellectual tenacity to be critical then there's nothing that the ivory tower can offer that isn't available on the web, at your local library, and right on your damn computer.
We don't live in the dark ages. Why do so many Computer Science people insist that only they know the true knowledge?
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.
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.
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.
I'm new to this site, but hopefully I can give some insight. I'm in Ireland and I'm in my fourth year of CS, but I've also worked at some startups because they frankly aren't mutually exclusive. I've had the pleasure of working with both self-taught and formally-educated programmers, and when it comes down to the daily grind of work the lines between us are pretty blurry.
What I'd miss if I dropped out isn't any notion of a foundation, I'd be able to get it all from the resources mentioned on this page. What I'd miss (as in, it's absence would sadden me) is being able to discuss compiler design and other areas that may not be of interest to most working programmers with respective experts in the field. I'd also miss the impact the piece of paper would have on any potential greencard application but that's another story.
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.
These developers hit a wall quickly, and have to work harder (or just write poorly thought-out/designed code) over time. That does not mean they are less capable than classicly trained CS programmers; it just means they have to overcome certain learning curves at a steeper incline. Saying this tho - personality, drive, etc makes a huge difference and overshadows this argument. Want to know how to optimize your website for a high-latency 3G mobile connection? I bet that having eaten some TCP/IP 7 layer burrito will help you in some way.
What many self taught software engineers lack is the shibboleths of the computer science community. The interview process at many large organization's like Google and some startup's seem to use many of these factors like obscure algorithim tricks to screen potential applicants. It is possible to pick these things up on one's own but it makes to it more difficult to transition between organizations.
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 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.
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. ;)
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.
People forget the saying "school if what you make of." School is just a place for facilitating the self-study of people by providing a guide devised by people who have already gone through the joy and pain of learning.
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."
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 :-)
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'".
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...)