add: slices: last 3 quizzes
This commit is contained in:
@ -1,67 +0,0 @@
|
||||
full slice exp
|
||||
make
|
||||
copy
|
||||
|
||||
# Slice Internals Quiz
|
||||
|
||||
## Where does a slice value stores its elements?
|
||||
1. In the global backing array that is shared by all the slices
|
||||
2. In a separate backing array that a slice value points to *CORRECT*
|
||||
3. In the slice value itself (like an array)
|
||||
|
||||
> **1:** There isn't something called the global backing array.
|
||||
>
|
||||
> **2:** That's right. A slice doesn't store any elements direcly. It points to an array that is stored separately on the computer memory, and a slice points to that array, a slice is just a window to that array.
|
||||
>
|
||||
> **3:** A slice values doesn't store any elements by itself. It's just a description of its backing array.
|
||||
|
||||
|
||||
## What's a backing array?
|
||||
1. An array of trustworthy friends that you can count on always
|
||||
2. An array that is stored in the slice value
|
||||
3. A slice value stores its elements in it *CORRECT*
|
||||
|
||||
> **1:** Oh, come on!
|
||||
>
|
||||
> **2:** Nope, a slice value doesn't store its backing array, the slice value just points to it. The backing array is stored separately from the slice value.
|
||||
|
||||
|
||||
## What does this program print?
|
||||
```go
|
||||
nums := []int{10, 15, 10, 2, 3, 4}
|
||||
digits := nums[len(nums)-3:]
|
||||
|
||||
nums[len(nums)-1] = 8
|
||||
digits[0] += nums[3]
|
||||
|
||||
fmt.Println(digits)
|
||||
```
|
||||
1. [2 3 4]
|
||||
2. [4 3 4]
|
||||
3. [4 3 8] *CORRECT*
|
||||
4. [10 15 10]
|
||||
5. [4 15 8]
|
||||
|
||||
> **3:** Awesome! At first, digits is [2 3 4]. After `nums[len(nums)-1] = 8`, the digits becomes [2 3 8] (it's because, digits is created by slicing the nums slice, so they share the same backing array). And lastly, after `digits[0] += nums[3]`, the digits becomes [4 3 8].
|
||||
|
||||
|
||||
## Find the correct explanation below
|
||||
1. A slice variable can store a slice value and the slice value is actually a slice header behind the scenes *CORRECT*
|
||||
2. A slice variable can only store the same slice value and it cannot be changed afterward
|
||||
3. A slice header stores the slice value
|
||||
|
||||
> **1:** That's right. You can change the slice values that is being stored in a slice variable, and the slice value is actually a slice header behind the scenes.
|
||||
>
|
||||
> **3:** Nope, actually a slice header and a slice value is the same thing.
|
||||
|
||||
|
||||
* after slicing, does it copy all the values to the new slice?
|
||||
* why indexing a slice is fast? (array is contagious on memory)
|
||||
* separate backing arrays question
|
||||
* sliced array share the same explicit array
|
||||
|
||||
##
|
||||
backing array
|
||||
slice header
|
||||
capacity
|
||||
append mechanics
|
73
16-slices/questions/6-capacity.md
Normal file
73
16-slices/questions/6-capacity.md
Normal file
@ -0,0 +1,73 @@
|
||||
# Capacity and Append Mechanics Quiz
|
||||
|
||||
## What is the difference between the length and capacity of a slice?
|
||||
1. They are the same
|
||||
2. The length is always greater than the capacity
|
||||
3. The capacity is always greater than the capacity
|
||||
4. The length describes the length of a slice but a capacity describes the length of the backing array beginning from the first element of the slice *CORRECT*
|
||||
|
||||
> **2:** The length is never greater than the capacity.
|
||||
>
|
||||
> **3:** The length and capacity of a slice can be equal.
|
||||
|
||||
|
||||
## What is the capacity of a nil slice?
|
||||
1. It is equal to its length + 1
|
||||
2. It is nil
|
||||
3. 0 *CORRECT*
|
||||
4. 1
|
||||
|
||||
> **2:** The capacity's type is int, it cannot be nil.
|
||||
|
||||
|
||||
## What are the length and capacity of the slice value?
|
||||
```go
|
||||
[]string{"i", "have", "a", "great", "capacity"}
|
||||
```
|
||||
1. Length: 5 - Capacity: 5 *CORRECT*
|
||||
2. Length: 0 - Capacity: 5
|
||||
3. Length: 5 - Capacity: 10
|
||||
4. Length: 10 - Capacity: 10
|
||||
|
||||
> **1:** That's right! A slice literal creates a new slice value with equal length and capacity.
|
||||
|
||||
|
||||
## What are the length and capacity of the 'words' slice?
|
||||
```go
|
||||
words := []string{"lucy", "in", "the", "sky", "with", "diamonds"}
|
||||
words = words[:0]
|
||||
```
|
||||
1. Length: 0 - Capacity: 0
|
||||
2. Length: 6 - Capacity: 6
|
||||
3. Length: 0 - Capacity: 6 *CORRECT*
|
||||
4. Length: 5 - Capacity: 10
|
||||
|
||||
> **3:** Right! `words[:0]` slices for 0 elements, which in turn returns a slice with zero-length. Because the `words` slice points to the same backing array, its capacity is equal to 6.
|
||||
|
||||
|
||||
## What are the length and capacity of the 'words' slice?
|
||||
```go
|
||||
words := []string{"lucy", "in", "the", "sky", "with", "diamonds"}
|
||||
words = words[0:]
|
||||
```
|
||||
1. Length: 0 - Capacity: 0
|
||||
2. Length: 6 - Capacity: 6 *CORRECT*
|
||||
3. Length: 0 - Capacity: 6
|
||||
4. Length: 5 - Capacity: 10
|
||||
|
||||
> **2:** Right! `words[0:]` slices for the rest of the elements, which in turn returns a slice with the same length as the original slice: 6. Beginning from the first array element, the `words` slice's backing array contains 6 elements; so its capacity is also 6.
|
||||
|
||||
|
||||
## What are the length and capacity of the 'words' slice?
|
||||
```go
|
||||
words := []string{"lucy", "in", "the", "sky", "with", "diamonds"}
|
||||
words = words[2:cap(words)-2]
|
||||
```
|
||||
1. Length: 4 - Capacity: 6
|
||||
2. Length: 6 - Capacity: 4
|
||||
3. Length: 2 - Capacity: 6
|
||||
4. Length: 2 - Capacity: 4 *CORRECT*
|
||||
|
||||
> **4:** Right! `words[2:cap(words)-2]` is equal to `words = words[2:4]`, so it returns: `["the" "sky"]`. So, its length is 2. But there are 4 more elements (`["the" "sky" "with" "diamonds"]`) in the backing array, so the capacity is 4.
|
||||
|
||||
|
68
16-slices/questions/7-mechanics-of-append.md
Normal file
68
16-slices/questions/7-mechanics-of-append.md
Normal file
@ -0,0 +1,68 @@
|
||||
# The Mechanics of Append Quiz
|
||||
|
||||
## Which append call below allocates a new backing array for the following slice?
|
||||
```go
|
||||
words := []string{"lucy", "in", "the", "sky", "with", "diamonds"}
|
||||
```
|
||||
1. words = append(words[:3], "crystals")
|
||||
2. words = append(words[:4], "crystals")
|
||||
3. words = append(words[:5], "crystals")
|
||||
4. words = append(words[:5], "crystals", "and", "diamonds") *CORRECT*
|
||||
|
||||
> **1:** No, it just overwrites the 4th element.
|
||||
>
|
||||
> **2:** No, it just overwrites the 5th element.
|
||||
>
|
||||
> **3:** No, it just overwrites the last element.
|
||||
>
|
||||
> **4:** Yes, it overwrites the last element, then it adds two element. However, there is not enough space to do that, so it allocates a new backing array.
|
||||
|
||||
|
||||
## What does the program print?
|
||||
```go
|
||||
words := []string{"lucy", "in", "the", "sky", "with", "diamonds"}
|
||||
words = append(words[:1], "is", "everywhere")
|
||||
words = append(words, words[len(words)+1:cap(words)]...)
|
||||
```
|
||||
1. lucy in the sky with diamonds
|
||||
2. lucy is everywhere in the sky with diamonds
|
||||
3. lucy is everywhere with diamonds *CORRECT*
|
||||
4. lucy is everywhere
|
||||
|
||||
> **3:** line #2 overwrites the 2nd and 3rd elements. line #3 appends ["with" "diamonds"] after the ["lucy" "is" "everwhere"].
|
||||
|
||||
|
||||
## What are the length and capacity of the words slice?
|
||||
```go
|
||||
// The words slice has 1023 elements.
|
||||
//
|
||||
// Tip: The keyed slice works like the same as a keyed array.
|
||||
// If you don't remember how it works, please check out the keyed elements in the arrays section.
|
||||
//
|
||||
words := []string{1022: ""}
|
||||
words = append(words, "boom!")
|
||||
```
|
||||
1. Length: 1024 - Capacity: 1024
|
||||
2. Length: 1025 - Capacity: 1025
|
||||
3. Length: 1025 - Capacity: 1280
|
||||
4. Length: 1024 - Capacity: 2048 *CORRECT*
|
||||
|
||||
> **4:** That's right! Append function grows by doubling the capacity of the previous slice.
|
||||
|
||||
|
||||
## What are the length and capacity of the words slice?
|
||||
```go
|
||||
// The words slice has 1024 elements.
|
||||
//
|
||||
// Tip: The keyed slice works like the same as a keyed array.
|
||||
// If you don't remember how it works, please check out the keyed elements in the arrays section.
|
||||
//
|
||||
words := []string{1023: ""}
|
||||
words = append(words, "boom!")
|
||||
```
|
||||
1. Length: 1024 - Capacity: 1024
|
||||
2. Length: 1025 - Capacity: 1025
|
||||
3. Length: 1025 - Capacity: 1280 *CORRECT*
|
||||
4. Length: 1025 - Capacity: 2048
|
||||
|
||||
> **3, 4:** After 1024 elements, the append function grows at a slower rate, about 25%.
|
129
16-slices/questions/8-advanced-ops.md
Normal file
129
16-slices/questions/8-advanced-ops.md
Normal file
@ -0,0 +1,129 @@
|
||||
# Advanced Slice Operations Quiz
|
||||
|
||||
## What are the length and capacity of the 'part' slice?
|
||||
```go
|
||||
lyric := []string{"show", "me", "my", "silver", "lining"}
|
||||
part := lyric[1:3:5]
|
||||
```
|
||||
1. Length: 1 - Capacity: 5
|
||||
2. Length: 1 - Capacity: 3
|
||||
3. Length: 3 - Capacity: 5
|
||||
4. Length: 2 - Capacity: 4 *CORRECT*
|
||||
|
||||
> **4:** General Formula: `[low:high:max]` => `length = high - max` and `capacity = max - low`. `lyric[1:3]` is `["me" "my"]`. `lyric[1:3:5]` is `["me" "my" "silver" "lining"]`. So, `[1:3]` is the returned slice, length: 2. `[1:3:5]` limits the capacity to four because after the 1st element there are only four more elements.
|
||||
|
||||
|
||||
## What are the lengths and capacities of the slices below?
|
||||
```go
|
||||
lyric := []string{"show", "me", "my", "silver", "lining"}
|
||||
part := lyric[:2:2]
|
||||
part = append(part, "right", "place")
|
||||
```
|
||||
1. lyric's len: 5, cap: 5 — part's len: 5, cap: 5
|
||||
2. lyric's len: 3, cap: 1 — part's len: 2, cap: 3
|
||||
3. lyric's len: 5, cap: 5 — part's len: 4, cap: 4 *CORRECT*
|
||||
4. lyric's len: 3, cap: 1 — part's len: 2, cap: 3
|
||||
|
||||
> **3:** `lyric[:2:2]` = ["show" "me"]. After the append the part becomes: ["show" "me" "right" "place"] — so it allocates a new backing array. `lyric` stays the same: `["show" "me" "my" "silver" "lining"]`.
|
||||
|
||||
|
||||
## When you might want to use the make function?
|
||||
1. To preallocate a backing array for a slice with a definite length *CORRECT*
|
||||
2. To create a slice faster
|
||||
3. To use less memory
|
||||
|
||||
> **1:** Yes! You can use the make function to preallocate a backing array for a slice upfront.
|
||||
|
||||
|
||||
## What does the program print?
|
||||
```go
|
||||
tasks := make([]string, 2)
|
||||
tasks = append(tasks, "hello", "world")
|
||||
|
||||
fmt.Printf("%q\n", tasks)
|
||||
```
|
||||
1. ["" "" "hello" "world"] *CORRECT*
|
||||
2. ["hello" "world"]
|
||||
3. ["hello" "world" "" ""]
|
||||
|
||||
> **1:** `make([]string, 2)` creates a slice with len: 2 and cap: 2, and it sets all the elements to their zero-values. `append()` appends after the length of the slice (after the first two elements). That's why the first two elements are zero-valued strings but the last two elements are the newly appended elements.
|
||||
|
||||
|
||||
## What does the program print?
|
||||
```go
|
||||
tasks := make([]string, 0, 2)
|
||||
tasks = append(tasks, "hello", "world")
|
||||
|
||||
fmt.Printf("%q\n", tasks)
|
||||
```
|
||||
1. ["" "" "hello" "world"]
|
||||
2. ["hello" "world"] *CORRECT*
|
||||
3. ["hello" "world" "" ""]
|
||||
|
||||
> **2:** `make([]string, 0, 2)` creates a slice with len: 0 and cap: 2. `append()` appends after the length of the slice (at the beginning). That's why the first two elements are overwritten with the newly appended elements. This is a common usage pattern when you want to use the `make` and the `append` functions together.
|
||||
|
||||
|
||||
## What does the program print?
|
||||
```go
|
||||
lyric := []string{"le", "vent", "nous", "portera"}
|
||||
n := copy(lyric, make([]string, 4))
|
||||
|
||||
fmt.Printf("%d %q\n", n, lyric)
|
||||
|
||||
// -- USEFUL INFORMATION (but not required to solve the question) --
|
||||
// In the following `copy` operation, `make` won't allocate
|
||||
// a slice with a new backing array up to 32768 bytes
|
||||
// (one string value is 8 bytes on a 64-bit machine).
|
||||
//
|
||||
// This is an optimization made by the Go compiler.
|
||||
```
|
||||
1. 4 ["le" "vent" "le" "vent"]
|
||||
2. 4 ["le" "vent" "nous" "portera"]
|
||||
3. 4 ["" "" "" ""] *CORRECT*
|
||||
4. 0 []
|
||||
|
||||
> **3:** `copy` copies a newly created slice with four elements (`make([]string, 4)`) onto `lyric` slice. They both have 4 elements, so the `copy` copies 4 elements. Remember: `make()` initializes a slice with zero-values of its element type. Here, this operation clears all the slice elements to their zero-values.
|
||||
|
||||
|
||||
## What does the program print?
|
||||
```go
|
||||
spendings := [][]int{{200, 100}, {}, {50, 25, 75}, {500}}
|
||||
total := spendings[2][1] + spendings[3][0] + spendings[0][0]
|
||||
|
||||
fmt.Printf("%d\n", total)
|
||||
```
|
||||
1. 725 *CORRECT*
|
||||
2. 650
|
||||
3. 500
|
||||
4. 750
|
||||
|
||||
> **1:** `spendings[2][1]` = 25. `spendings[3][0]` = 500. `spendings[0][0]` = 200. 25 + 500 + 200 = 725
|
||||
|
||||
|
||||
## What does the program print?
|
||||
```go
|
||||
spendings := [][]int{{1,2}}
|
||||
|
||||
// REMEMBER: %T prints the type of a given value
|
||||
fmt.Printf("%T - ", spendings)
|
||||
fmt.Printf("%T - ", spendings[0])
|
||||
fmt.Printf("%T", spendings[0][0])
|
||||
```
|
||||
1. [][]int{{1, 2}} - []int{1, 2} - int(2)
|
||||
2. [][]int - []int - int *CORRECT*
|
||||
3. []int - int - 2
|
||||
4. [][]int - [][]int - []int
|
||||
|
||||
> **2:** `spendings` is a 2-dimensional int slice, so its type is [][]int. Its element type is: `[]int`, so: `spendings[0]` is `[]int`. `spendings[0]`'s element type is: `int`. So `spendings[0][0]`'s type is `int`.
|
||||
|
||||
|
||||
## What is the 'element type' of the slice?
|
||||
```go
|
||||
[][][3]int{{{10, 5, 9}}}
|
||||
```
|
||||
1. [][][3]int
|
||||
2. [][]int
|
||||
3. [][3]int *CORRECT*
|
||||
4. [3]int
|
||||
|
||||
> **3:** `[][][3]int` is a multi-dimensional slice of `[][3]int` elements. `[][3]int` is a multi-dimensional slice of `[3]int` elements. `[3]int` is an array of 3 `int` values.
|
Reference in New Issue
Block a user