add: slice internals backing array and slice header
This commit is contained in:
@ -17,18 +17,9 @@ func main() {
|
|||||||
// think of this as search results of a search engine.
|
// think of this as search results of a search engine.
|
||||||
// it could have been fetched from a database
|
// it could have been fetched from a database
|
||||||
items := []string{
|
items := []string{
|
||||||
"pacman",
|
"pacman", "mario", "tetris", "doom",
|
||||||
"mario",
|
"galaga", "frogger", "asteroids", "simcity",
|
||||||
"tetris",
|
"metroid", "defender", "rayman", "tempest",
|
||||||
"doom",
|
|
||||||
"galaga",
|
|
||||||
"frogger",
|
|
||||||
"asteroids",
|
|
||||||
"simcity",
|
|
||||||
"metroid",
|
|
||||||
"defender",
|
|
||||||
"rayman",
|
|
||||||
"tempest",
|
|
||||||
"ultima",
|
"ultima",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
46
16-slices/09-slice-internals-2-slice-header/1-theory/main.go
Normal file
46
16-slices/09-slice-internals-2-slice-header/1-theory/main.go
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
// For more tutorials: https://blog.learngoprogramming.com
|
||||||
|
//
|
||||||
|
// Copyright © 2018 Inanc Gumus
|
||||||
|
// Learn Go Programming Course
|
||||||
|
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||||
|
//
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
s "github.com/inancgumus/prettyslice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
//
|
||||||
|
// each int element is 4 bytes (on 64-bit)
|
||||||
|
//
|
||||||
|
// let's say the ages point to 1000th.
|
||||||
|
// ages[1:] will point to 1004th
|
||||||
|
// ages[2:] will point to 1008th and so on.
|
||||||
|
//
|
||||||
|
// they all will be looking at the same
|
||||||
|
// backing array.
|
||||||
|
//
|
||||||
|
|
||||||
|
ages := []int{35, 15, 25}
|
||||||
|
red, green := ages[0:1], ages[1:3]
|
||||||
|
|
||||||
|
s.Show("ages", ages)
|
||||||
|
s.Show("red", red)
|
||||||
|
s.Show("green", green)
|
||||||
|
|
||||||
|
fmt.Println(red[0])
|
||||||
|
// fmt.Println(red[1]) // error
|
||||||
|
// fmt.Println(red[2]) // error
|
||||||
|
|
||||||
|
{
|
||||||
|
var ages []int
|
||||||
|
s.Show("nil slice", ages)
|
||||||
|
|
||||||
|
// or just:
|
||||||
|
s.Show("nil slice", []int(nil))
|
||||||
|
}
|
||||||
|
}
|
@ -19,7 +19,7 @@ type collection []string // #2
|
|||||||
|
|
||||||
// go is pass by copy
|
// go is pass by copy
|
||||||
// only the slice header is copied: 3 integer fields (24 bytes)
|
// only the slice header is copied: 3 integer fields (24 bytes)
|
||||||
// think of passing an array with millions of elements.
|
// think of passing an array with millions of elements instead.
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// SliceHeader lives here:
|
// SliceHeader lives here:
|
60
16-slices/exercises/16-internals-backing-array-fix/main.go
Normal file
60
16-slices/exercises/16-internals-backing-array-fix/main.go
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
// For more tutorials: https://blog.learngoprogramming.com
|
||||||
|
//
|
||||||
|
// Copyright © 2018 Inanc Gumus
|
||||||
|
// Learn Go Programming Course
|
||||||
|
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||||
|
//
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ---------------------------------------------------------
|
||||||
|
// EXERCISE: Fix the backing array problem
|
||||||
|
//
|
||||||
|
// You receive numbers from an API. After you're done working
|
||||||
|
// with it, the API needs to continue using those numbers.
|
||||||
|
//
|
||||||
|
// But your program changes the numbers (changes the API's slice).
|
||||||
|
//
|
||||||
|
// Fix the program so that your program doesn't modify
|
||||||
|
// the original numbers.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// RESTRICTION
|
||||||
|
//
|
||||||
|
// Fix your problem only in the designated area of the code below.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// EXPECTED OUTPUT
|
||||||
|
//
|
||||||
|
// Mine : [-50 -100 -150]
|
||||||
|
// Original nums: [56 89 15]
|
||||||
|
//
|
||||||
|
// Note: Original nums may vary (they're random)
|
||||||
|
// But your slice should look like the above (mine slice)
|
||||||
|
//
|
||||||
|
// Yes, it should output only three numbers for the both slices!
|
||||||
|
//
|
||||||
|
// ---------------------------------------------------------
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// API returns random numbers in an int slice
|
||||||
|
rand.Seed(time.Now().UnixNano())
|
||||||
|
nums := rand.Perm(100)
|
||||||
|
|
||||||
|
// ----------------------------------------
|
||||||
|
// RESTRICTIONS — ONLY ADD YOUR CODE HERE
|
||||||
|
//
|
||||||
|
mine := nums
|
||||||
|
//
|
||||||
|
// ----------------------------------------
|
||||||
|
|
||||||
|
mine[0], mine[1], mine[2] = -50, -100, -150
|
||||||
|
fmt.Println("Mine :", mine)
|
||||||
|
fmt.Println("Original nums:", nums[:3])
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
// For more tutorials: https://blog.learngoprogramming.com
|
||||||
|
//
|
||||||
|
// Copyright © 2018 Inanc Gumus
|
||||||
|
// Learn Go Programming Course
|
||||||
|
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||||
|
//
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
rand.Seed(time.Now().UnixNano())
|
||||||
|
nums := rand.Perm(100)
|
||||||
|
|
||||||
|
// ----------------------------------------
|
||||||
|
// breaks the connection:
|
||||||
|
// mine and nums now have different backing arrays
|
||||||
|
|
||||||
|
// verbose solution:
|
||||||
|
// var mine []int
|
||||||
|
// mine = append(mine, nums[:3]...)
|
||||||
|
|
||||||
|
// better solution (almost the same thing):
|
||||||
|
mine := append([]int(nil), nums[:3]...)
|
||||||
|
// ----------------------------------------
|
||||||
|
|
||||||
|
mine[0], mine[1], mine[2] = -50, -100, -150
|
||||||
|
fmt.Println("Mine :", mine)
|
||||||
|
fmt.Println("Original nums:", nums[:3])
|
||||||
|
}
|
52
16-slices/exercises/17-internals-backing-array-sort/main.go
Normal file
52
16-slices/exercises/17-internals-backing-array-sort/main.go
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
// For more tutorials: https://blog.learngoprogramming.com
|
||||||
|
//
|
||||||
|
// Copyright © 2018 Inanc Gumus
|
||||||
|
// Learn Go Programming Course
|
||||||
|
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||||
|
//
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ---------------------------------------------------------
|
||||||
|
// EXERCISE: Sort the backing array
|
||||||
|
//
|
||||||
|
// 1. Sort only the middle 3 items.
|
||||||
|
//
|
||||||
|
// 2. All the slices should see your change.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// RESTRICTION
|
||||||
|
//
|
||||||
|
// Do not sort manually. Sort by slicing then by using the sort package.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// EXPECTED OUTPUT
|
||||||
|
//
|
||||||
|
// Original: [pacman mario tetris doom galaga frogger asteroids simcity metroid defender rayman tempest ultima]
|
||||||
|
//
|
||||||
|
// Sorted : [pacman mario tetris doom galaga asteroids frogger simcity metroid defender rayman tempest ultima]
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// HINT:
|
||||||
|
//
|
||||||
|
// Middle items are : [frogger asteroids simcity]
|
||||||
|
//
|
||||||
|
// After sorting they become: [asteroids frogger simcity]
|
||||||
|
//
|
||||||
|
// ---------------------------------------------------------
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
items := []string{
|
||||||
|
"pacman", "mario", "tetris", "doom", "galaga", "frogger",
|
||||||
|
"asteroids", "simcity", "metroid", "defender", "rayman",
|
||||||
|
"tempest", "ultima",
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Original:", items)
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println("Sorted :", items)
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
// For more tutorials: https://blog.learngoprogramming.com
|
||||||
|
//
|
||||||
|
// Copyright © 2018 Inanc Gumus
|
||||||
|
// Learn Go Programming Course
|
||||||
|
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||||
|
//
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
items := []string{
|
||||||
|
"pacman", "mario", "tetris", "doom", "galaga", "frogger",
|
||||||
|
"asteroids", "simcity", "metroid", "defender", "rayman",
|
||||||
|
"tempest", "ultima",
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Original:", items)
|
||||||
|
|
||||||
|
mid := len(items) / 2
|
||||||
|
smid := items[mid-1 : mid+2]
|
||||||
|
|
||||||
|
// sorting the smid will affect the items
|
||||||
|
// as well. their backing array is the same.
|
||||||
|
sort.Strings(smid)
|
||||||
|
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println("Sorted :", items)
|
||||||
|
}
|
115
16-slices/exercises/18-internals-slice-header/main.go
Normal file
115
16-slices/exercises/18-internals-slice-header/main.go
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"runtime"
|
||||||
|
"runtime/debug"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ---------------------------------------------------------
|
||||||
|
// EXERCISE: Observe the memory allocations
|
||||||
|
//
|
||||||
|
// In this exercise, your goal is to observe the memory allocation
|
||||||
|
// differences between arrays and slices.
|
||||||
|
//
|
||||||
|
// You will create, assign arrays and slices then you will print
|
||||||
|
// the memory usage of your program on each step.
|
||||||
|
//
|
||||||
|
// Please follow the instructions inside the code.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// EXPECTED OUTPUT
|
||||||
|
//
|
||||||
|
// Note that, your memory usage numbers may vary. These are on my
|
||||||
|
// own system. However, the size of the arrays and slices should be
|
||||||
|
// the same on your own system as well (if you're on 64-bit machine).
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// <<< initial memory usage >>>
|
||||||
|
// > Memory Usage: 104 KB
|
||||||
|
// <<< after declaring an array >>>
|
||||||
|
// > Memory Usage: 78235 KB
|
||||||
|
// <<< after copying the array >>>
|
||||||
|
// > Memory Usage: 156365 KB
|
||||||
|
// <<< inside passArray >>>
|
||||||
|
// > Memory Usage: 234495 KB
|
||||||
|
// <<< after slicings >>>
|
||||||
|
// > Memory Usage: 234497 KB
|
||||||
|
// <<< inside passSlice >>>
|
||||||
|
// > Memory Usage: 234497 KB
|
||||||
|
//
|
||||||
|
// Array's size : 80000000 bytes.
|
||||||
|
// Array2's size: 80000000 bytes.
|
||||||
|
// Slice1's size: 24 bytes.
|
||||||
|
// Slice2's size: 24 bytes.
|
||||||
|
// Slice3's size: 24 bytes.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// HINTS
|
||||||
|
//
|
||||||
|
// I've declared a few function to help you.
|
||||||
|
//
|
||||||
|
// report function prints the memory usage.
|
||||||
|
// Just call it with a message that matches to the expected output.
|
||||||
|
//
|
||||||
|
// passArray function accepts a [size]int array, so you can pass it
|
||||||
|
// your array. It automatically prints the memory usage.
|
||||||
|
//
|
||||||
|
// passSlice function accepts an int slice, so you can pass it
|
||||||
|
// your one of your slices. It automatically prints the memory usage.
|
||||||
|
//
|
||||||
|
// ---------------------------------------------------------
|
||||||
|
|
||||||
|
const size = 1e7
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// stops the gc: prevents cleaning up the memory
|
||||||
|
debug.SetGCPercent(-1)
|
||||||
|
|
||||||
|
// run the program to see what this prints
|
||||||
|
report("initial memory usage")
|
||||||
|
|
||||||
|
// 1. allocate an array with 10 million int elements
|
||||||
|
// this array's size is equal to ~80MB
|
||||||
|
// hint: use the `size` constant
|
||||||
|
//
|
||||||
|
// 2. print the memory usage
|
||||||
|
|
||||||
|
// 3. copy the array to a new array (just assign)
|
||||||
|
// 4. print the memory usage
|
||||||
|
|
||||||
|
// 5. pass the array to passArray function
|
||||||
|
|
||||||
|
// 6. convert the array to a slice (by slicing)
|
||||||
|
// 7. slice only the first 1000 elements of the array
|
||||||
|
// 8. slice only the elements of the array between 1000 and 10000
|
||||||
|
// 9. print the memory usage
|
||||||
|
|
||||||
|
// 10. pass the one of the slices to passSlice function
|
||||||
|
|
||||||
|
// 11. print the sizes of the arrays and slices
|
||||||
|
// hint: use the unsafe.Sizeof function
|
||||||
|
}
|
||||||
|
|
||||||
|
// observe that passing an array affects the memory usage dramatically
|
||||||
|
//
|
||||||
|
// passes [size]int array — about 80MB!
|
||||||
|
func passArray(items [size]int) {
|
||||||
|
items[0] = 100
|
||||||
|
report("inside passArray")
|
||||||
|
}
|
||||||
|
|
||||||
|
// observe that passing a slice doesn't affect the memory usage
|
||||||
|
//
|
||||||
|
// only passes 24-bytes of slice header
|
||||||
|
func passSlice(items []int) {
|
||||||
|
items[0] = 100
|
||||||
|
report("inside passSlice")
|
||||||
|
}
|
||||||
|
|
||||||
|
func report(msg string) {
|
||||||
|
var m runtime.MemStats
|
||||||
|
runtime.ReadMemStats(&m)
|
||||||
|
fmt.Printf("<<< %s >>>\n", msg)
|
||||||
|
fmt.Printf("\t> Memory Usage: %v KB\n", m.Alloc/1024)
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
// For more tutorials: https://blog.learngoprogramming.com
|
||||||
|
//
|
||||||
|
// Copyright © 2018 Inanc Gumus
|
||||||
|
// Learn Go Programming Course
|
||||||
|
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||||
|
//
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"runtime"
|
||||||
|
"runtime/debug"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
const size = 1e7
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// stops the gc: prevents cleaning up the memory
|
||||||
|
debug.SetGCPercent(-1)
|
||||||
|
|
||||||
|
report("initial memory usage")
|
||||||
|
|
||||||
|
var array [size]int
|
||||||
|
report("after declaring an array")
|
||||||
|
|
||||||
|
array2 := array
|
||||||
|
report("after copying the array")
|
||||||
|
|
||||||
|
passArray(array)
|
||||||
|
|
||||||
|
slice1 := array[:]
|
||||||
|
slice2 := array[1e3:]
|
||||||
|
slice3 := array[1e3:1e4]
|
||||||
|
report("after slicings")
|
||||||
|
|
||||||
|
passSlice(slice3)
|
||||||
|
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Printf("Array's size : %d bytes.\n", unsafe.Sizeof(array))
|
||||||
|
fmt.Printf("Array2's size: %d bytes.\n", unsafe.Sizeof(array2))
|
||||||
|
fmt.Printf("Slice1's size: %d bytes.\n", unsafe.Sizeof(slice1))
|
||||||
|
fmt.Printf("Slice2's size: %d bytes.\n", unsafe.Sizeof(slice2))
|
||||||
|
fmt.Printf("Slice3's size: %d bytes.\n", unsafe.Sizeof(slice3))
|
||||||
|
}
|
||||||
|
|
||||||
|
func passArray(items [size]int) {
|
||||||
|
items[0] = 100
|
||||||
|
report("inside passArray")
|
||||||
|
}
|
||||||
|
|
||||||
|
func passSlice(items []int) {
|
||||||
|
report("inside passSlice")
|
||||||
|
}
|
||||||
|
|
||||||
|
func report(msg string) {
|
||||||
|
var m runtime.MemStats
|
||||||
|
runtime.ReadMemStats(&m)
|
||||||
|
fmt.Printf("<<< %s >>>\n", msg)
|
||||||
|
fmt.Printf("\t> Memory Usage: %v KB\n", m.Alloc/1024)
|
||||||
|
}
|
@ -41,4 +41,14 @@ These are warm-up exercises that will reinforce your knowledge of slices.
|
|||||||
|
|
||||||
2. **[Slicing by arguments](https://github.com/inancgumus/learngo/tree/master/16-slices/exercises/14-slicing-by-args)**
|
2. **[Slicing by arguments](https://github.com/inancgumus/learngo/tree/master/16-slices/exercises/14-slicing-by-args)**
|
||||||
|
|
||||||
3. **[Slicing the Housing Prices](https://github.com/inancgumus/learngo/tree/master/16-slices/exercises/15-slicing-housing-prices)**
|
3. **[Slicing the Housing Prices](https://github.com/inancgumus/learngo/tree/master/16-slices/exercises/15-slicing-housing-prices)**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Exercises Level IV - Internals
|
||||||
|
|
||||||
|
1. **[Fix the backing array problems](https://github.com/inancgumus/learngo/tree/master/16-slices/exercises/16-internals-backing-array-fix)**
|
||||||
|
|
||||||
|
2. **[Sort the backing array](https://github.com/inancgumus/learngo/tree/master/16-slices/exercises/17-internals-backing-array-sort)**
|
||||||
|
|
||||||
|
3. **[Observe the memory allocations](https://github.com/inancgumus/learngo/tree/master/16-slices/exercises/18-internals-slice-header)**
|
||||||
|
131
16-slices/questions/4-backing-array.md
Normal file
131
16-slices/questions/4-backing-array.md
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
# Backing Array Quiz
|
||||||
|
|
||||||
|
## Where does a slice store its elements?
|
||||||
|
1. In the slice value
|
||||||
|
2. In a global backing array that is shared by all the slices
|
||||||
|
3. In a backing array that is specific to a slice
|
||||||
|
4. In a backing array that the slice references *CORRECT*
|
||||||
|
|
||||||
|
> **1:** A slice value doesn't store any elements. It's just a simple data structure.
|
||||||
|
>
|
||||||
|
> **2:** There is not a global backing array.
|
||||||
|
>
|
||||||
|
> **3:** A backing array can be shared among slices. It may not be specific to a slice.
|
||||||
|
>
|
||||||
|
> **4:** Yep! A slice stores its elements in a backing that the slice references (or points to).
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
## When you slice a slice, what value does it return?
|
||||||
|
```go
|
||||||
|
// example:
|
||||||
|
s := []string{"i'm", "a", "slice"}
|
||||||
|
s[2:] // <-- slicing
|
||||||
|
```
|
||||||
|
1. It returns a new slice value with a new backing array
|
||||||
|
2. It returns the existing slice value with a new backing array
|
||||||
|
3. It returns a new slice value with the same backing array *CORRECT*
|
||||||
|
|
||||||
|
> **3:** Yes! Slicing returns a new slice that references to some segment of the same backing array.
|
||||||
|
|
||||||
|
|
||||||
|
## Why is slicing and indexing a slice efficient?
|
||||||
|
1. Slices are fast
|
||||||
|
2. Backing arrays are contiguous in memory *CORRECT*
|
||||||
|
3. Go uses clever algorithms
|
||||||
|
|
||||||
|
> **2:** Yes. A slice's backing array is contiguous in memory. So, accessing an element of a slice is very fast. Go can look at a specific memory location to find an element's value very fast.
|
||||||
|
|
||||||
|
|
||||||
|
## Which one is the backing array of "slice2"?
|
||||||
|
```go
|
||||||
|
arr := [...]int{1, 2, 3}
|
||||||
|
slice1 := arr[2:3]
|
||||||
|
slice2 := slice1[:1]
|
||||||
|
```
|
||||||
|
|
||||||
|
1. arr *CORRECT*
|
||||||
|
2. slice1
|
||||||
|
3. slice2
|
||||||
|
4. A hidden backing array
|
||||||
|
|
||||||
|
> **1:** Yes! When a slice is created by slicing an array, that array becomes the backing array of that slice.
|
||||||
|
>
|
||||||
|
> **4:** Nope. That only happens when a slice doesn't being created from an array.
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
## Which one is the backing array of "slice"?
|
||||||
|
```go
|
||||||
|
arr := [...]int{1, 2, 3}
|
||||||
|
slice := []int{1, 2, 3}
|
||||||
|
```
|
||||||
|
|
||||||
|
1. arr
|
||||||
|
2. slice1
|
||||||
|
3. slice2
|
||||||
|
4. A hidden backing array *CORRECT*
|
||||||
|
|
||||||
|
> **1:** Nope, the slice hasn't created by slicing an array.
|
||||||
|
>
|
||||||
|
> **4:** Yes! A slice literal always creates a new hidden array.
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
## Which answer is correct for the following slices?
|
||||||
|
```go
|
||||||
|
slice1 := []int{1, 2, 3}
|
||||||
|
slice2 := []int{1, 2, 3}
|
||||||
|
```
|
||||||
|
1. Their backing array is the same.
|
||||||
|
2. Their backing arrays are different. *CORRECT*
|
||||||
|
3. They don't have any backing arrays.
|
||||||
|
|
||||||
|
> **2:** That's right. A slice literal always creates a new backing array.
|
||||||
|
|
||||||
|
|
||||||
|
## Which answer is correct for the following slices?
|
||||||
|
```go
|
||||||
|
slice1 := []int{1, 2, 3}
|
||||||
|
slice2 := []int{1, 2, 3}
|
||||||
|
slice3 := slice1[:]
|
||||||
|
slice4 := slice2[:]
|
||||||
|
```
|
||||||
|
1. slice1 and slice2 have the same backing arrays.
|
||||||
|
2. slice1 and slice3 have the same backing arrays. *CORRECT*
|
||||||
|
3. slice1 and slice4 have the same backing arrays.
|
||||||
|
4. slice3 and slice4 have the same backing arrays.
|
||||||
|
|
||||||
|
> **2:** Yep! A slice that is being created by slicing shares the same backing with the sliced slice. Here, slice3 is being created from slice1. That is also true for slice2 and slice4.
|
||||||
|
|
||||||
|
|
||||||
|
## What does the backing array of the nums slice look like?
|
||||||
|
```go
|
||||||
|
nums := []int{9, 7, 5, 3, 1}
|
||||||
|
nums = nums[:1]
|
||||||
|
|
||||||
|
fmt.Println(nums) // prints: [9]
|
||||||
|
```
|
||||||
|
1. [9 7 5 3 1] *CORRECT*
|
||||||
|
2. [7 5 3 1]
|
||||||
|
3. [9]
|
||||||
|
4. []
|
||||||
|
|
||||||
|
|
||||||
|
## What does this code print?
|
||||||
|
```go
|
||||||
|
arr := [...]int{9, 7, 5, 3, 1}
|
||||||
|
nums := arr[2:]
|
||||||
|
nums2 := nums[1:]
|
||||||
|
|
||||||
|
arr[2]++
|
||||||
|
nums[1] -= arr[4] - 4
|
||||||
|
nums2[1] += 5
|
||||||
|
|
||||||
|
fmt.Println(nums)
|
||||||
|
```
|
||||||
|
1. [5 3 1]
|
||||||
|
2. [6 6 6] *CORRECT*
|
||||||
|
3. [9 7 5]
|
||||||
|
|
||||||
|
> **2:** Yes! Because the backing array of `nums` and `nums2` is the same: `arr`. See the explanation here: https://play.golang.org/p/xTy0W0S_8PN
|
90
16-slices/questions/5-slice-header.md
Normal file
90
16-slices/questions/5-slice-header.md
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
# Slice Header Quiz
|
||||||
|
|
||||||
|
## What is a slice header?
|
||||||
|
1. The first element of a slice value
|
||||||
|
2. The first element of the backing array
|
||||||
|
3. A tiny data structure that describes all or some part of a backing array *CORRECT*
|
||||||
|
4. A data structure that contains the elements of a slice
|
||||||
|
|
||||||
|
> **3:** Yes! It's just a tiny data structure with three numeric fields.
|
||||||
|
>
|
||||||
|
> **4:** A slice doesn't contain any elements on its own.
|
||||||
|
|
||||||
|
|
||||||
|
## What are the fields of a slice value?
|
||||||
|
1. Pointer, length, and capacity *CORRECT*
|
||||||
|
2. Length and capacity
|
||||||
|
3. Only a pointer
|
||||||
|
|
||||||
|
|
||||||
|
## Which slice value does the following slice header describe?
|
||||||
|
SLICE HEADER:
|
||||||
|
+ Pointer : 100th
|
||||||
|
+ Length : 5
|
||||||
|
+ Capacity: 10
|
||||||
|
|
||||||
|
Assume that the backing array is this one:
|
||||||
|
```go
|
||||||
|
var array [10]string
|
||||||
|
```
|
||||||
|
1. array[5:]
|
||||||
|
2. array[:5] *CORRECT*
|
||||||
|
3. array[3:]
|
||||||
|
4. array[100:]
|
||||||
|
|
||||||
|
> **1**: This slice's capacity is 5, it can only see the elements beginning with the 6th element.
|
||||||
|
>
|
||||||
|
> **2**: That's right. `array[:5]` returns a slice with the first 5 elements of the `array` (len is 5), but there are 5 more elements in the backing array of that slice, so in total its capacity is 10.
|
||||||
|
>
|
||||||
|
> **3**: This slice's capacity is 7, it can only see the elements beginning with the 4th element.
|
||||||
|
>
|
||||||
|
> **4**: This is an error. The backing array doesn't have 100 elements.
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
## Which one is the slice header of the following slice?
|
||||||
|
```go
|
||||||
|
var tasks []string
|
||||||
|
```
|
||||||
|
1. Pointer: 0, Length: 0, Capacity: 0 *CORRECT*
|
||||||
|
2. Pointer: 10, Length: 5, Capacity: 10
|
||||||
|
3. Pointer: 0, Length: 1, Capacity: 1
|
||||||
|
|
||||||
|
> **1:** A nil slice doesn't have backing array, so all the fields are equal to zero.
|
||||||
|
|
||||||
|
|
||||||
|
## What is the total memory usage of this code?
|
||||||
|
```go
|
||||||
|
var array [1000]int64
|
||||||
|
|
||||||
|
array2 := array
|
||||||
|
slice := array2[:]
|
||||||
|
```
|
||||||
|
|
||||||
|
1. 1024 bytes
|
||||||
|
2. 2024 bytes
|
||||||
|
3. 3000 bytes
|
||||||
|
4. 16024 bytes *CORRECT*
|
||||||
|
|
||||||
|
> **4:** `array` is 1000 x int64 (8 bytes) = 8000 bytes. Assigning an array copies all its elements, so `array2` adds additional 8000 bytes. A slice doesn't store anything on its own. Here, it's being created from array2, so it doesn't allocate a backing array as well. A slice header's size is 24 bytes. So in total: This program allocates 16024 bytes.
|
||||||
|
|
||||||
|
|
||||||
|
## What value does this code pass to the sort.Ints function?
|
||||||
|
```go
|
||||||
|
nums := []int{9, 7, 5, 3, 1}
|
||||||
|
sort.Ints(nums)
|
||||||
|
```
|
||||||
|
1. [9 7 5 3 1] — All the values of the nums slice
|
||||||
|
2. A pointer to the backing array of the nums slice
|
||||||
|
3. A pointer, length and capacity as three different arguments
|
||||||
|
4. The slice header that is stored in the nums variable *CORRECT*
|
||||||
|
|
||||||
|
> **1:** No, a slice value doesn't contain any elements. So it cannot pass the elements.
|
||||||
|
>
|
||||||
|
> **2:** Sorry but not only that.
|
||||||
|
>
|
||||||
|
> **3:** Nope. Remember, they are packed in a tiny data structure called the ....?
|
||||||
|
>
|
||||||
|
> **4:** Yep! A slice value is a slice header (pointer, length and capacity). A slice variable stores the slice header.
|
||||||
|
>
|
||||||
|
|
@ -4,4 +4,6 @@
|
|||||||
|
|
||||||
* [Appending](2-appending.md)
|
* [Appending](2-appending.md)
|
||||||
|
|
||||||
* [Slicing](3-slicing.md)
|
* [Slicing](3-slicing.md)
|
||||||
|
|
||||||
|
* [Backing Array](4-backing-array.md)
|
@ -1,21 +0,0 @@
|
|||||||
// For more tutorials: https://blog.learngoprogramming.com
|
|
||||||
//
|
|
||||||
// Copyright © 2018 Inanc Gumus
|
|
||||||
// Learn Go Programming Course
|
|
||||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
|
||||||
//
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import s "github.com/inancgumus/prettyslice"
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
ages := []int{35, 15, 25}
|
|
||||||
first, last := ages[0:1], ages[1:3]
|
|
||||||
|
|
||||||
s.Show("ages", ages)
|
|
||||||
s.Show("first", first)
|
|
||||||
s.Show("last", last)
|
|
||||||
|
|
||||||
s.Show("nil slice", []int(nil))
|
|
||||||
}
|
|
Reference in New Issue
Block a user