Написание детективов принципиально отличается от написания других произведений. Очевидно, отличается тем, что убийца до последнего должен оставаться загадкой (и да, «Коломбо» не в счет). Читая подобные произведения, порой восхищаешься продуманностью сюжета и дальновидностью автора. А писатели — читеры, они придумали очень хитрый трюк, чтобы добиться эффекта запутанности и казаться такими матерыми интриганами и гениями тактики.
Все просто, до последнего авторы сами не знают кто будет убийцей. Произведение пишется таким образом, чтобы каждый из персонажей имел алиби и мотивы, даже садовник. И, дописав произведение до заветного момента, когда вот-вот главный герой прозреет и поймет кто же на самом деле убийца, писатели останавливаются и крепко задумываются. Тут-то самое время определится и решить кто же он на самом деле и как он это сделал.
Конечно, алиби у всех участников может быть чересчур железное и мотивы недостаточно раскрыты. Еще бы неплохо оставить дополнительные подсказки читателю, чтобы самые пытливые и внимательные имели возможность догадаться до правильного ответа вместе с Пуаро или Марпл. И тогда писатели слегка редактируют произведение и или даже переписывают какие-то отдельные части. И в результате мистер Холмс раскрывает хитросплетения злоумышленника и они читателю кажутся сильно запутанными для того, чтобы такое придумать. Убийца выглядит гениальным, а вместе с ним, гениальным кажется и автор произведения.
Вывод из этого довольно простой. Когда хочется хитросплетений и неочевидных решений, то написание приложения должно быть похоже на написание детектива. Иными словами, если хочется сделать процесс запутанным и неочевидным, достаточно всего лишь в процессе не задумываться о результате. И строго говоря, обратное утверждение не совсем верное. Если хочется прозрачности и очевидности, то необходимо, но не достаточно просто иметь цель. Помимо цели понадобится еще ой как много чего.
Все просто, до последнего авторы сами не знают кто будет убийцей. Произведение пишется таким образом, чтобы каждый из персонажей имел алиби и мотивы, даже садовник. И, дописав произведение до заветного момента, когда вот-вот главный герой прозреет и поймет кто же на самом деле убийца, писатели останавливаются и крепко задумываются. Тут-то самое время определится и решить кто же он на самом деле и как он это сделал.
Конечно, алиби у всех участников может быть чересчур железное и мотивы недостаточно раскрыты. Еще бы неплохо оставить дополнительные подсказки читателю, чтобы самые пытливые и внимательные имели возможность догадаться до правильного ответа вместе с Пуаро или Марпл. И тогда писатели слегка редактируют произведение и или даже переписывают какие-то отдельные части. И в результате мистер Холмс раскрывает хитросплетения злоумышленника и они читателю кажутся сильно запутанными для того, чтобы такое придумать. Убийца выглядит гениальным, а вместе с ним, гениальным кажется и автор произведения.
Вывод из этого довольно простой. Когда хочется хитросплетений и неочевидных решений, то написание приложения должно быть похоже на написание детектива. Иными словами, если хочется сделать процесс запутанным и неочевидным, достаточно всего лишь в процессе не задумываться о результате. И строго говоря, обратное утверждение не совсем верное. Если хочется прозрачности и очевидности, то необходимо, но не достаточно просто иметь цель. Помимо цели понадобится еще ой как много чего.
И опять о художественной литературе. О фантастике.
В этом жанре ярче других выражена градация и разделения общества на разные классы, уровни и привилегии. Фракции в «Дивергенте», рационалы, эмоционалы и пестуны из «Сами Боги», специализации в «Геноме», уровни магов и стороны света в «Дозорах». В жизни такого встретить не часто получается, а вот писатели могут проводить четкие границы сколько им вздумается. Компьютерные игры все, как один, идут туда же. Уровни исчисляются целым положительным индексом, урон — единицами, а защита — поглощенным уроном. Не то чтобы это как-то плохо было, просто желание описать систему до ее появления неизбежно выливается в необходимость четких категорий и градаций.
А теперь вспомним приложения, которые призваны автоматизировать бизнес-процессы какие-нибудь. Программисты таких систем делают по сути то же самое, что и фантасты, только сложнее: пытаются структурировать и систематизировать процессы, которые и так работают. И в отличие от фантастов, которые придумывают систему с нуля и могут позволить себе любые вольности, программисты должны формализовать то, что появилось стохастически и ситуативно. Да еще и так, чтобы в результате получилась фантастика.
В этом жанре ярче других выражена градация и разделения общества на разные классы, уровни и привилегии. Фракции в «Дивергенте», рационалы, эмоционалы и пестуны из «Сами Боги», специализации в «Геноме», уровни магов и стороны света в «Дозорах». В жизни такого встретить не часто получается, а вот писатели могут проводить четкие границы сколько им вздумается. Компьютерные игры все, как один, идут туда же. Уровни исчисляются целым положительным индексом, урон — единицами, а защита — поглощенным уроном. Не то чтобы это как-то плохо было, просто желание описать систему до ее появления неизбежно выливается в необходимость четких категорий и градаций.
А теперь вспомним приложения, которые призваны автоматизировать бизнес-процессы какие-нибудь. Программисты таких систем делают по сути то же самое, что и фантасты, только сложнее: пытаются структурировать и систематизировать процессы, которые и так работают. И в отличие от фантастов, которые придумывают систему с нуля и могут позволить себе любые вольности, программисты должны формализовать то, что появилось стохастически и ситуативно. Да еще и так, чтобы в результате получилась фантастика.
Фантасты, если все-таки решают уделить время бесполезности градаций, в итоге сводят все к тому, что никаких градаций не существует и мир нельзя поделить на черное и белое. В играх вообще не парятся, если лук наносит урон 15-19, то так и пишут. Если это боевой лук, то им нельзя, скажем, подпереть дверь, чтобы не закрывалась, а стрелой нельзя воспользоваться как ножом. Хотя, казалось бы, если бы симуляция жизненных ситуаций была бы поподробней, то необходимо было бы и на такой сценарий рассчитывать.
Давайте представим, что нам нужно создать CRM-систему организации «Ночной Дозор». С уровнями доступа, трэкинга приказов и спецзаданий, учета артефактов, с досье на всех темных в городе, лицензиями, протоколами следственных действий и учетом отпусков и премий для сотрудников. Представили, да? Очень похоже на то, что магии на эту CRM-систему прийдется израсходовать прилично. Ну, ладно, надо же с чего-то начать. Давайте хотя бы учет сотрудников сделаем. А с выданными табельными артефактами, учетом текущих заданий и прочими протоколами потом разберемся, сейчас о них даже думать не будем. Казалось бы, одна табличка 'users' в реляционной базе данных и интерфейс для ее редактирования. Еще с отдельным доступом на чтение и запись. Ну ладно, с разными уровнями доступа на чтение. И с разными уровнями доступа на запись. И еще с интерфейсом редактирования уровней доступа. И уровнем доступа к интерфейсу редактирования уровней доступа. Со специализацией отдельного пользователя (целительница ли, боевой маг или перевертыш). И наверно еще с мультиспециализацией. С возможностью увольнения. И чтобы потом опять того же героя взять на работу можно было с сохранением истории. И самое главное, что описанная система окажется неспособной сделать всего того, что хотелось бы сделать. Обязательно найдется какой-нибудь случай, в который нельзя отразить в текущей системе. Появится какой-нибудь внештатный маг-фрилансер вне специализаций. Или какой-нибудь темный вампир, работающий на «Ночной Дозор», для которого в системе просто не будет предусмотренных специализаций и категорий. Что тогда? Добавлять граничных условий, новых абстракций и исключений из правил?
В общем случае написание хоть сколько-нибудь сложной программы сводится к набору фич и взаимодействию этих фич между собой. Например, что будет если переименовать пользователя и сослаться в комментарии на прежнее имя? Может ли удаленный пользователь зарегистрироваться заново в системе? Если у нас есть поддержка нескольких языков, то нужно ли имя проекта заполнять на нескольких языках сразу? Таких вот пересечений различных функциональностей в приложении больше, чем можно себе представить за один раз. Это квадрат от количества всех возможных фич. И в приложении, у которых можно выделить десять различных разнообразных отдельных возможностей, нужно позаботиться о корректной работе в ста разных случаях. Понятное дело, что не всё вот так вот пересекается между собой, но порядок сложности добавления новой функциональности в приложение понятен.
Этот эффект можно назвать «отложенной сложностью добавления новой функциональности».
Этот эффект можно назвать «отложенной сложностью добавления новой функциональности».
Личным сообщением прислали резонное замечание, что количество комбинаций взаимодействия между различными частями приложения будет факториал, а не квадрат от количества фич. Нужно ведь рассматривать каждую фичу не только в контексте другой какой-то одной фичи, а в контексте всех других возможностей приложения, да и ещё и с важностью последовательности их.
Это действительно так, и факториал в данном случае хуже квадрата, что лишь усиливает основную мысль поста.
Это действительно так, и факториал в данном случае хуже квадрата, что лишь усиливает основную мысль поста.
Ещё одно сравнение с «Ночным Дозором», только в этот раз будем говорить о квалификации.
Лукьяненко просто замечательно описал систему уровней магии и магов, да так, что на протяжении чтения книг иерархия сложности заклинаний и квалификация отдельного сотрудника сомнений не вызывали вовсе. В книгах уровни распределялись от седьмого к первому. Однозначным определением уровня мага был набор заклинаний и умений, который способен он сделать. Продвижение по карьерной лестнице у «иных» зависело не только от опыта, но и от текущей формы. «На пике своей формы», как говорили герои книг. Получается, что однажды освоив третий уровень Силы, вовсе не обязательно маг останется на нем до конца своей карьеры. Вполне вероятно, что через некоторое время он окажется на четвертом или даже пятом уровне (седьмой уровень — самый слабый, если что). Опять же, не все маги, прийдя в систему сразу становились семиуровневыми джунами. Некоторых из них определяли на, скажем, третий уровень силы с приставкой «неопытный, но перспективный». Интересно, как им платили зарплату? Как третьему или как седьмому уровню?
Лукьяненко просто замечательно описал систему уровней магии и магов, да так, что на протяжении чтения книг иерархия сложности заклинаний и квалификация отдельного сотрудника сомнений не вызывали вовсе. В книгах уровни распределялись от седьмого к первому. Однозначным определением уровня мага был набор заклинаний и умений, который способен он сделать. Продвижение по карьерной лестнице у «иных» зависело не только от опыта, но и от текущей формы. «На пике своей формы», как говорили герои книг. Получается, что однажды освоив третий уровень Силы, вовсе не обязательно маг останется на нем до конца своей карьеры. Вполне вероятно, что через некоторое время он окажется на четвертом или даже пятом уровне (седьмой уровень — самый слабый, если что). Опять же, не все маги, прийдя в систему сразу становились семиуровневыми джунами. Некоторых из них определяли на, скажем, третий уровень силы с приставкой «неопытный, но перспективный». Интересно, как им платили зарплату? Как третьему или как седьмому уровню?
Ребята, как вам идея существования черных дыр, которые старше самой вселенной? По-моему все довольно элегантно.
http://telegra.ph/Eldar-Black-Holes-02-24
http://telegra.ph/Eldar-Black-Holes-02-24
Telegraph
Eldar Black Holes
Adam Crowl had an amusing idea. A recent paper suggested that it is possible to have black hole(s) that are older than the universe. Imagine that you have a cyclic universe, where a universe is born in a big bang, ages, then finally dies in a big crunch.…
Некоторые специализации магов (а их там было дофига и разнообразных) естественно ограничивались по степени силы. Скажем, все оборотни были от седьмого до пятого уровня силы и лишь единицы добивались большего. В книге таким вот «высшим оборотнем» был один персонаж и его сила была «приблизительно равна первому уровню силы». К слову, это был один из старейших иных, описанных в книге — его возраст был около десяти тысяч лет. Приблизительно столько нужно, чтобы в профессии, которая ценится не так высоко, как остальные, добиться вершин. Верно говорю, верстальщики?
Вампиры в «Дозорах» были ограничены пятым уровнем сверху, но особняком стояли высшие вампиры, сила которых не уступала всем остальным. Эдакое расслоение на «высших» и «низших» в одной профессии определялось способностью контролировать людей и других вампиров. Низшие едва ли справлялись с одним-двумя, высшие подчиняли себе десятки. При том, что основной особенностью специализации вампиров была возможность превращать обычных людей в «иных». Ой, что-то мне очень сильно это напоминает.
Некоторые иные из «Дозоров» освоили всевозможные заклинания и набрались всевозможного опыта, что под первый уровень уже не подходили по критериям. Их называли «магами вне категорий» и таких было довольно мало. Они занимались какими-то неведанными и, с первого взгляда, крайне абсурдными занятиями с точки зрения семиуровневых джунов. Только в самом конце реализации задуманного, было понятно насколько качественно и продуманно было все спланировано сеньорами вне категорий. А вот любые попытки объяснить свои действия оканчивались неудачей — планы были настолько запутанными и хитросплетенными, что их объяснение не укладывалось в повседневную логику семи-, шести- и даже трехуровневых джунов и миддлов. Каждая неудача в действиях высших магов оборачивалась новой победой, каждое видимое поражение было хитро продумано и организовано. Автор произведений объяснял это тем, что высшие маги очень хорошо видят вероятности развития событий и они оперируют совершенно другими понятиями, недоступные остальным. В итоге все просто смирялись с указаниями высших иных. Если сказал делать так, значит надо делать так. И в дозорах такие вот мэтры магии действовали сообща, очень удачно манипулируя миддлами и джунами. Что, собственно, и качественно отличало их от остальных магов более низкой квалификации.
Как объяснить, что ту или эту функциональность приложения лучше оформить эдак вот так? Особенно если сейчас вовсе не требуется городить сложные системы, а достаточно лишь пару строчек костылей. Еще когда другие варианты кажутся проще в реализации и менее трудозатратными. Но вот эдакий вариант в будущем возможно окажется настолько удачнее любых аналогов, что текущие дополнительные затраты на реализацию сейчас окупятся с лихвой. Естественно нужно не переборщить и понимать, что в будущем разработка системы действительно окупится. Еще таких вот возможно-вариантов маги вне категорий видят несколько и каждый видимый возможный вариант развития событий возможен с разной вероятностью. Поэтому необходимо сейчас совершить такой набор действий (читать: «так спроектировать систему»), при которых в будущих вероятностных хитросплетениях будет максимальная выгода. И тот вариант, который кажется сеньорам магам правильным делать нужно не потому, что благодаря этому варианту развития событий лучше решается текущая проблема (и как правило наоборот), а из-за того, что этот вариант порождает минимальное количество проблем в будущем. Конечно же я говорю о «Дозорах» Лукьяненко, а никак не о программировании.
Лайвхаки от Экстраполяции
Гит прекрасен в консоли. Безусловно, интеграция с рабочими инструментами полезна и часто сокращает количество кликов, но консольная работа с гитом крайне базовая и иногда незаменимая. Самая насущная проблема в консольном гите — древовидное визуальное представление веток и коммитов. Для этого я использую два подхода.
Первый — GitX. Только не оригинальный, а форк. Хоть даже форк давно уже не поддерживается, с визуализацией он справляется отлично. Кроме того крайне легковесен, что немаловажно в эру реакт-нейтивов и электронов. http://rowanj.github.io/gitx/
Второй — консольная команда
Гит прекрасен в консоли. Безусловно, интеграция с рабочими инструментами полезна и часто сокращает количество кликов, но консольная работа с гитом крайне базовая и иногда незаменимая. Самая насущная проблема в консольном гите — древовидное визуальное представление веток и коммитов. Для этого я использую два подхода.
Первый — GitX. Только не оригинальный, а форк. Хоть даже форк давно уже не поддерживается, с визуализацией он справляется отлично. Кроме того крайне легковесен, что немаловажно в эру реакт-нейтивов и электронов. http://rowanj.github.io/gitx/
Второй — консольная команда
git log --graph --abbrev-commit --date=relative --all
. Конечно же, запоминать ее вообще не обязательно, а лучше добавить в глобальный gitconfig. Мой гитконфиг публично доступен и лежит в репозитории dotfiles на гитхабе. С таким конфигом, чтобы увидеть дерево коммитов, я использую команду git la
.Еще один клёвый инструмент для работы с гитом от читателей «Экстраполяции» — tig (https://jonas.github.io/tig/). Работает в консоли и позволяет все то, что полноценные оконные инструменты вроде GitX. Выглядит просто отлично! Попробуем?
Во всех псевдоинтеллектуальных системах нужно сначала ответить на вопрос о том, какие результаты нам можно видеть, а какие нельзя: ложноотрицательные или ложноположительные. Если ложноположительные можно видеть, а ложноотрицательные нельзя, то система будет указывать на те места, на которые она не должна указывать, но точно не пропустит настоящую ошибку. Если же ошибки просачиваться могут (ложноотрицательные результаты), то систему стоит воспринимать, как помощника, но точно не как заменителя. В системах, которых окажется, что можно пропускать и ложноположительные и ложноотрицательные результаты, будет слишком мало смысла за редким исключением.
Конечно, самая очевидная аналогия в данном случае с нейронными сетями, где погрешность и ложноотрицательные или ложноположительные результаты — часть системы. Но я предлагаю подумать об автоматических тестах. Каждый раз, когда нужно писать тест, ставится вопрос что же лучше будет: чтобы тест упал, когда все работает как надо или чтобы тест прошел успешно, когда что-то там сломается? И, конечно же, падающий тест вместе с работающей системой — это далеко не всегда хорошо. Решение нужно принимать индивидуально для каждого теста в отдельности.
Конечно, самая очевидная аналогия в данном случае с нейронными сетями, где погрешность и ложноотрицательные или ложноположительные результаты — часть системы. Но я предлагаю подумать об автоматических тестах. Каждый раз, когда нужно писать тест, ставится вопрос что же лучше будет: чтобы тест упал, когда все работает как надо или чтобы тест прошел успешно, когда что-то там сломается? И, конечно же, падающий тест вместе с работающей системой — это далеко не всегда хорошо. Решение нужно принимать индивидуально для каждого теста в отдельности.
Wrong number of arguments — объективно худшая ошибка в Руби.
Худший дизайн сообщения, который вообще мог бы быть.
Ошибка при вызове метода на nil прекрасна.
Ошибка wrong number of arguments могла бы быть не менее прекрасной, но нет.
Мы не говорим "передали вот это: тыц, тыц, тыц, пердыц, но надо было три аргумента".
Мы говорим "передали четыре аргумента, а надо было три".
И это в среднем 15-20 человеко-минут на одну такую ошибку.
Серийные убийцы.
Худший дизайн сообщения, который вообще мог бы быть.
Ошибка при вызове метода на nil прекрасна.
Ошибка wrong number of arguments могла бы быть не менее прекрасной, но нет.
Мы не говорим "передали вот это: тыц, тыц, тыц, пердыц, но надо было три аргумента".
Мы говорим "передали четыре аргумента, а надо было три".
И это в среднем 15-20 человеко-минут на одну такую ошибку.
Серийные убийцы.
Ребята, #хайринг. Воспользуюсь служебным положением и расскажу, что нам в команду (cimon.io) нужен дизайнер.
Чтобы хороший был, добрый и с бородой. Или без. И не обязательно «был», можно чтобы и «была». Но дизайнер. Ещё главное, чтобы добрый. Хотя, если будет злой, то тоже хорошо. Но только если дизайнер.
Работать нужно будет над одним из нескольких проектов, вроде riter.co или vault8.io. Работы вагон и маленькая тележка, прийдется много думать и принимать самостоятельные решения.
Мы очень любим технически подкованных дизайнеров. Которых не пугает работа с гитом, джаваскриптом и командной строкой. Если дизайнер будет такой подкованный, то не обязательно пусть будет добрым. Можно, чтобы был злым.
Дизайнеры, присылайте ссылку на работы свои личным сообщением в телеграме (@aratak). Отдельное спасибо за форвард сообщения друзьям-дизайнерам и в подконтрольные каналы и группы.
Чтобы хороший был, добрый и с бородой. Или без. И не обязательно «был», можно чтобы и «была». Но дизайнер. Ещё главное, чтобы добрый. Хотя, если будет злой, то тоже хорошо. Но только если дизайнер.
Работать нужно будет над одним из нескольких проектов, вроде riter.co или vault8.io. Работы вагон и маленькая тележка, прийдется много думать и принимать самостоятельные решения.
Мы очень любим технически подкованных дизайнеров. Которых не пугает работа с гитом, джаваскриптом и командной строкой. Если дизайнер будет такой подкованный, то не обязательно пусть будет добрым. Можно, чтобы был злым.
Дизайнеры, присылайте ссылку на работы свои личным сообщением в телеграме (@aratak). Отдельное спасибо за форвард сообщения друзьям-дизайнерам и в подконтрольные каналы и группы.
В каждом уважающем себя трекере задач всегда есть место для маркёра важности задачи. Ну, там «minor» или «important» или вообще «critical». Такие маркировки задач лишены смысла почти полностью и следующими несколькими постами давайте разберём почему.
Маркировка «критический» лишена всякого смысла, потому как если все действительно критично, то создавать задачи получается только постфактум, уже после исправлений критических проблем.
Если проблема действительно критически важна, то разработчик, расслаблено набирая
А обычно такой маркировкой пользуются для того, чтобы показать, что эту задачу нужно взять следующей. Ну или это когда тебе жена с кухни кричит «Дима, срочно подойди сюда!». Ты такой всё бросаешь, бежишь на кухню, а она такая «подай полотенце, у меня руки грязные».
Если постоянно кричать «Волки!», то люди перестанут обращать на это внимание.
Маркировка «критический» лишена всякого смысла, потому как если все действительно критично, то создавать задачи получается только постфактум, уже после исправлений критических проблем.
Если проблема действительно критически важна, то разработчик, расслаблено набирая
class MySuperSer...
, должен немедленно это бросить и, как пожарник, броситься срочно тушить пожар. Там уже не до трекеров, оформлений багов, стикеров и оценок. Бумаги заполняются после пожара, а не до него. А обычно такой маркировкой пользуются для того, чтобы показать, что эту задачу нужно взять следующей. Ну или это когда тебе жена с кухни кричит «Дима, срочно подойди сюда!». Ты такой всё бросаешь, бежишь на кухню, а она такая «подай полотенце, у меня руки грязные».
Если постоянно кричать «Волки!», то люди перестанут обращать на это внимание.
Рекомендации на этом канале можно увидеть не часто, но зато они все от чистого сердца. Мне очень нравятся авторские каналы, которые ведутся не ради наживы, а ради каких-то других скрытых и неявных целей. Посты таких каналов я читаю с удовольствием и стараюсь не пропустить ни одного поста на них.
С автором канала «Айти без галстуков», Дмитрием, мы знакомы лично и я уверенно могу сказать, что ему есть что рассказывать интересного ещё очень долгое время.
https://yangx.top/notieinIT
Для любителей нативной рекламы отдельно замечу, что получить подобного рода пост за деньги или за другую какую-либо награду на этом канале невозможно. Есть только один способ попасть в рекомендации канала «Экстраполяции» — иметь крутой авторский канал.
Подпишитесь на Дмитрия, уверен, это очень сильно мотивирует его больше писать клевых постов.
С автором канала «Айти без галстуков», Дмитрием, мы знакомы лично и я уверенно могу сказать, что ему есть что рассказывать интересного ещё очень долгое время.
https://yangx.top/notieinIT
Для любителей нативной рекламы отдельно замечу, что получить подобного рода пост за деньги или за другую какую-либо награду на этом канале невозможно. Есть только один способ попасть в рекомендации канала «Экстраполяции» — иметь крутой авторский канал.
Подпишитесь на Дмитрия, уверен, это очень сильно мотивирует его больше писать клевых постов.
Telegram
noTieinIT - Об IT без галстуков
Дмитрий Меньшиков, CTO в продуктовой компании. Вещаю о построении и развитии IT бизнеса, развитии команды, менеджменте и трендах.
Обратная связь - @notieinit_bot
Обратная связь - @notieinit_bot