What you'll learn
Quick Answer
Go is a small statically typed compiled language with built-in concurrency. Goroutines make concurrent work cheap, compilation produces a single binary with no runtime dependency, and the language deliberately omits features to keep code uniform.
Deliberately small
Go was created at Google to address specific frustrations: enormous C++ build times, dependency complexity, and codebases where every team used a different subset of the language.
The response was to leave things out. Go has no inheritance, no generics for its first decade, no exceptions, no operator overloading, and one loop keyword. The specification is short enough to read in an afternoon.
The intended consequence is uniformity. Go code from different teams looks alike, partly because the language offers few choices and partly because gofmt enforces one formatting style with no options. Nobody argues about braces because there is nothing to argue about.
Programmers who like expressive languages find this limiting, and that reaction is expected. Go optimises for reading code you did not write, over writing code you enjoy.
What it looks like
package main
import "fmt"
type Student struct {
Name string
Marks int
}
func (s Student) Grade() string {
if s.Marks >= 90 {
return "A"
}
return "B"
}
func main() {
students := []Student{{"Asha", 91}, {"Ravi", 68}}
for _, s := range students {
fmt.Printf("%s -> %s\n", s.Name, s.Grade())
}
}
Points worth noting. := declares and infers a type. Methods attach to types via a receiver rather than living inside a class. A capital first letter means exported — that is the entire visibility system, replacing public and private. And _ discards a value you do not need.
Unused variables and imports are compile errors, not warnings. This annoys newcomers and keeps codebases free of dead references.
Errors are returned, not thrown
data, err := os.ReadFile("config.json")
if err != nil {
return fmt.Errorf("reading config: %w", err)
}
There are no exceptions. Functions return an error alongside their result, and you check it. This pattern appears constantly — it is the single most distinctive thing about reading Go.
The criticism is obvious: it is repetitive, and if err != nil makes up a visible fraction of any Go file.
The defence is equally real: every failure point is visible at the call site. There is no invisible control flow jumping up the stack, and you cannot forget an error exists — the compiler will not let you silently ignore a returned value you assigned.
Wrapping with %w preserves the original error so the chain can be inspected, which is the equivalent of an exception cause.
Goroutines and channels
This is Go's headline feature and the main reason it is chosen for servers.
go doWork() // runs concurrently, that is the whole syntax
A goroutine is not an operating system thread. It starts with a very small stack and is multiplexed onto a few real threads by the runtime, so hundreds of thousands can run at once — a scale at which real threads would exhaust memory.
Communication uses channels rather than shared memory and locks:
ch := make(chan string)
go func() { ch <- "done" }()
msg := <-ch // blocks until a value arrives
fmt.Println(msg)
The Go proverb is "do not communicate by sharing memory; share memory by communicating." Passing values through channels avoids most of the shared mutable state that causes race conditions.
Go still has mutexes and can still deadlock — sending on a channel nobody reads blocks forever. It makes concurrency cheap and readable, not automatically correct.
Where Go fits
Strong fits: network services and APIs, command-line tools, and infrastructure software. Docker, Kubernetes, Terraform and Prometheus are all written in Go, which tells you what it is good at.
The deployment story is a large practical advantage: go build produces a single static binary with no interpreter and no dependencies. Copy one file to a server and run it. Compare with shipping a Python app plus its interpreter and packages, or a JVM application plus a runtime.
Weaker fits: data science and machine learning, where Python's ecosystem is unmatched; user interfaces; and domains wanting rich type-level expression.
For students in India: Go appears in backend and infrastructure roles, particularly at product companies and startups, and less in campus placement processes than Java. It is an excellent second backend language, and it is unusually quick to learn — the small surface area that frustrates experienced developers is genuinely helpful when starting.
