Подсчет количества строк "Go" в текстовом источнике
Условие задачи
Процессу на stdin приходят строки, содержащие URL или названия файлов.
Каждый такой URL нужно запросить, каждый файл нужно прочитать,
и посчитать кол-во вхождений строки "Go" в ответе. В конце работы
приложение выводит на экран общее кол-во найденных строк "Go" во всех
источниках данных, например:
$ echo -e 'https://golang.org\n/etc/passwd\nhttps://golang.org\nhttps://golan g.org' | go run 1.go
Count for https://golang.org: 9
Count for /etc/passwd: 0
Count for https://golang.org: 9
Count for https://golang.org: 9
Total: 27
Каждый источник данных должен начать обрабатываться сразу после
вычитывания и параллельно с вычитыванием следующего. Источники
должны обрабатываться параллельно,но не более k=5 одновременно.
Обработчики данных не должны порождать лишних горутин, т.е.
если k=1000, а обрабатываемых источников нет, не должно создаваться
1000 горутин. Нужно обойтись без глобальных переменных и
использовать только стандартные библиотеки.
Описание решения
Вычитывание источников данных из stdin происходит в главной горутине.
Пусть n - общее количество источников данных.
Для каждого источника запускается своя горутина обработки. Чтобы
ограничить количество создаваемых горутин, воспользуемся буферизованным
каналом, емкость которого равна k. Перед созданием горутины в
канал помещается флаг, когда горутина завершается, она считывает флаг из
канала. Вычитывание источников данных происходит быстрее, чем их
обработка, поэтому через некоторое время канал будет целиком заполнен
флагами, и вычитывание источников приостановится. Как только горутина
обработки завершится и уберет один флаг из канала, вычитывание
возобновится. Таким образом, одновременно обрабатываются только k
источников. Если количество источников меньше емкости канала k,
то это не приведет к созданию дополнительных k - n горутин
обработки и блокировке главной горутины.
По условию задачи у нас 2 типа источников данных:
- файлы на диске
- страницы Интернет
Унифицируем представление источников с помощью стандартного интерфейса
io.ReadCloser
Поиск количества вхождений строки "Go" в тексте выполним
с помощью регулярного выражения. Общее значение счетчика будем
увеличивать посредством атомарной операции.
Установка и запуск программы
Программа может быть установлена с помощью команды
$ go get -u github.com/ahamtat/go-interview/test/gowordcounter
После запуска программа ожидает ввода с клавиатуры источника данных.
Нажатие клавиши Enter запускает обработку источника. Нажатие
комбинации клавиш Ctrl+D корректно завершает программу.
Также приложение поддерживает Linux pipes и может быть запущено
следующим образом:
$ echo -e 'https://golang.org\n/etc/passwd\nhttps://golang.org\nhttps://golang.org' | gowordcounter
2020/06/28 15:48:00 Count for /etc/passwd: 0
2020/06/28 15:48:01 Count for https://golang.org: 14
2020/06/28 15:48:01 Count for https://golang.org: 14
2020/06/28 15:48:01 Count for https://golang.org: 14
2020/06/28 15:48:01 Total: 42
Фидбек от Mail.ru
Плюсы:
- понятный и оформленный ридми в репозитории
- код читаемый и понятный
- понятное разбиение на функции
- использует стандартную библиотеку
- есть комментарии
- есть тесты
Минусы: