Как стать автором
Обновить
12
0

Пользователь

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

Есть 3 основных режима:
Focus, Relax, Sleep. И в каждом из них еще подразделы по душе.

Из плюсов:
1) Есть текущий шум не подходит (ну не ложится именно сейчас на ритм), то есть возможность включить «то же самое, но другое».
2) Никаких агрессивных продаж. Простенькая подписка, и то списывает как-то через раз.
Никаких допфич, мега планов, рекламы, ни разу не встретил даже попытку повысить чек с меня. В вашем нынешнем мире — это очень ценно.

www.brain.fm
apps.apple.com/us/app/brain-fm-focus-music/id1110684238
Мы для реиндексации всегда используем фоновые задачи.
Если что-то пошло не так, реиндексация не прошла, фоновая задача через 1,2,3,5,8… секунд попробует еще раз и в итоге дореиндексирует.

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

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

Вы имеете права написать «я сторонник толстого common», а я имею права написать комментарий: «я считаю, что толстый common — антипаттерн».
И еще раз: не «тот, кто делает толстый common — дурак», а «я считаю, что толстый common — говно».

И да, мы живем в разных вселенных. Вы судя по всему любите SOLID, DIP, OCP, LSP…
А я их терпеть не могу. Почему? Потому что, я не видел еще ни одной группы разработчиков более 5 человеков, которые бы одинаково трактовали и применяли эти принципы.

Вот с тем, что миграции БД надо делать откатываемыми никто не спорит.
С тем что на больших нагруженных системах API должен быть идемпотентным, а на маленьких по желанию — тоже. Не все делают, но никто не спорит. Никто не спорит с тем, что пользовательский ввод надо валидировать, и еще с кучей других нормальных подходов.

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

И для меня если разработчик аргументирует свое решение только «ну потому что DIP» — то это не аргумент. Если разработчик не может без всяких аббревиатур обосновать своё решение, то кажется у него нет внятных и веских причин зачем он так сделал.

Для меня фраза: «ну потому что DIP» — это тоже самое что фраза «ну потому что алюминий». Алюминий отличный металл, из него делают самолеты, иногда машины,
а еще ложки, миски, фляжки, пищевую фольгу, банки для пива и еще кучу полезных вещей. Но «ну потому что алюминий», извините, не аргумент. И аналогично, «ну потому что SOLID/DIP/OCP/LSP/etc» — для меня тоже не аргумент.

Кстати рекомендую статью про применение этих принципов самим Робертом Мартином. В его же книге «Чистый код». Очень интересно. И очень интересные комментарии.

Ну и да, у нас разные подходы.
У Вас
при малейших намёках на реюзаемость компонента тащу его в common
. А у меня
должны быть очень веские причины, чтобы тащить код в common. Сначала напиши повторяемый код 7 раз. Заставь его работать. Покрой тестами. И только после этого, если всё еще есть желание вынести что-то в common — то тогда можно это сделать


Мы разные и это прекрасно)
Это все красиво на примере из трёх понятных доменных областей, в каждой из которой есть все слои. А когда их 20-30-50-100? У половины один набор слоёв, у другой половины другой набор слоёв.

