?

Log in

No account? Create an account

January 1st, 2037


12:00 am - Давайте знакомиться. [sticky post]
Я программист / орхетектор / бизнес аналитик / team lead / системный интегратор / консультант, больше всего - программист.

Больше всего пишу про программирование, являясь адептом культа теоретики кайфа и проповедником экзистенциализма в программировании.

А ввиду того, что это не тематический блог, а ЖЖ - готовтесь встретить всякий мусор эмоционального происхождения, да и прочий мусор тоже.

Заметки о программировании фильтруются по dev

Facebook

Google+

Linkedin

GitHub

cachelot.io


В комментариях можно оставлять всякое (сейчас этим предложением активно пользуются спам-боты, но все же...). Комментарии скринятся.
Tags:

(6 comments | Leave a comment)

March 8th, 2016


01:03 am - 1 год cachelot
С августа исправлял в cachelot дурацкий design bug. (Правда были еще смена работы и переезд в другую страну, и все это отняло много времени).
На реальной системе баг зарепродьюсить очень сложно, но на бенчмарках он вылезал постоянно.

Суть в следующем: памяти выделяется всегда столько, сколько попросили (нет разбития на чанки одинакового размера), за счет чего память расходуется очень экономно.
Понятно, что происходит сильная фрагментация, но cachelot поддерживает LRU eviction, т.е. умеет вытеснять старые данные при добавлении новых.
И вот тут начинается самое интересное.

Если подходящего куска памяти нет, то cachelot находил несколько кусков, объединял их и отдавал. Проблема в том, что эту операцию необходимо выполнить за O(1)
Тут я немного отвлекусь. При проектировании (near) real-time систем стабильный latency намного важнее чем скорость выполнения отдельной команды.
Лучше выполнять каждую команду за 2ms, чем за 1ms, но с "просадками" до 5ms.

Задача поиска нескольких элеменов, расположенных в памяти по соседству, да и еще "холодных" за константное время не решается. Потому механизм вытеснения работал на поиске самого большого "холодного" элемента и поиска от него влево-вправо. При таком подходе "горячие" данные могли быть выброшены, се ля ви.
(Это все в случае, когда подходящего куска памяти не нашлось).
В случае, когда он есть - ищем самый "старый" элемент среди тех, у которых размер больше, или равен искомому. Выбрасываем его. Так, кстати, работает memcached.

Теперь следим за руками.
Пользователь начинает добавлять в кэш элементы размером 10 байт.
Делает это до тех пор, пока память в кэше не забъется и не начнутся вытеснения.
Потом пользователь начинает вставлять элементы по 11 байт.
Cachelot удаляет 2 элемента и добавляет первый элемент.
Потом cachelot удаляет только что добавленный элемент и вставляет новый.
Потом cachelot удаляет только что добавленный элемент и вставляет новый.
Потом cachelot удаляет только что добавленный элемент и вставляет новый.

Вот такие пироги с котятами.

Теперь появились страницы (размер страницы - настраиваемая опция) и вытеснение происходит на уровне страниц. Самая "холодная" страница выбрасывается и начинает заполняться элементами по-новому. Элемент, размером больше чем страница, добавить нельзя. Таким образом для добавления нового элемента всегда нужно освободить максимум страницу.
Чем меньше страница (в пределах разумного - 4K страница на 64Mb хватает вполне), тем точнее работает вытеснение. Если нужны элементы большего размера - страницы всегда можно увеличить.

Зачем вообще нужен cachelot?
Его можно использовать как готовую библиотеку LRU cache прямо в коде. Отдаете фиксированный объем памяти, и весь кеш живет и крутится там.
Можно понаписывать биндинги во всякие Python, Go, Java, whatever.
Cachelot очень сильно оптимизирован по памяти, если хочется больше кэша, то можно пробовать его вместо memcached прямо сейчас (поддерживается текстовый протокол через TCP/UDP/Unix domain socket). Cachelot очень хорошо утилизирует CPU за счет того, что все внутренние структуры ложатся в CPU cache.
Cachelot хорошо подходит для всяких IoT устройств, где ресурсы жестко ограничены.

