Зацените тестовое задание
От: Kaifa Россия  
Дата: 28.09.18 14:11
Оценка: 4 (2) +2 :)
Т.к. принципиально тематика не моя (уж не знаю чего они там узрели в моем резюме, т.к. писал им не я), и кроме того просьбы не распространять не было, цитирую задание, которое даже не пытался решать. может кому-то будет полезно. контора United Traders

Вопрос 1.
Ваш друг детства Егор, всерьез занявшийся фермерским хозяйством, попросил Вас разработать сервис, который будет круглосуточно отслеживать изменения цен на капусту, продающуюся на Брюссельской Капустной Бирже. Также его интересуют цены на перец, который продают на Бирже Перца Болгарии.
Вы решили подключиться к обеим биржам по API, которые они предоставляют. Обе дают возможность подключаться как по HTTP REST, так и через веб-сокеты.
Сервис должен позволять складывать в базу данных информацию о ценах на продукты и историю изменения цен, а также давать возможность в любой момент просматривать текущие цены, не замедляя при этом сохранение новых цен.
Помните, что рынки капусты и перца — высоковолатильные, а значит цены на них меняются по 50-100 раз за секунду, а иногда и чаще.

Опишите в нескольких предложениях как бы Вы реализовали бэкенд такого сервиса?

Вопрос 2.
Егору очень понравился Ваш сервис мониторинга цен капусты и перца. Теперь он подумывает о том, чтобы собранная информация применялась бы и в другом его сервисе, который Вы делали ему в прошлом году — "Бухгалтерия Фермера".
В "Бухгалтерии Фермера" при каждом изменении цены на капусту или перец должны автоматически пересчитываться показатели доходности фермерского хозяйства.
Также Егор упомянул, что если все будет хорошо, то такие данных о ценах неплохо было бы в будущем передавать еще и в Мобильное приложение, которое Вы ему, как он надеется, сделаете. Но это в будущем, сейчас такую передачу делать ему не надо.

Опишите в нескольких предложениях, как бы Вы передавали собранную информацию из сервиса мониторинга цен в сервис "Бухгалтерия Фермера"?

Вопрос 3.
Оба Ваших новых сервиса очень понравились Егору. Но через некоторое время он пришел к Вам с новой проблемой. Егор точно помнит, что у него был покупатель Евгений, на вид лет 30-35, который купил у него по интернету очень много капустных пирожков, то ли с выставлением счета, то ли нет.
Егор сам пытался достать нужную ему информацию из сервиса "Бухгалтерия Фермера", и даже написал для этого SQL-запрос к PostgreSQL базе данных, но что-то не работает:

SELECT * FROM customers
JOIN payments ON payments.customer_id = customers.id
JOIN invoices ON invoices.customer_id = customers.id
WHERE customers.first_name LIKE 'Евгений' AND customers.birthdate >= DATE('1985-08-02')

Запрос не выдает совсем ничего.

В чем может быть дело?

Вопрос 4.
Вам надоело делать программы для фермы Егора, и Вы устроились на новую работу. Вам показывают исходный код проекта, с которым предстоит работать.
Среди прочего в исходниках есть следующий менеджер команд. Этот класс вроде бы потокобезопасен и работает, исполняя в специальном потоке те команды, что поставлены в очередь методом Enqueue.
Вам не понравился увиденный код. Опишите какие проблемы в классе Вы видите?

public class TasksManager
{
    private readonly Queue<Command> _commandQueue = new Queue<Command>();
    private readonly AutoResetEvent _newCommandArrivalEvent = new AutoResetEvent(false);
    private readonly Thread _commandRunningThread;
    private readonly Logger _logger;

    public TasksManager()
    {
        _logger = ServicesContainer.GetLogger();
    }

    public void Start()
    {
        _commandRunningThread = new Thread(ProcessCommands);
        _commandRunningThread.Start();
    }

    private void ProcessCommands()
    {
        while (true)
        {
            _newCommandArrivalEvent.WaitOne();
            lock (_commandQueue)
            {
                Command command = _commandQueue.Dequeue();
                command.Execute();
            }
        }
    }

    public void Enqueue(Command command)
    {
        lock (_commandQueue)
        {
            _commandQueue.Enqueue(command);
            _logger.Debug("Command enqueued");
        }
        _newCommandArrivalEvent.Set();
    }
}

