Как мы реализовали подписку на Хекслете
Долгое время обучение на Хекслете работало исключительно по подписке, поэтому эта часть системы была очень важной. Подписка в отличии от обычных платежей, довольно сложная штука, с кучей состояний начиная от неудачных попыток повторного списывания и грейс периода (когда деньги списать не получилось, но доступ еще остается так как будут другие попытки) заканчивая переходом по разным типам подписки. Честно говоря, реализация всех фич включая купоны, заморозку, переключение тарифов и другого, это страшная задача, которую совсем не хочется делать самостоятельно.
Как финская компания мы использовали страйп, который умеет делать практически все причем в довольно удобном формате. Но есть проблема, не все вопросы решаются только страйпом. Есть b2b который работает по другому, есть купоны которые работают не так как в страйпе, потом появились одиночные платежи за программу обучения. В этом случае мы не могли позволить себе завязывать полностью на возможности страйпа, так как пришлось бы вводить множество исключений, что вылилось бы в необходимость делать кучу разных проверок на то есть ли у человека доступ к разным элементам обучения. Поэтому нам пришлось придумать систему, которая достаточно простая в реализации, но при этом позволяет работать с разными способами получения доступа к обучению.
Концепция была в следующем, что с точки зрения платформы, должно быть не важно каким образом у человека появился доступ. Это может быть купон, страйп, доступ для друга, подарок, оплата через компанию и еще тысяча разных способов. Внутри платформы все это сводится к единому признаку “имеет доступ?”. Для этого мы придумали систему с днями доступа. Специальная таблица, в которую заносится любой доступ в виде дней. Например купил подписку на месяц (снялись деньги), получил 30 дней доступа (в зависимости от месяца). Дали купон на 10 дней, после активации туда заносится эта информация. С другой стороны, каждый день запускается скрипт, который списывает эти дни по одному. Фактически у нас получился аналог книги доходов/расходов в бухгалтерии.
Почему не даты. Если у вас есть фризы и всякие грейс периоды, это просто невозможно нормально делать учитывая что вам еще нужна историчность. Мы начали продумывать с дат, но чем дальше зарывались, тем больше становилось понятно что с датами не получится ничего именно из за всяких переходов, переносов и отмен. с днями кабздец как все просто, все имутабельно, добавление или вычитание это всегда новые записи в базе, а значит у вас всегда есть история и вам легко не только понять что произошло но и пофиксить
Эта система показала себя отлично, потому что биллинг внутри Хекслета отвязался от самой платформы. Добавления любого источника дней не влияет ни на что, кроме этой таблицы, которая выступает как медиатр между биллингом и платформой с ее проверками доступа. Кстати, потом нам пришлось прицепить cloudpayments, банковские кредиты, систему быстрых платежей, а сейчас мы еще и полностью уходим от страйпа. И сложившаяся система нас просто спасает, так как логика источников платежей сконцентрирована в одном месте.
Как-то раз я общался с Андреем Ребровым, который является СТО компании scentbird.com мы обсуждали с ним биллинг. Оказалось что они реализовали такую же схему, только у них были не дни, а недели или месяцы, сейчас уже не помню.
p.s. В ваших проектах есть подписки? Как они реализованы?
Долгое время обучение на Хекслете работало исключительно по подписке, поэтому эта часть системы была очень важной. Подписка в отличии от обычных платежей, довольно сложная штука, с кучей состояний начиная от неудачных попыток повторного списывания и грейс периода (когда деньги списать не получилось, но доступ еще остается так как будут другие попытки) заканчивая переходом по разным типам подписки. Честно говоря, реализация всех фич включая купоны, заморозку, переключение тарифов и другого, это страшная задача, которую совсем не хочется делать самостоятельно.
Как финская компания мы использовали страйп, который умеет делать практически все причем в довольно удобном формате. Но есть проблема, не все вопросы решаются только страйпом. Есть b2b который работает по другому, есть купоны которые работают не так как в страйпе, потом появились одиночные платежи за программу обучения. В этом случае мы не могли позволить себе завязывать полностью на возможности страйпа, так как пришлось бы вводить множество исключений, что вылилось бы в необходимость делать кучу разных проверок на то есть ли у человека доступ к разным элементам обучения. Поэтому нам пришлось придумать систему, которая достаточно простая в реализации, но при этом позволяет работать с разными способами получения доступа к обучению.
Концепция была в следующем, что с точки зрения платформы, должно быть не важно каким образом у человека появился доступ. Это может быть купон, страйп, доступ для друга, подарок, оплата через компанию и еще тысяча разных способов. Внутри платформы все это сводится к единому признаку “имеет доступ?”. Для этого мы придумали систему с днями доступа. Специальная таблица, в которую заносится любой доступ в виде дней. Например купил подписку на месяц (снялись деньги), получил 30 дней доступа (в зависимости от месяца). Дали купон на 10 дней, после активации туда заносится эта информация. С другой стороны, каждый день запускается скрипт, который списывает эти дни по одному. Фактически у нас получился аналог книги доходов/расходов в бухгалтерии.
Почему не даты. Если у вас есть фризы и всякие грейс периоды, это просто невозможно нормально делать учитывая что вам еще нужна историчность. Мы начали продумывать с дат, но чем дальше зарывались, тем больше становилось понятно что с датами не получится ничего именно из за всяких переходов, переносов и отмен. с днями кабздец как все просто, все имутабельно, добавление или вычитание это всегда новые записи в базе, а значит у вас всегда есть история и вам легко не только понять что произошло но и пофиксить
Эта система показала себя отлично, потому что биллинг внутри Хекслета отвязался от самой платформы. Добавления любого источника дней не влияет ни на что, кроме этой таблицы, которая выступает как медиатр между биллингом и платформой с ее проверками доступа. Кстати, потом нам пришлось прицепить cloudpayments, банковские кредиты, систему быстрых платежей, а сейчас мы еще и полностью уходим от страйпа. И сложившаяся система нас просто спасает, так как логика источников платежей сконцентрирована в одном месте.
Как-то раз я общался с Андреем Ребровым, который является СТО компании scentbird.com мы обсуждали с ним биллинг. Оказалось что они реализовали такую же схему, только у них были не дни, а недели или месяцы, сейчас уже не помню.
p.s. В ваших проектах есть подписки? Как они реализованы?
👍61🔥23❤6🤔1💘1
Почему плохой код? Потому что мы стартап
Очень часто плохой код и архитектура оправдывается тем что мы стартап, а значит надо все быстро и мы не успеваем делать хороший код. Доля правды в этом есть, но все же не настолько насколько это обычно бывает.
Если мы говорим про создание типовых веб-проектов, то у нас все достаточно просто. Современные фреймворки и их экосистема, позволяют без особых затрат и сложностей реализовывать проекты достаточно приличных размеров. Что для этого нужно? Модели, контроллеры и вьюхи/фронтенд, по большому счету все. Какой-то серьезной архитектуры тут еще нет, все сводится к тому что надо тратить немного времени на продумывании сущностей и их связей, это главная задача. А дальше как-то мы все это обрабатываем в контроллерах, выводим во вьюхах или отдаем по api. То насколько код здесь чистый не принципиально, а принципиальны две вещи:
⁃ Сущности и их связи. Фактически тут мы говорим о перекладывании модели предметной области на код. Здесь нужно немного думать вперед.
⁃ Структура API. Важно не облажаться с форматом, чтобы потом не пришлось переделывать. Менять публичное апи это еще та попаболь.
⁃ Идеально еще интеграционное тестирование, которое полезно даже в стартапах, так как не сильно зависит от внутренностей (об этом были свои посты)
Если программист опытный и имеет успешный опыт создания веб-проектов, то для него это не будет большой проблемой. А остальные абстракции, например сервисы, могут не понадобится еще долго. Проект на добрую сотню тысяч строк кода может легко жить без всего этого на паре тройке программистов.
Но кое-кто со мной не согласится. Что ж, я наблюдал немало проектов где были подобные жалобы и участвовал в выводе этих проектов из задницы. Вот некоторые причины, по которым проекты на начальной стадии вводились в паралич:
⁃ Сразу включаем микросервисы. Хаха, мое любимое. Будет отдельный пост
⁃ Забиваем на возможности фреймворков и пилим все сами. Вплоть до игнорирования ORM
⁃ Плохое знание экосистемы. Как ни странно даже среди вроде бы синьоров такое встречается. Пилят то, что уже напилено в виде библиотек. А иногда это “у нас не должно быть зависимостей” и дальше пилим все сами
⁃ Непонимание концепции автоматов и моделирования процессов на их базе. Бывает такое что интуитивно делают правильно, но часто делают не правильно
⁃ Использование необкатанных и не популярных инструментов, где еще как не в стартапе воткнуть светл?
⁃ Какие-то установки типа: 100% покрытие, на любой чих юнит-тест, вся логика в моделях, юзаем graphql, вводим три слоя абстракций, используем ddd, без паттернов жизнь не жизнь, внедряем event source и так далее.
Я видел ситуацию, когда ребята в стартапе написали фреймворк поверх jquery, потому что реакт слишком навороченный, а нам надо по проще. При том что люди которые это сделали, регулярно выступали на конференциях с докладами как писать и рефакторить код.
p.s. По каким причинам в ваших проектах плохой код?)
Очень часто плохой код и архитектура оправдывается тем что мы стартап, а значит надо все быстро и мы не успеваем делать хороший код. Доля правды в этом есть, но все же не настолько насколько это обычно бывает.
Если мы говорим про создание типовых веб-проектов, то у нас все достаточно просто. Современные фреймворки и их экосистема, позволяют без особых затрат и сложностей реализовывать проекты достаточно приличных размеров. Что для этого нужно? Модели, контроллеры и вьюхи/фронтенд, по большому счету все. Какой-то серьезной архитектуры тут еще нет, все сводится к тому что надо тратить немного времени на продумывании сущностей и их связей, это главная задача. А дальше как-то мы все это обрабатываем в контроллерах, выводим во вьюхах или отдаем по api. То насколько код здесь чистый не принципиально, а принципиальны две вещи:
⁃ Сущности и их связи. Фактически тут мы говорим о перекладывании модели предметной области на код. Здесь нужно немного думать вперед.
⁃ Структура API. Важно не облажаться с форматом, чтобы потом не пришлось переделывать. Менять публичное апи это еще та попаболь.
⁃ Идеально еще интеграционное тестирование, которое полезно даже в стартапах, так как не сильно зависит от внутренностей (об этом были свои посты)
Если программист опытный и имеет успешный опыт создания веб-проектов, то для него это не будет большой проблемой. А остальные абстракции, например сервисы, могут не понадобится еще долго. Проект на добрую сотню тысяч строк кода может легко жить без всего этого на паре тройке программистов.
Но кое-кто со мной не согласится. Что ж, я наблюдал немало проектов где были подобные жалобы и участвовал в выводе этих проектов из задницы. Вот некоторые причины, по которым проекты на начальной стадии вводились в паралич:
⁃ Сразу включаем микросервисы. Хаха, мое любимое. Будет отдельный пост
⁃ Забиваем на возможности фреймворков и пилим все сами. Вплоть до игнорирования ORM
⁃ Плохое знание экосистемы. Как ни странно даже среди вроде бы синьоров такое встречается. Пилят то, что уже напилено в виде библиотек. А иногда это “у нас не должно быть зависимостей” и дальше пилим все сами
⁃ Непонимание концепции автоматов и моделирования процессов на их базе. Бывает такое что интуитивно делают правильно, но часто делают не правильно
⁃ Использование необкатанных и не популярных инструментов, где еще как не в стартапе воткнуть светл?
⁃ Какие-то установки типа: 100% покрытие, на любой чих юнит-тест, вся логика в моделях, юзаем graphql, вводим три слоя абстракций, используем ddd, без паттернов жизнь не жизнь, внедряем event source и так далее.
Я видел ситуацию, когда ребята в стартапе написали фреймворк поверх jquery, потому что реакт слишком навороченный, а нам надо по проще. При том что люди которые это сделали, регулярно выступали на конференциях с докладами как писать и рефакторить код.
p.s. По каким причинам в ваших проектах плохой код?)
👍31🤣10🫡6👏4❤3🤔1
Через полчаса стартую новогодний стрим, где покажу все что скрыто. Новости Хекслета, как прошел год, что будет в следующем. Немного про канал, немного про программирование, отвечу на вопросы и вот это все https://www.youtube.com/watch?v=RgZ-YsDuibc
YouTube
Хекслет и 2023: эфир с Кириллом Мокевниным / Внедрение ChatGPT в онлайн-курсы, планы и разработка
✅ Полезные вебинары по программированию каждую неделю: https://ru.hexlet.io/link/xNJY4I
Готовьте ваши вопросы – традиционный прямой эфир с сооснователем Хекслета Кириллом Мокевниным уже 27 декабря! Поговорим о новостях Хекслета за 2023 год, поделимся планами…
Готовьте ваши вопросы – традиционный прямой эфир с сооснователем Хекслета Кириллом Мокевниным уже 27 декабря! Поговорим о новостях Хекслета за 2023 год, поделимся планами…
❤19👍11🤔1
Итоги 2023 года
В этом году встречаемся последний раз, поэтому можно немного подвести итогов. За шесть месяцев я нафигачил 68 постов (ничо си) и вас, мои дорогие, стало 3500 человек. Учитывая что все это происходит в свободное время без каких-то вложений, то результат достаточно хороший, но пока еще никто не пришел с предложением продавать рекламу. Делать я этого не буду, но все равно обидно :D
В целом опыт классный и я буду продолжать. Единственное до конца непонятно в какую сторону сдвигаться. Канал в любом случае про программирование и связанные темы, но есть нюансы. В какой стек больше подаваться? Больше технических деталей или про концепции? Нужно ли обсуждать новости? Нужно ли делиться какими-то ситуативными вещами, типа что мы делаем на хекслете или с какими штуками я сталкиваюсь в работе? Нужно ли говорить про инструменты? Нужно ли переодически рассказывать про бизнесовую часть связанную с программированием (программисты с трудом выносят такие разговоры)? И так далее, пока не до конца определился и буду снова экспериментировать. Немного набросов, немного про жизнь, немного про принципы, немного про хардкор.
В конечном итоге, моя цель не в том чтобы просто выговориться, а в том, чтобы вы открывали для себя что-то новое, что влияло бы на ваше представление о программировании и внедрялось в ваши проекты. Я знаю что это иногда происходит, даже когда под постами разгорается много споров)
Всем спасибо за доверие! С наступающим! Я не планирую уходить на выходные, буду писать и дальше. Уже есть план на два десятка статей. Накидывайте своих тем, я буду их добавлять в список.
p.s. Если у вас есть свой канал на любой площадке, сбросьте ссылку на него в комментах с описанием. Давайте посмотрим кто у нас тут собрался)
В этом году встречаемся последний раз, поэтому можно немного подвести итогов. За шесть месяцев я нафигачил 68 постов (ничо си) и вас, мои дорогие, стало 3500 человек. Учитывая что все это происходит в свободное время без каких-то вложений, то результат достаточно хороший, но пока еще никто не пришел с предложением продавать рекламу. Делать я этого не буду, но все равно обидно :D
В целом опыт классный и я буду продолжать. Единственное до конца непонятно в какую сторону сдвигаться. Канал в любом случае про программирование и связанные темы, но есть нюансы. В какой стек больше подаваться? Больше технических деталей или про концепции? Нужно ли обсуждать новости? Нужно ли делиться какими-то ситуативными вещами, типа что мы делаем на хекслете или с какими штуками я сталкиваюсь в работе? Нужно ли говорить про инструменты? Нужно ли переодически рассказывать про бизнесовую часть связанную с программированием (программисты с трудом выносят такие разговоры)? И так далее, пока не до конца определился и буду снова экспериментировать. Немного набросов, немного про жизнь, немного про принципы, немного про хардкор.
В конечном итоге, моя цель не в том чтобы просто выговориться, а в том, чтобы вы открывали для себя что-то новое, что влияло бы на ваше представление о программировании и внедрялось в ваши проекты. Я знаю что это иногда происходит, даже когда под постами разгорается много споров)
Всем спасибо за доверие! С наступающим! Я не планирую уходить на выходные, буду писать и дальше. Уже есть план на два десятка статей. Накидывайте своих тем, я буду их добавлять в список.
p.s. Если у вас есть свой канал на любой площадке, сбросьте ссылку на него в комментах с описанием. Давайте посмотрим кто у нас тут собрался)
❤79🔥24🎄15👍12🤔1
Если бы я делал веб-проект с нуля
Меня регулярно спрашивают, на каких технологиях я бы делал проект если бы пришлось делать его с нуля. И у меня есть ответ на это. Он не универсальный, есть совершенно разные проекты, но так как нельзя охватить сразу все, я опишу некий средний проект, в котором есть веб-морда с большим количеством логики, скорее это какое-то SaaS-решение.
Базовым стеком я бы назвал:
Ruby On Rails, React, React Native
Дальше по приоритетам:
⁃ Система будет очень сложной с большим количеством программистов сразу? Spring Boot
⁃ Нужно много бекендовой тяжелой обработки? Go или Java
⁃ Нет экспертизы в руби? Берем Laravel или Django
⁃ Нужны нативные мобильные приложения? Тут все понятно: Swift и Kotlin
⁃ Нужен реалтайм на фронте (а значит асинхронный бекенд)? Node.js, Go
⁃ Нужно e2e тестирование? Playwright
Критерии достаточно простые. Не так важно что есть более крутые альтернативы, гораздо важнее распространенность и устоканенность экосистемы. Это дает возможность быстрее нанимать, быстрее двигаться, быстрее решать проблемы и понимать какие они вообще бывают (с новыми инструментами это становится сюрпризом). Еще важно кто стоит за технологией. Должны быть крупные ребята, которые вкладываются в нее иначе слишком большие риски, что она пойдет не туда/ее оставят и тому подобное
p.s. На чем бы вы сделали проект с нуля?
Меня регулярно спрашивают, на каких технологиях я бы делал проект если бы пришлось делать его с нуля. И у меня есть ответ на это. Он не универсальный, есть совершенно разные проекты, но так как нельзя охватить сразу все, я опишу некий средний проект, в котором есть веб-морда с большим количеством логики, скорее это какое-то SaaS-решение.
Базовым стеком я бы назвал:
Ruby On Rails, React, React Native
Дальше по приоритетам:
⁃ Система будет очень сложной с большим количеством программистов сразу? Spring Boot
⁃ Нужно много бекендовой тяжелой обработки? Go или Java
⁃ Нет экспертизы в руби? Берем Laravel или Django
⁃ Нужны нативные мобильные приложения? Тут все понятно: Swift и Kotlin
⁃ Нужен реалтайм на фронте (а значит асинхронный бекенд)? Node.js, Go
⁃ Нужно e2e тестирование? Playwright
Критерии достаточно простые. Не так важно что есть более крутые альтернативы, гораздо важнее распространенность и устоканенность экосистемы. Это дает возможность быстрее нанимать, быстрее двигаться, быстрее решать проблемы и понимать какие они вообще бывают (с новыми инструментами это становится сюрпризом). Еще важно кто стоит за технологией. Должны быть крупные ребята, которые вкладываются в нее иначе слишком большие риски, что она пойдет не туда/ее оставят и тому подобное
p.s. На чем бы вы сделали проект с нуля?
👍70❤5🤔3😁2🔥1👏1
Хранение деревьев в базе: Материализованный путь
Обычно, для хранения деревьев в базе в таблицу добавляется поле parent_id. Это дубовое решение, которое работает хорошо в небольшом количестве ситуаций. Кому-то даже может хватить, но есть запросы, на которых такая схема не работает. Например если нам понадобится извлечь ветку этого дерева. В таком случае понадобится рекурсивно выполнять запрос с parent_id где для каждого нового запроса parent_id становится id записи из предыдущего запроса. Кто-то пытается решать эту задачу прямо в коде, создавая очень не эффективное решение, кто-то с помощью возможностей базы данных, что сильно привязывает к ней, плюс, страдает интеграция с ORM.
Однако, есть решение лучше. Кое-кто слышал про nested set и это действительно решение, но очень громоздкое, тяжелое в реализации и понимании. Поэтому тут мы его даже не будем рассматривать, так как есть по настоящему элегантное решение, которое называется materialized path.
Идея в Materialized path заключается в том, что каждый узел (каждая запись в базе) хранит полный путь до корня. То есть вместо parent_id, мы добавляем path, который выгляди
Этим подходом мы сразу решили проблему выборку всей нужной ветки. Все что нам надо будет сделать это в коде разд
При такой структуре, для выборки всех потомков понадобится такой запрос:
Для выборки детей:
Одна из приятнейших особенностей materialized path заключается в том, что это очень наглядная схема, когда глядя на сырые данные в базе, сразу понятно что куда. Запросы строятся на здравом смысле и все это еще легко отлаживать.
habr.com/en/articles/46659/
Обычно, для хранения деревьев в базе в таблицу добавляется поле parent_id. Это дубовое решение, которое работает хорошо в небольшом количестве ситуаций. Кому-то даже может хватить, но есть запросы, на которых такая схема не работает. Например если нам понадобится извлечь ветку этого дерева. В таком случае понадобится рекурсивно выполнять запрос с parent_id где для каждого нового запроса parent_id становится id записи из предыдущего запроса. Кто-то пытается решать эту задачу прямо в коде, создавая очень не эффективное решение, кто-то с помощью возможностей базы данных, что сильно привязывает к ней, плюс, страдает интеграция с ORM.
Однако, есть решение лучше. Кое-кто слышал про nested set и это действительно решение, но очень громоздкое, тяжелое в реализации и понимании. Поэтому тут мы его даже не будем рассматривать, так как есть по настоящему элегантное решение, которое называется materialized path.
Идея в Materialized path заключается в том, что каждый узел (каждая запись в базе) хранит полный путь до корня. То есть вместо parent_id, мы добавляем path, который выгляди
т, нап
ример,
так: 1/2/5/8/99/3. / - часто используется как разделитель, но можно выбрать и другой. 1 - в примере это корень под который попадает текущая запись, 3 это прямой родитель. Все что между это промежуточные родительские записи.Этим подходом мы сразу решили проблему выборку всей нужной ветки. Все что нам надо будет сделать это в коде разд
елить 1/2/5/
8/99/3 на идентификаторы, и сделать оди
н in запро
с IN (1, 2, 5, 8, 99, 3)При такой структуре, для выборки всех потомков понадобится такой запрос:
SELECT * FROM <name> WHERE path LIKE '1/2/%';
Для выборки детей:
SELECT * FROM <name> WHERE path LIKE '1/2';
Одна из приятнейших особенностей materialized path заключается в том, что это очень наглядная схема, когда глядя на сырые данные в базе, сразу понятно что куда. Запросы строятся на здравом смысле и все это еще легко отлаживать.
habr.com/en/articles/46659/
👍92🔥36❤3🤔1🐳1👾1
Как мы экономим на фронтенде используя виджеты
Хекслет фронтенда реализован в виде виджетов. Что это значит? Изначально сам проект представляет собой классический MVC (model2), в котором View это обычные серверные шаблоны, в нашем случае на haml.
Это дешево, быстро и эффективно. По дефолту все отлично с сео и кнопкой назад. Нет отдельного фронтенда со своими приколами и интеграцией. Пока на сайте мало интерактивности, с таким подходом можно жить очень долго и счастливо.
Но в какой-то момент нам понадобились интерактивные элементы, например механизм квизов (вопросы после теории), обсуждения (вопросы/ответы во время обучения), тренажер и так далее. Все это было решено делать в виде виджетов, то есть кода, который подключается в классический бекенд шаблон:
Эти файлы готовит webpack на базе entrypoints. Каждый entrypoint это свой виджет. Внутри уже идет подключение реакта, стилей и всего что там нужно (с точки зрения перфоманса вебпак выделяет общие чанки, которые подключаются один раз для всех).
В итоге у нас несколько десятков подобных виджетов, которые подключаются в разных местах, для решения локальных задач. Из общего кода у этих виджетов только библиотеки. Все остальное свое. Размер виджетов от десятков строк кода до 5 тысяч.
Такой подход позволяет оставаться в рамках классической серверной шаблонизации и при этом по необходимости внедрят интерактивные элементы на нужных страницах или на сквозь (как нотификации).
Хекслет фронтенда реализован в виде виджетов. Что это значит? Изначально сам проект представляет собой классический MVC (model2), в котором View это обычные серверные шаблоны, в нашем случае на haml.
.table-responsive
%table.table.table-striped
%thead
%tr
%th= sort_link(@search, :id)
%th= sort_link(@search, :email)
%tbody
- @users.each do |user|
%tr
%td= user.id
%td= user.email
Это дешево, быстро и эффективно. По дефолту все отлично с сео и кнопкой назад. Нет отдельного фронтенда со своими приколами и интеграцией. Пока на сайте мало интерактивности, с таким подходом можно жить очень долго и счастливо.
Но в какой-то момент нам понадобились интерактивные элементы, например механизм квизов (вопросы после теории), обсуждения (вопросы/ответы во время обучения), тренажер и так далее. Все это было решено делать в виде виджетов, то есть кода, который подключается в классический бекенд шаблон:
- append_javascript_packs 'community'
- append_stylesheet_packs 'community'
Эти файлы готовит webpack на базе entrypoints. Каждый entrypoint это свой виджет. Внутри уже идет подключение реакта, стилей и всего что там нужно (с точки зрения перфоманса вебпак выделяет общие чанки, которые подключаются один раз для всех).
import app from '../community/index.jsx';
import './community.scss';
const communityBoxId = 'community-box';
app.init(communityBoxId, /* параметры */);
В итоге у нас несколько десятков подобных виджетов, которые подключаются в разных местах, для решения локальных задач. Из общего кода у этих виджетов только библиотеки. Все остальное свое. Размер виджетов от десятков строк кода до 5 тысяч.
Такой подход позволяет оставаться в рамках классической серверной шаблонизации и при этом по необходимости внедрят интерактивные элементы на нужных страницах или на сквозь (как нотификации).
👍49🐳13🔥12⚡3❤2❤🔥2🤔2
Заблуждения программистов относительно времени
Кто работал со временем в коде, тот в цирке не смеется. Вот вам подборка заблуждений насчет времени, которые гуляют среди программистов:
1. В месяцах бывает 28, 29, 30 или 31 день.
2. В одно и то же время используется только одна календарная система.
3. Переход на летнее время происходит в одно и то же время каждый год.
4. Переход на летнее время происходит в одно и то же время в каждом часовом поясе.
5. Переход на летнее время всегда корректируется на час.
6. В одном и том же месяце везде одинаковое количество дней!
7. Время Unix - это количество секунд, прошедших с 1 января 1970 года.
8. День перед субботой всегда пятница.
9. Если создать два объекта даты рядом друг с другом, они будут представлять одно и то же время. (фантастический генератор Heisenbug)
10. Недели начинаются в понедельник.
11. Дни начинаются утром.
12. Выходные состоят из субботы и воскресенья.
13. В каждой минуте 60 секунд.
14. GMT и UTC - это один и тот же часовой пояс.
15. Время всегда идет вперед.
16. 24:12:34 - недействительное время.
17. Часовые пояса всегда отличаются на целый час
18. Двузначные годы должны быть где-то в диапазоне 1900-2099
19. Существует только 24 часовых пояса
20. Часовые пояса всегда на целые часы удалены от UTC
21. В году 365 или 366 дней.
22. Високосные годы случаются каждые 4 года.
p.s. оригинал поста https://infiniteundo.com/post/25509354022/more-falsehoods-programmers-believe-about-time Там 79 пунктов
Кто работал со временем в коде, тот в цирке не смеется. Вот вам подборка заблуждений насчет времени, которые гуляют среди программистов:
1. В месяцах бывает 28, 29, 30 или 31 день.
2. В одно и то же время используется только одна календарная система.
3. Переход на летнее время происходит в одно и то же время каждый год.
4. Переход на летнее время происходит в одно и то же время в каждом часовом поясе.
5. Переход на летнее время всегда корректируется на час.
6. В одном и том же месяце везде одинаковое количество дней!
7. Время Unix - это количество секунд, прошедших с 1 января 1970 года.
8. День перед субботой всегда пятница.
9. Если создать два объекта даты рядом друг с другом, они будут представлять одно и то же время. (фантастический генератор Heisenbug)
10. Недели начинаются в понедельник.
11. Дни начинаются утром.
12. Выходные состоят из субботы и воскресенья.
13. В каждой минуте 60 секунд.
14. GMT и UTC - это один и тот же часовой пояс.
15. Время всегда идет вперед.
16. 24:12:34 - недействительное время.
17. Часовые пояса всегда отличаются на целый час
18. Двузначные годы должны быть где-то в диапазоне 1900-2099
19. Существует только 24 часовых пояса
20. Часовые пояса всегда на целые часы удалены от UTC
21. В году 365 или 366 дней.
22. Високосные годы случаются каждые 4 года.
p.s. оригинал поста https://infiniteundo.com/post/25509354022/more-falsehoods-programmers-believe-about-time Там 79 пунктов
Tumblr
More falsehoods programmers believe about time; "wisdom of the crowd" edition
A couple of days ago I decided to [write down some of the things I've learned about testing][testing_post] over the course of the last [several years.][codeascraft] In the course of enumerating the...
👍35❤14🔥7😁7🤯5🤔4🤷♂2🤓1
Синхронные VS Асинхронные дейли
Дейли митинги, если без фанатизма, довольно неплохая практика в девелоперских командах. Почти везде где я работал они либо уже были, либо я их внедрял. Как полагалось дейли проводились в коротком формате, стоя и когда все соберутся в одно и тоже время. Этот формат для многих был долгое время единственно правильным.
В какой-то момент все чаще стали появляться удаленные сотрудники и дейли местами переехали в совместный кол по утрам. Кто жил в других часовых поясах напрягался, но в целом жить было можно. Потом у меня появилась своя компания где разница в часовых поясах и времени работы сместилась настолько, что проводить такие дейли стало проблемой. Плюс стал набирать обороты слак и общение частично переехало туда.
Я уже не помню когда пришла эта идея, но в слаке появились боты для проведения асинхронных дейли и мы решили их попробовать внедрить. Практически сразу стало понятно что это чертовски удобно и с тех пор (прошло очень много лет) дейли в командах только асинхронные. Что мы выяснили в процессе:
• Асинхронный дейли напрягает намного меньше 🙂
• Не нужен процессник, который ведет дейли и следит за тем как он проходит. Достаточно руководителя, который может поправить формат дейли, если кто-то пишет не в том формате, который требуется.
• Больше никаких завязок друг на друга, начал работать - заполнил дейли. Никто никого не ждет, никто не пропускает (если не отсутствует), никто не тратит время на то что ему не интересно.
• Асинхронный дейли в слаке внезапно оказался удобен тогда, когда нужно что-то уточнить или поправить человека. Любой человек в команде может зайти в тред к посту и что-то уточнить и синхронизировать свою работу. Плюс это видят остальные, что делает процесс прозрачным.
• Асинхронный текстовый дейли сохраняется, можно примерно понимать что происходит у человека или происходило не только в конкретный день но и в динамике.
В итоге перешли и остались довольны. Пример того как это работает можно посмотреть тут https://geekbot.com/
p.s. Какой дейли у вас в компании? Это эффективно иль нет?
Дейли митинги, если без фанатизма, довольно неплохая практика в девелоперских командах. Почти везде где я работал они либо уже были, либо я их внедрял. Как полагалось дейли проводились в коротком формате, стоя и когда все соберутся в одно и тоже время. Этот формат для многих был долгое время единственно правильным.
В какой-то момент все чаще стали появляться удаленные сотрудники и дейли местами переехали в совместный кол по утрам. Кто жил в других часовых поясах напрягался, но в целом жить было можно. Потом у меня появилась своя компания где разница в часовых поясах и времени работы сместилась настолько, что проводить такие дейли стало проблемой. Плюс стал набирать обороты слак и общение частично переехало туда.
Я уже не помню когда пришла эта идея, но в слаке появились боты для проведения асинхронных дейли и мы решили их попробовать внедрить. Практически сразу стало понятно что это чертовски удобно и с тех пор (прошло очень много лет) дейли в командах только асинхронные. Что мы выяснили в процессе:
• Асинхронный дейли напрягает намного меньше 🙂
• Не нужен процессник, который ведет дейли и следит за тем как он проходит. Достаточно руководителя, который может поправить формат дейли, если кто-то пишет не в том формате, который требуется.
• Больше никаких завязок друг на друга, начал работать - заполнил дейли. Никто никого не ждет, никто не пропускает (если не отсутствует), никто не тратит время на то что ему не интересно.
• Асинхронный дейли в слаке внезапно оказался удобен тогда, когда нужно что-то уточнить или поправить человека. Любой человек в команде может зайти в тред к посту и что-то уточнить и синхронизировать свою работу. Плюс это видят остальные, что делает процесс прозрачным.
• Асинхронный текстовый дейли сохраняется, можно примерно понимать что происходит у человека или происходило не только в конкретный день но и в динамике.
В итоге перешли и остались довольны. Пример того как это работает можно посмотреть тут https://geekbot.com/
p.s. Какой дейли у вас в компании? Это эффективно иль нет?
Geekbot
Geekbot — Standups, Polls & Surveys in Slack and MS Teams
Automate standups, run surveys, and use quick polls to make fast decisions. Free up time for meaningful work!
👍57🔥11❤2❤🔥1🤔1
Фил тут забахал пост в твиттере на тему того, какой язык вам нравится https://twitter.com/fillpackart/status/1750825875669688497 Мой топ для души: Elixir, Clojure, Ocaml, Ruby (и для работы). А у вас?
X (formerly Twitter)
Фил Ранжин (@fillpackart) on X
Какой язык программирования вам сейчас нравится больше всех? Именно нравится, кайф даёт процесс разработки на нём. На бизнес и его ебучие запросы похуй, прям вот для души: какой?
🤡20👍18💩4🤔1
В ближайшие месяцы хотим провести экскурсии в it компании для студентов нашего колледжа https://hexly.ru/ Это Москва, Питер и Новосиб. Ребят если вы можете это организовать или есть кому/кого посоветовать, то напишите плс. Лайк шер алишер.
hexly.ru
Хекслет IT колледж — обучение программированию после 9 и 11 класса
Открыт набор 2024/2025. Поступление без результатов экзаменов на IT-специальность. Колледж информационных технологий в Москве и Санкт-Петербурге. Первый IT-колледж с гарантированной стажировкой
👏16😁3🤔1
Ревью кода, которые не тормозят
Проведение ревью во многих компаниях довольно болезненная тема, пулреквесты висят дням, а то и неделями. Обсуждения затягиваются, иногда приходится много и долго переделывать, а в конце еще целый день ребейза чтобы выкатиться.
Корень сложности здесь кроется в том, что пулреквест обычно решает какую-то задачу от начала до конца. Поэтому недостаточно быстро пробежаться по коду, придется вникать целиком, в том числе в архитектуру решения, так как оно может не соответствовать тому как и куда движется проект, что может повлечь за собой серьезные обсуждения и переделки в конце концов. Все это требует времени и ресурсов мозга, который обычно сопротивляется крупным изменениям, в которые надо погружаться.
Можно считать это издержками производства, но можно пойти и другим путем. Например, разбивать задачу на более мелкие шаги, которые не решают задачу целиком (если она большая), но которые делают какое-то одно законченное понятное действие. Тут часть программистов, обычно, говорит что “моя фича не бьется”, но жизнь показывает, что почти все бьется, но чтобы это увидеть нужно немного потратить время на обсуждение.
По каким критериям можно разбивать задачу?
⁃ По слоям. Например мы можем сначала создать таблицы в базе данных и модели для них. Эта самая важная часть с точки зрения архитектуры кода и при этом она довольно компактная. Использование моделей уже можно добавлять позже, отдельным пулреквестом.
⁃ По возможностям. Можно ограничить функциональность, так чтобы первый рабочий вариант не включал всех требований и не поддерживал все возможные варианты поведения или форматы или что-то еще.
⁃ По компонентам. Просто добавляем куски кода, которые потом соберуться в картинку, но сейчас сами по себе не задействованы. Например утилитные классы и тому подобное. Тут конечно надо находить баланс, чтобы в pr можно было оценить все же этот код его правильность нужность и направление движения.
Одна из фишек такого подхода в том, что подобные пулреквесты требуют намного меньшего внимания так как изменения небольшие и даже если что-то пошло не туда, это можно быстро поправить. Таким образом значительно снижается шанс потерять время и деньги, а значит, что в немалом количестве случаев принятие пулреквестов можно делегировать ребятам с меньшим опытом или вообще дать возможность сливать что-то автоматом при прохождении всех проверок (например если есть требование писать тесты).
Например у себя мы делаем так, что опытные разработчики сами и сливают, при этом они посматривают код друг друга, но уже опосля. Иногда не сливают, если хотят посоветоваться. Мидлы сами не сливают, но пулреквесты делают небольшими. А у джуниоров не бывает больших пулреквестов, поэтому они их делают и ждут когда их проверят.
p.s. Вы страдаете от процесса проверки пулреквестов у вас в компании?
Проведение ревью во многих компаниях довольно болезненная тема, пулреквесты висят дням, а то и неделями. Обсуждения затягиваются, иногда приходится много и долго переделывать, а в конце еще целый день ребейза чтобы выкатиться.
Корень сложности здесь кроется в том, что пулреквест обычно решает какую-то задачу от начала до конца. Поэтому недостаточно быстро пробежаться по коду, придется вникать целиком, в том числе в архитектуру решения, так как оно может не соответствовать тому как и куда движется проект, что может повлечь за собой серьезные обсуждения и переделки в конце концов. Все это требует времени и ресурсов мозга, который обычно сопротивляется крупным изменениям, в которые надо погружаться.
Можно считать это издержками производства, но можно пойти и другим путем. Например, разбивать задачу на более мелкие шаги, которые не решают задачу целиком (если она большая), но которые делают какое-то одно законченное понятное действие. Тут часть программистов, обычно, говорит что “моя фича не бьется”, но жизнь показывает, что почти все бьется, но чтобы это увидеть нужно немного потратить время на обсуждение.
По каким критериям можно разбивать задачу?
⁃ По слоям. Например мы можем сначала создать таблицы в базе данных и модели для них. Эта самая важная часть с точки зрения архитектуры кода и при этом она довольно компактная. Использование моделей уже можно добавлять позже, отдельным пулреквестом.
⁃ По возможностям. Можно ограничить функциональность, так чтобы первый рабочий вариант не включал всех требований и не поддерживал все возможные варианты поведения или форматы или что-то еще.
⁃ По компонентам. Просто добавляем куски кода, которые потом соберуться в картинку, но сейчас сами по себе не задействованы. Например утилитные классы и тому подобное. Тут конечно надо находить баланс, чтобы в pr можно было оценить все же этот код его правильность нужность и направление движения.
Одна из фишек такого подхода в том, что подобные пулреквесты требуют намного меньшего внимания так как изменения небольшие и даже если что-то пошло не туда, это можно быстро поправить. Таким образом значительно снижается шанс потерять время и деньги, а значит, что в немалом количестве случаев принятие пулреквестов можно делегировать ребятам с меньшим опытом или вообще дать возможность сливать что-то автоматом при прохождении всех проверок (например если есть требование писать тесты).
Например у себя мы делаем так, что опытные разработчики сами и сливают, при этом они посматривают код друг друга, но уже опосля. Иногда не сливают, если хотят посоветоваться. Мидлы сами не сливают, но пулреквесты делают небольшими. А у джуниоров не бывает больших пулреквестов, поэтому они их делают и ждут когда их проверят.
p.s. Вы страдаете от процесса проверки пулреквестов у вас в компании?
👍41💯7❤4🤔3😭2🤡1
Парный кодинг для всех
Про парное программирование слышали наверное все, но все ли его практикуют?
Сразу к делу, парное программирование, при правильном использовании, лучшая техника прокачки и распространения знаний в команде. Кроме того, качество кода выдаваемое парами, намного выше чем код, который пишется в одиночку.
Небольшой ликбез. Парное программирование работает так, один пишет код, второй сидит сзади, вникает и подсказывает (а не сам сидит в своем ноуте и делает что-то другое). Пары меняются раз в какое-то время, например полчаса. Меняются это не значит что они работают за одним компом, окружение у всех разное, поэтому они скорее переходят от одного компьютера к другому. При этом парное программирование хорошо работает когда как минимум один из разработчиков опытен. Если оба новички, то им нужно помочь научиться работать в паре. Если говорить про уровень задач, то идеально в парах выполнять средние задачи, когда не слишком просто, но и не слишком сложно (где надо скорее больше сидеть думать или тратить часы на отладку). А еще парнокодить можно удаленно.
Что происходит в это время? Во-первых у разных людей разный уровень владения инструментами и видя как работает пара, другой человек постоянно узнает новые подходы, горячие клавиши и другие примеры оптимизации работы. Тоже самое происходит в коде, подходы, функции, анализ документации, ошибок и многое другое значительно влияют на обоих людей в паре. Это кстати работает как и для опытных разработчиков так и для пары в которой один человек новичок. В это время новичок конечно прокачивается значительно больше чем опытный. Во-вторых, человек который сидит сзади, находится немного в другом режиме работы (мозга), он замечает значительно больше архитектурных проблем и потенциальных багов. Это приводит к повышению качества кода при более высокой скорости разработки чем если бы это был один человек.
Из важного, работать в парах по началу может быть тяжело ментально, тут нужно время на привыкание. Плюс пары могут начать спорить из-за стандартов кодирования, поэтому такие вещи лучше зафиксировать заранее. Плюс, как это не странно, надо чистить зубы и иметь здоровый рот 🙂 В остальном это крутейшая техника, которую имеет смысл регулярно практиковать в любой компании.
Научные исследования https://tuple.app/pair-programming-guide/scientific-research-into-pair-programming
Отличный доклад на тему https://www.youtube.com/watch?v=Vu5ujdZDS6E
p.s. Практикуете ли вы парное программирование у себя в компании?
Про парное программирование слышали наверное все, но все ли его практикуют?
Сразу к делу, парное программирование, при правильном использовании, лучшая техника прокачки и распространения знаний в команде. Кроме того, качество кода выдаваемое парами, намного выше чем код, который пишется в одиночку.
Небольшой ликбез. Парное программирование работает так, один пишет код, второй сидит сзади, вникает и подсказывает (а не сам сидит в своем ноуте и делает что-то другое). Пары меняются раз в какое-то время, например полчаса. Меняются это не значит что они работают за одним компом, окружение у всех разное, поэтому они скорее переходят от одного компьютера к другому. При этом парное программирование хорошо работает когда как минимум один из разработчиков опытен. Если оба новички, то им нужно помочь научиться работать в паре. Если говорить про уровень задач, то идеально в парах выполнять средние задачи, когда не слишком просто, но и не слишком сложно (где надо скорее больше сидеть думать или тратить часы на отладку). А еще парнокодить можно удаленно.
Что происходит в это время? Во-первых у разных людей разный уровень владения инструментами и видя как работает пара, другой человек постоянно узнает новые подходы, горячие клавиши и другие примеры оптимизации работы. Тоже самое происходит в коде, подходы, функции, анализ документации, ошибок и многое другое значительно влияют на обоих людей в паре. Это кстати работает как и для опытных разработчиков так и для пары в которой один человек новичок. В это время новичок конечно прокачивается значительно больше чем опытный. Во-вторых, человек который сидит сзади, находится немного в другом режиме работы (мозга), он замечает значительно больше архитектурных проблем и потенциальных багов. Это приводит к повышению качества кода при более высокой скорости разработки чем если бы это был один человек.
Из важного, работать в парах по началу может быть тяжело ментально, тут нужно время на привыкание. Плюс пары могут начать спорить из-за стандартов кодирования, поэтому такие вещи лучше зафиксировать заранее. Плюс, как это не странно, надо чистить зубы и иметь здоровый рот 🙂 В остальном это крутейшая техника, которую имеет смысл регулярно практиковать в любой компании.
Научные исследования https://tuple.app/pair-programming-guide/scientific-research-into-pair-programming
Отличный доклад на тему https://www.youtube.com/watch?v=Vu5ujdZDS6E
p.s. Практикуете ли вы парное программирование у себя в компании?
tuple.app
Tuple's Pair Programming Guide
Comprehensive guides for thoughtful pair programmers.
👍45❤25🔥3🤔2
simple git hook для всех
Вы знаете что можно удобно управлять хуками в git с помощью либы simple-git-hook?
Два действия:
1. Ставится эта либа через npm
2. Прописывается нужная команда на нужный хук в package.json
3. Запускаетс
Шикарная вещь, ставим во все наши опенсорсы и внутренние проекты.
p.s. Какие подобные улучшалки вы еще знаете?
Вы знаете что можно удобно управлять хуками в git с помощью либы simple-git-hook?
Два действия:
1. Ставится эта либа через npm
2. Прописывается нужная команда на нужный хук в package.json
3. Запускаетс
я команда npx simple
-git-hooks, которая все сама апдейтит
{
"simple-git-hooks": {
"pre-commit": "npx lint-staged",
"pre-push": "cd ../../ && npm run format",
// All unused hooks will be removed automatically by default
// but you can use the `preserveUnused` option like following to prevent this behavior
// if you'd prefer preserve all unused hooks
"preserveUnused": true,
// if you'd prefer preserve specific unused hooks
"preserveUnused": ["commit-msg"]
}
}
Шикарная вещь, ставим во все наши опенсорсы и внутренние проекты.
p.s. Какие подобные улучшалки вы еще знаете?
👏15👍8🥴7🔥2❤1🤔1
Делать ли livecoding на собесе
Тут в твиттере разгорелось после того как Козуля написал о лайвкодинге, который не проходят люди подделавшие резюме. Твит раз https://twitter.com/vladkozulya/status/1754986992570450283 твит два https://twitter.com/vladkozulya/status/1755209744057299174
Как обычно все поделились на две группы, среди которых та что считает лайвкодинг злом. Хочу на эту тему кое что сказать.
Если коротко, то я считаю что уровень джуниор и большинство тех кто идет на мидла, должны проходить стадию лайвкодинга. У синьоров обычно есть либо открытые проекты либо куски кода, либо с ними можно глубоко закопаться в проблематику и технические решения из которых многое становится понятно. По лайвкодить в целом тоже можно, но тут скорее только если есть доп сомнения. В моей практике такого было мало.
С джуниорами у меня была ситуация когда я их нанимал в больших количествах и в какой-то момент почувствовал что могу очень быстро понимать кто потянет, а кто нет. Отменил лайвкодинг и буквально сразу после этого жизнь меня ударила обухом по голове. Я встретил как минимум двух людей, которые умудрились меня заболтать (я многого с них не спрашивал, они же джуны) и я повелся на их осведомленность и рассуждения по разным темам. А потом оказалось что люди просто не могут писать код и не обучаемы за разумное время (у меня за два месяца не получилось их сдвинуть с места). При том что у них был уже опыт на другом месте и когда я спрашивал как так они говорили “у меня были проблемы на другом месте, я подбирал все методом тыка”.
А что касается разговоров что собес это стресс и человек покажет себя хуже. Да это так, но во-первых задание все же, в моем случае, простое, а во-вторых, если человека так парализует, то риск что с ним произойдет тоже самое когда рухнет продакшен (да он потом окрепнет, но риск что нет тоже есть) не иллюзорный и как следствие в-третьих, выбор среди джуниоров достаточно большой, чтобы поставить себе планку “справился с лайвкодингом”.
p.s. Вы делаете лайвкодинг? Проходите его сами и завалили?
p.s.s. Задачка на разминку: Какой угол между часовой и минутной стрелкой когда на часах 15:15? 🙂
Тут в твиттере разгорелось после того как Козуля написал о лайвкодинге, который не проходят люди подделавшие резюме. Твит раз https://twitter.com/vladkozulya/status/1754986992570450283 твит два https://twitter.com/vladkozulya/status/1755209744057299174
Как обычно все поделились на две группы, среди которых та что считает лайвкодинг злом. Хочу на эту тему кое что сказать.
Если коротко, то я считаю что уровень джуниор и большинство тех кто идет на мидла, должны проходить стадию лайвкодинга. У синьоров обычно есть либо открытые проекты либо куски кода, либо с ними можно глубоко закопаться в проблематику и технические решения из которых многое становится понятно. По лайвкодить в целом тоже можно, но тут скорее только если есть доп сомнения. В моей практике такого было мало.
С джуниорами у меня была ситуация когда я их нанимал в больших количествах и в какой-то момент почувствовал что могу очень быстро понимать кто потянет, а кто нет. Отменил лайвкодинг и буквально сразу после этого жизнь меня ударила обухом по голове. Я встретил как минимум двух людей, которые умудрились меня заболтать (я многого с них не спрашивал, они же джуны) и я повелся на их осведомленность и рассуждения по разным темам. А потом оказалось что люди просто не могут писать код и не обучаемы за разумное время (у меня за два месяца не получилось их сдвинуть с места). При том что у них был уже опыт на другом месте и когда я спрашивал как так они говорили “у меня были проблемы на другом месте, я подбирал все методом тыка”.
А что касается разговоров что собес это стресс и человек покажет себя хуже. Да это так, но во-первых задание все же, в моем случае, простое, а во-вторых, если человека так парализует, то риск что с ним произойдет тоже самое когда рухнет продакшен (да он потом окрепнет, но риск что нет тоже есть) не иллюзорный и как следствие в-третьих, выбор среди джуниоров достаточно большой, чтобы поставить себе планку “справился с лайвкодингом”.
p.s. Вы делаете лайвкодинг? Проходите его сами и завалили?
p.s.s. Задачка на разминку: Какой угол между часовой и минутной стрелкой когда на часах 15:15? 🙂
X (formerly Twitter)
Козуля (@vladkozulya) on X
При чем написанное в резюме никак не коррелирует с тем, пройдет ли человек техническое интервью.
Лайвкодинг не щадит никого. Я почти никогда не угадываю, дойдет ли человек до финала или нет. Как так. Это даже не олимпиадная шняга, а задачи прямо из проекта…
Лайвкодинг не щадит никого. Я почти никогда не угадываю, дойдет ли человек до финала или нет. Как так. Это даже не олимпиадная шняга, а задачи прямо из проекта…
👍34🔥8👎2🤔1🤮1
Переписывание редактора Хекслета на TS
Давно я не махал шашками серьезно, а тут полез поправить одну штуку в редактор, ну и как-то затянуло и в итоге уже третью неделю я переписываю его с JS на TS. Заодно так сказать вливаюсь в современные тренды. Я еще не закончил, но история уже получается прикольная, что я даже пытаюсь податься с докладом на holyjs, чтобы там про это рассказать.
Здесь я поделюсь немного разными мыслями, которые возникли в процессе. Понимаю что для многих это банальщина так как TS щас используют все, но вдруг кому будет интересно и даже полезно. Посвящу этот пост бекенду на Next.js
Первое что я сделал это заменил бек fastify на nextjs. Я люблю fastify, но мне хотелось снизить уровень конфигурирования до минимума. Это получилось, что-что, а вот тут next работает из коробки очень хорошо. Иногда все же приходится рестартовать, когда почему-то стейт не обновляется на беке, но в целом оно как-то само там магически работает и достаточно легко поддается легкой кастомизации если надо.
Что удивило, это поддержка бека. Правда вебсокеты подрубаются как костыль и команда разработки не очень спешит заниматься этим вопросом, так как для их платформы Vercel это не вещь, которая принесет деньги. Из-за этого получилось что я одновременно для части апи использую старый роутинг pages, а для части новый в app. Это рекомендация во всех issues.
Из странного, некст не показывает access логи к апи. Если что-то не так, ты вообще не понимаешь что не так. Опций никаких нет, в ишьюсе тихо. Понятно что api не приоритет.
Их хорошего, за счет того что у неста все же есть бек и мне он подходит, то получилось что не надо стартовать два отдельных приложения и менеджерить их. А это всегда требует доп усилий, в таких случаях, надо поставить что-то типа foreman (pm2) или docker compose.
В целом у редактора бекенд очень небольшой, буквально вебсокеты с rpc на 15 действий поверх него и пара rest эндпоинтов. Некст такое обрабатывает легко. Но если бы у меня был по настоящему большой и развесистый бекенд, то я бы брал fastify.
Давно я не махал шашками серьезно, а тут полез поправить одну штуку в редактор, ну и как-то затянуло и в итоге уже третью неделю я переписываю его с JS на TS. Заодно так сказать вливаюсь в современные тренды. Я еще не закончил, но история уже получается прикольная, что я даже пытаюсь податься с докладом на holyjs, чтобы там про это рассказать.
Здесь я поделюсь немного разными мыслями, которые возникли в процессе. Понимаю что для многих это банальщина так как TS щас используют все, но вдруг кому будет интересно и даже полезно. Посвящу этот пост бекенду на Next.js
Первое что я сделал это заменил бек fastify на nextjs. Я люблю fastify, но мне хотелось снизить уровень конфигурирования до минимума. Это получилось, что-что, а вот тут next работает из коробки очень хорошо. Иногда все же приходится рестартовать, когда почему-то стейт не обновляется на беке, но в целом оно как-то само там магически работает и достаточно легко поддается легкой кастомизации если надо.
Что удивило, это поддержка бека. Правда вебсокеты подрубаются как костыль и команда разработки не очень спешит заниматься этим вопросом, так как для их платформы Vercel это не вещь, которая принесет деньги. Из-за этого получилось что я одновременно для части апи использую старый роутинг pages, а для части новый в app. Это рекомендация во всех issues.
Из странного, некст не показывает access логи к апи. Если что-то не так, ты вообще не понимаешь что не так. Опций никаких нет, в ишьюсе тихо. Понятно что api не приоритет.
Их хорошего, за счет того что у неста все же есть бек и мне он подходит, то получилось что не надо стартовать два отдельных приложения и менеджерить их. А это всегда требует доп усилий, в таких случаях, надо поставить что-то типа foreman (pm2) или docker compose.
В целом у редактора бекенд очень небольшой, буквально вебсокеты с rpc на 15 действий поверх него и пара rest эндпоинтов. Некст такое обрабатывает легко. Но если бы у меня был по настоящему большой и развесистый бекенд, то я бы брал fastify.
👍38🔥2🤔1
Кладбище забытых проектов
Большинство проектов на которых я работал программистом закрылись. Не взлетел стартап, разорилась компания, что-то стало не актуально. Иногда, когда надо показать что-то из прошлого, я понимаю, что даже ни один сайт, который хоть как-то был связан с тем что я делал, не работает.
Странное чувство, вроде и не в стол работал, а все в труху. Возникает вопрос, что оставил после себя? А у меня такой вопрос возникает, потому что как программист я уже не сделаю никаких свершений, хотя и продолжаю этим заниматься.
Кое что все таки оставил, одна часть это опенсорс, который может и не стал невероятно популярным, но все же я понаделал разного добра: отправил кучу пулреквестов (недавно у меня приняли пулреквест из php либы, который я года три-четыре назад сделал), создал немного относительно популярных библиотек, собрал большой список тестовых заданий, который наверное стал самым популярным из того что я начинал (но это не код хаха) https://github.com/Hexlet/ru-test-assignments.
Вторая это Хекслет, которым я занимаюсь уже 11 лет. Есть чем городиться, это довольно крутая техническая штука, которая даже легла в основу книги https://painlessrails.com/book/ Несмотря на размер (а Хекслет довольно большой) и возраст, он в отличном состоянии и поддерживается очень небольшой профессиональной командой. Но так как он свой, почему-то нет ощущения, что я сделал что-то как программист, с чужими это как-то по другому работает)
Но вообще больше я скорее сделал уже как наставник, преподаватель и автор курсов, но это уже совсем другая история.
p.s. Что самого крутого сделали вы?
Большинство проектов на которых я работал программистом закрылись. Не взлетел стартап, разорилась компания, что-то стало не актуально. Иногда, когда надо показать что-то из прошлого, я понимаю, что даже ни один сайт, который хоть как-то был связан с тем что я делал, не работает.
Странное чувство, вроде и не в стол работал, а все в труху. Возникает вопрос, что оставил после себя? А у меня такой вопрос возникает, потому что как программист я уже не сделаю никаких свершений, хотя и продолжаю этим заниматься.
Кое что все таки оставил, одна часть это опенсорс, который может и не стал невероятно популярным, но все же я понаделал разного добра: отправил кучу пулреквестов (недавно у меня приняли пулреквест из php либы, который я года три-четыре назад сделал), создал немного относительно популярных библиотек, собрал большой список тестовых заданий, который наверное стал самым популярным из того что я начинал (но это не код хаха) https://github.com/Hexlet/ru-test-assignments.
Вторая это Хекслет, которым я занимаюсь уже 11 лет. Есть чем городиться, это довольно крутая техническая штука, которая даже легла в основу книги https://painlessrails.com/book/ Несмотря на размер (а Хекслет довольно большой) и возраст, он в отличном состоянии и поддерживается очень небольшой профессиональной командой. Но так как он свой, почему-то нет ощущения, что я сделал что-то как программист, с чужими это как-то по другому работает)
Но вообще больше я скорее сделал уже как наставник, преподаватель и автор курсов, но это уже совсем другая история.
p.s. Что самого крутого сделали вы?
GitHub
GitHub - Hexlet/ru-test-assignments: Тестовые задания для самостоятельного выполнения от разных it компаний
Тестовые задания для самостоятельного выполнения от разных it компаний - Hexlet/ru-test-assignments
👍50🔥26❤9❤🔥1🤔1
Шаблоны проектирования
В разных стеках разное отношение к шаблонам проектирования. Где-то про них только и говорят, например, в Java. Там на собесе вас обязательно спросят про SOLID. Где-то себя противопоставляют шаблонам говоря, что они нам не нужны, мы же не Java. Существует даже такая фраза, что чем менее выразительный ваш язык, тем больше шаблонов проектирования в нем присутствует.
Шаблоны штука интересная, я посвятил много лет своей жизни ооп дизайну, но самое смешное, что больше всего шаблоны я понял именно тогда, когда начал заниматься фп. Стало понятна суть многих вещей. Поделюсь накопленной мудростью так сказать)
Большая часть шаблонов, которые описаны в известных книгах, посвящены конкретным кускам кода, а не архитектуре в целом. Честно говоря их влияние на систему не такое большое, как об этом принято думать или написано в этих же книгах, в отличии от архитектурных шаблонов типа MVC.
Какие проблемы они например решают? Вы возможно не поверите, но значительное количество шаблонов проектирования это всего лишь вариация на тему полиморфизма подтипов (или subtyping, не путать с параметрическим и ad-hoc полиморфизмами), когда у нас есть общий интерфейс (по смыслу, а не обязательно как конструкция) и разные реализации. Сюда входят: команда, стратегия, стейт, декоратор, прокси и адаптер. Если упрощать, то такой полиморфизм решает две задачи:
• Убирает ифы из кода. Да вот так вот просто.
• Позволяет управлять кодом через конфигурацию, когда мы не очередной иф вставляем или правим сам код где используется объект, а мы в конфигурации приложения меняем реализацию. В основном это делается в библиотеках, которые мы можем конфигурировать. На уровне приложений такое применяется там где есть контейнеры зависимостей, например, активно в php и java фреймворках. Редко в js, go, python, ruby.
Правильный взгляд на такие паттерны состоит в том, чтобы видеть именно задачу полиморфизма, в таком случае вы сможете использовать подходящее решение даже не зная паттерна. Но не надо забывать, что паттерн далеко не всегда решает проблемы, важно, чтобы он вводился только тогда, когда это выгоднее чем бахнуть обычный иф.
p.s. Часто ли вы используете паттерны?
p.s.s. Домашнее задание: Какой паттерн используется в ситуации, когда вы хотите иметь возможность подменить базу данных, в течении жизни приложения (например переехать с одной на другую) без изменения кода (в теории)
В разных стеках разное отношение к шаблонам проектирования. Где-то про них только и говорят, например, в Java. Там на собесе вас обязательно спросят про SOLID. Где-то себя противопоставляют шаблонам говоря, что они нам не нужны, мы же не Java. Существует даже такая фраза, что чем менее выразительный ваш язык, тем больше шаблонов проектирования в нем присутствует.
Шаблоны штука интересная, я посвятил много лет своей жизни ооп дизайну, но самое смешное, что больше всего шаблоны я понял именно тогда, когда начал заниматься фп. Стало понятна суть многих вещей. Поделюсь накопленной мудростью так сказать)
Большая часть шаблонов, которые описаны в известных книгах, посвящены конкретным кускам кода, а не архитектуре в целом. Честно говоря их влияние на систему не такое большое, как об этом принято думать или написано в этих же книгах, в отличии от архитектурных шаблонов типа MVC.
Какие проблемы они например решают? Вы возможно не поверите, но значительное количество шаблонов проектирования это всего лишь вариация на тему полиморфизма подтипов (или subtyping, не путать с параметрическим и ad-hoc полиморфизмами), когда у нас есть общий интерфейс (по смыслу, а не обязательно как конструкция) и разные реализации. Сюда входят: команда, стратегия, стейт, декоратор, прокси и адаптер. Если упрощать, то такой полиморфизм решает две задачи:
• Убирает ифы из кода. Да вот так вот просто.
• Позволяет управлять кодом через конфигурацию, когда мы не очередной иф вставляем или правим сам код где используется объект, а мы в конфигурации приложения меняем реализацию. В основном это делается в библиотеках, которые мы можем конфигурировать. На уровне приложений такое применяется там где есть контейнеры зависимостей, например, активно в php и java фреймворках. Редко в js, go, python, ruby.
Правильный взгляд на такие паттерны состоит в том, чтобы видеть именно задачу полиморфизма, в таком случае вы сможете использовать подходящее решение даже не зная паттерна. Но не надо забывать, что паттерн далеко не всегда решает проблемы, важно, чтобы он вводился только тогда, когда это выгоднее чем бахнуть обычный иф.
p.s. Часто ли вы используете паттерны?
p.s.s. Домашнее задание: Какой паттерн используется в ситуации, когда вы хотите иметь возможность подменить базу данных, в течении жизни приложения (например переехать с одной на другую) без изменения кода (в теории)
👍37🔥19❤8🤔1
План на ближайшие посты по шаблонам проектирования
Тема с шаблонами зашла, она как обычно вызывает разные чувства, но комментариев много и интерес есть. Я хочу сделать цикл прямо обучающих постов, в которых мы кое что разберем. Однако, сразу хочу обозначить. Это ни в коем случае не стандартное вот шаблон вот поехали. Мы попробуем разобраться со смысловой частью программирования, в которой появляются шаблоны с рассмотрением проблемы, альтернатив, плюсов минусов и так далее. И что важно, даже когда мы будем говорить про паттерны, мы не будем говорить про набор классов как это описано в большинстве мест, мы будем говорить про организацию кода, которая решает реальную проблему, не зависимо от того, на каком языке мы пишем. На выходе у вас должно появиться более четкое понимание проблем, которые вызывает сложный код и как это код можно упростить (или усложнить) разными решениями. Первый пост будет завтра, а тут немного комментариев на те комментарии, которые вы оставляли к посту:
> С тех пор как ушел на го, то сразу исчез этот мешок барахла в голове. Максимум на практике встречаются декораторы. Но у меня в конторе не фанатики писать код по книгам. Используем там где уместно, а уместно прям мало где. Но это в го.
Если смотреть в суть вещей, то проблемы, которые решают часть шаблонов (не все), являются языконезависимыми проблемами. Но даже к ним есть отторжение именно из-за постоянного навязывания и культа карго. Плюс на разных языках решают разные задачи, поэтому часть паттернов просто уходит автоматически. Например абстрактная фабрика это очень специфический паттерн, встречающийся в определенных задачах, которые решают полтора землекопа в мире (конечно чуть больше, но идея понятна).
> Неироничный вопрос: а чем программистов так пугают ифы? Ветвление - фундаментальная конструкция в языках программирования. А то иной раз вместо простого ифа два интерфейса, пять классов, абстрактная фабрика абстрактных синглтонов (утрировано). Так происходит от бездумного применения паттернов ради паттернов, потому что так написали в книжках умные дядьки. Простые вещи должны быть простыми.
Как раз в этом соль, когда понимание этой системы проблем, а за ними и шаблонов достаточно хорошее, то в каждой задаче достаточно легко ответить на вопрос, а нужно ли вообще что-то кроме ифов делать. В прикладном коде намного меньше чем кажется программистам. В библиотеках и фреймворках этого сильно больше, но их мало кто пишет.
> Интересно, кто-то на практике сталкивался с потребностью поменять базу во время жизни приложения?
У меня на практике разок было, но в первую очередь в ORM это сделано для того, чтобы какую бы вы базу не выбрали изначально, вам не пришлось бы как-то менять свои подходы в написании кода, по крайней мере в первое время.
> А в чем вообще разница между медиатором и адаптером?)
Поговорим) Однако тут надо идти от проблематики, в которых эти паттерны возникают.
p.s. Знаете ли вы что такое динамическая диспетчеризация и мультидиспетчеризация?
Тема с шаблонами зашла, она как обычно вызывает разные чувства, но комментариев много и интерес есть. Я хочу сделать цикл прямо обучающих постов, в которых мы кое что разберем. Однако, сразу хочу обозначить. Это ни в коем случае не стандартное вот шаблон вот поехали. Мы попробуем разобраться со смысловой частью программирования, в которой появляются шаблоны с рассмотрением проблемы, альтернатив, плюсов минусов и так далее. И что важно, даже когда мы будем говорить про паттерны, мы не будем говорить про набор классов как это описано в большинстве мест, мы будем говорить про организацию кода, которая решает реальную проблему, не зависимо от того, на каком языке мы пишем. На выходе у вас должно появиться более четкое понимание проблем, которые вызывает сложный код и как это код можно упростить (или усложнить) разными решениями. Первый пост будет завтра, а тут немного комментариев на те комментарии, которые вы оставляли к посту:
> С тех пор как ушел на го, то сразу исчез этот мешок барахла в голове. Максимум на практике встречаются декораторы. Но у меня в конторе не фанатики писать код по книгам. Используем там где уместно, а уместно прям мало где. Но это в го.
Если смотреть в суть вещей, то проблемы, которые решают часть шаблонов (не все), являются языконезависимыми проблемами. Но даже к ним есть отторжение именно из-за постоянного навязывания и культа карго. Плюс на разных языках решают разные задачи, поэтому часть паттернов просто уходит автоматически. Например абстрактная фабрика это очень специфический паттерн, встречающийся в определенных задачах, которые решают полтора землекопа в мире (конечно чуть больше, но идея понятна).
> Неироничный вопрос: а чем программистов так пугают ифы? Ветвление - фундаментальная конструкция в языках программирования. А то иной раз вместо простого ифа два интерфейса, пять классов, абстрактная фабрика абстрактных синглтонов (утрировано). Так происходит от бездумного применения паттернов ради паттернов, потому что так написали в книжках умные дядьки. Простые вещи должны быть простыми.
Как раз в этом соль, когда понимание этой системы проблем, а за ними и шаблонов достаточно хорошее, то в каждой задаче достаточно легко ответить на вопрос, а нужно ли вообще что-то кроме ифов делать. В прикладном коде намного меньше чем кажется программистам. В библиотеках и фреймворках этого сильно больше, но их мало кто пишет.
> Интересно, кто-то на практике сталкивался с потребностью поменять базу во время жизни приложения?
У меня на практике разок было, но в первую очередь в ORM это сделано для того, чтобы какую бы вы базу не выбрали изначально, вам не пришлось бы как-то менять свои подходы в написании кода, по крайней мере в первое время.
> А в чем вообще разница между медиатором и адаптером?)
Поговорим) Однако тут надо идти от проблематики, в которых эти паттерны возникают.
p.s. Знаете ли вы что такое динамическая диспетчеризация и мультидиспетчеризация?
❤39🔥20👍7🤩2🤔1👌1🤓1
Шаблоны проектирования: Синглотон
Начнем с чего-то наиболее простого, но наиболее известного. Синглотон, это объект, который создается ровно в одном экземпляре и за этим не надо следить, он сам за этим следит за счет того как его реализуют.
Эта идея кажется привлекательной только для тех, кто никогда с ними в коде не сталкивался. В реальности же, постоянно выясняется, что ситуаций где нужны разные объекты гораздо больше чем кажется. Сегодня была одна база данных, завтра мы подключимся к двум. Кроме того, в тестах почти всегда нужна возможность задавать любые объекты с нуля индивидуально, так как разные тесты как раз тестируют разные кейсы.
Фактически, синглотон больше используют там, где нужен доступ к объекту из совершенно разных мест приложения и не хочется его везде прокидывать. То есть с его помощью реализуют глобальную переменную, к которой есть доступ отовсюду. Подобный код говорит о двух вещах: в коде появляется много неявных зависимостей, которые особенно больно стреляют если объект имеет состояние и оно может меняться. В таком случае вы никогда не можете быть ни в чем уверенными, а в работающей программе будут появляться глюки. Ну и банально это говорит о том что абстракции текут по полной программе, раз мы работаем не через интерфейсы (не как конструкции, а по смыслу), а тянем такой объект напрямую во внутрь на любом уровне.
Но как это ни странно, все же есть разные экосистемы с разными порядками. Например эталонный пример где синглотоны никак не нужны и не используются почти никогда это spring (boot), так как там крутой контейнер зависимостей, который решает проблему доступа и управляет жизненным циклам объектов. В JavaScript, Python и Ruby подобные синглотоны встречаются, но в другой реализации. В JavaScript и Python иногда делают файлы, в которых формируются данные/объект, который может быть импортирован куда-то и этот объект инициализирован ровно один раз, так как сам файл интерпретируется только один раз. В Ruby такое принято и в самой Rails и в ее библиотеках, когда класс содержит статическое поле с объектом. Да это сильно упрощает написание кода (так как нет контейнера) и помогает новичкам, но иногда больно стреляет и если не следить за абстракциями, делает из кода кашу. Кстати поэтому в тестах на Ruby часто встречается такое когда синглотон меняют в начале теста и потом возвращают обратно в конце. Подобные хаки для синголотон встречаются и в других языках, я точно такое делал сам на php
Общий вывод такой. Синглотон лучше не использовать если есть возможность этого не делать, но в вашей экосистеме могут быть устоявшиеся каноны, которые лучше не нарушать или как минимум вы должны понимать последствия своих действий.
Про альтернативу синголотоном можно прочитать тут: https://en.wikipedia.org/wiki/Dependency_injection
p.s. Вы сталкивались с проблемами в использовании синглотонов?
Начнем с чего-то наиболее простого, но наиболее известного. Синглотон, это объект, который создается ровно в одном экземпляре и за этим не надо следить, он сам за этим следит за счет того как его реализуют.
public class Singleton {
// The volatile keyword ensures that multiple threads handle the uniqueInstance variable correctly when it is being initialized to the Singleton instance.
private static volatile Singleton uniqueInstance;
// private constructor so no one can instantiate the class from outside
private Singleton() {}
// Method to return an instance of the class
public static Singleton getInstance() {
// First check without locking to improve performance
if (uniqueInstance == null) {
// Locking the class object to only let one thread in to check and instantiate the singleton
synchronized (Singleton.class) {
// Double-check whether the instance is null or not to ensure that no two instances are created
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}
// other useful methods here
}
Эта идея кажется привлекательной только для тех, кто никогда с ними в коде не сталкивался. В реальности же, постоянно выясняется, что ситуаций где нужны разные объекты гораздо больше чем кажется. Сегодня была одна база данных, завтра мы подключимся к двум. Кроме того, в тестах почти всегда нужна возможность задавать любые объекты с нуля индивидуально, так как разные тесты как раз тестируют разные кейсы.
Фактически, синглотон больше используют там, где нужен доступ к объекту из совершенно разных мест приложения и не хочется его везде прокидывать. То есть с его помощью реализуют глобальную переменную, к которой есть доступ отовсюду. Подобный код говорит о двух вещах: в коде появляется много неявных зависимостей, которые особенно больно стреляют если объект имеет состояние и оно может меняться. В таком случае вы никогда не можете быть ни в чем уверенными, а в работающей программе будут появляться глюки. Ну и банально это говорит о том что абстракции текут по полной программе, раз мы работаем не через интерфейсы (не как конструкции, а по смыслу), а тянем такой объект напрямую во внутрь на любом уровне.
Но как это ни странно, все же есть разные экосистемы с разными порядками. Например эталонный пример где синглотоны никак не нужны и не используются почти никогда это spring (boot), так как там крутой контейнер зависимостей, который решает проблему доступа и управляет жизненным циклам объектов. В JavaScript, Python и Ruby подобные синглотоны встречаются, но в другой реализации. В JavaScript и Python иногда делают файлы, в которых формируются данные/объект, который может быть импортирован куда-то и этот объект инициализирован ровно один раз, так как сам файл интерпретируется только один раз. В Ruby такое принято и в самой Rails и в ее библиотеках, когда класс содержит статическое поле с объектом. Да это сильно упрощает написание кода (так как нет контейнера) и помогает новичкам, но иногда больно стреляет и если не следить за абстракциями, делает из кода кашу. Кстати поэтому в тестах на Ruby часто встречается такое когда синглотон меняют в начале теста и потом возвращают обратно в конце. Подобные хаки для синголотон встречаются и в других языках, я точно такое делал сам на php
Общий вывод такой. Синглотон лучше не использовать если есть возможность этого не делать, но в вашей экосистеме могут быть устоявшиеся каноны, которые лучше не нарушать или как минимум вы должны понимать последствия своих действий.
Про альтернативу синголотоном можно прочитать тут: https://en.wikipedia.org/wiki/Dependency_injection
p.s. Вы сталкивались с проблемами в использовании синглотонов?
Wikipedia
Dependency injection
technique in software engineering
👍46✍9🫡9❤7