Если вам нужны какие-то дополнительные фичи, то можно мне писать, возможно я их уже делаю, или сделаю.

Буду очень признателен за звездочки на гитхабе и вот это вот все.



Tags: ,

(4 comments | Leave a comment)

January 5th, 2016


03:42 pm - Вакансия Ассистента Рисерчера
Originally posted by maxim at Вакансия Ассистента Рисерчера
Друзья! У нас появилось немного денег, которые мы хотим потратить. В нашу эрланг компанию требуется стажер, возможно студент, который интересуется теорией типов и разработкой компиляторов. Если так получилось что вы родились в Украине, и вам тесно и грустно работать перекладывая байты из JSON в XML на Хаскеле, но вас не берут в крутые международные проекты под управлением Аводея, Байера и Мейера из-за отсутствия публикации -- это все поправимо.

Что мы предлагаем? Мы предлагаем вам присоединится к нам в качестве ассистента или младшего научного сотрудника. Все публикации, авторские права остаются за вами, никакого NDA или прочей неопределенности. Все статьи публикуются на превью площадки (Архив, РисерчГейт) как только достигнут качества "не стыдно".

Мы исследуем разные аспекты компиляции эрланг кода и компиляции в контексте эрланг инфраструктуры, так, например, компания Cloudozer занимается разрабткой статически-компилируемого LLVM языка L, основное назначение которого генерировать эффективный нативный код (с удалением информации о типах) из исходников похожих на Эрланг или с минимальными изменениями Эрланг кода. Synrc же занимается фул стек Erlang решениеми и исследованием в области доказательства корректности программ. Сейчас у нас есть два направления: 1) это доказательство алгоритмов используемых для обеспечения персистентного хранения цепочек (KVS/N2O/BPE), используя пруверы основанные на теории зависимых типов (мы используем Lean, вы должны уметь использовать любой прувер с Pi типами); 2) разработка собственного языка с рекурсивными полиномиальными типами и зависимыми рекордами (первоклассными модулями), который компилируется в промежуточную форму чистого языка на основе Henk/Morte/Om, а оттуда транформируется в Erlang AST (без компиляции паттерн мачинга, без необходимости своего gc, т.е. все самое сложное оставляем для виртуальной машины Эрланг и его оптимизирующего компилятора).

Что мы хотим? Мы хотим, чтобы вы знали основы Теории Категорий, могли нарисовать все коммутативные диаграммы и аксиомы необходимые для определния декартово-замкнутой категории и могли читать proof-theoretical аксиоматическую нотацию. Также вы должны понимать коммутативные диаграммы F-алгебр для рекурсивных типов, а также иметь понятие о кодировании Черча и его применении к кодированию индуктивных типов. Необязательно но полезно было бы быть знакомым со слоениями и slice категориями для категорного понимания зависимых типов.

Поверьте, такой опыт предложить в Украине не может ни одна компания. Важно иметь возможность проводить еженедельные совещания в оффлайне, удаленная работа полностью исключается.

Пишите: maxim@synrc.com

(2 comments | Leave a comment)

November 26th, 2015


11:44 pm - Punk programming
Для одного проекта нужно было сделать RPC на питоне.
Можно было взять готовую библиотеку, можно было написать свою. Но. Появилось решение, от которого я просто в восторге - настоящий панк.
Локальный скрипт дергает скрипт на удаленной машине по ssh. Remote скрипт сериализует ответ в stdout (да, обычный Pickle), локальный скрипт вычитывает ответ и десериализует. Все!
Работы меньше дня, аутентификация, шифрованный протокол, поддержка сессий. Работает как часы, никаких зависимостей, никаких нареканий.
Морали не будет. Хотя, да - на свои моральные комплексы пришлось наступить.
Current Mood: energeticenergetic
Current Music: Snarky Puppy - Shofukan

(6 comments | Leave a comment)

November 15th, 2015


