«Посмотри-и-скажи» — это последовательность чисел, начинающаяся следующим образом:
1, 11, 21, 1211, 111221, 312211, 13112221, 1113213211,… (последовательность A005150 в OEIS).
Каждое последующее число генерируется из предыдущего путём конкатенации цифры, из которой состоит группа одинаковых цифр и количества цифр в этой группе, для каждой группы одинаковых цифр в числе.
Решим задачу с leetcode: https://leetcode.com/problems/count-and-say
Пример1:
Input: n = 1
Output: '1'
Пример2:
Input: n = 4
Output: '1211'
Explanation:
countAndSay(1) = '1'
countAndSay(2) = say '1' = one 1 = '11'
countAndSay(3) = say '11' = two 1's = '21'
countAndSay(4) = say '21' = one 2 + one 1 = '12' + '11' = '1211'
Ограничения:
- 1 <= n <= 30
Решение:
func countAndSay(n int) string {
dp := make([]string, n + 1)
dp[1] = '1'
var current, next string
counter := 1
for i := 2; i <= n; i++ {
current = dp[i - 1]
next = ''
counter = 1
for j := 1; j < len(current); j++ {
if current[j - 1] == current[j] {
counter++
} else {
next += strconv.Itoa(counter) + string(current[j - 1])
counter = 1
}
}
next += strconv.Itoa(counter) + current[len(current) - 1:]
dp[i] = next
}
return dp[n]
}
👉 Пишите свое решение в комментариях👇
@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
🌀 Заполнение матрицы по спирали
Эта классическая задача часто встречается на собеседованиях и олимпиадах. Рассмотрим несколько способов решения на Python.
На вход программе подаются два натуральных числа n и m. Напишите программу, которая создает матрицу размером n х m, заполнив ее по спирали числами от 1 до n x m. Спираль начинается в левом верхнем углу и закручивается по часовой стрелке.
Пример ввода:
Пример вывода:
👉 Пишите свое решение в комментариях👇
@golang_interview
Эта классическая задача часто встречается на собеседованиях и олимпиадах. Рассмотрим несколько способов решения на Python.
На вход программе подаются два натуральных числа n и m. Напишите программу, которая создает матрицу размером n х m, заполнив ее по спирали числами от 1 до n x m. Спираль начинается в левом верхнем углу и закручивается по часовой стрелке.
Пример ввода:
7 6
Пример вывода:
1 2 3 4 5 6
22 23 24 25 26 7
21 36 37 38 27 8
20 35 42 39 28 9
19 34 41 40 29 10
18 33 32 31 30 11
17 16 15 14 13 12
👉 Пишите свое решение в комментариях👇
@golang_interview
Описание задачи
Разработать микросервис для работы с балансом пользователей (баланс, зачисление/списание/перевод средств).
Сервис должен предоставлять HTTP API и принимать/отдавать запросы/ответы в формате JSON. Дополнительно реализовать методы конвертации баланса и получение списка транзакций. Полное описание в TASK.
Реализация
▪Следование дизайну REST API.
▪Подход "Чистой Архитектуры" и техника внедрения зависимости.
▪Работа с фреймворком gin-gonic/gin.
▪Работа с СУБД Postgres с использованием библиотеки sqlx и написанием SQL запросов.
▪Конфигурация приложения - библиотека viper.
▪Запуск из Docker.
▪Unit/Интеграционное - тестирование уровней обработчикоов, бизнес-логики и взаимодействия с БД с помощью моков - библиотеки testify, mock.
📌 Github
@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
Необходимо реализовать сервис на Golang для генерации случайных значений.
Сервис реализует JSON API работающее по HTTP. Каждой генерации присваивать уникальный id, по которому можно получить результат генерации методом retrieve.
Реализовать методы
POST /api/generate/ - генерация случайного значения и его идентификатора
GET /api/retrieve/ - получение зачения по id, которое вернулось в методе generate
Задача может быть решена со следующими усложнениями
возможность задать входные параметры для метода /api/generate/
type - тип возвращаемого случайного значения (строка, число, guid, цифробуквенное, из заданных значений)
длина возвращаемого значения
возможность идемпотентных запросов (несколько запросов с одним requestId вернут то же самое число)
сервис поставляется как Docker образ, опубликованный в публичном репозитории
написать Unit тесты
Способы запуска сервиса
Тестовый запуск http-сервера с помощью CLI
go run cmd/avitornd/avitornd.go
Запуск через Docker-образ
docker build -t avitornd:local -f deployments/docker/avitornd-prod.Dockerfile .
docker run -p 8888:8888 avitornd:local
Запуск из публичного репозитория DockerHubdocker run -p 8888:8888 maintianone/avitornd:latest
Документация к RESTful API
Документация написана по стандарту OASv3 и расположена в директории
api/openapi-spec
@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
Тестовое задание для Go-разработчика — Разработка API
Описание задачи
Необходимо написать простейшее API для каталога товаров. Приложение должно содержать:
▪Категории товаров
▪Конкретные товары, которые принадлежат к какой-то категории (один товар может принадлежать нескольким категориям)
▪Пользователей, которые могут авторизоваться
Возможные действия:
▪Получение списка всех категорий
▪Получение списка товаров в конкретной категории
▪Авторизация пользователей
▪Добавление/Редактирование/Удаление категории (для авторизованных пользователей)
▪Добавление/Редактирование/Удаление товара (для авторизованных пользователей)
Технические требования
▪Приложение должно быть написано на Golang
▪Приложение не должно быть написано с помощью какого-либо фреймворка, однако можно устанавливать для него различные пакеты
▪Результаты запросов должны быть представлены в формате JSON
▪Результат задания должен быть выложен на github, должна быть инструкция по запуску проекта. Также необходимо пояснить, сколько на каждую часть проекта ушло времени
Критерии оценки
▪Архитектурная организация API
▪Корректная обработка внештатных ситуаций
▪Покрытие кода тестами
@golang_interview
Описание задачи
Необходимо написать простейшее API для каталога товаров. Приложение должно содержать:
▪Категории товаров
▪Конкретные товары, которые принадлежат к какой-то категории (один товар может принадлежать нескольким категориям)
▪Пользователей, которые могут авторизоваться
Возможные действия:
▪Получение списка всех категорий
▪Получение списка товаров в конкретной категории
▪Авторизация пользователей
▪Добавление/Редактирование/Удаление категории (для авторизованных пользователей)
▪Добавление/Редактирование/Удаление товара (для авторизованных пользователей)
Технические требования
▪Приложение должно быть написано на Golang
▪Приложение не должно быть написано с помощью какого-либо фреймворка, однако можно устанавливать для него различные пакеты
▪Результаты запросов должны быть представлены в формате JSON
▪Результат задания должен быть выложен на github, должна быть инструкция по запуску проекта. Также необходимо пояснить, сколько на каждую часть проекта ушло времени
Критерии оценки
▪Архитектурная организация API
▪Корректная обработка внештатных ситуаций
▪Покрытие кода тестами
@golang_interview
Даны два числа. Определить цифры, входящие в запись как первого, так и второго числа. Программа получает на вход два числа.
Гарантируется, что цифры в числах не повторяются. Числа в пределах от 0 до 10000. Программа должна вывести цифры, которые имеются в обоих числах, через пробел. Цифры выводятся в порядке их нахождения в первом числе.
Пример: Ввод: 564 8954 Вывод: 5 4
package main
import "fmt"
func main(){
var a, b, x , y int
fmt.Scan(&a, &b)
j:=10000
for a > 0{
x = a / j
a = a % j
y = b
for y > 0 && x > 0{
if y%10 == x {
fmt.Print(x, " ")
}
y = y/10
}
j = j/10
}
}
Вариант2
package main
import "fmt"
import "strconv"
func main() {
var (
sum string
a, b int
)
for true {
fmt.Println("Enter two nums 0 <= num <= 10000")
fmt.Scan(&a, &b)
if a < 0 || a > 10000 || b < 0 || b > 10000 {
fmt.Println("Enter correct nums")
continue
} else {
break
}
}
for _, n := range strconv.Itoa(a) {
for _, k := range strconv.Itoa(b) {
if n == k {
sum += string(n) + " "
}
}
}
fmt.Println(sum)
}
👉 Пишите свое решение в комментариях👇
@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
YouTube
Mock-собеседование Go разработчика из OZON | Самое полное интервью
Курсы по программированию: https://clck.ru/37iG2b
Потренироваться проходить собеседования: https://clck.ru/3C2CY3
Консультации:
https://getmentor.dev/mentor/vladimir-balun-191
https://solvery.io/ru/mentor/vladimir_balun
Таймкоды:
00:00 - Введение
00:11…
Потренироваться проходить собеседования: https://clck.ru/3C2CY3
Консультации:
https://getmentor.dev/mentor/vladimir-balun-191
https://solvery.io/ru/mentor/vladimir_balun
Таймкоды:
00:00 - Введение
00:11…
Частью этого отбора (кроме HR-параметров в резюме) было прохождение заданий на https://contest.yandex.ru/. Мы рассмотрим задачи, которые предлагалось решить.
▪Смотреть
▪Github
@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
📌 Задача leetcode. Sum of Subarray Minimums
Сложность: Средняя
Задача: Дан массив целых чисел, необходимо посчитать сумму минимумов подмассивов, ответ может быть большим, необходимо посчитать результат по модулю
Пример:
Ввод:
Вывод:
Примечание:
Подмассивы:
Решение:
Пишите свое решение в комментариях👇
Сложность: Средняя
Задача: Дан массив целых чисел, необходимо посчитать сумму минимумов подмассивов, ответ может быть большим, необходимо посчитать результат по модулю
10^9 + 7.
Пример:
Ввод:
arr = [3,1,2,4]
Вывод:
17
Примечание:
Подмассивы:
[3], [1], [2], [4], [3,1], [1,2], [2,4], [3,1,2], [1,2,4],
[3,1,2,4], минимумы этих подмассивов: 3, 1, 2, 4, 1, 1, 2, 1, 1, 1,
которые в сумме дают 17.Решение:
func sumSubarrayMins(arr []int) int {
out := 0
var st stack
st.push(-1) // setting left bound
for i := range arr {
for len(st) > 1 && arr[i] <= arr[st.peak()] {
idx := st.pop()
out += (i - idx) * (idx - st.peak()) * arr[idx]
}
st = append(st, i)
}
for len(st) > 1 {
idx := st.pop()
out += (len(arr) - idx) * (idx - st.peak()) * arr[idx]
}
return out % 1000000007
}
type stack []int
func (s *stack) push(v int) {
*s = append(*s, v)
}
func (s *stack) pop() int {
v := (*s)[len(*s)-1]
*s = (*s)[:len(*s)-1]
return v
}
func (s *stack) empty() bool {
return len(*s) == 0
}
func (s *stack) peak() int {
v := (*s)[len(*s)-1]
return v
}
Пишите свое решение в комментариях👇
@golang_interviewВсем привет! ✨
Команда SberMarket Tech ищет Golang разработчика, которому предстоит развивать новое направление - привлечение большего количества клиентов на витрины СберМаркета за счет органического трафика из поисковиков. Для этого будем разрабатывать и продвигать инструменты SEO, простраивать входную точку нашего каталога, чтобы клиенту было проще найти необходимое!
Чем будем заниматься:
- разрабатывать инструменты для настройки SEO на базе существующих сервисов (Go), а также монолита (Ruby);
- проектировать и реализовывать микросервисы;
- улучшать производительность работы микросервисов и находить оптимальные решения;
- разбирать баги, инциденты и устранять их последствия;
- прорабатывать масштабируемую архитектуру базы данных и микросервисов.
Мы рассчитываем, что ты:
- имеешь опыт коммерческой разработки на Go от 2 лет;
- проектировал высоконагруженные системы;
- работал с PostgreSQL/MySQL, Redis, Kafka;
- знаком с Unix, Git, понимаешь принципы CI/CD;
- работал с Docker-контейнерами, Istio и Kubernetes;
- хочешь участвовать в жизни продукта и командной работе;
- будет плюсом, если есть опыт в Ruby/Rails.
Что предлагаем:
- ДМС с первого месяца работы в компании;
- соцпакет на выбор — спорт, промокоды на заказ продуктов или билеты в отпуск;
- работаем удаленно. В Москве есть большой и красивый офис, поэтому если ты из этого города или будешь проездом — welcome;
- предоставляем технику для работы на твой выбор;
- помогаем интеллектуально и физически развиваться (электронная библиотека, книжный клуб, футбол);
- уделяем большое внимание обучению сотрудников, поэтому в нашей knowledge base ты найдёшь много интересных курсов, книг и записей конференций, а также у нас есть выделенный бюджет на образование.
А ещё:
- мы сами участвуем в конференциях, как спикеры;
- проводим внутренние митапы;
- не боимся экспериментировать с новыми решениями и технологиями;
- заботимся о сотрудниках: в компании есть специалист по здоровью и психологи для разговоров по душам 🙂
За всеми подробностями приходите в личку! Telegram HR: @Chernenko_Maria
Команда SberMarket Tech ищет Golang разработчика, которому предстоит развивать новое направление - привлечение большего количества клиентов на витрины СберМаркета за счет органического трафика из поисковиков. Для этого будем разрабатывать и продвигать инструменты SEO, простраивать входную точку нашего каталога, чтобы клиенту было проще найти необходимое!
Чем будем заниматься:
- разрабатывать инструменты для настройки SEO на базе существующих сервисов (Go), а также монолита (Ruby);
- проектировать и реализовывать микросервисы;
- улучшать производительность работы микросервисов и находить оптимальные решения;
- разбирать баги, инциденты и устранять их последствия;
- прорабатывать масштабируемую архитектуру базы данных и микросервисов.
Мы рассчитываем, что ты:
- имеешь опыт коммерческой разработки на Go от 2 лет;
- проектировал высоконагруженные системы;
- работал с PostgreSQL/MySQL, Redis, Kafka;
- знаком с Unix, Git, понимаешь принципы CI/CD;
- работал с Docker-контейнерами, Istio и Kubernetes;
- хочешь участвовать в жизни продукта и командной работе;
- будет плюсом, если есть опыт в Ruby/Rails.
Что предлагаем:
- ДМС с первого месяца работы в компании;
- соцпакет на выбор — спорт, промокоды на заказ продуктов или билеты в отпуск;
- работаем удаленно. В Москве есть большой и красивый офис, поэтому если ты из этого города или будешь проездом — welcome;
- предоставляем технику для работы на твой выбор;
- помогаем интеллектуально и физически развиваться (электронная библиотека, книжный клуб, футбол);
- уделяем большое внимание обучению сотрудников, поэтому в нашей knowledge base ты найдёшь много интересных курсов, книг и записей конференций, а также у нас есть выделенный бюджет на образование.
А ещё:
- мы сами участвуем в конференциях, как спикеры;
- проводим внутренние митапы;
- не боимся экспериментировать с новыми решениями и технологиями;
- заботимся о сотрудниках: в компании есть специалист по здоровью и психологи для разговоров по душам 🙂
За всеми подробностями приходите в личку! Telegram HR: @Chernenko_Maria
Реализовать микросервис для работы с балансом пользователей (зачисление средств, списание средств, перевод средств от пользователя к пользователю, а также метод получения баланса пользователя).
Сервис должен предоставлять
HTTP API
и принимать/отдавать запросы/ответы в формате JSON
.Инструкция по запуску
▪Клонировать репозиторий локально в любую деректорию своего устройства
git clone https://github.com/Owner-maker/microservice-for-working-with-user-balance.git
▪Перейти в директорию проекта вручную или с помощью консоли
cd microservice-for-working-with-user-balance
▪Создать и запустить Docker - контейнер docker-compose build && docker-compose up
▪После запуска контейнера все сущности автоматически будут созданы в базе данных
▪Также будут автоматически добавлены 2 тестовых пользователя с отсутствующими балансами
Их id = 1 и id = 2 соответственно
▪После запуска контейнера будет также доступна html - страница Swagger для удобства тестирования API
http://localhost:8080/swagger/index.html#/
@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
📌 Задача с Leetcode. Поиск в двумерной матрице
Сложность: Средняя
Условие задачи: напишите эффективный алгоритм для поиска наличия нужного числа в двумерной матрице, которая имеет следующие свойства:
▪ в строке элементы отсортированы по возрастанию (слева - направо);
▪ в столбце элементы отсортированы по возрастанию (снизу - вверх).
Пример:
Ввод:
Вывод:
Решение:
Временная сложность:
Пространственная сложность:
Пишите свое решение в комментариях👇
@golang_interview
Сложность: Средняя
Условие задачи: напишите эффективный алгоритм для поиска наличия нужного числа в двумерной матрице, которая имеет следующие свойства:
▪ в строке элементы отсортированы по возрастанию (слева - направо);
▪ в столбце элементы отсортированы по возрастанию (снизу - вверх).
Пример:
Ввод:
matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], target = 5
Вывод:
true
Решение:
func searchMatrix(matrix [][]int, target int) bool {
m, n := len(matrix), len(matrix[0])
i, j := 0, n-1
for i < m && j >= 0 {
if matrix[i][j] == target {
return true
}
if matrix[i][j] < target {
i++
} else {
j--
}
}
return false
}
Временная сложность:
O(m + n)
Пространственная сложность:
O(1)
Пишите свое решение в комментариях👇
@golang_interview
📌 Тестовое Задание (Golang + PostgreSQL)
Написать сервис, который будет слушать входящие запросы по HTTP, преобразовывать их в запрос к соответствующей функции Postgres, выполнять запрос и возвращать ответ клиенту.
Скиллы: Golang, Postgres, regexp, строки, работа с json в Golang и Postgres.
Web-сервис
Написать сервис, который будет слушать входящие запросы по HTTP, преобразовывать их в запрос к соответствующей функции Postgres (по схеме трансляции, приведённой ниже), выполнять запрос и возвращать ответ клиенту.
Как плюс: ограничить максимальное количество одновременных коннектов к БД.
Как два плюса: добавить prometheus метрики на вызовы (количество вызовов, длительность выполнения).
Настройки соединения с сервером Postgres читать из config файла:
port - (int) порт, на котором слушать запросы
endpoint - (string) название API
host - (string) hostname, где установлен Postgres
user - (string) имя пользователя Postgres
password - (string) пароль пользователя Postgres
schema - (string) схема в Postgres
Трансляция запроса в вызов Postgres функции
Формат запроса к сервису:
HTTP_METHOD server:port/endpoint/vversion[/object/id ...]]/destination/[id] , где
HTTP_METHOD - одно из: GET, POST, PUT, DELETE
server - сервер, где запущен веб-сервис
port - порт
endpoint - значение из config-файла
version - номер версии API, число
/object/id - необязательный повторяющийся параметр, определяющий путь в иерархии объектов
/destination/ - конечный объект
id - id конечного объекта. Обязателен для методов PUT, DELETE, не указывается для POST. Для GET -- если указан, то возвращает элемент с данным id, если не указан, возвращает полный список элементов.
Правила трансляции
запрос в Postgres = select * from схема.[object1[_object2]...]_destination_method( [id1[, id2]... ,] id[, params])
В зависимости от HTTP метода к имени функции добавляется cуффикс method:
для GET - get
для POST - ins
для PUT - upd
для DELETE - del
В случае, если идентификатор объекта не указан, соответствующий элемент id в запросе должен быть равен нулю, на примерах:
для запроса GET http://localhost:80/api/v1/user/12/comment/34
запрос в Postgres должен выглядеть так: select * from test.user_comment_get(12, 34) (комментарий c id=32 пользователя c id=12)
для запроса GET http://localhost:80/api/v1/user/12/comment/
запрос в Postgres должен выглядеть так: select * from test.user_comment_get(12, 0) (все комментарии пользователя 12)
для запроса GET http://localhost:80/api/v1/user/comment/
запрос в Postgres должен выглядеть так: select * from test.user_comment_get(0, 0) (все комментарии всех пользователей)
Для POST и PUT методов в теле запроса принимается JSON, который передаётся в Postgres в качестве параметра params.
Все методы должны возвращать результат работы соответствующей Postgres функции с ContentType = 'application/json'
🖥 Github
@golang_interview
Написать сервис, который будет слушать входящие запросы по HTTP, преобразовывать их в запрос к соответствующей функции Postgres, выполнять запрос и возвращать ответ клиенту.
Скиллы: Golang, Postgres, regexp, строки, работа с json в Golang и Postgres.
Web-сервис
Написать сервис, который будет слушать входящие запросы по HTTP, преобразовывать их в запрос к соответствующей функции Postgres (по схеме трансляции, приведённой ниже), выполнять запрос и возвращать ответ клиенту.
Как плюс: ограничить максимальное количество одновременных коннектов к БД.
Как два плюса: добавить prometheus метрики на вызовы (количество вызовов, длительность выполнения).
Настройки соединения с сервером Postgres читать из config файла:
port - (int) порт, на котором слушать запросы
endpoint - (string) название API
host - (string) hostname, где установлен Postgres
user - (string) имя пользователя Postgres
password - (string) пароль пользователя Postgres
schema - (string) схема в Postgres
Трансляция запроса в вызов Postgres функции
Формат запроса к сервису:
HTTP_METHOD server:port/endpoint/vversion[/object/id ...]]/destination/[id] , где
HTTP_METHOD - одно из: GET, POST, PUT, DELETE
server - сервер, где запущен веб-сервис
port - порт
endpoint - значение из config-файла
version - номер версии API, число
/object/id - необязательный повторяющийся параметр, определяющий путь в иерархии объектов
/destination/ - конечный объект
id - id конечного объекта. Обязателен для методов PUT, DELETE, не указывается для POST. Для GET -- если указан, то возвращает элемент с данным id, если не указан, возвращает полный список элементов.
Правила трансляции
запрос в Postgres = select * from схема.[object1[_object2]...]_destination_method( [id1[, id2]... ,] id[, params])
В зависимости от HTTP метода к имени функции добавляется cуффикс method:
для GET - get
для POST - ins
для PUT - upd
для DELETE - del
В случае, если идентификатор объекта не указан, соответствующий элемент id в запросе должен быть равен нулю, на примерах:
для запроса GET http://localhost:80/api/v1/user/12/comment/34
запрос в Postgres должен выглядеть так: select * from test.user_comment_get(12, 34) (комментарий c id=32 пользователя c id=12)
для запроса GET http://localhost:80/api/v1/user/12/comment/
запрос в Postgres должен выглядеть так: select * from test.user_comment_get(12, 0) (все комментарии пользователя 12)
для запроса GET http://localhost:80/api/v1/user/comment/
запрос в Postgres должен выглядеть так: select * from test.user_comment_get(0, 0) (все комментарии всех пользователей)
Для POST и PUT методов в теле запроса принимается JSON, который передаётся в Postgres в качестве параметра params.
Все методы должны возвращать результат работы соответствующей Postgres функции с ContentType = 'application/json'
@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
Описание задачи
Необходимо создать сервис для хранения и подачи объявлений. Объявления должны храниться в базе данных. Сервис должен предоставлять API, работающее поверх HTTP в формате JSON.
Метод получения списка объявлений
Пагинация: на одной странице должно присутствовать 10 объявлений;
Cортировки: по цене (возрастание/убывание) и по дате создания (возрастание/убывание);
Поля в ответе: название объявления, ссылка на главное фото (первое в списке), цена.
Метод получения конкретного объявления
Обязательные поля в ответе: название объявления, цена, ссылка на главное фото;
Опциональные поля (можно запросить, передав параметр fields): описание, ссылки на все фото.
Метод создания объявления:
Принимает все вышеперечисленные поля: название, описание, несколько ссылок на фотографии (сами фото загружать никуда не требуется), цена;
Возвращает ID созданного объявления и код результата (ошибка или успех).
Реализация
Следование дизайну REST API.
Подход "Чистой Архитектуры" и техника внедрения зависимости.
Работа с фреймворком echo.
Работа с БД Postgres с использованием библиотеки sqlx и написанием SQL запросов.
Конфигурация приложения - библиотека viper.
Реализация Graceful Shutdown.
Запуск из Docker.
Юнит-тестирование уровней обработчиков, бизнес-логики и взаимодействия с БД классическим способом и с помощью моков - библиотеки testify, mock.
Сквозное (E2E) тестирование - BDD фреймворк goconvey.
Проверка кода на соответствие стандартам с помощью линтера - утилита golangci-lint
Автоматическое создание документации с помощью Swagger 2.0 - библиотека echo-swagger.
Непрерывная интеграция - сборка приложения, проверка линтером и запуск тестов в Github action.
Структура проекта:
.
├── pkg
│ ├── error_message // сообщения об ошибках
│ ├── model // основные структуры
│ ├── handler // обработчики запросов
│ ├── service // бизнес-логика
│ └── repository // взаимодействие с БД
├── cmd // точка входа в приложение
├── migrations // SQL файлы с миграциями
├── scripts // SQL файлы с тестовыми данными
├── configs // файлы конфигурации
├── test // инициализация тестовой БД
└── e2e_test.go // сквозной тест
Архитектура
Приложение имеет 3 основных слоя, реализованных в отдельных пакетах.
Repository - слой взаимодействия с БД. Методы этого слоя принимают данные от Service и выполняют запросы к БД.
Service - слой бизнес-логики. Методы этого слоя принимают данные от Handler и применяют к ним бизнес-правила для достижения цели варианта использования.
Handler - слой обработчиков запросов. Содержит методы-обработчики для endpoints.
Пакет Model содержит структуры сущностей, используемых остальными слоями.
Endpoints
GET /api/adverts - получение списка объявлений
Параметры запроса:
page - номер страницы,
sort - параметры сортировки в формате [поле сортировки]_[порядок сортировки] (например price_desc).
GET /api/adverts/:id - получение объявления по id
Параметры запроса: - fields - флаг, если равен True, то вернуть все поля, иначе вернуть название, ссылку на главное фото и цену.
POST /api/adverts - создание объявления
Тело запроса:
title - название объявления,
description - описание объявления,
photos - ссылки на фотографии,
price - цена.
▪Задание
@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача. Слияние двух бинарных деревьев
Сложность: Лёгкая
Условие задачи: Даны два бинарных дерева, необходимо осуществить их наложение друг на друга и вывод результатов в новом дереве.
Примечание: Наложение представляет из себя суммирование соответствующих значений из узлов двух деревьев.
Пример:
Ввод: root1 = [1,3,2,5], root2 = [2,1,3,null,4,null,7]
Вывод:[3,4,5,5,4,null,7]
Ввод: root1 = [1], root2 = [1,2]
Вывод: [2,2]
Решение
Пишите свое мнение в комментариях👇
@golang_interview
Сложность: Лёгкая
Условие задачи: Даны два бинарных дерева, необходимо осуществить их наложение друг на друга и вывод результатов в новом дереве.
Примечание: Наложение представляет из себя суммирование соответствующих значений из узлов двух деревьев.
Пример:
Ввод: root1 = [1,3,2,5], root2 = [2,1,3,null,4,null,7]
Вывод:[3,4,5,5,4,null,7]
Ввод: root1 = [1], root2 = [1,2]
Вывод: [2,2]
Решение
Пишите свое мнение в комментариях👇
func mergeTrees(root1 *TreeNode, root2 *TreeNode) *TreeNode {
if root1 == nil {
return root2
}
if root2 == nil {
return root1
}
root1.Val += root2.Val
root1.Left = mergeTrees(root1.Left, root2.Left)
root1.Right = mergeTrees(root1.Right, root2.Right)
return root1
}
@golang_interview
В этой статье я поделился лучшими бесплатными онлайн-курсами по изучению Golang на таких сайтах, как freeCodecamp, YouTube, Udemy и Coursera .
▪ Читать
@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
Для создания файла с определенным MIME-типом в Go, необходимо создать файл и записать в него данные в нужном формате.
Пример создания файла с MIME-типом text/plain:
package main
import (
"io/ioutil"
"log"
)
func main() {
message := "Hello, world!"
err := ioutil.WriteFile("example.txt", []byte(message), 0644)
if err != nil {
log.Fatal(err)
}
}
В данном примере мы создаем файл example.txt и записываем в него сообщение Hello, world!. Так как тип данных в файле - текстовый, то его MIME-тип будет text/plain.
Пример создания файла с MIME-типом application/pdf:
package main
import (
"io/ioutil"
"log"
)
func main() {
// создаем бинарные данные для PDF-файла
pdfData := []byte{0x25, 0x50, 0x44, 0x46, 0x2d, 0x31, 0x2e, 0x34, ...}
err := ioutil.WriteFile("example.pdf", pdfData, 0644)
if err != nil {
log.Fatal(err)
}
}
В данном примере мы создаем файл example.pdf и записываем в него бинарные данные для PDF-файла. MIME-тип данного файла будет application/pdf.
Обратите внимание, что в данном примере мы создаем PDF-данные в виде слайса байтов вручную для примера. В реальном приложении вам может понадобиться использовать библиотеку для генерации PDF-файлов.
#Junior
@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
Разработкой начал заниматься ещё со старшей школы, изучал C/C++ (очень пригодилось при написании скриптов в injection для ультимы онлайн). Профессионально начал работать разработчиком приблизительно с 2014, основной язык до 2020 года был C# с примесью C++. Сначала разрабатывал и поддерживал некоторые проекты в банковской сфере, потом резко поменял предметную область и ушёл писать софт для автоматизации работы одного строительного девелопера. На начальных этапах это было огромное легаси на C# от бывшего архитектора, решившего стать программистом, с кучей багов и неочевидных решений, пришлось много переписывать.
Со временем появились задачи, которые не были привязаны к языку и технологиям в принципе (изначально писал, по сути, плагины к CAD-приложениям), и я попробовал Golang, а вместе с ним и микросервисы, NoSQL, gRPC и прочие модные штуки. Побывал в шкуре админа-девопса, так как новые сервисы я запускал и поддерживал сам.
Некоторое время назад наткнулся на пост про собеседования и решил рассказать Хабру про свой опыт. Возможно, кому-то он окажется полезным.
▪Читать дальше
@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
Тестовое задание:
1. Реализовать REST API со следующим функционалом
1.1. Получение курса валют на стороннем API (RUB / EUR / USD / JPY). (например: https://currencyfreaks.com/)
1.1.1. Если за текущий день не было курса, получить в 12:00 обновить курс валют
1.1.2 Реализовать сохранение курса валюты в БД (PostgreSQL, MySQL, Mongo на выбор)
1.2. Реализовать эндпоинты:
1.2.1. Получение курсов по указанной дате (все 4 валюты)
1.2.2. Получение валютных пар из указанных 4х. Т.е. хочу получить курс Рубля к Йене или Доллар к Евро и т.д.
1.3. Реализовать валидацию запросов (даты, тикеров валют)
1.4. Реализовать доступ к API через API key
1.5 Реализовать логирование в БД запросов к API. Сохраняем в логи - дату, вид запроса (по дате / по паре)
1.6. Использовать для проекта docker.
1.7. При инициализации сервера заполнить БД первоначальными данными курсов валют по нескольким датам (значения любые)
#практика
@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
Недавно я наткнулся на тест LinkedIn Golang, интересную возможность для разработчиков получить значок на сайте, демонстрирующий их знание языка (этот значок не только демонстрирует ваши навыки, но и помогает вам выделиться из толпы на конкурентном рынке труда).
Я нашёл вопросы в тесте довольно интересными,
▪Читать
@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
Вывод всех перестановок символов слайса или строки
Реализуйте функцию perm(), которая принимает слайс или строку и печатает все возможные комбинации символов.
Решение:
Пишите свое решение в комментариях👇
#junior #golang
@golang_interview
Реализуйте функцию perm(), которая принимает слайс или строку и печатает все возможные комбинации символов.
Решение:
package main
import "fmt"
// Perm calls f with each permutation of a.
func Perm(a []rune, f func([]rune)) {
perm(a, f, 0)
}
// Permute the values at index i to len(a)-1.
func perm(a []rune, f func([]rune), i int) {
if i > len(a) {
f(a)
return
}
perm(a, f, i+1)
for j := i + 1; j < len(a); j++ {
a[i], a[j] = a[j], a[i]
perm(a, f, i+1)
a[i], a[j] = a[j], a[i]
}
}
func main() {
Perm([]rune("abc"), func(a []rune) {
fmt.Println(string(a))
})
}
Пишите свое решение в комментариях👇
#junior #golang
@golang_interview