Pull to refresh
29
0

Программист C++/Scala/Go

Send message

Так в большинстве своем и нужны «фреймворковые программисты». Статья предлагает спрашивать на собеседовании лишь то, что релевантно тому чем придется заниматься. Нужны алгоритмы или ещё какие-то специальные знания - спрашивайте.

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

Кажется, что это опечатка:

Если вы вычислите arcsin(pi/2), вы получите «?.???».

Функция arcsin не определена только для значений от -1.0 до 1.0

Я лично писал такого рода тест на языке Go при использовании библиотеки google FHIR, потому что эта библиотека обладала неожиданной "фичёй" - при сериализации объект портился и некоторые свойства пропадали. При сериализации! Представить себе такое в Scala - крайне сложно.

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

Про мутационное тестирование. Интересно, в реальных проектах его применяют?

Как минимум одна команда Яндекс использовала их, общался с их лидом, они прогоняли мутации раз один-два раза в месяц, писали они на C++. Ну и скорей всего Авито, зря что ли они выложили фреймворк свой для мутационного тестирования на Go. Ну и для скалы, когда я смотрел на мутационное тестирование, был только один фреймворк, п потом тот фреймворк был заброшен, то появилась парочка новых. Раз пишет, значит кто-то использует. Единственное надо смотреть ограничения, не исключено, что какие-то библиотеки или плагины компилятора могут ломать работу этих фреймворков. Собственно с тем, что я встретил впервые - он ломался с аккой, когда подменялось поведение актора в процессе исполнения. Для скалы пока не встречал тех кто, использовал бы мутационное тестирование.

Типы vs тесты.

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

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

Еще пример, с сериализацией. Если говорить о JSON, то если поле опциональное и представляет собой коллекцию, что есть два варианта задать тип у поля кейс класса - Option[List[DataType]] или просто List[DataType]. Редко когда нужно отличать пустую коллекцию от не заданной, потому есть возможность задать значение по умолчанию (бывает такое и со скалярными значениями полезно), но разные библиотеки могут обрабатывать это по-разному. Одни, по умолчанию, при десериализации вместо отсутствующего поля в JSON подставят требуемое, другим нужно явно указать, чтобы в таком случае использовались значения по умолчанию. В обоих случаях поведение программы корректное, мне не попадалось библиотеки, где разница в поведении будет влиять на тип кодеков. Можно, конечно, один раз запустить и проверить, что всё хорошо, но это знание останется у того, кто это написал. Более того, значение по умолчанию у поля кейс класса не обязательно свидетельствует о том, что в принимаемом JSON это поле может отсутствовать.

При работе с БД, можно забыть проставить аннотацию у поля описывающее имя столбца, или изменить порядок полей и тоже нарушить запись/чтение в/из БД. И всё это никак не описать в типах. Эти ошибки могут возникнуть как при написании кода впервые и тут можно сказать, что достаточно запустить и посмотреть что всё хорошо, но также они могут возникнуть случайно в процессе поддержки. И если на это будет тест, то он это поймает. А еще, для енумов в БД может быть задан пользовательский тип и при расширении енума в коде, можно забыть добавить миграцию, меняющую пользовательский тип в БД. Если в тестах поднимается контейнер и схема накатывается из миграций, то тесты помогут выловить это.

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

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

Да, типы позволяют уменьшить количество тестов, но не заменить их полностью. То что вернулся идентификатор из БД, не дает гарантии, что данные были сохранены полностью. То что вернулся нужный тип - не означает, что данные буду сериализованы корректно. И на это нужны тесты. Условно, при сериализации в JSON было поведение, что поля со значением null оставались, а после обновления библиотеки сериализации, такие поля стали по умолчанию убираться Или сериализация енумов изменилась - сериализовывались как UPPER_SNAKE_CASE, а стали CamelCase. Как результат - может сломаться интеграция с внешней системой. Если эта часть кода будет не покрыта тестами, то о проблеме узнаем в момент проверки интеграции, а если будет покрыта тестами, то сразу после обновления библиотеки на машине разработчика.

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

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