11:32 pm - Религиозно-математическое
Профессор из MIT рассказывает студентам байку.
Была такая религиозная община - пифагорейцы, которые воспринимали математику, как религию. У них там были свои боги, все как надо. Добрый бог отвечал за рациональные числа, злой бог - за бесконечность и всякую иррациональщину.
Теперь к сути. В системе аксиом пифагорейцев была одна про то, что у конечной линии есть измеримая рациональная длина. С другой стороны они были в курсе, что длина гипотенузы прямоугольного треугольника с катетами по единице - корень из двух. Просто считали его рациональным. И тут появился человек, который доказал, что это не так. Это ставило под сомнение не только правильность большинства доказанных теорем, но и религиозное учение, как таковое. По легенде чувака убили, чтобы не вызывать смуты.
Соль этой байки в том, что это единственный известный человечеству случай, когда человека убивали за корень из двух.
Да, кто еще не в курсе, MIT выложил все свои курсы в открытый доступ

(2 comments | Leave a comment)

August 27th, 2015


03:44 am - Проджект менеджмент понарошку
Где-то через полгода работы над Cachelot пришло понимание, что так жить нельзя, и нужно переписывать задачи из блокнота в какой-то трекер. Таски я закрывал, но было совершенно непонятно сколько я сделал, сколько осталось сделать, а самое главное - непонятно, что делать прямо сейчас и для чего это нужно.
Время тратилось на какую-то абсолютную фигню, у меня появилось ощущение, что я стою на месте, и я впал во фрустрацию. Потому, засучив рукава, я приступил к поиску какого-то нормального трекера.
Оказалось их есть - wrike, но за 50$/мес. меня задавила жаба, а все остальное либо "типа энтерпрайс" - заполни тысячу полей чтобы добавить таску, либо хипсторский треш - "мы хотели сделать фейсбук, но кто-то его сделал за нас, поэтому вот вам тикетница с чятиком и фоточками, но без диаграм Ганта и нет зависимостей между тасками". Оставались еще клоны MS Project (уже можно работать, но я верил что можно лучше), ну или еще что-то совсем без функционала.

С одной стороны, карточки в стиле GTD, или Kanban - это хорошо, т.к. очень легко создать карточку, можно куда-то ее передвинуть, поменять местами, но совершенно непонятно сколько времени уйдет, чтобы закончить вот этот объем задач, и нет никакого вменяемого трекинга. Опять же - непонятно чем нужно заниматься сейчас.
В MS Project (Libre Project, и пр.) можно довольно легко набросать задачи, расставить зависимости, посмотреть на Gantt Chart, выбросить лишнее и получить вменяемый план работы. Так я и сделал - Libre Project, план, все понятно. Но. Cachelot - это ж мой домашний проект, со всеми вытекающими.
Во-первых я скорее буду прокрастинировать, чем делать задачу, которую по плану нужно делать. Можно конечно взять другую задачу по вкусу. Не хочется писать код - верстаешь сайт, не хочется сайт - пришешь промо-статью и т.д. Но тогда рушится план. Вторая проблема - у меня нет графика работы. Иногда я работаю на выходных, иногда нет. По настроению. И заранее я это планировать не хочу - вдруг погода будет хорошая, на покатуху позовут, или бухать, ну и так далее.
Получается, что график необходимо постоянно менять, иначе весь план безнадежно отстает от реальности. Получается предыдущая система с карандашом, блокнотом и салфетками, только электронно-вычислительная.

В итоге я выработал какую-то гибридную систему с карточками и понятными только мне маркерами, которая мне подошла.
(Наверняка кто-то изобрел ее до меня)

Для задач я использовал Trello (сейчас присматриваюсь к Phabricator), или куплю real-life доску и буду лепить разноцветные карточки.
Только вместо списков "TODO" / "Doing" / "Done" / "Backlog" я использую месяцы.


[   Июль   ]    [  Август  ]    [  Сентябрь  ]    [  Октябрь  ]   [  Ноябрь  ]    [  Декабрь  ]



