Про тестовое задание

16.07.2024, 13:15

В данный момент я активно ищу работу и часто прохожу различные этапы собеседований. Для проверки знаний мои потенциальные работодатели чаще всего организовывают техническое интервью. Примерно месяц назад мне предложили сделать тестовое задание. Я согласился и с удивлением обнаружил что делать тестовое мне понравилось больше, просто потому что это похоже на мою ежедневную рутину, а вот техническое интервью штука довольно необычная и на мой взгляд больше проверяет то как я подготовился к собеседованию, а не навыки реальной работы. Хотя я понимаю минусы задания и то, почему все выбирают интервью. Стараюсь лучше готовится к таким встречам.

О своем негативном опыте тех. интервью я уже рассказывал на просторах LinkedIn. Cегодня решил описать само тестовое задание и мое решение для него.

Условия тестового задания

После того как я согласился на тестовое, мне прислали небольшое ТЗ в Notion. Необходимо разработать приложение с графиком и фильтрами. Данные для построения предоставлены в файлах, формата CSV. Всего файлов два:

usages.csv, который содержал в себе множество строк следующей структуры:


export type Usag = {
  type: string;
  model: string;
  created_at: string;
  usage_input: number;
  usage_output: number;
};

costs.csv с несколькими строками следующей структуры:


export type Cost = {
  model: string;
  input: number;
  output: number;
};

Основное значения, по которому необходимо строить график, нужно рассчитывать по формуле: model cost of input usage _ usage_input + model cost of output usage _ usage_output.

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

Реализация

Для самого приложения я выбрал:

  • Next.js потому что он дает более широкий функционал в сравнении с React и привычен для меня, 
  • Recharts для построения графиков, 
  • csvtojson для обработки файлов CSV.

После того как приложение было развернуто, а все зависимости установлены, я написал простенький скрипт, который парсил CSV в массивы объектов, типов, описанных выше. И скормил его в recharts. На выходе получился совершенно нечитаемый график, который, кроме прочего, еще и значительно нагружал систему. Стало интереснее. Пошел изучать данные и довольно быстро заметил что в файле с юсаджами 100 000 строк, большинство из которых дублируют друг друга. Для каждого уникального сочетания свойств type и model за каждую приведенную дату, в файле находилось от 50 до 80 юсаджей. По сути можно было превратить каждый набор дублей в один объект той же структуры, тем самым значительно сократить нагрузку, создаваемую при попытке построить график без предварительной обработки.

Я прошелся по массиву в reduce и собрал примерно 1 500 уникальных объектов, содержащих в себе комбинацию свойств за каждый день и сумму всех значений по полям usage_input и usage_output. Скормил в resharts и получил график получше. С этим уже можно работать.

На сцену вышел перфоманс, который я сам сделал главным показателем. Проход по изначальному массиву и группировка данных от 100 000 до 1 500 объектов занимал примерно 3 секунды, что потенциально делало сервис очень медленным. 3 секунды само по себе много, а тут еще в зависимости от примененных фильтров нужно было дополнительно обрабатывать результирующий массив для построения графика.

На помощь пришёл Next.js. Я поместил первичную обработку в серверный слой приложения и настроил передачу данных из API ручки внутри приложения. На клиенте за получения данных отвечал fetch, который в Next, начиная с 14 версии, кеширует ответ под капотом, по аналогии с react query.

Таким образом, я получил поведение в котором первичная обработка данных происходит один раз при холодном старте приложения, а в дальнейшем fetch в среднем за 200мс возвращает кешированный массив в 1,5 тыс строк. В боевом проекте дополнительно нужно настроить время жизни кеша и серверные экшены для принудительного обновления. В данном случае этого не требовалось.

Дальнейшая реализация оказалась делом техники. Логику обработки данных графика я разместил на клиенте. Скрипт считает показатель по формуле из ТЗ и ориентируется на данные фильтров, которые приходят из get параметров URL. Каждое нажатие фильтра инициирует перезагрузку, которая пересчитывает график. Получилось быстрое приложение.

Из минусов recharts оказался плохо совместим с SSR в Next и я сделал его динамическим. А еще график довольно плохо подчинялся свойствам CSS и для построения сетки я написал кастомный хук с небольшой задержкой получающий размеры окна при его изменении и высчитывающий размеры блока с графиком. Что бы хорошо работало, когда меняешь размер окна в браузере или переворачиваешь устройство.

Я не стал уделять большого внимания стилизации проекта. Организовал стабильную сетку и сделал базовую мобильную адаптацию. Результат выложил на GitHub и  отдал рекрутеру, довольно быстро получив ответ с приглашением на следующий этап подбора.

Финал истории

Дальнейшая часть истории про то, как отсутствие нужной информации вышло мне боком. Я был настолько уверен, что нанимающего менеджера впечатлит моя реализация проекта, что практически не готовился к возможному техническому интервью. Думал, что на звонке, мы будем обсуждать тестовое задание и даже мысленно подготовил список того, что я мог бы улучшить в собственной реализации проекта. В реальности похоже на то, что нанимающий менеджер практически не изучал особенности моей реализации проекта. Мы не говорили про тестовое, это было техническое собеседование и я не очень хорошо отвечал на некоторые вопросы, потому что не готовился к ним.

Кроме того, одним из недостатков проекта оказалось отсутствие стилизации фильтров. Если бы я заранее узнал по каким критериям работодатель будет оценивать проект, то для стилизации выбрал бы Ant Design потому что уже имею хороший опыт работы с ним. И попал бы в яблочко, потому что он используется на проекте, в который меня собеседовали. 

chart

В итоге я не получил работу, но приобрел опыт и теперь стараюсь максимально уточнять требования и критерии оценки. Не только в тестовом задании, но и в рабочих проектах, которыми занимаюсь. Очень важно уметь уточнить требования бизнеса и сделать так как он хочет.

Спасибо, что дочитали до конца☺️. Всем добра!