For example:
For intro courses:
* Computer science an interdisciplinary approach (princeton)
* CS61A - UCB
* Introduction to CS and programming (MIT)
* Stanford
* CMU
Data Structures and Algorithms:
* Princeton Algorithms
* CS61B - UCB
* Stanford Algorithms course
* MIT Algorithms
* CMU
Apart from this you have multiple books on each topic - Data Structures/Algorithms, Discrete Mathematics, Theory of Computation, Operating systems, Networks, and so on.
Apart from these you also have resources like teachyourselfcs, ossu, functionalcs.github.io/curriculum/.
I am attracted by the resources/online/books posted by courses in UCB/Princeton/MIT/Stanford/CMU. At the same time I get boggled down and overwhelmed that I have soooooooooo many materials to cover. Intro courses aren't that big of a deal since I am able to recognize/solve most questions fairly easily in multiple resources. But my next step of Data structures and algorithms is overwhelming that I am unable to start somewhere.
How do you recommend to choose the right resource (online/book) for each topic/course? Is it worth going through multiple university courses/books for the same topic?
This book has very little in the way of prerequisites, and it covers a lot of fundamental algorithms and a little bit of Math, but it is a lot more accessible and didactic than, say, the Cormen book. I don't think you need any other resource for studying the book (videos, forums, etc.) other than maybe the website for convenient access to the source code (and maybe some other Java reference, although you don't need deep Java knowledge to understand the code).
Note: I'm plenty biased for this resource... I don't know why, but I find the implementations so elegant an easy to follow, even though the source code is Java, a language I admit sometimes can look anything but elegant (in its production form with all those imports and redundant type signatures :-). Many algorithms are implemented using data structures introduced in previous chapters, so it makes sense to read it cover to cover.
For Computer Architecture, Nand2Tetris [2] is another resource that comes up often and for good reason. I only worked through half of this book but I really like it too and have it on my back burner to complete the second half of it: first part is about implementing a computer from the ground up (nand gates being the "atoms"); second part is about implementing a parser/compiler for a higher level language targeting the same computer.
I think you'd be better served by doing a lot of courses from the same institution. If you choose courses that were designed to fit together, you'll have a lot less wasted time from overlapping material or holes from missing material.
> Is it worth going through multiple university courses/books for the same topic?
What is your goal exactly? Is it to evaluate and compare everyone's materials?
If your goal is your own learning, then why wouldn't you take a more advanced course from the same institution instead of repeating a slightly different version of what you've already learned?
His MIT Challenge page: https://www.scotthyoung.com/blog/myprojects/mit-challenge-2/
His Ultralearning page: https://www.scotthyoung.com/blog/ultralearning/
I would spend a bounded bit of time (maybe just 10 minutes) every day focusing on the meta question of "how can I make progress given the absolutely massive set of choices I have to make?" and relatedly "am I actually making progress?"
Then I'd just make an arbitrary choice. E.g. pick a topic that interests you, find the top two or three textbooks on the topic, choose one at random and start reading it.
Then keep going back to the meta question. Are you making progress? If not, try another path. If yes, keep going, but remember to ask yourself the meta question tomorrow.
If you do this, you'll get better over time at carving out your own way.
re: going through multiple university books on the same topic. I find it is useful to skim several university books on the same topic. They often have different perspectives, and this is useful for developing intuition. But after doing this I'd just do the exercises from the one I liked the best.
By engaging I mean doing exercises, implementing algorithms in code, writing pet projects.
This will ensure you understand a topic, not have an impression that you understand. In past, I made a mistake to rush read textbooks till the point I feel I understood the content and ignoring most of the exercises - the exam showed me that I was wrong :)
At the same time, I would not suggest to apply engage mode for every book and chapter - your progress will be slow, and you may lose motivation deep in the middle of some thick textbook, as you may not be able to relate very detailed information there to your current expertise.
Personally, I apply the combination of skimming and engagement.
What I do is to create spreadsheet with 4 columns:
- "Topic": the topic name, e.g.: "self balancing trees".
- "Material": did I read/watch the material for this topic.
- "Notes": do I have my own takeaways or notes about this material.
- "Code": do I have code for this? like a Jupyter notebook or source code, etc.
This approach worked for me, and helped me get better at online tests and interviews.
If you think you already understand a concept, you can just move on to another topic.
nand2teris.org and cs50.net
See if you can solve all the projects & assignments in these courses.
These cover a lot of ground. Once you are done with these two courses end to end, you will get a fair understanding of many of the computing big ideas.
+ Bach's The Design of the Unix Operating System describes how operating systems and file systems work. Even Windows describes it's similarities and differences using the same terminology.
+ Hellerstien's Berkeley CS 186 Intro to Databases lectures. Databases get more love at Berkeley than elsewhere. https://archive.org/details/UCBerkeley_Course_Computer_Scien...
That said, how much time do you want to spend on it? If you don't have all life to do it, pick 2 and stick to it. Just random ... MIT and Stanford, or Princeton and CMU, in the end there should be no fundamental difference. Stuff that you listed in any way will get you far enough, two approaches will be great.
In the end if you want to be realistic about your time, role the dice for one of those... I did not do any of those, I did small technical university in eastern Europe. I have well paying job in western Europe and have seen people who finished better universities that know less than me.
You know that 80% of the effects come from 20% of causes? Don't try to over optimize... No one will give a damn if you are self learning and you did MIT course over the internet. You are not getting MIT degree anyway. That said, I skimmed through some of MIT and Princeton lectures as well, and you know what? Those were not magically better than the ones from my small uni in eastern Europe... But you know if you have MIT degree it is still worth more just like Adidas shoes you walk with them the same as other sneakers...
As the url suggests, it's got an agenda about interview prep but the materials do not - they're straight up CS resources. Like I said, this may not be exactly what you want, but it could be helpful.
On a different note, I have completed the Stanford Algorithms Course part 1 (currently working on part 2) and I can recommend it.
One of my favorite mentees came in to a software development job from a biochemistry background. She’s got a knack for it and did a great job self learning a lot of basics, but I really saw some awesome improvement after she did a “CS masters bridge program” through NYU- https://engineering.nyu.edu/academics/programs/bridge-progra...
I guess it’s really meant to get you into a grad program, but I know she got a ton out of it as a career programmer.
You can enroll for free at: https://www.edx.org/course/cs50s-introduction-to-computer-sc...
I never went to University and didn't take a lot of CS courses but since I create web development video courses I wanted to be able to reference other courses to folks who asked so I took CS50 a few years ago to vet it. It was a great intro course and I even learned a little bit of C in the process. David Malan (the head instructor) is also top notch.
The good news: It probably doesn't matter that much. Different programming books will give you different strengths and weaknesses, and that's a good thing because teams need diverse skillsets. It's been years since I wrote production code in a strongly typed, statically typed language, but I did that for so long that I still think in types, and I bring that structured way of thinking to the table in Python/Javascript, which means I avoid a lot of the mistakes those languages allow you to make. I've worked with people who were very comfortable with metaprogramming, which always feels messy to me because it inherently muddles types. It's not a tool I ever reach for, and I push back when people add metaprogramming to codebases, which is a good thing, because too much metaprogramming can be bad. But sometimes, judiciously used, it can be very effective, so people with metaprogramming skill will solve problems that would be very difficult for me to solve. If we had both read all the same fundamental programming books, we'd never have these diverse skills that make our teams effective.
TL;DR: Pick the first one from a reputable organization and do it. Time spent agonizing on this decision is time wasted.
In college, I found this lecture series to be an excellent supplement to my autonama and formal languages course. I haven’t watched the whole thing, but it should check your “theory of computation” box. The lecturer is fantastic and thorough.
https://www.youtube.com/playlist?list=PL601FC994BDD963E4
The prerequisites for this should be discrete math, but to be honest, depending on how comfortable you are with math in general, you could probably skip it and look things up as needed.
Another person to look into is Scott Young who taught himself the MIT CS curriculum in a year. His book Ultralearning is excellent and contains many tips that would help with self-studying CS. Unless you just want to dive into the content, Ultralearning would actually be my first recommendation before learning CS fundamentals.
Compare the second homework assignments, which are supposed to be given after 2 weeks (~6 days) of instruction:
15-112: https://www.cs.cmu.edu/~rdriley/112/assignments/02/
CS 61A: https://cs61a.org/hw/hw02/
The 61A assignment forces higher order functions way too early, and it's often discouraging to people just starting out - and it's not even common (in my experience) to write code like this anyways. I also like the way that the CMU assignment writes tests as simple functions, without magic docstring tooling.
Don't skip the code tracing sections, where you read code and write the output by hand - it helps you understand and internalize what the code is doing, rather than just running code samples over and over again to see how it works.
Also, there's some nice notes on debugging https://www.cs.cmu.edu/~rdriley/112/notes/notes-debugging.ht...
[1] I took this version, which is ordered a bit differently http://www.kosbie.net/cmu/spring-16/15-112/schedule.html
https://ocw.mit.edu/courses/find-by-topic/#cat=engineering&s...
Introduction to Computer Science followed by Data Structures and Algorithms should give you a healthy start.
--
Learning these fundamentals is useful, but not necessarily immediately practical. Building and doing is the best way to learn. This is a good start, and the fundamentals will certainly give you an edge against most people graduating from a bootcamp, but after this I'd recommend finding a good tutorial, whatever the language that teaches you step by step how to build XYZ... I learned ruby/rails by doing Michael Hartl's tutorial building a microblogging platform like twitter.
Second advice is that once you've done a rote exercise find some way to push the boundaries of it. I've found that anything I can do to extend or customize the example helps engage my brain with the material and often leads to learning new things.
I'd also suggest a top-down approach where you start with a flexible end goal you'd want to achieve (e.g. be a full-stack dev), in which case you can start by babystepping a hands-on approach (e.g. learning javascript, learning client-side and server-side of things). Complimentary fundamental course outlines can also help, e.g. Comptia A+ gives you hardware fundamentals, Comptia Network+ gives you networking fundamentals, CloudAcademy can get you started on working with cloud providers like Azure/GCP/AWS, and so on and so forth.
It's easy to get lost in the theoretical side of things, being able to test them out in action as soon as you can could give you quite an ideal balance.
Just remember that material is material. Fundamentally, all of these courses are pointing you towards the same basic core of knowledge, with only minor stylistic differences. I like using multiple sources, like you do. Just stick with one good one at first, and then once you finish it you’ll be able to go through five more in the same time, because of the overlap.
...or use any other book or lecture series. Stop worrying about choosing the "right" resource; just find a resource and start learning.
You end up implementing the algorithms and data structures yourself in your language of choice, which I find is a good way to learn.
CS50 hits the sweet spot of excellent online material, large online community and fun.
1: https://www.edx.org/course/cs50s-introduction-to-computer-sc...
In particular, I like 'Category Theory for Programmers' by Bartosz Milewski as a great theoretical foundation to functional programming.
I’d suggest checking out 5-10 min worth of material from each one and choosing whichever you find most accessible.
If after completing one course you don’t feel confident you’ve absorbed the concepts, try another. Otherwise move on to the next set of concepts.
Going through hackerrank tasks is a great way to practice. Also Cracking the Coding Interview and online interview questions.
My suggestion would be to enroll in a college and pay for your education. This way, you'll be more motivated because the pace will be imposed and it will cost you more than your time if you don't do the work required to pass and more importantly, learn something of value.
Trying to learn computer science is like trying to learn sports. Swimming and tennis have very little in common and you can spend years trying every sport and never becoming good at any of them (what traditional cs education does)
If your goal is to get a job, your best bet is web development or mobile dev.
The big picture is we have CPUs that have instructions. Instructions boil down to moving data to/from someplace and manipulation of data.
Moving is how monitors display stuff, data gets stored on disk etc. Moving is how a program gets loaded and executed.
Manipulation is how you get math operations. Programming boils down to math operations and conditionals (if this, then that, else something else)
Math operations have a few basic types for performance reasons - floats, ints, etc.
Because math operations on the CPU have types, programming languages have types. Because CPUs have conditional operations, programming languages have operations. See the pattern? Programming languages are just conveniences on top of the language the CPU provides (called assembly).
The most popular 'low level' language is C. C gives you functions and the smallest set of data types you can get away with. The big deal here is organizing code into functions. Functions allow re-use and programming is all about doing the least amount of work possible by the programmer to achieve a task, in the shortest amount of time and memory use possible.
The study of shortest amount of code to achieve the fastest result with the least amount of memory use is algorithms.
To achieve fast results with least memory used, you want a language that gives you access to memory manipulation directly. This is why C is still king for anything performance critical.
If you don't care for performance much, Java the language is king of corporate software and all Android software too. It handles memory for you and your types are clever - you don't need to say how big an array you want when creating it, you just create one and it gets magically re-sized behind the scenes for you as you add elements in. All modern languages have clever types and ways of helping manage memory for you. This is to make programming more newbie-friendly and theoretically to lower the number of bugs, at the cost of performance and memory use.
Phew, so we have CPUs, C and Java. Now where do we typically store data and how do we display it?
Data is stored in databases. Databases mere mortals use are all SQL databases - the most popular and robust being Postgres. Learn what an index is and why it helps stuff run faster. Learn joins and one-to-many and many-to-many. Build a photo-sharing site with user registration - this'll cover needing to know all the basics.
Oh, to build the site, you'll need to display it. You have 3 options - web, ios or android. I'd recommend web because it's the easiest of the 3 and there are tons of excellent resources to learn from.
It is extremely easy to get bogged down in libraries such as 'react' and all the rest. It is extremely easy to get bogged down in new Javascript features. Stick with the basics! Stick with simple html/css and flexbox for layout. Use node with the most popular and simple web framework as a web server. Use the simplest library to talk to the database and write SQL, don't use ORM because you need to learn SQL and'll be around for the next 50 years - your ORM won't.
Phew, you've spent about 6 months and have built a photo sharing site. You know html/css, some javascript, a web server framework, how to store stuff in a database.
You're another 3-6 months away from getting a job as a web developer. You'll need to learn react or whatever other junk framework of the year is most popular these days. You'll then be plunged into a world of mediocre software and writing code for projects that make no sense, with deadlines that make even less sense. There'll be a lot of meetings, incompetence and your posture will suffer.
The pay is good however, and it should double within the first 2-5 years if not triple. Switch jobs every year and try to do contract work as soon as possible - it pays way better.
This is the outline for going from 0 to hero, if getting a job is your goal. If you don't want to end up working on projects of questionable importance for the rest of your career and you want to build software that will drive the next car, operate the next robot, help us go to Mars etc - you should simply attend a good University. There is no shortcut and you'll avoid wasting hundreds if not thousands of hours chasing your own tail reading tutorials written by people who learned programming 2 years ago themselves.
You'll meet other smart people and you may even want to get a Masters and a PhD. Oh, you may get hired by a top company if you're good and the pay there is great, and that's where you'll get to do great work. They care about degrees and which University you went to, don't believe anyone who says otherwise.
Self-learning CS is only for the crazy ones, or those who want a high paying job quickly, are smart and don't care what they work on.
My 2 cents of course, having gone the self-learning route myself many years ago :)
Oh, one last thing - if you go the self-learning route, you need a friend who's a good established programmer to answer your questions for 5-10 min everyday. I don't know if there are services online that do this or if you know somebody but this is absolutely critical to avoid wasting your time without knowing it, which is inevitable but you want to minimize it.
Now that I think of it, if you go to University, you absolutely want a real programmer too, to know which courses to simply get a passing grade on, and which to focus on, depending on your ambitions.
Other wise you are just looking for an instruction manual for life, which doesn’t exist as such.