Опять же, тесты позволяют проверить, что в случае ошибки, результат содержит определенную информацию достаточную, чтобы понять, что произошло. Что логи и метрики пишутся правильно. Это тоже нужно проверить, в меньшей степени, но бывает необходимо. Просто потому, что в процессе поддержки приложения внутренняя логика может измениться. И чем раньше о потенциальной ошибке станет известно, тем проще её будет исправить.

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

Будь у меня выбор как проект взять на сопровождение - с хорошими тестами (включая юнит-тесты) или проект с "хорошей" архитектурой и типизацией всего, что только можно, то я предпочту первый, так как его код можно будет переписывать и улучшать в процессе поддержки. А со вторым всё будет хорошо, до тех пор пока не придется вносить серьезных изменений, ну или в процессе "красивая" архитектура будет деградировать, так как существенные изменения будет делаться "сбоку", так как трогать код не покрытый тестами "страшно", поведение изменится и не будешь знать об этом.

Да, Вы, правы, спасибо за пояснение.

Компилятор как раз и должен знать о том как он реализует UB, так, что где UB - компилятор знает. В этом вся суть. Стандарт языка не описывает поведение и оставляет эти моменты на усмотрение разработчиков компиляторов.

Вы вполне можете сделать это сами, сделав свой тип ошибки со стеком, используя runtime.Callers для получения стека. Или воспользоваться уже готовым пакетом, например, go-errors/errors.

Я вот не пробовал, поначалу останавливало, что он Windows only, а потом, как-то всё руки не доходили. Но вижу, что .Net активно развивается, но в первую очередь C#.
А как по вакансия на F#?

Как-то подытоживая. Вместе с задачей (как часть) ставить задачу на проверку/дополнение документации в объеме задачи. Условно задача касается двух компонент, по итогу выполнения на диаграмме должны появится эти компоненты с указанием с кем и как они взаимодействуют, какие данные пересылают. Если компонент с которыми они взаимодействуют еще на диаграмме нет, то добавить их без уточнения с кем эти компоненты еще взаимодействуют. И это должно делаться не только новыми разработчиками, иначе это убьёт мотивацию новых разработчиков. Ну и форма документации должна быть такой, чтобы прочие разработчики были готовы её читать.

Посадить писать документацию - это скорее исключительная ситуация. Где документация была и ведение её не возбранялось, то когда приходил новый разработчик ему документацию (какая есть) и задачу. Если в ходе задачи он находил проблемы с документацией, то правил её. Важнее, даже не то, чтобы он написал всю документацию прямо здесь и сейчас, а показать, что она есть, что мы владеем документацией и её можно и нужно править. Далеко не всем разработчикам нравится читать документацию, а писать документацию, нравится еще меньшему числу. А те, кто могут написать хорошую документацию, которую будет приятно читать - единицы. Так что как временного техписа использовать нового разработчика не стоит.

Так же очень важно определиться для кого документация. Если для разработчиков команды, то, по моему опыту, стоит ограничится диаграммами. Я сам в явном виде не использовал модель C4, но всё что мы делали, было похоже на этот подход. Этого достаточно, чтобы понять взаимосвязи в приложении. Плюс небольшое описание зачем продукт нужен. В таком виде, если уж документации не было, то лид может обрисовать с 1 по 2, частично 3 уровни, а более полно 3 и 4 уровни уже доделывать силами разработчиков. Т.е. он взял задачу, разобрался, что и как надо сделать и тут же внес необходимые правки в диаграммы.

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

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

Ситуацию с написание документации на фуллтайм я встречал два раза, один раз мне такая задача ставилась, другой раз мой лид этим занимался. Ситуации объединяло, то, что в обоих случаях мы были единственными разработчиками на проекте и от которого был только код. И тут, написание документации - это способ понять как и что работает. Поэтому я и упомянул, выше, что на это скорее исключительная ситуация.

Да, согласен, Скала местами очень запутанная.

Так, может лучше нести Хаскель в массы, чтобы появлялось больше вакансий? Тут доклад, там доклад, сравнение решения на Го и на Хаскеле, например. А, может, и перформанса приложения. Глядишь начнут задумываться, что может ФП и хорошо и надо больше в его сторону идти. Ну или массово будут переходить на Хаскель или прочие языки активнее начнут завозить к себе всё, что нужно для ФП.

