Skip to content

pavelakafoks/MetaQuotes-test-task

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MetaQuotes-test-task

MetaQuotes test task - .Net Developer position

It is a Russian company thats why the task in Russian.

Тестовое задание на позицию разработчика .NET

Задача:

Разработать веб-приложение для получения координат пользователя по его IP-адресу и получения списка местоположений по названию города.

Средства разработки:

  1. C#, ASP.NET MVC 4 или 5 версии
  2. MS Visual Studio
  3. HTML5, CSS3, JavaScript
  4. Без использования СУБД

Требование к архитектуре и исходному коду:

  1. Веб-приложение должно быть спроектировано и разработано с расчетом на 10 000 000 уникальных пользователей в день и от 100 000 000 запросов в день.
  2. Клиентская часть должна быть выполнена в виде Single Page Application
  3. Исходный код должен быть оформлен в едином стиле и содержать необходимые комментарии.
  4. Аккуратность исходного кода будет оцениваться наряду с функциональностью приложения.
  5. Для клиентского кода нет требований по минимально поддерживаемой версии браузера. Можно использовать возможности последних версий браузеров (Chrome, Firefox, IE11, Edge).

Техническое описание приложения

  • База данных хранится в файле geobase.dat, которые содержится в прикрепленном к письму архиве.

  • База данных не будет изменятся она предназначена только для чтения.

  • База данных имеет бинарный формат. В файле последовательно хранятся:

  • 60 байт - заголовок int version; // версия база данных sbyte name[32]; // название/префикс для базы данных ulong timestamp; // время создания базы данных int records; // общее количество записей uint offset_ranges; // смещение относительно начала файла до начала списка записей с геоинформацией uint offset_cities; // смещение относительно начала файла до начала индекса с сортировкой по названию городов uint offset_locations; // смещение относительно начала файла до начала списка записей о местоположении 12 байт - Header.records (количество записей) - cписок записей с информацией об интервалах IP адресов, отсортированный по полям ip_from и ip_to

      uint ip_from;           // начало диапазона IP адресов
      uint ip_to;             // конец диапазона IP адресов
      uint location_index;     // индекс записи о местоположении
    
  • 96 байт - Header.records (количество записей) - cписок записей с информацией о местоположении с координатами (долгота и широта)

       sbyte country[8];        // название страны (случайная строка с префиксом "cou_")
       sbyte region[12];        // название области (случайная строка с префиксом "reg_")
       sbyte postal[12];        // почтовый индекс (случайная строка с префиксом "pos_")
       sbyte city[24];          // название города (случайная строка с префиксом "cit_")
       sbyte organization[32];  // название организации (случайная строка с префиксом "org_")
       float latitude;          // широта
       float longitude;         // долгота
    
  • 4 байта * Header.records (количество записей) - список индексов записей местоположения отсортированный по названию города*

  • База данных грузится полностью в память при старте приложения.

  • Время загрузки базы в память должно быть не более 200 мс (для информации: есть решение, которое позволяет загрузить базу в память быстрее 30 мс).

  • Необходимо реализовать быстрый поиск по загруженной базе по IP адресу и по точному совпадению названия города с учетом регистра.

  • В приложении должны быть реализованы два метода HTTP API:

    • GET /ip/location?ip=123.234.432.321
    • GET /city/locations?city=cit_Gbqw4 ответ сервера на каждый из запросов должен быть представлен в формате JSON.
  • Клиентская часть приложения должны быть выполнена в идеологии Single Page Application.

  • Страница должна состоять из двух частей: в левой части меню переключения экранов, в правой части отображается выбранный экран.

  • Клиентская часть должна реализовать два экрана: поиск гео-информации по IP, поиск списка местоположений по названию города.

  • Экран поиска гео-информации содержит: поле для ввода IP адреса, кнопку "Искать" и область для вывода результата.

  • По нажатию кнопки "Искать" на сервер отправляется запрос GET /ip/location?ip=123.234.432.321 Обработанный ответ от сервера выводится в область вывода результатов.

  • Экран поиска списка метоположений содержит: поле для ввода названия города, кнопку "Искать" и область для вывода результата. По нажатию кнопки "Искать" на сервер отправляется запрос GET /city/locations?city=cit_Gbqw4 Обработанный ответ от сервера выводится в область вывода результатов.

