Monday, 28 January 2019

How to Learn Computer Science? (from Zero to Hero)

How to Learn Computer Science? (from Zero to Hero)

If you aspire to be a software engineer and you’re just starting out, you probably have a lot of questions. What programming languages should I learn? Is it enough to learn one or two programming languages to secure a good job at a big tech company? What other skills do I need, if any?
With so much information out there, aspiring software engineers can find it difficult to ferret out the valuable information from the rubbish.
I know how it is because I’ve been there too.
Needless to say, it took me a long time to find the answers that I needed.  But it doesn’t have to be like that for you.
I searched online, trying to find quality information, but the ONLY good resource I found was an article written by Ozan Onay and Myles Byrne from the Bradfield School of Computer Science.
So I decided to write an article that reflects my personal opinions and experiences.
This article reflects my personal opinions and information that I’ve discovered through my real-world experiences. It gives you a broad overview of what your CS career will look like, from start to finish. It tells you what skills you absolutely must acquire. It even lets you know what to expect at each and every step of the way.
The overall thesis of this article is that software engineers pass through three different phases.
I am going to explain to you exactly what these three phases are. Afterwards, I’ll tell you exactly what skills you need to move from one phase to the next, so you can get what you want from your career.

The Three Phases of a Software Engineer

Highly successful software engineers progress through three consecutive phases.
I’d like to point out that some software engineers never progress beyond the first phase, and others don’t move beyond the second. Only highly successful software engineers reach the third phase.
These three phases are:
1- The Coder
2- The Programmer
3- The Computer Scientist
It is important to mention that this classification is my own development, based on my personal experiences and observations.
Let me explain each one of these phases.

First Phase: The Coder

Every software engineer begins his career as a coder.
This can happen at a very young age.
You don’t even need a college degree to be a coder.
So, what is a coder?
A coder is someone who knows how to speak the language of a machine.
When given a particular problem, a coder knows how to break down that problem into instructions that the machine can understand in order to come up with a solution.
Here’s the thing: if you find yourself really struggling at this phase, you may want to consider a different career path. The coding phase is literally the easiest phase of your CS career.
If you succeed at coding, congratulations! You might have a successful career as a software engineer.
Unfortunately, many software engineers remain in this phase for their whole career.
If you’re just a coder, your pay won’t be great because your skills are easily replaceable.
And if you remain just a coder, your promotions will be severely limited.
At this stage, you shouldn’t even expect to get an entry-level job at any of the big tech companies.
You need to evolve at least to the next phase for this to happen.
You need to be a programmer.

Second Phase: The Programmer

Once you have learned the basics of at least two programming languages (preferably one statically-typed and one dynamically-typed), you are a solid coder.
The question now is how do you promote yourself to the programmer status?
A programmer is essentially a sophisticated coder.
Writing code that does the job is what coders do but writing efficient code that does the job is what programmers do.
Here is a list of some skills that you should have as a programmer:
1- you should know the fundamentals of how any code eventually turns into something that a hardware chip can understand and execute.
2- you should understand that any system has finite compute, storage, and network resources and your software should utilize these resources efficiently.
3- you should know how to use data structures and algorithms to write efficient code.
4- you should understand what makes code efficient and what doesn’t.
5- you should understand that quality is important and that testing your code is crucial.
Now I have good news and bad news for you.
The Bad News: This is not the end. There is still a long way to go on your career path.
The Good News: There are a lot of coders out there, but there aren’t a lot of solid programmers. If you really master this phase, you can easily secure a job at one of the big tech companies like Google, Facebook, Amazon, and others. In fact, most of the interviews conducted at these companies test how good of a programmer, not how good of a coder, you are.
I wrote an in-depth article that discusses everything you need to know about the coding interview process. Be sure to check it out if you’re at this phase in your career.
The vast majority of software engineers retire at this phase.

Third Phase: The Computer Scientist

Learning does not stop after mastering the programming phase.
As a matter of fact, it actually starts here!
When you are at the computer scientist phase, you’re essentially an architect who thinks about the big picture more than the nitty gritty details.
You have a solid understanding of designing large distributed systems and you know how to build scalable systems that can handle large loads and tolerate failures.
A computer scientist also never stops learning, and always tries to stay up to date with the latest in technology.
At this level, you’ll most likely be in charge of big projects and you’ll be managing a team (usually of coders and solid programmers) to get the job done.
You might also need to cooperate with other teams.
All of these require stellar social and leadership skills.
In the rest of this article, I will go through the technical skills that you need in order to be a coder, then a programmer, and finally a computer scientist.
Let’s get started.

