Pull to refresh

Comments 28

Наброс про скази не понял. Нормальная машина состояния на низком уровне (а никакого другого уровня в драйвера не завезли).

Желаю успехов переписать это без goto (break и continue это тоже goto) с условием не использовать стек значительно больше, чем в приведённом примере (стек в ядре совсем не резиновый).

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

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

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

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

Ну бесконечный цикл постоянной занятости процессора в первых трёх строчках – это не вершина программистской мысли, с какой стороны ни посмотри. Или чем, к примеру, замечательно число 0x30000?

Очень многие драйверы – чудовищный кошмар внутри, и не только в линуксе.

Оооо, это вы ещё ембеджед не видели. Кофеварки, какие-нибудь.

Так то goto без проблем заменяется стандартными условиями, циклами да менеджерами контекста, было бы желание.

Статья понравилась, но хотелось поподробнее про Mushroom management, примеры последствия и т.д.

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

Ну вот простой пример, который везде наверное можно встретить. Переходим с продукта N на M. Старый продукт был интегрирован с другими системами и прекрасно отдавал данные, но по текущим временам по-старому, файликами. Для нового продукта и интеграция новая пишется, на основе "кролика". Все замечательно, только уже никто не помнит и не знает как данные ходили и трансформировались по пути. Аналитики этого не видят в глубинах кода и задача ставится примерно так : "Сделать обмен данными как было" =)

И вот сидишь, читаешь тонны старого кода просто чтобы понять что от тебя надо.

Прилетает одна задача "не работает сортировка. должна работать так", и тут же прилетает другая от другого человека тоже по сортировке, но условия иные.

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

Каждый раз когда я читаю таки статьи у меня вопрос, все же понимают что производительный код и код соблюдающий кучу принципов удобной архитектуры это почти всегда разный код. И компания должна понимать, за что она готов платить и что она получит. И не устаю приводить шикарный пример файла checker.ts из компилятора Typescript https://github.com/microsoft/TypeScript/blob/main/src/compiler/checker.ts. Это файл на 2.7 Мегабайта кода, в котором 2.5 тысячи функций объявленный словом function и ещё около тысячи стрелочных замыканий. Его даже гихаб отобразить нормально не может. Этому файлу больше 10 лет, он активно развивается. Больше 5 лет назад я предлагал способ его распилить https://github.com/microsoft/TypeScript/issues/17861 Распил приводит к потере производительности. Команда отказалась. Они готовы платить ту цену которую стоит поддержка такого файла для одной цели: скорости работы компилятора.

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

И очень тонка разница между безумием и следованием стратегии которая идёт против ветра современных веяний качества программного обеспечения.

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

А так принципы как раз и позволяют получать производительный или хорошо поддерживаемый код (не всегда одновременно, к сожалению. C'est la vie)

Нет, я с вами не согласен. Нет другой такой архитектуры которая бы позволила добиться такой скорости. Это давно измерено и известно, в JS обращение к замкнутой переменной быстрее чем к свойству объекта. И на данном масштабе это становится значимым. Не переписать это лучше с наскока. А Джоэл Спольски уже 23 года назад написал про то, что взять и всё переписать, это худшее что может предпринять любой большой проект https://habr.com/ru/articles/219651/

Вы слово "перепроектировать" от слова "переписать" отличаете? Переделывать плохое - плохое и получишь. Это ж очевидно! Плохое надо понять, отбросить и на основе выработанного понимания сделать новый проект - лучше (если получится). Но это долго и дорого, естественно - потому не всегда целесообразно.
По тем же замыканиям - вопрос не в том, что они быстрее (есть много способов это использовать), а в том что есть тысяча переменных/функций друг с другом связанна так, что их нельзя по разным файлам раскидать. Не проведена банальная декомпозиция. Архитектурная. Не выделены смысловые независимые множества. Проводить её - это не просто что-то там по модулям раскидать. Это переписать вообще всё.
А заниматься улучшайзингом ради улачшайзинга не имея более-менее точно измеримой цели (уменьшить размер исходного файла - это не цель разработки) - вот это антипаттерн.
Вот конкретно в вашем случае - требования к скорости явно были и до того как вы принялись править? Верно? И они были приоритетнее поддерживаемости, так? Так зачем вы вообще этим занялись, если заранее можно было понять, что по цели вы сделаете хуже а не лучше?

Не проведена банальная декомпозиция. Архитектурная. Не выделены смысловые независимые множества

это сделано сознательно. Разделение стейта чекера приведёт к деградации производительности.

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

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

Потому что точной цифры не было. Её узнали.

Просто авторы совершили фатальную ошибку, написал компилятор на жаббаскрипт и пытаясь потом выжать из него максимальную скорость - надо было писать его на C++ изначально и не извращаться )

В книге «Основы архитектуры программного обеспечения» Нила Форда ввели «Первый закон архитектуры программного обеспечения», который гласит: «Все в архитектуре программного обеспечения соткано из компромиссов».

Вот с этим согласен. И круто когда осознаются разные потребности и обоснованно одни приносятся в жертву в пользу других. К сожалению сегодня часто можно видеть фанатичное требование соблюдать какие-то архитектурные паттерны в угоду моде. Например, в какой-то момент все пихали mongo db во всё что можно и нельзя, просто потому что реляционная база это "старое медленное говно", благо сейчас потихоньку отпускать начало.

У нас в проекте один чел так из редиски БД сделал. Причём не просто класть туда данные, а как кэш-репозиторий. То есть запрашиваем, например, массив данных из таблицы - в редиску пойдут все строки из этой таблицы, причём, в один ключ кэша один документ. При повторном запросе идём в кэш и поштучно получаем идентификаторы...

Но и отказ от многих современных методов, которые действительно позволяют значительно сократить время разработки, повысив читаемость кода, тоже плохо и зачастую переходит грань фанатизма. Типа "новое жрёт много памяти" (спойлер: экономия на спичках), или "да 512 метров памяти для пыха на проде это слишком много - 128 метров норм", или "да зачем юзать плагин для IDE с хоткеями и уем - можно же консольную команду написать", и т.д.

Фанатизм в разработке как палка о двух концах: с одной стороны как отказ от нового, так и много этого неоправданного "нового" способно "выстрелить в ногу", так сказать. Здесь действительно главное уметь держать грань разумного.

В сфере разработки огромное количество паттернов и принципов, но предпочитаю руководствоваться всего одним:

Всегда пиши код так, будто поддерживать его будет неуравновешенный и склонный к насилию психопат, который знает где ты живёшь.

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

К сожалению, да. Но для личного роста очень даже помогает.

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

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

У вас акцент на плохих практиках разработки, а не архитектуры

Позвольте дополнить.

Top-1 плохой архитектуры - распределенный монолит. Все остальное просто меркнет на его фоне.

Исторически 3-6 лет назад половина вакансий в крупные нормально зарабатывающие компании в РФ были на распил монолита. У некоторых - получилось. Остальные же стали счастливыми обладателями распределенного монолита, со всеми вытекающими.

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

Sign up to leave a comment.