Что проще поддерживать в одном стиле?
100 доменных областей? Это невозможно, они все разные, у них у всех будет разный набор файлов, в одном будут ServiceObject в другом FormObject, в итоге все они будут написаны по своему, по разному(((

Намного проще поддерживать
— 50 контроллеров API в одном стиле
— 70 моделей в одном стиле
— 90 services в одном стиле

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

Что проще сделать:
— открыть папку app/controllers/api/ и проверить/подправить в ней 30 файлов на предмет изменений
или
— пройтись по 70 папкам с доменной областью, проверить, есть ли в них контроллер который для API и если есть, то что-то проверить/подправить?

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

А еще разделение на
— models
— controllers
— services
— routes
— views
одинаковое для всех веб-проектов и задается обычно фреймворком.
В этом его плюс. Открыл любой проект с MVC архитектурой — сразу ясно, что где лежит.

А разделение на доменные области — это поле для бескрайней фантазии, которое увы, обычно превращается в адский ад, и прийти на такой проект очень и очень сложно.
Спасибо за развернутые комментарий.
Просто для меня в приложении методы вроде
process_result_value
where_clause_iter
where_clause
__getattribute__


и классы вроде
FutureSelectWrapper

как красная тряпка для быка.

На мой взгляд существует две цели написания кода.
Первый — написание библиотеки/пакета/плагина/либы
Второй — написание приложения.
И IMHO они должны быть написаны по разному.

Библиотеками пользуются тысячи и миллионы проектов, они поддерживаются, они должны быть универсальными. Хорошая библиотека спроектирована в среднем лучше, чем среднее приложение. Если библиотеке 10 лет и все 10 лет она поддерживается, то шансов что ее и дальше будут поддерживать достаточно много. В библиотеке важно, чтобы ей было удобно пользоваться, и действительно очень важна универсальность. Поэтому внутри приходится писать всякие методы вроде __getattribute__ и т.д.

Приложение — это наоборот частный случай. Самый частный случай. В приложении конкретные сущности, конкретные запросы, конкретные пользователи с конкретным поведением. А еще в приложении средний срок работы программиста 1,5 года.

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


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

Кстати, пример из жизни:
Подключают провайдера данных. Конечно же хочется надо сделать универсально. И разработчик делает универсальный набор классов, который позволит удобно подключать новых провайдеров. Позаботился о будущих поколениях.
А потом подключают второго провайдера, потом подключают третьего провайдера. Это делают другие разработчики.
И знаете что в приложении после этого? Три разных универсальных набора подключателей провайдеров. И три провайдера, каждый из которых подключен через свой универсальный подключатель провайдеров. Каждый написан по своему, в каждом есть свой набор методов вроде process_request, свой стиль, свой набор параметров, свой BaseClass, весь набор наследования, полиморфизма и т.д.
Смешно? Нет. Грустно. Лучше бы написали три раза не универсальный код. Кода было бы в 6 раз меньше (проверено, когда удалил все универсальные подключатели, стало кода в 6 раз меньше и никакой универсальности).

Судя по вашему ответу на следующий комментарий:
Всё это можно сделать в 1 запрос к БД

Мне кажется, что цель «сделать всё в 1 запрос» — это первичная цель. Не удобный поддерживаемый код. Даже не производительность. А именно сделать из трех запросов один, потому что три это «долго и много». Плюс сразу вернуть нужный набор полей и нужный формат. Нет, три простых запроса — это не много, и нет это не долго. Как раз простые запросы в одну таблицу отлично кешируются на уровне БД. База с этим сама отлично справляется.

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

И потом если мы выдаем пользователю ленту с товарами, ничто не мешает нам запросить 25 товаров вместо 20, и перед выдачей проверить, что все они например в наличии.

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

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

1. Самые частые запросы к БД это что-то вроде
SELECT users . * FROM users WHERE users . id = ? LIMIT ?

или
SELECT currencies . * FROM currencies WHERE currencies . id = ? LIMIT ?


Дальше идут чуть сложнее запросы вроде:
SELECT SUM ( transactions . amount ) FROM transactions WHERE transactions . account_id = ? AND transactions . type = ? AND transactions . state = ?


Потом идут простые JOIN чтобы избежать N+1 в табличках.

На примере десятков крупных проектов в веб, с ORM — такие запросы к базе составляют 80% по коду, и 99% по количеству запросов к базе. И это не моя фантазия. Это аналитика, которую выдает мне тот же datadoghq, который собирает статистику по всем запросам к БД. И нет, это не простые проекты. Это проекты, где 100+ таблиц в БД, с сотнями foreign_key и сотнями индексов.

Поэтому утверждение автора
Пример крайне примитивен — он даже без подзапросов. Кажется, в моём текущем проекте таких запросов единицы.

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

2. Проект с небольшой командой разработчиков (человек в 5 максимум) уже через пару лет имеет сотню/другую routes к приложению. Клиентская часть, API, админка, и на каждую сущность CRUD + Index + Search + Filter. И 95% запросов должны быть очень и очень простыми, потому что они делают очень и очень простые вещи. И ORM как раз тут наш лучший друг.
current_client.orders.paid.last(default_limit)

превращается в
 SELECT "orders".* FROM "orders" WHERE "orders"."client_id" = ? AND "orders"."state" = ? ORDER BY "orders"."id" DESC LIMIT ? 


и ORM как раз помогает нам кратко, с учетом наших классов и сущностей писать запросы в базу более читабельно, понятнее и быстрее. И в 99% случаев делает именно то, что нам нужно. Лишь единицы запросов требуют какого-то шаманства. В таких случаях чистый SQL частенько даже лучше чем ORM. Но опять же, таких случаев единицы.

3. Теперь про комбинаторных взрыв. Реляционные БД хороши связями между таблицами. Foreign key наше всё. Именно реляционные БД дают нам уверенность в консистентности данных.

Например в интернет-магазине
— у order_items есть order_id
— в таблице orders точно есть запись с этим id
— и в ней точно есть client_id
— а в clients есть точно запись с этим client id и т.д. и т.п.
И мы можем спокойно писать тысячи строк кода, с уверенностью, что если у нас есть order_item то у него точно если order_id, client_id, и еще куча нужных нам данных в нужном нам формате.

И если мы уперлись в производительность, то зачем насиловать нашу реляционную БД?
Она хороша для другого.

А вот для того, чтобы быстро отдавать данные по разным фильтрам — подходит тот же ElasticSearch.
Построил индекс используя десятки таблиц, и дальше очень быстро ищешь с помощью него. Elastic возвращает нам массив ID товаров, которые подходят под условия, мы идем с этим массивом ID в нашу реляционную БД и с простыми JOIN по ID дергаем наши данные для того, чтобы отобразить их пользователю. ВСЁ. Никакого комбинаторного взрыва. Простейшее горизонтальное масштабирование. Как по Elastic, так и по реляционной БД.

Миллионы записей в основной таблице, десятки таблиц из которых собирается индекс для Elastic и бешенная производительность со всеми хотелками вроде «тут ищем только по точному совпадению», тут «по 4 символам», тут «по 3 символам, но только с начала». И т.д.

Под клиентскую часть — свои индексы со своим набором полей.
Под админку — свои индексы со своим набором полей.

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

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


Никогда еще в моей практике эта мотивация не приводила ни к чему кроме ада) И очень много раз я разгребал эту «хитрозакрученную логику». Всё должно быть очень просто, так что аж скучно. Читаешь код, и аж тошно, от того как всё скучно) Зато всё работает. Быстро. Просто. Надежно.
А можно поставить 10+ ?)
Спасибо за статью. Очень интересно. Вы раскрыли очень интересный этап: как всё начиналось с десятков тонн, и как быстро доросло до десятков тысяч тонн, и далее до сотен тысяч тонн.
Спасибо! Согласен на все 100%!

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