1- Programming

The first and only step to becoming a coder is to learn programming.
This is the easiest step in your CS career, and it gives you a quick feedback about whether you should pursue a CS career or not.
When it comes to choosing programming languages, I don’t want you to fret over what programming language to learn.
At this stage what matters is not the particular programming language, but the concepts that you will be learning. These concepts will hold true in almost any other programming language.
When you become a more seasoned programmer, you will reach a point where learning a new programming language doesn’t take more than a week, so don’t waste your time trying to find the “perfect” programming language to start with because: a) it doesn’t exist, and b) it doesn’t matter.
With that said, I personally recommend you start with the following two languages. I will explain my reasons behind these choices, but feel free to start with whatever you’re most comfortable with.

Python

I highly suggest you start with Python
Why?
Because Python is a language that is very easy to learn. Like, really, really easy!
It is a very high-level language which allows you to write real programs in just a few lines of code.
So, in a short amount of time, you will be able to build real software…not just hello-worldtype programs
These features of Python are extremely important, especially when you’re starting out.
To learn python, I highly recommend Python Crash Course.
I find it to be very useful for beginners.
I also like that the book is project-based, so you’ll have fun building things while you’re learning to code.

Java

Why another language though?
 The reason I recommend learning another language, especially Java, is because it will teach you some programming concepts that don’t even exist in Python.
For example, Python is a dynamically-typed language while Java is a statically-typed language. If you don’t know what that means, you will understand it after learning these two languages.
A combination of Python and Java is a very good way to start because together they provide you with a very solid idea of the programming concepts that you will need in almost any other programming language.
To add to the benefits mentioned above, both Python and Java are heavily used in industry. So not only will you be spending your time learning the foundations that will pave the way for you to progress further, but you will also be learning some practical languages that are very employable and in high demand.
I learned Java from the Java core series many years ago.
Two separate books are offered. One is for Java fundamentals, and the other is for advanced Java features.
I’d recommend not to overwhelm yourself with the advanced features for now. Focus on the fundamentals in this phase.
Congratulations! Now you are a coder!

2- The Software Stack

OK. So you can write code that can do some really cool stuff, but seriously do you even understand what’s going on?
Say you write a very simple program that just adds two integers and prints the result to the screen.
In Python, that would look like this:
x = 5
y = 10
print(x + y)
I take it you understand your code. You understand that a computer running your code should output 15.
But do you really understand what’s happening under the hood?
What does variable assignment (x = 5) mean at the hardware level? What is  x, really? How is the number 5 represented in hardware? How does addition actually happen? And how did the result end up on my screen?!!
At the end of the day, a computer is just a collection of hardware chips and wires.
How can a computer really understand your code? and execute it flawlessly?
The fact of the matter is, your code is just the tip of the iceberg. There are a lot of other layers under your code. Together, they make the whole thing work the way you expect it to work.
programmer unravels this magic.
At this level, you need a solid understanding of all the layers of the stack starting from your code, all the way down to the hardware layer.
The Elements of Computing Systems by Noam Nisan and Shimon Schocken is unequivocally my top suggestion for a book that will teach you the essential information you need to understand each layer of the stack.
The book covers hardware, compilers, linkers, and operating systems at a very basic level which makes it very beginner friendly.
It walks you through the steps of creating your first programming language, creating a compiler and a linker for it, and then creating an operating system.

3- Algorithms and Data Structures

Now you’re in a very good shape to go back and start programming again, but this time with a completely different mindset.
Because now, you REALLY know what’s happening under the hood.
You understand how hardware is eventually going to run your code.
You know that you have limited hardware resources and you understand the value of utilizing the available resources efficiently.
Studying algorithms and data structures will teach you how to write code in a way that makes your code more efficient, however you define efficiency. it could be speed, resource utilization, or both.
The skills that you are going to learn at this phase are some of the major differentiators that separate average coders from solid programmers.
In fact, most big tech companies like Google, Facebook, and Amazon focus a lot on data structures questions during their interview process.
I personally like Introduction to Algorithms: A Creative Approach by Udi Manber. It is well-written and includes a wealth of exercises.
Be aware that the topic of data structures and algorithms is language neutral, so it doesn’t matter which programming language you’re using.
However, some people prefer to read books that are specific to their preferred language.
Even though that’s not my style, but you can find a lot of good language-specific data structures books like this one for Java and this one for Python.

4- Networks

