Drills

Drills

Five tasks. All of them are about memory layout, not syntax.


1. InsertAt(items []Item, i int, it Item) []Item

Inserts it at position i and returns the new slice.

Count how many elements shifted. Do it for i = 0, i = n/2 and i = n. Which of the three is O(1), and why?


2. DeleteAt(items []Item, i int) []Item

Deletes an element while preserving order.

Then write DeleteFast, which does not preserve order: it moves the last element into the gap and shortens the slice.

How many shifts does each cost? When is DeleteFast the wrong choice?


3. Grow(n int) (reallocs, copied int)

Reproduce step 2's measurement without the algo command — just a function returning two numbers.

Then run it starting from make([]Item, 0, n), with the capacity reserved up front. How many reallocations do you get? Explain why.


4. MemoryPerItem(n int) float64

Work out how many bytes per item are actually reserved when a slice holds n elements: cap × size / n.

Run it for n from 1 to 100. When is the ratio worst? Tie your answer back to the capacity sequence in step 2.


5. The zero-value trap

What happens if you write lib := make([]Item, 1000) and then append to it?

Write a short program that shows it, and explain how make([]Item, 1000) differs from make([]Item, 0, 1000). This mistake gets made constantly.