fix 29 typos
This commit is contained in:
parent
69266412e0
commit
800cb4cefa
16 changed files with 29 additions and 29 deletions
|
@ -21,7 +21,7 @@
|
||||||
Нужно реализовать функцию `MakeLetter` из файла [letter.go](./letter.go),
|
Нужно реализовать функцию `MakeLetter` из файла [letter.go](./letter.go),
|
||||||
которая по go объекту нотификации генерирует её текстовое представление.
|
которая по go объекту нотификации генерирует её текстовое представление.
|
||||||
|
|
||||||
Для этого нужно написать `text/template` шаблон, сохранить его в отдлеьный файл, а затем получить его содержимое в коде с помомщью `go:embed`.
|
Для этого нужно написать `text/template` шаблон, сохранить его в отдельный файл, а затем получить его содержимое в коде с помомщью `go:embed`.
|
||||||
|
|
||||||
#### Прокомментированный пример из теста
|
#### Прокомментированный пример из теста
|
||||||
```
|
```
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
### Что нужно сделать?
|
### Что нужно сделать?
|
||||||
|
|
||||||
Нужно написать реализацию Cond используя каналы.
|
Нужно написать реализацию Cond, используя каналы.
|
||||||
|
|
||||||
Использование пакета [sync](https://golang.org/pkg/sync) в этой задаче запрещено!
|
Использование пакета [sync](https://golang.org/pkg/sync) в этой задаче запрещено!
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
# client
|
# client
|
||||||
|
|
||||||
Пакет `client` реализует клиента системы распределённой сборки. Клиент запускается локально, и имеет доступ к
|
Пакет `client` реализует клиента системы распределённой сборки. Клиент запускается локально и имеет доступ к
|
||||||
директории с исходным кодом.
|
директории с исходным кодом.
|
||||||
|
|
||||||
Клиент получает на вход `build.Graph` и запускает сборку на координаторе.
|
Клиент получает на вход `build.Graph` и запускает сборку на координаторе.
|
||||||
|
|
||||||
После того, как координатор создал новую сборку, клиент заливает недостающие файлы и посылает сигнал о завершении стадии заливки.
|
После того, как координатор создал новую сборку, клиент заливает недостающие файлы и посылает сигнал о завершении стадии заливки.
|
||||||
|
|
||||||
После этого, клиент следит за прогрессом сборки, дожидается завершения и выходит.
|
После этого клиент следит за прогрессом сборки, дожидается завершения и выходит.
|
||||||
|
|
||||||
Клиент тестируется интеграционными тестами из пакета `disttest`.
|
Клиент тестируется интеграционными тестами из пакета `disttest`.
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
- Вызов `GET /file?id=123` должен возвращать содержимое файла с `id=123`.
|
- Вызов `GET /file?id=123` должен возвращать содержимое файла с `id=123`.
|
||||||
- Вызов `PUT /file?id=123` должен заливать содержимое файла с `id=123`.
|
- Вызов `PUT /file?id=123` должен заливать содержимое файла с `id=123`.
|
||||||
|
|
||||||
**Обратите внимание:** Несколько клиентов могут начать заливать в кеш один и тот же набор файлов. В наивной реализации,
|
**Обратите внимание:** Несколько клиентов могут начать заливать в кеш один и тот же набор файлов. В наивной реализации
|
||||||
первый клиент залочит файл на запись, а следующие упадут с ошибкой. Ваш код должен обрабатывать эту ситуацию корректно,
|
первый клиент залочит файл на запись, а следующие упадут с ошибкой. Ваш код должен обрабатывать эту ситуацию корректно,
|
||||||
то есть последующие запросы должны дожидаться, пока первый запрос завершится. Для реализации этой логики
|
то есть последующие запросы должны дожидаться, пока первый запрос завершится. Для реализации этой логики
|
||||||
поведения вам поможет пакет [singleflight](https://godoc.org/golang.org/x/sync/singleflight).
|
поведения вам поможет пакет [singleflight](https://godoc.org/golang.org/x/sync/singleflight).
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
воркерами.
|
воркерами.
|
||||||
|
|
||||||
Для того, чтобы зачесть домашнее задание, достаточно реализовать упрощённый алгоритм планирования с
|
Для того, чтобы зачесть домашнее задание, достаточно реализовать упрощённый алгоритм планирования с
|
||||||
одной глобальной очередью. Функция `ScheduleJob` должна помещать `job` в очередь, или возвращать ссылку на существующий
|
одной глобальной очередью. Функция `ScheduleJob` должна помещать `job` в очередь или возвращать ссылку на существующий
|
||||||
`pendingJob`. Функция `PickJob` должна извлекать первый элемент из очереди. Обратите внимание, что функция `PickJob`
|
`pendingJob`. Функция `PickJob` должна извлекать первый элемент из очереди. Обратите внимание, что функция `PickJob`
|
||||||
принимает контекст. Поскольку это блокирующая операция, она должна поддерживать отмены. Если вы забудете
|
принимает контекст. Поскольку это блокирующая операция, она должна поддерживать отмены. Если вы забудете
|
||||||
реализовать отмену в этом месте, интеграционные тесты будут зависать.
|
реализовать отмену в этом месте, интеграционные тесты будут зависать.
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
1. Одна глобальная очередь.
|
1. Одна глобальная очередь.
|
||||||
2. По две локальные очереди на воркер.
|
2. По две локальные очереди на воркер.
|
||||||
|
|
||||||
При запросе нового джоба воркер выбирает случайную джобу из трех очередей - глобальной, и двух локальных относящихся
|
При запросе нового джоба воркер выбирает случайную джобу из трех очередей - глобальной и двух локальных, относящихся
|
||||||
к этому воркеру. Случайная очередь выбирается одним вызовом `select {}`.
|
к этому воркеру. Случайная очередь выбирается одним вызовом `select {}`.
|
||||||
|
|
||||||
Ожидающий исполнения джоб всегда находится в первой локальной очереди воркеров, на которых есть
|
Ожидающий исполнения джоб всегда находится в первой локальной очереди воркеров, на которых есть
|
||||||
|
@ -41,7 +41,7 @@
|
||||||
из множества зависимостей этого джоба.
|
из множества зависимостей этого джоба.
|
||||||
|
|
||||||
Определения первой и второй локальной очереди не зависят от того, в каком порядке в шедулер пришли джобы
|
Определения первой и второй локальной очереди не зависят от того, в каком порядке в шедулер пришли джобы
|
||||||
и информация о кеше артефактов. То есть, если джоб уже находится в глобальной очереди, и в этот момент приходит
|
и информация о кеше артефактов. То есть, если джоб уже находится в глобальной очереди и в этот момент приходит
|
||||||
информация, что этот джоб находится в кеше на воркере `W0`, то джоб должен быть добавлен
|
информация, что этот джоб находится в кеше на воркере `W0`, то джоб должен быть добавлен
|
||||||
в первую локальную очередь `W0`.
|
в первую локальную очередь `W0`.
|
||||||
|
|
||||||
|
@ -51,5 +51,5 @@
|
||||||
|
|
||||||
Вместо реального времени, юниттесты шедулера используют библиотеку `clockwork`. Это накладывает ограничения
|
Вместо реального времени, юниттесты шедулера используют библиотеку `clockwork`. Это накладывает ограничения
|
||||||
на детали вашей реализации. Ожидание `CacheTimeout` и `DepTimeout` должно быть реализовано как `select {}` на
|
на детали вашей реализации. Ожидание `CacheTimeout` и `DepTimeout` должно быть реализовано как `select {}` на
|
||||||
канале, который вернула функция `TimeAfter`. Мы считаем что `CacheTimeout < DepTimeout`, и ожидание этих
|
канале, который вернула функция `TimeAfter`. Мы считаем, что `CacheTimeout < DepTimeout`, и ожидание этих
|
||||||
таймаутов происходит последовательно в одной горутине.
|
таймаутов происходит последовательно в одной горутине.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# tarstream
|
# tarstream
|
||||||
|
|
||||||
Вам нужно уметь передавать директорию с артефактами между воркерами. Для этого, вам нужно
|
Вам нужно уметь передавать директорию с артефактами между воркерами. Для этого вам нужно
|
||||||
реализовать две операции:
|
реализовать две операции:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
go test -v ./dockertest/... -count=1
|
go test -v ./dockertest/... -count=1
|
||||||
```
|
```
|
||||||
|
|
||||||
Только **после того, как тесты пройдут локально** можете запушить решение в систему.
|
Только **после того, как тесты пройдут локально,** можете запушить решение в систему.
|
||||||
|
|
||||||
### С чего начать?
|
### С чего начать?
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ docker-compose up
|
||||||
|
|
||||||
Поискать решение проблемы в интернете.
|
Поискать решение проблемы в интернете.
|
||||||
|
|
||||||
Если решение найдено, и проблема выглядит общей, сделать merge request с улучшением README.
|
Если решение найдено и проблема выглядит общей, сделать merge request с улучшением README.
|
||||||
|
|
||||||
Если интернет не помог, спросить в чате.
|
Если интернет не помог, спросить в чате.
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ docker-compose down
|
||||||
|
|
||||||
### Docker cheat sheet
|
### Docker cheat sheet
|
||||||
|
|
||||||
Получить список образов
|
Получить список образов:
|
||||||
```
|
```
|
||||||
docker images
|
docker images
|
||||||
```
|
```
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
студентам, но будут запускаться в момент проверки решения в
|
студентам, но будут запускаться в момент проверки решения в
|
||||||
тестирующей системе.
|
тестирующей системе.
|
||||||
- При посылке решения, на сервер отправляются все файлы внутри пакета.
|
- При посылке решения, на сервер отправляются все файлы внутри пакета.
|
||||||
- При тестировании, используются изменённые файлы пакета, и
|
- При тестировании, используются изменённые файлы пакета и
|
||||||
оригинальные файлы тестов.
|
оригинальные файлы тестов.
|
||||||
- Файл пакета можно защитить от изменения, добавив `//go:build !change` в начало файла.
|
- Файл пакета можно защитить от изменения, добавив `//go:build !change` в начало файла.
|
||||||
В этом случае при тестировании посылки всегда будет использоваться оригинальная версия файла.
|
В этом случае при тестировании посылки всегда будет использоваться оригинальная версия файла.
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
В этой задаче нужно написать примитивный файрвол.
|
В этой задаче нужно написать примитивный файрвол.
|
||||||
|
|
||||||
Файрвол - это прокси сервер, пропускающий через себя все запросы,
|
Файрвол - это прокси сервер, пропускающий через себя все запросы
|
||||||
и отвергающий некоторые из них по заданному набору правил.
|
и отвергающий некоторые из них по заданному набору правил.
|
||||||
|
|
||||||
Пример правил можно посмотреть в [example.yaml](./configs/example.yaml).
|
Пример правил можно посмотреть в [example.yaml](./configs/example.yaml).
|
||||||
|
|
|
@ -30,7 +30,7 @@ f4640df4 (Fedor Korotkiy 2020-02-26 20:28:52 +0000 5) Задача считае
|
||||||
```
|
```
|
||||||
|
|
||||||
`git blame` с флагом `--porcelain` (см. `git blame --help`) возвращает информацию в машиночитаемом формате.
|
`git blame` с флагом `--porcelain` (см. `git blame --help`) возвращает информацию в машиночитаемом формате.
|
||||||
Кроме того, этот формат схлопывает соседние строки относящиеся к одному коммиту,
|
Кроме того, этот формат схлопывает соседние строки, относящиеся к одному коммиту,
|
||||||
что может сильно сократить размер результата. Поэтому использовать нужно его.
|
что может сильно сократить размер результата. Поэтому использовать нужно его.
|
||||||
|
|
||||||
Стоит помнить, что не все файлы из директории git проекта обязательно принадлежат git репозиторию.
|
Стоит помнить, что не все файлы из директории git проекта обязательно принадлежат git репозиторию.
|
||||||
|
@ -58,7 +58,7 @@ f4640df4 (Fedor Korotkiy 2020-02-26 20:28:52 +0000 5) Задача считае
|
||||||
|
|
||||||
**--revision** — указатель на коммит; HEAD по умолчанию
|
**--revision** — указатель на коммит; HEAD по умолчанию
|
||||||
|
|
||||||
**--order-by** — ключ сортировки результатов, один из `lines` (дефолт), `commits`, `files`.
|
**--order-by** — ключ сортировки результатов; один из `lines` (дефолт), `commits`, `files`.
|
||||||
|
|
||||||
По умолчанию результаты сортируются по убыванию ключа `(lines, commits, files)`.
|
По умолчанию результаты сортируются по убыванию ключа `(lines, commits, files)`.
|
||||||
При равенстве ключей выше будет автор с лексикографически меньшим именем.
|
При равенстве ключей выше будет автор с лексикографически меньшим именем.
|
||||||
|
@ -116,7 +116,7 @@ ferhat elmas,1,1,1
|
||||||
|
|
||||||
### Тесты
|
### Тесты
|
||||||
|
|
||||||
Команда для запуска тестов
|
Команда для запуска тестов:
|
||||||
```
|
```
|
||||||
go test -v ./gitfame/test/integration/...
|
go test -v ./gitfame/test/integration/...
|
||||||
```
|
```
|
||||||
|
@ -174,7 +174,7 @@ export PATH=$GOPATH/bin:$PATH
|
||||||
В cobra используется библиотека [pflag](https://pkg.go.dev/github.com/spf13/pflag) для работы с флагами.
|
В cobra используется библиотека [pflag](https://pkg.go.dev/github.com/spf13/pflag) для работы с флагами.
|
||||||
Библиотеку можно использовать и отдельно от cobra.
|
Библиотеку можно использовать и отдельно от cobra.
|
||||||
`pflag` может побольше, чем стандартный [flag](https://golang.org/pkg/flag/),
|
`pflag` может побольше, чем стандартный [flag](https://golang.org/pkg/flag/),
|
||||||
в частости, в `pflag` есть полезные для решаемой задачи флаги для работы с аргументами-массивами.
|
в частности, в `pflag` есть полезные для решаемой задачи флаги для работы с аргументами-массивами.
|
||||||
|
|
||||||
Помимо библиотеки, в cobra есть ещё и бинарь (с именем cobra) для кодогенерации основы проекта.
|
Помимо библиотеки, в cobra есть ещё и бинарь (с именем cobra) для кодогенерации основы проекта.
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
|
|
||||||
Обычные функции `json.Marshal` и `json.Unmarshal` работают с одним `json` объектом.
|
Обычные функции `json.Marshal` и `json.Unmarshal` работают с одним `json` объектом.
|
||||||
|
|
||||||
Иногда возникает ситуация, что вместо одного объекта, вам нужно передать последовательность объектов
|
Иногда возникает ситуация, что вместо одного объекта, вам нужно передать последовательность объектов,
|
||||||
разделённых пробельными символами. Например: `{"A": 1} {"B": 2} {"C": 3}`. Такую последовательность
|
разделённых пробельными символами. Например: `{"A": 1} {"B": 2} {"C": 3}`. Такую последовательность
|
||||||
можно прочитать используя `json.Decoder`, и можно записать используя `json.Encoder`.
|
можно прочитать используя `json.Decoder`, и можно записать используя `json.Encoder`.
|
||||||
|
|
||||||
Реализуйте функции `Marshal` и `Unmarshal`, которые работают со слайсом значений, и
|
Реализуйте функции `Marshal` и `Unmarshal`, которые работают со слайсом значений и
|
||||||
совершают подобное преобразование. По аналогии с пакетом `json`, функция `Marshal` принимает
|
совершают подобное преобразование. По аналогии с пакетом `json`, функция `Marshal` принимает
|
||||||
вторым аргументом слайс, а функция `Unmarshal` - указатель на слайс.
|
вторым аргументом слайс, а функция `Unmarshal` - указатель на слайс.
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
### Что нужно сделать?
|
### Что нужно сделать?
|
||||||
|
|
||||||
Нужно написать реализацию Once используя каналы.
|
Нужно написать реализацию Once, используя каналы.
|
||||||
|
|
||||||
Использование пакета [sync](https://golang.org/pkg/sync) в этой задаче запрещено!
|
Использование пакета [sync](https://golang.org/pkg/sync) в этой задаче запрещено!
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ func (l *Limiter) Stop()
|
||||||
После этого, пользователь вызывает `Acquire` из многих горутин. Некоторые из вызовов `Acquire` могут завершиться сразу,
|
После этого, пользователь вызывает `Acquire` из многих горутин. Некоторые из вызовов `Acquire` могут завершиться сразу,
|
||||||
а некоторые могут заблокироваться.
|
а некоторые могут заблокироваться.
|
||||||
|
|
||||||
`Limiter` должен гарантировать, что на любом интервале времени `interval`, не больше `maxCount` вызовов
|
`Limiter` должен гарантировать, что на любом интервале времени `interval` не больше `maxCount` вызовов
|
||||||
`Acquire` могут завершиться без ошибки. Например, если `interval` равен `1s`, `maxCount` равен 100,
|
`Acquire` могут завершиться без ошибки. Например, если `interval` равен `1s`, `maxCount` равен 100,
|
||||||
и 200 горутин сделали вызов `Acquire` одновременно, то 100 горутин должны выйти из `Acquire` сразу, а 100 других должны
|
и 200 горутин сделали вызов `Acquire` одновременно, то 100 горутин должны выйти из `Acquire` сразу, а 100 других должны
|
||||||
заблокироваться на секунду.
|
заблокироваться на секунду.
|
||||||
|
@ -25,4 +25,4 @@ func (l *Limiter) Stop()
|
||||||
во время ожидания. Об отмене `ctx` нужно узнавать по закрытию канала `ctx.Done()`. Если `ctx` отменён,
|
во время ожидания. Об отмене `ctx` нужно узнавать по закрытию канала `ctx.Done()`. Если `ctx` отменён,
|
||||||
нужно возвращать ошибку `ctx.Err()`.
|
нужно возвращать ошибку `ctx.Err()`.
|
||||||
|
|
||||||
Вызовы `Acquire()` после `Stop()`, должны сразу завершаться с ошибкой ErrStopped.
|
Вызовы `Acquire()` после `Stop()` должны сразу завершаться с ошибкой ErrStopped.
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
## rwmutex
|
## rwmutex
|
||||||
|
|
||||||
[sync.RWMutex](https://golang.org/pkg/sync/#RWMutex) -- это примитив синхронизации,
|
[sync.RWMutex](https://golang.org/pkg/sync/#RWMutex) -- это примитив синхронизации,
|
||||||
предоставляющий доступ к критической секции произвольному количеству читателей,
|
предоставляющий доступ к критической секции произвольному количеству читателей и
|
||||||
не более, чем одному писателю. При этом, если есть писатель, то читателей нет.
|
не более, чем одному писателю. При этом, если есть писатель, то читателей нет.
|
||||||
|
|
||||||
### Что нужно сделать?
|
### Что нужно сделать?
|
||||||
|
|
||||||
Нужно написать реализацию RWMutex используя каналы.
|
Нужно написать реализацию RWMutex, используя каналы.
|
||||||
|
|
||||||
Использование пакета [sync](https://golang.org/pkg/sync) в этой задаче запрещено!
|
Использование пакета [sync](https://golang.org/pkg/sync) в этой задаче запрещено!
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
### Что нужно сделать?
|
### Что нужно сделать?
|
||||||
|
|
||||||
Нужно написать реализацию WaitGroup используя каналы.
|
Нужно написать реализацию WaitGroup, используя каналы.
|
||||||
|
|
||||||
Использование пакета [sync](https://golang.org/pkg/sync) в этой задаче запрещено!
|
Использование пакета [sync](https://golang.org/pkg/sync) в этой задаче запрещено!
|
||||||
|
|
||||||
|
@ -26,4 +26,4 @@ func (wg *WaitGroup) Wait() {}
|
||||||
* Вызов `Wait` при числе большем нуля блокируется до тех пор, пока число не станет равным нулю.
|
* Вызов `Wait` при числе большем нуля блокируется до тех пор, пока число не станет равным нулю.
|
||||||
|
|
||||||
`WaitGroup` может быть "переиспользована".
|
`WaitGroup` может быть "переиспользована".
|
||||||
После достижения нуля можно вызвать `Add` заблокировав последующий `Wait`.
|
После достижения нуля можно вызвать `Add`, заблокировав последующий `Wait`.
|
||||||
|
|
|
@ -8,7 +8,7 @@ wscat принимает на вход единственный аргумент
|
||||||
После подключения программа начинает читать с stdin'а и отправлять пользовательские строки на сервер,
|
После подключения программа начинает читать с stdin'а и отправлять пользовательские строки на сервер,
|
||||||
печатая все сообщения от сервера в stdout.
|
печатая все сообщения от сервера в stdout.
|
||||||
|
|
||||||
Клиент должен обрабатывать SIGINT и SIGTERM и плавно завершаться с кодом 0 дожидаясь горутин.
|
Клиент должен обрабатывать SIGINT и SIGTERM и плавно завершаться с кодом 0, дожидаясь горутин.
|
||||||
Для этого может пригодиться [context](https://golang.org/pkg/context/).
|
Для этого может пригодиться [context](https://golang.org/pkg/context/).
|
||||||
|
|
||||||
Обратите внимание на то, что exit code `go run` - это не exit code исполняемого файла.
|
Обратите внимание на то, что exit code `go run` - это не exit code исполняемого файла.
|
||||||
|
|
Loading…
Reference in a new issue