Что входит, что где лучше, куда лучше например усилия Product Manager в стартапе, а куда бизнес-аналитику в суровом Enterprise
+1)
А еще взаимодействие с разными типами игр. У mail.ru были статьи, где они хорошо разбирали сегментацию и подгонку игры под разные типы игроков

habr.com/ru/company/mailru/blog/274263
habr.com/ru/company/mailru/blog/263839

Экономика игры это и стоимость привлечения игрока, и сколько денег он приносит, и виральность, LTV и т.д.
Есть отличная поговорка:
Когда встречается два человека: один с деньгами, другой с опытом, то тот, который с опытом — уходит с деньгами, а тот кто был с деньгами — уходит с опытом.

А истории 100 -> 400, это про истории когда кто-то заходит на рынок и с деньгами и с опытом. И судя по истории Шиллинг пришел в рынок с деньгами и без опыта)
Спасибо за статью. Кажется что все в мире любят иллюзии.

Ждать от бейсболиста успеха в геймдеве — тоже самое, что ждать от программиста успеха в бейсболе.

Давайте возьмём гениального программиста, дадим ему тренеров, массажистов, команду и будем ждать, что он выиграет чемпионат мира, олимпиаду или мировой турнир. Глупо?) А про бейсболиста, который вложил $50млн в революционную игру — не глупо?)

Это не означает, что спортсмен не может стать успешным предпринимателем. Конечно может. Только делают это успешные люди постепенно и последовательно, точно так же как и в спорте.

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

А тут, с наскока, не студия по выпуску маленьких игр, а сразу производство «революционной игры», $5млн в офис, лучшие таланты, нам нужные лучшие из лучших и т.д. Поэтому в целом результат предсказуемый.

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

Сотрудники заработали, банки заработали, создатели красивых офисов и думаю еще чертова туча людей заработали на всей этой истории. Потерял сам Шиллинг и те, кто дал ему кредит, который студия никогда не вернет.
Согласитесь, что формулировка:
«Если у вас много легаси и у вас принято решение поддерживать его, то в рамках периода этой поддержки использовать RPA может быть разумно»
несколько отличается от
«RPA как основа IT архитектуры, которая победит Микросервисы»

P.S. Я вообще не сторонник микросервисов. И считаю, в 9 из 10 случаев переход на микросервисную архитектура вредит. А RPA в контексте очередной волшебной таблетки я считаю еще бОльшим злом. Сам подход RPA может быть ок, но вот подача этого подхода как «Основа архитектуры», которая «Решит вашу боль» — это откровенное вредительство и введение в заблуждение.
Вот именно! Выиграть временно. То есть RPA — это временное решение. Согласен. Но согласитесь, что называть временное решение основой архитектуры — хреновая идея. Это как сказать, что антибиотики — это основа иммунитета, что капельница с глюкозой отлично подходящая в ряде случаев — основа правильного питания.

Просто разработчики/девелоперы имеет непосредственное дело с последствиями этих попыток выиграть время.
Почитал еще несколько статей по RPA

Сама идея хорошая:
Что-то спарсить. Откуда-то быстро собрать данные.
Как «сесть на трубу процесса» для его изучения и оптимизации — отличная штука.
Шикарная штука для внедрения изменений: сели на процесс «сбоку», автоматизировали, поняли какие данные есть, каких не хватает, оптимизировали процесс, доказали бизнесу эффективность и передали в разработку.

Но вот только не надо говорить что роботы, которые через интерфейсы как боты взаимодействуют со старым неэффективным неудобным интерфейсом — это основа хорошей архитектуры. Если текущая команда не может хорошо справиться со старой архитектурой, то старая архитектура + роботы поверх этого всего — это смерть. После появления роботов вносить изменения станет вообще невозможно. Особенно если они сядут где-то на интерфейсы, где-то на API. И судя по всему еще и будут сделаны какой-то внешней командой или под управление внешних «консультантов по RPA».

Представим задачу:
Маленький европейский городок, очень узкие улочки, нет железных дорог, в радиусе 1000 км нет ни одного грузовика, и надо срочно перевезти 20 тонн в 30-килограммовых мешках.
И тут вдруг мы обнаруживаем, что в городке есть очень дружная тусовка автолюбителей. И они как раз собираются в автопробег в нужном направлении, и можно в каждый из автомобилей накидать мешков, и вся колонка отлично перевезет наш груз. Командный дух, польза для города, задача решена, не надо решать сложные вопросы с грузовиками, нет нагрузки на наш старенький мост 15 века, не будет перекрыта дорога для погрузки и вообще всё прошло на ура. Фанфары, салют, все молодцы, задача решена!!!

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

Вот и с RPA так же. Шикарное решение, чтобы быстро собрать данные, что-то проанализировать, собрать прототип, и выкинуть. И IMHO называть это основой IT архитектуры — это уже вредительство)

Автору спасибо за статью.
Переводчикам спасибо за перевод.


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

Мой опыт показывает, что глаголы должны быть убраны из описания предметных областей.
Они всегда всё портят. Нужно оставить только один глагол: TO BE

Есть студенты.
Есть курсы.
Есть посещения студентом курса. (Это отдельный класс, а если речь про БД, то это будет таблица где будут например данные: id, student_id, course_id, date, time)
То есть нет никакого «Журнала посещаемости», который имеет записи. Есть просто ПОСЕЩЕНИЯ.

И тогда да, у вас у студента будут student.visits, у курса будут course.visits

И это всё прекрасно работает. Если вам хочется пересечения, то это уже отдельный объект/класс/таблица БД и т.д.

И кажется, что это не зависит от языков программирования. Так просто удобно. Если мы говорим про объекты, то надо говорить про их объекты и их свойства.
С Python интересная ситуация. Мне кажется в сообществе Python-разработчиков не очень модно занимать веб-разработкой. Data Science, AI, ML — вот трушные области работы для питониста. А в Ruby как: хочешь писать на Ruby — занимаешься веб-разработкой.

И поэтому (по-моему личному опыту) средний опыт питониста в веб-разработке ниже, чем у рубистов. И еще ниже, если речь идет о fullstack разработке. А именно о ней шла речь в статье. Ведь для того, чтобы хорошо разобраться в беке нужно время. А если потом еще добавить фронтовые webpack, postcss, linters, yarn, tree shacking, etc — то нужно еще больше времени.

И по-моему личному опыту, средний проект на Rails сделан лучше, чем средний проект на Django. Последние два проекта на Django, которые мне довелось смотреть были сделаны без git (точнее первичный git clone есть, а дальше вялые и брошенные попытки вести git c последним коммитом больше года назад), и все равно с диким хламом в репе (вроде node_modules, паролей, secrets), без тестов, без деплоя, с загрузкой кода по ssh и т.д.

Я в Rails проектах многое видел, но такого никогда не видел)
Спасибо за статью. Такая ситуация не только в PHP.

В Ruby сообществе последнее время еще модно пилить все на микросервисы, переписывать все на монады, сервис-объекты, 12factorapp и т.д. Архитектура ради архитектуры, программирование ради программирования.

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


Информация

В рейтинге
Не участвует
Откуда
Москва, Москва и Московская обл., Россия
Дата рождения
Зарегистрирован
Активность