Срок планирования - 3 месяца, у меня на борде есть списки на полгода, но три из них - это бэклог. Три первых месяца я планирую тщательно, три оставшихся - очень приблизительно.
У каждого месяца есть ярко-красная карточка "Month Goal" - это единственная задача, определенная по правилам S.P.E.C.I.A.L., остальные - просто задачи. В месяце чаще всего один Goal, максимум - два.
Дальше все просто. Для того, чтобы закрыть красную карточку, нужно сделать 3-5 задач поменьше (я маркирую их оранжевым).
Остаются еще мелкие, бесцветные, задачи. Цель месяца от них не зависит, но хочется их сделать в этом месяце, хотя если что - можно и перенести.
В этом же списке находятся личные задачи, которые отнимают существенный объем времени: "сходить к стоматологу", "сделать ТО сноуборду", "пройти курс на Coursera" и пр.
Чтобы не было соблазна постоянно откладывать задачи на следующий месяц, карточки не переносятся, а копируются. Если я переношу задачу с Августа на Сентябрь, то в Авгуте я оставляю ее и помечаю фиолетовым (Delayed).
Закрытые задачи становятся зелеными и радуют глаз.

Как понять какое количество задач ставить на месяц.
Сначала эмпирически, у меня в первом месяце получился длинный "хвост" из незавершенных задач, второй месяц я закрыл где-то на 90%.
Дальше легко, можно смело ориентироваться по длине списка. Даже при условии, что одна задача занимает 30 мин, другая 2-3 дня, длина списка в месяце получается примерно одинаковая. Я думаю, это связано со стереотипностью мышления. Как минимум - можно брать за ориентир.

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

Расскажите как это сделано у вас.



Current Music: Pink Floyd - Have A Cigar

(4 comments | Leave a comment)

August 24th, 2015


03:04 am - На тему собеседований
Некогда писать вдумчиво. Работа над cachelot кипит, потому галопом и сбивчиво.

Проскакивала такая тема: почему на собеседованиях задают однотипные и дебильные вопросы, навроде: "Кем вы видите себя через 5 лет?", "Назовите ваше самое большое достижение на прошлой работе" и т.д.
Ответ очевидный (почему-то не для всех). Собеседование - это как свидание, там тоже задают однотипные и дебильные вопросы - "А какую музыку ты слушаешь?". Вот и получается такой ритуал - танцуем с вопросами вокруг да около, а по ответам пытаемся выяснить подходит ли нам кандитат (работодатель).

Когда Sony выпускала Walkman, собрали фокус-группу, спрашивали какого цвета должен быть плеер. Большинство называли всякие яркие, нестандартные, цвета. По окончанию участникам предложили взять любой понравившийся плеер из коробки, все выбрали себе черные и серые.

Это не потому что все люди врут (хотя и врут тоже), чаще всего просто сами не знают чего хотят. А вам, если нанимаете человека, нужно знать наверняка.
Причем нанять сотрудника, а потом сказать ему что, мол извини - отношения не сложились чаще сложнее, чем расстаться с девушкой / парнем.

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

Я всегда спрашиваю про "самое большое достижение". Первою на что смотрю - загорелись ли глаза, когда человек это описывает. Важный момент: если глаза не загорелись - это не страшно. Человек спокойно говорит что сидел 3 года на саппорте и закрывал тикеты - это круто. Такие люди нужны. Вопрос только в том, такого ли человека мы ищем.
Или наоборот - человек с горящими глазами рассказывает как он из говна и палок собирал интернет магазин за полдня до сдачи заказчику. Слушайте, делайте выводы.

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

Главное, чему я научился - во время собеседования нужно обязательно вывести соискателя из равновесия. Рамки переходить ни в коем случае не нужно, просто поставить человека в нестандартную ситуацию. Это очень хороший тест на "адекватность", такой стресс-тест многое вскрывает.
Бывший директор отлично выступал. Был случай, когда он во время собеседования начал делать кандидату массаж плеч, спросил - "удобно ли?" - "может еще кофе?". Перед другим кандидатом он поставил ноги на стол и спросил: "Че ты сюда приперся?"... "Зачем. Ты. Сюда. Приперся?!"
Такой вот цирк может предотвратить безобразную драку в офисе, с применением стульев и прочего холодного оружия. Или например развеселое посылание нахуй заказчиков с их тупыми просьбами.
Это помогает отсеять профессиональных ходоков по собеседованиям (у них готового ответа на подобные ситуации нет, это скорее введет их в ступор), это помогает человеку выйти из ступора, в котором он из-за стресса (нестандартная ситуация включает мозги). И именно в таких ситуациях проявляется адекватность человека. С одной стороны ситуация неприятная, но например реагировать на нее рукоприкладством было бы явным перебором.

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

