<commit_before>## Chapter 1


### Compilation

1) Give an example of a feature common in interpreted languages that is rare in compiled languages.

Dynamic types are supported by interpreted languages, but not in compiled languages.

2) Name two advantages of static typing over dynamic typing.

allows you to catch errors before you run your code, safer than runtime erros

3) Give an example of a static semantic error.

errors that can be checked without actually understanding the program

4) What are two reasons you might want to turn off code optimization?

can change bugs and make them "appear or disappear", cut down on compile time

5) When you run `gcc` with `-S`, why might the results look different on different computers?

assembly code, looks different with different architechtures

6) If you spell a variable name wrong, or if you spell a function name wrong, the error messages you get might look very different.  Why?

so that you can understand what you did wrong.


7) What is a segmentation fault?

if you try to read or write an incorrect location in memory

## Chapter 2


### Processes

1) Give a real-world example of virtualization (ideally not one of the ones in the book).

The Netflix Delivery service makes it seem like I have access to every DVD out there, but those same DVDs are also brought to countless other people.

2) What is the difference between a program and a process?

A process is a software object that represents a running program and a program. All of the information that a program uses is stored in a data structure that is a process.

3) What is the primary purpose of the process abstraction?  What illusion does the process abstraction create?

The primary purpose of abstraction is so that users can interact with complex systems without knowing all of the details. This abstraction creates the illusion that there are a ton of CPUs and that the network that a machine is on is all of the networks.

4) What is the kernel?

The kernel is the part of the operating system that creates most of the core capabilities, like threading.

5) What is a daemon?

A daemon is a process that runs in the background and provides operating system services.

## Chapter 3


### Virtual memory
## Chapter 3


### Virtual memory

1) The Georgian alphabet has 33 letters.  How many bit are needed to specify a letter?

log233

2) In the UTF-16 character encoding, the binary representation of a character can take up to 32 bits. Ignoring the details of the encoding scheme, how many different characters can be represented?

4294967296

3) What is the difference between "memory" and "storage" as defined in Think OS?

Memory is used to store short-term data, typically kept in the RAM, and is volatile, so it is lost when the computer shuts down. Storage is used for long-term storage, kept in the physical drive, and non-volatile.

4) What is the difference between a GiB and a GB?  What is the percentage difference in their sizes?

A GiB is a gibibyte and a GB is a gigabyte, 2^30 and 10^9 bytes respectively. They have a 7% difference in size.

5) How does the virtual memory system help isolate processes from each other?

"a process cannot access data belonging to another process, because there is no virtual address it can generate that maps to physical memory allocated to another proces"

6) Why do you think the stack and the heap are usually located at opposite ends of the address space?

This allows them to grow in directions away from each other as they expand.

7) What Python data structure would you use to represent a sparse array?

Dictionary

8) What is a context switch?

A context switch is the mechanism that allows the operating system to to interrupt a running process, save its state, and run another process.

In this directory, you should find a subdirectory named `aspace` that contains `aspace.c`.  Run it on your computer and compare your results to mine.

Address of main is 0x40057d
Address of global is 0x60104c
Address of local is 0x7fffa0899044
Address of p is 0x2463010
  
1) Add a second call to `malloc` and check whether the heap on your system grows up (toward larger addresses).

Yes

2) Add a function that prints the address of a local variable, and check whether the stack grows down. 

No

3) Choose a random number between 1 and 32, and allocate two chunks with that size.  
How much space is there between them?  Hint: Google knows how to subtract hexadecimal numbers.

32 in decimal and 0x20 in hexadecimal


## Chapter 4


### Files and file systems

1) What abstractions do file systems provide?  Give an example of something that is logically true about files systems but not true of their implementations.

File systems provide the abstraction that a file's name maps to its contents and that files are a sequence of bytes. Abstractly, file systems are byte-based, whereas the actual implementation of persistent storage is block-based.

2) What information do you imagine is stored in an `OpenFileTableEntry`?

The state of the file, or metadata about the file. Could be a pointer to the current file location or the main data stored on the file.

3) What are some of the ways operating systems deal with the relatively slow performance of persistent storage?

Running other processes while waiting for a new block to be stored in memory, reading multiple blocks at once, prediciting future block reads and begin loading before requested, storing written files in memory and later writting to a disk which allows for file modification before block loading, and the os also keeps a copy of recently used blocks in memory allowing for faster use.

4) Suppose your program writes a file and prints a message indicating that it is done writing. Then a power cut crashes your computer.  After you restore power and reboot the computer, you find that the file you wrote is not there.  What happened?

The file was still in the stages of buffering. When a program write a file, the OS stores that in memory and writes it onto a block later. This is done for the sake of efficiency, but it is not great in this situation.

5) Can you think of one advantage of a File Allocation Table over a UNIX inode?  Or an advantage of a inode over a FAT?

A FAT can find empty files to be written faster than a UNIX inode, but because the files are not held continuously they are slower. I used [this resource](http://web.cs.ucla.edu/classes/fall10/cs111/scribe/11a/)

6) What is overhead?  What is fragmentation?

Overhead is the amount of space that the data allocator uses. Framentation is chunks of unused space.

7) Why is the "everything is a file" principle a good idea?  Why might it be a bad idea?

It allows for abstraction in other systems which can make them easier to understand and work with because you don't have to understand the small details. It could be bad because it might not be true for everything and might cause certain errors.

If you would like to learn more about file systems, a good next step is to learn about journaling file systems.  
Start with [this Wikipedia article](https://en.wikipedia.org/wiki/Journaling_file_system), then 
[Anatomy of Linux Journaling File Systems](http://www.ibm.com/developerworks/library/l-journaling-filesystems/index.html).  
Also consider reading [this USENIX paper](https://www.usenix.org/legacy/event/usenix05/tech/general/full_papers/prabhakaran/prabhakaran.pdf).


## Chapter 5


### Bits and bytes

1) Suppose you have the value 128 stored as an unsigned 8-bit number.  What happens if you convert 
it to a 16-bit number and accidentally apply sign extension?

2) Write a C expression that computes the two's complement of 12 using the XOR bitwise operator. 
Try it out and confirm that the result is interpreted as -12.

3) Can you guess why IEEE floating-point uses biased integers to represent the exponent rather than a
sign bit or two's complement?

4) Following the example in Section 5.4, write the 32-bit binary representation of -13 in single precision 
IEEE floating-point.  What would you get if you accidentally interpreted this value as an integer?

5) Write a function that takes a string and converts from lower-case to upper-case by flipping the sixth bit.  
As a challenge, you can make a faster version by reading the string 32 or 64 bits at a time, rather than one
character at a time.  This optimization is made easier if the length of the string is a multiple of 4 or 8 bytes.



## Chapter 6<commit_msg>Update thinkos.md<commit_after>## Chapter 1


### Compilation

1) Give an example of a feature common in interpreted languages that is rare in compiled languages.

Dynamic types are supported by interpreted languages, but not in compiled languages.

2) Name two advantages of static typing over dynamic typing.

allows you to catch errors before you run your code, safer than runtime erros

3) Give an example of a static semantic error.

errors that can be checked without actually understanding the program

4) What are two reasons you might want to turn off code optimization?

can change bugs and make them "appear or disappear", cut down on compile time

5) When you run `gcc` with `-S`, why might the results look different on different computers?

assembly code, looks different with different architechtures

6) If you spell a variable name wrong, or if you spell a function name wrong, the error messages you get might look very different.  Why?

so that you can understand what you did wrong.


7) What is a segmentation fault?

if you try to read or write an incorrect location in memory

## Chapter 2


### Processes

1) Give a real-world example of virtualization (ideally not one of the ones in the book).

The Netflix Delivery service makes it seem like I have access to every DVD out there, but those same DVDs are also brought to countless other people.

2) What is the difference between a program and a process?

A process is a software object that represents a running program and a program. All of the information that a program uses is stored in a data structure that is a process.

3) What is the primary purpose of the process abstraction?  What illusion does the process abstraction create?

The primary purpose of abstraction is so that users can interact with complex systems without knowing all of the details. This abstraction creates the illusion that there are a ton of CPUs and that the network that a machine is on is all of the networks.

4) What is the kernel?

The kernel is the part of the operating system that creates most of the core capabilities, like threading.

5) What is a daemon?

A daemon is a process that runs in the background and provides operating system services.

## Chapter 3


### Virtual memory
## Chapter 3


### Virtual memory

1) The Georgian alphabet has 33 letters.  How many bit are needed to specify a letter?

log233

2) In the UTF-16 character encoding, the binary representation of a character can take up to 32 bits. Ignoring the details of the encoding scheme, how many different characters can be represented?

4294967296

3) What is the difference between "memory" and "storage" as defined in Think OS?

Memory is used to store short-term data, typically kept in the RAM, and is volatile, so it is lost when the computer shuts down. Storage is used for long-term storage, kept in the physical drive, and non-volatile.

4) What is the difference between a GiB and a GB?  What is the percentage difference in their sizes?

A GiB is a gibibyte and a GB is a gigabyte, 2^30 and 10^9 bytes respectively. They have a 7% difference in size.

5) How does the virtual memory system help isolate processes from each other?

