refactor: slice exercises 16-21
This commit is contained in:
@ -9,25 +9,19 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ---------------------------------------------------------
|
// ---------------------------------------------------------
|
||||||
// EXERCISE: Fix the backing array problem
|
// EXERCISE: Fix the backing array problem
|
||||||
//
|
//
|
||||||
// You receive numbers from an API. After you're done working
|
// Ensure that changing the elements of the `mine` slice
|
||||||
// with it, the API needs to continue using those numbers.
|
// does not change the elements of the `nums` slice.
|
||||||
//
|
|
||||||
// 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
|
// CURRENT OUTPUT (INCORRECT)
|
||||||
//
|
//
|
||||||
// Fix the problem only in the designated area of the code below.
|
// Mine : [-50 -100 -150 25 30 50]
|
||||||
|
// Original nums: [-50 -100 -150]
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// EXPECTED OUTPUT
|
// EXPECTED OUTPUT
|
||||||
@ -35,26 +29,27 @@ import (
|
|||||||
// Mine : [-50 -100 -150]
|
// Mine : [-50 -100 -150]
|
||||||
// Original nums: [56 89 15]
|
// 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() {
|
func main() {
|
||||||
// API returns random numbers in an int slice
|
// DON'T TOUCH THE FOLLOWING CODE
|
||||||
rand.Seed(time.Now().UnixNano())
|
nums := []int{56, 89, 15, 25, 30, 50}
|
||||||
nums := rand.Perm(100)
|
|
||||||
|
|
||||||
// ----------------------------------------
|
// ----------------------------------------
|
||||||
// RESTRICTIONS — ONLY ADD YOUR CODE HERE
|
// ONLY ADD YOUR CODE HERE
|
||||||
//
|
//
|
||||||
|
// Ensure that nums slice never changes even though
|
||||||
|
// the mine slice changes.
|
||||||
mine := nums
|
mine := nums
|
||||||
//
|
|
||||||
// ----------------------------------------
|
// ----------------------------------------
|
||||||
|
|
||||||
|
// DON'T TOUCH THE FOLLOWING CODE
|
||||||
|
//
|
||||||
|
// This code changes the elements of the nums
|
||||||
|
// slice.
|
||||||
|
//
|
||||||
mine[0], mine[1], mine[2] = -50, -100, -150
|
mine[0], mine[1], mine[2] = -50, -100, -150
|
||||||
fmt.Println("Mine :", mine)
|
|
||||||
|
fmt.Println("Mine :", mine[:3])
|
||||||
fmt.Println("Original nums:", nums[:3])
|
fmt.Println("Original nums:", nums[:3])
|
||||||
}
|
}
|
||||||
|
@ -9,13 +9,10 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
rand.Seed(time.Now().UnixNano())
|
nums := []int{56, 89, 15, 25, 30, 50}
|
||||||
nums := rand.Perm(100)
|
|
||||||
|
|
||||||
// ----------------------------------------
|
// ----------------------------------------
|
||||||
// breaks the connection:
|
// breaks the connection:
|
||||||
|
@ -16,12 +16,12 @@ import (
|
|||||||
//
|
//
|
||||||
// 1. Sort only the middle 3 items.
|
// 1. Sort only the middle 3 items.
|
||||||
//
|
//
|
||||||
// 2. All the slices should see your change.
|
// 2. All the slices should see your changes.
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// RESTRICTION
|
// RESTRICTION
|
||||||
//
|
//
|
||||||
// Do not sort manually. Sort by slicing then by using the sort package.
|
// Do not sort manually. Sort by using the sort package.
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// EXPECTED OUTPUT
|
// EXPECTED OUTPUT
|
||||||
|
@ -20,9 +20,9 @@ import (
|
|||||||
//
|
//
|
||||||
// EXPECTED OUTPUT
|
// EXPECTED OUTPUT
|
||||||
//
|
//
|
||||||
// Note that, your memory usage numbers may vary. These are on my
|
// Note that, your memory usage numbers may vary. However, the size of the
|
||||||
// own system. However, the size of the arrays and slices should be
|
// arrays and slices should be the same on your own system as well
|
||||||
// the same on your own system as well (if you're on 64-bit machine).
|
// (if you're on a 64-bit machine).
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// [initial memory usage]
|
// [initial memory usage]
|
||||||
@ -54,62 +54,73 @@ import (
|
|||||||
// - Just call it with a message that matches to the expected output.
|
// - Just call it with a message that matches to the expected output.
|
||||||
//
|
//
|
||||||
// passArray function:
|
// passArray function:
|
||||||
// - Accepts a [size]int array, so you can pass it your array.
|
|
||||||
// - It automatically prints the memory usage.
|
// - It automatically prints the memory usage.
|
||||||
|
// - Accepts a [size]int array, so you can pass your array to it.
|
||||||
//
|
//
|
||||||
// passSlice function:
|
// passSlice function:
|
||||||
// - Accepts an int slice, so you can pass it one of your slices.
|
|
||||||
// - It automatically prints the memory usage.
|
// - It automatically prints the memory usage.
|
||||||
|
// - Accepts an int slice, so you can pass it one of your slices.
|
||||||
//
|
//
|
||||||
// ---------------------------------------------------------
|
// ---------------------------------------------------------
|
||||||
|
|
||||||
const size = 1e7
|
const size = 1e7
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// stops the gc: prevents cleaning up the memory
|
// don't worry about this code.
|
||||||
|
// it stops the garbage collector: prevents cleaning up the memory.
|
||||||
|
// see the link if you're curious:
|
||||||
|
// https://en.wikipedia.org/wiki/Garbage_collection_(computer_science)
|
||||||
debug.SetGCPercent(-1)
|
debug.SetGCPercent(-1)
|
||||||
|
|
||||||
// run the program to see what this prints
|
// run the program to see the initial memory usage.
|
||||||
report("initial memory usage")
|
report("initial memory usage")
|
||||||
|
|
||||||
// 1. allocate an array with 10 million int elements
|
// 1. allocate an array with 10 million int elements
|
||||||
// this array's size is equal to ~80MB
|
// the array's size will be equal to ~80MB
|
||||||
// hint: use the `size` constant
|
// hint: use the `size` constant above.
|
||||||
//
|
|
||||||
// 2. print the memory usage
|
// 2. print the memory usage (use the report func).
|
||||||
|
|
||||||
|
// 3. copy the array to a new array.
|
||||||
|
|
||||||
// 3. copy the array to a new array (just assign)
|
|
||||||
// 4. print the memory usage
|
// 4. print the memory usage
|
||||||
|
|
||||||
// 5. pass the array to the passArray function
|
// 5. pass the array to the passArray function
|
||||||
|
|
||||||
// 6. convert the one of the arrays to a slice (by slicing)
|
// 6. convert one of the arrays to a slice
|
||||||
|
|
||||||
// 7. slice only the first 1000 elements of the array
|
// 7. slice only the first 1000 elements of the array
|
||||||
|
|
||||||
// 8. slice only the elements of the array between 1000 and 10000
|
// 8. slice only the elements of the array between 1000 and 10000
|
||||||
// 9. print the memory usage
|
|
||||||
|
// 9. print the memory usage (report func)
|
||||||
|
|
||||||
// 10. pass the one of the slices to the passSlice function
|
// 10. pass the one of the slices to the passSlice function
|
||||||
|
|
||||||
// 11. print the sizes of the arrays and slices
|
// 11. print the sizes of the arrays and slices
|
||||||
// hint: use the unsafe.Sizeof function
|
// hint: use the unsafe.Sizeof function
|
||||||
|
// see more here: https://golang.org/pkg/unsafe/#Sizeof
|
||||||
}
|
}
|
||||||
|
|
||||||
// observe that passing an array affects the memory usage dramatically
|
|
||||||
//
|
|
||||||
// passes [size]int array — about 80MB!
|
// passes [size]int array — about 80MB!
|
||||||
|
//
|
||||||
|
// observe that passing an array to a function (or assigning it to a variable)
|
||||||
|
// affects the memory usage dramatically
|
||||||
func passArray(items [size]int) {
|
func passArray(items [size]int) {
|
||||||
items[0] = 100
|
items[0] = 100
|
||||||
report("inside passArray")
|
report("inside passArray")
|
||||||
}
|
}
|
||||||
|
|
||||||
// observe that passing a slice doesn't affect the memory usage
|
|
||||||
//
|
|
||||||
// only passes 24-bytes of slice header
|
// only passes 24-bytes of slice header
|
||||||
|
//
|
||||||
|
// observe that passing a slice doesn't affect the memory usage
|
||||||
func passSlice(items []int) {
|
func passSlice(items []int) {
|
||||||
items[0] = 100
|
items[0] = 100
|
||||||
report("inside passSlice")
|
report("inside passSlice")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reports the current memory usage
|
||||||
|
// don't worry about this code
|
||||||
func report(msg string) {
|
func report(msg string) {
|
||||||
var m runtime.MemStats
|
var m runtime.MemStats
|
||||||
runtime.ReadMemStats(&m)
|
runtime.ReadMemStats(&m)
|
||||||
|
@ -17,7 +17,6 @@ import (
|
|||||||
const size = 1e7
|
const size = 1e7
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// stops the gc: prevents cleaning up the memory
|
|
||||||
debug.SetGCPercent(-1)
|
debug.SetGCPercent(-1)
|
||||||
|
|
||||||
report("initial memory usage")
|
report("initial memory usage")
|
||||||
|
@ -27,7 +27,7 @@ func main() {
|
|||||||
//
|
//
|
||||||
// 7. comment out everything
|
// 7. comment out everything
|
||||||
//
|
//
|
||||||
// 8. declare it again using a slice literal
|
// 8. declare the games slice again using a slice literal
|
||||||
// (use the same elements from step 3)
|
// (use the same elements from step 3)
|
||||||
|
|
||||||
// --- #2 ---
|
// --- #2 ---
|
||||||
|
@ -34,7 +34,7 @@ import (
|
|||||||
//
|
//
|
||||||
// BONUS
|
// BONUS
|
||||||
//
|
//
|
||||||
// + Think about when does the append allocates a new backing array.
|
// + Think about when does the append allocate a new backing array.
|
||||||
//
|
//
|
||||||
// + Check whether your conclusions are correct.
|
// + Check whether your conclusions are correct.
|
||||||
//
|
//
|
||||||
|
@ -32,6 +32,19 @@ import (
|
|||||||
// `api.temps` slice.
|
// `api.temps` slice.
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
// BE CAREFUL
|
||||||
|
//
|
||||||
|
// This code imports the api package from the learn go programming
|
||||||
|
// original repository. So, when you change the code in the api folder
|
||||||
|
// ensure that this code imports your own code.
|
||||||
|
//
|
||||||
|
// see above (this is the original repository code):
|
||||||
|
// you need to change it to your own repository if you're using your own
|
||||||
|
// repository:
|
||||||
|
//
|
||||||
|
// "github.com/inancgumus/learngo/16-slices/exercises/23-limit-the-backing-array-sharing/api"
|
||||||
|
//
|
||||||
|
//
|
||||||
// STEPS
|
// STEPS
|
||||||
//
|
//
|
||||||
// You only need to change the code inside the `api/api.go` folder
|
// You only need to change the code inside the `api/api.go` folder
|
||||||
|
@ -55,6 +55,7 @@ import (
|
|||||||
//
|
//
|
||||||
// go get -u github.com/inancgumus/prettyslice
|
// go get -u github.com/inancgumus/prettyslice
|
||||||
//
|
//
|
||||||
|
//
|
||||||
// ---------------------------------------------------------
|
// ---------------------------------------------------------
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
@ -80,11 +80,11 @@ Please update your local copy of the prettyslice package for some examples to wo
|
|||||||
|
|
||||||
2. **[Limit the backing array sharing](https://github.com/inancgumus/learngo/tree/master/16-slices/exercises/23-limit-the-backing-array-sharing)**
|
2. **[Limit the backing array sharing](https://github.com/inancgumus/learngo/tree/master/16-slices/exercises/23-limit-the-backing-array-sharing)**
|
||||||
|
|
||||||
Your API does not control the slices that it share with the outside world. You need to fix it.
|
Your package needs to control the slices that it shares with the outside world.
|
||||||
|
|
||||||
3. **[Fix the Memory Leak](https://github.com/inancgumus/learngo/tree/master/16-slices/exercises/24-fix-the-memory-leak)**
|
3. **[Fix the Memory Leak](https://github.com/inancgumus/learngo/tree/master/16-slices/exercises/24-fix-the-memory-leak)**
|
||||||
|
|
||||||
A slice retrieved from an API causes a memory leak in your program. You need to fix it.
|
A slice retrieved from a package causes a memory leak in your program. You need to fix it.
|
||||||
|
|
||||||
4. **[Add a newline after each sentence](https://github.com/inancgumus/learngo/tree/master/16-slices/exercises/25-add-lines)**
|
4. **[Add a newline after each sentence](https://github.com/inancgumus/learngo/tree/master/16-slices/exercises/25-add-lines)**
|
||||||
|
|
||||||
@ -92,4 +92,4 @@ Please update your local copy of the prettyslice package for some examples to wo
|
|||||||
|
|
||||||
5. **[Print Daily Requests](https://github.com/inancgumus/learngo/tree/master/16-slices/exercises/26-print-daily-requests)**
|
5. **[Print Daily Requests](https://github.com/inancgumus/learngo/tree/master/16-slices/exercises/26-print-daily-requests)**
|
||||||
|
|
||||||
Group the requests log into a multi-dimensional from a single-dimensional slice. Allocate a slice with the exact size needed by doing some wizardary calculations. And lastly, pretty print the result.
|
Group the web request logs into a multi-dimensional slice. Allocate a slice with the exact size needed by doing some wizardary calculations. And lastly, pretty print the result.
|
||||||
|
Reference in New Issue
Block a user