It is very rare that your code will run on an isolated single machine.
Most useful code communicates with other computers either in a local network or the internet.
Programmers need to have a very solid foundation of how computer networking works.
I came across, in my opinion, the best networking book when I was a senior undergrad. It helped me overcome the dry text book that my professor at the time recommended.
Computer Networking: A Top-Down Approach by Kurose and Ross is a very well-written, super easy to understand book that covers all the networking basics that you need to know.
I still go back to this book every now and then if I need a refresher.

5- Operating Systems

Operating systems play a major role in the software stack.
If you are following this list in order, by now you should have a very broad idea of the role of an operating system in the stack.
But now is the time to have a deeper understanding of operating systems.
Operating Systems Concepts by Abraham Silberschatz is one of the best books on the subject.
You need some basic knowledge of C though, because the majority of operating systems are written in C.
My recommendation, unless you want to be a kernel developer,  is not to allow yourself to get stuck at this point.
This is a very dense topic. Understanding all the details of all the aspects of operating systems is very time consuming.
Grasping the main fundamental operating systems concepts is good enough to keep you going but don’t get bogged down in details.
Another resource I highly recommend is the OSDev Wiki, especially if you want to learn how to create your own kernel. This is pretty advanced, but it’s something that the vast majority of software engineers can’t do.
Look at that! You’ve achieved the status of programmer!

6- Distributed Systems

Welcome to the start of your computer scientist status.
In this level, you will be learning new skills while you improve the skills you learned as a programmer.
Distributed systems is about building and architecting software systems that are scalable and that can tolerate failures at the same time. This requires you to think of the bigger picture, rather than focusing on how to build the individual components–programmers and coders can do that.
For example, think about building a search engine service, like Google, for some text files that exist only in your laptop.
This service will listen to search queries that it receives over the network, search your files for the query, and respond with the results.
This is not a hard thing to do. Any programmer with a decent knowledge of algorithms and data structures can build an efficient search engine for a small number of files.
Now imagine that more and more people become interested in your service and they start using it.
Now you’re getting millions and millions of requests a second.
Not only that, but the size and number of files you are searching through begins to grow dramatically.
What happens if your laptop (that hosts the search service) fails?
Will you just ignore the millions of requests you’re getting?
Distributed systems is about creating an army of computers that work together to form a specific task (in our example, the search service).
It allows you to create scalable systems that can handle more requests or more data. At the same time, it provides redundancy that would be useful in case any one (or more) machine fails.
Now, let’s talk about resources.
By far, this blog post is the best resource I have found on the subject (disclaimer: you will need to read some academic papers).
If you are a text book kind of person, then this O’Reilly book by Martin Kleppmann is excellent. I have skimmed through it, and it covers most of the important topics.
With that said, Distributed Systems is a field where experience matters a lot.
So learn the theory, but also get your hands dirty by working on distributed systems projects.

7- Machine Learning

Machine learning is an interdisciplinary field that spans computer science, mathematics, and statistics.
To be able to build these types of software, you need to be more than just a solid programmer because as I mentioned this field requires a very strong mathematical and statistical foundation.
And no, learning everything about Python’s Scikit-Learn library (a very popular Python library for machine learning) won’t make you a data scientist or a machine learning expert. You still need to understand the mathematical and statistical underpinnings.
There are two ways to study machine learning: the top-down approach method, where you start first by writing machine learning code right away (for example ,by using Python’s Scikit-Learn library) and understand the math later, or the bottom-up approach, where you start with the math first and then move up to coding.
I personally prefer the second method, just because that’s what works best for me. Even though It’s harder to start and takes longer before you start writing code, once you grasp the concepts, learning how to use a machine learning library is going to be a piece of cake.
On the other hand, the top-down approach has the advantage of allowing you to begin writing machine-learning code fast.
This motivates a lot of people.
The downside of the top-down approach is that it will be much harder for you to understand why some techniques work, while others don’t, because you won’t have the necessary mathematical background at first.
Andrew Ng’s course on Coursera is a very good place to start.
If you have prior knowledge of mathematics, probability, and statistics, then An Introduction to Statistical Learning is a very good book for building the statistical and mathematical foundations for machine learning.
However, don’t use this book if you aren’t already strong in linear algebra, probabilities, and basic statistics because you will not be able to understand it.

No comments:

Post a Comment

Python Lambdas Explained (With Examples)

Python Lambdas Explained (With Examples) View Larger Image In this article, I will teach you exactly what a python lambda is. ...