Re: Зацените тестовое задание
От: RushDevion Россия  
Дата: 28.09.18 15:56
Оценка: 2 (2) +12
Мне понравилось.
Вопросы по делу (проектирование, многопоточность, SQL) и поданы нескучно.
Всяко лучше, чем гонять гномиков по спецификации языка и внутренностям CLR.
Re: Зацените тестовое задание
От: namespace  
Дата: 30.09.18 10:05
Оценка:
K>Т.к. принципиально тематика не моя (уж не знаю чего они там узрели в моем резюме, т.к. писал им не я), и кроме того просьбы не распространять не было, цитирую задание, которое даже не пытался решать. может кому-то будет полезно. контора United Traders
В целом все задания выдают уровень требований к соискателю, скажем так, он не очень высок. Характеризует разработчиков в команде, или задачи.

Первые два вообще нет смысла думать о реализации без обсуждения деталей. Я слишком ленив, чтобы переделывать свою же работу.
Re: Зацените тестовое задание
От: Sharowarsheg  
Дата: 30.09.18 10:17
Оценка:
Здравствуйте, Kaifa, Вы писали:

Не знаю ничего про буряки и вот это всё, но класс не потокобезопасный.
Re: Зацените тестовое задание
От: white_znake  
Дата: 01.10.18 14:08
Оценка:
Здравствуйте, Kaifa, Вы писали:

K>Т.к. принципиально тематика не моя (уж не знаю чего они там узрели в моем резюме, т.к. писал им не я), и кроме того просьбы не распространять не было, цитирую задание, которое даже не пытался решать. может кому-то будет полезно. контора United Traders


а по двум первым пунктам задания ни кто не просит реализовать, просят рассказать как будешь делать.
Так что нормальные вопросы.
Re: Зацените тестовое задание
От: AlexGin Беларусь  
Дата: 01.10.18 18:31
Оценка:
Здравствуйте, Kaifa, Вы писали:

K>Помните, что рынки капусты и перца — высоковолатильные, а значит цены на них меняются по 50-100 раз за секунду, а иногда и чаще.


Аффтор этого задания видимо что-то сильное курит
Re[2]: Зацените тестовое задание
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 01.10.18 18:38
Оценка:
Здравствуйте, AlexGin, Вы писали:

K>>Помните, что рынки капусты и перца — высоковолатильные, а значит цены на них меняются по 50-100 раз за секунду, а иногда и чаще.


AG>Аффтор этого задания видимо что-то сильное курит


HFT?
Маньяк Робокряк колесит по городу
Re[2]: Зацените тестовое задание
От: Max Mustermann  
Дата: 02.10.18 08:40
Оценка: +1
Здравствуйте, Sharowarsheg, Вы писали:

S>Не знаю ничего про буряки и вот это всё, но класс не потокобезопасный.

Наоборот, он супербезопасный. В "очереди" всегда не больше одной команды, а что-бы добавить следующую надо дождаться окончания работы предыдущей.
Re[3]: Зацените тестовое задание
От: RushDevion Россия  
Дата: 02.10.18 09:07
Оценка:
S>>Не знаю ничего про буряки и вот это всё, но класс не потокобезопасный.
MM>Наоборот, он супербезопасный. В "очереди" всегда не больше одной команды, а что-бы добавить следующую надо дождаться окончания работы предыдущей.

Вообще-то нет. При определенных условиях задачи будут копиться в очереди.
Re[3]: Зацените тестовое задание
От: Sharowarsheg  
Дата: 02.10.18 09:35
Оценка:
Здравствуйте, Max Mustermann, Вы писали:

MM>Здравствуйте, Sharowarsheg, Вы писали:


S>>Не знаю ничего про буряки и вот это всё, но класс не потокобезопасный.

MM>Наоборот, он супербезопасный. В "очереди" всегда не больше одной команды, а что-бы добавить следующую надо дождаться окончания работы предыдущей.

хернаны

private void ProcessCommands()
    {
        while (true)
        {
            _newCommandArrivalEvent.WaitOne();

ВОТ ЗДЕСЬ
если в этот момент успеть вызвать ещё одно Enqueue, то в очереди будет два запроса, а считается только один

            lock (_commandQueue)
            {

чтобы исправить, надо делать тут цикл и читать все запросы, пока очередь не кончится

                Command command = _commandQueue.Dequeue();
                command.Execute();
            }
        }
    }

    public void Enqueue(Command command)
    {
        lock (_commandQueue)
        {
            _commandQueue.Enqueue(command);
            _logger.Debug("Command enqueued");
        }

И ВОТ ЗДЕСЬ
такой же косяк, можно успеть вызвать еще одно Enqueue и поставить второй запрос в очередь

        _newCommandArrivalEvent.Set();

И, кстати, здесь тоже самое. нет гарантии, что поток-исполнитель проснётся немедленно
    }
Отредактировано 02.10.2018 9:41 Sharowarsheg . Предыдущая версия . Еще …
Отредактировано 02.10.2018 9:36 Sharowarsheg . Предыдущая версия .
Re[3]: Зацените тестовое задание
От: _Artem_ Россия  
Дата: 02.10.18 09:37
Оценка: +1
Здравствуйте, Max Mustermann, Вы писали:

MM>Наоборот, он супербезопасный. В "очереди" всегда не больше одной команды, а что-бы добавить следующую надо дождаться окончания работы предыдущей.


Ну вообще-то там может быть больше одной команды. Но тогда будет проблема, что может оставаться хвост необработанных команд. Если Enqueue успеет отработать, например, 2 раза до начала выгребания очереди, то ProcessCommands заберет из очереди только одну задачу. А вторая будет висеть и ждать _newCommandArrivalEvent.
Re[4]: Зацените тестовое задание
От: andrey.desman  
Дата: 02.10.18 10:07
Оценка:
Здравствуйте, Sharowarsheg, Вы писали:

S>ВОТ ЗДЕСЬ
S>если в этот момент успеть вызвать ещё одно Enqueue, то в очереди будет два запроса, а считается только один

S>            lock (_commandQueue)
S>            {

S>чтобы исправить, надо делать тут цикл и читать все запросы, пока очередь не кончится

S>                Command command = _commandQueue.Dequeue();
S>                command.Execute();
S>            }
S>        }
S>    }
S>


Тут еще сильный косяк в том, что Execute() вызывается под локом, что частично сводит на нет смысл отдельного треда. Если туда еще и цикл захреначить, то вообще все плохо станет.

Обычно делают так:
Queue tmp_queue;
lock();
queue.swap(tmp_queue);
unlock();
foreach(q: tmp_queue) q.Execute();


Ну или релок на каждый проход, если нужна возможность отмены таски.
Re[5]: Зацените тестовое задание
От: Sharowarsheg  
Дата: 02.10.18 13:32
Оценка:
Здравствуйте, andrey.desman, Вы писали:

AD>
S>>ВОТ ЗДЕСЬ
S>>если в этот момент успеть вызвать ещё одно Enqueue, то в очереди будет два запроса, а считается только один

S>>            lock (_commandQueue)
S>>            {

S>>чтобы исправить, надо делать тут цикл и читать все запросы, пока очередь не кончится

S>>                Command command = _commandQueue.Dequeue();
S>>                command.Execute();
S>>            }
S>>        }
S>>    }
S>>


AD>Тут еще сильный косяк в том, что Execute() вызывается под локом, что частично сводит на нет смысл отдельного треда. Если туда еще и цикл захреначить, то вообще все плохо станет.


Я бы сказал, что это менее сильный косяк. Медленно и правильно всё же лучше, чем неправильно.
Re: Зацените тестовое задание
От: Sharov Россия  
Дата: 02.10.18 13:55
Оценка:
Здравствуйте, Kaifa, Вы писали:



K>Вопрос 4.

K>Вам надоело делать программы для фермы Егора, и Вы устроились на новую работу. Вам показывают исходный код проекта, с которым предстоит работать.
K>Среди прочего в исходниках есть следующий менеджер команд. Этот класс вроде бы потокобезопасен и работает, исполняя в специальном потоке те команды, что поставлены в очередь методом Enqueue.
K>Вам не понравился увиденный код. Опишите какие проблемы в классе Вы видите?

K>
K>public class TasksManager
K>{
K>    private readonly Queue<Command> _commandQueue = new Queue<Command>();
K>    private readonly AutoResetEvent _newCommandArrivalEvent = new AutoResetEvent(false);
K>    private readonly Thread _commandRunningThread;
K>    private readonly Logger _logger;

K>    public TasksManager()
K>    {
K>        _logger = ServicesContainer.GetLogger();
K>    }

K>    public void Start()
K>    {
K>        _commandRunningThread = new Thread(ProcessCommands);
K>        _commandRunningThread.Start();
K>    }

K>    private void ProcessCommands()
K>    {
K>        while (true)
K>        {
K>            _newCommandArrivalEvent.WaitOne();
K>            lock (_commandQueue)
K>            {
K>                Command command = _commandQueue.Dequeue();
K>                command.Execute();
K>            }
K>        }
K>    }

K>    public void Enqueue(Command command)
K>    {
K>        lock (_commandQueue)
K>        {
K>            _commandQueue.Enqueue(command);
K>            _logger.Debug("Command enqueued");
K>        }
K>        _newCommandArrivalEvent.Set();
K>    }
K>}
K>

K>[/q]