Если вы ищете работу, то помните, что собеседование - это не вас спрашивают, вы отвечаете; это - диалог.
Выясните все заранее, когда подпишете контракт - будет поздно. По вопросам работодателя о нем точно так же можно делать выводы. И врать нет никакого смысла.
- "Как вы относитесь к овертаймам?" - тут овертаймят, инфа 100%. Не готовы овертаймить - так и скажите: "Семья, дети, велосипед".
Любите подольше поспать с утра? - Так спросите: "Как вы относитесь к тому, что я буду на 11 ходить?"

Всем эксплуататорам мегасотрудников, всем трудягам - работодателей мечты!

P.S. В тему.
Собеседовался я как-то на должность разработчик Oracle PL/SQL, DBA, вот это вот все. Побеседовали с HR, говорят - сейчас будет техническая часть. Сижу, жду.
Заходит чувак, говорит: - "Oracle знаешь?". Я: "Ээээ. Да." - "Ок, круто", говорит. И уходит.


Current Music: Therapy? - Don't expect roses
Tags: ,

(44 comments | Leave a comment)

May 26th, 2015


12:12 am - Сага про 1M RPS
Я на пару лет пропадал из ЖЖ, так как занимался пет проектом. Мне в 2011-м году пришло в голову сделать DBMS, которая поддерживала бы 1M RPS (просто потому что число красивое).
С того времени утекло много воды, было много кода и прокрастинации (например на тему сделать микропотоки - я как-нибудь расскажу почему в случае C++ это плохая идея). Изначально я думал про noSQL KVS с поддержкой транзакций, но потом понял что вечерами после работы я такое не потяну и начал с чего попроще - с memcached.

Я часто слышал, что KVS - это простая хэш таблица, мол чего там делать, но это нифига не так. Кэш имеет смысл только есть нормальный механизм вытеснения старых элементов (eviction) - это раз, нужно чтобы весь кэш помещался в фиксированный объем памяти - это два. А это уже полноценный memory manager.
А чтобы не было скучно - желательно чтобы все операции выполнялись за О(1).

Приблизительно так получился Cachelot /kæʃ-ə-ˈlɒt/. И само собой, я получил массу опыта.
Наверное самое важное - я научился брать куски хорошо написанного кода, покрытого тестами, и удалять к чертям.

Когда я дописал механизм кэширования, вышло 3M RPS (код оптимизирован под CPU cache, поэтому напрямую зависит от размера кэша). Потом прикрутил TCP транспорт и узнал много нового - 90% времени запроса проходит в kernel. Как его забороть я пока что не знаю, но буду думать.

Cachelot может быть хорошей альтернативой memcached: во-первых на небольшом количестве сессий (десятки) время выполнения запроса меньше, во-вторых cachelot экономнее расходует память (я еще попробую добавить компрессию), в-третьих он однопоточный, расходует мало ресурсов и утилизирует ~100% CPU. Синхронизацию потоков я делал через lock free очередь, оверхед получился незначительный, но конечно от cache thrashing никуда не деться.

Пока что разношу кэш и сервер, чтобы сделать отдельную кэш библиотеку. Большинство команд memcached уже поддерживаются (в некоторых наверное есть баги - work in progress, все такое).


Current Music: Pink Floyd - Comfortably Numb
Tags: ,

(2 comments | Leave a comment)

May 25th, 2015


07:52 pm - Почему мы должны перестать заниматься пет проектами
Наконец-то опубликовали мою статью.
http://megamozg.ru/post/15748/





(Leave a comment)

May 20th, 2015


10:47 am - РИТ++
Народ, если кто собирается на РИТ++ 21-22 мая в Москве, можем встретиться где-то на конференции.
Tags:

(Leave a comment)

April 21st, 2015


11:21 am - Для тех, кто использует Memcached
Написал практическое руководство по настройке и тюнингу (англ.)
Tags: ,

