Ответ
Это можно сделать через
runtime.GOMAXPROCS()
. Важно понимать, что при выставлении количества логических процессоров больше, чем есть у вас в системе, вы рискуете получить определенные проблемы с производительностью. Чтобы избежать этого можно задать runtime.GOMAXPROCS(runtime.NumCPU()), runtime.NumCPU() - количество логических процессоров.@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
Как принудительно переключить контекст?
Ответ
Переключение контекста вручную осуществляется с помощью функции
@golang_interview
Ответ
Переключение контекста вручную осуществляется с помощью функции
runtime.Goshed()
.@golang_interview
Ответ
wait group;
mutex;
atomic;
sync map;
channel.
@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
Для чего используется sync map?
Ответ
Простой ответ на этот вопрос: достаточно частый кейс использования в Go mutex, который защищает данные в map. sync.Map можно рассматривать как map+RWMutex обертку. Но на деле этот ответ не совсем правильный, так как sync.Map решает одну довольно конкретную проблему cache contention. Что же это такое? При использовании sync.RWMutex в случае блокировки на чтение каждая горутина должна обновить поле readerCount, что происходит атомарно. Довольно обще процесс выглядит так:
- ядро процессора обновляет счетчик;
- ядро процессора сбрасывает кэш для этого адреса для всех других ядер;
- ядро процессора объявляет, что только оно знает действующее значение для обрабатываемого адреса;
- следующее ядро процессора вычитывает значение из кэша предыдущего;
- процесс повторяется. Так вот, когда несколько ядер хотят обновить readerCount, образуется очередь. И операция, которую мы считали константной, становится линейной относительно количества ядер. Именно решая эту проблему и ввели sync.Map. sync.Map рекомендуется применять именно на многопроцессорных системах.
@golang_interview
Ответ
Простой ответ на этот вопрос: достаточно частый кейс использования в Go mutex, который защищает данные в map. sync.Map можно рассматривать как map+RWMutex обертку. Но на деле этот ответ не совсем правильный, так как sync.Map решает одну довольно конкретную проблему cache contention. Что же это такое? При использовании sync.RWMutex в случае блокировки на чтение каждая горутина должна обновить поле readerCount, что происходит атомарно. Довольно обще процесс выглядит так:
- ядро процессора обновляет счетчик;
- ядро процессора сбрасывает кэш для этого адреса для всех других ядер;
- ядро процессора объявляет, что только оно знает действующее значение для обрабатываемого адреса;
- следующее ядро процессора вычитывает значение из кэша предыдущего;
- процесс повторяется. Так вот, когда несколько ядер хотят обновить readerCount, образуется очередь. И операция, которую мы считали константной, становится линейной относительно количества ядер. Именно решая эту проблему и ввели sync.Map. sync.Map рекомендуется применять именно на многопроцессорных системах.
// Lock locks rw for writing.
// If the lock is already locked for reading or writing,
// Lock blocks until the lock is available.
func (rw *RWMutex) Lock() {
if race.Enabled {
_ = rw.w.state
race.Disable()
}
// First, resolve competition with other writers.
rw.w.Lock()
// Announce to readers there is a pending writer.
r := atomic.AddInt32(&rw.readerCount, -rwmutexMaxReaders) + rwmutexMaxReaders
// Wait for active readers.
if r != 0 && atomic.AddInt32(&rw.readerWait, r) != 0 {
runtime_SemacquireMutex(&rw.writerSem, false, 0)
}
if race.Enabled {
race.Enable()
race.Acquire(unsafe.Pointer(&rw.readerSem))
race.Acquire(unsafe.Pointer(&rw.writerSem))
}
}
@golang_interview
Если размер стэка горутины превышен (к примеру запустили бесконечную рекурсию), то приложение упадет с fatal error.
runtime: goroutine stack exceeds 1000000000-byte limit
fatal error: stack overflow
@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
https://go101.org/blog/2022-08-22-some-undocumented-chang
@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
go101.org
Some Undocumented Changes in Go 1.18 and 1.19 -Go 101
Golang online books, articles, tools, etc.
#практика
Необходимо реализовать сервис, позволяющий следить за изменением цены любого объявления на Авито (другой аналогичный сайт с объявлениями):
1. Сервис должен предоставить HTTP метод для подписки на изменение цены. На вход метод получает - ссылку на объявление, email на который присылать уведомления.
2.После успешной подписки, сервис должен следить за ценой объявления и присылать уведомления на указанный email.
3. Если несколько пользователей подписались на одно и тоже объявление, сервис не должен лишний раз проверять цену объявления.
Требования к решению
- Необходимо проработать архитектуру сервиса и описать принципиальную схему работы в виде текста и/или диаграмм.
- Приложить фрагменты кода, решающие конкретные задачи:
- Подписка на изменение цены
- Отслеживание изменений цены
- Отправка уведомления на почту
Работа с БД
- Язык программирования Golang.
Чтобы получить цену объявления, можно:
- парсить web-страницу объявления
- самостоятельно проанализировать трафик на мобильных приложениях или мобильном сайте и выяснить какой там API для получения информации об объявлении
Усложнения
- Реализовать полноценный сервис, который решает поставленную задачу (сервис должен запускаться в docker-контейнере).
- Написаны тесты (постарайтесь достичь покрытия в 70% и больше).
- Подтверждение email пользователя.
Ставьте ❤️, если вам интересно увидеть практические задания с реальных собеседований.
@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
Нам нужно разбить процессы на несколько горутин — при этом не создавать новую горутину каждый раз, а просто переиспользовать уже имеющиеся. Для этого создадим канал с джобами и результирующий канал. Для каждого воркера создадим горутину, который будет ждать новую джобу, применять к ней заданную функцию и пулять ответ в результирующий канал.
Решение
package main
import (
"fmt"
)
func worker(id int, f func(int) int, jobs <-chan int, results chan<- int) {
for j := range jobs {
results <- f(j)
}
}
func main() {
const numJobs = 5
jobs := make(chan int, numJobs)
results := make(chan int, numJobs)
multiplier := func(x int) int {
return x * 10
}
for w := 1; w <= 3; w++ {
go worker(w, multiplier, jobs, results)
}
for j := 1; j <= numJobs; j++ {
jobs <- j
}
close(jobs)
for i := 1; i <= numJobs; i++ {
fmt.Println(<-results)
}
}
@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from Golang
Тестовое задание для кандидата на должность Golang разработчика.
Описание
Есть внешний сервис, который обрабатывает некие абстрактные объекты батчами. Данный сервис может обрабатывать только определенное количество элементов n в заданный временной интервал p. При превышении ограничения, сервис блокирует последующую обработку на долгое время.
Задача заключается в реализации клиента к данному внешнему сервису, который позволит обрабатывать максимально возможное количество объектов без блокировки. Приводить реализацию внешнего сервиса необязательно!
Определение сервиса:
package main
import (
"context"
"errors"
"time"
)
// ErrBlocked reports if service is blocked.
var ErrBlocked = errors.New("blocked")
// Service defines external service that can process batches of items.
type Service interface {
GetLimits() (n uint64, p time.Duration)
Process(ctx context.Context, batch Batch) error
}
// Batch is a batch of items.
type Batch []Item
// Item is some abstract item.
type Item struct{}
Требования
- язык программирования Golang.
- решение должно быть в git-репозитории (можно прислать архив или опубликовать на github, gitlab, bitbucket...).
Пожелания
- документирование кода;
- тесты;
- использование статического анализатора (конфигурацию положить в репозиторий).
Варианты решений можно присылать в комментарии.
❤️, если нравится такие задачи.
@Golang_google
Please open Telegram to view this post
VIEW IN TELEGRAM
Ваша компания отправляет СМС с трекинговой ссылкой, но ссылка достаточно длинная и из-за этого СМС выходит за 70 символов (длина 1 СМС). Необходимо спроектировать сервис-«укорачиватель ссылок» на языке GO, чтобы сэкономить деньги компании. Интервьюер при этом выступает заказчиком со стороны бизнеса и ему можно задавать вопросы по сути задачи.
Примечание
Задача хороша тем, что в нее можно углубляться по нескольким направлениям и оценить сразу несколько скиллов кандидата, а также глубину проработки (по сути его опыт), причём даже если он её уже решал (а многие действительно это делали). Основные направления обсуждения:
- как будем делать с точки зрения структуры приложения (в самом проекте/микросервисе и критерии, по которым мы делаем этот выбор). И тот, и другой варианты допустимы — все дело в аргументации. Если кандидат вообще не говорит про задачу с этой стороны, а, например, сразу переходит к структуре таблицы, то, скорее всего, кандидат никогда не задумывается над такими вопросами и/или не работал в более-менее крупных проектах;
- структура данных и выбор хранилища (СУБД, key-value типа Redis, еще какие-то варианты, плюсы и минусы тех или иных вариантов). Опять же, в зависимости от вопросов кандидата и желания интервьюера можно подвести к выбору какого-то варианта, но в целом есть множество вариантов реализации, которые будут оправданы — опять же, вопрос в аргументации выбора;
- хеши/коллизии, устойчивость к перебору ссылок (расчет количества необходимых вариантов). Важно, чтобы собеседуемый разработчик узнал про количество ссылок, оценил максимально возможную длину ссылки (и срок действия) и принял решение о том, какое количество символов стоит заложить в короткий URL. Плохо, если кандидат сильно перезакладывается или берет слишком маленькое количество символов, что может привести к тому, что допустимые комбинации в обозримом будущем закончатся;
- дополнительно можно углубиться в смежные темы: деплой/мониторинг сервиса в том или ином виде в зависимости от выбора в предыдущих вопросах, приблизительная оценка ресурсов, минимально необходимых для эксплуатации, отказоустойчивость.
@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
Загрузка из «плохого» API большого количества данных и их синхронизация с табличкой в БД (например, Postgres). Считаем, что на входе мы скачиваем JSON-массив из N (>100k) объектов (dict) заданной структуры (primary key поле + некоторое количество строковых полей). Считаем, что нам надо раз в некоторое время запускать функцию, которая создаст записи, которые есть в JSON, но их нет в базе, а далее обновит строковые поля там, где что-то поменялось, и пометить удаленными записи, которых нет в JSON, но они все еще есть в базе.
Примечание
Есть 3 простых решения. Первое — просто перебрать записи из JSON, выбирая из базы записи по одной по pk, но тогда мы получим N запросов в базу, что может приводить к неконтролируемой пиковой нагрузке. Второе — выбрать из базы полностью таблицу и сравнить 2 массива, что будет работать, скорее всего, быстрее других вариантов, но будет максимально неэффективно по памяти (упрощаем решение задачи выделением дополнительных ресурсов, но, опять же, есть вероятность, что из-за неожиданно большого объема данных памяти может не хватить и выполнение таска прервется). Компромиссный вариант по производительности, нагрузке на базу и памяти — проходить циклом по JSON (или записям базы, но там есть нюансы) бачами по 100-1000 шт., накапливая обработанные id. Это сократит количество запросов на 2-3 порядка, не потребует загрузки в память всех текущих данных, но при этом будет всё ещё достаточно быстро. Также тут можно обсудить варианты реализации чисто средствами базы (временные таблицы, bulk upsert-ы и т.д.)
@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
***
Что такое транзакция? Приведите пример, где это может пригодиться. Расскажите про свойства транзакций и уровень изолированности.
Ответ
Транзакция объединяет последовательность действий в одну операцию и обеспечивает выполнение либо всех действий из последовательности, либо ни одного. Канонический пример — списывание денег с одного счета и зачисление на другой, что требует два update-а, которые гарантированно должны выполниться или не выполниться вместе.
Что такое server side cursor и зачем он нужен?
Ответ
Способ работы с результатом запроса в базу данных, который позволяет не загружать весь объем данных в память, позволяет работать с большими объемами данных. Дополнительно углубленно можно поговорить про особенности работы в связке с pgbouncer.
Что такое VACUUM и зачем он нужен в PostgreSQL?
Ответ
Команда VACUUM высвобождает пространство, занимаемое «мертвыми» кортежами, что актуально для часто используемых таблиц. При обычных операциях в Postgres кортежи, удаленные или устаревшие в результаты обновления, физически не удаляются, а сохраняются в таблице до очистки.
Что такое EXPLAIN? Какая разница между ним и EXPLAIN ANALYZE?
Ответ
EXPLAIN ANALYZE – в отличие от просто EXPLAIN не только показывает план выполнения запроса, но и непосредственно выполняет запрос и показывает реальное время выполнения
@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
Ответ
package main
import (
"fmt"
)
func main() {
naturals := make(chan int)
squares := make(chan int)
go func() {
for x := 0; x <= 10; x++ {
naturals <- x
}
close(naturals)
}()
go func() {
for x := range naturals {
squares <- x * x
}
close(squares)
}()
for x := range squares {
fmt.Println(x)
}
}
@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
Вариант решения
package main
import (
"errors"
"fmt"
"os"
)
func main() {
file, err := os.Open("data.json")
if errors.Is(err, os.ErrNotExist) {
fmt.Println("File not found")
return
}
// Выполните какое-нибудь действие с файлом
defer file.Close()
}
Пишите свой вариант в комментариях
@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
Вариант решения
brandsMap := map[string]string{
"ford": "ford",
"audi": "ford",
"lada": "nil",
}
_, value := brandsMap["lada"]
fmt.Print(value) // true,
//value выдаст true или false, если ключ lada есть в brandsMap
Пишите свой вариант в комментариях.
@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача, которая была популярна в своё время на собеседованиях в Amazon. Мы русифицировали её, но смысл остался тот же. Вам нужно продолжить последовательность.
Ответ
Вот один из возможных ответов на эту задачу. Последовательности сопоставлены буквы алфавита, закодированные в набор «П» и «К» — некоторых характеристик. Нужно найти что-то, чего в букве А три, в Б — две и т.д. Тут подходит количество прямых штрихов и кривых. Далее несложно догадаться, что букве Д соответствует, например, «ППППП», в случае её написания как на предложенном рисунке.
Последовательности сопоставлены буквы алфавита, закодированные в набор «П» и «К» — некоторых характеристик. Нужно найти что-то, чего в букве А три, в Б — две и т.д. Тут подходит количество прямых штрихов и кривых. Далее несложно догадаться, что букве Д соответствует, например, «ППППП», в случае её написания как на предложенном рисунке.
@golang_interview
Ответ
Вот один из возможных ответов на эту задачу. Последовательности сопоставлены буквы алфавита, закодированные в набор «П» и «К» — некоторых характеристик. Нужно найти что-то, чего в букве А три, в Б — две и т.д. Тут подходит количество прямых штрихов и кривых. Далее несложно догадаться, что букве Д соответствует, например, «ППППП», в случае её написания как на предложенном рисунке.
Последовательности сопоставлены буквы алфавита, закодированные в набор «П» и «К» — некоторых характеристик. Нужно найти что-то, чего в букве А три, в Б — две и т.д. Тут подходит количество прямых штрихов и кривых. Далее несложно догадаться, что букве Д соответствует, например, «ППППП», в случае её написания как на предложенном рисунке.
@golang_interview
На самом деле, не существует чётко определённого ограничения на количество запускаемых контейнеров на Docker. Тем менее, ограничение накладывает само оборудование.
Всего существует два основных фактора, которые могут ограничить число запускаемых контейнеров – размер вашего приложения и мощность вашего CPU. Если ваше приложение не изобилует функциями, и у вас есть большой запас мощности CPU, то вы можете запустить огромное количество контейнеров Docker одновременно.
✔️ Чем Docker Отличается От Hypervisor?
Опять же, ещё один вопрос собеседования по Docker для новичков, который потребует от вас знаний других инструментов для контейнеризации. Ответив на данный вопрос, вы покажете свою компетентность в сфере разработки в целом, а не только расскажете про использование Docker (что очень хорошо!).
По сути, здесь всё сводится к одной простой вещи – Hypervisor для стабильного функционирования потребует от вас обширного оборудования, тогда как Docker запускается лишь на операционной системе. Это позволяет Docker быть невероятно быстрым и выполнять задачи более плавно – в этом Hypervisor ему явно уступает.
#docker #junior #Go
@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
Описание:
Есть функция, которая принимает от всех модулей значение комиссии за предоставление услуг компании.
Размер комиссии может быть от 0 до 99.99
Максимальное количество знаков после запятой: 2
В базу данных записываются только целые значения, поэтому запятую приходится сдвигать на 2 знака.
Например для комиссии размером 1.5 значение в базе данных будет соответствовать 150
Работа с функцией не должна требовать каких-либо проверок перед отправкой значения.
Результат работы функции не должен требовать перепроверки со стороны модулей, т.е. возвращаемое значение всегда считается корректным.
Разработчик реализовал функцию проверки корректности ввода и преобразования вводимого значения.
Со стороны клиентов поступают жалобы на то, что вводимая ими комиссия записывается не верно или не записывается вовсе, однако все утверждают, что заполняют корректное значение с дробной частью или без.
Задание для разработчика:
Исправьте функцию проверки вводимого значения и дальнейшего преобразования для корректной записи в базу данных итогового значения.
Под данными для записи в базу данных подразумевается результат работы функции check_commission()
Задание для тестировщика:
Проверьте корректность работы фукнции изменяя входящее значение по вашему усмотрению.
В случае выявления ошибок опишите порядок действий, которые привели к ошибке.
Задание для системного аналитика: Напишите постановку данной задачи для разработчика с максимальной детализацией.
Готовое решение нужно предоставить в виде ссылки по кнопке "Share"
package main
// Импортируем библиотеки вывода и конвертации
import (
"fmt"
"strconv"
)
// Функция проверки комиссии
func check_commission(number string) uint64 {
// Конвертируем присланное значение из строки в число с запятой во временную переменную
tempValue, err := strconv.ParseFloat(number, 64)
// Если конвертация не получилась
if err != nil {
// Скажем об этом
fmt.Println("Введено не число:", number)
// И выйдем из функции
return 0
}
// Если конвертация удалась
// Умножим значение на 100, тем самым сдвинем запятую
tempValue = tempValue * 100
// Преобразуем значение в нужный тип данных
result := uint64(tempValue)
// Возвращаем корректное значение
return result
}
// Ввиду ограничений формы входящее значение от пользователя всегда в string
// Пеменная input будет эмулировать входящее значение
func main() {
// Проверяем маленькое значение
input := "0.01"
fmt.Println("Первое значение:", input)
fmt.Println("Преобразованное значение:", check_commission(input))
// Проверяем большое значение
input = "99.99"
fmt.Println("\nВторое значение:", input)
fmt.Println("Преобразованное значение:", check_commission(input))
// Проверяем если ввели не число
input = "неЧисло"
fmt.Println("\nСтроковое значение:", input)
fmt.Println("Преобразованное значение:", check_commission(input))
}
@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
Яндекс это же сайт, что я там буду делать?
Разговор с тимлидом команды Serverless Yandex Cloud про продуктовые исследования, фичеборды, виртуальные команды и топ-качества разработчиков.
Смотрите выпуск на YouTube канале Yandex Cloud ➡️
00:00 Приветствие
01:19 Как держать темп разработки в распределенной команде?
03:29 Про то, как работают виртуальные команды
07:50 Как получается удержать экспертизу в команде?
10:04 Про продуктовые исследования
15:04 Про работу с сообществом и custdev
19:23 Про фичеборд и голосование
23:35 Продукт для разработчиков
24:24 Про вклад стажёров в развитие продукта
28:18 "Яндекс это же сайт, что я там буду делать?" путь Андрея в Яндексе
30:45 Топ-качества разработчиков команды Serverless
35:02 Про плов и то, что объединяет
Разговор с тимлидом команды Serverless Yandex Cloud про продуктовые исследования, фичеборды, виртуальные команды и топ-качества разработчиков.
Смотрите выпуск на YouTube канале Yandex Cloud ➡️
00:00 Приветствие
01:19 Как держать темп разработки в распределенной команде?
03:29 Про то, как работают виртуальные команды
07:50 Как получается удержать экспертизу в команде?
10:04 Про продуктовые исследования
15:04 Про работу с сообществом и custdev
19:23 Про фичеборд и голосование
23:35 Продукт для разработчиков
24:24 Про вклад стажёров в развитие продукта
28:18 "Яндекс это же сайт, что я там буду делать?" путь Андрея в Яндексе
30:45 Топ-качества разработчиков команды Serverless
35:02 Про плов и то, что объединяет
YouTube
Команда Serverless в Yandex Cloud, топ-качества разработчиков
Сегодня говорим про продуктовые исследования, фичеборды, виртуальные команды и топ-качества разработчиков команды бессерверных вычислений в Yandex Cloud.
Смотрите новый выпуск подкаста "Про людей".
00:00 Приветствие
01:19 Как держать темп разработки в…
Смотрите новый выпуск подкаста "Про людей".
00:00 Приветствие
01:19 Как держать темп разработки в…
Микросервис для работы с балансом пользователей
Проблема:
В нашей компании есть много различных микросервисов. Многие из них так или иначе хотят взаимодействовать с балансом пользователя. На архитектурном комитете приняли решение централизовать работу с балансом пользователя в отдельный сервис.
Задача:
Необходимо реализовать микросервис для работы с балансом пользователей (зачисление средств, списание средств, перевод средств от пользователя к пользователю, а также метод получения баланса пользователя). Сервис должен предоставлять HTTP API и принимать/отдавать запросы/ответы в формате JSON.
Сценарии использования:
Далее описаны несколько упрощенных кейсов приближенных к реальности.
1. Сервис биллинга с помощью внешних мерчантов (аля через visa/mastercard) обработал зачисление денег на наш счет. Теперь биллингу нужно добавить эти деньги на баланс пользователя.
2. Пользователь хочет купить у нас какую-то услугу. Для этого у нас есть специальный сервис управления услугами, который перед применением услуги резервирует деньги на отдельном счете и потом списывает в доход компании.
3.Бухгалтерия раз в месяц хочет получить сводный отчет по всем пользователям в разрезе каждой услуги.
Требования к сервису:
1. Сервис должен предоставлять HTTP API с форматом JSON как при отправке запроса, так и при получении результата.
2.Язык разработки: Golang.
3.Фреймворки и библиотеки можно использовать любые.
4.Реляционная СУБД: MySQL или PostgreSQL.
5.Использование docker и docker-compose для поднятия и развертывания dev-среды.
6.Весь код должен быть выложен на Github с Readme файлом с инструкцией по запуску и примерами запросов/ответов (можно просто описать в Readme методы, можно через Postman, можно в Readme curl запросы скопировать, и так далее).
7.Если есть потребность в асинхронных сценариях, то использование любых систем очередей - допускается.
8.При возникновении вопросов по ТЗ оставляем принятие решения за кандидатом (в таком случае Readme файле к проекту должен быть указан список вопросов с которыми кандидат столкнулся и каким образом он их решил).
9.Разработка интерфейса в браузере НЕ ТРЕБУЕТСЯ. Взаимодействие с API предполагается посредством запросов из кода другого сервиса. Для тестирования можно использовать любой удобный инструмент. Например: в терминале через curl или Postman.
Будет плюсом:
Покрытие кода тестами.
Swagger файл для вашего API.
Реализовать сценарий разрезервирования денег, если услугу применить не удалось.
Основное задание (минимум):
Метод начисления средств на баланс. Принимает id пользователя и сколько средств зачислить. Метод резервирования средств с основного баланса на отдельном счете. Принимает id пользователя, ИД услуги, ИД заказа, стоимость. Метод признания выручки – списывает из резерва деньги, добавляет данные в отчет для бухгалтерии. Принимает id пользователя, ИД услуги, ИД заказа, сумму. Метод получения баланса пользователя. Принимает id пользователя.
Детали по заданию:
- По умолчанию сервис не содержит в себе никаких данных о балансах (пустая табличка в БД). Данные о балансе появляются при первом зачислении денег.
- Валидацию данных и обработку ошибок оставляем на усмотрение кандидата.
Список полей к методам не фиксированный. Перечислен лишь необходимый минимум. В рамках выполнения доп. заданий возможны дополнительные поля.
- Механизм миграции не нужен. Достаточно предоставить конечный SQL файл с созданием всех необходимых таблиц в БД.
- Баланс пользователя - очень важные данные в которых недопустимы ошибки (фактически мы работаем тут с реальными деньгами). Необходимо всегда держать баланс в актуальном состоянии и не допускать ситуаций когда баланс может уйти в минус.
- Мультивалютность реализовывать не требуется.
Дополнительные задания
Далее перечислены дополнительные задания. Они не являются обязательными, но их выполнение даст существенный плюс перед другими кандидатами.
@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM