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/decimal
var 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
— сборка в../bin
make 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
→AUTH
AUTH
→CHARGE
илиCANCEL
CHARGE
→REFUND
- Глобальный конфиг через
viper
- Подключение к БД
- Автомиграции (по флагу из конфига)
- Создание транзакций и смена статусов