Initial commit

This commit is contained in:
NortPerm 2023-10-30 15:21:12 +03:00 committed by GitHub
commit 13e2575b4e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
149 changed files with 3961 additions and 0 deletions

0
.github/.sync vendored Normal file
View File

1
.github/CODEOWNERS vendored Normal file
View File

@ -0,0 +1 @@
* @OtusGolang/teachers-and-mentors

View File

@ -0,0 +1,16 @@
## Домашнее задание №1 «Hello, OTUS!»
### Чек-лист студента ([Что это?](https://github.com/OtusGolang/home_work/wiki/%D0%9A%D0%BE%D0%BC%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80%D0%B8%D0%B8-%D0%BA-%D1%87%D0%B5%D0%BA-%D0%BB%D0%B8%D1%81%D1%82%D1%83-%D1%81%D1%82%D1%83%D0%B4%D0%B5%D0%BD%D1%82%D0%B0))
- [ ] Я перечитал задание после решения. [Зачем перечитывать задание?](https://github.com/OtusGolang/home_work/wiki/%D0%9A%D0%BE%D0%BC%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80%D0%B8%D0%B8-%D0%BA-%D1%87%D0%B5%D0%BA-%D0%BB%D0%B8%D1%81%D1%82%D1%83-%D1%81%D1%82%D1%83%D0%B4%D0%B5%D0%BD%D1%82%D0%B0#user-content-%D0%97%D0%B0%D1%87%D0%B5%D0%BC-%D0%BF%D0%B5%D1%80%D0%B5%D1%87%D0%B8%D1%82%D1%8B%D0%B2%D0%B0%D1%82%D1%8C-%D0%B7%D0%B0%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5)
- [ ] Я запустил `go mod tidy`.
- [ ] Я удалил `.sync` файл. [Зачем его удалять?](https://github.com/OtusGolang/home_work/wiki/%5B%D0%A1%D1%82%D1%83%D0%B4%D0%B5%D0%BD%D1%82%D0%B0%D0%BC%5D-%D0%9F%D1%80%D0%BE%D1%86%D0%B5%D1%81%D1%81-%D1%81%D0%B4%D0%B0%D1%87%D0%B8-%D0%94%D0%97#user-content-%D0%92%D0%B0%D1%80%D0%B8%D0%B0%D0%BD%D1%82-2)
- [ ] Я использовал `stringutil.Reverse`.
- [ ] Я сравнил объем кода с объемом авторского решения. [Зачем сверять объем кода?](https://github.com/OtusGolang/home_work/wiki/%D0%9A%D0%BE%D0%BC%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80%D0%B8%D0%B8-%D0%BA-%D1%87%D0%B5%D0%BA-%D0%BB%D0%B8%D1%81%D1%82%D1%83-%D1%81%D1%82%D1%83%D0%B4%D0%B5%D0%BD%D1%82%D0%B0#user-content-%D0%97%D0%B0%D1%87%D0%B5%D0%BC-%D1%81%D0%B2%D0%B5%D1%80%D1%8F%D1%82%D1%8C-%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC-%D0%BA%D0%BE%D0%B4%D0%B0)
- main.go ~12 строк
### Критерии оценки
- [ ] Пайплайн зелёный - 4 балла
- [ ] Используется `stringutil` - 4 балла
- [ ] Понятность и чистота кода - до 2 баллов
#### Зачёт от 7 баллов

View File

@ -0,0 +1,16 @@
## Домашнее задание №2 «Распаковка строки»
### Чек-лист студента ([Что это?](https://github.com/OtusGolang/home_work/wiki/%D0%9A%D0%BE%D0%BC%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80%D0%B8%D0%B8-%D0%BA-%D1%87%D0%B5%D0%BA-%D0%BB%D0%B8%D1%81%D1%82%D1%83-%D1%81%D1%82%D1%83%D0%B4%D0%B5%D0%BD%D1%82%D0%B0))
- [ ] Я перечитал задание после решения. [Зачем перечитывать задание?](https://github.com/OtusGolang/home_work/wiki/%D0%9A%D0%BE%D0%BC%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80%D0%B8%D0%B8-%D0%BA-%D1%87%D0%B5%D0%BA-%D0%BB%D0%B8%D1%81%D1%82%D1%83-%D1%81%D1%82%D1%83%D0%B4%D0%B5%D0%BD%D1%82%D0%B0#user-content-%D0%97%D0%B0%D1%87%D0%B5%D0%BC-%D0%BF%D0%B5%D1%80%D0%B5%D1%87%D0%B8%D1%82%D1%8B%D0%B2%D0%B0%D1%82%D1%8C-%D0%B7%D0%B0%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5)
- [ ] Я запустил `go mod tidy`.
- [ ] Я удалил `.sync` файл. [Зачем его удалять?](https://github.com/OtusGolang/home_work/wiki/%5B%D0%A1%D1%82%D1%83%D0%B4%D0%B5%D0%BD%D1%82%D0%B0%D0%BC%5D-%D0%9F%D1%80%D0%BE%D1%86%D0%B5%D1%81%D1%81-%D1%81%D0%B4%D0%B0%D1%87%D0%B8-%D0%94%D0%97#user-content-%D0%92%D0%B0%D1%80%D0%B8%D0%B0%D0%BD%D1%82-2)
- [ ] Я сравнил объем кода с объемом авторского решения. [Зачем сверять объем кода?](https://github.com/OtusGolang/home_work/wiki/%D0%9A%D0%BE%D0%BC%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80%D0%B8%D0%B8-%D0%BA-%D1%87%D0%B5%D0%BA-%D0%BB%D0%B8%D1%81%D1%82%D1%83-%D1%81%D1%82%D1%83%D0%B4%D0%B5%D0%BD%D1%82%D0%B0#user-content-%D0%97%D0%B0%D1%87%D0%B5%D0%BC-%D1%81%D0%B2%D0%B5%D1%80%D1%8F%D1%82%D1%8C-%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC-%D0%BA%D0%BE%D0%B4%D0%B0)
- unpack.go ~45 строк для задания без звездочки
- unpack.go ~75 строк для задания со звездочкой
### Критерии оценки
- [ ] Пайплайн зелёный - 4 балла
- [ ] Добавлены новые юнит-тесты - до 4 баллов
- [ ] Понятность и чистота кода - до 2 баллов
#### Зачёт от 7 баллов

View File

@ -0,0 +1,13 @@
## Домашнее задание №3 «Частотный анализ»
### Чек-лист студента ([Что это?](https://github.com/OtusGolang/home_work/wiki/%D0%9A%D0%BE%D0%BC%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80%D0%B8%D0%B8-%D0%BA-%D1%87%D0%B5%D0%BA-%D0%BB%D0%B8%D1%81%D1%82%D1%83-%D1%81%D1%82%D1%83%D0%B4%D0%B5%D0%BD%D1%82%D0%B0))
- [ ] Я перечитал задание после решения. [Зачем перечитывать задание?](https://github.com/OtusGolang/home_work/wiki/%D0%9A%D0%BE%D0%BC%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80%D0%B8%D0%B8-%D0%BA-%D1%87%D0%B5%D0%BA-%D0%BB%D0%B8%D1%81%D1%82%D1%83-%D1%81%D1%82%D1%83%D0%B4%D0%B5%D0%BD%D1%82%D0%B0#user-content-%D0%97%D0%B0%D1%87%D0%B5%D0%BC-%D0%BF%D0%B5%D1%80%D0%B5%D1%87%D0%B8%D1%82%D1%8B%D0%B2%D0%B0%D1%82%D1%8C-%D0%B7%D0%B0%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5)
- [ ] Я запустил `go mod tidy`.
- [ ] Я удалил `.sync` файл. [Зачем его удалять?](https://github.com/OtusGolang/home_work/wiki/%5B%D0%A1%D1%82%D1%83%D0%B4%D0%B5%D0%BD%D1%82%D0%B0%D0%BC%5D-%D0%9F%D1%80%D0%BE%D1%86%D0%B5%D1%81%D1%81-%D1%81%D0%B4%D0%B0%D1%87%D0%B8-%D0%94%D0%97#user-content-%D0%92%D0%B0%D1%80%D0%B8%D0%B0%D0%BD%D1%82-2)
### Критерии оценки
- [ ] Пайплайн зелёный - 4 балла
- [ ] Добавлены новые юнит-тесты - до 4 баллов
- [ ] Понятность и чистота кода - до 2 баллов
#### Зачёт от 7 баллов

View File

@ -0,0 +1,16 @@
## Домашнее задание №4 «LRU-кэш»
### Чек-лист студента ([Что это?](https://github.com/OtusGolang/home_work/wiki/%D0%9A%D0%BE%D0%BC%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80%D0%B8%D0%B8-%D0%BA-%D1%87%D0%B5%D0%BA-%D0%BB%D0%B8%D1%81%D1%82%D1%83-%D1%81%D1%82%D1%83%D0%B4%D0%B5%D0%BD%D1%82%D0%B0))
- [ ] Я перечитал задание после решения. [Зачем перечитывать задание?](https://github.com/OtusGolang/home_work/wiki/%D0%9A%D0%BE%D0%BC%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80%D0%B8%D0%B8-%D0%BA-%D1%87%D0%B5%D0%BA-%D0%BB%D0%B8%D1%81%D1%82%D1%83-%D1%81%D1%82%D1%83%D0%B4%D0%B5%D0%BD%D1%82%D0%B0#user-content-%D0%97%D0%B0%D1%87%D0%B5%D0%BC-%D0%BF%D0%B5%D1%80%D0%B5%D1%87%D0%B8%D1%82%D1%8B%D0%B2%D0%B0%D1%82%D1%8C-%D0%B7%D0%B0%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5)
- [ ] Я запустил `go mod tidy`.
- [ ] Я удалил `.sync` файл. [Зачем его удалять?](https://github.com/OtusGolang/home_work/wiki/%5B%D0%A1%D1%82%D1%83%D0%B4%D0%B5%D0%BD%D1%82%D0%B0%D0%BC%5D-%D0%9F%D1%80%D0%BE%D1%86%D0%B5%D1%81%D1%81-%D1%81%D0%B4%D0%B0%D1%87%D0%B8-%D0%94%D0%97#user-content-%D0%92%D0%B0%D1%80%D0%B8%D0%B0%D0%BD%D1%82-2)
- [ ] Я проверил, что все операции выполняются за О(1).
### Критерии оценки
- [ ] Пайплайн зелёный - 4 балла
- [ ] Добавлены новые юнит-тесты для списка - 1 балл
- [ ] Добавлены новые юнит-тесты для кэша (включая тест на логику
выталкивания из кэша редко используемых элементов) - до 3 баллов
- [ ] Понятность и чистота кода - до 2 баллов
#### Зачёт от 7 баллов

View File

@ -0,0 +1,15 @@
## Домашнее задание №5 «Параллельное исполнение»
### Чек-лист студента ([Что это?](https://github.com/OtusGolang/home_work/wiki/%D0%9A%D0%BE%D0%BC%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80%D0%B8%D0%B8-%D0%BA-%D1%87%D0%B5%D0%BA-%D0%BB%D0%B8%D1%81%D1%82%D1%83-%D1%81%D1%82%D1%83%D0%B4%D0%B5%D0%BD%D1%82%D0%B0))
- [ ] Я перечитал задание после решения. [Зачем перечитывать задание?](https://github.com/OtusGolang/home_work/wiki/%D0%9A%D0%BE%D0%BC%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80%D0%B8%D0%B8-%D0%BA-%D1%87%D0%B5%D0%BA-%D0%BB%D0%B8%D1%81%D1%82%D1%83-%D1%81%D1%82%D1%83%D0%B4%D0%B5%D0%BD%D1%82%D0%B0#user-content-%D0%97%D0%B0%D1%87%D0%B5%D0%BC-%D0%BF%D0%B5%D1%80%D0%B5%D1%87%D0%B8%D1%82%D1%8B%D0%B2%D0%B0%D1%82%D1%8C-%D0%B7%D0%B0%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5)
- [ ] Я запустил `go mod tidy`.
- [ ] Я удалил `.sync` файл. [Зачем его удалять?](https://github.com/OtusGolang/home_work/wiki/%5B%D0%A1%D1%82%D1%83%D0%B4%D0%B5%D0%BD%D1%82%D0%B0%D0%BC%5D-%D0%9F%D1%80%D0%BE%D1%86%D0%B5%D1%81%D1%81-%D1%81%D0%B4%D0%B0%D1%87%D0%B8-%D0%94%D0%97#user-content-%D0%92%D0%B0%D1%80%D0%B8%D0%B0%D0%BD%D1%82-2)
- [ ] Я сравнил объем кода с объемом авторского решения. [Зачем сверять объем кода?](https://github.com/OtusGolang/home_work/wiki/%D0%9A%D0%BE%D0%BC%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80%D0%B8%D0%B8-%D0%BA-%D1%87%D0%B5%D0%BA-%D0%BB%D0%B8%D1%81%D1%82%D1%83-%D1%81%D1%82%D1%83%D0%B4%D0%B5%D0%BD%D1%82%D0%B0#user-content-%D0%97%D0%B0%D1%87%D0%B5%D0%BC-%D1%81%D0%B2%D0%B5%D1%80%D1%8F%D1%82%D1%8C-%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC-%D0%BA%D0%BE%D0%B4%D0%B0)
- run.go ~55 строк
### Критерии оценки
- [ ] Пайплайн зелёный - 4 балла
- [ ] Добавлены новые юнит-тесты - до 4 баллов
- [ ] Понятность и чистота кода - до 2 баллов
#### Зачёт от 7 баллов

View File

@ -0,0 +1,15 @@
## Домашнее задание №6 «Пайплайн»
### Чек-лист студента ([Что это?](https://github.com/OtusGolang/home_work/wiki/%D0%9A%D0%BE%D0%BC%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80%D0%B8%D0%B8-%D0%BA-%D1%87%D0%B5%D0%BA-%D0%BB%D0%B8%D1%81%D1%82%D1%83-%D1%81%D1%82%D1%83%D0%B4%D0%B5%D0%BD%D1%82%D0%B0))
- [ ] Я перечитал задание после решения. [Зачем перечитывать задание?](https://github.com/OtusGolang/home_work/wiki/%D0%9A%D0%BE%D0%BC%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80%D0%B8%D0%B8-%D0%BA-%D1%87%D0%B5%D0%BA-%D0%BB%D0%B8%D1%81%D1%82%D1%83-%D1%81%D1%82%D1%83%D0%B4%D0%B5%D0%BD%D1%82%D0%B0#user-content-%D0%97%D0%B0%D1%87%D0%B5%D0%BC-%D0%BF%D0%B5%D1%80%D0%B5%D1%87%D0%B8%D1%82%D1%8B%D0%B2%D0%B0%D1%82%D1%8C-%D0%B7%D0%B0%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5)
- [ ] Я запустил `go mod tidy`.
- [ ] Я удалил `.sync` файл. [Зачем его удалять?](https://github.com/OtusGolang/home_work/wiki/%5B%D0%A1%D1%82%D1%83%D0%B4%D0%B5%D0%BD%D1%82%D0%B0%D0%BC%5D-%D0%9F%D1%80%D0%BE%D1%86%D0%B5%D1%81%D1%81-%D1%81%D0%B4%D0%B0%D1%87%D0%B8-%D0%94%D0%97#user-content-%D0%92%D0%B0%D1%80%D0%B8%D0%B0%D0%BD%D1%82-2)
- [ ] Я сравнил объем кода с объемом авторского решения. [Зачем сверять объем кода?](https://github.com/OtusGolang/home_work/wiki/%D0%9A%D0%BE%D0%BC%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80%D0%B8%D0%B8-%D0%BA-%D1%87%D0%B5%D0%BA-%D0%BB%D0%B8%D1%81%D1%82%D1%83-%D1%81%D1%82%D1%83%D0%B4%D0%B5%D0%BD%D1%82%D0%B0#user-content-%D0%97%D0%B0%D1%87%D0%B5%D0%BC-%D1%81%D0%B2%D0%B5%D1%80%D1%8F%D1%82%D1%8C-%D0%BE%D0%B1%D1%8A%D0%B5%D0%BC-%D0%BA%D0%BE%D0%B4%D0%B0)
- pipeline.go ~55 строк
### Критерии оценки
- [ ] CI-пайплайн зелёный - 5 баллов
- [ ] Добавлены новые юнит-тесты - до 2 баллов
- [ ] Понятность и чистота кода - до 3 баллов
#### Зачёт от 7 баллов

View File

@ -0,0 +1,14 @@
## Домашнее задание №7 «Утилита для копирования файлов»
### Чек-лист студента ([Что это?](https://github.com/OtusGolang/home_work/wiki/%D0%9A%D0%BE%D0%BC%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80%D0%B8%D0%B8-%D0%BA-%D1%87%D0%B5%D0%BA-%D0%BB%D0%B8%D1%81%D1%82%D1%83-%D1%81%D1%82%D1%83%D0%B4%D0%B5%D0%BD%D1%82%D0%B0))
- [ ] Я перечитал задание после решения. [Зачем перечитывать задание?](https://github.com/OtusGolang/home_work/wiki/%D0%9A%D0%BE%D0%BC%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80%D0%B8%D0%B8-%D0%BA-%D1%87%D0%B5%D0%BA-%D0%BB%D0%B8%D1%81%D1%82%D1%83-%D1%81%D1%82%D1%83%D0%B4%D0%B5%D0%BD%D1%82%D0%B0#user-content-%D0%97%D0%B0%D1%87%D0%B5%D0%BC-%D0%BF%D0%B5%D1%80%D0%B5%D1%87%D0%B8%D1%82%D1%8B%D0%B2%D0%B0%D1%82%D1%8C-%D0%B7%D0%B0%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5)
- [ ] Я запустил `go mod tidy`.
- [ ] Я удалил `.sync` файл. [Зачем его удалять?](https://github.com/OtusGolang/home_work/wiki/%5B%D0%A1%D1%82%D1%83%D0%B4%D0%B5%D0%BD%D1%82%D0%B0%D0%BC%5D-%D0%9F%D1%80%D0%BE%D1%86%D0%B5%D1%81%D1%81-%D1%81%D0%B4%D0%B0%D1%87%D0%B8-%D0%94%D0%97#user-content-%D0%92%D0%B0%D1%80%D0%B8%D0%B0%D0%BD%D1%82-2)
- [ ] Я провел ручное тестирование программы (например, запускал `test.sh`).
### Критерии оценки
- [ ] Пайплайн зелёный - 4 балла
- [ ] Добавлены юнит-тесты - до 4 баллов
- [ ] Понятность и чистота кода - до 2 баллов
#### Зачёт от 7 баллов

View File

@ -0,0 +1,14 @@
## Домашнее задание №8 «Утилита envdir»
### Чек-лист студента ([Что это?](https://github.com/OtusGolang/home_work/wiki/%D0%9A%D0%BE%D0%BC%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80%D0%B8%D0%B8-%D0%BA-%D1%87%D0%B5%D0%BA-%D0%BB%D0%B8%D1%81%D1%82%D1%83-%D1%81%D1%82%D1%83%D0%B4%D0%B5%D0%BD%D1%82%D0%B0))
- [ ] Я перечитал задание после решения. [Зачем перечитывать задание?](https://github.com/OtusGolang/home_work/wiki/%D0%9A%D0%BE%D0%BC%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80%D0%B8%D0%B8-%D0%BA-%D1%87%D0%B5%D0%BA-%D0%BB%D0%B8%D1%81%D1%82%D1%83-%D1%81%D1%82%D1%83%D0%B4%D0%B5%D0%BD%D1%82%D0%B0#user-content-%D0%97%D0%B0%D1%87%D0%B5%D0%BC-%D0%BF%D0%B5%D1%80%D0%B5%D1%87%D0%B8%D1%82%D1%8B%D0%B2%D0%B0%D1%82%D1%8C-%D0%B7%D0%B0%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5)
- [ ] Я запустил `go mod tidy`.
- [ ] Я удалил `.sync` файл. [Зачем его удалять?](https://github.com/OtusGolang/home_work/wiki/%5B%D0%A1%D1%82%D1%83%D0%B4%D0%B5%D0%BD%D1%82%D0%B0%D0%BC%5D-%D0%9F%D1%80%D0%BE%D1%86%D0%B5%D1%81%D1%81-%D1%81%D0%B4%D0%B0%D1%87%D0%B8-%D0%94%D0%97#user-content-%D0%92%D0%B0%D1%80%D0%B8%D0%B0%D0%BD%D1%82-2)
- [ ] Я провел ручное тестирование программы (например, запускал `test.sh`).
### Критерии оценки
- [ ] Пайплайн зелёный - 4 балла
- [ ] Добавлены юнит-тесты - до 4 баллов
- [ ] Понятность и чистота кода - до 2 баллов
#### Зачёт от 7 баллов

View File

@ -0,0 +1,13 @@
## Домашнее задание №9 «Валидатор структур»
### Чек-лист студента ([Что это?](https://github.com/OtusGolang/home_work/wiki/%D0%9A%D0%BE%D0%BC%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80%D0%B8%D0%B8-%D0%BA-%D1%87%D0%B5%D0%BA-%D0%BB%D0%B8%D1%81%D1%82%D1%83-%D1%81%D1%82%D1%83%D0%B4%D0%B5%D0%BD%D1%82%D0%B0))
- [ ] Я перечитал задание после решения. [Зачем перечитывать задание?](https://github.com/OtusGolang/home_work/wiki/%D0%9A%D0%BE%D0%BC%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80%D0%B8%D0%B8-%D0%BA-%D1%87%D0%B5%D0%BA-%D0%BB%D0%B8%D1%81%D1%82%D1%83-%D1%81%D1%82%D1%83%D0%B4%D0%B5%D0%BD%D1%82%D0%B0#user-content-%D0%97%D0%B0%D1%87%D0%B5%D0%BC-%D0%BF%D0%B5%D1%80%D0%B5%D1%87%D0%B8%D1%82%D1%8B%D0%B2%D0%B0%D1%82%D1%8C-%D0%B7%D0%B0%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5)
- [ ] Я запустил `go mod tidy`.
- [ ] Я удалил `.sync` файл. [Зачем его удалять?](https://github.com/OtusGolang/home_work/wiki/%5B%D0%A1%D1%82%D1%83%D0%B4%D0%B5%D0%BD%D1%82%D0%B0%D0%BC%5D-%D0%9F%D1%80%D0%BE%D1%86%D0%B5%D1%81%D1%81-%D1%81%D0%B4%D0%B0%D1%87%D0%B8-%D0%94%D0%97#user-content-%D0%92%D0%B0%D1%80%D0%B8%D0%B0%D0%BD%D1%82-2)
### Критерии оценки
- [ ] Пайплайн зелёный - 3 балла
- [ ] Добавлены юнит-тесты - до 4 баллов
- [ ] Понятность и чистота кода - до 3 баллов
#### Зачёт от 7 баллов

View File

@ -0,0 +1,14 @@
## Домашнее задание №10 «Оптимизация программы»
### Чек-лист студента ([Что это?](https://github.com/OtusGolang/home_work/wiki/%D0%9A%D0%BE%D0%BC%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80%D0%B8%D0%B8-%D0%BA-%D1%87%D0%B5%D0%BA-%D0%BB%D0%B8%D1%81%D1%82%D1%83-%D1%81%D1%82%D1%83%D0%B4%D0%B5%D0%BD%D1%82%D0%B0))
- [ ] Я перечитал задание после решения. [Зачем перечитывать задание?](https://github.com/OtusGolang/home_work/wiki/%D0%9A%D0%BE%D0%BC%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80%D0%B8%D0%B8-%D0%BA-%D1%87%D0%B5%D0%BA-%D0%BB%D0%B8%D1%81%D1%82%D1%83-%D1%81%D1%82%D1%83%D0%B4%D0%B5%D0%BD%D1%82%D0%B0#user-content-%D0%97%D0%B0%D1%87%D0%B5%D0%BC-%D0%BF%D0%B5%D1%80%D0%B5%D1%87%D0%B8%D1%82%D1%8B%D0%B2%D0%B0%D1%82%D1%8C-%D0%B7%D0%B0%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5)
- [ ] Я запустил `go mod tidy`.
- [ ] Я удалил `.sync` файл. [Зачем его удалять?](https://github.com/OtusGolang/home_work/wiki/%5B%D0%A1%D1%82%D1%83%D0%B4%D0%B5%D0%BD%D1%82%D0%B0%D0%BC%5D-%D0%9F%D1%80%D0%BE%D1%86%D0%B5%D1%81%D1%81-%D1%81%D0%B4%D0%B0%D1%87%D0%B8-%D0%94%D0%97#user-content-%D0%92%D0%B0%D1%80%D0%B8%D0%B0%D0%BD%D1%82-2)
- [ ] Я написал бенчмарк и приложил результаты benchstat.
### Критерии оценки
- [ ] Пайплайн зелёный и нет попытки «обмануть» систему - 4 балла
- [ ] Добавлены юнит-тесты - до 3 баллов
- [ ] Понятность и чистота кода - до 3 баллов
#### Зачёт от 7 баллов

View File

@ -0,0 +1,14 @@
## Домашнее задание №11 «Клиент TELNET»
### Чек-лист студента ([Что это?](https://github.com/OtusGolang/home_work/wiki/%D0%9A%D0%BE%D0%BC%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80%D0%B8%D0%B8-%D0%BA-%D1%87%D0%B5%D0%BA-%D0%BB%D0%B8%D1%81%D1%82%D1%83-%D1%81%D1%82%D1%83%D0%B4%D0%B5%D0%BD%D1%82%D0%B0))
- [ ] Я перечитал задание после решения. [Зачем перечитывать задание?](https://github.com/OtusGolang/home_work/wiki/%D0%9A%D0%BE%D0%BC%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%80%D0%B8%D0%B8-%D0%BA-%D1%87%D0%B5%D0%BA-%D0%BB%D0%B8%D1%81%D1%82%D1%83-%D1%81%D1%82%D1%83%D0%B4%D0%B5%D0%BD%D1%82%D0%B0#user-content-%D0%97%D0%B0%D1%87%D0%B5%D0%BC-%D0%BF%D0%B5%D1%80%D0%B5%D1%87%D0%B8%D1%82%D1%8B%D0%B2%D0%B0%D1%82%D1%8C-%D0%B7%D0%B0%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5)
- [ ] Я запустил `go mod tidy`.
- [ ] Я удалил `.sync` файл. [Зачем его удалять?](https://github.com/OtusGolang/home_work/wiki/%5B%D0%A1%D1%82%D1%83%D0%B4%D0%B5%D0%BD%D1%82%D0%B0%D0%BC%5D-%D0%9F%D1%80%D0%BE%D1%86%D0%B5%D1%81%D1%81-%D1%81%D0%B4%D0%B0%D1%87%D0%B8-%D0%94%D0%97#user-content-%D0%92%D0%B0%D1%80%D0%B8%D0%B0%D0%BD%D1%82-2)
- [ ] Я провел ручное тестирование программы (например, запускал `test.sh`).
### Критерии оценки
- [ ] Пайплайн зелёный - 4 балла
- [ ] Добавлены юнит-тесты - до 2 баллов
- [ ] Понятность и чистота кода - до 4 баллов
#### Зачёт от 7 баллов

View File

@ -0,0 +1,16 @@
## Домашнее задание №12 «Заготовка сервиса Календарь»
### Критерии оценки
- [ ] Makefile заполнен и пайплайн зеленый - 1 балл
- [ ] Понятность и чистота кода (включая факт, что проект разбит
на пакеты по определенной логике) - до 2 баллов
- [ ] Реализовано конфигурирование сервиса - 1 балл
- [ ] Используется логгер и он настраивается из конфига - 1 балл
- [ ] Запускается простой HTTP-сервер, мидлвара удовлетворяет ТЗ - 1 балл
- [ ] Присутствуют юнит-тесты - 1 балл
Реализовано хранилище:
- [ ] in-memory - 1 балл
- [ ] sql + миграции - 2 балла
#### Зачёт от 7 баллов

View File

@ -0,0 +1,10 @@
## Домашнее задание №13 «API к Календарю»
### Критерии оценки
- [ ] Makefile заполнен и пайплайн зеленый - 1 балл
- [ ] Реализовано GRPC API и `make generate` - 3 балла
- [ ] Реализовано HTTP API - 2 балла
- [ ] Написаны юнит-тесты на API - до 2 баллов
- [ ] Понятность и чистота кода - до 2 баллов
#### Зачёт от 7 баллов

View File

@ -0,0 +1,14 @@
## Домашнее задание №14 «Кроликизация Календаря»
### Критерии оценки
- [ ] Makefile заполнен и пайплайн зеленый - 1 балл
- [ ] Работа с RMQ выделена в отдельный пакет, код не дублируется - 1 балл
- [ ] Реализован Рассыльщик - 2 балла
- [ ] Можно собрать сервисы одной командой (`make build`) - 1 балл
- [ ] Понятность и чистота кода - до 2 баллов
Реализован Планировщик:
- [ ] отсылает уведомления о выбранных событиях - 2 балла
- [ ] удаляет старые события - 1 балл
#### Зачёт от 7 баллов

View File

@ -0,0 +1,12 @@
## Домашнее задание №15 «Докеризация и интеграционное тестирование Календаря»
### Критерии оценки
- [ ] Проект полностью запускается и останавливается с помощью `make up` / `make down` - 3 балла
- [ ] Интеграционные тесты запускаются с помощью `make integration-tests`. Команда возвращает верный код ответа - 1 балл
Интеграционные тесты покрывают бизнес сценарии:
- [ ] добавление события и обработка бизнес ошибок - 2 балла
- [ ] получение листинга событий на день/неделю/месяц - 2 балла
- [ ] отправка уведомлений - 2 балла
#### Зачёт от 7 баллов

85
.github/workflows/tests.yml vendored Normal file
View File

@ -0,0 +1,85 @@
name: Otus homework tests
on:
push:
branches:
- hw*
env:
GO111MODULE: "on"
jobs:
lint:
runs-on: ubuntu-latest
if: ${{ !contains(github.ref, 'calendar') }}
steps:
- name: Extract branch name
run: echo "BRANCH=${GITHUB_REF#refs/heads/}" >> $GITHUB_ENV
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: ~1.19
- name: Check out code
uses: actions/checkout@v3
- name: Linters
uses: golangci/golangci-lint-action@v3
with:
version: v1.50.1
working-directory: ${{ env.BRANCH }}
tests:
runs-on: ubuntu-latest
if: ${{ !contains(github.ref, 'calendar') }}
steps:
- name: Extract branch name
run: echo "BRANCH=${GITHUB_REF#refs/heads/}" >> $GITHUB_ENV
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: ^1.19
- name: Check out code
uses: actions/checkout@v3
- name: Unit tests
run: go test -v -count=1 -race -timeout=1m ./...
working-directory: ${{ env.BRANCH }}
- name: Optimization tests
run: go test -v -count=1 -timeout=1m -tags bench ./...
if: env.BRANCH == 'hw10_program_optimization'
working-directory: ${{ env.BRANCH }}
- name: Bash tests
shell: bash
run: ./test.sh
if: contains('hw01_hello_otus hw07_file_copying hw08_envdir_tool hw11_telnet_client', env.BRANCH)
working-directory: ${{ env.BRANCH }}
tests_by_makefile:
runs-on: ubuntu-latest
if: contains(github.ref, 'calendar')
steps:
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: ^1.19
- name: Check out code
uses: actions/checkout@v3
- name: make lint
run: make lint
working-directory: hw12_13_14_15_calendar
- name: make build
run: make build
working-directory: hw12_13_14_15_calendar
- name: make test
run: make test
working-directory: hw12_13_14_15_calendar

28
.gitignore vendored Normal file
View File

@ -0,0 +1,28 @@
### Go template
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
go-cp
go-envdir
go-telnet
# Test binary, build with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
### User defined
.idea/
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
.vscode/
*.bak

67
.golangci.yml Normal file
View File

@ -0,0 +1,67 @@
run:
tests: true
build-tags:
- bench
- !bench
linters-settings:
funlen:
lines: 150
statements: 80
issues:
exclude-rules:
- path: _test\.go
linters:
- errcheck
- dupl
- gocyclo
- gosec
linters:
disable-all: true
enable:
- asciicheck
- bodyclose
- depguard
- dogsled
- dupl
- durationcheck
- errorlint
- exhaustive
- exportloopref
- funlen
- gci
- gocognit
- goconst
- gocritic
- gocyclo
- godot
- gofmt
- gofumpt
- goheader
- goprintffuncname
- gosec
- gosimple
- govet
- importas
- ineffassign
- lll
- makezero
- misspell
- nestif
- nilerr
- noctx
- nolintlint
- prealloc
- predeclared
- revive
- staticcheck
- stylecheck
- tagliatelle
- thelper
- typecheck
- unconvert
- unparam
- unused
- whitespace

0
.scripts/.sync Normal file
View File

17
.scripts/lint.sh Executable file
View File

@ -0,0 +1,17 @@
#!/bin/zsh
sed -i.bak '/- deadcode/d' .golangci.yml
sed -i '' '/- unused/d' .golangci.yml
sed -i '' '/- structcheck/d' .golangci.yml
for d in $(ls)
do
if [[ $d == hw* ]]; then
cd $d
echo "Lint ${d}..."
golangci-lint run ./...
cd ..
fi
done
mv .golangci.yml.bak .golangci.yml

16
.scripts/sync.sh Executable file
View File

@ -0,0 +1,16 @@
#!/bin/bash
dst=$1
if [[ ! -d "${dst}" ]]; then
echo "Usage: ./.scripts/sync.sh <destination dir>."
echo "The destination dir should exist"
exit 1
fi
GLOBIGNORE=".:..:.git"
for f in *; do
[[ -d "${dst}/${f}" ]] && [[ ! -f "${dst}/${f}/.sync" ]] && continue
echo "syncing ${f}..."
cp -R "${f}" "${dst}"
done

12
.scripts/update.sh Executable file
View File

@ -0,0 +1,12 @@
#!/bin/zsh
for d in $(ls)
do
if [[ $d == hw* ]]; then
cd $d
echo "Update deps in ${d}..."
go mod tidy
go get -t -u ./...
cd ..
fi
done

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
Copyright (c) 2020, Дмитрий Смаль, Антон Телышев
Разрешается повторное распространение и использование как в виде исходного кода, так и в двоичной форме,
с изменениями или без, при соблюдении следующих условий:
- При повторном распространении исходного кода должно оставаться указанное выше уведомление об авторском праве,
этот список условий и последующий отказ от гарантий.
- При повторном распространении двоичного кода должна сохраняться указанная выше информация об авторском праве,
этот список условий и последующий отказ от гарантий в документации и/или в других материалах, поставляемых при распространении.
- Ни название ООО «Отус онлайн-образование», ни имена её сотрудников и преподавателей не могут быть использованы в
качестве поддержки или продвижения продуктов, основанных на этом ПО без предварительного письменного разрешения.
ЭТА ПРОГРАММА ПРЕДОСТАВЛЕНА ВЛАДЕЛЬЦАМИ АВТОРСКИХ ПРАВ И/ИЛИ ДРУГИМИ СТОРОНАМИ «КАК ОНА ЕСТЬ» БЕЗ КАКОГО-ЛИБО ВИДА ГАРАНТИЙ,
ВЫРАЖЕННЫХ ЯВНО ИЛИ ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ИМИ, ПОДРАЗУМЕВАЕМЫЕ ГАРАНТИИ КОММЕРЧЕСКОЙ ЦЕННОСТИ И ПРИГОДНОСТИ ДЛЯ КОНКРЕТНОЙ ЦЕЛИ.
НИ В КОЕМ СЛУЧАЕ НИ ОДИН ВЛАДЕЛЕЦ АВТОРСКИХ ПРАВ И НИ ОДНО ДРУГОЕ ЛИЦО, КОТОРОЕ МОЖЕТ ИЗМЕНЯТЬ И/ИЛИ ПОВТОРНО РАСПРОСТРАНЯТЬ ПРОГРАММУ,
КАК БЫЛО СКАЗАНО ВЫШЕ, НЕ НЕСЁТ ОТВЕТСТВЕННОСТИ, ВКЛЮЧАЯ ЛЮБЫЕ ОБЩИЕ, СЛУЧАЙНЫЕ, СПЕЦИАЛЬНЫЕ ИЛИ ПОСЛЕДОВАВШИЕ УБЫТКИ, ВСЛЕДСТВИЕ ИСПОЛЬЗОВАНИЯ
ИЛИ НЕВОЗМОЖНОСТИ ИСПОЛЬЗОВАНИЯ ПРОГРАММЫ (ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ПОТЕРЕЙ ДАННЫХ, ИЛИ ДАННЫМИ, СТАВШИМИ НЕПРАВИЛЬНЫМИ, ИЛИ ПОТЕРЯМИ,
ПРИНЕСЕННЫМИ ИЗ-ЗА ВАС ИЛИ ТРЕТЬИХ ЛИЦ, ИЛИ ОТКАЗОМ ПРОГРАММЫ РАБОТАТЬ СОВМЕСТНО С ДРУГИМИ ПРОГРАММАМИ), ДАЖЕ ЕСЛИ ТАКОЙ ВЛАДЕЛЕЦ ИЛИ ДРУГОЕ
ЛИЦО БЫЛИ ИЗВЕЩЕНЫ О ВОЗМОЖНОСТИ ТАКИХ УБЫТКОВ.

32
README.md Normal file
View File

@ -0,0 +1,32 @@
## Домашние задания курса [OTUS «Разработчик Golang»](https://otus.ru/lessons/golang-professional/?utm_source=github&utm_medium=free&utm_campaign=otus)
1) [«Hello, OTUS!»](./hw01_hello_otus)
2) [«Распаковка строки»](./hw02_unpack_string)
3) [«Частотный анализ»](./hw03_frequency_analysis)
4) [«LRU-кэш»](./hw04_lru_cache)
5) [«Параллельное исполнение»](./hw05_parallel_execution)
6) [«Пайплайн»](./hw06_pipeline_execution)
7) [«Утилита для копирования файлов»](./hw07_file_copying)
8) [«Утилита envdir»](./hw08_envdir_tool)
9) [«Валидатор структур»](./hw09_struct_validator)
10) [«Оптимизация программы»](./hw10_program_optimization)
11) [«Клиент TELNET»](./hw11_telnet_client)
12) [«Заготовка сервиса Календарь»](./hw12_13_14_15_calendar/docs/12_README.md)
13) [«API к Календарю»](./hw12_13_14_15_calendar/docs/13_README.md)
14) [«Кроликизация Календаря»](./hw12_13_14_15_calendar/docs/14_README.md)
15) [«Докеризация и интеграционное тестирование Календаря»](./hw12_13_14_15_calendar/docs/15_README.md)
16) [«Проект»](https://github.com/OtusGolang/final_project)
---
[Инструкция по сдаче ДЗ](https://github.com/OtusGolang/home_work/wiki#%D0%A1%D1%82%D1%83%D0%B4%D0%B5%D0%BD%D1%82%D0%B0%D0%BC).
---
Используемая версия [golangci-lint](https://golangci-lint.run/usage/install/#other-ci): <b>v1.50.1</b>
```
$ golangci-lint version
golangci-lint has version 1.50.1 built from 8926a95 on 2022-10-22T10:48:48Z
```
---
Авторы ДЗ:
- [Дмитрий Смаль](https://github.com/mialinx)
- [Антон Телышев](https://github.com/Antonboom)

0
hw01_hello_otus/.sync Normal file
View File

22
hw01_hello_otus/README.md Normal file
View File

@ -0,0 +1,22 @@
## Домашнее задание №1 «Hello, OTUS!»
Необходимо написать программу, печатающую в стандартный вывод перевернутую фразу
```
Hello, OTUS!
```
Для переворота строки следует воспользоваться возможностями
[golang.org/x/example/stringutil](https://github.com/golang/example/tree/master/stringutil).
Кроме этого необходимо исправить **go.mod** так, чтобы для данного модуля работала
команда `go get`, а полученный **go.sum** закоммитить.
### Критерии оценки
- Пайплайн зелёный - 4 балла
- Используется `stringutil` - 4 балла
- Понятность и чистота кода - до 2 баллов
#### Зачёт от 7 баллов
### Подсказки
- `Reverse`

3
hw01_hello_otus/go.mod Normal file
View File

@ -0,0 +1,3 @@
module github.com/fixme_my_friend/hw01_hello_otus
go 1.19

5
hw01_hello_otus/main.go Normal file
View File

@ -0,0 +1,5 @@
package main
func main() {
// Place your code here.
}

8
hw01_hello_otus/test.sh Executable file
View File

@ -0,0 +1,8 @@
#!/usr/bin/env bash
set -xeuo pipefail
expected='!SUTO ,olleH'
result=$(go run main.go | sed 's/^ *//;s/ *$//')
[ "${result}" = "${expected}" ] || (echo -e "invalid output: ${result}" && exit 1)
echo "PASS"

0
hw02_unpack_string/.sync Normal file
View File

View File

@ -0,0 +1,41 @@
## Домашнее задание №2 «Распаковка строки»
Необходимо написать Go функцию, осуществляющую примитивную распаковку строки,
содержащую повторяющиеся символы/руны, например:
* "a4bc2d5e" => "aaaabccddddde"
* "abcd" => "abcd"
* "3abc" => "" (некорректная строка)
* "45" => "" (некорректная строка)
* "aaa10b" => "" (некорректная строка)
* "aaa0b" => "aab"
* "" => ""
* "d\n5abc" => "d\n\n\n\n\nabc"
Как видно из примеров, разрешено использование цифр, но не чисел.
В случае, если была передана некорректная строка, функция должна возвращать ошибку.
При необходимости можно выделять дополнительные функции / ошибки.
**(*) Дополнительное задание: поддержка экранирования через `\`:**
**(обратите внимание на косые кавычки)**
* \`qwe\4\5\` => "qwe45"
* \`qwe\45\` => "qwe44444"
* \`qwe\\\5\` => \`qwe\\\\\\\\\\`
* \`qw\ne\` => "" (некорректная строка)
Как видно из примера, заэкранировать можно только цифру или слэш.
### Критерии оценки
- Пайплайн зелёный - 4 балла
- Добавлены новые юнит-тесты - до 4 баллов
- Понятность и чистота кода - до 2 баллов
- Дополнительное задание на баллы не влияет
#### Зачёт от 7 баллов
### Подсказки
- https://golang.org/ref/spec#String_literals
- `strings.Builder`
- `strings.Repeat`
- `strconv.Atoi`

11
hw02_unpack_string/go.mod Normal file
View File

@ -0,0 +1,11 @@
module github.com/fixme_my_friend/hw02_unpack_string
go 1.19
require github.com/stretchr/testify v1.7.0
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
)

13
hw02_unpack_string/go.sum Normal file
View File

@ -0,0 +1,13 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -0,0 +1,12 @@
package hw02unpackstring
import (
"errors"
)
var ErrInvalidString = errors.New("invalid string")
func Unpack(_ string) (string, error) {
// Place your code here.
return "", nil
}

View File

@ -0,0 +1,45 @@
package hw02unpackstring
import (
"errors"
"testing"
"github.com/stretchr/testify/require"
)
func TestUnpack(t *testing.T) {
tests := []struct {
input string
expected string
}{
{input: "a4bc2d5e", expected: "aaaabccddddde"},
{input: "abccd", expected: "abccd"},
{input: "", expected: ""},
{input: "aaa0b", expected: "aab"},
// uncomment if task with asterisk completed
// {input: `qwe\4\5`, expected: `qwe45`},
// {input: `qwe\45`, expected: `qwe44444`},
// {input: `qwe\\5`, expected: `qwe\\\\\`},
// {input: `qwe\\\3`, expected: `qwe\3`},
}
for _, tc := range tests {
tc := tc
t.Run(tc.input, func(t *testing.T) {
result, err := Unpack(tc.input)
require.NoError(t, err)
require.Equal(t, tc.expected, result)
})
}
}
func TestUnpackInvalidString(t *testing.T) {
invalidStrings := []string{"3abc", "45", "aaa10b"}
for _, tc := range invalidStrings {
tc := tc
t.Run(tc, func(t *testing.T) {
_, err := Unpack(tc)
require.Truef(t, errors.Is(err, ErrInvalidString), "actual error %q", err)
})
}
}

View File

View File

@ -0,0 +1,60 @@
## Домашнее задание №3 «Частотный анализ»
Необходимо написать Go функцию, принимающую на вход строку с текстом и
возвращающую слайс с 10-ю наиболее часто встречаемыми в тексте словами.
Если слова имеют одинаковую частоту, то должны быть отсортированы **лексикографически**.
* Словом считается набор символов, разделенных пробельными символами.
* Если есть более 10 самых частотых слов (например 15 разных слов встречаются ровно 133 раза,
остальные < 100), то следует вернуть 10 лексикографически первых слов.
* Словоформы не учитываем: "нога", "ногу", "ноги" - это разные слова.
* Слово с большой и маленькой буквы считать за разные слова. "Нога" и "нога" - это разные слова.
* Знаки препинания считать "буквами" слова или отдельными словами.
"-" (тире) - это отдельное слово. "нога," и "нога" - это разные слова.
#### Пример
```
cat and dog, one dog,two cats and one man
```
Топ 7:
- `and` (2)
- `one` (2)
- `cat` (1)
- `cats` (1)
- `dog,` (1)
- `dog,two` (1)
- `man` (1)
При необходимости можно выделять дополнительные функции / ошибки.
**(*) Дополнительное задание: не учитывать регистр букв и знаки препинания по краям слова:**
* "Нога" и "нога" - это одинаковые слова, "нога!", "нога", "нога," и " 'нога' " - это одинаковые слова;
* "какой-то" и "какойто" - это разные слова.
* "dog,cat", "dog...cat", "dogcat" - разные слова
* "-------" это слово
* "-" словом не является
### Критерии оценки
- Пайплайн зелёный - 4 балла
- Добавлены новые юнит-тесты - до 4 баллов
- Понятность и чистота кода - до 2 баллов
- Дополнительное задание на баллы не влияет
#### Зачёт от 7 баллов
### Подсказки
- `regexp.MustCompile`
- `strings.Split`
- `strings.Fields`
- `sort.Slice`
### Частые ошибки
- `regexp.MustCompile` используется в функции, а не уровне пакета - это плохо по следующим причинам:
* производительность: нет смысла компилировать регулярку каждый раз при вызове функции;
* функция не должна паниковать!
- При выполнении задания со звёздочкой забывают, что тире не должно являться словом.

View File

@ -0,0 +1,11 @@
module github.com/fixme_my_friend/hw03_frequency_analysis
go 1.19
require github.com/stretchr/testify v1.7.0
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
)

View File

@ -0,0 +1,13 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -0,0 +1,6 @@
package hw03frequencyanalysis
func Top10(_ string) []string {
// Place your code here.
return nil
}

View File

@ -0,0 +1,82 @@
package hw03frequencyanalysis
import (
"testing"
"github.com/stretchr/testify/require"
)
// Change to true if needed.
var taskWithAsteriskIsCompleted = false
var text = `Как видите, он спускается по лестнице вслед за своим
другом Кристофером Робином, головой вниз, пересчитывая
ступеньки собственным затылком: бум-бум-бум. Другого способа
сходить с лестницы он пока не знает. Иногда ему, правда,
кажется, что можно бы найти какой-то другой способ, если бы он
только мог на минутку перестать бумкать и как следует
сосредоточиться. Но увы - сосредоточиться-то ему и некогда.
Как бы то ни было, вот он уже спустился и готов с вами
познакомиться.
- Винни-Пух. Очень приятно!
Вас, вероятно, удивляет, почему его так странно зовут, а
если вы знаете английский, то вы удивитесь еще больше.
Это необыкновенное имя подарил ему Кристофер Робин. Надо
вам сказать, что когда-то Кристофер Робин был знаком с одним
лебедем на пруду, которого он звал Пухом. Для лебедя это было
очень подходящее имя, потому что если ты зовешь лебедя
громко: "Пу-ух! Пу-ух!"- а он не откликается, то ты всегда
можешь сделать вид, что ты просто понарошку стрелял; а если ты
звал его тихо, то все подумают, что ты просто подул себе на
нос. Лебедь потом куда-то делся, а имя осталось, и Кристофер
Робин решил отдать его своему медвежонку, чтобы оно не пропало
зря.
А Винни - так звали самую лучшую, самую добрую медведицу
в зоологическом саду, которую очень-очень любил Кристофер
Робин. А она очень-очень любила его. Ее ли назвали Винни в
честь Пуха, или Пуха назвали в ее честь - теперь уже никто не
знает, даже папа Кристофера Робина. Когда-то он знал, а теперь
забыл.
Словом, теперь мишку зовут Винни-Пух, и вы знаете почему.
Иногда Винни-Пух любит вечерком во что-нибудь поиграть, а
иногда, особенно когда папа дома, он больше любит тихонько
посидеть у огня и послушать какую-нибудь интересную сказку.
В этот вечер...`
func TestTop10(t *testing.T) {
t.Run("no words in empty string", func(t *testing.T) {
require.Len(t, Top10(""), 0)
})
t.Run("positive test", func(t *testing.T) {
if taskWithAsteriskIsCompleted {
expected := []string{
"а", // 8
"он", // 8
"и", // 6
"ты", // 5
"что", // 5
"в", // 4
"его", // 4
"если", // 4
"кристофер", // 4
"не", // 4
}
require.Equal(t, expected, Top10(text))
} else {
expected := []string{
"он", // 8
"а", // 6
"и", // 6
"ты", // 5
"что", // 5
"-", // 4
"Кристофер", // 4
"если", // 4
"не", // 4
"то", // 4
}
require.Equal(t, expected, Top10(text))
}
})
}

0
hw04_lru_cache/.sync Normal file
View File

84
hw04_lru_cache/README.md Normal file
View File

@ -0,0 +1,84 @@
## Домашнее задание №4 «LRU-кэш»
Необходимо реализовать LRU-кэш на основе двусвязного списка.
Задание состоит из двух частей, которые необходимо выполнять последовательно.
### 1) Реализация двусвязного списка
Список имеет структуру вида
```text
nil <- (prev) front <-> ... <-> elem <-> ... <-> back (next) -> nil
```
Необходимо реализовать следующий интерфейс List:
- Len() int // длина списка
- Front() *ListItem // первый элемент списка
- Back() *ListItem // последний элемент списка
- PushFront(v interface{}) *ListItem // добавить значение в начало
- PushBack(v interface{}) *ListItem // добавить значение в конец
- Remove(i *ListItem) // удалить элемент
- MoveToFront(i *ListItem) // переместить элемент в начало
**Считаем, что методы Remove и MoveToFront вызываются только от существующих в списке элементов.**
Элемент списка ListItem:
- Value interface{} // значение
- Next *ListItem // следующий элемент
- Prev *ListItem // предыдущий элемент
Сложность всех операций должна быть O(1),
т.е. не должно быть мест, где осуществляется полный обход списка.
### 2) Реализация кэша на основе ранее написанного списка
Необходимо реализовать следующий интерфейс Cache:
- Set(key Key, value interface{}) bool // Добавить значение в кэш по ключу.
- Get(key Key) (interface{}, bool) // Получить значение из кэша по ключу.
- Clear() // Очистить кэш.
Структура кэша:
- ёмкость (количество сохраняемых в кэше элементов)
- очередь \[последних используемых элементов\] на основе двусвязного списка
- словарь, отображающий ключ (строка) на элемент очереди
Элемент кэша хранит в себе ключ, по которому он лежит в словаре, и само значение.
Для чего это нужно понятно из алгоритма работы кэша (см. ниже).
Сложность операций `Set`/`Get` должна быть O(1), при желании `Clear` тоже можно сделать О(1).
Алгоритм работы кэша:
- при добавлении элемента:
- если элемент присутствует в словаре, то обновить его значение и переместить элемент в начало очереди;
- если элемента нет в словаре, то добавить в словарь и в начало очереди
(при этом, если размер очереди больше ёмкости кэша,
то необходимо удалить последний элемент из очереди и его значение из словаря);
- возвращаемое значение - флаг, присутствовал ли элемент в кэше.
- при получении элемента:
- если элемент присутствует в словаре, то переместить элемент в начало очереди и вернуть его значение и true;
- если элемента нет в словаре, то вернуть nil и false
(работа с кешом похожа на работу с `map`)
Ожидаются следующие тесты:
- на логику выталкивания элементов из-за размера очереди
(например: n = 3, добавили 4 элемента - 1й из кэша вытолкнулся);
- на логику выталкивания давно используемых элементов
(например: n = 3, добавили 3 элемента, обратились несколько раз к разным элементам:
изменили значение, получили значение и пр. - добавили 4й элемент,
из первой тройки вытолкнется тот элемент, что был затронут наиболее давно).
**(*) Дополнительное задание: сделать кэш горутино-безопасным.**
### Критерии оценки
- Пайплайн зелёный - 4 балла
- Добавлены новые юнит-тесты для списка - 1 балл
- Добавлены новые юнит-тесты для кэша (см. выше) - до 3 баллов
- Понятность и чистота кода - до 2 баллов
- Дополнительное задание на баллы не влияет
#### Зачёт от 7 баллов
### Подсказки
- https://en.wikipedia.org/wiki/Doubly_linked_list
- https://ru.bmstu.wiki/LRU_(Least_Recently_Used)
- `sync.Mutex`
### Частые ошибки
1) В задании со звёздочкой забывают про синхронизацию в методе Clear кэша.

25
hw04_lru_cache/cache.go Normal file
View File

@ -0,0 +1,25 @@
package hw04lrucache
type Key string
type Cache interface {
Set(key Key, value interface{}) bool
Get(key Key) (interface{}, bool)
Clear()
}
type lruCache struct {
Cache // Remove me after realization.
capacity int
queue List
items map[Key]*ListItem
}
func NewCache(capacity int) Cache {
return &lruCache{
capacity: capacity,
queue: NewList(),
items: make(map[Key]*ListItem, capacity),
}
}

View File

@ -0,0 +1,79 @@
package hw04lrucache
import (
"math/rand"
"strconv"
"sync"
"testing"
"github.com/stretchr/testify/require"
)
func TestCache(t *testing.T) {
t.Run("empty cache", func(t *testing.T) {
c := NewCache(10)
_, ok := c.Get("aaa")
require.False(t, ok)
_, ok = c.Get("bbb")
require.False(t, ok)
})
t.Run("simple", func(t *testing.T) {
c := NewCache(5)
wasInCache := c.Set("aaa", 100)
require.False(t, wasInCache)
wasInCache = c.Set("bbb", 200)
require.False(t, wasInCache)
val, ok := c.Get("aaa")
require.True(t, ok)
require.Equal(t, 100, val)
val, ok = c.Get("bbb")
require.True(t, ok)
require.Equal(t, 200, val)
wasInCache = c.Set("aaa", 300)
require.True(t, wasInCache)
val, ok = c.Get("aaa")
require.True(t, ok)
require.Equal(t, 300, val)
val, ok = c.Get("ccc")
require.False(t, ok)
require.Nil(t, val)
})
t.Run("purge logic", func(t *testing.T) {
// Write me
})
}
func TestCacheMultithreading(t *testing.T) {
t.Skip() // Remove me if task with asterisk completed.
c := NewCache(10)
wg := &sync.WaitGroup{}
wg.Add(2)
go func() {
defer wg.Done()
for i := 0; i < 1_000_000; i++ {
c.Set(Key(strconv.Itoa(i)), i)
}
}()
go func() {
defer wg.Done()
for i := 0; i < 1_000_000; i++ {
c.Get(Key(strconv.Itoa(rand.Intn(1_000_000))))
}
}()
wg.Wait()
}

11
hw04_lru_cache/go.mod Normal file
View File

@ -0,0 +1,11 @@
module github.com/fixme_my_friend/hw04_lru_cache
go 1.19
require github.com/stretchr/testify v1.7.0
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
)

13
hw04_lru_cache/go.sum Normal file
View File

@ -0,0 +1,13 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

26
hw04_lru_cache/list.go Normal file
View File

@ -0,0 +1,26 @@
package hw04lrucache
type List interface {
Len() int
Front() *ListItem
Back() *ListItem
PushFront(v interface{}) *ListItem
PushBack(v interface{}) *ListItem
Remove(i *ListItem)
MoveToFront(i *ListItem)
}
type ListItem struct {
Value interface{}
Next *ListItem
Prev *ListItem
}
type list struct {
List // Remove me after realization.
// Place your code here.
}
func NewList() List {
return new(list)
}

View File

@ -0,0 +1,51 @@
package hw04lrucache
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestList(t *testing.T) {
t.Run("empty list", func(t *testing.T) {
l := NewList()
require.Equal(t, 0, l.Len())
require.Nil(t, l.Front())
require.Nil(t, l.Back())
})
t.Run("complex", func(t *testing.T) {
l := NewList()
l.PushFront(10) // [10]
l.PushBack(20) // [10, 20]
l.PushBack(30) // [10, 20, 30]
require.Equal(t, 3, l.Len())
middle := l.Front().Next // 20
l.Remove(middle) // [10, 30]
require.Equal(t, 2, l.Len())
for i, v := range [...]int{40, 50, 60, 70, 80} {
if i%2 == 0 {
l.PushFront(v)
} else {
l.PushBack(v)
}
} // [80, 60, 40, 10, 30, 50, 70]
require.Equal(t, 7, l.Len())
require.Equal(t, 80, l.Front().Value)
require.Equal(t, 70, l.Back().Value)
l.MoveToFront(l.Front()) // [80, 60, 40, 10, 30, 50, 70]
l.MoveToFront(l.Back()) // [70, 80, 60, 40, 10, 30, 50]
elems := make([]int, 0, l.Len())
for i := l.Front(); i != nil; i = i.Next {
elems = append(elems, i.Value.(int))
}
require.Equal(t, []int{70, 80, 60, 40, 10, 30, 50}, elems)
})
}

View File

View File

@ -0,0 +1,84 @@
## Домашнее задание №5 «Параллельное исполнение»
Необходимо написать функцию для параллельного выполнения заданий в n параллельных горутинах:
* количество создаваемых горутин не должно зависеть от числа заданий, т.е. функция должна запускать n горутин для конкурентной обработки заданий и, возможно, еще несколько вспомогательных горутин;
* функция должна останавливать свою работу, если произошло m ошибок;
* после завершения работы функции (успешного или из-за превышения m) не должно оставаться работающих горутин.
Нужно учесть, что задания могут выполняться разное время, а длина списка задач
`len(tasks)` может быть больше или меньше n.
Значение m <= 0 трактуется на усмотрение программиста:
- или это знак игнорировать ошибки в принципе;
- или считать это как "максимум 0 ошибок", значит функция всегда будет возвращать
`ErrErrorsLimitExceeded`;
- на эту логику следует написать юнит-тест.
Граничные случаи:
* если задачи работают без ошибок, то выполнятся `len(tasks)` задач, т.е. все задачи;
* если в первых выполненных m задачах (или вообще всех) происходят ошибки, то всего выполнится не более n+m задач.
**(*) Дополнительное задание: написать тест на concurrency без time.Sleep**
Придумайте тест, который проверит concurrency другим способом.
Текущий тест "tasks without errors" использует time.Sleep и подсчет времени выполнения, чтобы сделать вывод о конкурентности использования. Проблема тестов на слипчиках в том, что на CI часто не хватает CPU и подобные тесты работают нестабильно.
Подсказка: используйте `require.Eventually`.
---
#### Пример
Имеем 10 задач, n=4 воркера, m=2 ошибки.
- Запускаем:
```
--------------ok (узнал, что лимит превышен и остановился)
-----------err
-------err
--------------------ok
```
Выполнится 4 задачи (2 успешно) <= 4 + 2, остальные задачи  не берем.
- Другая ситуация, работающие воркеры успели еще взять задач:
```
------ok--------ok (узнал, что лимит превышен и остановился)
-----------err
---err
--------ok-------ok
```
Выполнится 6 задач (4 успешно) <= 4 + 2, остальные задачи не берем.
- Ошибок не было:
```
-------ok-----ok-----ok-----ok (1 воркер выполнил 4 задачи)
-----------ok-------------ok (2 воркер выполнил 2 задачи)
-----ok---------ok---------ok (3 воркер выполнил 3 задачи)
--------------------ok (4 воркер выполнил 1 задачу)
```
Выполнится 10 задач (10 успешно): задач не осталось, воркеры остановились.
---
При необходимости можно выделять дополнительные функции / ошибки.
### Критерии оценки
- Пайплайн зелёный - 4 балла
- Добавлены новые юнит-тесты - до 4 баллов
- Понятность и чистота кода - до 2 баллов
#### Зачёт от 7 баллов
### Подсказки
- https://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem
- `sync.WaitGroup`
- `go test -v -race -count=100 .`
### Частые ошибки
1) `racedetector` ругается на строчку с ассертом в тестах:
- простой случай: после выхода из `Run` остаются висячие горутины, отсюда и получаем `data race` -
ассерт в тестах неатомарно обращается к `runTasksCount`, в то время как зомби-горутины атомарно пытаюся её поменять.
- случай посложнее: один тест завершается успешно, но висячие горутины, им порожденные, аффектят ассерты в
последующих тестах.
2) Запускаются лишние горутины (инструкции `go`). Их количество за все время работы `Run` должно быть n (плюс, возможно, еще одна-две, если по другому не получается). В некоторых решениях ошибочно контроллируется количество одновременно работающих, а не общее количество.
**Решение**: внимательно посмотреть места выхода из функции и гарантировать, что все порождённые вами горутины
завершились к этому моменту.

View File

@ -0,0 +1,16 @@
module github.com/fixme_my_friend/hw05_parallel_execution
go 1.19
require (
github.com/stretchr/testify v1.7.0
go.uber.org/goleak v1.1.10
)
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 // indirect
golang.org/x/tools v0.1.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
)

View File

@ -0,0 +1,55 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0=
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 h1:2M3HP5CCK1Si9FQhwnzYhXdG6DXeebvUHFpre8QvbyI=
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 h1:myAQVi0cGEoqQVR5POX+8RR2mrocKqNN1hmeMqhX27k=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -0,0 +1,15 @@
package hw05parallelexecution
import (
"errors"
)
var ErrErrorsLimitExceeded = errors.New("errors limit exceeded")
type Task func() error
// Run starts tasks in n goroutines and stops its work when receiving m errors from tasks.
func Run(tasks []Task, n, m int) error {
// Place your code here.
return nil
}

View File

@ -0,0 +1,70 @@
package hw05parallelexecution
import (
"errors"
"fmt"
"math/rand"
"sync/atomic"
"testing"
"time"
"github.com/stretchr/testify/require"
"go.uber.org/goleak"
)
func TestRun(t *testing.T) {
defer goleak.VerifyNone(t)
t.Run("if were errors in first M tasks, than finished not more N+M tasks", func(t *testing.T) {
tasksCount := 50
tasks := make([]Task, 0, tasksCount)
var runTasksCount int32
for i := 0; i < tasksCount; i++ {
err := fmt.Errorf("error from task %d", i)
tasks = append(tasks, func() error {
time.Sleep(time.Millisecond * time.Duration(rand.Intn(100)))
atomic.AddInt32(&runTasksCount, 1)
return err
})
}
workersCount := 10
maxErrorsCount := 23
err := Run(tasks, workersCount, maxErrorsCount)
require.Truef(t, errors.Is(err, ErrErrorsLimitExceeded), "actual err - %v", err)
require.LessOrEqual(t, runTasksCount, int32(workersCount+maxErrorsCount), "extra tasks were started")
})
t.Run("tasks without errors", func(t *testing.T) {
tasksCount := 50
tasks := make([]Task, 0, tasksCount)
var runTasksCount int32
var sumTime time.Duration
for i := 0; i < tasksCount; i++ {
taskSleep := time.Millisecond * time.Duration(rand.Intn(100))
sumTime += taskSleep
tasks = append(tasks, func() error {
time.Sleep(taskSleep)
atomic.AddInt32(&runTasksCount, 1)
return nil
})
}
workersCount := 5
maxErrorsCount := 1
start := time.Now()
err := Run(tasks, workersCount, maxErrorsCount)
elapsedTime := time.Since(start)
require.NoError(t, err)
require.Equal(t, runTasksCount, int32(tasksCount), "not all tasks were completed")
require.LessOrEqual(t, int64(elapsedTime), int64(sumTime/2), "tasks were run sequentially?")
})
}

View File

View File

@ -0,0 +1,37 @@
## Домашнее задание №6 «Пайплайн»
Необходимо реализовать функцию для запуска конкуррентного пайплайна, состоящего из стейджей.
Стейдж - функция, принимающая канал на чтение и отдающая канал на чтение, внутри в горутине берущая данные из входного канала, выполняющая полезную работу и отдающая результат в выходной канал:
```golang
func Stage(in <-chan interface{}) (out <-chan interface{}) {
out = make(chan interface{})
go func() { /* Some work */ }()
return out
}
```
Особенность пайплайна в том, что обработка последующего элемента входных данных должна
происходить **без ожидания завершения всего пайплайна** для текущего элемента.
Т.е. пайплан из 4 функций по 100 мс каждая для 5 входных элементов **должен выполняться
гораздо быстрее**, чем за 2 секунды (4 * 100 мс * 5).
Также **должна быть реализована возможность остановить пайплайн** через
дополнительный сигнальный канал (`done`/`terminate`/etc.).
При необходимости можно выделять дополнительные функции.
**Нельзя менять сигнатуры исходных функций.**
Для большего понимания см. тесты.
### Критерии оценки
- CI-пайплайн зелёный - 5 баллов
- Добавлены новые юнит-тесты - до 2 баллов
- Понятность и чистота кода - до 3 баллов
#### Зачёт от 7 баллов
### Подсказки
- https://github.com/golang/go/wiki/CommonMistakes#using-goroutines-on-loop-iterator-variables
- `go test -v -race -count=100 .`

View File

@ -0,0 +1,11 @@
module github.com/fixme_my_friend/hw06_pipeline_execution
go 1.19
require github.com/stretchr/testify v1.7.0
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
)

View File

@ -0,0 +1,13 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -0,0 +1,14 @@
package hw06pipelineexecution
type (
In = <-chan interface{}
Out = In
Bi = chan interface{}
)
type Stage func(in In) (out Out)
func ExecutePipeline(in In, done In, stages ...Stage) Out {
// Place your code here.
return nil
}

View File

@ -0,0 +1,93 @@
package hw06pipelineexecution
import (
"strconv"
"testing"
"time"
"github.com/stretchr/testify/require"
)
const (
sleepPerStage = time.Millisecond * 100
fault = sleepPerStage / 2
)
func TestPipeline(t *testing.T) {
// Stage generator
g := func(_ string, f func(v interface{}) interface{}) Stage {
return func(in In) Out {
out := make(Bi)
go func() {
defer close(out)
for v := range in {
time.Sleep(sleepPerStage)
out <- f(v)
}
}()
return out
}
}
stages := []Stage{
g("Dummy", func(v interface{}) interface{} { return v }),
g("Multiplier (* 2)", func(v interface{}) interface{} { return v.(int) * 2 }),
g("Adder (+ 100)", func(v interface{}) interface{} { return v.(int) + 100 }),
g("Stringifier", func(v interface{}) interface{} { return strconv.Itoa(v.(int)) }),
}
t.Run("simple case", func(t *testing.T) {
in := make(Bi)
data := []int{1, 2, 3, 4, 5}
go func() {
for _, v := range data {
in <- v
}
close(in)
}()
result := make([]string, 0, 10)
start := time.Now()
for s := range ExecutePipeline(in, nil, stages...) {
result = append(result, s.(string))
}
elapsed := time.Since(start)
require.Equal(t, []string{"102", "104", "106", "108", "110"}, result)
require.Less(t,
int64(elapsed),
// ~0.8s for processing 5 values in 4 stages (100ms every) concurrently
int64(sleepPerStage)*int64(len(stages)+len(data)-1)+int64(fault))
})
t.Run("done case", func(t *testing.T) {
in := make(Bi)
done := make(Bi)
data := []int{1, 2, 3, 4, 5}
// Abort after 200ms
abortDur := sleepPerStage * 2
go func() {
<-time.After(abortDur)
close(done)
}()
go func() {
for _, v := range data {
in <- v
}
close(in)
}()
result := make([]string, 0, 10)
start := time.Now()
for s := range ExecutePipeline(in, done, stages...) {
result = append(result, s.(string))
}
elapsed := time.Since(start)
require.Len(t, result, 0)
require.Less(t, int64(elapsed), int64(abortDur)+int64(fault))
})
}

0
hw07_file_copying/.sync Normal file
View File

View File

@ -0,0 +1,37 @@
## Домашнее задание №7 «Утилита для копирования файлов»
Необходимо реализовать утилиту копирования файлов (упрощенный аналог `dd`).
Тулза должна принимать следующие аргументы:
* путь к исходному файлу (`-from`);
* путь к копии (`-to`);
* отступ в источнике (`-offset`), по умолчанию - 0;
* количество копируемых байт (`-limit`), по умолчанию - 0 (весь файл из `-from`).
Особенности:
* offset больше, чем размер файла - невалидная ситуация;
* limit больше, чем размер файла - валидная ситуация, копируется исходный файл до его EOF;
* программа может НЕ обрабатывать файлы, у которых неизвестна длина (например, /dev/urandom);
Также необходимо выводить в консоль прогресс копирования в процентах (%),
допускается использовать для этого стороннюю библиотеку.
Юнит-тесты могут использовать файлы из `testdata` (разрешено добавить свои, но запрещено удалять имеющиеся)
и должны чистить за собой создаваемые файлы (или работать в `/tmp`).
При необходимости можно выделять дополнительные функции / ошибки.
**(*) Дополнительное задание: реализовать прогресс-бар самостоятельно.**
### Критерии оценки
- Пайплайн зелёный - 4 балла
- Добавлены юнит-тесты - до 4 баллов
- Понятность и чистота кода - до 2 баллов
- Дополнительное задание на баллы не влияет
#### Зачёт от 7 баллов
### Подсказки
- `github.com/cheggaaa/pb`
- `os.OpenFile`, `os.Create`, `os.FileMode`
- `io.CopyN`
- `os.CreateTemp`

15
hw07_file_copying/copy.go Normal file
View File

@ -0,0 +1,15 @@
package main
import (
"errors"
)
var (
ErrUnsupportedFile = errors.New("unsupported file")
ErrOffsetExceedsFileSize = errors.New("offset exceeds file size")
)
func Copy(fromPath, toPath string, offset, limit int64) error {
// Place your code here.
return nil
}

View File

@ -0,0 +1,7 @@
package main
import "testing"
func TestCopy(t *testing.T) {
// Place your code here.
}

3
hw07_file_copying/go.mod Normal file
View File

@ -0,0 +1,3 @@
module github.com/fixme_my_friend/hw07_file_copying
go 1.19

0
hw07_file_copying/go.sum Normal file
View File

22
hw07_file_copying/main.go Normal file
View File

@ -0,0 +1,22 @@
package main
import (
"flag"
)
var (
from, to string
limit, offset int64
)
func init() {
flag.StringVar(&from, "from", "", "file to read from")
flag.StringVar(&to, "to", "", "file to write to")
flag.Int64Var(&limit, "limit", 0, "limit of bytes to copy")
flag.Int64Var(&offset, "offset", 0, "offset in input file")
}
func main() {
flag.Parse()
// Place your code here.
}

25
hw07_file_copying/test.sh Executable file
View File

@ -0,0 +1,25 @@
#!/usr/bin/env bash
set -xeuo pipefail
go build -o go-cp
./go-cp -from testdata/input.txt -to out.txt
cmp out.txt testdata/out_offset0_limit0.txt
./go-cp -from testdata/input.txt -to out.txt -limit 10
cmp out.txt testdata/out_offset0_limit10.txt
./go-cp -from testdata/input.txt -to out.txt -limit 1000
cmp out.txt testdata/out_offset0_limit1000.txt
./go-cp -from testdata/input.txt -to out.txt -limit 10000
cmp out.txt testdata/out_offset0_limit10000.txt
./go-cp -from testdata/input.txt -to out.txt -offset 100 -limit 1000
cmp out.txt testdata/out_offset100_limit1000.txt
./go-cp -from testdata/input.txt -to out.txt -offset 6000 -limit 1000
cmp out.txt testdata/out_offset6000_limit1000.txt
rm -f go-cp out.txt
echo "PASS"

125
hw07_file_copying/testdata/input.txt vendored Normal file
View File

@ -0,0 +1,125 @@
Go
Documents
Packages
The Project
Help
Blog
Play
Search
Getting Started
Install the Go tools
Test your installation
Installing extra Go versions
Uninstalling Go
Getting help
Download the Go distribution
Download Go
Click here to visit the downloads page
Official binary distributions are available for the FreeBSD (release 10-STABLE and above), Linux, macOS (10.10 and above), and Windows operating systems and the 32-bit (386) and 64-bit (amd64) x86 processor architectures.
If a binary distribution is not available for your combination of operating system and architecture, try installing from source or installing gccgo instead of gc.
System requirements
Go binary distributions are available for these supported operating systems and architectures. Please ensure your system meets these requirements before proceeding. If your OS or architecture is not on the list, you may be able to install from source or use gccgo instead.
Operating system Architectures Notes
FreeBSD 10.3 or later amd64, 386 Debian GNU/kFreeBSD not supported
Linux 2.6.23 or later with glibc amd64, 386, arm, arm64,
s390x, ppc64le CentOS/RHEL 5.x not supported.
Install from source for other libc.
macOS 10.10 or later amd64 use the clang or gcc† that comes with Xcode‡ for cgo support
Windows 7, Server 2008R2 or later amd64, 386 use MinGW (386) or MinGW-W64 (amd64) gcc†.
No need for cygwin or msys.
†A C compiler is required only if you plan to use cgo.
‡You only need to install the command line tools for Xcode. If you have already installed Xcode 4.3+, you can install it from the Components tab of the Downloads preferences panel.
Install the Go tools
If you are upgrading from an older version of Go you must first remove the existing version.
Linux, macOS, and FreeBSD tarballs
Download the archive and extract it into /usr/local, creating a Go tree in /usr/local/go. For example:
tar -C /usr/local -xzf go$VERSION.$OS-$ARCH.tar.gz
Choose the archive file appropriate for your installation. For instance, if you are installing Go version 1.2.1 for 64-bit x86 on Linux, the archive you want is called go1.2.1.linux-amd64.tar.gz.
(Typically these commands must be run as root or through sudo.)
Add /usr/local/go/bin to the PATH environment variable. You can do this by adding this line to your /etc/profile (for a system-wide installation) or $HOME/.profile:
export PATH=$PATH:/usr/local/go/bin
Note: changes made to a profile file may not apply until the next time you log into your computer. To apply the changes immediately, just run the shell commands directly or execute them from the profile using a command such as source $HOME/.profile.
macOS package installer
Download the package file, open it, and follow the prompts to install the Go tools. The package installs the Go distribution to /usr/local/go.
The package should put the /usr/local/go/bin directory in your PATH environment variable. You may need to restart any open Terminal sessions for the change to take effect.
Windows
The Go project provides two installation options for Windows users (besides installing from source): a zip archive that requires you to set some environment variables and an MSI installer that configures your installation automatically.
MSI installer
Open the MSI file and follow the prompts to install the Go tools. By default, the installer puts the Go distribution in c:\Go.
The installer should put the c:\Go\bin directory in your PATH environment variable. You may need to restart any open command prompts for the change to take effect.
Zip archive
Download the zip file and extract it into the directory of your choice (we suggest c:\Go).
Add the bin subdirectory of your Go root (for example, c:\Go\bin) to your PATH environment variable.
Setting environment variables under Windows
Under Windows, you may set environment variables through the "Environment Variables" button on the "Advanced" tab of the "System" control panel. Some versions of Windows provide this control panel through the "Advanced System Settings" option inside the "System" control panel.
Test your installation
Check that Go is installed correctly by setting up a workspace and building a simple program, as follows.
Create your workspace directory, $HOME/go. (If you'd like to use a different directory, you will need to set the GOPATH environment variable.)
Next, make the directory src/hello inside your workspace, and in that directory create a file named hello.go that looks like:
package main
import "fmt"
func main() {
fmt.Printf("hello, world\n")
}
Then build it with the go tool:
$ cd $HOME/go/src/hello
$ go build
The command above will build an executable named hello in the directory alongside your source code. Execute it to see the greeting:
$ ./hello
hello, world
If you see the "hello, world" message then your Go installation is working.
You can run go install to install the binary into your workspace's bin directory or go clean -i to remove it.
Before rushing off to write Go code please read the How to Write Go Code document, which describes some essential concepts about using the Go tools.
Installing extra Go versions
It may be useful to have multiple Go versions installed on the same machine, for example, to ensure that a package's tests pass on multiple Go versions. Once you have one Go version installed, you can install another (such as 1.10.7) as follows:
$ go get golang.org/dl/go1.10.7
$ go1.10.7 download
The newly downloaded version can be used like go:
$ go1.10.7 version
go version go1.10.7 linux/amd64
All Go versions available via this method are listed on the download page. You can find where each of these extra Go versions is installed by looking at its GOROOT; for example, go1.10.7 env GOROOT. To uninstall a downloaded version, just remove its GOROOT directory and the goX.Y.Z binary.
Uninstalling Go
To remove an existing Go installation from your system delete the go directory. This is usually /usr/local/go under Linux, macOS, and FreeBSD or c:\Go under Windows.
You should also remove the Go bin directory from your PATH environment variable. Under Linux and FreeBSD you should edit /etc/profile or $HOME/.profile. If you installed Go with the macOS package then you should remove the /etc/paths.d/go file. Windows users should read the section about setting environment variables under Windows.
Getting help
For help, see the list of Go mailing lists, forums, and places to chat.
Report bugs either by running “go bug”, or manually at the Go issue tracker.
The Go Gopher
Copyright Terms of Service Privacy Policy Report a website issue
Supported by Google

View File

@ -0,0 +1,125 @@
Go
Documents
Packages
The Project
Help
Blog
Play
Search
Getting Started
Install the Go tools
Test your installation
Installing extra Go versions
Uninstalling Go
Getting help
Download the Go distribution
Download Go
Click here to visit the downloads page
Official binary distributions are available for the FreeBSD (release 10-STABLE and above), Linux, macOS (10.10 and above), and Windows operating systems and the 32-bit (386) and 64-bit (amd64) x86 processor architectures.
If a binary distribution is not available for your combination of operating system and architecture, try installing from source or installing gccgo instead of gc.
System requirements
Go binary distributions are available for these supported operating systems and architectures. Please ensure your system meets these requirements before proceeding. If your OS or architecture is not on the list, you may be able to install from source or use gccgo instead.
Operating system Architectures Notes
FreeBSD 10.3 or later amd64, 386 Debian GNU/kFreeBSD not supported
Linux 2.6.23 or later with glibc amd64, 386, arm, arm64,
s390x, ppc64le CentOS/RHEL 5.x not supported.
Install from source for other libc.
macOS 10.10 or later amd64 use the clang or gcc† that comes with Xcode‡ for cgo support
Windows 7, Server 2008R2 or later amd64, 386 use MinGW (386) or MinGW-W64 (amd64) gcc†.
No need for cygwin or msys.
†A C compiler is required only if you plan to use cgo.
‡You only need to install the command line tools for Xcode. If you have already installed Xcode 4.3+, you can install it from the Components tab of the Downloads preferences panel.
Install the Go tools
If you are upgrading from an older version of Go you must first remove the existing version.
Linux, macOS, and FreeBSD tarballs
Download the archive and extract it into /usr/local, creating a Go tree in /usr/local/go. For example:
tar -C /usr/local -xzf go$VERSION.$OS-$ARCH.tar.gz
Choose the archive file appropriate for your installation. For instance, if you are installing Go version 1.2.1 for 64-bit x86 on Linux, the archive you want is called go1.2.1.linux-amd64.tar.gz.
(Typically these commands must be run as root or through sudo.)
Add /usr/local/go/bin to the PATH environment variable. You can do this by adding this line to your /etc/profile (for a system-wide installation) or $HOME/.profile:
export PATH=$PATH:/usr/local/go/bin
Note: changes made to a profile file may not apply until the next time you log into your computer. To apply the changes immediately, just run the shell commands directly or execute them from the profile using a command such as source $HOME/.profile.
macOS package installer
Download the package file, open it, and follow the prompts to install the Go tools. The package installs the Go distribution to /usr/local/go.
The package should put the /usr/local/go/bin directory in your PATH environment variable. You may need to restart any open Terminal sessions for the change to take effect.
Windows
The Go project provides two installation options for Windows users (besides installing from source): a zip archive that requires you to set some environment variables and an MSI installer that configures your installation automatically.
MSI installer
Open the MSI file and follow the prompts to install the Go tools. By default, the installer puts the Go distribution in c:\Go.
The installer should put the c:\Go\bin directory in your PATH environment variable. You may need to restart any open command prompts for the change to take effect.
Zip archive
Download the zip file and extract it into the directory of your choice (we suggest c:\Go).
Add the bin subdirectory of your Go root (for example, c:\Go\bin) to your PATH environment variable.
Setting environment variables under Windows
Under Windows, you may set environment variables through the "Environment Variables" button on the "Advanced" tab of the "System" control panel. Some versions of Windows provide this control panel through the "Advanced System Settings" option inside the "System" control panel.
Test your installation
Check that Go is installed correctly by setting up a workspace and building a simple program, as follows.
Create your workspace directory, $HOME/go. (If you'd like to use a different directory, you will need to set the GOPATH environment variable.)
Next, make the directory src/hello inside your workspace, and in that directory create a file named hello.go that looks like:
package main
import "fmt"
func main() {
fmt.Printf("hello, world\n")
}
Then build it with the go tool:
$ cd $HOME/go/src/hello
$ go build
The command above will build an executable named hello in the directory alongside your source code. Execute it to see the greeting:
$ ./hello
hello, world
If you see the "hello, world" message then your Go installation is working.
You can run go install to install the binary into your workspace's bin directory or go clean -i to remove it.
Before rushing off to write Go code please read the How to Write Go Code document, which describes some essential concepts about using the Go tools.
Installing extra Go versions
It may be useful to have multiple Go versions installed on the same machine, for example, to ensure that a package's tests pass on multiple Go versions. Once you have one Go version installed, you can install another (such as 1.10.7) as follows:
$ go get golang.org/dl/go1.10.7
$ go1.10.7 download
The newly downloaded version can be used like go:
$ go1.10.7 version
go version go1.10.7 linux/amd64
All Go versions available via this method are listed on the download page. You can find where each of these extra Go versions is installed by looking at its GOROOT; for example, go1.10.7 env GOROOT. To uninstall a downloaded version, just remove its GOROOT directory and the goX.Y.Z binary.
Uninstalling Go
To remove an existing Go installation from your system delete the go directory. This is usually /usr/local/go under Linux, macOS, and FreeBSD or c:\Go under Windows.
You should also remove the Go bin directory from your PATH environment variable. Under Linux and FreeBSD you should edit /etc/profile or $HOME/.profile. If you installed Go with the macOS package then you should remove the /etc/paths.d/go file. Windows users should read the section about setting environment variables under Windows.
Getting help
For help, see the list of Go mailing lists, forums, and places to chat.
Report bugs either by running “go bug”, or manually at the Go issue tracker.
The Go Gopher
Copyright Terms of Service Privacy Policy Report a website issue
Supported by Google

View File

@ -0,0 +1,2 @@
Go
Documen

View File

@ -0,0 +1,27 @@
Go
Documents
Packages
The Project
Help
Blog
Play
Search
Getting Started
Install the Go tools
Test your installation
Installing extra Go versions
Uninstalling Go
Getting help
Download the Go distribution
Download Go
Click here to visit the downloads page
Official binary distributions are available for the FreeBSD (release 10-STABLE and above), Linux, macOS (10.10 and above), and Windows operating systems and the 32-bit (386) and 64-bit (amd64) x86 processor architectures.
If a binary distribution is not available for your combination of operating system and architecture, try installing from source or installing gccgo instead of gc.
System requirements
Go binary distributions are available for these supported operating systems and architectures. Please ensure your system meets these requirements before proceeding. If your OS or architecture is not on the list, you may be able to install from source or use gccgo instead.
Operating system Architectures Notes
FreeBSD 10.3 or later amd64

View File

@ -0,0 +1,125 @@
Go
Documents
Packages
The Project
Help
Blog
Play
Search
Getting Started
Install the Go tools
Test your installation
Installing extra Go versions
Uninstalling Go
Getting help
Download the Go distribution
Download Go
Click here to visit the downloads page
Official binary distributions are available for the FreeBSD (release 10-STABLE and above), Linux, macOS (10.10 and above), and Windows operating systems and the 32-bit (386) and 64-bit (amd64) x86 processor architectures.
If a binary distribution is not available for your combination of operating system and architecture, try installing from source or installing gccgo instead of gc.
System requirements
Go binary distributions are available for these supported operating systems and architectures. Please ensure your system meets these requirements before proceeding. If your OS or architecture is not on the list, you may be able to install from source or use gccgo instead.
Operating system Architectures Notes
FreeBSD 10.3 or later amd64, 386 Debian GNU/kFreeBSD not supported
Linux 2.6.23 or later with glibc amd64, 386, arm, arm64,
s390x, ppc64le CentOS/RHEL 5.x not supported.
Install from source for other libc.
macOS 10.10 or later amd64 use the clang or gcc† that comes with Xcode‡ for cgo support
Windows 7, Server 2008R2 or later amd64, 386 use MinGW (386) or MinGW-W64 (amd64) gcc†.
No need for cygwin or msys.
†A C compiler is required only if you plan to use cgo.
‡You only need to install the command line tools for Xcode. If you have already installed Xcode 4.3+, you can install it from the Components tab of the Downloads preferences panel.
Install the Go tools
If you are upgrading from an older version of Go you must first remove the existing version.
Linux, macOS, and FreeBSD tarballs
Download the archive and extract it into /usr/local, creating a Go tree in /usr/local/go. For example:
tar -C /usr/local -xzf go$VERSION.$OS-$ARCH.tar.gz
Choose the archive file appropriate for your installation. For instance, if you are installing Go version 1.2.1 for 64-bit x86 on Linux, the archive you want is called go1.2.1.linux-amd64.tar.gz.
(Typically these commands must be run as root or through sudo.)
Add /usr/local/go/bin to the PATH environment variable. You can do this by adding this line to your /etc/profile (for a system-wide installation) or $HOME/.profile:
export PATH=$PATH:/usr/local/go/bin
Note: changes made to a profile file may not apply until the next time you log into your computer. To apply the changes immediately, just run the shell commands directly or execute them from the profile using a command such as source $HOME/.profile.
macOS package installer
Download the package file, open it, and follow the prompts to install the Go tools. The package installs the Go distribution to /usr/local/go.
The package should put the /usr/local/go/bin directory in your PATH environment variable. You may need to restart any open Terminal sessions for the change to take effect.
Windows
The Go project provides two installation options for Windows users (besides installing from source): a zip archive that requires you to set some environment variables and an MSI installer that configures your installation automatically.
MSI installer
Open the MSI file and follow the prompts to install the Go tools. By default, the installer puts the Go distribution in c:\Go.
The installer should put the c:\Go\bin directory in your PATH environment variable. You may need to restart any open command prompts for the change to take effect.
Zip archive
Download the zip file and extract it into the directory of your choice (we suggest c:\Go).
Add the bin subdirectory of your Go root (for example, c:\Go\bin) to your PATH environment variable.
Setting environment variables under Windows
Under Windows, you may set environment variables through the "Environment Variables" button on the "Advanced" tab of the "System" control panel. Some versions of Windows provide this control panel through the "Advanced System Settings" option inside the "System" control panel.
Test your installation
Check that Go is installed correctly by setting up a workspace and building a simple program, as follows.
Create your workspace directory, $HOME/go. (If you'd like to use a different directory, you will need to set the GOPATH environment variable.)
Next, make the directory src/hello inside your workspace, and in that directory create a file named hello.go that looks like:
package main
import "fmt"
func main() {
fmt.Printf("hello, world\n")
}
Then build it with the go tool:
$ cd $HOME/go/src/hello
$ go build
The command above will build an executable named hello in the directory alongside your source code. Execute it to see the greeting:
$ ./hello
hello, world
If you see the "hello, world" message then your Go installation is working.
You can run go install to install the binary into your workspace's bin directory or go clean -i to remove it.
Before rushing off to write Go code please read the How to Write Go Code document, which describes some essential concepts about using the Go tools.
Installing extra Go versions
It may be useful to have multiple Go versions installed on the same machine, for example, to ensure that a package's tests pass on multiple Go versions. Once you have one Go version installed, you can install another (such as 1.10.7) as follows:
$ go get golang.org/dl/go1.10.7
$ go1.10.7 download
The newly downloaded version can be used like go:
$ go1.10.7 version
go version go1.10.7 linux/amd64
All Go versions available via this method are listed on the download page. You can find where each of these extra Go versions is installed by looking at its GOROOT; for example, go1.10.7 env GOROOT. To uninstall a downloaded version, just remove its GOROOT directory and the goX.Y.Z binary.
Uninstalling Go
To remove an existing Go installation from your system delete the go directory. This is usually /usr/local/go under Linux, macOS, and FreeBSD or c:\Go under Windows.
You should also remove the Go bin directory from your PATH environment variable. Under Linux and FreeBSD you should edit /etc/profile or $HOME/.profile. If you installed Go with the macOS package then you should remove the /etc/paths.d/go file. Windows users should read the section about setting environment variables under Windows.
Getting help
For help, see the list of Go mailing lists, forums, and places to chat.
Report bugs either by running “go bug”, or manually at the Go issue tracker.
The Go Gopher
Copyright Terms of Service Privacy Policy Report a website issue
Supported by Google

View File

@ -0,0 +1,18 @@
our installation
Installing extra Go versions
Uninstalling Go
Getting help
Download the Go distribution
Download Go
Click here to visit the downloads page
Official binary distributions are available for the FreeBSD (release 10-STABLE and above), Linux, macOS (10.10 and above), and Windows operating systems and the 32-bit (386) and 64-bit (amd64) x86 processor architectures.
If a binary distribution is not available for your combination of operating system and architecture, try installing from source or installing gccgo instead of gc.
System requirements
Go binary distributions are available for these supported operating systems and architectures. Please ensure your system meets these requirements before proceeding. If your OS or architecture is not on the list, you may be able to install from source or use gccgo instead.
Operating system Architectures Notes
FreeBSD 10.3 or later amd64, 386 Debian GNU/kFreeBSD not supported
Linux 2.6.23 or later with glibc amd64, 386, arm, arm64,
s39

View File

@ -0,0 +1,12 @@
nder Windows.
You should also remove the Go bin directory from your PATH environment variable. Under Linux and FreeBSD you should edit /etc/profile or $HOME/.profile. If you installed Go with the macOS package then you should remove the /etc/paths.d/go file. Windows users should read the section about setting environment variables under Windows.
Getting help
For help, see the list of Go mailing lists, forums, and places to chat.
Report bugs either by running “go bug”, or manually at the Go issue tracker.
The Go Gopher
Copyright Terms of Service Privacy Policy Report a website issue
Supported by Google

0
hw08_envdir_tool/.sync Normal file
View File

View File

@ -0,0 +1,48 @@
## Домашнее задание №8 «Утилита envdir»
Необходимо реализовать утилиту `envdir` на Go.
Эта утилита позволяет запускать программы, получая переменные окружения из определенной директории:
- если директория содержит файл с именем `S`, первой строкой которого является `T`, то
`envdir` удаляет переменную среды с именем `S`, если таковая существует, а затем добавляет
переменную среды с именем `S` и значением `T`;
- имя `S` не должно содержать `=`; пробелы и табуляция в конце `T` удаляются; терминальные нули (`0x00`) заменяются на перевод строки (`\n`);
- если файл полностью пустой (длина - 0 байт), то `envdir` удаляет переменную окружения с именем `S`.
---
Пример использования:
```bash
$ go-envdir /path/to/env/dir command arg1 arg2
```
Если в директории `/path/to/env/dir` содержатся файлы:
* `FOO` с содержимым `123`;
* `BAR` с содержимым `value`,
то вызов выше эквивалентен вызову
```bash
$ FOO=123 BAR=value command arg1 arg2
```
---
Также необходимо, чтобы:
* стандартные потоки ввода/вывода/ошибок пробрасывались в вызываемую программу;
* код выхода утилиты совпадал с кодом выхода программы.
При необходимости можно выделять дополнительные функции / ошибки.
Юнит-тесты могут использовать файлы из `testdata` или создавать свои директории / файлы,
которые **обязаны** подчищать после своего выполнения.
### Критерии оценки
- Пайплайн зелёный - 4 балла
- Добавлены юнит-тесты - до 4 баллов
- Понятность и чистота кода - до 2 баллов
#### Зачёт от 7 баллов
### Подсказки
- https://www.unix.com/man-page/debian/8/envdir/
- `os.Args`
- `ioutil.ReadDir`
- `bytes.Replace`, `strings.TrimRight`
- `exec.Command`

View File

@ -0,0 +1,16 @@
package main
type Environment map[string]EnvValue
// EnvValue helps to distinguish between empty files and files with the first empty line.
type EnvValue struct {
Value string
NeedRemove bool
}
// ReadDir reads a specified directory and returns map of env variables.
// Variables represented as files where filename is name of variable, file first line is a value.
func ReadDir(dir string) (Environment, error) {
// Place your code here
return nil, nil
}

View File

@ -0,0 +1,7 @@
package main
import "testing"
func TestReadDir(t *testing.T) {
// Place your code here
}

View File

@ -0,0 +1,7 @@
package main
// RunCmd runs a command + arguments (cmd) with environment variables from env.
func RunCmd(cmd []string, env Environment) (returnCode int) {
// Place your code here.
return
}

View File

@ -0,0 +1,7 @@
package main
import "testing"
func TestRunCmd(t *testing.T) {
// Place your code here
}

3
hw08_envdir_tool/go.mod Normal file
View File

@ -0,0 +1,3 @@
module github.com/fixme_my_friend/hw08_envdir_tool
go 1.19

5
hw08_envdir_tool/main.go Normal file
View File

@ -0,0 +1,5 @@
package main
func main() {
// Place your code here.
}

25
hw08_envdir_tool/test.sh Executable file
View File

@ -0,0 +1,25 @@
#!/usr/bin/env bash
set -xeuo pipefail
go build -o go-envdir
export HELLO="SHOULD_REPLACE"
export FOO="SHOULD_REPLACE"
export UNSET="SHOULD_REMOVE"
export ADDED="from original env"
export EMPTY="SHOULD_BE_EMPTY"
result=$(./go-envdir "$(pwd)/testdata/env" "/bin/bash" "$(pwd)/testdata/echo.sh" arg1=1 arg2=2)
expected='HELLO is ("hello")
BAR is (bar)
FOO is ( foo
with new line)
UNSET is ()
ADDED is (from original env)
EMPTY is ()
arguments are arg1=1 arg2=2'
[ "${result}" = "${expected}" ] || (echo -e "invalid output: ${result}" && exit 1)
rm -f go-envdir
echo "PASS"

9
hw08_envdir_tool/testdata/echo.sh vendored Executable file
View File

@ -0,0 +1,9 @@
#!/usr/bin/env bash
echo -e "HELLO is (${HELLO})
BAR is (${BAR})
FOO is (${FOO})
UNSET is (${UNSET})
ADDED is (${ADDED})
EMPTY is (${EMPTY})
arguments are $*"

2
hw08_envdir_tool/testdata/env/BAR vendored Normal file
View File

@ -0,0 +1,2 @@
bar
PLEASE IGNORE SECOND LINE

1
hw08_envdir_tool/testdata/env/EMPTY vendored Normal file
View File

@ -0,0 +1 @@

BIN
hw08_envdir_tool/testdata/env/FOO vendored Normal file

Binary file not shown.

1
hw08_envdir_tool/testdata/env/HELLO vendored Normal file
View File

@ -0,0 +1 @@
"hello"

0
hw08_envdir_tool/testdata/env/UNSET vendored Normal file
View File

View File

View File

@ -0,0 +1,65 @@
## Домашнее задание №9 «Валидатор структур»
Необходимо реализовать функцию:
```golang
func Validate(v interface{}) error
```
Она должна валидировать публичные поля входной структуры на основе структурного тэга `validate`.
Функция может возвращать
- или программную ошибку, произошедшую во время валидации;
- или `ValidationErrors` - ошибку, являющуюся слайсом структур, содержащих имя поля и ошибку его валидации.
Таким образом, нужно накопить все ошибки валидации, а не прерывать валидацию на первой ошибке.
Если у поля нет структурных тэгов или нет тэга `validate`, то функция игнорирует его.
Типы полей, которые обязательно должны поддерживаться:
- `int`, `[]int`;
- `string`, `[]string`.
ри желании можно дополнительно поддержать любые другие типы (на ваше усмотрение)._
Необходимо реализовать следующие валидаторы:
- Для строк:
* `len:32` - длина строки должна быть ровно 32 символа;
* `regexp:\\d+` - согласно регулярному выражению строка должна состоять из цифр
(`\\` - экранирование слэша);
* `in:foo,bar` - строка должна входить в множество строк {"foo", "bar"}.
- Для чисел:
* `min:10` - число не может быть меньше 10;
* `max:20` - число не может быть больше 20;
* `in:256,1024` - число должно входить в множество чисел {256, 1024};
- Для слайсов валидируется каждый элемент слайса.
ри желании можно дополнительно добавить парочку новых правил (на ваше усмотрение)._
Допускается комбинация валидаторов по логическому "И" с помощью `|`, например:
* `min:0|max:10` - число должно находится в пределах [0, 10];
* `regexp:\\d+|len:20` - строка должна состоять из цифр и иметь длину 20.
**(\*) Дополнительное задание: поддержка валидации вложенных по композиции структур.**
```golang
type User struct {
m Meta `validate:"nested"`
}
```
### Критерии оценки
- Пайплайн зелёный - 3 балла
- Добавлены юнит-тесты - до 4 баллов
- Понятность и чистота кода - до 3 баллов
- Дополнительное задание на баллы не влияет
#### Зачёт от 7 баллов
### Подсказки
- `reflect.StructTag`
- `regexp.Compile`
- `errors.Is`
### Частые ошибки
- Отсутствует проверка на то, что входной `interface{}` - структура.
- Нет разделения на программные ошибки (неверный тэг, регулярка и пр.) и ошибки валидации.
- Ошибки валидации не вынесены в отдельные переменные и не завраплены.
- Соответственно в тестах не используется `errors.Is` / `errors.As`.

View File

@ -0,0 +1,3 @@
module github.com/fixme_my_friend/hw09_struct_validator
go 1.19

View File

@ -0,0 +1,17 @@
package hw09structvalidator
type ValidationError struct {
Field string
Err error
}
type ValidationErrors []ValidationError
func (v ValidationErrors) Error() string {
panic("implement me")
}
func Validate(v interface{}) error {
// Place your code here.
return nil
}

View File

@ -0,0 +1,60 @@
package hw09structvalidator
import (
"encoding/json"
"fmt"
"testing"
)
type UserRole string
// Test the function on different structures and other types.
type (
User struct {
ID string `json:"id" validate:"len:36"`
Name string
Age int `validate:"min:18|max:50"`
Email string `validate:"regexp:^\\w+@\\w+\\.\\w+$"`
Role UserRole `validate:"in:admin,stuff"`
Phones []string `validate:"len:11"`
meta json.RawMessage //nolint:unused
}
App struct {
Version string `validate:"len:5"`
}
Token struct {
Header []byte
Payload []byte
Signature []byte
}
Response struct {
Code int `validate:"in:200,404,500"`
Body string `json:"omitempty"`
}
)
func TestValidate(t *testing.T) {
tests := []struct {
in interface{}
expectedErr error
}{
{
// Place your code here.
},
// ...
// Place your code here.
}
for i, tt := range tests {
t.Run(fmt.Sprintf("case %d", i), func(t *testing.T) {
tt := tt
t.Parallel()
// Place your code here.
_ = tt
})
}
}

View File

View File

@ -0,0 +1,52 @@
## Домашнее задание №10 «Оптимизация программы»
Вам дан исходный код функции `GetDomainStat(r io.Reader, domain string)`, которая:
* читает построчно из `r` пользовательские данные вида
```text
{"Id":1,"Name":"Howard Mendoza","Username":"0Oliver","Email":"aliquid_qui_ea@Browsedrive.gov","Phone":"6-866-899-36-79","Password":"InAQJvsq","Address":"Blackbird Place 25"}
{"Id":2,"Name":"Brian Olson","Username":"non_quia_id","Email":"FrancesEllis@Quinu.edu","Phone":"237-75-34","Password":"cmEPhX8","Address":"Butterfield Junction 74"}
{"Id":3,"Name":"Justin Oliver Jr. Sr.","Username":"oPerez","Email":"MelissaGutierrez@Twinte.gov","Phone":"106-05-18","Password":"f00GKr9i","Address":"Oak Valley Lane 19"}
```
(осторожно, в отличие от конкретной строки файл целиком не является валидным JSON);
* подсчитывает количество email-доменов пользователей на основе домена первого уровня `domain`.
Например, для данных, представленных выше:
```text
GetDomainStat(r, "com") // {}
GetDomainStat(r, "gov") // {"browsedrive": 1, "twinte": 1}
GetDomainStat(r, "edu") // {"quinu": 1}
```
Для большего понимания см. исходный код и тесты.
**Необходимо оптимизировать программу таким образом, чтобы она проходила все тесты.**
Нельзя:
- изменять сигнатуру функции `GetDomainStat`;
- удалять или изменять существующие юнит-тесты.
Можно:
- писать любой новый необходимый код;
- удалять имеющийся лишний код (кроме функции `GetDomainStat`);
- использовать сторонние библиотеки по ускорению анмаршалинга JSON;
- добавлять юнит-тесты.
**Обратите внимание на запуск TestGetDomainStat_Time_And_Memory**
```bash
go test -v -count=1 -timeout=30s -tags bench .
```
Здесь используется билд-тэг bench, чтобы отделить обычные тесты от тестов производительности.
### Оформление пул-риквеста
В идеале к подобным пул-риквестам пишут бенчмарки и прикладывают результаты работы benchstat, чтобы сразу было видно, что стало лучше и насколько.
### Критерии оценки
- Пайплайн зелёный и нет попытки «обмануть» систему - 4 балла
- Добавлены юнит-тесты - до 3 баллов
- Понятность и чистота кода - до 3 баллов
### Частые ошибки
- Работа с сырыми байтами, нахождение позиции `"Email"` и пр. вместо ускорения анмаршалинга более поддерживаемыми и понятными средствами.
#### Зачёт от 7 баллов

Some files were not shown because too many files have changed in this diff Show More