(Leave a comment)

January 28th, 2015


02:14 pm - Вендекапец
Fedora21_screen

В мире этого вашего Linux все спокойно.
Попробовал поставить Fedora 21, в меню создания partition вылезла ошибка "Не хватает места для partition" и привет! Инсталлятор вылез за границы монитора, поглотив в пучине кнопку "Continue", или "Install". Что там было?
В свое время с подобным сталкивался и в Debian/Ubuntu, и в CentOS. Сделать UI для разбивки диска - это что-то невозможное в реалиях Linux.
http://fedoraproject.org/wiki/Common_F21_bugs#Custom_partitioning_screen_resizes_and_becomes_unusable_during_German_install_at_lower_resolutions_.28possibly_other_languages.29

Не забудьте прокомментировать почему ваш %дистрибутив_нэйм% не говно, в отличие от...

(20 comments | Leave a comment)

January 12th, 2015


02:35 pm - Посоветуйте пожалуйста...
... книг, блогов, сайтов, курсов, прочего по бизнесу (будет здорово про IT, только не стартапы) и какие-нибудь базовые вещи по экономике из категории must read.
Пишите название ресурса, даже если он уже есть в комментариях (будет понятно что читать в первую очередь).
Спасибо.
Tags: ,

(2 comments | Leave a comment)

December 19th, 2014


02:46 am - Про waterfall и agile в дизайне и разработке
Немного банальностей про подходы к дизайну и разработке ПО. В свое время мне чего-то подобного не хватало, так что может кому-нибудь еще этот текст пригодится.

Здесь waterfall - делаем детальный дизайн, а по дизайну делаем готовый продукт. Agile - делаем черновой вариант дизайна, начинаем делать продукт, как только сталкиваемся с неприятностями из реального мира, которые в дизайне не учли, возвращаемся, меняем дизайн, потом код.
Некоторые люди громко кричат, что waterfall не работает. Я этих людей прекрасно понимаю, им нужно книжки по agile продавать и платные тренинги проводить. Но если бы это было правдой, многих вещей просто не существовало бы.
Здесь я немного отвлекусь и напомню, что программирование - это инженерная специальность (computer science я не рассматриваю, там немного другие материи). Мне нравится ходить за метафорами к другим инженерам, так получается и забавнее и проще.

Давайте представим, что waterfall и правда не работает, толпа рабочих увлеченно строит многоэтажный дом итеративным методом, меняет дизайн фундамента, когда 2-3 этажа уже выстроено. Но ведь нет. Там хитрые инженеры как-то делают хороший дизайн с первого раза. И таких примеров много: самолеты, ракеты, корабли, орбитальные станции. Даже в сфере IT есть интеграционные проекты, миграции с одной системы на другую, и оно как-то работает. В чем секрет?
На самом деле все очень просто.
Для того чтобы сделать хороший waterfall проект нужно несколько инженеров, которые минимум 5 лет учились делать именно такие проекты, а потом еще несколько лет работали по той же специальности in the wild.
Что происходит в IT на самом деле? "Вот команда прекрасных авиаконструкторов, они вам сделают такой танк, как вы хотите".
Программист, занимавшийся СУБД, не сможет написать игру. Но кого это волнует? "Тыжпрограммист"!
Дальше может быть еще веселее, чтобы парочке хороших инженеров было веселее, им нанимают падаванов, работу которых нужно переделывать, и постоянно следить чтобы нигде не накосячили (в смежных сферах есть чернорабочие, и ничего). Со стороны заказчика обещают выделить эксперта, но эксперт очень занят, и в конце концов заказчик этим тыжпрограммистам кучу бабла платит, они должны быть профессионалами, поэтому будет Любочка, которая в случае чего будет консультироваться с экспертом. И проект, весело громыхая, несется прямо в ад. Под конец, если повезет, будет затяжной кранч, и тыжпрограммисты вытянут проект на своем горбу, переписав 80% кода за 20% оставшегося времени. Ах да, это все при условии, что в процессе разработки требования не будут меняться.

