Irbisa · Шпаргалка
Стандартная библиотека на практике
io и bufio, encoding/json, time, strconv, regexp, embed
Какие поля структуры кодирует
encoding/jsonи что может изменить тегjson:"..."?// wrong: nothing is exported: Marshal returns "{}" and a nil errortype order struct { id int64 total int64 `json:"total"` // a tag on an unexported field does nothing status string}…Как прочитать файл в Go (
os.ReadFile,os.Openсbufioилиio.Copy) и когда что выбирать?// small file: one call, memory = file sizefunc loadJSON(path string, v any) error { b, err := os.ReadFile(path) if err != nil { return err }…Что
bufio.Writerделает с записанными в него байтами и почему перед закрытием файла обязателенFlush?type Row struct { ID int64 Name string} func export(path string, rows []Row) (err error) {…Что выведет этот код и как правильно превратить число в строку и обратно?
func main() { n := 65 a := string(n) b := strconv.Itoa(n) c, err := strconv.Atoi("65 ") fmt.Printf("%q %q %d %v\n", a, b, c, err)}Почему в Go дата форматируется layout'ом
2006-01-02 15:04:05, а неYYYY-MM-DD?const layout = "2006-01-02 15:04:05" // an example, not a pattern func main() { t := time.Date(2024, 3, 5, 9, 7, 0, 0, time.UTC) // wrong: Format never errors: unknown letters are copied through as themselves…Что делает
//go:embed, какие типы переменных он умеет заполнять и почему он чинит путь к файлу, который работает из директории проекта, но не на сервере?//go:embed version.txtvar version string // one file as a string //go:embed templates/*.htmlvar tmplFS embed.FS…Когда нужен
crypto/rand, а неmath/rand, и что изменилось с появлениемmath/rand/v2и в сидировании?import ( crand "crypto/rand" "math/rand/v2" "time")…Как загрузить файл, попутно сжимая его gzip, считая хеш и подсчитывая объём (за один проход и не держа его в памяти), только средствами стандартной библиотеки?
// One pass: gzip to dst, sha256 of the plaintext, count of compressed bytes.func upload(dst io.Writer, name string) (sum []byte, n int64, err error) { f, err := os.Open(name) if err != nil { return nil, 0, err }…Чем
bufio.Scannerотличается отbufio.Readerи почему Scanner на некоторых файлах останавливается сtoken too long?func importLines(r io.Reader, handle func([]byte) error) error { s := bufio.NewScanner(r) s.Buffer(make([]byte, 0, 64*1024), 4*1024*1024) // 64 KB start, 4 MB cap for s.Scan() { // s.Bytes() aliases the scanner's buffer: copy it if you keep it if err := handle(s.Bytes()); err != nil {…Что
omitemptyсчитает пустым и почему нулевойtime.Timeвсё равно попадает в JSON?type Profile struct { Tags []string `json:"tags"` // nil -> null, []string{} -> [] Nick string `json:"nick,omitempty"` // "" -> key absent Score int `json:"score,omitempty"` // 0 -> absent: "score 0" cannot be sent Seen *int `json:"seen,omitempty"` // nil -> absent, &0 -> "seen":0 Created time.Time `json:"created,omitempty"` // wrong: a struct is never "empty"…Ретранслятор вебхуков декодирует payload в
map[string]anyи кодирует обратно. Что выведет этот код и почему большие id приходят изменёнными?const raw = `{"order_id":12345678901234567}` func main() { var m map[string]any json.Unmarshal([]byte(raw), &m) fmt.Printf("%T\n", m["order_id"]) out, _ := json.Marshal(m) fmt.Println(string(out))}Ключ конфига
max_connsсталmaxConnections, и сервис молча поднялся с пулом в ноль. Какие правилаencoding/jsonэто допустили и как заставить его падать?type Config struct { Addr string `json:"addr"` MaxConns int `json:"max_conns"`} func load(r io.Reader) (Config, error) {…Найдите баг: у некоторых заказов появляется купон, которого клиент не вводил.
type Order struct { ID string `json:"id"` Coupon string `json:"coupon"`} func parseOrders(lines [][]byte) ([]Order, error) { var out []Order var o Order for _, line := range lines { if err := json.Unmarshal(line, &o); err != nil { return nil, err } out = append(out, o) } return out, nil}Этот
MarshalJSONдолжен кодироватьEvent.Atпростой датой. Почему первый же вызов роняет весь процесс и как это исправить?type Event struct { Name string `json:"name"` At time.Time `json:"at"`} func (e Event) MarshalJSON() ([]byte, error) { type payload = Event // "a copy of Event without the method" return json.Marshal(struct { payload At string `json:"at"` }{payload(e), e.At.Format(time.DateOnly)})}Что меняет экспериментальный
encoding/json/v2из Go 1.25 по сравнению сencoding/jsonи когда команды всё ещё выбираютeasyjsonилиsonic?Что такое рефлексия в Go, где на неё опирается стандартная библиотека и чем она обходится?
type Config struct { Host string `env:"APP_HOST"` Port int `env:"APP_PORT"`} // Fills string and int fields from the env vars named in `env` tags.…Почему
regexpв Go гарантированно работает за линейное время и чего он не умеет?Как загрузить конфигурацию Go-сервиса только средствами стандартной библиотеки (дефолты, переменные окружения, флаги) и где место валидации?
type Config struct { Addr string DatabaseURL string Timeout time.Duration}…Как написать TCP-сервер на
net.ListenиAcceptи что нужно добавить для дедлайнов и graceful shutdown?type Server struct { ln net.Listener wg sync.WaitGroup conns sync.Map // live connections done chan struct{} // closed by Shutdown: the quit signal}…NTP переводит часы на 400 мс назад:
time.Since(start)остаётся верным, аend.UnixNano() - start.UnixNano()уходит в минус. Что несёт в себеtime.Time, из-за чего такая разница?Как загрузить NDJSON-файл на 40 ГБ, где форма
dataзависит от поляtypeкаждой строки, в постоянной памяти и декодируя каждую строку в Go-значения один раз?type Envelope struct { Type string `json:"type"` Data json.RawMessage `json:"data"` // raw bytes until Type is known} type Push struct{ Ref string `json:"ref"` }…Что
unsafe.Pointerумеет такого, чего не может обычный Go, и почему преобразование[]byteвstringбез копирования черезunsafe.Stringстановится багом, если байты меняются?func main() { buf := []byte("alice") // wrong: zero-copy, so name shares buf's bytes name := unsafe.String(unsafe.SliceData(buf), len(buf)) seen := map[string]bool{name: true}…Найдите баг:
checksumотgzip.Readerобычно не совпадает сsha256sumраспакованного файла, хотя ошибки нет.// called as: zr, _ := gzip.NewReader(f); sum, err := checksum(zr)func checksum(r io.Reader) ([]byte, error) { h := sha256.New() buf := make([]byte, 32*1024) for { n, err := r.Read(buf) if err == io.EOF { break } if err != nil { return nil, err } h.Write(buf[:n]) } return h.Sum(nil), nil}