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. | ||||
| 	// it could have been fetched from a database | ||||
| 	items := []string{ | ||||
| 		"pacman", | ||||
| 		"mario", | ||||
| 		"tetris", | ||||
| 		"doom", | ||||
| 		"galaga", | ||||
| 		"frogger", | ||||
| 		"asteroids", | ||||
| 		"simcity", | ||||
| 		"metroid", | ||||
| 		"defender", | ||||
| 		"rayman", | ||||
| 		"tempest", | ||||
| 		"pacman", "mario", "tetris", "doom", | ||||
| 		"galaga", "frogger", "asteroids", "simcity", | ||||
| 		"metroid", "defender", "rayman", "tempest", | ||||
| 		"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 | ||||
| // 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() { | ||||
| 	// 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)** | ||||
|  | ||||
| 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) | ||||
|  | ||||
| * [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