Go (или Golang) — это компилируемый, строго типизированный язык программирования от Google, созданный для разработки быстрых, надёжных и масштабируемых приложений.
💡 Особенности:
- Простота синтаксиса, как у Python
- Производительность на уровне C
- Встроенная конкурентность через
goroutines - Идеально для серверной разработки, микросервисов, сетевых программ, CLI-инструментов
- Официальный сайт: https://go.dev/
- Установка: https://go.dev/doc/install
- Архив всех версий: https://go.dev/dl/
- Онлайн-песочница: https://go.dev/play/
Go использует модули для управления зависимостями и сборкой. Каждый проект — это отдельный модуль.
Пример структуры:
amfs/
├── cmd/
│ └── amfs/ ← точка входа (main.go) для приложения
├── internal/ ← внутренние пакеты (нельзя импортировать извне)
├── pkg/ ← переиспользуемые публичные пакеты
├── go.mod ← описание модуля и зависимостей
├── main.go ← стартовый файл
└── other.go ← дополнительные исходники
Функция main() — стартовая точка выполнения программы.
Она должна находиться в пакете main, иначе компиляция завершится с ошибкой.
go mod init amfs # инициализация модуля
go run main.go # компиляция и запуск
go build # компиляция → бинарный файл
go get <package> # установка стороннего пакетаПример:
go get github.com/shopspring/decimalvar x int = 10 // явное объявление
x := 10 // короткая форма (внутри функций)
const Pi = 3.14 // константа (нельзя изменить)| Категория | Типы |
|---|---|
| Целые | int, int8, int16, int32, int64 |
| Беззнаковые | uint, uint8, uint16, uint32, uint64 |
| С плавающей точкой | float32, float64 |
| Логические | bool |
| Строки | string |
| Символы | rune (аналог char, по сути int32) |
| Указатели | *int, *string и т. д. |
| Обобщённый тип | interface{} |
⚠️ Никогда не используйтеfloatдля хранения финансов — используйтеdecimal.
Модуль fmt используется для ввода/вывода и форматирования.
fmt.Println("Hello") // С пробелами и новой строкой
fmt.Printf("x = %d", 10) // Форматированный вывод
s := fmt.Sprintf("Pi=%.2f", 3.1415) // Возврат строкиfmt.Scan(&x, &y) // Считывает через пробел
fmt.Scanf("%d %s", &a, &b) // Форматированный ввод| Спецификатор | Назначение |
|---|---|
%d |
Целое число (int) |
%f |
Число с плавающей точкой |
%.2f |
Float с 2 знаками после запятой |
%s |
Строка |
%t |
Boolean |
%v |
Значение как есть |
%T |
Тип значения |
if a > b {
fmt.Println("a больше b")
} else if a == b {
fmt.Println("равны")
} else {
fmt.Println("b больше a")
}- Скобки
()не требуются! - Переменные можно объявлять внутри
if:
if n := rand.Intn(10); n > 5 {
fmt.Println("Большое:", n)
}Переменная n не видна за пределами if.
switch выражение {
case значение1:
// действие
case значение2:
// другое действие
default:
// если ничего не подошло
}type EComStatus uint8
const (
New EComStatus = iota
PreAuth
Complete
Declined
Refunded
Reversed
)
func (status EComStatus) IsValid() bool {
switch status {
case New, PreAuth, Complete, Declined, Refunded, Reversed:
return true
}
return false
}const (
A = iota // 0
B // 1
C // 2
)Полезен для:
- Перечислений (
enum) - Побитовых флагов
- Автоматической генерации чисел
Все задачи должны быть оформлены по базовой структуре проекта Go с соблюдением принципов DRY, KISS, SOLID.
Структура проекта:
project/
├── cmd/ # точка входа в приложение
├── internal/ # внутренняя логика
├── pkg/ # переиспользуемые пакеты
├── Makefile # команды управления
├── .gitignore # исключения для Git
├── .env # переменные окружения (опционально)
├── .env.dist # шаблон .env
Создать мини-приложение, которое:
- Оформлено по структуре
internal/pkg/cmd - Совмещает в себе функционал двух предыдущих задач (в виде функций в отдельных модулях)
- Имеет
Makefileс командами:make run— запуск приложенияmake build— сборка в../binmake link— проверка форматирования и статики (go fmt,go vet)
- Содержит
.gitignore,.env,.env.dist— для будущих задач
- Использовать
fmtдля ввода и вывода - Использовать пакет
shopspring/decimal
Вход:
15
Выход:
7800 KZT
Обработать массив транзакций, где каждая — это map[int]decimal.Decimal, где:
int— номер дня недели (1 = Пн, 7 = Вс)decimal.Decimal— сумма транзакции
Положительная сумма = доход, отрицательная = расход
transactions := []map[int]decimal.Decimal{
{1: decimal.NewFromFloat(25000.00)},
{1: decimal.NewFromFloat(20000.00)},
{2: decimal.NewFromFloat(-9800.00)},
{3: decimal.NewFromFloat(-1222.22)},
{4: decimal.NewFromFloat(-1500.07)},
{5: decimal.NewFromFloat(1201.37)},
{6: decimal.NewFromFloat(-100.32)},
{7: decimal.NewFromFloat(-523.33)},
}- Применить:
for,if / else if / else,switch - Итоговый вывод:
- День недели
- Доход / Расход за день
- Общий итог за неделю
Понедельник
Поступление: 45000.00
Вторник
Списание: 9800.00
Среда
Списание: 1222.22
Четверг
Списание: 1500.07
Пятница
Поступление: 1201.37
Суббота
Списание: 100.32
Воскресенье
Списание: 523.33
Итог за неделю: -10844.57
Также показать грамотное применение логических конструкций и позитивных практик написания кода.
Массив — это фиксированная по длине коллекция однотипных элементов. Длина массива является частью его типа.
var a [3]int // массив из трёх int, по умолчанию [0, 0, 0]
a[0] = 10 // установка значения
fmt.Println(a[1]) // доступ к элементу: 0- Тип
[3]intи[4]int— разные типы. - Массивы копируются по значению.
- Можно итерировать через
for i, v := range a - Нельзя изменить длину массива после создания.
- Внутри
range— копия массива (если не использовать указатель).
Слайс — это обёртка над массивом, включающая длину и ёмкость.
b := []int{1, 2, 3}
b = append(b, 4)len(b)— текущая длина,cap(b)— ёмкость.appendможет выделить новую память.- Слайсы передаются по ссылке.
- Срезы:
b[1:3],b[:2],b[2:] - Можно делать срез от среза:
b2 := b[1:]
m := make(map[string]int)
m["apple"] = 5
val, ok := m["apple"]
delete(m, "apple")- Проверка ключа:
val, ok := m["key"] - Удаление:
delete(m, "key") - Порядок итерации не гарантируется.
- Ключи — сравнимые типы.
- Значения — любые типы.
Функции — основной строительный блок в Go.
func Add(a int, b int) int {
return a + b
}func Swap(x, y string) (string, string) {
return y, x
}func NamedReturn() (a int, b int) {
a = 1
b = 2
return
}f := func(x int) int {
return x * x
}
fmt.Println(f(5))func() {
fmt.Println("Привет!")
}()func Counter() func() int {
count := 0
return func() int {
count++
return count
}
}func Apply(fn func(int) int, val int) int {
return fn(val)
}func Sum(nums ...int) int {
total := 0
for _, n := range nums {
total += n
}
return total
}func Factorial(n int) int {
if n == 0 {
return 1
}
return n * Factorial(n-1)
}func AddOne(x *int) {
*x = *x + 1
}
val := 10
AddOne(&val)
fmt.Println(val) // 11*x— разыменование&val— получение адреса- Nil-указатели:
var p *int
type User struct {
Name string
Age int
}
u := User{Name: "Alice", Age: 30}
fmt.Println(u.Name)- Можно создавать указатели
u := &User{} - Сравнимы, если все поля сравнимы
set := make(map[string]struct{})
set["apple"] = struct{}{}
_, ok := set["apple"]
delete(set, "apple")- Тип
struct{}— 0 байт - Проверка:
_, ok := set[key]
Разработать Go-сервис, который:
- Загружает конфигурацию через
viper - Подключается к PostgreSQL
- Автоматически мигрирует таблицы
- Работает с транзакциями и статусами
- Порт приложения
- DEBUG режим
- Автомиграция
- Данные БД
- Docker переменные
.env.distкак пример
| Поле | Тип данных | Описание |
|---|---|---|
| id | UUID (PK) | Уникальный ID |
| client_id | TEXT | ID клиента |
| client_secret | TEXT | Секретный ключ |
| uuid | TEXT | Активен ли |
| Поле | Тип | Описание |
|---|---|---|
| id | UUID | ID транзакции |
| terminal_id | UUID | FK на терминал |
| order_id | TEXT | ID клиента |
| amount | NUMERIC(12,2) | Сумма |
| status | TEXT | Статус |
| created_at | TIMESTAMP | Создана |
| status_changed | TIMESTAMP | Статус изменён |
| code | TEXT | Код |
| message | TEXT | Сообщение |
| Статус | Описание |
|---|---|
REFUND |
Возврат суммы |
AUTH |
Блокировка суммы |
CANCEL |
Разблокировка |
CHARGE |
Списание |
VERIFIED |
Проверка карты |
CANCEL_OLD |
Истёк срок CHARGE |
FAILED |
Неуспешно |
FINGERPRINT |
Проверка перед 3D |
3D |
Ошибка 3D |
NEW |
Ожидание |
REJECT |
Отклонено |
NEW→AUTHAUTH→CHARGEилиCANCELCHARGE→REFUND
- Глобальный конфиг через
viper - Подключение к БД
- Автомиграции (по флагу из конфига)
- Создание транзакций и смена статусов