По моему в "Человеческом факторе" написано, что цена ошибки растет с развитием проекта, тоесть поправить баг в коде намного дешевле, чем поправить баг в дизайне. Это было правдой 20 лет назад, сейчас это правило работает не всегда. Waterfall до сих пор оправдан там, где стоимость продакшена очень высокая, настолько высокая, что можно вложить кучу денег в дизайн, и это все равно окупает продакшен. Раньше это было справедливо и для IT, но сейчас это не так. Разработка очень часто не стоит ничего, можно за неделю на готовых фреймворках сделать вполне годное web приложение. И теперь появляется вопрос, а стоит ли вкладывать кучу ресурсов в дизайн.
Как я уже говорил, разработчик СУБД не сделает игру, но с важной оговоркой: "с первого раза". Agile в этом случае это знаменитая циатата, которую приписывают Эдисону: "Я с успехом определил пять тысяч способов, которые никуда не годятся".
Дешевый продакшен дает огромное преимущество, можно сделать более качественный продукт, исходя из реальных проблем, а не выдуманных на стадии дизайна. Очевидно, чтобы продакшен был действительно дешевым, нужно просто писать меньше кода. Самый простой пример, пишем класс строки, понадобился trim left, делаем trim left, но не trim right, который на всякий случай. Еще один распространенный случай, когда программист оставляет возможности для неинтрузивного изменения кода, подключение плагинов, или что-то подобное. Я называю это защитное программирование, тоесть попытка защитить себя от изменения требований. При чистом agile подходе весь код можно рассматривать как что-то постоянно эволюционирующее, и писать исходя из текущей ситуации, руководствуясь принципом меньше кода - лучше. Если продукт проживет довольно долго, то никакое защитное программирование не спасет код от обветшания. Но это и не значит, что можно говнокодить, технический долг никто не отменял, вне зависимости от методологий.
Как всегда, вообще ни к чему не стоит относиться догматично. Например авиаконструкторы делают самолет по waterfall (пока все не соберешь, оно точно не взлетит), но при этом они не гнушаются делать стенд для тестирования двигателя, проверять обтекаемость крыла в аэродинамической трубе и поменять его форму, и т.п.
Так же и с agile подходами. Все эти XP, SCRUM и прочие Kanban могут неплохо вставлять палки в колеса. Наиболее эффективные команды, которые я видел, создают свои собственные методологии, учитывая особенности работы, менталитет, заказчиков, рынок, etc.. Waterfall до сих пор живее всех живых, у нас он с успехом применяется для долгосрочного планирования, потом отдельные проекты разрабатываются итеративно.

Good coding, everyone.

Current Music: Deftones - What Happened To You?

(24 comments | Leave a comment)

December 2nd, 2014


12:24 am - AbstractFactoryCreator.CreateNewAbstractFactory("Moo"), или top down дизайн чмо
В Мире нет такого процесса, как т.н. top down дизайн, но давайте пофантазируем и представим, что он есть.
Предполагается, что мы начнем осмысливать систему сверху, постепенно спускаясь на уровень ниже, и еще ниже, описывая текущий уровень в терминах сущностей, которые характеризуют этот уровень, ниже и ниже, вплоть до деталей реализации.
Плохие новости: люди такого делать не умеют в принципе. Мы можем дробить сущность на составляющие, но с одной оговоркой - мы до этого мы уже собирали эту сущность из деталей. "Слон состоит из ушей, хобота и бегемота" (c)
В процессе задействуется предыдущий опыт, ассоциативное мышление и механизм аналогий, но результат скорее вредит, чем приносит пользу. При таком подходе доминируют абстрактные сущности и появляются ложные, которые не имеют никакого отношения к поставленной задаче. Концепции, на первый взгляд кажущиеся такими стройными, с треском разлетаются о суровую действительность.
Само собой, опыт играет важную роль, и какие-то вещи можно просто угадать, но это не имеет никакого отношения к дизайну. С другой стороны опыт может сыграть и злую шутку. Например человек, работающий с финансовыми системами, неглядя придумает "account". А ведь может получиться так, что в рамках поставленной задачи плательщик и получатель денег будут настолько разными сущностями, что иметь вместо этого одну выльется в тысячи строк boilerplate code.

