00:00:00
Computers make no sense. Throw some metal in a box
and boom [monke]. What the heck is going on here?
00:00:11
Inside your PC is a Central Processing Unit,
or CPU. It’s basically just a piece of silicon
00:00:15
with billions of microscopic switches called
transistors. Depending on the flow of electricity,
00:00:19
they can be on or off, kind of like a light
bulb, which gives us two states: 1 and 0.
00:00:23
The value at one of these switches is called a
“bit”. One bit by itself doesn’t really do much.
00:00:28
But put them together, and magic starts to happen.
A group of 8 bits is called a “byte” and can
00:00:32
have 256 different combinations of 0s and 1s.
Congratulations! We can now store information
00:00:37
by counting in a system called “binary”.
Every bit represents a power of 2,
00:00:41
1 meaning the power is included and 0 meaning
it’s not, so this number has 1 times 64,
00:00:45
1 times 4, and 1 times 1, which adds up to 69.
This is nice, but for humans, hexadecimal is
00:00:50
even better: It’s often denoted by this 0x and
is simply a more readable format than binary:
00:00:54
Four binary bits can take any value from
0 to 15. Hexadecimal uses 0-9 and a-f
00:01:00
to represent those values, so a group of four
bits can be replaced by one hexadecimal digit.
00:01:04
Okay. Now that we can store numbers,
we just need computers to actually,
00:01:07
you know, do something with them.
Using transistors, you can make logic gates,
00:01:11
which are electronic circuits that encapsulate
logical statements. You can think of it as a
00:01:14
lightbulb with two switches, where the light
only turns on under certain conditions.
00:01:18
For example, only if A AND B are on.
By combining logic gates in a clever way,
00:01:22
you can build circuits that perform calculations
according to Boolean algebra, which is a system
00:01:26
formalizing mathematical operations in binary.
But, even though computers understand 0s and 1s,
00:01:31
for humans, it’s not really all that useful.
So, using a character encoding like ASCII,
00:01:35
we can assign a binary number to each
character. When you type an A on your keyboard,
00:01:39
it gets translated into this binary code, and as
soon as the computer sees this, it says: “Ah yes,
00:01:44
that is a capital A.”, and slaps it on the screen.
How these devices fit together is handled by an
00:01:48
operating system kernel, like Windows, Linux or
Mac, which sits between computer hardware and
00:01:52
applications and manages how they all work
together, for example with device drivers.
00:01:56
Input devices allow you to give the computer
instructions with the press of a button,
00:02:00
but at the lowest level, computers only
understand instructions in machine code,
00:02:03
which is binary code telling the CPU
what to do, and which data to use.
00:02:06
When it comes to following these instructions,
the CPU is kind of like a genius, just with the
00:02:10
memory of a demented goldfish. It can handle
any instructions but it cannot store any data,
00:02:15
so it’s only really useful with
random access memory or RAM.
00:02:18
You can imagine it like a grid, where
every box can hold one byte of information,
00:02:21
which can be data or instructions, and has an
address, so the CPU can access it in four steps:
00:02:26
Fetch from memory, decode instructions
and data and finally, execute and store
00:02:30
the result. This is one machine cycle.
Since a program is basically just a list
00:02:33
of instructions in memory, to run it,
the CPU executes them one by one in
00:02:37
machine cycles until it’s complete. Oh yeah did
I mention that this happens, like, really fast?
00:02:41
Modern CPUs can do billions of cycles every
second, which are coordinated and synchronized
00:02:45
by a clock generator. The speed of this clock
is measured in GHz, and people often overclock
00:02:50
their CPUs to improve performance, which is
nice, but might just set your PC on fire.
00:02:54
What’s ever crazier though, is that a CPU has
multiple cores, which can all execute different
00:02:58
instructions in parallel, so at the same time.
Each core can be split into multiple threads,
00:03:03
which also allows every single core to
handle multiple instructions concurrently,
00:03:06
so switch between them really quickly.
Okay, that’s cool, but it doesn’t matter
00:03:10
how powerful a computer is if you have no way
to give it instructions in the first place.
00:03:14
Typing machine code by hand would probably make
you go insane, but luckily, you don’t have to:
00:03:18
The kernel is wrapped in a shell, which is just
a program that exposes the kernel to the user,
00:03:22
allowing for simple instructions in a
command line interface with text inputs.
00:03:26
But the best way to make a computer do
something useful is with a programming language,
00:03:29
which uses abstraction, so that instead of
this, you can write code that looks like this,
00:03:33
which is then converted into machine code for you.
Some languages like Python use an interpreter,
00:03:37
which directly tries to execute the source
code line by line. Other languages like C
00:03:41
or GO use a compiler, which converts
the entire program into machine code,
00:03:44
before putting it in a file the CPU can execute.
Now, every programming language has different
00:03:48
syntax, but there’s some basic
tools almost all of them have:
00:03:51
The most basic way to use data is with
variables, which assigns a value to a name,
00:03:55
which can then be reused and modified.
Depending on the value, variables can have
00:03:58
different data types. For text, there’s single
characters and strings of multiple characters.
00:04:02
For numbers, there’s integers, which can also
be signed if they’re negative, and floating
00:04:06
point numbers for decimal values. They’re called
floating point, because the decimal point can
00:04:09
float around to trade off precision with range.
This is possible because they use scientific
00:04:13
notation. It’s some number times a power telling
you where to put the decimal point, which is
00:04:17
exactly what they look like under the hood.
The actual number is stored with binary
00:04:21
fractions. Some fractions like 1/3 can only be
approximated in binary with an infinite sum, but,
00:04:26
since memory is not infinite, you have to cut it
off at some point, which leads to rounding errors,
00:04:30
causing pretty weird calculations, sometimes.
If these are not enough, long and double
00:04:33
use twice the amount of memory to
double the range of ints and floats.
00:04:36
Some languages like Python automatically
figure out which type a variable is,
00:04:40
but in a language like C, you have to
explicitly declare the type of a variable.
00:04:44
The value of a variable is stored at some
address in memory. Pointers are variables whose
00:04:47
value is the memory address of another variable,
which is denoted by this ampersand. So really,
00:04:52
a pointer is just some chunk of memory,
pointing to another chunk of memory.
00:04:55
Since a memory address is just a number,
you can add and subtract from it to navigate
00:04:58
through individual bytes of memory.
This is called “pointer arithmetic”.
00:05:01
In some low-level languages like C, you have to
manually allocate and free up memory once it’s
00:05:05
no longer used. This all happens in the heap,
which is a part of memory that can dynamically
00:05:09
grow and shrink as the program demands,
which allows for more control but makes in
00:05:12
incredibly easy to completely break your code.
You could touch memory you’re not supposed to,
00:05:16
or that simply doesn’t exist, which is known as
a “segmentation fault”. But also, if there’s some
00:05:20
chunk of memory that’s no longer used, and you
forget to free it or you have no way to access
00:05:23
it anymore, that memory is no longer usable.
This is called a “memory leak” and will make
00:05:27
the program slow down and eventually crash.
To avoid this mess, high level languages
00:05:31
like Python have built in garbage
collectors that manage memory for you.
00:05:34
Different data types take up a different amount of
memory. Integers are most often 4 bytes of memory.
00:05:39
A single character is most often one
byte of memory, and a string is just
00:05:42
multiple character bytes, with a “NUL”
character to signal the end of the string.
00:05:45
Storing multiple items in a contiguous chunk
of memory like this is the idea of an array:
00:05:49
More generally, it’s a list of
items with the same data type,
00:05:51
with each item having a numerical index, most
often starting at 0. Since the items are next
00:05:56
to each other in memory, by knowing the address
of the first item, you can quickly index to any
00:06:00
item in the array by using pointer arithmetic.
Arrays are what’s known as a data structure,
00:06:04
which is just a way to organize
data to make it easier to work with.
00:06:07
Retrieving values from an array is blazingly
fast, but the size of an array is often fixed
00:06:11
when creating it, so when it’s full, you can’t
add anything, and if you don’t use all of it,
00:06:15
it’s just wasted memory, so a more
flexible option is a linked list.
00:06:18
It uses nodes containing a value
and a pointer to the next node,
00:06:21
which allows them to be spread apart in memory.
Also, it can grow and shrink dynamically,
00:06:24
as you can add and remove any node, and you can
reorder it, by simply rearranging the pointers.
00:06:29
This is great, but they can be impractical, as
you have no way to access the last node except
00:06:32
if you traverse every single one before it. But
still, both arrays and liked lists are useful,
00:06:37
as they allow you to create queues and stacks.
A stack follows the last in, first out principle,
00:06:41
just like taking a pancake from a stack.
Practically, just imagine a pointer that
00:06:45
always points to the item that was last added
to the structure. Then you can pop, so remove
00:06:49
the last item which increments the pointer back.
A queue follows the first in first out principle
00:06:53
and uses two pointers, one for
the first item that was added,
00:06:56
and one for the last. Any new item gets added
after the last pointer, which is then updated,
00:07:00
and dequeuing starts at the first pointer.
Another useful data structure is a hash map,
00:07:04
which is just a collection of key value pairs.
It works kind of like an array but uses a hash
00:07:08
function to take a key and assign it to
an index, where its value is then stored.
00:07:12
But sometimes, two different keys can map to the
same index, which is called a “collision”. There’s
00:07:16
different ways to deal with this, but one way is
to create a linked list at that position in the
00:07:19
array, which makes it a little slower to look up
that value, but still, hash maps are incredibly
00:07:24
useful, because you can define the keys that point
to every value, and since they’re based on arrays,
00:07:28
retrieving them is blazingly fast.
For many problems, it can be very
00:07:31
useful to represent the relationship between
different datapoints as a data structure.
00:07:35
If you take the nodes of a linked list, but
allow any node to point to any other node,
00:07:38
you get a graph, where the nodes are
connected by edges that can be directed,
00:07:42
undirected and can even carry a weight, which can
stand for any metric, such as distance or cost.
00:07:46
Graphs are useful for analyzing groups inside
networks or finding the shortest path between two
00:07:50
points, for example in Google Maps. There’s two
main ways to search a graph: Breadth first search,
00:07:55
starts at one node and moves out layer by
layer until it finds the target node for the
00:07:58
first time. Depth first search explores every
single path fully until it reaches a dead end,
00:08:02
then it backtracks to the last node with a
different path and continues from there in
00:08:05
the same way until it finds the target node.
A graph where any two nodes are connected by
00:08:10
exactly one path is called a tree, and represents
a hierarchy, for example the file system on your
00:08:14
computer. A tree starts at the root and branches
out into subtrees, which end in leaf nodes.
00:08:18
Parent nodes can have any number of child
nodes, but oftentimes, binary trees are the
00:08:22
most useful. For example, a binary tree where
all the values left of any node are smaller,
00:08:26
and all the values right of it are greater,
is called a “binary search tree”, which makes
00:08:29
finding specific values super fast.
If you want to find a target value, just
00:08:33
start at the root. If the target is smaller than
that node , go left, if it’s greater, go right,
00:08:37
and repeat this until you find the target.
What we just used is a very simple algorithm,
00:08:41
which is just a set of instructions
that solves a problem step by step.
00:08:44
The simplest way to write an algorithm is
in the form of a function. It takes inputs,
00:08:48
does something with them, and returns an output.
Just like variables, you can then call a function
00:08:52
by its name and pass in different arguments.
When calling a function, the function call
00:08:55
gets pushed onto the call stack, which is
short-term memory used for executing code,
00:08:59
and as the name implies, it’s based on the stack
data structure, which means last in first out.
00:09:03
To implement algorithms, you often have to
compare two values, which you can do with
00:09:06
operators like greater than or equality, and
logical expressions such as AND, OR and NOT.
00:09:11
Expressions like these are simple:
they can be true or false, which are
00:09:14
the possible values of the Boolean data type
and allow you to write conditional statements:
00:09:18
If some condition is true, do this, else do that.
Booleans can also be used to loop over certain
00:09:24
parts of code. One way is with a while loop: While
this condition is true, this code will execute.
00:09:28
Another way is a for loop, which can iterate
over every element inside a data structure
00:09:32
like an array, but can also loop for a specific
number of iterations, by setting a starting value,
00:09:36
incrementing it after each iteration, and
setting an upper bound with a condition.
00:09:40
Functions can also call themselves, which is known
as “recursion”. This is useful when a problem
00:09:44
can be broken down into smaller identical
problems, such as calculating 5 factorial,
00:09:48
which is just 5 times 4 factorial, which
is just 4 times 3 factorial and so on.
00:09:51
But, by default, a recursive function will
just keep on calling itself forever. This
00:09:55
means that it keeps pushing more function
calls onto the call stack, until the stack
00:09:58
memory is exceeded in a “stack overflow”.
To stop this, you have to add a base condition
00:10:03
to a recursive function, which defines when
to stop. Only then will the function calls
00:10:07
be executed without crashing your PC.
Recursion is cool, but it can be pretty
00:10:11
expensive time and spacewise. So, to minimize the
amount of computations needed, past results can be
00:10:15
saved in a cache, so if they come up again,
the computer doesn’t have to recompute them
00:10:19
from scratch. This is called “memoization”.
Speaking of performance, to judge how good
00:10:23
an algorithm is, you can look at time and
space complexity, so how much time or space
00:10:27
is required to run it. This is measured in Big
O notation, which describes the relationship
00:10:30
between growth of input size and number of
operations needed to execute the algorithm.
00:10:34
For example, adding 1 to every number inside an
array is O(n), because the number of operations
00:10:39
increases in a linear way as the array grows.
What’s relevant is not the exact number of
00:10:43
operations, but rather the trend as the the input
size goes to infinity. You see, something like n!
00:10:48
grows way faster than any linear function ever
could, so as long as the time complexity is some
00:10:53
kind of linear relation, it’s simplified down to
O(n), and the same thing goes for any other group.
00:10:57
When writing algorithms, there’s some general
approaches: For example, when searching an item
00:11:00
in a list, a brute force approach would be to
simply check every item until we find the target,
00:11:04
but a more sophisticated approach would be divide
and conquer. For example, in binary search,
00:11:10
you cut the problem in half each time by checking
the middle element of a list and seeing on which
00:11:12
side the target is until you land on the target.
Now, when solving a problem with code, there’s
00:11:17
always multiple ways to achieve the same result,
which are called programming paradigms. Let’s try
00:11:20
to find the sum of all elements in this list.
“Declarative programming”, describes what the
00:11:22
code does, but not how exactly the computer
should do it, whereas “Imperative programming”
00:11:26
explicitly describes how the computer should
achieve a result with detailed instructions.
00:11:30
An extension of imperative programming is
object-oriented programming, where you can
00:11:33
define classes as blueprints for objects, which
are single units consisting of data in the form of
00:11:38
properties and behaviours in the form of methods.
To code a call, you begin by defining the
00:11:42
properties as variables, and
the methods as functions.
00:11:45
After encapsulating properties and methods
in a class, you can instantiate an object
00:11:49
and use the dot notation to work
with its properties and methods.
00:11:52
Classes make it easy to organize and reuse code,
because you can define subclasses that inherit
00:11:56
properties and behaviours of a superclass,
but can also extend and override them.
00:12:00
For example, a RubberDuck subclass might implement
quack() with a squeak(), instead. As a result,
00:12:05
rubber rucks can be treated as objects of the
Duck class, but behave differently when quack()
00:12:08
is called, which is the concept of “polymorphism”.
But for some problems, none of these traditional
00:12:13
paradigms will work.
Let’s say you want to make
00:12:15
a computer recognize which of these images
is a bee. The problem is, you can’t really
00:12:19
describe what a bee looks like with code.
This is where machine learning comes in,
00:12:22
aka teaching a computer to do a task without
explicitly programming it to do that task.
00:12:27
First you need a lot of data which
you split into training and test data.
00:12:31
Next you choose an algorithm that
can change its parameters over time,
00:12:34
for example a neural network, where the weights
can be updated to achieve a different result. By
00:12:38
feeding lots and lots of training data into
this algorithm you can build a model, whose
00:12:42
accuracy you can then check with the test data.
If it’s not quite right, the model can improve
00:12:46
over time by comparing the output to what it
should have been, capturing the difference
00:12:49
in an error function, and tweaking its
parameters to minimize the difference.
00:12:52
But no matter how futuristic, bleeding-edge,
blazingly fast and optimized it is, if you
00:12:57
want people to actually use the application
you wrote, you should probably know about
00:13:00
the internet. It’s a network of computers from
all around the globe connected by wires. Like,
00:13:04
literally, the internet is a bunch of thicc
cables that run at the bottom of the ocean
00:13:08
along with facilities like Internet Service
Providers that connect you to your destination.
00:13:12
These computers communicate with the Internet
Protocol Suite. Every computer on the network
00:13:16
has a unique IP address. Two computers can
then transfer data with the transmission
00:13:19
control protocol. It breaks messages into a bunch
of packets, sends them through a network of wires,
00:13:24
before the receiving end puts the message back
together. If you have a poor internet connection,
00:13:27
you might have experienced “packet loss”, which is
just if some these packets get lost along the way.
00:13:31
If the internet is the hardware, then the web is
the software, which you can use with a browser.
00:13:36
Every page on the web has a URL. When you type it
into your browser, it looks up the IP address of
00:13:40
the server hosting this website with the domain
name system, which is like a dictionary mapping
00:13:44
domain names to IP addresses of actual servers.
After connecting to it via TCP, your browser,
00:13:49
called the client, uses the hypertext transfer
protocol to send an http request to the server,
00:13:53
which then gives a response, ideally
containing the contents of the webpage.
00:13:57
The actual website most often consists of three
parts: An HTML file contains all the content of
00:14:01
a website and is basically just a collection of
elements, which can be text, links, buttons and
00:14:05
so on. A CSS file controls the visuals and makes
a website look nice. But, a website is useless if
00:14:10
pressing nice looking buttons does nothing, so
a language like JavaScript adds functionality.
00:14:15
But sometimes things can go wrong. With
every http response comes a response code,
00:14:19
which carries information about the status
of the response. For example, 200 means “OK”,
00:14:23
and anything starting with 4 is an error, the
most famous one being “404 – page not found”.
00:14:28
HTTP requests can carry different methods, for
example GET, POST, PUT and DELETE, so retrieve,
00:14:33
add, update and delete information. These are
often used by Application Programming Interfaces,
00:14:38
which connect two applications and allow
them to interact with each other, for
00:14:41
example store and retrieve data from a database.
The most common type of database is a relational
00:14:46
database, which uses tables to store data.
Columns of a table contain different attributes,
00:14:50
and rows represent individual datapoints.
Also, each table has one unique attribute
00:14:55
called the primary key. A foreign key
is the primary key of another table,
00:14:59
establishing a relationship between the two. In
this case, each book is connected to an author.
00:15:03
With a language like SQL, you can write statements
to work with data from these tables. You could
00:15:07
look up the titles and authors of all books,
whose title starts with “H”, but for that,
00:15:11
we have to join the authors table with
the books table on the matching key to
00:15:15
combine two attributes from different
tables into one, giving us this output.
00:15:19
These statements are useful, but you’ve got
to be careful, or you might just delete an
00:15:22
entire database with one line of code. But,
don’t worry. That’s never happened before.
00:15:27
Behind every login page is a database with
usernames and passwords. When a user tries to
00:15:31
log in, an SQL query is often used to check if the
user input matches with an entry in the database.
00:15:36
That’s good, but, a devious actor could type
something like this, which changes the query by
00:15:41
terminating the string early and commenting out
the rest, which means as long as this username
00:15:45
exists in the database, access is granted.
This is called an SQL injection attack and
00:15:49
is one of the easiest ways hackers
get places they’re not supposed to.
00:16:03
Hearing about all these concepts is
one thing, but to really learn them,
00:16:06
you have to see them in action and use
them yourself, which is exactly what you
00:16:09
can do with Brilliant, which has thousands
of interactive lessons for everything from
00:16:12
math and data science to programming and AI.
They make knowledge stick with visual lessons
00:16:16
and interactive problems, which is not only fun
and builds intuitive problem solving skills,
00:16:20
but also proven to be 6x more effective
than simply watching hours of lectures.
00:16:24
I know that making time to learn new skills can be
difficult, but Brilliant makes it so easy: You can
00:16:29
build valuable knowledge from the ground up in
just a couple of minutes a day with bite-sized
00:16:32
lessons from any device, anywhere, anytime.
You’ll go from the basics of data science
00:16:36
to analysing real datasets from
Spotify in absolutely no time,
00:16:40
which you can supplement with math fundamentals
and programming courses in Python to build one
00:16:43
of the most in demand skillsets of our time.
The best part? You can try everything Brilliant
00:16:47
has to offer for free for a full 30 days, by
visiting brilliant.org/WackyScience/. You’ll
00:16:52
also get 20% off an annual premium subscription.
Thanks to Brilliant for sponsoring this video.