Дополнительно

  • Проявление инициативы сверх основного задания приветствуется.

Пояснительная записка к заданию:

Её же можно найти на странице About.

Реализована работа в трёх режимах:

  1. Dirrect - прямой доступ к памяти. Работа на уровне байтов и арифметикой позиционирования. Плюсы:
  • Практически мгновенная готовность к работе. 5мс. на подготовку к работе
  • Масштабируемость Минусы:
  • Сложность поддержки
  • Уступает при поиске в скорости Marshal режиму

Примечания: Описание размерности полей вынесено как CustomAttribute, что позволяет динамически менять размер полей, все сдвиги пересчитаются автоматически. Размерность можно получить и из простых типов (кроме stirng), но лучше везде использовать один подход для однообразия.

  1. Marshal - маршаллинг всей структуры при загрузке. **Плюсы: **
  • Простая поддержка
  • Лучшая скороть работы при поиске Минусы
  • Проигрывает в скорости подготовки к работе - 45 мс
  • Плохая масштабируемость
  1. Сombined - смешанный режим. Попытка взять лучшее от обоих методов и выжать выше скорость. Плюсы:
  • Выигрывает в скорости на некоторых тестах у Dirrect
  • Проще в поддержке, чем Dirrect способ
  • Высокая скорость подготовки к работе (инициализация) Минусы:
  • Проигрывает на мультипоточных тестах двум другим методам

Переключение режимов в настроечном файле "appsettings.json".

Скорость на мультипоточном тесте: Поиск по IP адресу: 1000 потоков x 6 запросов

  • Dirrect : 2 мс.

  • Marshal : 0.5 мс.

  • Combined: 3 мс.

    Поиск по городу: 1000 потоков x 8 запросов

  • Dirrect : 122 мс.

  • Marshal : 46 мс.

  • Combined: 266 мс

При многопоточном режиме выигрывает в скорости тип Marshal, но тратит больше времени на загрузку Combined - выигрывает на некоторых тестах, но в целом проигрывает. Dirrect - загружается в 9 раз быстрее, чем Marshal (5 мс. против 45 мс), проще масштабируется, но поиск медленнее.

Реализованы тесты в отдельном проекте:

  • Performance: анализ различных подходов для одной и той же задачи
  • На правильность работы процедур поиска по IP и по городу
  • Работа в многопоточном режиме

Замечания, допущения:

  • В задание забыли добавить структуру индексов городов (но может это тоже часть задания на находчивость).
  • Большую задержку вносит вывод в режиме Debug. При тестах нужно переключиться в режиме Release.
  • Во многих городах на конце стоит пробел. Нужно их вводить также с пробелом (обрезка строк не производится). Согласно заданию - должны совпадать все символы. Например, город "cit_A " должен так и передаваться - с пробелом на конце.
  • Не фронтенде было испольвание по минимуму: только JQuery для удобства работы с DOM и Bootstrap для красоты.
  • Инициализация объекта в веб приложении в виде dependence injection от mvc core, singleton. Проверка производительности DI, сравнение со static, и другими библитеками DI - не проводилась.
  • Немногочисленные комментарии на английском языке. Убеждёт, что хороший код должен быть самодокументируемым.
  • WebApi находится в веб приложении. В реальном приложении имеет смысл подумать о выносе API в виде отдельного приложения/проекта
  • Перевод ip в int есть две реализации с разным порядком байтов, проверял по следующим сервисам: https://www.browserling.com/tools/dec-to-ip http://www.smartconversion.com/unit_conversion/IP_Address_Converter.aspx http://www.silisoftware.com/tools/ipconverter.php Если нужно в другом порядке, то нужно раскомментировать строки в IpHelper.cs Мой ответ по теме: https://stackoverflow.com/questions/36831/how-do-you-parse-an-ip-address-string-to-a-uint-value-in-c

About

MetaQuotes test task - .Net Developer position

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published