"a process cannot access data belonging to another process, because there is no virtual address it can generate that maps to physical memory allocated to another proces"

6) Why do you think the stack and the heap are usually located at opposite ends of the address space?

This allows them to grow in directions away from each other as they expand.

7) What Python data structure would you use to represent a sparse array?

Dictionary

8) What is a context switch?

A context switch is the mechanism that allows the operating system to to interrupt a running process, save its state, and run another process.

In this directory, you should find a subdirectory named `aspace` that contains `aspace.c`.  Run it on your computer and compare your results to mine.

Address of main is 0x40057d
Address of global is 0x60104c
Address of local is 0x7fffa0899044
Address of p is 0x2463010
  
1) Add a second call to `malloc` and check whether the heap on your system grows up (toward larger addresses).

Yes

2) Add a function that prints the address of a local variable, and check whether the stack grows down. 

No

3) Choose a random number between 1 and 32, and allocate two chunks with that size.  
How much space is there between them?  Hint: Google knows how to subtract hexadecimal numbers.

32 in decimal and 0x20 in hexadecimal


## Chapter 4


### Files and file systems

1) What abstractions do file systems provide?  Give an example of something that is logically true about files systems but not true of their implementations.

File systems provide the abstraction that a file's name maps to its contents and that files are a sequence of bytes. Abstractly, file systems are byte-based, whereas the actual implementation of persistent storage is block-based.

2) What information do you imagine is stored in an `OpenFileTableEntry`?

The state of the file, or metadata about the file. Could be a pointer to the current file location or the main data stored on the file.

3) What are some of the ways operating systems deal with the relatively slow performance of persistent storage?

Running other processes while waiting for a new block to be stored in memory, reading multiple blocks at once, prediciting future block reads and begin loading before requested, storing written files in memory and later writting to a disk which allows for file modification before block loading, and the os also keeps a copy of recently used blocks in memory allowing for faster use.

4) Suppose your program writes a file and prints a message indicating that it is done writing. Then a power cut crashes your computer.  After you restore power and reboot the computer, you find that the file you wrote is not there.  What happened?

The file was still in the stages of buffering. When a program write a file, the OS stores that in memory and writes it onto a block later. This is done for the sake of efficiency, but it is not great in this situation.

5) Can you think of one advantage of a File Allocation Table over a UNIX inode?  Or an advantage of a inode over a FAT?

A FAT can find empty files to be written faster than a UNIX inode, but because the files are not held continuously they are slower. I used [this resource](http://web.cs.ucla.edu/classes/fall10/cs111/scribe/11a/)

6) What is overhead?  What is fragmentation?

Overhead is the amount of space that the data allocator uses. Framentation is chunks of unused space.

7) Why is the "everything is a file" principle a good idea?  Why might it be a bad idea?

It allows for abstraction in other systems which can make them easier to understand and work with because you don't have to understand the small details. It could be bad because it might not be true for everything and might cause certain errors.

If you would like to learn more about file systems, a good next step is to learn about journaling file systems.  
Start with [this Wikipedia article](https://en.wikipedia.org/wiki/Journaling_file_system), then 
[Anatomy of Linux Journaling File Systems](http://www.ibm.com/developerworks/library/l-journaling-filesystems/index.html).  
Also consider reading [this USENIX paper](https://www.usenix.org/legacy/event/usenix05/tech/general/full_papers/prabhakaran/prabhakaran.pdf).


## Chapter 5


### Bits and bytes

1) Suppose you have the value 128 stored as an unsigned 8-bit number.  What happens if you convert it to a 16-bit number and accidentally apply sign extension?

Nothing should change about the number other than the number of bits. Because unsigned numbers are assumed positive, a sign extension would only add more 0's.

2) Write a C expression that computes the two's complement of 12 using the XOR bitwise operator. Try it out and confirm that the result is interpreted as -12.

PUT LINK HERE

3) Can you guess why IEEE floating-point uses biased integers to represent the exponent rather than a sign bit or two's complement?

4) Following the example in Section 5.4, write the 32-bit binary representation of -13 in single precision IEEE floating-point.  What would you get if you accidentally interpreted this value as an integer?

5) Write a function that takes a string and converts from lower-case to upper-case by flipping the sixth bit. As a challenge, you can make a faster version by reading the string 32 or 64 bits at a time, rather than one character at a time.  This optimization is made easier if the length of the string is a multiple of 4 or 8 bytes.



## Chapter 6
{'fraction_non_alphanumeric': 0.03650700934579439, 'fraction_numerical': 0.01594626168224299, 'mean_word_length': 4.146077547339946, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 4, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3839335', 'n_tokens_mistral': 4396, 'n_tokens_neox': 4114, 'n_words': 2835}