Я вот такое встречал in the wild:


class Foo {
    void bar() {
        if (this.type == 1)
            do_1();
        else if (this.type == 2)
            do_2();
    }
};



Бывает даже еще хуже:

class Foo {
    void bar() {
        if (this.type == 1)
            dynamic_cast<Derived1>(this)->do_1();
        else if (this.type == 2)
            dynamic_cast<Derived2>(this)->do_2();
    }
};



В итоге то, что принято называть top down дизайн - это "топ хрен знает куда", и не дизайн. Подобный подход можно использовать для brainstorming. Но это не дизайн! Ни в коем случае нельзя тащить сущности, рожденные таким образом, сразу в код, какими бы стройными они не казались.
Лучше всего проектировать систему в терминах сценариев использования, т.е. сообщений. При таком подходе вырисовывается абсолютно понятный data flow, а ключевые компоненты (классы, модули) появляются сами собой. Самое главное, что при моделировании сценариев, роли компонентов очевидны, и эти роли можно обосновать.
Sequence диаграмма дает представление о системе, в отличие от сухой диаграммы классов, и что самое главное - "косяки" с большой долей вероятности проявятся на этапе проектирования (чего мы собственно и хотим). Намного легче понять, что сценарии взаимодействия сложные, чем то, что диаграмма классов не соответствует действительности.

Давайте покажу еще один пример плохого дизайна.

Вот пишем мы, значит, С++ обертку над С библиотекой:

class DatabaseConnection {
public:
    // ...
    void connect(string host, short port) {
        if (db_connect(ctx, host.c_str(), port) != 0) {
            throw DatabaseError(db_get_last_error());
        }
    }

    void execute(string sql) {
        if (db_exec(ctx, sql.c_str(), sql.size()) != 0) {
            throw DatabaseError(db_get_last_error());
        }
    }

    void commit() {
        if (db_commit(ctx) != 0) {
            throw DatabaseError(db_get_last_error());
        }   
    }

    void rollback() {
        if (db_rollback(ctx) != 0) {
            throw DatabaseError(db_get_last_error());
        }   
    }
private:
    struct dbconn_ctx * ctx;
};



Вопрос: что не так с этим кодом?

[Та вроде все ок]


99% случаев использования этого класса:

void StoreSomethToDB(DatabaseConnection & connection, const Someth & superdata) {
    try {
        connection.execute("INSERT INTO t1 .... ", ....);
        connection.execute("INSERT INTO t2 .... ", ....);
    } catch (const DatabaseError &) {
        // наблюдаем за руками
        try {
            connection.rollback();
        } catch (...) {
            // да мне насрать на самом деле, мне нужно откатиться, вот и все!
        }
    }
}



Спустя какое-то время кто-нибудь все же напишет функцию rollback_nothrow(DatabaseConnection &), где-нибудь в отдельных утилитках, но это уже совсем другая история.

Так происходит, потому что не учитываются сценарии взаимодействия, на первый план выходит механизм аналогий (наш мозг, кстати, постоянно пытается снизить когнитивную нагрузку путем обобщений, механизм, хоть и рабочий, но дает много false positive)



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

UML Class Diagrams - NOT BROS. Их можно выбросить на помойку, они не говорят ровным счетом ничего, но глядя на них можно придумать что-нибудь вроде AbstractFactoryFactory.
UML Sequence Diagrams - BROS. Они раскрывают структуру системы, провоцируют проектировать систему в терминах data flow, когда у сущности single responsibility, а сами сущности - черные ящики.
(В этом месте функциональщики ехидно улыбнулись)
Домашнее задание:
Вспомните boilerplate код в вашем продукте и подумайте откуда он появился. Если в вашей кодобазе нет ничего лишнего, обязательно похвастайтесь этим в комментариях.

Current Mood: okayokay
Current Music: Keith Jarrett - La Scala

(27 comments | Leave a comment)

D.Rider on everything

> Recent Entries
> Archive
> Friends
> Profile
> previous 15 entries

> previous 15 entries
> Go to Top
LiveJournal.com