Показаны сообщения с ярлыком программирование. Показать все сообщения
Показаны сообщения с ярлыком программирование. Показать все сообщения

воскресенье, 20 декабря 2020 г.

Сравнение флотов (чисел с плавающей точкой) в NUnit

0.9999999999
vs
1.0000000001
У чисел с плавающей запятой (float, double) есть такая особенность, что из-за проблем потери точности, они могут получаться не равными, даже если должны быть такими с точки зрения математики. И это зависит не только от используемых операций, но и от архитектуры железа, а также флагов процессора, установленных в момент вычислений.
Например, 72/6 может быть не равно 3*4.
Но сравнивать их все равно нужно. Поэтому используется сравнение с определенной точностью. Берется модуль (абсолютное значение) разности этих чисел и сравнивается с небольшой константой. Если модуль разницы больше этой константы, числа считаются разными.
В библиотеке NUnit для таких сравнений есть специальные конструкции
Вместо велосипедов
Assert.IsTrue(Mathf.Abs(actualValue - expectedValue) < tolerance);
и
Assert.Less(Mathf.Abs(actualValue - expectedValue), tolerance);
В NUnit есть
Assert.AreEqual(expectedValue, actualValue, tolerance); 

пятница, 2 июня 2017 г.

Олимпиадное vs Промышленное программирование

Задачи

Если в промышленном программировании нужно реализовывать новый функционал (фичи), то в олимпиадном - составить корректную в пределах тестовых данных и сценариев программу, уложившись в ограничения по памяти и времени исполнения.


Время

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

Код

В промышленном программировании код пишется для дальнейшего сопровождения (то есть многократного чтения для расширения и правок). Он должен быть гибким, расширяемым. И самое главное - хорошо читаемым.
В олимпиадном программировании код пишется на один раз (write-only). Никто не собирается его в дальнейшем вычитывать, расширять или править баги.

Навыки

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

Выводы

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

четверг, 26 января 2017 г.

Идеальное тестовое задание для программиста

This is not fine

Типичное тестовое задание для программиста обычно предлагает в одиночку написать небольшую программу, реализующую какой-нибудь известный алгоритм или сложную структуру данных.
То есть, по-сути, сделать то, что реальные программисты в своей работе не делают:

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

Но кто же пишет такие программы, и, следовательно, хорошо справится с таким заданием?

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

Таким образом, компании набирают не тех, кто лучше будет справляться с работой, а тех, кто лучше делает тестовые задания.
Итак, каким же, по моему мнению, должно быть идеальное тестовое задание?
В идеале тестовое задание должно быть максимально похоже на реальную работу. И задание должно быть добавить фичу/исправить баг/провести рефакторинг/написать юнит-тест.
То есть это должна быть та самая программа с которой предстоит в будущем работать. И в этой системе, разумеется будет обычный букет всех реальных программ: куча багов, недоделанных и полувырезанных фич, дублирование кода и логики и т.д.
К сожалению, это, как правило, возможно лишь для open-source разработки, а также в случае наличия open-source альтернативы вашего продукта. Тогда задания можно давать на ней.
Разумным компромиссом мне кажется специальная программа (возможно, разработанная для выполнения предыдущих вариантов тестового задания), содержащая баги, недофичи, не полностью покрытая тестами. Она должна содержать хотя бы 10 тысяч строк кода.
Таким образом можно будет посмотреть на работу программиста в условиях гораздо ближе к его реальной будущей работе.