Кстати, например, вот Скала - смесь ООП и ФП, даже сообщество раскололось. Один за чистое ФП, другие за ООП с элементами и ФП. Ну и в итоге первые ушли на Котлин и некоторые на Го, количество вакансий сократилось. Ну и смысл в ФП? :)

Ну и к тому же, допустить ошибку в таком сплаве парадигм легче и потом сиди и думай, почему в этом месте uuid/временные метки все разные, а тут, этот же скопированный код, всегда отдаёт один и тот же uuid/время. Ладно кто понимает как и что работает, то что ниже используется, а новичку совсем от этого грустно становится.

Констрейты так-то есть. Чтобы использовать тип внутри дженерика его как раз и надо указать. https://go.dev/blog/intro-generics

Для «хаскеле-подобобия» не хватает синтаксического сахара и чего-то типа sealed типов с проверкой инварианта компилятором :)

Так, что если хочется хаскеля, то лучше на нем и писать, благо с точки зрения языковых конструкций хаскель не сложнее го, а что касается тайпклассов и монад - то в целом язык не важен и хаскель (или другой ФП язык), где это нативно и нельзя смешать разные стили, выглядит предпочтительнее. Ну это если хочется чистого ФП.

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

Вот как раз для таких случаев и хорошо иметь статистику, что на этом проекте заменить описание - это 10 минут, а вот на этом 2 часа.

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

Самое сложное построить доверительные отношения, чтобы не было и такого, что сотрудник не успевает и в тихоня что-то в ночи доделывает, а потом рапортует, что всё ОК, в срок уложился.

Касается это не только того где время меряют буквально, но и где оценки идут в сторипоинтах. Заложили 3 сторипоинта, а в итоге получилось , что делали весь спринт, при средней скорости в 5 сторипоинтов.

Так же как и когда время никак не фиксируется. Если человек на постоянной основе на зплачи которые требуют полдня тратит по целом дню, то рано или поздно к не у появятся вопросы, ну или не появятся, но и роста зарплаты у него не будет.

Плюс задача не одна, есть очередь, так что закончив одну четырех часовую задачу, можно перейти к другой. Тут уже задача руководителя обеспечить работника работой на полный рабочий день. Тут все очень сильно зависит от руководства. К тому же всегда был вариант сегодня уйти пораньше, что не бросать на середине следующую задачу, а завтра поработать подольше. Ну и в целом, тому чтобы доделать следующую задачу способствовало то, что переработки в пределах, вроде, 15% от рабочего времени оплачивались автоматом по трекеру. И в целом всех всё устраивало.

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

Ну, так можно сказать о любом сервисе. Сегодня он есть, а завтра нет. Ну и если речь идет об исследовании, то телеграмм - это просто канал передачи информации от респондентов, так же как и гугл док.

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

При этом по мимо закрытия сервиса, в современном мире возможны блокировки работы сервиса или конкретных его пользователей. А так для респондента из России телеграмм весьма удобный канал обмена информацией с большими техническими возможностями. К тому же, модно сделать бота, который сообщения из каналов тут же будет сохранять, чтобы минимизировать потери в случае закрытия/блокировки сервиса.

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

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

Более того, отличное знание JavaScript в ребованиях не подразумевает, что человеку нужно знать так же отлично CSS и HTML - этим могут заниматься другие люди - верстальщики, например. А JS-разработчику останется только скомпоновать правильно данные. А про любовь к путешествиям - может весь отдел такие и постоянно это обсуждают, а то и вообще вместе куда-то ездят. А человек без такой страсти, просто будет всегда с боку, что может вызвать демотивацию.

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

Анимированные картинки с текстом - плохая идея. Отвлекают, плюс дошел до неё, она в этот момент показывается вся (ну вот так совпало), начал читать, а у картинки начался новый цикл повтора и то, что ты сейчас читал - исчезло. Брр…

Information

Rating
Does not participate
Location
Санкт-Петербург, Санкт-Петербург и область, Россия
Registered
Activity