A concise, interview‑ready reference for Go fundamentals, runtime internals, and concurrency.
1. Structs
Struct Initialization
Go uses composite literals (similar to JS objects, no new keyword required).
type S struct {
f string
f1 int
}
c := S{f: "l", f1: 1}
fmt.Println(c.f)
2. Methods & Receivers
2.1 Value Receiver
- Operates on a copy of the struct
- Original value is not modified
- Go may optimize by passing address internally
func (s S) Update() {
s.f = "x"
}
2.2 Pointer Receiver
- Operates on the original struct
- Mutations persist
func (s *S) Update() {
s.f = "x"
}
Rule of thumb
- Read‑only → value receiver
- Mutations / large structs → pointer receiver
3. Random Numbers
Generate values in [min, max)
rand.Intn(max-min) + min
4. Arrays vs Slices
Arrays
- Fixed length
- Value types (copied on assignment)
arr := [3]int{1, 2, 3}
Slices
- Dynamic length
- Reference to an underlying array
slice := []int{1, 2, 3}
Conceptual representation:
type Slice struct {
ptr *T
len int
cap int
}
Key Differences
| Feature | Array | Slice |
|---|---|---|
| Length | Fixed | Dynamic |
| Copy | Value copy | Reference copy |
| Resize | ❌ | ✅ |
Common Operations
append(slice, val)
len(slice)
slice[:]
slice[a:b]
Spread operator:
newSlice := append([]int{}, slice...)
Looping
for i, ele := range arr {
_ = i
_ = ele
}
5. Strings
From the strings package:
strings.ToUpper()
strings.ToLower()
strings.Split()
strings.Trim()
strings.Replace()
strings.Count()
6. Runes & ASCII
- Go strings are UTF‑8
-
rune=int32
r := 'a'
fmt.Println(r) // 97
ASCII:
-
'0'→ 48 -
'a'→ 97
7. make vs new
make
Initializes reference types and their backing data.
make([]int, 0)
make(map[string]int)
make(chan int)
new
Allocates zero value and returns a pointer.
p := new(int)
8. Errors, Panic & Defer
Error
- Expected failure
- Must be handled
return errors.New("something went wrong")
Panic
- Program is in an invalid state
panic("fatal error")
Defer
- Executes after the surrounding function returns
- Runs in LIFO order
defer cleanup()
When defer does NOT run ❌
os.Exit()SIGKILL- Power failure 😄
Recovering from Panic
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered:", r)
}
}()
9. Goroutines & Go Runtime
Goroutines
- Created using
go - Always concurrent
- Parallelism depends on
GOMAXPROCS
go doWork()
9.1 Goroutines vs OS Threads
- Goroutines are not threads
- Managed by the Go runtime scheduler
9.4 GMP Scheduler & OS Threads
What does it mean when the GMP scheduler runs a goroutine on a specific OS thread?
- The Go runtime scheduler decides which goroutine (G) runs on which logical processor (P)
- A P is bound to an OS thread (M)
- The OS provides threads on demand when requested by the Go runtime
Key Points
- OS allocates threads at the runtime’s request
- The Go program runs inside an OS process
- The runtime multiplexes goroutines over OS threads
High‑level Architecture
OS
└─ Process (your Go app)
├─ Go runtime
│ ├─ Scheduler
│ ├─ GC
│ ├─ M:P:G
│ └─ Threads
└─ Goroutines
OS Process Startup
OS
├─ Loads Go binary
├─ Creates process
├─ Sets up virtual memory
│ ├─ code
│ ├─ globals
│ ├─ stack (main thread)
│ └─ heap address range (empty)
├─ Sets up FD table
└─ Sets env vars
Go Runtime Initialization
Go runtime starts
├─ Initializes memory allocator
│ ├─ Requests heap pages from OS (mmap)
│ ├─ Creates arenas, spans, size classes
├─ Initializes GC
├─ Initializes scheduler (G-M-P)
├─ Creates OS threads
└─ Prepares goroutine stacks
10. File Descriptors & Sockets (Linux)
Process
└─ FD table
└─ FD (int) → Kernel Object
├─ regular file
├─ socket
├─ pipe
└─ device
- Unix socket → IPC
- Network socket → Networking
11. Channels
Basics
ch := make(chan int)
ch <- 1
val := <-ch
Unbuffered Channel
- Send blocks until receive
ch := make(chan int)
Buffered Channel
- Send blocks only when buffer is full
ch := make(chan int, 5)
Closing Channels
close(ch)
Rules:
- Sending after close → panic
- Receiving after close → zero value
- Channel freed after buffer drains
WaitGroup
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
}()
wg.Wait()
12. Channel Internals (Conceptual)
type hchan struct {
buf unsafe.Pointer
elemsize uintptr
qcount uint
dataqsiz uint
sendx uint
recvx uint
recvq waitq
sendq waitq
closed uint32
lock mutex
}
- Channels live on the heap
- Buffered → circular buffer
- Unbuffered → direct handoff
13. Maps
Map Basics
m := make(map[string]int)
m["a"] = 1
val := m["a"]
Zero Value
-
nilmap → cannot assign
var m map[string]int
// m["x"] = 1 // panic
Existence Check
val, ok := m["key"]
Delete
delete(m, "key")
Iteration Order
- Not guaranteed
- Randomized intentionally
for k, v := range m {
_ = k
_ = v
}
Maps are Reference Types
- Passed by reference
- Mutations visible across functions
🔑 Key Takeaways
- Arrays are values, slices & maps are references
- Goroutines are multiplexed over OS threads
- GMP scheduler abstracts thread management
- Channels coordinate goroutines, not store data
-
defer,panic, andrecoverform Go’s failure‑handling trio
Top comments (0)