1) Нету dispose, в то время как AutoResetEvent diposable;
2) Если есть api для запука потока, должно быть и для остановки;
3) Смысли городить огород с очердью и синхронизацией, когда есть уже изкаропки BlockingQueue?
Кодом людям нужно помогать!
Re[2]: Зацените тестовое задание
От: StatujaLeha на правах ИМХО
Дата: 03.10.18 09:46
Оценка: +1 :)
Здравствуйте, Sharov, Вы писали:

S>1) Нету dispose, в то время как AutoResetEvent diposable;

S>2) Если есть api для запука потока, должно быть и для остановки;
S>3) Смысли городить огород с очердью и синхронизацией, когда есть уже изкаропки BlockingQueue?

4) Нет защиты на случай повторного вызова Start()

PS Это такой провокационный способ найма. Сотрудник компании создает тему и кидает ТЗ в стиле "я просто разместил". А в это время hr из UT мониторят тему и понравившимся кандидатам спамят личку
Re[2]: Зацените тестовое задание
От: Философ Ад http://vk.com/id10256428
Дата: 03.10.18 12:13
Оценка:
Здравствуйте, Sharov, Вы писали:

) Нету dispose, в то время как AutoResetEvent diposable;
S>2) Если есть api для запука потока, должно быть и для остановки;
S>3) Смысли городить огород с очердью и синхронизацией, когда есть уже изкаропки BlockingQueue?

Маловато ты увидел. Смотри ещё: код проблемный. Я бы начала с описания проблем, а не недостатков решения. BlockingCollection<T> а так же BlockingQueue ConcurrentQueue<T> появилась далеко не сразу, и во многих проектах свои велосипеды на эту тему, к тому же оно не всё что нужно реализует.
Всё сказанное выше — личное мнение, если не указано обратное.
Re: Зацените тестовое задание
От: Философ Ад http://vk.com/id10256428
Дата: 03.10.18 12:17
Оценка: +2
Здравствуйте, Kaifa, Вы писали:

K>Вопрос 4.

K>Вам надоело делать программы для фермы Егора, и Вы устроились на новую работу. Вам показывают исходный код проекта, с которым предстоит работать.
K>Среди прочего в исходниках есть следующий менеджер команд. Этот класс вроде бы потокобезопасен и работает, исполняя в специальном потоке те команды, что поставлены в очередь методом Enqueue.
K>Вам не понравился увиденный код. Опишите какие проблемы в классе Вы видите?

K>
K>public class TasksManager {} //...
K>

K>[/q]

Отлично!!!!
Прекрасный вопрос для того чтобы понять, может ли человек в многопоток или нет. Тут во время обсуждения можно столько нюансов выудить, что ты об опыте и возможностях человека будешь знать всё.
Очень понравился вопрос.
Всё сказанное выше — личное мнение, если не указано обратное.
Re[3]: Зацените тестовое задание
От: Sharov Россия  
Дата: 03.10.18 12:55
Оценка:
Здравствуйте, Философ, Вы писали:

Ф>Маловато ты увидел. Смотри ещё: код проблемный. Я бы начала с описания проблем, а не недостатков решения. BlockingCollection<T> а так же BlockingQueue ConcurrentQueue<T> появилась далеко не сразу, и во многих проектах свои велосипеды на эту тему, к тому же оно не всё что нужно реализует.


Я не включал уже вышеупомянутые замечаниее с возможными rc.
Кодом людям нужно помогать!
Re[6]: Зацените тестовое задание
От: Тёмчик Австралия жж
Дата: 04.10.18 02:06
Оценка: 2 (1) +1
Здравствуйте, Sharowarsheg, Вы писали:

AD>>
S>>>ВОТ ЗДЕСЬ
S>>>если в этот момент успеть вызвать ещё одно Enqueue, то в очереди будет два запроса, а считается только один

S>>>            lock (_commandQueue)
S>>>            {

S>>>чтобы исправить, надо делать тут цикл и читать все запросы, пока очередь не кончится

S>>>                Command command = _commandQueue.Dequeue();
S>>>                command.Execute();
S>>>            }
S>>>        }
S>>>    }
S>>>


AD>>Тут еще сильный косяк в том, что Execute() вызывается под локом, что частично сводит на нет смысл отдельного треда. Если туда еще и цикл захреначить, то вообще все плохо станет.


S>Я бы сказал, что это менее сильный косяк. Медленно и правильно всё же лучше, чем неправильно.


Оно затупит и упадёт от нехватки памяти. Явная течь в очереди команд, неявная- может быть у вызывающего кода. Например, если вызывающий код имеет собственную очередь или вызовы идут от потоков из менеджера потоков- он можен наплодить новых worker-в.
Ещё слона то не заметил. Если Execute порождает новые команды в очередь- то deadlock.
Отредактировано 04.10.2018 2:43 Артём . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.