Kindle Notes & Highlights
Read between
February 22 - April 5, 2021
Temporal Locality: when a memory address is accessed, it's probable it will be accessed again soon. • Spatial Locality: when a memory address is accessed, it's probable addresses that are adjacent to it are going to be accessed soon.
It's possible to build an extremely fast auxiliary memory, integrated with the CPU. We call it the L1 cache.
After the L1 cache is about 50 KB in size, further increasing it gets very expensive. The better solution is to build an additional memory cache: the L2 cache. By allowing it to be slower, it can be much larger than the L1 cache. A modern CPU will have about 200 KB of L2 cache.
Many manufacturers are now shipping processors with an L3 cache: larger and slower than the L2, but still faster than the RAM. The L1/L2/L3 caches are so important they take up most of the silicon space inside a CPU chip.
Next time you go buy a computer, remember to compare the different sizes of L1/L2/L3 caches of the CPUs you're looking at. Better CPUs will have larger caches. It's often better to get a CPU with a slower clock but larger cache.
The RAM memory is often called primary memory, whereas programs and data stored in the disk are said to be in secondary memory.
The CPU cannot directly access secondary memory. Prior to execution, programs stored in the secondary memory must be copied to the primary memory. In fact, each time you boot your computer, even your operating system has to be copied from the disk to the RAM before the CPU can run it.
It's important to ensure all the data and programs a computer handles during typical activity can fit in its RAM.
When a computer is constantly getting data from the disk into RAM, we say that it's in thrashing mode.
If connected to a network, a computer can access memory managed by other computers, either in the local network or on the Internet (aka in the cloud).
Tertiary storage is only suitable for archiving data you'll rarely need to access.
Some manufacturers are producing hybrid disks with both SSD and magnetic technology. The frequently accessed data is stored in the SSD, and the less frequently accessed data is kept in the slower magnetic part.
Computers can do complex computations simply because of the massive amount of basic operations their CPUs can do.
The caching principle discussed in this chapter can be applied to many scenarios. Identifying parts of data more frequently used by your application and making this data faster to access is one of the most used strategies to make computer programs run faster.
For now, only coders have the power to instruct a machine on what to do without constraints. And as your knowledge of programming languages deepens, your power as a coder grows.
Programming languages differ wildly, but all of them exist to do one thing: manipulate information. These languages rely on three basic building blocks to do this. A value represents information. An expression produces a value. A statement uses a value to give an instruction to a computer.
You can create a value in two ways: either by writing a literal, or by calling a function.
Functions, on the other hand, will generate a value following a method or procedure that's coded somewhere else.
An operator can join simple expressions to form more complex ones.
In fact, an expression is anything you write that the computer will be able to reduce to a single value. Big expressions can be combined with other expressions through operators, forming even larger expressions. In the end, even the most complex expression must always evaluate to a single value.
Parentheses allows control over operator precedence:
While an expression is used to represent a value, a statement is used to instruct the computer to do something.
Programming languages have special statements, called definitions. They change the state of a program by adding an entity that didn't exist, like a new value or function.2 To refer to an entity we defined, we need to associate a name to it. That's called name binding.
A variable associates a name to the memory address where a value is stored, serving as an "alias".
Some languages even require you to declare a name as a variable, before it is defined.
This statement reserves a memory block, writes the value 3.142 in it, and associates the name "pi" to the memory block's address.
In most programming languages, variables must have an assigned type (e.g. integer, float, or string). This way, the program knows how it should interpret the 1s and 0s it reads in the variable's memory block.
Some languages prefer checking types dynamically. With dynamic type checking, any variable can store any type of value, so no type declaration is required.
As programs get bigger, the same names of variables (such as time, length, or speed) might end up being used in unrelated parts of the code.
To avoid collisions, names bindings are not valid over the entire source code. The variable's scope defines where it is valid and can be used.
The current context, or environment, is the set of all name bindings that are available in a program at a given point.
you can bypass this rule and create variables that are always accessible anywhere in your program. These are called global variables.
The collection of all names available globally consists of your namespace.
A paradigm is a specific collection of concepts and practices that define a field of science. A paradigm will orientate how you approach a problem, the techniques you use, and the structure of your solution.
programming paradigm is a point of view of the coding realm. It will direct your coding style and technique.
There are three main programming paradigms: imperative, declarative, and logic.
Knowing about all three is important, because it will enable you to benefit from the features and opportunities each programming language offers. This way, you'll be able to code with maximum effectiveness.
The imperative programming paradigm is about instructing the computer on what it must do exactly at each step using specific commands.
It's also a natural extension of the way humans work: we use this paradigm to describe a cooking recipe, a car repair routine, and other everyday procedures.
ASM is used to program systems such as an electronic microwave, or the computer system in a car. This programming style is also used on sections of code where extreme performance is needed, where saving even a few CPU cycles is relevant.
In 1968, Dijkstra wrote his famous manifesto "GOTO Statement Considered Harmful", and it ushered a revolution. Code began to be separated in logical parts. Instead of ad-hoc GOTOs, programmers began to use control structures (if, else, while, for…). That enabled programs to be much more easily written and debugged.
The next advance in the art of coding was procedural programming. It allows code to be organized into procedures, to avoid code replication and to increase code reusability.
The declarative programming paradigm makes you state your desired result without dealing with every single intricate step that gets you there.
That's called a syntactic sugar: added syntax that lets you write expressions in simpler and shorter forms. Many programming languages provide several forms of syntactic sugar for you. Use them and abuse them.
Higher-order functions don't just receive functions as inputs—they can also produce new functions as outputs. They're even able to enclose a reference to a value into the function they generate. We call that a closure. A function that has a closure "remembers" stuff and can access the environment of its enclosed values.
Whenever your problem is the solution to a set of logical formulas, you can use logic programming.
The greatest advantage of the logical programming paradigm is that programming itself is kept to a minimum. Only facts, statements and queries are presented to the computer. The computer is in charge of finding the best way to search the solution space and present the results. This paradigm isn't very well used in the mainstream, but if you find yourself working with artificial intelligence, natural language processing, remember to look into this.
There are some important topics in computer science that are notably absent from this
. We normally use d = 10 because we have ten
The number 4,321 in different

